Update year range in copyright notice of binutils files
[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}
b3adc24a 7 Copyright (C) 2014-2020 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
6c19b93b 10
837a17b3
NC
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"
1ff6de03 33#include "ctf-api.h"
837a17b3
NC
34
35#include "ld.h"
7ef3addb 36#include "getopt.h"
837a17b3
NC
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"
7ef3addb
JL
44#include <ldgram.h>
45
46enum regions
47{
48 REGION_NONE = 0,
49 REGION_LOWER,
50 REGION_UPPER,
51 REGION_EITHER = 3,
52};
53
54enum either_placement_stage
55{
56 LOWER_TO_UPPER,
57 UPPER_TO_LOWER,
58};
59
60enum { ROM, RAM };
61
62static int data_region = REGION_NONE;
63static int code_region = REGION_NONE;
64static bfd_boolean disable_sec_transformation = FALSE;
65
66#define MAX_PREFIX_LENGTH 7
837a17b3
NC
67
68EOF
69
70# Import any needed special functions and/or overrides.
71#
72if test -n "$EXTRA_EM_FILE" ; then
73 source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
74fi
75
76if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
77fragment <<EOF
78
79static void
80gld${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. */
0e1862bb 88 if (!bfd_link_relocatable (&link_info))
837a17b3
NC
89 TARGET_ENABLE_RELAXATION;
90}
91
92EOF
93fi
94
95if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
96fragment <<EOF
97
98static char *
99gld${EMULATION_NAME}_get_script (int *isfile)
100EOF
101
102if test x"$COMPILE_IN" = xyes
103then
104# Scripts compiled in.
105
106# sed commands to quote an ld script as a C string.
107sc="-f stringify.sed"
108
109fragment <<EOF
110{
111 *isfile = 0;
112
0e1862bb 113 if (bfd_link_relocatable (&link_info) && config.build_constructors)
837a17b3
NC
114 return
115EOF
116sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
0e1862bb 117echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
837a17b3
NC
118sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
119echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
120sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
121echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
122sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
123echo ' ; else return' >> e${EMULATION_NAME}.c
124sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
125echo '; }' >> e${EMULATION_NAME}.c
126
127else
128# Scripts read from the filesystem.
129
130fragment <<EOF
131{
132 *isfile = 1;
133
0e1862bb 134 if (bfd_link_relocatable (&link_info) && config.build_constructors)
837a17b3 135 return "ldscripts/${EMULATION_NAME}.xu";
0e1862bb 136 else if (bfd_link_relocatable (&link_info))
837a17b3
NC
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}
145EOF
146fi
147fi
148
149if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
150fragment <<EOF
151
7ef3addb
JL
152static unsigned int
153data_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:
d003af55 172 einfo (_("%P: error: unhandled data_statement size\n"));
7ef3addb
JL
173 FAIL ();
174 }
175 return size;
176}
177
837a17b3
NC
178/* Helper function for place_orphan that computes the size
179 of sections already mapped to the given statement. */
180
181static bfd_size_type
182scan_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:
7ef3addb 197 case lang_padding_statement_enum:
837a17b3
NC
198 break;
199
200 case lang_wild_statement_enum:
6c19b93b 201 amount += scan_children (l->wild_statement.children.head);
837a17b3
NC
202 break;
203
7ef3addb
JL
204 case lang_data_statement_enum:
205 amount += data_statement_size (&l->data_statement);
206 break;
207
837a17b3
NC
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}
6c19b93b 218
e25de718
JL
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.". */
228static void
229warn_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
837a17b3
NC
253/* Place an orphan section. We use this to put .either sections
254 into either their lower or their upper equivalents. */
255
256static lang_output_section_statement_type *
257gld${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;
e1fa0163 264 char * buf = NULL;
837a17b3
NC
265 lang_output_section_statement_type * lower;
266 lang_output_section_statement_type * upper;
837a17b3
NC
267
268 if ((s->flags & SEC_ALLOC) == 0)
269 return NULL;
270
0e1862bb 271 if (bfd_link_relocatable (&link_info))
837a17b3
NC
272 return NULL;
273
274 /* If constraints are involved let the linker handle the placement normally. */
275 if (constraint != 0)
276 return NULL;
277
e25de718
JL
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
837a17b3
NC
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 {
e1fa0163 297 buf = name = xstrdup (secname);
837a17b3
NC
298
299 * strchr (name + 1, '.') = 0;
300 }
301 else
302 name = (char *) secname;
6c19b93b 303
e1fa0163
NC
304 lower_name = concat (".lower", name, NULL);
305 upper_name = concat (".upper", name, NULL);
837a17b3
NC
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);
837a17b3 310
7ef3addb
JL
311 if (lower == NULL && upper == NULL)
312 {
d003af55 313 einfo (_("%P: error: no section named %s or %s in linker script\n"),
7ef3addb
JL
314 lower_name, upper_name);
315 goto end;
316 }
317 else if (lower == NULL)
837a17b3 318 {
7ef3addb
JL
319 lower = lang_output_section_find (name);
320 if (lower == NULL)
321 {
d003af55 322 einfo (_("%P: error: no section named %s in linker script\n"), name);
e1fa0163 323 goto end;
837a17b3
NC
324 }
325 }
7ef3addb
JL
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 if (buf)
334 free (buf);
335 return lower;
336}
337EOF
338fi
339
340fragment <<EOF
341
342static bfd_boolean
343change_output_section (lang_statement_union_type ** head,
344 asection *s,
345 lang_output_section_statement_type * new_output_section)
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 s->output_section = NULL;
361 lang_add_section (& (new_output_section->children), s, NULL,
362 new_output_section);
363 /* Remove the section from the old output section. */
364 if (prev == NULL)
365 *head = curr->header.next;
366 else
367 prev->header.next = curr->header.next;
368 return TRUE;
369 }
370 break;
371 case lang_wild_statement_enum:
372 if (change_output_section (&(curr->wild_statement.children.head),
373 s, new_output_section))
374 return TRUE;
375 break;
376 default:
377 break;
378 }
379 prev = curr;
380 curr = curr->header.next;
381 }
382 return FALSE;
383}
384
7ef3addb 385static void
fd361982
AM
386add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s,
387 void *unused ATTRIBUTE_UNUSED)
7ef3addb 388{
fd361982 389 const char *curr_name = bfd_section_name (s);
7ef3addb
JL
390 int region = REGION_NONE;
391
392 if (strncmp (curr_name, ".text", 5) == 0)
e25de718 393 region = code_region;
7ef3addb 394 else if (strncmp (curr_name, ".data", 5) == 0)
e25de718 395 region = data_region;
7ef3addb 396 else if (strncmp (curr_name, ".bss", 4) == 0)
e25de718 397 region = data_region;
7ef3addb 398 else if (strncmp (curr_name, ".rodata", 7) == 0)
e25de718 399 region = data_region;
7ef3addb
JL
400 else
401 return;
402
403 switch (region)
404 {
405 case REGION_NONE:
406 break;
407 case REGION_UPPER:
fd361982 408 bfd_rename_section (s, concat (".upper", curr_name, NULL));
7ef3addb
JL
409 break;
410 case REGION_LOWER:
fd361982 411 bfd_rename_section (s, concat (".lower", curr_name, NULL));
7ef3addb
JL
412 break;
413 case REGION_EITHER:
414 s->name = concat (".either", curr_name, NULL);
415 break;
416 default:
417 /* Unreachable. */
418 FAIL ();
419 break;
420 }
7ef3addb
JL
421}
422
423static void
424msp430_elf_after_open (void)
425{
426 bfd *abfd;
427
428 gld${EMULATION_NAME}_after_open ();
837a17b3 429
7ef3addb
JL
430 /* If neither --code-region or --data-region have been passed, do not
431 transform sections names. */
432 if ((code_region == REGION_NONE && data_region == REGION_NONE)
433 || disable_sec_transformation)
434 return;
435
436 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
437 bfd_map_over_sections (abfd, add_region_prefix, NULL);
438}
439
440#define OPTION_CODE_REGION 321
441#define OPTION_DATA_REGION (OPTION_CODE_REGION + 1)
442#define OPTION_DISABLE_TRANS (OPTION_CODE_REGION + 2)
443
444static void
445gld${EMULATION_NAME}_add_options
446 (int ns, char **shortopts, int nl, struct option **longopts,
447 int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
448{
449 static const char xtra_short[] = { };
837a17b3 450
7ef3addb
JL
451 static const struct option xtra_long[] =
452 {
453 { "code-region", required_argument, NULL, OPTION_CODE_REGION },
454 { "data-region", required_argument, NULL, OPTION_DATA_REGION },
455 { "disable-sec-transformation", no_argument, NULL,
456 OPTION_DISABLE_TRANS },
457 { NULL, no_argument, NULL, 0 }
458 };
459
460 *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
461 memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
462 *longopts = (struct option *)
463 xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
464 memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
465}
837a17b3 466
7ef3addb
JL
467static void
468gld${EMULATION_NAME}_list_options (FILE * file)
469{
df5f2391
AM
470 fprintf (file, _(" --code-region={either,lower,upper,none}\n\
471 Transform .text* sections to {either,lower,upper,none}.text* sections\n"));
472 fprintf (file, _(" --data-region={either,lower,upper,none}\n\
473 Transform .data*, .rodata* and .bss* sections to\n\
474 {either,lower,upper,none}.{bss,data,rodata}* sections\n"));
475 fprintf (file, _(" --disable-sec-transformation\n\
476 Disable transformation of .{text,data,bss,rodata}* sections to\n\
477 add the {either,lower,upper,none} prefixes\n"));
7ef3addb 478}
837a17b3 479
7ef3addb
JL
480static bfd_boolean
481gld${EMULATION_NAME}_handle_option (int optc)
482{
483 switch (optc)
484 {
485 case OPTION_CODE_REGION:
486 if (strcmp (optarg, "upper") == 0)
487 code_region = REGION_UPPER;
488 else if (strcmp (optarg, "lower") == 0)
489 code_region = REGION_LOWER;
490 else if (strcmp (optarg, "either") == 0)
491 code_region = REGION_EITHER;
492 else if (strcmp (optarg, "none") == 0)
493 code_region = REGION_NONE;
494 else if (strlen (optarg) == 0)
495 {
df5f2391
AM
496 einfo (_("%P: --code-region requires an argument: "
497 "{upper,lower,either,none}\n"));
7ef3addb
JL
498 return FALSE;
499 }
837a17b3 500 else
7ef3addb 501 {
df5f2391
AM
502 einfo (_("%P: error: unrecognized argument to --code-region= option: "
503 "\"%s\"\n"), optarg);
7ef3addb
JL
504 return FALSE;
505 }
506 break;
507
508 case OPTION_DATA_REGION:
509 if (strcmp (optarg, "upper") == 0)
510 data_region = REGION_UPPER;
511 else if (strcmp (optarg, "lower") == 0)
512 data_region = REGION_LOWER;
513 else if (strcmp (optarg, "either") == 0)
514 data_region = REGION_EITHER;
515 else if (strcmp (optarg, "none") == 0)
516 data_region = REGION_NONE;
517 else if (strlen (optarg) == 0)
518 {
df5f2391
AM
519 einfo (_("%P: --data-region requires an argument: "
520 "{upper,lower,either,none}\n"));
7ef3addb
JL
521 return FALSE;
522 }
523 else
524 {
df5f2391
AM
525 einfo (_("%P: error: unrecognized argument to --data-region= option: "
526 "\"%s\"\n"), optarg);
7ef3addb
JL
527 return FALSE;
528 }
529 break;
530
531 case OPTION_DISABLE_TRANS:
532 disable_sec_transformation = TRUE;
533 break;
534
535 default:
536 return FALSE;
537 }
538 return TRUE;
539}
540
541static void
fd361982
AM
542eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
543 asection *s, void *data)
7ef3addb 544{
96d01d93 545 const char * base_sec_name;
7ef3addb
JL
546 const char * curr_name;
547 char * either_name;
548 int curr_region;
549
550 lang_output_section_statement_type * lower;
551 lang_output_section_statement_type * upper;
552 static bfd_size_type *lower_size = 0;
553 static bfd_size_type *upper_size = 0;
554 static bfd_size_type lower_size_rom = 0;
555 static bfd_size_type lower_size_ram = 0;
556 static bfd_size_type upper_size_rom = 0;
557 static bfd_size_type upper_size_ram = 0;
558
559 if ((s->flags & SEC_ALLOC) == 0)
560 return;
561 if (bfd_link_relocatable (&link_info))
562 return;
563
96d01d93 564 base_sec_name = (const char *) data;
fd361982 565 curr_name = bfd_section_name (s);
7ef3addb
JL
566
567 /* Only concerned with .either input sections in the upper output section. */
568 either_name = concat (".either", base_sec_name, NULL);
569 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
570 || strncmp (s->output_section->name, ".upper", 6) != 0)
571 goto end;
572
573 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
574 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
575
576 if (upper == NULL || upper->region == NULL)
577 goto end;
578 else if (lower == NULL)
579 lower = lang_output_section_find (base_sec_name);
580 if (lower == NULL || lower->region == NULL)
581 goto end;
582
583 if (strcmp (base_sec_name, ".text") == 0
584 || strcmp (base_sec_name, ".rodata") == 0)
585 curr_region = ROM;
586 else
587 curr_region = RAM;
588
589 if (curr_region == ROM)
590 {
591 if (lower_size_rom == 0)
592 {
593 lower_size_rom = lower->region->current - lower->region->origin;
594 upper_size_rom = upper->region->current - upper->region->origin;
595 }
596 lower_size = &lower_size_rom;
597 upper_size = &upper_size_rom;
598 }
599 else if (curr_region == RAM)
600 {
601 if (lower_size_ram == 0)
602 {
603 lower_size_ram = lower->region->current - lower->region->origin;
604 upper_size_ram = upper->region->current - upper->region->origin;
605 }
606 lower_size = &lower_size_ram;
607 upper_size = &upper_size_ram;
837a17b3
NC
608 }
609
7ef3addb
JL
610 /* Move sections in the upper region that would fit in the lower
611 region to the lower region. */
612 if (*lower_size + s->size < lower->region->length)
613 {
614 if (change_output_section (&(upper->children.head), s, lower))
615 {
616 *upper_size -= s->size;
617 *lower_size += s->size;
618 }
619 }
e1fa0163 620 end:
7ef3addb 621 free (either_name);
837a17b3 622}
837a17b3 623
7ef3addb 624static void
fd361982
AM
625eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
626 asection *s, void *data)
7ef3addb 627{
96d01d93 628 const char * base_sec_name;
7ef3addb
JL
629 const char * curr_name;
630 char * either_name;
631 int curr_region;
632 lang_output_section_statement_type * output_sec;
633 lang_output_section_statement_type * lower;
634 lang_output_section_statement_type * upper;
635
636 static bfd_size_type *lower_size = 0;
637 static bfd_size_type lower_size_rom = 0;
638 static bfd_size_type lower_size_ram = 0;
639
640 if ((s->flags & SEC_ALLOC) == 0)
641 return;
642 if (bfd_link_relocatable (&link_info))
643 return;
644
96d01d93 645 base_sec_name = (const char *) data;
fd361982 646 curr_name = bfd_section_name (s);
7ef3addb
JL
647
648 /* Only concerned with .either input sections in the lower or "default"
649 output section i.e. not in the upper output section. */
650 either_name = concat (".either", base_sec_name, NULL);
651 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
652 || strncmp (s->output_section->name, ".upper", 6) == 0)
653 return;
654
655 if (strcmp (base_sec_name, ".text") == 0
656 || strcmp (base_sec_name, ".rodata") == 0)
657 curr_region = ROM;
658 else
659 curr_region = RAM;
660
661 output_sec = lang_output_section_find (s->output_section->name);
662
663 /* If the output_section doesn't exist, this has already been reported in
664 place_orphan, so don't need to warn again. */
665 if (output_sec == NULL || output_sec->region == NULL)
666 goto end;
667
668 /* lower and output_sec might be the same, but in some cases an .either
669 section can end up in base_sec_name if it hasn't been placed by
670 place_orphan. */
671 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
672 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
673 if (upper == NULL)
674 goto end;
675
676 if (curr_region == ROM)
677 {
678 if (lower_size_rom == 0)
679 {
680 /* Get the size of other items in the lower region that aren't the
681 sections to be moved around. */
682 lower_size_rom
683 = (output_sec->region->current - output_sec->region->origin)
684 - scan_children (output_sec->children.head);
685 if (output_sec != lower && lower != NULL)
686 lower_size_rom -= scan_children (lower->children.head);
687 }
688 lower_size = &lower_size_rom;
689 }
690 else if (curr_region == RAM)
691 {
692 if (lower_size_ram == 0)
693 {
694 lower_size_ram
695 = (output_sec->region->current - output_sec->region->origin)
696 - scan_children (output_sec->children.head);
697 if (output_sec != lower && lower != NULL)
698 lower_size_ram -= scan_children (lower->children.head);
699 }
700 lower_size = &lower_size_ram;
701 }
702 /* Move sections that cause the lower region to overflow to the upper region. */
703 if (*lower_size + s->size > output_sec->region->length)
704 change_output_section (&(output_sec->children.head), s, upper);
705 else
706 *lower_size += s->size;
707 end:
708 free (either_name);
709}
710
711/* This function is similar to lang_relax_sections, but without the size
712 evaluation code that is always executed after relaxation. */
713static void
714intermediate_relax_sections (void)
715{
716 int i = link_info.relax_pass;
717
718 /* The backend can use it to determine the current pass. */
719 link_info.relax_pass = 0;
720
721 while (i--)
722 {
723 bfd_boolean relax_again;
724
725 link_info.relax_trip = -1;
726 do
727 {
728 link_info.relax_trip++;
729
730 lang_do_assignments (lang_assigning_phase_enum);
731
732 lang_reset_memory_regions ();
733
734 relax_again = FALSE;
735 lang_size_sections (&relax_again, FALSE);
736 }
737 while (relax_again);
738
739 link_info.relax_pass++;
740 }
741}
742
743static void
744msp430_elf_after_allocation (void)
745{
746 int relax_count = 0;
96d01d93 747 unsigned int i;
7ef3addb
JL
748 /* Go over each section twice, once to place either sections that don't fit
749 in lower into upper, and then again to move any sections in upper that
750 fit in lower into lower. */
751 for (i = 0; i < 8; i++)
752 {
753 int placement_stage = (i < 4) ? LOWER_TO_UPPER : UPPER_TO_LOWER;
96d01d93 754 const char * base_sec_name;
7ef3addb
JL
755 lang_output_section_statement_type * upper;
756
757 switch (i % 4)
758 {
96d01d93 759 default:
7ef3addb 760 case 0:
96d01d93 761 base_sec_name = ".text";
7ef3addb
JL
762 break;
763 case 1:
96d01d93 764 base_sec_name = ".data";
7ef3addb
JL
765 break;
766 case 2:
96d01d93 767 base_sec_name = ".bss";
7ef3addb
JL
768 break;
769 case 3:
96d01d93 770 base_sec_name = ".rodata";
7ef3addb
JL
771 break;
772 }
773 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
774 if (upper != NULL)
775 {
776 /* Can't just use one iteration over the all the sections to make
777 both lower->upper and upper->lower transformations because the
778 iterator encounters upper sections before all lower sections have
779 been examined. */
780 bfd *abfd;
781
782 if (placement_stage == LOWER_TO_UPPER)
783 {
784 /* Perform relaxation and get the final size of sections
785 before trying to fit .either sections in the correct
786 ouput sections. */
787 if (relax_count == 0)
788 {
789 intermediate_relax_sections ();
790 relax_count++;
791 }
792 for (abfd = link_info.input_bfds; abfd != NULL;
793 abfd = abfd->link.next)
794 {
795 bfd_map_over_sections (abfd, eval_lower_either_sections,
96d01d93 796 (void *) base_sec_name);
7ef3addb
JL
797 }
798 }
799 else if (placement_stage == UPPER_TO_LOWER)
800 {
801 /* Relax again before moving upper->lower. */
802 if (relax_count == 1)
803 {
804 intermediate_relax_sections ();
805 relax_count++;
806 }
807 for (abfd = link_info.input_bfds; abfd != NULL;
808 abfd = abfd->link.next)
809 {
810 bfd_map_over_sections (abfd, eval_upper_either_sections,
96d01d93 811 (void *) base_sec_name);
7ef3addb
JL
812 }
813 }
814
815 }
7ef3addb
JL
816 }
817 gld${EMULATION_NAME}_after_allocation ();
818}
837a17b3
NC
819
820struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
821{
822 ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
823 ${LDEMUL_SYSLIB-syslib_default},
824 ${LDEMUL_HLL-hll_default},
825 ${LDEMUL_AFTER_PARSE-after_parse_default},
7ef3addb 826 msp430_elf_after_open,
5c3261b0 827 after_check_relocs_default,
7ef3addb 828 msp430_elf_after_allocation,
837a17b3
NC
829 ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
830 ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
831 ${LDEMUL_BEFORE_ALLOCATION-before_allocation_default},
832 ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
833 "${EMULATION_NAME}",
834 "${OUTPUT_FORMAT}",
835 ${LDEMUL_FINISH-finish_default},
836 ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
837 ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL},
838 ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
839 ${LDEMUL_SET_SYMBOLS-NULL},
840 ${LDEMUL_PARSE_ARGS-NULL},
7ef3addb
JL
841 gld${EMULATION_NAME}_add_options,
842 gld${EMULATION_NAME}_handle_option,
837a17b3 843 ${LDEMUL_UNRECOGNIZED_FILE-NULL},
7ef3addb 844 gld${EMULATION_NAME}_list_options,
837a17b3
NC
845 ${LDEMUL_RECOGNIZED_FILE-NULL},
846 ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
847 ${LDEMUL_NEW_VERS_PATTERN-NULL},
1ff6de03
NA
848 ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
849 ${LDEMUL_EMIT_CTF_EARLY-NULL},
850 ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL}
837a17b3
NC
851};
852EOF
853# \f
854# Local Variables:
855# mode: c
856# End:
This page took 0.247856 seconds and 4 git commands to generate.