1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 cat >e${EMULATION_NAME}.c <<EOF
5 /* The original file generated returned different default scripts depending
6 on whether certain switches were set, but these switches pertain to the
7 Linux system and that particular version of coff. In the NT case, we
8 only determine if the subsystem is console or windows in order to select
9 the correct entry point by default. */
12 /* This file is part of GLD, the Gnu Linker.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
45 #include "coff/internal.h"
46 #include "../bfd/libcoff.h"
48 static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
49 static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *isfile));
52 static struct internal_extra_pe_aouthdr pe;
56 gld_${EMULATION_NAME}_before_parse()
58 ldfile_output_architecture = bfd_arch_${ARCH};
62 /* Used for setting flags in the PE header. */
63 #define OPTION_BASE_FILE (300 + 1)
64 #define OPTION_DLL (OPTION_BASE_FILE + 1)
65 #define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
66 #define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
67 #define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
68 #define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
69 #define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
70 #define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
71 #define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
72 #define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
73 #define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
74 #define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
75 #define OPTION_SUBSYSTEM (OPTION_STACK + 1)
76 #define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
78 static struct option longopts[] = {
80 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
81 {"dll", no_argument, NULL, OPTION_DLL},
82 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
83 {"heap", required_argument, NULL, OPTION_HEAP},
84 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
85 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
86 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
87 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
88 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
89 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
90 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
91 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
92 {"stack", required_argument, NULL, OPTION_STACK},
93 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
94 {NULL, no_argument, NULL, 0}
98 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
99 parameters which may be input from the command line */
111 #define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
113 static definfo init[] =
115 /* imagebase must be first */
116 #define IMAGEBASEOFF 0
117 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
119 {&dll, sizeof(dll), 0, "__dll__"},
120 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
121 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
122 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
123 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
124 D(MajorImageVersion,"__major_image_version__", 1),
125 D(MinorImageVersion,"__minor_image_version__", 0),
126 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
127 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
128 D(Subsystem,"__subsystem__", 3),
129 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x100000),
130 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
131 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
132 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
133 D(LoaderFlags,"__loader_flags__", 0x0),
139 set_pe_name (name, val)
144 /* Find the name and set it. */
145 for (i = 0; init[i].ptr; i++)
147 if (strcmp (name, init[i].symbol) == 0)
169 {"native", BFD_PE_NATIVE},
170 {"windows",BFD_PE_WINDOWS},
171 {"console",BFD_PE_CONSOLE},
173 {"posix", BFD_PE_POSIX},
177 for (i = 0; v[i].name; i++)
179 if (!strcmp (optarg, v[i].name))
181 set_pe_name ("__subsystem__", v[i].value);
185 einfo ("%P%F: invalid subsystem type %s\n", optarg);
196 set_pe_name (name, strtoul (optarg, &end, 16));
199 einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
206 set_pe_stack_heap (resname, comname)
213 set_pe_value (resname);
217 set_pe_value (comname);
221 einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
228 gld_${EMULATION_NAME}_parse_args(argc, argv)
234 int prevoptind = optind;
235 int prevopterr = opterr;
237 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
245 case OPTION_BASE_FILE:
246 link_info.base_file = (PTR) fopen (optarg,"w");
247 if (link_info.base_file == NULL)
249 fprintf (stderr, "%s: Can't open base file %s\n",
250 program_name, optarg);
257 set_pe_stack_heap ("__heap_reserve__", "__heap_commit__");
260 set_pe_stack_heap ("__stack_reserve__", "__stack_commit__");
262 case OPTION_SUBSYSTEM:
265 case OPTION_MAJOR_OS_VERSION:
266 set_pe_value ("__major_os_version__");
268 case OPTION_MINOR_OS_VERSION:
269 set_pe_value ("__minor_os_version__");
271 case OPTION_MAJOR_SUBSYSTEM_VERSION:
272 set_pe_value ("__major_subsystem_version__");
274 case OPTION_MINOR_SUBSYSTEM_VERSION:
275 set_pe_value ("__minor_subsytem_version__");
277 case OPTION_MAJOR_IMAGE_VERSION:
278 set_pe_value ("__major_image_version__");
280 case OPTION_MINOR_IMAGE_VERSION:
281 set_pe_value ("__minor_image_version__");
283 case OPTION_FILE_ALIGNMENT:
284 set_pe_value ("__file_alignment__");
286 case OPTION_SECTION_ALIGNMENT:
287 set_pe_value ("__section_alignment__");
290 set_pe_name ("__dll__", 1);
292 case OPTION_IMAGE_BASE:
293 set_pe_value ("__image_base__");
300 gld_${EMULATION_NAME}_set_symbols()
303 /* Run through and invent symbols for all the
304 names and insert the defaults. */
307 if (!init[IMAGEBASEOFF].inited)
308 init[IMAGEBASEOFF].value = init[DLLOFF].value
309 ? NT_DLL_IMAGE_BASE : NT_EXE_IMAGE_BASE;
311 for (j = 0; init[j].ptr; j++)
313 long val = init[j].value;
314 lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
315 if (init[j].size == sizeof(short))
316 *(short *)init[j].ptr = val;
317 else if (init[j].size == sizeof(int))
318 *(int *)init[j].ptr = val;
319 else if (init[j].size == sizeof(long))
320 *(long *)init[j].ptr = val;
324 if (pe.FileAlignment >
327 einfo ("%P: warning, file alignment > section alignment.\n");
332 gld_${EMULATION_NAME}_after_open()
334 /* Pass the wacky PE command line options into the output bfd */
335 struct internal_extra_pe_aouthdr *i;
336 if (!coff_data(output_bfd)->pe)
338 einfo ("%F%P: PE operations on non PE file.\n");
341 pe_data(output_bfd)->pe_opthdr = pe;
342 pe_data(output_bfd)->dll = init[DLLOFF].value;
346 /* Callback function for qsort in sort_sections. */
348 static int sfunc (a, b)
352 lang_statement_union_type **ra = a;
353 lang_statement_union_type **rb = b;
354 return strcmp ((*ra)->input_section.ifile->filename,
355 (*rb)->input_section.ifile->filename);
358 /* Sort the input sections of archives into filename order. */
362 lang_statement_union_type *s;
364 for (; s ; s = s->next)
365 switch (s->header.type)
367 case lang_output_section_statement_enum:
368 sort_sections (s->output_section_statement.children.head);
370 case lang_wild_statement_enum:
372 lang_statement_union_type **p = &s->wild_statement.children.head;
374 /* Sort any children in the same archive. Run through all
375 the children of this wild statement, when an
376 input_section in an archive is found, scan forward to
377 find all input_sections which are in the same archive.
378 Sort them by their filename and then re-thread the
383 lang_statement_union_type *start = *p;
384 if (start->header.type != lang_input_section_enum
385 || !start->input_section.ifile->the_bfd->my_archive)
386 p = &(start->header.next);
389 lang_statement_union_type **vec;
390 lang_statement_union_type *end;
391 lang_statement_union_type *np;
395 for (end = start, count = 0;
396 end && end->header.type == lang_input_section_enum
397 && (end->input_section.ifile->the_bfd->my_archive
398 == start->input_section.ifile->the_bfd->my_archive);
404 vec = (lang_statement_union_type **)
405 alloca (count * sizeof (lang_statement_union_type *));
407 for (end = start, i = 0; i < count; i++, end = end->next)
410 qsort (vec, count, sizeof (vec[0]), sfunc);
412 /* Fill in the next pointers again. */
414 for (i = 0; i < count - 1; i++)
415 vec[i]->header.next = vec[i + 1];
416 vec[i]->header.next = np;
417 p = &(vec[i]->header.next);
428 gld_${EMULATION_NAME}_before_allocation()
430 extern lang_statement_list_type *stat_ptr;
431 sort_sections (*stat_ptr);
435 gld_${EMULATION_NAME}_get_script(isfile)
438 # Scripts compiled in.
439 # sed commands to quote an ld script as a C string.
440 sc="-f ${srcdir}/emultempl/stringify.sed"
442 cat >>e${EMULATION_NAME}.c <<EOF
446 if (link_info.relocateable == true && config.build_constructors == true)
449 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
450 echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
451 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
452 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
453 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
454 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
455 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
456 echo ' ; else return' >> e${EMULATION_NAME}.c
457 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
458 echo '; }' >> e${EMULATION_NAME}.c
460 cat >>e${EMULATION_NAME}.c <<EOF
464 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
466 gld_${EMULATION_NAME}_before_parse,
470 gld_${EMULATION_NAME}_after_open,
471 after_allocation_default,
472 set_output_arch_default,
473 ldemul_default_target,
474 gld_${EMULATION_NAME}_before_allocation,
475 gld_${EMULATION_NAME}_get_script,
479 NULL, /* create output section statements */
480 NULL, /* open dynamic archive */
481 NULL, /* place orphan */
482 gld_${EMULATION_NAME}_set_symbols,
483 gld_${EMULATION_NAME}_parse_args