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