bfd/
[deliverable/binutils-gdb.git] / ld / emultempl / xtensaelf.em
CommitLineData
e0001a05 1# This shell script emits a C file. -*- C -*-
c7e2358a 2# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
e0001a05
NC
3# Free Software Foundation, Inc.
4#
f96b4a7b 5# This file is part of the GNU Binutils.
e0001a05
NC
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
f96b4a7b 9# the Free Software Foundation; either version 3 of the License, or
e0001a05
NC
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
f96b4a7b
NC
19# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20# MA 02110-1301, USA.
e0001a05
NC
21#
22
23# This file is sourced from elf32.em, and defines extra xtensa-elf
24# specific routines.
25#
92b93329 26fragment <<EOF
e0001a05
NC
27
28#include <xtensa-config.h>
43cd72b9
BW
29#include "../bfd/elf-bfd.h"
30#include "../bfd/libbfd.h"
31#include "elf/xtensa.h"
32#include "bfd.h"
e0001a05 33
2caa7ca0
BW
34/* Provide default values for new configuration settings. */
35#ifndef XSHAL_ABI
36#define XSHAL_ABI 0
37#endif
38
0c7a8e5a
AM
39static void xtensa_wild_group_interleave (lang_statement_union_type *);
40static void xtensa_colocate_output_literals (lang_statement_union_type *);
a255b6c7
BW
41static void xtensa_strip_inconsistent_linkonce_sections
42 (lang_statement_list_type *);
e0001a05
NC
43
44
e0001a05
NC
45/* This number is irrelevant until we turn on use_literal_pages */
46static bfd_vma xtensa_page_power = 12; /* 4K pages. */
47
48/* To force a page break between literals and text, change
43cd72b9 49 xtensa_use_literal_pages to "TRUE". */
e0001a05
NC
50static bfd_boolean xtensa_use_literal_pages = FALSE;
51
52#define EXTRA_VALIDATION 0
53
54
55static char *
0c7a8e5a
AM
56elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
57 char **argv ATTRIBUTE_UNUSED)
e0001a05
NC
58{
59 if (XCHAL_HAVE_BE)
60 return "${BIG_OUTPUT_FORMAT}";
61 else
62 return "${LITTLE_OUTPUT_FORMAT}";
63}
64
65
e0001a05 66static void
0c7a8e5a 67elf_xtensa_before_parse (void)
e0001a05
NC
68{
69 /* Just call the default hook.... Tensilica's version of this function
70 does some other work that isn't relevant here. */
71 gld${EMULATION_NAME}_before_parse ();
72}
73
74
7fa3d080
BW
75static void
76remove_section (bfd *abfd, asection *os)
43cd72b9
BW
77{
78 asection **spp;
79 for (spp = &abfd->sections; *spp; spp = &(*spp)->next)
80 if (*spp == os)
81 {
82 *spp = os->next;
83 os->owner->section_count--;
84 break;
85 }
86}
87
88
7fa3d080
BW
89static bfd_boolean
90replace_insn_sec_with_prop_sec (bfd *abfd,
91 const char *insn_sec_name,
92 const char *prop_sec_name,
93 char **error_message)
43cd72b9
BW
94{
95 asection *insn_sec;
96 asection *prop_sec;
97 bfd_byte *prop_contents = NULL;
98 bfd_byte *insn_contents = NULL;
99 unsigned entry_count;
100 unsigned entry;
d4730f92 101 Elf_Internal_Shdr *rel_hdr;
43cd72b9
BW
102 Elf_Internal_Rela *internal_relocs = NULL;
103 unsigned reloc_count;
92b93329 104
43cd72b9
BW
105 *error_message = "";
106 insn_sec = bfd_get_section_by_name (abfd, insn_sec_name);
107 if (insn_sec == NULL)
108 return TRUE;
109 entry_count = insn_sec->size / 8;
110
111 prop_sec = bfd_get_section_by_name (abfd, prop_sec_name);
112 if (prop_sec != NULL && insn_sec != NULL)
113 {
114 *error_message = _("file already has property tables");
115 return FALSE;
116 }
92b93329 117
43cd72b9
BW
118 if (insn_sec->size != 0)
119 {
120 insn_contents = (bfd_byte *) bfd_malloc (insn_sec->size);
121 if (insn_contents == NULL)
122 {
123 *error_message = _("out of memory");
124 goto cleanup;
125 }
126 if (! bfd_get_section_contents (abfd, insn_sec, insn_contents,
127 (file_ptr) 0, insn_sec->size))
128 {
129 *error_message = _("failed to read section contents");
130 goto cleanup;
131 }
132 }
133
2caa7ca0 134 /* Create a property table section for it. */
43cd72b9 135 prop_sec_name = strdup (prop_sec_name);
2caa7ca0
BW
136 prop_sec = bfd_make_section_with_flags
137 (abfd, prop_sec_name, bfd_get_section_flags (abfd, insn_sec));
43cd72b9 138 if (prop_sec == NULL
43cd72b9
BW
139 || ! bfd_set_section_alignment (abfd, prop_sec, 2))
140 {
141 *error_message = _("could not create new section");
142 goto cleanup;
143 }
92b93329 144
43cd72b9
BW
145 prop_sec->size = entry_count * 12;
146 prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size);
147 elf_section_data (prop_sec)->this_hdr.contents = prop_contents;
148
149 /* The entry size and size must be set to allow the linker to compute
150 the number of relocations since it does not use reloc_count. */
d4730f92
BS
151 rel_hdr = _bfd_elf_single_rel_hdr (prop_sec);
152 rel_hdr->sh_entsize = sizeof (Elf32_External_Rela);
153 rel_hdr->sh_size = _bfd_elf_single_rel_hdr (insn_sec)->sh_size;
43cd72b9
BW
154
155 if (prop_contents == NULL && prop_sec->size != 0)
156 {
157 *error_message = _("could not allocate section contents");
158 goto cleanup;
159 }
160
161 /* Read the relocations. */
162 reloc_count = insn_sec->reloc_count;
163 if (reloc_count != 0)
164 {
165 /* If there is already an internal_reloc, then save it so that the
166 read_relocs function freshly allocates a copy. */
167 Elf_Internal_Rela *saved_relocs = elf_section_data (insn_sec)->relocs;
92b93329 168
43cd72b9 169 elf_section_data (insn_sec)->relocs = NULL;
92b93329 170 internal_relocs =
43cd72b9
BW
171 _bfd_elf_link_read_relocs (abfd, insn_sec, NULL, NULL, FALSE);
172 elf_section_data (insn_sec)->relocs = saved_relocs;
92b93329 173
43cd72b9
BW
174 if (internal_relocs == NULL)
175 {
176 *error_message = _("out of memory");
177 goto cleanup;
178 }
179 }
180
181 /* Create a relocation section for the property section. */
182 if (internal_relocs != NULL)
183 {
184 elf_section_data (prop_sec)->relocs = internal_relocs;
185 prop_sec->reloc_count = reloc_count;
186 }
92b93329 187
43cd72b9
BW
188 /* Now copy each insn table entry to the prop table entry with
189 appropriate flags. */
190 for (entry = 0; entry < entry_count; ++entry)
191 {
192 unsigned value;
99ded152 193 unsigned flags = (XTENSA_PROP_INSN | XTENSA_PROP_NO_TRANSFORM
43cd72b9
BW
194 | XTENSA_PROP_INSN_NO_REORDER);
195 value = bfd_get_32 (abfd, insn_contents + entry * 8 + 0);
196 bfd_put_32 (abfd, value, prop_contents + entry * 12 + 0);
197 value = bfd_get_32 (abfd, insn_contents + entry * 8 + 4);
198 bfd_put_32 (abfd, value, prop_contents + entry * 12 + 4);
199 bfd_put_32 (abfd, flags, prop_contents + entry * 12 + 8);
200 }
201
202 /* Now copy all of the relocations. Change offsets for the
203 instruction table section to offsets in the property table
204 section. */
205 if (internal_relocs)
206 {
207 unsigned i;
43cd72b9
BW
208
209 for (i = 0; i < reloc_count; i++)
210 {
211 Elf_Internal_Rela *rela;
212 unsigned r_offset;
213
214 rela = &internal_relocs[i];
215
92b93329 216 /* If this relocation is to the .xt.insn section,
43cd72b9
BW
217 change the section number and the offset. */
218 r_offset = rela->r_offset;
219 r_offset += 4 * (r_offset / 8);
220 rela->r_offset = r_offset;
221 }
222 }
223
224 remove_section (abfd, insn_sec);
92b93329 225
43cd72b9
BW
226 if (insn_contents)
227 free (insn_contents);
92b93329 228
43cd72b9
BW
229 return TRUE;
230
231 cleanup:
232 if (prop_sec && prop_sec->owner)
233 remove_section (abfd, prop_sec);
234 if (insn_contents)
235 free (insn_contents);
236 if (internal_relocs)
237 free (internal_relocs);
238
239 return FALSE;
240}
241
242
243#define PROP_SEC_BASE_NAME ".xt.prop"
244#define INSN_SEC_BASE_NAME ".xt.insn"
245#define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x."
246
247
7fa3d080
BW
248static void
249replace_instruction_table_sections (bfd *abfd, asection *sec)
43cd72b9
BW
250{
251 char *message = "";
252 const char *insn_sec_name = NULL;
253 char *prop_sec_name = NULL;
254 char *owned_prop_sec_name = NULL;
255 const char *sec_name;
92b93329 256
43cd72b9
BW
257 sec_name = bfd_get_section_name (abfd, sec);
258 if (strcmp (sec_name, INSN_SEC_BASE_NAME) == 0)
259 {
260 insn_sec_name = INSN_SEC_BASE_NAME;
261 prop_sec_name = PROP_SEC_BASE_NAME;
262 }
0112cd26 263 else if (CONST_STRNEQ (sec_name, LINKONCE_SEC_OLD_TEXT_BASE_NAME))
43cd72b9
BW
264 {
265 insn_sec_name = sec_name;
266 owned_prop_sec_name = (char *) xmalloc (strlen (sec_name) + 20);
267 prop_sec_name = owned_prop_sec_name;
268 strcpy (prop_sec_name, ".gnu.linkonce.prop.t.");
269 strcat (prop_sec_name,
270 sec_name + strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME));
271 }
272 if (insn_sec_name != NULL)
273 {
274 if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
275 &message))
276 {
277 einfo (_("%P: warning: failed to convert %s table in %B (%s); subsequent disassembly may be incomplete\n"),
278 insn_sec_name, abfd, message);
279 }
280 }
281 if (owned_prop_sec_name)
282 free (owned_prop_sec_name);
283}
284
285
286/* This is called after all input sections have been opened to convert
287 instruction tables (.xt.insn, gnu.linkonce.x.*) tables into property
288 tables (.xt.prop) before any section placement. */
289
290static void
291elf_xtensa_after_open (void)
292{
43cd72b9
BW
293 /* First call the ELF version. */
294 gld${EMULATION_NAME}_after_open ();
92b93329 295
43cd72b9 296 /* Now search the input files looking for instruction table sections. */
2caa7ca0 297 LANG_FOR_EACH_INPUT_STATEMENT (f)
43cd72b9 298 {
2caa7ca0 299 asection *sec = f->the_bfd->sections;
43cd72b9
BW
300 asection *next_sec;
301
302 /* Do not use bfd_map_over_sections here since we are removing
303 sections as we iterate. */
304 while (sec != NULL)
305 {
306 next_sec = sec->next;
2caa7ca0 307 replace_instruction_table_sections (f->the_bfd, sec);
43cd72b9
BW
308 sec = next_sec;
309 }
310 }
311}
312
313
2caa7ca0
BW
314static bfd_boolean
315xt_config_info_unpack_and_check (char *data,
316 bfd_boolean *pmismatch,
317 char **pmsg)
318{
319 char *d, *key;
320 unsigned num;
321
322 *pmismatch = FALSE;
323
324 d = data;
325 while (*d)
326 {
327 key = d;
328 d = strchr (d, '=');
329 if (! d)
330 goto error;
331
332 /* Overwrite the equal sign. */
333 *d++ = 0;
334
335 /* Check if this is a quoted string or a number. */
336 if (*d == '"')
337 {
338 /* No string values are currently checked by LD;
339 just skip over the quotes. */
340 d++;
341 d = strchr (d, '"');
342 if (! d)
343 goto error;
344 /* Overwrite the trailing quote. */
345 *d++ = 0;
346 }
347 else
348 {
349 if (*d == 0)
350 goto error;
351 num = strtoul (d, &d, 0);
352
353 if (! strcmp (key, "ABI"))
354 {
355 if (num != XSHAL_ABI)
356 {
357 *pmismatch = TRUE;
358 *pmsg = "ABI does not match";
359 }
360 }
361 else if (! strcmp (key, "USE_ABSOLUTE_LITERALS"))
362 {
363 if (num != XSHAL_USE_ABSOLUTE_LITERALS)
364 {
365 *pmismatch = TRUE;
366 *pmsg = "incompatible use of the Extended L32R option";
367 }
368 }
369 }
370
371 if (*d++ != '\n')
372 goto error;
373 }
374
375 return TRUE;
376
377 error:
378 return FALSE;
379}
380
381
382#define XTINFO_NAME "Xtensa_Info"
383#define XTINFO_NAMESZ 12
384#define XTINFO_TYPE 1
385
386static void
387check_xtensa_info (bfd *abfd, asection *info_sec)
388{
389 char *data, *errmsg = "";
390 bfd_boolean mismatch;
391
392 data = xmalloc (info_sec->size);
393 if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec->size))
394 einfo (_("%F%P:%B: cannot read contents of section %A\n"), abfd, info_sec);
395
396 if (info_sec->size > 24
397 && info_sec->size >= 24 + bfd_get_32 (abfd, data + 4)
398 && bfd_get_32 (abfd, data + 0) == XTINFO_NAMESZ
399 && bfd_get_32 (abfd, data + 8) == XTINFO_TYPE
400 && strcmp (data + 12, XTINFO_NAME) == 0
401 && xt_config_info_unpack_and_check (data + 12 + XTINFO_NAMESZ,
402 &mismatch, &errmsg))
403 {
404 if (mismatch)
405 einfo (_("%P:%B: warning: incompatible Xtensa configuration (%s)\n"),
406 abfd, errmsg);
407 }
408 else
409 einfo (_("%P:%B: warning: cannot parse .xtensa.info section\n"), abfd);
410
411 free (data);
412}
413
414
e0001a05
NC
415/* This is called after the sections have been attached to output
416 sections, but before any sizes or addresses have been set. */
417
0c7a8e5a
AM
418static void
419elf_xtensa_before_allocation (void)
e0001a05 420{
2caa7ca0
BW
421 asection *info_sec, *first_info_sec;
422 bfd *first_bfd;
e0001a05
NC
423 bfd_boolean is_big_endian = XCHAL_HAVE_BE;
424
425 /* Check that the output endianness matches the Xtensa
426 configuration. The BFD library always includes both big and
427 little endian target vectors for Xtensa, but it only supports the
428 detailed instruction encode/decode operations (such as are
429 required to process relocations) for the selected Xtensa
430 configuration. */
431
f13a99db
AM
432 if (is_big_endian
433 && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
e0001a05
NC
434 {
435 einfo (_("%F%P: little endian output does not match "
436 "Xtensa configuration\n"));
437 }
f13a99db
AM
438 if (!is_big_endian
439 && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_BIG)
e0001a05
NC
440 {
441 einfo (_("%F%P: big endian output does not match "
442 "Xtensa configuration\n"));
443 }
444
2caa7ca0
BW
445 /* Keep track of the first input .xtensa.info section, and as a fallback,
446 the first input bfd where a .xtensa.info section could be created.
447 After the input .xtensa.info has been checked, the contents of the
448 first one will be replaced with the output .xtensa.info table. */
449 first_info_sec = 0;
450 first_bfd = 0;
e0001a05 451
2caa7ca0
BW
452 LANG_FOR_EACH_INPUT_STATEMENT (f)
453 {
454 /* Check that the endianness for each input file matches the output.
455 The merge_private_bfd_data hook has already reported any mismatches
456 as errors, but those errors are not fatal. At this point, we
457 cannot go any further if there are any mismatches. */
458 if ((is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
459 || (!is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_BIG))
460 einfo (_("%F%P: cross-endian linking for %B not supported\n"),
461 f->the_bfd);
462
463 if (! first_bfd)
464 first_bfd = f->the_bfd;
465
466 info_sec = bfd_get_section_by_name (f->the_bfd, ".xtensa.info");
467 if (! info_sec)
468 continue;
469
470 if (! first_info_sec)
471 first_info_sec = info_sec;
472
473 /* Unpack the .xtensa.info section and check it against the current
474 Xtensa configuration. */
475 check_xtensa_info (f->the_bfd, info_sec);
476
477 /* Do not include this copy of .xtensa.info in the output. */
478 info_sec->size = 0;
479 info_sec->flags |= SEC_EXCLUDE;
480 }
481
482 /* Reuse the first .xtensa.info input section to hold the output
483 .xtensa.info; or, if none were found, create a new section in the
484 first input bfd (assuming there is one). */
485 info_sec = first_info_sec;
486 if (! info_sec && first_bfd)
487 {
488 info_sec = bfd_make_section_with_flags (first_bfd, ".xtensa.info",
489 SEC_HAS_CONTENTS | SEC_READONLY);
490 if (! info_sec)
491 einfo (_("%F%P: failed to create .xtensa.info section\n"));
492 }
493 if (info_sec)
e0001a05 494 {
2caa7ca0
BW
495 int xtensa_info_size;
496 char *data;
497
498 info_sec->flags &= ~SEC_EXCLUDE;
499 info_sec->flags |= SEC_IN_MEMORY;
500
501 data = xmalloc (100);
502 sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
503 XSHAL_USE_ABSOLUTE_LITERALS, XSHAL_ABI);
504 xtensa_info_size = strlen (data) + 1;
505
506 /* Add enough null terminators to pad to a word boundary. */
507 do
508 data[xtensa_info_size++] = 0;
509 while ((xtensa_info_size & 3) != 0);
510
511 info_sec->size = 12 + XTINFO_NAMESZ + xtensa_info_size;
512 info_sec->contents = xmalloc (info_sec->size);
513 bfd_put_32 (info_sec->owner, XTINFO_NAMESZ, info_sec->contents + 0);
514 bfd_put_32 (info_sec->owner, xtensa_info_size, info_sec->contents + 4);
515 bfd_put_32 (info_sec->owner, XTINFO_TYPE, info_sec->contents + 8);
516 memcpy (info_sec->contents + 12, XTINFO_NAME, XTINFO_NAMESZ);
517 memcpy (info_sec->contents + 12 + XTINFO_NAMESZ, data, xtensa_info_size);
518 free (data);
e0001a05
NC
519 }
520
521 /* Enable relaxation by default if the "--no-relax" option was not
522 specified. This is done here instead of in the before_parse hook
523 because there is a check in main() to prohibit use of --relax and
524 -r together and that combination should be allowed for Xtensa. */
28d5f677
NC
525 if (RELAXATION_DISABLED_BY_DEFAULT)
526 ENABLE_RELAXATION;
e0001a05 527
a255b6c7
BW
528 xtensa_strip_inconsistent_linkonce_sections (stat_ptr);
529
e0001a05
NC
530 gld${EMULATION_NAME}_before_allocation ();
531
532 xtensa_wild_group_interleave (stat_ptr->head);
28d5f677
NC
533
534 if (RELAXATION_ENABLED)
e0001a05
NC
535 xtensa_colocate_output_literals (stat_ptr->head);
536
537 /* TBD: We need to force the page alignments to here and only do
538 them as needed for the entire output section. Finally, if this
1049f94e 539 is a relocatable link then we need to add alignment notes so
e0001a05
NC
540 that the literals can be separated later. */
541}
542
543
544typedef struct wildcard_list section_name_list;
545
546typedef struct reloc_deps_e_t reloc_deps_e;
547typedef struct reloc_deps_section_t reloc_deps_section;
548typedef struct reloc_deps_graph_t reloc_deps_graph;
549
550
551struct reloc_deps_e_t
552{
553 asection *src; /* Contains l32rs. */
554 asection *tgt; /* Contains literals. */
555 reloc_deps_e *next;
556};
557
558/* Place these in the userdata field. */
559struct reloc_deps_section_t
560{
561 reloc_deps_e *preds;
562 reloc_deps_e *succs;
563 bfd_boolean is_only_literal;
564};
565
566
567struct reloc_deps_graph_t
568{
569 size_t count;
570 size_t size;
571 asection **sections;
572};
573
574static void xtensa_layout_wild
0c7a8e5a 575 (const reloc_deps_graph *, lang_wild_statement_type *);
e0001a05 576
0c7a8e5a
AM
577typedef void (*deps_callback_t) (asection *, /* src_sec */
578 bfd_vma, /* src_offset */
579 asection *, /* target_sec */
580 bfd_vma, /* target_offset */
581 void *); /* closure */
e0001a05 582
e0001a05 583extern bfd_boolean xtensa_callback_required_dependence
0c7a8e5a 584 (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
7fa3d080 585static void xtensa_ldlang_clear_addresses (lang_statement_union_type *);
e0001a05 586static bfd_boolean ld_local_file_relocations_fit
0c7a8e5a 587 (lang_statement_union_type *, const reloc_deps_graph *);
e0001a05 588static bfd_vma ld_assign_relative_paged_dot
0c7a8e5a
AM
589 (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *,
590 bfd_boolean);
e0001a05 591static bfd_vma ld_xtensa_insert_page_offsets
0c7a8e5a 592 (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean);
e0001a05 593#if EXTRA_VALIDATION
7fa3d080 594static size_t ld_count_children (lang_statement_union_type *);
e0001a05 595#endif
e0001a05
NC
596
597extern lang_statement_list_type constructor_list;
598
0c7a8e5a
AM
599static reloc_deps_section *
600xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
601 asection *sec)
e0001a05
NC
602{
603 /* We have a separate function for this so that
604 we could in the future keep a completely independent
605 structure that maps a section to its dependence edges.
606 For now, we place these in the sec->userdata field. */
0c7a8e5a 607 reloc_deps_section *sec_deps = sec->userdata;
e0001a05
NC
608 return sec_deps;
609}
610
0c7a8e5a
AM
611static void
612xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
613 asection *sec,
614 reloc_deps_section *deps_section)
e0001a05 615{
0c7a8e5a 616 sec->userdata = deps_section;
e0001a05
NC
617}
618
619
620/* This is used to keep a list of all of the sections participating in
621 the graph so we can clean them up quickly. */
622
0c7a8e5a
AM
623static void
624xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec)
e0001a05
NC
625{
626 if (deps->size <= deps->count)
627 {
628 asection **new_sections;
629 size_t i;
630 size_t new_size;
0c7a8e5a 631
e0001a05
NC
632 new_size = deps->size * 2;
633 if (new_size == 0)
634 new_size = 20;
0c7a8e5a
AM
635
636 new_sections = xmalloc (sizeof (asection *) * new_size);
637 memset (new_sections, 0, sizeof (asection *) * new_size);
638 for (i = 0; i < deps->count; i++)
e0001a05
NC
639 {
640 new_sections[i] = deps->sections[i];
641 }
642 if (deps->sections != NULL)
643 free (deps->sections);
644 deps->sections = new_sections;
645 deps->size = new_size;
646 }
647 deps->sections[deps->count] = sec;
648 deps->count++;
649}
650
651
0c7a8e5a
AM
652static void
653free_reloc_deps_graph (reloc_deps_graph *deps)
e0001a05
NC
654{
655 size_t i;
656 for (i = 0; i < deps->count; i++)
657 {
658 asection *sec = deps->sections[i];
659 reloc_deps_section *sec_deps;
660 sec_deps = xtensa_get_section_deps (deps, sec);
0c7a8e5a 661 if (sec_deps)
e0001a05
NC
662 {
663 reloc_deps_e *next;
664 while (sec_deps->succs != NULL)
665 {
666 next = sec_deps->succs->next;
667 free (sec_deps->succs);
668 sec_deps->succs = next;
669 }
0c7a8e5a 670
e0001a05
NC
671 while (sec_deps->preds != NULL)
672 {
673 next = sec_deps->preds->next;
674 free (sec_deps->preds);
675 sec_deps->preds = next;
676 }
677 free (sec_deps);
678 }
679 xtensa_set_section_deps (deps, sec, NULL);
680 }
681 if (deps->sections)
682 free (deps->sections);
683
684 free (deps);
685}
686
687
0c7a8e5a
AM
688static bfd_boolean
689section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
690 lang_statement_union_type *s)
e0001a05
NC
691{
692 asection *sec;
693 const reloc_deps_section *sec_deps;
694
695 if (s->header.type != lang_input_section_enum)
696 return FALSE;
697 sec = s->input_section.section;
698
699 sec_deps = xtensa_get_section_deps (deps, sec);
0c7a8e5a 700 return sec_deps && sec_deps->succs != NULL;
e0001a05
NC
701}
702
703
0c7a8e5a
AM
704static bfd_boolean
705section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
706 lang_statement_union_type *s)
e0001a05
NC
707{
708 asection *sec;
709 const reloc_deps_section *sec_deps;
710
711 if (s->header.type != lang_input_section_enum)
712 return FALSE;
713 sec = s->input_section.section;
714
715 sec_deps = xtensa_get_section_deps (deps, sec);
0c7a8e5a 716 return sec_deps && sec_deps->preds != NULL;
e0001a05
NC
717}
718
7fa3d080 719
0c7a8e5a
AM
720static bfd_boolean
721section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
722 lang_statement_union_type *s)
e0001a05
NC
723{
724 return (section_is_source (deps, s)
725 || section_is_target (deps, s));
726}
727
728
729typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack;
730typedef struct xtensa_ld_iter_t xtensa_ld_iter;
731
732struct xtensa_ld_iter_t
733{
734 lang_statement_union_type *parent; /* Parent of the list. */
735 lang_statement_list_type *l; /* List that holds it. */
736 lang_statement_union_type **loc; /* Place in the list. */
737};
738
739struct xtensa_ld_iter_stack_t
740{
741 xtensa_ld_iter iterloc; /* List that hold it. */
0c7a8e5a 742
e0001a05
NC
743 xtensa_ld_iter_stack *next; /* Next in the stack. */
744 xtensa_ld_iter_stack *prev; /* Back pointer for stack. */
745};
746
e0001a05 747
0c7a8e5a
AM
748static void
749ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current)
e0001a05
NC
750{
751 lang_statement_union_type *to_next;
752 lang_statement_union_type *current_next;
753 lang_statement_union_type **e;
754
755#if EXTRA_VALIDATION
756 size_t old_to_count, new_to_count;
757 size_t old_current_count, new_current_count;
758#endif
759
760 if (to == current)
761 return;
0c7a8e5a 762
e0001a05
NC
763#if EXTRA_VALIDATION
764 old_to_count = ld_count_children (to->parent);
765 old_current_count = ld_count_children (current->parent);
766#endif
767
768 to_next = *(to->loc);
769 current_next = (*current->loc)->header.next;
0c7a8e5a 770
e0001a05 771 *(to->loc) = *(current->loc);
0c7a8e5a 772
e0001a05
NC
773 *(current->loc) = current_next;
774 (*(to->loc))->header.next = to_next;
775
776 /* reset "to" list tail */
777 for (e = &to->l->head; *e != NULL; e = &(*e)->header.next)
778 ;
779 to->l->tail = e;
780
781 /* reset "current" list tail */
782 for (e = &current->l->head; *e != NULL; e = &(*e)->header.next)
783 ;
784 current->l->tail = e;
785
786#if EXTRA_VALIDATION
787 new_to_count = ld_count_children (to->parent);
788 new_current_count = ld_count_children (current->parent);
789
0c7a8e5a 790 ASSERT ((old_to_count + old_current_count)
e0001a05
NC
791 == (new_to_count + new_current_count));
792#endif
793}
794
795
796/* Can only be called with lang_statements that have lists. Returns
43cd72b9 797 FALSE if the list is empty. */
e0001a05 798
0c7a8e5a
AM
799static bfd_boolean
800iter_stack_empty (xtensa_ld_iter_stack **stack_p)
e0001a05 801{
0c7a8e5a 802 return *stack_p == NULL;
e0001a05
NC
803}
804
805
806static bfd_boolean
0c7a8e5a
AM
807iter_stack_push (xtensa_ld_iter_stack **stack_p,
808 lang_statement_union_type *parent)
e0001a05
NC
809{
810 xtensa_ld_iter_stack *stack;
811 lang_statement_list_type *l = NULL;
812
0c7a8e5a 813 switch (parent->header.type)
e0001a05
NC
814 {
815 case lang_output_section_statement_enum:
816 l = &parent->output_section_statement.children;
817 break;
818 case lang_wild_statement_enum:
819 l = &parent->wild_statement.children;
820 break;
821 case lang_group_statement_enum:
822 l = &parent->group_statement.children;
823 break;
824 default:
825 ASSERT (0);
826 return FALSE;
827 }
828
829 /* Empty. do not push. */
0c7a8e5a 830 if (l->tail == &l->head)
e0001a05
NC
831 return FALSE;
832
0c7a8e5a 833 stack = xmalloc (sizeof (xtensa_ld_iter_stack));
e0001a05
NC
834 memset (stack, 0, sizeof (xtensa_ld_iter_stack));
835 stack->iterloc.parent = parent;
836 stack->iterloc.l = l;
837 stack->iterloc.loc = &l->head;
838
839 stack->next = *stack_p;
840 stack->prev = NULL;
0c7a8e5a 841 if (*stack_p != NULL)
e0001a05
NC
842 (*stack_p)->prev = stack;
843 *stack_p = stack;
844 return TRUE;
845}
846
847
0c7a8e5a
AM
848static void
849iter_stack_pop (xtensa_ld_iter_stack **stack_p)
e0001a05
NC
850{
851 xtensa_ld_iter_stack *stack;
852
853 stack = *stack_p;
854
0c7a8e5a 855 if (stack == NULL)
e0001a05
NC
856 {
857 ASSERT (stack != NULL);
858 return;
859 }
860
0c7a8e5a 861 if (stack->next != NULL)
e0001a05
NC
862 stack->next->prev = NULL;
863
864 *stack_p = stack->next;
865 free (stack);
866}
867
868
869/* This MUST be called if, during iteration, the user changes the
870 underlying structure. It will check for a NULL current and advance
871 accordingly. */
872
873static void
0c7a8e5a 874iter_stack_update (xtensa_ld_iter_stack **stack_p)
e0001a05
NC
875{
876 if (!iter_stack_empty (stack_p)
0c7a8e5a 877 && (*(*stack_p)->iterloc.loc) == NULL)
e0001a05
NC
878 {
879 iter_stack_pop (stack_p);
880
881 while (!iter_stack_empty (stack_p)
882 && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
883 {
884 iter_stack_pop (stack_p);
885 }
886 if (!iter_stack_empty (stack_p))
887 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
888 }
889}
890
891
0c7a8e5a
AM
892static void
893iter_stack_next (xtensa_ld_iter_stack **stack_p)
e0001a05
NC
894{
895 xtensa_ld_iter_stack *stack;
896 lang_statement_union_type *current;
897 stack = *stack_p;
898
899 current = *stack->iterloc.loc;
900 /* If we are on the first element. */
0c7a8e5a 901 if (current != NULL)
e0001a05 902 {
0c7a8e5a 903 switch (current->header.type)
e0001a05
NC
904 {
905 case lang_output_section_statement_enum:
906 case lang_wild_statement_enum:
907 case lang_group_statement_enum:
908 /* If the list if not empty, we are done. */
909 if (iter_stack_push (stack_p, *stack->iterloc.loc))
910 return;
911 /* Otherwise increment the pointer as normal. */
912 break;
913 default:
914 break;
915 }
916 }
917
918 while (!iter_stack_empty (stack_p)
919 && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
920 {
921 iter_stack_pop (stack_p);
922 }
923 if (!iter_stack_empty (stack_p))
924 (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
925}
926
927
928static lang_statement_union_type *
0c7a8e5a 929iter_stack_current (xtensa_ld_iter_stack **stack_p)
e0001a05
NC
930{
931 return *((*stack_p)->iterloc.loc);
932}
933
934
935/* The iter stack is a preorder. */
936
0c7a8e5a
AM
937static void
938iter_stack_create (xtensa_ld_iter_stack **stack_p,
939 lang_statement_union_type *parent)
e0001a05
NC
940{
941 iter_stack_push (stack_p, parent);
942}
943
944
0c7a8e5a 945static void
7fa3d080 946iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front)
e0001a05
NC
947{
948 *front = (*stack_p)->iterloc;
949}
950
951
0c7a8e5a
AM
952static void
953xtensa_colocate_literals (reloc_deps_graph *deps,
954 lang_statement_union_type *statement)
e0001a05
NC
955{
956 /* Keep a stack of pointers to control iteration through the contours. */
957 xtensa_ld_iter_stack *stack = NULL;
958 xtensa_ld_iter_stack **stack_p = &stack;
959
960 xtensa_ld_iter front; /* Location where new insertion should occur. */
961 xtensa_ld_iter *front_p = NULL;
962
963 xtensa_ld_iter current; /* Location we are checking. */
964 xtensa_ld_iter *current_p = NULL;
965 bfd_boolean in_literals = FALSE;
966
967 if (deps->count == 0)
968 return;
969
e0001a05
NC
970 iter_stack_create (stack_p, statement);
971
0c7a8e5a 972 while (!iter_stack_empty (stack_p))
e0001a05
NC
973 {
974 bfd_boolean skip_increment = FALSE;
975 lang_statement_union_type *l = iter_stack_current (stack_p);
0c7a8e5a
AM
976
977 switch (l->header.type)
e0001a05
NC
978 {
979 case lang_assignment_statement_enum:
980 /* Any assignment statement should block reordering across it. */
981 front_p = NULL;
982 in_literals = FALSE;
983 break;
984
985 case lang_input_section_enum:
986 if (front_p == NULL)
987 {
988 in_literals = (section_is_target (deps, l)
989 && !section_is_source (deps, l));
0c7a8e5a 990 if (in_literals)
e0001a05
NC
991 {
992 front_p = &front;
993 iter_stack_copy_current (stack_p, front_p);
994 }
0c7a8e5a 995 }
e0001a05
NC
996 else
997 {
998 bfd_boolean is_target;
999 current_p = &current;
1000 iter_stack_copy_current (stack_p, current_p);
1001 is_target = (section_is_target (deps, l)
1002 && !section_is_source (deps, l));
1003
1004 if (in_literals)
1005 {
1006 iter_stack_copy_current (stack_p, front_p);
1007 if (!is_target)
1008 in_literals = FALSE;
1009 }
1010 else
1011 {
0c7a8e5a 1012 if (is_target)
e0001a05
NC
1013 {
1014 /* Try to insert in place. */
1015 ld_xtensa_move_section_after (front_p, current_p);
0c7a8e5a 1016 ld_assign_relative_paged_dot (0x100000,
e0001a05
NC
1017 statement,
1018 deps,
1019 xtensa_use_literal_pages);
0c7a8e5a 1020
e0001a05
NC
1021 /* We use this code because it's already written. */
1022 if (!ld_local_file_relocations_fit (statement, deps))
1023 {
1024 /* Move it back. */
1025 ld_xtensa_move_section_after (current_p, front_p);
1026 /* Reset the literal placement. */
1027 iter_stack_copy_current (stack_p, front_p);
1028 }
0c7a8e5a 1029 else
e0001a05
NC
1030 {
1031 /* Move front pointer up by one. */
1032 front_p->loc = &(*front_p->loc)->header.next;
1033
1034 /* Do not increment the current pointer. */
1035 skip_increment = TRUE;
1036 }
1037 }
1038 }
1039 }
1040 break;
1041 default:
1042 break;
1043 }
1044
1045 if (!skip_increment)
1046 iter_stack_next (stack_p);
1047 else
1048 /* Be careful to update the stack_p if it now is a null. */
1049 iter_stack_update (stack_p);
1050 }
0c7a8e5a 1051
e0001a05
NC
1052 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement);
1053}
1054
1055
0c7a8e5a
AM
1056static void
1057xtensa_move_dependencies_to_front (reloc_deps_graph *deps,
1058 lang_wild_statement_type *w)
e0001a05
NC
1059{
1060 /* Keep a front pointer and a current pointer. */
1061 lang_statement_union_type **front;
1062 lang_statement_union_type **current;
1063
1064 /* Walk to the end of the targets. */
1065 for (front = &w->children.head;
1066 (*front != NULL) && section_is_source_or_target (deps, *front);
1067 front = &(*front)->header.next)
1068 ;
1069
1070 if (*front == NULL)
1071 return;
1072
1073 current = &(*front)->header.next;
0c7a8e5a 1074 while (*current != NULL)
e0001a05
NC
1075 {
1076 if (section_is_source_or_target (deps, *current))
1077 {
1078 /* Insert in place. */
1079 xtensa_ld_iter front_iter;
1080 xtensa_ld_iter current_iter;
1081
1082 front_iter.parent = (lang_statement_union_type *) w;
1083 front_iter.l = &w->children;
1084 front_iter.loc = front;
1085
1086 current_iter.parent = (lang_statement_union_type *) w;
1087 current_iter.l = &w->children;
1088 current_iter.loc = current;
1089
1090 ld_xtensa_move_section_after (&front_iter, &current_iter);
1091 front = &(*front)->header.next;
1092 }
1093 else
1094 {
1095 current = &(*current)->header.next;
1096 }
1097 }
1098}
1099
1100
1101static bfd_boolean
7fa3d080 1102deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt)
e0001a05
NC
1103{
1104 const reloc_deps_section *sec_deps;
1105 const reloc_deps_e *sec_deps_e;
1106
1107 sec_deps = xtensa_get_section_deps (deps, src);
1108 if (sec_deps == NULL)
1109 return FALSE;
0c7a8e5a 1110
e0001a05 1111 for (sec_deps_e = sec_deps->succs;
0c7a8e5a 1112 sec_deps_e != NULL;
e0001a05
NC
1113 sec_deps_e = sec_deps_e->next)
1114 {
1115 ASSERT (sec_deps_e->src == src);
0c7a8e5a 1116 if (sec_deps_e->tgt == tgt)
e0001a05
NC
1117 return TRUE;
1118 }
1119 return FALSE;
1120}
1121
1122
1123static bfd_boolean
0c7a8e5a
AM
1124deps_has_edge (const reloc_deps_graph *deps,
1125 lang_statement_union_type *src,
1126 lang_statement_union_type *tgt)
e0001a05
NC
1127{
1128 if (!section_is_source (deps, src))
1129 return FALSE;
1130 if (!section_is_target (deps, tgt))
1131 return FALSE;
1132
1133 if (src->header.type != lang_input_section_enum)
1134 return FALSE;
1135 if (tgt->header.type != lang_input_section_enum)
1136 return FALSE;
0c7a8e5a 1137
e0001a05
NC
1138 return deps_has_sec_edge (deps, src->input_section.section,
1139 tgt->input_section.section);
1140}
1141
1142
1143static void
7fa3d080 1144add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec)
e0001a05
NC
1145{
1146 reloc_deps_section *src_sec_deps;
1147 reloc_deps_section *tgt_sec_deps;
1148
1149 reloc_deps_e *src_edge;
1150 reloc_deps_e *tgt_edge;
1151
1152 if (deps_has_sec_edge (deps, src_sec, tgt_sec))
1153 return;
0c7a8e5a 1154
e0001a05
NC
1155 src_sec_deps = xtensa_get_section_deps (deps, src_sec);
1156 if (src_sec_deps == NULL)
1157 {
1158 /* Add a section. */
0c7a8e5a 1159 src_sec_deps = xmalloc (sizeof (reloc_deps_section));
e0001a05
NC
1160 memset (src_sec_deps, 0, sizeof (reloc_deps_section));
1161 src_sec_deps->is_only_literal = 0;
1162 src_sec_deps->preds = NULL;
1163 src_sec_deps->succs = NULL;
1164 xtensa_set_section_deps (deps, src_sec, src_sec_deps);
1165 xtensa_append_section_deps (deps, src_sec);
1166 }
1167
1168 tgt_sec_deps = xtensa_get_section_deps (deps, tgt_sec);
1169 if (tgt_sec_deps == NULL)
1170 {
1171 /* Add a section. */
0c7a8e5a 1172 tgt_sec_deps = xmalloc (sizeof (reloc_deps_section));
e0001a05
NC
1173 memset (tgt_sec_deps, 0, sizeof (reloc_deps_section));
1174 tgt_sec_deps->is_only_literal = 0;
1175 tgt_sec_deps->preds = NULL;
1176 tgt_sec_deps->succs = NULL;
1177 xtensa_set_section_deps (deps, tgt_sec, tgt_sec_deps);
1178 xtensa_append_section_deps (deps, tgt_sec);
1179 }
1180
1181 /* Add the edges. */
0c7a8e5a 1182 src_edge = xmalloc (sizeof (reloc_deps_e));
e0001a05
NC
1183 memset (src_edge, 0, sizeof (reloc_deps_e));
1184 src_edge->src = src_sec;
1185 src_edge->tgt = tgt_sec;
1186 src_edge->next = src_sec_deps->succs;
1187 src_sec_deps->succs = src_edge;
1188
0c7a8e5a 1189 tgt_edge = xmalloc (sizeof (reloc_deps_e));
e0001a05
NC
1190 memset (tgt_edge, 0, sizeof (reloc_deps_e));
1191 tgt_edge->src = src_sec;
1192 tgt_edge->tgt = tgt_sec;
1193 tgt_edge->next = tgt_sec_deps->preds;
1194 tgt_sec_deps->preds = tgt_edge;
1195}
1196
1197
0c7a8e5a
AM
1198static void
1199build_deps_graph_callback (asection *src_sec,
1200 bfd_vma src_offset ATTRIBUTE_UNUSED,
1201 asection *target_sec,
1202 bfd_vma target_offset ATTRIBUTE_UNUSED,
1203 void *closure)
e0001a05 1204{
0c7a8e5a 1205 reloc_deps_graph *deps = closure;
e0001a05
NC
1206
1207 /* If the target is defined. */
1208 if (target_sec != NULL)
1209 add_deps_edge (deps, src_sec, target_sec);
1210}
1211
1212
0c7a8e5a
AM
1213static reloc_deps_graph *
1214ld_build_required_section_dependence (lang_statement_union_type *s)
e0001a05
NC
1215{
1216 reloc_deps_graph *deps;
1217 xtensa_ld_iter_stack *stack = NULL;
1218
0c7a8e5a 1219 deps = xmalloc (sizeof (reloc_deps_graph));
e0001a05
NC
1220 deps->sections = NULL;
1221 deps->count = 0;
1222 deps->size = 0;
0c7a8e5a 1223
e0001a05
NC
1224 for (iter_stack_create (&stack, s);
1225 !iter_stack_empty (&stack);
0c7a8e5a 1226 iter_stack_next (&stack))
e0001a05
NC
1227 {
1228 lang_statement_union_type *l = iter_stack_current (&stack);
1229
1230 if (l->header.type == lang_input_section_enum)
1231 {
1232 lang_input_section_type *input;
1233 input = &l->input_section;
7b986e99 1234 xtensa_callback_required_dependence (input->section->owner,
e0001a05
NC
1235 input->section,
1236 &link_info,
1237 /* Use the same closure. */
1238 build_deps_graph_callback,
0c7a8e5a 1239 deps);
e0001a05
NC
1240 }
1241 }
1242 return deps;
1243}
1244
1245
1246#if EXTRA_VALIDATION
0c7a8e5a
AM
1247static size_t
1248ld_count_children (lang_statement_union_type *s)
e0001a05
NC
1249{
1250 size_t count = 0;
1251 xtensa_ld_iter_stack *stack = NULL;
1252 for (iter_stack_create (&stack, s);
1253 !iter_stack_empty (&stack);
0c7a8e5a 1254 iter_stack_next (&stack))
e0001a05
NC
1255 {
1256 lang_statement_union_type *l = iter_stack_current (&stack);
1257 ASSERT (l != NULL);
1258 count++;
1259 }
1260 return count;
1261}
1262#endif /* EXTRA_VALIDATION */
1263
1264
a255b6c7
BW
1265/* Check if a particular section is included in the link. This will only
1266 be true for one instance of a particular linkonce section. */
1267
1268static bfd_boolean input_section_found = FALSE;
1269static asection *input_section_target = NULL;
1270
1271static void
1272input_section_linked_worker (lang_statement_union_type *statement)
1273{
1274 if ((statement->header.type == lang_input_section_enum
1275 && (statement->input_section.section == input_section_target)))
1276 input_section_found = TRUE;
1277}
1278
1279static bfd_boolean
1280input_section_linked (asection *sec)
1281{
1282 input_section_found = FALSE;
1283 input_section_target = sec;
1284 lang_for_each_statement_worker (input_section_linked_worker, stat_ptr->head);
1285 return input_section_found;
1286}
1287
1288
a77dc2cc 1289/* Strip out any linkonce property tables or XCC exception tables where the
a255b6c7
BW
1290 associated linkonce text is from a different object file. Normally,
1291 a matching set of linkonce sections is taken from the same object file,
1292 but sometimes the files are compiled differently so that some of the
1293 linkonce sections are not present in all files. Stripping the
1294 inconsistent sections like this is not completely robust -- a much
1295 better solution is to use comdat groups. */
1296
1297static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
1298
1299static bfd_boolean
1300is_inconsistent_linkonce_section (asection *sec)
1301{
1302 bfd *abfd = sec->owner;
1303 const char *sec_name = bfd_get_section_name (abfd, sec);
a77dc2cc 1304 const char *name;
a255b6c7
BW
1305
1306 if ((bfd_get_section_flags (abfd, sec) & SEC_LINK_ONCE) == 0
1307 || strncmp (sec_name, ".gnu.linkonce.", linkonce_len) != 0)
1308 return FALSE;
1309
a77dc2cc
BW
1310 /* Check if this is an Xtensa property section or an exception table
1311 for Tensilica's XCC compiler. */
1312 name = sec_name + linkonce_len;
1313 if (CONST_STRNEQ (name, "prop."))
1314 name = strchr (name + 5, '.') + 1;
1315 else if (name[1] == '.'
1316 && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h'))
1317 name += 2;
1318 else
1319 name = 0;
644143c8
BW
1320
1321 if (name)
a255b6c7 1322 {
644143c8 1323 char *dep_sec_name = xmalloc (strlen (sec_name) + 1);
a255b6c7
BW
1324 asection *dep_sec;
1325
1326 /* Get the associated linkonce text section and check if it is
1327 included in the link. If not, this section is inconsistent
1328 and should be stripped. */
644143c8
BW
1329 strcpy (dep_sec_name, ".gnu.linkonce.t.");
1330 strcat (dep_sec_name, name);
a255b6c7
BW
1331 dep_sec = bfd_get_section_by_name (abfd, dep_sec_name);
1332 if (dep_sec == NULL || ! input_section_linked (dep_sec))
1333 {
1334 free (dep_sec_name);
1335 return TRUE;
1336 }
1337 free (dep_sec_name);
1338 }
1339
1340 return FALSE;
1341}
1342
1343
1344static void
1345xtensa_strip_inconsistent_linkonce_sections (lang_statement_list_type *slist)
1346{
1347 lang_statement_union_type **s_p = &slist->head;
1348 while (*s_p)
1349 {
1350 lang_statement_union_type *s = *s_p;
1351 lang_statement_union_type *s_next = (*s_p)->header.next;
1352
1353 switch (s->header.type)
1354 {
1355 case lang_input_section_enum:
1356 if (is_inconsistent_linkonce_section (s->input_section.section))
1357 {
b2f28975 1358 s->input_section.section->output_section = bfd_abs_section_ptr;
a255b6c7
BW
1359 *s_p = s_next;
1360 continue;
1361 }
1362 break;
1363
1364 case lang_constructors_statement_enum:
1365 xtensa_strip_inconsistent_linkonce_sections (&constructor_list);
1366 break;
1367
1368 case lang_output_section_statement_enum:
1369 if (s->output_section_statement.children.head)
1370 xtensa_strip_inconsistent_linkonce_sections
1371 (&s->output_section_statement.children);
1372 break;
1373
1374 case lang_wild_statement_enum:
1375 xtensa_strip_inconsistent_linkonce_sections
1376 (&s->wild_statement.children);
1377 break;
1378
1379 case lang_group_statement_enum:
1380 xtensa_strip_inconsistent_linkonce_sections
1381 (&s->group_statement.children);
1382 break;
1383
1384 case lang_data_statement_enum:
1385 case lang_reloc_statement_enum:
1386 case lang_object_symbols_statement_enum:
1387 case lang_output_statement_enum:
1388 case lang_target_statement_enum:
1389 case lang_input_statement_enum:
1390 case lang_assignment_statement_enum:
1391 case lang_padding_statement_enum:
1392 case lang_address_statement_enum:
1393 case lang_fill_statement_enum:
1394 break;
1395
1396 default:
1397 FAIL ();
1398 break;
1399 }
1400
1401 s_p = &(*s_p)->header.next;
1402 }
1403
1404 /* Reset the tail of the list, in case the last entry was removed. */
1405 if (s_p != slist->tail)
1406 slist->tail = s_p;
1407}
1408
1409
0c7a8e5a
AM
1410static void
1411xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
e0001a05
NC
1412{
1413 lang_wild_statement_type *w;
1414 reloc_deps_graph *deps;
1415 if (statement->header.type == lang_wild_statement_enum)
1416 {
1417#if EXTRA_VALIDATION
1418 size_t old_child_count;
1419 size_t new_child_count;
1420#endif
1421 bfd_boolean no_reorder;
1422
1423 w = &statement->wild_statement;
1424
1425 no_reorder = FALSE;
1426
1427 /* If it has 0 or 1 section bound, then do not reorder. */
1428 if (w->children.head == NULL
1429 || (w->children.head->header.type == lang_input_section_enum
1430 && w->children.head->header.next == NULL))
1431 no_reorder = TRUE;
1432
1433 if (w->filenames_sorted)
1434 no_reorder = TRUE;
1435
1436 /* Check for sorting in a section list wildcard spec as well. */
1437 if (!no_reorder)
1438 {
1439 struct wildcard_list *l;
1440 for (l = w->section_list; l != NULL; l = l->next)
1441 {
1442 if (l->spec.sorted == TRUE)
1443 {
1444 no_reorder = TRUE;
1445 break;
1446 }
1447 }
0c7a8e5a 1448 }
e0001a05
NC
1449
1450 /* Special case until the NOREORDER linker directive is supported:
0c7a8e5a 1451 *(.init) output sections and *(.fini) specs may NOT be reordered. */
e0001a05
NC
1452
1453 /* Check for sorting in a section list wildcard spec as well. */
0c7a8e5a 1454 if (!no_reorder)
e0001a05
NC
1455 {
1456 struct wildcard_list *l;
1457 for (l = w->section_list; l != NULL; l = l->next)
1458 {
1459 if (l->spec.name
1460 && ((strcmp (".init", l->spec.name) == 0)
1461 || (strcmp (".fini", l->spec.name) == 0)))
1462 {
1463 no_reorder = TRUE;
1464 break;
1465 }
1466 }
1467 }
1468
1469#if EXTRA_VALIDATION
1470 old_child_count = ld_count_children (statement);
1471#endif
1472
1473 /* It is now officially a target. Build the graph of source
0c7a8e5a 1474 section -> target section (kept as a list of edges). */
e0001a05
NC
1475 deps = ld_build_required_section_dependence (statement);
1476
1477 /* If this wildcard does not reorder.... */
1478 if (!no_reorder && deps->count != 0)
1479 {
1480 /* First check for reverse dependences. Fix if possible. */
1481 xtensa_layout_wild (deps, w);
1482
1483 xtensa_move_dependencies_to_front (deps, w);
1484#if EXTRA_VALIDATION
1485 new_child_count = ld_count_children (statement);
1486 ASSERT (new_child_count == old_child_count);
1487#endif
1488
1489 xtensa_colocate_literals (deps, statement);
1490
1491#if EXTRA_VALIDATION
1492 new_child_count = ld_count_children (statement);
1493 ASSERT (new_child_count == old_child_count);
1494#endif
1495 }
1496
1497 /* Clean up. */
1498 free_reloc_deps_graph (deps);
1499 }
1500}
1501
1502
0c7a8e5a
AM
1503static void
1504xtensa_wild_group_interleave (lang_statement_union_type *s)
e0001a05
NC
1505{
1506 lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s);
1507}
1508
1509
0c7a8e5a 1510static void
7fa3d080 1511xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w)
e0001a05
NC
1512{
1513 /* If it does not fit initially, we need to do this step. Move all
1514 of the wild literal sections to a new list, then move each of
1515 them back in just before the first section they depend on. */
1516 lang_statement_union_type **s_p;
1517#if EXTRA_VALIDATION
1518 size_t old_count, new_count;
1519 size_t ct1, ct2;
1520#endif
0c7a8e5a 1521
e0001a05
NC
1522 lang_wild_statement_type literal_wild;
1523 literal_wild.header.next = NULL;
1524 literal_wild.header.type = lang_wild_statement_enum;
1525 literal_wild.filename = NULL;
1526 literal_wild.filenames_sorted = FALSE;
1527 literal_wild.section_list = NULL;
1528 literal_wild.keep_sections = FALSE;
1529 literal_wild.children.head = NULL;
1530 literal_wild.children.tail = &literal_wild.children.head;
1531
1532#if EXTRA_VALIDATION
1533 old_count = ld_count_children ((lang_statement_union_type*) w);
1534#endif
1535
1536 s_p = &w->children.head;
1537 while (*s_p != NULL)
1538 {
1539 lang_statement_union_type *l = *s_p;
1540 if (l->header.type == lang_input_section_enum)
1541 {
1542 if (section_is_target (deps, l)
0c7a8e5a 1543 && ! section_is_source (deps, l))
e0001a05
NC
1544 {
1545 /* Detach. */
1546 *s_p = l->header.next;
1547 if (*s_p == NULL)
1548 w->children.tail = s_p;
1549 l->header.next = NULL;
1550
1551 /* Append. */
1552 *literal_wild.children.tail = l;
1553 literal_wild.children.tail = &l->header.next;
1554 continue;
0c7a8e5a 1555 }
e0001a05
NC
1556 }
1557 s_p = &(*s_p)->header.next;
1558 }
1559
1560#if EXTRA_VALIDATION
1561 ct1 = ld_count_children ((lang_statement_union_type*) w);
1562 ct2 = ld_count_children ((lang_statement_union_type*) &literal_wild);
0c7a8e5a 1563
e0001a05
NC
1564 ASSERT (old_count == (ct1 + ct2));
1565#endif
0c7a8e5a 1566
e0001a05
NC
1567 /* Now place them back in front of their dependent sections. */
1568
1569 while (literal_wild.children.head != NULL)
1570 {
1571 lang_statement_union_type *lit = literal_wild.children.head;
1572 bfd_boolean placed = FALSE;
1573
1574#if EXTRA_VALIDATION
1575 ASSERT (ct2 > 0);
1576 ct2--;
1577#endif
1578
1579 /* Detach. */
1580 literal_wild.children.head = lit->header.next;
0c7a8e5a 1581 if (literal_wild.children.head == NULL)
e0001a05
NC
1582 literal_wild.children.tail = &literal_wild.children.head;
1583 lit->header.next = NULL;
1584
1585 /* Find a spot to place it. */
0c7a8e5a 1586 for (s_p = &w->children.head; *s_p != NULL; s_p = &(*s_p)->header.next)
e0001a05
NC
1587 {
1588 lang_statement_union_type *src = *s_p;
1589 if (deps_has_edge (deps, src, lit))
1590 {
1591 /* Place it here. */
1592 lit->header.next = *s_p;
1593 *s_p = lit;
1594 placed = TRUE;
1595 break;
1596 }
1597 }
0c7a8e5a 1598
e0001a05
NC
1599 if (!placed)
1600 {
1601 /* Put it at the end. */
1602 *w->children.tail = lit;
1603 w->children.tail = &lit->header.next;
1604 }
1605 }
1606
1607#if EXTRA_VALIDATION
1608 new_count = ld_count_children ((lang_statement_union_type*) w);
1609 ASSERT (new_count == old_count);
1610#endif
1611}
1612
1613
0c7a8e5a
AM
1614static void
1615xtensa_colocate_output_literals_callback (lang_statement_union_type *statement)
e0001a05 1616{
e0001a05
NC
1617 reloc_deps_graph *deps;
1618 if (statement->header.type == lang_output_section_statement_enum)
1619 {
1620 /* Now, we walk over the contours of the output section statement.
1621
1622 First we build the literal section dependences as before.
1623
1624 At the first uniquely_literal section, we mark it as a good
1625 spot to place other literals. Continue walking (and counting
1626 sizes) until we find the next literal section. If this
1627 section can be moved to the first one, then we move it. If
1628 we every find a modification of ".", start over. If we find
1629 a labeling of the current location, start over. Finally, at
1630 the end, if we require page alignment, add page alignments. */
1631
1632#if EXTRA_VALIDATION
1633 size_t old_child_count;
1634 size_t new_child_count;
1635#endif
1636 bfd_boolean no_reorder = FALSE;
1637
e0001a05
NC
1638#if EXTRA_VALIDATION
1639 old_child_count = ld_count_children (statement);
1640#endif
1641
1642 /* It is now officially a target. Build the graph of source
0c7a8e5a 1643 section -> target section (kept as a list of edges). */
e0001a05
NC
1644
1645 deps = ld_build_required_section_dependence (statement);
1646
1647 /* If this wildcard does not reorder.... */
1648 if (!no_reorder)
1649 {
1650 /* First check for reverse dependences. Fix if possible. */
1651 xtensa_colocate_literals (deps, statement);
1652
1653#if EXTRA_VALIDATION
1654 new_child_count = ld_count_children (statement);
1655 ASSERT (new_child_count == old_child_count);
1656#endif
1657 }
1658
1659 /* Insert align/offset assignment statement. */
1660 if (xtensa_use_literal_pages)
1661 {
0c7a8e5a 1662 ld_xtensa_insert_page_offsets (0, statement, deps,
e0001a05
NC
1663 xtensa_use_literal_pages);
1664 lang_for_each_statement_worker (xtensa_ldlang_clear_addresses,
1665 statement);
1666 }
1667
1668 /* Clean up. */
1669 free_reloc_deps_graph (deps);
1670 }
1671}
1672
1673
0c7a8e5a
AM
1674static void
1675xtensa_colocate_output_literals (lang_statement_union_type *s)
e0001a05
NC
1676{
1677 lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s);
1678}
1679
1680
0c7a8e5a
AM
1681static void
1682xtensa_ldlang_clear_addresses (lang_statement_union_type *statement)
e0001a05
NC
1683{
1684 switch (statement->header.type)
1685 {
0c7a8e5a 1686 case lang_input_section_enum:
e0001a05
NC
1687 {
1688 asection *bfd_section = statement->input_section.section;
1689 bfd_section->output_offset = 0;
1690 }
1691 break;
1692 default:
1693 break;
1694 }
1695}
1696
1697
0c7a8e5a
AM
1698static bfd_vma
1699ld_assign_relative_paged_dot (bfd_vma dot,
1700 lang_statement_union_type *s,
1701 const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
1702 bfd_boolean lit_align)
e0001a05
NC
1703{
1704 /* Walk through all of the input statements in this wild statement
1705 assign dot to all of them. */
0c7a8e5a 1706
e0001a05
NC
1707 xtensa_ld_iter_stack *stack = NULL;
1708 xtensa_ld_iter_stack **stack_p = &stack;
1709
1710 bfd_boolean first_section = FALSE;
1711 bfd_boolean in_literals = FALSE;
1712
1713 for (iter_stack_create (stack_p, s);
1714 !iter_stack_empty (stack_p);
0c7a8e5a 1715 iter_stack_next (stack_p))
e0001a05
NC
1716 {
1717 lang_statement_union_type *l = iter_stack_current (stack_p);
0c7a8e5a
AM
1718
1719 switch (l->header.type)
e0001a05
NC
1720 {
1721 case lang_input_section_enum:
1722 {
1723 asection *section = l->input_section.section;
1724 size_t align_pow = section->alignment_power;
1725 bfd_boolean do_xtensa_alignment = FALSE;
0c7a8e5a 1726
e0001a05
NC
1727 if (lit_align)
1728 {
1729 bfd_boolean sec_is_target = section_is_target (deps, l);
1730 bfd_boolean sec_is_source = section_is_source (deps, l);
1731
eea6121a 1732 if (section->size != 0
e0001a05
NC
1733 && (first_section
1734 || (in_literals && !sec_is_target)
1735 || (!in_literals && sec_is_target)))
1736 {
1737 do_xtensa_alignment = TRUE;
1738 }
1739 first_section = FALSE;
eea6121a 1740 if (section->size != 0)
e0001a05
NC
1741 in_literals = (sec_is_target && !sec_is_source);
1742 }
1743
1744 if (do_xtensa_alignment && xtensa_page_power != 0)
1745 dot += (1 << xtensa_page_power);
1746
1747 dot = align_power (dot, align_pow);
1748 section->output_offset = dot;
eea6121a 1749 dot += section->size;
e0001a05
NC
1750 }
1751 break;
1752 case lang_fill_statement_enum:
1753 dot += l->fill_statement.size;
1754 break;
1755 case lang_padding_statement_enum:
1756 dot += l->padding_statement.size;
1757 break;
1758 default:
1759 break;
1760 }
1761 }
1762 return dot;
1763}
1764
1765
0c7a8e5a
AM
1766static bfd_boolean
1767ld_local_file_relocations_fit (lang_statement_union_type *statement,
1768 const reloc_deps_graph *deps ATTRIBUTE_UNUSED)
e0001a05
NC
1769{
1770 /* Walk over all of the dependencies that we identified and make
1771 sure that IF the source and target are here (addr != 0):
1772 1) target addr < source addr
0c7a8e5a 1773 2) (roundup(source + source_size, 4) - rounddown(target, 4))
e0001a05
NC
1774 < (256K - (1 << bad align))
1775 Need a worst-case proof.... */
0c7a8e5a 1776
e0001a05
NC
1777 xtensa_ld_iter_stack *stack = NULL;
1778 xtensa_ld_iter_stack **stack_p = &stack;
1779 size_t max_align_power = 0;
1780 size_t align_penalty = 256;
1781 reloc_deps_e *e;
1782 size_t i;
1783
1784 /* Find the worst-case alignment requirement for this set of statements. */
1785 for (iter_stack_create (stack_p, statement);
1786 !iter_stack_empty (stack_p);
0c7a8e5a 1787 iter_stack_next (stack_p))
e0001a05
NC
1788 {
1789 lang_statement_union_type *l = iter_stack_current (stack_p);
0c7a8e5a 1790 if (l->header.type == lang_input_section_enum)
e0001a05
NC
1791 {
1792 lang_input_section_type *input = &l->input_section;
1793 asection *section = input->section;
1794 if (section->alignment_power > max_align_power)
1795 max_align_power = section->alignment_power;
1796 }
1797 }
1798
1799 /* Now check that everything fits. */
1800 for (i = 0; i < deps->count; i++)
1801 {
1802 asection *sec = deps->sections[i];
0c7a8e5a 1803 const reloc_deps_section *deps_section =
e0001a05
NC
1804 xtensa_get_section_deps (deps, sec);
1805 if (deps_section)
1806 {
1807 /* We choose to walk through the successors. */
1808 for (e = deps_section->succs; e != NULL; e = e->next)
1809 {
0c7a8e5a 1810 if (e->src != e->tgt
e0001a05
NC
1811 && e->src->output_section == e->tgt->output_section
1812 && e->src->output_offset != 0
1813 && e->tgt->output_offset != 0)
1814 {
0c7a8e5a 1815 bfd_vma l32r_addr =
eea6121a 1816 align_power (e->src->output_offset + e->src->size, 2);
0c7a8e5a 1817 bfd_vma target_addr = e->tgt->output_offset & ~3;
e0001a05
NC
1818 if (l32r_addr < target_addr)
1819 {
1820 fprintf (stderr, "Warning: "
1821 "l32r target section before l32r\n");
1822 return FALSE;
1823 }
1824
0c7a8e5a 1825 if (l32r_addr - target_addr > 256 * 1024 - align_penalty)
e0001a05
NC
1826 return FALSE;
1827 }
1828 }
1829 }
1830 }
1831
1832 return TRUE;
1833}
1834
1835
0c7a8e5a
AM
1836static bfd_vma
1837ld_xtensa_insert_page_offsets (bfd_vma dot,
1838 lang_statement_union_type *s,
1839 reloc_deps_graph *deps,
1840 bfd_boolean lit_align)
e0001a05
NC
1841{
1842 xtensa_ld_iter_stack *stack = NULL;
1843 xtensa_ld_iter_stack **stack_p = &stack;
1844
1845 bfd_boolean first_section = FALSE;
1846 bfd_boolean in_literals = FALSE;
0c7a8e5a 1847
e0001a05
NC
1848 if (!lit_align)
1849 return FALSE;
1850
1851 for (iter_stack_create (stack_p, s);
1852 !iter_stack_empty (stack_p);
0c7a8e5a 1853 iter_stack_next (stack_p))
e0001a05
NC
1854 {
1855 lang_statement_union_type *l = iter_stack_current (stack_p);
1856
0c7a8e5a
AM
1857 switch (l->header.type)
1858 {
e0001a05
NC
1859 case lang_input_section_enum:
1860 {
1861 asection *section = l->input_section.section;
1862 bfd_boolean do_xtensa_alignment = FALSE;
0c7a8e5a 1863
e0001a05
NC
1864 if (lit_align)
1865 {
eea6121a 1866 if (section->size != 0
e0001a05
NC
1867 && (first_section
1868 || (in_literals && !section_is_target (deps, l))
1869 || (!in_literals && section_is_target (deps, l))))
1870 {
1871 do_xtensa_alignment = TRUE;
1872 }
1873 first_section = FALSE;
eea6121a 1874 if (section->size != 0)
e0001a05
NC
1875 {
1876 in_literals = (section_is_target (deps, l)
1877 && !section_is_source (deps, l));
1878 }
1879 }
1880
1881 if (do_xtensa_alignment && xtensa_page_power != 0)
1882 {
1883 /* Create an expression that increments the current address,
1884 i.e., "dot", by (1 << xtensa_align_power). */
1885 etree_type *name_op = exp_nameop (NAME, ".");
1886 etree_type *addend_op = exp_intop (1 << xtensa_page_power);
1887 etree_type *add_op = exp_binop ('+', name_op, addend_op);
1888 etree_type *assign_op = exp_assop ('=', ".", add_op);
1889
1890 lang_assignment_statement_type *assign_stmt;
1891 lang_statement_union_type *assign_union;
1892 lang_statement_list_type tmplist;
0c7a8e5a 1893
e0001a05
NC
1894 /* There is hidden state in "lang_add_assignment". It
1895 appends the new assignment statement to the stat_ptr
1896 list. Thus, we swap it before and after the call. */
1897
bde18da4
AM
1898 lang_list_init (&tmplist);
1899 push_stat_ptr (&tmplist);
e0001a05
NC
1900 /* Warning: side effect; statement appended to stat_ptr. */
1901 assign_stmt = lang_add_assignment (assign_op);
1902 assign_union = (lang_statement_union_type *) assign_stmt;
bde18da4 1903 pop_stat_ptr ();
e0001a05
NC
1904
1905 assign_union->header.next = l;
1906 *(*stack_p)->iterloc.loc = assign_union;
1907 iter_stack_next (stack_p);
0c7a8e5a
AM
1908 }
1909 }
1910 break;
1911 default:
1912 break;
1913 }
e0001a05
NC
1914 }
1915 return dot;
1916}
1917
1918EOF
1919
43cd72b9 1920# Define some shell vars to insert bits of code into the standard ELF
e0001a05
NC
1921# parse_args and list_options functions.
1922#
1923PARSE_AND_LIST_PROLOGUE='
43cd72b9 1924#define OPTION_OPT_SIZEOPT (300)
28d5f677 1925#define OPTION_LITERAL_MOVEMENT (OPTION_OPT_SIZEOPT + 1)
43cd72b9
BW
1926#define OPTION_NO_LITERAL_MOVEMENT (OPTION_LITERAL_MOVEMENT + 1)
1927extern int elf32xtensa_size_opt;
1928extern int elf32xtensa_no_literal_movement;
e0001a05
NC
1929'
1930
1931PARSE_AND_LIST_LONGOPTS='
43cd72b9 1932 { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT},
43cd72b9
BW
1933 { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT},
1934 { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
e0001a05
NC
1935'
1936
1937PARSE_AND_LIST_OPTIONS='
442996ee
AM
1938 fprintf (file, _("\
1939 --size-opt When relaxing longcalls, prefer size\n\
1940 optimization over branch target alignment\n"));
e0001a05
NC
1941'
1942
1943PARSE_AND_LIST_ARGS_CASES='
43cd72b9
BW
1944 case OPTION_OPT_SIZEOPT:
1945 elf32xtensa_size_opt = 1;
1946 break;
43cd72b9
BW
1947 case OPTION_LITERAL_MOVEMENT:
1948 elf32xtensa_no_literal_movement = 0;
1949 break;
1950 case OPTION_NO_LITERAL_MOVEMENT:
1951 elf32xtensa_no_literal_movement = 1;
1952 break;
e0001a05
NC
1953'
1954
1955# Replace some of the standard ELF functions with our own versions.
1956#
1957LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse
43cd72b9 1958LDEMUL_AFTER_OPEN=elf_xtensa_after_open
e0001a05 1959LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target
e0001a05 1960LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation
This page took 0.432885 seconds and 4 git commands to generate.