1 /* 32-bit ELF support for TI PRU. 2 Copyright (C) 2014-2018 Free Software Foundation, Inc. 3 Contributed by Dimitar Dimitrov <dimitar@dinux.eu> 4 Based on elf32-nios2.c 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23 /* This file handles TI PRU ELF targets. */ 24 25 #include "sysdep.h" 26 #include "bfd.h" 27 #include "libbfd.h" 28 #include "bfdlink.h" 29 #include "genlink.h" 30 #include "elf-bfd.h" 31 #include "elf/pru.h" 32 #include "opcode/pru.h" 33 #include "libiberty.h" 34 35 #define SWAP_VALS(A,B) \ 36 do { \ 37 (A) ^= (B); \ 38 (B) ^= (A); \ 39 (A) ^= (B); \ 40 } while (0) 41 42 /* Enable debugging printout at stdout with this variable. */ 43 static bfd_boolean debug_relax = FALSE; 44 45 /* Forward declarations. */ 46 static bfd_reloc_status_type pru_elf32_pmem_relocate 47 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 48 static bfd_reloc_status_type pru_elf32_s10_pcrel_relocate 49 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 50 static bfd_reloc_status_type pru_elf32_u8_pcrel_relocate 51 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 52 static bfd_reloc_status_type pru_elf32_ldi32_relocate 53 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 54 static bfd_reloc_status_type bfd_elf_pru_diff_relocate 55 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 56 57 /* Target vector. */ 58 extern const bfd_target pru_elf32_vec; 59 60 /* The relocation table used for SHT_REL sections. */ 61 static reloc_howto_type elf_pru_howto_table_rel[] = { 62 /* No relocation. */ 63 HOWTO (R_PRU_NONE, /* type */ 64 0, /* rightshift */ 65 0, /* size (0 = byte, 1 = short, 2 = long) */ 66 3, /* bitsize */ 67 FALSE, /* pc_relative */ 68 0, /* bitpos */ 69 complain_overflow_dont,/* complain_on_overflow */ 70 bfd_elf_generic_reloc, /* special_function */ 71 "R_PRU_NONE", /* name */ 72 FALSE, /* partial_inplace */ 73 0, /* src_mask */ 74 0, /* dst_mask */ 75 FALSE), /* pcrel_offset */ 76 77 HOWTO (R_PRU_16_PMEM, 78 2, 79 1, /* short */ 80 32, 81 FALSE, 82 0, 83 complain_overflow_dont, 84 bfd_elf_generic_reloc, 85 "R_PRU_16_PMEM", 86 FALSE, 87 0, /* src_mask */ 88 0xffff, 89 FALSE), 90 91 HOWTO (R_PRU_U16_PMEMIMM, 92 2, 93 2, 94 32, 95 FALSE, 96 8, 97 complain_overflow_unsigned, 98 pru_elf32_pmem_relocate, 99 "R_PRU_U16_PMEMIMM", 100 FALSE, 101 0, /* src_mask */ 102 0x00ffff00, 103 FALSE), 104 105 HOWTO (R_PRU_BFD_RELOC_16, 106 0, 107 1, /* short */ 108 16, 109 FALSE, 110 0, 111 complain_overflow_bitfield, 112 bfd_elf_generic_reloc, 113 "R_PRU_BFD_RELOC16", 114 FALSE, 115 0, /* src_mask */ 116 0x0000ffff, 117 FALSE), 118 119 /* 16-bit unsigned immediate relocation. */ 120 HOWTO (R_PRU_U16, /* type */ 121 0, /* rightshift */ 122 2, /* size (0 = byte, 1 = short, 2 = long) */ 123 16, /* bitsize */ 124 FALSE, /* pc_relative */ 125 8, /* bitpos */ 126 complain_overflow_unsigned, /* complain on overflow */ 127 bfd_elf_generic_reloc, /* special function */ 128 "R_PRU_U16", /* name */ 129 FALSE, /* partial_inplace */ 130 0, /* src_mask */ 131 0x00ffff00, /* dest_mask */ 132 FALSE), /* pcrel_offset */ 133 134 HOWTO (R_PRU_32_PMEM, 135 2, 136 2, /* long */ 137 32, 138 FALSE, 139 0, 140 complain_overflow_dont, 141 pru_elf32_pmem_relocate, 142 "R_PRU_32_PMEM", 143 FALSE, 144 0, /* src_mask */ 145 0xffffffff, 146 FALSE), 147 148 HOWTO (R_PRU_BFD_RELOC_32, 149 0, 150 2, /* long */ 151 32, 152 FALSE, 153 0, 154 complain_overflow_dont, 155 bfd_elf_generic_reloc, 156 "R_PRU_BFD_RELOC32", 157 FALSE, 158 0, /* src_mask */ 159 0xffffffff, 160 FALSE), 161 162 HOWTO (R_PRU_S10_PCREL, 163 2, 164 2, 165 10, 166 TRUE, 167 0, 168 complain_overflow_bitfield, 169 pru_elf32_s10_pcrel_relocate, 170 "R_PRU_S10_PCREL", 171 FALSE, 172 0, /* src_mask */ 173 0x060000ff, 174 TRUE), 175 176 HOWTO (R_PRU_U8_PCREL, 177 2, 178 2, 179 8, 180 TRUE, 181 0, 182 complain_overflow_unsigned, 183 pru_elf32_u8_pcrel_relocate, 184 "R_PRU_U8_PCREL", 185 FALSE, 186 0, /* src_mask */ 187 0x000000ff, 188 TRUE), 189 190 HOWTO (R_PRU_LDI32, 191 0, /* rightshift */ 192 4, /* size (4 = 8bytes) */ 193 32, /* bitsize */ 194 FALSE, /* pc_relative */ 195 0, /* bitpos */ 196 complain_overflow_unsigned, /* complain on overflow */ 197 pru_elf32_ldi32_relocate, /* special function */ 198 "R_PRU_LDI32", /* name */ 199 FALSE, /* partial_inplace */ 200 0, /* src_mask */ 201 0xffffffff, /* dest_mask */ 202 FALSE), /* pcrel_offset */ 203 204 /* GNU-specific relocations. */ 205 HOWTO (R_PRU_GNU_BFD_RELOC_8, 206 0, 207 0, /* byte */ 208 8, 209 FALSE, 210 0, 211 complain_overflow_bitfield, 212 bfd_elf_generic_reloc, 213 "R_PRU_BFD_RELOC8", 214 FALSE, 215 0, /* src_mask */ 216 0x000000ff, 217 FALSE), 218 219 HOWTO (R_PRU_GNU_DIFF8, /* type */ 220 0, /* rightshift */ 221 0, /* size (0 = byte, 1 = short, 2 = long) */ 222 8, /* bitsize */ 223 FALSE, /* pc_relative */ 224 0, /* bitpos */ 225 complain_overflow_bitfield, /* complain_on_overflow */ 226 bfd_elf_pru_diff_relocate, /* special_function */ 227 "R_PRU_DIFF8", /* name */ 228 FALSE, /* partial_inplace */ 229 0, /* src_mask */ 230 0xff, /* dst_mask */ 231 FALSE), /* pcrel_offset */ 232 233 HOWTO (R_PRU_GNU_DIFF16, /* type */ 234 0, /* rightshift */ 235 1, /* size (0 = byte, 1 = short, 2 = long) */ 236 16, /* bitsize */ 237 FALSE, /* pc_relative */ 238 0, /* bitpos */ 239 complain_overflow_bitfield, /* complain_on_overflow */ 240 bfd_elf_pru_diff_relocate,/* special_function */ 241 "R_PRU_DIFF16", /* name */ 242 FALSE, /* partial_inplace */ 243 0, /* src_mask */ 244 0xffff, /* dst_mask */ 245 FALSE), /* pcrel_offset */ 246 247 HOWTO (R_PRU_GNU_DIFF32, /* type */ 248 0, /* rightshift */ 249 2, /* size (0 = byte, 1 = short, 2 = long) */ 250 32, /* bitsize */ 251 FALSE, /* pc_relative */ 252 0, /* bitpos */ 253 complain_overflow_bitfield, /* complain_on_overflow */ 254 bfd_elf_pru_diff_relocate,/* special_function */ 255 "R_PRU_DIFF32", /* name */ 256 FALSE, /* partial_inplace */ 257 0, /* src_mask */ 258 0xffffffff, /* dst_mask */ 259 FALSE), /* pcrel_offset */ 260 261 HOWTO (R_PRU_GNU_DIFF16_PMEM, /* type */ 262 0, /* rightshift */ 263 1, /* size (0 = byte, 1 = short, 2 = long) */ 264 16, /* bitsize */ 265 FALSE, /* pc_relative */ 266 0, /* bitpos */ 267 complain_overflow_bitfield, /* complain_on_overflow */ 268 bfd_elf_pru_diff_relocate,/* special_function */ 269 "R_PRU_DIFF16_PMEM", /* name */ 270 FALSE, /* partial_inplace */ 271 0, /* src_mask */ 272 0xffff, /* dst_mask */ 273 FALSE), /* pcrel_offset */ 274 275 HOWTO (R_PRU_GNU_DIFF32_PMEM, /* type */ 276 0, /* rightshift */ 277 2, /* size (0 = byte, 1 = short, 2 = long) */ 278 32, /* bitsize */ 279 FALSE, /* pc_relative */ 280 0, /* bitpos */ 281 complain_overflow_bitfield, /* complain_on_overflow */ 282 bfd_elf_pru_diff_relocate,/* special_function */ 283 "R_PRU_DIFF32_PMEM", /* name */ 284 FALSE, /* partial_inplace */ 285 0, /* src_mask */ 286 0xffffffff, /* dst_mask */ 287 FALSE), /* pcrel_offset */ 288 289 /* Add other relocations here. */ 290 }; 291 292 static unsigned char elf_code_to_howto_index[R_PRU_ILLEGAL + 1]; 293 294 /* Return the howto for relocation RTYPE. */ 295 296 static reloc_howto_type * 297 lookup_howto (unsigned int rtype) 298 { 299 static bfd_boolean initialized = FALSE; 300 int i; 301 int howto_tbl_size = (int) (sizeof (elf_pru_howto_table_rel) 302 / sizeof (elf_pru_howto_table_rel[0])); 303 304 if (! initialized) 305 { 306 initialized = TRUE; 307 memset (elf_code_to_howto_index, 0xff, 308 sizeof (elf_code_to_howto_index)); 309 for (i = 0; i < howto_tbl_size; i++) 310 elf_code_to_howto_index[elf_pru_howto_table_rel[i].type] = i; 311 } 312 313 if (rtype > R_PRU_ILLEGAL) 314 return NULL; 315 i = elf_code_to_howto_index[rtype]; 316 if (i >= howto_tbl_size) 317 return NULL; 318 return elf_pru_howto_table_rel + i; 319 } 320 321 /* Map for converting BFD reloc types to PRU reloc types. */ 322 323 struct elf_reloc_map 324 { 325 bfd_reloc_code_real_type bfd_val; 326 enum elf_pru_reloc_type elf_val; 327 }; 328 329 static const struct elf_reloc_map pru_reloc_map[] = 330 { 331 {BFD_RELOC_NONE, R_PRU_NONE}, 332 {BFD_RELOC_PRU_16_PMEM, R_PRU_16_PMEM}, 333 {BFD_RELOC_PRU_U16_PMEMIMM, R_PRU_U16_PMEMIMM}, 334 {BFD_RELOC_16, R_PRU_BFD_RELOC_16}, 335 {BFD_RELOC_PRU_U16, R_PRU_U16}, 336 {BFD_RELOC_PRU_32_PMEM, R_PRU_32_PMEM}, 337 {BFD_RELOC_32, R_PRU_BFD_RELOC_32}, 338 {BFD_RELOC_PRU_S10_PCREL, R_PRU_S10_PCREL}, 339 {BFD_RELOC_PRU_U8_PCREL, R_PRU_U8_PCREL}, 340 {BFD_RELOC_PRU_LDI32, R_PRU_LDI32}, 341 342 {BFD_RELOC_8, R_PRU_GNU_BFD_RELOC_8}, 343 {BFD_RELOC_PRU_GNU_DIFF8, R_PRU_GNU_DIFF8}, 344 {BFD_RELOC_PRU_GNU_DIFF16, R_PRU_GNU_DIFF16}, 345 {BFD_RELOC_PRU_GNU_DIFF32, R_PRU_GNU_DIFF32}, 346 {BFD_RELOC_PRU_GNU_DIFF16_PMEM, R_PRU_GNU_DIFF16_PMEM}, 347 {BFD_RELOC_PRU_GNU_DIFF32_PMEM, R_PRU_GNU_DIFF32_PMEM}, 348 }; 349 350 351 /* Assorted hash table functions. */ 352 353 /* Create an entry in a PRU ELF linker hash table. */ 354 355 static struct bfd_hash_entry * 356 link_hash_newfunc (struct bfd_hash_entry *entry, 357 struct bfd_hash_table *table, const char *string) 358 { 359 /* Allocate the structure if it has not already been allocated by a 360 subclass. */ 361 if (entry == NULL) 362 { 363 entry = bfd_hash_allocate (table, 364 sizeof (struct elf_link_hash_entry)); 365 if (entry == NULL) 366 return entry; 367 } 368 369 /* Call the allocation method of the superclass. */ 370 entry = _bfd_elf_link_hash_newfunc (entry, table, string); 371 372 return entry; 373 } 374 375 /* Implement bfd_elf32_bfd_reloc_type_lookup: 376 Given a BFD reloc type, return a howto structure. */ 377 378 static reloc_howto_type * 379 pru_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 380 bfd_reloc_code_real_type code) 381 { 382 unsigned int i; 383 384 for (i = 0; i < ARRAY_SIZE (pru_reloc_map); ++i) 385 if (pru_reloc_map[i].bfd_val == code) 386 return lookup_howto ((unsigned int) pru_reloc_map[i].elf_val); 387 return NULL; 388 } 389 390 /* Implement bfd_elf32_bfd_reloc_name_lookup: 391 Given a reloc name, return a howto structure. */ 392 393 static reloc_howto_type * 394 pru_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 395 const char *r_name) 396 { 397 unsigned int i; 398 399 for (i = 0; i < ARRAY_SIZE (elf_pru_howto_table_rel); i++) 400 if (elf_pru_howto_table_rel[i].name 401 && strcasecmp (elf_pru_howto_table_rel[i].name, r_name) == 0) 402 return &elf_pru_howto_table_rel[i]; 403 404 return NULL; 405 } 406 407 /* Implement elf_info_to_howto: 408 Given a ELF32 relocation, fill in a arelent structure. */ 409 410 static bfd_boolean 411 pru_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr, 412 Elf_Internal_Rela *dst) 413 { 414 unsigned int r_type; 415 416 r_type = ELF32_R_TYPE (dst->r_info); 417 if (r_type >= R_PRU_ILLEGAL) 418 { 419 /* xgettext:c-format */ 420 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type); 421 bfd_set_error (bfd_error_bad_value); 422 return FALSE; 423 } 424 425 cache_ptr->howto = lookup_howto (r_type); 426 return cache_ptr->howto != NULL; 427 } 428 429 /* Do the relocations that require special handling. */ 430 /* Produce a word address for program memory. Linker scripts will put .text 431 at a high offset in order to differentiate it from .data. So here we also 432 mask the high bits of PMEM address. 433 434 But why 1MB when internal Program Memory much smaller? We want to catch 435 unintended overflows. 436 437 Why not use (1<<31) as an offset and a mask? Sitara DDRAM usually resides 438 there, and users might want to put some shared carveout memory region in 439 their linker scripts. So 0x80000000 might be a valid .data address. 440 441 Note that we still keep and pass down the original howto. This way we 442 can reuse this function for several different relocations. */ 443 static bfd_reloc_status_type 444 pru_elf32_do_pmem_relocate (bfd *abfd, reloc_howto_type *howto, 445 asection *input_section, 446 bfd_byte *data, bfd_vma offset, 447 bfd_vma symbol_value, bfd_vma addend) 448 { 449 symbol_value = symbol_value + addend; 450 addend = 0; 451 symbol_value &= 0x3fffff; 452 return _bfd_final_link_relocate (howto, abfd, input_section, 453 data, offset, symbol_value, addend); 454 } 455 456 /* Direct copy of _bfd_final_link_relocate, but with special 457 "fill-in". This copy-paste mumbo jumbo is only needed because BFD 458 cannot deal correctly with non-contiguous bit fields. */ 459 static bfd_reloc_status_type 460 pru_elf32_do_s10_pcrel_relocate (bfd *input_bfd, reloc_howto_type *howto, 461 asection *input_section, 462 bfd_byte *contents, bfd_vma address, 463 bfd_vma relocation, bfd_vma addend) 464 { 465 bfd_byte *location; 466 bfd_vma x = 0; 467 bfd_vma qboff; 468 bfd_reloc_status_type flag = bfd_reloc_ok; 469 470 /* Sanity check the address. */ 471 if (address > bfd_get_section_limit (input_bfd, input_section)) 472 return bfd_reloc_outofrange; 473 474 BFD_ASSERT (howto->pc_relative); 475 BFD_ASSERT (howto->pcrel_offset); 476 477 relocation = relocation + addend - (input_section->output_section->vma 478 + input_section->output_offset) - address; 479 480 location = contents + address; 481 482 /* Get the value we are going to relocate. */ 483 BFD_ASSERT (bfd_get_reloc_size (howto) == 4); 484 x = bfd_get_32 (input_bfd, location); 485 486 qboff = GET_BROFF_SIGNED (x) << howto->rightshift; 487 relocation += qboff; 488 489 BFD_ASSERT (howto->complain_on_overflow == complain_overflow_bitfield); 490 491 if (relocation > 2047 && relocation < (bfd_vma)-2048l) 492 flag = bfd_reloc_overflow; 493 494 /* Check that target address is word-aligned. */ 495 if (relocation & ((1 << howto->rightshift) - 1)) 496 flag = bfd_reloc_outofrange; 497 498 relocation >>= (bfd_vma) howto->rightshift; 499 500 /* Fill-in the RELOCATION to the right bits of X. */ 501 SET_BROFF_URAW (x, relocation); 502 503 bfd_put_32 (input_bfd, x, location); 504 505 return flag; 506 } 507 508 static bfd_reloc_status_type 509 pru_elf32_do_u8_pcrel_relocate (bfd *abfd, reloc_howto_type *howto, 510 asection *input_section, 511 bfd_byte *data, bfd_vma offset, 512 bfd_vma symbol_value, bfd_vma addend) 513 { 514 bfd_vma relocation; 515 516 BFD_ASSERT (howto->pc_relative); 517 BFD_ASSERT (howto->pcrel_offset); 518 519 relocation = symbol_value + addend - (input_section->output_section->vma 520 + input_section->output_offset) - offset; 521 relocation >>= howto->rightshift; 522 523 /* 0 and 1 are invalid target labels for LOOP. We cannot 524 encode this info in HOWTO, so catch such cases here. */ 525 if (relocation < 2) 526 return bfd_reloc_outofrange; 527 528 return _bfd_final_link_relocate (howto, abfd, input_section, 529 data, offset, symbol_value, addend); 530 } 531 532 /* Idea and code taken from elf32-d30v. */ 533 static bfd_reloc_status_type 534 pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto, 535 asection *input_section, 536 bfd_byte *data, bfd_vma offset, 537 bfd_vma symbol_value, bfd_vma addend) 538 { 539 bfd_signed_vma relocation; 540 bfd_size_type octets = offset * bfd_octets_per_byte (abfd); 541 bfd_byte *location; 542 unsigned long in1, in2; 543 544 /* A hacked-up version of _bfd_final_link_relocate() follows. */ 545 546 /* Sanity check the address. */ 547 if (octets + bfd_get_reloc_size (howto) 548 > bfd_get_section_limit_octets (abfd, input_section)) 549 return bfd_reloc_outofrange; 550 551 /* This function assumes that we are dealing with a basic relocation 552 against a symbol. We want to compute the value of the symbol to 553 relocate to. This is just VALUE, the value of the symbol, plus 554 ADDEND, any addend associated with the reloc. */ 555 relocation = symbol_value + addend; 556 557 BFD_ASSERT (!howto->pc_relative); 558 559 /* A hacked-up version of _bfd_relocate_contents() follows. */ 560 location = data + offset * bfd_octets_per_byte (abfd); 561 562 BFD_ASSERT (!howto->pc_relative); 563 564 in1 = bfd_get_32 (abfd, location); 565 in2 = bfd_get_32 (abfd, location + 4); 566 567 SET_INSN_FIELD (IMM16, in1, relocation >> 16); 568 SET_INSN_FIELD (IMM16, in2, relocation & 0xffff); 569 570 bfd_put_32 (abfd, in1, location); 571 bfd_put_32 (abfd, in2, location + 4); 572 573 /* Old GAS and LD versions have a bug, where the two 574 LDI instructions are swapped. Detect such object 575 files and bail. */ 576 if (GET_INSN_FIELD (RDSEL, in1) != RSEL_31_16) 577 { 578 /* xgettext:c-format */ 579 _bfd_error_handler (_("error: %pB: old incompatible object file detected"), 580 abfd); 581 return bfd_reloc_notsupported; 582 } 583 584 return bfd_reloc_ok; 585 } 586 587 /* HOWTO handlers for relocations that require special handling. */ 588 589 static bfd_reloc_status_type 590 pru_elf32_pmem_relocate (bfd *abfd, arelent *reloc_entry, 591 asymbol *symbol, void *data, 592 asection *input_section, bfd *output_bfd, 593 char **error_message) 594 { 595 /* If this is a relocatable link (output_bfd test tells us), just 596 call the generic function. Any adjustment will be done at final 597 link time. */ 598 if (output_bfd != NULL) 599 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 600 input_section, output_bfd, error_message); 601 602 BFD_ASSERT (0); 603 return pru_elf32_do_pmem_relocate (abfd, reloc_entry->howto, 604 input_section, 605 data, reloc_entry->address, 606 (symbol->value 607 + symbol->section->output_section->vma 608 + symbol->section->output_offset), 609 reloc_entry->addend); 610 } 611 612 static bfd_reloc_status_type 613 pru_elf32_s10_pcrel_relocate (bfd *abfd, arelent *reloc_entry, 614 asymbol *symbol, void *data, 615 asection *input_section, bfd *output_bfd, 616 char **error_message) 617 { 618 /* If this is a relocatable link (output_bfd test tells us), just 619 call the generic function. Any adjustment will be done at final 620 link time. */ 621 if (output_bfd != NULL) 622 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 623 input_section, output_bfd, error_message); 624 625 return pru_elf32_do_s10_pcrel_relocate (abfd, reloc_entry->howto, 626 input_section, data, 627 reloc_entry->address, 628 (symbol->value 629 + symbol->section->output_section->vma 630 + symbol->section->output_offset), 631 reloc_entry->addend); 632 } 633 634 static bfd_reloc_status_type 635 pru_elf32_u8_pcrel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 636 void *data, asection *input_section, 637 bfd *output_bfd, 638 char **error_message) 639 { 640 /* If this is a relocatable link (output_bfd test tells us), just 641 call the generic function. Any adjustment will be done at final 642 link time. */ 643 if (output_bfd != NULL) 644 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 645 input_section, output_bfd, error_message); 646 647 return pru_elf32_do_u8_pcrel_relocate (abfd, reloc_entry->howto, 648 input_section, 649 data, reloc_entry->address, 650 (symbol->value 651 + symbol->section->output_section->vma 652 + symbol->section->output_offset), 653 reloc_entry->addend); 654 } 655 656 static bfd_reloc_status_type 657 pru_elf32_ldi32_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 658 void *data, asection *input_section, 659 bfd *output_bfd, 660 char **error_message) 661 { 662 /* If this is a relocatable link (output_bfd test tells us), just 663 call the generic function. Any adjustment will be done at final 664 link time. */ 665 if (output_bfd != NULL) 666 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 667 input_section, output_bfd, error_message); 668 669 return pru_elf32_do_ldi32_relocate (abfd, reloc_entry->howto, 670 input_section, 671 data, reloc_entry->address, 672 (symbol->value 673 + symbol->section->output_section->vma 674 + symbol->section->output_offset), 675 reloc_entry->addend); 676 } 677 678 679 /* Implement elf_backend_relocate_section. */ 680 static bfd_boolean 681 pru_elf32_relocate_section (bfd *output_bfd, 682 struct bfd_link_info *info, 683 bfd *input_bfd, 684 asection *input_section, 685 bfd_byte *contents, 686 Elf_Internal_Rela *relocs, 687 Elf_Internal_Sym *local_syms, 688 asection **local_sections) 689 { 690 struct bfd_elf_section_data * esd = elf_section_data (input_section); 691 Elf_Internal_Shdr *symtab_hdr; 692 struct elf_link_hash_entry **sym_hashes; 693 Elf_Internal_Rela *rel; 694 Elf_Internal_Rela *relend; 695 bfd_boolean is_rel_reloc; 696 697 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 698 sym_hashes = elf_sym_hashes (input_bfd); 699 relend = relocs + input_section->reloc_count; 700 701 /* See if we have a REL type relocation. */ 702 is_rel_reloc = (esd->rel.hdr != NULL); 703 /* Sanity check - only one type of relocation per section. 704 FIXME: Theoretically it is possible to have both types, 705 but if that happens how can we distinguish between the two ? */ 706 BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr); 707 708 for (rel = relocs; rel < relend; rel++) 709 { 710 reloc_howto_type *howto; 711 unsigned long r_symndx; 712 Elf_Internal_Sym *sym; 713 asection *sec; 714 struct elf_link_hash_entry *h; 715 bfd_vma relocation; 716 bfd_reloc_status_type r = bfd_reloc_ok; 717 const char *name = NULL; 718 const char* msg = (const char*) NULL; 719 bfd_boolean unresolved_reloc; 720 bfd_vma addend; 721 722 /* If we are using a REL relocation then the addend should be empty. */ 723 BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0); 724 725 r_symndx = ELF32_R_SYM (rel->r_info); 726 727 howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info)); 728 h = NULL; 729 sym = NULL; 730 sec = NULL; 731 732 if (r_symndx < symtab_hdr->sh_info) 733 { 734 sym = local_syms + r_symndx; 735 sec = local_sections[r_symndx]; 736 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 737 } 738 else 739 { 740 bfd_boolean warned, ignored; 741 742 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 743 r_symndx, symtab_hdr, sym_hashes, 744 h, sec, relocation, 745 unresolved_reloc, warned, ignored); 746 } 747 748 if (sec && discarded_section (sec)) 749 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 750 rel, 1, relend, howto, 0, contents); 751 752 /* Nothing more to do unless this is a final link. */ 753 if (bfd_link_relocatable (info)) 754 continue; 755 756 if (howto) 757 { 758 switch (howto->type) 759 { 760 case R_PRU_NONE: 761 /* We don't need to find a value for this symbol. It's just a 762 marker. */ 763 r = bfd_reloc_ok; 764 break; 765 766 case R_PRU_U16: 767 if (is_rel_reloc) 768 { 769 unsigned long insn; 770 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); 771 addend = GET_INSN_FIELD (IMM16, insn); 772 } 773 else 774 addend = rel->r_addend; 775 r = _bfd_final_link_relocate (howto, input_bfd, 776 input_section, contents, 777 rel->r_offset, relocation, 778 addend); 779 break; 780 781 case R_PRU_U16_PMEMIMM: 782 case R_PRU_32_PMEM: 783 case R_PRU_16_PMEM: 784 if (is_rel_reloc && howto->type == R_PRU_U16_PMEMIMM) 785 { 786 unsigned long insn; 787 insn = bfd_get_32 (input_bfd, contents + rel->r_offset); 788 addend = GET_INSN_FIELD (IMM16, insn) << 2; 789 } 790 else if (is_rel_reloc && howto->type == R_PRU_32_PMEM) 791 { 792 addend = bfd_get_32 (input_bfd, contents + rel->r_offset); 793 addend <<= 2; 794 } 795 else if (is_rel_reloc && howto->type == R_PRU_16_PMEM) 796 { 797 addend = bfd_get_16 (input_bfd, contents + rel->r_offset); 798 addend <<= 2; 799 } 800 else 801 { 802 BFD_ASSERT (!is_rel_reloc); 803 addend = rel->r_addend; 804 } 805 r = pru_elf32_do_pmem_relocate (input_bfd, howto, 806 input_section, 807 contents, rel->r_offset, 808 relocation, addend); 809 break; 810 case R_PRU_S10_PCREL: 811 BFD_ASSERT (! is_rel_reloc); 812 r = pru_elf32_do_s10_pcrel_relocate (input_bfd, howto, 813 input_section, 814 contents, 815 rel->r_offset, 816 relocation, 817 rel->r_addend); 818 break; 819 case R_PRU_U8_PCREL: 820 BFD_ASSERT (! is_rel_reloc); 821 r = pru_elf32_do_u8_pcrel_relocate (input_bfd, howto, 822 input_section, 823 contents, 824 rel->r_offset, 825 relocation, 826 rel->r_addend); 827 break; 828 case R_PRU_LDI32: 829 if (is_rel_reloc) 830 { 831 unsigned long in1, in2; 832 in1 = bfd_get_32 (input_bfd, contents + rel->r_offset); 833 in2 = bfd_get_32 (input_bfd, contents + rel->r_offset + 4); 834 addend = (GET_INSN_FIELD (IMM16, in1) << 16) 835 | GET_INSN_FIELD (IMM16, in2); 836 } 837 else 838 { 839 addend = rel->r_addend; 840 } 841 r = pru_elf32_do_ldi32_relocate (input_bfd, howto, 842 input_section, 843 contents, 844 rel->r_offset, 845 relocation, 846 addend); 847 break; 848 case R_PRU_GNU_DIFF8: 849 case R_PRU_GNU_DIFF16: 850 case R_PRU_GNU_DIFF32: 851 case R_PRU_GNU_DIFF16_PMEM: 852 case R_PRU_GNU_DIFF32_PMEM: 853 /* GNU extensions support only rela. */ 854 BFD_ASSERT (! is_rel_reloc); 855 /* Nothing to do here, as contents already contain the 856 diff value. */ 857 r = bfd_reloc_ok; 858 break; 859 860 case R_PRU_BFD_RELOC_16: 861 if (is_rel_reloc) 862 addend = bfd_get_16 (input_bfd, contents + rel->r_offset); 863 else 864 addend = rel->r_addend; 865 r = _bfd_final_link_relocate (howto, input_bfd, 866 input_section, contents, 867 rel->r_offset, relocation, 868 addend); 869 break; 870 871 case R_PRU_BFD_RELOC_32: 872 if (is_rel_reloc) 873 addend = bfd_get_32 (input_bfd, contents + rel->r_offset); 874 else 875 addend = rel->r_addend; 876 r = _bfd_final_link_relocate (howto, input_bfd, 877 input_section, contents, 878 rel->r_offset, relocation, 879 addend); 880 break; 881 882 case R_PRU_GNU_BFD_RELOC_8: 883 BFD_ASSERT (! is_rel_reloc); 884 r = _bfd_final_link_relocate (howto, input_bfd, 885 input_section, contents, 886 rel->r_offset, relocation, 887 rel->r_addend); 888 break; 889 890 default: 891 BFD_ASSERT (0); 892 break; 893 } 894 } 895 else 896 r = bfd_reloc_notsupported; 897 898 if (r != bfd_reloc_ok) 899 { 900 if (h != NULL) 901 name = h->root.root.string; 902 else 903 { 904 name = bfd_elf_string_from_elf_section (input_bfd, 905 symtab_hdr->sh_link, 906 sym->st_name); 907 if (name == NULL || *name == '\0') 908 name = bfd_section_name (input_bfd, sec); 909 } 910 911 switch (r) 912 { 913 case bfd_reloc_overflow: 914 (*info->callbacks->reloc_overflow) (info, NULL, name, 915 howto->name, (bfd_vma) 0, 916 input_bfd, input_section, 917 rel->r_offset); 918 break; 919 920 case bfd_reloc_undefined: 921 (*info->callbacks->undefined_symbol) (info, name, input_bfd, 922 input_section, 923 rel->r_offset, TRUE); 924 break; 925 926 case bfd_reloc_outofrange: 927 if (msg == NULL) 928 msg = _("relocation out of range"); 929 break; 930 931 case bfd_reloc_notsupported: 932 if (msg == NULL) 933 msg = _("unsupported relocation"); 934 break; 935 936 case bfd_reloc_dangerous: 937 if (msg == NULL) 938 msg = _("dangerous relocation"); 939 break; 940 941 default: 942 if (msg == NULL) 943 msg = _("unknown error"); 944 break; 945 } 946 947 if (msg) 948 { 949 (*info->callbacks->warning) (info, msg, name, input_bfd, 950 input_section, rel->r_offset); 951 return FALSE; 952 } 953 } 954 } 955 return TRUE; 956 } 957 958 959 /* Perform a diff relocation. Nothing to do, as the difference value is 960 already written into the section's contents. */ 961 962 static bfd_reloc_status_type 963 bfd_elf_pru_diff_relocate (bfd *abfd ATTRIBUTE_UNUSED, 964 arelent *reloc_entry ATTRIBUTE_UNUSED, 965 asymbol *symbol ATTRIBUTE_UNUSED, 966 void *data ATTRIBUTE_UNUSED, 967 asection *input_section ATTRIBUTE_UNUSED, 968 bfd *output_bfd ATTRIBUTE_UNUSED, 969 char **error_message ATTRIBUTE_UNUSED) 970 { 971 return bfd_reloc_ok; 972 } 973 974 975 /* Returns whether the relocation type passed is a diff reloc. */ 976 977 static bfd_boolean 978 elf32_pru_is_diff_reloc (Elf_Internal_Rela *irel) 979 { 980 return (ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF8 981 || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16 982 || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32 983 || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16_PMEM 984 || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32_PMEM); 985 } 986 987 /* Reduce the diff value written in the section by count if the shrinked 988 insn address happens to fall between the two symbols for which this 989 diff reloc was emitted. */ 990 991 static void 992 elf32_pru_adjust_diff_reloc_value (bfd *abfd, 993 struct bfd_section *isec, 994 Elf_Internal_Rela *irel, 995 bfd_vma symval, 996 bfd_vma shrinked_insn_address, 997 int count) 998 { 999 unsigned char *reloc_contents = NULL; 1000 unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents; 1001 if (isec_contents == NULL) 1002 { 1003 if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents)) 1004 return; 1005 1006 elf_section_data (isec)->this_hdr.contents = isec_contents; 1007 } 1008 1009 reloc_contents = isec_contents + irel->r_offset; 1010 1011 /* Read value written in object file. */ 1012 bfd_signed_vma x = 0; 1013 switch (ELF32_R_TYPE (irel->r_info)) 1014 { 1015 case R_PRU_GNU_DIFF8: 1016 { 1017 x = bfd_get_signed_8 (abfd, reloc_contents); 1018 break; 1019 } 1020 case R_PRU_GNU_DIFF16: 1021 { 1022 x = bfd_get_signed_16 (abfd, reloc_contents); 1023 break; 1024 } 1025 case R_PRU_GNU_DIFF32: 1026 { 1027 x = bfd_get_signed_32 (abfd, reloc_contents); 1028 break; 1029 } 1030 case R_PRU_GNU_DIFF16_PMEM: 1031 { 1032 x = bfd_get_signed_16 (abfd, reloc_contents) * 4; 1033 break; 1034 } 1035 case R_PRU_GNU_DIFF32_PMEM: 1036 { 1037 x = bfd_get_signed_32 (abfd, reloc_contents) * 4; 1038 break; 1039 } 1040 default: 1041 { 1042 BFD_FAIL (); 1043 } 1044 } 1045 1046 /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written 1047 into the object file at the reloc offset. sym2's logical value is 1048 symval (<start_of_section>) + reloc addend. Compute the start and end 1049 addresses and check if the shrinked insn falls between sym1 and sym2. */ 1050 1051 bfd_vma end_address = symval + irel->r_addend; 1052 bfd_vma start_address = end_address - x; 1053 1054 /* Shrink the absolute DIFF value (get the to labels "closer" 1055 together), because we have removed data between labels. */ 1056 if (x < 0) 1057 { 1058 x += count; 1059 /* In case the signed x is negative, restore order. */ 1060 SWAP_VALS (end_address, start_address); 1061 } 1062 else 1063 { 1064 x -= count; 1065 } 1066 1067 /* Reduce the diff value by count bytes and write it back into section 1068 contents. */ 1069 1070 if (shrinked_insn_address >= start_address 1071 && shrinked_insn_address <= end_address) 1072 { 1073 switch (ELF32_R_TYPE (irel->r_info)) 1074 { 1075 case R_PRU_GNU_DIFF8: 1076 { 1077 bfd_put_signed_8 (abfd, x & 0xFF, reloc_contents); 1078 break; 1079 } 1080 case R_PRU_GNU_DIFF16: 1081 { 1082 bfd_put_signed_16 (abfd, x & 0xFFFF, reloc_contents); 1083 break; 1084 } 1085 case R_PRU_GNU_DIFF32: 1086 { 1087 bfd_put_signed_32 (abfd, x & 0xFFFFFFFF, reloc_contents); 1088 break; 1089 } 1090 case R_PRU_GNU_DIFF16_PMEM: 1091 { 1092 bfd_put_signed_16 (abfd, (x / 4) & 0xFFFF, reloc_contents); 1093 break; 1094 } 1095 case R_PRU_GNU_DIFF32_PMEM: 1096 { 1097 bfd_put_signed_32 (abfd, (x / 4) & 0xFFFFFFFF, reloc_contents); 1098 break; 1099 } 1100 default: 1101 { 1102 BFD_FAIL (); 1103 } 1104 } 1105 1106 } 1107 } 1108 1109 /* Delete some bytes from a section while changing the size of an instruction. 1110 The parameter "addr" denotes the section-relative offset pointing just 1111 behind the shrinked instruction. "addr+count" point at the first 1112 byte just behind the original unshrinked instruction. 1113 1114 Idea copied from the AVR port. */ 1115 1116 static bfd_boolean 1117 pru_elf_relax_delete_bytes (bfd *abfd, 1118 asection *sec, 1119 bfd_vma addr, 1120 int count) 1121 { 1122 Elf_Internal_Shdr *symtab_hdr; 1123 unsigned int sec_shndx; 1124 bfd_byte *contents; 1125 Elf_Internal_Rela *irel, *irelend; 1126 Elf_Internal_Sym *isym; 1127 Elf_Internal_Sym *isymbuf = NULL; 1128 bfd_vma toaddr; 1129 struct elf_link_hash_entry **sym_hashes; 1130 struct elf_link_hash_entry **end_hashes; 1131 unsigned int symcount; 1132 1133 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1134 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1135 contents = elf_section_data (sec)->this_hdr.contents; 1136 1137 toaddr = sec->size; 1138 1139 irel = elf_section_data (sec)->relocs; 1140 irelend = irel + sec->reloc_count; 1141 1142 /* Actually delete the bytes. */ 1143 if (toaddr - addr - count > 0) 1144 memmove (contents + addr, contents + addr + count, 1145 (size_t) (toaddr - addr - count)); 1146 sec->size -= count; 1147 1148 /* Adjust all the reloc addresses. */ 1149 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 1150 { 1151 bfd_vma old_reloc_address; 1152 1153 old_reloc_address = (sec->output_section->vma 1154 + sec->output_offset + irel->r_offset); 1155 1156 /* Get the new reloc address. */ 1157 if ((irel->r_offset > addr 1158 && irel->r_offset < toaddr)) 1159 { 1160 if (debug_relax) 1161 printf ("Relocation at address 0x%x needs to be moved.\n" 1162 "Old section offset: 0x%x, New section offset: 0x%x \n", 1163 (unsigned int) old_reloc_address, 1164 (unsigned int) irel->r_offset, 1165 (unsigned int) ((irel->r_offset) - count)); 1166 1167 irel->r_offset -= count; 1168 } 1169 1170 } 1171 1172 /* The reloc's own addresses are now ok. However, we need to readjust 1173 the reloc's addend, i.e. the reloc's value if two conditions are met: 1174 1.) the reloc is relative to a symbol in this section that 1175 is located in front of the shrinked instruction 1176 2.) symbol plus addend end up behind the shrinked instruction. 1177 1178 The most common case where this happens are relocs relative to 1179 the section-start symbol. 1180 1181 This step needs to be done for all of the sections of the bfd. */ 1182 1183 { 1184 struct bfd_section *isec; 1185 1186 for (isec = abfd->sections; isec; isec = isec->next) 1187 { 1188 bfd_vma symval; 1189 bfd_vma shrinked_insn_address; 1190 1191 if (isec->reloc_count == 0) 1192 continue; 1193 1194 shrinked_insn_address = (sec->output_section->vma 1195 + sec->output_offset + addr); 1196 1197 irel = elf_section_data (isec)->relocs; 1198 /* PR 12161: Read in the relocs for this section if necessary. */ 1199 if (irel == NULL) 1200 irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE); 1201 1202 for (irelend = irel + isec->reloc_count; 1203 irel < irelend; 1204 irel++) 1205 { 1206 /* Read this BFD's local symbols if we haven't done 1207 so already. */ 1208 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1209 { 1210 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1211 if (isymbuf == NULL) 1212 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1213 symtab_hdr->sh_info, 0, 1214 NULL, NULL, NULL); 1215 if (isymbuf == NULL) 1216 return FALSE; 1217 } 1218 1219 /* Get the value of the symbol referred to by the reloc. */ 1220 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1221 { 1222 /* A local symbol. */ 1223 asection *sym_sec; 1224 1225 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1226 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1227 symval = isym->st_value; 1228 /* If the reloc is absolute, it will not have 1229 a symbol or section associated with it. */ 1230 if (sym_sec == sec) 1231 { 1232 symval += sym_sec->output_section->vma 1233 + sym_sec->output_offset; 1234 1235 if (debug_relax) 1236 printf ("Checking if the relocation's " 1237 "addend needs corrections.\n" 1238 "Address of anchor symbol: 0x%x \n" 1239 "Address of relocation target: 0x%x \n" 1240 "Address of relaxed insn: 0x%x \n", 1241 (unsigned int) symval, 1242 (unsigned int) (symval + irel->r_addend), 1243 (unsigned int) shrinked_insn_address); 1244 1245 /* Shrink the special DIFF relocations. */ 1246 if (elf32_pru_is_diff_reloc (irel)) 1247 { 1248 elf32_pru_adjust_diff_reloc_value (abfd, isec, irel, 1249 symval, 1250 shrinked_insn_address, 1251 count); 1252 } 1253 1254 /* Fix the addend, if it is affected. */ 1255 if (symval <= shrinked_insn_address 1256 && (symval + irel->r_addend) > shrinked_insn_address) 1257 { 1258 1259 irel->r_addend -= count; 1260 1261 if (debug_relax) 1262 printf ("Relocation's addend needed to be fixed \n"); 1263 } 1264 } 1265 /* else...Reference symbol is absolute. 1266 No adjustment needed. */ 1267 } 1268 /* else...Reference symbol is extern. No need for adjusting 1269 the addend. */ 1270 } 1271 } 1272 } 1273 1274 /* Adjust the local symbols defined in this section. */ 1275 isym = (Elf_Internal_Sym *) symtab_hdr->contents; 1276 /* Fix PR 9841, there may be no local symbols. */ 1277 if (isym != NULL) 1278 { 1279 Elf_Internal_Sym *isymend; 1280 1281 isymend = isym + symtab_hdr->sh_info; 1282 for (; isym < isymend; isym++) 1283 { 1284 if (isym->st_shndx == sec_shndx) 1285 { 1286 if (isym->st_value > addr 1287 && isym->st_value <= toaddr) 1288 isym->st_value -= count; 1289 1290 if (isym->st_value <= addr 1291 && isym->st_value + isym->st_size > addr) 1292 { 1293 /* If this assert fires then we have a symbol that ends 1294 part way through an instruction. Does that make 1295 sense? */ 1296 BFD_ASSERT (isym->st_value + isym->st_size >= addr + count); 1297 isym->st_size -= count; 1298 } 1299 } 1300 } 1301 } 1302 1303 /* Now adjust the global symbols defined in this section. */ 1304 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1305 - symtab_hdr->sh_info); 1306 sym_hashes = elf_sym_hashes (abfd); 1307 end_hashes = sym_hashes + symcount; 1308 for (; sym_hashes < end_hashes; sym_hashes++) 1309 { 1310 struct elf_link_hash_entry *sym_hash = *sym_hashes; 1311 if ((sym_hash->root.type == bfd_link_hash_defined 1312 || sym_hash->root.type == bfd_link_hash_defweak) 1313 && sym_hash->root.u.def.section == sec) 1314 { 1315 if (sym_hash->root.u.def.value > addr 1316 && sym_hash->root.u.def.value <= toaddr) 1317 sym_hash->root.u.def.value -= count; 1318 1319 if (sym_hash->root.u.def.value <= addr 1320 && (sym_hash->root.u.def.value + sym_hash->size > addr)) 1321 { 1322 /* If this assert fires then we have a symbol that ends 1323 part way through an instruction. Does that make 1324 sense? */ 1325 BFD_ASSERT (sym_hash->root.u.def.value + sym_hash->size 1326 >= addr + count); 1327 sym_hash->size -= count; 1328 } 1329 } 1330 } 1331 1332 return TRUE; 1333 } 1334 1335 static bfd_boolean 1336 pru_elf32_relax_section (bfd * abfd, asection * sec, 1337 struct bfd_link_info * link_info, 1338 bfd_boolean * again) 1339 { 1340 Elf_Internal_Shdr * symtab_hdr; 1341 Elf_Internal_Rela * internal_relocs; 1342 Elf_Internal_Rela * irel; 1343 Elf_Internal_Rela * irelend; 1344 bfd_byte * contents = NULL; 1345 Elf_Internal_Sym * isymbuf = NULL; 1346 1347 /* Assume nothing changes. */ 1348 *again = FALSE; 1349 1350 /* We don't have to do anything for a relocatable link, if 1351 this section does not have relocs, or if this is not a 1352 code section. */ 1353 if (bfd_link_relocatable (link_info) 1354 || (sec->flags & SEC_RELOC) == 0 1355 || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0) 1356 return TRUE; 1357 1358 symtab_hdr = & elf_tdata (abfd)->symtab_hdr; 1359 1360 /* Get a copy of the native relocations. */ 1361 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 1362 link_info->keep_memory); 1363 if (internal_relocs == NULL) 1364 goto error_return; 1365 1366 /* Walk through them looking for relaxing opportunities. */ 1367 irelend = internal_relocs + sec->reloc_count; 1368 1369 for (irel = internal_relocs; irel < irelend; irel++) 1370 { 1371 bfd_vma symval; 1372 1373 /* Get the section contents if we haven't done so already. */ 1374 if (contents == NULL) 1375 { 1376 /* Get cached copy if it exists. */ 1377 if (elf_section_data (sec)->this_hdr.contents != NULL) 1378 contents = elf_section_data (sec)->this_hdr.contents; 1379 else if (! bfd_malloc_and_get_section (abfd, sec, &contents)) 1380 goto error_return; 1381 } 1382 1383 /* Read this BFD's local symbols if we haven't done so already. */ 1384 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1385 { 1386 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1387 if (isymbuf == NULL) 1388 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1389 symtab_hdr->sh_info, 0, 1390 NULL, NULL, NULL); 1391 if (isymbuf == NULL) 1392 goto error_return; 1393 } 1394 1395 /* Get the value of the symbol referred to by the reloc. */ 1396 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1397 { 1398 /* A local symbol. */ 1399 Elf_Internal_Sym *isym; 1400 asection *sym_sec; 1401 1402 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1403 if (isym->st_shndx == SHN_UNDEF) 1404 sym_sec = bfd_und_section_ptr; 1405 else if (isym->st_shndx == SHN_ABS) 1406 sym_sec = bfd_abs_section_ptr; 1407 else if (isym->st_shndx == SHN_COMMON) 1408 sym_sec = bfd_com_section_ptr; 1409 else 1410 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1411 symval = (isym->st_value 1412 + sym_sec->output_section->vma + sym_sec->output_offset); 1413 } 1414 else 1415 { 1416 unsigned long indx; 1417 struct elf_link_hash_entry *h; 1418 1419 /* An external symbol. */ 1420 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1421 h = elf_sym_hashes (abfd)[indx]; 1422 BFD_ASSERT (h != NULL); 1423 1424 if (h->root.type != bfd_link_hash_defined 1425 && h->root.type != bfd_link_hash_defweak) 1426 /* This appears to be a reference to an undefined 1427 symbol. Just ignore it--it will be caught by the 1428 regular reloc processing. */ 1429 continue; 1430 1431 symval = (h->root.u.def.value 1432 + h->root.u.def.section->output_section->vma 1433 + h->root.u.def.section->output_offset); 1434 } 1435 1436 /* For simplicity of coding, we are going to modify the section 1437 contents, the section relocs, and the BFD symbol table. We 1438 must tell the rest of the code not to free up this 1439 information. It would be possible to instead create a table 1440 of changes which have to be made, as is done in coff-mips.c; 1441 that would be more work, but would require less memory when 1442 the linker is run. */ 1443 1444 /* Check if we can remove an LDI instruction from the LDI32 1445 pseudo instruction if the upper 16 operand bits are zero. */ 1446 if (ELF32_R_TYPE (irel->r_info) == (int) R_PRU_LDI32) 1447 { 1448 bfd_vma value = symval + irel->r_addend; 1449 1450 if (debug_relax) 1451 printf ("R_PRU_LDI32 with value=0x%lx\n", (long) value); 1452 1453 if ((long) value >> 16 == 0) 1454 { 1455 unsigned long insn; 1456 1457 /* Note that we've changed the relocs, section contents. */ 1458 elf_section_data (sec)->relocs = internal_relocs; 1459 elf_section_data (sec)->this_hdr.contents = contents; 1460 symtab_hdr->contents = (unsigned char *) isymbuf; 1461 1462 /* Make the second instruction load the 16-bit constant 1463 into the full 32-bit register. */ 1464 insn = bfd_get_32 (abfd, contents + irel->r_offset + 4); 1465 1466 /* Old GAS and LD versions have a bug, where the two 1467 LDI instructions are swapped. Detect such object 1468 files and bail. */ 1469 if (GET_INSN_FIELD (RDSEL, insn) != RSEL_15_0) 1470 { 1471 /* xgettext:c-format */ 1472 _bfd_error_handler (_("error: %pB: old incompatible object file detected"), 1473 abfd); 1474 goto error_return; 1475 } 1476 1477 SET_INSN_FIELD (RDSEL, insn, RSEL_31_0); 1478 bfd_put_32 (abfd, insn, contents + irel->r_offset + 4); 1479 1480 /* Delete the first LDI instruction. Note that there should 1481 be no relocations or symbols pointing to the second LDI 1482 instruction. */ 1483 if (!pru_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 4)) 1484 goto error_return; 1485 1486 /* We're done with deletion of the first instruction. 1487 Set a regular LDI relocation for the second instruction 1488 we left to load the 16-bit value into the 32-bit 1489 register. */ 1490 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1491 R_PRU_U16); 1492 1493 /* That will change things, so, we should relax again. 1494 Note that this is not required, and it may be slow. */ 1495 *again = TRUE; 1496 } 1497 } 1498 } 1499 1500 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf) 1501 { 1502 if (!link_info->keep_memory) 1503 free (isymbuf); 1504 else 1505 { 1506 /* Cache the symbols for elf_link_input_bfd. */ 1507 symtab_hdr->contents = (unsigned char *) isymbuf; 1508 } 1509 } 1510 1511 if (contents != NULL 1512 && elf_section_data (sec)->this_hdr.contents != contents) 1513 { 1514 if (!link_info->keep_memory) 1515 free (contents); 1516 else 1517 { 1518 /* Cache the section contents for elf_link_input_bfd. */ 1519 elf_section_data (sec)->this_hdr.contents = contents; 1520 } 1521 } 1522 1523 if (internal_relocs != NULL 1524 && elf_section_data (sec)->relocs != internal_relocs) 1525 free (internal_relocs); 1526 1527 return TRUE; 1528 1529 error_return: 1530 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf) 1531 free (isymbuf); 1532 if (contents != NULL 1533 && elf_section_data (sec)->this_hdr.contents != contents) 1534 free (contents); 1535 if (internal_relocs != NULL 1536 && elf_section_data (sec)->relocs != internal_relocs) 1537 free (internal_relocs); 1538 1539 return FALSE; 1540 } 1541 1542 /* Free the derived linker hash table. */ 1543 static void 1544 pru_elf32_link_hash_table_free (bfd *obfd) 1545 { 1546 _bfd_elf_link_hash_table_free (obfd); 1547 } 1548 1549 /* Implement bfd_elf32_bfd_link_hash_table_create. */ 1550 static struct bfd_link_hash_table * 1551 pru_elf32_link_hash_table_create (bfd *abfd) 1552 { 1553 struct elf_link_hash_table *ret; 1554 bfd_size_type amt = sizeof (struct elf_link_hash_table); 1555 1556 ret = bfd_zmalloc (amt); 1557 if (ret == NULL) 1558 return NULL; 1559 1560 if (!_bfd_elf_link_hash_table_init (ret, abfd, 1561 link_hash_newfunc, 1562 sizeof (struct 1563 elf_link_hash_entry), 1564 PRU_ELF_DATA)) 1565 { 1566 free (ret); 1567 return NULL; 1568 } 1569 1570 ret->root.hash_table_free = pru_elf32_link_hash_table_free; 1571 1572 return &ret->root; 1573 } 1574 1575 #define ELF_ARCH bfd_arch_pru 1576 #define ELF_TARGET_ID PRU_ELF_DATA 1577 #define ELF_MACHINE_CODE EM_TI_PRU 1578 1579 #define ELF_MAXPAGESIZE 1 1580 1581 #define bfd_elf32_bfd_link_hash_table_create \ 1582 pru_elf32_link_hash_table_create 1583 1584 /* Relocation table lookup macros. */ 1585 1586 #define bfd_elf32_bfd_reloc_type_lookup pru_elf32_bfd_reloc_type_lookup 1587 #define bfd_elf32_bfd_reloc_name_lookup pru_elf32_bfd_reloc_name_lookup 1588 1589 #define elf_info_to_howto pru_elf32_info_to_howto 1590 #define elf_info_to_howto_rel NULL 1591 1592 /* elf backend functions. */ 1593 1594 /* TI folks like to use a mix of REL and RELA relocations. See also 1595 the MSP430 and TI C6X backends. */ 1596 #define elf_backend_may_use_rel_p 1 1597 #define elf_backend_may_use_rela_p 1 1598 #define elf_backend_default_use_rela_p 1 1599 1600 #define elf_backend_rela_normal 1 1601 1602 #define elf_backend_relocate_section pru_elf32_relocate_section 1603 #define bfd_elf32_bfd_relax_section pru_elf32_relax_section 1604 1605 #define TARGET_LITTLE_SYM pru_elf32_vec 1606 #define TARGET_LITTLE_NAME "elf32-pru" 1607 1608 #include "elf32-target.h" 1609