1 /* BFD back-end for National Semiconductor's CRX ELF 2 Copyright (C) 2004-2014 Free Software Foundation, Inc. 3 Written by Tomer Levi, NSC, Israel. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include "bfd.h" 24 #include "bfdlink.h" 25 #include "libbfd.h" 26 #include "elf-bfd.h" 27 #include "elf/crx.h" 28 29 static reloc_howto_type *elf_crx_reloc_type_lookup 30 (bfd *, bfd_reloc_code_real_type); 31 static void elf_crx_info_to_howto 32 (bfd *, arelent *, Elf_Internal_Rela *); 33 static bfd_boolean elf32_crx_relax_delete_bytes 34 (struct bfd_link_info *, bfd *, asection *, bfd_vma, int); 35 static bfd_reloc_status_type crx_elf_final_link_relocate 36 (reloc_howto_type *, bfd *, bfd *, asection *, 37 bfd_byte *, bfd_vma, bfd_vma, bfd_vma, 38 struct bfd_link_info *, asection *, int); 39 static bfd_boolean elf32_crx_relocate_section 40 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 41 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 42 static bfd_boolean elf32_crx_relax_section 43 (bfd *, asection *, struct bfd_link_info *, bfd_boolean *); 44 static bfd_byte * elf32_crx_get_relocated_section_contents 45 (bfd *, struct bfd_link_info *, struct bfd_link_order *, 46 bfd_byte *, bfd_boolean, asymbol **); 47 48 /* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */ 49 50 struct crx_reloc_map 51 { 52 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */ 53 unsigned short crx_reloc_type; /* CRX relocation type. */ 54 }; 55 56 static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] = 57 { 58 {BFD_RELOC_NONE, R_CRX_NONE}, 59 {BFD_RELOC_CRX_REL4, R_CRX_REL4}, 60 {BFD_RELOC_CRX_REL8, R_CRX_REL8}, 61 {BFD_RELOC_CRX_REL8_CMP, R_CRX_REL8_CMP}, 62 {BFD_RELOC_CRX_REL16, R_CRX_REL16}, 63 {BFD_RELOC_CRX_REL24, R_CRX_REL24}, 64 {BFD_RELOC_CRX_REL32, R_CRX_REL32}, 65 {BFD_RELOC_CRX_REGREL12, R_CRX_REGREL12}, 66 {BFD_RELOC_CRX_REGREL22, R_CRX_REGREL22}, 67 {BFD_RELOC_CRX_REGREL28, R_CRX_REGREL28}, 68 {BFD_RELOC_CRX_REGREL32, R_CRX_REGREL32}, 69 {BFD_RELOC_CRX_ABS16, R_CRX_ABS16}, 70 {BFD_RELOC_CRX_ABS32, R_CRX_ABS32}, 71 {BFD_RELOC_CRX_NUM8, R_CRX_NUM8}, 72 {BFD_RELOC_CRX_NUM16, R_CRX_NUM16}, 73 {BFD_RELOC_CRX_NUM32, R_CRX_NUM32}, 74 {BFD_RELOC_CRX_IMM16, R_CRX_IMM16}, 75 {BFD_RELOC_CRX_IMM32, R_CRX_IMM32}, 76 {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8}, 77 {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16}, 78 {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32} 79 }; 80 81 static reloc_howto_type crx_elf_howto_table[] = 82 { 83 HOWTO (R_CRX_NONE, /* type */ 84 0, /* rightshift */ 85 2, /* size */ 86 32, /* bitsize */ 87 FALSE, /* pc_relative */ 88 0, /* bitpos */ 89 complain_overflow_dont,/* complain_on_overflow */ 90 bfd_elf_generic_reloc, /* special_function */ 91 "R_CRX_NONE", /* name */ 92 FALSE, /* partial_inplace */ 93 0, /* src_mask */ 94 0, /* dst_mask */ 95 FALSE), /* pcrel_offset */ 96 97 HOWTO (R_CRX_REL4, /* type */ 98 1, /* rightshift */ 99 0, /* size */ 100 4, /* bitsize */ 101 TRUE, /* pc_relative */ 102 0, /* bitpos */ 103 complain_overflow_bitfield,/* complain_on_overflow */ 104 bfd_elf_generic_reloc, /* special_function */ 105 "R_CRX_REL4", /* name */ 106 FALSE, /* partial_inplace */ 107 0x0, /* src_mask */ 108 0xf, /* dst_mask */ 109 FALSE), /* pcrel_offset */ 110 111 HOWTO (R_CRX_REL8, /* type */ 112 1, /* rightshift */ 113 0, /* size */ 114 8, /* bitsize */ 115 TRUE, /* pc_relative */ 116 0, /* bitpos */ 117 complain_overflow_bitfield,/* complain_on_overflow */ 118 bfd_elf_generic_reloc, /* special_function */ 119 "R_CRX_REL8", /* name */ 120 FALSE, /* partial_inplace */ 121 0x0, /* src_mask */ 122 0xff, /* dst_mask */ 123 FALSE), /* pcrel_offset */ 124 125 HOWTO (R_CRX_REL8_CMP, /* type */ 126 1, /* rightshift */ 127 0, /* size */ 128 8, /* bitsize */ 129 TRUE, /* pc_relative */ 130 0, /* bitpos */ 131 complain_overflow_bitfield,/* complain_on_overflow */ 132 bfd_elf_generic_reloc, /* special_function */ 133 "R_CRX_REL8_CMP", /* name */ 134 FALSE, /* partial_inplace */ 135 0x0, /* src_mask */ 136 0xff, /* dst_mask */ 137 FALSE), /* pcrel_offset */ 138 139 HOWTO (R_CRX_REL16, /* type */ 140 1, /* rightshift */ 141 1, /* size */ 142 16, /* bitsize */ 143 TRUE, /* pc_relative */ 144 0, /* bitpos */ 145 complain_overflow_bitfield,/* complain_on_overflow */ 146 bfd_elf_generic_reloc, /* special_function */ 147 "R_CRX_REL16", /* name */ 148 FALSE, /* partial_inplace */ 149 0x0, /* src_mask */ 150 0xffff, /* dst_mask */ 151 FALSE), /* pcrel_offset */ 152 153 HOWTO (R_CRX_REL24, /* type */ 154 1, /* rightshift */ 155 2, /* size */ 156 24, /* bitsize */ 157 TRUE, /* pc_relative */ 158 0, /* bitpos */ 159 complain_overflow_bitfield,/* complain_on_overflow */ 160 bfd_elf_generic_reloc, /* special_function */ 161 "R_CRX_REL24", /* name */ 162 FALSE, /* partial_inplace */ 163 0x0, /* src_mask */ 164 0xffffff, /* dst_mask */ 165 FALSE), /* pcrel_offset */ 166 167 HOWTO (R_CRX_REL32, /* type */ 168 1, /* rightshift */ 169 2, /* size */ 170 32, /* bitsize */ 171 TRUE, /* pc_relative */ 172 0, /* bitpos */ 173 complain_overflow_bitfield,/* complain_on_overflow */ 174 bfd_elf_generic_reloc, /* special_function */ 175 "R_CRX_REL32", /* name */ 176 FALSE, /* partial_inplace */ 177 0x0, /* src_mask */ 178 0xffffffff, /* dst_mask */ 179 FALSE), /* pcrel_offset */ 180 181 HOWTO (R_CRX_REGREL12, /* type */ 182 0, /* rightshift */ 183 1, /* size */ 184 12, /* bitsize */ 185 FALSE, /* pc_relative */ 186 0, /* bitpos */ 187 complain_overflow_bitfield,/* complain_on_overflow */ 188 bfd_elf_generic_reloc, /* special_function */ 189 "R_CRX_REGREL12", /* name */ 190 FALSE, /* partial_inplace */ 191 0x0, /* src_mask */ 192 0xfff, /* dst_mask */ 193 FALSE), /* pcrel_offset */ 194 195 HOWTO (R_CRX_REGREL22, /* type */ 196 0, /* rightshift */ 197 2, /* size */ 198 22, /* bitsize */ 199 FALSE, /* pc_relative */ 200 0, /* bitpos */ 201 complain_overflow_bitfield,/* complain_on_overflow */ 202 bfd_elf_generic_reloc, /* special_function */ 203 "R_CRX_REGREL22", /* name */ 204 FALSE, /* partial_inplace */ 205 0x0, /* src_mask */ 206 0x3fffff, /* dst_mask */ 207 FALSE), /* pcrel_offset */ 208 209 HOWTO (R_CRX_REGREL28, /* type */ 210 0, /* rightshift */ 211 2, /* size */ 212 28, /* bitsize */ 213 FALSE, /* pc_relative */ 214 0, /* bitpos */ 215 complain_overflow_bitfield,/* complain_on_overflow */ 216 bfd_elf_generic_reloc, /* special_function */ 217 "R_CRX_REGREL28", /* name */ 218 FALSE, /* partial_inplace */ 219 0x0, /* src_mask */ 220 0xfffffff, /* dst_mask */ 221 FALSE), /* pcrel_offset */ 222 223 HOWTO (R_CRX_REGREL32, /* type */ 224 0, /* rightshift */ 225 2, /* size */ 226 32, /* bitsize */ 227 FALSE, /* pc_relative */ 228 0, /* bitpos */ 229 complain_overflow_bitfield,/* complain_on_overflow */ 230 bfd_elf_generic_reloc, /* special_function */ 231 "R_CRX_REGREL32", /* name */ 232 FALSE, /* partial_inplace */ 233 0x0, /* src_mask */ 234 0xffffffff, /* dst_mask */ 235 FALSE), /* pcrel_offset */ 236 237 HOWTO (R_CRX_ABS16, /* type */ 238 0, /* rightshift */ 239 1, /* size */ 240 16, /* bitsize */ 241 FALSE, /* pc_relative */ 242 0, /* bitpos */ 243 complain_overflow_bitfield,/* complain_on_overflow */ 244 bfd_elf_generic_reloc, /* special_function */ 245 "R_CRX_ABS16", /* name */ 246 FALSE, /* partial_inplace */ 247 0x0, /* src_mask */ 248 0xffff, /* dst_mask */ 249 FALSE), /* pcrel_offset */ 250 251 HOWTO (R_CRX_ABS32, /* type */ 252 0, /* rightshift */ 253 2, /* size */ 254 32, /* bitsize */ 255 FALSE, /* pc_relative */ 256 0, /* bitpos */ 257 complain_overflow_bitfield,/* complain_on_overflow */ 258 bfd_elf_generic_reloc, /* special_function */ 259 "R_CRX_ABS32", /* name */ 260 FALSE, /* partial_inplace */ 261 0x0, /* src_mask */ 262 0xffffffff, /* dst_mask */ 263 FALSE), /* pcrel_offset */ 264 265 HOWTO (R_CRX_NUM8, /* type */ 266 0, /* rightshift */ 267 0, /* size */ 268 8, /* bitsize */ 269 FALSE, /* pc_relative */ 270 0, /* bitpos */ 271 complain_overflow_bitfield,/* complain_on_overflow */ 272 bfd_elf_generic_reloc, /* special_function */ 273 "R_CRX_NUM8", /* name */ 274 FALSE, /* partial_inplace */ 275 0x0, /* src_mask */ 276 0xff, /* dst_mask */ 277 FALSE), /* pcrel_offset */ 278 279 HOWTO (R_CRX_NUM16, /* type */ 280 0, /* rightshift */ 281 1, /* size */ 282 16, /* bitsize */ 283 FALSE, /* pc_relative */ 284 0, /* bitpos */ 285 complain_overflow_bitfield,/* complain_on_overflow */ 286 bfd_elf_generic_reloc, /* special_function */ 287 "R_CRX_NUM16", /* name */ 288 FALSE, /* partial_inplace */ 289 0x0, /* src_mask */ 290 0xffff, /* dst_mask */ 291 FALSE), /* pcrel_offset */ 292 293 HOWTO (R_CRX_NUM32, /* type */ 294 0, /* rightshift */ 295 2, /* size */ 296 32, /* bitsize */ 297 FALSE, /* pc_relative */ 298 0, /* bitpos */ 299 complain_overflow_bitfield,/* complain_on_overflow */ 300 bfd_elf_generic_reloc, /* special_function */ 301 "R_CRX_NUM32", /* name */ 302 FALSE, /* partial_inplace */ 303 0x0, /* src_mask */ 304 0xffffffff, /* dst_mask */ 305 FALSE), /* pcrel_offset */ 306 307 HOWTO (R_CRX_IMM16, /* type */ 308 0, /* rightshift */ 309 1, /* size */ 310 16, /* bitsize */ 311 FALSE, /* pc_relative */ 312 0, /* bitpos */ 313 complain_overflow_bitfield,/* complain_on_overflow */ 314 bfd_elf_generic_reloc, /* special_function */ 315 "R_CRX_IMM16", /* name */ 316 FALSE, /* partial_inplace */ 317 0x0, /* src_mask */ 318 0xffff, /* dst_mask */ 319 FALSE), /* pcrel_offset */ 320 321 HOWTO (R_CRX_IMM32, /* type */ 322 0, /* rightshift */ 323 2, /* size */ 324 32, /* bitsize */ 325 FALSE, /* pc_relative */ 326 0, /* bitpos */ 327 complain_overflow_bitfield,/* complain_on_overflow */ 328 bfd_elf_generic_reloc, /* special_function */ 329 "R_CRX_IMM32", /* name */ 330 FALSE, /* partial_inplace */ 331 0x0, /* src_mask */ 332 0xffffffff, /* dst_mask */ 333 FALSE), /* pcrel_offset */ 334 335 /* An 8 bit switch table entry. This is generated for an expression 336 such as ``.byte L1 - L2''. The offset holds the difference 337 between the reloc address and L2. */ 338 HOWTO (R_CRX_SWITCH8, /* type */ 339 0, /* rightshift */ 340 0, /* size (0 = byte, 1 = short, 2 = long) */ 341 8, /* bitsize */ 342 FALSE, /* pc_relative */ 343 0, /* bitpos */ 344 complain_overflow_unsigned, /* complain_on_overflow */ 345 bfd_elf_generic_reloc, /* special_function */ 346 "R_CRX_SWITCH8", /* name */ 347 FALSE, /* partial_inplace */ 348 0x0, /* src_mask */ 349 0xff, /* dst_mask */ 350 TRUE), /* pcrel_offset */ 351 352 /* A 16 bit switch table entry. This is generated for an expression 353 such as ``.word L1 - L2''. The offset holds the difference 354 between the reloc address and L2. */ 355 HOWTO (R_CRX_SWITCH16, /* type */ 356 0, /* rightshift */ 357 1, /* size (0 = byte, 1 = short, 2 = long) */ 358 16, /* bitsize */ 359 FALSE, /* pc_relative */ 360 0, /* bitpos */ 361 complain_overflow_unsigned, /* complain_on_overflow */ 362 bfd_elf_generic_reloc, /* special_function */ 363 "R_CRX_SWITCH16", /* name */ 364 FALSE, /* partial_inplace */ 365 0x0, /* src_mask */ 366 0xffff, /* dst_mask */ 367 TRUE), /* pcrel_offset */ 368 369 /* A 32 bit switch table entry. This is generated for an expression 370 such as ``.long L1 - L2''. The offset holds the difference 371 between the reloc address and L2. */ 372 HOWTO (R_CRX_SWITCH32, /* type */ 373 0, /* rightshift */ 374 2, /* size (0 = byte, 1 = short, 2 = long) */ 375 32, /* bitsize */ 376 FALSE, /* pc_relative */ 377 0, /* bitpos */ 378 complain_overflow_unsigned, /* complain_on_overflow */ 379 bfd_elf_generic_reloc, /* special_function */ 380 "R_CRX_SWITCH32", /* name */ 381 FALSE, /* partial_inplace */ 382 0x0, /* src_mask */ 383 0xffffffff, /* dst_mask */ 384 TRUE) /* pcrel_offset */ 385 }; 386 387 /* Retrieve a howto ptr using a BFD reloc_code. */ 388 389 static reloc_howto_type * 390 elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 391 bfd_reloc_code_real_type code) 392 { 393 unsigned int i; 394 395 for (i = 0; i < R_CRX_MAX; i++) 396 if (code == crx_reloc_map[i].bfd_reloc_enum) 397 return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type]; 398 399 printf ("This relocation Type is not supported -0x%x\n", code); 400 return 0; 401 } 402 403 static reloc_howto_type * 404 elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 405 const char *r_name) 406 { 407 unsigned int i; 408 409 for (i = 0; 410 i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]); 411 i++) 412 if (crx_elf_howto_table[i].name != NULL 413 && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0) 414 return &crx_elf_howto_table[i]; 415 416 return NULL; 417 } 418 419 /* Retrieve a howto ptr using an internal relocation entry. */ 420 421 static void 422 elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, 423 Elf_Internal_Rela *dst) 424 { 425 unsigned int r_type = ELF32_R_TYPE (dst->r_info); 426 BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX); 427 cache_ptr->howto = &crx_elf_howto_table[r_type]; 428 } 429 430 /* Perform a relocation as part of a final link. */ 431 432 static bfd_reloc_status_type 433 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, 434 bfd *output_bfd ATTRIBUTE_UNUSED, 435 asection *input_section, bfd_byte *contents, 436 bfd_vma offset, bfd_vma Rvalue, bfd_vma addend, 437 struct bfd_link_info *info ATTRIBUTE_UNUSED, 438 asection *sec ATTRIBUTE_UNUSED, 439 int is_local ATTRIBUTE_UNUSED) 440 { 441 unsigned short r_type = howto->type; 442 bfd_byte *hit_data = contents + offset; 443 bfd_vma reloc_bits, check; 444 445 switch (r_type) 446 { 447 case R_CRX_IMM16: 448 case R_CRX_IMM32: 449 case R_CRX_ABS16: 450 case R_CRX_ABS32: 451 case R_CRX_REL8_CMP: 452 case R_CRX_REL16: 453 case R_CRX_REL24: 454 case R_CRX_REL32: 455 case R_CRX_REGREL12: 456 case R_CRX_REGREL22: 457 case R_CRX_REGREL28: 458 case R_CRX_REGREL32: 459 /* 'hit_data' is relative to the start of the instruction, not the 460 relocation offset. Advance it to account for the exact offset. */ 461 hit_data += 2; 462 break; 463 464 case R_CRX_REL4: 465 /* This relocation type is used only in 'Branch if Equal to 0' 466 instructions and requires special handling. */ 467 Rvalue -= 1; 468 break; 469 470 case R_CRX_NONE: 471 return bfd_reloc_ok; 472 break; 473 474 case R_CRX_SWITCH8: 475 case R_CRX_SWITCH16: 476 case R_CRX_SWITCH32: 477 /* We only care about the addend, where the difference between 478 expressions is kept. */ 479 Rvalue = 0; 480 481 default: 482 break; 483 } 484 485 if (howto->pc_relative) 486 { 487 /* Subtract the address of the section containing the location. */ 488 Rvalue -= (input_section->output_section->vma 489 + input_section->output_offset); 490 /* Subtract the position of the location within the section. */ 491 Rvalue -= offset; 492 } 493 494 /* Add in supplied addend. */ 495 Rvalue += addend; 496 497 /* Complain if the bitfield overflows, whether it is considered 498 as signed or unsigned. */ 499 check = Rvalue >> howto->rightshift; 500 501 /* Assumes two's complement. This expression avoids 502 overflow if howto->bitsize is the number of bits in 503 bfd_vma. */ 504 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 505 506 if (((bfd_vma) check & ~reloc_bits) != 0 507 && (((bfd_vma) check & ~reloc_bits) 508 != (-(bfd_vma) 1 & ~reloc_bits))) 509 { 510 /* The above right shift is incorrect for a signed 511 value. See if turning on the upper bits fixes the 512 overflow. */ 513 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0) 514 { 515 check |= ((bfd_vma) - 1 516 & ~((bfd_vma) - 1 517 >> howto->rightshift)); 518 if (((bfd_vma) check & ~reloc_bits) 519 != (-(bfd_vma) 1 & ~reloc_bits)) 520 return bfd_reloc_overflow; 521 } 522 else 523 return bfd_reloc_overflow; 524 } 525 526 /* Drop unwanted bits from the value we are relocating to. */ 527 Rvalue >>= (bfd_vma) howto->rightshift; 528 529 /* Apply dst_mask to select only relocatable part of the insn. */ 530 Rvalue &= howto->dst_mask; 531 532 switch (howto->size) 533 { 534 case 0: 535 if (r_type == R_CRX_REL4) 536 { 537 Rvalue <<= 4; 538 Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f); 539 } 540 541 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data); 542 break; 543 544 case 1: 545 if (r_type == R_CRX_REGREL12) 546 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000); 547 548 bfd_put_16 (input_bfd, Rvalue, hit_data); 549 break; 550 551 case 2: 552 if (r_type == R_CRX_REL24 553 || r_type == R_CRX_REGREL22 554 || r_type == R_CRX_REGREL28) 555 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) | 556 bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask); 557 558 if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32) 559 /* Relocation on DATA is purely little-endian, that is, for a 560 multi-byte datum, the lowest address in memory contains the 561 little end of the datum, that is, the least significant byte. 562 Therefore we use BFD's byte Putting functions. */ 563 bfd_put_32 (input_bfd, Rvalue, hit_data); 564 else 565 /* Relocation on INSTRUCTIONS is different : Instructions are 566 word-addressable, that is, each word itself is arranged according 567 to little-endian convention, whereas the words are arranged with 568 respect to one another in BIG ENDIAN fashion. 569 When there is an immediate value that spans a word boundary, it is 570 split in a big-endian way with respect to the words. */ 571 { 572 bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data); 573 bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2); 574 } 575 break; 576 577 default: 578 return bfd_reloc_notsupported; 579 } 580 581 return bfd_reloc_ok; 582 } 583 584 /* Delete some bytes from a section while relaxing. */ 585 586 static bfd_boolean 587 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 588 asection *sec, bfd_vma addr, int count) 589 { 590 Elf_Internal_Shdr *symtab_hdr; 591 unsigned int sec_shndx; 592 bfd_byte *contents; 593 Elf_Internal_Rela *irel, *irelend; 594 bfd_vma toaddr; 595 Elf_Internal_Sym *isym; 596 Elf_Internal_Sym *isymend; 597 struct elf_link_hash_entry **sym_hashes; 598 struct elf_link_hash_entry **end_hashes; 599 struct elf_link_hash_entry **start_hashes; 600 unsigned int symcount; 601 602 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 603 604 contents = elf_section_data (sec)->this_hdr.contents; 605 606 toaddr = sec->size; 607 608 irel = elf_section_data (sec)->relocs; 609 irelend = irel + sec->reloc_count; 610 611 /* Actually delete the bytes. */ 612 memmove (contents + addr, contents + addr + count, 613 (size_t) (toaddr - addr - count)); 614 sec->size -= count; 615 616 /* Adjust all the relocs. */ 617 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 618 { 619 /* Get the new reloc address. */ 620 if ((irel->r_offset > addr 621 && irel->r_offset < toaddr)) 622 irel->r_offset -= count; 623 } 624 625 /* Adjust the local symbols defined in this section. */ 626 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 627 isym = (Elf_Internal_Sym *) symtab_hdr->contents; 628 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 629 { 630 if (isym->st_shndx == sec_shndx 631 && isym->st_value > addr 632 && isym->st_value < toaddr) 633 { 634 /* Adjust the addend of SWITCH relocations in this section, 635 which reference this local symbol. */ 636 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 637 { 638 unsigned long r_symndx; 639 Elf_Internal_Sym *rsym; 640 bfd_vma addsym, subsym; 641 642 /* Skip if not a SWITCH relocation. */ 643 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8 644 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16 645 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32) 646 continue; 647 648 r_symndx = ELF32_R_SYM (irel->r_info); 649 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx; 650 651 /* Skip if not the local adjusted symbol. */ 652 if (rsym != isym) 653 continue; 654 655 addsym = isym->st_value; 656 subsym = addsym - irel->r_addend; 657 658 /* Fix the addend only when -->> (addsym > addr >= subsym). */ 659 if (subsym <= addr) 660 irel->r_addend -= count; 661 else 662 continue; 663 } 664 665 isym->st_value -= count; 666 } 667 } 668 669 /* Now adjust the global symbols defined in this section. */ 670 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 671 - symtab_hdr->sh_info); 672 sym_hashes = start_hashes = elf_sym_hashes (abfd); 673 end_hashes = sym_hashes + symcount; 674 675 for (; sym_hashes < end_hashes; sym_hashes++) 676 { 677 struct elf_link_hash_entry *sym_hash = *sym_hashes; 678 679 /* The '--wrap SYMBOL' option is causing a pain when the object file, 680 containing the definition of __wrap_SYMBOL, includes a direct 681 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 682 the same symbol (which is __wrap_SYMBOL), but still exist as two 683 different symbols in 'sym_hashes', we don't want to adjust 684 the global symbol __wrap_SYMBOL twice. 685 This check is only relevant when symbols are being wrapped. */ 686 if (link_info->wrap_hash != NULL) 687 { 688 struct elf_link_hash_entry **cur_sym_hashes; 689 690 /* Loop only over the symbols whom been already checked. */ 691 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 692 cur_sym_hashes++) 693 { 694 /* If the current symbol is identical to 'sym_hash', that means 695 the symbol was already adjusted (or at least checked). */ 696 if (*cur_sym_hashes == sym_hash) 697 break; 698 } 699 /* Don't adjust the symbol again. */ 700 if (cur_sym_hashes < sym_hashes) 701 continue; 702 } 703 704 if ((sym_hash->root.type == bfd_link_hash_defined 705 || sym_hash->root.type == bfd_link_hash_defweak) 706 && sym_hash->root.u.def.section == sec 707 && sym_hash->root.u.def.value > addr 708 && sym_hash->root.u.def.value < toaddr) 709 sym_hash->root.u.def.value -= count; 710 } 711 712 return TRUE; 713 } 714 715 /* This is a version of bfd_generic_get_relocated_section_contents 716 which uses elf32_crx_relocate_section. */ 717 718 static bfd_byte * 719 elf32_crx_get_relocated_section_contents (bfd *output_bfd, 720 struct bfd_link_info *link_info, 721 struct bfd_link_order *link_order, 722 bfd_byte *data, 723 bfd_boolean relocatable, 724 asymbol **symbols) 725 { 726 Elf_Internal_Shdr *symtab_hdr; 727 asection *input_section = link_order->u.indirect.section; 728 bfd *input_bfd = input_section->owner; 729 asection **sections = NULL; 730 Elf_Internal_Rela *internal_relocs = NULL; 731 Elf_Internal_Sym *isymbuf = NULL; 732 733 /* We only need to handle the case of relaxing, or of having a 734 particular set of section contents, specially. */ 735 if (relocatable 736 || elf_section_data (input_section)->this_hdr.contents == NULL) 737 return bfd_generic_get_relocated_section_contents (output_bfd, link_info, 738 link_order, data, 739 relocatable, 740 symbols); 741 742 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 743 744 memcpy (data, elf_section_data (input_section)->this_hdr.contents, 745 (size_t) input_section->size); 746 747 if ((input_section->flags & SEC_RELOC) != 0 748 && input_section->reloc_count > 0) 749 { 750 Elf_Internal_Sym *isym; 751 Elf_Internal_Sym *isymend; 752 asection **secpp; 753 bfd_size_type amt; 754 755 internal_relocs = (_bfd_elf_link_read_relocs 756 (input_bfd, input_section, NULL, 757 (Elf_Internal_Rela *) NULL, FALSE)); 758 if (internal_relocs == NULL) 759 goto error_return; 760 761 if (symtab_hdr->sh_info != 0) 762 { 763 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 764 if (isymbuf == NULL) 765 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 766 symtab_hdr->sh_info, 0, 767 NULL, NULL, NULL); 768 if (isymbuf == NULL) 769 goto error_return; 770 } 771 772 amt = symtab_hdr->sh_info; 773 amt *= sizeof (asection *); 774 sections = bfd_malloc (amt); 775 if (sections == NULL && amt != 0) 776 goto error_return; 777 778 isymend = isymbuf + symtab_hdr->sh_info; 779 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp) 780 { 781 asection *isec; 782 783 if (isym->st_shndx == SHN_UNDEF) 784 isec = bfd_und_section_ptr; 785 else if (isym->st_shndx == SHN_ABS) 786 isec = bfd_abs_section_ptr; 787 else if (isym->st_shndx == SHN_COMMON) 788 isec = bfd_com_section_ptr; 789 else 790 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 791 792 *secpp = isec; 793 } 794 795 if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd, 796 input_section, data, internal_relocs, 797 isymbuf, sections)) 798 goto error_return; 799 800 if (sections != NULL) 801 free (sections); 802 if (isymbuf != NULL 803 && symtab_hdr->contents != (unsigned char *) isymbuf) 804 free (isymbuf); 805 if (elf_section_data (input_section)->relocs != internal_relocs) 806 free (internal_relocs); 807 } 808 809 return data; 810 811 error_return: 812 if (sections != NULL) 813 free (sections); 814 if (isymbuf != NULL 815 && symtab_hdr->contents != (unsigned char *) isymbuf) 816 free (isymbuf); 817 if (internal_relocs != NULL 818 && elf_section_data (input_section)->relocs != internal_relocs) 819 free (internal_relocs); 820 return NULL; 821 } 822 823 /* Relocate a CRX ELF section. */ 824 825 static bfd_boolean 826 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 827 bfd *input_bfd, asection *input_section, 828 bfd_byte *contents, Elf_Internal_Rela *relocs, 829 Elf_Internal_Sym *local_syms, 830 asection **local_sections) 831 { 832 Elf_Internal_Shdr *symtab_hdr; 833 struct elf_link_hash_entry **sym_hashes; 834 Elf_Internal_Rela *rel, *relend; 835 836 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 837 sym_hashes = elf_sym_hashes (input_bfd); 838 839 rel = relocs; 840 relend = relocs + input_section->reloc_count; 841 for (; rel < relend; rel++) 842 { 843 int r_type; 844 reloc_howto_type *howto; 845 unsigned long r_symndx; 846 Elf_Internal_Sym *sym; 847 asection *sec; 848 struct elf_link_hash_entry *h; 849 bfd_vma relocation; 850 bfd_reloc_status_type r; 851 852 r_symndx = ELF32_R_SYM (rel->r_info); 853 r_type = ELF32_R_TYPE (rel->r_info); 854 howto = crx_elf_howto_table + (r_type); 855 856 h = NULL; 857 sym = NULL; 858 sec = NULL; 859 if (r_symndx < symtab_hdr->sh_info) 860 { 861 sym = local_syms + r_symndx; 862 sec = local_sections[r_symndx]; 863 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 864 } 865 else 866 { 867 bfd_boolean unresolved_reloc, warned, ignored; 868 869 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 870 r_symndx, symtab_hdr, sym_hashes, 871 h, sec, relocation, 872 unresolved_reloc, warned, ignored); 873 } 874 875 if (sec != NULL && discarded_section (sec)) 876 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 877 rel, 1, relend, howto, 0, contents); 878 879 if (info->relocatable) 880 continue; 881 882 r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd, 883 input_section, 884 contents, rel->r_offset, 885 relocation, rel->r_addend, 886 info, sec, h == NULL); 887 888 if (r != bfd_reloc_ok) 889 { 890 const char *name; 891 const char *msg = (const char *) 0; 892 893 if (h != NULL) 894 name = h->root.root.string; 895 else 896 { 897 name = (bfd_elf_string_from_elf_section 898 (input_bfd, symtab_hdr->sh_link, sym->st_name)); 899 if (name == NULL || *name == '\0') 900 name = bfd_section_name (input_bfd, sec); 901 } 902 903 switch (r) 904 { 905 case bfd_reloc_overflow: 906 if (!((*info->callbacks->reloc_overflow) 907 (info, (h ? &h->root : NULL), name, howto->name, 908 (bfd_vma) 0, input_bfd, input_section, 909 rel->r_offset))) 910 return FALSE; 911 break; 912 913 case bfd_reloc_undefined: 914 if (!((*info->callbacks->undefined_symbol) 915 (info, name, input_bfd, input_section, 916 rel->r_offset, TRUE))) 917 return FALSE; 918 break; 919 920 case bfd_reloc_outofrange: 921 msg = _("internal error: out of range error"); 922 goto common_error; 923 924 case bfd_reloc_notsupported: 925 msg = _("internal error: unsupported relocation error"); 926 goto common_error; 927 928 case bfd_reloc_dangerous: 929 msg = _("internal error: dangerous error"); 930 goto common_error; 931 932 default: 933 msg = _("internal error: unknown error"); 934 /* Fall through. */ 935 936 common_error: 937 if (!((*info->callbacks->warning) 938 (info, msg, name, input_bfd, input_section, 939 rel->r_offset))) 940 return FALSE; 941 break; 942 } 943 } 944 } 945 946 return TRUE; 947 } 948 949 /* This function handles relaxing for the CRX. 950 951 There's quite a few relaxing opportunites available on the CRX: 952 953 * bal/bcond:32 -> bal/bcond:16 2 bytes 954 * bcond:16 -> bcond:8 2 bytes 955 * cmpbcond:24 -> cmpbcond:8 2 bytes 956 * arithmetic imm32 -> arithmetic imm16 2 bytes 957 958 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */ 959 960 static bfd_boolean 961 elf32_crx_relax_section (bfd *abfd, asection *sec, 962 struct bfd_link_info *link_info, bfd_boolean *again) 963 { 964 Elf_Internal_Shdr *symtab_hdr; 965 Elf_Internal_Rela *internal_relocs; 966 Elf_Internal_Rela *irel, *irelend; 967 bfd_byte *contents = NULL; 968 Elf_Internal_Sym *isymbuf = NULL; 969 970 /* Assume nothing changes. */ 971 *again = FALSE; 972 973 /* We don't have to do anything for a relocatable link, if 974 this section does not have relocs, or if this is not a 975 code section. */ 976 if (link_info->relocatable 977 || (sec->flags & SEC_RELOC) == 0 978 || sec->reloc_count == 0 979 || (sec->flags & SEC_CODE) == 0) 980 return TRUE; 981 982 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 983 984 /* Get a copy of the native relocations. */ 985 internal_relocs = (_bfd_elf_link_read_relocs 986 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, 987 link_info->keep_memory)); 988 if (internal_relocs == NULL) 989 goto error_return; 990 991 /* Walk through them looking for relaxing opportunities. */ 992 irelend = internal_relocs + sec->reloc_count; 993 for (irel = internal_relocs; irel < irelend; irel++) 994 { 995 bfd_vma symval; 996 997 /* If this isn't something that can be relaxed, then ignore 998 this reloc. */ 999 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32 1000 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16 1001 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24 1002 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32) 1003 continue; 1004 1005 /* Get the section contents if we haven't done so already. */ 1006 if (contents == NULL) 1007 { 1008 /* Get cached copy if it exists. */ 1009 if (elf_section_data (sec)->this_hdr.contents != NULL) 1010 contents = elf_section_data (sec)->this_hdr.contents; 1011 /* Go get them off disk. */ 1012 else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 1013 goto error_return; 1014 } 1015 1016 /* Read this BFD's local symbols if we haven't done so already. */ 1017 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1018 { 1019 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1020 if (isymbuf == NULL) 1021 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1022 symtab_hdr->sh_info, 0, 1023 NULL, NULL, NULL); 1024 if (isymbuf == NULL) 1025 goto error_return; 1026 } 1027 1028 /* Get the value of the symbol referred to by the reloc. */ 1029 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1030 { 1031 /* A local symbol. */ 1032 Elf_Internal_Sym *isym; 1033 asection *sym_sec; 1034 1035 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1036 if (isym->st_shndx == SHN_UNDEF) 1037 sym_sec = bfd_und_section_ptr; 1038 else if (isym->st_shndx == SHN_ABS) 1039 sym_sec = bfd_abs_section_ptr; 1040 else if (isym->st_shndx == SHN_COMMON) 1041 sym_sec = bfd_com_section_ptr; 1042 else 1043 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1044 symval = (isym->st_value 1045 + sym_sec->output_section->vma 1046 + sym_sec->output_offset); 1047 } 1048 else 1049 { 1050 unsigned long indx; 1051 struct elf_link_hash_entry *h; 1052 1053 /* An external symbol. */ 1054 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1055 h = elf_sym_hashes (abfd)[indx]; 1056 BFD_ASSERT (h != NULL); 1057 1058 if (h->root.type != bfd_link_hash_defined 1059 && h->root.type != bfd_link_hash_defweak) 1060 /* This appears to be a reference to an undefined 1061 symbol. Just ignore it--it will be caught by the 1062 regular reloc processing. */ 1063 continue; 1064 1065 symval = (h->root.u.def.value 1066 + h->root.u.def.section->output_section->vma 1067 + h->root.u.def.section->output_offset); 1068 } 1069 1070 /* For simplicity of coding, we are going to modify the section 1071 contents, the section relocs, and the BFD symbol table. We 1072 must tell the rest of the code not to free up this 1073 information. It would be possible to instead create a table 1074 of changes which have to be made, as is done in coff-mips.c; 1075 that would be more work, but would require less memory when 1076 the linker is run. */ 1077 1078 /* Try to turn a 32bit pc-relative branch/call into 1079 a 16bit pc-relative branch/call. */ 1080 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32) 1081 { 1082 bfd_vma value = symval; 1083 1084 /* Deal with pc-relative gunk. */ 1085 value -= (sec->output_section->vma + sec->output_offset); 1086 value -= irel->r_offset; 1087 value += irel->r_addend; 1088 1089 /* See if the value will fit in 16 bits, note the high value is 1090 0xfffe + 2 as the target will be two bytes closer if we are 1091 able to relax. */ 1092 if ((long) value < 0x10000 && (long) value > -0x10002) 1093 { 1094 unsigned short code; 1095 1096 /* Get the opcode. */ 1097 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1098 1099 /* Verify it's a 'bal'/'bcond' and fix the opcode. */ 1100 if ((code & 0xfff0) == 0x3170) 1101 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1); 1102 else if ((code & 0xf0ff) == 0x707f) 1103 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset); 1104 else 1105 continue; 1106 1107 /* Note that we've changed the relocs, section contents, etc. */ 1108 elf_section_data (sec)->relocs = internal_relocs; 1109 elf_section_data (sec)->this_hdr.contents = contents; 1110 symtab_hdr->contents = (unsigned char *) isymbuf; 1111 1112 /* Fix the relocation's type. */ 1113 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1114 R_CRX_REL16); 1115 1116 /* Delete two bytes of data. */ 1117 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1118 irel->r_offset + 2, 2)) 1119 goto error_return; 1120 1121 /* That will change things, so, we should relax again. 1122 Note that this is not required, and it may be slow. */ 1123 *again = TRUE; 1124 } 1125 } 1126 1127 /* Try to turn a 16bit pc-relative branch into an 1128 8bit pc-relative branch. */ 1129 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16) 1130 { 1131 bfd_vma value = symval; 1132 1133 /* Deal with pc-relative gunk. */ 1134 value -= (sec->output_section->vma + sec->output_offset); 1135 value -= irel->r_offset; 1136 value += irel->r_addend; 1137 1138 /* See if the value will fit in 8 bits, note the high value is 1139 0xfc + 2 as the target will be two bytes closer if we are 1140 able to relax. */ 1141 if ((long) value < 0xfe && (long) value > -0x100) 1142 { 1143 unsigned short code; 1144 1145 /* Get the opcode. */ 1146 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1147 1148 /* Verify it's a 'bcond' opcode. */ 1149 if ((code & 0xf0ff) != 0x707e) 1150 continue; 1151 1152 /* Note that we've changed the relocs, section contents, etc. */ 1153 elf_section_data (sec)->relocs = internal_relocs; 1154 elf_section_data (sec)->this_hdr.contents = contents; 1155 symtab_hdr->contents = (unsigned char *) isymbuf; 1156 1157 /* Fix the relocation's type. */ 1158 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1159 R_CRX_REL8); 1160 1161 /* Delete two bytes of data. */ 1162 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1163 irel->r_offset + 2, 2)) 1164 goto error_return; 1165 1166 /* That will change things, so, we should relax again. 1167 Note that this is not required, and it may be slow. */ 1168 *again = TRUE; 1169 } 1170 } 1171 1172 /* Try to turn a 24bit pc-relative cmp&branch into 1173 an 8bit pc-relative cmp&branch. */ 1174 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24) 1175 { 1176 bfd_vma value = symval; 1177 1178 /* Deal with pc-relative gunk. */ 1179 value -= (sec->output_section->vma + sec->output_offset); 1180 value -= irel->r_offset; 1181 value += irel->r_addend; 1182 1183 /* See if the value will fit in 8 bits, note the high value is 1184 0x7e + 2 as the target will be two bytes closer if we are 1185 able to relax. */ 1186 if ((long) value < 0x100 && (long) value > -0x100) 1187 { 1188 unsigned short code; 1189 1190 /* Get the opcode. */ 1191 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1192 1193 /* Verify it's a 'cmp&branch' opcode. */ 1194 if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190 1195 && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0 1196 && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0 1197 /* Or a Co-processor branch ('bcop'). */ 1198 && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110) 1199 continue; 1200 1201 /* Note that we've changed the relocs, section contents, etc. */ 1202 elf_section_data (sec)->relocs = internal_relocs; 1203 elf_section_data (sec)->this_hdr.contents = contents; 1204 symtab_hdr->contents = (unsigned char *) isymbuf; 1205 1206 /* Fix the opcode. */ 1207 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1); 1208 1209 /* Fix the relocation's type. */ 1210 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1211 R_CRX_REL8_CMP); 1212 1213 /* Delete two bytes of data. */ 1214 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1215 irel->r_offset + 4, 2)) 1216 goto error_return; 1217 1218 /* That will change things, so, we should relax again. 1219 Note that this is not required, and it may be slow. */ 1220 *again = TRUE; 1221 } 1222 } 1223 1224 /* Try to turn a 32bit immediate address into 1225 a 16bit immediate address. */ 1226 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32) 1227 { 1228 bfd_vma value = symval; 1229 1230 /* See if the value will fit in 16 bits. */ 1231 if ((long) value < 0x7fff && (long) value > -0x8000) 1232 { 1233 unsigned short code; 1234 1235 /* Get the opcode. */ 1236 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1237 1238 /* Verify it's a 'arithmetic double'. */ 1239 if ((code & 0xf0f0) != 0x20f0) 1240 continue; 1241 1242 /* Note that we've changed the relocs, section contents, etc. */ 1243 elf_section_data (sec)->relocs = internal_relocs; 1244 elf_section_data (sec)->this_hdr.contents = contents; 1245 symtab_hdr->contents = (unsigned char *) isymbuf; 1246 1247 /* Fix the opcode. */ 1248 bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset); 1249 1250 /* Fix the relocation's type. */ 1251 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1252 R_CRX_IMM16); 1253 1254 /* Delete two bytes of data. */ 1255 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1256 irel->r_offset + 2, 2)) 1257 goto error_return; 1258 1259 /* That will change things, so, we should relax again. 1260 Note that this is not required, and it may be slow. */ 1261 *again = TRUE; 1262 } 1263 } 1264 } 1265 1266 if (isymbuf != NULL 1267 && symtab_hdr->contents != (unsigned char *) isymbuf) 1268 { 1269 if (! link_info->keep_memory) 1270 free (isymbuf); 1271 else 1272 { 1273 /* Cache the symbols for elf_link_input_bfd. */ 1274 symtab_hdr->contents = (unsigned char *) isymbuf; 1275 } 1276 } 1277 1278 if (contents != NULL 1279 && elf_section_data (sec)->this_hdr.contents != contents) 1280 { 1281 if (! link_info->keep_memory) 1282 free (contents); 1283 else 1284 { 1285 /* Cache the section contents for elf_link_input_bfd. */ 1286 elf_section_data (sec)->this_hdr.contents = contents; 1287 } 1288 } 1289 1290 if (internal_relocs != NULL 1291 && elf_section_data (sec)->relocs != internal_relocs) 1292 free (internal_relocs); 1293 1294 return TRUE; 1295 1296 error_return: 1297 if (isymbuf != NULL 1298 && symtab_hdr->contents != (unsigned char *) isymbuf) 1299 free (isymbuf); 1300 if (contents != NULL 1301 && elf_section_data (sec)->this_hdr.contents != contents) 1302 free (contents); 1303 if (internal_relocs != NULL 1304 && elf_section_data (sec)->relocs != internal_relocs) 1305 free (internal_relocs); 1306 1307 return FALSE; 1308 } 1309 1310 /* Definitions for setting CRX target vector. */ 1311 #define TARGET_LITTLE_SYM crx_elf32_vec 1312 #define TARGET_LITTLE_NAME "elf32-crx" 1313 #define ELF_ARCH bfd_arch_crx 1314 #define ELF_MACHINE_CODE EM_CRX 1315 #define ELF_MAXPAGESIZE 0x1 1316 #define elf_symbol_leading_char '_' 1317 1318 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup 1319 #define bfd_elf32_bfd_reloc_name_lookup \ 1320 elf_crx_reloc_name_lookup 1321 #define elf_info_to_howto elf_crx_info_to_howto 1322 #define elf_info_to_howto_rel 0 1323 #define elf_backend_relocate_section elf32_crx_relocate_section 1324 #define bfd_elf32_bfd_relax_section elf32_crx_relax_section 1325 #define bfd_elf32_bfd_get_relocated_section_contents \ 1326 elf32_crx_get_relocated_section_contents 1327 #define elf_backend_can_gc_sections 1 1328 #define elf_backend_rela_normal 1 1329 1330 #include "elf32-target.h" 1331