OSDN Git Service

7b08e3cd6a2c9ded902988dba49cd259d45e068e
[pf3gnuchains/pf3gnuchains3x.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 /* Apply R_SPU_REL9 and R_SPU_REL9I relocs.  */
146
147 static bfd_reloc_status_type
148 spu_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
194 static bfd_boolean
195 spu_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
213 static void
214 spu_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
224 struct 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
265 struct 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
282 static struct bfd_hash_entry *
283 stub_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
313 static struct bfd_link_hash_table *
314 spu_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
343 static void
344 spu_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
356 static bfd_boolean
357 get_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
433 static char *
434 spu_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
481 bfd_boolean
482 spu_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
532 static asection *
533 spu_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
562 static int
563 sort_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
577 bfd_boolean
578 spu_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
678 static bfd_boolean
679 is_branch (const unsigned char *insn)
680 {
681   return (((insn[0] & 0xec) == 0x20 && (insn[1] & 0x80) == 0)
682           || (insn[0] & 0xfc) == 0x10);
683 }
684
685 struct 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
693 static bfd_boolean
694 populate_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
704 static int
705 sort_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
734 bfd_boolean
735 spu_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_sec->owner, sym_name);
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
1054 static void *
1055 ovl_mgr_open (struct bfd *nbfd ATTRIBUTE_UNUSED, void *stream)
1056 {
1057   return stream;
1058 }
1059
1060 static file_ptr
1061 ovl_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 = (const char *) os->end - (const 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, (const char *) os->start + offset, count);
1082   return count;
1083 }
1084
1085 bfd_boolean
1086 spu_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
1101 static bfd_boolean
1102 write_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
1180 static struct elf_link_hash_entry *
1181 define_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
1214 bfd_boolean
1215 spu_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
1338 static bfd_boolean
1339 spu_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
1500 static int spu_plugin = 0;
1501
1502 void
1503 spu_elf_plugin (int val)
1504 {
1505   spu_plugin = val;
1506 }
1507
1508 /* Set ELF header e_type for plugins.  */
1509
1510 static void
1511 spu_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
1525 static int
1526 spu_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
1545 static bfd_boolean
1546 spu_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
1602 asection *
1603 spu_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
1622 static int
1623 spu_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
1709 static bfd_boolean
1710 spu_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"