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