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