]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/emultempl/msp430.em
Update year range in copyright notice of binutils files
[thirdparty/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}
d87bef3a 7 Copyright (C) 2014-2023 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;
f38a2680 64static bool disable_sec_transformation = false;
7ef3addb
JL
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{
f38a2680
AM
231 static bool warned[2][4] = {{false, false, false, false},
232 {false, false, false, false}};
e25de718
JL
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)
f38a2680 239 warned[i][WARN_TEXT] = true;
e25de718 240 else if (!warned[i][WARN_DATA] && strcmp (name + 6, ".data") == 0)
f38a2680 241 warned[i][WARN_DATA] = true;
e25de718 242 else if (!warned[i][WARN_BSS] && strcmp (name + 6, ".bss") == 0)
f38a2680 243 warned[i][WARN_BSS] = true;
e25de718 244 else if (!warned[i][WARN_RODATA] && strcmp (name + 6, ".rodata") == 0)
f38a2680 245 warned[i][WARN_RODATA] = true;
e25de718
JL
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;
264 lang_output_section_statement_type * lower;
265 lang_output_section_statement_type * upper;
837a17b3
NC
266
267 if ((s->flags & SEC_ALLOC) == 0)
268 return NULL;
269
0e1862bb 270 if (bfd_link_relocatable (&link_info))
837a17b3
NC
271 return NULL;
272
273 /* If constraints are involved let the linker handle the placement normally. */
274 if (constraint != 0)
275 return NULL;
276
e25de718
JL
277 if (strncmp (secname, ".upper.", 7) == 0
278 || strncmp (secname, ".lower.", 7) == 0)
279 {
280 warn_no_output_section (secname);
281 return NULL;
282 }
283
837a17b3
NC
284 /* We only need special handling for .either sections. */
285 if (strncmp (secname, ".either.", 8) != 0)
286 return NULL;
287
288 /* Skip the .either prefix. */
289 secname += 7;
290
291 /* Compute the names of the corresponding upper and lower
292 sections. If the input section name contains another period,
293 only use the part of the name before the second dot. */
294 if (strchr (secname + 1, '.') != NULL)
295 {
82b94616 296 name = xstrdup (secname);
837a17b3
NC
297
298 * strchr (name + 1, '.') = 0;
299 }
300 else
301 name = (char *) secname;
6c19b93b 302
e1fa0163
NC
303 lower_name = concat (".lower", name, NULL);
304 upper_name = concat (".upper", name, NULL);
837a17b3
NC
305
306 /* Find the corresponding lower and upper sections. */
307 lower = lang_output_section_find (lower_name);
308 upper = lang_output_section_find (upper_name);
837a17b3 309
7ef3addb
JL
310 if (lower == NULL && upper == NULL)
311 {
d003af55 312 einfo (_("%P: error: no section named %s or %s in linker script\n"),
7ef3addb
JL
313 lower_name, upper_name);
314 goto end;
315 }
316 else if (lower == NULL)
837a17b3 317 {
7ef3addb
JL
318 lower = lang_output_section_find (name);
319 if (lower == NULL)
320 {
d003af55 321 einfo (_("%P: error: no section named %s in linker script\n"), name);
e1fa0163 322 goto end;
837a17b3
NC
323 }
324 }
7ef3addb
JL
325
326 /* Always place orphaned sections in lower. Optimal placement of either
327 sections is performed later, once section sizes have been finalized. */
b209b5a6 328 lang_add_section (& lower->children, s, NULL, NULL, lower);
7ef3addb
JL
329 end:
330 free (upper_name);
331 free (lower_name);
7ef3addb
JL
332 return lower;
333}
334EOF
335fi
336
337fragment <<EOF
338
f38a2680 339static bool
1a9f72a7 340change_output_section (lang_statement_union_type **head,
7ef3addb 341 asection *s,
1a9f72a7
JL
342 lang_output_section_statement_type *new_os,
343 lang_output_section_statement_type *old_os)
7ef3addb
JL
344{
345 asection *is;
346 lang_statement_union_type * prev = NULL;
347 lang_statement_union_type * curr;
348
349 curr = *head;
350 while (curr != NULL)
351 {
352 switch (curr->header.type)
353 {
354 case lang_input_section_enum:
355 is = curr->input_section.section;
356 if (is == s)
357 {
1a9f72a7
JL
358 lang_statement_list_type *old_list
359 = (lang_statement_list_type *) &old_os->children;
7ef3addb 360 s->output_section = NULL;
b209b5a6
AM
361 lang_add_section (&new_os->children, s,
362 curr->input_section.pattern, NULL, new_os);
1a9f72a7 363
7ef3addb
JL
364 /* Remove the section from the old output section. */
365 if (prev == NULL)
366 *head = curr->header.next;
367 else
368 prev->header.next = curr->header.next;
1a9f72a7
JL
369 /* If the input section we just moved is the tail of the old
370 output section, then we also need to adjust that tail. */
371 if (old_list->tail == (lang_statement_union_type **) curr)
372 old_list->tail = (lang_statement_union_type **) prev;
373
f38a2680 374 return true;
7ef3addb
JL
375 }
376 break;
377 case lang_wild_statement_enum:
378 if (change_output_section (&(curr->wild_statement.children.head),
1a9f72a7 379 s, new_os, old_os))
f38a2680 380 return true;
7ef3addb
JL
381 break;
382 default:
383 break;
384 }
385 prev = curr;
386 curr = curr->header.next;
387 }
f38a2680 388 return false;
7ef3addb
JL
389}
390
7ef3addb 391static void
fd361982
AM
392add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s,
393 void *unused ATTRIBUTE_UNUSED)
7ef3addb 394{
fd361982 395 const char *curr_name = bfd_section_name (s);
7ef3addb
JL
396 int region = REGION_NONE;
397
398 if (strncmp (curr_name, ".text", 5) == 0)
e25de718 399 region = code_region;
7ef3addb 400 else if (strncmp (curr_name, ".data", 5) == 0)
e25de718 401 region = data_region;
7ef3addb 402 else if (strncmp (curr_name, ".bss", 4) == 0)
e25de718 403 region = data_region;
7ef3addb 404 else if (strncmp (curr_name, ".rodata", 7) == 0)
e25de718 405 region = data_region;
7ef3addb
JL
406 else
407 return;
408
409 switch (region)
410 {
411 case REGION_NONE:
412 break;
413 case REGION_UPPER:
fd361982 414 bfd_rename_section (s, concat (".upper", curr_name, NULL));
7ef3addb
JL
415 break;
416 case REGION_LOWER:
fd361982 417 bfd_rename_section (s, concat (".lower", curr_name, NULL));
7ef3addb
JL
418 break;
419 case REGION_EITHER:
e7d942e0 420 bfd_rename_section (s, concat (".either", curr_name, NULL));
7ef3addb
JL
421 break;
422 default:
423 /* Unreachable. */
424 FAIL ();
425 break;
426 }
7ef3addb
JL
427}
428
429static void
430msp430_elf_after_open (void)
431{
432 bfd *abfd;
433
434 gld${EMULATION_NAME}_after_open ();
837a17b3 435
7ef3addb
JL
436 /* If neither --code-region or --data-region have been passed, do not
437 transform sections names. */
438 if ((code_region == REGION_NONE && data_region == REGION_NONE)
439 || disable_sec_transformation)
440 return;
441
442 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
443 bfd_map_over_sections (abfd, add_region_prefix, NULL);
444}
445
446#define OPTION_CODE_REGION 321
447#define OPTION_DATA_REGION (OPTION_CODE_REGION + 1)
448#define OPTION_DISABLE_TRANS (OPTION_CODE_REGION + 2)
449
450static void
451gld${EMULATION_NAME}_add_options
452 (int ns, char **shortopts, int nl, struct option **longopts,
453 int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
454{
455 static const char xtra_short[] = { };
837a17b3 456
7ef3addb
JL
457 static const struct option xtra_long[] =
458 {
459 { "code-region", required_argument, NULL, OPTION_CODE_REGION },
460 { "data-region", required_argument, NULL, OPTION_DATA_REGION },
461 { "disable-sec-transformation", no_argument, NULL,
462 OPTION_DISABLE_TRANS },
463 { NULL, no_argument, NULL, 0 }
464 };
465
466 *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
467 memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
468 *longopts = (struct option *)
469 xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
470 memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
471}
837a17b3 472
7ef3addb
JL
473static void
474gld${EMULATION_NAME}_list_options (FILE * file)
475{
df5f2391
AM
476 fprintf (file, _(" --code-region={either,lower,upper,none}\n\
477 Transform .text* sections to {either,lower,upper,none}.text* sections\n"));
478 fprintf (file, _(" --data-region={either,lower,upper,none}\n\
479 Transform .data*, .rodata* and .bss* sections to\n\
480 {either,lower,upper,none}.{bss,data,rodata}* sections\n"));
481 fprintf (file, _(" --disable-sec-transformation\n\
482 Disable transformation of .{text,data,bss,rodata}* sections to\n\
483 add the {either,lower,upper,none} prefixes\n"));
7ef3addb 484}
837a17b3 485
f38a2680 486static bool
7ef3addb
JL
487gld${EMULATION_NAME}_handle_option (int optc)
488{
489 switch (optc)
490 {
491 case OPTION_CODE_REGION:
492 if (strcmp (optarg, "upper") == 0)
493 code_region = REGION_UPPER;
494 else if (strcmp (optarg, "lower") == 0)
495 code_region = REGION_LOWER;
496 else if (strcmp (optarg, "either") == 0)
497 code_region = REGION_EITHER;
498 else if (strcmp (optarg, "none") == 0)
499 code_region = REGION_NONE;
500 else if (strlen (optarg) == 0)
501 {
df5f2391
AM
502 einfo (_("%P: --code-region requires an argument: "
503 "{upper,lower,either,none}\n"));
f38a2680 504 return false;
7ef3addb 505 }
837a17b3 506 else
7ef3addb 507 {
df5f2391
AM
508 einfo (_("%P: error: unrecognized argument to --code-region= option: "
509 "\"%s\"\n"), optarg);
f38a2680 510 return false;
7ef3addb
JL
511 }
512 break;
513
514 case OPTION_DATA_REGION:
515 if (strcmp (optarg, "upper") == 0)
516 data_region = REGION_UPPER;
517 else if (strcmp (optarg, "lower") == 0)
518 data_region = REGION_LOWER;
519 else if (strcmp (optarg, "either") == 0)
520 data_region = REGION_EITHER;
521 else if (strcmp (optarg, "none") == 0)
522 data_region = REGION_NONE;
523 else if (strlen (optarg) == 0)
524 {
df5f2391
AM
525 einfo (_("%P: --data-region requires an argument: "
526 "{upper,lower,either,none}\n"));
f38a2680 527 return false;
7ef3addb
JL
528 }
529 else
530 {
df5f2391
AM
531 einfo (_("%P: error: unrecognized argument to --data-region= option: "
532 "\"%s\"\n"), optarg);
f38a2680 533 return false;
7ef3addb
JL
534 }
535 break;
536
537 case OPTION_DISABLE_TRANS:
f38a2680 538 disable_sec_transformation = true;
7ef3addb
JL
539 break;
540
541 default:
f38a2680 542 return false;
7ef3addb 543 }
f38a2680 544 return true;
7ef3addb
JL
545}
546
547static void
fd361982
AM
548eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
549 asection *s, void *data)
7ef3addb 550{
96d01d93 551 const char * base_sec_name;
7ef3addb
JL
552 const char * curr_name;
553 char * either_name;
554 int curr_region;
555
556 lang_output_section_statement_type * lower;
557 lang_output_section_statement_type * upper;
558 static bfd_size_type *lower_size = 0;
559 static bfd_size_type *upper_size = 0;
560 static bfd_size_type lower_size_rom = 0;
561 static bfd_size_type lower_size_ram = 0;
562 static bfd_size_type upper_size_rom = 0;
563 static bfd_size_type upper_size_ram = 0;
564
565 if ((s->flags & SEC_ALLOC) == 0)
566 return;
567 if (bfd_link_relocatable (&link_info))
568 return;
569
96d01d93 570 base_sec_name = (const char *) data;
fd361982 571 curr_name = bfd_section_name (s);
7ef3addb
JL
572
573 /* Only concerned with .either input sections in the upper output section. */
574 either_name = concat (".either", base_sec_name, NULL);
575 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
576 || strncmp (s->output_section->name, ".upper", 6) != 0)
577 goto end;
578
579 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
580 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
581
582 if (upper == NULL || upper->region == NULL)
583 goto end;
584 else if (lower == NULL)
585 lower = lang_output_section_find (base_sec_name);
586 if (lower == NULL || lower->region == NULL)
587 goto end;
588
589 if (strcmp (base_sec_name, ".text") == 0
590 || strcmp (base_sec_name, ".rodata") == 0)
591 curr_region = ROM;
592 else
593 curr_region = RAM;
594
595 if (curr_region == ROM)
596 {
597 if (lower_size_rom == 0)
598 {
599 lower_size_rom = lower->region->current - lower->region->origin;
600 upper_size_rom = upper->region->current - upper->region->origin;
601 }
602 lower_size = &lower_size_rom;
603 upper_size = &upper_size_rom;
604 }
605 else if (curr_region == RAM)
606 {
607 if (lower_size_ram == 0)
608 {
609 lower_size_ram = lower->region->current - lower->region->origin;
610 upper_size_ram = upper->region->current - upper->region->origin;
611 }
612 lower_size = &lower_size_ram;
613 upper_size = &upper_size_ram;
837a17b3
NC
614 }
615
1a9f72a7
JL
616 /* If the upper region is overflowing, try moving sections to the lower
617 region.
618 Note that there isn't any general benefit to using lower memory over upper
619 memory, so we only move sections around with the goal of making the program
620 fit. */
621 if (*upper_size > upper->region->length
622 && *lower_size + s->size < lower->region->length)
7ef3addb 623 {
1a9f72a7 624 if (change_output_section (&(upper->children.head), s, lower, upper))
7ef3addb
JL
625 {
626 *upper_size -= s->size;
627 *lower_size += s->size;
628 }
629 }
e1fa0163 630 end:
7ef3addb 631 free (either_name);
837a17b3 632}
837a17b3 633
7ef3addb 634static void
fd361982
AM
635eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
636 asection *s, void *data)
7ef3addb 637{
96d01d93 638 const char * base_sec_name;
7ef3addb
JL
639 const char * curr_name;
640 char * either_name;
641 int curr_region;
642 lang_output_section_statement_type * output_sec;
643 lang_output_section_statement_type * lower;
644 lang_output_section_statement_type * upper;
645
646 static bfd_size_type *lower_size = 0;
647 static bfd_size_type lower_size_rom = 0;
648 static bfd_size_type lower_size_ram = 0;
649
650 if ((s->flags & SEC_ALLOC) == 0)
651 return;
652 if (bfd_link_relocatable (&link_info))
653 return;
654
96d01d93 655 base_sec_name = (const char *) data;
fd361982 656 curr_name = bfd_section_name (s);
7ef3addb
JL
657
658 /* Only concerned with .either input sections in the lower or "default"
659 output section i.e. not in the upper output section. */
660 either_name = concat (".either", base_sec_name, NULL);
661 if (strncmp (curr_name, either_name, strlen (either_name)) != 0
662 || strncmp (s->output_section->name, ".upper", 6) == 0)
663 return;
664
665 if (strcmp (base_sec_name, ".text") == 0
666 || strcmp (base_sec_name, ".rodata") == 0)
667 curr_region = ROM;
668 else
669 curr_region = RAM;
670
671 output_sec = lang_output_section_find (s->output_section->name);
672
673 /* If the output_section doesn't exist, this has already been reported in
674 place_orphan, so don't need to warn again. */
675 if (output_sec == NULL || output_sec->region == NULL)
676 goto end;
677
678 /* lower and output_sec might be the same, but in some cases an .either
679 section can end up in base_sec_name if it hasn't been placed by
680 place_orphan. */
681 lower = lang_output_section_find (concat (".lower", base_sec_name, NULL));
682 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
683 if (upper == NULL)
684 goto end;
685
686 if (curr_region == ROM)
687 {
688 if (lower_size_rom == 0)
689 {
690 /* Get the size of other items in the lower region that aren't the
691 sections to be moved around. */
692 lower_size_rom
693 = (output_sec->region->current - output_sec->region->origin)
694 - scan_children (output_sec->children.head);
695 if (output_sec != lower && lower != NULL)
696 lower_size_rom -= scan_children (lower->children.head);
697 }
698 lower_size = &lower_size_rom;
699 }
700 else if (curr_region == RAM)
701 {
702 if (lower_size_ram == 0)
703 {
704 lower_size_ram
705 = (output_sec->region->current - output_sec->region->origin)
706 - scan_children (output_sec->children.head);
707 if (output_sec != lower && lower != NULL)
708 lower_size_ram -= scan_children (lower->children.head);
709 }
710 lower_size = &lower_size_ram;
711 }
712 /* Move sections that cause the lower region to overflow to the upper region. */
713 if (*lower_size + s->size > output_sec->region->length)
1a9f72a7 714 change_output_section (&(output_sec->children.head), s, upper, output_sec);
7ef3addb
JL
715 else
716 *lower_size += s->size;
717 end:
718 free (either_name);
719}
720
721/* This function is similar to lang_relax_sections, but without the size
722 evaluation code that is always executed after relaxation. */
723static void
724intermediate_relax_sections (void)
725{
726 int i = link_info.relax_pass;
727
728 /* The backend can use it to determine the current pass. */
729 link_info.relax_pass = 0;
730
731 while (i--)
732 {
f38a2680 733 bool relax_again;
7ef3addb
JL
734
735 link_info.relax_trip = -1;
736 do
737 {
738 link_info.relax_trip++;
739
740 lang_do_assignments (lang_assigning_phase_enum);
741
742 lang_reset_memory_regions ();
743
f38a2680
AM
744 relax_again = false;
745 lang_size_sections (&relax_again, false);
7ef3addb
JL
746 }
747 while (relax_again);
748
749 link_info.relax_pass++;
750 }
751}
752
753static void
754msp430_elf_after_allocation (void)
755{
756 int relax_count = 0;
96d01d93 757 unsigned int i;
7ef3addb
JL
758 /* Go over each section twice, once to place either sections that don't fit
759 in lower into upper, and then again to move any sections in upper that
760 fit in lower into lower. */
761 for (i = 0; i < 8; i++)
762 {
763 int placement_stage = (i < 4) ? LOWER_TO_UPPER : UPPER_TO_LOWER;
96d01d93 764 const char * base_sec_name;
7ef3addb
JL
765 lang_output_section_statement_type * upper;
766
767 switch (i % 4)
768 {
96d01d93 769 default:
7ef3addb 770 case 0:
96d01d93 771 base_sec_name = ".text";
7ef3addb
JL
772 break;
773 case 1:
96d01d93 774 base_sec_name = ".data";
7ef3addb
JL
775 break;
776 case 2:
96d01d93 777 base_sec_name = ".bss";
7ef3addb
JL
778 break;
779 case 3:
96d01d93 780 base_sec_name = ".rodata";
7ef3addb
JL
781 break;
782 }
783 upper = lang_output_section_find (concat (".upper", base_sec_name, NULL));
784 if (upper != NULL)
785 {
786 /* Can't just use one iteration over the all the sections to make
787 both lower->upper and upper->lower transformations because the
788 iterator encounters upper sections before all lower sections have
789 been examined. */
790 bfd *abfd;
791
792 if (placement_stage == LOWER_TO_UPPER)
793 {
794 /* Perform relaxation and get the final size of sections
795 before trying to fit .either sections in the correct
796 ouput sections. */
797 if (relax_count == 0)
798 {
799 intermediate_relax_sections ();
800 relax_count++;
801 }
802 for (abfd = link_info.input_bfds; abfd != NULL;
803 abfd = abfd->link.next)
804 {
805 bfd_map_over_sections (abfd, eval_lower_either_sections,
96d01d93 806 (void *) base_sec_name);
7ef3addb
JL
807 }
808 }
809 else if (placement_stage == UPPER_TO_LOWER)
810 {
811 /* Relax again before moving upper->lower. */
812 if (relax_count == 1)
813 {
814 intermediate_relax_sections ();
815 relax_count++;
816 }
817 for (abfd = link_info.input_bfds; abfd != NULL;
818 abfd = abfd->link.next)
819 {
820 bfd_map_over_sections (abfd, eval_upper_either_sections,
96d01d93 821 (void *) base_sec_name);
7ef3addb
JL
822 }
823 }
824
825 }
7ef3addb
JL
826 }
827 gld${EMULATION_NAME}_after_allocation ();
828}
837a17b3 829
64b63c29
JL
830/* Return TRUE if a non-debug input section in L has positive size and matches
831 the given name. */
832static int
833input_section_exists (lang_statement_union_type * l, const char * name)
834{
835 while (l != NULL)
836 {
837 switch (l->header.type)
838 {
839 case lang_input_section_enum:
840 if ((l->input_section.section->flags & SEC_ALLOC)
841 && l->input_section.section->size > 0
842 && !strcmp (l->input_section.section->name, name))
f38a2680 843 return true;
64b63c29
JL
844 break;
845
846 case lang_wild_statement_enum:
847 if (input_section_exists (l->wild_statement.children.head, name))
f38a2680 848 return true;
64b63c29
JL
849 break;
850
851 default:
852 break;
853 }
854 l = l->header.next;
855 }
f38a2680 856 return false;
64b63c29
JL
857}
858
859/* Some MSP430 linker scripts do not include ALIGN directives to ensure
860 __preinit_array_start, __init_array_start or __fini_array_start are word
861 aligned.
862 If __*_array_start symbols are not word aligned, the code in crt0 to run
863 through the array and call the functions will crash.
864 To avoid warning unnecessarily when the .*_array sections are not being
865 used for running constructors/destructors, only emit the warning if
866 the associated section exists and has size. */
867static void
868check_array_section_alignment (void)
869{
870 int i;
871 lang_output_section_statement_type * rodata_sec;
872 lang_output_section_statement_type * rodata2_sec;
873 const char * array_names[3][2] = { { ".init_array", "__init_array_start" },
874 { ".preinit_array", "__preinit_array_start" },
875 { ".fini_array", "__fini_array_start" } };
876
877 /* .{preinit,init,fini}_array could be in either .rodata or .rodata2. */
878 rodata_sec = lang_output_section_find (".rodata");
879 rodata2_sec = lang_output_section_find (".rodata2");
880 if (rodata_sec == NULL && rodata2_sec == NULL)
881 return;
882
883 /* There are 3 .*_array sections which must be checked for alignment. */
884 for (i = 0; i < 3; i++)
885 {
886 struct bfd_link_hash_entry * sym;
887 if (((rodata_sec && input_section_exists (rodata_sec->children.head,
888 array_names[i][0]))
889 || (rodata2_sec && input_section_exists (rodata2_sec->children.head,
890 array_names[i][0])))
891 && (sym = bfd_link_hash_lookup (link_info.hash, array_names[i][1],
f38a2680 892 false, false, true))
64b63c29
JL
893 && sym->type == bfd_link_hash_defined
894 && sym->u.def.value % 2)
895 {
896 einfo ("%P: warning: \"%s\" symbol (%pU) is not word aligned\n",
897 array_names[i][1], NULL);
898 }
899 }
900}
901
902static void
903gld${EMULATION_NAME}_finish (void)
904{
905 finish_default ();
906 check_array_section_alignment ();
907}
837a17b3 908EOF
a9261391
L
909
910LDEMUL_AFTER_OPEN=msp430_elf_after_open
911LDEMUL_AFTER_ALLOCATION=msp430_elf_after_allocation
912LDEMUL_PLACE_ORPHAN=${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}
913LDEMUL_FINISH=gld${EMULATION_NAME}_finish
914LDEMUL_ADD_OPTIONS=gld${EMULATION_NAME}_add_options
915LDEMUL_HANDLE_OPTION=gld${EMULATION_NAME}_handle_option
916LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options
917
918source_em ${srcdir}/emultempl/emulation.em
837a17b3
NC
919# \f
920# Local Variables:
921# mode: c
922# End: