]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/emultempl/msp430.em
Update year range in copyright notice of binutils files
[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-2023 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 bool 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 bool 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 lang_output_section_statement_type * lower;
265 lang_output_section_statement_type * upper;
266
267 if ((s->flags & SEC_ALLOC) == 0)
268 return NULL;
269
270 if (bfd_link_relocatable (&link_info))
271 return NULL;
272
273 /* If constraints are involved let the linker handle the placement normally. */
274 if (constraint != 0)
275 return NULL;
276
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
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 {
296 name = xstrdup (secname);
297
298 * strchr (name + 1, '.') = 0;
299 }
300 else
301 name = (char *) secname;
302
303 lower_name = concat (".lower", name, NULL);
304 upper_name = concat (".upper", name, NULL);
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);
309
310 if (lower == NULL && upper == NULL)
311 {
312 einfo (_("%P: error: no section named %s or %s in linker script\n"),
313 lower_name, upper_name);
314 goto end;
315 }
316 else if (lower == NULL)
317 {
318 lower = lang_output_section_find (name);
319 if (lower == NULL)
320 {
321 einfo (_("%P: error: no section named %s in linker script\n"), name);
322 goto end;
323 }
324 }
325
326 /* Always place orphaned sections in lower. Optimal placement of either
327 sections is performed later, once section sizes have been finalized. */
328 lang_add_section (& lower->children, s, NULL, NULL, lower);
329 end:
330 free (upper_name);
331 free (lower_name);
332 return lower;
333 }
334 EOF
335 fi
336
337 fragment <<EOF
338
339 static bool
340 change_output_section (lang_statement_union_type **head,
341 asection *s,
342 lang_output_section_statement_type *new_os,
343 lang_output_section_statement_type *old_os)
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 {
358 lang_statement_list_type *old_list
359 = (lang_statement_list_type *) &old_os->children;
360 s->output_section = NULL;
361 lang_add_section (&new_os->children, s,
362 curr->input_section.pattern, NULL, new_os);
363
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;
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
374 return true;
375 }
376 break;
377 case lang_wild_statement_enum:
378 if (change_output_section (&(curr->wild_statement.children.head),
379 s, new_os, old_os))
380 return true;
381 break;
382 default:
383 break;
384 }
385 prev = curr;
386 curr = curr->header.next;
387 }
388 return false;
389 }
390
391 static void
392 add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s,
393 void *unused ATTRIBUTE_UNUSED)
394 {
395 const char *curr_name = bfd_section_name (s);
396 int region = REGION_NONE;
397
398 if (strncmp (curr_name, ".text", 5) == 0)
399 region = code_region;
400 else if (strncmp (curr_name, ".data", 5) == 0)
401 region = data_region;
402 else if (strncmp (curr_name, ".bss", 4) == 0)
403 region = data_region;
404 else if (strncmp (curr_name, ".rodata", 7) == 0)
405 region = data_region;
406 else
407 return;
408
409 switch (region)
410 {
411 case REGION_NONE:
412 break;
413 case REGION_UPPER:
414 bfd_rename_section (s, concat (".upper", curr_name, NULL));
415 break;
416 case REGION_LOWER:
417 bfd_rename_section (s, concat (".lower", curr_name, NULL));
418 break;
419 case REGION_EITHER:
420 bfd_rename_section (s, concat (".either", curr_name, NULL));
421 break;
422 default:
423 /* Unreachable. */
424 FAIL ();
425 break;
426 }
427 }
428
429 static void
430 msp430_elf_after_open (void)
431 {
432 bfd *abfd;
433
434 gld${EMULATION_NAME}_after_open ();
435
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
450 static void
451 gld${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[] = { };
456
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 }
472
473 static void
474 gld${EMULATION_NAME}_list_options (FILE * file)
475 {
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"));
484 }
485
486 static bool
487 gld${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 {
502 einfo (_("%P: --code-region requires an argument: "
503 "{upper,lower,either,none}\n"));
504 return false;
505 }
506 else
507 {
508 einfo (_("%P: error: unrecognized argument to --code-region= option: "
509 "\"%s\"\n"), optarg);
510 return false;
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 {
525 einfo (_("%P: --data-region requires an argument: "
526 "{upper,lower,either,none}\n"));
527 return false;
528 }
529 else
530 {
531 einfo (_("%P: error: unrecognized argument to --data-region= option: "
532 "\"%s\"\n"), optarg);
533 return false;
534 }
535 break;
536
537 case OPTION_DISABLE_TRANS:
538 disable_sec_transformation = true;
539 break;
540
541 default:
542 return false;
543 }
544 return true;
545 }
546
547 static void
548 eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
549 asection *s, void *data)
550 {
551 const char * base_sec_name;
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
570 base_sec_name = (const char *) data;
571 curr_name = bfd_section_name (s);
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;
614 }
615
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)
623 {
624 if (change_output_section (&(upper->children.head), s, lower, upper))
625 {
626 *upper_size -= s->size;
627 *lower_size += s->size;
628 }
629 }
630 end:
631 free (either_name);
632 }
633
634 static void
635 eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
636 asection *s, void *data)
637 {
638 const char * base_sec_name;
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
655 base_sec_name = (const char *) data;
656 curr_name = bfd_section_name (s);
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)
714 change_output_section (&(output_sec->children.head), s, upper, output_sec);
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. */
723 static void
724 intermediate_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 {
733 bool relax_again;
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
744 relax_again = false;
745 lang_size_sections (&relax_again, false);
746 }
747 while (relax_again);
748
749 link_info.relax_pass++;
750 }
751 }
752
753 static void
754 msp430_elf_after_allocation (void)
755 {
756 int relax_count = 0;
757 unsigned int i;
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;
764 const char * base_sec_name;
765 lang_output_section_statement_type * upper;
766
767 switch (i % 4)
768 {
769 default:
770 case 0:
771 base_sec_name = ".text";
772 break;
773 case 1:
774 base_sec_name = ".data";
775 break;
776 case 2:
777 base_sec_name = ".bss";
778 break;
779 case 3:
780 base_sec_name = ".rodata";
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,
806 (void *) base_sec_name);
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,
821 (void *) base_sec_name);
822 }
823 }
824
825 }
826 }
827 gld${EMULATION_NAME}_after_allocation ();
828 }
829
830 /* Return TRUE if a non-debug input section in L has positive size and matches
831 the given name. */
832 static int
833 input_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))
843 return true;
844 break;
845
846 case lang_wild_statement_enum:
847 if (input_section_exists (l->wild_statement.children.head, name))
848 return true;
849 break;
850
851 default:
852 break;
853 }
854 l = l->header.next;
855 }
856 return false;
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. */
867 static void
868 check_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],
892 false, false, true))
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
902 static void
903 gld${EMULATION_NAME}_finish (void)
904 {
905 finish_default ();
906 check_array_section_alignment ();
907 }
908 EOF
909
910 LDEMUL_AFTER_OPEN=msp430_elf_after_open
911 LDEMUL_AFTER_ALLOCATION=msp430_elf_after_allocation
912 LDEMUL_PLACE_ORPHAN=${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}
913 LDEMUL_FINISH=gld${EMULATION_NAME}_finish
914 LDEMUL_ADD_OPTIONS=gld${EMULATION_NAME}_add_options
915 LDEMUL_HANDLE_OPTION=gld${EMULATION_NAME}_handle_option
916 LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options
917
918 source_em ${srcdir}/emultempl/emulation.em
919 # \f
920 # Local Variables:
921 # mode: c
922 # End: