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, 1998 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. */
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. */
32 #include "libiberty.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}_after_parse PARAMS ((void));
52 static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
53 static boolean gld_${EMULATION_NAME}_place_orphan
54 PARAMS ((lang_input_statement_type *, asection *));
55 static void gld${EMULATION_NAME}_place_section
56 PARAMS ((lang_statement_union_type *));
57 static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
58 static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
60 static struct internal_extra_pe_aouthdr pe;
62 static int support_old_code = 0;
64 extern const char *output_filename;
67 gld_${EMULATION_NAME}_before_parse()
69 output_filename = "a.exe";
70 ldfile_output_architecture = bfd_arch_${ARCH};
73 /* PE format extra command line options. */
75 /* Used for setting flags in the PE header. */
76 #define OPTION_BASE_FILE (300 + 1)
77 #define OPTION_DLL (OPTION_BASE_FILE + 1)
78 #define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
79 #define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
80 #define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
81 #define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
82 #define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
83 #define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
84 #define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
85 #define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
86 #define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
87 #define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
88 #define OPTION_SUBSYSTEM (OPTION_STACK + 1)
89 #define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
90 #define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1)
92 static struct option longopts[] =
95 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
96 {"dll", no_argument, NULL, OPTION_DLL},
97 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
98 {"heap", required_argument, NULL, OPTION_HEAP},
99 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
100 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
101 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
102 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
103 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
104 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
105 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
106 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
107 {"stack", required_argument, NULL, OPTION_STACK},
108 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
109 {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
110 {NULL, no_argument, NULL, 0}
114 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
115 parameters which may be input from the command line */
126 #define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
128 static definfo init[] =
130 /* imagebase must be first */
131 #define IMAGEBASEOFF 0
132 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
134 {&dll, sizeof(dll), 0, "__dll__"},
135 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
136 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
137 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
138 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
139 D(MajorImageVersion,"__major_image_version__", 1),
140 D(MinorImageVersion,"__minor_image_version__", 0),
141 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
142 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
143 D(Subsystem,"__subsystem__", 3),
144 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
145 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
146 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
147 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
148 D(LoaderFlags,"__loader_flags__", 0x0),
149 { NULL, 0, 0, NULL, 0 }
153 gld_${EMULATION_NAME}_list_options (file)
156 fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n"));
157 fprintf (file, _(" --dll Set image base to the default for DLLs\n"));
158 fprintf (file, _(" --file-alignment <size> Set file alignment\n"));
159 fprintf (file, _(" --heap <size> Set initial size of the heap\n"));
160 fprintf (file, _(" --image-base <address> Set start address of the executable\n"));
161 fprintf (file, _(" --major-image-version <number> Set version number of the executable\n"));
162 fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n"));
163 fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n"));
164 fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n"));
165 fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n"));
166 fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"));
167 fprintf (file, _(" --section-alignment <size> Set section alignment\n"));
168 fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
169 fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
170 fprintf (file, _(" --support-old-code Support interworking with old code\n"));
174 set_pe_name (name, val)
179 /* Find the name and set it. */
180 for (i = 0; init[i].ptr; i++)
182 if (strcmp (name, init[i].symbol) == 0)
207 { "native", 1, "_NtProcessStartup" },
208 { "windows", 2, "_WinMainCRTStartup" },
209 { "console", 3, "_mainCRTStartup" },
211 /* The Microsoft linker does not recognize this. */
214 { "posix", 7, "___PosixProcessStartup"},
218 sver = strchr (optarg, ':');
220 len = strlen (optarg);
226 set_pe_name ("__major_subsystem_version__",
227 strtoul (sver + 1, &end, 0));
229 set_pe_name ("__minor_subsystem_version__",
230 strtoul (end + 1, &end, 0));
232 einfo (_("%P: warning: bad version number in -subsystem option\n"));
235 for (i = 0; v[i].name; i++)
237 if (strncmp (optarg, v[i].name, len) == 0
238 && v[i].name[len] == '\0')
240 set_pe_name ("__subsystem__", v[i].value);
242 lang_add_entry (v[i].entry, 1);
248 einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
260 set_pe_name (name, strtoul (optarg, &end, 0));
263 einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
269 set_pe_stack_heap (resname, comname)
273 set_pe_value (resname);
278 set_pe_value (comname);
281 einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
287 gld_${EMULATION_NAME}_parse_args(argc, argv)
293 int prevoptind = optind;
294 int prevopterr = opterr;
296 static int lastoptind = -1;
298 if (lastoptind != optind)
304 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
315 case OPTION_BASE_FILE:
316 link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
317 if (link_info.base_file == NULL)
319 /* xgettext:c-format */
320 fprintf (stderr, _("%s: Can't open base file %s\n"),
321 program_name, optarg);
328 set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
331 set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
333 case OPTION_SUBSYSTEM:
336 case OPTION_MAJOR_OS_VERSION:
337 set_pe_value ("__major_os_version__");
339 case OPTION_MINOR_OS_VERSION:
340 set_pe_value ("__minor_os_version__");
342 case OPTION_MAJOR_SUBSYSTEM_VERSION:
343 set_pe_value ("__major_subsystem_version__");
345 case OPTION_MINOR_SUBSYSTEM_VERSION:
346 set_pe_value ("__minor_subsystem_version__");
348 case OPTION_MAJOR_IMAGE_VERSION:
349 set_pe_value ("__major_image_version__");
351 case OPTION_MINOR_IMAGE_VERSION:
352 set_pe_value ("__minor_image_version__");
354 case OPTION_FILE_ALIGNMENT:
355 set_pe_value ("__file_alignment__");
357 case OPTION_SECTION_ALIGNMENT:
358 set_pe_value ("__section_alignment__");
361 set_pe_name ("__dll__", 1);
363 case OPTION_IMAGE_BASE:
364 set_pe_value ("__image_base__");
366 case OPTION_SUPPORT_OLD_CODE:
367 support_old_code = 1;
373 /* Assign values to the special symbols before the linker script is
377 gld_${EMULATION_NAME}_set_symbols ()
379 /* Run through and invent symbols for all the
380 names and insert the defaults. */
382 lang_statement_list_type *save;
384 if (!init[IMAGEBASEOFF].inited)
386 if (link_info.relocateable)
387 init[IMAGEBASEOFF].value = 0;
388 else if (init[DLLOFF].value)
389 init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
391 init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
394 /* Don't do any symbol assignments if this is a relocateable link. */
395 if (link_info.relocateable)
398 /* Glue the assignments into the abs section */
401 stat_ptr = &(abs_output_section->children);
403 for (j = 0; init[j].ptr; j++)
405 long val = init[j].value;
406 lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
407 if (init[j].size == sizeof(short))
408 *(short *)init[j].ptr = val;
409 else if (init[j].size == sizeof(int))
410 *(int *)init[j].ptr = val;
411 else if (init[j].size == sizeof(long))
412 *(long *)init[j].ptr = val;
413 /* This might be a long long or other special type. */
414 else if (init[j].size == sizeof(bfd_vma))
415 *(bfd_vma *)init[j].ptr = val;
418 /* Restore the pointer. */
421 if (pe.FileAlignment >
424 einfo (_("%P: warning, file alignment > section alignment.\n"));
428 /* This is called after the linker script and the command line options
432 gld_${EMULATION_NAME}_after_parse ()
434 /* The Windows libraries are designed for the linker to treat the
435 entry point as an undefined symbol. Otherwise, the .obj that
436 defines mainCRTStartup is brought in because it is the first
437 encountered in libc.lib and it has other symbols in it which will
438 be pulled in by the link process. To avoid this, we act as
439 though the user specified -u with the entry point symbol.
441 This function is called after the linker script and command line
442 options have been read, so at this point we know the right entry
443 point. This function is called before the input files are
444 opened, so registering the symbol as undefined will make a
447 ldlang_add_undef (entry_symbol);
451 gld_${EMULATION_NAME}_after_open ()
453 /* Pass the wacky PE command line options into the output bfd.
454 FIXME: This should be done via a function, rather than by
455 including an internal BFD header. */
457 if (!coff_data (output_bfd)->pe)
458 einfo (_("%F%P: PE operations on non PE file.\n"));
460 pe_data (output_bfd)->pe_opthdr = pe;
461 pe_data (output_bfd)->dll = init[DLLOFF].value;
463 #ifdef TARGET_IS_armpe
465 /* Find a BFD that can hold the interworking stubs. */
466 LANG_FOR_EACH_INPUT_STATEMENT (is)
468 if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
476 gld_${EMULATION_NAME}_before_allocation()
478 #ifdef TARGET_IS_ppcpe
479 /* Here we rummage through the found bfds to collect toc information */
481 LANG_FOR_EACH_INPUT_STATEMENT (is)
483 if (!ppc_process_before_allocation (is->the_bfd, &link_info))
485 /* xgettext:c-format */
486 einfo (_("Errors encountered processing file %s\n"), is->filename);
491 /* We have seen it all. Allocate it, and carry on */
492 ppc_allocate_toc_section (&link_info);
493 #endif /* TARGET_IS_ppcpe */
495 #ifdef TARGET_IS_armpe
496 /* FIXME: we should be able to set the size of the interworking stub
499 Here we rummage through the found bfds to collect glue
500 information. FIXME: should this be based on a command line
501 option? krk@cygnus.com */
503 LANG_FOR_EACH_INPUT_STATEMENT (is)
505 if (! bfd_arm_process_before_allocation
506 (is->the_bfd, & link_info, support_old_code))
508 /* xgettext:c-format */
509 einfo (_("Errors encountered processing file %s for interworking"),
515 /* We have seen it all. Allocate it, and carry on */
516 bfd_arm_allocate_interworking_sections (& link_info);
517 #endif /* TARGET_IS_armpe */
520 /* Place an orphan section.
522 We use this to put sections in a reasonable place in the file, and
523 to ensure that they are aligned as required.
525 We handle grouped sections here as well. A section named .foo$nn
526 goes into the output section .foo. All grouped sections are sorted
529 Grouped sections for the default sections are handled by the
530 default linker script using wildcards, and are sorted by
533 static asection *hold_section;
534 static char *hold_section_name;
535 static lang_output_section_statement_type *hold_use;
536 static lang_output_section_statement_type *hold_text;
537 static lang_output_section_statement_type *hold_rdata;
538 static lang_output_section_statement_type *hold_data;
539 static lang_output_section_statement_type *hold_bss;
541 /* Place an orphan section. We use this to put random SHF_ALLOC
542 sections in the right segment. */
546 gld_${EMULATION_NAME}_place_orphan (file, s)
547 lang_input_statement_type *file;
553 if ((s->flags & SEC_ALLOC) == 0)
556 secname = bfd_get_section_name (s->owner, s);
558 /* Look through the script to see where to place this section. */
562 hold_section_name = xstrdup (secname);
563 dollar = strchr (hold_section_name, '$');
568 lang_for_each_statement (gld${EMULATION_NAME}_place_section);
570 if (hold_use == NULL)
572 lang_output_section_statement_type *place;
574 asection *snew, **pps;
575 lang_statement_list_type *old;
576 lang_statement_list_type add;
579 /* Try to put the new output section in a reasonable place based
580 on the section name and section flags. */
582 if ((s->flags & SEC_HAS_CONTENTS) == 0
585 else if ((s->flags & SEC_READONLY) == 0
586 && hold_data != NULL)
588 else if ((s->flags & SEC_CODE) == 0
589 && (s->flags & SEC_READONLY) != 0
590 && hold_rdata != NULL)
592 else if ((s->flags & SEC_READONLY) != 0
593 && hold_text != NULL)
596 /* Choose a unique name for the section. This will be needed if
597 the same section name appears in the input file with
598 different loadable or allocateable characteristics. */
599 outsecname = xstrdup (hold_section_name);
600 if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
606 len = strlen (outsecname);
607 newname = xmalloc (len + 5);
608 strcpy (newname, outsecname);
612 sprintf (newname + len, "%d", i);
615 while (bfd_get_section_by_name (output_bfd, newname) != NULL);
618 outsecname = newname;
621 /* We don't want to free OUTSECNAME, as it may get attached to
622 the output section statement. */
624 /* Create the section in the output file, and put it in the
625 right place. This shuffling is to make the output file look
627 snew = bfd_make_section (output_bfd, outsecname);
629 einfo ("%P%F: output format %s cannot represent section called %s\n",
630 output_bfd->xvec->name, outsecname);
631 if (place != NULL && place->bfd_section != NULL)
633 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
636 snew->next = place->bfd_section->next;
637 place->bfd_section->next = snew;
640 /* Start building a list of statements for this section. */
643 lang_list_init (stat_ptr);
645 if (link_info.relocateable)
649 /* All sections in an executable must be aligned to a page
651 address = exp_unop (ALIGN_K,
652 exp_nameop (NAME, "__section_alignment__"));
655 lang_enter_output_section_statement (outsecname, address, 0,
659 (etree_type *) NULL);
661 hold_use = lang_output_section_statement_lookup (outsecname);
663 lang_leave_output_section_statement
664 ((bfd_vma) 0, "*default*",
665 (struct lang_output_section_phdr_list *) NULL);
667 /* Now stick the new statement list right after PLACE. */
670 *add.tail = place->header.next;
671 place->header.next = add.head;
678 wild_doit (&hold_use->children, s, hold_use, file);
681 lang_statement_union_type **pl;
682 boolean found_dollar;
683 lang_statement_list_type list;
685 /* The section name has a '$'. Sort it with the other '$'
688 found_dollar = false;
689 for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next)
691 lang_input_section_type *ls;
694 if ((*pl)->header.type != lang_input_section_enum)
697 ls = &(*pl)->input_section;
699 lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
700 if (strchr (lname, '$') == NULL)
708 if (strcmp (secname, lname) < 0)
713 lang_list_init (&list);
714 wild_doit (&list, s, hold_use, file);
715 ASSERT (list.head != NULL && list.head->next == NULL);
717 list.head->next = *pl;
721 free (hold_section_name);
727 gld${EMULATION_NAME}_place_section (s)
728 lang_statement_union_type *s;
730 lang_output_section_statement_type *os;
732 if (s->header.type != lang_output_section_statement_enum)
735 os = &s->output_section_statement;
737 if (strcmp (os->name, hold_section_name) == 0
738 && os->bfd_section != NULL
739 && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
740 == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
743 if (strcmp (os->name, ".text") == 0)
745 else if (strcmp (os->name, ".rdata") == 0)
747 else if (strcmp (os->name, ".data") == 0)
749 else if (strcmp (os->name, ".bss") == 0)
754 gld_${EMULATION_NAME}_get_script(isfile)
757 # Scripts compiled in.
758 # sed commands to quote an ld script as a C string.
759 sc="-f ${srcdir}/emultempl/stringify.sed"
761 cat >>e${EMULATION_NAME}.c <<EOF
765 if (link_info.relocateable == true && config.build_constructors == true)
768 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
769 echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
770 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
771 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
772 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
773 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
774 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
775 echo ' ; else return' >> e${EMULATION_NAME}.c
776 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
777 echo '; }' >> e${EMULATION_NAME}.c
779 cat >>e${EMULATION_NAME}.c <<EOF
782 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
784 gld_${EMULATION_NAME}_before_parse,
787 gld_${EMULATION_NAME}_after_parse,
788 gld_${EMULATION_NAME}_after_open,
789 after_allocation_default,
790 set_output_arch_default,
791 ldemul_default_target,
792 gld_${EMULATION_NAME}_before_allocation,
793 gld_${EMULATION_NAME}_get_script,
797 NULL, /* create output section statements */
798 NULL, /* open dynamic archive */
799 gld_${EMULATION_NAME}_place_orphan,
800 gld_${EMULATION_NAME}_set_symbols,
801 gld_${EMULATION_NAME}_parse_args,
802 NULL, /* unrecognised file */
803 gld_${EMULATION_NAME}_list_options