1 /* BFD back-end for National Semiconductor's CR16 ELF 2 Copyright 2007 Free Software Foundation, Inc. 3 Written by M R Swami Reddy. 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 Foundation, 19 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "bfdlink.h" 24 #include "libbfd.h" 25 #include "libiberty.h" 26 #include "elf-bfd.h" 27 #include "elf/cr16.h" 28 29 /* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */ 30 31 struct cr16_reloc_map 32 { 33 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */ 34 unsigned short cr16_reloc_type; /* CR16 relocation type. */ 35 }; 36 37 static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] = 38 { 39 {BFD_RELOC_NONE, R_CR16_NONE}, 40 {BFD_RELOC_CR16_NUM8, R_CR16_NUM8}, 41 {BFD_RELOC_CR16_NUM16, R_CR16_NUM16}, 42 {BFD_RELOC_CR16_NUM32, R_CR16_NUM32}, 43 {BFD_RELOC_CR16_NUM32a, R_CR16_NUM32a}, 44 {BFD_RELOC_CR16_REGREL4, R_CR16_REGREL4}, 45 {BFD_RELOC_CR16_REGREL4a, R_CR16_REGREL4a}, 46 {BFD_RELOC_CR16_REGREL14, R_CR16_REGREL14}, 47 {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a}, 48 {BFD_RELOC_CR16_REGREL16, R_CR16_REGREL16}, 49 {BFD_RELOC_CR16_REGREL20, R_CR16_REGREL20}, 50 {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a}, 51 {BFD_RELOC_CR16_ABS20, R_CR16_ABS20}, 52 {BFD_RELOC_CR16_ABS24, R_CR16_ABS24}, 53 {BFD_RELOC_CR16_IMM4, R_CR16_IMM4}, 54 {BFD_RELOC_CR16_IMM8, R_CR16_IMM8}, 55 {BFD_RELOC_CR16_IMM16, R_CR16_IMM16}, 56 {BFD_RELOC_CR16_IMM20, R_CR16_IMM20}, 57 {BFD_RELOC_CR16_IMM24, R_CR16_IMM24}, 58 {BFD_RELOC_CR16_IMM32, R_CR16_IMM32}, 59 {BFD_RELOC_CR16_IMM32a, R_CR16_IMM32a}, 60 {BFD_RELOC_CR16_DISP4, R_CR16_DISP4}, 61 {BFD_RELOC_CR16_DISP8, R_CR16_DISP8}, 62 {BFD_RELOC_CR16_DISP16, R_CR16_DISP16}, 63 {BFD_RELOC_CR16_DISP24, R_CR16_DISP24}, 64 {BFD_RELOC_CR16_DISP24a, R_CR16_DISP24a}, 65 {BFD_RELOC_CR16_SWITCH8, R_CR16_SWITCH8}, 66 {BFD_RELOC_CR16_SWITCH16, R_CR16_SWITCH16}, 67 {BFD_RELOC_CR16_SWITCH32, R_CR16_SWITCH32} 68 }; 69 70 static reloc_howto_type cr16_elf_howto_table[] = 71 { 72 HOWTO (R_CR16_NONE, /* type */ 73 0, /* rightshift */ 74 2, /* size */ 75 32, /* bitsize */ 76 FALSE, /* pc_relative */ 77 0, /* bitpos */ 78 complain_overflow_dont, /* complain_on_overflow */ 79 bfd_elf_generic_reloc, /* special_function */ 80 "R_CR16_NONE", /* name */ 81 FALSE, /* partial_inplace */ 82 0, /* src_mask */ 83 0, /* dst_mask */ 84 FALSE), /* pcrel_offset */ 85 86 HOWTO (R_CR16_NUM8, /* type */ 87 0, /* rightshift */ 88 0, /* size */ 89 8, /* bitsize */ 90 FALSE, /* pc_relative */ 91 0, /* bitpos */ 92 complain_overflow_bitfield,/* complain_on_overflow */ 93 bfd_elf_generic_reloc, /* special_function */ 94 "R_CR16_NUM8", /* name */ 95 FALSE, /* partial_inplace */ 96 0xff, /* src_mask */ 97 0xff, /* dst_mask */ 98 FALSE), /* pcrel_offset */ 99 100 HOWTO (R_CR16_NUM16, /* type */ 101 0, /* rightshift */ 102 1, /* size */ 103 16, /* bitsize */ 104 FALSE, /* pc_relative */ 105 0, /* bitpos */ 106 complain_overflow_bitfield,/* complain_on_overflow */ 107 bfd_elf_generic_reloc, /* special_function */ 108 "R_CR16_NUM16", /* name */ 109 FALSE, /* partial_inplace */ 110 0xffff, /* src_mask */ 111 0xffff, /* dst_mask */ 112 FALSE), /* pcrel_offset */ 113 114 HOWTO (R_CR16_NUM32, /* type */ 115 0, /* rightshift */ 116 2, /* size */ 117 32, /* bitsize */ 118 FALSE, /* pc_relative */ 119 0, /* bitpos */ 120 complain_overflow_bitfield,/* complain_on_overflow */ 121 bfd_elf_generic_reloc, /* special_function */ 122 "R_CR16_NUM32", /* name */ 123 FALSE, /* partial_inplace */ 124 0xffffffff, /* src_mask */ 125 0xffffffff, /* dst_mask */ 126 FALSE), /* pcrel_offset */ 127 128 HOWTO (R_CR16_NUM32a, /* type */ 129 1, /* rightshift */ 130 2, /* size */ 131 32, /* bitsize */ 132 FALSE, /* pc_relative */ 133 0, /* bitpos */ 134 complain_overflow_bitfield,/* complain_on_overflow */ 135 bfd_elf_generic_reloc, /* special_function */ 136 "R_CR16_NUM32a", /* name */ 137 FALSE, /* partial_inplace */ 138 0xffffffff, /* src_mask */ 139 0xffffffff, /* dst_mask */ 140 FALSE), /* pcrel_offset */ 141 142 HOWTO (R_CR16_REGREL4, /* type */ 143 0, /* rightshift */ 144 0, /* size */ 145 4, /* bitsize */ 146 FALSE, /* pc_relative */ 147 0, /* bitpos */ 148 complain_overflow_bitfield,/* complain_on_overflow */ 149 bfd_elf_generic_reloc, /* special_function */ 150 "R_CR16_REGREL4", /* name */ 151 FALSE, /* partial_inplace */ 152 0xf, /* src_mask */ 153 0xf, /* dst_mask */ 154 FALSE), /* pcrel_offset */ 155 156 HOWTO (R_CR16_REGREL4a, /* type */ 157 0, /* rightshift */ 158 0, /* size */ 159 4, /* bitsize */ 160 FALSE, /* pc_relative */ 161 0, /* bitpos */ 162 complain_overflow_bitfield,/* complain_on_overflow */ 163 bfd_elf_generic_reloc, /* special_function */ 164 "R_CR16_REGREL4a", /* name */ 165 FALSE, /* partial_inplace */ 166 0xf, /* src_mask */ 167 0xf, /* dst_mask */ 168 FALSE), /* pcrel_offset */ 169 170 HOWTO (R_CR16_REGREL14, /* type */ 171 0, /* rightshift */ 172 1, /* size */ 173 14, /* bitsize */ 174 FALSE, /* pc_relative */ 175 0, /* bitpos */ 176 complain_overflow_bitfield,/* complain_on_overflow */ 177 bfd_elf_generic_reloc, /* special_function */ 178 "R_CR16_REGREL14", /* name */ 179 FALSE, /* partial_inplace */ 180 0x3fff, /* src_mask */ 181 0x3fff, /* dst_mask */ 182 FALSE), /* pcrel_offset */ 183 184 HOWTO (R_CR16_REGREL14a, /* type */ 185 0, /* rightshift */ 186 1, /* size */ 187 14, /* bitsize */ 188 FALSE, /* pc_relative */ 189 0, /* bitpos */ 190 complain_overflow_bitfield,/* complain_on_overflow */ 191 bfd_elf_generic_reloc, /* special_function */ 192 "R_CR16_REGREL14a", /* name */ 193 FALSE, /* partial_inplace */ 194 0x3fff, /* src_mask */ 195 0x3fff, /* dst_mask */ 196 FALSE), /* pcrel_offset */ 197 198 HOWTO (R_CR16_REGREL16, /* type */ 199 0, /* rightshift */ 200 1, /* size */ 201 16, /* bitsize */ 202 FALSE, /* pc_relative */ 203 0, /* bitpos */ 204 complain_overflow_bitfield,/* complain_on_overflow */ 205 bfd_elf_generic_reloc, /* special_function */ 206 "R_CR16_REGREL16", /* name */ 207 FALSE, /* partial_inplace */ 208 0xffff, /* src_mask */ 209 0xffff, /* dst_mask */ 210 FALSE), /* pcrel_offset */ 211 212 HOWTO (R_CR16_REGREL20, /* type */ 213 0, /* rightshift */ 214 2, /* size */ 215 20, /* bitsize */ 216 FALSE, /* pc_relative */ 217 0, /* bitpos */ 218 complain_overflow_bitfield,/* complain_on_overflow */ 219 bfd_elf_generic_reloc, /* special_function */ 220 "R_CR16_REGREL20", /* name */ 221 FALSE, /* partial_inplace */ 222 0xfffff, /* src_mask */ 223 0xfffff, /* dst_mask */ 224 FALSE), /* pcrel_offset */ 225 226 HOWTO (R_CR16_REGREL20a, /* type */ 227 0, /* rightshift */ 228 2, /* size */ 229 20, /* bitsize */ 230 FALSE, /* pc_relative */ 231 0, /* bitpos */ 232 complain_overflow_bitfield,/* complain_on_overflow */ 233 bfd_elf_generic_reloc, /* special_function */ 234 "R_CR16_REGREL20a", /* name */ 235 FALSE, /* partial_inplace */ 236 0xfffff, /* src_mask */ 237 0xfffff, /* dst_mask */ 238 FALSE), /* pcrel_offset */ 239 240 HOWTO (R_CR16_ABS20, /* type */ 241 0, /* rightshift */ 242 2, /* size */ 243 20, /* bitsize */ 244 FALSE, /* pc_relative */ 245 0, /* bitpos */ 246 complain_overflow_bitfield,/* complain_on_overflow */ 247 bfd_elf_generic_reloc, /* special_function */ 248 "R_CR16_ABS20", /* name */ 249 FALSE, /* partial_inplace */ 250 0xfffff, /* src_mask */ 251 0xfffff, /* dst_mask */ 252 FALSE), /* pcrel_offset */ 253 254 HOWTO (R_CR16_ABS24, /* type */ 255 0, /* rightshift */ 256 2, /* size */ 257 24, /* bitsize */ 258 FALSE, /* pc_relative */ 259 0, /* bitpos */ 260 complain_overflow_bitfield,/* complain_on_overflow */ 261 bfd_elf_generic_reloc, /* special_function */ 262 "R_CR16_ABS24", /* name */ 263 FALSE, /* partial_inplace */ 264 0xffffff, /* src_mask */ 265 0xffffff, /* dst_mask */ 266 FALSE), /* pcrel_offset */ 267 268 HOWTO (R_CR16_IMM4, /* type */ 269 0, /* rightshift */ 270 0, /* size */ 271 4, /* bitsize */ 272 FALSE, /* pc_relative */ 273 0, /* bitpos */ 274 complain_overflow_bitfield,/* complain_on_overflow */ 275 bfd_elf_generic_reloc, /* special_function */ 276 "R_CR16_IMM4", /* name */ 277 FALSE, /* partial_inplace */ 278 0xf, /* src_mask */ 279 0xf, /* dst_mask */ 280 FALSE), /* pcrel_offset */ 281 282 HOWTO (R_CR16_IMM8, /* type */ 283 0, /* rightshift */ 284 0, /* size */ 285 8, /* bitsize */ 286 FALSE, /* pc_relative */ 287 0, /* bitpos */ 288 complain_overflow_bitfield,/* complain_on_overflow */ 289 bfd_elf_generic_reloc, /* special_function */ 290 "R_CR16_IMM8", /* name */ 291 FALSE, /* partial_inplace */ 292 0xff, /* src_mask */ 293 0xff, /* dst_mask */ 294 FALSE), /* pcrel_offset */ 295 296 HOWTO (R_CR16_IMM16, /* type */ 297 0, /* rightshift */ 298 1, /* size */ 299 16, /* bitsize */ 300 FALSE, /* pc_relative */ 301 0, /* bitpos */ 302 complain_overflow_bitfield,/* complain_on_overflow */ 303 bfd_elf_generic_reloc, /* special_function */ 304 "R_CR16_IMM16", /* name */ 305 FALSE, /* partial_inplace */ 306 0xffff, /* src_mask */ 307 0xffff, /* dst_mask */ 308 FALSE), /* pcrel_offset */ 309 310 HOWTO (R_CR16_IMM20, /* type */ 311 0, /* rightshift */ 312 2, /* size */ 313 20, /* bitsize */ 314 FALSE, /* pc_relative */ 315 0, /* bitpos */ 316 complain_overflow_bitfield,/* complain_on_overflow */ 317 bfd_elf_generic_reloc, /* special_function */ 318 "R_CR16_IMM20", /* name */ 319 FALSE, /* partial_inplace */ 320 0xfffff, /* src_mask */ 321 0xfffff, /* dst_mask */ 322 FALSE), /* pcrel_offset */ 323 324 HOWTO (R_CR16_IMM24, /* type */ 325 0, /* rightshift */ 326 2, /* size */ 327 24, /* bitsize */ 328 FALSE, /* pc_relative */ 329 0, /* bitpos */ 330 complain_overflow_bitfield,/* complain_on_overflow */ 331 bfd_elf_generic_reloc, /* special_function */ 332 "R_CR16_IMM24", /* name */ 333 FALSE, /* partial_inplace */ 334 0xffffff, /* src_mask */ 335 0xffffff, /* dst_mask */ 336 FALSE), /* pcrel_offset */ 337 338 HOWTO (R_CR16_IMM32, /* type */ 339 0, /* rightshift */ 340 2, /* size */ 341 32, /* bitsize */ 342 FALSE, /* pc_relative */ 343 0, /* bitpos */ 344 complain_overflow_bitfield,/* complain_on_overflow */ 345 bfd_elf_generic_reloc, /* special_function */ 346 "R_CR16_IMM32", /* name */ 347 FALSE, /* partial_inplace */ 348 0xffffffff, /* src_mask */ 349 0xffffffff, /* dst_mask */ 350 FALSE), /* pcrel_offset */ 351 352 HOWTO (R_CR16_IMM32a, /* type */ 353 1, /* rightshift */ 354 2, /* size */ 355 32, /* bitsize */ 356 FALSE, /* pc_relative */ 357 0, /* bitpos */ 358 complain_overflow_bitfield,/* complain_on_overflow */ 359 bfd_elf_generic_reloc, /* special_function */ 360 "R_CR16_IMM32a", /* name */ 361 FALSE, /* partial_inplace */ 362 0xffffffff, /* src_mask */ 363 0xffffffff, /* dst_mask */ 364 FALSE), /* pcrel_offset */ 365 366 HOWTO (R_CR16_DISP4, /* type */ 367 1, /* rightshift */ 368 0, /* size (0 = byte, 1 = short, 2 = long) */ 369 4, /* bitsize */ 370 TRUE, /* pc_relative */ 371 0, /* bitpos */ 372 complain_overflow_unsigned, /* complain_on_overflow */ 373 bfd_elf_generic_reloc, /* special_function */ 374 "R_CR16_DISP4", /* name */ 375 FALSE, /* partial_inplace */ 376 0xf, /* src_mask */ 377 0xf, /* dst_mask */ 378 FALSE), /* pcrel_offset */ 379 380 HOWTO (R_CR16_DISP8, /* type */ 381 1, /* rightshift */ 382 0, /* size (0 = byte, 1 = short, 2 = long) */ 383 8, /* bitsize */ 384 TRUE, /* pc_relative */ 385 0, /* bitpos */ 386 complain_overflow_unsigned, /* complain_on_overflow */ 387 bfd_elf_generic_reloc, /* special_function */ 388 "R_CR16_DISP8", /* name */ 389 FALSE, /* partial_inplace */ 390 0x1ff, /* src_mask */ 391 0x1ff, /* dst_mask */ 392 FALSE), /* pcrel_offset */ 393 394 HOWTO (R_CR16_DISP16, /* type */ 395 0, /* rightshift REVIITS: To sync with WinIDEA*/ 396 1, /* size (0 = byte, 1 = short, 2 = long) */ 397 16, /* bitsize */ 398 TRUE, /* pc_relative */ 399 0, /* bitpos */ 400 complain_overflow_unsigned, /* complain_on_overflow */ 401 bfd_elf_generic_reloc, /* special_function */ 402 "R_CR16_DISP16", /* name */ 403 FALSE, /* partial_inplace */ 404 0x1ffff, /* src_mask */ 405 0x1ffff, /* dst_mask */ 406 FALSE), /* pcrel_offset */ 407 /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc 408 but its not done, to sync with WinIDEA and CR16 4.1 tools */ 409 HOWTO (R_CR16_DISP24, /* type */ 410 0, /* rightshift */ 411 2, /* size (0 = byte, 1 = short, 2 = long) */ 412 24, /* bitsize */ 413 TRUE, /* pc_relative */ 414 0, /* bitpos */ 415 complain_overflow_unsigned, /* complain_on_overflow */ 416 bfd_elf_generic_reloc, /* special_function */ 417 "R_CR16_DISP24", /* name */ 418 FALSE, /* partial_inplace */ 419 0x1ffffff, /* src_mask */ 420 0x1ffffff, /* dst_mask */ 421 FALSE), /* pcrel_offset */ 422 423 HOWTO (R_CR16_DISP24a, /* type */ 424 0, /* rightshift */ 425 2, /* size (0 = byte, 1 = short, 2 = long) */ 426 24, /* bitsize */ 427 TRUE, /* pc_relative */ 428 0, /* bitpos */ 429 complain_overflow_unsigned, /* complain_on_overflow */ 430 bfd_elf_generic_reloc, /* special_function */ 431 "R_CR16_DISP24a", /* name */ 432 FALSE, /* partial_inplace */ 433 0xffffff, /* src_mask */ 434 0xffffff, /* dst_mask */ 435 FALSE), /* pcrel_offset */ 436 437 /* An 8 bit switch table entry. This is generated for an expression 438 such as ``.byte L1 - L2''. The offset holds the difference 439 between the reloc address and L2. */ 440 HOWTO (R_CR16_SWITCH8, /* type */ 441 0, /* rightshift */ 442 0, /* size (0 = byte, 1 = short, 2 = long) */ 443 8, /* bitsize */ 444 FALSE, /* pc_relative */ 445 0, /* bitpos */ 446 complain_overflow_unsigned, /* complain_on_overflow */ 447 bfd_elf_generic_reloc, /* special_function */ 448 "R_CR16_SWITCH8", /* name */ 449 FALSE, /* partial_inplace */ 450 0xff, /* src_mask */ 451 0xff, /* dst_mask */ 452 TRUE), /* pcrel_offset */ 453 454 /* A 16 bit switch table entry. This is generated for an expression 455 such as ``.word L1 - L2''. The offset holds the difference 456 between the reloc address and L2. */ 457 HOWTO (R_CR16_SWITCH16, /* type */ 458 0, /* rightshift */ 459 1, /* size (0 = byte, 1 = short, 2 = long) */ 460 16, /* bitsize */ 461 FALSE, /* pc_relative */ 462 0, /* bitpos */ 463 complain_overflow_unsigned, /* complain_on_overflow */ 464 bfd_elf_generic_reloc, /* special_function */ 465 "R_CR16_SWITCH16", /* name */ 466 FALSE, /* partial_inplace */ 467 0xffff, /* src_mask */ 468 0xffff, /* dst_mask */ 469 TRUE), /* pcrel_offset */ 470 471 /* A 32 bit switch table entry. This is generated for an expression 472 such as ``.long L1 - L2''. The offset holds the difference 473 between the reloc address and L2. */ 474 HOWTO (R_CR16_SWITCH32, /* type */ 475 0, /* rightshift */ 476 2, /* size (0 = byte, 1 = short, 2 = long) */ 477 32, /* bitsize */ 478 FALSE, /* pc_relative */ 479 0, /* bitpos */ 480 complain_overflow_unsigned, /* complain_on_overflow */ 481 bfd_elf_generic_reloc, /* special_function */ 482 "R_CR16_SWITCH32", /* name */ 483 FALSE, /* partial_inplace */ 484 0xffffffff, /* src_mask */ 485 0xffffffff, /* dst_mask */ 486 TRUE) /* pcrel_offset */ 487 }; 488 489 /* Retrieve a howto ptr using a BFD reloc_code. */ 490 491 static reloc_howto_type * 492 elf_cr16_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 493 bfd_reloc_code_real_type code) 494 { 495 unsigned int i; 496 497 for (i = 0; i < R_CR16_MAX; i++) 498 if (code == cr16_reloc_map[i].bfd_reloc_enum) 499 return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type]; 500 501 _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code); 502 return NULL; 503 } 504 505 static reloc_howto_type * 506 elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 507 const char *r_name) 508 { 509 unsigned int i; 510 511 for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++) 512 if (cr16_elf_howto_table[i].name != NULL 513 && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0) 514 return cr16_elf_howto_table + i; 515 516 return NULL; 517 } 518 519 /* Retrieve a howto ptr using an internal relocation entry. */ 520 521 static void 522 elf_cr16_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, 523 Elf_Internal_Rela *dst) 524 { 525 unsigned int r_type = ELF32_R_TYPE (dst->r_info); 526 527 BFD_ASSERT (r_type < (unsigned int) R_CR16_MAX); 528 cache_ptr->howto = &cr16_elf_howto_table[r_type]; 529 } 530 531 /* Perform a relocation as part of a final link. */ 532 533 static bfd_reloc_status_type 534 cr16_elf_final_link_relocate (reloc_howto_type *howto, 535 bfd *input_bfd, 536 bfd *output_bfd ATTRIBUTE_UNUSED, 537 asection *input_section, 538 bfd_byte *contents, 539 bfd_vma offset, 540 bfd_vma Rvalue, 541 bfd_vma addend, 542 struct bfd_link_info *info ATTRIBUTE_UNUSED, 543 asection *sec ATTRIBUTE_UNUSED, 544 int is_local ATTRIBUTE_UNUSED) 545 { 546 unsigned short r_type = howto->type; 547 bfd_byte *hit_data = contents + offset; 548 bfd_vma reloc_bits, check, Rvalue1; 549 550 switch (r_type) 551 { 552 case R_CR16_IMM4: 553 case R_CR16_IMM20: 554 case R_CR16_ABS20: 555 break; 556 557 case R_CR16_IMM8: 558 case R_CR16_IMM16: 559 case R_CR16_IMM32: 560 case R_CR16_IMM32a: 561 case R_CR16_REGREL4: 562 case R_CR16_REGREL4a: 563 case R_CR16_REGREL14: 564 case R_CR16_REGREL14a: 565 case R_CR16_REGREL16: 566 case R_CR16_REGREL20: 567 case R_CR16_ABS24: 568 case R_CR16_DISP16: 569 case R_CR16_DISP24: 570 /* 'hit_data' is relative to the start of the instruction, not the 571 relocation offset. Advance it to account for the exact offset. */ 572 hit_data += 2; 573 break; 574 575 case R_CR16_NONE: 576 return bfd_reloc_ok; 577 break; 578 579 case R_CR16_DISP4: 580 if (is_local) 581 Rvalue += -1; 582 break; 583 584 case R_CR16_DISP8: 585 case R_CR16_DISP24a: 586 if (is_local) 587 Rvalue -= -1; 588 break; 589 590 case R_CR16_SWITCH8: 591 case R_CR16_SWITCH16: 592 case R_CR16_SWITCH32: 593 /* We only care about the addend, where the difference between 594 expressions is kept. */ 595 Rvalue = 0; 596 597 default: 598 break; 599 } 600 601 if (howto->pc_relative) 602 { 603 /* Subtract the address of the section containing the location. */ 604 Rvalue -= (input_section->output_section->vma 605 + input_section->output_offset); 606 /* Subtract the position of the location within the section. */ 607 Rvalue -= offset; 608 } 609 610 /* Add in supplied addend. */ 611 Rvalue += addend; 612 613 /* Complain if the bitfield overflows, whether it is considered 614 as signed or unsigned. */ 615 check = Rvalue >> howto->rightshift; 616 617 /* Assumes two's complement. This expression avoids 618 overflow if howto->bitsize is the number of bits in 619 bfd_vma. */ 620 reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; 621 622 if (((bfd_vma) check & ~reloc_bits) != 0 623 && (((bfd_vma) check & ~reloc_bits) 624 != (-(bfd_vma) 1 & ~reloc_bits))) 625 { 626 /* The above right shift is incorrect for a signed 627 value. See if turning on the upper bits fixes the 628 overflow. */ 629 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0) 630 { 631 check |= ((bfd_vma) - 1 632 & ~((bfd_vma) - 1 633 >> howto->rightshift)); 634 635 if (((bfd_vma) check & ~reloc_bits) 636 != (-(bfd_vma) 1 & ~reloc_bits)) 637 return bfd_reloc_overflow; 638 } 639 else 640 return bfd_reloc_overflow; 641 } 642 643 /* Drop unwanted bits from the value we are relocating to. */ 644 Rvalue >>= (bfd_vma) howto->rightshift; 645 646 /* Apply dst_mask to select only relocatable part of the insn. */ 647 Rvalue &= howto->dst_mask; 648 649 switch (howto->size) 650 { 651 case 0: 652 if (r_type == R_CR16_DISP8) 653 { 654 Rvalue1 = bfd_get_16 (input_bfd, hit_data); 655 Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00) 656 | (Rvalue1 & 0x00f0) | (Rvalue & 0xf)); 657 bfd_put_16 (input_bfd, Rvalue, hit_data); 658 } 659 else if (r_type == R_CR16_IMM4) 660 { 661 Rvalue1 = bfd_get_16 (input_bfd, hit_data); 662 Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0) 663 | ((Rvalue1 & 0x0f00) >> 8)); 664 bfd_put_16 (input_bfd, Rvalue, hit_data); 665 } 666 else if (r_type == R_CR16_DISP4) 667 { 668 Rvalue1 = bfd_get_16 (input_bfd, hit_data); 669 Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4)); 670 bfd_put_16 (input_bfd, Rvalue, hit_data); 671 } 672 else 673 { 674 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data); 675 } 676 break; 677 678 case 1: 679 if (r_type == R_CR16_DISP16) 680 { 681 Rvalue |= (bfd_get_16 (input_bfd, hit_data)); 682 Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1)); 683 } 684 685 bfd_put_16 (input_bfd, Rvalue, hit_data); 686 break; 687 688 case 2: 689 if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20)) 690 { 691 bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data)) 692 | ((Rvalue >> 16) & 0xf), hit_data); 693 bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2); 694 } 695 else 696 { 697 if (r_type == R_CR16_ABS24) 698 { 699 Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >> 16) & 0xf) << 8) 700 | (bfd_get_16 (input_bfd, hit_data))) 701 | ((Rvalue & 0xffff) << 16)); 702 } 703 if (r_type == R_CR16_DISP24) 704 { 705 Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf) << 8) 706 | (bfd_get_16 (input_bfd, hit_data))) 707 | (((Rvalue & 0xfffe) 708 | ((Rvalue >> 24) & 0x1)) << 16)); 709 } 710 else if ((r_type == R_CR16_IMM32) ||(r_type == R_CR16_IMM32a)) 711 { 712 Rvalue = (((Rvalue >> 16)& 0xffff) 713 | (bfd_get_16 (input_bfd, hit_data))) 714 | ((Rvalue & 0xffff) << 16); 715 } 716 else if (r_type == R_CR16_DISP24a) 717 { 718 Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23))); 719 Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16) 720 | (bfd_get_32 (input_bfd, hit_data)); 721 } 722 723 bfd_put_32 (input_bfd, Rvalue, hit_data); 724 } 725 break; 726 727 default: 728 return bfd_reloc_notsupported; 729 } 730 731 return bfd_reloc_ok; 732 } 733 734 /* Delete some bytes from a section while relaxing. */ 735 736 static bfd_boolean 737 elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 738 asection *sec, bfd_vma addr, int count) 739 { 740 Elf_Internal_Shdr *symtab_hdr; 741 unsigned int sec_shndx; 742 bfd_byte *contents; 743 Elf_Internal_Rela *irel, *irelend; 744 Elf_Internal_Rela *irelalign; 745 bfd_vma toaddr; 746 Elf_Internal_Sym *isym; 747 Elf_Internal_Sym *isymend; 748 struct elf_link_hash_entry **sym_hashes; 749 struct elf_link_hash_entry **end_hashes; 750 struct elf_link_hash_entry **start_hashes; 751 unsigned int symcount; 752 753 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 754 755 contents = elf_section_data (sec)->this_hdr.contents; 756 757 /* The deletion must stop at the next ALIGN reloc for an aligment 758 power larger than the number of bytes we are deleting. */ 759 irelalign = NULL; 760 toaddr = sec->size; 761 762 irel = elf_section_data (sec)->relocs; 763 irelend = irel + sec->reloc_count; 764 765 /* Actually delete the bytes. */ 766 memmove (contents + addr, contents + addr + count, 767 (size_t) (toaddr - addr - count)); 768 sec->size -= count; 769 770 /* Adjust all the relocs. */ 771 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 772 /* Get the new reloc address. */ 773 if ((irel->r_offset > addr && irel->r_offset < toaddr)) 774 irel->r_offset -= count; 775 776 /* Adjust the local symbols defined in this section. */ 777 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 778 isym = (Elf_Internal_Sym *) symtab_hdr->contents; 779 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 780 { 781 if (isym->st_shndx == sec_shndx 782 && isym->st_value > addr 783 && isym->st_value < toaddr) 784 { 785 /* Adjust the addend of SWITCH relocations in this section, 786 which reference this local symbol. */ 787 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 788 { 789 unsigned long r_symndx; 790 Elf_Internal_Sym *rsym; 791 bfd_vma addsym, subsym; 792 793 /* Skip if not a SWITCH relocation. */ 794 if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8 795 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16 796 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32) 797 continue; 798 799 r_symndx = ELF32_R_SYM (irel->r_info); 800 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx; 801 802 /* Skip if not the local adjusted symbol. */ 803 if (rsym != isym) 804 continue; 805 806 addsym = isym->st_value; 807 subsym = addsym - irel->r_addend; 808 809 /* Fix the addend only when -->> (addsym > addr >= subsym). */ 810 if (subsym <= addr) 811 irel->r_addend -= count; 812 else 813 continue; 814 } 815 816 isym->st_value -= count; 817 } 818 } 819 820 /* Now adjust the global symbols defined in this section. */ 821 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 822 - symtab_hdr->sh_info); 823 sym_hashes = start_hashes = elf_sym_hashes (abfd); 824 end_hashes = sym_hashes + symcount; 825 826 for (; sym_hashes < end_hashes; sym_hashes++) 827 { 828 struct elf_link_hash_entry *sym_hash = *sym_hashes; 829 830 /* The '--wrap SYMBOL' option is causing a pain when the object file, 831 containing the definition of __wrap_SYMBOL, includes a direct 832 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 833 the same symbol (which is __wrap_SYMBOL), but still exist as two 834 different symbols in 'sym_hashes', we don't want to adjust 835 the global symbol __wrap_SYMBOL twice. 836 This check is only relevant when symbols are being wrapped. */ 837 if (link_info->wrap_hash != NULL) 838 { 839 struct elf_link_hash_entry **cur_sym_hashes; 840 841 /* Loop only over the symbols whom been already checked. */ 842 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 843 cur_sym_hashes++) 844 /* If the current symbol is identical to 'sym_hash', that means 845 the symbol was already adjusted (or at least checked). */ 846 if (*cur_sym_hashes == sym_hash) 847 break; 848 849 /* Don't adjust the symbol again. */ 850 if (cur_sym_hashes < sym_hashes) 851 continue; 852 } 853 854 if ((sym_hash->root.type == bfd_link_hash_defined 855 || sym_hash->root.type == bfd_link_hash_defweak) 856 && sym_hash->root.u.def.section == sec 857 && sym_hash->root.u.def.value > addr 858 && sym_hash->root.u.def.value < toaddr) 859 sym_hash->root.u.def.value -= count; 860 } 861 862 return TRUE; 863 } 864 865 /* Relocate a CR16 ELF section. */ 866 867 static bfd_boolean 868 elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 869 bfd *input_bfd, asection *input_section, 870 bfd_byte *contents, Elf_Internal_Rela *relocs, 871 Elf_Internal_Sym *local_syms, 872 asection **local_sections) 873 { 874 Elf_Internal_Shdr *symtab_hdr; 875 struct elf_link_hash_entry **sym_hashes; 876 Elf_Internal_Rela *rel, *relend; 877 878 if (info->relocatable) 879 return TRUE; 880 881 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 882 sym_hashes = elf_sym_hashes (input_bfd); 883 884 rel = relocs; 885 relend = relocs + input_section->reloc_count; 886 for (; rel < relend; rel++) 887 { 888 int r_type; 889 reloc_howto_type *howto; 890 unsigned long r_symndx; 891 Elf_Internal_Sym *sym; 892 asection *sec; 893 struct elf_link_hash_entry *h; 894 bfd_vma relocation; 895 bfd_reloc_status_type r; 896 897 r_symndx = ELF32_R_SYM (rel->r_info); 898 r_type = ELF32_R_TYPE (rel->r_info); 899 howto = cr16_elf_howto_table + (r_type); 900 901 h = NULL; 902 sym = NULL; 903 sec = NULL; 904 if (r_symndx < symtab_hdr->sh_info) 905 { 906 sym = local_syms + r_symndx; 907 sec = local_sections[r_symndx]; 908 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 909 } 910 else 911 { 912 bfd_boolean unresolved_reloc, warned; 913 914 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 915 r_symndx, symtab_hdr, sym_hashes, 916 h, sec, relocation, 917 unresolved_reloc, warned); 918 } 919 920 r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd, 921 input_section, 922 contents, rel->r_offset, 923 relocation, rel->r_addend, 924 info, sec, h == NULL); 925 926 if (r != bfd_reloc_ok) 927 { 928 const char *name; 929 const char *msg = NULL; 930 931 if (h != NULL) 932 name = h->root.root.string; 933 else 934 { 935 name = (bfd_elf_string_from_elf_section 936 (input_bfd, symtab_hdr->sh_link, sym->st_name)); 937 if (name == NULL || *name == '\0') 938 name = bfd_section_name (input_bfd, sec); 939 } 940 941 switch (r) 942 { 943 case bfd_reloc_overflow: 944 if (!((*info->callbacks->reloc_overflow) 945 (info, (h ? &h->root : NULL), name, howto->name, 946 (bfd_vma) 0, input_bfd, input_section, 947 rel->r_offset))) 948 return FALSE; 949 break; 950 951 case bfd_reloc_undefined: 952 if (!((*info->callbacks->undefined_symbol) 953 (info, name, input_bfd, input_section, 954 rel->r_offset, TRUE))) 955 return FALSE; 956 break; 957 958 case bfd_reloc_outofrange: 959 msg = _("internal error: out of range error"); 960 goto common_error; 961 962 case bfd_reloc_notsupported: 963 msg = _("internal error: unsupported relocation error"); 964 goto common_error; 965 966 case bfd_reloc_dangerous: 967 msg = _("internal error: dangerous error"); 968 goto common_error; 969 970 default: 971 msg = _("internal error: unknown error"); 972 /* Fall through. */ 973 974 common_error: 975 if (!((*info->callbacks->warning) 976 (info, msg, name, input_bfd, input_section, 977 rel->r_offset))) 978 return FALSE; 979 break; 980 } 981 } 982 } 983 984 return TRUE; 985 } 986 987 /* This is a version of bfd_generic_get_relocated_section_contents 988 which uses elf32_cr16_relocate_section. */ 989 990 static bfd_byte * 991 elf32_cr16_get_relocated_section_contents (bfd *output_bfd, 992 struct bfd_link_info *link_info, 993 struct bfd_link_order *link_order, 994 bfd_byte *data, 995 bfd_boolean relocatable, 996 asymbol **symbols) 997 { 998 Elf_Internal_Shdr *symtab_hdr; 999 asection *input_section = link_order->u.indirect.section; 1000 bfd *input_bfd = input_section->owner; 1001 asection **sections = NULL; 1002 Elf_Internal_Rela *internal_relocs = NULL; 1003 Elf_Internal_Sym *isymbuf = NULL; 1004 1005 /* We only need to handle the case of relaxing, or of having a 1006 particular set of section contents, specially. */ 1007 if (relocatable 1008 || elf_section_data (input_section)->this_hdr.contents == NULL) 1009 return bfd_generic_get_relocated_section_contents (output_bfd, link_info, 1010 link_order, data, 1011 relocatable, 1012 symbols); 1013 1014 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 1015 1016 memcpy (data, elf_section_data (input_section)->this_hdr.contents, 1017 (size_t) input_section->size); 1018 1019 if ((input_section->flags & SEC_RELOC) != 0 1020 && input_section->reloc_count > 0) 1021 { 1022 Elf_Internal_Sym *isym; 1023 Elf_Internal_Sym *isymend; 1024 asection **secpp; 1025 bfd_size_type amt; 1026 1027 internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section, 1028 NULL, NULL, FALSE); 1029 if (internal_relocs == NULL) 1030 goto error_return; 1031 1032 if (symtab_hdr->sh_info != 0) 1033 { 1034 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1035 if (isymbuf == NULL) 1036 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, 1037 symtab_hdr->sh_info, 0, 1038 NULL, NULL, NULL); 1039 if (isymbuf == NULL) 1040 goto error_return; 1041 } 1042 1043 amt = symtab_hdr->sh_info; 1044 amt *= sizeof (asection *); 1045 sections = bfd_malloc (amt); 1046 if (sections == NULL && amt != 0) 1047 goto error_return; 1048 1049 isymend = isymbuf + symtab_hdr->sh_info; 1050 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp) 1051 { 1052 asection *isec; 1053 1054 if (isym->st_shndx == SHN_UNDEF) 1055 isec = bfd_und_section_ptr; 1056 else if (isym->st_shndx == SHN_ABS) 1057 isec = bfd_abs_section_ptr; 1058 else if (isym->st_shndx == SHN_COMMON) 1059 isec = bfd_com_section_ptr; 1060 else 1061 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 1062 1063 *secpp = isec; 1064 } 1065 1066 if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd, 1067 input_section, data, internal_relocs, 1068 isymbuf, sections)) 1069 goto error_return; 1070 1071 if (sections != NULL) 1072 free (sections); 1073 if (isymbuf != NULL 1074 && symtab_hdr->contents != (unsigned char *) isymbuf) 1075 free (isymbuf); 1076 if (elf_section_data (input_section)->relocs != internal_relocs) 1077 free (internal_relocs); 1078 } 1079 1080 return data; 1081 1082 error_return: 1083 if (sections != NULL) 1084 free (sections); 1085 if (isymbuf != NULL 1086 && symtab_hdr->contents != (unsigned char *) isymbuf) 1087 free (isymbuf); 1088 if (internal_relocs != NULL 1089 && elf_section_data (input_section)->relocs != internal_relocs) 1090 free (internal_relocs); 1091 return NULL; 1092 } 1093 1094 /* This function handles relaxing for the CR16. 1095 1096 There's quite a few relaxing opportunites available on the CR16: 1097 1098 * bcond:24 -> bcond:16 2 bytes 1099 * bcond:16 -> bcond:8 2 bytes 1100 * arithmetic imm32 -> arithmetic imm20/imm16 2 bytes 1101 * arithmetic imm20/imm16 -> arithmetic imm4 2 bytes 1102 1103 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */ 1104 1105 static bfd_boolean 1106 elf32_cr16_relax_section (bfd *abfd, asection *sec, 1107 struct bfd_link_info *link_info, bfd_boolean *again) 1108 { 1109 Elf_Internal_Shdr *symtab_hdr; 1110 Elf_Internal_Rela *internal_relocs; 1111 Elf_Internal_Rela *irel, *irelend; 1112 bfd_byte *contents = NULL; 1113 Elf_Internal_Sym *isymbuf = NULL; 1114 1115 /* Assume nothing changes. */ 1116 *again = FALSE; 1117 1118 /* We don't have to do anything for a relocatable link, if 1119 this section does not have relocs, or if this is not a 1120 code section. */ 1121 if (link_info->relocatable 1122 || (sec->flags & SEC_RELOC) == 0 1123 || sec->reloc_count == 0 1124 || (sec->flags & SEC_CODE) == 0) 1125 return TRUE; 1126 1127 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1128 1129 /* Get a copy of the native relocations. */ 1130 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 1131 link_info->keep_memory); 1132 if (internal_relocs == NULL) 1133 goto error_return; 1134 1135 /* Walk through them looking for relaxing opportunities. */ 1136 irelend = internal_relocs + sec->reloc_count; 1137 for (irel = internal_relocs; irel < irelend; irel++) 1138 { 1139 bfd_vma symval; 1140 1141 /* If this isn't something that can be relaxed, then ignore 1142 this reloc. */ 1143 if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16 1144 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24 1145 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32 1146 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20 1147 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16) 1148 continue; 1149 1150 /* Get the section contents if we haven't done so already. */ 1151 if (contents == NULL) 1152 { 1153 /* Get cached copy if it exists. */ 1154 if (elf_section_data (sec)->this_hdr.contents != NULL) 1155 contents = elf_section_data (sec)->this_hdr.contents; 1156 /* Go get them off disk. */ 1157 else if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 1158 goto error_return; 1159 } 1160 1161 /* Read this BFD's local symbols if we haven't done so already. */ 1162 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1163 { 1164 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1165 if (isymbuf == NULL) 1166 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1167 symtab_hdr->sh_info, 0, 1168 NULL, NULL, NULL); 1169 if (isymbuf == NULL) 1170 goto error_return; 1171 } 1172 1173 /* Get the value of the symbol referred to by the reloc. */ 1174 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1175 { 1176 /* A local symbol. */ 1177 Elf_Internal_Sym *isym; 1178 asection *sym_sec; 1179 1180 isym = isymbuf + ELF32_R_SYM (irel->r_info); 1181 if (isym->st_shndx == SHN_UNDEF) 1182 sym_sec = bfd_und_section_ptr; 1183 else if (isym->st_shndx == SHN_ABS) 1184 sym_sec = bfd_abs_section_ptr; 1185 else if (isym->st_shndx == SHN_COMMON) 1186 sym_sec = bfd_com_section_ptr; 1187 else 1188 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1189 symval = (isym->st_value 1190 + sym_sec->output_section->vma 1191 + sym_sec->output_offset); 1192 } 1193 else 1194 { 1195 unsigned long indx; 1196 struct elf_link_hash_entry *h; 1197 1198 /* An external symbol. */ 1199 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 1200 h = elf_sym_hashes (abfd)[indx]; 1201 BFD_ASSERT (h != NULL); 1202 1203 if (h->root.type != bfd_link_hash_defined 1204 && h->root.type != bfd_link_hash_defweak) 1205 /* This appears to be a reference to an undefined 1206 symbol. Just ignore it--it will be caught by the 1207 regular reloc processing. */ 1208 continue; 1209 1210 symval = (h->root.u.def.value 1211 + h->root.u.def.section->output_section->vma 1212 + h->root.u.def.section->output_offset); 1213 } 1214 1215 /* For simplicity of coding, we are going to modify the section 1216 contents, the section relocs, and the BFD symbol table. We 1217 must tell the rest of the code not to free up this 1218 information. It would be possible to instead create a table 1219 of changes which have to be made, as is done in coff-mips.c; 1220 that would be more work, but would require less memory when 1221 the linker is run. */ 1222 1223 /* Try to turn a 24 branch/call into a 16bit relative 1224 branch/call. */ 1225 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24) 1226 { 1227 bfd_vma value = symval; 1228 1229 /* Deal with pc-relative gunk. */ 1230 value -= (sec->output_section->vma + sec->output_offset); 1231 value -= irel->r_offset; 1232 value += irel->r_addend; 1233 1234 /* See if the value will fit in 16 bits, note the high value is 1235 0xfffe + 2 as the target will be two bytes closer if we are 1236 able to relax. */ 1237 if ((long) value < 0x10000 && (long) value > -0x10002) 1238 { 1239 unsigned int code; 1240 1241 /* Get the opcode. */ 1242 code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset); 1243 1244 /* Verify it's a 'bcond' and fix the opcode. */ 1245 if ((code & 0xffff) == 0x0010) 1246 { 1247 bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset); 1248 bfd_put_16 (abfd, value, contents + irel->r_offset + 2); 1249 } 1250 else 1251 continue; 1252 1253 /* Note that we've changed the relocs, section contents, etc. */ 1254 elf_section_data (sec)->relocs = internal_relocs; 1255 elf_section_data (sec)->this_hdr.contents = contents; 1256 symtab_hdr->contents = (unsigned char *) isymbuf; 1257 1258 /* Fix the relocation's type. */ 1259 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1260 R_CR16_DISP16); 1261 1262 /* Delete two bytes of data. */ 1263 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1264 irel->r_offset + 2, 2)) 1265 goto error_return; 1266 1267 /* That will change things, so, we should relax again. 1268 Note that this is not required, and it may be slow. */ 1269 *again = TRUE; 1270 } 1271 } 1272 1273 /* Try to turn a 16-bit pc-relative branch into an 1274 8-bit pc-relative branch. */ 1275 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16) 1276 { 1277 bfd_vma value = symval; 1278 1279 /* Deal with pc-relative gunk. */ 1280 value -= (sec->output_section->vma + sec->output_offset); 1281 value -= irel->r_offset; 1282 value += irel->r_addend; 1283 1284 /* See if the value will fit in 8 bits, note the high value is 1285 0xfc + 2 as the target will be two bytes closer if we are 1286 able to relax. */ 1287 if ((long) value < 0xfe && (long) value > -0x100) 1288 { 1289 unsigned short code; 1290 1291 /* Get the opcode. */ 1292 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1293 1294 /* Verify it's a 'bcond' opcode. */ 1295 if ((code & 0xff00) == 0x1800) 1296 { 1297 bfd_put_8 (abfd, 0x1 | ((0xf & (code >> 4)) << 4), contents + irel->r_offset); 1298 bfd_put_8 (abfd, value, contents + irel->r_offset + 2); 1299 } 1300 else 1301 continue; 1302 1303 /* Note that we've changed the relocs, section contents, etc. */ 1304 elf_section_data (sec)->relocs = internal_relocs; 1305 elf_section_data (sec)->this_hdr.contents = contents; 1306 symtab_hdr->contents = (unsigned char *) isymbuf; 1307 1308 /* Fix the relocation's type. */ 1309 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1310 R_CR16_DISP8); 1311 1312 /* Delete two bytes of data. */ 1313 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1314 irel->r_offset + 2, 2)) 1315 goto error_return; 1316 1317 /* That will change things, so, we should relax again. 1318 Note that this is not required, and it may be slow. */ 1319 *again = TRUE; 1320 } 1321 } 1322 1323 /* Try to turn a 32bit immediate address into 1324 a 20/16bit immediate address. */ 1325 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32) 1326 { 1327 bfd_vma value = symval; 1328 unsigned short is_add_mov = 0; 1329 1330 /* See if the value will fit in 20 bits. */ 1331 if ((long) value < 0xfffff && (long) value > 0) 1332 { 1333 unsigned short code; 1334 1335 /* Get the opcode. */ 1336 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1337 1338 /* Verify it's a arithmetic ADDD or MOVD instruction. 1339 For ADDD and MOVD only, convert to IMM32 -> IMM20. */ 1340 if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020)) 1341 is_add_mov = 1; 1342 1343 if (is_add_mov) 1344 { 1345 /* Note that we've changed the relocs, section contents, 1346 etc. */ 1347 elf_section_data (sec)->relocs = internal_relocs; 1348 elf_section_data (sec)->this_hdr.contents = contents; 1349 symtab_hdr->contents = (unsigned char *) isymbuf; 1350 1351 /* Fix the opcode. */ 1352 if ((code & 0xfff0) == 0x0070) /* For movd. */ 1353 bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1); 1354 else /* code == 0x0020 for addd. */ 1355 bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1); 1356 1357 bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset); 1358 1359 1360 /* Fix the relocation's type. */ 1361 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1362 R_CR16_IMM20); 1363 /* Delete two bytes of data. */ 1364 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1365 irel->r_offset + 2, 2)) 1366 goto error_return; 1367 1368 /* That will change things, so, we should relax again. 1369 Note that this is not required, and it may be slow. */ 1370 *again = TRUE; 1371 } 1372 } 1373 /* See if the value will fit in 16 bits. */ 1374 if ((!is_add_mov) && ((long) value < 0x7fff && (long) value > 0)) 1375 { 1376 unsigned short code; 1377 1378 /* Get the opcode. */ 1379 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1380 1381 /* Note that we've changed the relocs, section contents, etc. */ 1382 elf_section_data (sec)->relocs = internal_relocs; 1383 elf_section_data (sec)->this_hdr.contents = contents; 1384 symtab_hdr->contents = (unsigned char *) isymbuf; 1385 1386 /* Fix the opcode. */ 1387 if ((code & 0xf0) == 0x70) /* For movd. */ 1388 bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1); 1389 else if ((code & 0xf0) == 0x20) /* For addd. */ 1390 bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1); 1391 else if ((code & 0xf0) == 0x90) /* For cmpd. */ 1392 bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1); 1393 else 1394 continue; 1395 1396 bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset); 1397 1398 /* Fix the relocation's type. */ 1399 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1400 R_CR16_IMM16); 1401 1402 /* Delete two bytes of data. */ 1403 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1404 irel->r_offset + 2, 2)) 1405 goto error_return; 1406 1407 /* That will change things, so, we should relax again. 1408 Note that this is not required, and it may be slow. */ 1409 *again = TRUE; 1410 } 1411 } 1412 1413 /* Try to turn a 20/16bit immediate address into 1414 a 4bit immediate address. */ 1415 if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20) 1416 || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16)) 1417 { 1418 bfd_vma value = symval; 1419 1420 /* See if the value will fit in 4 bits. */ 1421 if ((long) value < 0xf && (long) value > 0) 1422 { 1423 unsigned short code; 1424 1425 /* Get the opcode. */ 1426 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset); 1427 1428 /* Note that we've changed the relocs, section contents, etc. */ 1429 elf_section_data (sec)->relocs = internal_relocs; 1430 elf_section_data (sec)->this_hdr.contents = contents; 1431 symtab_hdr->contents = (unsigned char *) isymbuf; 1432 1433 /* Fix the opcode. */ 1434 if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500)) 1435 { 1436 if ((code & 0x0f00) == 0x0400) /* For movd imm20. */ 1437 bfd_put_8 (abfd, 0x60, contents + irel->r_offset); 1438 else /* For addd imm20. */ 1439 bfd_put_8 (abfd, 0x54, contents + irel->r_offset); 1440 bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1); 1441 } 1442 else 1443 { 1444 if ((code & 0xfff0) == 0x56b0) /* For cmpd imm16. */ 1445 bfd_put_8 (abfd, 0x56, contents + irel->r_offset); 1446 else if ((code & 0xfff0) == 0x54b0) /* For movd imm16. */ 1447 bfd_put_8 (abfd, 0x54, contents + irel->r_offset); 1448 else if ((code & 0xfff0) == 0x58b0) /* For movb imm16. */ 1449 bfd_put_8 (abfd, 0x58, contents + irel->r_offset); 1450 else if ((code & 0xfff0) == 0x5Ab0) /* For movw imm16. */ 1451 bfd_put_8 (abfd, 0x5A, contents + irel->r_offset); 1452 else if ((code & 0xfff0) == 0x60b0) /* For addd imm16. */ 1453 bfd_put_8 (abfd, 0x60, contents + irel->r_offset); 1454 else if ((code & 0xfff0) == 0x30b0) /* For addb imm16. */ 1455 bfd_put_8 (abfd, 0x30, contents + irel->r_offset); 1456 else if ((code & 0xfff0) == 0x2Cb0) /* For addub imm16. */ 1457 bfd_put_8 (abfd, 0x2C, contents + irel->r_offset); 1458 else if ((code & 0xfff0) == 0x32b0) /* For adduw imm16. */ 1459 bfd_put_8 (abfd, 0x32, contents + irel->r_offset); 1460 else if ((code & 0xfff0) == 0x38b0) /* For subb imm16. */ 1461 bfd_put_8 (abfd, 0x38, contents + irel->r_offset); 1462 else if ((code & 0xfff0) == 0x3Ab0) /* For subw imm16. */ 1463 bfd_put_8 (abfd, 0x3A, contents + irel->r_offset); 1464 else if ((code & 0xfff0) == 0x50b0) /* For cmpb imm16. */ 1465 bfd_put_8 (abfd, 0x50, contents + irel->r_offset); 1466 else if ((code & 0xfff0) == 0x52b0) /* For cmpw imm16. */ 1467 bfd_put_8 (abfd, 0x52, contents + irel->r_offset); 1468 else 1469 continue; 1470 1471 bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1); 1472 } 1473 1474 /* Fix the relocation's type. */ 1475 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1476 R_CR16_IMM4); 1477 1478 /* Delete two bytes of data. */ 1479 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec, 1480 irel->r_offset + 2, 2)) 1481 goto error_return; 1482 1483 /* That will change things, so, we should relax again. 1484 Note that this is not required, and it may be slow. */ 1485 *again = TRUE; 1486 } 1487 } 1488 } 1489 1490 if (isymbuf != NULL 1491 && symtab_hdr->contents != (unsigned char *) isymbuf) 1492 { 1493 if (! link_info->keep_memory) 1494 free (isymbuf); 1495 else 1496 /* Cache the symbols for elf_link_input_bfd. */ 1497 symtab_hdr->contents = (unsigned char *) isymbuf; 1498 } 1499 1500 if (contents != NULL 1501 && elf_section_data (sec)->this_hdr.contents != contents) 1502 { 1503 if (! link_info->keep_memory) 1504 free (contents); 1505 else 1506 /* Cache the section contents for elf_link_input_bfd. */ 1507 elf_section_data (sec)->this_hdr.contents = contents; 1508 } 1509 1510 if (internal_relocs != NULL 1511 && elf_section_data (sec)->relocs != internal_relocs) 1512 free (internal_relocs); 1513 1514 return TRUE; 1515 1516 error_return: 1517 if (isymbuf != NULL 1518 && symtab_hdr->contents != (unsigned char *) isymbuf) 1519 free (isymbuf); 1520 if (contents != NULL 1521 && elf_section_data (sec)->this_hdr.contents != contents) 1522 free (contents); 1523 if (internal_relocs != NULL 1524 && elf_section_data (sec)->relocs != internal_relocs) 1525 free (internal_relocs); 1526 1527 return FALSE; 1528 } 1529 1530 static asection * 1531 elf32_cr16_gc_mark_hook (asection *sec, 1532 struct bfd_link_info *info ATTRIBUTE_UNUSED, 1533 Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, 1534 struct elf_link_hash_entry *h, 1535 Elf_Internal_Sym *sym) 1536 { 1537 if (h == NULL) 1538 return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 1539 1540 switch (h->root.type) 1541 { 1542 case bfd_link_hash_defined: 1543 case bfd_link_hash_defweak: 1544 return h->root.u.def.section; 1545 1546 case bfd_link_hash_common: 1547 return h->root.u.c.p->section; 1548 1549 default: 1550 return NULL; 1551 } 1552 } 1553 1554 /* Update the got entry reference counts for the section being removed. */ 1555 1556 static bfd_boolean 1557 elf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, 1558 struct bfd_link_info *info ATTRIBUTE_UNUSED, 1559 asection *sec ATTRIBUTE_UNUSED, 1560 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) 1561 { 1562 /* We don't support garbage collection of GOT and PLT relocs yet. */ 1563 return TRUE; 1564 } 1565 1566 /* Definitions for setting CR16 target vector. */ 1567 #define TARGET_LITTLE_SYM bfd_elf32_cr16_vec 1568 #define TARGET_LITTLE_NAME "elf32-cr16" 1569 #define ELF_ARCH bfd_arch_cr16 1570 #define ELF_MACHINE_CODE EM_CR16 1571 #define ELF_MACHINE_ALT1 EM_CR16_OLD 1572 #define ELF_MAXPAGESIZE 0x1 1573 #define elf_symbol_leading_char '_' 1574 1575 #define bfd_elf32_bfd_reloc_type_lookup elf_cr16_reloc_type_lookup 1576 #define bfd_elf32_bfd_reloc_name_lookup elf_cr16_reloc_name_lookup 1577 #define elf_info_to_howto elf_cr16_info_to_howto 1578 #define elf_info_to_howto_rel 0 1579 #define elf_backend_relocate_section elf32_cr16_relocate_section 1580 #define bfd_elf32_bfd_relax_section elf32_cr16_relax_section 1581 #define bfd_elf32_bfd_get_relocated_section_contents \ 1582 elf32_cr16_get_relocated_section_contents 1583 #define elf_backend_gc_mark_hook elf32_cr16_gc_mark_hook 1584 #define elf_backend_gc_sweep_hook elf32_cr16_gc_sweep_hook 1585 #define elf_backend_can_gc_sections 1 1586 #define elf_backend_rela_normal 1 1587 1588 #include "elf32-target.h" 1589