1# $MirOS: src/gnu/usr.bin/binutils/ld/emultempl/beos.em,v 1.3 2009/10/04 03:06:14 tg Exp $
2
3# This shell script emits a C file. -*- C -*-
4# It does some substitutions.
5if [ -z "$MACHINE" ]; then
6  OUTPUT_ARCH=${ARCH}
7else
8  OUTPUT_ARCH=${ARCH}:${MACHINE}
9fi
10cat >e${EMULATION_NAME}.c <<EOF
11/* This file is part of GLD, the Gnu Linker.
12   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
13   2005 Free Software Foundation, Inc.
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
28
29/* For WINDOWS_NT */
30/* The original file generated returned different default scripts depending
31   on whether certain switches were set, but these switches pertain to the
32   Linux system and that particular version of coff.  In the NT case, we
33   only determine if the subsystem is console or windows in order to select
34   the correct entry point by default. */
35
36#include "bfd.h"
37#include "sysdep.h"
38#include "bfdlink.h"
39#include "getopt.h"
40#include "libiberty.h"
41#include "ld.h"
42#include "ldmain.h"
43#include "ldexp.h"
44#include "ldlang.h"
45#include "ldfile.h"
46#include "ldemul.h"
47#include <ldgram.h>
48#include "ldlex.h"
49#include "ldmisc.h"
50#include "ldctor.h"
51#include "coff/internal.h"
52#include "../bfd/libcoff.h"
53
54#define TARGET_IS_${EMULATION_NAME}
55
56static struct internal_extra_pe_aouthdr pe;
57static int dll;
58
59extern const char *output_filename;
60
61static void
62gld_${EMULATION_NAME}_before_parse (void)
63{
64  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
65  output_filename = "a.exe";
66}
67
68/* PE format extra command line options.  */
69
70/* Used for setting flags in the PE header. */
71#define OPTION_BASE_FILE		(300  + 1)
72#define OPTION_DLL			(OPTION_BASE_FILE + 1)
73#define OPTION_FILE_ALIGNMENT		(OPTION_DLL + 1)
74#define OPTION_IMAGE_BASE		(OPTION_FILE_ALIGNMENT + 1)
75#define OPTION_MAJOR_IMAGE_VERSION	(OPTION_IMAGE_BASE + 1)
76#define OPTION_MAJOR_OS_VERSION		(OPTION_MAJOR_IMAGE_VERSION + 1)
77#define OPTION_MAJOR_SUBSYSTEM_VERSION	(OPTION_MAJOR_OS_VERSION + 1)
78#define OPTION_MINOR_IMAGE_VERSION	(OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
79#define OPTION_MINOR_OS_VERSION		(OPTION_MINOR_IMAGE_VERSION + 1)
80#define OPTION_MINOR_SUBSYSTEM_VERSION	(OPTION_MINOR_OS_VERSION + 1)
81#define OPTION_SECTION_ALIGNMENT	(OPTION_MINOR_SUBSYSTEM_VERSION + 1)
82#define OPTION_STACK                    (OPTION_SECTION_ALIGNMENT + 1)
83#define OPTION_SUBSYSTEM                (OPTION_STACK + 1)
84#define OPTION_HEAP			(OPTION_SUBSYSTEM + 1)
85
86static void
87gld${EMULATION_NAME}_add_options
88  (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
89   struct option **longopts, int nrl ATTRIBUTE_UNUSED,
90   struct option **really_longopts ATTRIBUTE_UNUSED)
91{
92  static const struct option xtra_long[] = {
93    /* PE options */
94    {"base-file", required_argument, NULL, OPTION_BASE_FILE},
95    {"dll", no_argument, NULL, OPTION_DLL},
96    {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
97    {"heap", required_argument, NULL, OPTION_HEAP},
98    {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
99    {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
100    {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
101    {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
102    {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
103    {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
104    {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
105    {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
106    {"stack", required_argument, NULL, OPTION_STACK},
107    {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
108    {NULL, no_argument, NULL, 0}
109  };
110
111  *longopts = (struct option *)
112    xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
113  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
114}
115
116
117/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
118   parameters which may be input from the command line */
119
120typedef struct {
121  void *ptr;
122  int size;
123  int value;
124  char *symbol;
125  int inited;
126} definfo;
127
128#define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
129
130static definfo init[] =
131{
132  /* imagebase must be first */
133#define IMAGEBASEOFF 0
134  D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
135#define DLLOFF 1
136  {&dll, sizeof(dll), 0, "__dll__", 0},
137  D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
138  D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
139  D(MajorOperatingSystemVersion,"__major_os_version__", 4),
140  D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
141  D(MajorImageVersion,"__major_image_version__", 1),
142  D(MinorImageVersion,"__minor_image_version__", 0),
143  D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
144  D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
145  D(Subsystem,"__subsystem__", 3),
146  D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
147  D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
148  D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
149  D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
150  D(LoaderFlags,"__loader_flags__", 0x0),
151  { NULL, 0, 0, NULL, 0 }
152};
153
154
155static void
156set_pe_name (char *name, long val)
157{
158  int i;
159  /* Find the name and set it. */
160  for (i = 0; init[i].ptr; i++)
161    {
162      if (strcmp (name, init[i].symbol) == 0)
163	{
164	  init[i].value = val;
165	  init[i].inited = 1;
166	  return;
167	}
168    }
169  abort();
170}
171
172
173static void
174set_pe_subsystem (void)
175{
176  const char *sver;
177  int len;
178  int i;
179  static const struct
180    {
181      const char *name;
182      const int value;
183      const char *entry;
184    }
185  v[] =
186    {
187      { "native", 1, "_NtProcessStartup" },
188      { "windows", 2, "_WinMainCRTStartup" },
189      { "wwindows", 2, "_wWinMainCRTStartup" },
190      { "console", 3, "_mainCRTStartup" },
191      { "wconsole", 3, "_wmainCRTStartup" },
192      { "posix", 7, "___PosixProcessStartup"},
193      { 0, 0, 0 }
194    };
195
196  sver = strchr (optarg, ':');
197  if (sver == NULL)
198    len = strlen (optarg);
199  else
200    {
201      char *end;
202
203      len = sver - optarg;
204      set_pe_name ("__major_subsystem_version__",
205		   strtoul (sver + 1, &end, 0));
206      if (*end == '.')
207	set_pe_name ("__minor_subsystem_version__",
208		     strtoul (end + 1, &end, 0));
209      if (*end != '\0')
210	einfo ("%P: warning: bad version number in -subsystem option\n");
211    }
212
213  for (i = 0; v[i].name; i++)
214    {
215      if (strncmp (optarg, v[i].name, len) == 0
216	  && v[i].name[len] == '\0')
217	{
218	  set_pe_name ("__subsystem__", v[i].value);
219
220	  /* If the subsystem is windows, we use a different entry
221	     point.  */
222	  lang_default_entry (v[i].entry);
223
224	  return;
225	}
226    }
227  einfo ("%P%F: invalid subsystem type %s\n", optarg);
228}
229
230
231static void
232set_pe_value (char *name)
233{
234  char *end;
235  set_pe_name (name,  strtoul (optarg, &end, 0));
236  if (end == optarg)
237    {
238      einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
239    }
240
241  optarg = end;
242}
243
244static void
245set_pe_stack_heap (char *resname, char *comname)
246{
247  set_pe_value (resname);
248  if (*optarg == ',')
249    {
250      optarg++;
251      set_pe_value (comname);
252    }
253  else if (*optarg)
254    {
255      einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
256    }
257}
258
259
260static bfd_boolean
261gld${EMULATION_NAME}_handle_option (int optc)
262{
263  switch (optc)
264    {
265    default:
266      return FALSE;
267
268    case OPTION_BASE_FILE:
269      link_info.base_file = fopen (optarg, FOPEN_WB);
270      if (link_info.base_file == NULL)
271	{
272	  fprintf (stderr, "%s: Can't open base file %s\n",
273		   program_name, optarg);
274	  xexit (1);
275	}
276      break;
277
278      /* PE options */
279    case OPTION_HEAP:
280      set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
281      break;
282    case OPTION_STACK:
283      set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
284      break;
285    case OPTION_SUBSYSTEM:
286      set_pe_subsystem ();
287      break;
288    case OPTION_MAJOR_OS_VERSION:
289      set_pe_value ("__major_os_version__");
290      break;
291    case OPTION_MINOR_OS_VERSION:
292      set_pe_value ("__minor_os_version__");
293      break;
294    case OPTION_MAJOR_SUBSYSTEM_VERSION:
295      set_pe_value ("__major_subsystem_version__");
296      break;
297    case OPTION_MINOR_SUBSYSTEM_VERSION:
298      set_pe_value ("__minor_subsystem_version__");
299      break;
300    case OPTION_MAJOR_IMAGE_VERSION:
301      set_pe_value ("__major_image_version__");
302      break;
303    case OPTION_MINOR_IMAGE_VERSION:
304      set_pe_value ("__minor_image_version__");
305      break;
306    case OPTION_FILE_ALIGNMENT:
307      set_pe_value ("__file_alignment__");
308      break;
309    case OPTION_SECTION_ALIGNMENT:
310      set_pe_value ("__section_alignment__");
311      break;
312    case OPTION_DLL:
313      set_pe_name ("__dll__", 1);
314      break;
315    case OPTION_IMAGE_BASE:
316      set_pe_value ("__image_base__");
317      break;
318    }
319  return TRUE;
320}
321
322/* Assign values to the special symbols before the linker script is
323   read.  */
324
325static void
326gld_${EMULATION_NAME}_set_symbols (void)
327{
328  /* Run through and invent symbols for all the
329     names and insert the defaults. */
330  int j;
331  lang_statement_list_type *save;
332
333  if (!init[IMAGEBASEOFF].inited)
334    {
335      if (link_info.relocatable)
336	init[IMAGEBASEOFF].value = 0;
337      else if (init[DLLOFF].value)
338	init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
339      else
340	init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
341    }
342
343  /* Don't do any symbol assignments if this is a relocatable link.  */
344  if (link_info.relocatable)
345    return;
346
347  /* Glue the assignments into the abs section */
348  save = stat_ptr;
349
350  stat_ptr = &(abs_output_section->children);
351
352  for (j = 0; init[j].ptr; j++)
353    {
354      long val = init[j].value;
355      lang_add_assignment (exp_assop ('=', init[j].symbol, exp_intop (val)));
356      if (init[j].size == sizeof(short))
357	*(short *)init[j].ptr = val;
358      else if (init[j].size == sizeof(int))
359	*(int *)init[j].ptr = val;
360      else if (init[j].size == sizeof(long))
361	*(long *)init[j].ptr = val;
362      /* This might be a long long or other special type.  */
363      else if (init[j].size == sizeof(bfd_vma))
364	*(bfd_vma *)init[j].ptr = val;
365      else	abort();
366    }
367  /* Restore the pointer. */
368  stat_ptr = save;
369
370  if (pe.FileAlignment >
371      pe.SectionAlignment)
372    {
373      einfo ("%P: warning, file alignment > section alignment.\n");
374    }
375}
376
377static void
378gld_${EMULATION_NAME}_after_open (void)
379{
380  /* Pass the wacky PE command line options into the output bfd.
381     FIXME: This should be done via a function, rather than by
382     including an internal BFD header.  */
383  if (!coff_data(output_bfd)->pe)
384    {
385      einfo ("%F%P: PE operations on non PE file.\n");
386    }
387
388  pe_data(output_bfd)->pe_opthdr = pe;
389  pe_data(output_bfd)->dll = init[DLLOFF].value;
390
391}
392
393/* Callback functions for qsort in sort_sections. */
394
395static int
396sort_by_file_name (const void *a, const void *b)
397{
398  const lang_statement_union_type *const *ra = a;
399  const lang_statement_union_type *const *rb = b;
400  int i, a_sec, b_sec;
401
402  i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename,
403	      (*rb)->input_section.ifile->the_bfd->my_archive->filename);
404  if (i != 0)
405    return i;
406
407  i = strcmp ((*ra)->input_section.ifile->filename,
408		 (*rb)->input_section.ifile->filename);
409  if (i != 0)
410    return i;
411  /* the tail idata4/5 are the only ones without relocs to an
412     idata\$6 section unless we are importing by ordinal,
413     so sort them to last to terminate the IAT
414     and HNT properly. if no reloc this one is import by ordinal
415     so we have to sort by section contents */
416
417  if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) )
418    {
419       i =  (((*ra)->input_section.section->reloc_count >
420		 (*rb)->input_section.section->reloc_count) ? -1 : 0);
421       if ( i != 0)
422         return i;
423
424        return  (((*ra)->input_section.section->reloc_count >
425		 (*rb)->input_section.section->reloc_count) ? 0 : 1);
426    }
427  else
428    {
429       if ( (strcmp( (*ra)->input_section.section->name, ".idata\$6") == 0) )
430          return 0; /* don't sort .idata\$6 or .idata\$7 FIXME dlltool eliminate .idata\$7 */
431
432       if (! bfd_get_section_contents ((*ra)->input_section.ifile->the_bfd,
433         (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec)))
434            einfo ("%F%B: Can't read contents of section .idata: %E\n",
435                 (*ra)->input_section.ifile->the_bfd);
436
437       if (! bfd_get_section_contents ((*rb)->input_section.ifile->the_bfd,
438        (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) ))
439           einfo ("%F%B: Can't read contents of section .idata: %E\n",
440                (*rb)->input_section.ifile->the_bfd);
441
442      i =  ((a_sec < b_sec) ? -1 : 0);
443      if ( i != 0)
444        return i;
445      return  ((a_sec < b_sec) ? 0 : 1);
446   }
447return 0;
448}
449
450static int
451sort_by_section_name (const void *a, const void *b)
452{
453  const lang_statement_union_type *const *ra = a;
454  const lang_statement_union_type *const *rb = b;
455  int i;
456  i = strcmp ((*ra)->input_section.section->name,
457		 (*rb)->input_section.section->name);
458/* this is a hack to make .stab and .stabstr last, so we don't have
459   to fix strip/objcopy for .reloc sections.
460   FIXME stripping images with a .rsrc section still needs to be fixed */
461  if ( i != 0)
462    {
463      if ((strncmp ((*ra)->input_section.section->name, ".stab", 5) == 0)
464           && (strncmp ((*rb)->input_section.section->name, ".stab", 5) != 0))
465         return 1;
466      return i;
467    }
468  return i;
469}
470
471/* Subroutine of sort_sections to a contiguous subset of a list of sections.
472   NEXT_AFTER is the element after the last one to sort.
473   The result is a pointer to the last element's "next" pointer.  */
474
475static lang_statement_union_type **
476sort_sections_1 (lang_statement_union_type **startptr,
477		 lang_statement_union_type *next_after,
478		 int count,
479		 int (*sort_func) (const void *, const void *))
480{
481  lang_statement_union_type **vec;
482  lang_statement_union_type *p;
483  int i;
484  lang_statement_union_type **ret;
485
486  if (count == 0)
487    return startptr;
488
489  vec = ((lang_statement_union_type **)
490	 xmalloc (count * sizeof (lang_statement_union_type *)));
491
492  for (p = *startptr, i = 0; i < count; i++, p = p->header.next)
493    vec[i] = p;
494
495  qsort (vec, count, sizeof (vec[0]), sort_func);
496
497  /* Fill in the next pointers again. */
498  *startptr = vec[0];
499  for (i = 0; i < count - 1; i++)
500    vec[i]->header.next = vec[i + 1];
501  vec[i]->header.next = next_after;
502  ret = &vec[i]->header.next;
503  free (vec);
504  return ret;
505}
506
507/* Sort the .idata\$foo input sections of archives into filename order.
508   The reason is so dlltool can arrange to have the pe dll import information
509   generated correctly - the head of the list goes into dh.o, the tail into
510   dt.o, and the guts into ds[nnnn].o.  Note that this is only needed for the
511   .idata section.
512   FIXME: This may no longer be necessary with grouped sections.  Instead of
513   sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
514   .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
515   This would have to be elaborated upon to handle multiple DLLs
516   [assuming such an eloboration is possible of course].
517
518   We also sort sections in '\$' wild statements.  These are created by the
519   place_orphans routine to implement grouped sections.  */
520
521static void
522sort_sections (lang_statement_union_type *s)
523{
524  for (; s ; s = s->header.next)
525    switch (s->header.type)
526      {
527      case lang_output_section_statement_enum:
528	sort_sections (s->output_section_statement.children.head);
529	break;
530      case lang_wild_statement_enum:
531	{
532	  lang_statement_union_type **p = &s->wild_statement.children.head;
533	  struct wildcard_list *sec;
534
535	  for (sec = s->wild_statement.section_list; sec; sec = sec->next)
536	    {
537	      /* Is this the .idata section?  */
538	      if (sec->spec.name != NULL
539		  && strncmp (sec->spec.name, ".idata", 6) == 0)
540		{
541		  /* Sort the children.  We want to sort any objects in
542		     the same archive.  In order to handle the case of
543		     including a single archive multiple times, we sort
544		     all the children by archive name and then by object
545		     name.  After sorting them, we re-thread the pointer
546		     chain.  */
547
548		  while (*p)
549		    {
550		      lang_statement_union_type *start = *p;
551		      if (start->header.type != lang_input_section_enum
552			  || !start->input_section.ifile->the_bfd->my_archive)
553			p = &(start->header.next);
554		      else
555			{
556			  lang_statement_union_type *end;
557			  int count;
558
559			  for (end = start, count = 0;
560			       end && (end->header.type
561				       == lang_input_section_enum);
562			       end = end->header.next)
563			    count++;
564
565			  p = sort_sections_1 (p, end, count,
566					       sort_by_file_name);
567			}
568		    }
569		  break;
570		}
571
572	      /* If this is a collection of grouped sections, sort them.
573		 The linker script must explicitly mention "*(.foo\$)" or
574		 "*(.foo\$*)".  Don't sort them if \$ is not the last
575		 character (not sure if this is really useful, but it
576		 allows explicitly mentioning some \$ sections and letting
577		 the linker handle the rest).  */
578	      if (sec->spec.name != NULL)
579		{
580		  char *q = strchr (sec->spec.name, '\$');
581
582		  if (q != NULL
583		      && (q[1] == '\0'
584			  || (q[1] == '*' && q[2] == '\0')))
585		    {
586		      lang_statement_union_type *end;
587		      int count;
588
589		      for (end = *p, count = 0; end; end = end->header.next)
590			{
591			  if (end->header.type != lang_input_section_enum)
592			    abort ();
593			  count++;
594			}
595		      (void) sort_sections_1 (p, end, count,
596					      sort_by_section_name);
597		    }
598		  break;
599		}
600	    }
601	}
602	break;
603      default:
604	break;
605      }
606}
607
608static void
609gld_${EMULATION_NAME}_before_allocation (void)
610{
611  extern lang_statement_list_type *stat_ptr;
612
613#ifdef TARGET_IS_ppcpe
614  /* Here we rummage through the found bfds to collect toc information */
615  {
616    LANG_FOR_EACH_INPUT_STATEMENT (is)
617      {
618	if (!ppc_process_before_allocation(is->the_bfd, &link_info))
619	  {
620	    einfo("Errors encountered processing file %s\n", is->filename);
621	  }
622      }
623  }
624
625  /* We have seen it all. Allocate it, and carry on */
626  ppc_allocate_toc_section (&link_info);
627#else
628#ifdef TARGET_IS_armpe
629  /* FIXME: we should be able to set the size of the interworking stub
630     section.
631
632     Here we rummage through the found bfds to collect glue
633     information.  FIXME: should this be based on a command line
634     option?  krk@cygnus.com */
635  {
636    LANG_FOR_EACH_INPUT_STATEMENT (is)
637      {
638	if (!arm_process_before_allocation (is->the_bfd, & link_info))
639	  {
640	    einfo ("Errors encountered processing file %s", is->filename);
641	  }
642      }
643  }
644
645  /* We have seen it all. Allocate it, and carry on */
646  arm_allocate_interworking_sections (& link_info);
647#endif /* TARGET_IS_armpe */
648#endif /* TARGET_IS_ppcpe */
649
650  sort_sections (stat_ptr->head);
651
652  if (!link_info.relocatable)
653    strip_excluded_output_sections ();
654}
655
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.
662
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.  */
666
667static bfd_boolean
668gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s)
669{
670  const char *secname;
671  char *output_secname, *ps;
672  lang_output_section_statement_type *os;
673  lang_statement_union_type *l;
674
675  if ((s->flags & SEC_ALLOC) == 0)
676    return FALSE;
677
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;
684
685  secname = bfd_get_section_name (s->owner, s);
686
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;
693
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);
701
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.  */
706
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;
713
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);
723
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, file);
729
730  return TRUE;
731}
732
733static char *
734gld_${EMULATION_NAME}_get_script (int *isfile)
735EOF
736# Scripts compiled in.
737# sed commands to quote an ld script as a C string.
738sc="-f stringify.sed"
739
740cat >>e${EMULATION_NAME}.c <<EOF
741{
742  *isfile = 0;
743
744  if (link_info.relocatable && config.build_constructors)
745    return
746EOF
747sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
748echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
749sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
750echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
751sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
752echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
753sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
754echo '  ; else return'                                 >> e${EMULATION_NAME}.c
755sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
756echo '; }'                                             >> e${EMULATION_NAME}.c
757
758cat >>e${EMULATION_NAME}.c <<EOF
759
760
761struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
762{
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  NULL, /* finish */
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 */
788};
789EOF
790