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