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