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