1/* Freescale XGATE-specific support for 32-bit ELF 2 Copyright (C) 2010-2017 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. */ 33static reloc_howto_type * 34bfd_elf32_bfd_reloc_type_lookup (bfd *, bfd_reloc_code_real_type); 35static reloc_howto_type * 36bfd_elf32_bfd_reloc_name_lookup (bfd *, const char *); 37static void 38xgate_info_to_howto_rel (bfd *, arelent *, Elf_Internal_Rela *); 39static bfd_boolean 40xgate_elf_set_mach_from_flags (bfd *); 41static struct bfd_hash_entry * 42stub_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, 43 const char *); 44static struct bfd_link_hash_table* 45xgate_elf_bfd_link_hash_table_create (bfd *); 46 47/* Use REL instead of RELA to save space */ 48#define USE_REL 1 49 50static 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 356struct xgate_reloc_map 357{ 358 bfd_reloc_code_real_type bfd_reloc_val; 359 unsigned char elf_reloc_val; 360}; 361 362static 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 389static reloc_howto_type * 390bfd_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 402static reloc_howto_type * 403bfd_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 417static void 418xgate_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 if (r_type >= (unsigned int) R_XGATE_max) 426 { 427 /* xgettext:c-format */ 428 _bfd_error_handler (_("%B: invalid XGate reloc number: %d"), abfd, r_type); 429 r_type = 0; 430 } 431 cache_ptr->howto = &elf_xgate_howto_table[r_type]; 432} 433 434/* Destroy an XGATE ELF linker hash table. */ 435 436static void 437xgate_elf_bfd_link_hash_table_free (bfd *obfd) 438{ 439 struct xgate_elf_link_hash_table *ret = 440 (struct xgate_elf_link_hash_table *) obfd->link.hash; 441 442 bfd_hash_table_free (ret->stub_hash_table); 443 free (ret->stub_hash_table); 444 _bfd_elf_link_hash_table_free (obfd); 445} 446 447/* Create an XGATE ELF linker hash table. */ 448 449static struct bfd_link_hash_table* 450xgate_elf_bfd_link_hash_table_create (bfd *abfd) 451{ 452 struct xgate_elf_link_hash_table *ret; 453 bfd_size_type amt = sizeof(struct xgate_elf_link_hash_table); 454 455 ret = (struct xgate_elf_link_hash_table *) bfd_zmalloc (amt); 456 if (ret == (struct xgate_elf_link_hash_table *) NULL) 457 return NULL; 458 459 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, 460 _bfd_elf_link_hash_newfunc, sizeof(struct elf_link_hash_entry), 461 XGATE_ELF_DATA)) 462 { 463 free (ret); 464 return NULL; 465 } 466 467 /* Init the stub hash table too. */ 468 amt = sizeof(struct bfd_hash_table); 469 ret->stub_hash_table = (struct bfd_hash_table*) bfd_zmalloc (amt); 470 if (ret->stub_hash_table == NULL) 471 { 472 _bfd_elf_link_hash_table_free (abfd); 473 return NULL; 474 } 475 476 if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc, 477 sizeof(struct elf32_xgate_stub_hash_entry))) 478 { 479 free (ret->stub_hash_table); 480 _bfd_elf_link_hash_table_free (abfd); 481 return NULL; 482 } 483 ret->root.root.hash_table_free = xgate_elf_bfd_link_hash_table_free; 484 485 return &ret->root.root; 486} 487 488static bfd_boolean 489xgate_elf_set_mach_from_flags (bfd *abfd ATTRIBUTE_UNUSED) 490{ 491 return TRUE; 492} 493 494/* Specific sections: 495 - The .page0 is a data section that is mapped in [0x0000..0x00FF]. 496 Page0 accesses are faster on the M68HC12. 497 - The .vectors is the section that represents the interrupt 498 vectors. 499 - The .xgate section is starts in 0xE08800 or as xgate sees it 0x0800. */ 500static const struct bfd_elf_special_section elf32_xgate_special_sections[] = 501{ 502 { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 503 { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 504 { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 505 { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC }, 506/*{ STRING_COMMA_LEN (".xgate"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 507 TODO finish this implementation */ 508 { NULL, 0, 0, 0, 0 } 509}; 510 511struct xgate_scan_param 512{ 513 struct xgate_page_info* pinfo; 514 bfd_boolean use_memory_banks; 515}; 516 517/* Assorted hash table functions. */ 518 519/* Initialize an entry in the stub hash table. */ 520 521static struct bfd_hash_entry * 522stub_hash_newfunc (struct bfd_hash_entry *entry, 523 struct bfd_hash_table *table ATTRIBUTE_UNUSED, 524 const char *string ATTRIBUTE_UNUSED) 525{ 526 return entry; 527} 528 529/* Hook called by the linker routine which adds symbols from an object 530 file. */ 531 532bfd_boolean 533elf32_xgate_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED, 534 struct bfd_link_info *info ATTRIBUTE_UNUSED, 535 Elf_Internal_Sym *sym, 536 const char **namep ATTRIBUTE_UNUSED, 537 flagword *flagsp ATTRIBUTE_UNUSED, 538 asection **secp ATTRIBUTE_UNUSED, 539 bfd_vma *valp ATTRIBUTE_UNUSED) 540{ 541 /* For some reason the st_target_internal value is not retained 542 after xgate_frob_symbol is called, hence this temp hack. */ 543 sym->st_target_internal = 1; 544 return TRUE; 545} 546 547/* External entry points for sizing and building linker stubs. */ 548 549/* Set up various things so that we can make a list of input sections 550 for each output section included in the link. Returns -1 on error, 551 0 when no stubs will be needed, and 1 on success. */ 552 553int 554elf32_xgate_setup_section_lists (bfd *output_bfd ATTRIBUTE_UNUSED, 555 struct bfd_link_info *info ATTRIBUTE_UNUSED) 556{ 557 return 1; 558} 559 560/* Determine and set the size of the stub section for a final link. 561 The basic idea here is to examine all the relocations looking for 562 PC-relative calls to a target that is unreachable with any "9-bit PC-REL" 563 instruction. */ 564 565bfd_boolean 566elf32_xgate_size_stubs (bfd *output_bfd ATTRIBUTE_UNUSED, 567 bfd *stub_bfd ATTRIBUTE_UNUSED, 568 struct bfd_link_info *info ATTRIBUTE_UNUSED, 569 asection * (*add_stub_section) (const char*, asection*) ATTRIBUTE_UNUSED) 570{ 571 return FALSE; 572} 573 574/* Build all the stubs associated with the current output file. The 575 stubs are kept in a hash table attached to the main linker hash 576 table. This function is called via xgateelf_finish in the 577 linker. */ 578 579bfd_boolean 580elf32_xgate_build_stubs (bfd *abfd ATTRIBUTE_UNUSED, 581 struct bfd_link_info *info ATTRIBUTE_UNUSED) 582{ 583 return TRUE; 584} 585 586void 587xgate_elf_get_bank_parameters (struct bfd_link_info *info ATTRIBUTE_UNUSED) 588{ 589 return; 590} 591 592/* This function is used for relocs which are only used for relaxing, 593 which the linker should otherwise ignore. */ 594 595bfd_reloc_status_type 596xgate_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, 597 arelent *reloc_entry, 598 asymbol *symbol ATTRIBUTE_UNUSED, 599 void *data ATTRIBUTE_UNUSED, 600 asection *input_section, 601 bfd *output_bfd, 602 char **error_message ATTRIBUTE_UNUSED) 603{ 604 if (output_bfd != NULL) 605 reloc_entry->address += input_section->output_offset; 606 return bfd_reloc_ok; 607} 608 609bfd_reloc_status_type 610xgate_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED, 611 arelent *reloc_entry ATTRIBUTE_UNUSED, 612 asymbol *symbol ATTRIBUTE_UNUSED, 613 void *data ATTRIBUTE_UNUSED, 614 asection *input_section ATTRIBUTE_UNUSED, 615 bfd *output_bfd ATTRIBUTE_UNUSED, 616 char **error_message ATTRIBUTE_UNUSED) 617{ 618 abort (); 619} 620 621/* Look through the relocs for a section during the first phase. 622 Since we don't do .gots or .plts, we just need to consider the 623 virtual table relocs for gc. */ 624 625bfd_boolean 626elf32_xgate_check_relocs (bfd *abfd ATTRIBUTE_UNUSED, 627 struct bfd_link_info *info ATTRIBUTE_UNUSED, 628 asection *sec ATTRIBUTE_UNUSED, 629 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) 630{ 631 return TRUE; 632} 633 634/* Relocate a XGATE/S12x ELF section. */ 635 636bfd_boolean 637elf32_xgate_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 638 struct bfd_link_info *info ATTRIBUTE_UNUSED, 639 bfd *input_bfd ATTRIBUTE_UNUSED, 640 asection *input_section ATTRIBUTE_UNUSED, 641 bfd_byte *contents ATTRIBUTE_UNUSED, 642 Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED, 643 Elf_Internal_Sym *local_syms ATTRIBUTE_UNUSED, 644 asection **local_sections ATTRIBUTE_UNUSED) 645{ 646 return TRUE; 647} 648 649/* Set and control ELF flags in ELF header. */ 650 651bfd_boolean 652_bfd_xgate_elf_set_private_flags (bfd *abfd ATTRIBUTE_UNUSED, 653 flagword flags ATTRIBUTE_UNUSED) 654{ 655 return TRUE; 656} 657 658bfd_boolean 659_bfd_xgate_elf_print_private_bfd_data (bfd *abfd, void *ptr) 660{ 661 FILE *file = (FILE *) ptr; 662 663 BFD_ASSERT (abfd != NULL && ptr != NULL); 664 665 /* Print normal ELF private data. */ 666 _bfd_elf_print_private_bfd_data (abfd, ptr); 667 668 /* xgettext:c-format */ 669 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); 670 671 if (elf_elfheader (abfd)->e_flags & E_XGATE_I32) 672 fprintf (file, _("[abi=32-bit int, ")); 673 else 674 fprintf (file, _("[abi=16-bit int, ")); 675 676 if (elf_elfheader (abfd)->e_flags & E_XGATE_F64) 677 fprintf (file, _("64-bit double, ")); 678 else 679 fprintf (file, _("32-bit double, ")); 680 if (elf_elfheader (abfd)->e_flags & EF_XGATE_MACH) 681 fprintf (file, _("cpu=XGATE]")); 682 else 683 fprintf (file, _("error reading cpu type from elf private data")); 684 fputc ('\n', file); 685 686 return TRUE; 687} 688 689void 690elf32_xgate_post_process_headers (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED) 691{ 692 693} 694 695#define ELF_ARCH bfd_arch_xgate 696#define ELF_MACHINE_CODE EM_XGATE 697#define ELF_TARGET_ID XGATE_ELF_DATA 698 699#define ELF_MAXPAGESIZE 0x1000 700 701#define TARGET_BIG_SYM xgate_elf32_vec 702#define TARGET_BIG_NAME "elf32-xgate" 703 704#define elf_info_to_howto 0 705#define elf_info_to_howto_rel xgate_info_to_howto_rel 706#define elf_backend_check_relocs elf32_xgate_check_relocs 707#define elf_backend_relocate_section elf32_xgate_relocate_section 708#define elf_backend_object_p xgate_elf_set_mach_from_flags 709#define elf_backend_final_write_processing 0 710#define elf_backend_can_gc_sections 1 711#define elf_backend_special_sections elf32_xgate_special_sections 712#define elf_backend_post_process_headers elf32_xgate_post_process_headers 713#define elf_backend_add_symbol_hook elf32_xgate_add_symbol_hook 714 715#define bfd_elf32_bfd_link_hash_table_create xgate_elf_bfd_link_hash_table_create 716#define bfd_elf32_bfd_set_private_flags _bfd_xgate_elf_set_private_flags 717#define bfd_elf32_bfd_print_private_bfd_data _bfd_xgate_elf_print_private_bfd_data 718 719#define xgate_stub_hash_lookup(table, string, create, copy) \ 720 ((struct elf32_xgate_stub_hash_entry *) \ 721 bfd_hash_lookup ((table), (string), (create), (copy))) 722 723#include "elf32-target.h" 724