1 /* Freescale XGATE-specific support for 32-bit ELF 2 Copyright (C) 2010-2018 Free Software Foundation, Inc. 3 Contributed by Sean Keys(skeys@ipdatasys.com) 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 "elf32-xgate.h" 28 #include "elf/xgate.h" 29 #include "opcode/xgate.h" 30 #include "libiberty.h" 31 32 /* Relocation functions. */ 33 static reloc_howto_type * 34 bfd_elf32_bfd_reloc_type_lookup (bfd *, bfd_reloc_code_real_type); 35 static reloc_howto_type * 36 bfd_elf32_bfd_reloc_name_lookup (bfd *, const char *); 37 static bfd_boolean 38 xgate_info_to_howto_rel (bfd *, arelent *, Elf_Internal_Rela *); 39 static bfd_boolean 40 xgate_elf_set_mach_from_flags (bfd *); 41 static struct bfd_hash_entry * 42 stub_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, 43 const char *); 44 static struct bfd_link_hash_table* 45 xgate_elf_bfd_link_hash_table_create (bfd *); 46 47 /* Use REL instead of RELA to save space */ 48 #define USE_REL 1 49 50 static reloc_howto_type elf_xgate_howto_table[] = 51 { 52 /* This reloc does nothing. */ 53 HOWTO (R_XGATE_NONE, /* type */ 54 0, /* rightshift */ 55 3, /* size (0 = byte, 1 = short, 2 = long) */ 56 0, /* bitsize */ 57 FALSE, /* pc_relative */ 58 0, /* bitpos */ 59 complain_overflow_dont,/* complain_on_overflow */ 60 bfd_elf_generic_reloc, /* special_function */ 61 "R_XGATE_NONE", /* name */ 62 FALSE, /* partial_inplace */ 63 0, /* src_mask */ 64 0, /* dst_mask */ 65 FALSE), /* pcrel_offset */ 66 67 /* A 8 bit absolute relocation. */ 68 HOWTO (R_XGATE_8, /* type */ 69 0, /* rightshift */ 70 0, /* size (0 = byte, 1 = short, 2 = long) */ 71 8, /* bitsize */ 72 FALSE, /* pc_relative */ 73 0, /* bitpos */ 74 complain_overflow_bitfield, /* complain_on_overflow */ 75 bfd_elf_generic_reloc, /* special_function */ 76 "R_XGATE_8", /* name */ 77 FALSE, /* partial_inplace */ 78 0x00ff, /* src_mask */ 79 0x00ff, /* dst_mask */ 80 FALSE), /* pcrel_offset */ 81 82 /* A 8 bit PC-rel relocation. */ 83 HOWTO (R_XGATE_PCREL_8, /* type */ 84 0, /* rightshift */ 85 0, /* size (0 = byte, 1 = short, 2 = long) */ 86 8, /* bitsize */ 87 TRUE, /* pc_relative */ 88 0, /* bitpos */ 89 complain_overflow_bitfield, /* complain_on_overflow */ 90 bfd_elf_generic_reloc, /* special_function */ 91 "R_XGATE_PCREL_8", /* name */ 92 FALSE, /* partial_inplace */ 93 0x00ff, /* src_mask */ 94 0x00ff, /* dst_mask */ 95 TRUE), /* pcrel_offset */ 96 97 /* A 16 bit absolute relocation. */ 98 HOWTO (R_XGATE_16, /* type */ 99 0, /* rightshift */ 100 1, /* size (0 = byte, 1 = short, 2 = long) */ 101 16, /* bitsize */ 102 FALSE, /* pc_relative */ 103 0, /* bitpos */ 104 complain_overflow_dont /*bitfield */, /* complain_on_overflow */ 105 bfd_elf_generic_reloc, /* special_function */ 106 "R_XGATE_16", /* name */ 107 FALSE, /* partial_inplace */ 108 0xffff, /* src_mask */ 109 0xffff, /* dst_mask */ 110 FALSE), /* pcrel_offset */ 111 112 /* A 32 bit absolute relocation. This one is never used for the 113 code relocation. It's used by gas for -gstabs generation. */ 114 HOWTO (R_XGATE_32, /* type */ 115 0, /* rightshift */ 116 2, /* size (0 = byte, 1 = short, 2 = long) */ 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_XGATE_32", /* name */ 123 FALSE, /* partial_inplace */ 124 0xffffffff, /* src_mask */ 125 0xffffffff, /* dst_mask */ 126 FALSE), /* pcrel_offset */ 127 128 /* A 16 bit PC-rel relocation. */ 129 HOWTO (R_XGATE_PCREL_16, /* type */ 130 0, /* rightshift */ 131 1, /* size (0 = byte, 1 = short, 2 = long) */ 132 16, /* bitsize */ 133 TRUE, /* pc_relative */ 134 0, /* bitpos */ 135 complain_overflow_dont, /* complain_on_overflow */ 136 bfd_elf_generic_reloc, /* special_function */ 137 "R_XGATE_PCREL_16", /* name */ 138 FALSE, /* partial_inplace */ 139 0xffff, /* src_mask */ 140 0xffff, /* dst_mask */ 141 TRUE), /* pcrel_offset */ 142 143 /* GNU extension to record C++ vtable hierarchy. */ 144 HOWTO (R_XGATE_GNU_VTINHERIT, /* type */ 145 0, /* rightshift */ 146 1, /* size (0 = byte, 1 = short, 2 = long) */ 147 0, /* bitsize */ 148 FALSE, /* pc_relative */ 149 0, /* bitpos */ 150 complain_overflow_dont, /* complain_on_overflow */ 151 NULL, /* special_function */ 152 "R_XGATE_GNU_VTINHERIT", /* name */ 153 FALSE, /* partial_inplace */ 154 0, /* src_mask */ 155 0, /* dst_mask */ 156 FALSE), /* pcrel_offset */ 157 158 /* GNU extension to record C++ vtable member usage. */ 159 HOWTO (R_XGATE_GNU_VTENTRY, /* type */ 160 0, /* rightshift */ 161 1, /* size (0 = byte, 1 = short, 2 = long) */ 162 0, /* bitsize */ 163 FALSE, /* pc_relative */ 164 0, /* bitpos */ 165 complain_overflow_dont, /* complain_on_overflow */ 166 _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 167 "R_XGATE_GNU_VTENTRY", /* name */ 168 FALSE, /* partial_inplace */ 169 0, /* src_mask */ 170 0, /* dst_mask */ 171 FALSE), /* pcrel_offset */ 172 173 /* A 24 bit relocation. */ 174 HOWTO (R_XGATE_24, /* type */ 175 0, /* rightshift */ 176 1, /* size (0 = byte, 1 = short, 2 = long) */ 177 16, /* bitsize */ 178 FALSE, /* pc_relative */ 179 0, /* bitpos */ 180 complain_overflow_dont, /* complain_on_overflow */ 181 bfd_elf_generic_reloc, /* special_function */ 182 "R_XGATE_IMM8_LO", /* name */ 183 FALSE, /* partial_inplace */ 184 0x00ff, /* src_mask */ 185 0x00ff, /* dst_mask */ 186 FALSE), /* pcrel_offset */ 187 188 /* A 16-bit low relocation. */ 189 HOWTO (R_XGATE_LO16, /* type */ 190 8, /* rightshift */ 191 1, /* size (0 = byte, 1 = short, 2 = long) */ 192 16, /* bitsize */ 193 FALSE, /* pc_relative */ 194 0, /* bitpos */ 195 complain_overflow_dont, /* complain_on_overflow */ 196 bfd_elf_generic_reloc, /* special_function */ 197 "R_XGATE_IMM8_HI", /* name */ 198 FALSE, /* partial_inplace */ 199 0x00ff, /* src_mask */ 200 0x00ff, /* dst_mask */ 201 FALSE), /* pcrel_offset */ 202 203 /* A page relocation. */ 204 HOWTO (R_XGATE_GPAGE, /* type */ 205 0, /* rightshift */ 206 0, /* size (0 = byte, 1 = short, 2 = long) */ 207 8, /* bitsize */ 208 FALSE, /* pc_relative */ 209 0, /* bitpos */ 210 complain_overflow_dont, /* complain_on_overflow */ 211 xgate_elf_special_reloc,/* special_function */ 212 "R_XGATE_GPAGE", /* name */ 213 FALSE, /* partial_inplace */ 214 0x00ff, /* src_mask */ 215 0x00ff, /* dst_mask */ 216 FALSE), /* pcrel_offset */ 217 218 /* A 9 bit absolute relocation. */ 219 HOWTO (R_XGATE_PCREL_9, /* type */ 220 0, /* rightshift */ 221 1, /* size (0 = byte, 1 = short, 2 = long) */ 222 9, /* bitsize */ 223 TRUE, /* pc_relative */ 224 0, /* bitpos */ 225 complain_overflow_bitfield, /* complain_on_overflow */ 226 bfd_elf_generic_reloc, /* special_function */ 227 "R_XGATE_PCREL_9", /* name */ 228 FALSE, /* partial_inplace */ 229 0xffff, /* src_mask */ 230 0xffff, /* dst_mask */ 231 TRUE), /* pcrel_offset */ 232 233 /* A 8 bit absolute relocation (upper address). */ 234 HOWTO (R_XGATE_PCREL_10, /* type */ 235 8, /* rightshift */ 236 0, /* size (0 = byte, 1 = short, 2 = long) */ 237 10, /* bitsize */ 238 TRUE, /* pc_relative */ 239 0, /* bitpos */ 240 complain_overflow_dont, /* complain_on_overflow */ 241 bfd_elf_generic_reloc, /* special_function */ 242 "R_XGATE_PCREL_10", /* name */ 243 FALSE, /* partial_inplace */ 244 0x00ff, /* src_mask */ 245 0x00ff, /* dst_mask */ 246 TRUE), /* pcrel_offset */ 247 248 /* A 8 bit absolute relocation. */ 249 HOWTO (R_XGATE_IMM8_LO, /* type */ 250 0, /* rightshift */ 251 1, /* size (0 = byte, 1 = short, 2 = long) */ 252 16, /* bitsize */ 253 FALSE, /* pc_relative */ 254 0, /* bitpos */ 255 complain_overflow_dont, /* complain_on_overflow */ 256 bfd_elf_generic_reloc, /* special_function */ 257 "R_XGATE_IMM8_LO", /* name */ 258 FALSE, /* partial_inplace */ 259 0xffff, /* src_mask */ 260 0xffff, /* dst_mask */ 261 FALSE), /* pcrel_offset */ 262 263 /* A 16 bit absolute relocation (upper address). */ 264 HOWTO (R_XGATE_IMM8_HI, /* type */ 265 8, /* rightshift */ 266 1, /* size (0 = byte, 1 = short, 2 = long) */ 267 16, /* bitsize */ 268 FALSE, /* pc_relative */ 269 0, /* bitpos */ 270 complain_overflow_dont, /* complain_on_overflow */ 271 bfd_elf_generic_reloc, /* special_function */ 272 "R_XGATE_IMM8_HI", /* name */ 273 FALSE, /* partial_inplace */ 274 0x00ff, /* src_mask */ 275 0x00ff, /* dst_mask */ 276 FALSE), /* pcrel_offset */ 277 278 /* A 3 bit absolute relocation. */ 279 HOWTO (R_XGATE_IMM3, /* type */ 280 8, /* rightshift */ 281 1, /* size (0 = byte, 1 = short, 2 = long) */ 282 16, /* bitsize */ 283 FALSE, /* pc_relative */ 284 0, /* bitpos */ 285 complain_overflow_dont, /* complain_on_overflow */ 286 bfd_elf_generic_reloc, /* special_function */ 287 "R_XGATE_IMM3", /* name */ 288 FALSE, /* partial_inplace */ 289 0x00ff, /* src_mask */ 290 0x00ff, /* dst_mask */ 291 FALSE), /* pcrel_offset */ 292 293 /* A 4 bit absolute relocation. */ 294 HOWTO (R_XGATE_IMM4, /* type */ 295 8, /* rightshift */ 296 1, /* size (0 = byte, 1 = short, 2 = long) */ 297 16, /* bitsize */ 298 FALSE, /* pc_relative */ 299 0, /* bitpos */ 300 complain_overflow_dont, /* complain_on_overflow */ 301 bfd_elf_generic_reloc, /* special_function */ 302 "R_XGATE_IMM4", /* name */ 303 FALSE, /* partial_inplace */ 304 0x00ff, /* src_mask */ 305 0x00ff, /* dst_mask */ 306 FALSE), /* pcrel_offset */ 307 308 /* A 5 bit absolute relocation. */ 309 HOWTO (R_XGATE_IMM5, /* type */ 310 8, /* rightshift */ 311 1, /* size (0 = byte, 1 = short, 2 = long) */ 312 16, /* bitsize */ 313 FALSE, /* pc_relative */ 314 0, /* bitpos */ 315 complain_overflow_dont, /* complain_on_overflow */ 316 bfd_elf_generic_reloc, /* special_function */ 317 "R_XGATE_IMM5", /* name */ 318 FALSE, /* partial_inplace */ 319 0x00ff, /* src_mask */ 320 0x00ff, /* dst_mask */ 321 FALSE), /* pcrel_offset */ 322 323 /* Mark beginning of a jump instruction (any form). */ 324 HOWTO (R_XGATE_RL_JUMP, /* type */ 325 0, /* rightshift */ 326 1, /* size (0 = byte, 1 = short, 2 = long) */ 327 0, /* bitsize */ 328 FALSE, /* pc_relative */ 329 0, /* bitpos */ 330 complain_overflow_dont, /* complain_on_overflow */ 331 xgate_elf_ignore_reloc, /* special_function */ 332 "R_XGATE_RL_JUMP", /* name */ 333 TRUE, /* partial_inplace */ 334 0, /* src_mask */ 335 0, /* dst_mask */ 336 TRUE), /* pcrel_offset */ 337 338 /* Mark beginning of Gcc relaxation group instruction. */ 339 HOWTO (R_XGATE_RL_GROUP, /* type */ 340 0, /* rightshift */ 341 1, /* size (0 = byte, 1 = short, 2 = long) */ 342 0, /* bitsize */ 343 FALSE, /* pc_relative */ 344 0, /* bitpos */ 345 complain_overflow_dont, /* complain_on_overflow */ 346 xgate_elf_ignore_reloc, /* special_function */ 347 "R_XGATE_RL_GROUP", /* name */ 348 TRUE, /* partial_inplace */ 349 0, /* src_mask */ 350 0, /* dst_mask */ 351 TRUE), /* pcrel_offset */ 352 }; 353 354 /* Map BFD reloc types to XGATE ELF reloc types. */ 355 356 struct xgate_reloc_map 357 { 358 bfd_reloc_code_real_type bfd_reloc_val; 359 unsigned char elf_reloc_val; 360 }; 361 362 static const struct xgate_reloc_map xgate_reloc_map[] = 363 { 364 {BFD_RELOC_NONE, R_XGATE_NONE}, 365 {BFD_RELOC_8, R_XGATE_8}, 366 {BFD_RELOC_8_PCREL, R_XGATE_PCREL_8}, 367 {BFD_RELOC_16_PCREL, R_XGATE_PCREL_16}, 368 {BFD_RELOC_16, R_XGATE_16}, 369 {BFD_RELOC_32, R_XGATE_32}, 370 371 {BFD_RELOC_VTABLE_INHERIT, R_XGATE_GNU_VTINHERIT}, 372 {BFD_RELOC_VTABLE_ENTRY, R_XGATE_GNU_VTENTRY}, 373 374 {BFD_RELOC_XGATE_LO16, R_XGATE_LO16}, 375 {BFD_RELOC_XGATE_GPAGE, R_XGATE_GPAGE}, 376 {BFD_RELOC_XGATE_24, R_XGATE_24}, 377 {BFD_RELOC_XGATE_PCREL_9, R_XGATE_PCREL_9}, 378 {BFD_RELOC_XGATE_PCREL_10, R_XGATE_PCREL_10}, 379 {BFD_RELOC_XGATE_IMM8_LO, R_XGATE_IMM8_LO}, 380 {BFD_RELOC_XGATE_IMM8_HI, R_XGATE_IMM8_HI}, 381 {BFD_RELOC_XGATE_IMM3, R_XGATE_IMM3}, 382 {BFD_RELOC_XGATE_IMM4, R_XGATE_IMM4}, 383 {BFD_RELOC_XGATE_IMM5, R_XGATE_IMM5}, 384 385 {BFD_RELOC_XGATE_RL_JUMP, R_XGATE_RL_JUMP}, 386 {BFD_RELOC_XGATE_RL_GROUP, R_XGATE_RL_GROUP}, 387 }; 388 389 static reloc_howto_type * 390 bfd_elf32_bfd_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 < ARRAY_SIZE (xgate_reloc_map); i++) 396 if (xgate_reloc_map[i].bfd_reloc_val == code) 397 return &elf_xgate_howto_table[xgate_reloc_map[i].elf_reloc_val]; 398 399 return NULL; 400 } 401 402 static reloc_howto_type * 403 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 404 { 405 unsigned int i; 406 407 for (i = 0; i < ARRAY_SIZE (elf_xgate_howto_table); i++) 408 if (elf_xgate_howto_table[i].name != NULL 409 && strcasecmp (elf_xgate_howto_table[i].name, r_name) == 0) 410 return &elf_xgate_howto_table[i]; 411 412 return NULL; 413 } 414 415 /* Set the howto pointer for an XGATE ELF reloc. */ 416 417 static bfd_boolean 418 xgate_info_to_howto_rel (bfd *abfd, 419 arelent *cache_ptr, 420 Elf_Internal_Rela *dst) 421 { 422 unsigned int r_type; 423 424 r_type = ELF32_R_TYPE (dst->r_info); 425 if (r_type >= (unsigned int) R_XGATE_max) 426 { 427 /* xgettext:c-format */ 428 _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 429 abfd, r_type); 430 bfd_set_error (bfd_error_bad_value); 431 return FALSE; 432 } 433 cache_ptr->howto = &elf_xgate_howto_table[r_type]; 434 return TRUE; 435 } 436 437 /* Destroy an XGATE ELF linker hash table. */ 438 439 static void 440 xgate_elf_bfd_link_hash_table_free (bfd *obfd) 441 { 442 struct xgate_elf_link_hash_table *ret = 443 (struct xgate_elf_link_hash_table *) obfd->link.hash; 444 445 bfd_hash_table_free (ret->stub_hash_table); 446 free (ret->stub_hash_table); 447 _bfd_elf_link_hash_table_free (obfd); 448 } 449 450 /* Create an XGATE ELF linker hash table. */ 451 452 static struct bfd_link_hash_table* 453 xgate_elf_bfd_link_hash_table_create (bfd *abfd) 454 { 455 struct xgate_elf_link_hash_table *ret; 456 bfd_size_type amt = sizeof(struct xgate_elf_link_hash_table); 457 458 ret = (struct xgate_elf_link_hash_table *) bfd_zmalloc (amt); 459 if (ret == (struct xgate_elf_link_hash_table *) NULL) 460 return NULL; 461 462 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, 463 _bfd_elf_link_hash_newfunc, sizeof(struct elf_link_hash_entry), 464 XGATE_ELF_DATA)) 465 { 466 free (ret); 467 return NULL; 468 } 469 470 /* Init the stub hash table too. */ 471 amt = sizeof(struct bfd_hash_table); 472 ret->stub_hash_table = (struct bfd_hash_table*) bfd_zmalloc (amt); 473 if (ret->stub_hash_table == NULL) 474 { 475 _bfd_elf_link_hash_table_free (abfd); 476 return NULL; 477 } 478 479 if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc, 480 sizeof(struct elf32_xgate_stub_hash_entry))) 481 { 482 free (ret->stub_hash_table); 483 _bfd_elf_link_hash_table_free (abfd); 484 return NULL; 485 } 486 ret->root.root.hash_table_free = xgate_elf_bfd_link_hash_table_free; 487 488 return &ret->root.root; 489 } 490 491 static bfd_boolean 492 xgate_elf_set_mach_from_flags (bfd *abfd ATTRIBUTE_UNUSED) 493 { 494 return TRUE; 495 } 496 497 /* Specific sections: 498 - The .page0 is a data section that is mapped in [0x0000..0x00FF]. 499 Page0 accesses are faster on the M68HC12. 500 - The .vectors is the section that represents the interrupt 501 vectors. 502 - The .xgate section is starts in 0xE08800 or as xgate sees it 0x0800. */ 503 static const struct bfd_elf_special_section elf32_xgate_special_sections[] = 504 { 505 { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 506 { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 507 { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 508 { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC }, 509 /*{ STRING_COMMA_LEN (".xgate"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 510 TODO finish this implementation */ 511 { NULL, 0, 0, 0, 0 } 512 }; 513 514 struct xgate_scan_param 515 { 516 struct xgate_page_info* pinfo; 517 bfd_boolean use_memory_banks; 518 }; 519 520 /* Assorted hash table functions. */ 521 522 /* Initialize an entry in the stub hash table. */ 523 524 static struct bfd_hash_entry * 525 stub_hash_newfunc (struct bfd_hash_entry *entry, 526 struct bfd_hash_table *table ATTRIBUTE_UNUSED, 527 const char *string ATTRIBUTE_UNUSED) 528 { 529 return entry; 530 } 531 532 /* Hook called by the linker routine which adds symbols from an object 533 file. */ 534 535 bfd_boolean 536 elf32_xgate_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED, 537 struct bfd_link_info *info ATTRIBUTE_UNUSED, 538 Elf_Internal_Sym *sym, 539 const char **namep ATTRIBUTE_UNUSED, 540 flagword *flagsp ATTRIBUTE_UNUSED, 541 asection **secp ATTRIBUTE_UNUSED, 542 bfd_vma *valp ATTRIBUTE_UNUSED) 543 { 544 /* For some reason the st_target_internal value is not retained 545 after xgate_frob_symbol is called, hence this temp hack. */ 546 sym->st_target_internal = 1; 547 return TRUE; 548 } 549 550 /* External entry points for sizing and building linker stubs. */ 551 552 /* Set up various things so that we can make a list of input sections 553 for each output section included in the link. Returns -1 on error, 554 0 when no stubs will be needed, and 1 on success. */ 555 556 int 557 elf32_xgate_setup_section_lists (bfd *output_bfd ATTRIBUTE_UNUSED, 558 struct bfd_link_info *info ATTRIBUTE_UNUSED) 559 { 560 return 1; 561 } 562 563 /* Determine and set the size of the stub section for a final link. 564 The basic idea here is to examine all the relocations looking for 565 PC-relative calls to a target that is unreachable with any "9-bit PC-REL" 566 instruction. */ 567 568 bfd_boolean 569 elf32_xgate_size_stubs (bfd *output_bfd ATTRIBUTE_UNUSED, 570 bfd *stub_bfd ATTRIBUTE_UNUSED, 571 struct bfd_link_info *info ATTRIBUTE_UNUSED, 572 asection * (*add_stub_section) (const char*, asection*) ATTRIBUTE_UNUSED) 573 { 574 return FALSE; 575 } 576 577 /* Build all the stubs associated with the current output file. The 578 stubs are kept in a hash table attached to the main linker hash 579 table. This function is called via xgateelf_finish in the 580 linker. */ 581 582 bfd_boolean 583 elf32_xgate_build_stubs (bfd *abfd ATTRIBUTE_UNUSED, 584 struct bfd_link_info *info ATTRIBUTE_UNUSED) 585 { 586 return TRUE; 587 } 588 589 void 590 xgate_elf_get_bank_parameters (struct bfd_link_info *info ATTRIBUTE_UNUSED) 591 { 592 return; 593 } 594 595 /* This function is used for relocs which are only used for relaxing, 596 which the linker should otherwise ignore. */ 597 598 bfd_reloc_status_type 599 xgate_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, 600 arelent *reloc_entry, 601 asymbol *symbol ATTRIBUTE_UNUSED, 602 void *data ATTRIBUTE_UNUSED, 603 asection *input_section, 604 bfd *output_bfd, 605 char **error_message ATTRIBUTE_UNUSED) 606 { 607 if (output_bfd != NULL) 608 reloc_entry->address += input_section->output_offset; 609 return bfd_reloc_ok; 610 } 611 612 bfd_reloc_status_type 613 xgate_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED, 614 arelent *reloc_entry ATTRIBUTE_UNUSED, 615 asymbol *symbol ATTRIBUTE_UNUSED, 616 void *data ATTRIBUTE_UNUSED, 617 asection *input_section ATTRIBUTE_UNUSED, 618 bfd *output_bfd ATTRIBUTE_UNUSED, 619 char **error_message ATTRIBUTE_UNUSED) 620 { 621 abort (); 622 } 623 624 /* Look through the relocs for a section during the first phase. 625 Since we don't do .gots or .plts, we just need to consider the 626 virtual table relocs for gc. */ 627 628 bfd_boolean 629 elf32_xgate_check_relocs (bfd *abfd ATTRIBUTE_UNUSED, 630 struct bfd_link_info *info ATTRIBUTE_UNUSED, 631 asection *sec ATTRIBUTE_UNUSED, 632 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) 633 { 634 return TRUE; 635 } 636 637 /* Relocate a XGATE/S12x ELF section. */ 638 639 bfd_boolean 640 elf32_xgate_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 641 struct bfd_link_info *info ATTRIBUTE_UNUSED, 642 bfd *input_bfd ATTRIBUTE_UNUSED, 643 asection *input_section ATTRIBUTE_UNUSED, 644 bfd_byte *contents ATTRIBUTE_UNUSED, 645 Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED, 646 Elf_Internal_Sym *local_syms ATTRIBUTE_UNUSED, 647 asection **local_sections ATTRIBUTE_UNUSED) 648 { 649 return TRUE; 650 } 651 652 /* Set and control ELF flags in ELF header. */ 653 654 bfd_boolean 655 _bfd_xgate_elf_set_private_flags (bfd *abfd ATTRIBUTE_UNUSED, 656 flagword flags ATTRIBUTE_UNUSED) 657 { 658 return TRUE; 659 } 660 661 bfd_boolean 662 _bfd_xgate_elf_print_private_bfd_data (bfd *abfd, void *ptr) 663 { 664 FILE *file = (FILE *) ptr; 665 666 BFD_ASSERT (abfd != NULL && ptr != NULL); 667 668 /* Print normal ELF private data. */ 669 _bfd_elf_print_private_bfd_data (abfd, ptr); 670 671 /* xgettext:c-format */ 672 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); 673 674 if (elf_elfheader (abfd)->e_flags & E_XGATE_I32) 675 fprintf (file, _("[abi=32-bit int, ")); 676 else 677 fprintf (file, _("[abi=16-bit int, ")); 678 679 if (elf_elfheader (abfd)->e_flags & E_XGATE_F64) 680 fprintf (file, _("64-bit double, ")); 681 else 682 fprintf (file, _("32-bit double, ")); 683 if (elf_elfheader (abfd)->e_flags & EF_XGATE_MACH) 684 fprintf (file, _("cpu=XGATE]")); 685 else 686 fprintf (file, _("error reading cpu type from elf private data")); 687 fputc ('\n', file); 688 689 return TRUE; 690 } 691 692 void 693 elf32_xgate_post_process_headers (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED) 694 { 695 696 } 697 698 #define ELF_ARCH bfd_arch_xgate 699 #define ELF_MACHINE_CODE EM_XGATE 700 #define ELF_TARGET_ID XGATE_ELF_DATA 701 702 #define ELF_MAXPAGESIZE 0x1000 703 704 #define TARGET_BIG_SYM xgate_elf32_vec 705 #define TARGET_BIG_NAME "elf32-xgate" 706 707 #define elf_info_to_howto NULL 708 #define elf_info_to_howto_rel xgate_info_to_howto_rel 709 #define elf_backend_check_relocs elf32_xgate_check_relocs 710 #define elf_backend_relocate_section elf32_xgate_relocate_section 711 #define elf_backend_object_p xgate_elf_set_mach_from_flags 712 #define elf_backend_final_write_processing NULL 713 #define elf_backend_can_gc_sections 1 714 #define elf_backend_special_sections elf32_xgate_special_sections 715 #define elf_backend_post_process_headers elf32_xgate_post_process_headers 716 #define elf_backend_add_symbol_hook elf32_xgate_add_symbol_hook 717 718 #define bfd_elf32_bfd_link_hash_table_create xgate_elf_bfd_link_hash_table_create 719 #define bfd_elf32_bfd_set_private_flags _bfd_xgate_elf_set_private_flags 720 #define bfd_elf32_bfd_print_private_bfd_data _bfd_xgate_elf_print_private_bfd_data 721 722 #define xgate_stub_hash_lookup(table, string, create, copy) \ 723 ((struct elf32_xgate_stub_hash_entry *) \ 724 bfd_hash_lookup ((table), (string), (create), (copy))) 725 726 #include "elf32-target.h" 727