Import binutils 2.18
[nacl-binutils.git] / ld / emultempl / beos.em
blob23d3849c5d70f27cd9caa15d9027c3e4cd7c4d4f
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 if [ -z "$MACHINE" ]; then
4   OUTPUT_ARCH=${ARCH}
5 else
6   OUTPUT_ARCH=${ARCH}:${MACHINE}
7 fi
8 fragment <<EOF
9 /* This file is part of GLD, the Gnu Linker.
10    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
11    2005, 2006, 2007 Free Software Foundation, Inc.
13    This file is part of the GNU Binutils.
15    This program is free software; you can redistribute it and/or modify
16    it under the terms of the GNU General Public License as published by
17    the Free Software Foundation; either version 3 of the License, or
18    (at your option) any later version.
20    This program is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23    GNU General Public License for more details.
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
28    MA 02110-1301, USA.  */
31 /* For WINDOWS_NT */
32 /* The original file generated returned different default scripts depending
33    on whether certain switches were set, but these switches pertain to the
34    Linux system and that particular version of coff.  In the NT case, we
35    only determine if the subsystem is console or windows in order to select
36    the correct entry point by default. */
38 #include "sysdep.h"
39 #include "bfd.h"
40 #include "bfdlink.h"
41 #include "getopt.h"
42 #include "libiberty.h"
43 #include "ld.h"
44 #include "ldmain.h"
45 #include "ldexp.h"
46 #include "ldlang.h"
47 #include "ldfile.h"
48 #include "ldemul.h"
49 #include <ldgram.h>
50 #include "ldlex.h"
51 #include "ldmisc.h"
52 #include "ldctor.h"
53 #include "coff/internal.h"
54 #include "../bfd/libcoff.h"
56 #define TARGET_IS_${EMULATION_NAME}
58 static struct internal_extra_pe_aouthdr pe;
59 static int dll;
61 extern const char *output_filename;
63 static void
64 gld_${EMULATION_NAME}_before_parse (void)
66   ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
67   output_filename = "a.exe";
70 /* PE format extra command line options.  */
72 /* Used for setting flags in the PE header. */
73 #define OPTION_BASE_FILE                (300  + 1)
74 #define OPTION_DLL                      (OPTION_BASE_FILE + 1)
75 #define OPTION_FILE_ALIGNMENT           (OPTION_DLL + 1)
76 #define OPTION_IMAGE_BASE               (OPTION_FILE_ALIGNMENT + 1)
77 #define OPTION_MAJOR_IMAGE_VERSION      (OPTION_IMAGE_BASE + 1)
78 #define OPTION_MAJOR_OS_VERSION         (OPTION_MAJOR_IMAGE_VERSION + 1)
79 #define OPTION_MAJOR_SUBSYSTEM_VERSION  (OPTION_MAJOR_OS_VERSION + 1)
80 #define OPTION_MINOR_IMAGE_VERSION      (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
81 #define OPTION_MINOR_OS_VERSION         (OPTION_MINOR_IMAGE_VERSION + 1)
82 #define OPTION_MINOR_SUBSYSTEM_VERSION  (OPTION_MINOR_OS_VERSION + 1)
83 #define OPTION_SECTION_ALIGNMENT        (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
84 #define OPTION_STACK                    (OPTION_SECTION_ALIGNMENT + 1)
85 #define OPTION_SUBSYSTEM                (OPTION_STACK + 1)
86 #define OPTION_HEAP                     (OPTION_SUBSYSTEM + 1)
88 static void
89 gld${EMULATION_NAME}_add_options
90   (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
91    struct option **longopts, int nrl ATTRIBUTE_UNUSED,
92    struct option **really_longopts ATTRIBUTE_UNUSED)
94   static const struct option xtra_long[] = {
95     /* PE options */
96     {"base-file", required_argument, NULL, OPTION_BASE_FILE},
97     {"dll", no_argument, NULL, OPTION_DLL},
98     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
99     {"heap", required_argument, NULL, OPTION_HEAP},
100     {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
101     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
102     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
103     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
104     {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
105     {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
106     {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
107     {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
108     {"stack", required_argument, NULL, OPTION_STACK},
109     {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
110     {NULL, no_argument, NULL, 0}
111   };
113   *longopts = (struct option *)
114     xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
115   memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
119 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
120    parameters which may be input from the command line */
122 typedef struct {
123   void *ptr;
124   int size;
125   int value;
126   char *symbol;
127   int inited;
128 } definfo;
130 #define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
132 static definfo init[] =
134   /* imagebase must be first */
135 #define IMAGEBASEOFF 0
136   D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
137 #define DLLOFF 1
138   {&dll, sizeof(dll), 0, "__dll__", 0},
139   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
140   D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
141   D(MajorOperatingSystemVersion,"__major_os_version__", 4),
142   D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
143   D(MajorImageVersion,"__major_image_version__", 1),
144   D(MinorImageVersion,"__minor_image_version__", 0),
145   D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
146   D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
147   D(Subsystem,"__subsystem__", 3),
148   D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
149   D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
150   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
151   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
152   D(LoaderFlags,"__loader_flags__", 0x0),
153   { NULL, 0, 0, NULL, 0 }
157 static void
158 set_pe_name (char *name, long val)
160   int i;
161   /* Find the name and set it. */
162   for (i = 0; init[i].ptr; i++)
163     {
164       if (strcmp (name, init[i].symbol) == 0)
165         {
166           init[i].value = val;
167           init[i].inited = 1;
168           return;
169         }
170     }
171   abort();
175 static void
176 set_pe_subsystem (void)
178   const char *sver;
179   int len;
180   int i;
181   static const struct
182     {
183       const char *name;
184       const int value;
185       const char *entry;
186     }
187   v[] =
188     {
189       { "native", 1, "_NtProcessStartup" },
190       { "windows", 2, "_WinMainCRTStartup" },
191       { "wwindows", 2, "_wWinMainCRTStartup" },
192       { "console", 3, "_mainCRTStartup" },
193       { "wconsole", 3, "_wmainCRTStartup" },
194       { "posix", 7, "___PosixProcessStartup"},
195       { 0, 0, 0 }
196     };
198   sver = strchr (optarg, ':');
199   if (sver == NULL)
200     len = strlen (optarg);
201   else
202     {
203       char *end;
205       len = sver - optarg;
206       set_pe_name ("__major_subsystem_version__",
207                    strtoul (sver + 1, &end, 0));
208       if (*end == '.')
209         set_pe_name ("__minor_subsystem_version__",
210                      strtoul (end + 1, &end, 0));
211       if (*end != '\0')
212         einfo ("%P: warning: bad version number in -subsystem option\n");
213     }
215   for (i = 0; v[i].name; i++)
216     {
217       if (strncmp (optarg, v[i].name, len) == 0
218           && v[i].name[len] == '\0')
219         {
220           set_pe_name ("__subsystem__", v[i].value);
222           /* If the subsystem is windows, we use a different entry
223              point.  */
224           lang_default_entry (v[i].entry);
226           return;
227         }
228     }
229   einfo ("%P%F: invalid subsystem type %s\n", optarg);
233 static void
234 set_pe_value (char *name)
236   char *end;
237   set_pe_name (name,  strtoul (optarg, &end, 0));
238   if (end == optarg)
239     {
240       einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
241     }
243   optarg = end;
246 static void
247 set_pe_stack_heap (char *resname, char *comname)
249   set_pe_value (resname);
250   if (*optarg == ',')
251     {
252       optarg++;
253       set_pe_value (comname);
254     }
255   else if (*optarg)
256     {
257       einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
258     }
262 static bfd_boolean
263 gld${EMULATION_NAME}_handle_option (int optc)
265   switch (optc)
266     {
267     default:
268       return FALSE;
270     case OPTION_BASE_FILE:
271       link_info.base_file = fopen (optarg, FOPEN_WB);
272       if (link_info.base_file == NULL)
273         {
274           fprintf (stderr, "%s: Can't open base file %s\n",
275                    program_name, optarg);
276           xexit (1);
277         }
278       break;
280       /* PE options */
281     case OPTION_HEAP:
282       set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
283       break;
284     case OPTION_STACK:
285       set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
286       break;
287     case OPTION_SUBSYSTEM:
288       set_pe_subsystem ();
289       break;
290     case OPTION_MAJOR_OS_VERSION:
291       set_pe_value ("__major_os_version__");
292       break;
293     case OPTION_MINOR_OS_VERSION:
294       set_pe_value ("__minor_os_version__");
295       break;
296     case OPTION_MAJOR_SUBSYSTEM_VERSION:
297       set_pe_value ("__major_subsystem_version__");
298       break;
299     case OPTION_MINOR_SUBSYSTEM_VERSION:
300       set_pe_value ("__minor_subsystem_version__");
301       break;
302     case OPTION_MAJOR_IMAGE_VERSION:
303       set_pe_value ("__major_image_version__");
304       break;
305     case OPTION_MINOR_IMAGE_VERSION:
306       set_pe_value ("__minor_image_version__");
307       break;
308     case OPTION_FILE_ALIGNMENT:
309       set_pe_value ("__file_alignment__");
310       break;
311     case OPTION_SECTION_ALIGNMENT:
312       set_pe_value ("__section_alignment__");
313       break;
314     case OPTION_DLL:
315       set_pe_name ("__dll__", 1);
316       break;
317     case OPTION_IMAGE_BASE:
318       set_pe_value ("__image_base__");
319       break;
320     }
321   return TRUE;
324 /* Assign values to the special symbols before the linker script is
325    read.  */
327 static void
328 gld_${EMULATION_NAME}_set_symbols (void)
330   /* Run through and invent symbols for all the
331      names and insert the defaults. */
332   int j;
333   lang_statement_list_type *save;
335   if (!init[IMAGEBASEOFF].inited)
336     {
337       if (link_info.relocatable)
338         init[IMAGEBASEOFF].value = 0;
339       else if (init[DLLOFF].value)
340         init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
341       else
342         init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
343     }
345   /* Don't do any symbol assignments if this is a relocatable link.  */
346   if (link_info.relocatable)
347     return;
349   /* Glue the assignments into the abs section */
350   save = stat_ptr;
352   stat_ptr = &(abs_output_section->children);
354   for (j = 0; init[j].ptr; j++)
355     {
356       long val = init[j].value;
357       lang_add_assignment (exp_assop ('=', init[j].symbol, exp_intop (val)));
358       if (init[j].size == sizeof(short))
359         *(short *)init[j].ptr = val;
360       else if (init[j].size == sizeof(int))
361         *(int *)init[j].ptr = val;
362       else if (init[j].size == sizeof(long))
363         *(long *)init[j].ptr = val;
364       /* This might be a long long or other special type.  */
365       else if (init[j].size == sizeof(bfd_vma))
366         *(bfd_vma *)init[j].ptr = val;
367       else      abort();
368     }
369   /* Restore the pointer. */
370   stat_ptr = save;
372   if (pe.FileAlignment >
373       pe.SectionAlignment)
374     {
375       einfo ("%P: warning, file alignment > section alignment.\n");
376     }
379 static void
380 gld_${EMULATION_NAME}_after_open (void)
382   /* Pass the wacky PE command line options into the output bfd.
383      FIXME: This should be done via a function, rather than by
384      including an internal BFD header.  */
385   if (!coff_data(output_bfd)->pe)
386     {
387       einfo ("%F%P: PE operations on non PE file.\n");
388     }
390   pe_data(output_bfd)->pe_opthdr = pe;
391   pe_data(output_bfd)->dll = init[DLLOFF].value;
395 /* Callback functions for qsort in sort_sections. */
397 static int
398 sort_by_file_name (const void *a, const void *b)
400   const lang_statement_union_type *const *ra = a;
401   const lang_statement_union_type *const *rb = b;
402   int i, a_sec, b_sec;
404   i = strcmp ((*ra)->input_section.section->owner->my_archive->filename,
405               (*rb)->input_section.section->owner->my_archive->filename);
406   if (i != 0)
407     return i;
409   i = strcmp ((*ra)->input_section.section->owner->filename,
410                  (*rb)->input_section.section->owner->filename);
411   if (i != 0)
412     return i;
413   /* the tail idata4/5 are the only ones without relocs to an
414      idata$6 section unless we are importing by ordinal,
415      so sort them to last to terminate the IAT
416      and HNT properly. if no reloc this one is import by ordinal
417      so we have to sort by section contents */
419   if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) )
420     {
421        i =  (((*ra)->input_section.section->reloc_count >
422                  (*rb)->input_section.section->reloc_count) ? -1 : 0);
423        if ( i != 0)
424          return i;
426         return  (((*ra)->input_section.section->reloc_count >
427                  (*rb)->input_section.section->reloc_count) ? 0 : 1);
428     }
429   else
430     {
431        if ( (strcmp( (*ra)->input_section.section->name, ".idata$6") == 0) )
432           return 0; /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */
434        if (! bfd_get_section_contents ((*ra)->input_section.section->owner,
435          (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec)))
436             einfo ("%F%B: Can't read contents of section .idata: %E\n",
437                  (*ra)->input_section.section->owner);
439        if (! bfd_get_section_contents ((*rb)->input_section.section->owner,
440         (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) ))
441            einfo ("%F%B: Can't read contents of section .idata: %E\n",
442                 (*rb)->input_section.section->owner);
444       i =  ((a_sec < b_sec) ? -1 : 0);
445       if ( i != 0)
446         return i;
447       return  ((a_sec < b_sec) ? 0 : 1);
448    }
449 return 0;
452 static int
453 sort_by_section_name (const void *a, const void *b)
455   const lang_statement_union_type *const *ra = a;
456   const lang_statement_union_type *const *rb = b;
457   int i;
458   i = strcmp ((*ra)->input_section.section->name,
459               (*rb)->input_section.section->name);
460   /* This is a hack to make .stab and .stabstr last, so we don't have
461      to fix strip/objcopy for .reloc sections.
462      FIXME stripping images with a .rsrc section still needs to be fixed.  */
463   if (i != 0)
464     {
465       if ((CONST_STRNEQ ((*ra)->input_section.section->name, ".stab"))
466            && (! CONST_STRNEQ ((*rb)->input_section.section->name, ".stab")))
467          return 1;
468     }
469   return i;
472 /* Subroutine of sort_sections to a contiguous subset of a list of sections.
473    NEXT_AFTER is the element after the last one to sort.
474    The result is a pointer to the last element's "next" pointer.  */
476 static lang_statement_union_type **
477 sort_sections_1 (lang_statement_union_type **startptr,
478                  lang_statement_union_type *next_after,
479                  int count,
480                  int (*sort_func) (const void *, const void *))
482   lang_statement_union_type **vec;
483   lang_statement_union_type *p;
484   int i;
485   lang_statement_union_type **ret;
487   if (count == 0)
488     return startptr;
490   vec = ((lang_statement_union_type **)
491          xmalloc (count * sizeof (lang_statement_union_type *)));
493   for (p = *startptr, i = 0; i < count; i++, p = p->header.next)
494     vec[i] = p;
496   qsort (vec, count, sizeof (vec[0]), sort_func);
498   /* Fill in the next pointers again. */
499   *startptr = vec[0];
500   for (i = 0; i < count - 1; i++)
501     vec[i]->header.next = vec[i + 1];
502   vec[i]->header.next = next_after;
503   ret = &vec[i]->header.next;
504   free (vec);
505   return ret;
508 /* Sort the .idata\$foo input sections of archives into filename order.
509    The reason is so dlltool can arrange to have the pe dll import information
510    generated correctly - the head of the list goes into dh.o, the tail into
511    dt.o, and the guts into ds[nnnn].o.  Note that this is only needed for the
512    .idata section.
513    FIXME: This may no longer be necessary with grouped sections.  Instead of
514    sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
515    .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
516    This would have to be elaborated upon to handle multiple dll's
517    [assuming such an eloboration is possible of course].
519    We also sort sections in '\$' wild statements.  These are created by the
520    place_orphans routine to implement grouped sections.  */
522 static void
523 sort_sections (lang_statement_union_type *s)
525   for (; s ; s = s->header.next)
526     switch (s->header.type)
527       {
528       case lang_output_section_statement_enum:
529         sort_sections (s->output_section_statement.children.head);
530         break;
531       case lang_wild_statement_enum:
532         {
533           lang_statement_union_type **p = &s->wild_statement.children.head;
534           struct wildcard_list *sec;
536           for (sec = s->wild_statement.section_list; sec; sec = sec->next)
537             {
538               /* Is this the .idata section?  */
539               if (sec->spec.name != NULL
540                   && CONST_STRNEQ (sec->spec.name, ".idata"))
541                 {
542                   /* Sort the children.  We want to sort any objects in
543                      the same archive.  In order to handle the case of
544                      including a single archive multiple times, we sort
545                      all the children by archive name and then by object
546                      name.  After sorting them, we re-thread the pointer
547                      chain.  */
549                   while (*p)
550                     {
551                       lang_statement_union_type *start = *p;
552                       if (start->header.type != lang_input_section_enum
553                           || !start->input_section.section->owner->my_archive)
554                         p = &(start->header.next);
555                       else
556                         {
557                           lang_statement_union_type *end;
558                           int count;
560                           for (end = start, count = 0;
561                                end && (end->header.type
562                                        == lang_input_section_enum);
563                                end = end->header.next)
564                             count++;
566                           p = sort_sections_1 (p, end, count,
567                                                sort_by_file_name);
568                         }
569                     }
570                   break;
571                 }
573               /* If this is a collection of grouped sections, sort them.
574                  The linker script must explicitly mention "*(.foo\$)" or
575                  "*(.foo\$*)".  Don't sort them if \$ is not the last
576                  character (not sure if this is really useful, but it
577                  allows explicitly mentioning some \$ sections and letting
578                  the linker handle the rest).  */
579               if (sec->spec.name != NULL)
580                 {
581                   char *q = strchr (sec->spec.name, '\$');
583                   if (q != NULL
584                       && (q[1] == '\0'
585                           || (q[1] == '*' && q[2] == '\0')))
586                     {
587                       lang_statement_union_type *end;
588                       int count;
590                       for (end = *p, count = 0; end; end = end->header.next)
591                         {
592                           if (end->header.type != lang_input_section_enum)
593                             abort ();
594                           count++;
595                         }
596                       (void) sort_sections_1 (p, end, count,
597                                               sort_by_section_name);
598                     }
599                   break;
600                 }
601             }
602         }
603         break;
604       default:
605         break;
606       }
609 static void
610 gld_${EMULATION_NAME}_before_allocation (void)
612   extern lang_statement_list_type *stat_ptr;
614 #ifdef TARGET_IS_ppcpe
615   /* Here we rummage through the found bfds to collect toc information */
616   {
617     LANG_FOR_EACH_INPUT_STATEMENT (is)
618       {
619         if (!ppc_process_before_allocation(is->the_bfd, &link_info))
620           {
621             einfo("Errors encountered processing file %s\n", is->filename);
622           }
623       }
624   }
626   /* We have seen it all. Allocate it, and carry on */
627   ppc_allocate_toc_section (&link_info);
628 #else
629 #ifdef TARGET_IS_armpe
630   /* FIXME: we should be able to set the size of the interworking stub
631      section.
633      Here we rummage through the found bfds to collect glue
634      information.  FIXME: should this be based on a command line
635      option?  krk@cygnus.com */
636   {
637     LANG_FOR_EACH_INPUT_STATEMENT (is)
638       {
639         if (!arm_process_before_allocation (is->the_bfd, & link_info))
640           {
641             einfo ("Errors encountered processing file %s", is->filename);
642           }
643       }
644   }
646   /* We have seen it all. Allocate it, and carry on */
647   arm_allocate_interworking_sections (& link_info);
648 #endif /* TARGET_IS_armpe */
649 #endif /* TARGET_IS_ppcpe */
651   sort_sections (stat_ptr->head);
653   before_allocation_default ();
656 /* Place an orphan section.  We use this to put sections with a '\$' in them
657    into the right place.  Any section with a '\$' in them (e.g. .text\$foo)
658    gets mapped to the output section with everything from the '\$' on stripped
659    (e.g. .text).
660    See the Microsoft Portable Executable and Common Object File Format
661    Specification 4.1, section 4.2, Grouped Sections.
663    FIXME: This is now handled by the linker script using wildcards,
664    but I'm leaving this here in case we want to enable it for sections
665    which are not mentioned in the linker script.  */
667 static bfd_boolean
668 gld${EMULATION_NAME}_place_orphan (asection *s)
670   const char *secname;
671   char *output_secname, *ps;
672   lang_output_section_statement_type *os;
673   lang_statement_union_type *l;
675   if ((s->flags & SEC_ALLOC) == 0)
676     return FALSE;
678   /* Don't process grouped sections unless doing a final link.
679      If they're marked as COMDAT sections, we don't want .text\$foo to
680      end up in .text and then have .text disappear because it's marked
681      link-once-discard.  */
682   if (link_info.relocatable)
683     return FALSE;
685   secname = bfd_get_section_name (s->owner, s);
687   /* Everything from the '\$' on gets deleted so don't allow '\$' as the
688      first character.  */
689   if (*secname == '\$')
690     einfo ("%P%F: section %s has '\$' as first character\n", secname);
691   if (strchr (secname + 1, '\$') == NULL)
692     return FALSE;
694   /* Look up the output section.  The Microsoft specs say sections names in
695      image files never contain a '\$'.  Fortunately, lang_..._lookup creates
696      the section if it doesn't exist.  */
697   output_secname = xstrdup (secname);
698   ps = strchr (output_secname + 1, '\$');
699   *ps = 0;
700   os = lang_output_section_statement_lookup (output_secname);
702   /* Find the '\$' wild statement for this section.  We currently require the
703      linker script to explicitly mention "*(.foo\$)".
704      FIXME: ppcpe.sc has .CRT\$foo in the .rdata section.  According to the
705      Microsoft docs this isn't correct so it's not (currently) handled.  */
707   ps[0] = '\$';
708   ps[1] = 0;
709   for (l = os->children.head; l; l = l->header.next)
710     if (l->header.type == lang_wild_statement_enum)
711       {
712         struct wildcard_list *sec;
714         for (sec = l->wild_statement.section_list; sec; sec = sec->next)
715           if (sec->spec.name && strcmp (sec->spec.name, output_secname) == 0)
716             break;
717         if (sec)
718           break;
719       }
720   ps[0] = 0;
721   if (l == NULL)
722     einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
724   /* Link the input section in and we're done for now.
725      The sections still have to be sorted, but that has to wait until
726      all such sections have been processed by us.  The sorting is done by
727      sort_sections.  */
728   lang_add_section (&l->wild_statement.children, s, os);
730   return TRUE;
733 static char *
734 gld_${EMULATION_NAME}_get_script (int *isfile)
736 # Scripts compiled in.
737 # sed commands to quote an ld script as a C string.
738 sc="-f stringify.sed"
740 fragment <<EOF
742   *isfile = 0;
744   if (link_info.relocatable && config.build_constructors)
745     return
747 sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
748 echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
749 sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
750 echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
751 sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
752 echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
753 sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
754 echo '  ; else return'                                 >> e${EMULATION_NAME}.c
755 sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
756 echo '; }'                                             >> e${EMULATION_NAME}.c
758 fragment <<EOF
761 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
763   gld_${EMULATION_NAME}_before_parse,
764   syslib_default,
765   hll_default,
766   after_parse_default,
767   gld_${EMULATION_NAME}_after_open,
768   after_allocation_default,
769   set_output_arch_default,
770   ldemul_default_target,
771   gld_${EMULATION_NAME}_before_allocation,
772   gld_${EMULATION_NAME}_get_script,
773   "${EMULATION_NAME}",
774   "${OUTPUT_FORMAT}",
775   finish_default,
776   NULL, /* create output section statements */
777   NULL, /* open dynamic archive */
778   gld${EMULATION_NAME}_place_orphan,
779   gld_${EMULATION_NAME}_set_symbols,
780   NULL, /* parse_args */
781   gld${EMULATION_NAME}_add_options,
782   gld${EMULATION_NAME}_handle_option,
783   NULL, /* unrecognized file */
784   NULL, /* list options */
785   NULL, /* recognized file */
786   NULL, /* find_potential_libraries */
787   NULL  /* new_vers_pattern */