* ldlang.c (lang_insert_orphan): Add __start_<section> symbol
[deliverable/binutils-gdb.git] / bfd / elf32-spu.c
CommitLineData
e9f53129
AM
1/* SPU specific support for 32-bit ELF
2
cd4a7468 3 Copyright 2006, 2007, 2008, 2009 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"
9dcc4794 22#include "libiberty.h"
3db64b00 23#include "bfd.h"
e9f53129
AM
24#include "bfdlink.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/spu.h"
28#include "elf32-spu.h"
29
30/* We use RELA style relocs. Don't define USE_REL. */
31
32static bfd_reloc_status_type spu_elf_rel9 (bfd *, arelent *, asymbol *,
33 void *, asection *,
34 bfd *, char **);
35
36/* Values of type 'enum elf_spu_reloc_type' are used to index this
37 array, so it must be declared in the order of that type. */
38
39static reloc_howto_type elf_howto_table[] = {
40 HOWTO (R_SPU_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
41 bfd_elf_generic_reloc, "SPU_NONE",
42 FALSE, 0, 0x00000000, FALSE),
43 HOWTO (R_SPU_ADDR10, 4, 2, 10, FALSE, 14, complain_overflow_bitfield,
44 bfd_elf_generic_reloc, "SPU_ADDR10",
45 FALSE, 0, 0x00ffc000, FALSE),
46 HOWTO (R_SPU_ADDR16, 2, 2, 16, FALSE, 7, complain_overflow_bitfield,
47 bfd_elf_generic_reloc, "SPU_ADDR16",
48 FALSE, 0, 0x007fff80, FALSE),
49 HOWTO (R_SPU_ADDR16_HI, 16, 2, 16, FALSE, 7, complain_overflow_bitfield,
50 bfd_elf_generic_reloc, "SPU_ADDR16_HI",
51 FALSE, 0, 0x007fff80, FALSE),
52 HOWTO (R_SPU_ADDR16_LO, 0, 2, 16, FALSE, 7, complain_overflow_dont,
53 bfd_elf_generic_reloc, "SPU_ADDR16_LO",
54 FALSE, 0, 0x007fff80, FALSE),
55 HOWTO (R_SPU_ADDR18, 0, 2, 18, FALSE, 7, complain_overflow_bitfield,
56 bfd_elf_generic_reloc, "SPU_ADDR18",
57 FALSE, 0, 0x01ffff80, FALSE),
b427ea91 58 HOWTO (R_SPU_ADDR32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
e9f53129
AM
59 bfd_elf_generic_reloc, "SPU_ADDR32",
60 FALSE, 0, 0xffffffff, FALSE),
61 HOWTO (R_SPU_REL16, 2, 2, 16, TRUE, 7, complain_overflow_bitfield,
62 bfd_elf_generic_reloc, "SPU_REL16",
63 FALSE, 0, 0x007fff80, TRUE),
64 HOWTO (R_SPU_ADDR7, 0, 2, 7, FALSE, 14, complain_overflow_dont,
65 bfd_elf_generic_reloc, "SPU_ADDR7",
66 FALSE, 0, 0x001fc000, FALSE),
67 HOWTO (R_SPU_REL9, 2, 2, 9, TRUE, 0, complain_overflow_signed,
68 spu_elf_rel9, "SPU_REL9",
69 FALSE, 0, 0x0180007f, TRUE),
70 HOWTO (R_SPU_REL9I, 2, 2, 9, TRUE, 0, complain_overflow_signed,
71 spu_elf_rel9, "SPU_REL9I",
72 FALSE, 0, 0x0000c07f, TRUE),
73 HOWTO (R_SPU_ADDR10I, 0, 2, 10, FALSE, 14, complain_overflow_signed,
74 bfd_elf_generic_reloc, "SPU_ADDR10I",
75 FALSE, 0, 0x00ffc000, FALSE),
76 HOWTO (R_SPU_ADDR16I, 0, 2, 16, FALSE, 7, complain_overflow_signed,
77 bfd_elf_generic_reloc, "SPU_ADDR16I",
78 FALSE, 0, 0x007fff80, FALSE),
b427ea91 79 HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
e9f53129
AM
80 bfd_elf_generic_reloc, "SPU_REL32",
81 FALSE, 0, 0xffffffff, TRUE),
4f4416b5
AM
82 HOWTO (R_SPU_ADDR16X, 0, 2, 16, FALSE, 7, complain_overflow_bitfield,
83 bfd_elf_generic_reloc, "SPU_ADDR16X",
84 FALSE, 0, 0x007fff80, FALSE),
b427ea91 85 HOWTO (R_SPU_PPU32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
ece5ef60
AM
86 bfd_elf_generic_reloc, "SPU_PPU32",
87 FALSE, 0, 0xffffffff, FALSE),
b427ea91 88 HOWTO (R_SPU_PPU64, 0, 4, 64, FALSE, 0, complain_overflow_dont,
ece5ef60
AM
89 bfd_elf_generic_reloc, "SPU_PPU64",
90 FALSE, 0, -1, FALSE),
e9f53129
AM
91};
92
93static struct bfd_elf_special_section const spu_elf_special_sections[] = {
8374f9d4 94 { "._ea", 4, 0, SHT_PROGBITS, SHF_WRITE },
e9f53129
AM
95 { ".toe", 4, 0, SHT_NOBITS, SHF_ALLOC },
96 { NULL, 0, 0, 0, 0 }
97};
98
99static enum elf_spu_reloc_type
100spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
101{
102 switch (code)
103 {
104 default:
105 return R_SPU_NONE;
106 case BFD_RELOC_SPU_IMM10W:
107 return R_SPU_ADDR10;
108 case BFD_RELOC_SPU_IMM16W:
109 return R_SPU_ADDR16;
110 case BFD_RELOC_SPU_LO16:
111 return R_SPU_ADDR16_LO;
112 case BFD_RELOC_SPU_HI16:
113 return R_SPU_ADDR16_HI;
114 case BFD_RELOC_SPU_IMM18:
115 return R_SPU_ADDR18;
116 case BFD_RELOC_SPU_PCREL16:
117 return R_SPU_REL16;
118 case BFD_RELOC_SPU_IMM7:
119 return R_SPU_ADDR7;
120 case BFD_RELOC_SPU_IMM8:
121 return R_SPU_NONE;
122 case BFD_RELOC_SPU_PCREL9a:
123 return R_SPU_REL9;
124 case BFD_RELOC_SPU_PCREL9b:
125 return R_SPU_REL9I;
126 case BFD_RELOC_SPU_IMM10:
127 return R_SPU_ADDR10I;
128 case BFD_RELOC_SPU_IMM16:
129 return R_SPU_ADDR16I;
130 case BFD_RELOC_32:
131 return R_SPU_ADDR32;
132 case BFD_RELOC_32_PCREL:
133 return R_SPU_REL32;
ece5ef60
AM
134 case BFD_RELOC_SPU_PPU32:
135 return R_SPU_PPU32;
136 case BFD_RELOC_SPU_PPU64:
137 return R_SPU_PPU64;
e9f53129
AM
138 }
139}
140
141static void
142spu_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
143 arelent *cache_ptr,
144 Elf_Internal_Rela *dst)
145{
146 enum elf_spu_reloc_type r_type;
147
148 r_type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info);
149 BFD_ASSERT (r_type < R_SPU_max);
150 cache_ptr->howto = &elf_howto_table[(int) r_type];
151}
152
153static reloc_howto_type *
154spu_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
155 bfd_reloc_code_real_type code)
156{
b16f296e
AM
157 enum elf_spu_reloc_type r_type = spu_elf_bfd_to_reloc_type (code);
158
159 if (r_type == R_SPU_NONE)
160 return NULL;
161
162 return elf_howto_table + r_type;
e9f53129
AM
163}
164
157090f7
AM
165static reloc_howto_type *
166spu_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
167 const char *r_name)
168{
169 unsigned int i;
170
171 for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
172 if (elf_howto_table[i].name != NULL
173 && strcasecmp (elf_howto_table[i].name, r_name) == 0)
174 return &elf_howto_table[i];
175
176 return NULL;
177}
178
e9f53129
AM
179/* Apply R_SPU_REL9 and R_SPU_REL9I relocs. */
180
181static bfd_reloc_status_type
182spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
183 void *data, asection *input_section,
184 bfd *output_bfd, char **error_message)
185{
186 bfd_size_type octets;
187 bfd_vma val;
188 long insn;
189
190 /* If this is a relocatable link (output_bfd test tells us), just
191 call the generic function. Any adjustment will be done at final
192 link time. */
193 if (output_bfd != NULL)
194 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
195 input_section, output_bfd, error_message);
196
197 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
198 return bfd_reloc_outofrange;
199 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
200
201 /* Get symbol value. */
202 val = 0;
203 if (!bfd_is_com_section (symbol->section))
204 val = symbol->value;
205 if (symbol->section->output_section)
206 val += symbol->section->output_section->vma;
207
208 val += reloc_entry->addend;
209
210 /* Make it pc-relative. */
211 val -= input_section->output_section->vma + input_section->output_offset;
212
213 val >>= 2;
214 if (val + 256 >= 512)
215 return bfd_reloc_overflow;
216
217 insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
218
219 /* Move two high bits of value to REL9I and REL9 position.
220 The mask will take care of selecting the right field. */
221 val = (val & 0x7f) | ((val & 0x180) << 7) | ((val & 0x180) << 16);
222 insn &= ~reloc_entry->howto->dst_mask;
223 insn |= val & reloc_entry->howto->dst_mask;
224 bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
225 return bfd_reloc_ok;
226}
227
228static bfd_boolean
229spu_elf_new_section_hook (bfd *abfd, asection *sec)
230{
231 if (!sec->used_by_bfd)
232 {
233 struct _spu_elf_section_data *sdata;
234
235 sdata = bfd_zalloc (abfd, sizeof (*sdata));
236 if (sdata == NULL)
237 return FALSE;
238 sec->used_by_bfd = sdata;
239 }
240
241 return _bfd_elf_new_section_hook (abfd, sec);
242}
243
124b52c6
AM
244/* Set up overlay info for executables. */
245
246static bfd_boolean
247spu_elf_object_p (bfd *abfd)
248{
249 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
250 {
251 unsigned int i, num_ovl, num_buf;
252 Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
253 Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
254 Elf_Internal_Phdr *last_phdr = NULL;
255
256 for (num_buf = 0, num_ovl = 0, i = 0; i < ehdr->e_phnum; i++, phdr++)
257 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_OVERLAY) != 0)
258 {
259 unsigned int j;
260
261 ++num_ovl;
262 if (last_phdr == NULL
263 || ((last_phdr->p_vaddr ^ phdr->p_vaddr) & 0x3ffff) != 0)
264 ++num_buf;
265 last_phdr = phdr;
266 for (j = 1; j < elf_numsections (abfd); j++)
267 {
268 Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[j];
269
270 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (shdr, phdr))
271 {
272 asection *sec = shdr->bfd_section;
273 spu_elf_section_data (sec)->u.o.ovl_index = num_ovl;
274 spu_elf_section_data (sec)->u.o.ovl_buf = num_buf;
275 }
276 }
277 }
278 }
279 return TRUE;
280}
281
e9f53129
AM
282/* Specially mark defined symbols named _EAR_* with BSF_KEEP so that
283 strip --strip-unneeded will not remove them. */
284
285static void
286spu_elf_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
287{
288 if (sym->name != NULL
289 && sym->section != bfd_abs_section_ptr
290 && strncmp (sym->name, "_EAR_", 5) == 0)
291 sym->flags |= BSF_KEEP;
292}
293
294/* SPU ELF linker hash table. */
295
296struct spu_link_hash_table
297{
298 struct elf_link_hash_table elf;
299
64615358
AM
300 struct spu_elf_params *params;
301
e9f53129 302 /* Shortcuts to overlay sections. */
e9f53129 303 asection *ovtab;
cd4a7468 304 asection *init;
47f6dab9
AM
305 asection *toe;
306 asection **ovl_sec;
307
308 /* Count of stubs in each overlay section. */
309 unsigned int *stub_count;
310
311 /* The stub section for each overlay section. */
312 asection **stub_sec;
e9f53129 313
a7e11ee1 314 struct elf_link_hash_entry *ovly_entry[2];
e9f53129 315
e9f53129
AM
316 /* Number of overlay buffers. */
317 unsigned int num_buf;
318
319 /* Total number of overlays. */
320 unsigned int num_overlays;
321
cd4a7468
AM
322 /* For soft icache. */
323 unsigned int line_size_log2;
324 unsigned int num_lines_log2;
325
9dcc4794
AM
326 /* How much memory we have. */
327 unsigned int local_store;
328 /* Local store --auto-overlay should reserve for non-overlay
329 functions and data. */
330 unsigned int overlay_fixed;
331 /* Local store --auto-overlay should reserve for stack and heap. */
332 unsigned int reserved;
99302af9
AM
333 /* If reserved is not specified, stack analysis will calculate a value
334 for the stack. This parameter adjusts that value to allow for
335 negative sp access (the ABI says 2000 bytes below sp are valid,
336 and the overlay manager uses some of this area). */
337 int extra_stack_space;
9dcc4794
AM
338 /* Count of overlay stubs needed in non-overlay area. */
339 unsigned int non_ovly_stub;
340
e9f53129 341 /* Set on error. */
47f6dab9 342 unsigned int stub_err : 1;
e9f53129
AM
343};
344
47f6dab9 345/* Hijack the generic got fields for overlay stub accounting. */
e9f53129 346
47f6dab9 347struct got_entry
e9f53129 348{
47f6dab9
AM
349 struct got_entry *next;
350 unsigned int ovl;
cd4a7468
AM
351 union {
352 bfd_vma addend;
353 bfd_vma br_addr;
354 };
47f6dab9 355 bfd_vma stub_addr;
e9f53129
AM
356};
357
47f6dab9
AM
358#define spu_hash_table(p) \
359 ((struct spu_link_hash_table *) ((p)->hash))
e9f53129 360
64615358
AM
361struct call_info
362{
363 struct function_info *fun;
364 struct call_info *next;
365 unsigned int count;
366 unsigned int max_depth;
367 unsigned int is_tail : 1;
368 unsigned int is_pasted : 1;
cd4a7468 369 unsigned int priority : 13;
64615358
AM
370};
371
372struct function_info
373{
374 /* List of functions called. Also branches to hot/cold part of
375 function. */
376 struct call_info *call_list;
377 /* For hot/cold part of function, point to owner. */
378 struct function_info *start;
379 /* Symbol at start of function. */
380 union {
381 Elf_Internal_Sym *sym;
382 struct elf_link_hash_entry *h;
383 } u;
384 /* Function section. */
385 asection *sec;
386 asection *rodata;
387 /* Where last called from, and number of sections called from. */
388 asection *last_caller;
389 unsigned int call_count;
390 /* Address range of (this part of) function. */
391 bfd_vma lo, hi;
cd4a7468
AM
392 /* Offset where we found a store of lr, or -1 if none found. */
393 bfd_vma lr_store;
394 /* Offset where we found the stack adjustment insn. */
395 bfd_vma sp_adjust;
64615358
AM
396 /* Stack usage. */
397 int stack;
398 /* Distance from root of call tree. Tail and hot/cold branches
399 count as one deeper. We aren't counting stack frames here. */
400 unsigned int depth;
401 /* Set if global symbol. */
402 unsigned int global : 1;
403 /* Set if known to be start of function (as distinct from a hunk
404 in hot/cold section. */
405 unsigned int is_func : 1;
406 /* Set if not a root node. */
407 unsigned int non_root : 1;
408 /* Flags used during call tree traversal. It's cheaper to replicate
409 the visit flags than have one which needs clearing after a traversal. */
410 unsigned int visit1 : 1;
411 unsigned int visit2 : 1;
412 unsigned int marking : 1;
413 unsigned int visit3 : 1;
414 unsigned int visit4 : 1;
415 unsigned int visit5 : 1;
416 unsigned int visit6 : 1;
417 unsigned int visit7 : 1;
418};
419
420struct spu_elf_stack_info
421{
422 int num_fun;
423 int max_fun;
424 /* Variable size array describing functions, one per contiguous
425 address range belonging to a function. */
426 struct function_info fun[1];
427};
428
cd4a7468
AM
429static struct function_info *find_function (asection *, bfd_vma,
430 struct bfd_link_info *);
431
e9f53129
AM
432/* Create a spu ELF linker hash table. */
433
434static struct bfd_link_hash_table *
435spu_elf_link_hash_table_create (bfd *abfd)
436{
437 struct spu_link_hash_table *htab;
438
439 htab = bfd_malloc (sizeof (*htab));
440 if (htab == NULL)
441 return NULL;
442
443 if (!_bfd_elf_link_hash_table_init (&htab->elf, abfd,
444 _bfd_elf_link_hash_newfunc,
445 sizeof (struct elf_link_hash_entry)))
446 {
447 free (htab);
448 return NULL;
449 }
450
47f6dab9
AM
451 memset (&htab->ovtab, 0,
452 sizeof (*htab) - offsetof (struct spu_link_hash_table, ovtab));
e9f53129 453
47f6dab9
AM
454 htab->elf.init_got_refcount.refcount = 0;
455 htab->elf.init_got_refcount.glist = NULL;
456 htab->elf.init_got_offset.offset = 0;
457 htab->elf.init_got_offset.glist = NULL;
e9f53129
AM
458 return &htab->elf.root;
459}
460
64615358
AM
461void
462spu_elf_setup (struct bfd_link_info *info, struct spu_elf_params *params)
463{
464 struct spu_link_hash_table *htab = spu_hash_table (info);
465 htab->params = params;
cd4a7468
AM
466 htab->line_size_log2 = bfd_log2 (htab->params->line_size);
467 htab->num_lines_log2 = bfd_log2 (htab->params->num_lines);
64615358
AM
468}
469
e9f53129
AM
470/* Find the symbol for the given R_SYMNDX in IBFD and set *HP and *SYMP
471 to (hash, NULL) for global symbols, and (NULL, sym) for locals. Set
472 *SYMSECP to the symbol's section. *LOCSYMSP caches local syms. */
473
474static bfd_boolean
475get_sym_h (struct elf_link_hash_entry **hp,
476 Elf_Internal_Sym **symp,
477 asection **symsecp,
478 Elf_Internal_Sym **locsymsp,
479 unsigned long r_symndx,
480 bfd *ibfd)
481{
482 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
483
484 if (r_symndx >= symtab_hdr->sh_info)
485 {
486 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
487 struct elf_link_hash_entry *h;
488
489 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
490 while (h->root.type == bfd_link_hash_indirect
491 || h->root.type == bfd_link_hash_warning)
492 h = (struct elf_link_hash_entry *) h->root.u.i.link;
493
494 if (hp != NULL)
495 *hp = h;
496
497 if (symp != NULL)
498 *symp = NULL;
499
500 if (symsecp != NULL)
501 {
502 asection *symsec = NULL;
503 if (h->root.type == bfd_link_hash_defined
504 || h->root.type == bfd_link_hash_defweak)
505 symsec = h->root.u.def.section;
506 *symsecp = symsec;
507 }
508 }
509 else
510 {
511 Elf_Internal_Sym *sym;
512 Elf_Internal_Sym *locsyms = *locsymsp;
513
514 if (locsyms == NULL)
515 {
516 locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
517 if (locsyms == NULL)
1f27ab8d
AM
518 locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
519 symtab_hdr->sh_info,
520 0, NULL, NULL, NULL);
e9f53129
AM
521 if (locsyms == NULL)
522 return FALSE;
523 *locsymsp = locsyms;
524 }
525 sym = locsyms + r_symndx;
526
527 if (hp != NULL)
528 *hp = NULL;
529
530 if (symp != NULL)
531 *symp = sym;
532
533 if (symsecp != NULL)
cb33740c 534 *symsecp = bfd_section_from_elf_index (ibfd, sym->st_shndx);
e9f53129 535 }
49fa1e15 536
e9f53129
AM
537 return TRUE;
538}
539
e9f53129
AM
540/* Create the note section if not already present. This is done early so
541 that the linker maps the sections to the right place in the output. */
542
543bfd_boolean
64615358 544spu_elf_create_sections (struct bfd_link_info *info)
e9f53129
AM
545{
546 bfd *ibfd;
547
58eb693e 548 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
e9f53129
AM
549 if (bfd_get_section_by_name (ibfd, SPU_PTNOTE_SPUNAME) != NULL)
550 break;
551
552 if (ibfd == NULL)
553 {
554 /* Make SPU_PTNOTE_SPUNAME section. */
555 asection *s;
556 size_t name_len;
557 size_t size;
558 bfd_byte *data;
559 flagword flags;
560
561 ibfd = info->input_bfds;
562 flags = SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
563 s = bfd_make_section_anyway_with_flags (ibfd, SPU_PTNOTE_SPUNAME, flags);
564 if (s == NULL
565 || !bfd_set_section_alignment (ibfd, s, 4))
566 return FALSE;
567
c65be8d7 568 name_len = strlen (bfd_get_filename (info->output_bfd)) + 1;
e9f53129
AM
569 size = 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4);
570 size += (name_len + 3) & -4;
571
572 if (!bfd_set_section_size (ibfd, s, size))
573 return FALSE;
574
575 data = bfd_zalloc (ibfd, size);
576 if (data == NULL)
577 return FALSE;
578
579 bfd_put_32 (ibfd, sizeof (SPU_PLUGIN_NAME), data + 0);
580 bfd_put_32 (ibfd, name_len, data + 4);
581 bfd_put_32 (ibfd, 1, data + 8);
582 memcpy (data + 12, SPU_PLUGIN_NAME, sizeof (SPU_PLUGIN_NAME));
583 memcpy (data + 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4),
c65be8d7 584 bfd_get_filename (info->output_bfd), name_len);
e9f53129
AM
585 s->contents = data;
586 }
587
588 return TRUE;
589}
590
e9f53129
AM
591/* qsort predicate to sort sections by vma. */
592
593static int
594sort_sections (const void *a, const void *b)
595{
596 const asection *const *s1 = a;
597 const asection *const *s2 = b;
598 bfd_signed_vma delta = (*s1)->vma - (*s2)->vma;
599
600 if (delta != 0)
601 return delta < 0 ? -1 : 1;
602
603 return (*s1)->index - (*s2)->index;
604}
605
ad2adbc8
AM
606/* Identify overlays in the output bfd, and number them.
607 Returns 0 on error, 1 if no overlays, 2 if overlays. */
e9f53129 608
ad2adbc8 609int
c65be8d7 610spu_elf_find_overlays (struct bfd_link_info *info)
e9f53129
AM
611{
612 struct spu_link_hash_table *htab = spu_hash_table (info);
613 asection **alloc_sec;
614 unsigned int i, n, ovl_index, num_buf;
615 asection *s;
616 bfd_vma ovl_end;
ad2adbc8
AM
617 static const char *const entry_names[2][2] = {
618 { "__ovly_load", "__icache_br_handler" },
619 { "__ovly_return", "__icache_call_handler" }
620 };
e9f53129 621
c65be8d7 622 if (info->output_bfd->section_count < 2)
ad2adbc8 623 return 1;
e9f53129 624
c65be8d7
AM
625 alloc_sec
626 = bfd_malloc (info->output_bfd->section_count * sizeof (*alloc_sec));
e9f53129 627 if (alloc_sec == NULL)
ad2adbc8 628 return 0;
e9f53129
AM
629
630 /* Pick out all the alloced sections. */
c65be8d7 631 for (n = 0, s = info->output_bfd->sections; s != NULL; s = s->next)
e9f53129
AM
632 if ((s->flags & SEC_ALLOC) != 0
633 && (s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != SEC_THREAD_LOCAL
634 && s->size != 0)
635 alloc_sec[n++] = s;
636
637 if (n == 0)
638 {
639 free (alloc_sec);
ad2adbc8 640 return 1;
e9f53129
AM
641 }
642
643 /* Sort them by vma. */
644 qsort (alloc_sec, n, sizeof (*alloc_sec), sort_sections);
645
e9f53129 646 ovl_end = alloc_sec[0]->vma + alloc_sec[0]->size;
cd4a7468 647 if (htab->params->ovly_flavour == ovly_soft_icache)
e9f53129 648 {
cd4a7468
AM
649 /* Look for an overlapping vma to find the first overlay section. */
650 bfd_vma vma_start = 0;
651 bfd_vma lma_start = 0;
652
653 for (i = 1; i < n; i++)
e9f53129 654 {
cd4a7468
AM
655 s = alloc_sec[i];
656 if (s->vma < ovl_end)
657 {
658 asection *s0 = alloc_sec[i - 1];
659 vma_start = s0->vma;
77ae44b0
AM
660 if (strncmp (s0->name, ".ovl.init", 9) != 0)
661 lma_start = s0->lma;
662 else
663 lma_start = s->lma;
cd4a7468
AM
664 ovl_end = (s0->vma
665 + ((bfd_vma) 1
666 << (htab->num_lines_log2 + htab->line_size_log2)));
667 --i;
668 break;
669 }
670 else
671 ovl_end = s->vma + s->size;
672 }
e9f53129 673
cd4a7468
AM
674 /* Now find any sections within the cache area. */
675 for (ovl_index = 0, num_buf = 0; i < n; i++)
676 {
677 s = alloc_sec[i];
678 if (s->vma >= ovl_end)
679 break;
680
681 /* A section in an overlay area called .ovl.init is not
682 an overlay, in the sense that it might be loaded in
683 by the overlay manager, but rather the initial
684 section contents for the overlay buffer. */
685 if (strncmp (s->name, ".ovl.init", 9) != 0)
e9f53129 686 {
cd4a7468
AM
687 num_buf = ((s->vma - vma_start) >> htab->line_size_log2) + 1;
688 if (((s->vma - vma_start) & (htab->params->line_size - 1))
689 || ((s->lma - lma_start) & (htab->params->line_size - 1)))
690 {
691 info->callbacks->einfo (_("%X%P: overlay section %A "
692 "does not start on a cache line.\n"),
693 s);
3209bffa 694 bfd_set_error (bfd_error_bad_value);
ad2adbc8 695 return 0;
cd4a7468
AM
696 }
697 else if (s->size > htab->params->line_size)
698 {
699 info->callbacks->einfo (_("%X%P: overlay section %A "
700 "is larger than a cache line.\n"),
701 s);
3209bffa 702 bfd_set_error (bfd_error_bad_value);
ad2adbc8 703 return 0;
cd4a7468
AM
704 }
705
706 alloc_sec[ovl_index++] = s;
707 spu_elf_section_data (s)->u.o.ovl_index
708 = ((s->lma - lma_start) >> htab->line_size_log2) + 1;
709 spu_elf_section_data (s)->u.o.ovl_buf = num_buf;
e9f53129 710 }
cd4a7468
AM
711 }
712
713 /* Ensure there are no more overlay sections. */
714 for ( ; i < n; i++)
715 {
716 s = alloc_sec[i];
717 if (s->vma < ovl_end)
e9f53129 718 {
cd4a7468
AM
719 info->callbacks->einfo (_("%X%P: overlay section %A "
720 "is not in cache area.\n"),
721 alloc_sec[i-1]);
3209bffa 722 bfd_set_error (bfd_error_bad_value);
ad2adbc8 723 return 0;
e9f53129 724 }
cd4a7468
AM
725 else
726 ovl_end = s->vma + s->size;
727 }
728 }
729 else
730 {
731 /* Look for overlapping vmas. Any with overlap must be overlays.
732 Count them. Also count the number of overlay regions. */
733 for (ovl_index = 0, num_buf = 0, i = 1; i < n; i++)
734 {
735 s = alloc_sec[i];
736 if (s->vma < ovl_end)
737 {
738 asection *s0 = alloc_sec[i - 1];
739
740 if (spu_elf_section_data (s0)->u.o.ovl_index == 0)
741 {
742 ++num_buf;
743 if (strncmp (s0->name, ".ovl.init", 9) != 0)
744 {
745 alloc_sec[ovl_index] = s0;
746 spu_elf_section_data (s0)->u.o.ovl_index = ++ovl_index;
747 spu_elf_section_data (s0)->u.o.ovl_buf = num_buf;
748 }
749 else
750 ovl_end = s->vma + s->size;
751 }
752 if (strncmp (s->name, ".ovl.init", 9) != 0)
753 {
754 alloc_sec[ovl_index] = s;
755 spu_elf_section_data (s)->u.o.ovl_index = ++ovl_index;
756 spu_elf_section_data (s)->u.o.ovl_buf = num_buf;
757 if (s0->vma != s->vma)
758 {
759 info->callbacks->einfo (_("%X%P: overlay sections %A "
760 "and %A do not start at the "
761 "same address.\n"),
762 s0, s);
3209bffa 763 bfd_set_error (bfd_error_bad_value);
ad2adbc8 764 return 0;
cd4a7468
AM
765 }
766 if (ovl_end < s->vma + s->size)
767 ovl_end = s->vma + s->size;
768 }
769 }
770 else
47f6dab9 771 ovl_end = s->vma + s->size;
e9f53129 772 }
e9f53129
AM
773 }
774
775 htab->num_overlays = ovl_index;
776 htab->num_buf = num_buf;
47f6dab9 777 htab->ovl_sec = alloc_sec;
ad2adbc8
AM
778
779 if (ovl_index == 0)
780 return 1;
781
782 for (i = 0; i < 2; i++)
783 {
784 const char *name;
785 struct elf_link_hash_entry *h;
786
787 name = entry_names[i][htab->params->ovly_flavour];
788 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
789 if (h == NULL)
790 return 0;
791
792 if (h->root.type == bfd_link_hash_new)
793 {
794 h->root.type = bfd_link_hash_undefined;
795 h->ref_regular = 1;
796 h->ref_regular_nonweak = 1;
797 h->non_elf = 0;
798 }
799 htab->ovly_entry[i] = h;
800 }
801
802 return 2;
e9f53129
AM
803}
804
cd4a7468
AM
805/* Non-zero to use bra in overlay stubs rather than br. */
806#define BRA_STUBS 0
807
808#define BRA 0x30000000
809#define BRASL 0x31000000
47f6dab9 810#define BR 0x32000000
cd4a7468 811#define BRSL 0x33000000
e9f53129 812#define NOP 0x40200000
47f6dab9
AM
813#define LNOP 0x00200000
814#define ILA 0x42000000
e9f53129 815
49fa1e15 816/* Return true for all relative and absolute branch instructions.
e9f53129
AM
817 bra 00110000 0..
818 brasl 00110001 0..
819 br 00110010 0..
820 brsl 00110011 0..
821 brz 00100000 0..
822 brnz 00100001 0..
823 brhz 00100010 0..
49fa1e15
AM
824 brhnz 00100011 0.. */
825
826static bfd_boolean
827is_branch (const unsigned char *insn)
828{
829 return (insn[0] & 0xec) == 0x20 && (insn[1] & 0x80) == 0;
830}
831
fad9eaf0
AM
832/* Return true for all indirect branch instructions.
833 bi 00110101 000
834 bisl 00110101 001
835 iret 00110101 010
836 bisled 00110101 011
837 biz 00100101 000
838 binz 00100101 001
839 bihz 00100101 010
840 bihnz 00100101 011 */
841
842static bfd_boolean
843is_indirect_branch (const unsigned char *insn)
844{
845 return (insn[0] & 0xef) == 0x25 && (insn[1] & 0x80) == 0;
846}
847
49fa1e15 848/* Return true for branch hint instructions.
e9f53129
AM
849 hbra 0001000..
850 hbrr 0001001.. */
851
852static bfd_boolean
49fa1e15 853is_hint (const unsigned char *insn)
e9f53129 854{
49fa1e15 855 return (insn[0] & 0xfc) == 0x10;
e9f53129
AM
856}
857
fdba2fcd 858/* True if INPUT_SECTION might need overlay stubs. */
aa7a0635
AM
859
860static bfd_boolean
64615358 861maybe_needs_stubs (asection *input_section)
fdba2fcd
AM
862{
863 /* No stubs for debug sections and suchlike. */
864 if ((input_section->flags & SEC_ALLOC) == 0)
865 return FALSE;
866
867 /* No stubs for link-once sections that will be discarded. */
64615358 868 if (input_section->output_section == bfd_abs_section_ptr)
fdba2fcd
AM
869 return FALSE;
870
871 /* Don't create stubs for .eh_frame references. */
872 if (strcmp (input_section->name, ".eh_frame") == 0)
873 return FALSE;
874
875 return TRUE;
876}
877
878enum _stub_type
879{
880 no_stub,
cd4a7468
AM
881 call_ovl_stub,
882 br000_ovl_stub,
883 br001_ovl_stub,
884 br010_ovl_stub,
885 br011_ovl_stub,
886 br100_ovl_stub,
887 br101_ovl_stub,
888 br110_ovl_stub,
889 br111_ovl_stub,
fdba2fcd
AM
890 nonovl_stub,
891 stub_error
892};
893
894/* Return non-zero if this reloc symbol should go via an overlay stub.
895 Return 2 if the stub must be in non-overlay area. */
896
897static enum _stub_type
898needs_ovl_stub (struct elf_link_hash_entry *h,
899 Elf_Internal_Sym *sym,
aa7a0635
AM
900 asection *sym_sec,
901 asection *input_section,
fdba2fcd
AM
902 Elf_Internal_Rela *irela,
903 bfd_byte *contents,
904 struct bfd_link_info *info)
aa7a0635 905{
fdba2fcd
AM
906 struct spu_link_hash_table *htab = spu_hash_table (info);
907 enum elf_spu_reloc_type r_type;
908 unsigned int sym_type;
cd4a7468 909 bfd_boolean branch, hint, call;
fdba2fcd 910 enum _stub_type ret = no_stub;
cd4a7468 911 bfd_byte insn[4];
aa7a0635
AM
912
913 if (sym_sec == NULL
64615358 914 || sym_sec->output_section == bfd_abs_section_ptr
2c67c5f3 915 || spu_elf_section_data (sym_sec->output_section) == NULL)
fdba2fcd 916 return ret;
aa7a0635 917
fdba2fcd
AM
918 if (h != NULL)
919 {
920 /* Ensure no stubs for user supplied overlay manager syms. */
ad2adbc8 921 if (h == htab->ovly_entry[0] || h == htab->ovly_entry[1])
fdba2fcd
AM
922 return ret;
923
924 /* setjmp always goes via an overlay stub, because then the return
925 and hence the longjmp goes via __ovly_return. That magically
926 makes setjmp/longjmp between overlays work. */
927 if (strncmp (h->root.root.string, "setjmp", 6) == 0
928 && (h->root.root.string[6] == '\0' || h->root.root.string[6] == '@'))
cd4a7468 929 ret = call_ovl_stub;
fdba2fcd 930 }
aa7a0635 931
fdba2fcd
AM
932 if (h != NULL)
933 sym_type = h->type;
934 else
935 sym_type = ELF_ST_TYPE (sym->st_info);
936
937 r_type = ELF32_R_TYPE (irela->r_info);
938 branch = FALSE;
cd4a7468
AM
939 hint = FALSE;
940 call = FALSE;
fdba2fcd
AM
941 if (r_type == R_SPU_REL16 || r_type == R_SPU_ADDR16)
942 {
fdba2fcd
AM
943 if (contents == NULL)
944 {
945 contents = insn;
946 if (!bfd_get_section_contents (input_section->owner,
947 input_section,
948 contents,
949 irela->r_offset, 4))
950 return stub_error;
951 }
952 else
953 contents += irela->r_offset;
954
cd4a7468
AM
955 branch = is_branch (contents);
956 hint = is_hint (contents);
957 if (branch || hint)
fdba2fcd 958 {
cd4a7468
AM
959 call = (contents[0] & 0xfd) == 0x31;
960 if (call
fdba2fcd 961 && sym_type != STT_FUNC
9dcc4794 962 && contents != insn)
fdba2fcd
AM
963 {
964 /* It's common for people to write assembly and forget
965 to give function symbols the right type. Handle
966 calls to such symbols, but warn so that (hopefully)
967 people will fix their code. We need the symbol
968 type to be correct to distinguish function pointer
969 initialisation from other pointer initialisations. */
970 const char *sym_name;
971
972 if (h != NULL)
973 sym_name = h->root.root.string;
974 else
975 {
976 Elf_Internal_Shdr *symtab_hdr;
977 symtab_hdr = &elf_tdata (input_section->owner)->symtab_hdr;
978 sym_name = bfd_elf_sym_name (input_section->owner,
979 symtab_hdr,
980 sym,
981 sym_sec);
982 }
983 (*_bfd_error_handler) (_("warning: call to non-function"
984 " symbol %s defined in %B"),
985 sym_sec->owner, sym_name);
986
987 }
988 }
989 }
990
cd4a7468
AM
991 if ((!branch && htab->params->ovly_flavour == ovly_soft_icache)
992 || (sym_type != STT_FUNC
993 && !(branch || hint)
994 && (sym_sec->flags & SEC_CODE) == 0))
995 return no_stub;
996
997 /* Usually, symbols in non-overlay sections don't need stubs. */
998 if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index == 0
999 && !htab->params->non_overlay_stubs)
fdba2fcd 1000 return ret;
aa7a0635
AM
1001
1002 /* A reference from some other section to a symbol in an overlay
1003 section needs a stub. */
47f6dab9
AM
1004 if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index
1005 != spu_elf_section_data (input_section->output_section)->u.o.ovl_index)
cd4a7468
AM
1006 {
1007 if (call || sym_type == STT_FUNC)
1008 ret = call_ovl_stub;
1009 else
1010 {
1011 ret = br000_ovl_stub;
1012
1013 if (branch)
1014 {
1015 unsigned int lrlive = (contents[1] & 0x70) >> 4;
1016 ret += lrlive;
1017 }
1018 }
1019 }
aa7a0635
AM
1020
1021 /* If this insn isn't a branch then we are possibly taking the
cd4a7468
AM
1022 address of a function and passing it out somehow. Soft-icache code
1023 always generates inline code to do indirect branches. */
1024 if (!(branch || hint)
1025 && sym_type == STT_FUNC
1026 && htab->params->ovly_flavour != ovly_soft_icache)
1027 ret = nonovl_stub;
1028
1029 return ret;
aa7a0635
AM
1030}
1031
47f6dab9
AM
1032static bfd_boolean
1033count_stub (struct spu_link_hash_table *htab,
1034 bfd *ibfd,
1035 asection *isec,
fdba2fcd 1036 enum _stub_type stub_type,
47f6dab9
AM
1037 struct elf_link_hash_entry *h,
1038 const Elf_Internal_Rela *irela)
1039{
1040 unsigned int ovl = 0;
1041 struct got_entry *g, **head;
4a628337 1042 bfd_vma addend;
47f6dab9
AM
1043
1044 /* If this instruction is a branch or call, we need a stub
1045 for it. One stub per function per overlay.
1046 If it isn't a branch, then we are taking the address of
1047 this function so need a stub in the non-overlay area
1048 for it. One stub per function. */
fdba2fcd 1049 if (stub_type != nonovl_stub)
47f6dab9
AM
1050 ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
1051
1052 if (h != NULL)
1053 head = &h->got.glist;
1054 else
1055 {
1056 if (elf_local_got_ents (ibfd) == NULL)
1057 {
1058 bfd_size_type amt = (elf_tdata (ibfd)->symtab_hdr.sh_info
1059 * sizeof (*elf_local_got_ents (ibfd)));
1060 elf_local_got_ents (ibfd) = bfd_zmalloc (amt);
1061 if (elf_local_got_ents (ibfd) == NULL)
1062 return FALSE;
1063 }
1064 head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
1065 }
1066
cd4a7468
AM
1067 if (htab->params->ovly_flavour == ovly_soft_icache)
1068 {
1069 htab->stub_count[ovl] += 1;
1070 return TRUE;
1071 }
1072
4a628337
AM
1073 addend = 0;
1074 if (irela != NULL)
1075 addend = irela->r_addend;
47f6dab9
AM
1076
1077 if (ovl == 0)
1078 {
1079 struct got_entry *gnext;
1080
4a628337
AM
1081 for (g = *head; g != NULL; g = g->next)
1082 if (g->addend == addend && g->ovl == 0)
1083 break;
1084
1085 if (g == NULL)
47f6dab9 1086 {
4a628337
AM
1087 /* Need a new non-overlay area stub. Zap other stubs. */
1088 for (g = *head; g != NULL; g = gnext)
1089 {
1090 gnext = g->next;
1091 if (g->addend == addend)
1092 {
1093 htab->stub_count[g->ovl] -= 1;
1094 free (g);
1095 }
1096 }
47f6dab9
AM
1097 }
1098 }
1099 else
1100 {
4a628337
AM
1101 for (g = *head; g != NULL; g = g->next)
1102 if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
47f6dab9
AM
1103 break;
1104 }
1105
1106 if (g == NULL)
1107 {
1108 g = bfd_malloc (sizeof *g);
1109 if (g == NULL)
1110 return FALSE;
1111 g->ovl = ovl;
4a628337 1112 g->addend = addend;
47f6dab9
AM
1113 g->stub_addr = (bfd_vma) -1;
1114 g->next = *head;
1115 *head = g;
1116
1117 htab->stub_count[ovl] += 1;
1118 }
1119
1120 return TRUE;
1121}
1122
64615358 1123/* Support two sizes of overlay stubs, a slower more compact stub of two
a7e11ee1
AM
1124 intructions, and a faster stub of four instructions.
1125 Soft-icache stubs are four or eight words. */
1126
1127static unsigned int
1128ovl_stub_size (struct spu_elf_params *params)
1129{
1130 return 16 << params->ovly_flavour >> params->compact_stub;
1131}
64615358
AM
1132
1133static unsigned int
a7e11ee1 1134ovl_stub_size_log2 (struct spu_elf_params *params)
64615358 1135{
a7e11ee1 1136 return 4 + params->ovly_flavour - params->compact_stub;
64615358
AM
1137}
1138
47f6dab9
AM
1139/* Two instruction overlay stubs look like:
1140
1141 brsl $75,__ovly_load
1142 .word target_ovl_and_address
1143
1144 ovl_and_address is a word with the overlay number in the top 14 bits
1145 and local store address in the bottom 18 bits.
1146
1147 Four instruction overlay stubs look like:
1148
1149 ila $78,ovl_number
1150 lnop
1151 ila $79,target_address
cd4a7468
AM
1152 br __ovly_load
1153
1154 Software icache stubs are:
1155
1156 .word target_index
1157 .word target_ia;
1158 .word lrlive_branchlocalstoreaddr;
1159 brasl $75,__icache_br_handler
1160 .quad xor_pattern
1161*/
47f6dab9
AM
1162
1163static bfd_boolean
cd4a7468 1164build_stub (struct bfd_link_info *info,
47f6dab9
AM
1165 bfd *ibfd,
1166 asection *isec,
fdba2fcd 1167 enum _stub_type stub_type,
47f6dab9
AM
1168 struct elf_link_hash_entry *h,
1169 const Elf_Internal_Rela *irela,
1170 bfd_vma dest,
1171 asection *dest_sec)
1172{
cd4a7468
AM
1173 struct spu_link_hash_table *htab = spu_hash_table (info);
1174 unsigned int ovl, dest_ovl, set_id;
47f6dab9
AM
1175 struct got_entry *g, **head;
1176 asection *sec;
cd4a7468
AM
1177 bfd_vma addend, from, to, br_dest, patt;
1178 unsigned int lrlive;
47f6dab9
AM
1179
1180 ovl = 0;
fdba2fcd 1181 if (stub_type != nonovl_stub)
47f6dab9
AM
1182 ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
1183
1184 if (h != NULL)
1185 head = &h->got.glist;
1186 else
1187 head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
1188
4a628337
AM
1189 addend = 0;
1190 if (irela != NULL)
1191 addend = irela->r_addend;
47f6dab9 1192
cd4a7468
AM
1193 if (htab->params->ovly_flavour == ovly_soft_icache)
1194 {
1195 g = bfd_malloc (sizeof *g);
1196 if (g == NULL)
1197 return FALSE;
1198 g->ovl = ovl;
1199 g->br_addr = 0;
1200 if (irela != NULL)
1201 g->br_addr = (irela->r_offset
1202 + isec->output_offset
1203 + isec->output_section->vma);
1204 g->next = *head;
1205 *head = g;
1206 }
1207 else
1208 {
1209 for (g = *head; g != NULL; g = g->next)
1210 if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
1211 break;
1212 if (g == NULL)
1213 abort ();
47f6dab9 1214
cd4a7468
AM
1215 if (g->ovl == 0 && ovl != 0)
1216 return TRUE;
4a628337 1217
cd4a7468
AM
1218 if (g->stub_addr != (bfd_vma) -1)
1219 return TRUE;
1220 }
47f6dab9
AM
1221
1222 sec = htab->stub_sec[ovl];
1223 dest += dest_sec->output_offset + dest_sec->output_section->vma;
1224 from = sec->size + sec->output_offset + sec->output_section->vma;
1225 g->stub_addr = from;
a7e11ee1
AM
1226 to = (htab->ovly_entry[0]->root.u.def.value
1227 + htab->ovly_entry[0]->root.u.def.section->output_offset
1228 + htab->ovly_entry[0]->root.u.def.section->output_section->vma);
64615358
AM
1229
1230 if (((dest | to | from) & 3) != 0)
47f6dab9
AM
1231 {
1232 htab->stub_err = 1;
1233 return FALSE;
1234 }
64615358 1235 dest_ovl = spu_elf_section_data (dest_sec->output_section)->u.o.ovl_index;
47f6dab9 1236
a7e11ee1
AM
1237 if (htab->params->ovly_flavour == ovly_normal
1238 && !htab->params->compact_stub)
47f6dab9 1239 {
64615358 1240 bfd_put_32 (sec->owner, ILA + ((dest_ovl << 7) & 0x01ffff80) + 78,
47f6dab9
AM
1241 sec->contents + sec->size);
1242 bfd_put_32 (sec->owner, LNOP,
1243 sec->contents + sec->size + 4);
1244 bfd_put_32 (sec->owner, ILA + ((dest << 7) & 0x01ffff80) + 79,
1245 sec->contents + sec->size + 8);
cd4a7468
AM
1246 if (!BRA_STUBS)
1247 bfd_put_32 (sec->owner, BR + (((to - (from + 12)) << 5) & 0x007fff80),
1248 sec->contents + sec->size + 12);
1249 else
1250 bfd_put_32 (sec->owner, BRA + ((to << 5) & 0x007fff80),
1251 sec->contents + sec->size + 12);
a7e11ee1
AM
1252 }
1253 else if (htab->params->ovly_flavour == ovly_normal
1254 && htab->params->compact_stub)
1255 {
cd4a7468
AM
1256 if (!BRA_STUBS)
1257 bfd_put_32 (sec->owner, BRSL + (((to - from) << 5) & 0x007fff80) + 75,
1258 sec->contents + sec->size);
1259 else
1260 bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
1261 sec->contents + sec->size);
64615358 1262 bfd_put_32 (sec->owner, (dest & 0x3ffff) | (dest_ovl << 18),
47f6dab9 1263 sec->contents + sec->size + 4);
a7e11ee1
AM
1264 }
1265 else if (htab->params->ovly_flavour == ovly_soft_icache)
1266 {
cd4a7468
AM
1267 lrlive = 0;
1268 if (stub_type == nonovl_stub)
1269 ;
1270 else if (stub_type == call_ovl_stub)
1271 /* A brsl makes lr live and *(*sp+16) is live.
1272 Tail calls have the same liveness. */
1273 lrlive = 5;
1274 else if (!htab->params->lrlive_analysis)
1275 /* Assume stack frame and lr save. */
1276 lrlive = 1;
1277 else if (irela != NULL)
1278 {
1279 /* Analyse branch instructions. */
1280 struct function_info *caller;
1281 bfd_vma off;
1282
1283 caller = find_function (isec, irela->r_offset, info);
1284 if (caller->start == NULL)
1285 off = irela->r_offset;
1286 else
1287 {
1288 struct function_info *found = NULL;
1289
1290 /* Find the earliest piece of this function that
1291 has frame adjusting instructions. We might
1292 see dynamic frame adjustment (eg. for alloca)
1293 in some later piece, but functions using
1294 alloca always set up a frame earlier. Frame
1295 setup instructions are always in one piece. */
1296 if (caller->lr_store != (bfd_vma) -1
1297 || caller->sp_adjust != (bfd_vma) -1)
1298 found = caller;
1299 while (caller->start != NULL)
1300 {
1301 caller = caller->start;
1302 if (caller->lr_store != (bfd_vma) -1
1303 || caller->sp_adjust != (bfd_vma) -1)
1304 found = caller;
1305 }
1306 if (found != NULL)
1307 caller = found;
1308 off = (bfd_vma) -1;
1309 }
1310
1311 if (off > caller->sp_adjust)
1312 {
1313 if (off > caller->lr_store)
1314 /* Only *(*sp+16) is live. */
1315 lrlive = 1;
1316 else
1317 /* If no lr save, then we must be in a
1318 leaf function with a frame.
1319 lr is still live. */
1320 lrlive = 4;
1321 }
1322 else if (off > caller->lr_store)
1323 {
1324 /* Between lr save and stack adjust. */
1325 lrlive = 3;
1326 /* This should never happen since prologues won't
1327 be split here. */
1328 BFD_ASSERT (0);
1329 }
1330 else
1331 /* On entry to function. */
1332 lrlive = 5;
1333
1334 if (stub_type != br000_ovl_stub
1335 && lrlive != stub_type - br000_ovl_stub)
1336 info->callbacks->einfo (_("%A:0x%v lrlive .brinfo (%u) differs "
1337 "from analysis (%u)\n"),
1338 isec, irela->r_offset, lrlive,
1339 stub_type - br000_ovl_stub);
1340 }
1341
1342 /* If given lrlive info via .brinfo, use it. */
1343 if (stub_type > br000_ovl_stub)
1344 lrlive = stub_type - br000_ovl_stub;
1345
a7e11ee1
AM
1346 if (ovl == 0)
1347 to = (htab->ovly_entry[1]->root.u.def.value
1348 + htab->ovly_entry[1]->root.u.def.section->output_offset
1349 + htab->ovly_entry[1]->root.u.def.section->output_section->vma);
1350
1351 if (!htab->params->compact_stub)
1352 {
1353 /* The branch that uses this stub goes to stub_addr + 12. We'll
1354 set up an xor pattern that can be used by the icache manager
1355 to modify this branch to go directly to its destination. */
1356 g->stub_addr += 12;
1357 br_dest = g->stub_addr;
1358 if (irela == NULL)
1359 {
1360 /* Except in the case of _SPUEAR_ stubs, the branch in
1361 question is the one in the stub itself. */
1362 BFD_ASSERT (stub_type == nonovl_stub);
1363 g->br_addr = g->stub_addr;
1364 br_dest = to;
1365 }
1366
1367 bfd_put_32 (sec->owner, dest_ovl - 1,
1368 sec->contents + sec->size + 0);
1369 set_id = ((dest_ovl - 1) >> htab->num_lines_log2) + 1;
1370 bfd_put_32 (sec->owner, (set_id << 18) | (dest & 0x3ffff),
1371 sec->contents + sec->size + 4);
1372 bfd_put_32 (sec->owner, (lrlive << 29) | (g->br_addr & 0x3ffff),
1373 sec->contents + sec->size + 8);
1374 bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
1375 sec->contents + sec->size + 12);
1376 patt = dest ^ br_dest;
1377 if (irela != NULL && ELF32_R_TYPE (irela->r_info) == R_SPU_REL16)
1378 patt = (dest - g->br_addr) ^ (br_dest - g->br_addr);
1379 bfd_put_32 (sec->owner, (patt << 5) & 0x007fff80,
1380 sec->contents + sec->size + 16 + (g->br_addr & 0xf));
1381 }
1382 else
cd4a7468 1383 {
a7e11ee1
AM
1384 g->stub_addr += 4;
1385 br_dest = g->stub_addr;
1386 if (irela == NULL)
1387 {
1388 BFD_ASSERT (stub_type == nonovl_stub);
1389 g->br_addr = g->stub_addr;
1390 br_dest = to;
1391 }
1392
1393 set_id = ((dest_ovl - 1) >> htab->num_lines_log2) + 1;
1394 bfd_put_32 (sec->owner, (set_id << 18) | (dest & 0x3ffff),
1395 sec->contents + sec->size);
1396 bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
1397 sec->contents + sec->size + 4);
1398 bfd_put_32 (sec->owner, (lrlive << 29) | (g->br_addr & 0x3ffff),
1399 sec->contents + sec->size + 8);
1400 patt = dest ^ br_dest;
1401 if (irela != NULL && ELF32_R_TYPE (irela->r_info) == R_SPU_REL16)
1402 patt = (dest - g->br_addr) ^ (br_dest - g->br_addr);
1403 bfd_put_32 (sec->owner, (patt << 5) & 0x007fff80,
1404 sec->contents + sec->size + 12);
cd4a7468
AM
1405 }
1406
cd4a7468
AM
1407 if (ovl == 0)
1408 /* Extra space for linked list entries. */
1409 sec->size += 16;
47f6dab9 1410 }
a7e11ee1
AM
1411 else
1412 abort ();
1413
1414 sec->size += ovl_stub_size (htab->params);
47f6dab9 1415
64615358 1416 if (htab->params->emit_stub_syms)
47f6dab9
AM
1417 {
1418 size_t len;
1419 char *name;
1420 int add;
1421
1422 len = 8 + sizeof (".ovl_call.") - 1;
1423 if (h != NULL)
1424 len += strlen (h->root.root.string);
1425 else
1426 len += 8 + 1 + 8;
1427 add = 0;
1428 if (irela != NULL)
1429 add = (int) irela->r_addend & 0xffffffff;
1430 if (add != 0)
1431 len += 1 + 8;
1432 name = bfd_malloc (len);
1433 if (name == NULL)
1434 return FALSE;
1435
1436 sprintf (name, "%08x.ovl_call.", g->ovl);
1437 if (h != NULL)
1438 strcpy (name + 8 + sizeof (".ovl_call.") - 1, h->root.root.string);
1439 else
1440 sprintf (name + 8 + sizeof (".ovl_call.") - 1, "%x:%x",
1441 dest_sec->id & 0xffffffff,
1442 (int) ELF32_R_SYM (irela->r_info) & 0xffffffff);
1443 if (add != 0)
1444 sprintf (name + len - 9, "+%x", add);
1445
1446 h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
1447 free (name);
1448 if (h == NULL)
1449 return FALSE;
1450 if (h->root.type == bfd_link_hash_new)
1451 {
1452 h->root.type = bfd_link_hash_defined;
1453 h->root.u.def.section = sec;
a7e11ee1 1454 h->size = ovl_stub_size (htab->params);
64615358 1455 h->root.u.def.value = sec->size - h->size;
47f6dab9
AM
1456 h->type = STT_FUNC;
1457 h->ref_regular = 1;
1458 h->def_regular = 1;
1459 h->ref_regular_nonweak = 1;
1460 h->forced_local = 1;
1461 h->non_elf = 0;
1462 }
1463 }
1464
1465 return TRUE;
1466}
1467
f4b39977
AM
1468/* Called via elf_link_hash_traverse to allocate stubs for any _SPUEAR_
1469 symbols. */
1470
1471static bfd_boolean
1472allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
1473{
1474 /* Symbols starting with _SPUEAR_ need a stub because they may be
1475 invoked by the PPU. */
380814a6
AM
1476 struct bfd_link_info *info = inf;
1477 struct spu_link_hash_table *htab = spu_hash_table (info);
1478 asection *sym_sec;
1479
f4b39977
AM
1480 if ((h->root.type == bfd_link_hash_defined
1481 || h->root.type == bfd_link_hash_defweak)
1482 && h->def_regular
380814a6
AM
1483 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
1484 && (sym_sec = h->root.u.def.section) != NULL
64615358 1485 && sym_sec->output_section != bfd_abs_section_ptr
380814a6
AM
1486 && spu_elf_section_data (sym_sec->output_section) != NULL
1487 && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
64615358 1488 || htab->params->non_overlay_stubs))
f4b39977 1489 {
f3c29e8a 1490 return count_stub (htab, NULL, NULL, nonovl_stub, h, NULL);
f4b39977
AM
1491 }
1492
1493 return TRUE;
1494}
1495
e9f53129 1496static bfd_boolean
47f6dab9 1497build_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
e9f53129 1498{
47f6dab9
AM
1499 /* Symbols starting with _SPUEAR_ need a stub because they may be
1500 invoked by the PPU. */
380814a6
AM
1501 struct bfd_link_info *info = inf;
1502 struct spu_link_hash_table *htab = spu_hash_table (info);
1503 asection *sym_sec;
1504
47f6dab9
AM
1505 if ((h->root.type == bfd_link_hash_defined
1506 || h->root.type == bfd_link_hash_defweak)
1507 && h->def_regular
380814a6
AM
1508 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
1509 && (sym_sec = h->root.u.def.section) != NULL
64615358 1510 && sym_sec->output_section != bfd_abs_section_ptr
380814a6
AM
1511 && spu_elf_section_data (sym_sec->output_section) != NULL
1512 && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
64615358 1513 || htab->params->non_overlay_stubs))
47f6dab9 1514 {
cd4a7468 1515 return build_stub (info, NULL, NULL, nonovl_stub, h, NULL,
f3c29e8a 1516 h->root.u.def.value, sym_sec);
47f6dab9
AM
1517 }
1518
e9f53129
AM
1519 return TRUE;
1520}
1521
47f6dab9 1522/* Size or build stubs. */
e9f53129 1523
47f6dab9 1524static bfd_boolean
c65be8d7 1525process_stubs (struct bfd_link_info *info, bfd_boolean build)
e9f53129
AM
1526{
1527 struct spu_link_hash_table *htab = spu_hash_table (info);
1528 bfd *ibfd;
e9f53129 1529
e9f53129
AM
1530 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
1531 {
1532 extern const bfd_target bfd_elf32_spu_vec;
1533 Elf_Internal_Shdr *symtab_hdr;
47f6dab9 1534 asection *isec;
e9f53129
AM
1535 Elf_Internal_Sym *local_syms = NULL;
1536
1537 if (ibfd->xvec != &bfd_elf32_spu_vec)
1538 continue;
1539
1540 /* We'll need the symbol table in a second. */
1541 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1542 if (symtab_hdr->sh_info == 0)
1543 continue;
1544
1545 /* Walk over each section attached to the input bfd. */
47f6dab9 1546 for (isec = ibfd->sections; isec != NULL; isec = isec->next)
e9f53129
AM
1547 {
1548 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1549
1550 /* If there aren't any relocs, then there's nothing more to do. */
47f6dab9 1551 if ((isec->flags & SEC_RELOC) == 0
47f6dab9 1552 || isec->reloc_count == 0)
e9f53129
AM
1553 continue;
1554
64615358 1555 if (!maybe_needs_stubs (isec))
e9f53129
AM
1556 continue;
1557
1558 /* Get the relocs. */
47f6dab9
AM
1559 internal_relocs = _bfd_elf_link_read_relocs (ibfd, isec, NULL, NULL,
1560 info->keep_memory);
e9f53129
AM
1561 if (internal_relocs == NULL)
1562 goto error_ret_free_local;
1563
1564 /* Now examine each relocation. */
1565 irela = internal_relocs;
47f6dab9 1566 irelaend = irela + isec->reloc_count;
e9f53129
AM
1567 for (; irela < irelaend; irela++)
1568 {
1569 enum elf_spu_reloc_type r_type;
1570 unsigned int r_indx;
1571 asection *sym_sec;
1572 Elf_Internal_Sym *sym;
1573 struct elf_link_hash_entry *h;
fdba2fcd 1574 enum _stub_type stub_type;
e9f53129
AM
1575
1576 r_type = ELF32_R_TYPE (irela->r_info);
1577 r_indx = ELF32_R_SYM (irela->r_info);
1578
1579 if (r_type >= R_SPU_max)
1580 {
1581 bfd_set_error (bfd_error_bad_value);
47f6dab9
AM
1582 error_ret_free_internal:
1583 if (elf_section_data (isec)->relocs != internal_relocs)
1584 free (internal_relocs);
1585 error_ret_free_local:
1586 if (local_syms != NULL
1587 && (symtab_hdr->contents
1588 != (unsigned char *) local_syms))
1589 free (local_syms);
1590 return FALSE;
e9f53129
AM
1591 }
1592
1593 /* Determine the reloc target section. */
1f27ab8d 1594 if (!get_sym_h (&h, &sym, &sym_sec, &local_syms, r_indx, ibfd))
e9f53129
AM
1595 goto error_ret_free_internal;
1596
fdba2fcd
AM
1597 stub_type = needs_ovl_stub (h, sym, sym_sec, isec, irela,
1598 NULL, info);
1599 if (stub_type == no_stub)
e9f53129 1600 continue;
fdba2fcd
AM
1601 else if (stub_type == stub_error)
1602 goto error_ret_free_internal;
e9f53129 1603
47f6dab9 1604 if (htab->stub_count == NULL)
e9f53129 1605 {
47f6dab9
AM
1606 bfd_size_type amt;
1607 amt = (htab->num_overlays + 1) * sizeof (*htab->stub_count);
1608 htab->stub_count = bfd_zmalloc (amt);
1609 if (htab->stub_count == NULL)
1610 goto error_ret_free_internal;
e9f53129
AM
1611 }
1612
47f6dab9 1613 if (!build)
e9f53129 1614 {
fdba2fcd 1615 if (!count_stub (htab, ibfd, isec, stub_type, h, irela))
47f6dab9 1616 goto error_ret_free_internal;
e9f53129 1617 }
e9f53129 1618 else
47f6dab9
AM
1619 {
1620 bfd_vma dest;
1621
1622 if (h != NULL)
1623 dest = h->root.u.def.value;
1624 else
1625 dest = sym->st_value;
4a628337 1626 dest += irela->r_addend;
cd4a7468 1627 if (!build_stub (info, ibfd, isec, stub_type, h, irela,
47f6dab9
AM
1628 dest, sym_sec))
1629 goto error_ret_free_internal;
1630 }
e9f53129
AM
1631 }
1632
1633 /* We're done with the internal relocs, free them. */
47f6dab9 1634 if (elf_section_data (isec)->relocs != internal_relocs)
e9f53129
AM
1635 free (internal_relocs);
1636 }
1637
1638 if (local_syms != NULL
1639 && symtab_hdr->contents != (unsigned char *) local_syms)
1640 {
1641 if (!info->keep_memory)
1642 free (local_syms);
1643 else
1644 symtab_hdr->contents = (unsigned char *) local_syms;
1645 }
1646 }
1647
47f6dab9
AM
1648 return TRUE;
1649}
1650
a7e11ee1
AM
1651/* Allocate space for overlay call and return stubs.
1652 Return 0 on error, 1 if no stubs, 2 otherwise. */
47f6dab9
AM
1653
1654int
64615358 1655spu_elf_size_stubs (struct bfd_link_info *info)
47f6dab9 1656{
64615358 1657 struct spu_link_hash_table *htab;
47f6dab9
AM
1658 bfd *ibfd;
1659 bfd_size_type amt;
1660 flagword flags;
1661 unsigned int i;
1662 asection *stub;
cd4a7468 1663 const char *ovout;
47f6dab9 1664
c65be8d7 1665 if (!process_stubs (info, FALSE))
47f6dab9
AM
1666 return 0;
1667
64615358 1668 htab = spu_hash_table (info);
380814a6 1669 elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, info);
47f6dab9
AM
1670 if (htab->stub_err)
1671 return 0;
f4b39977 1672
47f6dab9
AM
1673 if (htab->stub_count == NULL)
1674 return 1;
e9f53129
AM
1675
1676 ibfd = info->input_bfds;
47f6dab9
AM
1677 amt = (htab->num_overlays + 1) * sizeof (*htab->stub_sec);
1678 htab->stub_sec = bfd_zmalloc (amt);
1679 if (htab->stub_sec == NULL)
1680 return 0;
e9f53129 1681
47f6dab9 1682 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
e9f53129 1683 | SEC_HAS_CONTENTS | SEC_IN_MEMORY);
47f6dab9
AM
1684 stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
1685 htab->stub_sec[0] = stub;
1686 if (stub == NULL
64615358 1687 || !bfd_set_section_alignment (ibfd, stub,
a7e11ee1 1688 ovl_stub_size_log2 (htab->params)))
47f6dab9 1689 return 0;
a7e11ee1 1690 stub->size = htab->stub_count[0] * ovl_stub_size (htab->params);
cd4a7468
AM
1691 if (htab->params->ovly_flavour == ovly_soft_icache)
1692 /* Extra space for linked list entries. */
1693 stub->size += htab->stub_count[0] * 16;
64615358 1694 (*htab->params->place_spu_section) (stub, NULL, ".text");
e9f53129 1695
47f6dab9 1696 for (i = 0; i < htab->num_overlays; ++i)
e9f53129 1697 {
47f6dab9
AM
1698 asection *osec = htab->ovl_sec[i];
1699 unsigned int ovl = spu_elf_section_data (osec)->u.o.ovl_index;
1700 stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
1701 htab->stub_sec[ovl] = stub;
1702 if (stub == NULL
64615358 1703 || !bfd_set_section_alignment (ibfd, stub,
a7e11ee1 1704 ovl_stub_size_log2 (htab->params)))
47f6dab9 1705 return 0;
a7e11ee1 1706 stub->size = htab->stub_count[ovl] * ovl_stub_size (htab->params);
64615358 1707 (*htab->params->place_spu_section) (stub, osec, NULL);
e9f53129 1708 }
e9f53129 1709
47f6dab9
AM
1710 flags = (SEC_ALLOC | SEC_LOAD
1711 | SEC_HAS_CONTENTS | SEC_IN_MEMORY);
1712 htab->ovtab = bfd_make_section_anyway_with_flags (ibfd, ".ovtab", flags);
1713 if (htab->ovtab == NULL
1714 || !bfd_set_section_alignment (ibfd, htab->ovtab, 4))
1715 return 0;
e9f53129 1716
cd4a7468
AM
1717 if (htab->params->ovly_flavour == ovly_soft_icache)
1718 {
1719 /* Space for icache manager tables.
1720 a) Tag array, one quadword per cache line.
a7e11ee1
AM
1721 b) Linked list elements, max_branch per line quadwords. */
1722 htab->ovtab->size = 16 * ((1 + htab->params->max_branch)
1723 << htab->num_lines_log2);
cd4a7468
AM
1724
1725 htab->init = bfd_make_section_anyway_with_flags (ibfd, ".ovini", flags);
1726 if (htab->init == NULL
1727 || !bfd_set_section_alignment (ibfd, htab->init, 4))
1728 return 0;
1729
1730 htab->init->size = 16;
1731 (*htab->params->place_spu_section) (htab->init, NULL, ".ovl.init");
1732 }
1733 else
1734 {
1735 /* htab->ovtab consists of two arrays.
1736 . struct {
1737 . u32 vma;
1738 . u32 size;
1739 . u32 file_off;
1740 . u32 buf;
1741 . } _ovly_table[];
1742 .
1743 . struct {
1744 . u32 mapped;
1745 . } _ovly_buf_table[];
1746 . */
1747
1748 htab->ovtab->size = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
1749 }
1750 ovout = ".data";
1751 if (htab->params->ovly_flavour == ovly_soft_icache)
1752 ovout = ".data.icache";
1753 (*htab->params->place_spu_section) (htab->ovtab, NULL, ovout);
47f6dab9
AM
1754
1755 htab->toe = bfd_make_section_anyway_with_flags (ibfd, ".toe", SEC_ALLOC);
1756 if (htab->toe == NULL
1757 || !bfd_set_section_alignment (ibfd, htab->toe, 4))
1758 return 0;
cd4a7468 1759 htab->toe->size = htab->params->ovly_flavour == ovly_soft_icache ? 256 : 16;
64615358 1760 (*htab->params->place_spu_section) (htab->toe, NULL, ".toe");
47f6dab9
AM
1761
1762 return 2;
e9f53129
AM
1763}
1764
1765/* Functions to handle embedded spu_ovl.o object. */
1766
1767static void *
1768ovl_mgr_open (struct bfd *nbfd ATTRIBUTE_UNUSED, void *stream)
1769{
1770 return stream;
1771}
1772
1773static file_ptr
1774ovl_mgr_pread (struct bfd *abfd ATTRIBUTE_UNUSED,
1775 void *stream,
1776 void *buf,
1777 file_ptr nbytes,
1778 file_ptr offset)
1779{
1780 struct _ovl_stream *os;
1781 size_t count;
1782 size_t max;
1783
1784 os = (struct _ovl_stream *) stream;
7a8757b3 1785 max = (const char *) os->end - (const char *) os->start;
e9f53129
AM
1786
1787 if ((ufile_ptr) offset >= max)
1788 return 0;
1789
1790 count = nbytes;
1791 if (count > max - offset)
1792 count = max - offset;
1793
7a8757b3 1794 memcpy (buf, (const char *) os->start + offset, count);
e9f53129
AM
1795 return count;
1796}
1797
1798bfd_boolean
1799spu_elf_open_builtin_lib (bfd **ovl_bfd, const struct _ovl_stream *stream)
1800{
1801 *ovl_bfd = bfd_openr_iovec ("builtin ovl_mgr",
1802 "elf32-spu",
1803 ovl_mgr_open,
1804 (void *) stream,
1805 ovl_mgr_pread,
f6cf9273 1806 NULL,
e9f53129
AM
1807 NULL);
1808 return *ovl_bfd != NULL;
1809}
1810
cd4a7468
AM
1811static unsigned int
1812overlay_index (asection *sec)
1813{
1814 if (sec == NULL
1815 || sec->output_section == bfd_abs_section_ptr)
1816 return 0;
1817 return spu_elf_section_data (sec->output_section)->u.o.ovl_index;
1818}
1819
e9f53129
AM
1820/* Define an STT_OBJECT symbol. */
1821
1822static struct elf_link_hash_entry *
1823define_ovtab_symbol (struct spu_link_hash_table *htab, const char *name)
1824{
1825 struct elf_link_hash_entry *h;
1826
1827 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
1828 if (h == NULL)
1829 return NULL;
1830
1831 if (h->root.type != bfd_link_hash_defined
1832 || !h->def_regular)
1833 {
1834 h->root.type = bfd_link_hash_defined;
1835 h->root.u.def.section = htab->ovtab;
1836 h->type = STT_OBJECT;
1837 h->ref_regular = 1;
1838 h->def_regular = 1;
1839 h->ref_regular_nonweak = 1;
1840 h->non_elf = 0;
1841 }
b0c41709 1842 else if (h->root.u.def.section->owner != NULL)
e9f53129
AM
1843 {
1844 (*_bfd_error_handler) (_("%B is not allowed to define %s"),
1845 h->root.u.def.section->owner,
1846 h->root.root.string);
1847 bfd_set_error (bfd_error_bad_value);
1848 return NULL;
1849 }
b0c41709
AM
1850 else
1851 {
1852 (*_bfd_error_handler) (_("you are not allowed to define %s in a script"),
1853 h->root.root.string);
1854 bfd_set_error (bfd_error_bad_value);
1855 return NULL;
1856 }
e9f53129
AM
1857
1858 return h;
1859}
1860
1861/* Fill in all stubs and the overlay tables. */
1862
cd4a7468 1863static bfd_boolean
64615358 1864spu_elf_build_stubs (struct bfd_link_info *info)
e9f53129
AM
1865{
1866 struct spu_link_hash_table *htab = spu_hash_table (info);
1867 struct elf_link_hash_entry *h;
1868 bfd_byte *p;
1869 asection *s;
1870 bfd *obfd;
1871 unsigned int i;
1872
47f6dab9
AM
1873 if (htab->stub_count == NULL)
1874 return TRUE;
1875
1876 for (i = 0; i <= htab->num_overlays; i++)
1877 if (htab->stub_sec[i]->size != 0)
1878 {
1879 htab->stub_sec[i]->contents = bfd_zalloc (htab->stub_sec[i]->owner,
1880 htab->stub_sec[i]->size);
1881 if (htab->stub_sec[i]->contents == NULL)
1882 return FALSE;
1883 htab->stub_sec[i]->rawsize = htab->stub_sec[i]->size;
1884 htab->stub_sec[i]->size = 0;
1885 }
e9f53129 1886
ad2adbc8 1887 for (i = 0; i < 2; i++)
cd4a7468 1888 {
ad2adbc8
AM
1889 h = htab->ovly_entry[i];
1890 BFD_ASSERT (h != NULL);
a7e11ee1 1891
ad2adbc8
AM
1892 if ((h->root.type == bfd_link_hash_defined
1893 || h->root.type == bfd_link_hash_defweak)
1894 && h->def_regular)
1895 {
1896 s = h->root.u.def.section->output_section;
1897 if (spu_elf_section_data (s)->u.o.ovl_index)
1898 {
1899 (*_bfd_error_handler) (_("%s in overlay section"),
1900 h->root.root.string);
1901 bfd_set_error (bfd_error_bad_value);
1902 return FALSE;
1903 }
1904 }
1905 else
1906 BFD_ASSERT (0);
cd4a7468 1907 }
47f6dab9 1908
c65be8d7
AM
1909 /* Fill in all the stubs. */
1910 process_stubs (info, TRUE);
f3c29e8a
AM
1911 if (!htab->stub_err)
1912 elf_link_hash_traverse (&htab->elf, build_spuear_stubs, info);
47f6dab9 1913
47f6dab9 1914 if (htab->stub_err)
f3c29e8a
AM
1915 {
1916 (*_bfd_error_handler) (_("overlay stub relocation overflow"));
1917 bfd_set_error (bfd_error_bad_value);
1918 return FALSE;
1919 }
e9f53129 1920
47f6dab9
AM
1921 for (i = 0; i <= htab->num_overlays; i++)
1922 {
1923 if (htab->stub_sec[i]->size != htab->stub_sec[i]->rawsize)
1924 {
1925 (*_bfd_error_handler) (_("stubs don't match calculated size"));
1926 bfd_set_error (bfd_error_bad_value);
1927 return FALSE;
1928 }
1929 htab->stub_sec[i]->rawsize = 0;
1930 }
1931
cd4a7468
AM
1932 if (htab->ovtab == NULL || htab->ovtab->size == 0)
1933 return TRUE;
1934
e9f53129
AM
1935 htab->ovtab->contents = bfd_zalloc (htab->ovtab->owner, htab->ovtab->size);
1936 if (htab->ovtab->contents == NULL)
1937 return FALSE;
1938
e9f53129 1939 p = htab->ovtab->contents;
cd4a7468 1940 if (htab->params->ovly_flavour == ovly_soft_icache)
e9f53129 1941 {
a7e11ee1 1942 bfd_vma off, icache_base, linklist;
cd4a7468 1943
77ae44b0 1944 h = define_ovtab_symbol (htab, "__icache_tag_array");
cd4a7468
AM
1945 if (h == NULL)
1946 return FALSE;
1947 h->root.u.def.value = 0;
1948 h->size = 16 << htab->num_lines_log2;
1949 off = h->size;
77ae44b0
AM
1950
1951 h = define_ovtab_symbol (htab, "__icache_tag_array_size");
1952 if (h == NULL)
1953 return FALSE;
1954 h->root.u.def.value = 16 << htab->num_lines_log2;
1955 h->root.u.def.section = bfd_abs_section_ptr;
1956
cd4a7468
AM
1957 icache_base = htab->ovl_sec[0]->vma;
1958 linklist = (htab->ovtab->output_section->vma
1959 + htab->ovtab->output_offset
1960 + off);
1961 for (i = 0; i < htab->params->num_lines; i++)
1962 {
1963 bfd_vma line_end = icache_base + ((i + 1) << htab->line_size_log2);
1964 bfd_vma stub_base = line_end - htab->params->max_branch * 32;
1965 bfd_vma link_elem = linklist + i * htab->params->max_branch * 16;
1966 bfd_vma locator = link_elem - stub_base / 2;
1967
1968 bfd_put_32 (htab->ovtab->owner, locator, p + 4);
1969 bfd_put_16 (htab->ovtab->owner, link_elem, p + 8);
1970 bfd_put_16 (htab->ovtab->owner, link_elem, p + 10);
1971 bfd_put_16 (htab->ovtab->owner, link_elem, p + 12);
1972 bfd_put_16 (htab->ovtab->owner, link_elem, p + 14);
1973 p += 16;
1974 }
1975
1976 h = define_ovtab_symbol (htab, "__icache_linked_list");
1977 if (h == NULL)
1978 return FALSE;
1979 h->root.u.def.value = off;
1980 h->size = htab->params->max_branch << (htab->num_lines_log2 + 4);
1981 off += h->size;
1982 p += h->size;
1983
cd4a7468
AM
1984 h = define_ovtab_symbol (htab, "__icache_base");
1985 if (h == NULL)
1986 return FALSE;
460e679b
AM
1987 h->root.u.def.value = htab->ovl_sec[0]->vma;
1988 h->root.u.def.section = bfd_abs_section_ptr;
cd4a7468 1989 h->size = htab->num_buf << htab->line_size_log2;
e9f53129 1990
50e00962
AM
1991 h = define_ovtab_symbol (htab, "__icache_neg_log2_linesize");
1992 if (h == NULL)
1993 return FALSE;
1994 h->root.u.def.value = -htab->line_size_log2;
1995 h->root.u.def.section = bfd_abs_section_ptr;
1996
cd4a7468 1997 if (htab->init != NULL && htab->init->size != 0)
e9f53129 1998 {
cd4a7468
AM
1999 htab->init->contents = bfd_zalloc (htab->init->owner,
2000 htab->init->size);
2001 if (htab->init->contents == NULL)
2002 return FALSE;
47f6dab9 2003
cd4a7468
AM
2004 h = define_ovtab_symbol (htab, "__icache_fileoff");
2005 if (h == NULL)
2006 return FALSE;
2007 h->root.u.def.value = 0;
2008 h->root.u.def.section = htab->init;
2009 h->size = 8;
e9f53129
AM
2010 }
2011 }
cd4a7468
AM
2012 else
2013 {
2014 /* Write out _ovly_table. */
2015 /* set low bit of .size to mark non-overlay area as present. */
2016 p[7] = 1;
2017 obfd = htab->ovtab->output_section->owner;
2018 for (s = obfd->sections; s != NULL; s = s->next)
2019 {
2020 unsigned int ovl_index = spu_elf_section_data (s)->u.o.ovl_index;
e9f53129 2021
cd4a7468
AM
2022 if (ovl_index != 0)
2023 {
2024 unsigned long off = ovl_index * 16;
2025 unsigned int ovl_buf = spu_elf_section_data (s)->u.o.ovl_buf;
2026
2027 bfd_put_32 (htab->ovtab->owner, s->vma, p + off);
2028 bfd_put_32 (htab->ovtab->owner, (s->size + 15) & -16,
2029 p + off + 4);
2030 /* file_off written later in spu_elf_modify_program_headers. */
2031 bfd_put_32 (htab->ovtab->owner, ovl_buf, p + off + 12);
2032 }
2033 }
e9f53129 2034
cd4a7468
AM
2035 h = define_ovtab_symbol (htab, "_ovly_table");
2036 if (h == NULL)
2037 return FALSE;
2038 h->root.u.def.value = 16;
2039 h->size = htab->num_overlays * 16;
e9f53129 2040
cd4a7468
AM
2041 h = define_ovtab_symbol (htab, "_ovly_table_end");
2042 if (h == NULL)
2043 return FALSE;
2044 h->root.u.def.value = htab->num_overlays * 16 + 16;
2045 h->size = 0;
e9f53129 2046
cd4a7468
AM
2047 h = define_ovtab_symbol (htab, "_ovly_buf_table");
2048 if (h == NULL)
2049 return FALSE;
2050 h->root.u.def.value = htab->num_overlays * 16 + 16;
2051 h->size = htab->num_buf * 4;
2052
2053 h = define_ovtab_symbol (htab, "_ovly_buf_table_end");
2054 if (h == NULL)
2055 return FALSE;
2056 h->root.u.def.value = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
2057 h->size = 0;
2058 }
e9f53129
AM
2059
2060 h = define_ovtab_symbol (htab, "_EAR_");
2061 if (h == NULL)
2062 return FALSE;
47f6dab9 2063 h->root.u.def.section = htab->toe;
e9f53129 2064 h->root.u.def.value = 0;
cd4a7468 2065 h->size = htab->params->ovly_flavour == ovly_soft_icache ? 16 * 16 : 16;
e9f53129
AM
2066
2067 return TRUE;
2068}
2069
c65be8d7 2070/* Check that all loadable section VMAs lie in the range
9dcc4794 2071 LO .. HI inclusive, and stash some parameters for --auto-overlay. */
c65be8d7
AM
2072
2073asection *
64615358 2074spu_elf_check_vma (struct bfd_link_info *info)
c65be8d7
AM
2075{
2076 struct elf_segment_map *m;
2077 unsigned int i;
9dcc4794 2078 struct spu_link_hash_table *htab = spu_hash_table (info);
c65be8d7 2079 bfd *abfd = info->output_bfd;
64615358
AM
2080 bfd_vma hi = htab->params->local_store_hi;
2081 bfd_vma lo = htab->params->local_store_lo;
c65be8d7 2082
9dcc4794 2083 htab->local_store = hi + 1 - lo;
9dcc4794 2084
c65be8d7
AM
2085 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
2086 if (m->p_type == PT_LOAD)
2087 for (i = 0; i < m->count; i++)
2088 if (m->sections[i]->size != 0
2089 && (m->sections[i]->vma < lo
2090 || m->sections[i]->vma > hi
2091 || m->sections[i]->vma + m->sections[i]->size - 1 > hi))
2092 return m->sections[i];
2093
2094 return NULL;
2095}
2096
49fa1e15 2097/* OFFSET in SEC (presumably) is the beginning of a function prologue.
cd4a7468
AM
2098 Search for stack adjusting insns, and return the sp delta.
2099 If a store of lr is found save the instruction offset to *LR_STORE.
2100 If a stack adjusting instruction is found, save that offset to
2101 *SP_ADJUST. */
49fa1e15
AM
2102
2103static int
cd4a7468
AM
2104find_function_stack_adjust (asection *sec,
2105 bfd_vma offset,
2106 bfd_vma *lr_store,
2107 bfd_vma *sp_adjust)
49fa1e15 2108{
49fa1e15
AM
2109 int reg[128];
2110
2111 memset (reg, 0, sizeof (reg));
667f3338 2112 for ( ; offset + 4 <= sec->size; offset += 4)
49fa1e15
AM
2113 {
2114 unsigned char buf[4];
2115 int rt, ra;
2116 int imm;
2117
2118 /* Assume no relocs on stack adjusing insns. */
2119 if (!bfd_get_section_contents (sec->owner, sec, buf, offset, 4))
2120 break;
2121
49fa1e15
AM
2122 rt = buf[3] & 0x7f;
2123 ra = ((buf[2] & 0x3f) << 1) | (buf[3] >> 7);
cd4a7468
AM
2124
2125 if (buf[0] == 0x24 /* stqd */)
2126 {
2127 if (rt == 0 /* lr */ && ra == 1 /* sp */)
2128 *lr_store = offset;
2129 continue;
2130 }
2131
49fa1e15
AM
2132 /* Partly decoded immediate field. */
2133 imm = (buf[1] << 9) | (buf[2] << 1) | (buf[3] >> 7);
2134
2135 if (buf[0] == 0x1c /* ai */)
2136 {
2137 imm >>= 7;
2138 imm = (imm ^ 0x200) - 0x200;
2139 reg[rt] = reg[ra] + imm;
2140
2141 if (rt == 1 /* sp */)
2142 {
667f3338 2143 if (reg[rt] > 0)
49fa1e15 2144 break;
cd4a7468 2145 *sp_adjust = offset;
49fa1e15
AM
2146 return reg[rt];
2147 }
2148 }
2149 else if (buf[0] == 0x18 && (buf[1] & 0xe0) == 0 /* a */)
2150 {
2151 int rb = ((buf[1] & 0x1f) << 2) | ((buf[2] & 0xc0) >> 6);
2152
2153 reg[rt] = reg[ra] + reg[rb];
2154 if (rt == 1)
667f3338
AM
2155 {
2156 if (reg[rt] > 0)
2157 break;
cd4a7468 2158 *sp_adjust = offset;
667f3338
AM
2159 return reg[rt];
2160 }
49fa1e15 2161 }
9b175a76
UW
2162 else if (buf[0] == 0x08 && (buf[1] & 0xe0) == 0 /* sf */)
2163 {
2164 int rb = ((buf[1] & 0x1f) << 2) | ((buf[2] & 0xc0) >> 6);
2165
2166 reg[rt] = reg[rb] - reg[ra];
2167 if (rt == 1)
2168 {
2169 if (reg[rt] > 0)
2170 break;
2171 *sp_adjust = offset;
2172 return reg[rt];
2173 }
2174 }
49fa1e15
AM
2175 else if ((buf[0] & 0xfc) == 0x40 /* il, ilh, ilhu, ila */)
2176 {
2177 if (buf[0] >= 0x42 /* ila */)
2178 imm |= (buf[0] & 1) << 17;
2179 else
2180 {
2181 imm &= 0xffff;
2182
2183 if (buf[0] == 0x40 /* il */)
2184 {
2185 if ((buf[1] & 0x80) == 0)
667f3338 2186 continue;
49fa1e15
AM
2187 imm = (imm ^ 0x8000) - 0x8000;
2188 }
2189 else if ((buf[1] & 0x80) == 0 /* ilhu */)
2190 imm <<= 16;
2191 }
2192 reg[rt] = imm;
2193 continue;
2194 }
2195 else if (buf[0] == 0x60 && (buf[1] & 0x80) != 0 /* iohl */)
2196 {
2197 reg[rt] |= imm & 0xffff;
2198 continue;
2199 }
2200 else if (buf[0] == 0x04 /* ori */)
2201 {
2202 imm >>= 7;
2203 imm = (imm ^ 0x200) - 0x200;
2204 reg[rt] = reg[ra] | imm;
2205 continue;
2206 }
667f3338
AM
2207 else if (buf[0] == 0x32 && (buf[1] & 0x80) != 0 /* fsmbi */)
2208 {
2209 reg[rt] = ( ((imm & 0x8000) ? 0xff000000 : 0)
2210 | ((imm & 0x4000) ? 0x00ff0000 : 0)
2211 | ((imm & 0x2000) ? 0x0000ff00 : 0)
2212 | ((imm & 0x1000) ? 0x000000ff : 0));
2213 continue;
2214 }
2215 else if (buf[0] == 0x16 /* andbi */)
49fa1e15 2216 {
667f3338
AM
2217 imm >>= 7;
2218 imm &= 0xff;
2219 imm |= imm << 8;
2220 imm |= imm << 16;
2221 reg[rt] = reg[ra] & imm;
2222 continue;
2223 }
2224 else if (buf[0] == 0x33 && imm == 1 /* brsl .+4 */)
2225 {
2226 /* Used in pic reg load. Say rt is trashed. Won't be used
2227 in stack adjust, but we need to continue past this branch. */
49fa1e15
AM
2228 reg[rt] = 0;
2229 continue;
2230 }
fad9eaf0 2231 else if (is_branch (buf) || is_indirect_branch (buf))
49fa1e15
AM
2232 /* If we hit a branch then we must be out of the prologue. */
2233 break;
49fa1e15
AM
2234 }
2235
2236 return 0;
2237}
2238
2239/* qsort predicate to sort symbols by section and value. */
2240
2241static Elf_Internal_Sym *sort_syms_syms;
2242static asection **sort_syms_psecs;
2243
2244static int
2245sort_syms (const void *a, const void *b)
2246{
2247 Elf_Internal_Sym *const *s1 = a;
2248 Elf_Internal_Sym *const *s2 = b;
2249 asection *sec1,*sec2;
2250 bfd_signed_vma delta;
2251
2252 sec1 = sort_syms_psecs[*s1 - sort_syms_syms];
2253 sec2 = sort_syms_psecs[*s2 - sort_syms_syms];
2254
2255 if (sec1 != sec2)
2256 return sec1->index - sec2->index;
2257
2258 delta = (*s1)->st_value - (*s2)->st_value;
2259 if (delta != 0)
2260 return delta < 0 ? -1 : 1;
2261
2262 delta = (*s2)->st_size - (*s1)->st_size;
2263 if (delta != 0)
2264 return delta < 0 ? -1 : 1;
2265
2266 return *s1 < *s2 ? -1 : 1;
2267}
2268
49fa1e15
AM
2269/* Allocate a struct spu_elf_stack_info with MAX_FUN struct function_info
2270 entries for section SEC. */
2271
2272static struct spu_elf_stack_info *
2273alloc_stack_info (asection *sec, int max_fun)
2274{
2275 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
2276 bfd_size_type amt;
2277
2278 amt = sizeof (struct spu_elf_stack_info);
2279 amt += (max_fun - 1) * sizeof (struct function_info);
47f6dab9
AM
2280 sec_data->u.i.stack_info = bfd_zmalloc (amt);
2281 if (sec_data->u.i.stack_info != NULL)
2282 sec_data->u.i.stack_info->max_fun = max_fun;
2283 return sec_data->u.i.stack_info;
49fa1e15
AM
2284}
2285
2286/* Add a new struct function_info describing a (part of a) function
2287 starting at SYM_H. Keep the array sorted by address. */
2288
2289static struct function_info *
2290maybe_insert_function (asection *sec,
2291 void *sym_h,
2292 bfd_boolean global,
2293 bfd_boolean is_func)
2294{
2295 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 2296 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
2297 int i;
2298 bfd_vma off, size;
2299
2300 if (sinfo == NULL)
2301 {
2302 sinfo = alloc_stack_info (sec, 20);
2303 if (sinfo == NULL)
2304 return NULL;
2305 }
2306
2307 if (!global)
2308 {
2309 Elf_Internal_Sym *sym = sym_h;
2310 off = sym->st_value;
2311 size = sym->st_size;
2312 }
2313 else
2314 {
2315 struct elf_link_hash_entry *h = sym_h;
2316 off = h->root.u.def.value;
2317 size = h->size;
2318 }
2319
2320 for (i = sinfo->num_fun; --i >= 0; )
2321 if (sinfo->fun[i].lo <= off)
2322 break;
2323
2324 if (i >= 0)
2325 {
2326 /* Don't add another entry for an alias, but do update some
2327 info. */
2328 if (sinfo->fun[i].lo == off)
2329 {
2330 /* Prefer globals over local syms. */
2331 if (global && !sinfo->fun[i].global)
2332 {
2333 sinfo->fun[i].global = TRUE;
2334 sinfo->fun[i].u.h = sym_h;
2335 }
2336 if (is_func)
2337 sinfo->fun[i].is_func = TRUE;
2338 return &sinfo->fun[i];
2339 }
2340 /* Ignore a zero-size symbol inside an existing function. */
2341 else if (sinfo->fun[i].hi > off && size == 0)
2342 return &sinfo->fun[i];
2343 }
2344
1f27ab8d 2345 if (sinfo->num_fun >= sinfo->max_fun)
49fa1e15
AM
2346 {
2347 bfd_size_type amt = sizeof (struct spu_elf_stack_info);
2348 bfd_size_type old = amt;
2349
2350 old += (sinfo->max_fun - 1) * sizeof (struct function_info);
2351 sinfo->max_fun += 20 + (sinfo->max_fun >> 1);
2352 amt += (sinfo->max_fun - 1) * sizeof (struct function_info);
2353 sinfo = bfd_realloc (sinfo, amt);
2354 if (sinfo == NULL)
2355 return NULL;
2356 memset ((char *) sinfo + old, 0, amt - old);
47f6dab9 2357 sec_data->u.i.stack_info = sinfo;
49fa1e15 2358 }
1f27ab8d
AM
2359
2360 if (++i < sinfo->num_fun)
2361 memmove (&sinfo->fun[i + 1], &sinfo->fun[i],
2362 (sinfo->num_fun - i) * sizeof (sinfo->fun[i]));
49fa1e15
AM
2363 sinfo->fun[i].is_func = is_func;
2364 sinfo->fun[i].global = global;
2365 sinfo->fun[i].sec = sec;
2366 if (global)
2367 sinfo->fun[i].u.h = sym_h;
2368 else
2369 sinfo->fun[i].u.sym = sym_h;
2370 sinfo->fun[i].lo = off;
2371 sinfo->fun[i].hi = off + size;
cd4a7468
AM
2372 sinfo->fun[i].lr_store = -1;
2373 sinfo->fun[i].sp_adjust = -1;
2374 sinfo->fun[i].stack = -find_function_stack_adjust (sec, off,
2375 &sinfo->fun[i].lr_store,
2376 &sinfo->fun[i].sp_adjust);
49fa1e15
AM
2377 sinfo->num_fun += 1;
2378 return &sinfo->fun[i];
2379}
2380
2381/* Return the name of FUN. */
2382
2383static const char *
2384func_name (struct function_info *fun)
2385{
2386 asection *sec;
2387 bfd *ibfd;
2388 Elf_Internal_Shdr *symtab_hdr;
2389
2390 while (fun->start != NULL)
2391 fun = fun->start;
2392
2393 if (fun->global)
2394 return fun->u.h->root.root.string;
2395
2396 sec = fun->sec;
2397 if (fun->u.sym->st_name == 0)
2398 {
2399 size_t len = strlen (sec->name);
2400 char *name = bfd_malloc (len + 10);
2401 if (name == NULL)
2402 return "(null)";
2403 sprintf (name, "%s+%lx", sec->name,
2404 (unsigned long) fun->u.sym->st_value & 0xffffffff);
2405 return name;
2406 }
2407 ibfd = sec->owner;
2408 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2409 return bfd_elf_sym_name (ibfd, symtab_hdr, fun->u.sym, sec);
2410}
2411
2412/* Read the instruction at OFF in SEC. Return true iff the instruction
2413 is a nop, lnop, or stop 0 (all zero insn). */
2414
2415static bfd_boolean
2416is_nop (asection *sec, bfd_vma off)
2417{
2418 unsigned char insn[4];
2419
2420 if (off + 4 > sec->size
2421 || !bfd_get_section_contents (sec->owner, sec, insn, off, 4))
2422 return FALSE;
2423 if ((insn[0] & 0xbf) == 0 && (insn[1] & 0xe0) == 0x20)
2424 return TRUE;
2425 if (insn[0] == 0 && insn[1] == 0 && insn[2] == 0 && insn[3] == 0)
2426 return TRUE;
2427 return FALSE;
2428}
2429
2430/* Extend the range of FUN to cover nop padding up to LIMIT.
2431 Return TRUE iff some instruction other than a NOP was found. */
2432
2433static bfd_boolean
2434insns_at_end (struct function_info *fun, bfd_vma limit)
2435{
2436 bfd_vma off = (fun->hi + 3) & -4;
2437
2438 while (off < limit && is_nop (fun->sec, off))
2439 off += 4;
2440 if (off < limit)
2441 {
2442 fun->hi = off;
2443 return TRUE;
2444 }
2445 fun->hi = limit;
2446 return FALSE;
2447}
2448
2449/* Check and fix overlapping function ranges. Return TRUE iff there
2450 are gaps in the current info we have about functions in SEC. */
2451
2452static bfd_boolean
2453check_function_ranges (asection *sec, struct bfd_link_info *info)
2454{
2455 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 2456 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
2457 int i;
2458 bfd_boolean gaps = FALSE;
2459
2460 if (sinfo == NULL)
2461 return FALSE;
2462
2463 for (i = 1; i < sinfo->num_fun; i++)
2464 if (sinfo->fun[i - 1].hi > sinfo->fun[i].lo)
2465 {
2466 /* Fix overlapping symbols. */
2467 const char *f1 = func_name (&sinfo->fun[i - 1]);
2468 const char *f2 = func_name (&sinfo->fun[i]);
2469
2470 info->callbacks->einfo (_("warning: %s overlaps %s\n"), f1, f2);
2471 sinfo->fun[i - 1].hi = sinfo->fun[i].lo;
2472 }
2473 else if (insns_at_end (&sinfo->fun[i - 1], sinfo->fun[i].lo))
2474 gaps = TRUE;
2475
2476 if (sinfo->num_fun == 0)
2477 gaps = TRUE;
2478 else
2479 {
2480 if (sinfo->fun[0].lo != 0)
2481 gaps = TRUE;
2482 if (sinfo->fun[sinfo->num_fun - 1].hi > sec->size)
2483 {
2484 const char *f1 = func_name (&sinfo->fun[sinfo->num_fun - 1]);
2485
2486 info->callbacks->einfo (_("warning: %s exceeds section size\n"), f1);
2487 sinfo->fun[sinfo->num_fun - 1].hi = sec->size;
2488 }
2489 else if (insns_at_end (&sinfo->fun[sinfo->num_fun - 1], sec->size))
2490 gaps = TRUE;
2491 }
2492 return gaps;
2493}
2494
2495/* Search current function info for a function that contains address
2496 OFFSET in section SEC. */
2497
2498static struct function_info *
2499find_function (asection *sec, bfd_vma offset, struct bfd_link_info *info)
2500{
2501 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
47f6dab9 2502 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
49fa1e15
AM
2503 int lo, hi, mid;
2504
2505 lo = 0;
2506 hi = sinfo->num_fun;
2507 while (lo < hi)
2508 {
2509 mid = (lo + hi) / 2;
2510 if (offset < sinfo->fun[mid].lo)
2511 hi = mid;
2512 else if (offset >= sinfo->fun[mid].hi)
2513 lo = mid + 1;
2514 else
2515 return &sinfo->fun[mid];
2516 }
2517 info->callbacks->einfo (_("%A:0x%v not found in function table\n"),
2518 sec, offset);
3209bffa 2519 bfd_set_error (bfd_error_bad_value);
49fa1e15
AM
2520 return NULL;
2521}
2522
9dcc4794
AM
2523/* Add CALLEE to CALLER call list if not already present. Return TRUE
2524 if CALLEE was new. If this function return FALSE, CALLEE should
2525 be freed. */
49fa1e15
AM
2526
2527static bfd_boolean
2528insert_callee (struct function_info *caller, struct call_info *callee)
2529{
055ed83b
AM
2530 struct call_info **pp, *p;
2531
2532 for (pp = &caller->call_list; (p = *pp) != NULL; pp = &p->next)
49fa1e15
AM
2533 if (p->fun == callee->fun)
2534 {
2535 /* Tail calls use less stack than normal calls. Retain entry
2536 for normal call over one for tail call. */
c65be8d7
AM
2537 p->is_tail &= callee->is_tail;
2538 if (!p->is_tail)
2539 {
2540 p->fun->start = NULL;
2541 p->fun->is_func = TRUE;
2542 }
9dcc4794 2543 p->count += 1;
055ed83b
AM
2544 /* Reorder list so most recent call is first. */
2545 *pp = p->next;
2546 p->next = caller->call_list;
2547 caller->call_list = p;
49fa1e15
AM
2548 return FALSE;
2549 }
2550 callee->next = caller->call_list;
9dcc4794 2551 callee->count += 1;
49fa1e15
AM
2552 caller->call_list = callee;
2553 return TRUE;
2554}
2555
9dcc4794
AM
2556/* Copy CALL and insert the copy into CALLER. */
2557
2558static bfd_boolean
2559copy_callee (struct function_info *caller, const struct call_info *call)
2560{
2561 struct call_info *callee;
2562 callee = bfd_malloc (sizeof (*callee));
2563 if (callee == NULL)
2564 return FALSE;
2565 *callee = *call;
2566 if (!insert_callee (caller, callee))
2567 free (callee);
2568 return TRUE;
2569}
2570
055ed83b
AM
2571/* We're only interested in code sections. Testing SEC_IN_MEMORY excludes
2572 overlay stub sections. */
2573
2574static bfd_boolean
64615358 2575interesting_section (asection *s)
055ed83b 2576{
64615358 2577 return (s->output_section != bfd_abs_section_ptr
055ed83b
AM
2578 && ((s->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_IN_MEMORY))
2579 == (SEC_ALLOC | SEC_LOAD | SEC_CODE))
2580 && s->size != 0);
2581}
2582
49fa1e15
AM
2583/* Rummage through the relocs for SEC, looking for function calls.
2584 If CALL_TREE is true, fill in call graph. If CALL_TREE is false,
2585 mark destination symbols on calls as being functions. Also
2586 look at branches, which may be tail calls or go to hot/cold
2587 section part of same function. */
2588
2589static bfd_boolean
2590mark_functions_via_relocs (asection *sec,
2591 struct bfd_link_info *info,
2592 int call_tree)
2593{
2594 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
2ec9638b 2595 Elf_Internal_Shdr *symtab_hdr;
d0249648 2596 void *psyms;
cd4a7468 2597 unsigned int priority = 0;
49fa1e15
AM
2598 static bfd_boolean warned;
2599
64615358 2600 if (!interesting_section (sec)
055ed83b
AM
2601 || sec->reloc_count == 0)
2602 return TRUE;
2603
49fa1e15
AM
2604 internal_relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
2605 info->keep_memory);
2606 if (internal_relocs == NULL)
2607 return FALSE;
2608
2609 symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
d0249648 2610 psyms = &symtab_hdr->contents;
49fa1e15
AM
2611 irela = internal_relocs;
2612 irelaend = irela + sec->reloc_count;
2613 for (; irela < irelaend; irela++)
2614 {
2615 enum elf_spu_reloc_type r_type;
2616 unsigned int r_indx;
2617 asection *sym_sec;
2618 Elf_Internal_Sym *sym;
2619 struct elf_link_hash_entry *h;
2620 bfd_vma val;
9dcc4794 2621 bfd_boolean reject, is_call;
49fa1e15
AM
2622 struct function_info *caller;
2623 struct call_info *callee;
2624
9dcc4794 2625 reject = FALSE;
49fa1e15
AM
2626 r_type = ELF32_R_TYPE (irela->r_info);
2627 if (r_type != R_SPU_REL16
2628 && r_type != R_SPU_ADDR16)
9dcc4794
AM
2629 {
2630 reject = TRUE;
64615358 2631 if (!(call_tree && spu_hash_table (info)->params->auto_overlay))
9dcc4794
AM
2632 continue;
2633 }
49fa1e15
AM
2634
2635 r_indx = ELF32_R_SYM (irela->r_info);
2636 if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, sec->owner))
2637 return FALSE;
2638
2639 if (sym_sec == NULL
64615358 2640 || sym_sec->output_section == bfd_abs_section_ptr)
49fa1e15
AM
2641 continue;
2642
9dcc4794
AM
2643 is_call = FALSE;
2644 if (!reject)
2645 {
2646 unsigned char insn[4];
2647
2648 if (!bfd_get_section_contents (sec->owner, sec, insn,
2649 irela->r_offset, 4))
2650 return FALSE;
2651 if (is_branch (insn))
2652 {
2653 is_call = (insn[0] & 0xfd) == 0x31;
cd4a7468
AM
2654 priority = insn[1] & 0x0f;
2655 priority <<= 8;
2656 priority |= insn[2];
2657 priority <<= 8;
2658 priority |= insn[3];
2659 priority >>= 7;
9dcc4794
AM
2660 if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
2661 != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
2662 {
2663 if (!warned)
2664 info->callbacks->einfo
2665 (_("%B(%A+0x%v): call to non-code section"
2666 " %B(%A), analysis incomplete\n"),
2667 sec->owner, sec, irela->r_offset,
2668 sym_sec->owner, sym_sec);
2669 warned = TRUE;
2670 continue;
2671 }
2672 }
2673 else
2674 {
2675 reject = TRUE;
64615358 2676 if (!(call_tree && spu_hash_table (info)->params->auto_overlay)
9dcc4794
AM
2677 || is_hint (insn))
2678 continue;
2679 }
2680 }
49fa1e15 2681
9dcc4794 2682 if (reject)
49fa1e15 2683 {
9dcc4794
AM
2684 /* For --auto-overlay, count possible stubs we need for
2685 function pointer references. */
2686 unsigned int sym_type;
2687 if (h)
2688 sym_type = h->type;
2689 else
2690 sym_type = ELF_ST_TYPE (sym->st_info);
2691 if (sym_type == STT_FUNC)
2692 spu_hash_table (info)->non_ovly_stub += 1;
49fa1e15
AM
2693 continue;
2694 }
2695
49fa1e15
AM
2696 if (h)
2697 val = h->root.u.def.value;
2698 else
2699 val = sym->st_value;
2700 val += irela->r_addend;
2701
2702 if (!call_tree)
2703 {
2704 struct function_info *fun;
2705
2706 if (irela->r_addend != 0)
2707 {
2708 Elf_Internal_Sym *fake = bfd_zmalloc (sizeof (*fake));
2709 if (fake == NULL)
2710 return FALSE;
2711 fake->st_value = val;
2712 fake->st_shndx
2713 = _bfd_elf_section_from_bfd_section (sym_sec->owner, sym_sec);
2714 sym = fake;
2715 }
2716 if (sym)
2717 fun = maybe_insert_function (sym_sec, sym, FALSE, is_call);
2718 else
2719 fun = maybe_insert_function (sym_sec, h, TRUE, is_call);
2720 if (fun == NULL)
2721 return FALSE;
2722 if (irela->r_addend != 0
2723 && fun->u.sym != sym)
2724 free (sym);
2725 continue;
2726 }
2727
2728 caller = find_function (sec, irela->r_offset, info);
2729 if (caller == NULL)
2730 return FALSE;
2731 callee = bfd_malloc (sizeof *callee);
2732 if (callee == NULL)
2733 return FALSE;
2734
2735 callee->fun = find_function (sym_sec, val, info);
2736 if (callee->fun == NULL)
2737 return FALSE;
2738 callee->is_tail = !is_call;
9dcc4794 2739 callee->is_pasted = FALSE;
cd4a7468 2740 callee->priority = priority;
9dcc4794
AM
2741 callee->count = 0;
2742 if (callee->fun->last_caller != sec)
2743 {
2744 callee->fun->last_caller = sec;
2745 callee->fun->call_count += 1;
2746 }
49fa1e15
AM
2747 if (!insert_callee (caller, callee))
2748 free (callee);
2749 else if (!is_call
2750 && !callee->fun->is_func
2751 && callee->fun->stack == 0)
2752 {
2753 /* This is either a tail call or a branch from one part of
2754 the function to another, ie. hot/cold section. If the
2755 destination has been called by some other function then
2756 it is a separate function. We also assume that functions
2757 are not split across input files. */
911f096e 2758 if (sec->owner != sym_sec->owner)
49fa1e15
AM
2759 {
2760 callee->fun->start = NULL;
2761 callee->fun->is_func = TRUE;
2762 }
911f096e 2763 else if (callee->fun->start == NULL)
49fa1e15 2764 callee->fun->start = caller;
911f096e
AM
2765 else
2766 {
2767 struct function_info *callee_start;
2768 struct function_info *caller_start;
2769 callee_start = callee->fun;
2770 while (callee_start->start)
2771 callee_start = callee_start->start;
2772 caller_start = caller;
2773 while (caller_start->start)
2774 caller_start = caller_start->start;
2775 if (caller_start != callee_start)
2776 {
2777 callee->fun->start = NULL;
2778 callee->fun->is_func = TRUE;
2779 }
2780 }
49fa1e15
AM
2781 }
2782 }
2783
2784 return TRUE;
2785}
2786
2787/* Handle something like .init or .fini, which has a piece of a function.
2788 These sections are pasted together to form a single function. */
2789
2790static bfd_boolean
3209bffa 2791pasted_function (asection *sec)
49fa1e15
AM
2792{
2793 struct bfd_link_order *l;
2794 struct _spu_elf_section_data *sec_data;
2795 struct spu_elf_stack_info *sinfo;
2796 Elf_Internal_Sym *fake;
2797 struct function_info *fun, *fun_start;
2798
2799 fake = bfd_zmalloc (sizeof (*fake));
2800 if (fake == NULL)
2801 return FALSE;
2802 fake->st_value = 0;
2803 fake->st_size = sec->size;
2804 fake->st_shndx
2805 = _bfd_elf_section_from_bfd_section (sec->owner, sec);
2806 fun = maybe_insert_function (sec, fake, FALSE, FALSE);
2807 if (!fun)
2808 return FALSE;
2809
2810 /* Find a function immediately preceding this section. */
2811 fun_start = NULL;
2812 for (l = sec->output_section->map_head.link_order; l != NULL; l = l->next)
2813 {
2814 if (l->u.indirect.section == sec)
2815 {
2816 if (fun_start != NULL)
9dcc4794
AM
2817 {
2818 struct call_info *callee = bfd_malloc (sizeof *callee);
2819 if (callee == NULL)
2820 return FALSE;
2821
2822 fun->start = fun_start;
2823 callee->fun = fun;
2824 callee->is_tail = TRUE;
2825 callee->is_pasted = TRUE;
2826 callee->count = 0;
2827 if (!insert_callee (fun_start, callee))
2828 free (callee);
2829 return TRUE;
2830 }
2831 break;
49fa1e15
AM
2832 }
2833 if (l->type == bfd_indirect_link_order
2834 && (sec_data = spu_elf_section_data (l->u.indirect.section)) != NULL
47f6dab9 2835 && (sinfo = sec_data->u.i.stack_info) != NULL
49fa1e15
AM
2836 && sinfo->num_fun != 0)
2837 fun_start = &sinfo->fun[sinfo->num_fun - 1];
2838 }
2839
3209bffa
AM
2840 /* Don't return an error if we did not find a function preceding this
2841 section. The section may have incorrect flags. */
2842 return TRUE;
49fa1e15
AM
2843}
2844
49fa1e15
AM
2845/* Map address ranges in code sections to functions. */
2846
2847static bfd_boolean
c65be8d7 2848discover_functions (struct bfd_link_info *info)
49fa1e15 2849{
49fa1e15
AM
2850 bfd *ibfd;
2851 int bfd_idx;
2852 Elf_Internal_Sym ***psym_arr;
2853 asection ***sec_arr;
2854 bfd_boolean gaps = FALSE;
2855
2856 bfd_idx = 0;
2857 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2858 bfd_idx++;
2859
2860 psym_arr = bfd_zmalloc (bfd_idx * sizeof (*psym_arr));
2861 if (psym_arr == NULL)
2862 return FALSE;
2863 sec_arr = bfd_zmalloc (bfd_idx * sizeof (*sec_arr));
2864 if (sec_arr == NULL)
2865 return FALSE;
49fa1e15
AM
2866
2867 for (ibfd = info->input_bfds, bfd_idx = 0;
2868 ibfd != NULL;
2869 ibfd = ibfd->link_next, bfd_idx++)
2870 {
2871 extern const bfd_target bfd_elf32_spu_vec;
2872 Elf_Internal_Shdr *symtab_hdr;
2873 asection *sec;
2874 size_t symcount;
2875 Elf_Internal_Sym *syms, *sy, **psyms, **psy;
2876 asection **psecs, **p;
2877
2878 if (ibfd->xvec != &bfd_elf32_spu_vec)
2879 continue;
2880
2881 /* Read all the symbols. */
2882 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2883 symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
2884 if (symcount == 0)
055ed83b
AM
2885 {
2886 if (!gaps)
2887 for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
64615358 2888 if (interesting_section (sec))
055ed83b
AM
2889 {
2890 gaps = TRUE;
2891 break;
2892 }
2893 continue;
2894 }
49fa1e15 2895
1f27ab8d 2896 if (symtab_hdr->contents != NULL)
49fa1e15 2897 {
1f27ab8d
AM
2898 /* Don't use cached symbols since the generic ELF linker
2899 code only reads local symbols, and we need globals too. */
2900 free (symtab_hdr->contents);
2901 symtab_hdr->contents = NULL;
49fa1e15 2902 }
1f27ab8d
AM
2903 syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
2904 NULL, NULL, NULL);
2905 symtab_hdr->contents = (void *) syms;
2906 if (syms == NULL)
2907 return FALSE;
49fa1e15
AM
2908
2909 /* Select defined function symbols that are going to be output. */
2910 psyms = bfd_malloc ((symcount + 1) * sizeof (*psyms));
2911 if (psyms == NULL)
2912 return FALSE;
2913 psym_arr[bfd_idx] = psyms;
2914 psecs = bfd_malloc (symcount * sizeof (*psecs));
2915 if (psecs == NULL)
2916 return FALSE;
2917 sec_arr[bfd_idx] = psecs;
2918 for (psy = psyms, p = psecs, sy = syms; sy < syms + symcount; ++p, ++sy)
2919 if (ELF_ST_TYPE (sy->st_info) == STT_NOTYPE
3209bffa 2920 || ELF_ST_TYPE (sy->st_info) == STT_FUNC)
49fa1e15
AM
2921 {
2922 asection *s;
2923
2924 *p = s = bfd_section_from_elf_index (ibfd, sy->st_shndx);
64615358 2925 if (s != NULL && interesting_section (s))
49fa1e15
AM
2926 *psy++ = sy;
2927 }
2928 symcount = psy - psyms;
2929 *psy = NULL;
2930
2931 /* Sort them by section and offset within section. */
2932 sort_syms_syms = syms;
2933 sort_syms_psecs = psecs;
2934 qsort (psyms, symcount, sizeof (*psyms), sort_syms);
2935
2936 /* Now inspect the function symbols. */
2937 for (psy = psyms; psy < psyms + symcount; )
2938 {
2939 asection *s = psecs[*psy - syms];
2940 Elf_Internal_Sym **psy2;
2941
2942 for (psy2 = psy; ++psy2 < psyms + symcount; )
2943 if (psecs[*psy2 - syms] != s)
2944 break;
2945
2946 if (!alloc_stack_info (s, psy2 - psy))
2947 return FALSE;
2948 psy = psy2;
2949 }
2950
2951 /* First install info about properly typed and sized functions.
2952 In an ideal world this will cover all code sections, except
2953 when partitioning functions into hot and cold sections,
2954 and the horrible pasted together .init and .fini functions. */
2955 for (psy = psyms; psy < psyms + symcount; ++psy)
2956 {
2957 sy = *psy;
2958 if (ELF_ST_TYPE (sy->st_info) == STT_FUNC)
2959 {
2960 asection *s = psecs[sy - syms];
2961 if (!maybe_insert_function (s, sy, FALSE, TRUE))
2962 return FALSE;
2963 }
2964 }
2965
2966 for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
64615358 2967 if (interesting_section (sec))
49fa1e15
AM
2968 gaps |= check_function_ranges (sec, info);
2969 }
2970
2971 if (gaps)
2972 {
2973 /* See if we can discover more function symbols by looking at
2974 relocations. */
2975 for (ibfd = info->input_bfds, bfd_idx = 0;
2976 ibfd != NULL;
2977 ibfd = ibfd->link_next, bfd_idx++)
2978 {
2979 asection *sec;
2980
2981 if (psym_arr[bfd_idx] == NULL)
2982 continue;
2983
2984 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
055ed83b
AM
2985 if (!mark_functions_via_relocs (sec, info, FALSE))
2986 return FALSE;
49fa1e15
AM
2987 }
2988
2989 for (ibfd = info->input_bfds, bfd_idx = 0;
2990 ibfd != NULL;
2991 ibfd = ibfd->link_next, bfd_idx++)
2992 {
2993 Elf_Internal_Shdr *symtab_hdr;
2994 asection *sec;
2995 Elf_Internal_Sym *syms, *sy, **psyms, **psy;
2996 asection **psecs;
2997
2998 if ((psyms = psym_arr[bfd_idx]) == NULL)
2999 continue;
3000
3001 psecs = sec_arr[bfd_idx];
3002
3003 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3004 syms = (Elf_Internal_Sym *) symtab_hdr->contents;
3005
3006 gaps = FALSE;
3007 for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
64615358 3008 if (interesting_section (sec))
49fa1e15
AM
3009 gaps |= check_function_ranges (sec, info);
3010 if (!gaps)
3011 continue;
3012
3013 /* Finally, install all globals. */
3014 for (psy = psyms; (sy = *psy) != NULL; ++psy)
3015 {
3016 asection *s;
3017
3018 s = psecs[sy - syms];
3019
3020 /* Global syms might be improperly typed functions. */
3021 if (ELF_ST_TYPE (sy->st_info) != STT_FUNC
3022 && ELF_ST_BIND (sy->st_info) == STB_GLOBAL)
3023 {
3024 if (!maybe_insert_function (s, sy, FALSE, FALSE))
3025 return FALSE;
3026 }
3027 }
055ed83b
AM
3028 }
3029
3030 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
3031 {
3032 extern const bfd_target bfd_elf32_spu_vec;
3033 asection *sec;
3034
3035 if (ibfd->xvec != &bfd_elf32_spu_vec)
3036 continue;
49fa1e15
AM
3037
3038 /* Some of the symbols we've installed as marking the
3039 beginning of functions may have a size of zero. Extend
3040 the range of such functions to the beginning of the
3041 next symbol of interest. */
3042 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
64615358 3043 if (interesting_section (sec))
49fa1e15
AM
3044 {
3045 struct _spu_elf_section_data *sec_data;
3046 struct spu_elf_stack_info *sinfo;
3047
3048 sec_data = spu_elf_section_data (sec);
47f6dab9 3049 sinfo = sec_data->u.i.stack_info;
3209bffa 3050 if (sinfo != NULL && sinfo->num_fun != 0)
49fa1e15
AM
3051 {
3052 int fun_idx;
3053 bfd_vma hi = sec->size;
3054
3055 for (fun_idx = sinfo->num_fun; --fun_idx >= 0; )
3056 {
3057 sinfo->fun[fun_idx].hi = hi;
3058 hi = sinfo->fun[fun_idx].lo;
3059 }
3209bffa
AM
3060
3061 sinfo->fun[0].lo = 0;
49fa1e15
AM
3062 }
3063 /* No symbols in this section. Must be .init or .fini
3064 or something similar. */
3209bffa 3065 else if (!pasted_function (sec))
49fa1e15
AM
3066 return FALSE;
3067 }
3068 }
3069 }
3070
3071 for (ibfd = info->input_bfds, bfd_idx = 0;
3072 ibfd != NULL;
3073 ibfd = ibfd->link_next, bfd_idx++)
3074 {
3075 if (psym_arr[bfd_idx] == NULL)
3076 continue;
3077
3078 free (psym_arr[bfd_idx]);
3079 free (sec_arr[bfd_idx]);
3080 }
3081
3082 free (psym_arr);
3083 free (sec_arr);
3084
3085 return TRUE;
3086}
3087
055ed83b
AM
3088/* Iterate over all function_info we have collected, calling DOIT on
3089 each node if ROOT_ONLY is false. Only call DOIT on root nodes
3090 if ROOT_ONLY. */
3091
3092static bfd_boolean
3093for_each_node (bfd_boolean (*doit) (struct function_info *,
3094 struct bfd_link_info *,
3095 void *),
3096 struct bfd_link_info *info,
3097 void *param,
3098 int root_only)
3099{
3100 bfd *ibfd;
3101
3102 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
3103 {
3104 extern const bfd_target bfd_elf32_spu_vec;
3105 asection *sec;
3106
3107 if (ibfd->xvec != &bfd_elf32_spu_vec)
3108 continue;
3109
3110 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
3111 {
3112 struct _spu_elf_section_data *sec_data;
3113 struct spu_elf_stack_info *sinfo;
3114
3115 if ((sec_data = spu_elf_section_data (sec)) != NULL
3116 && (sinfo = sec_data->u.i.stack_info) != NULL)
3117 {
3118 int i;
3119 for (i = 0; i < sinfo->num_fun; ++i)
3120 if (!root_only || !sinfo->fun[i].non_root)
3121 if (!doit (&sinfo->fun[i], info, param))
3122 return FALSE;
3123 }
3124 }
3125 }
3126 return TRUE;
3127}
3128
3129/* Transfer call info attached to struct function_info entries for
3130 all of a given function's sections to the first entry. */
3131
3132static bfd_boolean
3133transfer_calls (struct function_info *fun,
3134 struct bfd_link_info *info ATTRIBUTE_UNUSED,
3135 void *param ATTRIBUTE_UNUSED)
3136{
3137 struct function_info *start = fun->start;
3138
3139 if (start != NULL)
3140 {
3141 struct call_info *call, *call_next;
3142
3143 while (start->start != NULL)
3144 start = start->start;
3145 for (call = fun->call_list; call != NULL; call = call_next)
3146 {
3147 call_next = call->next;
3148 if (!insert_callee (start, call))
3149 free (call);
3150 }
3151 fun->call_list = NULL;
3152 }
3153 return TRUE;
3154}
3155
49fa1e15
AM
3156/* Mark nodes in the call graph that are called by some other node. */
3157
055ed83b
AM
3158static bfd_boolean
3159mark_non_root (struct function_info *fun,
3160 struct bfd_link_info *info ATTRIBUTE_UNUSED,
3161 void *param ATTRIBUTE_UNUSED)
49fa1e15
AM
3162{
3163 struct call_info *call;
3164
055ed83b
AM
3165 if (fun->visit1)
3166 return TRUE;
49fa1e15
AM
3167 fun->visit1 = TRUE;
3168 for (call = fun->call_list; call; call = call->next)
3169 {
3170 call->fun->non_root = TRUE;
055ed83b 3171 mark_non_root (call->fun, 0, 0);
49fa1e15 3172 }
055ed83b 3173 return TRUE;
49fa1e15
AM
3174}
3175
9dcc4794 3176/* Remove cycles from the call graph. Set depth of nodes. */
49fa1e15 3177
055ed83b
AM
3178static bfd_boolean
3179remove_cycles (struct function_info *fun,
3180 struct bfd_link_info *info,
9dcc4794 3181 void *param)
49fa1e15
AM
3182{
3183 struct call_info **callp, *call;
9dcc4794
AM
3184 unsigned int depth = *(unsigned int *) param;
3185 unsigned int max_depth = depth;
49fa1e15 3186
9dcc4794 3187 fun->depth = depth;
49fa1e15
AM
3188 fun->visit2 = TRUE;
3189 fun->marking = TRUE;
3190
3191 callp = &fun->call_list;
3192 while ((call = *callp) != NULL)
3193 {
25076afa 3194 call->max_depth = depth + !call->is_pasted;
49fa1e15 3195 if (!call->fun->visit2)
055ed83b 3196 {
9dcc4794 3197 if (!remove_cycles (call->fun, info, &call->max_depth))
055ed83b 3198 return FALSE;
9dcc4794
AM
3199 if (max_depth < call->max_depth)
3200 max_depth = call->max_depth;
055ed83b 3201 }
49fa1e15
AM
3202 else if (call->fun->marking)
3203 {
cd4a7468
AM
3204 struct spu_link_hash_table *htab = spu_hash_table (info);
3205
3206 if (!htab->params->auto_overlay
3207 && htab->params->stack_analysis)
9dcc4794
AM
3208 {
3209 const char *f1 = func_name (fun);
3210 const char *f2 = func_name (call->fun);
49fa1e15 3211
9dcc4794
AM
3212 info->callbacks->info (_("Stack analysis will ignore the call "
3213 "from %s to %s\n"),
3214 f1, f2);
3215 }
49fa1e15 3216 *callp = call->next;
055ed83b 3217 free (call);
49fa1e15
AM
3218 continue;
3219 }
3220 callp = &call->next;
3221 }
3222 fun->marking = FALSE;
9dcc4794 3223 *(unsigned int *) param = max_depth;
055ed83b 3224 return TRUE;
49fa1e15
AM
3225}
3226
667f3338
AM
3227/* Check that we actually visited all nodes in remove_cycles. If we
3228 didn't, then there is some cycle in the call graph not attached to
3229 any root node. Arbitrarily choose a node in the cycle as a new
3230 root and break the cycle. */
3231
3232static bfd_boolean
3233mark_detached_root (struct function_info *fun,
3234 struct bfd_link_info *info,
3235 void *param)
3236{
3237 if (fun->visit2)
3238 return TRUE;
3239 fun->non_root = FALSE;
3240 *(unsigned int *) param = 0;
3241 return remove_cycles (fun, info, param);
3242}
3243
49fa1e15
AM
3244/* Populate call_list for each function. */
3245
3246static bfd_boolean
c65be8d7 3247build_call_tree (struct bfd_link_info *info)
49fa1e15 3248{
49fa1e15 3249 bfd *ibfd;
9dcc4794 3250 unsigned int depth;
49fa1e15
AM
3251
3252 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
3253 {
3254 extern const bfd_target bfd_elf32_spu_vec;
3255 asection *sec;
3256
3257 if (ibfd->xvec != &bfd_elf32_spu_vec)
3258 continue;
3259
3260 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
055ed83b
AM
3261 if (!mark_functions_via_relocs (sec, info, TRUE))
3262 return FALSE;
49fa1e15
AM
3263 }
3264
055ed83b
AM
3265 /* Transfer call info from hot/cold section part of function
3266 to main entry. */
64615358 3267 if (!spu_hash_table (info)->params->auto_overlay
9dcc4794 3268 && !for_each_node (transfer_calls, info, 0, FALSE))
055ed83b 3269 return FALSE;
49fa1e15 3270
055ed83b
AM
3271 /* Find the call graph root(s). */
3272 if (!for_each_node (mark_non_root, info, 0, FALSE))
3273 return FALSE;
49fa1e15
AM
3274
3275 /* Remove cycles from the call graph. We start from the root node(s)
3276 so that we break cycles in a reasonable place. */
9dcc4794 3277 depth = 0;
667f3338
AM
3278 if (!for_each_node (remove_cycles, info, &depth, TRUE))
3279 return FALSE;
3280
3281 return for_each_node (mark_detached_root, info, &depth, FALSE);
9dcc4794
AM
3282}
3283
cd4a7468 3284/* qsort predicate to sort calls by priority, max_depth then count. */
9dcc4794
AM
3285
3286static int
3287sort_calls (const void *a, const void *b)
3288{
3289 struct call_info *const *c1 = a;
3290 struct call_info *const *c2 = b;
3291 int delta;
3292
cd4a7468
AM
3293 delta = (*c2)->priority - (*c1)->priority;
3294 if (delta != 0)
3295 return delta;
3296
9dcc4794
AM
3297 delta = (*c2)->max_depth - (*c1)->max_depth;
3298 if (delta != 0)
3299 return delta;
3300
3301 delta = (*c2)->count - (*c1)->count;
3302 if (delta != 0)
3303 return delta;
3304
667f3338 3305 return (char *) c1 - (char *) c2;
9dcc4794
AM
3306}
3307
3308struct _mos_param {
3309 unsigned int max_overlay_size;
3310};
3311
3312/* Set linker_mark and gc_mark on any sections that we will put in
3313 overlays. These flags are used by the generic ELF linker, but we
3314 won't be continuing on to bfd_elf_final_link so it is OK to use
3315 them. linker_mark is clear before we get here. Set segment_mark
3316 on sections that are part of a pasted function (excluding the last
3317 section).
3318
3319 Set up function rodata section if --overlay-rodata. We don't
3320 currently include merged string constant rodata sections since
3321
3322 Sort the call graph so that the deepest nodes will be visited
3323 first. */
3324
3325static bfd_boolean
3326mark_overlay_section (struct function_info *fun,
3327 struct bfd_link_info *info,
3328 void *param)
3329{
3330 struct call_info *call;
3331 unsigned int count;
3332 struct _mos_param *mos_param = param;
fb266b8b 3333 struct spu_link_hash_table *htab = spu_hash_table (info);
9dcc4794
AM
3334
3335 if (fun->visit4)
3336 return TRUE;
3337
3338 fun->visit4 = TRUE;
fb266b8b
AM
3339 if (!fun->sec->linker_mark
3340 && (htab->params->ovly_flavour != ovly_soft_icache
3341 || htab->params->non_ia_text
3342 || strncmp (fun->sec->name, ".text.ia.", 9) == 0))
9dcc4794 3343 {
4f0d75be
AM
3344 unsigned int size;
3345
9dcc4794
AM
3346 fun->sec->linker_mark = 1;
3347 fun->sec->gc_mark = 1;
3348 fun->sec->segment_mark = 0;
3349 /* Ensure SEC_CODE is set on this text section (it ought to
3350 be!), and SEC_CODE is clear on rodata sections. We use
3351 this flag to differentiate the two overlay section types. */
3352 fun->sec->flags |= SEC_CODE;
4f0d75be 3353
fb266b8b
AM
3354 size = fun->sec->size;
3355 if (htab->params->auto_overlay & OVERLAY_RODATA)
9dcc4794
AM
3356 {
3357 char *name = NULL;
9dcc4794
AM
3358
3359 /* Find the rodata section corresponding to this function's
3360 text section. */
3361 if (strcmp (fun->sec->name, ".text") == 0)
3362 {
3363 name = bfd_malloc (sizeof (".rodata"));
3364 if (name == NULL)
3365 return FALSE;
3366 memcpy (name, ".rodata", sizeof (".rodata"));
3367 }
3368 else if (strncmp (fun->sec->name, ".text.", 6) == 0)
3369 {
3370 size_t len = strlen (fun->sec->name);
3371 name = bfd_malloc (len + 3);
3372 if (name == NULL)
3373 return FALSE;
3374 memcpy (name, ".rodata", sizeof (".rodata"));
3375 memcpy (name + 7, fun->sec->name + 5, len - 4);
3376 }
3377 else if (strncmp (fun->sec->name, ".gnu.linkonce.t.", 16) == 0)
3378 {
3379 size_t len = strlen (fun->sec->name) + 1;
3380 name = bfd_malloc (len);
3381 if (name == NULL)
3382 return FALSE;
3383 memcpy (name, fun->sec->name, len);
3384 name[14] = 'r';
3385 }
3386
3387 if (name != NULL)
3388 {
3389 asection *rodata = NULL;
3390 asection *group_sec = elf_section_data (fun->sec)->next_in_group;
3391 if (group_sec == NULL)
3392 rodata = bfd_get_section_by_name (fun->sec->owner, name);
3393 else
3394 while (group_sec != NULL && group_sec != fun->sec)
3395 {
3396 if (strcmp (group_sec->name, name) == 0)
3397 {
3398 rodata = group_sec;
3399 break;
3400 }
3401 group_sec = elf_section_data (group_sec)->next_in_group;
3402 }
3403 fun->rodata = rodata;
3404 if (fun->rodata)
3405 {
fb266b8b
AM
3406 size += fun->rodata->size;
3407 if (htab->params->line_size != 0
3408 && size > htab->params->line_size)
3409 {
3410 size -= fun->rodata->size;
3411 fun->rodata = NULL;
3412 }
3413 else
3414 {
3415 fun->rodata->linker_mark = 1;
3416 fun->rodata->gc_mark = 1;
3417 fun->rodata->flags &= ~SEC_CODE;
3418 }
9dcc4794
AM
3419 }
3420 free (name);
3421 }
9dcc4794 3422 }
4f0d75be
AM
3423 if (mos_param->max_overlay_size < size)
3424 mos_param->max_overlay_size = size;
9dcc4794
AM
3425 }
3426
3427 for (count = 0, call = fun->call_list; call != NULL; call = call->next)
3428 count += 1;
3429
3430 if (count > 1)
3431 {
3432 struct call_info **calls = bfd_malloc (count * sizeof (*calls));
3433 if (calls == NULL)
3434 return FALSE;
3435
3436 for (count = 0, call = fun->call_list; call != NULL; call = call->next)
3437 calls[count++] = call;
3438
3439 qsort (calls, count, sizeof (*calls), sort_calls);
3440
3441 fun->call_list = NULL;
3442 while (count != 0)
3443 {
3444 --count;
3445 calls[count]->next = fun->call_list;
3446 fun->call_list = calls[count];
3447 }
3448 free (calls);
3449 }
3450
3451 for (call = fun->call_list; call != NULL; call = call->next)
3452 {
3453 if (call->is_pasted)
3454 {
3455 /* There can only be one is_pasted call per function_info. */
3456 BFD_ASSERT (!fun->sec->segment_mark);
3457 fun->sec->segment_mark = 1;
3458 }
3459 if (!mark_overlay_section (call->fun, info, param))
3460 return FALSE;
3461 }
3462
3463 /* Don't put entry code into an overlay. The overlay manager needs
cd4a7468 3464 a stack! Also, don't mark .ovl.init as an overlay. */
9dcc4794 3465 if (fun->lo + fun->sec->output_offset + fun->sec->output_section->vma
cd4a7468
AM
3466 == info->output_bfd->start_address
3467 || strncmp (fun->sec->output_section->name, ".ovl.init", 9) == 0)
9dcc4794
AM
3468 {
3469 fun->sec->linker_mark = 0;
3470 if (fun->rodata != NULL)
3471 fun->rodata->linker_mark = 0;
3472 }
3473 return TRUE;
3474}
3475
99302af9
AM
3476/* If non-zero then unmark functions called from those within sections
3477 that we need to unmark. Unfortunately this isn't reliable since the
3478 call graph cannot know the destination of function pointer calls. */
3479#define RECURSE_UNMARK 0
3480
9dcc4794
AM
3481struct _uos_param {
3482 asection *exclude_input_section;
3483 asection *exclude_output_section;
3484 unsigned long clearing;
3485};
3486
3487/* Undo some of mark_overlay_section's work. */
3488
3489static bfd_boolean
3490unmark_overlay_section (struct function_info *fun,
3491 struct bfd_link_info *info,
3492 void *param)
3493{
3494 struct call_info *call;
3495 struct _uos_param *uos_param = param;
3496 unsigned int excluded = 0;
3497
3498 if (fun->visit5)
3499 return TRUE;
3500
3501 fun->visit5 = TRUE;
3502
3503 excluded = 0;
3504 if (fun->sec == uos_param->exclude_input_section
3505 || fun->sec->output_section == uos_param->exclude_output_section)
3506 excluded = 1;
3507
99302af9
AM
3508 if (RECURSE_UNMARK)
3509 uos_param->clearing += excluded;
9dcc4794 3510
99302af9 3511 if (RECURSE_UNMARK ? uos_param->clearing : excluded)
9dcc4794
AM
3512 {
3513 fun->sec->linker_mark = 0;
3514 if (fun->rodata)
3515 fun->rodata->linker_mark = 0;
3516 }
3517
3518 for (call = fun->call_list; call != NULL; call = call->next)
3519 if (!unmark_overlay_section (call->fun, info, param))
3520 return FALSE;
3521
99302af9
AM
3522 if (RECURSE_UNMARK)
3523 uos_param->clearing -= excluded;
9dcc4794
AM
3524 return TRUE;
3525}
3526
3527struct _cl_param {
3528 unsigned int lib_size;
3529 asection **lib_sections;
3530};
3531
3532/* Add sections we have marked as belonging to overlays to an array
3533 for consideration as non-overlay sections. The array consist of
3534 pairs of sections, (text,rodata), for functions in the call graph. */
3535
3536static bfd_boolean
3537collect_lib_sections (struct function_info *fun,
3538 struct bfd_link_info *info,
3539 void *param)
3540{
3541 struct _cl_param *lib_param = param;
3542 struct call_info *call;
3543 unsigned int size;
3544
3545 if (fun->visit6)
3546 return TRUE;
3547
3548 fun->visit6 = TRUE;
3549 if (!fun->sec->linker_mark || !fun->sec->gc_mark || fun->sec->segment_mark)
3550 return TRUE;
3551
3552 size = fun->sec->size;
3553 if (fun->rodata)
3554 size += fun->rodata->size;
cd4a7468 3555
b0c41709 3556 if (size <= lib_param->lib_size)
9dcc4794 3557 {
b0c41709
AM
3558 *lib_param->lib_sections++ = fun->sec;
3559 fun->sec->gc_mark = 0;
3560 if (fun->rodata && fun->rodata->linker_mark && fun->rodata->gc_mark)
3561 {
3562 *lib_param->lib_sections++ = fun->rodata;
3563 fun->rodata->gc_mark = 0;
3564 }
3565 else
3566 *lib_param->lib_sections++ = NULL;
9dcc4794 3567 }
9dcc4794
AM
3568
3569 for (call = fun->call_list; call != NULL; call = call->next)
3570 collect_lib_sections (call->fun, info, param);
3571
3572 return TRUE;
3573}
3574
3575/* qsort predicate to sort sections by call count. */
3576
3577static int
3578sort_lib (const void *a, const void *b)
3579{
3580 asection *const *s1 = a;
3581 asection *const *s2 = b;
3582 struct _spu_elf_section_data *sec_data;
3583 struct spu_elf_stack_info *sinfo;
3584 int delta;
3585
3586 delta = 0;
3587 if ((sec_data = spu_elf_section_data (*s1)) != NULL
3588 && (sinfo = sec_data->u.i.stack_info) != NULL)
3589 {
3590 int i;
3591 for (i = 0; i < sinfo->num_fun; ++i)
3592 delta -= sinfo->fun[i].call_count;
3593 }
3594
3595 if ((sec_data = spu_elf_section_data (*s2)) != NULL
3596 && (sinfo = sec_data->u.i.stack_info) != NULL)
3597 {
3598 int i;
3599 for (i = 0; i < sinfo->num_fun; ++i)
3600 delta += sinfo->fun[i].call_count;
3601 }
3602
3603 if (delta != 0)
3604 return delta;
3605
3606 return s1 - s2;
3607}
3608
3609/* Remove some sections from those marked to be in overlays. Choose
3610 those that are called from many places, likely library functions. */
3611
3612static unsigned int
3613auto_ovl_lib_functions (struct bfd_link_info *info, unsigned int lib_size)
3614{
3615 bfd *ibfd;
3616 asection **lib_sections;
3617 unsigned int i, lib_count;
3618 struct _cl_param collect_lib_param;
3619 struct function_info dummy_caller;
64615358 3620 struct spu_link_hash_table *htab;
9dcc4794
AM
3621
3622 memset (&dummy_caller, 0, sizeof (dummy_caller));
3623 lib_count = 0;
3624 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
3625 {
3626 extern const bfd_target bfd_elf32_spu_vec;
3627 asection *sec;
3628
3629 if (ibfd->xvec != &bfd_elf32_spu_vec)
3630 continue;
3631
3632 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
3633 if (sec->linker_mark
3634 && sec->size < lib_size
3635 && (sec->flags & SEC_CODE) != 0)
3636 lib_count += 1;
3637 }
3638 lib_sections = bfd_malloc (lib_count * 2 * sizeof (*lib_sections));
3639 if (lib_sections == NULL)
3640 return (unsigned int) -1;
3641 collect_lib_param.lib_size = lib_size;
3642 collect_lib_param.lib_sections = lib_sections;
3643 if (!for_each_node (collect_lib_sections, info, &collect_lib_param,
3644 TRUE))
3645 return (unsigned int) -1;
3646 lib_count = (collect_lib_param.lib_sections - lib_sections) / 2;
3647
3648 /* Sort sections so that those with the most calls are first. */
3649 if (lib_count > 1)
3650 qsort (lib_sections, lib_count, 2 * sizeof (*lib_sections), sort_lib);
3651
64615358 3652 htab = spu_hash_table (info);
9dcc4794
AM
3653 for (i = 0; i < lib_count; i++)
3654 {
3655 unsigned int tmp, stub_size;
3656 asection *sec;
3657 struct _spu_elf_section_data *sec_data;
3658 struct spu_elf_stack_info *sinfo;
3659
3660 sec = lib_sections[2 * i];
3661 /* If this section is OK, its size must be less than lib_size. */
3662 tmp = sec->size;
3663 /* If it has a rodata section, then add that too. */
3664 if (lib_sections[2 * i + 1])
3665 tmp += lib_sections[2 * i + 1]->size;
3666 /* Add any new overlay call stubs needed by the section. */
3667 stub_size = 0;
3668 if (tmp < lib_size
3669 && (sec_data = spu_elf_section_data (sec)) != NULL
3670 && (sinfo = sec_data->u.i.stack_info) != NULL)
3671 {
3672 int k;
3673 struct call_info *call;
3674
3675 for (k = 0; k < sinfo->num_fun; ++k)
3676 for (call = sinfo->fun[k].call_list; call; call = call->next)
3677 if (call->fun->sec->linker_mark)
3678 {
3679 struct call_info *p;
3680 for (p = dummy_caller.call_list; p; p = p->next)
3681 if (p->fun == call->fun)
3682 break;
3683 if (!p)
a7e11ee1 3684 stub_size += ovl_stub_size (htab->params);
9dcc4794
AM
3685 }
3686 }
3687 if (tmp + stub_size < lib_size)
3688 {
3689 struct call_info **pp, *p;
3690
3691 /* This section fits. Mark it as non-overlay. */
3692 lib_sections[2 * i]->linker_mark = 0;
3693 if (lib_sections[2 * i + 1])
3694 lib_sections[2 * i + 1]->linker_mark = 0;
3695 lib_size -= tmp + stub_size;
3696 /* Call stubs to the section we just added are no longer
3697 needed. */
3698 pp = &dummy_caller.call_list;
3699 while ((p = *pp) != NULL)
3700 if (!p->fun->sec->linker_mark)
3701 {
a7e11ee1 3702 lib_size += ovl_stub_size (htab->params);
9dcc4794
AM
3703 *pp = p->next;
3704 free (p);
3705 }
3706 else
3707 pp = &p->next;
3708 /* Add new call stubs to dummy_caller. */
3709 if ((sec_data = spu_elf_section_data (sec)) != NULL
3710 && (sinfo = sec_data->u.i.stack_info) != NULL)
3711 {
3712 int k;
3713 struct call_info *call;
3714
3715 for (k = 0; k < sinfo->num_fun; ++k)
3716 for (call = sinfo->fun[k].call_list;
3717 call;
3718 call = call->next)
3719 if (call->fun->sec->linker_mark)
3720 {
3721 struct call_info *callee;
3722 callee = bfd_malloc (sizeof (*callee));
3723 if (callee == NULL)
3724 return (unsigned int) -1;
3725 *callee = *call;
3726 if (!insert_callee (&dummy_caller, callee))
3727 free (callee);
3728 }
3729 }
3730 }
3731 }
3732 while (dummy_caller.call_list != NULL)
3733 {
3734 struct call_info *call = dummy_caller.call_list;
3735 dummy_caller.call_list = call->next;
3736 free (call);
3737 }
3738 for (i = 0; i < 2 * lib_count; i++)
3739 if (lib_sections[i])
3740 lib_sections[i]->gc_mark = 1;
3741 free (lib_sections);
3742 return lib_size;
3743}
3744
3745/* Build an array of overlay sections. The deepest node's section is
2ec9638b 3746 added first, then its parent node's section, then everything called
9dcc4794
AM
3747 from the parent section. The idea being to group sections to
3748 minimise calls between different overlays. */
3749
3750static bfd_boolean
3751collect_overlays (struct function_info *fun,
3752 struct bfd_link_info *info,
3753 void *param)
3754{
3755 struct call_info *call;
3756 bfd_boolean added_fun;
3757 asection ***ovly_sections = param;
3758
3759 if (fun->visit7)
3760 return TRUE;
3761
3762 fun->visit7 = TRUE;
3763 for (call = fun->call_list; call != NULL; call = call->next)
3764 if (!call->is_pasted)
3765 {
3766 if (!collect_overlays (call->fun, info, ovly_sections))
3767 return FALSE;
3768 break;
3769 }
3770
3771 added_fun = FALSE;
3772 if (fun->sec->linker_mark && fun->sec->gc_mark)
3773 {
3774 fun->sec->gc_mark = 0;
3775 *(*ovly_sections)++ = fun->sec;
3776 if (fun->rodata && fun->rodata->linker_mark && fun->rodata->gc_mark)
3777 {
3778 fun->rodata->gc_mark = 0;
3779 *(*ovly_sections)++ = fun->rodata;
3780 }
3781 else
3782 *(*ovly_sections)++ = NULL;
3783 added_fun = TRUE;
3784
3785 /* Pasted sections must stay with the first section. We don't
3786 put pasted sections in the array, just the first section.
3787 Mark subsequent sections as already considered. */
3788 if (fun->sec->segment_mark)
3789 {
3790 struct function_info *call_fun = fun;
3791 do
3792 {
3793 for (call = call_fun->call_list; call != NULL; call = call->next)
3794 if (call->is_pasted)
3795 {
3796 call_fun = call->fun;
3797 call_fun->sec->gc_mark = 0;
3798 if (call_fun->rodata)
3799 call_fun->rodata->gc_mark = 0;
3800 break;
3801 }
3802 if (call == NULL)
3803 abort ();
3804 }
3805 while (call_fun->sec->segment_mark);
3806 }
3807 }
3808
3809 for (call = fun->call_list; call != NULL; call = call->next)
3810 if (!collect_overlays (call->fun, info, ovly_sections))
3811 return FALSE;
3812
3813 if (added_fun)
3814 {
3815 struct _spu_elf_section_data *sec_data;
3816 struct spu_elf_stack_info *sinfo;
3817
3818 if ((sec_data = spu_elf_section_data (fun->sec)) != NULL
3819 && (sinfo = sec_data->u.i.stack_info) != NULL)
3820 {
3821 int i;
3822 for (i = 0; i < sinfo->num_fun; ++i)
3823 if (!collect_overlays (&sinfo->fun[i], info, ovly_sections))
3824 return FALSE;
3825 }
3826 }
3827
3828 return TRUE;
49fa1e15
AM
3829}
3830
055ed83b
AM
3831struct _sum_stack_param {
3832 size_t cum_stack;
3833 size_t overall_stack;
3834 bfd_boolean emit_stack_syms;
3835};
3836
49fa1e15
AM
3837/* Descend the call graph for FUN, accumulating total stack required. */
3838
055ed83b 3839static bfd_boolean
49fa1e15
AM
3840sum_stack (struct function_info *fun,
3841 struct bfd_link_info *info,
055ed83b 3842 void *param)
49fa1e15
AM
3843{
3844 struct call_info *call;
055ed83b
AM
3845 struct function_info *max;
3846 size_t stack, cum_stack;
49fa1e15 3847 const char *f1;
9dcc4794 3848 bfd_boolean has_call;
055ed83b 3849 struct _sum_stack_param *sum_stack_param = param;
9dcc4794 3850 struct spu_link_hash_table *htab;
49fa1e15 3851
055ed83b
AM
3852 cum_stack = fun->stack;
3853 sum_stack_param->cum_stack = cum_stack;
49fa1e15 3854 if (fun->visit3)
055ed83b 3855 return TRUE;
49fa1e15 3856
9dcc4794 3857 has_call = FALSE;
055ed83b 3858 max = NULL;
49fa1e15
AM
3859 for (call = fun->call_list; call; call = call->next)
3860 {
9dcc4794
AM
3861 if (!call->is_pasted)
3862 has_call = TRUE;
055ed83b
AM
3863 if (!sum_stack (call->fun, info, sum_stack_param))
3864 return FALSE;
3865 stack = sum_stack_param->cum_stack;
49fa1e15
AM
3866 /* Include caller stack for normal calls, don't do so for
3867 tail calls. fun->stack here is local stack usage for
3868 this function. */
9dcc4794 3869 if (!call->is_tail || call->is_pasted || call->fun->start != NULL)
49fa1e15 3870 stack += fun->stack;
055ed83b 3871 if (cum_stack < stack)
49fa1e15 3872 {
055ed83b 3873 cum_stack = stack;
49fa1e15
AM
3874 max = call->fun;
3875 }
3876 }
3877
055ed83b
AM
3878 sum_stack_param->cum_stack = cum_stack;
3879 stack = fun->stack;
3880 /* Now fun->stack holds cumulative stack. */
3881 fun->stack = cum_stack;
3882 fun->visit3 = TRUE;
3883
3884 if (!fun->non_root
3885 && sum_stack_param->overall_stack < cum_stack)
3886 sum_stack_param->overall_stack = cum_stack;
3887
9dcc4794 3888 htab = spu_hash_table (info);
64615358 3889 if (htab->params->auto_overlay)
9dcc4794
AM
3890 return TRUE;
3891
49fa1e15 3892 f1 = func_name (fun);
cd4a7468 3893 if (htab->params->stack_analysis)
49fa1e15 3894 {
cd4a7468
AM
3895 if (!fun->non_root)
3896 info->callbacks->info (_(" %s: 0x%v\n"), f1, (bfd_vma) cum_stack);
3897 info->callbacks->minfo (_("%s: 0x%v 0x%v\n"),
3898 f1, (bfd_vma) stack, (bfd_vma) cum_stack);
49fa1e15 3899
cd4a7468
AM
3900 if (has_call)
3901 {
3902 info->callbacks->minfo (_(" calls:\n"));
3903 for (call = fun->call_list; call; call = call->next)
3904 if (!call->is_pasted)
3905 {
3906 const char *f2 = func_name (call->fun);
3907 const char *ann1 = call->fun == max ? "*" : " ";
3908 const char *ann2 = call->is_tail ? "t" : " ";
3909
3910 info->callbacks->minfo (_(" %s%s %s\n"), ann1, ann2, f2);
3911 }
3912 }
49fa1e15
AM
3913 }
3914
055ed83b 3915 if (sum_stack_param->emit_stack_syms)
49fa1e15 3916 {
49fa1e15
AM
3917 char *name = bfd_malloc (18 + strlen (f1));
3918 struct elf_link_hash_entry *h;
3919
055ed83b
AM
3920 if (name == NULL)
3921 return FALSE;
3922
3923 if (fun->global || ELF_ST_BIND (fun->u.sym->st_info) == STB_GLOBAL)
3924 sprintf (name, "__stack_%s", f1);
3925 else
3926 sprintf (name, "__stack_%x_%s", fun->sec->id & 0xffffffff, f1);
3927
3928 h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
3929 free (name);
3930 if (h != NULL
3931 && (h->root.type == bfd_link_hash_new
3932 || h->root.type == bfd_link_hash_undefined
3933 || h->root.type == bfd_link_hash_undefweak))
49fa1e15 3934 {
055ed83b
AM
3935 h->root.type = bfd_link_hash_defined;
3936 h->root.u.def.section = bfd_abs_section_ptr;
3937 h->root.u.def.value = cum_stack;
3938 h->size = 0;
3939 h->type = 0;
3940 h->ref_regular = 1;
3941 h->def_regular = 1;
3942 h->ref_regular_nonweak = 1;
3943 h->forced_local = 1;
3944 h->non_elf = 0;
49fa1e15
AM
3945 }
3946 }
3947
055ed83b 3948 return TRUE;
49fa1e15
AM
3949}
3950
9dcc4794
AM
3951/* SEC is part of a pasted function. Return the call_info for the
3952 next section of this function. */
3953
3954static struct call_info *
3955find_pasted_call (asection *sec)
3956{
3957 struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
3958 struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
3959 struct call_info *call;
3960 int k;
3961
3962 for (k = 0; k < sinfo->num_fun; ++k)
3963 for (call = sinfo->fun[k].call_list; call != NULL; call = call->next)
3964 if (call->is_pasted)
3965 return call;
3966 abort ();
3967 return 0;
3968}
3969
3970/* qsort predicate to sort bfds by file name. */
3971
3972static int
3973sort_bfds (const void *a, const void *b)
3974{
3975 bfd *const *abfd1 = a;
3976 bfd *const *abfd2 = b;
3977
3978 return strcmp ((*abfd1)->filename, (*abfd2)->filename);
3979}
3980
cd4a7468
AM
3981static unsigned int
3982print_one_overlay_section (FILE *script,
3983 unsigned int base,
3984 unsigned int count,
3985 unsigned int ovlynum,
3986 unsigned int *ovly_map,
3987 asection **ovly_sections,
3988 struct bfd_link_info *info)
3989{
3990 unsigned int j;
3991
3992 for (j = base; j < count && ovly_map[j] == ovlynum; j++)
3993 {
3994 asection *sec = ovly_sections[2 * j];
3995
3996 if (fprintf (script, " %s%c%s (%s)\n",
3997 (sec->owner->my_archive != NULL
3998 ? sec->owner->my_archive->filename : ""),
3999 info->path_separator,
4000 sec->owner->filename,
4001 sec->name) <= 0)
4002 return -1;
4003 if (sec->segment_mark)
4004 {
4005 struct call_info *call = find_pasted_call (sec);
4006 while (call != NULL)
4007 {
4008 struct function_info *call_fun = call->fun;
4009 sec = call_fun->sec;
4010 if (fprintf (script, " %s%c%s (%s)\n",
4011 (sec->owner->my_archive != NULL
4012 ? sec->owner->my_archive->filename : ""),
4013 info->path_separator,
4014 sec->owner->filename,
4015 sec->name) <= 0)
4016 return -1;
4017 for (call = call_fun->call_list; call; call = call->next)
4018 if (call->is_pasted)
4019 break;
4020 }
4021 }
4022 }
4023
4024 for (j = base; j < count && ovly_map[j] == ovlynum; j++)
4025 {
4026 asection *sec = ovly_sections[2 * j + 1];
4027 if (sec != NULL
4028 && fprintf (script, " %s%c%s (%s)\n",
4029 (sec->owner->my_archive != NULL
4030 ? sec->owner->my_archive->filename : ""),
4031 info->path_separator,
4032 sec->owner->filename,
4033 sec->name) <= 0)
4034 return -1;
4035
4036 sec = ovly_sections[2 * j];
4037 if (sec->segment_mark)
4038 {
4039 struct call_info *call = find_pasted_call (sec);
4040 while (call != NULL)
4041 {
4042 struct function_info *call_fun = call->fun;
4043 sec = call_fun->rodata;
4044 if (sec != NULL
4045 && fprintf (script, " %s%c%s (%s)\n",
4046 (sec->owner->my_archive != NULL
4047 ? sec->owner->my_archive->filename : ""),
4048 info->path_separator,
4049 sec->owner->filename,
4050 sec->name) <= 0)
4051 return -1;
4052 for (call = call_fun->call_list; call; call = call->next)
4053 if (call->is_pasted)
4054 break;
4055 }
4056 }
4057 }
4058
4059 return j;
4060}
4061
9dcc4794
AM
4062/* Handle --auto-overlay. */
4063
9dcc4794 4064static void
64615358 4065spu_elf_auto_overlay (struct bfd_link_info *info)
9dcc4794
AM
4066{
4067 bfd *ibfd;
4068 bfd **bfd_arr;
4069 struct elf_segment_map *m;
4070 unsigned int fixed_size, lo, hi;
4071 struct spu_link_hash_table *htab;
4072 unsigned int base, i, count, bfd_count;
a3a219a9 4073 unsigned int region, ovlynum;
9dcc4794 4074 asection **ovly_sections, **ovly_p;
a3a219a9 4075 unsigned int *ovly_map;
9dcc4794
AM
4076 FILE *script;
4077 unsigned int total_overlay_size, overlay_size;
cd4a7468 4078 const char *ovly_mgr_entry;
9dcc4794
AM
4079 struct elf_link_hash_entry *h;
4080 struct _mos_param mos_param;
4081 struct _uos_param uos_param;
4082 struct function_info dummy_caller;
4083
4084 /* Find the extents of our loadable image. */
4085 lo = (unsigned int) -1;
4086 hi = 0;
4087 for (m = elf_tdata (info->output_bfd)->segment_map; m != NULL; m = m->next)
4088 if (m->p_type == PT_LOAD)
4089 for (i = 0; i < m->count; i++)
4090 if (m->sections[i]->size != 0)
4091 {
4092 if (m->sections[i]->vma < lo)
4093 lo = m->sections[i]->vma;
4094 if (m->sections[i]->vma + m->sections[i]->size - 1 > hi)
4095 hi = m->sections[i]->vma + m->sections[i]->size - 1;
4096 }
4097 fixed_size = hi + 1 - lo;
4098
4099 if (!discover_functions (info))
4100 goto err_exit;
4101
4102 if (!build_call_tree (info))
4103 goto err_exit;
4104
a14c90c1
UW
4105 htab = spu_hash_table (info);
4106 if (htab->reserved == 0)
4107 {
4108 struct _sum_stack_param sum_stack_param;
4109
4110 sum_stack_param.emit_stack_syms = 0;
4111 sum_stack_param.overall_stack = 0;
4112 if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE))
4113 goto err_exit;
4114 htab->reserved = sum_stack_param.overall_stack + htab->extra_stack_space;
4115 }
4116
4117 /* No need for overlays if everything already fits. */
4118 if (fixed_size + htab->reserved <= htab->local_store
4119 && htab->params->ovly_flavour != ovly_soft_icache)
4120 {
4121 htab->params->auto_overlay = 0;
4122 return;
4123 }
4124
9dcc4794
AM
4125 uos_param.exclude_input_section = 0;
4126 uos_param.exclude_output_section
4127 = bfd_get_section_by_name (info->output_bfd, ".interrupt");
4128
cd4a7468
AM
4129 ovly_mgr_entry = "__ovly_load";
4130 if (htab->params->ovly_flavour == ovly_soft_icache)
4131 ovly_mgr_entry = "__icache_br_handler";
4132 h = elf_link_hash_lookup (&htab->elf, ovly_mgr_entry,
9dcc4794
AM
4133 FALSE, FALSE, FALSE);
4134 if (h != NULL
4135 && (h->root.type == bfd_link_hash_defined
4136 || h->root.type == bfd_link_hash_defweak)
4137 && h->def_regular)
4138 {
4139 /* We have a user supplied overlay manager. */
4140 uos_param.exclude_input_section = h->root.u.def.section;
4141 }
4142 else
4143 {
4144 /* If no user overlay manager, spu_elf_load_ovl_mgr will add our
4145 builtin version to .text, and will adjust .text size. */
64615358 4146 fixed_size += (*htab->params->spu_elf_load_ovl_mgr) ();
9dcc4794
AM
4147 }
4148
4149 /* Mark overlay sections, and find max overlay section size. */
4150 mos_param.max_overlay_size = 0;
4151 if (!for_each_node (mark_overlay_section, info, &mos_param, TRUE))
4152 goto err_exit;
4153
4154 /* We can't put the overlay manager or interrupt routines in
4155 overlays. */
4156 uos_param.clearing = 0;
4157 if ((uos_param.exclude_input_section
4158 || uos_param.exclude_output_section)
4159 && !for_each_node (unmark_overlay_section, info, &uos_param, TRUE))
4160 goto err_exit;
4161
4162 bfd_count = 0;
4163 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
4164 ++bfd_count;
4165 bfd_arr = bfd_malloc (bfd_count * sizeof (*bfd_arr));
4166 if (bfd_arr == NULL)
4167 goto err_exit;
4168
4169 /* Count overlay sections, and subtract their sizes from "fixed_size". */
4170 count = 0;
4171 bfd_count = 0;
4172 total_overlay_size = 0;
4173 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
4174 {
4175 extern const bfd_target bfd_elf32_spu_vec;
4176 asection *sec;
4177 unsigned int old_count;
4178
4179 if (ibfd->xvec != &bfd_elf32_spu_vec)
4180 continue;
4181
4182 old_count = count;
4183 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
4184 if (sec->linker_mark)
4185 {
4186 if ((sec->flags & SEC_CODE) != 0)
4187 count += 1;
4188 fixed_size -= sec->size;
4189 total_overlay_size += sec->size;
4190 }
cd4a7468
AM
4191 else if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)
4192 && sec->output_section->owner == info->output_bfd
4193 && strncmp (sec->output_section->name, ".ovl.init", 9) == 0)
4194 fixed_size -= sec->size;
9dcc4794
AM
4195 if (count != old_count)
4196 bfd_arr[bfd_count++] = ibfd;
4197 }
4198
4199 /* Since the overlay link script selects sections by file name and
4200 section name, ensure that file names are unique. */
4201 if (bfd_count > 1)
4202 {
4203 bfd_boolean ok = TRUE;
4204
4205 qsort (bfd_arr, bfd_count, sizeof (*bfd_arr), sort_bfds);
4206 for (i = 1; i < bfd_count; ++i)
4207 if (strcmp (bfd_arr[i - 1]->filename, bfd_arr[i]->filename) == 0)
4208 {
97407faf 4209 if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
9dcc4794 4210 {
97407faf 4211 if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
9dcc4794 4212 info->callbacks->einfo (_("%s duplicated in %s\n"),
97407faf 4213 bfd_arr[i]->filename,
9dcc4794 4214 bfd_arr[i]->my_archive->filename);
97407faf
AM
4215 else
4216 info->callbacks->einfo (_("%s duplicated\n"),
4217 bfd_arr[i]->filename);
4218 ok = FALSE;
9dcc4794 4219 }
9dcc4794
AM
4220 }
4221 if (!ok)
4222 {
9dcc4794
AM
4223 info->callbacks->einfo (_("sorry, no support for duplicate "
4224 "object files in auto-overlay script\n"));
4225 bfd_set_error (bfd_error_bad_value);
4226 goto err_exit;
4227 }
4228 }
4229 free (bfd_arr);
4230
9dcc4794 4231 fixed_size += htab->reserved;
a7e11ee1 4232 fixed_size += htab->non_ovly_stub * ovl_stub_size (htab->params);
9dcc4794
AM
4233 if (fixed_size + mos_param.max_overlay_size <= htab->local_store)
4234 {
cd4a7468
AM
4235 if (htab->params->ovly_flavour == ovly_soft_icache)
4236 {
4237 /* Stubs in the non-icache area are bigger. */
4238 fixed_size += htab->non_ovly_stub * 16;
4239 /* Space for icache manager tables.
4240 a) Tag array, one quadword per cache line.
4241 - word 0: ia address of present line, init to zero.
4242 - word 1: link locator. link_elem=stub_addr/2+locator
4243 - halfwords 4-7: head/tail pointers for linked lists. */
4244 fixed_size += 16 << htab->num_lines_log2;
4245 /* b) Linked list elements, max_branch per line. */
4246 fixed_size += htab->params->max_branch << (htab->num_lines_log2 + 4);
4247 /* c) Indirect branch descriptors, 8 quadwords. */
4248 fixed_size += 8 * 16;
4249 /* d) Pointers to __ea backing store, 16 quadwords. */
4250 fixed_size += 16 * 16;
4251 }
4252 else
4253 {
4254 /* Guess number of overlays. Assuming overlay buffer is on
4255 average only half full should be conservative. */
4256 ovlynum = (total_overlay_size * 2 * htab->params->num_lines
4257 / (htab->local_store - fixed_size));
4258 /* Space for _ovly_table[], _ovly_buf_table[] and toe. */
4259 fixed_size += ovlynum * 16 + 16 + 4 + 16;
4260 }
9dcc4794
AM
4261 }
4262
4263 if (fixed_size + mos_param.max_overlay_size > htab->local_store)
4f0d75be
AM
4264 info->callbacks->einfo (_("non-overlay size of 0x%v plus maximum overlay "
4265 "size of 0x%v exceeds local store\n"),
4266 (bfd_vma) fixed_size,
4267 (bfd_vma) mos_param.max_overlay_size);
9dcc4794
AM
4268
4269 /* Now see if we should put some functions in the non-overlay area. */
e5e6a5ff 4270 else if (fixed_size < htab->overlay_fixed)
9dcc4794 4271 {
e5e6a5ff
AM
4272 unsigned int max_fixed, lib_size;
4273
4274 max_fixed = htab->local_store - mos_param.max_overlay_size;
4275 if (max_fixed > htab->overlay_fixed)
4276 max_fixed = htab->overlay_fixed;
4277 lib_size = max_fixed - fixed_size;
9dcc4794
AM
4278 lib_size = auto_ovl_lib_functions (info, lib_size);
4279 if (lib_size == (unsigned int) -1)
4280 goto err_exit;
e5e6a5ff 4281 fixed_size = max_fixed - lib_size;
9dcc4794
AM
4282 }
4283
4284 /* Build an array of sections, suitably sorted to place into
4285 overlays. */
4286 ovly_sections = bfd_malloc (2 * count * sizeof (*ovly_sections));
4287 if (ovly_sections == NULL)
4288 goto err_exit;
4289 ovly_p = ovly_sections;
4290 if (!for_each_node (collect_overlays, info, &ovly_p, TRUE))
4291 goto err_exit;
4292 count = (size_t) (ovly_p - ovly_sections) / 2;
a3a219a9
AM
4293 ovly_map = bfd_malloc (count * sizeof (*ovly_map));
4294 if (ovly_map == NULL)
4295 goto err_exit;
9dcc4794
AM
4296
4297 memset (&dummy_caller, 0, sizeof (dummy_caller));
cd4a7468
AM
4298 overlay_size = (htab->local_store - fixed_size) / htab->params->num_lines;
4299 if (htab->params->line_size != 0)
4300 overlay_size = htab->params->line_size;
9dcc4794
AM
4301 base = 0;
4302 ovlynum = 0;
4303 while (base < count)
4304 {
4305 unsigned int size = 0;
9dcc4794
AM
4306
4307 for (i = base; i < count; i++)
4308 {
4309 asection *sec;
4310 unsigned int tmp;
64615358 4311 unsigned int num_stubs;
9dcc4794
AM
4312 struct call_info *call, *pasty;
4313 struct _spu_elf_section_data *sec_data;
4314 struct spu_elf_stack_info *sinfo;
4315 int k;
4316
4317 /* See whether we can add this section to the current
4318 overlay without overflowing our overlay buffer. */
4319 sec = ovly_sections[2 * i];
4320 tmp = size + sec->size;
4321 if (ovly_sections[2 * i + 1])
4322 tmp += ovly_sections[2 * i + 1]->size;
4323 if (tmp > overlay_size)
4324 break;
4325 if (sec->segment_mark)
4326 {
4327 /* Pasted sections must stay together, so add their
4328 sizes too. */
4329 struct call_info *pasty = find_pasted_call (sec);
4330 while (pasty != NULL)
4331 {
4332 struct function_info *call_fun = pasty->fun;
4333 tmp += call_fun->sec->size;
4334 if (call_fun->rodata)
4335 tmp += call_fun->rodata->size;
4336 for (pasty = call_fun->call_list; pasty; pasty = pasty->next)
4337 if (pasty->is_pasted)
4338 break;
4339 }
4340 }
4341 if (tmp > overlay_size)
4342 break;
4343
4344 /* If we add this section, we might need new overlay call
4345 stubs. Add any overlay section calls to dummy_call. */
4346 pasty = NULL;
4347 sec_data = spu_elf_section_data (sec);
4348 sinfo = sec_data->u.i.stack_info;
4349 for (k = 0; k < sinfo->num_fun; ++k)
4350 for (call = sinfo->fun[k].call_list; call; call = call->next)
4351 if (call->is_pasted)
4352 {
4353 BFD_ASSERT (pasty == NULL);
4354 pasty = call;
4355 }
4356 else if (call->fun->sec->linker_mark)
4357 {
4358 if (!copy_callee (&dummy_caller, call))
4359 goto err_exit;
4360 }
4361 while (pasty != NULL)
4362 {
4363 struct function_info *call_fun = pasty->fun;
4364 pasty = NULL;
4365 for (call = call_fun->call_list; call; call = call->next)
4366 if (call->is_pasted)
4367 {
4368 BFD_ASSERT (pasty == NULL);
4369 pasty = call;
4370 }
4371 else if (!copy_callee (&dummy_caller, call))
4372 goto err_exit;
4373 }
4374
4375 /* Calculate call stub size. */
64615358 4376 num_stubs = 0;
9dcc4794
AM
4377 for (call = dummy_caller.call_list; call; call = call->next)
4378 {
4379 unsigned int k;
4380
64615358 4381 ++num_stubs;
9dcc4794
AM
4382 /* If the call is within this overlay, we won't need a
4383 stub. */
4384 for (k = base; k < i + 1; k++)
4385 if (call->fun->sec == ovly_sections[2 * k])
4386 {
64615358 4387 --num_stubs;
9dcc4794
AM
4388 break;
4389 }
4390 }
cd4a7468
AM
4391 if (htab->params->ovly_flavour == ovly_soft_icache
4392 && num_stubs > htab->params->max_branch)
4393 break;
a7e11ee1 4394 if (tmp + num_stubs * ovl_stub_size (htab->params)
64615358 4395 > overlay_size)
9dcc4794 4396 break;
9dcc4794
AM
4397 size = tmp;
4398 }
4399
4400 if (i == base)
4401 {
4402 info->callbacks->einfo (_("%B:%A%s exceeds overlay size\n"),
4403 ovly_sections[2 * i]->owner,
4404 ovly_sections[2 * i],
4405 ovly_sections[2 * i + 1] ? " + rodata" : "");
4406 bfd_set_error (bfd_error_bad_value);
4407 goto err_exit;
4408 }
4409
a3a219a9
AM
4410 while (dummy_caller.call_list != NULL)
4411 {
4412 struct call_info *call = dummy_caller.call_list;
4413 dummy_caller.call_list = call->next;
4414 free (call);
4415 }
4416
4417 ++ovlynum;
4418 while (base < i)
4419 ovly_map[base++] = ovlynum;
4420 }
4421
4422 script = htab->params->spu_elf_open_overlay_script ();
4423
4424 if (fprintf (script, "SECTIONS\n{\n") <= 0)
4425 goto file_err;
4426
cd4a7468 4427 if (htab->params->ovly_flavour == ovly_soft_icache)
a3a219a9 4428 {
cd4a7468
AM
4429 if (fprintf (script,
4430 " .data.icache ALIGN (16) : { *(.ovtab) *(.data.icache) }\n"
4431 " . = ALIGN (%u);\n"
4432 " .ovl.init : { *(.ovl.init) }\n"
4433 " . = ABSOLUTE (ADDR (.ovl.init));\n",
4434 htab->params->line_size) <= 0)
4435 goto file_err;
4436
a3a219a9 4437 base = 0;
cd4a7468
AM
4438 ovlynum = 1;
4439 while (base < count)
4440 {
4441 unsigned int indx = ovlynum - 1;
4442 unsigned int vma, lma;
a3a219a9 4443
37107878 4444 vma = (indx & (htab->params->num_lines - 1)) << htab->line_size_log2;
cd4a7468
AM
4445 lma = indx << htab->line_size_log2;
4446
4447 if (fprintf (script, " .ovly%u ABSOLUTE (ADDR (.ovl.init)) + %u "
4448 ": AT (ALIGN (LOADADDR (.ovl.init) + SIZEOF (.ovl.init), 16) + %u) {\n",
4449 ovlynum, vma, lma) <= 0)
4450 goto file_err;
4451
4452 base = print_one_overlay_section (script, base, count, ovlynum,
4453 ovly_map, ovly_sections, info);
4454 if (base == (unsigned) -1)
4455 goto file_err;
4456
4457 if (fprintf (script, " }\n") <= 0)
4458 goto file_err;
4459
4460 ovlynum++;
4461 }
a3a219a9 4462
cd4a7468
AM
4463 if (fprintf (script, " . = ABSOLUTE (ADDR (.ovl.init)) + %u;\n",
4464 1 << (htab->num_lines_log2 + htab->line_size_log2)) <= 0)
4465 goto file_err;
4466 }
4467 else
4468 {
4469 if (fprintf (script,
4470 " . = ALIGN (16);\n"
4471 " .ovl.init : { *(.ovl.init) }\n"
4472 " . = ABSOLUTE (ADDR (.ovl.init));\n") <= 0)
9dcc4794 4473 goto file_err;
a3a219a9 4474
cd4a7468 4475 for (region = 1; region <= htab->params->num_lines; region++)
9dcc4794 4476 {
cd4a7468
AM
4477 ovlynum = region;
4478 base = 0;
4479 while (base < count && ovly_map[base] < ovlynum)
4480 base++;
a3a219a9 4481
cd4a7468
AM
4482 if (base == count)
4483 break;
a3a219a9 4484
cd4a7468
AM
4485 if (region == 1)
4486 {
4487 /* We need to set lma since we are overlaying .ovl.init. */
4488 if (fprintf (script,
4489 " OVERLAY : AT (ALIGN (LOADADDR (.ovl.init) + SIZEOF (.ovl.init), 16))\n {\n") <= 0)
4490 goto file_err;
4491 }
4492 else
4493 {
4494 if (fprintf (script, " OVERLAY :\n {\n") <= 0)
a3a219a9 4495 goto file_err;
9dcc4794 4496 }
9dcc4794 4497
cd4a7468 4498 while (base < count)
9dcc4794 4499 {
cd4a7468 4500 if (fprintf (script, " .ovly%u {\n", ovlynum) <= 0)
a3a219a9
AM
4501 goto file_err;
4502
cd4a7468
AM
4503 base = print_one_overlay_section (script, base, count, ovlynum,
4504 ovly_map, ovly_sections, info);
4505 if (base == (unsigned) -1)
4506 goto file_err;
4507
4508 if (fprintf (script, " }\n") <= 0)
4509 goto file_err;
4510
4511 ovlynum += htab->params->num_lines;
4512 while (base < count && ovly_map[base] < ovlynum)
4513 base++;
9dcc4794 4514 }
9dcc4794 4515
cd4a7468 4516 if (fprintf (script, " }\n") <= 0)
a3a219a9 4517 goto file_err;
9dcc4794
AM
4518 }
4519
9dcc4794 4520 }
a3a219a9
AM
4521
4522 free (ovly_map);
9dcc4794
AM
4523 free (ovly_sections);
4524
a3a219a9 4525 if (fprintf (script, "}\nINSERT BEFORE .text;\n") <= 0)
9dcc4794
AM
4526 goto file_err;
4527 if (fclose (script) != 0)
4528 goto file_err;
4529
64615358
AM
4530 if (htab->params->auto_overlay & AUTO_RELINK)
4531 (*htab->params->spu_elf_relink) ();
9dcc4794
AM
4532
4533 xexit (0);
4534
4535 file_err:
4536 bfd_set_error (bfd_error_system_call);
4537 err_exit:
4538 info->callbacks->einfo ("%F%P: auto overlay error: %E\n");
4539 xexit (1);
4540}
4541
49fa1e15
AM
4542/* Provide an estimate of total stack required. */
4543
4544static bfd_boolean
64615358 4545spu_elf_stack_analysis (struct bfd_link_info *info)
49fa1e15 4546{
64615358 4547 struct spu_link_hash_table *htab;
055ed83b 4548 struct _sum_stack_param sum_stack_param;
49fa1e15 4549
c65be8d7 4550 if (!discover_functions (info))
49fa1e15
AM
4551 return FALSE;
4552
c65be8d7 4553 if (!build_call_tree (info))
49fa1e15
AM
4554 return FALSE;
4555
64615358 4556 htab = spu_hash_table (info);
cd4a7468
AM
4557 if (htab->params->stack_analysis)
4558 {
4559 info->callbacks->info (_("Stack size for call graph root nodes.\n"));
4560 info->callbacks->minfo (_("\nStack size for functions. "
4561 "Annotations: '*' max stack, 't' tail call\n"));
4562 }
49fa1e15 4563
64615358 4564 sum_stack_param.emit_stack_syms = htab->params->emit_stack_syms;
055ed83b
AM
4565 sum_stack_param.overall_stack = 0;
4566 if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE))
4567 return FALSE;
49fa1e15 4568
cd4a7468
AM
4569 if (htab->params->stack_analysis)
4570 info->callbacks->info (_("Maximum stack required is 0x%v\n"),
4571 (bfd_vma) sum_stack_param.overall_stack);
49fa1e15
AM
4572 return TRUE;
4573}
4574
4575/* Perform a final link. */
4576
4577static bfd_boolean
4578spu_elf_final_link (bfd *output_bfd, struct bfd_link_info *info)
4579{
4580 struct spu_link_hash_table *htab = spu_hash_table (info);
4581
64615358
AM
4582 if (htab->params->auto_overlay)
4583 spu_elf_auto_overlay (info);
9dcc4794 4584
cd4a7468
AM
4585 if ((htab->params->stack_analysis
4586 || (htab->params->ovly_flavour == ovly_soft_icache
4587 && htab->params->lrlive_analysis))
64615358 4588 && !spu_elf_stack_analysis (info))
cd4a7468
AM
4589 info->callbacks->einfo ("%X%P: stack/lrlive analysis error: %E\n");
4590
4591 if (!spu_elf_build_stubs (info))
4592 info->callbacks->einfo ("%F%P: can not build overlay stubs: %E\n");
49fa1e15
AM
4593
4594 return bfd_elf_final_link (output_bfd, info);
4595}
4596
ece5ef60
AM
4597/* Called when not normally emitting relocs, ie. !info->relocatable
4598 and !info->emitrelocations. Returns a count of special relocs
4599 that need to be emitted. */
4600
4601static unsigned int
58217f29 4602spu_elf_count_relocs (struct bfd_link_info *info, asection *sec)
ece5ef60 4603{
58217f29 4604 Elf_Internal_Rela *relocs;
ece5ef60 4605 unsigned int count = 0;
ece5ef60 4606
58217f29
AM
4607 relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
4608 info->keep_memory);
4609 if (relocs != NULL)
ece5ef60 4610 {
58217f29
AM
4611 Elf_Internal_Rela *rel;
4612 Elf_Internal_Rela *relend = relocs + sec->reloc_count;
4613
4614 for (rel = relocs; rel < relend; rel++)
4615 {
4616 int r_type = ELF32_R_TYPE (rel->r_info);
4617 if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
4618 ++count;
4619 }
4620
4621 if (elf_section_data (sec)->relocs != relocs)
4622 free (relocs);
ece5ef60
AM
4623 }
4624
4625 return count;
4626}
4627
e9f53129
AM
4628/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
4629
d16c7321 4630static int
e9f53129
AM
4631spu_elf_relocate_section (bfd *output_bfd,
4632 struct bfd_link_info *info,
4633 bfd *input_bfd,
4634 asection *input_section,
4635 bfd_byte *contents,
4636 Elf_Internal_Rela *relocs,
4637 Elf_Internal_Sym *local_syms,
4638 asection **local_sections)
4639{
4640 Elf_Internal_Shdr *symtab_hdr;
4641 struct elf_link_hash_entry **sym_hashes;
4642 Elf_Internal_Rela *rel, *relend;
4643 struct spu_link_hash_table *htab;
64615358 4644 asection *ea;
d16c7321 4645 int ret = TRUE;
ece5ef60 4646 bfd_boolean emit_these_relocs = FALSE;
cc5ca406 4647 bfd_boolean is_ea_sym;
fdba2fcd 4648 bfd_boolean stubs;
cd4a7468 4649 unsigned int iovl = 0;
e9f53129 4650
e9f53129 4651 htab = spu_hash_table (info);
fdba2fcd 4652 stubs = (htab->stub_sec != NULL
64615358 4653 && maybe_needs_stubs (input_section));
cd4a7468 4654 iovl = overlay_index (input_section);
64615358 4655 ea = bfd_get_section_by_name (output_bfd, "._ea");
e9f53129
AM
4656 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4657 sym_hashes = (struct elf_link_hash_entry **) (elf_sym_hashes (input_bfd));
4658
4659 rel = relocs;
4660 relend = relocs + input_section->reloc_count;
4661 for (; rel < relend; rel++)
4662 {
4663 int r_type;
4664 reloc_howto_type *howto;
8374f9d4 4665 unsigned int r_symndx;
e9f53129
AM
4666 Elf_Internal_Sym *sym;
4667 asection *sec;
4668 struct elf_link_hash_entry *h;
4669 const char *sym_name;
4670 bfd_vma relocation;
4671 bfd_vma addend;
4672 bfd_reloc_status_type r;
4673 bfd_boolean unresolved_reloc;
4674 bfd_boolean warned;
cd4a7468 4675 bfd_boolean overlay_encoded;
124b52c6 4676 enum _stub_type stub_type;
e9f53129
AM
4677
4678 r_symndx = ELF32_R_SYM (rel->r_info);
4679 r_type = ELF32_R_TYPE (rel->r_info);
4680 howto = elf_howto_table + r_type;
4681 unresolved_reloc = FALSE;
4682 warned = FALSE;
e9f53129
AM
4683 h = NULL;
4684 sym = NULL;
4685 sec = NULL;
4686 if (r_symndx < symtab_hdr->sh_info)
4687 {
4688 sym = local_syms + r_symndx;
4689 sec = local_sections[r_symndx];
4690 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
4691 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
4692 }
4693 else
4694 {
dc1859a6
AM
4695 if (sym_hashes == NULL)
4696 return FALSE;
4697
4698 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4699
4700 while (h->root.type == bfd_link_hash_indirect
4701 || h->root.type == bfd_link_hash_warning)
4702 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4703
4704 relocation = 0;
4705 if (h->root.type == bfd_link_hash_defined
4706 || h->root.type == bfd_link_hash_defweak)
4707 {
4708 sec = h->root.u.def.section;
4709 if (sec == NULL
4710 || sec->output_section == NULL)
4711 /* Set a flag that will be cleared later if we find a
4712 relocation value for this symbol. output_section
4713 is typically NULL for symbols satisfied by a shared
4714 library. */
4715 unresolved_reloc = TRUE;
4716 else
4717 relocation = (h->root.u.def.value
4718 + sec->output_section->vma
4719 + sec->output_offset);
4720 }
4721 else if (h->root.type == bfd_link_hash_undefweak)
4722 ;
4723 else if (info->unresolved_syms_in_objects == RM_IGNORE
4724 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
4725 ;
4726 else if (!info->relocatable
4727 && !(r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64))
4728 {
4729 bfd_boolean err;
4730 err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
4731 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
4732 if (!info->callbacks->undefined_symbol (info,
4733 h->root.root.string,
4734 input_bfd,
4735 input_section,
4736 rel->r_offset, err))
4737 return FALSE;
4738 warned = TRUE;
4739 }
e9f53129
AM
4740 sym_name = h->root.root.string;
4741 }
4742
ab96bf03
AM
4743 if (sec != NULL && elf_discarded_section (sec))
4744 {
4745 /* For relocs against symbols from removed linkonce sections,
4746 or sections discarded by a linker script, we just want the
4747 section contents zeroed. Avoid any special processing. */
4748 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4749 rel->r_info = 0;
4750 rel->r_addend = 0;
4751 continue;
4752 }
4753
4754 if (info->relocatable)
4755 continue;
4756
cc5ca406
AM
4757 is_ea_sym = (ea != NULL
4758 && sec != NULL
4759 && sec->output_section == ea);
cd4a7468
AM
4760 overlay_encoded = FALSE;
4761
4762 /* If this symbol is in an overlay area, we may need to relocate
4763 to the overlay stub. */
4764 addend = rel->r_addend;
4765 if (stubs
4766 && !is_ea_sym
4767 && (stub_type = needs_ovl_stub (h, sym, sec, input_section, rel,
4768 contents, info)) != no_stub)
4769 {
4770 unsigned int ovl = 0;
4771 struct got_entry *g, **head;
4772
4773 if (stub_type != nonovl_stub)
4774 ovl = iovl;
4775
4776 if (h != NULL)
4777 head = &h->got.glist;
4778 else
4779 head = elf_local_got_ents (input_bfd) + r_symndx;
cc5ca406 4780
cd4a7468
AM
4781 for (g = *head; g != NULL; g = g->next)
4782 if (htab->params->ovly_flavour == ovly_soft_icache
4783 ? g->br_addr == (rel->r_offset
4784 + input_section->output_offset
4785 + input_section->output_section->vma)
4786 : g->addend == addend && (g->ovl == ovl || g->ovl == 0))
4787 break;
4788 if (g == NULL)
4789 abort ();
4790
4791 relocation = g->stub_addr;
4792 addend = 0;
4793 }
4794 else
4795 {
4796 /* For soft icache, encode the overlay index into addresses. */
4797 if (htab->params->ovly_flavour == ovly_soft_icache
4798 && !is_ea_sym)
4799 {
4800 unsigned int ovl = overlay_index (sec);
4801 if (ovl != 0)
4802 {
30c665df 4803 unsigned int set_id = ((ovl - 1) >> htab->num_lines_log2) + 1;
cd4a7468 4804 relocation += set_id << 18;
30c665df 4805 overlay_encoded = TRUE;
cd4a7468
AM
4806 }
4807 }
4808 }
4809
4810 if (unresolved_reloc)
4811 ;
4812 else if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
8374f9d4 4813 {
cc5ca406 4814 if (is_ea_sym)
8374f9d4
AM
4815 {
4816 /* ._ea is a special section that isn't allocated in SPU
4817 memory, but rather occupies space in PPU memory as
4818 part of an embedded ELF image. If this reloc is
4819 against a symbol defined in ._ea, then transform the
4820 reloc into an equivalent one without a symbol
4821 relative to the start of the ELF image. */
4822 rel->r_addend += (relocation
4823 - ea->vma
4824 + elf_section_data (ea)->this_hdr.sh_offset);
4825 rel->r_info = ELF32_R_INFO (0, r_type);
4826 }
4827 emit_these_relocs = TRUE;
4828 continue;
4829 }
cd4a7468 4830 else if (is_ea_sym)
8374f9d4
AM
4831 unresolved_reloc = TRUE;
4832
e9f53129
AM
4833 if (unresolved_reloc)
4834 {
4835 (*_bfd_error_handler)
4836 (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
4837 input_bfd,
4838 bfd_get_section_name (input_bfd, input_section),
4839 (long) rel->r_offset,
4840 howto->name,
4841 sym_name);
4842 ret = FALSE;
4843 }
4844
e9f53129
AM
4845 r = _bfd_final_link_relocate (howto,
4846 input_bfd,
4847 input_section,
4848 contents,
4849 rel->r_offset, relocation, addend);
4850
4851 if (r != bfd_reloc_ok)
4852 {
4853 const char *msg = (const char *) 0;
4854
4855 switch (r)
4856 {
4857 case bfd_reloc_overflow:
cd4a7468
AM
4858 /* FIXME: We don't want to warn on most references
4859 within an overlay to itself, but this may silence a
4860 warning that should be reported. */
4861 if (overlay_encoded && sec == input_section)
4862 break;
e9f53129
AM
4863 if (!((*info->callbacks->reloc_overflow)
4864 (info, (h ? &h->root : NULL), sym_name, howto->name,
4865 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
4866 return FALSE;
4867 break;
4868
4869 case bfd_reloc_undefined:
4870 if (!((*info->callbacks->undefined_symbol)
4871 (info, sym_name, input_bfd, input_section,
4872 rel->r_offset, TRUE)))
4873 return FALSE;
4874 break;
4875
4876 case bfd_reloc_outofrange:
4877 msg = _("internal error: out of range error");
4878 goto common_error;
4879
4880 case bfd_reloc_notsupported:
4881 msg = _("internal error: unsupported relocation error");
4882 goto common_error;
4883
4884 case bfd_reloc_dangerous:
4885 msg = _("internal error: dangerous error");
4886 goto common_error;
4887
4888 default:
4889 msg = _("internal error: unknown error");
4890 /* fall through */
4891
4892 common_error:
d16c7321 4893 ret = FALSE;
e9f53129
AM
4894 if (!((*info->callbacks->warning)
4895 (info, msg, sym_name, input_bfd, input_section,
4896 rel->r_offset)))
4897 return FALSE;
4898 break;
4899 }
4900 }
4901 }
4902
ece5ef60
AM
4903 if (ret
4904 && emit_these_relocs
ece5ef60
AM
4905 && !info->emitrelocations)
4906 {
4907 Elf_Internal_Rela *wrel;
4908 Elf_Internal_Shdr *rel_hdr;
4909
4910 wrel = rel = relocs;
4911 relend = relocs + input_section->reloc_count;
4912 for (; rel < relend; rel++)
4913 {
4914 int r_type;
4915
4916 r_type = ELF32_R_TYPE (rel->r_info);
4917 if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
4918 *wrel++ = *rel;
4919 }
4920 input_section->reloc_count = wrel - relocs;
4921 /* Backflips for _bfd_elf_link_output_relocs. */
4922 rel_hdr = &elf_section_data (input_section)->rel_hdr;
4923 rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
4924 ret = 2;
4925 }
4926
e9f53129
AM
4927 return ret;
4928}
4929
c1b2796f
AM
4930/* Adjust _SPUEAR_ syms to point at their overlay stubs. */
4931
4932static bfd_boolean
4933spu_elf_output_symbol_hook (struct bfd_link_info *info,
4934 const char *sym_name ATTRIBUTE_UNUSED,
4935 Elf_Internal_Sym *sym,
4936 asection *sym_sec ATTRIBUTE_UNUSED,
4937 struct elf_link_hash_entry *h)
4938{
4939 struct spu_link_hash_table *htab = spu_hash_table (info);
4940
4941 if (!info->relocatable
47f6dab9 4942 && htab->stub_sec != NULL
c1b2796f
AM
4943 && h != NULL
4944 && (h->root.type == bfd_link_hash_defined
4945 || h->root.type == bfd_link_hash_defweak)
4946 && h->def_regular
4947 && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
4948 {
4a628337 4949 struct got_entry *g;
c1b2796f 4950
4a628337 4951 for (g = h->got.glist; g != NULL; g = g->next)
cd4a7468
AM
4952 if (htab->params->ovly_flavour == ovly_soft_icache
4953 ? g->br_addr == g->stub_addr
4954 : g->addend == 0 && g->ovl == 0)
4a628337
AM
4955 {
4956 sym->st_shndx = (_bfd_elf_section_from_bfd_section
4957 (htab->stub_sec[0]->output_section->owner,
4958 htab->stub_sec[0]->output_section));
4959 sym->st_value = g->stub_addr;
4960 break;
4961 }
c1b2796f
AM
4962 }
4963
4964 return TRUE;
4965}
4966
e9f53129
AM
4967static int spu_plugin = 0;
4968
4969void
4970spu_elf_plugin (int val)
4971{
4972 spu_plugin = val;
4973}
4974
4975/* Set ELF header e_type for plugins. */
4976
4977static void
4978spu_elf_post_process_headers (bfd *abfd,
4979 struct bfd_link_info *info ATTRIBUTE_UNUSED)
4980{
4981 if (spu_plugin)
4982 {
4983 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4984
4985 i_ehdrp->e_type = ET_DYN;
4986 }
4987}
4988
4989/* We may add an extra PT_LOAD segment for .toe. We also need extra
4990 segments for overlays. */
4991
4992static int
4993spu_elf_additional_program_headers (bfd *abfd, struct bfd_link_info *info)
4994{
ceae84aa 4995 int extra = 0;
e9f53129
AM
4996 asection *sec;
4997
ceae84aa
AM
4998 if (info != NULL)
4999 {
5000 struct spu_link_hash_table *htab = spu_hash_table (info);
5001 extra = htab->num_overlays;
5002 }
5003
e9f53129
AM
5004 if (extra)
5005 ++extra;
5006
5007 sec = bfd_get_section_by_name (abfd, ".toe");
5008 if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
5009 ++extra;
5010
5011 return extra;
5012}
5013
5014/* Remove .toe section from other PT_LOAD segments and put it in
5015 a segment of its own. Put overlays in separate segments too. */
5016
5017static bfd_boolean
5018spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
5019{
5020 asection *toe, *s;
5021 struct elf_segment_map *m;
5022 unsigned int i;
5023
5024 if (info == NULL)
5025 return TRUE;
5026
5027 toe = bfd_get_section_by_name (abfd, ".toe");
5028 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
5029 if (m->p_type == PT_LOAD && m->count > 1)
5030 for (i = 0; i < m->count; i++)
5031 if ((s = m->sections[i]) == toe
47f6dab9 5032 || spu_elf_section_data (s)->u.o.ovl_index != 0)
e9f53129
AM
5033 {
5034 struct elf_segment_map *m2;
5035 bfd_vma amt;
5036
5037 if (i + 1 < m->count)
5038 {
5039 amt = sizeof (struct elf_segment_map);
5040 amt += (m->count - (i + 2)) * sizeof (m->sections[0]);
5041 m2 = bfd_zalloc (abfd, amt);
5042 if (m2 == NULL)
5043 return FALSE;
5044 m2->count = m->count - (i + 1);
5045 memcpy (m2->sections, m->sections + i + 1,
5046 m2->count * sizeof (m->sections[0]));
5047 m2->p_type = PT_LOAD;
5048 m2->next = m->next;
5049 m->next = m2;
5050 }
5051 m->count = 1;
5052 if (i != 0)
5053 {
5054 m->count = i;
5055 amt = sizeof (struct elf_segment_map);
5056 m2 = bfd_zalloc (abfd, amt);
5057 if (m2 == NULL)
5058 return FALSE;
5059 m2->p_type = PT_LOAD;
5060 m2->count = 1;
5061 m2->sections[0] = s;
5062 m2->next = m->next;
5063 m->next = m2;
5064 }
5065 break;
5066 }
5067
5068 return TRUE;
5069}
5070
7d3287cb
AM
5071/* Tweak the section type of .note.spu_name. */
5072
5073static bfd_boolean
5074spu_elf_fake_sections (bfd *obfd ATTRIBUTE_UNUSED,
5075 Elf_Internal_Shdr *hdr,
5076 asection *sec)
5077{
5078 if (strcmp (sec->name, SPU_PTNOTE_SPUNAME) == 0)
5079 hdr->sh_type = SHT_NOTE;
5080 return TRUE;
5081}
5082
e9f53129
AM
5083/* Tweak phdrs before writing them out. */
5084
5085static int
5086spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
5087{
5088 const struct elf_backend_data *bed;
5089 struct elf_obj_tdata *tdata;
5090 Elf_Internal_Phdr *phdr, *last;
5091 struct spu_link_hash_table *htab;
5092 unsigned int count;
5093 unsigned int i;
5094
5095 if (info == NULL)
5096 return TRUE;
5097
5098 bed = get_elf_backend_data (abfd);
5099 tdata = elf_tdata (abfd);
5100 phdr = tdata->phdr;
5101 count = tdata->program_header_size / bed->s->sizeof_phdr;
5102 htab = spu_hash_table (info);
5103 if (htab->num_overlays != 0)
5104 {
5105 struct elf_segment_map *m;
5106 unsigned int o;
5107
5108 for (i = 0, m = elf_tdata (abfd)->segment_map; m; ++i, m = m->next)
5109 if (m->count != 0
47f6dab9 5110 && (o = spu_elf_section_data (m->sections[0])->u.o.ovl_index) != 0)
e9f53129
AM
5111 {
5112 /* Mark this as an overlay header. */
5113 phdr[i].p_flags |= PF_OVERLAY;
5114
cd4a7468
AM
5115 if (htab->ovtab != NULL && htab->ovtab->size != 0
5116 && htab->params->ovly_flavour != ovly_soft_icache)
e9f53129
AM
5117 {
5118 bfd_byte *p = htab->ovtab->contents;
47f6dab9 5119 unsigned int off = o * 16 + 8;
e9f53129
AM
5120
5121 /* Write file_off into _ovly_table. */
5122 bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off);
5123 }
5124 }
cd4a7468
AM
5125 /* Soft-icache has its file offset put in .ovl.init. */
5126 if (htab->init != NULL && htab->init->size != 0)
5127 {
5128 bfd_vma val = elf_section_data (htab->ovl_sec[0])->this_hdr.sh_offset;
5129
5130 bfd_put_32 (htab->init->owner, val, htab->init->contents + 4);
5131 }
e9f53129
AM
5132 }
5133
5134 /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
5135 of 16. This should always be possible when using the standard
5136 linker scripts, but don't create overlapping segments if
5137 someone is playing games with linker scripts. */
5138 last = NULL;
5139 for (i = count; i-- != 0; )
5140 if (phdr[i].p_type == PT_LOAD)
5141 {
5142 unsigned adjust;
5143
5144 adjust = -phdr[i].p_filesz & 15;
5145 if (adjust != 0
5146 && last != NULL
5147 && phdr[i].p_offset + phdr[i].p_filesz > last->p_offset - adjust)
5148 break;
5149
5150 adjust = -phdr[i].p_memsz & 15;
5151 if (adjust != 0
5152 && last != NULL
5153 && phdr[i].p_filesz != 0
5154 && phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust
5155 && phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr)
5156 break;
5157
5158 if (phdr[i].p_filesz != 0)
5159 last = &phdr[i];
5160 }
5161
5162 if (i == (unsigned int) -1)
5163 for (i = count; i-- != 0; )
5164 if (phdr[i].p_type == PT_LOAD)
5165 {
5166 unsigned adjust;
5167
5168 adjust = -phdr[i].p_filesz & 15;
5169 phdr[i].p_filesz += adjust;
5170
5171 adjust = -phdr[i].p_memsz & 15;
5172 phdr[i].p_memsz += adjust;
5173 }
5174
5175 return TRUE;
5176}
5177
e9f53129
AM
5178#define TARGET_BIG_SYM bfd_elf32_spu_vec
5179#define TARGET_BIG_NAME "elf32-spu"
5180#define ELF_ARCH bfd_arch_spu
5181#define ELF_MACHINE_CODE EM_SPU
5182/* This matches the alignment need for DMA. */
5183#define ELF_MAXPAGESIZE 0x80
5184#define elf_backend_rela_normal 1
5185#define elf_backend_can_gc_sections 1
5186
5187#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
ad2adbc8 5188#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_lookup
e9f53129 5189#define elf_info_to_howto spu_elf_info_to_howto
ece5ef60 5190#define elf_backend_count_relocs spu_elf_count_relocs
e9f53129
AM
5191#define elf_backend_relocate_section spu_elf_relocate_section
5192#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
c1b2796f 5193#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
124b52c6 5194#define elf_backend_object_p spu_elf_object_p
e9f53129
AM
5195#define bfd_elf32_new_section_hook spu_elf_new_section_hook
5196#define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create
e9f53129
AM
5197
5198#define elf_backend_additional_program_headers spu_elf_additional_program_headers
5199#define elf_backend_modify_segment_map spu_elf_modify_segment_map
5200#define elf_backend_modify_program_headers spu_elf_modify_program_headers
5201#define elf_backend_post_process_headers spu_elf_post_process_headers
7d3287cb 5202#define elf_backend_fake_sections spu_elf_fake_sections
e9f53129 5203#define elf_backend_special_sections spu_elf_special_sections
49fa1e15 5204#define bfd_elf32_bfd_final_link spu_elf_final_link
e9f53129
AM
5205
5206#include "elf32-target.h"
This page took 0.398122 seconds and 4 git commands to generate.