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