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