1 /* BFD back-end for National Semiconductor's CRX ELF 2 Copyright (C) 2004-2019 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 bfd_boolean 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 3, /* size */ 86 0, /* 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 bfd_boolean 422 elf_crx_info_to_howto (bfd *abfd, arelent *cache_ptr, 423 Elf_Internal_Rela *dst) 424 { 425 unsigned int r_type = ELF32_R_TYPE (dst->r_info); 426 if (r_type >= R_CRX_MAX) 427 { 428 /* xgettext:c-format */ 429 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 430 abfd, r_type); 431 bfd_set_error (bfd_error_bad_value); 432 return FALSE; 433 } 434 cache_ptr->howto = &crx_elf_howto_table[r_type]; 435 return TRUE; 436 } 437 438 /* Perform a relocation as part of a final link. */ 439 440 static bfd_reloc_status_type 441 crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, 442 bfd *output_bfd ATTRIBUTE_UNUSED, 443 asection *input_section, bfd_byte *contents, 444 bfd_vma offset, bfd_vma Rvalue, bfd_vma addend, 445 struct bfd_link_info *info ATTRIBUTE_UNUSED, 446 asection *sec ATTRIBUTE_UNUSED, 447 int is_local ATTRIBUTE_UNUSED) 448 { 449 unsigned short r_type = howto->type; 450 bfd_byte *hit_data = contents + offset; 451 bfd_vma reloc_bits, check; 452 453 switch (r_type) 454 { 455 case R_CRX_IMM16: 456 case R_CRX_IMM32: 457 case R_CRX_ABS16: 458 case R_CRX_ABS32: 459 case R_CRX_REL8_CMP: 460 case R_CRX_REL16: 461 case R_CRX_REL24: 462 case R_CRX_REL32: 463 case R_CRX_REGREL12: 464 case R_CRX_REGREL22: 465 case R_CRX_REGREL28: 466 case R_CRX_REGREL32: 467 /* 'hit_data' is relative to the start of the instruction, not the 468 relocation offset. Advance it to account for the exact offset. */ 469 hit_data += 2; 470 break; 471 472 case R_CRX_REL4: 473 /* This relocation type is used only in 'Branch if Equal to 0' 474 instructions and requires special handling. */ 475 Rvalue -= 1; 476 break; 477 478 case R_CRX_NONE: 479 return bfd_reloc_ok; 480 break; 481 482 case R_CRX_SWITCH8: 483 case R_CRX_SWITCH16: 484 case R_CRX_SWITCH32: 485 /* We only care about the addend, where the difference between 486 expressions is kept. */ 487 Rvalue = 0; 488 489 default: 490 break; 491 } 492 493 if (howto->pc_relative) 494 { 495 /* Subtract the address of the section containing the location. */ 496 Rvalue -= (input_section->output_section->vma 497 + input_section->output_offset); 498 /* Subtract the position of the location within the section. */ 499 Rvalue -= offset; 500 } 501 502 /* Add in supplied addend. */ 503 Rvalue += addend; 504 505 /* Complain if the bitfield overflows, whether it is considered 506 as signed or unsigned. */ 507 check = Rvalue >> howto->rightshift; 508 509 /* Assumes two's complement. This expression avoids 510 overflow if howto->bitsize is the number of bits in 511 bfd_vma. */ 512 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 513 514 if (((bfd_vma) check & ~reloc_bits) != 0 515 && (((bfd_vma) check & ~reloc_bits) 516 != (-(bfd_vma) 1 & ~reloc_bits))) 517 { 518 /* The above right shift is incorrect for a signed 519 value. See if turning on the upper bits fixes the 520 overflow. */ 521 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0) 522 { 523 check |= ((bfd_vma) - 1 524 & ~((bfd_vma) - 1 525 >> howto->rightshift)); 526 if (((bfd_vma) check & ~reloc_bits) 527 != (-(bfd_vma) 1 & ~reloc_bits)) 528 return bfd_reloc_overflow; 529 } 530 else 531 return bfd_reloc_overflow; 532 } 533 534 /* Drop unwanted bits from the value we are relocating to. */ 535 Rvalue >>= (bfd_vma) howto->rightshift; 536 537 /* Apply dst_mask to select only relocatable part of the insn. */ 538 Rvalue &= howto->dst_mask; 539 540 switch (howto->size) 541 { 542 case 0: 543 if (r_type == R_CRX_REL4) 544 { 545 Rvalue <<= 4; 546 Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f); 547 } 548 549 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data); 550 break; 551 552 case 1: 553 if (r_type == R_CRX_REGREL12) 554 Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000); 555 556 bfd_put_16 (input_bfd, Rvalue, hit_data); 557 break; 558 559 case 2: 560 if (r_type == R_CRX_REL24 561 || r_type == R_CRX_REGREL22 562 || r_type == R_CRX_REGREL28) 563 Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) | 564 bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask); 565 566 if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32) 567 /* Relocation on DATA is purely little-endian, that is, for a 568 multi-byte datum, the lowest address in memory contains the 569 little end of the datum, that is, the least significant byte. 570 Therefore we use BFD's byte Putting functions. */ 571 bfd_put_32 (input_bfd, Rvalue, hit_data); 572 else 573 /* Relocation on INSTRUCTIONS is different : Instructions are 574 word-addressable, that is, each word itself is arranged according 575 to little-endian convention, whereas the words are arranged with 576 respect to one another in BIG ENDIAN fashion. 577 When there is an immediate value that spans a word boundary, it is 578 split in a big-endian way with respect to the words. */ 579 { 580 bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data); 581 bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2); 582 } 583 break; 584 585 default: 586 return bfd_reloc_notsupported; 587 } 588 589 return bfd_reloc_ok; 590 } 591 592 /* Delete some bytes from a section while relaxing. */ 593 594 static bfd_boolean 595 elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 596 asection *sec, bfd_vma addr, int count) 597 { 598 Elf_Internal_Shdr *symtab_hdr; 599 unsigned int sec_shndx; 600 bfd_byte *contents; 601 Elf_Internal_Rela *irel, *irelend; 602 bfd_vma toaddr; 603 Elf_Internal_Sym *isym; 604 Elf_Internal_Sym *isymend; 605 struct elf_link_hash_entry **sym_hashes; 606 struct elf_link_hash_entry **end_hashes; 607 struct elf_link_hash_entry **start_hashes; 608 unsigned int symcount; 609 610 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 611 612 contents = elf_section_data (sec)->this_hdr.contents; 613 614 toaddr = sec->size; 615 616 irel = elf_section_data (sec)->relocs; 617 irelend = irel + sec->reloc_count; 618 619 /* Actually delete the bytes. */ 620 memmove (contents + addr, contents + addr + count, 621 (size_t) (toaddr - addr - count)); 622 sec->size -= count; 623 624 /* Adjust all the relocs. */ 625 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 626 { 627 /* Get the new reloc address. */ 628 if ((irel->r_offset > addr 629 && irel->r_offset < toaddr)) 630 irel->r_offset -= count; 631 } 632 633 /* Adjust the local symbols defined in this section. */ 634 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 635 isym = (Elf_Internal_Sym *) symtab_hdr->contents; 636 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 637 { 638 if (isym->st_shndx == sec_shndx 639 && isym->st_value > addr 640 && isym->st_value < toaddr) 641 { 642 /* Adjust the addend of SWITCH relocations in this section, 643 which reference this local symbol. */ 644 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 645 { 646 unsigned long r_symndx; 647 Elf_Internal_Sym *rsym; 648 bfd_vma addsym, subsym; 649 650 /* Skip if not a SWITCH relocation. */ 651 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8 652 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16 653 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32) 654 continue; 655 656 r_symndx = ELF32_R_SYM (irel->r_info); 657 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx; 658 659 /* Skip if not the local adjusted symbol. */ 660 if (rsym != isym) 661 continue; 662 663 addsym = isym->st_value; 664 subsym = addsym - irel->r_addend; 665 666 /* Fix the addend only when -->> (addsym > addr >= subsym). */ 667 if (subsym <= addr) 668 irel->r_addend -= count; 669 else 670 continue; 671 } 672 673 isym->st_value -= count; 674 } 675 } 676 677 /* Now adjust the global symbols defined in this section. */ 678 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 679 - symtab_hdr->sh_info); 680 sym_hashes = start_hashes = elf_sym_hashes (abfd); 681 end_hashes = sym_hashes + symcount; 682 683 for (; sym_hashes < end_hashes; sym_hashes++) 684 { 685 struct elf_link_hash_entry *sym_hash = *sym_hashes; 686 687 /* The '--wrap SYMBOL' option is causing a pain when the object file, 688 containing the definition of __wrap_SYMBOL, includes a direct 689 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 690 the same symbol (which is __wrap_SYMBOL), but still exist as two 691 different symbols in 'sym_hashes', we don't want to adjust 692 the global symbol __wrap_SYMBOL twice. 693 This check is only relevant when symbols are being wrapped. */ 694 if (link_info->wrap_hash != NULL) 695 { 696 struct elf_link_hash_entry **cur_sym_hashes; 697 698 /* Loop only over the symbols whom been already checked. */ 699 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 700 cur_sym_hashes++) 701 { 702 /* If the current symbol is identical to 'sym_hash', that means 703 the symbol was already adjusted (or at least checked). */ 704 if (*cur_sym_hashes == sym_hash) 705 break; 706 } 707 /* Don't adjust the symbol again. */ 708 if (cur_sym_hashes < sym_hashes) 709 continue; 710 } 711 712 if ((sym_hash->root.type == bfd_link_hash_defined 713 || sym_hash->root.type == bfd_link_hash_defweak) 714 && sym_hash->root.u.def.section == sec 715 && sym_hash->root.u.def.value > addr 716 && sym_hash->root.u.def.value < toaddr) 717 sym_hash->root.u.def.value -= count; 718 } 719 720 return TRUE; 721 } 722 723 /* This is a version of bfd_generic_get_relocated_section_contents 724 which uses elf32_crx_relocate_section. */ 725 726 static bfd_byte * 727 elf32_crx_get_relocated_section_contents (bfd *output_bfd, 728 struct bfd_link_info *link_info, 729 struct bfd_link_order *link_order, 730 bfd_byte *data, 731 bfd_boolean relocatable, 732 asymbol **symbols) 733 { 734 Elf_Internal_Shdr *symtab_hdr; 735 asection *input_section = link_order->u.indirect.section; 736 bfd *input_bfd = input_section->owner; 737 asection **sections = NULL; 738 Elf_Internal_Rela *internal_relocs = NULL; 739 Elf_Internal_Sym *isymbuf = NULL; 740 741 /* We only need to handle the case of relaxing, or of having a 742 particular set of section contents, specially. */ 743 if (relocatable 744 || elf_section_data (input_section)->this_hdr.contents == NULL) 745 return bfd_generic_get_relocated_section_contents (output_bfd, link_info, 746 link_order, data, 747 relocatable, 748 symbols); 749 750 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 751 752 memcpy (data, elf_section_data (input_section)->this_hdr.contents, 753 (size_t) input_section->size); 754 755 if ((input_section->flags & SEC_RELOC) != 0 756 && input_section->reloc_count > 0) 757 { 758 Elf_Internal_Sym *isym; 759 Elf_Internal_Sym *isymend; 760 asection **secpp; 761 bfd_size_type amt; 762 763 internal_relocs = (_bfd_elf_link_read_relocs 764 (input_bfd, input_section, NULL, 765 (Elf_Internal_Rela *) NULL, FALSE)); 766 if (internal_relocs == NULL) 767 goto error_return; 768 769 if (symtab_hdr->sh_info != 0) 770 { 771 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 772 if (isymbuf == NULL) 773 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 774 symtab_hdr->sh_info, 0, 775 NULL, NULL, NULL); 776 if (isymbuf == NULL) 777 goto error_return; 778 } 779 780 amt = symtab_hdr->sh_info; 781 amt *= sizeof (asection *); 782 sections = bfd_malloc (amt); 783 if (sections == NULL && amt != 0) 784 goto error_return; 785 786 isymend = isymbuf + symtab_hdr->sh_info; 787 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp) 788 { 789 asection *isec; 790 791 if (isym->st_shndx == SHN_UNDEF) 792 isec = bfd_und_section_ptr; 793 else if (isym->st_shndx == SHN_ABS) 794 isec = bfd_abs_section_ptr; 795 else if (isym->st_shndx == SHN_COMMON) 796 isec = bfd_com_section_ptr; 797 else 798 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 799 800 *secpp = isec; 801 } 802 803 if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd, 804 input_section, data, internal_relocs, 805 isymbuf, sections)) 806 goto error_return; 807 808 if (sections != NULL) 809 free (sections); 810 if (isymbuf != NULL 811 && symtab_hdr->contents != (unsigned char *) isymbuf) 812 free (isymbuf); 813 if (elf_section_data (input_section)->relocs != internal_relocs) 814 free (internal_relocs); 815 } 816 817 return data; 818 819 error_return: 820 if (sections != NULL) 821 free (sections); 822 if (isymbuf != NULL 823 && symtab_hdr->contents != (unsigned char *) isymbuf) 824 free (isymbuf); 825 if (internal_relocs != NULL 826 && elf_section_data (input_section)->relocs != internal_relocs) 827 free (internal_relocs); 828 return NULL; 829 } 830 831 /* Relocate a CRX ELF section. */ 832 833 static bfd_boolean 834 elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 835 bfd *input_bfd, asection *input_section, 836 bfd_byte *contents, Elf_Internal_Rela *relocs, 837 Elf_Internal_Sym *local_syms, 838 asection **local_sections) 839 { 840 Elf_Internal_Shdr *symtab_hdr; 841 struct elf_link_hash_entry **sym_hashes; 842 Elf_Internal_Rela *rel, *relend; 843 844 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 845 sym_hashes = elf_sym_hashes (input_bfd); 846 847 rel = relocs; 848 relend = relocs + input_section->reloc_count; 849 for (; rel < relend; rel++) 850 { 851 int r_type; 852 reloc_howto_type *howto; 853 unsigned long r_symndx; 854 Elf_Internal_Sym *sym; 855 asection *sec; 856 struct elf_link_hash_entry *h; 857 bfd_vma relocation; 858 bfd_reloc_status_type r; 859 860 r_symndx = ELF32_R_SYM (rel->r_info); 861 r_type = ELF32_R_TYPE (rel->r_info); 862 howto = crx_elf_howto_table + (r_type); 863 864 h = NULL; 865 sym = NULL; 866 sec = NULL; 867 if (r_symndx < symtab_hdr->sh_info) 868 { 869 sym = local_syms + r_symndx; 870 sec = local_sections[r_symndx]; 871 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 872 } 873 else 874 { 875 bfd_boolean unresolved_reloc, warned, ignored; 876 877 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 878 r_symndx, symtab_hdr, sym_hashes, 879 h, sec, relocation, 880 unresolved_reloc, warned, ignored); 881 } 882 883 if (sec != NULL && discarded_section (sec)) 884 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 885 rel, 1, relend, howto, 0, contents); 886 887 if (bfd_link_relocatable (info)) 888 continue; 889 890 r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd, 891 input_section, 892 contents, rel->r_offset, 893 relocation, rel->r_addend, 894 info, sec, h == NULL); 895 896 if (r != bfd_reloc_ok) 897 { 898 const char *name; 899 const char *msg = (const char *) 0; 900 901 if (h != NULL) 902 name = h->root.root.string; 903 else 904 { 905 name = (bfd_elf_string_from_elf_section 906 (input_bfd, symtab_hdr->sh_link, sym->st_name)); 907 if (name == NULL || *name == '\0') 908 name = bfd_section_name (input_bfd, sec); 909 } 910 911 switch (r) 912 { 913 case bfd_reloc_overflow: 914 (*info->callbacks->reloc_overflow) 915 (info, (h ? &h->root : NULL), name, howto->name, 916 (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 917 break; 918 919 case bfd_reloc_undefined: 920 (*info->callbacks->undefined_symbol) 921 (info, name, input_bfd, input_section, rel->r_offset, TRUE); 922 break; 923 924 case bfd_reloc_outofrange: 925 msg = _("internal error: out of range error"); 926 goto common_error; 927 928 case bfd_reloc_notsupported: 929 msg = _("internal error: unsupported relocation error"); 930 goto common_error; 931 932 case bfd_reloc_dangerous: 933 msg = _("internal error: dangerous error"); 934 goto common_error; 935 936 default: 937 msg = _("internal error: unknown error"); 938 /* Fall through. */ 939 940 common_error: 941 (*info->callbacks->warning) (info, msg, name, input_bfd, 942 input_section, rel->r_offset); 943 break; 944 } 945 } 946 } 947 948 return TRUE; 949 } 950 951 /* This function handles relaxing for the CRX. 952 953 There's quite a few relaxing opportunites available on the CRX: 954 955 * bal/bcond:32 -> bal/bcond:16 2 bytes 956 * bcond:16 -> bcond:8 2 bytes 957 * cmpbcond:24 -> cmpbcond:8 2 bytes 958 * arithmetic imm32 -> arithmetic imm16 2 bytes 959 960 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */ 961 962 static bfd_boolean 963 elf32_crx_relax_section (bfd *abfd, asection *sec, 964 struct bfd_link_info *link_info, bfd_boolean *again) 965 { 966 Elf_Internal_Shdr *symtab_hdr; 967 Elf_Internal_Rela *internal_relocs; 968 Elf_Internal_Rela *irel, *irelend; 969 bfd_byte *contents = NULL; 970 Elf_Internal_Sym *isymbuf = NULL; 971 972 /* Assume nothing changes. */ 973 *again = FALSE; 974 975 /* We don't have to do anything for a relocatable link, if 976 this section does not have relocs, or if this is not a 977 code section. */ 978 if (bfd_link_relocatable (link_info) 979 || (sec->flags & SEC_RELOC) == 0 980 || sec->reloc_count == 0 981 || (sec->flags & SEC_CODE) == 0) 982 return TRUE; 983 984 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 985 986 /* Get a copy of the native relocations. */ 987 internal_relocs = (_bfd_elf_link_read_relocs 988 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL, 989 link_info->keep_memory)); 990 if (internal_relocs == NULL) 991 goto error_return; 992 993 /* Walk through them looking for relaxing opportunities. */ 994 irelend = internal_relocs + sec->reloc_count; 995 for (irel = internal_relocs; irel < irelend; irel++) 996 { 997 bfd_vma symval; 998 999 /* If this isn't something that can be relaxed, then ignore 1000 this reloc. */ 1001 if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32 1002 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16 1003 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24 1004 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32) 1005 continue; 1006 1007 /* Get the section contents if we haven't done so already. */ 1008 if (contents == NULL) 1009 { 1010 /* Get cached copy if it exists. */ 1011 if (elf_section_data (sec)->this_hdr.contents != NULL) 1012 contents = elf_section_data (sec)->this_hdr.contents; 1013 /* Go get them off disk. */ 1014 else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 1015 goto error_return; 1016 } 1017 1018 /* Read this BFD's local symbols if we haven't done so already. */ 1019 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1020 { 1021 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1022 if (isymbuf == NULL) 1023 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1024 symtab_hdr->sh_info, 0, 1025 NULL, NULL, NULL); 1026 if (isymbuf == NULL) 1027 goto error_return; 1028 } 1029 1030 /* Get the value of the symbol referred to by the reloc. */ 1031 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1032 { 1033 /* A local symbol. */ 1034 Elf_Internal_Sym *isym; 1035 asection *sym_sec; 1036 1037 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1038 if (isym->st_shndx == SHN_UNDEF) 1039 sym_sec = bfd_und_section_ptr; 1040 else if (isym->st_shndx == SHN_ABS) 1041 sym_sec = bfd_abs_section_ptr; 1042 else if (isym->st_shndx == SHN_COMMON) 1043 sym_sec = bfd_com_section_ptr; 1044 else 1045 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1046 symval = (isym->st_value 1047 + sym_sec->output_section->vma 1048 + sym_sec->output_offset); 1049 } 1050 else 1051 { 1052 unsigned long indx; 1053 struct elf_link_hash_entry *h; 1054 1055 /* An external symbol. */ 1056 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1057 h = elf_sym_hashes (abfd)[indx]; 1058 BFD_ASSERT (h != NULL); 1059 1060 if (h->root.type != bfd_link_hash_defined 1061 && h->root.type != bfd_link_hash_defweak) 1062 /* This appears to be a reference to an undefined 1063 symbol. Just ignore it--it will be caught by the 1064 regular reloc processing. */ 1065 continue; 1066 1067 symval = (h->root.u.def.value 1068 + h->root.u.def.section->output_section->vma 1069 + h->root.u.def.section->output_offset); 1070 } 1071 1072 /* For simplicity of coding, we are going to modify the section 1073 contents, the section relocs, and the BFD symbol table. We 1074 must tell the rest of the code not to free up this 1075 information. It would be possible to instead create a table 1076 of changes which have to be made, as is done in coff-mips.c; 1077 that would be more work, but would require less memory when 1078 the linker is run. */ 1079 1080 /* Try to turn a 32bit pc-relative branch/call into 1081 a 16bit pc-relative branch/call. */ 1082 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32) 1083 { 1084 bfd_vma value = symval; 1085 1086 /* Deal with pc-relative gunk. */ 1087 value -= (sec->output_section->vma + sec->output_offset); 1088 value -= irel->r_offset; 1089 value += irel->r_addend; 1090 1091 /* See if the value will fit in 16 bits, note the high value is 1092 0xfffe + 2 as the target will be two bytes closer if we are 1093 able to relax. */ 1094 if ((long) value < 0x10000 && (long) value > -0x10002) 1095 { 1096 unsigned short code; 1097 1098 /* Get the opcode. */ 1099 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1100 1101 /* Verify it's a 'bal'/'bcond' and fix the opcode. */ 1102 if ((code & 0xfff0) == 0x3170) 1103 bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1); 1104 else if ((code & 0xf0ff) == 0x707f) 1105 bfd_put_8 (abfd, 0x7e, contents + irel->r_offset); 1106 else 1107 continue; 1108 1109 /* Note that we've changed the relocs, section contents, etc. */ 1110 elf_section_data (sec)->relocs = internal_relocs; 1111 elf_section_data (sec)->this_hdr.contents = contents; 1112 symtab_hdr->contents = (unsigned char *) isymbuf; 1113 1114 /* Fix the relocation's type. */ 1115 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1116 R_CRX_REL16); 1117 1118 /* Delete two bytes of data. */ 1119 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1120 irel->r_offset + 2, 2)) 1121 goto error_return; 1122 1123 /* That will change things, so, we should relax again. 1124 Note that this is not required, and it may be slow. */ 1125 *again = TRUE; 1126 } 1127 } 1128 1129 /* Try to turn a 16bit pc-relative branch into an 1130 8bit pc-relative branch. */ 1131 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16) 1132 { 1133 bfd_vma value = symval; 1134 1135 /* Deal with pc-relative gunk. */ 1136 value -= (sec->output_section->vma + sec->output_offset); 1137 value -= irel->r_offset; 1138 value += irel->r_addend; 1139 1140 /* See if the value will fit in 8 bits, note the high value is 1141 0xfc + 2 as the target will be two bytes closer if we are 1142 able to relax. */ 1143 if ((long) value < 0xfe && (long) value > -0x100) 1144 { 1145 unsigned short code; 1146 1147 /* Get the opcode. */ 1148 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1149 1150 /* Verify it's a 'bcond' opcode. */ 1151 if ((code & 0xf0ff) != 0x707e) 1152 continue; 1153 1154 /* Note that we've changed the relocs, section contents, etc. */ 1155 elf_section_data (sec)->relocs = internal_relocs; 1156 elf_section_data (sec)->this_hdr.contents = contents; 1157 symtab_hdr->contents = (unsigned char *) isymbuf; 1158 1159 /* Fix the relocation's type. */ 1160 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1161 R_CRX_REL8); 1162 1163 /* Delete two bytes of data. */ 1164 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1165 irel->r_offset + 2, 2)) 1166 goto error_return; 1167 1168 /* That will change things, so, we should relax again. 1169 Note that this is not required, and it may be slow. */ 1170 *again = TRUE; 1171 } 1172 } 1173 1174 /* Try to turn a 24bit pc-relative cmp&branch into 1175 an 8bit pc-relative cmp&branch. */ 1176 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24) 1177 { 1178 bfd_vma value = symval; 1179 1180 /* Deal with pc-relative gunk. */ 1181 value -= (sec->output_section->vma + sec->output_offset); 1182 value -= irel->r_offset; 1183 value += irel->r_addend; 1184 1185 /* See if the value will fit in 8 bits, note the high value is 1186 0x7e + 2 as the target will be two bytes closer if we are 1187 able to relax. */ 1188 if ((long) value < 0x100 && (long) value > -0x100) 1189 { 1190 unsigned short code; 1191 1192 /* Get the opcode. */ 1193 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1194 1195 /* Verify it's a 'cmp&branch' opcode. */ 1196 if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190 1197 && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0 1198 && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0 1199 /* Or a Co-processor branch ('bcop'). */ 1200 && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110) 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, 0x30, contents + irel->r_offset + 1); 1210 1211 /* Fix the relocation's type. */ 1212 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1213 R_CRX_REL8_CMP); 1214 1215 /* Delete two bytes of data. */ 1216 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1217 irel->r_offset + 4, 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 /* Try to turn a 32bit immediate address into 1227 a 16bit immediate address. */ 1228 if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32) 1229 { 1230 bfd_vma value = symval; 1231 1232 /* See if the value will fit in 16 bits. */ 1233 if ((long) value < 0x7fff && (long) value > -0x8000) 1234 { 1235 unsigned short code; 1236 1237 /* Get the opcode. */ 1238 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1239 1240 /* Verify it's a 'arithmetic double'. */ 1241 if ((code & 0xf0f0) != 0x20f0) 1242 continue; 1243 1244 /* Note that we've changed the relocs, section contents, etc. */ 1245 elf_section_data (sec)->relocs = internal_relocs; 1246 elf_section_data (sec)->this_hdr.contents = contents; 1247 symtab_hdr->contents = (unsigned char *) isymbuf; 1248 1249 /* Fix the opcode. */ 1250 bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset); 1251 1252 /* Fix the relocation's type. */ 1253 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1254 R_CRX_IMM16); 1255 1256 /* Delete two bytes of data. */ 1257 if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec, 1258 irel->r_offset + 2, 2)) 1259 goto error_return; 1260 1261 /* That will change things, so, we should relax again. 1262 Note that this is not required, and it may be slow. */ 1263 *again = TRUE; 1264 } 1265 } 1266 } 1267 1268 if (isymbuf != NULL 1269 && symtab_hdr->contents != (unsigned char *) isymbuf) 1270 { 1271 if (! link_info->keep_memory) 1272 free (isymbuf); 1273 else 1274 { 1275 /* Cache the symbols for elf_link_input_bfd. */ 1276 symtab_hdr->contents = (unsigned char *) isymbuf; 1277 } 1278 } 1279 1280 if (contents != NULL 1281 && elf_section_data (sec)->this_hdr.contents != contents) 1282 { 1283 if (! link_info->keep_memory) 1284 free (contents); 1285 else 1286 { 1287 /* Cache the section contents for elf_link_input_bfd. */ 1288 elf_section_data (sec)->this_hdr.contents = contents; 1289 } 1290 } 1291 1292 if (internal_relocs != NULL 1293 && elf_section_data (sec)->relocs != internal_relocs) 1294 free (internal_relocs); 1295 1296 return TRUE; 1297 1298 error_return: 1299 if (isymbuf != NULL 1300 && symtab_hdr->contents != (unsigned char *) isymbuf) 1301 free (isymbuf); 1302 if (contents != NULL 1303 && elf_section_data (sec)->this_hdr.contents != contents) 1304 free (contents); 1305 if (internal_relocs != NULL 1306 && elf_section_data (sec)->relocs != internal_relocs) 1307 free (internal_relocs); 1308 1309 return FALSE; 1310 } 1311 1312 /* Definitions for setting CRX target vector. */ 1313 #define TARGET_LITTLE_SYM crx_elf32_vec 1314 #define TARGET_LITTLE_NAME "elf32-crx" 1315 #define ELF_ARCH bfd_arch_crx 1316 #define ELF_MACHINE_CODE EM_CRX 1317 #define ELF_MAXPAGESIZE 0x1 1318 #define elf_symbol_leading_char '_' 1319 1320 #define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup 1321 #define bfd_elf32_bfd_reloc_name_lookup \ 1322 elf_crx_reloc_name_lookup 1323 #define elf_info_to_howto elf_crx_info_to_howto 1324 #define elf_info_to_howto_rel NULL 1325 #define elf_backend_relocate_section elf32_crx_relocate_section 1326 #define bfd_elf32_bfd_relax_section elf32_crx_relax_section 1327 #define bfd_elf32_bfd_get_relocated_section_contents \ 1328 elf32_crx_get_relocated_section_contents 1329 #define elf_backend_can_gc_sections 1 1330 #define elf_backend_rela_normal 1 1331 1332 #include "elf32-target.h" 1333