1/* SPU specific support for 32-bit ELF 2 3 Copyright 2006 Free Software Foundation, Inc. 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 2 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 along 18 with this program; if not, write to the Free Software Foundation, Inc., 19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21#include "bfd.h" 22#include "sysdep.h" 23#include "bfdlink.h" 24#include "libbfd.h" 25#include "elf-bfd.h" 26#include "elf/spu.h" 27#include "elf32-spu.h" 28 29/* We use RELA style relocs. Don't define USE_REL. */ 30 31static bfd_reloc_status_type spu_elf_rel9 (bfd *, arelent *, asymbol *, 32 void *, asection *, 33 bfd *, char **); 34 35/* Values of type 'enum elf_spu_reloc_type' are used to index this 36 array, so it must be declared in the order of that type. */ 37 38static reloc_howto_type elf_howto_table[] = { 39 HOWTO (R_SPU_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont, 40 bfd_elf_generic_reloc, "SPU_NONE", 41 FALSE, 0, 0x00000000, FALSE), 42 HOWTO (R_SPU_ADDR10, 4, 2, 10, FALSE, 14, complain_overflow_bitfield, 43 bfd_elf_generic_reloc, "SPU_ADDR10", 44 FALSE, 0, 0x00ffc000, FALSE), 45 HOWTO (R_SPU_ADDR16, 2, 2, 16, FALSE, 7, complain_overflow_bitfield, 46 bfd_elf_generic_reloc, "SPU_ADDR16", 47 FALSE, 0, 0x007fff80, FALSE), 48 HOWTO (R_SPU_ADDR16_HI, 16, 2, 16, FALSE, 7, complain_overflow_bitfield, 49 bfd_elf_generic_reloc, "SPU_ADDR16_HI", 50 FALSE, 0, 0x007fff80, FALSE), 51 HOWTO (R_SPU_ADDR16_LO, 0, 2, 16, FALSE, 7, complain_overflow_dont, 52 bfd_elf_generic_reloc, "SPU_ADDR16_LO", 53 FALSE, 0, 0x007fff80, FALSE), 54 HOWTO (R_SPU_ADDR18, 0, 2, 18, FALSE, 7, complain_overflow_bitfield, 55 bfd_elf_generic_reloc, "SPU_ADDR18", 56 FALSE, 0, 0x01ffff80, FALSE), 57 HOWTO (R_SPU_ADDR32, 0, 2, 32, FALSE, 0, complain_overflow_dont, 58 bfd_elf_generic_reloc, "SPU_ADDR32", 59 FALSE, 0, 0xffffffff, FALSE), 60 HOWTO (R_SPU_REL16, 2, 2, 16, TRUE, 7, complain_overflow_bitfield, 61 bfd_elf_generic_reloc, "SPU_REL16", 62 FALSE, 0, 0x007fff80, TRUE), 63 HOWTO (R_SPU_ADDR7, 0, 2, 7, FALSE, 14, complain_overflow_dont, 64 bfd_elf_generic_reloc, "SPU_ADDR7", 65 FALSE, 0, 0x001fc000, FALSE), 66 HOWTO (R_SPU_REL9, 2, 2, 9, TRUE, 0, complain_overflow_signed, 67 spu_elf_rel9, "SPU_REL9", 68 FALSE, 0, 0x0180007f, TRUE), 69 HOWTO (R_SPU_REL9I, 2, 2, 9, TRUE, 0, complain_overflow_signed, 70 spu_elf_rel9, "SPU_REL9I", 71 FALSE, 0, 0x0000c07f, TRUE), 72 HOWTO (R_SPU_ADDR10I, 0, 2, 10, FALSE, 14, complain_overflow_signed, 73 bfd_elf_generic_reloc, "SPU_ADDR10I", 74 FALSE, 0, 0x00ffc000, FALSE), 75 HOWTO (R_SPU_ADDR16I, 0, 2, 16, FALSE, 7, complain_overflow_signed, 76 bfd_elf_generic_reloc, "SPU_ADDR16I", 77 FALSE, 0, 0x007fff80, FALSE), 78 HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont, 79 bfd_elf_generic_reloc, "SPU_REL32", 80 FALSE, 0, 0xffffffff, TRUE), 81}; 82 83static struct bfd_elf_special_section const spu_elf_special_sections[] = { 84 { ".toe", 4, 0, SHT_NOBITS, SHF_ALLOC }, 85 { NULL, 0, 0, 0, 0 } 86}; 87 88static enum elf_spu_reloc_type 89spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code) 90{ 91 switch (code) 92 { 93 default: 94 return R_SPU_NONE; 95 case BFD_RELOC_SPU_IMM10W: 96 return R_SPU_ADDR10; 97 case BFD_RELOC_SPU_IMM16W: 98 return R_SPU_ADDR16; 99 case BFD_RELOC_SPU_LO16: 100 return R_SPU_ADDR16_LO; 101 case BFD_RELOC_SPU_HI16: 102 return R_SPU_ADDR16_HI; 103 case BFD_RELOC_SPU_IMM18: 104 return R_SPU_ADDR18; 105 case BFD_RELOC_SPU_PCREL16: 106 return R_SPU_REL16; 107 case BFD_RELOC_SPU_IMM7: 108 return R_SPU_ADDR7; 109 case BFD_RELOC_SPU_IMM8: 110 return R_SPU_NONE; 111 case BFD_RELOC_SPU_PCREL9a: 112 return R_SPU_REL9; 113 case BFD_RELOC_SPU_PCREL9b: 114 return R_SPU_REL9I; 115 case BFD_RELOC_SPU_IMM10: 116 return R_SPU_ADDR10I; 117 case BFD_RELOC_SPU_IMM16: 118 return R_SPU_ADDR16I; 119 case BFD_RELOC_32: 120 return R_SPU_ADDR32; 121 case BFD_RELOC_32_PCREL: 122 return R_SPU_REL32; 123 } 124} 125 126static void 127spu_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 128 arelent *cache_ptr, 129 Elf_Internal_Rela *dst) 130{ 131 enum elf_spu_reloc_type r_type; 132 133 r_type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info); 134 BFD_ASSERT (r_type < R_SPU_max); 135 cache_ptr->howto = &elf_howto_table[(int) r_type]; 136} 137 138static reloc_howto_type * 139spu_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 140 bfd_reloc_code_real_type code) 141{ 142 return elf_howto_table + spu_elf_bfd_to_reloc_type (code); 143} 144 145/* Apply R_SPU_REL9 and R_SPU_REL9I relocs. */ 146 147static bfd_reloc_status_type 148spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 149 void *data, asection *input_section, 150 bfd *output_bfd, char **error_message) 151{ 152 bfd_size_type octets; 153 bfd_vma val; 154 long insn; 155 156 /* If this is a relocatable link (output_bfd test tells us), just 157 call the generic function. Any adjustment will be done at final 158 link time. */ 159 if (output_bfd != NULL) 160 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 161 input_section, output_bfd, error_message); 162 163 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 164 return bfd_reloc_outofrange; 165 octets = reloc_entry->address * bfd_octets_per_byte (abfd); 166 167 /* Get symbol value. */ 168 val = 0; 169 if (!bfd_is_com_section (symbol->section)) 170 val = symbol->value; 171 if (symbol->section->output_section) 172 val += symbol->section->output_section->vma; 173 174 val += reloc_entry->addend; 175 176 /* Make it pc-relative. */ 177 val -= input_section->output_section->vma + input_section->output_offset; 178 179 val >>= 2; 180 if (val + 256 >= 512) 181 return bfd_reloc_overflow; 182 183 insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); 184 185 /* Move two high bits of value to REL9I and REL9 position. 186 The mask will take care of selecting the right field. */ 187 val = (val & 0x7f) | ((val & 0x180) << 7) | ((val & 0x180) << 16); 188 insn &= ~reloc_entry->howto->dst_mask; 189 insn |= val & reloc_entry->howto->dst_mask; 190 bfd_put_32 (abfd, insn, (bfd_byte *) data + octets); 191 return bfd_reloc_ok; 192} 193 194static bfd_boolean 195spu_elf_new_section_hook (bfd *abfd, asection *sec) 196{ 197 if (!sec->used_by_bfd) 198 { 199 struct _spu_elf_section_data *sdata; 200 201 sdata = bfd_zalloc (abfd, sizeof (*sdata)); 202 if (sdata == NULL) 203 return FALSE; 204 sec->used_by_bfd = sdata; 205 } 206 207 return _bfd_elf_new_section_hook (abfd, sec); 208} 209 210/* Specially mark defined symbols named _EAR_* with BSF_KEEP so that 211 strip --strip-unneeded will not remove them. */ 212 213static void 214spu_elf_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) 215{ 216 if (sym->name != NULL 217 && sym->section != bfd_abs_section_ptr 218 && strncmp (sym->name, "_EAR_", 5) == 0) 219 sym->flags |= BSF_KEEP; 220} 221 222/* SPU ELF linker hash table. */ 223 224struct spu_link_hash_table 225{ 226 struct elf_link_hash_table elf; 227 228 /* The stub hash table. */ 229 struct bfd_hash_table stub_hash_table; 230 231 /* Shortcuts to overlay sections. */ 232 asection *stub; 233 asection *ovtab; 234 235 struct elf_link_hash_entry *ovly_load; 236 237 /* An array of two output sections per overlay region, chosen such that 238 the first section vma is the overlay buffer vma (ie. the section has 239 the lowest vma in the group that occupy the region), and the second 240 section vma+size specifies the end of the region. We keep pointers 241 to sections like this because section vmas may change when laying 242 them out. */ 243 asection **ovl_region; 244 245 /* Number of overlay buffers. */ 246 unsigned int num_buf; 247 248 /* Total number of overlays. */ 249 unsigned int num_overlays; 250 251 /* Set if we should emit symbols for stubs. */ 252 unsigned int emit_stub_syms:1; 253 254 /* Set if we want stubs on calls out of overlay regions to 255 non-overlay regions. */ 256 unsigned int non_overlay_stubs : 1; 257 258 /* Set on error. */ 259 unsigned int stub_overflow : 1; 260}; 261 262#define spu_hash_table(p) \ 263 ((struct spu_link_hash_table *) ((p)->hash)) 264 265struct spu_stub_hash_entry 266{ 267 struct bfd_hash_entry root; 268 269 /* Destination of this stub. */ 270 asection *target_section; 271 bfd_vma target_off; 272 273 /* Offset of entry in stub section. */ 274 bfd_vma off; 275 276 /* Offset from this stub to stub that loads the overlay index. */ 277 bfd_vma delta; 278}; 279 280/* Create an entry in a spu stub hash table. */ 281 282static struct bfd_hash_entry * 283stub_hash_newfunc (struct bfd_hash_entry *entry, 284 struct bfd_hash_table *table, 285 const char *string) 286{ 287 /* Allocate the structure if it has not already been allocated by a 288 subclass. */ 289 if (entry == NULL) 290 { 291 entry = bfd_hash_allocate (table, sizeof (struct spu_stub_hash_entry)); 292 if (entry == NULL) 293 return entry; 294 } 295 296 /* Call the allocation method of the superclass. */ 297 entry = bfd_hash_newfunc (entry, table, string); 298 if (entry != NULL) 299 { 300 struct spu_stub_hash_entry *sh = (struct spu_stub_hash_entry *) entry; 301 302 sh->target_section = NULL; 303 sh->target_off = 0; 304 sh->off = 0; 305 sh->delta = 0; 306 } 307 308 return entry; 309} 310 311/* Create a spu ELF linker hash table. */ 312 313static struct bfd_link_hash_table * 314spu_elf_link_hash_table_create (bfd *abfd) 315{ 316 struct spu_link_hash_table *htab; 317 318 htab = bfd_malloc (sizeof (*htab)); 319 if (htab == NULL) 320 return NULL; 321 322 if (!_bfd_elf_link_hash_table_init (&htab->elf, abfd, 323 _bfd_elf_link_hash_newfunc, 324 sizeof (struct elf_link_hash_entry))) 325 { 326 free (htab); 327 return NULL; 328 } 329 330 /* Init the stub hash table too. */ 331 if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc, 332 sizeof (struct spu_stub_hash_entry))) 333 return NULL; 334 335 memset (&htab->stub, 0, 336 sizeof (*htab) - offsetof (struct spu_link_hash_table, stub)); 337 338 return &htab->elf.root; 339} 340 341/* Free the derived linker hash table. */ 342 343static void 344spu_elf_link_hash_table_free (struct bfd_link_hash_table *hash) 345{ 346 struct spu_link_hash_table *ret = (struct spu_link_hash_table *) hash; 347 348 bfd_hash_table_free (&ret->stub_hash_table); 349 _bfd_generic_link_hash_table_free (hash); 350} 351 352/* Find the symbol for the given R_SYMNDX in IBFD and set *HP and *SYMP 353 to (hash, NULL) for global symbols, and (NULL, sym) for locals. Set 354 *SYMSECP to the symbol's section. *LOCSYMSP caches local syms. */ 355 356static bfd_boolean 357get_sym_h (struct elf_link_hash_entry **hp, 358 Elf_Internal_Sym **symp, 359 asection **symsecp, 360 Elf_Internal_Sym **locsymsp, 361 unsigned long r_symndx, 362 bfd *ibfd) 363{ 364 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; 365 366 if (r_symndx >= symtab_hdr->sh_info) 367 { 368 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd); 369 struct elf_link_hash_entry *h; 370 371 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 372 while (h->root.type == bfd_link_hash_indirect 373 || h->root.type == bfd_link_hash_warning) 374 h = (struct elf_link_hash_entry *) h->root.u.i.link; 375 376 if (hp != NULL) 377 *hp = h; 378 379 if (symp != NULL) 380 *symp = NULL; 381 382 if (symsecp != NULL) 383 { 384 asection *symsec = NULL; 385 if (h->root.type == bfd_link_hash_defined 386 || h->root.type == bfd_link_hash_defweak) 387 symsec = h->root.u.def.section; 388 *symsecp = symsec; 389 } 390 } 391 else 392 { 393 Elf_Internal_Sym *sym; 394 Elf_Internal_Sym *locsyms = *locsymsp; 395 396 if (locsyms == NULL) 397 { 398 locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; 399 if (locsyms == NULL) 400 locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, 401 symtab_hdr->sh_info, 402 0, NULL, NULL, NULL); 403 if (locsyms == NULL) 404 return FALSE; 405 *locsymsp = locsyms; 406 } 407 sym = locsyms + r_symndx; 408 409 if (hp != NULL) 410 *hp = NULL; 411 412 if (symp != NULL) 413 *symp = sym; 414 415 if (symsecp != NULL) 416 { 417 asection *symsec = NULL; 418 if ((sym->st_shndx != SHN_UNDEF 419 && sym->st_shndx < SHN_LORESERVE) 420 || sym->st_shndx > SHN_HIRESERVE) 421 symsec = bfd_section_from_elf_index (ibfd, sym->st_shndx); 422 *symsecp = symsec; 423 } 424 } 425 return TRUE; 426} 427 428/* Build a name for an entry in the stub hash table. The input section 429 id isn't really necessary but we add that in for consistency with 430 ppc32 and ppc64 stub names. We can't use a local symbol name 431 because ld -r might generate duplicate local symbols. */ 432 433static char * 434spu_stub_name (const asection *input_sec, 435 const asection *sym_sec, 436 const struct elf_link_hash_entry *h, 437 const Elf_Internal_Rela *rel) 438{ 439 char *stub_name; 440 bfd_size_type len; 441 442 if (h) 443 { 444 len = 8 + 1 + strlen (h->root.root.string) + 1 + 8 + 1; 445 stub_name = bfd_malloc (len); 446 if (stub_name == NULL) 447 return stub_name; 448 449 sprintf (stub_name, "%08x.%s+%x", 450 input_sec->id & 0xffffffff, 451 h->root.root.string, 452 (int) rel->r_addend & 0xffffffff); 453 len -= 8; 454 } 455 else 456 { 457 len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1; 458 stub_name = bfd_malloc (len); 459 if (stub_name == NULL) 460 return stub_name; 461 462 sprintf (stub_name, "%08x.%x:%x+%x", 463 input_sec->id & 0xffffffff, 464 sym_sec->id & 0xffffffff, 465 (int) ELF32_R_SYM (rel->r_info) & 0xffffffff, 466 (int) rel->r_addend & 0xffffffff); 467 len = strlen (stub_name); 468 } 469 470 if (stub_name[len - 2] == '+' 471 && stub_name[len - 1] == '0' 472 && stub_name[len] == 0) 473 stub_name[len - 2] = 0; 474 475 return stub_name; 476} 477 478/* Create the note section if not already present. This is done early so 479 that the linker maps the sections to the right place in the output. */ 480 481bfd_boolean 482spu_elf_create_sections (bfd *output_bfd, struct bfd_link_info *info) 483{ 484 bfd *ibfd; 485 486 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->next) 487 if (bfd_get_section_by_name (ibfd, SPU_PTNOTE_SPUNAME) != NULL) 488 break; 489 490 if (ibfd == NULL) 491 { 492 /* Make SPU_PTNOTE_SPUNAME section. */ 493 asection *s; 494 size_t name_len; 495 size_t size; 496 bfd_byte *data; 497 flagword flags; 498 499 ibfd = info->input_bfds; 500 flags = SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY; 501 s = bfd_make_section_anyway_with_flags (ibfd, SPU_PTNOTE_SPUNAME, flags); 502 if (s == NULL 503 || !bfd_set_section_alignment (ibfd, s, 4)) 504 return FALSE; 505 506 name_len = strlen (bfd_get_filename (output_bfd)) + 1; 507 size = 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4); 508 size += (name_len + 3) & -4; 509 510 if (!bfd_set_section_size (ibfd, s, size)) 511 return FALSE; 512 513 data = bfd_zalloc (ibfd, size); 514 if (data == NULL) 515 return FALSE; 516 517 bfd_put_32 (ibfd, sizeof (SPU_PLUGIN_NAME), data + 0); 518 bfd_put_32 (ibfd, name_len, data + 4); 519 bfd_put_32 (ibfd, 1, data + 8); 520 memcpy (data + 12, SPU_PLUGIN_NAME, sizeof (SPU_PLUGIN_NAME)); 521 memcpy (data + 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4), 522 bfd_get_filename (output_bfd), name_len); 523 s->contents = data; 524 } 525 526 return TRUE; 527} 528 529/* Return the section that should be marked against GC for a given 530 relocation. */ 531 532static asection * 533spu_elf_gc_mark_hook (asection *sec, 534 struct bfd_link_info *info ATTRIBUTE_UNUSED, 535 Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, 536 struct elf_link_hash_entry *h, 537 Elf_Internal_Sym *sym) 538{ 539 if (h != NULL) 540 { 541 switch (h->root.type) 542 { 543 case bfd_link_hash_defined: 544 case bfd_link_hash_defweak: 545 return h->root.u.def.section; 546 547 case bfd_link_hash_common: 548 return h->root.u.c.p->section; 549 550 default: 551 break; 552 } 553 } 554 else 555 return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 556 557 return NULL; 558} 559 560/* qsort predicate to sort sections by vma. */ 561 562static int 563sort_sections (const void *a, const void *b) 564{ 565 const asection *const *s1 = a; 566 const asection *const *s2 = b; 567 bfd_signed_vma delta = (*s1)->vma - (*s2)->vma; 568 569 if (delta != 0) 570 return delta < 0 ? -1 : 1; 571 572 return (*s1)->index - (*s2)->index; 573} 574 575/* Identify overlays in the output bfd, and number them. */ 576 577bfd_boolean 578spu_elf_find_overlays (bfd *output_bfd, struct bfd_link_info *info) 579{ 580 struct spu_link_hash_table *htab = spu_hash_table (info); 581 asection **alloc_sec; 582 unsigned int i, n, ovl_index, num_buf; 583 asection *s; 584 bfd_vma ovl_end; 585 586 if (output_bfd->section_count < 2) 587 return FALSE; 588 589 alloc_sec = bfd_malloc (output_bfd->section_count * sizeof (*alloc_sec)); 590 if (alloc_sec == NULL) 591 return FALSE; 592 593 /* Pick out all the alloced sections. */ 594 for (n = 0, s = output_bfd->sections; s != NULL; s = s->next) 595 if ((s->flags & SEC_ALLOC) != 0 596 && (s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != SEC_THREAD_LOCAL 597 && s->size != 0) 598 alloc_sec[n++] = s; 599 600 if (n == 0) 601 { 602 free (alloc_sec); 603 return FALSE; 604 } 605 606 /* Sort them by vma. */ 607 qsort (alloc_sec, n, sizeof (*alloc_sec), sort_sections); 608 609 /* Look for overlapping vmas. Any with overlap must be overlays. 610 Count them. Also count the number of overlay regions and for 611 each region save a section from that region with the lowest vma 612 and another section with the highest end vma. */ 613 ovl_end = alloc_sec[0]->vma + alloc_sec[0]->size; 614 for (ovl_index = 0, num_buf = 0, i = 1; i < n; i++) 615 { 616 s = alloc_sec[i]; 617 if (s->vma < ovl_end) 618 { 619 asection *s0 = alloc_sec[i - 1]; 620 621 if (spu_elf_section_data (s0)->ovl_index == 0) 622 { 623 spu_elf_section_data (s0)->ovl_index = ++ovl_index; 624 alloc_sec[num_buf * 2] = s0; 625 alloc_sec[num_buf * 2 + 1] = s0; 626 num_buf++; 627 } 628 spu_elf_section_data (s)->ovl_index = ++ovl_index; 629 if (ovl_end < s->vma + s->size) 630 { 631 ovl_end = s->vma + s->size; 632 alloc_sec[num_buf * 2 - 1] = s; 633 } 634 } 635 else 636 ovl_end = s->vma + s->size; 637 } 638 639 htab->num_overlays = ovl_index; 640 htab->num_buf = num_buf; 641 if (ovl_index == 0) 642 { 643 free (alloc_sec); 644 return FALSE; 645 } 646 647 alloc_sec = bfd_realloc (alloc_sec, num_buf * 2 * sizeof (*alloc_sec)); 648 if (alloc_sec == NULL) 649 return FALSE; 650 651 htab->ovl_region = alloc_sec; 652 return TRUE; 653} 654 655/* One of these per stub. */ 656#define SIZEOF_STUB1 8 657#define ILA_79 0x4200004f /* ila $79,function_address */ 658#define BR 0x32000000 /* br stub2 */ 659 660/* One of these per overlay. */ 661#define SIZEOF_STUB2 8 662#define ILA_78 0x4200004e /* ila $78,overlay_number */ 663 /* br __ovly_load */ 664#define NOP 0x40200000 665 666/* Return true for all relative and absolute branch and hint instructions. 667 bra 00110000 0.. 668 brasl 00110001 0.. 669 br 00110010 0.. 670 brsl 00110011 0.. 671 brz 00100000 0.. 672 brnz 00100001 0.. 673 brhz 00100010 0.. 674 brhnz 00100011 0.. 675 hbra 0001000.. 676 hbrr 0001001.. */ 677 678static bfd_boolean 679is_branch (const unsigned char *insn) 680{ 681 return (((insn[0] & 0xec) == 0x20 && (insn[1] & 0x80) == 0) 682 || (insn[0] & 0xfc) == 0x10); 683} 684 685struct stubarr { 686 struct spu_stub_hash_entry **sh; 687 unsigned int count; 688}; 689 690/* Called via bfd_hash_traverse to set up pointers to all symbols 691 in the stub hash table. */ 692 693static bfd_boolean 694populate_stubs (struct bfd_hash_entry *bh, void *inf) 695{ 696 struct stubarr *stubs = inf; 697 698 stubs->sh[--stubs->count] = (struct spu_stub_hash_entry *) bh; 699 return TRUE; 700} 701 702/* qsort predicate to sort stubs by overlay number. */ 703 704static int 705sort_stubs (const void *a, const void *b) 706{ 707 const struct spu_stub_hash_entry *const *sa = a; 708 const struct spu_stub_hash_entry *const *sb = b; 709 int i; 710 bfd_signed_vma d; 711 712 i = spu_elf_section_data ((*sa)->target_section->output_section)->ovl_index; 713 i -= spu_elf_section_data ((*sb)->target_section->output_section)->ovl_index; 714 if (i != 0) 715 return i; 716 717 d = ((*sa)->target_section->output_section->vma 718 + (*sa)->target_section->output_offset 719 + (*sa)->target_off 720 - (*sb)->target_section->output_section->vma 721 - (*sb)->target_section->output_offset 722 - (*sb)->target_off); 723 if (d != 0) 724 return d < 0 ? -1 : 1; 725 726 /* Two functions at the same address. Aliases perhaps. */ 727 i = strcmp ((*sb)->root.string, (*sa)->root.string); 728 BFD_ASSERT (i != 0); 729 return i; 730} 731 732/* Allocate space for overlay call and return stubs. */ 733 734bfd_boolean 735spu_elf_size_stubs (bfd *output_bfd, 736 struct bfd_link_info *info, 737 int non_overlay_stubs, 738 asection **stub, 739 asection **ovtab, 740 asection **toe) 741{ 742 struct spu_link_hash_table *htab = spu_hash_table (info); 743 bfd *ibfd; 744 struct stubarr stubs; 745 unsigned i, group; 746 flagword flags; 747 748 htab->non_overlay_stubs = non_overlay_stubs; 749 stubs.count = 0; 750 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) 751 { 752 extern const bfd_target bfd_elf32_spu_vec; 753 Elf_Internal_Shdr *symtab_hdr; 754 asection *section; 755 Elf_Internal_Sym *local_syms = NULL; 756 757 if (ibfd->xvec != &bfd_elf32_spu_vec) 758 continue; 759 760 /* We'll need the symbol table in a second. */ 761 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; 762 if (symtab_hdr->sh_info == 0) 763 continue; 764 765 /* Walk over each section attached to the input bfd. */ 766 for (section = ibfd->sections; section != NULL; section = section->next) 767 { 768 Elf_Internal_Rela *internal_relocs, *irelaend, *irela; 769 770 /* If there aren't any relocs, then there's nothing more to do. */ 771 if ((section->flags & SEC_RELOC) == 0 772 || (section->flags & SEC_ALLOC) == 0 773 || (section->flags & SEC_LOAD) == 0 774 || section->reloc_count == 0) 775 continue; 776 777 /* If this section is a link-once section that will be 778 discarded, then don't create any stubs. */ 779 if (section->output_section == NULL 780 || section->output_section->owner != output_bfd) 781 continue; 782 783 /* Get the relocs. */ 784 internal_relocs 785 = _bfd_elf_link_read_relocs (ibfd, section, NULL, NULL, 786 info->keep_memory); 787 if (internal_relocs == NULL) 788 goto error_ret_free_local; 789 790 /* Now examine each relocation. */ 791 irela = internal_relocs; 792 irelaend = irela + section->reloc_count; 793 for (; irela < irelaend; irela++) 794 { 795 enum elf_spu_reloc_type r_type; 796 unsigned int r_indx; 797 asection *sym_sec; 798 Elf_Internal_Sym *sym; 799 struct elf_link_hash_entry *h; 800 char *stub_name; 801 struct spu_stub_hash_entry *sh; 802 unsigned int sym_type; 803 enum _insn_type { non_branch, branch, call } insn_type; 804 805 r_type = ELF32_R_TYPE (irela->r_info); 806 r_indx = ELF32_R_SYM (irela->r_info); 807 808 if (r_type >= R_SPU_max) 809 { 810 bfd_set_error (bfd_error_bad_value); 811 goto error_ret_free_internal; 812 } 813 814 /* Determine the reloc target section. */ 815 if (!get_sym_h (&h, &sym, &sym_sec, &local_syms, r_indx, ibfd)) 816 goto error_ret_free_internal; 817 818 if (sym_sec == NULL 819 || sym_sec->output_section == NULL 820 || sym_sec->output_section->owner != output_bfd) 821 continue; 822 823 /* Ensure no stubs for user supplied overlay manager syms. */ 824 if (h != NULL 825 && (strcmp (h->root.root.string, "__ovly_load") == 0 826 || strcmp (h->root.root.string, "__ovly_return") == 0)) 827 continue; 828 829 insn_type = non_branch; 830 if (r_type == R_SPU_REL16 831 || r_type == R_SPU_ADDR16) 832 { 833 unsigned char insn[4]; 834 835 if (!bfd_get_section_contents (ibfd, section, insn, 836 irela->r_offset, 4)) 837 goto error_ret_free_internal; 838 839 if (is_branch (insn)) 840 { 841 insn_type = branch; 842 if ((insn[0] & 0xfd) == 0x31) 843 insn_type = call; 844 } 845 } 846 847 /* We are only interested in function symbols. */ 848 if (h != NULL) 849 sym_type = h->type; 850 else 851 sym_type = ELF_ST_TYPE (sym->st_info); 852 if (sym_type != STT_FUNC) 853 { 854 /* It's common for people to write assembly and forget 855 to give function symbols the right type. Handle 856 calls to such symbols, but warn so that (hopefully) 857 people will fix their code. We need the symbol 858 type to be correct to distinguish function pointer 859 initialisation from other pointer initialisation. */ 860 if (insn_type == call) 861 { 862 const char *sym_name; 863 864 if (h != NULL) 865 sym_name = h->root.root.string; 866 else 867 sym_name = bfd_elf_sym_name (sym_sec->owner, 868 symtab_hdr, 869 sym, 870 sym_sec); 871 872 (*_bfd_error_handler) (_("warning: call to non-function" 873 " symbol %s defined in %B"), 874 sym_name, sym_sec->owner); 875 } 876 else 877 continue; 878 } 879 880 /* Usually, non-overlay sections don't need stubs. */ 881 if (!spu_elf_section_data (sym_sec->output_section)->ovl_index 882 && !non_overlay_stubs) 883 continue; 884 885 /* We need a reference from some other section before 886 we consider that a symbol might need an overlay stub. */ 887 if (spu_elf_section_data (sym_sec->output_section)->ovl_index 888 == spu_elf_section_data (section->output_section)->ovl_index) 889 { 890 /* Or we need this to *not* be a branch. ie. We are 891 possibly taking the address of a function and 892 passing it out somehow. */ 893 if (insn_type != non_branch) 894 continue; 895 } 896 897 stub_name = spu_stub_name (section, sym_sec, h, irela); 898 if (stub_name == NULL) 899 goto error_ret_free_internal; 900 901 sh = (struct spu_stub_hash_entry *) 902 bfd_hash_lookup (&htab->stub_hash_table, stub_name, 903 TRUE, FALSE); 904 if (sh == NULL) 905 { 906 free (stub_name); 907 error_ret_free_internal: 908 if (elf_section_data (section)->relocs != internal_relocs) 909 free (internal_relocs); 910 error_ret_free_local: 911 if (local_syms != NULL 912 && (symtab_hdr->contents 913 != (unsigned char *) local_syms)) 914 free (local_syms); 915 return FALSE; 916 } 917 918 /* If this entry isn't new, we already have a stub. */ 919 if (sh->target_section != NULL) 920 { 921 free (stub_name); 922 continue; 923 } 924 925 sh->target_section = sym_sec; 926 if (h != NULL) 927 sh->target_off = h->root.u.def.value; 928 else 929 sh->target_off = sym->st_value; 930 sh->target_off += irela->r_addend; 931 932 stubs.count += 1; 933 } 934 935 /* We're done with the internal relocs, free them. */ 936 if (elf_section_data (section)->relocs != internal_relocs) 937 free (internal_relocs); 938 } 939 940 if (local_syms != NULL 941 && symtab_hdr->contents != (unsigned char *) local_syms) 942 { 943 if (!info->keep_memory) 944 free (local_syms); 945 else 946 symtab_hdr->contents = (unsigned char *) local_syms; 947 } 948 } 949 950 *stub = NULL; 951 if (stubs.count == 0) 952 return TRUE; 953 954 ibfd = info->input_bfds; 955 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY 956 | SEC_HAS_CONTENTS | SEC_IN_MEMORY); 957 htab->stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags); 958 *stub = htab->stub; 959 if (htab->stub == NULL 960 || !bfd_set_section_alignment (ibfd, htab->stub, 2)) 961 return FALSE; 962 963 flags = (SEC_ALLOC | SEC_LOAD 964 | SEC_HAS_CONTENTS | SEC_IN_MEMORY); 965 htab->ovtab = bfd_make_section_anyway_with_flags (ibfd, ".ovtab", flags); 966 *ovtab = htab->ovtab; 967 if (htab->ovtab == NULL 968 || !bfd_set_section_alignment (ibfd, htab->stub, 4)) 969 return FALSE; 970 971 *toe = bfd_make_section_anyway_with_flags (ibfd, ".toe", SEC_ALLOC); 972 if (*toe == NULL 973 || !bfd_set_section_alignment (ibfd, *toe, 4)) 974 return FALSE; 975 (*toe)->size = 16; 976 977 /* Retrieve all the stubs and sort. */ 978 stubs.sh = bfd_malloc (stubs.count * sizeof (*stubs.sh)); 979 if (stubs.sh == NULL) 980 return FALSE; 981 i = stubs.count; 982 bfd_hash_traverse (&htab->stub_hash_table, populate_stubs, &stubs); 983 BFD_ASSERT (stubs.count == 0); 984 985 stubs.count = i; 986 qsort (stubs.sh, stubs.count, sizeof (*stubs.sh), sort_stubs); 987 988 /* Now that the stubs are sorted, place them in the stub section. 989 Stubs are grouped per overlay 990 . ila $79,func1 991 . br 1f 992 . ila $79,func2 993 . br 1f 994 . 995 . 996 . ila $79,funcn 997 . nop 998 . 1: 999 . ila $78,ovl_index 1000 . br __ovly_load */ 1001 1002 group = 0; 1003 for (i = 0; i < stubs.count; i++) 1004 { 1005 if (spu_elf_section_data (stubs.sh[group]->target_section 1006 ->output_section)->ovl_index 1007 != spu_elf_section_data (stubs.sh[i]->target_section 1008 ->output_section)->ovl_index) 1009 { 1010 htab->stub->size += SIZEOF_STUB2; 1011 for (; group != i; group++) 1012 stubs.sh[group]->delta 1013 = stubs.sh[i - 1]->off - stubs.sh[group]->off; 1014 } 1015 if (group == i 1016 || ((stubs.sh[i - 1]->target_section->output_section->vma 1017 + stubs.sh[i - 1]->target_section->output_offset 1018 + stubs.sh[i - 1]->target_off) 1019 != (stubs.sh[i]->target_section->output_section->vma 1020 + stubs.sh[i]->target_section->output_offset 1021 + stubs.sh[i]->target_off))) 1022 { 1023 stubs.sh[i]->off = htab->stub->size; 1024 htab->stub->size += SIZEOF_STUB1; 1025 } 1026 else 1027 stubs.sh[i]->off = stubs.sh[i - 1]->off; 1028 } 1029 if (group != i) 1030 htab->stub->size += SIZEOF_STUB2; 1031 for (; group != i; group++) 1032 stubs.sh[group]->delta = stubs.sh[i - 1]->off - stubs.sh[group]->off; 1033 1034 /* htab->ovtab consists of two arrays. 1035 . struct { 1036 . u32 vma; 1037 . u32 size; 1038 . u32 file_off; 1039 . u32 buf; 1040 . } _ovly_table[]; 1041 . 1042 . struct { 1043 . u32 mapped; 1044 . } _ovly_buf_table[]; */ 1045 1046 htab->ovtab->alignment_power = 4; 1047 htab->ovtab->size = htab->num_overlays * 16 + htab->num_buf * 4; 1048 1049 return TRUE; 1050} 1051 1052/* Functions to handle embedded spu_ovl.o object. */ 1053 1054static void * 1055ovl_mgr_open (struct bfd *nbfd ATTRIBUTE_UNUSED, void *stream) 1056{ 1057 return stream; 1058} 1059 1060static file_ptr 1061ovl_mgr_pread (struct bfd *abfd ATTRIBUTE_UNUSED, 1062 void *stream, 1063 void *buf, 1064 file_ptr nbytes, 1065 file_ptr offset) 1066{ 1067 struct _ovl_stream *os; 1068 size_t count; 1069 size_t max; 1070 1071 os = (struct _ovl_stream *) stream; 1072 max = (char *) os->end - (char *) os->start; 1073 1074 if ((ufile_ptr) offset >= max) 1075 return 0; 1076 1077 count = nbytes; 1078 if (count > max - offset) 1079 count = max - offset; 1080 1081 memcpy (buf, (char *) os->start + offset, count); 1082 return count; 1083} 1084 1085bfd_boolean 1086spu_elf_open_builtin_lib (bfd **ovl_bfd, const struct _ovl_stream *stream) 1087{ 1088 *ovl_bfd = bfd_openr_iovec ("builtin ovl_mgr", 1089 "elf32-spu", 1090 ovl_mgr_open, 1091 (void *) stream, 1092 ovl_mgr_pread, 1093 NULL, 1094 NULL); 1095 return *ovl_bfd != NULL; 1096} 1097 1098/* Fill in the ila and br for a stub. On the last stub for a group, 1099 write the stub that sets the overlay number too. */ 1100 1101static bfd_boolean 1102write_one_stub (struct bfd_hash_entry *bh, void *inf) 1103{ 1104 struct spu_stub_hash_entry *ent = (struct spu_stub_hash_entry *) bh; 1105 struct spu_link_hash_table *htab = inf; 1106 asection *sec = htab->stub; 1107 asection *s = ent->target_section; 1108 unsigned int ovl; 1109 bfd_vma val; 1110 1111 val = ent->target_off + s->output_offset + s->output_section->vma; 1112 bfd_put_32 (sec->owner, ILA_79 + ((val << 7) & 0x01ffff80), 1113 sec->contents + ent->off); 1114 val = ent->delta + 4; 1115 bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80), 1116 sec->contents + ent->off + 4); 1117 1118 /* If this is the last stub of this group, write stub2. */ 1119 if (ent->delta == 0) 1120 { 1121 bfd_put_32 (sec->owner, NOP, 1122 sec->contents + ent->off + 4); 1123 1124 ovl = spu_elf_section_data (s->output_section)->ovl_index; 1125 bfd_put_32 (sec->owner, ILA_78 + ((ovl << 7) & 0x01ffff80), 1126 sec->contents + ent->off + 8); 1127 1128 val = (htab->ovly_load->root.u.def.section->output_section->vma 1129 + htab->ovly_load->root.u.def.section->output_offset 1130 + htab->ovly_load->root.u.def.value 1131 - (sec->output_section->vma 1132 + sec->output_offset 1133 + ent->off + 12)); 1134 1135 if (val + 0x20000 >= 0x40000) 1136 htab->stub_overflow = TRUE; 1137 1138 bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80), 1139 sec->contents + ent->off + 12); 1140 } 1141 1142 if (htab->emit_stub_syms) 1143 { 1144 struct elf_link_hash_entry *h; 1145 size_t len1, len2; 1146 char *name; 1147 1148 len1 = sizeof ("ovl_call.") - 1; 1149 len2 = strlen (ent->root.string); 1150 name = bfd_malloc (len1 + len2 + 1); 1151 if (name == NULL) 1152 return FALSE; 1153 memcpy (name, ent->root.string, 9); 1154 memcpy (name + 9, "ovl_call.", len1); 1155 memcpy (name + 9 + len1, ent->root.string + 9, len2 - 9 + 1); 1156 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE); 1157 if (h == NULL) 1158 return FALSE; 1159 if (h->root.type == bfd_link_hash_new) 1160 { 1161 h->root.type = bfd_link_hash_defined; 1162 h->root.u.def.section = sec; 1163 h->root.u.def.value = ent->off; 1164 h->size = (ent->delta == 0 1165 ? SIZEOF_STUB1 + SIZEOF_STUB2 : SIZEOF_STUB1); 1166 h->type = STT_FUNC; 1167 h->ref_regular = 1; 1168 h->def_regular = 1; 1169 h->ref_regular_nonweak = 1; 1170 h->forced_local = 1; 1171 h->non_elf = 0; 1172 } 1173 } 1174 1175 return TRUE; 1176} 1177 1178/* Define an STT_OBJECT symbol. */ 1179 1180static struct elf_link_hash_entry * 1181define_ovtab_symbol (struct spu_link_hash_table *htab, const char *name) 1182{ 1183 struct elf_link_hash_entry *h; 1184 1185 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE); 1186 if (h == NULL) 1187 return NULL; 1188 1189 if (h->root.type != bfd_link_hash_defined 1190 || !h->def_regular) 1191 { 1192 h->root.type = bfd_link_hash_defined; 1193 h->root.u.def.section = htab->ovtab; 1194 h->type = STT_OBJECT; 1195 h->ref_regular = 1; 1196 h->def_regular = 1; 1197 h->ref_regular_nonweak = 1; 1198 h->non_elf = 0; 1199 } 1200 else 1201 { 1202 (*_bfd_error_handler) (_("%B is not allowed to define %s"), 1203 h->root.u.def.section->owner, 1204 h->root.root.string); 1205 bfd_set_error (bfd_error_bad_value); 1206 return NULL; 1207 } 1208 1209 return h; 1210} 1211 1212/* Fill in all stubs and the overlay tables. */ 1213 1214bfd_boolean 1215spu_elf_build_stubs (struct bfd_link_info *info, int emit_syms, asection *toe) 1216{ 1217 struct spu_link_hash_table *htab = spu_hash_table (info); 1218 struct elf_link_hash_entry *h; 1219 bfd_byte *p; 1220 asection *s; 1221 bfd *obfd; 1222 unsigned int i; 1223 1224 htab->emit_stub_syms = emit_syms; 1225 htab->stub->contents = bfd_zalloc (htab->stub->owner, htab->stub->size); 1226 if (htab->stub->contents == NULL) 1227 return FALSE; 1228 1229 h = elf_link_hash_lookup (&htab->elf, "__ovly_load", FALSE, FALSE, FALSE); 1230 htab->ovly_load = h; 1231 BFD_ASSERT (h != NULL 1232 && (h->root.type == bfd_link_hash_defined 1233 || h->root.type == bfd_link_hash_defweak) 1234 && h->def_regular); 1235 1236 s = h->root.u.def.section->output_section; 1237 if (spu_elf_section_data (s)->ovl_index) 1238 { 1239 (*_bfd_error_handler) (_("%s in overlay section"), 1240 h->root.u.def.section->owner); 1241 bfd_set_error (bfd_error_bad_value); 1242 return FALSE; 1243 } 1244 1245 /* Write out all the stubs. */ 1246 bfd_hash_traverse (&htab->stub_hash_table, write_one_stub, htab); 1247 1248 if (htab->stub_overflow) 1249 { 1250 (*_bfd_error_handler) (_("overlay stub relocation overflow")); 1251 bfd_set_error (bfd_error_bad_value); 1252 return FALSE; 1253 } 1254 1255 htab->ovtab->contents = bfd_zalloc (htab->ovtab->owner, htab->ovtab->size); 1256 if (htab->ovtab->contents == NULL) 1257 return FALSE; 1258 1259 /* Write out _ovly_table. */ 1260 p = htab->ovtab->contents; 1261 obfd = htab->ovtab->output_section->owner; 1262 for (s = obfd->sections; s != NULL; s = s->next) 1263 { 1264 unsigned int ovl_index = spu_elf_section_data (s)->ovl_index; 1265 1266 if (ovl_index != 0) 1267 { 1268 unsigned int lo, hi, mid; 1269 unsigned long off = (ovl_index - 1) * 16; 1270 bfd_put_32 (htab->ovtab->owner, s->vma, p + off); 1271 bfd_put_32 (htab->ovtab->owner, (s->size + 15) & -16, p + off + 4); 1272 /* file_off written later in spu_elf_modify_program_headers. */ 1273 1274 lo = 0; 1275 hi = htab->num_buf; 1276 while (lo < hi) 1277 { 1278 mid = (lo + hi) >> 1; 1279 if (htab->ovl_region[2 * mid + 1]->vma 1280 + htab->ovl_region[2 * mid + 1]->size <= s->vma) 1281 lo = mid + 1; 1282 else if (htab->ovl_region[2 * mid]->vma > s->vma) 1283 hi = mid; 1284 else 1285 { 1286 bfd_put_32 (htab->ovtab->owner, mid + 1, p + off + 12); 1287 break; 1288 } 1289 } 1290 BFD_ASSERT (lo < hi); 1291 } 1292 } 1293 1294 /* Write out _ovly_buf_table. */ 1295 p = htab->ovtab->contents + htab->num_overlays * 16; 1296 for (i = 0; i < htab->num_buf; i++) 1297 { 1298 bfd_put_32 (htab->ovtab->owner, 0, p); 1299 p += 4; 1300 } 1301 1302 h = define_ovtab_symbol (htab, "_ovly_table"); 1303 if (h == NULL) 1304 return FALSE; 1305 h->root.u.def.value = 0; 1306 h->size = htab->num_overlays * 16; 1307 1308 h = define_ovtab_symbol (htab, "_ovly_table_end"); 1309 if (h == NULL) 1310 return FALSE; 1311 h->root.u.def.value = htab->num_overlays * 16; 1312 h->size = 0; 1313 1314 h = define_ovtab_symbol (htab, "_ovly_buf_table"); 1315 if (h == NULL) 1316 return FALSE; 1317 h->root.u.def.value = htab->num_overlays * 16; 1318 h->size = htab->num_buf * 4; 1319 1320 h = define_ovtab_symbol (htab, "_ovly_buf_table_end"); 1321 if (h == NULL) 1322 return FALSE; 1323 h->root.u.def.value = htab->num_overlays * 16 + htab->num_buf * 4; 1324 h->size = 0; 1325 1326 h = define_ovtab_symbol (htab, "_EAR_"); 1327 if (h == NULL) 1328 return FALSE; 1329 h->root.u.def.section = toe; 1330 h->root.u.def.value = 0; 1331 h->size = 16; 1332 1333 return TRUE; 1334} 1335 1336/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */ 1337 1338static bfd_boolean 1339spu_elf_relocate_section (bfd *output_bfd, 1340 struct bfd_link_info *info, 1341 bfd *input_bfd, 1342 asection *input_section, 1343 bfd_byte *contents, 1344 Elf_Internal_Rela *relocs, 1345 Elf_Internal_Sym *local_syms, 1346 asection **local_sections) 1347{ 1348 Elf_Internal_Shdr *symtab_hdr; 1349 struct elf_link_hash_entry **sym_hashes; 1350 Elf_Internal_Rela *rel, *relend; 1351 struct spu_link_hash_table *htab; 1352 bfd_boolean ret = TRUE; 1353 1354 if (info->relocatable) 1355 return TRUE; 1356 1357 htab = spu_hash_table (info); 1358 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 1359 sym_hashes = (struct elf_link_hash_entry **) (elf_sym_hashes (input_bfd)); 1360 1361 rel = relocs; 1362 relend = relocs + input_section->reloc_count; 1363 for (; rel < relend; rel++) 1364 { 1365 int r_type; 1366 reloc_howto_type *howto; 1367 unsigned long r_symndx; 1368 Elf_Internal_Sym *sym; 1369 asection *sec; 1370 struct elf_link_hash_entry *h; 1371 const char *sym_name; 1372 bfd_vma relocation; 1373 bfd_vma addend; 1374 bfd_reloc_status_type r; 1375 bfd_boolean unresolved_reloc; 1376 bfd_boolean warned; 1377 1378 r_symndx = ELF32_R_SYM (rel->r_info); 1379 r_type = ELF32_R_TYPE (rel->r_info); 1380 howto = elf_howto_table + r_type; 1381 unresolved_reloc = FALSE; 1382 warned = FALSE; 1383 1384 h = NULL; 1385 sym = NULL; 1386 sec = NULL; 1387 if (r_symndx < symtab_hdr->sh_info) 1388 { 1389 sym = local_syms + r_symndx; 1390 sec = local_sections[r_symndx]; 1391 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec); 1392 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 1393 } 1394 else 1395 { 1396 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 1397 r_symndx, symtab_hdr, sym_hashes, 1398 h, sec, relocation, 1399 unresolved_reloc, warned); 1400 sym_name = h->root.root.string; 1401 } 1402 1403 if (unresolved_reloc) 1404 { 1405 (*_bfd_error_handler) 1406 (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"), 1407 input_bfd, 1408 bfd_get_section_name (input_bfd, input_section), 1409 (long) rel->r_offset, 1410 howto->name, 1411 sym_name); 1412 ret = FALSE; 1413 } 1414 1415 /* If this symbol is in an overlay area, we may need to relocate 1416 to the overlay stub. */ 1417 addend = rel->r_addend; 1418 if (sec != NULL 1419 && sec->output_section != NULL 1420 && sec->output_section->owner == output_bfd 1421 && (spu_elf_section_data (sec->output_section)->ovl_index != 0 1422 || htab->non_overlay_stubs) 1423 && !(sec == input_section 1424 && is_branch (contents + rel->r_offset))) 1425 { 1426 char *stub_name; 1427 struct spu_stub_hash_entry *sh; 1428 1429 stub_name = spu_stub_name (input_section, sec, h, rel); 1430 if (stub_name == NULL) 1431 return FALSE; 1432 1433 sh = (struct spu_stub_hash_entry *) 1434 bfd_hash_lookup (&htab->stub_hash_table, stub_name, FALSE, FALSE); 1435 if (sh != NULL) 1436 { 1437 relocation = (htab->stub->output_section->vma 1438 + htab->stub->output_offset 1439 + sh->off); 1440 addend = 0; 1441 } 1442 free (stub_name); 1443 } 1444 1445 r = _bfd_final_link_relocate (howto, 1446 input_bfd, 1447 input_section, 1448 contents, 1449 rel->r_offset, relocation, addend); 1450 1451 if (r != bfd_reloc_ok) 1452 { 1453 const char *msg = (const char *) 0; 1454 1455 switch (r) 1456 { 1457 case bfd_reloc_overflow: 1458 if (!((*info->callbacks->reloc_overflow) 1459 (info, (h ? &h->root : NULL), sym_name, howto->name, 1460 (bfd_vma) 0, input_bfd, input_section, rel->r_offset))) 1461 return FALSE; 1462 break; 1463 1464 case bfd_reloc_undefined: 1465 if (!((*info->callbacks->undefined_symbol) 1466 (info, sym_name, input_bfd, input_section, 1467 rel->r_offset, TRUE))) 1468 return FALSE; 1469 break; 1470 1471 case bfd_reloc_outofrange: 1472 msg = _("internal error: out of range error"); 1473 goto common_error; 1474 1475 case bfd_reloc_notsupported: 1476 msg = _("internal error: unsupported relocation error"); 1477 goto common_error; 1478 1479 case bfd_reloc_dangerous: 1480 msg = _("internal error: dangerous error"); 1481 goto common_error; 1482 1483 default: 1484 msg = _("internal error: unknown error"); 1485 /* fall through */ 1486 1487 common_error: 1488 if (!((*info->callbacks->warning) 1489 (info, msg, sym_name, input_bfd, input_section, 1490 rel->r_offset))) 1491 return FALSE; 1492 break; 1493 } 1494 } 1495 } 1496 1497 return ret; 1498} 1499 1500static int spu_plugin = 0; 1501 1502void 1503spu_elf_plugin (int val) 1504{ 1505 spu_plugin = val; 1506} 1507 1508/* Set ELF header e_type for plugins. */ 1509 1510static void 1511spu_elf_post_process_headers (bfd *abfd, 1512 struct bfd_link_info *info ATTRIBUTE_UNUSED) 1513{ 1514 if (spu_plugin) 1515 { 1516 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); 1517 1518 i_ehdrp->e_type = ET_DYN; 1519 } 1520} 1521 1522/* We may add an extra PT_LOAD segment for .toe. We also need extra 1523 segments for overlays. */ 1524 1525static int 1526spu_elf_additional_program_headers (bfd *abfd, struct bfd_link_info *info) 1527{ 1528 struct spu_link_hash_table *htab = spu_hash_table (info); 1529 int extra = htab->num_overlays; 1530 asection *sec; 1531 1532 if (extra) 1533 ++extra; 1534 1535 sec = bfd_get_section_by_name (abfd, ".toe"); 1536 if (sec != NULL && (sec->flags & SEC_LOAD) != 0) 1537 ++extra; 1538 1539 return extra; 1540} 1541 1542/* Remove .toe section from other PT_LOAD segments and put it in 1543 a segment of its own. Put overlays in separate segments too. */ 1544 1545static bfd_boolean 1546spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) 1547{ 1548 asection *toe, *s; 1549 struct elf_segment_map *m; 1550 unsigned int i; 1551 1552 if (info == NULL) 1553 return TRUE; 1554 1555 toe = bfd_get_section_by_name (abfd, ".toe"); 1556 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) 1557 if (m->p_type == PT_LOAD && m->count > 1) 1558 for (i = 0; i < m->count; i++) 1559 if ((s = m->sections[i]) == toe 1560 || spu_elf_section_data (s)->ovl_index != 0) 1561 { 1562 struct elf_segment_map *m2; 1563 bfd_vma amt; 1564 1565 if (i + 1 < m->count) 1566 { 1567 amt = sizeof (struct elf_segment_map); 1568 amt += (m->count - (i + 2)) * sizeof (m->sections[0]); 1569 m2 = bfd_zalloc (abfd, amt); 1570 if (m2 == NULL) 1571 return FALSE; 1572 m2->count = m->count - (i + 1); 1573 memcpy (m2->sections, m->sections + i + 1, 1574 m2->count * sizeof (m->sections[0])); 1575 m2->p_type = PT_LOAD; 1576 m2->next = m->next; 1577 m->next = m2; 1578 } 1579 m->count = 1; 1580 if (i != 0) 1581 { 1582 m->count = i; 1583 amt = sizeof (struct elf_segment_map); 1584 m2 = bfd_zalloc (abfd, amt); 1585 if (m2 == NULL) 1586 return FALSE; 1587 m2->p_type = PT_LOAD; 1588 m2->count = 1; 1589 m2->sections[0] = s; 1590 m2->next = m->next; 1591 m->next = m2; 1592 } 1593 break; 1594 } 1595 1596 return TRUE; 1597} 1598 1599/* Check that all loadable section VMAs lie in the range 1600 LO .. HI inclusive. */ 1601 1602asection * 1603spu_elf_check_vma (bfd *abfd, bfd_vma lo, bfd_vma hi) 1604{ 1605 struct elf_segment_map *m; 1606 unsigned int i; 1607 1608 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) 1609 if (m->p_type == PT_LOAD) 1610 for (i = 0; i < m->count; i++) 1611 if (m->sections[i]->size != 0 1612 && (m->sections[i]->vma < lo 1613 || m->sections[i]->vma > hi 1614 || m->sections[i]->vma + m->sections[i]->size - 1 > hi)) 1615 return m->sections[i]; 1616 1617 return NULL; 1618} 1619 1620/* Tweak phdrs before writing them out. */ 1621 1622static int 1623spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info) 1624{ 1625 const struct elf_backend_data *bed; 1626 struct elf_obj_tdata *tdata; 1627 Elf_Internal_Phdr *phdr, *last; 1628 struct spu_link_hash_table *htab; 1629 unsigned int count; 1630 unsigned int i; 1631 1632 if (info == NULL) 1633 return TRUE; 1634 1635 bed = get_elf_backend_data (abfd); 1636 tdata = elf_tdata (abfd); 1637 phdr = tdata->phdr; 1638 count = tdata->program_header_size / bed->s->sizeof_phdr; 1639 htab = spu_hash_table (info); 1640 if (htab->num_overlays != 0) 1641 { 1642 struct elf_segment_map *m; 1643 unsigned int o; 1644 1645 for (i = 0, m = elf_tdata (abfd)->segment_map; m; ++i, m = m->next) 1646 if (m->count != 0 1647 && (o = spu_elf_section_data (m->sections[0])->ovl_index) != 0) 1648 { 1649 /* Mark this as an overlay header. */ 1650 phdr[i].p_flags |= PF_OVERLAY; 1651 1652 if (htab->ovtab != NULL && htab->ovtab->size != 0) 1653 { 1654 bfd_byte *p = htab->ovtab->contents; 1655 unsigned int off = (o - 1) * 16 + 8; 1656 1657 /* Write file_off into _ovly_table. */ 1658 bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off); 1659 } 1660 } 1661 } 1662 1663 /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples 1664 of 16. This should always be possible when using the standard 1665 linker scripts, but don't create overlapping segments if 1666 someone is playing games with linker scripts. */ 1667 last = NULL; 1668 for (i = count; i-- != 0; ) 1669 if (phdr[i].p_type == PT_LOAD) 1670 { 1671 unsigned adjust; 1672 1673 adjust = -phdr[i].p_filesz & 15; 1674 if (adjust != 0 1675 && last != NULL 1676 && phdr[i].p_offset + phdr[i].p_filesz > last->p_offset - adjust) 1677 break; 1678 1679 adjust = -phdr[i].p_memsz & 15; 1680 if (adjust != 0 1681 && last != NULL 1682 && phdr[i].p_filesz != 0 1683 && phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust 1684 && phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr) 1685 break; 1686 1687 if (phdr[i].p_filesz != 0) 1688 last = &phdr[i]; 1689 } 1690 1691 if (i == (unsigned int) -1) 1692 for (i = count; i-- != 0; ) 1693 if (phdr[i].p_type == PT_LOAD) 1694 { 1695 unsigned adjust; 1696 1697 adjust = -phdr[i].p_filesz & 15; 1698 phdr[i].p_filesz += adjust; 1699 1700 adjust = -phdr[i].p_memsz & 15; 1701 phdr[i].p_memsz += adjust; 1702 } 1703 1704 return TRUE; 1705} 1706 1707/* Arrange for our linker created section to be output. */ 1708 1709static bfd_boolean 1710spu_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, 1711 Elf_Internal_Shdr *i_shdrp) 1712{ 1713 asection *sec; 1714 1715 sec = i_shdrp->bfd_section; 1716 if (sec != NULL 1717 && (sec->flags & SEC_LINKER_CREATED) != 0 1718 && sec->name != NULL 1719 && strcmp (sec->name, SPU_PTNOTE_SPUNAME) == 0) 1720 i_shdrp->contents = sec->contents; 1721 1722 return TRUE; 1723} 1724 1725#define TARGET_BIG_SYM bfd_elf32_spu_vec 1726#define TARGET_BIG_NAME "elf32-spu" 1727#define ELF_ARCH bfd_arch_spu 1728#define ELF_MACHINE_CODE EM_SPU 1729/* This matches the alignment need for DMA. */ 1730#define ELF_MAXPAGESIZE 0x80 1731#define elf_backend_rela_normal 1 1732#define elf_backend_can_gc_sections 1 1733 1734#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup 1735#define elf_info_to_howto spu_elf_info_to_howto 1736#define elf_backend_gc_mark_hook spu_elf_gc_mark_hook 1737#define elf_backend_relocate_section spu_elf_relocate_section 1738#define elf_backend_symbol_processing spu_elf_backend_symbol_processing 1739#define bfd_elf32_new_section_hook spu_elf_new_section_hook 1740#define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create 1741#define bfd_elf32_bfd_link_hash_table_free spu_elf_link_hash_table_free 1742 1743#define elf_backend_additional_program_headers spu_elf_additional_program_headers 1744#define elf_backend_modify_segment_map spu_elf_modify_segment_map 1745#define elf_backend_modify_program_headers spu_elf_modify_program_headers 1746#define elf_backend_post_process_headers spu_elf_post_process_headers 1747#define elf_backend_section_processing spu_elf_section_processing 1748#define elf_backend_special_sections spu_elf_special_sections 1749 1750#include "elf32-target.h" 1751