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