1 /* Freescale XGATE-specific support for 32-bit ELF 2 Copyright (C) 2010-2014 Free Software Foundation, Inc. 3 Contributed by Sean Keys(skeys (at) 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 void 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 2, /* size (0 = byte, 1 = short, 2 = long) */ 56 32, /* 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 void 418 xgate_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, 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 BFD_ASSERT(r_type < (unsigned int) R_XGATE_max); 426 cache_ptr->howto = &elf_xgate_howto_table[r_type]; 427 } 428 429 /* Destroy an XGATE ELF linker hash table. */ 430 431 static void 432 xgate_elf_bfd_link_hash_table_free (bfd *obfd) 433 { 434 struct xgate_elf_link_hash_table *ret = 435 (struct xgate_elf_link_hash_table *) obfd->link.hash; 436 437 bfd_hash_table_free (ret->stub_hash_table); 438 free (ret->stub_hash_table); 439 _bfd_elf_link_hash_table_free (obfd); 440 } 441 442 /* Create an XGATE ELF linker hash table. */ 443 444 static struct bfd_link_hash_table* 445 xgate_elf_bfd_link_hash_table_create (bfd *abfd) 446 { 447 struct xgate_elf_link_hash_table *ret; 448 bfd_size_type amt = sizeof(struct xgate_elf_link_hash_table); 449 450 ret = (struct xgate_elf_link_hash_table *) bfd_zmalloc (amt); 451 if (ret == (struct xgate_elf_link_hash_table *) NULL) 452 return NULL; 453 454 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, 455 _bfd_elf_link_hash_newfunc, sizeof(struct elf_link_hash_entry), 456 XGATE_ELF_DATA)) 457 { 458 free (ret); 459 return NULL; 460 } 461 462 /* Init the stub hash table too. */ 463 amt = sizeof(struct bfd_hash_table); 464 ret->stub_hash_table = (struct bfd_hash_table*) bfd_zmalloc (amt); 465 if (ret->stub_hash_table == NULL) 466 { 467 _bfd_elf_link_hash_table_free (abfd); 468 return NULL; 469 } 470 471 if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc, 472 sizeof(struct elf32_xgate_stub_hash_entry))) 473 { 474 free (ret->stub_hash_table); 475 _bfd_elf_link_hash_table_free (abfd); 476 return NULL; 477 } 478 ret->root.root.hash_table_free = xgate_elf_bfd_link_hash_table_free; 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 xgate_elf32_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_merge_private_bfd_data _bfd_xgate_elf_merge_private_bfd_data 722 #define bfd_elf32_bfd_set_private_flags _bfd_xgate_elf_set_private_flags 723 #define bfd_elf32_bfd_print_private_bfd_data _bfd_xgate_elf_print_private_bfd_data 724 725 #define xgate_stub_hash_lookup(table, string, create, copy) \ 726 ((struct elf32_xgate_stub_hash_entry *) \ 727 bfd_hash_lookup ((table), (string), (create), (copy))) 728 729 #include "elf32-target.h" 730