* emultempl/elf32.em (gld${EMULATION_NAME}_check_ld_so_conf): New
[deliverable/binutils-gdb.git] / ld / emultempl / pe.em
CommitLineData
5f8ac7e7
SC
1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
4/* For WINDOWS_NT */
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. */
10
11
12/* This file is part of GLD, the Gnu Linker.
13
14This program is free software; you can redistribute it and/or modify
15it under the terms of the GNU General Public License as published by
16the Free Software Foundation; either version 2 of the License, or
17(at your option) any later version.
18
19This program is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22GNU General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; if not, write to the Free Software
26Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27
28
29#include "bfd.h"
30#include "sysdep.h"
31#include "bfdlink.h"
32#include "getopt.h"
33#include "ld.h"
5f8ac7e7
SC
34#include "ld.h"
35#include "ldmain.h"
36#include "ldgram.h"
37#include "ldexp.h"
38#include "ldlang.h"
39#include "ldemul.h"
40#include "ldlex.h"
41#include "ldmisc.h"
42#include "ldctor.h"
43#include "ldfile.h"
44#include "coff/internal.h"
45#include "../bfd/libcoff.h"
46
d4279937
SC
47#define TARGET_IS_${EMULATION_NAME}
48
5f8ac7e7
SC
49static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
50static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *isfile));
51
52
53static struct internal_extra_pe_aouthdr pe;
54static int dll;
55
56static void
57gld_${EMULATION_NAME}_before_parse()
58{
59 ldfile_output_architecture = bfd_arch_${ARCH};
60}
61
62
63/* Used for setting flags in the PE header. */
64#define OPTION_BASE_FILE (300 + 1)
65#define OPTION_DLL (OPTION_BASE_FILE + 1)
66#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
67#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
68#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
69#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
70#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
71#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
72#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
73#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
74#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
75#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
76#define OPTION_SUBSYSTEM (OPTION_STACK + 1)
77#define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
78
79 static struct option longopts[] = {
80 /* PE options */
81 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
82 {"dll", no_argument, NULL, OPTION_DLL},
83 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
84 {"heap", required_argument, NULL, OPTION_HEAP},
85 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
86 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
87 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
88 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
89 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
90 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
91 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
92 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
93 {"stack", required_argument, NULL, OPTION_STACK},
94 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
95 {NULL, no_argument, NULL, 0}
96 };
97
98
99/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
100 parameters which may be input from the command line */
101
102
103
104typedef struct {
105 void *ptr;
106 int size;
107 int value;
108 char *symbol;
109 int inited;
110} definfo;
111
112#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
113
114static definfo init[] =
115{
116 /* imagebase must be first */
117#define IMAGEBASEOFF 0
118 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
119#define DLLOFF 1
120 {&dll, sizeof(dll), 0, "__dll__"},
121 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
122 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
123 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
124 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
125 D(MajorImageVersion,"__major_image_version__", 1),
126 D(MinorImageVersion,"__minor_image_version__", 0),
127 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
128 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
129 D(Subsystem,"__subsystem__", 3),
130 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x100000),
131 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
132 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
133 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
134 D(LoaderFlags,"__loader_flags__", 0x0),
135 0
136};
137
138
139static void
140set_pe_name (name, val)
141 char *name;
142 long val;
143{
144 int i;
145 /* Find the name and set it. */
146 for (i = 0; init[i].ptr; i++)
147 {
148 if (strcmp (name, init[i].symbol) == 0)
149 {
150 init[i].value = val;
151 init[i].inited = 1;
152 return;
153 }
154 }
155 abort();
156}
157
158
159static void
160set_pe_subsystem ()
161{
162 int i;
163 static struct
164 {
165 char *name ;
166 int value;
167 }
168 v[] =
169 {
2543860d
SC
170 {"native", 1},
171 {"windows",2},
172 {"console",3},
173 {"os2",5},
174 {"posix", 7},
5f8ac7e7
SC
175 {0,0}
176 };
177
178 for (i = 0; v[i].name; i++)
179 {
180 if (!strcmp (optarg, v[i].name))
181 {
182 set_pe_name ("__subsystem__", v[i].value);
183 return;
184 }
185 }
186 einfo ("%P%F: invalid subsystem type %s\n", optarg);
187}
188
189
190
191static void
192set_pe_value (name)
193 char *name;
194
195{
196 char *end;
197 set_pe_name (name, strtoul (optarg, &end, 16));
198 if (end == optarg)
199 {
200 einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
201 }
202
203 optarg = end;
204}
205
206static void
207set_pe_stack_heap (resname, comname)
208 char *resname;
209 char *comname;
210{
211 char *begin_commit;
212 char *end;
213
214 set_pe_value (resname);
215 if (*optarg == ',')
216 {
217 optarg++;
218 set_pe_value (comname);
219 }
220 else if (*optarg)
221 {
222 einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
223 }
224}
225
226
227
228static int
229gld_${EMULATION_NAME}_parse_args(argc, argv)
230 int argc;
231 char **argv;
232{
233 int longind;
234 int optc;
235 int prevoptind = optind;
236 int prevopterr = opterr;
2543860d
SC
237 int wanterror;
238 static int lastoptind = -1;
239
240 if (lastoptind != optind)
241 opterr = 0;
242 wanterror = opterr;
243
244 lastoptind = optind;
245
5f8ac7e7
SC
246 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
247 opterr = prevopterr;
2543860d 248
5f8ac7e7
SC
249 switch (optc)
250 {
251 default:
2543860d
SC
252 if (wanterror)
253 xexit (1);
254 optind = prevoptind;
5f8ac7e7
SC
255 return 0;
256
257 case OPTION_BASE_FILE:
d4279937 258 link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
5f8ac7e7
SC
259 if (link_info.base_file == NULL)
260 {
261 fprintf (stderr, "%s: Can't open base file %s\n",
262 program_name, optarg);
263 xexit (1);
264 }
265 break;
266
267 /* PE options */
268 case OPTION_HEAP:
269 set_pe_stack_heap ("__heap_reserve__", "__heap_commit__");
270 break;
271 case OPTION_STACK:
272 set_pe_stack_heap ("__stack_reserve__", "__stack_commit__");
273 break;
274 case OPTION_SUBSYSTEM:
275 set_pe_subsystem ();
276 break;
277 case OPTION_MAJOR_OS_VERSION:
278 set_pe_value ("__major_os_version__");
279 break;
280 case OPTION_MINOR_OS_VERSION:
281 set_pe_value ("__minor_os_version__");
282 break;
283 case OPTION_MAJOR_SUBSYSTEM_VERSION:
284 set_pe_value ("__major_subsystem_version__");
285 break;
286 case OPTION_MINOR_SUBSYSTEM_VERSION:
2543860d 287 set_pe_value ("__minor_subsystem_version__");
5f8ac7e7
SC
288 break;
289 case OPTION_MAJOR_IMAGE_VERSION:
290 set_pe_value ("__major_image_version__");
291 break;
292 case OPTION_MINOR_IMAGE_VERSION:
293 set_pe_value ("__minor_image_version__");
294 break;
295 case OPTION_FILE_ALIGNMENT:
296 set_pe_value ("__file_alignment__");
297 break;
298 case OPTION_SECTION_ALIGNMENT:
299 set_pe_value ("__section_alignment__");
300 break;
301 case OPTION_DLL:
302 set_pe_name ("__dll__", 1);
303 break;
304 case OPTION_IMAGE_BASE:
305 set_pe_value ("__image_base__");
306 break;
307 }
308 return 1;
309}
310
311static void
312gld_${EMULATION_NAME}_set_symbols()
313{
5f8ac7e7
SC
314 /* Run through and invent symbols for all the
315 names and insert the defaults. */
316 int j;
2543860d 317 lang_statement_list_type *save;
5f8ac7e7
SC
318
319 if (!init[IMAGEBASEOFF].inited)
320 init[IMAGEBASEOFF].value = init[DLLOFF].value
321 ? NT_DLL_IMAGE_BASE : NT_EXE_IMAGE_BASE;
322
2543860d 323 /* Glue the assignments into the abs section */
d4279937 324 save = stat_ptr;
2543860d
SC
325
326 stat_ptr = &(abs_output_section->children);
d4279937 327
5f8ac7e7
SC
328 for (j = 0; init[j].ptr; j++)
329 {
330 long val = init[j].value;
331 lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
332 if (init[j].size == sizeof(short))
333 *(short *)init[j].ptr = val;
334 else if (init[j].size == sizeof(int))
335 *(int *)init[j].ptr = val;
336 else if (init[j].size == sizeof(long))
337 *(long *)init[j].ptr = val;
338 else abort();
339 }
2543860d
SC
340 /* Restore the pointer. */
341 stat_ptr = save;
342
5f8ac7e7
SC
343 if (pe.FileAlignment >
344 pe.SectionAlignment)
345 {
346 einfo ("%P: warning, file alignment > section alignment.\n");
347 }
348}
349
350static void
351gld_${EMULATION_NAME}_after_open()
352{
353 /* Pass the wacky PE command line options into the output bfd */
354 struct internal_extra_pe_aouthdr *i;
355 if (!coff_data(output_bfd)->pe)
356 {
357 einfo ("%F%P: PE operations on non PE file.\n");
358 }
359
360 pe_data(output_bfd)->pe_opthdr = pe;
361 pe_data(output_bfd)->dll = init[DLLOFF].value;
362
363}
364
365/* Callback function for qsort in sort_sections. */
366
367static int sfunc (a, b)
368void *a;
369void *b;
370{
371 lang_statement_union_type **ra = a;
372 lang_statement_union_type **rb = b;
373 return strcmp ((*ra)->input_section.ifile->filename,
374 (*rb)->input_section.ifile->filename);
375}
376
377/* Sort the input sections of archives into filename order. */
378\f
379static void
380sort_sections (s)
381 lang_statement_union_type *s;
382{
383 for (; s ; s = s->next)
384 switch (s->header.type)
385 {
386 case lang_output_section_statement_enum:
387 sort_sections (s->output_section_statement.children.head);
388 break;
389 case lang_wild_statement_enum:
390 {
391 lang_statement_union_type **p = &s->wild_statement.children.head;
392
393 /* Sort any children in the same archive. Run through all
394 the children of this wild statement, when an
395 input_section in an archive is found, scan forward to
396 find all input_sections which are in the same archive.
397 Sort them by their filename and then re-thread the
398 pointer chain. */
399
400 while (*p)
401 {
402 lang_statement_union_type *start = *p;
403 if (start->header.type != lang_input_section_enum
404 || !start->input_section.ifile->the_bfd->my_archive)
405 p = &(start->header.next);
406 else
407 {
408 lang_statement_union_type **vec;
409 lang_statement_union_type *end;
410 lang_statement_union_type *np;
411 int count;
412 int i;
413
414 for (end = start, count = 0;
415 end && end->header.type == lang_input_section_enum
416 && (end->input_section.ifile->the_bfd->my_archive
417 == start->input_section.ifile->the_bfd->my_archive);
418 end = end->next)
419 count++;
420
421 np = end;
422
423 vec = (lang_statement_union_type **)
424 alloca (count * sizeof (lang_statement_union_type *));
425
426 for (end = start, i = 0; i < count; i++, end = end->next)
427 vec[i] = end;
428
429 qsort (vec, count, sizeof (vec[0]), sfunc);
430
431 /* Fill in the next pointers again. */
432 *p = vec[0];
433 for (i = 0; i < count - 1; i++)
434 vec[i]->header.next = vec[i + 1];
435 vec[i]->header.next = np;
436 p = &(vec[i]->header.next);
437 }
438 }
439 }
440 break;
441 default:
442 break;
443 }
444}
445
446static void
447gld_${EMULATION_NAME}_before_allocation()
448{
449 extern lang_statement_list_type *stat_ptr;
d4279937
SC
450
451#ifdef TARGET_IS_ppcpe
452 /* Here we rummage through the found bfds to collect toc information */
453 {
454 LANG_FOR_EACH_INPUT_STATEMENT (is)
455 {
456 ppc_process_before_allocation(is->the_bfd, &link_info);
457 }
458 }
459
460 /* We have seen it all. Allocate it, and carry on */
461 ppc_allocate_toc_section (&link_info);
462#endif
463
5f8ac7e7
SC
464 sort_sections (*stat_ptr);
465}
466
467static char *
468gld_${EMULATION_NAME}_get_script(isfile)
469 int *isfile;
470EOF
471# Scripts compiled in.
472# sed commands to quote an ld script as a C string.
473sc="-f ${srcdir}/emultempl/stringify.sed"
474
475cat >>e${EMULATION_NAME}.c <<EOF
476{
477 *isfile = 0;
478
479 if (link_info.relocateable == true && config.build_constructors == true)
480 return
481EOF
482sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
483echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
484sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
485echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
486sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
487echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
488sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
489echo ' ; else return' >> e${EMULATION_NAME}.c
490sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
491echo '; }' >> e${EMULATION_NAME}.c
492
493cat >>e${EMULATION_NAME}.c <<EOF
494
495
496
497struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
498{
499 gld_${EMULATION_NAME}_before_parse,
500 syslib_default,
501 hll_default,
502 after_parse_default,
503 gld_${EMULATION_NAME}_after_open,
504 after_allocation_default,
505 set_output_arch_default,
506 ldemul_default_target,
507 gld_${EMULATION_NAME}_before_allocation,
508 gld_${EMULATION_NAME}_get_script,
509 "${EMULATION_NAME}",
510 "${OUTPUT_FORMAT}",
511 NULL, /* finish */
512 NULL, /* create output section statements */
513 NULL, /* open dynamic archive */
514 NULL, /* place orphan */
515 gld_${EMULATION_NAME}_set_symbols,
516 gld_${EMULATION_NAME}_parse_args
517};
518EOF
519
This page took 0.132108 seconds and 4 git commands to generate.