file make-gas.com was initially added on branch binutils-2_10-branch.
[binutils.git] / ld / emultempl / beos.em
blob2c14fbcce3c77a6f726b6aaf3e80fe4341bf344c
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 cat >e${EMULATION_NAME}.c <<EOF
4 /* This file is part of GLD, the Gnu Linker.
5    Copyright 1995, 96, 97, 98, 1999 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21 /* For WINDOWS_NT */
22 /* The original file generated returned different default scripts depending
23    on whether certain switches were set, but these switches pertain to the
24    Linux system and that particular version of coff.  In the NT case, we
25    only determine if the subsystem is console or windows in order to select
26    the correct entry point by default. */ 
27   
28 #include "bfd.h"
29 #include "sysdep.h"
30 #include "bfdlink.h"
31 #include "getopt.h"
32 #include "libiberty.h"
33 #include "ld.h"
34 #include "ldmain.h"
35 #include "ldgram.h"
36 #include "ldexp.h"
37 #include "ldlang.h"
38 #include "ldemul.h"
39 #include "ldlex.h"
40 #include "ldmisc.h"
41 #include "ldctor.h"
42 #include "ldfile.h"
43 #include "coff/internal.h"
44 #include "../bfd/libcoff.h"
46 #define TARGET_IS_${EMULATION_NAME}
48 static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
49 static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
50 static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
51 static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
52 static boolean gld${EMULATION_NAME}_place_orphan
53   PARAMS ((lang_input_statement_type *, asection *));
54 static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
55 static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
57 #if 0 /* argument to qsort so don't prototype */
58 static int sort_by_file_name PARAMS ((void *, void *));
59 static int sort_by_section_name PARAMS ((void *, void *));
60 #endif
61 static lang_statement_union_type **sort_sections_1
62   PARAMS ((lang_statement_union_type **, lang_statement_union_type *, int,
63            int (*)()));
64 static void sort_sections PARAMS ((lang_statement_union_type *));
66 static struct internal_extra_pe_aouthdr pe;
67 static int dll;
69 extern const char *output_filename;
71 static void
72 gld_${EMULATION_NAME}_before_parse()
74   output_filename = "a.exe";
75   ldfile_output_architecture = bfd_arch_${ARCH};
78 /* PE format extra command line options.  */
80 /* Used for setting flags in the PE header. */
81 #define OPTION_BASE_FILE                (300  + 1)
82 #define OPTION_DLL                      (OPTION_BASE_FILE + 1)
83 #define OPTION_FILE_ALIGNMENT           (OPTION_DLL + 1)
84 #define OPTION_IMAGE_BASE               (OPTION_FILE_ALIGNMENT + 1)
85 #define OPTION_MAJOR_IMAGE_VERSION      (OPTION_IMAGE_BASE + 1)
86 #define OPTION_MAJOR_OS_VERSION         (OPTION_MAJOR_IMAGE_VERSION + 1)
87 #define OPTION_MAJOR_SUBSYSTEM_VERSION  (OPTION_MAJOR_OS_VERSION + 1)
88 #define OPTION_MINOR_IMAGE_VERSION      (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
89 #define OPTION_MINOR_OS_VERSION         (OPTION_MINOR_IMAGE_VERSION + 1)
90 #define OPTION_MINOR_SUBSYSTEM_VERSION  (OPTION_MINOR_OS_VERSION + 1)
91 #define OPTION_SECTION_ALIGNMENT        (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
92 #define OPTION_STACK                    (OPTION_SECTION_ALIGNMENT + 1)
93 #define OPTION_SUBSYSTEM                (OPTION_STACK + 1)
94 #define OPTION_HEAP                     (OPTION_SUBSYSTEM + 1)
96 static struct option longopts[] = {
97   /* PE options */
98     {"base-file", required_argument, NULL, OPTION_BASE_FILE},
99     {"dll", no_argument, NULL, OPTION_DLL},
100     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
101     {"heap", required_argument, NULL, OPTION_HEAP}, 
102     {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, 
103     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
104     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
105     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
106     {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
107     {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
108     {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
109     {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
110     {"stack", required_argument, NULL, OPTION_STACK},
111     {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
112    {NULL, no_argument, NULL, 0}
113   };
116 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
117    parameters which may be input from the command line */
119 typedef struct {
120   void *ptr;
121   int size;
122   int value;
123   char *symbol;
124   int inited;
125 } definfo;
127 #define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
129 static definfo init[] =
131   /* imagebase must be first */
132 #define IMAGEBASEOFF 0
133   D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
134 #define DLLOFF 1
135   {&dll, sizeof(dll), 0, "__dll__"},
136   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
137   D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
138   D(MajorOperatingSystemVersion,"__major_os_version__", 4),
139   D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
140   D(MajorImageVersion,"__major_image_version__", 1),
141   D(MinorImageVersion,"__minor_image_version__", 0),
142   D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
143   D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
144   D(Subsystem,"__subsystem__", 3),
145   D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
146   D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
147   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
148   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
149   D(LoaderFlags,"__loader_flags__", 0x0),
150   { NULL, 0, 0, NULL, 0 }
154 static void
155 set_pe_name (name, val)
156      char *name;
157      long val;
159   int i;
160   /* Find the name and set it. */
161   for (i = 0; init[i].ptr; i++)
162     {
163       if (strcmp (name, init[i].symbol) == 0)
164         {
165           init[i].value = val;
166           init[i].inited = 1;
167           return;
168         }
169     }
170   abort();
174 static void
175 set_pe_subsystem ()
177   const char *sver;
178   int len;
179   int i;
180   static const struct 
181     {
182       const char *name;
183       const int value;
184       const char *entry;
185     }
186   v[] =
187     {
188       { "native", 1, "_NtProcessStartup" },
189       { "windows", 2, "_WinMainCRTStartup" },
190       { "wwindows", 2, "_wWinMainCRTStartup" },
191       { "console", 3, "_mainCRTStartup" },
192       { "wconsole", 3, "_wmainCRTStartup" },
193 #if 0
194       /* The Microsoft linker does not recognize this.  */
195       { "os2", 5, "" },
196 #endif
197       { "posix", 7, "___PosixProcessStartup"},
198       { 0, 0, 0 }
199     };
201   sver = strchr (optarg, ':');
202   if (sver == NULL)
203     len = strlen (optarg);
204   else
205     {
206       char *end;
208       len = sver - optarg;
209       set_pe_name ("__major_subsystem_version__",
210                    strtoul (sver + 1, &end, 0));
211       if (*end == '.')
212         set_pe_name ("__minor_subsystem_version__",
213                      strtoul (end + 1, &end, 0));
214       if (*end != '\0')
215         einfo ("%P: warning: bad version number in -subsystem option\n");
216     }
218   for (i = 0; v[i].name; i++)
219     {
220       if (strncmp (optarg, v[i].name, len) == 0
221           && v[i].name[len] == '\0')
222         {
223           set_pe_name ("__subsystem__", v[i].value);
225           /* If the subsystem is windows, we use a different entry
226              point.  We also register the entry point as an undefined
227              symbol. from lang_add_entry() The reason we do
228              this is so that the user
229              doesn't have to because they would have to use the -u
230              switch if they were specifying an entry point other than
231              _mainCRTStartup.  Specifically, if creating a windows
232              application, entry point _WinMainCRTStartup must be
233              specified.  What I have found for non console
234              applications (entry not _mainCRTStartup) is that the .obj
235              that contains mainCRTStartup is brought in since it is
236              the first encountered in libc.lib and it has other
237              symbols in it which will be pulled in by the link
238              process.  To avoid this, adding -u with the entry point
239              name specified forces the correct .obj to be used.  We
240              can avoid making the user do this by always adding the
241              entry point name as an undefined symbol.  */
242           lang_add_entry (v[i].entry, 1);
244           return;
245         }
246     }
247   einfo ("%P%F: invalid subsystem type %s\n", optarg);
252 static void
253 set_pe_value (name)
254      char *name;
255      
257   char *end;
258   set_pe_name (name,  strtoul (optarg, &end, 0));
259   if (end == optarg)
260     {
261       einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
262     }
264   optarg = end;
267 static void
268 set_pe_stack_heap (resname, comname)
269      char *resname;
270      char *comname;
272   set_pe_value (resname);
273   if (*optarg == ',')
274     {
275       optarg++;
276       set_pe_value (comname);
277     }
278   else if (*optarg)
279     {
280       einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
281     }
286 static int
287 gld_${EMULATION_NAME}_parse_args(argc, argv)
288      int argc;
289      char **argv;
291   int longind;
292   int optc;
293   int prevoptind = optind;
294   int prevopterr = opterr;
295   int wanterror;
296   static int lastoptind = -1;
298   if (lastoptind != optind)
299     opterr = 0;
300   wanterror = opterr;
302   lastoptind = optind;
304   optc = getopt_long_only (argc, argv, "-", longopts, &longind);
305   opterr = prevopterr;
307   switch (optc)
308     {
309     default:
310       if (wanterror)
311         xexit (1);
312       optind =  prevoptind;
313       return 0;
315     case OPTION_BASE_FILE:
316       link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
317       if (link_info.base_file == NULL)
318         {
319           fprintf (stderr, "%s: Can't open base file %s\n",
320                    program_name, optarg);
321           xexit (1);
322         }
323       break;
325       /* PE options */
326     case OPTION_HEAP: 
327       set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
328       break;
329     case OPTION_STACK: 
330       set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
331       break;
332     case OPTION_SUBSYSTEM:
333       set_pe_subsystem ();
334       break;
335     case OPTION_MAJOR_OS_VERSION:
336       set_pe_value ("__major_os_version__");
337       break;
338     case OPTION_MINOR_OS_VERSION:
339       set_pe_value ("__minor_os_version__");
340       break;
341     case OPTION_MAJOR_SUBSYSTEM_VERSION:
342       set_pe_value ("__major_subsystem_version__");
343       break;
344     case OPTION_MINOR_SUBSYSTEM_VERSION:
345       set_pe_value ("__minor_subsystem_version__");
346       break;
347     case OPTION_MAJOR_IMAGE_VERSION:
348       set_pe_value ("__major_image_version__");
349       break;
350     case OPTION_MINOR_IMAGE_VERSION:
351       set_pe_value ("__minor_image_version__");
352       break;
353     case OPTION_FILE_ALIGNMENT:
354       set_pe_value ("__file_alignment__");
355       break;
356     case OPTION_SECTION_ALIGNMENT:
357       set_pe_value ("__section_alignment__");
358       break;
359     case OPTION_DLL:
360       set_pe_name ("__dll__", 1);
361       break;
362     case OPTION_IMAGE_BASE:
363       set_pe_value ("__image_base__");
364       break;
365     }
366   return 1;
369 /* Assign values to the special symbols before the linker script is
370    read.  */
372 static void
373 gld_${EMULATION_NAME}_set_symbols()
375   /* Run through and invent symbols for all the
376      names and insert the defaults. */
377   int j;
378   lang_statement_list_type *save;
380   if (!init[IMAGEBASEOFF].inited)
381     {
382       if (link_info.relocateable)
383         init[IMAGEBASEOFF].value = 0;
384       else if (init[DLLOFF].value)
385         init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
386       else
387         init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
388     }
390   /* Don't do any symbol assignments if this is a relocateable link.  */
391   if (link_info.relocateable)
392     return;
394   /* Glue the assignments into the abs section */
395   save = stat_ptr;
397   stat_ptr = &(abs_output_section->children);
399   for (j = 0; init[j].ptr; j++)
400     {
401       long val = init[j].value;
402       lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
403       if (init[j].size == sizeof(short))
404         *(short *)init[j].ptr = val;
405       else if (init[j].size == sizeof(int))
406         *(int *)init[j].ptr = val;
407       else if (init[j].size == sizeof(long))
408         *(long *)init[j].ptr = val;
409       /* This might be a long long or other special type.  */
410       else if (init[j].size == sizeof(bfd_vma))
411         *(bfd_vma *)init[j].ptr = val;
412       else      abort();
413     }
414   /* Restore the pointer. */
415   stat_ptr = save;
416   
417   if (pe.FileAlignment >
418       pe.SectionAlignment)
419     {
420       einfo ("%P: warning, file alignment > section alignment.\n");
421     }
424 static void
425 gld_${EMULATION_NAME}_after_open()
427   /* Pass the wacky PE command line options into the output bfd.
428      FIXME: This should be done via a function, rather than by
429      including an internal BFD header.  */
430   if (!coff_data(output_bfd)->pe)
431     {
432       einfo ("%F%P: PE operations on non PE file.\n");
433     }
435   pe_data(output_bfd)->pe_opthdr = pe;
436   pe_data(output_bfd)->dll = init[DLLOFF].value;
440 /* Callback functions for qsort in sort_sections. */
442 static int
443 sort_by_file_name (a, b)
444      void *a;
445      void *b;
447   lang_statement_union_type **ra = a;
448   lang_statement_union_type **rb = b;
449   int i, a_sec, b_sec;
451   i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename,
452               (*rb)->input_section.ifile->the_bfd->my_archive->filename);
453   if (i != 0)
454     return i;
456   i = strcmp ((*ra)->input_section.ifile->filename,
457                  (*rb)->input_section.ifile->filename);
458   if (i != 0)
459     return i;
460   /* the tail idata4/5 are the only ones without relocs to an
461      idata$6 section unless we are importing by ordinal, 
462      so sort them to last to terminate the IAT
463      and HNT properly. if no reloc this one is import by ordinal
464      so we have to sort by section contents */
466   if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) )
467     {
468        i =  (((*ra)->input_section.section->reloc_count > 
469                  (*rb)->input_section.section->reloc_count) ? -1 : 0);
470        if ( i != 0)
471          return i;
473         return  (((*ra)->input_section.section->reloc_count > 
474                  (*rb)->input_section.section->reloc_count) ? 0 : 1);
475     }
476   else
477     {
478        if ( (strcmp( (*ra)->input_section.section->name, ".idata$6") == 0) )
479           return 0; /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */
481        if (! bfd_get_section_contents ((*ra)->input_section.ifile->the_bfd, 
482          (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec)))
483             einfo ("%F%B: Can't read contents of section .idata: %E\n",
484                  (*ra)->input_section.ifile->the_bfd);
486        if (! bfd_get_section_contents ((*rb)->input_section.ifile->the_bfd, 
487         (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) ))
488            einfo ("%F%B: Can't read contents of section .idata: %E\n",
489                 (*rb)->input_section.ifile->the_bfd);
491       i =  ((a_sec < b_sec) ? -1 : 0);
492       if ( i != 0)
493         return i;
494       return  ((a_sec < b_sec) ? 0 : 1);
495    }
496 return 0;
499 static int
500 sort_by_section_name (a, b)
501      void *a;
502      void *b;
504   lang_statement_union_type **ra = a;
505   lang_statement_union_type **rb = b;
506   int i;
507   i = strcmp ((*ra)->input_section.section->name,
508                  (*rb)->input_section.section->name);
509 /* this is a hack to make .stab and .stabstr last, so we don't have
510    to fix strip/objcopy for .reloc sections.
511    FIXME stripping images with a .rsrc section still needs to be fixed */
512   if ( i != 0)
513     {
514       if ((strncmp ((*ra)->input_section.section->name, ".stab", 5) == 0)
515            && (strncmp ((*rb)->input_section.section->name, ".stab", 5) != 0))
516          return 1;
517       return i;
518     }
519   return i;
522 /* Subroutine of sort_sections to a contiguous subset of a list of sections.
523    NEXT_AFTER is the element after the last one to sort.
524    The result is a pointer to the last element's "next" pointer.  */
526 static lang_statement_union_type **
527 sort_sections_1 (startptr, next_after, count, sort_func)
528      lang_statement_union_type **startptr,*next_after;
529      int count;
530      int (*sort_func) ();
532   lang_statement_union_type **vec;
533   lang_statement_union_type *p;
534   int i;
535   lang_statement_union_type **ret;
537   if (count == 0)
538     return startptr;
540   vec = ((lang_statement_union_type **)
541          xmalloc (count * sizeof (lang_statement_union_type *)));
543   for (p = *startptr, i = 0; i < count; i++, p = p->next)
544     vec[i] = p;
546   qsort (vec, count, sizeof (vec[0]), sort_func);
548   /* Fill in the next pointers again. */
549   *startptr = vec[0];
550   for (i = 0; i < count - 1; i++)
551     vec[i]->header.next = vec[i + 1];
552   vec[i]->header.next = next_after;
553   ret = &vec[i]->header.next;
554   free (vec);
555   return ret;
558 /* Sort the .idata\$foo input sections of archives into filename order.
559    The reason is so dlltool can arrange to have the pe dll import information
560    generated correctly - the head of the list goes into dh.o, the tail into
561    dt.o, and the guts into ds[nnnn].o.  Note that this is only needed for the
562    .idata section.
563    FIXME: This may no longer be necessary with grouped sections.  Instead of
564    sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
565    .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
566    This would have to be elaborated upon to handle multiple dll's
567    [assuming such an eloboration is possible of course].
569    We also sort sections in '\$' wild statements.  These are created by the
570    place_orphans routine to implement grouped sections.  */
572 static void
573 sort_sections (s)
574      lang_statement_union_type *s;
576   for (; s ; s = s->next)
577     switch (s->header.type)
578       {
579       case lang_output_section_statement_enum:
580         sort_sections (s->output_section_statement.children.head);
581         break;
582       case lang_wild_statement_enum:
583         {
584           lang_statement_union_type **p = &s->wild_statement.children.head;
586           /* Is this the .idata section?  */
587           if (s->wild_statement.section_name != NULL
588               && strncmp (s->wild_statement.section_name, ".idata", 6) == 0)
589             {
590               /* Sort the children.  We want to sort any objects in
591                  the same archive.  In order to handle the case of
592                  including a single archive multiple times, we sort
593                  all the children by archive name and then by object
594                  name.  After sorting them, we re-thread the pointer
595                  chain.  */
597               while (*p)
598                 {
599                   lang_statement_union_type *start = *p;
600                   if (start->header.type != lang_input_section_enum
601                       || !start->input_section.ifile->the_bfd->my_archive)
602                     p = &(start->header.next);
603                   else
604                     {
605                       lang_statement_union_type *end;
606                       int count;
608                       for (end = start, count = 0;
609                            end && end->header.type == lang_input_section_enum;
610                            end = end->next)
611                         count++;
613                       p = sort_sections_1 (p, end, count, sort_by_file_name);
614                     }
615                 }
616               break;
617             }
619           /* If this is a collection of grouped sections, sort them.
620              The linker script must explicitly mention "*(.foo\$)" or
621              "*(.foo\$*)".  Don't sort them if \$ is not the last
622              character (not sure if this is really useful, but it
623              allows explicitly mentioning some \$ sections and letting
624              the linker handle the rest).  */
625           if (s->wild_statement.section_name != NULL)
626             {
627               char *q = strchr (s->wild_statement.section_name, '\$');
629               if (q != NULL
630                   && (q[1] == '\0'
631                       || (q[1] == '*' && q[2] == '\0')))
632                 {
633                   lang_statement_union_type *end;
634                   int count;
636                   for (end = *p, count = 0; end; end = end->next)
637                     {
638                       if (end->header.type != lang_input_section_enum)
639                         abort ();
640                       count++;
641                     }
642                   (void) sort_sections_1 (p, end, count, sort_by_section_name);
643                 }
644               break;
645             }
646         }
647         break;
648       default:
649         break;
650       }
653 static void  
654 gld_${EMULATION_NAME}_before_allocation()
656   extern lang_statement_list_type *stat_ptr;
658 #ifdef TARGET_IS_ppcpe
659   /* Here we rummage through the found bfds to collect toc information */
660   {
661     LANG_FOR_EACH_INPUT_STATEMENT (is)
662       {
663         if (!ppc_process_before_allocation(is->the_bfd, &link_info))
664           {
665             einfo("Errors encountered processing file %s\n", is->filename);
666           }
667       }
668   }
670   /* We have seen it all. Allocate it, and carry on */
671   ppc_allocate_toc_section (&link_info);
672 #else
673 #ifdef TARGET_IS_armpe
674   /* FIXME: we should be able to set the size of the interworking stub
675      section.
677      Here we rummage through the found bfds to collect glue
678      information.  FIXME: should this be based on a command line
679      option?  krk@cygnus.com */
680   {
681     LANG_FOR_EACH_INPUT_STATEMENT (is)
682       {
683         if (!arm_process_before_allocation (is->the_bfd, & link_info))
684           {
685             einfo ("Errors encountered processing file %s", is->filename);
686           }
687       }
688   }
690   /* We have seen it all. Allocate it, and carry on */
691   arm_allocate_interworking_sections (& link_info);
692 #endif /* TARGET_IS_armpe */
693 #endif /* TARGET_IS_ppcpe */
695   sort_sections (stat_ptr->head);
698 /* Place an orphan section.  We use this to put sections with a '\$' in them
699    into the right place.  Any section with a '\$' in them (e.g. .text\$foo)
700    gets mapped to the output section with everything from the '\$' on stripped
701    (e.g. .text).
702    See the Microsoft Portable Executable and Common Object File Format
703    Specification 4.1, section 4.2, Grouped Sections.
705    FIXME: This is now handled by the linker script using wildcards,
706    but I'm leaving this here in case we want to enable it for sections
707    which are not mentioned in the linker script.  */
709 /*ARGSUSED*/
710 static boolean
711 gld${EMULATION_NAME}_place_orphan (file, s)
712      lang_input_statement_type *file;
713      asection *s;
715   const char *secname;
716   char *output_secname, *ps;
717   lang_output_section_statement_type *os;
718   lang_statement_union_type *l;
720   if ((s->flags & SEC_ALLOC) == 0)
721     return false;
723   /* Don't process grouped sections unless doing a final link.
724      If they're marked as COMDAT sections, we don't want .text\$foo to
725      end up in .text and then have .text disappear because it's marked
726      link-once-discard.  */
727   if (link_info.relocateable)
728     return false;
730   secname = bfd_get_section_name (s->owner, s);
732   /* Everything from the '\$' on gets deleted so don't allow '\$' as the
733      first character.  */
734   if (*secname == '\$')
735     einfo ("%P%F: section %s has '\$' as first character\n", secname);
736   if (strchr (secname + 1, '\$') == NULL)
737     return false;
739   /* Look up the output section.  The Microsoft specs say sections names in
740      image files never contain a '\$'.  Fortunately, lang_..._lookup creates
741      the section if it doesn't exist.  */
742   output_secname = buystring (secname);
743   ps = strchr (output_secname + 1, '\$');
744   *ps = 0;
745   os = lang_output_section_statement_lookup (output_secname);
747   /* Find the '\$' wild statement for this section.  We currently require the
748      linker script to explicitly mention "*(.foo\$)".
749      FIXME: ppcpe.sc has .CRT\$foo in the .rdata section.  According to the
750      Microsoft docs this isn't correct so it's not (currently) handled.  */
752   ps[0] = '\$';
753   ps[1] = 0;
754   for (l = os->children.head; l; l = l->next)
755     {
756       if (l->header.type == lang_wild_statement_enum
757           && strcmp (l->wild_statement.section_name, output_secname) == 0)
758         break;
759     }
760   ps[0] = 0;
761   if (l == NULL)
762 #if 1
763     einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
764 #else /* FIXME: This block is untried.  It exists to convey the intent,
765          should one decide to not require *(.foo\$) to appear in the linker
766          script.  */
767     {
768       lang_wild_statement_type *new = new_stat (lang_wild_statement,
769                                                 &os->children);
770       new->section_name = xmalloc (strlen (output_secname) + 2);
771       sprintf (new->section_name, "%s\$", output_secname);
772       new->filename = NULL;
773       lang_list_init (&new->children);
774       l = new;
775     }
776 #endif
778   /* Link the input section in and we're done for now.
779      The sections still have to be sorted, but that has to wait until
780      all such sections have been processed by us.  The sorting is done by
781      sort_sections.  */
782   wild_doit (&l->wild_statement.children, s, os, file);
784   return true;
787 static char *
788 gld_${EMULATION_NAME}_get_script(isfile)
789      int *isfile;
791 # Scripts compiled in.
792 # sed commands to quote an ld script as a C string.
793 sc="-f stringify.sed"
795 cat >>e${EMULATION_NAME}.c <<EOF
796 {                            
797   *isfile = 0;
799   if (link_info.relocateable == true && config.build_constructors == true)
800     return
802 sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
803 echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
804 sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
805 echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
806 sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
807 echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
808 sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
809 echo '  ; else return'                                     >> e${EMULATION_NAME}.c
810 sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
811 echo '; }'                                                 >> e${EMULATION_NAME}.c
813 cat >>e${EMULATION_NAME}.c <<EOF
816 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
818   gld_${EMULATION_NAME}_before_parse,
819   syslib_default,
820   hll_default,
821   after_parse_default,
822   gld_${EMULATION_NAME}_after_open,
823   after_allocation_default,
824   set_output_arch_default,
825   ldemul_default_target,
826   gld_${EMULATION_NAME}_before_allocation,
827   gld_${EMULATION_NAME}_get_script,
828   "${EMULATION_NAME}",
829   "${OUTPUT_FORMAT}",
830   NULL, /* finish */
831   NULL, /* create output section statements */
832   NULL, /* open dynamic archive */
833   gld${EMULATION_NAME}_place_orphan,
834   gld_${EMULATION_NAME}_set_symbols,
835   gld_${EMULATION_NAME}_parse_args,
836   NULL, /* unrecognized file */
837   NULL, /* list options */
838   NULL, /* recognized file */
839   NULL  /* find_potential_libraries */