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