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