Second part of ms1 to mt renaming.
[binutils.git] / ld / emultempl / xtensaelf.em
blob6773fb8bfd7177a42c82977db3e91bf2781278f1
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 2003, 2004, 2005
3 #   Free Software Foundation, Inc.
5 # This file is part of GLD, the Gnu Linker.
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.
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.
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.
22 # This file is sourced from elf32.em, and defines extra xtensa-elf
23 # specific routines.
25 cat >>e${EMULATION_NAME}.c <<EOF
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"
33 static void xtensa_wild_group_interleave (lang_statement_union_type *);
34 static void xtensa_colocate_output_literals (lang_statement_union_type *);
37 /* Flag for the emulation-specific "--no-relax" option.  */
38 static bfd_boolean disable_relaxation = FALSE;
40 /* This number is irrelevant until we turn on use_literal_pages */
41 static bfd_vma xtensa_page_power = 12; /* 4K pages.  */
43 /* To force a page break between literals and text, change
44    xtensa_use_literal_pages to "TRUE".  */
45 static bfd_boolean xtensa_use_literal_pages = FALSE;
47 #define EXTRA_VALIDATION 0
50 static char *
51 elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
52                           char **argv ATTRIBUTE_UNUSED)
54   if (XCHAL_HAVE_BE)
55     return "${BIG_OUTPUT_FORMAT}";
56   else
57     return "${LITTLE_OUTPUT_FORMAT}";
61 static bfd_boolean
62 elf_xtensa_place_orphan (asection *s)
64   /* Early exit for relocatable links.  */
65   if (link_info.relocatable)
66     return FALSE;
68   return gld${EMULATION_NAME}_place_orphan (s);
72 static void
73 elf_xtensa_before_parse (void)
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 ();
81 static void
82 remove_section (bfd *abfd, asection *os)
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       }
95 static bfd_boolean
96 replace_insn_sec_with_prop_sec (bfd *abfd,
97                                 const char *insn_sec_name,
98                                 const char *prop_sec_name,
99                                 char **error_message)
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;
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;
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     }
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;
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;
170   if (prop_contents == NULL && prop_sec->size != 0)
171     {
172       *error_message = _("could not allocate section contents");
173       goto cleanup;
174     }
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     }
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     }
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;
225       for (i = 0; i < reloc_count; i++)
226         {
227           Elf_Internal_Rela *rela;
228           unsigned r_offset;
230           rela = &internal_relocs[i];
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     }
240   remove_section (abfd, insn_sec);
241   
242   if (insn_contents)
243     free (insn_contents);
244   
245   return TRUE;
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);
255   return FALSE;
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."
264 static void
265 replace_instruction_table_sections (bfd *abfd, asection *sec)
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);
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.  */
307 static void
308 elf_xtensa_after_open (void)
310   bfd *abfd;
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;
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     }
335 /* This is called after the sections have been attached to output
336    sections, but before any sizes or addresses have been set.  */
338 static void
339 elf_xtensa_before_allocation (void)
341   bfd *in_bfd;
342   bfd_boolean is_big_endian = XCHAL_HAVE_BE;
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.  */
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     }
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.  */
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     }
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.  */
381   if (!disable_relaxation)
382     command_line.relax = TRUE;
384   gld${EMULATION_NAME}_before_allocation ();
386   xtensa_wild_group_interleave (stat_ptr->head);
387   if (command_line.relax)
388     xtensa_colocate_output_literals (stat_ptr->head);
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.  */
397 typedef struct wildcard_list section_name_list;
399 typedef struct reloc_deps_e_t reloc_deps_e;
400 typedef struct reloc_deps_section_t reloc_deps_section;
401 typedef struct reloc_deps_graph_t reloc_deps_graph;
404 struct reloc_deps_e_t
406   asection *src; /* Contains l32rs.  */
407   asection *tgt; /* Contains literals.  */
408   reloc_deps_e *next;
411 /* Place these in the userdata field.  */
412 struct reloc_deps_section_t
414   reloc_deps_e *preds;
415   reloc_deps_e *succs;
416   bfd_boolean is_only_literal;
420 struct reloc_deps_graph_t
422   size_t count;
423   size_t size;
424   asection **sections;
427 static void xtensa_layout_wild
428   (const reloc_deps_graph *, lang_wild_statement_type *);
430 typedef void (*deps_callback_t) (asection *, /* src_sec */
431                                  bfd_vma,    /* src_offset */
432                                  asection *, /* target_sec */
433                                  bfd_vma,    /* target_offset */
434                                  void *);    /* closure */
436 extern bfd_boolean xtensa_callback_required_dependence
437   (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
438 static void xtensa_ldlang_clear_addresses (lang_statement_union_type *);
439 static bfd_boolean ld_local_file_relocations_fit
440   (lang_statement_union_type *, const reloc_deps_graph *);
441 static bfd_vma ld_assign_relative_paged_dot
442   (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *,
443    bfd_boolean);
444 static bfd_vma ld_xtensa_insert_page_offsets
445   (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean);
446 #if EXTRA_VALIDATION
447 static size_t ld_count_children (lang_statement_union_type *);
448 #endif
450 extern lang_statement_list_type constructor_list;
452 /*  Begin verbatim code from ldlang.c:
453     the following are copied from ldlang.c because they are defined
454     there statically.  */
456 static void
457 lang_for_each_statement_worker (void (*func) (lang_statement_union_type *),
458                                 lang_statement_union_type *s)
460   for (; s != (lang_statement_union_type *) NULL; s = s->header.next)
461     {
462       func (s);
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     }
502 /* End of verbatim code from ldlang.c.  */
505 static reloc_deps_section *
506 xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
507                          asection *sec)
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;
517 static void
518 xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
519                          asection *sec,
520                          reloc_deps_section *deps_section)
522   sec->userdata = deps_section;
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.  */
529 static void
530 xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec)
532   if (deps->size <= deps->count)
533     {
534       asection **new_sections;
535       size_t i;
536       size_t new_size;
538       new_size = deps->size * 2;
539       if (new_size == 0)
540         new_size = 20;
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++;
558 static void
559 free_reloc_deps_graph (reloc_deps_graph *deps)
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             }
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);
590   free (deps);
594 static bfd_boolean
595 section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
596                    lang_statement_union_type *s)
598   asection *sec;
599   const reloc_deps_section *sec_deps;
601   if (s->header.type != lang_input_section_enum)
602     return FALSE;
603   sec = s->input_section.section;
605   sec_deps = xtensa_get_section_deps (deps, sec);
606   return sec_deps && sec_deps->succs != NULL;
610 static bfd_boolean
611 section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
612                    lang_statement_union_type *s)
614   asection *sec;
615   const reloc_deps_section *sec_deps;
617   if (s->header.type != lang_input_section_enum)
618     return FALSE;
619   sec = s->input_section.section;
621   sec_deps = xtensa_get_section_deps (deps, sec);
622   return sec_deps && sec_deps->preds != NULL;
626 static bfd_boolean
627 section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
628                              lang_statement_union_type *s)
630   return (section_is_source (deps, s)
631           || section_is_target (deps, s));
635 typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack;
636 typedef struct xtensa_ld_iter_t xtensa_ld_iter;
638 struct xtensa_ld_iter_t
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.  */
645 struct xtensa_ld_iter_stack_t
647   xtensa_ld_iter iterloc;               /* List that hold it.  */
649   xtensa_ld_iter_stack *next;           /* Next in the stack.  */
650   xtensa_ld_iter_stack *prev;           /* Back pointer for stack.  */
654 static void
655 ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current)
657   lang_statement_union_type *to_next;
658   lang_statement_union_type *current_next;
659   lang_statement_union_type **e;
661 #if EXTRA_VALIDATION
662   size_t old_to_count, new_to_count;
663   size_t old_current_count, new_current_count;
664 #endif
666   if (to == current)
667     return;
669 #if EXTRA_VALIDATION
670   old_to_count = ld_count_children (to->parent);
671   old_current_count = ld_count_children (current->parent);
672 #endif
674   to_next = *(to->loc);
675   current_next = (*current->loc)->header.next;
677   *(to->loc) = *(current->loc);
679   *(current->loc) = current_next;
680   (*(to->loc))->header.next = to_next;
682   /* reset "to" list tail */
683   for (e = &to->l->head; *e != NULL; e = &(*e)->header.next)
684     ;
685   to->l->tail = e;
687   /* reset "current" list tail */
688   for (e = &current->l->head; *e != NULL; e = &(*e)->header.next)
689     ;
690   current->l->tail = e;
692 #if EXTRA_VALIDATION
693   new_to_count = ld_count_children (to->parent);
694   new_current_count = ld_count_children (current->parent);
696   ASSERT ((old_to_count + old_current_count)
697           == (new_to_count + new_current_count));
698 #endif
702 /* Can only be called with lang_statements that have lists.  Returns
703    FALSE if the list is empty.  */
705 static bfd_boolean
706 iter_stack_empty (xtensa_ld_iter_stack **stack_p)
708   return *stack_p == NULL;
712 static bfd_boolean
713 iter_stack_push (xtensa_ld_iter_stack **stack_p,
714                  lang_statement_union_type *parent)
716   xtensa_ld_iter_stack *stack;
717   lang_statement_list_type *l = NULL;
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     }
735   /* Empty. do not push.  */
736   if (l->tail == &l->head)
737     return FALSE;
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;
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;
754 static void
755 iter_stack_pop (xtensa_ld_iter_stack **stack_p)
757   xtensa_ld_iter_stack *stack;
759   stack = *stack_p;
761   if (stack == NULL)
762     {
763       ASSERT (stack != NULL);
764       return;
765     }
767   if (stack->next != NULL)
768     stack->next->prev = NULL;
770   *stack_p = stack->next;
771   free (stack);
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.  */
779 static void
780 iter_stack_update (xtensa_ld_iter_stack **stack_p)
782   if (!iter_stack_empty (stack_p)
783       && (*(*stack_p)->iterloc.loc) == NULL)
784     {
785       iter_stack_pop (stack_p);
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     }
798 static void
799 iter_stack_next (xtensa_ld_iter_stack **stack_p)
801   xtensa_ld_iter_stack *stack;
802   lang_statement_union_type *current;
803   stack = *stack_p;
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     }
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;
834 static lang_statement_union_type *
835 iter_stack_current (xtensa_ld_iter_stack **stack_p)
837   return *((*stack_p)->iterloc.loc);
841 /* The iter stack is a preorder.  */
843 static void
844 iter_stack_create (xtensa_ld_iter_stack **stack_p,
845                    lang_statement_union_type *parent)
847   iter_stack_push (stack_p, parent);
851 static void
852 iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front)
854   *front = (*stack_p)->iterloc;
858 static void
859 xtensa_colocate_literals (reloc_deps_graph *deps,
860                           lang_statement_union_type *statement)
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;
866   xtensa_ld_iter front;  /* Location where new insertion should occur.  */
867   xtensa_ld_iter *front_p = NULL;
869   xtensa_ld_iter current; /* Location we are checking.  */
870   xtensa_ld_iter *current_p = NULL;
871   bfd_boolean in_literals = FALSE;
873   if (deps->count == 0)
874     return;
876   iter_stack_create (stack_p, statement);
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);
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;
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));
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);
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;
940                           /* Do not increment the current pointer.  */
941                           skip_increment = TRUE;
942                         }
943                     }
944                 }
945             }
946           break;
947         default:
948           break;
949         }
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     }
958   lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement);
962 static void
963 xtensa_move_dependencies_to_front (reloc_deps_graph *deps,
964                                    lang_wild_statement_type *w)
966   /* Keep a front pointer and a current pointer.  */
967   lang_statement_union_type **front;
968   lang_statement_union_type **current;
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     ;
976   if (*front == NULL)
977     return;
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;
988           front_iter.parent = (lang_statement_union_type *) w;
989           front_iter.l = &w->children;
990           front_iter.loc = front;
992           current_iter.parent = (lang_statement_union_type *) w;
993           current_iter.l = &w->children;
994           current_iter.loc = current;
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     }
1007 static bfd_boolean
1008 deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt)
1010   const reloc_deps_section *sec_deps;
1011   const reloc_deps_e *sec_deps_e;
1013   sec_deps = xtensa_get_section_deps (deps, src);
1014   if (sec_deps == NULL)
1015     return FALSE;
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;
1029 static bfd_boolean
1030 deps_has_edge (const reloc_deps_graph *deps,
1031                lang_statement_union_type *src,
1032                lang_statement_union_type *tgt)
1034   if (!section_is_source (deps, src))
1035     return FALSE;
1036   if (!section_is_target (deps, tgt))
1037     return FALSE;
1039   if (src->header.type != lang_input_section_enum)
1040     return FALSE;
1041   if (tgt->header.type != lang_input_section_enum)
1042     return FALSE;
1044   return deps_has_sec_edge (deps, src->input_section.section,
1045                             tgt->input_section.section);
1049 static void
1050 add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec)
1052   reloc_deps_section *src_sec_deps;
1053   reloc_deps_section *tgt_sec_deps;
1055   reloc_deps_e *src_edge;
1056   reloc_deps_e *tgt_edge;
1058   if (deps_has_sec_edge (deps, src_sec, tgt_sec))
1059     return;
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     }
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     }
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;
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;
1104 static void
1105 build_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)
1111   reloc_deps_graph *deps = closure;
1113   /* If the target is defined.  */
1114   if (target_sec != NULL)
1115     add_deps_edge (deps, src_sec, target_sec);
1119 static reloc_deps_graph *
1120 ld_build_required_section_dependence (lang_statement_union_type *s)
1122   reloc_deps_graph *deps;
1123   xtensa_ld_iter_stack *stack = NULL;
1125   deps = xmalloc (sizeof (reloc_deps_graph));
1126   deps->sections = NULL;
1127   deps->count = 0;
1128   deps->size = 0;
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);
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->section->owner,
1141                                                input->section,
1142                                                &link_info,
1143                                                /* Use the same closure.  */
1144                                                build_deps_graph_callback,
1145                                                deps);
1146         }
1147     }
1148   return deps;
1152 #if EXTRA_VALIDATION
1153 static size_t
1154 ld_count_children (lang_statement_union_type *s)
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;
1168 #endif /* EXTRA_VALIDATION */
1171 static void
1172 xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
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;
1184       w = &statement->wild_statement;
1186       no_reorder = FALSE;
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;
1194       if (w->filenames_sorted)
1195         no_reorder = TRUE;
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         }
1211       /* Special case until the NOREORDER linker directive is supported:
1212          *(.init) output sections and *(.fini) specs may NOT be reordered.  */
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         }
1230 #if EXTRA_VALIDATION
1231       old_child_count = ld_count_children (statement);
1232 #endif
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);
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);
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
1250           xtensa_colocate_literals (deps, statement);
1252 #if EXTRA_VALIDATION
1253           new_child_count = ld_count_children (statement);
1254           ASSERT (new_child_count == old_child_count);
1255 #endif
1256         }
1258       /* Clean up.  */
1259       free_reloc_deps_graph (deps);
1260     }
1264 static void
1265 xtensa_wild_group_interleave (lang_statement_union_type *s)
1267   lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s);
1271 static void
1272 xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w)
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
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;
1293 #if EXTRA_VALIDATION
1294   old_count = ld_count_children ((lang_statement_union_type*) w);
1295 #endif
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;
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     }
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);
1325   ASSERT (old_count == (ct1 + ct2));
1326 #endif
1328   /* Now place them back in front of their dependent sections.  */
1330   while (literal_wild.children.head != NULL)
1331     {
1332       lang_statement_union_type *lit = literal_wild.children.head;
1333       bfd_boolean placed = FALSE;
1335 #if EXTRA_VALIDATION
1336       ASSERT (ct2 > 0);
1337       ct2--;
1338 #endif
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;
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         }
1360       if (!placed)
1361         {
1362           /* Put it at the end.  */
1363           *w->children.tail = lit;
1364           w->children.tail = &lit->header.next;
1365         }
1366     }
1368 #if EXTRA_VALIDATION
1369   new_count = ld_count_children ((lang_statement_union_type*) w);
1370   ASSERT (new_count == old_count);
1371 #endif
1375 static void
1376 xtensa_colocate_output_literals_callback (lang_statement_union_type *statement)
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.
1384          First we build the literal section dependences as before.
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.  */
1394 #if EXTRA_VALIDATION
1395       size_t old_child_count;
1396       size_t new_child_count;
1397 #endif
1398       bfd_boolean no_reorder = FALSE;
1400       os = &statement->output_section_statement;
1402 #if EXTRA_VALIDATION
1403       old_child_count = ld_count_children (statement);
1404 #endif
1406       /* It is now officially a target.  Build the graph of source
1407          section -> target section (kept as a list of edges).  */
1409       deps = ld_build_required_section_dependence (statement);
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);
1417 #if EXTRA_VALIDATION
1418           new_child_count = ld_count_children (statement);
1419           ASSERT (new_child_count == old_child_count);
1420 #endif
1421         }
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         }
1432       /* Clean up.  */
1433       free_reloc_deps_graph (deps);
1434     }
1438 static void
1439 xtensa_colocate_output_literals (lang_statement_union_type *s)
1441   lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s);
1445 static void
1446 xtensa_ldlang_clear_addresses (lang_statement_union_type *statement)
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     }
1462 static bfd_vma
1463 ld_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)
1468   /* Walk through all of the input statements in this wild statement
1469      assign dot to all of them.  */
1471   xtensa_ld_iter_stack *stack = NULL;
1472   xtensa_ld_iter_stack **stack_p = &stack;
1474   bfd_boolean first_section = FALSE;
1475   bfd_boolean in_literals = FALSE;
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);
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;
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);
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               }
1508             if (do_xtensa_alignment && xtensa_page_power != 0)
1509               dot += (1 << xtensa_page_power);
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;
1530 static bfd_boolean
1531 ld_local_file_relocations_fit (lang_statement_union_type *statement,
1532                                const reloc_deps_graph *deps ATTRIBUTE_UNUSED)
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....  */
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;
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     }
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                     }
1589                   if (l32r_addr - target_addr > 256 * 1024 - align_penalty)
1590                     return FALSE;
1591                 }
1592             }
1593         }
1594     }
1596   return TRUE;
1600 static bfd_vma
1601 ld_xtensa_insert_page_offsets (bfd_vma dot,
1602                                lang_statement_union_type *s,
1603                                reloc_deps_graph *deps,
1604                                bfd_boolean lit_align)
1606   xtensa_ld_iter_stack *stack = NULL;
1607   xtensa_ld_iter_stack **stack_p = &stack;
1609   bfd_boolean first_section = FALSE;
1610   bfd_boolean in_literals = FALSE;
1612   if (!lit_align)
1613     return FALSE;
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);
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;
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               }
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);
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;
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.  */
1663                 tmplist.head = NULL;
1664                 tmplist.tail = &tmplist.head;
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;
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;
1687 # Define some shell vars to insert bits of code into the standard ELF
1688 # parse_args and list_options functions.
1690 PARSE_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)
1695 extern int elf32xtensa_size_opt;
1696 extern int elf32xtensa_no_literal_movement;
1699 PARSE_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},
1706 PARSE_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"));
1711 PARSE_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;
1726 # Replace some of the standard ELF functions with our own versions.
1728 LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse
1729 LDEMUL_AFTER_OPEN=elf_xtensa_after_open
1730 LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target
1731 LDEMUL_PLACE_ORPHAN=elf_xtensa_place_orphan
1732 LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation