]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/emultempl/msp430.em
MSP430: ld: Update output section tail when shuffling ".either" sections
[thirdparty/binutils-gdb.git] / ld / emultempl / msp430.em
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 fragment <<EOF
4 /* This file is is generated by a shell script. DO NOT EDIT! */
5
6 /* Emulate the original gld for the given ${EMULATION_NAME}
7 Copyright (C) 2014-2020 Free Software Foundation, Inc.
8 Written by Steve Chamberlain steve@cygnus.com
9 Extended for the MSP430 by Nick Clifton nickc@redhat.com
10
11 This file is part of the GNU Binutils.
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
26 MA 02110-1301, USA. */
27
28 #define TARGET_IS_${EMULATION_NAME}
29
30 #include "sysdep.h"
31 #include "bfd.h"
32 #include "bfdlink.h"
33 #include "ctf-api.h"
34
35 #include "ld.h"
36 #include "getopt.h"
37 #include "ldmain.h"
38 #include "ldmisc.h"
39 #include "ldexp.h"
40 #include "ldlang.h"
41 #include "ldfile.h"
42 #include "ldemul.h"
43 #include "libiberty.h"
44 #include <ldgram.h>
45
46 enum regions
47 {
48 REGION_NONE = 0,
49 REGION_LOWER,
50 REGION_UPPER,
51 REGION_EITHER = 3,
52 };
53
54 enum either_placement_stage
55 {
56 LOWER_TO_UPPER,
57 UPPER_TO_LOWER,
58 };
59
60 enum { ROM, RAM };
61
62 static int data_region = REGION_NONE;
63 static int code_region = REGION_NONE;
64 static bfd_boolean disable_sec_transformation = FALSE;
65
66 #define MAX_PREFIX_LENGTH 7
67
68 EOF
69
70 # Import any needed special functions and/or overrides.
71 #
72 if test -n "$EXTRA_EM_FILE" ; then
73 source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
74 fi
75
76 if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
77 fragment <<EOF
78
79 static void
80 gld${EMULATION_NAME}_before_parse (void)
81 {
82 #ifndef TARGET_ /* I.e., if not generic. */
83 ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
84 #endif /* not TARGET_ */
85
86 /* The MSP430 port *needs* linker relaxtion in order to cope with large
87 functions where conditional branches do not fit into a +/- 1024 byte range. */
88 if (!bfd_link_relocatable (&link_info))
89 TARGET_ENABLE_RELAXATION;
90 }
91
92 EOF
93 fi
94
95 if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
96 fragment <<EOF
97
98 static char *
99 gld${EMULATION_NAME}_get_script (int *isfile)
100 EOF
101
102 if test x"$COMPILE_IN" = xyes
103 then
104 # Scripts compiled in.
105
106 # sed commands to quote an ld script as a C string.
107 sc="-f stringify.sed"
108
109 fragment <<EOF
110 {
111 *isfile = 0;
112
113 if (bfd_link_relocatable (&link_info) && config.build_constructors)
114 return
115 EOF
116 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
117 echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
118 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
119 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
120 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
121 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
122 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
123 echo ' ; else return' >> e${EMULATION_NAME}.c
124 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
125 echo '; }' >> e${EMULATION_NAME}.c
126
127 else
128 # Scripts read from the filesystem.
129
130 fragment <<EOF
131 {
132 *isfile = 1;
133
134 if (bfd_link_relocatable (&link_info) && config.build_constructors)
135 return "ldscripts/${EMULATION_NAME}.xu";
136 else if (bfd_link_relocatable (&link_info))
137 return "ldscripts/${EMULATION_NAME}.xr";
138 else if (!config.text_read_only)
139 return "ldscripts/${EMULATION_NAME}.xbn";
140 else if (!config.magic_demand_paged)
141 return "ldscripts/${EMULATION_NAME}.xn";
142 else
143 return "ldscripts/${EMULATION_NAME}.x";
144 }
145 EOF
146 fi
147 fi
148
149 if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
150 fragment <<EOF
151
152 static unsigned int
153 data_statement_size (lang_data_statement_type *d)
154 {
155 unsigned int size = 0;
156 switch (d->type)
157 {
158 case QUAD:
159 case SQUAD:
160 size = QUAD_SIZE;
161 break;
162 case LONG:
163 size = LONG_SIZE;
164 break;
165 case SHORT:
166 size = SHORT_SIZE;
167 break;
168 case BYTE:
169 size = BYTE_SIZE;
170 break;
171 default:
172 einfo (_("%P: error: unhandled data_statement size\n"));
173 FAIL ();
174 }
175 return size;
176 }
177
178 /* Helper function for place_orphan that computes the size
179 of sections already mapped to the given statement. */
180
181 static bfd_size_type
182 scan_children (lang_statement_union_type * l)
183 {
184 bfd_size_type amount = 0;
185
186 while (l != NULL)
187 {
188 switch (l->header.type)
189 {
190 case lang_input_section_enum:
191 if (l->input_section.section->flags & SEC_ALLOC)
192 amount += l->input_section.section->size;
193 break;
194
195 case lang_constructors_statement_enum:
196 case lang_assignment_statement_enum:
197 case lang_padding_statement_enum:
198 break;
199
200 case lang_wild_statement_enum:
201 amount += scan_children (l->wild_statement.children.head);
202 break;
203
204 case lang_data_statement_enum:
205 amount += data_statement_size (&l->data_statement);
206 break;
207
208 default:
209 fprintf (stderr, "msp430 orphan placer: unhandled lang type %d\n", l->header.type);
210 break;
211 }
212
213 l = l->header.next;
214 }
215
216 return amount;
217 }
218
219 #define WARN_UPPER 0
220 #define WARN_LOWER 1
221 #define WARN_TEXT 0
222 #define WARN_DATA 1
223 #define WARN_BSS 2
224 #define WARN_RODATA 3
225
226 /* Warn only once per output section.
227 * NAME starts with ".upper." or ".lower.". */
228 static void
229 warn_no_output_section (const char *name)
230 {
231 static bfd_boolean warned[2][4] = {{FALSE, FALSE, FALSE, FALSE},
232 {FALSE, FALSE, FALSE, FALSE}};
233 int i = WARN_LOWER;
234
235 if (strncmp (name, ".upper.", 7) == 0)
236 i = WARN_UPPER;
237
238 if (!warned[i][WARN_TEXT] && strcmp (name + 6, ".text") == 0)
239 warned[i][WARN_TEXT] = TRUE;
240 else if (!warned[i][WARN_DATA] && strcmp (name + 6, ".data") == 0)
241 warned[i][WARN_DATA] = TRUE;
242 else if (!warned[i][WARN_BSS] && strcmp (name + 6, ".bss") == 0)
243 warned[i][WARN_BSS] = TRUE;
244 else if (!warned[i][WARN_RODATA] && strcmp (name + 6, ".rodata") == 0)
245 warned[i][WARN_RODATA] = TRUE;
246 else
247 return;
248 einfo ("%P: warning: no input section rule matches %s in linker script\n",
249 name);
250 }
251
252
253 /* Place an orphan section. We use this to put .either sections
254 into either their lower or their upper equivalents. */
255
256 static lang_output_section_statement_type *
257 gld${EMULATION_NAME}_place_orphan (asection * s,
258 const char * secname,
259 int constraint)
260 {
261 char * lower_name;
262 char * upper_name;
263 char * name;
264 char * buf = NULL;
265 lang_output_section_statement_type * lower;
266 lang_output_section_statement_type * upper;
267
268 if ((s->flags & SEC_ALLOC) == 0)
269 return NULL;
270
271 if (bfd_link_relocatable (&link_info))
272 return NULL;
273
274 /* If constraints are involved let the linker handle the placement normally. */
275 if (constraint != 0)
276 return NULL;
277
278 if (strncmp (secname, ".upper.", 7) == 0
279 || strncmp (secname, ".lower.", 7) == 0)
280 {
281 warn_no_output_section (secname);
282 return NULL;
283 }
284
285 /* We only need special handling for .either sections. */
286 if (strncmp (secname, ".either.", 8) != 0)
287 return NULL;
288
289 /* Skip the .either prefix. */
290 secname += 7;
291
292 /* Compute the names of the corresponding upper and lower
293 sections. If the input section name contains another period,
294 only use the part of the name before the second dot. */
295 if (strchr (secname + 1, '.') != NULL)
296 {
297 buf = name = xstrdup (secname);
298
299 * strchr (name + 1, '.') = 0;
300 }
301 else
302 name = (char *) secname;
303
304 lower_name = concat (".lower", name, NULL);
305 upper_name = concat (".upper", name, NULL);
306
307 /* Find the corresponding lower and upper sections. */
308 lower = lang_output_section_find (lower_name);
309 upper = lang_output_section_find (upper_name);
310
311 if (lower == NULL && upper == NULL)
312 {
313 einfo (_("%P: error: no section named %s or %s in linker script\n"),
314 lower_name, upper_name);
315 goto end;
316 }
317 else if (lower == NULL)
318 {
319 lower = lang_output_section_find (name);
320 if (lower == NULL)
321 {
322 einfo (_("%P: error: no section named %s in linker script\n"), name);
323 goto end;
324 }
325 }
326
327 /* Always place orphaned sections in lower. Optimal placement of either
328 sections is performed later, once section sizes have been finalized. */
329 lang_add_section (& lower->children, s, NULL, lower);
330 end:
331 free (upper_name);
332 free (lower_name);
333 free (buf);
334 return lower;
335 }
336 EOF
337 fi
338
339 fragment <<EOF
340
341 static bfd_boolean
342 change_output_section (lang_statement_union_type **head,
343 asection *s,
344 lang_output_section_statement_type *new_os,
345 lang_output_section_statement_type *old_os)
346 {
347 asection *is;
348 lang_statement_union_type * prev = NULL;
349 lang_statement_union_type * curr;
350
351 curr = *head;
352 while (curr != NULL)
353 {
354 switch (curr->header.type)
355 {
356 case lang_input_section_enum:
357 is = curr->input_section.section;
358 if (is == s)
359 {
360 lang_statement_list_type *old_list
361 = (lang_statement_list_type *) &old_os->children;
362 s->output_section = NULL;
363 lang_add_section (&new_os->children, s, NULL, new_os);
364
365 /* Remove the section from the old output section. */
366 if (prev == NULL)
367 *head = curr->header.next;
368 else
369 prev->header.next = curr->header.next;
370 /* If the input section we just moved is the tail of the old
371 output section, then we also need to adjust that tail. */
372 if (old_list->tail == (lang_statement_union_type **) curr)
373 old_list->tail = (lang_statement_union_type **) prev;
374
375 return TRUE;
376 }
377 break;
378 case lang_wild_statement_enum:
379 if (change_output_section (&(curr->wild_statement.children.head),
380 s, new_os, old_os))
381 return TRUE;
382 break;
383 default:
384 break;
385 }
386 prev = curr;
387 curr = curr->header.next;
388 }
389 return FALSE;
390 }
391
392 static void
393 add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s,
394 void *unused ATTRIBUTE_UNUSED)
395 {
396 const char *curr_name = bfd_section_name (s);
397 int region = REGION_NONE;
398
399 if (strncmp (curr_name, ".text", 5) == 0)
400 region = code_region;
401 else if (strncmp (curr_name, ".data", 5) == 0)
402 region = data_region;
403 else if (strncmp (curr_name, ".bss", 4) == 0)
404 region = data_region;
405 else if (strncmp (curr_name, ".rodata", 7) == 0)
406 region = data_region;
407 else
408 return;
409
410 switch (region)
411 {
412 case REGION_NONE:
413 break;
414 case REGION_UPPER:
415 bfd_rename_section (s, concat (".upper", curr_name, NULL));
416 break;
417 case REGION_LOWER:
418 bfd_rename_section (s, concat (".lower", curr_name, NULL));
419 break;
420 case REGION_EITHER:
421 s->name = concat (".either", curr_name, NULL);
422 break;
423 default:
424 /* Unreachable. */
425 FAIL ();
426 break;
427 }
428 }
429
430 static void
431 msp430_elf_after_open (void)
432 {
433 bfd *abfd;
434
435 gld${EMULATION_NAME}_after_open ();
436
437 /* If neither --code-region or --data-region have been passed, do not
438 transform sections names. */
439 if ((code_region == REGION_NONE && data_region == REGION_NONE)
440 || disable_sec_transformation)
441 return;
442
443 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
444 bfd_map_over_sections (abfd, add_region_prefix, NULL);
445 }
446
447 #define OPTION_CODE_REGION 321
448 #define OPTION_DATA_REGION (OPTION_CODE_REGION + 1)
449 #define OPTION_DISABLE_TRANS (OPTION_CODE_REGION + 2)
450
451 static void
452 gld${EMULATION_NAME}_add_options
453 (int ns, char **shortopts, int nl, struct option **longopts,
454 int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
455 {
456 static const char xtra_short[] = { };
457
458 static const struct option xtra_long[] =
459 {
460 { "code-region", required_argument, NULL, OPTION_CODE_REGION },
461 { "data-region", required_argument, NULL, OPTION_DATA_REGION },
462 { "disable-sec-transformation", no_argument, NULL,
463 OPTION_DISABLE_TRANS },
464 { NULL, no_argument, NULL, 0 }
465 };
466
467 *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
468 memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
469 *longopts = (struct option *)
470 xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
471 memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
472 }
473
474 static void
475 gld${EMULATION_NAME}_list_options (FILE * file)
476 {
477 fprintf (file, _(" --code-region={either,lower,upper,none}\n\
478 Transform .text* sections to {either,lower,upper,none}.text* sections\n"));
479 fprintf (file, _(" --data-region={either,lower,upper,none}\n\
480 Transform .data*, .rodata* and .bss* sections to\n\
481 {either,lower,upper,none}.{bss,data,rodata}* sections\n"));
482 fprintf (file, _(" --disable-sec-transformation\n\
483 Disable transformation of .{text,data,bss,rodata}* sections to\n\
484 add the {either,lower,upper,none} prefixes\n"));
485 }
486
487 static bfd_boolean
488 gld${EMULATION_NAME}_handle_option (int optc)
489 {
490 switch (optc)
491 {
492 case OPTION_CODE_REGION:
493 if (strcmp (optarg, "upper") == 0)
494 code_region = REGION_UPPER;
495 else if (strcmp (optarg, "lower") == 0)
496 code_region = REGION_LOWER;
497 else if (strcmp (optarg, "either") == 0)
498 code_region = REGION_EITHER;
499 else if (strcmp (optarg, "none") == 0)
500 code_region = REGION_NONE;
501 else if (strlen (optarg) == 0)
502 {
503 einfo (_("%P: --code-region requires an argument: "
504 "{upper,lower,either,none}\n"));
505 return FALSE;
506 }
507 else
508 {
509 einfo (_("%P: error: unrecognized argument to --code-region= option: "
510 "\"%s\"\n"), optarg);
511 return FALSE;
512 }
513 break;
514
515 case OPTION_DATA_REGION:
516 if (strcmp (optarg, "upper") == 0)
517 data_region = REGION_UPPER;
518 else if (strcmp (optarg, "lower") == 0)
519 data_region = REGION_LOWER;
520 else if (strcmp (optarg, "either") == 0)
521 data_region = REGION_EITHER;
522 else if (strcmp (optarg, "none") == 0)
523 data_region = REGION_NONE;
524 else if (strlen (optarg) == 0)
525 {
526 einfo (_("%P: --data-region requires an argument: "
527 "{upper,lower,either,none}\n"));
528 return FALSE;
529 }
530 else
531 {
532 einfo (_("%P: error: unrecognized argument to --data-region= option: "
533 "\"%s\"\n"), optarg);
534 return FALSE;
535 }
536 break;
537
538 case OPTION_DISABLE_TRANS:
539 disable_sec_transformation = TRUE;
540 break;
541
542 default:
543 return FALSE;
544 }
545 return TRUE;
546 }
547
548 static void
549 eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
550 asection *s, void *data)
551 {
552 const char * base_sec_name;
553 const char * curr_name;
554 char * either_name;
555 int curr_region;
556
557 lang_output_section_statement_type * lower;
558 lang_output_section_statement_type * upper;
559 static bfd_size_type *lower_size = 0;
560 static bfd_size_type *upper_size = 0;
561 static bfd_size_type lower_size_rom = 0;
562 static bfd_size_type lower_size_ram = 0;
563 static bfd_size_type upper_size_rom = 0;
564 static bfd_size_type upper_size_ram = 0;
565
566 if ((s->flags & SEC_ALLOC) == 0)
567 return;
568 if (bfd_link_relocatable (&link_info))
569 return;
570
571 base_sec_name = (const char *) data;
572 curr_name = bfd_section_name (s);
573
574 /* Only concerned with .either input sections in the upper output section. */
575 either_name = concat (".either", base_sec_name, NULL);
576 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
577 || strncmp (s->output_section->name, ".upper", 6) != 0)
578 goto end;
579
580 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
581 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
582
583 if (upper == NULL || upper->region == NULL)
584 goto end;
585 else if (lower == NULL)
586 lower = lang_output_section_find (base_sec_name);
587 if (lower == NULL || lower->region == NULL)
588 goto end;
589
590 if (strcmp (base_sec_name, ".text") == 0
591 || strcmp (base_sec_name, ".rodata") == 0)
592 curr_region = ROM;
593 else
594 curr_region = RAM;
595
596 if (curr_region == ROM)
597 {
598 if (lower_size_rom == 0)
599 {
600 lower_size_rom = lower->region->current - lower->region->origin;
601 upper_size_rom = upper->region->current - upper->region->origin;
602 }
603 lower_size = &lower_size_rom;
604 upper_size = &upper_size_rom;
605 }
606 else if (curr_region == RAM)
607 {
608 if (lower_size_ram == 0)
609 {
610 lower_size_ram = lower->region->current - lower->region->origin;
611 upper_size_ram = upper->region->current - upper->region->origin;
612 }
613 lower_size = &lower_size_ram;
614 upper_size = &upper_size_ram;
615 }
616
617 /* If the upper region is overflowing, try moving sections to the lower
618 region.
619 Note that there isn't any general benefit to using lower memory over upper
620 memory, so we only move sections around with the goal of making the program
621 fit. */
622 if (*upper_size > upper->region->length
623 && *lower_size + s->size < lower->region->length)
624 {
625 if (change_output_section (&(upper->children.head), s, lower, upper))
626 {
627 *upper_size -= s->size;
628 *lower_size += s->size;
629 }
630 }
631 end:
632 free (either_name);
633 }
634
635 static void
636 eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
637 asection *s, void *data)
638 {
639 const char * base_sec_name;
640 const char * curr_name;
641 char * either_name;
642 int curr_region;
643 lang_output_section_statement_type * output_sec;
644 lang_output_section_statement_type * lower;
645 lang_output_section_statement_type * upper;
646
647 static bfd_size_type *lower_size = 0;
648 static bfd_size_type lower_size_rom = 0;
649 static bfd_size_type lower_size_ram = 0;
650
651 if ((s->flags & SEC_ALLOC) == 0)
652 return;
653 if (bfd_link_relocatable (&link_info))
654 return;
655
656 base_sec_name = (const char *) data;
657 curr_name = bfd_section_name (s);
658
659 /* Only concerned with .either input sections in the lower or "default"
660 output section i.e. not in the upper output section. */
661 either_name = concat (".either", base_sec_name, NULL);
662 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
663 || strncmp (s->output_section->name, ".upper", 6) == 0)
664 return;
665
666 if (strcmp (base_sec_name, ".text") == 0
667 || strcmp (base_sec_name, ".rodata") == 0)
668 curr_region = ROM;
669 else
670 curr_region = RAM;
671
672 output_sec = lang_output_section_find (s->output_section->name);
673
674 /* If the output_section doesn't exist, this has already been reported in
675 place_orphan, so don't need to warn again. */
676 if (output_sec == NULL || output_sec->region == NULL)
677 goto end;
678
679 /* lower and output_sec might be the same, but in some cases an .either
680 section can end up in base_sec_name if it hasn't been placed by
681 place_orphan. */
682 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
683 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
684 if (upper == NULL)
685 goto end;
686
687 if (curr_region == ROM)
688 {
689 if (lower_size_rom == 0)
690 {
691 /* Get the size of other items in the lower region that aren't the
692 sections to be moved around. */
693 lower_size_rom
694 = (output_sec->region->current - output_sec->region->origin)
695 - scan_children (output_sec->children.head);
696 if (output_sec != lower && lower != NULL)
697 lower_size_rom -= scan_children (lower->children.head);
698 }
699 lower_size = &lower_size_rom;
700 }
701 else if (curr_region == RAM)
702 {
703 if (lower_size_ram == 0)
704 {
705 lower_size_ram
706 = (output_sec->region->current - output_sec->region->origin)
707 - scan_children (output_sec->children.head);
708 if (output_sec != lower && lower != NULL)
709 lower_size_ram -= scan_children (lower->children.head);
710 }
711 lower_size = &lower_size_ram;
712 }
713 /* Move sections that cause the lower region to overflow to the upper region. */
714 if (*lower_size + s->size > output_sec->region->length)
715 change_output_section (&(output_sec->children.head), s, upper, output_sec);
716 else
717 *lower_size += s->size;
718 end:
719 free (either_name);
720 }
721
722 /* This function is similar to lang_relax_sections, but without the size
723 evaluation code that is always executed after relaxation. */
724 static void
725 intermediate_relax_sections (void)
726 {
727 int i = link_info.relax_pass;
728
729 /* The backend can use it to determine the current pass. */
730 link_info.relax_pass = 0;
731
732 while (i--)
733 {
734 bfd_boolean relax_again;
735
736 link_info.relax_trip = -1;
737 do
738 {
739 link_info.relax_trip++;
740
741 lang_do_assignments (lang_assigning_phase_enum);
742
743 lang_reset_memory_regions ();
744
745 relax_again = FALSE;
746 lang_size_sections (&relax_again, FALSE);
747 }
748 while (relax_again);
749
750 link_info.relax_pass++;
751 }
752 }
753
754 static void
755 msp430_elf_after_allocation (void)
756 {
757 int relax_count = 0;
758 unsigned int i;
759 /* Go over each section twice, once to place either sections that don't fit
760 in lower into upper, and then again to move any sections in upper that
761 fit in lower into lower. */
762 for (i = 0; i < 8; i++)
763 {
764 int placement_stage = (i < 4) ? LOWER_TO_UPPER : UPPER_TO_LOWER;
765 const char * base_sec_name;
766 lang_output_section_statement_type * upper;
767
768 switch (i % 4)
769 {
770 default:
771 case 0:
772 base_sec_name = ".text";
773 break;
774 case 1:
775 base_sec_name = ".data";
776 break;
777 case 2:
778 base_sec_name = ".bss";
779 break;
780 case 3:
781 base_sec_name = ".rodata";
782 break;
783 }
784 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
785 if (upper != NULL)
786 {
787 /* Can't just use one iteration over the all the sections to make
788 both lower->upper and upper->lower transformations because the
789 iterator encounters upper sections before all lower sections have
790 been examined. */
791 bfd *abfd;
792
793 if (placement_stage == LOWER_TO_UPPER)
794 {
795 /* Perform relaxation and get the final size of sections
796 before trying to fit .either sections in the correct
797 ouput sections. */
798 if (relax_count == 0)
799 {
800 intermediate_relax_sections ();
801 relax_count++;
802 }
803 for (abfd = link_info.input_bfds; abfd != NULL;
804 abfd = abfd->link.next)
805 {
806 bfd_map_over_sections (abfd, eval_lower_either_sections,
807 (void *) base_sec_name);
808 }
809 }
810 else if (placement_stage == UPPER_TO_LOWER)
811 {
812 /* Relax again before moving upper->lower. */
813 if (relax_count == 1)
814 {
815 intermediate_relax_sections ();
816 relax_count++;
817 }
818 for (abfd = link_info.input_bfds; abfd != NULL;
819 abfd = abfd->link.next)
820 {
821 bfd_map_over_sections (abfd, eval_upper_either_sections,
822 (void *) base_sec_name);
823 }
824 }
825
826 }
827 }
828 gld${EMULATION_NAME}_after_allocation ();
829 }
830
831 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
832 {
833 ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
834 ${LDEMUL_SYSLIB-syslib_default},
835 ${LDEMUL_HLL-hll_default},
836 ${LDEMUL_AFTER_PARSE-after_parse_default},
837 msp430_elf_after_open,
838 after_check_relocs_default,
839 before_place_orphans_default,
840 msp430_elf_after_allocation,
841 ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
842 ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
843 ${LDEMUL_BEFORE_ALLOCATION-before_allocation_default},
844 ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
845 "${EMULATION_NAME}",
846 "${OUTPUT_FORMAT}",
847 ${LDEMUL_FINISH-finish_default},
848 ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
849 ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL},
850 ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
851 ${LDEMUL_SET_SYMBOLS-NULL},
852 ${LDEMUL_PARSE_ARGS-NULL},
853 gld${EMULATION_NAME}_add_options,
854 gld${EMULATION_NAME}_handle_option,
855 ${LDEMUL_UNRECOGNIZED_FILE-NULL},
856 gld${EMULATION_NAME}_list_options,
857 ${LDEMUL_RECOGNIZED_FILE-NULL},
858 ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
859 ${LDEMUL_NEW_VERS_PATTERN-NULL},
860 ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
861 ${LDEMUL_EMIT_CTF_EARLY-NULL},
862 ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL},
863 ${LDEMUL_PRINT_SYMBOL-NULL}
864 };
865 EOF
866 # \f
867 # Local Variables:
868 # mode: c
869 # End: