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