From Craig Silverstein: implement -z defs.
[deliverable/binutils-gdb.git] / bfd / elf32-spu.c
CommitLineData
e9f53129
AM
1/* SPU specific support for 32-bit ELF
2
d16c7321 3 Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
e9f53129
AM
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
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
e9f53129
AM
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
e9f53129 21#include "sysdep.h"
3db64b00 22#include "bfd.h"
e9f53129
AM
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),
b427ea91 57 HOWTO (R_SPU_ADDR32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
e9f53129
AM
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),
b427ea91 78 HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
e9f53129
AM
79 bfd_elf_generic_reloc, "SPU_REL32",
80 FALSE, 0, 0xffffffff, TRUE),
4f4416b5
AM
81 HOWTO (R_SPU_ADDR16X, 0, 2, 16, FALSE, 7, complain_overflow_bitfield,
82 bfd_elf_generic_reloc, "SPU_ADDR16X",
83 FALSE, 0, 0x007fff80, FALSE),
b427ea91 84 HOWTO (R_SPU_PPU32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
ece5ef60
AM
85 bfd_elf_generic_reloc, "SPU_PPU32",
86 FALSE, 0, 0xffffffff, FALSE),
b427ea91 87 HOWTO (R_SPU_PPU64, 0, 4, 64, FALSE, 0, complain_overflow_dont,
ece5ef60
AM
88 bfd_elf_generic_reloc, "SPU_PPU64",
89 FALSE, 0, -1, FALSE),
e9f53129
AM
90};
91
92static struct bfd_elf_special_section const spu_elf_special_sections[] = {
93 { ".toe", 4, 0, SHT_NOBITS, SHF_ALLOC },
94 { NULL, 0, 0, 0, 0 }
95};
96
97static enum elf_spu_reloc_type
98spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
99{
100 switch (code)
101 {
102 default:
103 return R_SPU_NONE;
104 case BFD_RELOC_SPU_IMM10W:
105 return R_SPU_ADDR10;
106 case BFD_RELOC_SPU_IMM16W:
107 return R_SPU_ADDR16;
108 case BFD_RELOC_SPU_LO16:
109 return R_SPU_ADDR16_LO;
110 case BFD_RELOC_SPU_HI16:
111 return R_SPU_ADDR16_HI;
112 case BFD_RELOC_SPU_IMM18:
113 return R_SPU_ADDR18;
114 case BFD_RELOC_SPU_PCREL16:
115 return R_SPU_REL16;
116 case BFD_RELOC_SPU_IMM7:
117 return R_SPU_ADDR7;
118 case BFD_RELOC_SPU_IMM8:
119 return R_SPU_NONE;
120 case BFD_RELOC_SPU_PCREL9a:
121 return R_SPU_REL9;
122 case BFD_RELOC_SPU_PCREL9b:
123 return R_SPU_REL9I;
124 case BFD_RELOC_SPU_IMM10:
125 return R_SPU_ADDR10I;
126 case BFD_RELOC_SPU_IMM16:
127 return R_SPU_ADDR16I;
128 case BFD_RELOC_32:
129 return R_SPU_ADDR32;
130 case BFD_RELOC_32_PCREL:
131 return R_SPU_REL32;
ece5ef60
AM
132 case BFD_RELOC_SPU_PPU32:
133 return R_SPU_PPU32;
134 case BFD_RELOC_SPU_PPU64:
135 return R_SPU_PPU64;
e9f53129
AM
136 }
137}
138
139static void
140spu_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
141 arelent *cache_ptr,
142 Elf_Internal_Rela *dst)
143{
144 enum elf_spu_reloc_type r_type;
145
146 r_type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info);
147 BFD_ASSERT (r_type < R_SPU_max);
148 cache_ptr->howto = &elf_howto_table[(int) r_type];
149}
150
151static reloc_howto_type *
152spu_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
153 bfd_reloc_code_real_type code)
154{
b16f296e
AM
155 enum elf_spu_reloc_type r_type = spu_elf_bfd_to_reloc_type (code);
156
157 if (r_type == R_SPU_NONE)
158 return NULL;
159
160 return elf_howto_table + r_type;
e9f53129
AM
161}
162
157090f7
AM
163static reloc_howto_type *
164spu_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
165 const char *r_name)
166{
167 unsigned int i;
168
169 for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
170 if (elf_howto_table[i].name != NULL
171 && strcasecmp (elf_howto_table[i].name, r_name) == 0)
172 return &elf_howto_table[i];
173
174 return NULL;
175}
176
e9f53129
AM
177/* Apply R_SPU_REL9 and R_SPU_REL9I relocs. */
178
179static bfd_reloc_status_type
180spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
181 void *data, asection *input_section,
182 bfd *output_bfd, char **error_message)
183{
184 bfd_size_type octets;
185 bfd_vma val;
186 long insn;
187
188 /* If this is a relocatable link (output_bfd test tells us), just
189 call the generic function. Any adjustment will be done at final
190 link time. */
191 if (output_bfd != NULL)
192 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
193 input_section, output_bfd, error_message);
194
195 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
196 return bfd_reloc_outofrange;
197 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
198
199 /* Get symbol value. */
200 val = 0;
201 if (!bfd_is_com_section (symbol->section))
202 val = symbol->value;
203 if (symbol->section->output_section)
204 val += symbol->section->output_section->vma;
205
206 val += reloc_entry->addend;
207
208 /* Make it pc-relative. */
209 val -= input_section->output_section->vma + input_section->output_offset;
210
211 val >>= 2;
212 if (val + 256 >= 512)
213 return bfd_reloc_overflow;
214
215 insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
216
217 /* Move two high bits of value to REL9I and REL9 position.
218 The mask will take care of selecting the right field. */
219 val = (val & 0x7f) | ((val & 0x180) << 7) | ((val & 0x180) << 16);
220 insn &= ~reloc_entry->howto->dst_mask;
221 insn |= val & reloc_entry->howto->dst_mask;
222 bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
223 return bfd_reloc_ok;
224}
225
226static bfd_boolean
227spu_elf_new_section_hook (bfd *abfd, asection *sec)
228{
229 if (!sec->used_by_bfd)
230 {
231 struct _spu_elf_section_data *sdata;
232
233 sdata = bfd_zalloc (abfd, sizeof (*sdata));
234 if (sdata == NULL)
235 return FALSE;
236 sec->used_by_bfd = sdata;
237 }
238
239 return _bfd_elf_new_section_hook (abfd, sec);
240}
241
242/* Specially mark defined symbols named _EAR_* with BSF_KEEP so that
243 strip --strip-unneeded will not remove them. */
244
245static void
246spu_elf_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
247{
248 if (sym->name != NULL
249 && sym->section != bfd_abs_section_ptr
250 && strncmp (sym->name, "_EAR_", 5) == 0)
251 sym->flags |= BSF_KEEP;
252}
253
254/* SPU ELF linker hash table. */
255
256struct spu_link_hash_table
257{
258 struct elf_link_hash_table elf;
259
e9f53129 260 /* Shortcuts to overlay sections. */
e9f53129 261 asection *ovtab;
47f6dab9
AM
262 asection *toe;
263 asection **ovl_sec;
264
265 /* Count of stubs in each overlay section. */
266 unsigned int *stub_count;
267
268 /* The stub section for each overlay section. */
269 asection **stub_sec;
e9f53129
AM
270
271 struct elf_link_hash_entry *ovly_load;
47f6dab9 272 struct elf_link_hash_entry *ovly_return;
2cb5950e 273 unsigned long ovly_load_r_symndx;
e9f53129 274
e9f53129
AM
275 /* Number of overlay buffers. */
276 unsigned int num_buf;
277
278 /* Total number of overlays. */
279 unsigned int num_overlays;
280
281 /* Set if we should emit symbols for stubs. */
282 unsigned int emit_stub_syms:1;
283
284 /* Set if we want stubs on calls out of overlay regions to
285 non-overlay regions. */
286 unsigned int non_overlay_stubs : 1;
287
288 /* Set on error. */
47f6dab9 289 unsigned int stub_err : 1;
49fa1e15
AM
290
291 /* Set if stack size analysis should be done. */
292 unsigned int stack_analysis : 1;
293
294 /* Set if __stack_* syms will be emitted. */
295 unsigned int emit_stack_syms : 1;
e9f53129
AM
296};
297
47f6dab9 298/* Hijack the generic got fields for overlay stub accounting. */
e9f53129 299
47f6dab9 300struct got_entry
e9f53129 301{
47f6dab9
AM
302 struct got_entry *next;
303 unsigned int ovl;
4a628337 304 bfd_vma addend;
47f6dab9 305 bfd_vma stub_addr;
e9f53129
AM
306};
307
47f6dab9
AM
308#define spu_hash_table(p) \
309 ((struct spu_link_hash_table *) ((p)->hash))
e9f53129
AM
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
47f6dab9
AM
330 memset (&htab->ovtab, 0,
331 sizeof (*htab) - offsetof (struct spu_link_hash_table, ovtab));
e9f53129 332
47f6dab9
AM
333 htab->elf.init_got_refcount.refcount = 0;
334 htab->elf.init_got_refcount.glist = NULL;
335 htab->elf.init_got_offset.offset = 0;
336 htab->elf.init_got_offset.glist = NULL;
e9f53129
AM
337 return &htab->elf.root;
338}
339
e9f53129
AM
340/* Find the symbol for the given R_SYMNDX in IBFD and set *HP and *SYMP
341 to (hash, NULL) for global symbols, and (NULL, sym) for locals. Set
342 *SYMSECP to the symbol's section. *LOCSYMSP caches local syms. */
343
344static bfd_boolean
345get_sym_h (struct elf_link_hash_entry **hp,
346 Elf_Internal_Sym **symp,
347 asection **symsecp,
348 Elf_Internal_Sym **locsymsp,
349 unsigned long r_symndx,
350 bfd *ibfd)
351{
352 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
353
354 if (r_symndx >= symtab_hdr->sh_info)
355 {
356 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
357 struct elf_link_hash_entry *h;
358
359 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
360 while (h->root.type == bfd_link_hash_indirect
361 || h->root.type == bfd_link_hash_warning)
362 h = (struct elf_link_hash_entry *) h->root.u.i.link;
363
364 if (hp != NULL)
365 *hp = h;
366
367 if (symp != NULL)
368 *symp = NULL;
369
370 if (symsecp != NULL)
371 {
372 asection *symsec = NULL;
373 if (h->root.type == bfd_link_hash_defined
374 || h->root.type == bfd_link_hash_defweak)
375 symsec = h->root.u.def.section;
376 *symsecp = symsec;
377 }
378 }
379 else
380 {
381 Elf_Internal_Sym *sym;
382 Elf_Internal_Sym *locsyms = *locsymsp;
383
384 if (locsyms == NULL)
385 {
386 locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
387 if (locsyms == NULL)
49fa1e15
AM
388 {
389 size_t symcount = symtab_hdr->sh_info;
390
391 /* If we are reading symbols into the contents, then
392 read the global syms too. This is done to cache
393 syms for later stack analysis. */
394 if ((unsigned char **) locsymsp == &symtab_hdr->contents)
395 symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
396 locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
397 NULL, NULL, NULL);
398 }
e9f53129
AM
399 if (locsyms == NULL)
400 return FALSE;
401 *locsymsp = locsyms;
402 }
403 sym = locsyms + r_symndx;
404
405 if (hp != NULL)
406 *hp = NULL;
407
408 if (symp != NULL)
409 *symp = sym;
410
411 if (symsecp != NULL)
cb33740c 412 *symsecp = bfd_section_from_elf_index (ibfd, sym->st_shndx);
e9f53129 413 }
49fa1e15 414
e9f53129
AM
415 return TRUE;
416}
417
e9f53129
AM
418/* Create the note section if not already present. This is done early so
419 that the linker maps the sections to the right place in the output. */
420
421bfd_boolean
49fa1e15
AM
422spu_elf_create_sections (bfd *output_bfd,
423 struct bfd_link_info *info,
424 int stack_analysis,
425 int emit_stack_syms)
e9f53129
AM
426{
427 bfd *ibfd;
49fa1e15
AM
428 struct spu_link_hash_table *htab = spu_hash_table (info);
429
430 /* Stash some options away where we can get at them later. */
431 htab->stack_analysis = stack_analysis;
432 htab->emit_stack_syms = emit_stack_syms;
e9f53129 433
58eb693e 434 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
e9f53129
AM
435 if (bfd_get_section_by_name (ibfd, SPU_PTNOTE_SPUNAME) != NULL)
436 break;
437
438 if (ibfd == NULL)
439 {
440 /* Make SPU_PTNOTE_SPUNAME section. */
441 asection *s;
442 size_t name_len;
443 size_t size;
444 bfd_byte *data;
445 flagword flags;
446
447 ibfd = info->input_bfds;
448 flags = SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
449 s = bfd_make_section_anyway_with_flags (ibfd, SPU_PTNOTE_SPUNAME, flags);
450 if (s == NULL
451 || !bfd_set_section_alignment (ibfd, s, 4))
452 return FALSE;
453
454 name_len = strlen (bfd_get_filename (output_bfd)) + 1;
455 size = 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4);
456 size += (name_len + 3) & -4;
457
458 if (!bfd_set_section_size (ibfd, s, size))
459 return FALSE;
460
461 data = bfd_zalloc (ibfd, size);
462 if (data == NULL)
463 return FALSE;
464
465 bfd_put_32 (ibfd, sizeof (SPU_PLUGIN_NAME), data + 0);
466 bfd_put_32 (ibfd, name_len, data + 4);
467 bfd_put_32 (ibfd, 1, data + 8);
468 memcpy (data + 12, SPU_PLUGIN_NAME, sizeof (SPU_PLUGIN_NAME));
469 memcpy (data + 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4),
470 bfd_get_filename (output_bfd), name_len);
471 s->contents = data;
472 }
473
474 return TRUE;
475}
476
e9f53129
AM
477/* qsort predicate to sort sections by vma. */
478
479static int
480sort_sections (const void *a, const void *b)
481{
482 const asection *const *s1 = a;
483 const asection *const *s2 = b;
484 bfd_signed_vma delta = (*s1)->vma - (*s2)->vma;
485
486 if (delta != 0)
487 return delta < 0 ? -1 : 1;
488
489 return (*s1)->index - (*s2)->index;
490}
491
492/* Identify overlays in the output bfd, and number them. */
493
494bfd_boolean
495spu_elf_find_overlays (bfd *output_bfd, struct bfd_link_info *info)
496{
497 struct spu_link_hash_table *htab = spu_hash_table (info);
498 asection **alloc_sec;
499 unsigned int i, n, ovl_index, num_buf;
500 asection *s;
501 bfd_vma ovl_end;
502
503 if (output_bfd->section_count < 2)
504 return FALSE;
505
506 alloc_sec = bfd_malloc (output_bfd->section_count * sizeof (*alloc_sec));
507 if (alloc_sec == NULL)
508 return FALSE;
509
510 /* Pick out all the alloced sections. */
511 for (n = 0, s = output_bfd->sections; s != NULL; s = s->next)
512 if ((s->flags & SEC_ALLOC) != 0
513 && (s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != SEC_THREAD_LOCAL
514 && s->size != 0)
515 alloc_sec[n++] = s;
516
517 if (n == 0)
518 {
519 free (alloc_sec);
520 return FALSE;
521 }
522
523 /* Sort them by vma. */
524 qsort (alloc_sec, n, sizeof (*alloc_sec), sort_sections);
525
526 /* Look for overlapping vmas. Any with overlap must be overlays.
47f6dab9 527 Count them. Also count the number of overlay regions. */
e9f53129
AM
528 ovl_end = alloc_sec[0]->vma + alloc_sec[0]->size;
529 for (ovl_index = 0, num_buf = 0, i = 1; i < n; i++)
530 {
531 s = alloc_sec[i];
532 if (s->vma < ovl_end)
533 {
534 asection *s0 = alloc_sec[i - 1];
535
47f6dab9 536 if (spu_elf_section_data (s0)->u.o.ovl_index == 0)
e9f53129 537 {
47f6dab9
AM
538 alloc_sec[ovl_index] = s0;
539 spu_elf_section_data (s0)->u.o.ovl_index = ++ovl_index;
540 spu_elf_section_data (s0)->u.o.ovl_buf = ++num_buf;
e9f53129 541 }
47f6dab9
AM
542 alloc_sec[ovl_index] = s;
543 spu_elf_section_data (s)->u.o.ovl_index = ++ovl_index;
544 spu_elf_section_data (s)->u.o.ovl_buf = num_buf;
545 if (s0->vma != s->vma)
e9f53129 546 {
47f6dab9
AM
547 info->callbacks->einfo (_("%X%P: overlay sections %A and %A "
548 "do not start at the same address.\n"),
549 s0, s);
550 return FALSE;
e9f53129 551 }
47f6dab9
AM
552 if (ovl_end < s->vma + s->size)
553 ovl_end = s->vma + s->size;
e9f53129
AM
554 }
555 else
556 ovl_end = s->vma + s->size;
557 }
558
559 htab->num_overlays = ovl_index;
560 htab->num_buf = num_buf;
47f6dab9 561 htab->ovl_sec = alloc_sec;
fdba2fcd
AM
562 htab->ovly_load = elf_link_hash_lookup (&htab->elf, "__ovly_load",
563 FALSE, FALSE, FALSE);
564 htab->ovly_return = elf_link_hash_lookup (&htab->elf, "__ovly_return",
565 FALSE, FALSE, FALSE);
47f6dab9 566 return ovl_index != 0;
e9f53129
AM
567}
568
47f6dab9
AM
569/* Support two sizes of overlay stubs, a slower more compact stub of two
570 intructions, and a faster stub of four instructions. */
571#ifndef OVL_STUB_SIZE
572/* Default to faster. */
573#define OVL_STUB_SIZE 16
574/* #define OVL_STUB_SIZE 8 */
575#endif
576#define BRSL 0x33000000
577#define BR 0x32000000
e9f53129 578#define NOP 0x40200000
47f6dab9
AM
579#define LNOP 0x00200000
580#define ILA 0x42000000
e9f53129 581
49fa1e15 582/* Return true for all relative and absolute branch instructions.
e9f53129
AM
583 bra 00110000 0..
584 brasl 00110001 0..
585 br 00110010 0..
586 brsl 00110011 0..
587 brz 00100000 0..
588 brnz 00100001 0..
589 brhz 00100010 0..
49fa1e15
AM
590 brhnz 00100011 0.. */
591
592static bfd_boolean
593is_branch (const unsigned char *insn)
594{
595 return (insn[0] & 0xec) == 0x20 && (insn[1] & 0x80) == 0;
596}
597
fad9eaf0
AM
598/* Return true for all indirect branch instructions.
599 bi 00110101 000
600 bisl 00110101 001
601 iret 00110101 010
602 bisled 00110101 011
603 biz 00100101 000
604 binz 00100101 001
605 bihz 00100101 010
606 bihnz 00100101 011 */
607
608static bfd_boolean
609is_indirect_branch (const unsigned char *insn)
610{
611 return (insn[0] & 0xef) == 0x25 && (insn[1] & 0x80) == 0;
612}
613
49fa1e15 614/* Return true for branch hint instructions.
e9f53129
AM
615 hbra 0001000..
616 hbrr 0001001.. */
617
618static bfd_boolean
49fa1e15 619is_hint (const unsigned char *insn)
e9f53129 620{
49fa1e15 621 return (insn[0] & 0xfc) == 0x10;
e9f53129
AM
622}
623
fdba2fcd 624/* True if INPUT_SECTION might need overlay stubs. */
aa7a0635
AM
625
626static bfd_boolean
fdba2fcd
AM
627maybe_needs_stubs (asection *input_section, bfd *output_bfd)
628{
629 /* No stubs for debug sections and suchlike. */
630 if ((input_section->flags & SEC_ALLOC) == 0)
631 return FALSE;
632
633 /* No stubs for link-once sections that will be discarded. */
634 if (input_section->output_section == NULL
635 || input_section->output_section->owner != output_bfd)
636 return FALSE;
637
638 /* Don't create stubs for .eh_frame references. */
639 if (strcmp (input_section->name, ".eh_frame") == 0)
640 return FALSE;
641
642 return TRUE;
643}
644
645enum _stub_type
646{
647 no_stub,
648 ovl_stub,
649 nonovl_stub,
650 stub_error
651};
652
653/* Return non-zero if this reloc symbol should go via an overlay stub.
654 Return 2 if the stub must be in non-overlay area. */
655
656static enum _stub_type
657needs_ovl_stub (struct elf_link_hash_entry *h,
658 Elf_Internal_Sym *sym,
aa7a0635
AM
659 asection *sym_sec,
660 asection *input_section,
fdba2fcd
AM
661 Elf_Internal_Rela *irela,
662 bfd_byte *contents,
663 struct bfd_link_info *info)
aa7a0635 664{
fdba2fcd
AM
665 struct spu_link_hash_table *htab = spu_hash_table (info);
666 enum elf_spu_reloc_type r_type;
667 unsigned int sym_type;
668 bfd_boolean branch;
669 enum _stub_type ret = no_stub;
aa7a0635
AM
670
671 if (sym_sec == NULL
2c67c5f3 672 || sym_sec->output_section == NULL
fdba2fcd 673 || sym_sec->output_section->owner != info->output_bfd
2c67c5f3 674 || spu_elf_section_data (sym_sec->output_section) == NULL)
fdba2fcd 675 return ret;
aa7a0635 676
fdba2fcd
AM
677 if (h != NULL)
678 {
679 /* Ensure no stubs for user supplied overlay manager syms. */
680 if (h == htab->ovly_load || h == htab->ovly_return)
681 return ret;
682
683 /* setjmp always goes via an overlay stub, because then the return
684 and hence the longjmp goes via __ovly_return. That magically
685 makes setjmp/longjmp between overlays work. */
686 if (strncmp (h->root.root.string, "setjmp", 6) == 0
687 && (h->root.root.string[6] == '\0' || h->root.root.string[6] == '@'))
688 ret = ovl_stub;
689 }
aa7a0635
AM
690
691 /* Usually, symbols in non-overlay sections don't need stubs. */
47f6dab9 692 if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index == 0
aa7a0635 693 && !htab->non_overlay_stubs)
fdba2fcd
AM
694 return ret;
695
696 if (h != NULL)
697 sym_type = h->type;
698 else
699 sym_type = ELF_ST_TYPE (sym->st_info);
700
701 r_type = ELF32_R_TYPE (irela->r_info);
702 branch = FALSE;
703 if (r_type == R_SPU_REL16 || r_type == R_SPU_ADDR16)
704 {
705 bfd_byte insn[4];
706
707 if (contents == NULL)
708 {
709 contents = insn;
710 if (!bfd_get_section_contents (input_section->owner,
711 input_section,
712 contents,
713 irela->r_offset, 4))
714 return stub_error;
715 }
716 else
717 contents += irela->r_offset;
718
719 if (is_branch (contents) || is_hint (contents))
720 {
721 branch = TRUE;
722 if ((contents[0] & 0xfd) == 0x31
723 && sym_type != STT_FUNC
724 && contents == insn)
725 {
726 /* It's common for people to write assembly and forget
727 to give function symbols the right type. Handle
728 calls to such symbols, but warn so that (hopefully)
729 people will fix their code. We need the symbol
730 type to be correct to distinguish function pointer
731 initialisation from other pointer initialisations. */
732 const char *sym_name;
733
734 if (h != NULL)
735 sym_name = h->root.root.string;
736 else
737 {
738 Elf_Internal_Shdr *symtab_hdr;
739 symtab_hdr = &elf_tdata (input_section->owner)->symtab_hdr;
740 sym_name = bfd_elf_sym_name (input_section->owner,
741 symtab_hdr,
742 sym,
743 sym_sec);
744 }
745 (*_bfd_error_handler) (_("warning: call to non-function"
746 " symbol %s defined in %B"),
747 sym_sec->owner, sym_name);
748
749 }
750 }
751 }
752
753 if (sym_type != STT_FUNC
754 && !branch
755 && (sym_sec->flags & SEC_CODE) == 0)
756 return ret;
aa7a0635
AM
757
758 /* A reference from some other section to a symbol in an overlay
759 section needs a stub. */
47f6dab9
AM
760 if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index
761 != spu_elf_section_data (input_section->output_section)->u.o.ovl_index)
fdba2fcd 762 return ovl_stub;
aa7a0635
AM
763
764 /* If this insn isn't a branch then we are possibly taking the
765 address of a function and passing it out somehow. */
fdba2fcd 766 return !branch && sym_type == STT_FUNC ? nonovl_stub : ret;
aa7a0635
AM
767}
768
47f6dab9
AM
769static bfd_boolean
770count_stub (struct spu_link_hash_table *htab,
771 bfd *ibfd,
772 asection *isec,
fdba2fcd 773 enum _stub_type stub_type,
47f6dab9
AM
774 struct elf_link_hash_entry *h,
775 const Elf_Internal_Rela *irela)
776{
777 unsigned int ovl = 0;
778 struct got_entry *g, **head;
4a628337 779 bfd_vma addend;
47f6dab9
AM
780
781 /* If this instruction is a branch or call, we need a stub
782 for it. One stub per function per overlay.
783 If it isn't a branch, then we are taking the address of
784 this function so need a stub in the non-overlay area
785 for it. One stub per function. */
fdba2fcd 786 if (stub_type != nonovl_stub)
47f6dab9
AM
787 ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
788
789 if (h != NULL)
790 head = &h->got.glist;
791 else
792 {
793 if (elf_local_got_ents (ibfd) == NULL)
794 {
795 bfd_size_type amt = (elf_tdata (ibfd)->symtab_hdr.sh_info
796 * sizeof (*elf_local_got_ents (ibfd)));
797 elf_local_got_ents (ibfd) = bfd_zmalloc (amt);
798 if (elf_local_got_ents (ibfd) == NULL)
799 return FALSE;
800 }
801 head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
802 }
803
4a628337
AM
804 addend = 0;
805 if (irela != NULL)
806 addend = irela->r_addend;
47f6dab9
AM
807
808 if (ovl == 0)
809 {
810 struct got_entry *gnext;
811
4a628337
AM
812 for (g = *head; g != NULL; g = g->next)
813 if (g->addend == addend && g->ovl == 0)
814 break;
815
816 if (g == NULL)
47f6dab9 817 {
4a628337
AM
818 /* Need a new non-overlay area stub. Zap other stubs. */
819 for (g = *head; g != NULL; g = gnext)
820 {
821 gnext = g->next;
822 if (g->addend == addend)
823 {
824 htab->stub_count[g->ovl] -= 1;
825 free (g);
826 }
827 }
47f6dab9
AM
828 }
829 }
830 else
831 {
4a628337
AM
832 for (g = *head; g != NULL; g = g->next)
833 if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
47f6dab9
AM
834 break;
835 }
836
837 if (g == NULL)
838 {
839 g = bfd_malloc (sizeof *g);
840 if (g == NULL)
841 return FALSE;
842 g->ovl = ovl;
4a628337 843 g->addend = addend;
47f6dab9
AM
844 g->stub_addr = (bfd_vma) -1;
845 g->next = *head;
846 *head = g;
847
848 htab->stub_count[ovl] += 1;
849 }
850
851 return TRUE;
852}
853
854/* Two instruction overlay stubs look like:
855
856 brsl $75,__ovly_load
857 .word target_ovl_and_address
858
859 ovl_and_address is a word with the overlay number in the top 14 bits
860 and local store address in the bottom 18 bits.
861
862 Four instruction overlay stubs look like:
863
864 ila $78,ovl_number
865 lnop
866 ila $79,target_address
867 br __ovly_load */
868
869static bfd_boolean
870build_stub (struct spu_link_hash_table *htab,
871 bfd *ibfd,
872 asection *isec,
fdba2fcd 873 enum _stub_type stub_type,
47f6dab9
AM
874 struct elf_link_hash_entry *h,
875 const Elf_Internal_Rela *irela,
876 bfd_vma dest,
877 asection *dest_sec)
878{
879 unsigned int ovl;
880 struct got_entry *g, **head;
881 asection *sec;
4a628337 882 bfd_vma addend, val, from, to;
47f6dab9
AM
883
884 ovl = 0;
fdba2fcd 885 if (stub_type != nonovl_stub)
47f6dab9
AM
886 ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
887
888 if (h != NULL)
889 head = &h->got.glist;
890 else
891 head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
892
4a628337
AM
893 addend = 0;
894 if (irela != NULL)
895 addend = irela->r_addend;
47f6dab9 896
4a628337
AM
897 for (g = *head; g != NULL; g = g->next)
898 if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
47f6dab9
AM
899 break;
900 if (g == NULL)
901 abort ();
902
4a628337
AM
903 if (g->ovl == 0 && ovl != 0)
904 return TRUE;
905
47f6dab9
AM
906 if (g->stub_addr != (bfd_vma) -1)
907 return TRUE;
908
909 sec = htab->stub_sec[ovl];
910 dest += dest_sec->output_offset + dest_sec->output_section->vma;
911 from = sec->size + sec->output_offset + sec->output_section->vma;
912 g->stub_addr = from;
913 to = (htab->ovly_load->root.u.def.value
914 + htab->ovly_load->root.u.def.section->output_offset
915 + htab->ovly_load->root.u.def.section->output_section->vma);
916 val = to - from;
917 if (OVL_STUB_SIZE == 16)
918 val -= 12;
919 if (((dest | to | from) & 3) != 0
920 || val + 0x20000 >= 0x40000)
921 {
922 htab->stub_err = 1;
923 return FALSE;
924 }
925 ovl = spu_elf_section_data (dest_sec->output_section)->u.o.ovl_index;
926
927 if (OVL_STUB_SIZE == 16)
928 {
929 bfd_put_32 (sec->owner, ILA + ((ovl << 7) & 0x01ffff80) + 78,
930 sec->contents + sec->size);
931 bfd_put_32 (sec->owner, LNOP,
932 sec->contents + sec->size + 4);
933 bfd_put_32 (sec->owner, ILA + ((dest << 7) & 0x01ffff80) + 79,
934 sec->contents + sec->size + 8);
935 bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80),
936 sec->contents + sec->size + 12);
937 }
938 else if (OVL_STUB_SIZE == 8)
939 {
940 bfd_put_32 (sec->owner, BRSL + ((val << 5) & 0x007fff80) + 75,
941 sec->contents + sec->size);
942
943 val = (dest & 0x3ffff) | (ovl << 14);
944 bfd_put_32 (sec->owner, val,
945 sec->contents + sec->size + 4);
946 }
947 else
948 abort ();
949 sec->size += OVL_STUB_SIZE;
950
951 if (htab->emit_stub_syms)
952 {
953 size_t len;
954 char *name;
955 int add;
956
957 len = 8 + sizeof (".ovl_call.") - 1;
958 if (h != NULL)
959 len += strlen (h->root.root.string);
960 else
961 len += 8 + 1 + 8;
962 add = 0;
963 if (irela != NULL)
964 add = (int) irela->r_addend & 0xffffffff;
965 if (add != 0)
966 len += 1 + 8;
967 name = bfd_malloc (len);
968 if (name == NULL)
969 return FALSE;
970
971 sprintf (name, "%08x.ovl_call.", g->ovl);
972 if (h != NULL)
973 strcpy (name + 8 + sizeof (".ovl_call.") - 1, h->root.root.string);
974 else
975 sprintf (name + 8 + sizeof (".ovl_call.") - 1, "%x:%x",
976 dest_sec->id & 0xffffffff,
977 (int) ELF32_R_SYM (irela->r_info) & 0xffffffff);
978 if (add != 0)
979 sprintf (name + len - 9, "+%x", add);
980
981 h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
982 free (name);
983 if (h == NULL)
984 return FALSE;
985 if (h->root.type == bfd_link_hash_new)
986 {
987 h->root.type = bfd_link_hash_defined;
988 h->root.u.def.section = sec;
989 h->root.u.def.value = sec->size - OVL_STUB_SIZE;
990 h->size = OVL_STUB_SIZE;
991 h->type = STT_FUNC;
992 h->ref_regular = 1;
993 h->def_regular = 1;
994 h->ref_regular_nonweak = 1;
995 h->forced_local = 1;
996 h->non_elf = 0;
997 }
998 }
999
1000 return TRUE;
1001}
1002
f4b39977
AM
1003/* Called via elf_link_hash_traverse to allocate stubs for any _SPUEAR_
1004 symbols. */
1005
1006static bfd_boolean
1007allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
1008{
1009 /* Symbols starting with _SPUEAR_ need a stub because they may be
1010 invoked by the PPU. */
1011 if ((h->root.type == bfd_link_hash_defined
1012 || h->root.type == bfd_link_hash_defweak)
1013 && h->def_regular
1014 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
1015 {
98e89a7d 1016 struct spu_link_hash_table *htab = inf;
f4b39977 1017
fdba2fcd 1018 count_stub (htab, NULL, NULL, nonovl_stub, h, NULL);
f4b39977
AM
1019 }
1020
1021 return TRUE;
1022}
1023
e9f53129 1024static bfd_boolean
47f6dab9 1025build_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
e9f53129 1026{
47f6dab9
AM
1027 /* Symbols starting with _SPUEAR_ need a stub because they may be
1028 invoked by the PPU. */
1029 if ((h->root.type == bfd_link_hash_defined
1030 || h->root.type == bfd_link_hash_defweak)
1031 && h->def_regular
1032 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
1033 {
1034 struct spu_link_hash_table *htab = inf;
e9f53129 1035
fdba2fcd 1036 build_stub (htab, NULL, NULL, nonovl_stub, h, NULL,
47f6dab9
AM
1037 h->root.u.def.value, h->root.u.def.section);
1038 }
1039
e9f53129
AM
1040 return TRUE;
1041}
1042
47f6dab9 1043/* Size or build stubs. */
e9f53129 1044
47f6dab9
AM
1045static bfd_boolean
1046process_stubs (bfd *output_bfd,
1047 struct bfd_link_info *info,
1048 bfd_boolean build)
e9f53129
AM
1049{
1050 struct spu_link_hash_table *htab = spu_hash_table (info);
1051 bfd *ibfd;
e9f53129 1052
e9f53129
AM
1053 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
1054 {
1055 extern const bfd_target bfd_elf32_spu_vec;
1056 Elf_Internal_Shdr *symtab_hdr;
47f6dab9 1057 asection *isec;
e9f53129 1058 Elf_Internal_Sym *local_syms = NULL;
d0249648 1059 void *psyms;
e9f53129
AM
1060
1061 if (ibfd->xvec != &bfd_elf32_spu_vec)
1062 continue;
1063
1064 /* We'll need the symbol table in a second. */
1065 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1066 if (symtab_hdr->sh_info == 0)
1067 continue;
1068
49fa1e15
AM
1069 /* Arrange to read and keep global syms for later stack analysis. */
1070 psyms = &local_syms;
47f6dab9 1071 if (htab->stack_analysis)
d0249648 1072 psyms = &symtab_hdr->contents;
49fa1e15 1073
e9f53129 1074 /* Walk over each section attached to the input bfd. */
47f6dab9 1075 for (isec = ibfd->sections; isec != NULL; isec = isec->next)
e9f53129
AM
1076 {
1077 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1078
1079 /* If there aren't any relocs, then there's nothing more to do. */
47f6dab9 1080 if ((isec->flags & SEC_RELOC) == 0
47f6dab9 1081 || isec->reloc_count == 0)
e9f53129
AM
1082 continue;
1083
fdba2fcd 1084 if (!maybe_needs_stubs (isec, output_bfd))
e9f53129
AM
1085 continue;
1086
1087 /* Get the relocs. */
47f6dab9
AM
1088 internal_relocs = _bfd_elf_link_read_relocs (ibfd, isec, NULL, NULL,
1089 info->keep_memory);
e9f53129
AM
1090 if (internal_relocs == NULL)
1091 goto error_ret_free_local;
1092
1093 /* Now examine each relocation. */
1094 irela = internal_relocs;
47f6dab9 1095 irelaend = irela + isec->reloc_count;
e9f53129
AM
1096 for (; irela < irelaend; irela++)
1097 {
1098 enum elf_spu_reloc_type r_type;
1099 unsigned int r_indx;
1100 asection *sym_sec;
1101 Elf_Internal_Sym *sym;
1102 struct elf_link_hash_entry *h;
fdba2fcd 1103 enum _stub_type stub_type;
e9f53129
AM
1104
1105 r_type = ELF32_R_TYPE (irela->r_info);
1106 r_indx = ELF32_R_SYM (irela->r_info);
1107
1108 if (r_type >= R_SPU_max)
1109 {
1110 bfd_set_error (bfd_error_bad_value);
47f6dab9
AM
1111 error_ret_free_internal:
1112 if (elf_section_data (isec)->relocs != internal_relocs)
1113 free (internal_relocs);
1114 error_ret_free_local:
1115 if (local_syms != NULL
1116 && (symtab_hdr->contents
1117 != (unsigned char *) local_syms))
1118 free (local_syms);
1119 return FALSE;
e9f53129
AM
1120 }
1121
1122 /* Determine the reloc target section. */
49fa1e15 1123 if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, ibfd))
e9f53129
AM
1124 goto error_ret_free_internal;
1125
fdba2fcd
AM
1126 stub_type = needs_ovl_stub (h, sym, sym_sec, isec, irela,
1127 NULL, info);
1128 if (stub_type == no_stub)
e9f53129 1129 continue;
fdba2fcd
AM
1130 else if (stub_type == stub_error)
1131 goto error_ret_free_internal;
e9f53129 1132
47f6dab9 1133 if (htab->stub_count == NULL)
e9f53129 1134 {
47f6dab9
AM
1135 bfd_size_type amt;
1136 amt = (htab->num_overlays + 1) * sizeof (*htab->stub_count);
1137 htab->stub_count = bfd_zmalloc (amt);
1138 if (htab->stub_count == NULL)
1139 goto error_ret_free_internal;
e9f53129
AM
1140 }
1141
47f6dab9 1142 if (!build)
e9f53129 1143 {
fdba2fcd 1144 if (!count_stub (htab, ibfd, isec, stub_type, h, irela))
47f6dab9 1145 goto error_ret_free_internal;
e9f53129 1146 }
e9f53129 1147 else
47f6dab9
AM
1148 {
1149 bfd_vma dest;
1150
1151 if (h != NULL)
1152 dest = h->root.u.def.value;
1153 else
1154 dest = sym->st_value;
4a628337 1155 dest += irela->r_addend;
fdba2fcd 1156 if (!build_stub (htab, ibfd, isec, stub_type, h, irela,
47f6dab9
AM
1157 dest, sym_sec))
1158 goto error_ret_free_internal;
1159 }
e9f53129
AM
1160 }
1161
1162 /* We're done with the internal relocs, free them. */
47f6dab9 1163 if (elf_section_data (isec)->relocs != internal_relocs)
e9f53129
AM
1164 free (internal_relocs);
1165 }
1166
1167 if (local_syms != NULL
1168 && symtab_hdr->contents != (unsigned char *) local_syms)
1169 {
1170 if (!info->keep_memory)
1171 free (local_syms);
1172 else
1173 symtab_hdr->contents = (unsigned char *) local_syms;
1174 }
1175 }
1176
47f6dab9
AM
1177 return TRUE;
1178}
1179
1180/* Allocate space for overlay call and return stubs. */
1181
1182int
1183spu_elf_size_stubs (bfd *output_bfd,
1184 struct bfd_link_info *info,
1185 void (*place_spu_section) (asection *, asection *,
1186 const char *),
1187 int non_overlay_stubs)
1188{
1189 struct spu_link_hash_table *htab = spu_hash_table (info);
1190 bfd *ibfd;
1191 bfd_size_type amt;
1192 flagword flags;
1193 unsigned int i;
1194 asection *stub;
1195
1196 htab->non_overlay_stubs = non_overlay_stubs;
1197 if (!process_stubs (output_bfd, info, FALSE))
1198 return 0;
1199
98e89a7d 1200 elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, htab);
47f6dab9
AM
1201 if (htab->stub_err)
1202 return 0;
f4b39977 1203
47f6dab9
AM
1204 if (htab->stub_count == NULL)
1205 return 1;
e9f53129
AM
1206
1207 ibfd = info->input_bfds;
47f6dab9
AM
1208 amt = (htab->num_overlays + 1) * sizeof (*htab->stub_sec);
1209 htab->stub_sec = bfd_zmalloc (amt);
1210 if (htab->stub_sec == NULL)
1211 return 0;
e9f53129 1212
47f6dab9 1213 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
e9f53129 1214 | SEC_HAS_CONTENTS | SEC_IN_MEMORY);
47f6dab9
AM
1215 stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
1216 htab->stub_sec[0] = stub;
1217 if (stub == NULL
1218 || !bfd_set_section_alignment (ibfd, stub, 3 + (OVL_STUB_SIZE > 8)))
1219 return 0;
1220 stub->size = htab->stub_count[0] * OVL_STUB_SIZE;
1221 (*place_spu_section) (stub, NULL, ".text");
e9f53129 1222
47f6dab9 1223 for (i = 0; i < htab->num_overlays; ++i)
e9f53129 1224 {
47f6dab9
AM
1225 asection *osec = htab->ovl_sec[i];
1226 unsigned int ovl = spu_elf_section_data (osec)->u.o.ovl_index;
1227 stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
1228 htab->stub_sec[ovl] = stub;
1229 if (stub == NULL
1230 || !bfd_set_section_alignment (ibfd, stub, 3 + (OVL_STUB_SIZE > 8)))
1231 return 0;
1232 stub->size = htab->stub_count[ovl] * OVL_STUB_SIZE;
1233 (*place_spu_section) (stub, osec, NULL);
e9f53129 1234 }
e9f53129
AM
1235
1236 /* htab->ovtab consists of two arrays.
1237 . struct {
1238 . u32 vma;
1239 . u32 size;
1240 . u32 file_off;
1241 . u32 buf;
1242 . } _ovly_table[];
1243 .
1244 . struct {
1245 . u32 mapped;
47f6dab9
AM
1246 . } _ovly_buf_table[];
1247 . */
e9f53129 1248
47f6dab9
AM
1249 flags = (SEC_ALLOC | SEC_LOAD
1250 | SEC_HAS_CONTENTS | SEC_IN_MEMORY);
1251 htab->ovtab = bfd_make_section_anyway_with_flags (ibfd, ".ovtab", flags);
1252 if (htab->ovtab == NULL
1253 || !bfd_set_section_alignment (ibfd, htab->ovtab, 4))
1254 return 0;
e9f53129 1255
2e444bea 1256 htab->ovtab->size = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
47f6dab9
AM
1257 (*place_spu_section) (htab->ovtab, NULL, ".data");
1258
1259 htab->toe = bfd_make_section_anyway_with_flags (ibfd, ".toe", SEC_ALLOC);
1260 if (htab->toe == NULL
1261 || !bfd_set_section_alignment (ibfd, htab->toe, 4))
1262 return 0;
1263 htab->toe->size = 16;
1264 (*place_spu_section) (htab->toe, NULL, ".toe");
1265
1266 return 2;
e9f53129
AM
1267}
1268
1269/* Functions to handle embedded spu_ovl.o object. */
1270
1271static void *
1272ovl_mgr_open (struct bfd *nbfd ATTRIBUTE_UNUSED, void *stream)
1273{
1274 return stream;
1275}
1276
1277static file_ptr
1278ovl_mgr_pread (struct bfd *abfd ATTRIBUTE_UNUSED,
1279 void *stream,
1280 void *buf,
1281 file_ptr nbytes,
1282 file_ptr offset)
1283{
1284 struct _ovl_stream *os;
1285 size_t count;
1286 size_t max;
1287
1288 os = (struct _ovl_stream *) stream;
7a8757b3 1289 max = (const char *) os->end - (const char *) os->start;
e9f53129
AM
1290
1291 if ((ufile_ptr) offset >= max)
1292 return 0;
1293
1294 count = nbytes;
1295 if (count > max - offset)
1296 count = max - offset;
1297
7a8757b3 1298 memcpy (buf, (const char *) os->start + offset, count);
e9f53129
AM
1299 return count;
1300}
1301
1302bfd_boolean
1303spu_elf_open_builtin_lib (bfd **ovl_bfd, const struct _ovl_stream *stream)
1304{
1305 *ovl_bfd = bfd_openr_iovec ("builtin ovl_mgr",
1306 "elf32-spu",
1307 ovl_mgr_open,
1308 (void *) stream,
1309 ovl_mgr_pread,
f6cf9273 1310 NULL,
e9f53129
AM
1311 NULL);
1312 return *ovl_bfd != NULL;
1313}
1314
e9f53129
AM
1315/* Define an STT_OBJECT symbol. */
1316
1317static struct elf_link_hash_entry *
1318define_ovtab_symbol (struct spu_link_hash_table *htab, const char *name)
1319{
1320 struct elf_link_hash_entry *h;
1321
1322 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
1323 if (h == NULL)
1324 return NULL;
1325
1326 if (h->root.type != bfd_link_hash_defined
1327 || !h->def_regular)
1328 {
1329 h->root.type = bfd_link_hash_defined;
1330 h->root.u.def.section = htab->ovtab;
1331 h->type = STT_OBJECT;
1332 h->ref_regular = 1;
1333 h->def_regular = 1;
1334 h->ref_regular_nonweak = 1;
1335 h->non_elf = 0;
1336 }
1337 else
1338 {
1339 (*_bfd_error_handler) (_("%B is not allowed to define %s"),
1340 h->root.u.def.section->owner,
1341 h->root.root.string);
1342 bfd_set_error (bfd_error_bad_value);
1343 return NULL;
1344 }
1345
1346 return h;
1347}
1348
1349/* Fill in all stubs and the overlay tables. */
1350
1351bfd_boolean
47f6dab9 1352spu_elf_build_stubs (struct bfd_link_info *info, int emit_syms)
e9f53129
AM
1353{
1354 struct spu_link_hash_table *htab = spu_hash_table (info);
1355 struct elf_link_hash_entry *h;
1356 bfd_byte *p;
1357 asection *s;
1358 bfd *obfd;
1359 unsigned int i;
1360
1361 htab->emit_stub_syms = emit_syms;
47f6dab9
AM
1362 if (htab->stub_count == NULL)
1363 return TRUE;
1364
1365 for (i = 0; i <= htab->num_overlays; i++)
1366 if (htab->stub_sec[i]->size != 0)
1367 {
1368 htab->stub_sec[i]->contents = bfd_zalloc (htab->stub_sec[i]->owner,
1369 htab->stub_sec[i]->size);
1370 if (htab->stub_sec[i]->contents == NULL)
1371 return FALSE;
1372 htab->stub_sec[i]->rawsize = htab->stub_sec[i]->size;
1373 htab->stub_sec[i]->size = 0;
1374 }
e9f53129
AM
1375
1376 h = elf_link_hash_lookup (&htab->elf, "__ovly_load", FALSE, FALSE, FALSE);
1377 htab->ovly_load = h;
1378 BFD_ASSERT (h != NULL
1379 && (h->root.type == bfd_link_hash_defined
1380 || h->root.type == bfd_link_hash_defweak)
1381 && h->def_regular);
1382
1383 s = h->root.u.def.section->output_section;
47f6dab9 1384 if (spu_elf_section_data (s)->u.o.ovl_index)
e9f53129
AM
1385 {
1386 (*_bfd_error_handler) (_("%s in overlay section"),
1387 h->root.u.def.section->owner);
1388 bfd_set_error (bfd_error_bad_value);
1389 return FALSE;
1390 }
1391
47f6dab9
AM
1392 h = elf_link_hash_lookup (&htab->elf, "__ovly_return", FALSE, FALSE, FALSE);
1393 htab->ovly_return = h;
1394
e9f53129 1395 /* Write out all the stubs. */
47f6dab9
AM
1396 obfd = htab->ovtab->output_section->owner;
1397 process_stubs (obfd, info, TRUE);
1398
1399 elf_link_hash_traverse (&htab->elf, build_spuear_stubs, htab);
1400 if (htab->stub_err)
1401 return FALSE;
e9f53129 1402
47f6dab9
AM
1403 for (i = 0; i <= htab->num_overlays; i++)
1404 {
1405 if (htab->stub_sec[i]->size != htab->stub_sec[i]->rawsize)
1406 {
1407 (*_bfd_error_handler) (_("stubs don't match calculated size"));
1408 bfd_set_error (bfd_error_bad_value);
1409 return FALSE;
1410 }
1411 htab->stub_sec[i]->rawsize = 0;
1412 }
1413
1414 if (htab->stub_err)
e9f53129
AM
1415 {
1416 (*_bfd_error_handler) (_("overlay stub relocation overflow"));
1417 bfd_set_error (bfd_error_bad_value);
1418 return FALSE;
1419 }
1420
1421 htab->ovtab->contents = bfd_zalloc (htab->ovtab->owner, htab->ovtab->size);
1422 if (htab->ovtab->contents == NULL)
1423 return FALSE;
1424
1425 /* Write out _ovly_table. */
1426 p = htab->ovtab->contents;
2e444bea
AM
1427 /* set low bit of .size to mark non-overlay area as present. */
1428 p[7] = 1;
e9f53129
AM
1429 for (s = obfd->sections; s != NULL; s = s->next)
1430 {
47f6dab9 1431 unsigned int ovl_index = spu_elf_section_data (s)->u.o.ovl_index;
e9f53129
AM
1432
1433 if (ovl_index != 0)
1434 {
47f6dab9
AM
1435 unsigned long off = ovl_index * 16;
1436 unsigned int ovl_buf = spu_elf_section_data (s)->u.o.ovl_buf;
1437
e9f53129
AM
1438 bfd_put_32 (htab->ovtab->owner, s->vma, p + off);
1439 bfd_put_32 (htab->ovtab->owner, (s->size + 15) & -16, p + off + 4);
1440 /* file_off written later in spu_elf_modify_program_headers. */
2e444bea 1441 bfd_put_32 (htab->ovtab->owner, ovl_buf, p + off + 12);
e9f53129
AM
1442 }
1443 }
1444
e9f53129
AM
1445 h = define_ovtab_symbol (htab, "_ovly_table");
1446 if (h == NULL)
1447 return FALSE;
47f6dab9 1448 h->root.u.def.value = 16;
e9f53129
AM
1449 h->size = htab->num_overlays * 16;
1450
1451 h = define_ovtab_symbol (htab, "_ovly_table_end");
1452 if (h == NULL)
1453 return FALSE;
47f6dab9 1454 h->root.u.def.value = htab->num_overlays * 16 + 16;
e9f53129
AM
1455 h->size = 0;
1456
1457 h = define_ovtab_symbol (htab, "_ovly_buf_table");
1458 if (h == NULL)
1459 return FALSE;
47f6dab9 1460 h->root.u.def.value = htab->num_overlays * 16 + 16;
2e444bea 1461 h->size = htab->num_buf * 4;
e9f53129
AM
1462
1463 h = define_ovtab_symbol (htab, "_ovly_buf_table_end");
1464 if (h == NULL)
1465 return FALSE;
2e444bea 1466 h->root.u.def.value = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
e9f53129
AM
1467 h->size = 0;
1468
1469 h = define_ovtab_symbol (htab, "_EAR_");
1470 if (h == NULL)
1471 return FALSE;
47f6dab9 1472 h->root.u.def.section = htab->toe;
e9f53129
AM
1473 h->root.u.def.value = 0;
1474 h->size = 16;
1475
1476 return TRUE;
1477}
1478
49fa1e15
AM
1479/* OFFSET in SEC (presumably) is the beginning of a function prologue.
1480 Search for stack adjusting insns, and return the sp delta. */
1481
1482static int
1483find_function_stack_adjust (asection *sec, bfd_vma offset)
1484{
1485 int unrecog;
1486 int reg[128];
1487
1488 memset (reg, 0, sizeof (reg));
1489 for (unrecog = 0; offset + 4 <= sec->size && unrecog < 32; offset += 4)
1490 {
1491 unsigned char buf[4];
1492 int rt, ra;
1493 int imm;
1494
1495 /* Assume no relocs on stack adjusing insns. */
1496 if (!bfd_get_section_contents (sec->owner, sec, buf, offset, 4))
1497 break;
1498
1499 if (buf[0] == 0x24 /* stqd */)
1500 continue;
1501
1502 rt = buf[3] & 0x7f;
1503 ra = ((buf[2] & 0x3f) << 1) | (buf[3] >> 7);
1504 /* Partly decoded immediate field. */
1505 imm = (buf[1] << 9) | (buf[2] << 1) | (buf[3] >> 7);
1506
1507 if (buf[0] == 0x1c /* ai */)
1508 {
1509 imm >>= 7;
1510 imm = (imm ^ 0x200) - 0x200;
1511 reg[rt] = reg[ra] + imm;
1512
1513 if (rt == 1 /* sp */)
1514 {
1515 if (imm > 0)
1516 break;
1517 return reg[rt];
1518 }
1519 }
1520 else if (buf[0] == 0x18 && (buf[1] & 0xe0) == 0 /* a */)
1521 {
1522 int rb = ((buf[1] & 0x1f) << 2) | ((buf[2] & 0xc0) >> 6);
1523
1524 reg[rt] = reg[ra] + reg[rb];
1525 if (rt == 1)
1526 return reg[rt];
1527 }
1528 else if ((buf[0] & 0xfc) == 0x40 /* il, ilh, ilhu, ila */)
1529 {
1530 if (buf[0] >= 0x42 /* ila */)
1531 imm |= (buf[0] & 1) << 17;
1532 else
1533 {
1534 imm &= 0xffff;
1535
1536 if (buf[0] == 0x40 /* il */)
1537 {
1538 if ((buf[1] & 0x80) == 0)
1539 goto unknown_insn;
1540 imm = (imm ^ 0x8000) - 0x8000;
1541 }
1542 else if ((buf[1] & 0x80) == 0 /* ilhu */)
1543 imm <<= 16;
1544 }
1545 reg[rt] = imm;
1546 continue;
1547 }
1548 else if (buf[0] == 0x60 && (buf[1] & 0x80) != 0 /* iohl */)
1549 {
1550 reg[rt] |= imm & 0xffff;
1551 continue;
1552 }
1553 else if (buf[0] == 0x04 /* ori */)
1554 {
1555 imm >>= 7;
1556 imm = (imm ^ 0x200) - 0x200;
1557 reg[rt] = reg[ra] | imm;
1558 continue;
1559 }
1560 else if ((buf[0] == 0x33 && imm == 1 /* brsl .+4 */)
1561 || (buf[0] == 0x08 && (buf[1] & 0xe0) == 0 /* sf */))
1562 {
1563 /* Used in pic reg load. Say rt is trashed. */
1564 reg[rt] = 0;
1565 continue;
1566 }
fad9eaf0 1567 else if (is_branch (buf) || is_indirect_branch (buf))
49fa1e15
AM
1568 /* If we hit a branch then we must be out of the prologue. */
1569 break;
1570 unknown_insn:
1571 ++unrecog;
1572 }
1573
1574 return 0;
1575}
1576
1577/* qsort predicate to sort symbols by section and value. */
1578
1579static Elf_Internal_Sym *sort_syms_syms;
1580static asection **sort_syms_psecs;
1581
1582static int
1583sort_syms (const void *a, const void *b)
1584{
1585 Elf_Internal_Sym *const *s1 = a;
1586 Elf_Internal_Sym *const *s2 = b;
1587 asection *sec1,*sec2;
1588 bfd_signed_vma delta;
1589
1590 sec1 = sort_syms_psecs[*s1 - sort_syms_syms];
1591 sec2 = sort_syms_psecs[*s2 - sort_syms_syms];
1592
1593 if (sec1 != sec2)
1594 return sec1->index - sec2->index;
1595
1596 delta = (*s1)->st_value - (*s2)->st_value;
1597 if (delta != 0)
1598 return delta < 0 ? -1 : 1;
1599
1600 delta = (*s2)->st_size - (*s1)->st_size;
1601 if (delta != 0)
1602 return delta < 0 ? -1 : 1;
1603
1604 return *s1 < *s2 ? -1 : 1;
1605}
1606
1607struct call_info
1608{
1609 struct function_info *fun;
1610 struct call_info *next;
1611 int is_tail;
1612};
1613
1614struct function_info
1615{
1616 /* List of functions called. Also branches to hot/cold part of
1617 function. */
1618 struct call_info *call_list;
1619 /* For hot/cold part of function, point to owner. */
1620 struct function_info *start;
1621 /* Symbol at start of function. */
1622 union {
1623 Elf_Internal_Sym *sym;
1624 struct elf_link_hash_entry *h;
1625 } u;
1626 /* Function section. */
1627 asection *sec;
1628 /* Address range of (this part of) function. */
1629 bfd_vma lo, hi;
1630 /* Stack usage. */
1631 int stack;
1632 /* Set if global symbol. */
1633 unsigned int global : 1;
1634 /* Set if known to be start of function (as distinct from a hunk
1635 in hot/cold section. */
1636 unsigned int is_func : 1;
1637 /* Flags used during call tree traversal. */
1638 unsigned int visit1 : 1;
1639 unsigned int non_root : 1;
1640 unsigned int visit2 : 1;
1641 unsigned int marking : 1;
1642 unsigned int visit3 : 1;
1643};
1644
1645struct spu_elf_stack_info
1646{
1647 int num_fun;
1648 int max_fun;
1649 /* Variable size array describing functions, one per contiguous
1650 address range belonging to a function. */
1651 struct function_info fun[1];
1652};
1653
1654/* Allocate a struct spu_elf_stack_info with MAX_FUN struct function_info
1655 entries for section SEC. */
1656
1657static struct spu_elf_stack_info *
1658alloc_stack_info (asection *sec, int max_fun)
1659{
1660 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
1661 bfd_size_type amt;
1662
1663 amt = sizeof (struct spu_elf_stack_info);
1664 amt += (max_fun - 1) * sizeof (struct function_info);
47f6dab9
AM
1665 sec_data->u.i.stack_info = bfd_zmalloc (amt);
1666 if (sec_data->u.i.stack_info != NULL)
1667 sec_data->u.i.stack_info->max_fun = max_fun;
1668 return sec_data->u.i.stack_info;
49fa1e15
AM
1669}
1670
1671/* Add a new struct function_info describing a (part of a) function
1672 starting at SYM_H. Keep the array sorted by address. */
1673
1674static struct function_info *
1675maybe_insert_function (asection *sec,
1676 void *sym_h,
1677 bfd_boolean global,
1678 bfd_boolean is_func)
1679{
1680 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 1681 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
1682 int i;
1683 bfd_vma off, size;
1684
1685 if (sinfo == NULL)
1686 {
1687 sinfo = alloc_stack_info (sec, 20);
1688 if (sinfo == NULL)
1689 return NULL;
1690 }
1691
1692 if (!global)
1693 {
1694 Elf_Internal_Sym *sym = sym_h;
1695 off = sym->st_value;
1696 size = sym->st_size;
1697 }
1698 else
1699 {
1700 struct elf_link_hash_entry *h = sym_h;
1701 off = h->root.u.def.value;
1702 size = h->size;
1703 }
1704
1705 for (i = sinfo->num_fun; --i >= 0; )
1706 if (sinfo->fun[i].lo <= off)
1707 break;
1708
1709 if (i >= 0)
1710 {
1711 /* Don't add another entry for an alias, but do update some
1712 info. */
1713 if (sinfo->fun[i].lo == off)
1714 {
1715 /* Prefer globals over local syms. */
1716 if (global && !sinfo->fun[i].global)
1717 {
1718 sinfo->fun[i].global = TRUE;
1719 sinfo->fun[i].u.h = sym_h;
1720 }
1721 if (is_func)
1722 sinfo->fun[i].is_func = TRUE;
1723 return &sinfo->fun[i];
1724 }
1725 /* Ignore a zero-size symbol inside an existing function. */
1726 else if (sinfo->fun[i].hi > off && size == 0)
1727 return &sinfo->fun[i];
1728 }
1729
1730 if (++i < sinfo->num_fun)
1731 memmove (&sinfo->fun[i + 1], &sinfo->fun[i],
1732 (sinfo->num_fun - i) * sizeof (sinfo->fun[i]));
1733 else if (i >= sinfo->max_fun)
1734 {
1735 bfd_size_type amt = sizeof (struct spu_elf_stack_info);
1736 bfd_size_type old = amt;
1737
1738 old += (sinfo->max_fun - 1) * sizeof (struct function_info);
1739 sinfo->max_fun += 20 + (sinfo->max_fun >> 1);
1740 amt += (sinfo->max_fun - 1) * sizeof (struct function_info);
1741 sinfo = bfd_realloc (sinfo, amt);
1742 if (sinfo == NULL)
1743 return NULL;
1744 memset ((char *) sinfo + old, 0, amt - old);
47f6dab9 1745 sec_data->u.i.stack_info = sinfo;
49fa1e15
AM
1746 }
1747 sinfo->fun[i].is_func = is_func;
1748 sinfo->fun[i].global = global;
1749 sinfo->fun[i].sec = sec;
1750 if (global)
1751 sinfo->fun[i].u.h = sym_h;
1752 else
1753 sinfo->fun[i].u.sym = sym_h;
1754 sinfo->fun[i].lo = off;
1755 sinfo->fun[i].hi = off + size;
1756 sinfo->fun[i].stack = -find_function_stack_adjust (sec, off);
1757 sinfo->num_fun += 1;
1758 return &sinfo->fun[i];
1759}
1760
1761/* Return the name of FUN. */
1762
1763static const char *
1764func_name (struct function_info *fun)
1765{
1766 asection *sec;
1767 bfd *ibfd;
1768 Elf_Internal_Shdr *symtab_hdr;
1769
1770 while (fun->start != NULL)
1771 fun = fun->start;
1772
1773 if (fun->global)
1774 return fun->u.h->root.root.string;
1775
1776 sec = fun->sec;
1777 if (fun->u.sym->st_name == 0)
1778 {
1779 size_t len = strlen (sec->name);
1780 char *name = bfd_malloc (len + 10);
1781 if (name == NULL)
1782 return "(null)";
1783 sprintf (name, "%s+%lx", sec->name,
1784 (unsigned long) fun->u.sym->st_value & 0xffffffff);
1785 return name;
1786 }
1787 ibfd = sec->owner;
1788 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1789 return bfd_elf_sym_name (ibfd, symtab_hdr, fun->u.sym, sec);
1790}
1791
1792/* Read the instruction at OFF in SEC. Return true iff the instruction
1793 is a nop, lnop, or stop 0 (all zero insn). */
1794
1795static bfd_boolean
1796is_nop (asection *sec, bfd_vma off)
1797{
1798 unsigned char insn[4];
1799
1800 if (off + 4 > sec->size
1801 || !bfd_get_section_contents (sec->owner, sec, insn, off, 4))
1802 return FALSE;
1803 if ((insn[0] & 0xbf) == 0 && (insn[1] & 0xe0) == 0x20)
1804 return TRUE;
1805 if (insn[0] == 0 && insn[1] == 0 && insn[2] == 0 && insn[3] == 0)
1806 return TRUE;
1807 return FALSE;
1808}
1809
1810/* Extend the range of FUN to cover nop padding up to LIMIT.
1811 Return TRUE iff some instruction other than a NOP was found. */
1812
1813static bfd_boolean
1814insns_at_end (struct function_info *fun, bfd_vma limit)
1815{
1816 bfd_vma off = (fun->hi + 3) & -4;
1817
1818 while (off < limit && is_nop (fun->sec, off))
1819 off += 4;
1820 if (off < limit)
1821 {
1822 fun->hi = off;
1823 return TRUE;
1824 }
1825 fun->hi = limit;
1826 return FALSE;
1827}
1828
1829/* Check and fix overlapping function ranges. Return TRUE iff there
1830 are gaps in the current info we have about functions in SEC. */
1831
1832static bfd_boolean
1833check_function_ranges (asection *sec, struct bfd_link_info *info)
1834{
1835 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 1836 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
1837 int i;
1838 bfd_boolean gaps = FALSE;
1839
1840 if (sinfo == NULL)
1841 return FALSE;
1842
1843 for (i = 1; i < sinfo->num_fun; i++)
1844 if (sinfo->fun[i - 1].hi > sinfo->fun[i].lo)
1845 {
1846 /* Fix overlapping symbols. */
1847 const char *f1 = func_name (&sinfo->fun[i - 1]);
1848 const char *f2 = func_name (&sinfo->fun[i]);
1849
1850 info->callbacks->einfo (_("warning: %s overlaps %s\n"), f1, f2);
1851 sinfo->fun[i - 1].hi = sinfo->fun[i].lo;
1852 }
1853 else if (insns_at_end (&sinfo->fun[i - 1], sinfo->fun[i].lo))
1854 gaps = TRUE;
1855
1856 if (sinfo->num_fun == 0)
1857 gaps = TRUE;
1858 else
1859 {
1860 if (sinfo->fun[0].lo != 0)
1861 gaps = TRUE;
1862 if (sinfo->fun[sinfo->num_fun - 1].hi > sec->size)
1863 {
1864 const char *f1 = func_name (&sinfo->fun[sinfo->num_fun - 1]);
1865
1866 info->callbacks->einfo (_("warning: %s exceeds section size\n"), f1);
1867 sinfo->fun[sinfo->num_fun - 1].hi = sec->size;
1868 }
1869 else if (insns_at_end (&sinfo->fun[sinfo->num_fun - 1], sec->size))
1870 gaps = TRUE;
1871 }
1872 return gaps;
1873}
1874
1875/* Search current function info for a function that contains address
1876 OFFSET in section SEC. */
1877
1878static struct function_info *
1879find_function (asection *sec, bfd_vma offset, struct bfd_link_info *info)
1880{
1881 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 1882 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
1883 int lo, hi, mid;
1884
1885 lo = 0;
1886 hi = sinfo->num_fun;
1887 while (lo < hi)
1888 {
1889 mid = (lo + hi) / 2;
1890 if (offset < sinfo->fun[mid].lo)
1891 hi = mid;
1892 else if (offset >= sinfo->fun[mid].hi)
1893 lo = mid + 1;
1894 else
1895 return &sinfo->fun[mid];
1896 }
1897 info->callbacks->einfo (_("%A:0x%v not found in function table\n"),
1898 sec, offset);
1899 return NULL;
1900}
1901
1902/* Add CALLEE to CALLER call list if not already present. */
1903
1904static bfd_boolean
1905insert_callee (struct function_info *caller, struct call_info *callee)
1906{
1907 struct call_info *p;
1908 for (p = caller->call_list; p != NULL; p = p->next)
1909 if (p->fun == callee->fun)
1910 {
1911 /* Tail calls use less stack than normal calls. Retain entry
1912 for normal call over one for tail call. */
1913 if (p->is_tail > callee->is_tail)
1914 p->is_tail = callee->is_tail;
1915 return FALSE;
1916 }
1917 callee->next = caller->call_list;
1918 caller->call_list = callee;
1919 return TRUE;
1920}
1921
1922/* Rummage through the relocs for SEC, looking for function calls.
1923 If CALL_TREE is true, fill in call graph. If CALL_TREE is false,
1924 mark destination symbols on calls as being functions. Also
1925 look at branches, which may be tail calls or go to hot/cold
1926 section part of same function. */
1927
1928static bfd_boolean
1929mark_functions_via_relocs (asection *sec,
1930 struct bfd_link_info *info,
1931 int call_tree)
1932{
1933 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1934 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
d0249648
AM
1935 Elf_Internal_Sym *syms;
1936 void *psyms;
49fa1e15
AM
1937 static bfd_boolean warned;
1938
1939 internal_relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
1940 info->keep_memory);
1941 if (internal_relocs == NULL)
1942 return FALSE;
1943
1944 symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
d0249648
AM
1945 psyms = &symtab_hdr->contents;
1946 syms = *(Elf_Internal_Sym **) psyms;
49fa1e15
AM
1947 irela = internal_relocs;
1948 irelaend = irela + sec->reloc_count;
1949 for (; irela < irelaend; irela++)
1950 {
1951 enum elf_spu_reloc_type r_type;
1952 unsigned int r_indx;
1953 asection *sym_sec;
1954 Elf_Internal_Sym *sym;
1955 struct elf_link_hash_entry *h;
1956 bfd_vma val;
1957 unsigned char insn[4];
1958 bfd_boolean is_call;
1959 struct function_info *caller;
1960 struct call_info *callee;
1961
1962 r_type = ELF32_R_TYPE (irela->r_info);
1963 if (r_type != R_SPU_REL16
1964 && r_type != R_SPU_ADDR16)
1965 continue;
1966
1967 r_indx = ELF32_R_SYM (irela->r_info);
1968 if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, sec->owner))
1969 return FALSE;
1970
1971 if (sym_sec == NULL
1972 || sym_sec->output_section == NULL
1973 || sym_sec->output_section->owner != sec->output_section->owner)
1974 continue;
1975
1976 if (!bfd_get_section_contents (sec->owner, sec, insn,
1977 irela->r_offset, 4))
1978 return FALSE;
1979 if (!is_branch (insn))
1980 continue;
1981
1982 if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
1983 != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
1984 {
1985 if (!call_tree)
1986 warned = TRUE;
1987 if (!call_tree || !warned)
1988 info->callbacks->einfo (_("%B(%A+0x%v): call to non-code section"
1989 " %B(%A), stack analysis incomplete\n"),
1990 sec->owner, sec, irela->r_offset,
1991 sym_sec->owner, sym_sec);
1992 continue;
1993 }
1994
1995 is_call = (insn[0] & 0xfd) == 0x31;
1996
1997 if (h)
1998 val = h->root.u.def.value;
1999 else
2000 val = sym->st_value;
2001 val += irela->r_addend;
2002
2003 if (!call_tree)
2004 {
2005 struct function_info *fun;
2006
2007 if (irela->r_addend != 0)
2008 {
2009 Elf_Internal_Sym *fake = bfd_zmalloc (sizeof (*fake));
2010 if (fake == NULL)
2011 return FALSE;
2012 fake->st_value = val;
2013 fake->st_shndx
2014 = _bfd_elf_section_from_bfd_section (sym_sec->owner, sym_sec);
2015 sym = fake;
2016 }
2017 if (sym)
2018 fun = maybe_insert_function (sym_sec, sym, FALSE, is_call);
2019 else
2020 fun = maybe_insert_function (sym_sec, h, TRUE, is_call);
2021 if (fun == NULL)
2022 return FALSE;
2023 if (irela->r_addend != 0
2024 && fun->u.sym != sym)
2025 free (sym);
2026 continue;
2027 }
2028
2029 caller = find_function (sec, irela->r_offset, info);
2030 if (caller == NULL)
2031 return FALSE;
2032 callee = bfd_malloc (sizeof *callee);
2033 if (callee == NULL)
2034 return FALSE;
2035
2036 callee->fun = find_function (sym_sec, val, info);
2037 if (callee->fun == NULL)
2038 return FALSE;
2039 callee->is_tail = !is_call;
2040 if (!insert_callee (caller, callee))
2041 free (callee);
2042 else if (!is_call
2043 && !callee->fun->is_func
2044 && callee->fun->stack == 0)
2045 {
2046 /* This is either a tail call or a branch from one part of
2047 the function to another, ie. hot/cold section. If the
2048 destination has been called by some other function then
2049 it is a separate function. We also assume that functions
2050 are not split across input files. */
911f096e 2051 if (sec->owner != sym_sec->owner)
49fa1e15
AM
2052 {
2053 callee->fun->start = NULL;
2054 callee->fun->is_func = TRUE;
2055 }
911f096e 2056 else if (callee->fun->start == NULL)
49fa1e15 2057 callee->fun->start = caller;
911f096e
AM
2058 else
2059 {
2060 struct function_info *callee_start;
2061 struct function_info *caller_start;
2062 callee_start = callee->fun;
2063 while (callee_start->start)
2064 callee_start = callee_start->start;
2065 caller_start = caller;
2066 while (caller_start->start)
2067 caller_start = caller_start->start;
2068 if (caller_start != callee_start)
2069 {
2070 callee->fun->start = NULL;
2071 callee->fun->is_func = TRUE;
2072 }
2073 }
49fa1e15
AM
2074 }
2075 }
2076
2077 return TRUE;
2078}
2079
2080/* Handle something like .init or .fini, which has a piece of a function.
2081 These sections are pasted together to form a single function. */
2082
2083static bfd_boolean
2084pasted_function (asection *sec, struct bfd_link_info *info)
2085{
2086 struct bfd_link_order *l;
2087 struct _spu_elf_section_data *sec_data;
2088 struct spu_elf_stack_info *sinfo;
2089 Elf_Internal_Sym *fake;
2090 struct function_info *fun, *fun_start;
2091
2092 fake = bfd_zmalloc (sizeof (*fake));
2093 if (fake == NULL)
2094 return FALSE;
2095 fake->st_value = 0;
2096 fake->st_size = sec->size;
2097 fake->st_shndx
2098 = _bfd_elf_section_from_bfd_section (sec->owner, sec);
2099 fun = maybe_insert_function (sec, fake, FALSE, FALSE);
2100 if (!fun)
2101 return FALSE;
2102
2103 /* Find a function immediately preceding this section. */
2104 fun_start = NULL;
2105 for (l = sec->output_section->map_head.link_order; l != NULL; l = l->next)
2106 {
2107 if (l->u.indirect.section == sec)
2108 {
2109 if (fun_start != NULL)
911f096e 2110 fun->start = fun_start;
49fa1e15
AM
2111 return TRUE;
2112 }
2113 if (l->type == bfd_indirect_link_order
2114 && (sec_data = spu_elf_section_data (l->u.indirect.section)) != NULL
47f6dab9 2115 && (sinfo = sec_data->u.i.stack_info) != NULL
49fa1e15
AM
2116 && sinfo->num_fun != 0)
2117 fun_start = &sinfo->fun[sinfo->num_fun - 1];
2118 }
2119
2120 info->callbacks->einfo (_("%A link_order not found\n"), sec);
2121 return FALSE;
2122}
2123
47f6dab9
AM
2124/* We're only interested in code sections. Testing SEC_IN_MEMORY excludes
2125 overlay stub sections. */
49fa1e15
AM
2126
2127static bfd_boolean
47f6dab9 2128interesting_section (asection *s, bfd *obfd)
49fa1e15 2129{
47f6dab9 2130 return (s->output_section != NULL
49fa1e15 2131 && s->output_section->owner == obfd
47f6dab9 2132 && ((s->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_IN_MEMORY))
49fa1e15
AM
2133 == (SEC_ALLOC | SEC_LOAD | SEC_CODE))
2134 && s->size != 0);
2135}
2136
2137/* Map address ranges in code sections to functions. */
2138
2139static bfd_boolean
2140discover_functions (bfd *output_bfd, struct bfd_link_info *info)
2141{
49fa1e15
AM
2142 bfd *ibfd;
2143 int bfd_idx;
2144 Elf_Internal_Sym ***psym_arr;
2145 asection ***sec_arr;
2146 bfd_boolean gaps = FALSE;
2147
2148 bfd_idx = 0;
2149 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2150 bfd_idx++;
2151
2152 psym_arr = bfd_zmalloc (bfd_idx * sizeof (*psym_arr));
2153 if (psym_arr == NULL)
2154 return FALSE;
2155 sec_arr = bfd_zmalloc (bfd_idx * sizeof (*sec_arr));
2156 if (sec_arr == NULL)
2157 return FALSE;
2158
2159
2160 for (ibfd = info->input_bfds, bfd_idx = 0;
2161 ibfd != NULL;
2162 ibfd = ibfd->link_next, bfd_idx++)
2163 {
2164 extern const bfd_target bfd_elf32_spu_vec;
2165 Elf_Internal_Shdr *symtab_hdr;
2166 asection *sec;
2167 size_t symcount;
2168 Elf_Internal_Sym *syms, *sy, **psyms, **psy;
2169 asection **psecs, **p;
2170
2171 if (ibfd->xvec != &bfd_elf32_spu_vec)
2172 continue;
2173
2174 /* Read all the symbols. */
2175 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2176 symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
2177 if (symcount == 0)
2178 continue;
2179
2180 syms = (Elf_Internal_Sym *) symtab_hdr->contents;
2181 if (syms == NULL)
2182 {
2183 syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
2184 NULL, NULL, NULL);
2185 symtab_hdr->contents = (void *) syms;
2186 if (syms == NULL)
2187 return FALSE;
2188 }
2189
2190 /* Select defined function symbols that are going to be output. */
2191 psyms = bfd_malloc ((symcount + 1) * sizeof (*psyms));
2192 if (psyms == NULL)
2193 return FALSE;
2194 psym_arr[bfd_idx] = psyms;
2195 psecs = bfd_malloc (symcount * sizeof (*psecs));
2196 if (psecs == NULL)
2197 return FALSE;
2198 sec_arr[bfd_idx] = psecs;
2199 for (psy = psyms, p = psecs, sy = syms; sy < syms + symcount; ++p, ++sy)
2200 if (ELF_ST_TYPE (sy->st_info) == STT_NOTYPE
2201 || ELF_ST_TYPE (sy->st_info) == STT_FUNC)
2202 {
2203 asection *s;
2204
2205 *p = s = bfd_section_from_elf_index (ibfd, sy->st_shndx);
47f6dab9 2206 if (s != NULL && interesting_section (s, output_bfd))
49fa1e15
AM
2207 *psy++ = sy;
2208 }
2209 symcount = psy - psyms;
2210 *psy = NULL;
2211
2212 /* Sort them by section and offset within section. */
2213 sort_syms_syms = syms;
2214 sort_syms_psecs = psecs;
2215 qsort (psyms, symcount, sizeof (*psyms), sort_syms);
2216
2217 /* Now inspect the function symbols. */
2218 for (psy = psyms; psy < psyms + symcount; )
2219 {
2220 asection *s = psecs[*psy - syms];
2221 Elf_Internal_Sym **psy2;
2222
2223 for (psy2 = psy; ++psy2 < psyms + symcount; )
2224 if (psecs[*psy2 - syms] != s)
2225 break;
2226
2227 if (!alloc_stack_info (s, psy2 - psy))
2228 return FALSE;
2229 psy = psy2;
2230 }
2231
2232 /* First install info about properly typed and sized functions.
2233 In an ideal world this will cover all code sections, except
2234 when partitioning functions into hot and cold sections,
2235 and the horrible pasted together .init and .fini functions. */
2236 for (psy = psyms; psy < psyms + symcount; ++psy)
2237 {
2238 sy = *psy;
2239 if (ELF_ST_TYPE (sy->st_info) == STT_FUNC)
2240 {
2241 asection *s = psecs[sy - syms];
2242 if (!maybe_insert_function (s, sy, FALSE, TRUE))
2243 return FALSE;
2244 }
2245 }
2246
2247 for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
47f6dab9 2248 if (interesting_section (sec, output_bfd))
49fa1e15
AM
2249 gaps |= check_function_ranges (sec, info);
2250 }
2251
2252 if (gaps)
2253 {
2254 /* See if we can discover more function symbols by looking at
2255 relocations. */
2256 for (ibfd = info->input_bfds, bfd_idx = 0;
2257 ibfd != NULL;
2258 ibfd = ibfd->link_next, bfd_idx++)
2259 {
2260 asection *sec;
2261
2262 if (psym_arr[bfd_idx] == NULL)
2263 continue;
2264
2265 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
47f6dab9 2266 if (interesting_section (sec, output_bfd)
49fa1e15
AM
2267 && sec->reloc_count != 0)
2268 {
2269 if (!mark_functions_via_relocs (sec, info, FALSE))
2270 return FALSE;
2271 }
2272 }
2273
2274 for (ibfd = info->input_bfds, bfd_idx = 0;
2275 ibfd != NULL;
2276 ibfd = ibfd->link_next, bfd_idx++)
2277 {
2278 Elf_Internal_Shdr *symtab_hdr;
2279 asection *sec;
2280 Elf_Internal_Sym *syms, *sy, **psyms, **psy;
2281 asection **psecs;
2282
2283 if ((psyms = psym_arr[bfd_idx]) == NULL)
2284 continue;
2285
2286 psecs = sec_arr[bfd_idx];
2287
2288 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2289 syms = (Elf_Internal_Sym *) symtab_hdr->contents;
2290
2291 gaps = FALSE;
2292 for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
47f6dab9 2293 if (interesting_section (sec, output_bfd))
49fa1e15
AM
2294 gaps |= check_function_ranges (sec, info);
2295 if (!gaps)
2296 continue;
2297
2298 /* Finally, install all globals. */
2299 for (psy = psyms; (sy = *psy) != NULL; ++psy)
2300 {
2301 asection *s;
2302
2303 s = psecs[sy - syms];
2304
2305 /* Global syms might be improperly typed functions. */
2306 if (ELF_ST_TYPE (sy->st_info) != STT_FUNC
2307 && ELF_ST_BIND (sy->st_info) == STB_GLOBAL)
2308 {
2309 if (!maybe_insert_function (s, sy, FALSE, FALSE))
2310 return FALSE;
2311 }
2312 }
2313
2314 /* Some of the symbols we've installed as marking the
2315 beginning of functions may have a size of zero. Extend
2316 the range of such functions to the beginning of the
2317 next symbol of interest. */
2318 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
47f6dab9 2319 if (interesting_section (sec, output_bfd))
49fa1e15
AM
2320 {
2321 struct _spu_elf_section_data *sec_data;
2322 struct spu_elf_stack_info *sinfo;
2323
2324 sec_data = spu_elf_section_data (sec);
47f6dab9 2325 sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
2326 if (sinfo != NULL)
2327 {
2328 int fun_idx;
2329 bfd_vma hi = sec->size;
2330
2331 for (fun_idx = sinfo->num_fun; --fun_idx >= 0; )
2332 {
2333 sinfo->fun[fun_idx].hi = hi;
2334 hi = sinfo->fun[fun_idx].lo;
2335 }
2336 }
2337 /* No symbols in this section. Must be .init or .fini
2338 or something similar. */
2339 else if (!pasted_function (sec, info))
2340 return FALSE;
2341 }
2342 }
2343 }
2344
2345 for (ibfd = info->input_bfds, bfd_idx = 0;
2346 ibfd != NULL;
2347 ibfd = ibfd->link_next, bfd_idx++)
2348 {
2349 if (psym_arr[bfd_idx] == NULL)
2350 continue;
2351
2352 free (psym_arr[bfd_idx]);
2353 free (sec_arr[bfd_idx]);
2354 }
2355
2356 free (psym_arr);
2357 free (sec_arr);
2358
2359 return TRUE;
2360}
2361
2362/* Mark nodes in the call graph that are called by some other node. */
2363
2364static void
2365mark_non_root (struct function_info *fun)
2366{
2367 struct call_info *call;
2368
2369 fun->visit1 = TRUE;
2370 for (call = fun->call_list; call; call = call->next)
2371 {
2372 call->fun->non_root = TRUE;
2373 if (!call->fun->visit1)
2374 mark_non_root (call->fun);
2375 }
2376}
2377
2378/* Remove cycles from the call graph. */
2379
2380static void
2381call_graph_traverse (struct function_info *fun, struct bfd_link_info *info)
2382{
2383 struct call_info **callp, *call;
2384
2385 fun->visit2 = TRUE;
2386 fun->marking = TRUE;
2387
2388 callp = &fun->call_list;
2389 while ((call = *callp) != NULL)
2390 {
2391 if (!call->fun->visit2)
2392 call_graph_traverse (call->fun, info);
2393 else if (call->fun->marking)
2394 {
2395 const char *f1 = func_name (fun);
2396 const char *f2 = func_name (call->fun);
2397
2398 info->callbacks->info (_("Stack analysis will ignore the call "
2399 "from %s to %s\n"),
2400 f1, f2);
2401 *callp = call->next;
2402 continue;
2403 }
2404 callp = &call->next;
2405 }
2406 fun->marking = FALSE;
2407}
2408
2409/* Populate call_list for each function. */
2410
2411static bfd_boolean
2412build_call_tree (bfd *output_bfd, struct bfd_link_info *info)
2413{
49fa1e15
AM
2414 bfd *ibfd;
2415
2416 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2417 {
2418 extern const bfd_target bfd_elf32_spu_vec;
2419 asection *sec;
2420
2421 if (ibfd->xvec != &bfd_elf32_spu_vec)
2422 continue;
2423
2424 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2425 {
47f6dab9 2426 if (!interesting_section (sec, output_bfd)
49fa1e15
AM
2427 || sec->reloc_count == 0)
2428 continue;
2429
2430 if (!mark_functions_via_relocs (sec, info, TRUE))
2431 return FALSE;
2432 }
2433
2434 /* Transfer call info from hot/cold section part of function
2435 to main entry. */
2436 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2437 {
2438 struct _spu_elf_section_data *sec_data;
2439 struct spu_elf_stack_info *sinfo;
2440
2441 if ((sec_data = spu_elf_section_data (sec)) != NULL
47f6dab9 2442 && (sinfo = sec_data->u.i.stack_info) != NULL)
49fa1e15
AM
2443 {
2444 int i;
2445 for (i = 0; i < sinfo->num_fun; ++i)
2446 {
911f096e
AM
2447 struct function_info *start = sinfo->fun[i].start;
2448
2449 if (start != NULL)
49fa1e15 2450 {
911f096e 2451 struct call_info *call;
49fa1e15 2452
911f096e
AM
2453 while (start->start != NULL)
2454 start = start->start;
2455 call = sinfo->fun[i].call_list;
49fa1e15
AM
2456 while (call != NULL)
2457 {
2458 struct call_info *call_next = call->next;
911f096e 2459 if (!insert_callee (start, call))
49fa1e15
AM
2460 free (call);
2461 call = call_next;
2462 }
2463 sinfo->fun[i].call_list = NULL;
2464 sinfo->fun[i].non_root = TRUE;
2465 }
2466 }
2467 }
2468 }
2469 }
2470
2471 /* Find the call graph root(s). */
2472 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2473 {
2474 extern const bfd_target bfd_elf32_spu_vec;
2475 asection *sec;
2476
2477 if (ibfd->xvec != &bfd_elf32_spu_vec)
2478 continue;
2479
2480 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2481 {
2482 struct _spu_elf_section_data *sec_data;
2483 struct spu_elf_stack_info *sinfo;
2484
2485 if ((sec_data = spu_elf_section_data (sec)) != NULL
47f6dab9 2486 && (sinfo = sec_data->u.i.stack_info) != NULL)
49fa1e15
AM
2487 {
2488 int i;
2489 for (i = 0; i < sinfo->num_fun; ++i)
2490 if (!sinfo->fun[i].visit1)
2491 mark_non_root (&sinfo->fun[i]);
2492 }
2493 }
2494 }
2495
2496 /* Remove cycles from the call graph. We start from the root node(s)
2497 so that we break cycles in a reasonable place. */
2498 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2499 {
2500 extern const bfd_target bfd_elf32_spu_vec;
2501 asection *sec;
2502
2503 if (ibfd->xvec != &bfd_elf32_spu_vec)
2504 continue;
2505
2506 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2507 {
2508 struct _spu_elf_section_data *sec_data;
2509 struct spu_elf_stack_info *sinfo;
2510
2511 if ((sec_data = spu_elf_section_data (sec)) != NULL
47f6dab9 2512 && (sinfo = sec_data->u.i.stack_info) != NULL)
49fa1e15
AM
2513 {
2514 int i;
2515 for (i = 0; i < sinfo->num_fun; ++i)
2516 if (!sinfo->fun[i].non_root)
2517 call_graph_traverse (&sinfo->fun[i], info);
2518 }
2519 }
2520 }
2521
2522 return TRUE;
2523}
2524
2525/* Descend the call graph for FUN, accumulating total stack required. */
2526
2527static bfd_vma
2528sum_stack (struct function_info *fun,
2529 struct bfd_link_info *info,
2530 int emit_stack_syms)
2531{
2532 struct call_info *call;
2533 struct function_info *max = NULL;
2534 bfd_vma max_stack = fun->stack;
2535 bfd_vma stack;
2536 const char *f1;
2537
2538 if (fun->visit3)
2539 return max_stack;
2540
2541 for (call = fun->call_list; call; call = call->next)
2542 {
2543 stack = sum_stack (call->fun, info, emit_stack_syms);
2544 /* Include caller stack for normal calls, don't do so for
2545 tail calls. fun->stack here is local stack usage for
2546 this function. */
2547 if (!call->is_tail)
2548 stack += fun->stack;
2549 if (max_stack < stack)
2550 {
2551 max_stack = stack;
2552 max = call->fun;
2553 }
2554 }
2555
2556 f1 = func_name (fun);
fad9eaf0
AM
2557 info->callbacks->minfo (_("%s: 0x%v 0x%v\n"),
2558 f1, (bfd_vma) fun->stack, max_stack);
49fa1e15
AM
2559
2560 if (fun->call_list)
2561 {
2562 info->callbacks->minfo (_(" calls:\n"));
2563 for (call = fun->call_list; call; call = call->next)
2564 {
2565 const char *f2 = func_name (call->fun);
2566 const char *ann1 = call->fun == max ? "*" : " ";
2567 const char *ann2 = call->is_tail ? "t" : " ";
2568
2569 info->callbacks->minfo (_(" %s%s %s\n"), ann1, ann2, f2);
2570 }
2571 }
2572
2573 /* Now fun->stack holds cumulative stack. */
2574 fun->stack = max_stack;
2575 fun->visit3 = TRUE;
2576
2577 if (emit_stack_syms)
2578 {
2579 struct spu_link_hash_table *htab = spu_hash_table (info);
2580 char *name = bfd_malloc (18 + strlen (f1));
2581 struct elf_link_hash_entry *h;
2582
2583 if (name != NULL)
2584 {
2585 if (fun->global || ELF_ST_BIND (fun->u.sym->st_info) == STB_GLOBAL)
2586 sprintf (name, "__stack_%s", f1);
2587 else
2588 sprintf (name, "__stack_%x_%s", fun->sec->id & 0xffffffff, f1);
2589
2590 h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
2591 free (name);
2592 if (h != NULL
2593 && (h->root.type == bfd_link_hash_new
2594 || h->root.type == bfd_link_hash_undefined
2595 || h->root.type == bfd_link_hash_undefweak))
2596 {
2597 h->root.type = bfd_link_hash_defined;
2598 h->root.u.def.section = bfd_abs_section_ptr;
2599 h->root.u.def.value = max_stack;
2600 h->size = 0;
2601 h->type = 0;
2602 h->ref_regular = 1;
2603 h->def_regular = 1;
2604 h->ref_regular_nonweak = 1;
2605 h->forced_local = 1;
2606 h->non_elf = 0;
2607 }
2608 }
2609 }
2610
2611 return max_stack;
2612}
2613
2614/* Provide an estimate of total stack required. */
2615
2616static bfd_boolean
2617spu_elf_stack_analysis (bfd *output_bfd,
2618 struct bfd_link_info *info,
2619 int emit_stack_syms)
2620{
2621 bfd *ibfd;
2622 bfd_vma max_stack = 0;
2623
2624 if (!discover_functions (output_bfd, info))
2625 return FALSE;
2626
2627 if (!build_call_tree (output_bfd, info))
2628 return FALSE;
2629
2630 info->callbacks->info (_("Stack size for call graph root nodes.\n"));
2631 info->callbacks->minfo (_("\nStack size for functions. "
2632 "Annotations: '*' max stack, 't' tail call\n"));
2633 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2634 {
2635 extern const bfd_target bfd_elf32_spu_vec;
2636 asection *sec;
2637
2638 if (ibfd->xvec != &bfd_elf32_spu_vec)
2639 continue;
2640
2641 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2642 {
2643 struct _spu_elf_section_data *sec_data;
2644 struct spu_elf_stack_info *sinfo;
2645
2646 if ((sec_data = spu_elf_section_data (sec)) != NULL
47f6dab9 2647 && (sinfo = sec_data->u.i.stack_info) != NULL)
49fa1e15
AM
2648 {
2649 int i;
2650 for (i = 0; i < sinfo->num_fun; ++i)
2651 {
2652 if (!sinfo->fun[i].non_root)
2653 {
2654 bfd_vma stack;
2655 const char *f1;
2656
2657 stack = sum_stack (&sinfo->fun[i], info,
2658 emit_stack_syms);
2659 f1 = func_name (&sinfo->fun[i]);
2660 info->callbacks->info (_(" %s: 0x%v\n"),
2661 f1, stack);
2662 if (max_stack < stack)
2663 max_stack = stack;
2664 }
2665 }
2666 }
2667 }
2668 }
2669
2670 info->callbacks->info (_("Maximum stack required is 0x%v\n"), max_stack);
2671 return TRUE;
2672}
2673
2674/* Perform a final link. */
2675
2676static bfd_boolean
2677spu_elf_final_link (bfd *output_bfd, struct bfd_link_info *info)
2678{
2679 struct spu_link_hash_table *htab = spu_hash_table (info);
2680
2681 if (htab->stack_analysis
2682 && !spu_elf_stack_analysis (output_bfd, info, htab->emit_stack_syms))
2683 info->callbacks->einfo ("%X%P: stack analysis error: %E\n");
2684
2685 return bfd_elf_final_link (output_bfd, info);
2686}
2687
ece5ef60
AM
2688/* Called when not normally emitting relocs, ie. !info->relocatable
2689 and !info->emitrelocations. Returns a count of special relocs
2690 that need to be emitted. */
2691
2692static unsigned int
2693spu_elf_count_relocs (asection *sec, Elf_Internal_Rela *relocs)
2694{
2695 unsigned int count = 0;
2696 Elf_Internal_Rela *relend = relocs + sec->reloc_count;
2697
2698 for (; relocs < relend; relocs++)
2699 {
2700 int r_type = ELF32_R_TYPE (relocs->r_info);
2701 if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
2702 ++count;
2703 }
2704
2705 return count;
2706}
2707
e9f53129
AM
2708/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
2709
d16c7321 2710static int
e9f53129
AM
2711spu_elf_relocate_section (bfd *output_bfd,
2712 struct bfd_link_info *info,
2713 bfd *input_bfd,
2714 asection *input_section,
2715 bfd_byte *contents,
2716 Elf_Internal_Rela *relocs,
2717 Elf_Internal_Sym *local_syms,
2718 asection **local_sections)
2719{
2720 Elf_Internal_Shdr *symtab_hdr;
2721 struct elf_link_hash_entry **sym_hashes;
2722 Elf_Internal_Rela *rel, *relend;
2723 struct spu_link_hash_table *htab;
d16c7321 2724 int ret = TRUE;
ece5ef60 2725 bfd_boolean emit_these_relocs = FALSE;
fdba2fcd 2726 bfd_boolean stubs;
e9f53129 2727
e9f53129 2728 htab = spu_hash_table (info);
fdba2fcd
AM
2729 stubs = (htab->stub_sec != NULL
2730 && maybe_needs_stubs (input_section, output_bfd));
e9f53129
AM
2731 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2732 sym_hashes = (struct elf_link_hash_entry **) (elf_sym_hashes (input_bfd));
2733
2734 rel = relocs;
2735 relend = relocs + input_section->reloc_count;
2736 for (; rel < relend; rel++)
2737 {
2738 int r_type;
2739 reloc_howto_type *howto;
2740 unsigned long r_symndx;
2741 Elf_Internal_Sym *sym;
2742 asection *sec;
2743 struct elf_link_hash_entry *h;
2744 const char *sym_name;
2745 bfd_vma relocation;
2746 bfd_vma addend;
2747 bfd_reloc_status_type r;
2748 bfd_boolean unresolved_reloc;
2749 bfd_boolean warned;
2750
2751 r_symndx = ELF32_R_SYM (rel->r_info);
2752 r_type = ELF32_R_TYPE (rel->r_info);
ece5ef60
AM
2753 if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
2754 {
2755 emit_these_relocs = TRUE;
2756 continue;
2757 }
2758
e9f53129
AM
2759 howto = elf_howto_table + r_type;
2760 unresolved_reloc = FALSE;
2761 warned = FALSE;
e9f53129
AM
2762 h = NULL;
2763 sym = NULL;
2764 sec = NULL;
2765 if (r_symndx < symtab_hdr->sh_info)
2766 {
2767 sym = local_syms + r_symndx;
2768 sec = local_sections[r_symndx];
2769 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2770 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2771 }
2772 else
2773 {
2774 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2775 r_symndx, symtab_hdr, sym_hashes,
2776 h, sec, relocation,
2777 unresolved_reloc, warned);
2778 sym_name = h->root.root.string;
2779 }
2780
ab96bf03
AM
2781 if (sec != NULL && elf_discarded_section (sec))
2782 {
2783 /* For relocs against symbols from removed linkonce sections,
2784 or sections discarded by a linker script, we just want the
2785 section contents zeroed. Avoid any special processing. */
2786 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2787 rel->r_info = 0;
2788 rel->r_addend = 0;
2789 continue;
2790 }
2791
2792 if (info->relocatable)
2793 continue;
2794
e9f53129
AM
2795 if (unresolved_reloc)
2796 {
2797 (*_bfd_error_handler)
2798 (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
2799 input_bfd,
2800 bfd_get_section_name (input_bfd, input_section),
2801 (long) rel->r_offset,
2802 howto->name,
2803 sym_name);
2804 ret = FALSE;
2805 }
2806
2807 /* If this symbol is in an overlay area, we may need to relocate
2808 to the overlay stub. */
2809 addend = rel->r_addend;
fdba2fcd 2810 if (stubs)
e9f53129 2811 {
fdba2fcd 2812 enum _stub_type stub_type;
47f6dab9 2813
fdba2fcd
AM
2814 stub_type = needs_ovl_stub (h, sym, sec, input_section, rel,
2815 contents, info);
2816 if (stub_type != no_stub)
5f5fb9ec
AM
2817 {
2818 unsigned int ovl = 0;
2819 struct got_entry *g, **head;
2820
fdba2fcd 2821 if (stub_type != nonovl_stub)
5f5fb9ec
AM
2822 ovl = (spu_elf_section_data (input_section->output_section)
2823 ->u.o.ovl_index);
2824
2825 if (h != NULL)
2826 head = &h->got.glist;
2827 else
2828 head = elf_local_got_ents (input_bfd) + r_symndx;
47f6dab9 2829
5f5fb9ec
AM
2830 for (g = *head; g != NULL; g = g->next)
2831 if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
2832 break;
2833 if (g == NULL)
2834 abort ();
2835
2836 relocation = g->stub_addr;
2837 addend = 0;
2838 }
e9f53129
AM
2839 }
2840
2841 r = _bfd_final_link_relocate (howto,
2842 input_bfd,
2843 input_section,
2844 contents,
2845 rel->r_offset, relocation, addend);
2846
2847 if (r != bfd_reloc_ok)
2848 {
2849 const char *msg = (const char *) 0;
2850
2851 switch (r)
2852 {
2853 case bfd_reloc_overflow:
2854 if (!((*info->callbacks->reloc_overflow)
2855 (info, (h ? &h->root : NULL), sym_name, howto->name,
2856 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
2857 return FALSE;
2858 break;
2859
2860 case bfd_reloc_undefined:
2861 if (!((*info->callbacks->undefined_symbol)
2862 (info, sym_name, input_bfd, input_section,
2863 rel->r_offset, TRUE)))
2864 return FALSE;
2865 break;
2866
2867 case bfd_reloc_outofrange:
2868 msg = _("internal error: out of range error");
2869 goto common_error;
2870
2871 case bfd_reloc_notsupported:
2872 msg = _("internal error: unsupported relocation error");
2873 goto common_error;
2874
2875 case bfd_reloc_dangerous:
2876 msg = _("internal error: dangerous error");
2877 goto common_error;
2878
2879 default:
2880 msg = _("internal error: unknown error");
2881 /* fall through */
2882
2883 common_error:
d16c7321 2884 ret = FALSE;
e9f53129
AM
2885 if (!((*info->callbacks->warning)
2886 (info, msg, sym_name, input_bfd, input_section,
2887 rel->r_offset)))
2888 return FALSE;
2889 break;
2890 }
2891 }
2892 }
2893
ece5ef60
AM
2894 if (ret
2895 && emit_these_relocs
2896 && !info->relocatable
2897 && !info->emitrelocations)
2898 {
2899 Elf_Internal_Rela *wrel;
2900 Elf_Internal_Shdr *rel_hdr;
2901
2902 wrel = rel = relocs;
2903 relend = relocs + input_section->reloc_count;
2904 for (; rel < relend; rel++)
2905 {
2906 int r_type;
2907
2908 r_type = ELF32_R_TYPE (rel->r_info);
2909 if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
2910 *wrel++ = *rel;
2911 }
2912 input_section->reloc_count = wrel - relocs;
2913 /* Backflips for _bfd_elf_link_output_relocs. */
2914 rel_hdr = &elf_section_data (input_section)->rel_hdr;
2915 rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
2916 ret = 2;
2917 }
2918
e9f53129
AM
2919 return ret;
2920}
2921
c1b2796f
AM
2922/* Adjust _SPUEAR_ syms to point at their overlay stubs. */
2923
2924static bfd_boolean
2925spu_elf_output_symbol_hook (struct bfd_link_info *info,
2926 const char *sym_name ATTRIBUTE_UNUSED,
2927 Elf_Internal_Sym *sym,
2928 asection *sym_sec ATTRIBUTE_UNUSED,
2929 struct elf_link_hash_entry *h)
2930{
2931 struct spu_link_hash_table *htab = spu_hash_table (info);
2932
2933 if (!info->relocatable
47f6dab9 2934 && htab->stub_sec != NULL
c1b2796f
AM
2935 && h != NULL
2936 && (h->root.type == bfd_link_hash_defined
2937 || h->root.type == bfd_link_hash_defweak)
2938 && h->def_regular
2939 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
2940 {
4a628337 2941 struct got_entry *g;
c1b2796f 2942
4a628337
AM
2943 for (g = h->got.glist; g != NULL; g = g->next)
2944 if (g->addend == 0 && g->ovl == 0)
2945 {
2946 sym->st_shndx = (_bfd_elf_section_from_bfd_section
2947 (htab->stub_sec[0]->output_section->owner,
2948 htab->stub_sec[0]->output_section));
2949 sym->st_value = g->stub_addr;
2950 break;
2951 }
c1b2796f
AM
2952 }
2953
2954 return TRUE;
2955}
2956
e9f53129
AM
2957static int spu_plugin = 0;
2958
2959void
2960spu_elf_plugin (int val)
2961{
2962 spu_plugin = val;
2963}
2964
2965/* Set ELF header e_type for plugins. */
2966
2967static void
2968spu_elf_post_process_headers (bfd *abfd,
2969 struct bfd_link_info *info ATTRIBUTE_UNUSED)
2970{
2971 if (spu_plugin)
2972 {
2973 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
2974
2975 i_ehdrp->e_type = ET_DYN;
2976 }
2977}
2978
2979/* We may add an extra PT_LOAD segment for .toe. We also need extra
2980 segments for overlays. */
2981
2982static int
2983spu_elf_additional_program_headers (bfd *abfd, struct bfd_link_info *info)
2984{
2985 struct spu_link_hash_table *htab = spu_hash_table (info);
2986 int extra = htab->num_overlays;
2987 asection *sec;
2988
2989 if (extra)
2990 ++extra;
2991
2992 sec = bfd_get_section_by_name (abfd, ".toe");
2993 if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
2994 ++extra;
2995
2996 return extra;
2997}
2998
2999/* Remove .toe section from other PT_LOAD segments and put it in
3000 a segment of its own. Put overlays in separate segments too. */
3001
3002static bfd_boolean
3003spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
3004{
3005 asection *toe, *s;
3006 struct elf_segment_map *m;
3007 unsigned int i;
3008
3009 if (info == NULL)
3010 return TRUE;
3011
3012 toe = bfd_get_section_by_name (abfd, ".toe");
3013 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
3014 if (m->p_type == PT_LOAD && m->count > 1)
3015 for (i = 0; i < m->count; i++)
3016 if ((s = m->sections[i]) == toe
47f6dab9 3017 || spu_elf_section_data (s)->u.o.ovl_index != 0)
e9f53129
AM
3018 {
3019 struct elf_segment_map *m2;
3020 bfd_vma amt;
3021
3022 if (i + 1 < m->count)
3023 {
3024 amt = sizeof (struct elf_segment_map);
3025 amt += (m->count - (i + 2)) * sizeof (m->sections[0]);
3026 m2 = bfd_zalloc (abfd, amt);
3027 if (m2 == NULL)
3028 return FALSE;
3029 m2->count = m->count - (i + 1);
3030 memcpy (m2->sections, m->sections + i + 1,
3031 m2->count * sizeof (m->sections[0]));
3032 m2->p_type = PT_LOAD;
3033 m2->next = m->next;
3034 m->next = m2;
3035 }
3036 m->count = 1;
3037 if (i != 0)
3038 {
3039 m->count = i;
3040 amt = sizeof (struct elf_segment_map);
3041 m2 = bfd_zalloc (abfd, amt);
3042 if (m2 == NULL)
3043 return FALSE;
3044 m2->p_type = PT_LOAD;
3045 m2->count = 1;
3046 m2->sections[0] = s;
3047 m2->next = m->next;
3048 m->next = m2;
3049 }
3050 break;
3051 }
3052
3053 return TRUE;
3054}
3055
3056/* Check that all loadable section VMAs lie in the range
3057 LO .. HI inclusive. */
3058
3059asection *
3060spu_elf_check_vma (bfd *abfd, bfd_vma lo, bfd_vma hi)
3061{
3062 struct elf_segment_map *m;
3063 unsigned int i;
3064
3065 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
3066 if (m->p_type == PT_LOAD)
3067 for (i = 0; i < m->count; i++)
3068 if (m->sections[i]->size != 0
3069 && (m->sections[i]->vma < lo
3070 || m->sections[i]->vma > hi
3071 || m->sections[i]->vma + m->sections[i]->size - 1 > hi))
3072 return m->sections[i];
3073
3074 return NULL;
3075}
3076
7d3287cb
AM
3077/* Tweak the section type of .note.spu_name. */
3078
3079static bfd_boolean
3080spu_elf_fake_sections (bfd *obfd ATTRIBUTE_UNUSED,
3081 Elf_Internal_Shdr *hdr,
3082 asection *sec)
3083{
3084 if (strcmp (sec->name, SPU_PTNOTE_SPUNAME) == 0)
3085 hdr->sh_type = SHT_NOTE;
3086 return TRUE;
3087}
3088
e9f53129
AM
3089/* Tweak phdrs before writing them out. */
3090
3091static int
3092spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
3093{
3094 const struct elf_backend_data *bed;
3095 struct elf_obj_tdata *tdata;
3096 Elf_Internal_Phdr *phdr, *last;
3097 struct spu_link_hash_table *htab;
3098 unsigned int count;
3099 unsigned int i;
3100
3101 if (info == NULL)
3102 return TRUE;
3103
3104 bed = get_elf_backend_data (abfd);
3105 tdata = elf_tdata (abfd);
3106 phdr = tdata->phdr;
3107 count = tdata->program_header_size / bed->s->sizeof_phdr;
3108 htab = spu_hash_table (info);
3109 if (htab->num_overlays != 0)
3110 {
3111 struct elf_segment_map *m;
3112 unsigned int o;
3113
3114 for (i = 0, m = elf_tdata (abfd)->segment_map; m; ++i, m = m->next)
3115 if (m->count != 0
47f6dab9 3116 && (o = spu_elf_section_data (m->sections[0])->u.o.ovl_index) != 0)
e9f53129
AM
3117 {
3118 /* Mark this as an overlay header. */
3119 phdr[i].p_flags |= PF_OVERLAY;
3120
3121 if (htab->ovtab != NULL && htab->ovtab->size != 0)
3122 {
3123 bfd_byte *p = htab->ovtab->contents;
47f6dab9 3124 unsigned int off = o * 16 + 8;
e9f53129
AM
3125
3126 /* Write file_off into _ovly_table. */
3127 bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off);
3128 }
3129 }
3130 }
3131
3132 /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
3133 of 16. This should always be possible when using the standard
3134 linker scripts, but don't create overlapping segments if
3135 someone is playing games with linker scripts. */
3136 last = NULL;
3137 for (i = count; i-- != 0; )
3138 if (phdr[i].p_type == PT_LOAD)
3139 {
3140 unsigned adjust;
3141
3142 adjust = -phdr[i].p_filesz & 15;
3143 if (adjust != 0
3144 && last != NULL
3145 && phdr[i].p_offset + phdr[i].p_filesz > last->p_offset - adjust)
3146 break;
3147
3148 adjust = -phdr[i].p_memsz & 15;
3149 if (adjust != 0
3150 && last != NULL
3151 && phdr[i].p_filesz != 0
3152 && phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust
3153 && phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr)
3154 break;
3155
3156 if (phdr[i].p_filesz != 0)
3157 last = &phdr[i];
3158 }
3159
3160 if (i == (unsigned int) -1)
3161 for (i = count; i-- != 0; )
3162 if (phdr[i].p_type == PT_LOAD)
3163 {
3164 unsigned adjust;
3165
3166 adjust = -phdr[i].p_filesz & 15;
3167 phdr[i].p_filesz += adjust;
3168
3169 adjust = -phdr[i].p_memsz & 15;
3170 phdr[i].p_memsz += adjust;
3171 }
3172
3173 return TRUE;
3174}
3175
e9f53129
AM
3176#define TARGET_BIG_SYM bfd_elf32_spu_vec
3177#define TARGET_BIG_NAME "elf32-spu"
3178#define ELF_ARCH bfd_arch_spu
3179#define ELF_MACHINE_CODE EM_SPU
3180/* This matches the alignment need for DMA. */
3181#define ELF_MAXPAGESIZE 0x80
3182#define elf_backend_rela_normal 1
3183#define elf_backend_can_gc_sections 1
3184
3185#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
157090f7 3186#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_lookup
e9f53129 3187#define elf_info_to_howto spu_elf_info_to_howto
ece5ef60 3188#define elf_backend_count_relocs spu_elf_count_relocs
e9f53129
AM
3189#define elf_backend_relocate_section spu_elf_relocate_section
3190#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
c1b2796f 3191#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
e9f53129
AM
3192#define bfd_elf32_new_section_hook spu_elf_new_section_hook
3193#define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create
e9f53129
AM
3194
3195#define elf_backend_additional_program_headers spu_elf_additional_program_headers
3196#define elf_backend_modify_segment_map spu_elf_modify_segment_map
3197#define elf_backend_modify_program_headers spu_elf_modify_program_headers
3198#define elf_backend_post_process_headers spu_elf_post_process_headers
7d3287cb 3199#define elf_backend_fake_sections spu_elf_fake_sections
e9f53129 3200#define elf_backend_special_sections spu_elf_special_sections
49fa1e15 3201#define bfd_elf32_bfd_final_link spu_elf_final_link
e9f53129
AM
3202
3203#include "elf32-target.h"
This page took 0.258415 seconds and 4 git commands to generate.