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