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