xref: /netbsd-src/external/gpl3/binutils/dist/ld/emultempl/msp430.em (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
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}
7   Copyright (C) 2014-2020 Free Software Foundation, Inc.
8   Written by Steve Chamberlain steve@cygnus.com
9   Extended for the MSP430 by Nick Clifton  nickc@redhat.com
10
11   This file is part of the GNU Binutils.
12
13   This program is free software; you can redistribute it and/or modify
14   it under the terms of the GNU General Public License as published by
15   the Free Software Foundation; either version 3 of the License, or
16   (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21   GNU General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
26   MA 02110-1301, USA.  */
27
28#define TARGET_IS_${EMULATION_NAME}
29
30#include "sysdep.h"
31#include "bfd.h"
32#include "bfdlink.h"
33#include "ctf-api.h"
34
35#include "ld.h"
36#include "getopt.h"
37#include "ldmain.h"
38#include "ldmisc.h"
39#include "ldexp.h"
40#include "ldlang.h"
41#include "ldfile.h"
42#include "ldemul.h"
43#include "libiberty.h"
44#include <ldgram.h>
45
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
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.  */
88  if (!bfd_link_relocatable (&link_info))
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
113  if (bfd_link_relocatable (&link_info) && config.build_constructors)
114    return
115EOF
116sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
117echo '  ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
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
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}
145EOF
146fi
147fi
148
149if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
150fragment <<EOF
151
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:
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
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:
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.".  */
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
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  char * buf = NULL;
265  lang_output_section_statement_type * lower;
266  lang_output_section_statement_type * upper;
267
268  if ((s->flags & SEC_ALLOC) == 0)
269    return NULL;
270
271  if (bfd_link_relocatable (&link_info))
272    return NULL;
273
274  /* If constraints are involved let the linker handle the placement normally.  */
275  if (constraint != 0)
276    return NULL;
277
278  if (strncmp (secname, ".upper.", 7) == 0
279      || strncmp (secname, ".lower.", 7) == 0)
280    {
281      warn_no_output_section (secname);
282      return NULL;
283    }
284
285  /* We only need special handling for .either sections.  */
286  if (strncmp (secname, ".either.", 8) != 0)
287    return NULL;
288
289  /* Skip the .either prefix.  */
290  secname += 7;
291
292  /* Compute the names of the corresponding upper and lower
293     sections.  If the input section name contains another period,
294     only use the part of the name before the second dot.  */
295  if (strchr (secname + 1, '.') != NULL)
296    {
297      buf = name = xstrdup (secname);
298
299      * strchr (name + 1, '.') = 0;
300    }
301  else
302    name = (char *) secname;
303
304  lower_name = concat (".lower", name, NULL);
305  upper_name = concat (".upper", name, NULL);
306
307  /* Find the corresponding lower and upper sections.  */
308  lower = lang_output_section_find (lower_name);
309  upper = lang_output_section_find (upper_name);
310
311  if (lower == NULL && upper == NULL)
312    {
313      einfo (_("%P: error: no section named %s or %s in linker script\n"),
314	     lower_name, upper_name);
315      goto end;
316    }
317  else if (lower == NULL)
318    {
319      lower = lang_output_section_find (name);
320      if (lower == NULL)
321	{
322	  einfo (_("%P: error: no section named %s in linker script\n"), name);
323	  goto end;
324	}
325    }
326
327  /* Always place orphaned sections in lower.  Optimal placement of either
328     sections is performed later, once section sizes have been finalized.  */
329  lang_add_section (& lower->children, s, NULL, lower);
330 end:
331  free (upper_name);
332  free (lower_name);
333  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
385static void
386add_region_prefix (bfd *abfd ATTRIBUTE_UNUSED, asection *s,
387		   void *unused ATTRIBUTE_UNUSED)
388{
389  const char *curr_name = bfd_section_name (s);
390  int region = REGION_NONE;
391
392  if (strncmp (curr_name, ".text", 5) == 0)
393    region = code_region;
394  else if (strncmp (curr_name, ".data", 5) == 0)
395    region = data_region;
396  else if (strncmp (curr_name, ".bss", 4) == 0)
397    region = data_region;
398  else if (strncmp (curr_name, ".rodata", 7) == 0)
399    region = data_region;
400  else
401    return;
402
403  switch (region)
404    {
405    case REGION_NONE:
406      break;
407    case REGION_UPPER:
408      bfd_rename_section (s, concat (".upper", curr_name, NULL));
409      break;
410    case REGION_LOWER:
411      bfd_rename_section (s, concat (".lower", curr_name, NULL));
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    }
421}
422
423static void
424msp430_elf_after_open (void)
425{
426  bfd *abfd;
427
428  gld${EMULATION_NAME}_after_open ();
429
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[] = { };
450
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}
466
467static void
468gld${EMULATION_NAME}_list_options (FILE * file)
469{
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"));
478}
479
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	{
496	  einfo (_("%P: --code-region requires an argument: "
497		   "{upper,lower,either,none}\n"));
498	  return FALSE;
499	}
500      else
501	{
502	  einfo (_("%P: error: unrecognized argument to --code-region= option: "
503		   "\"%s\"\n"), optarg);
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	{
519	  einfo (_("%P: --data-region requires an argument: "
520		   "{upper,lower,either,none}\n"));
521	  return FALSE;
522	}
523      else
524	{
525	  einfo (_("%P: error: unrecognized argument to --data-region= option: "
526		   "\"%s\"\n"), optarg);
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
542eval_upper_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
543			    asection *s, void *data)
544{
545  const char * base_sec_name;
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
564  base_sec_name = (const char *) data;
565  curr_name = bfd_section_name (s);
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;
608    }
609
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    }
620 end:
621  free (either_name);
622}
623
624static void
625eval_lower_either_sections (bfd *abfd ATTRIBUTE_UNUSED,
626			    asection *s, void *data)
627{
628  const char * base_sec_name;
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
645  base_sec_name = (const char *) data;
646  curr_name = bfd_section_name (s);
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;
747  unsigned int i;
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;
754      const char * base_sec_name;
755      lang_output_section_statement_type * upper;
756
757      switch (i % 4)
758	{
759	default:
760	case 0:
761	  base_sec_name = ".text";
762	  break;
763	case 1:
764	  base_sec_name = ".data";
765	  break;
766	case 2:
767	  base_sec_name = ".bss";
768	  break;
769	case 3:
770	  base_sec_name = ".rodata";
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,
796					 (void *) base_sec_name);
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,
811					 (void *) base_sec_name);
812		}
813	    }
814
815	}
816    }
817  gld${EMULATION_NAME}_after_allocation ();
818}
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},
826  msp430_elf_after_open,
827  after_check_relocs_default,
828  msp430_elf_after_allocation,
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},
841  gld${EMULATION_NAME}_add_options,
842  gld${EMULATION_NAME}_handle_option,
843  ${LDEMUL_UNRECOGNIZED_FILE-NULL},
844  gld${EMULATION_NAME}_list_options,
845  ${LDEMUL_RECOGNIZED_FILE-NULL},
846  ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
847  ${LDEMUL_NEW_VERS_PATTERN-NULL},
848  ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL},
849  ${LDEMUL_EMIT_CTF_EARLY-NULL},
850  ${LDEMUL_EXAMINE_STRTAB_FOR_CTF-NULL}
851};
852EOF
853#
854# Local Variables:
855# mode: c
856# End:
857