2001-08-02 Charles Wilson <cwilson@ece.gatech.edu>
[deliverable/binutils-gdb.git] / ld / emultempl / pe.em
1 # This shell script emits a C file. -*- C -*-
2 # It does some substitutions.
3 if [ -z "$MACHINE" ]; then
4 OUTPUT_ARCH=${ARCH}
5 else
6 OUTPUT_ARCH=${ARCH}:${MACHINE}
7 fi
8 rm -f e${EMULATION_NAME}.c
9 (echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
10 cat >>e${EMULATION_NAME}.c <<EOF
11 /* This file is part of GLD, the Gnu Linker.
12 Copyright 1995, 1996, 1997, 1998, 1999, 2000
13 Free Software Foundation, Inc.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "ldgram.h"
44 #include "ldexp.h"
45 #include "ldlang.h"
46 #include "ldfile.h"
47 #include "ldemul.h"
48 #include "ldlex.h"
49 #include "ldmisc.h"
50 #include "ldctor.h"
51 #include "coff/internal.h"
52
53 /* FIXME: This is a BFD internal header file, and we should not be
54 using it here. */
55 #include "../bfd/libcoff.h"
56
57 #include "deffile.h"
58 #include "pe-dll.h"
59
60 #include <ctype.h>
61
62 #define TARGET_IS_${EMULATION_NAME}
63
64 /* Permit the emulation parameters to override the default section
65 alignment by setting OVERRIDE_SECTION_ALIGNMENT. FIXME: This makes
66 it seem that include/coff/internal.h should not define
67 PE_DEF_SECTION_ALIGNMENT. */
68 #if PE_DEF_SECTION_ALIGNMENT != ${OVERRIDE_SECTION_ALIGNMENT:-PE_DEF_SECTION_ALIGNMENT}
69 #undef PE_DEF_SECTION_ALIGNMENT
70 #define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT}
71 #endif
72
73 #if defined(TARGET_IS_i386pe)
74 #define DLL_SUPPORT
75 #endif
76 #if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe) || defined(TARGET_IS_armpe)
77 #define DLL_SUPPORT
78 #endif
79
80 #if defined(TARGET_IS_i386pe) || ! defined(DLL_SUPPORT)
81 #define PE_DEF_SUBSYSTEM 3
82 #else
83 #undef NT_EXE_IMAGE_BASE
84 #undef PE_DEF_SECTION_ALIGNMENT
85 #undef PE_DEF_FILE_ALIGNMENT
86 #define NT_EXE_IMAGE_BASE 0x00010000
87 #ifdef TARGET_IS_armpe
88 #define PE_DEF_SECTION_ALIGNMENT 0x00001000
89 #define PE_DEF_SUBSYSTEM 9
90 #else
91 #define PE_DEF_SECTION_ALIGNMENT 0x00000400
92 #define PE_DEF_SUBSYSTEM 2
93 #endif
94 #define PE_DEF_FILE_ALIGNMENT 0x00000200
95 #endif
96
97 #ifdef TARGET_IS_arm_epoc_pe
98 #define bfd_arm_pe_allocate_interworking_sections \
99 bfd_arm_epoc_pe_allocate_interworking_sections
100 #define bfd_arm_pe_get_bfd_for_interworking \
101 bfd_arm_epoc_pe_get_bfd_for_interworking
102 #define bfd_arm_pe_process_before_allocation \
103 bfd_arm_epoc_pe_process_before_allocation
104 #endif
105
106 static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
107 static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
108 static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
109 static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
110 static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
111 static boolean gld_${EMULATION_NAME}_place_orphan
112 PARAMS ((lang_input_statement_type *, asection *));
113 static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
114 static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
115 static void gld_${EMULATION_NAME}_finish PARAMS ((void));
116 static boolean gld_${EMULATION_NAME}_open_dynamic_archive
117 PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
118
119 static struct internal_extra_pe_aouthdr pe;
120 static int dll;
121 static int support_old_code = 0;
122 static char * thumb_entry_symbol = NULL;
123 static lang_assignment_statement_type *image_base_statement = 0;
124
125 #ifdef DLL_SUPPORT
126 static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */
127 static char *pe_out_def_filename = NULL;
128 static char *pe_implib_filename = NULL;
129 static int pe_enable_auto_image_base = 0;
130 static char *pe_dll_search_prefix = NULL;
131 #endif
132
133 extern const char *output_filename;
134
135 static void
136 gld_${EMULATION_NAME}_before_parse()
137 {
138 const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}");
139 if (arch)
140 {
141 ldfile_output_architecture = arch->arch;
142 ldfile_output_machine = arch->mach;
143 ldfile_output_machine_name = arch->printable_name;
144 }
145 else
146 ldfile_output_architecture = bfd_arch_${ARCH};
147 output_filename = "${EXECUTABLE_NAME:-a.exe}";
148 #ifdef DLL_SUPPORT
149 config.dynamic_link = true;
150 config.has_shared = 1;
151 /* link_info.pei386_auto_import = true; */
152
153 #if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
154 #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
155 lang_add_entry ("WinMainCRTStartup", 1);
156 #else
157 lang_add_entry ("_WinMainCRTStartup", 1);
158 #endif
159 #endif
160 #endif
161 }
162 \f
163 /* PE format extra command line options. */
164
165 /* Used for setting flags in the PE header. */
166 #define OPTION_BASE_FILE (300 + 1)
167 #define OPTION_DLL (OPTION_BASE_FILE + 1)
168 #define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
169 #define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
170 #define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
171 #define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
172 #define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
173 #define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
174 #define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
175 #define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
176 #define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
177 #define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
178 #define OPTION_SUBSYSTEM (OPTION_STACK + 1)
179 #define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
180 #define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1)
181 #define OPTION_OUT_DEF (OPTION_SUPPORT_OLD_CODE + 1)
182 #define OPTION_EXPORT_ALL (OPTION_OUT_DEF + 1)
183 #define OPTION_EXCLUDE_SYMBOLS (OPTION_EXPORT_ALL + 1)
184 #define OPTION_KILL_ATS (OPTION_EXCLUDE_SYMBOLS + 1)
185 #define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1)
186 #define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1)
187 #define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1)
188 #define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1)
189 #define OPTION_THUMB_ENTRY (OPTION_IMPLIB_FILENAME + 1)
190 #define OPTION_WARN_DUPLICATE_EXPORTS (OPTION_THUMB_ENTRY + 1)
191 #define OPTION_IMP_COMPAT (OPTION_WARN_DUPLICATE_EXPORTS + 1)
192 #define OPTION_ENABLE_AUTO_IMAGE_BASE (OPTION_IMP_COMPAT + 1)
193 #define OPTION_DISABLE_AUTO_IMAGE_BASE (OPTION_ENABLE_AUTO_IMAGE_BASE + 1)
194 #define OPTION_DLL_SEARCH_PREFIX (OPTION_DISABLE_AUTO_IMAGE_BASE + 1)
195 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_DLL_SEARCH_PREFIX + 1)
196 #define OPTION_DLL_ENABLE_AUTO_IMPORT (OPTION_NO_DEFAULT_EXCLUDES + 1)
197 #define OPTION_DLL_DISABLE_AUTO_IMPORT (OPTION_DLL_ENABLE_AUTO_IMPORT + 1)
198 #define OPTION_ENABLE_EXTRA_PE_DEBUG (OPTION_DLL_DISABLE_AUTO_IMPORT + 1)
199
200 static struct option longopts[] = {
201 /* PE options */
202 {"base-file", required_argument, NULL, OPTION_BASE_FILE},
203 {"dll", no_argument, NULL, OPTION_DLL},
204 {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
205 {"heap", required_argument, NULL, OPTION_HEAP},
206 {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
207 {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
208 {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
209 {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
210 {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
211 {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
212 {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
213 {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
214 {"stack", required_argument, NULL, OPTION_STACK},
215 {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
216 {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
217 {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
218 #ifdef DLL_SUPPORT
219 /* getopt allows abbreviations, so we do this to stop it from treating -o
220 as an abbreviation for this option */
221 {"output-def", required_argument, NULL, OPTION_OUT_DEF},
222 {"output-def", required_argument, NULL, OPTION_OUT_DEF},
223 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
224 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
225 {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
226 {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
227 {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
228 {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
229 {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
230 {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS},
231 {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
232 {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE},
233 {"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE},
234 {"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX},
235 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
236 {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT},
237 {"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT},
238 {"enable-extra-pe-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
239 #endif
240 {NULL, no_argument, NULL, 0}
241 };
242
243
244 /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
245 parameters which may be input from the command line */
246
247 typedef struct
248 {
249 void *ptr;
250 int size;
251 int value;
252 char *symbol;
253 int inited;
254 } definfo;
255
256 #define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
257
258 static definfo init[] =
259 {
260 /* imagebase must be first */
261 #define IMAGEBASEOFF 0
262 D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
263 #define DLLOFF 1
264 {&dll, sizeof(dll), 0, "__dll__", 0},
265 D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
266 D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
267 D(MajorOperatingSystemVersion,"__major_os_version__", 4),
268 D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
269 D(MajorImageVersion,"__major_image_version__", 1),
270 D(MinorImageVersion,"__minor_image_version__", 0),
271 #ifdef TARGET_IS_armpe
272 D(MajorSubsystemVersion,"__major_subsystem_version__", 2),
273 #else
274 D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
275 #endif
276 D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
277 D(Subsystem,"__subsystem__", ${SUBSYSTEM}),
278 D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x200000),
279 D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
280 D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
281 D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
282 D(LoaderFlags,"__loader_flags__", 0x0),
283 { NULL, 0, 0, NULL, 0 }
284 };
285
286 static void
287 gld_${EMULATION_NAME}_list_options (file)
288 FILE * file;
289 {
290 fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n"));
291 fprintf (file, _(" --dll Set image base to the default for DLLs\n"));
292 fprintf (file, _(" --file-alignment <size> Set file alignment\n"));
293 fprintf (file, _(" --heap <size> Set initial size of the heap\n"));
294 fprintf (file, _(" --image-base <address> Set start address of the executable\n"));
295 fprintf (file, _(" --major-image-version <number> Set version number of the executable\n"));
296 fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n"));
297 fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n"));
298 fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n"));
299 fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n"));
300 fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"));
301 fprintf (file, _(" --section-alignment <size> Set section alignment\n"));
302 fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
303 fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
304 fprintf (file, _(" --support-old-code Support interworking with old code\n"));
305 fprintf (file, _(" --thumb-entry=<symbol> Set the entry point to be Thumb <symbol>\n"));
306 #ifdef DLL_SUPPORT
307 fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
308 fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
309 fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
310 fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"));
311 fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n"));
312 fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
313 fprintf (file, _(" --out-implib <file> Generate import library\n"));
314 fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
315 fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n"));
316 fprintf (file, _(" --compat-implib Create backward compatible import libs;\n"));
317 fprintf (file, _(" create __imp_<SYMBOL> as well.\n"));
318 fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n"));
319 fprintf (file, _(" unless user specifies one\n"));
320 fprintf (file, _(" --disable-auto-image-base Do not auto-choose image base. (default)\n"));
321 fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll witout an\n"));
322 fprintf (file, _(" importlib, use <string><basename>.dll \n"));
323 fprintf (file, _(" in preference to lib<basename>.dll \n"));
324 fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to \n"));
325 fprintf (file, _(" __imp_sym for DATA references\n"));
326 fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n"));
327 fprintf (file, _(" --enable-extra-pe-debug Enable verbose debug output when building\n"));
328 fprintf (file, _(" or linking to DLLs (esp. auto-import)\n"));
329 #endif
330 }
331
332 static void
333 set_pe_name (name, val)
334 char *name;
335 long val;
336 {
337 int i;
338 /* Find the name and set it. */
339 for (i = 0; init[i].ptr; i++)
340 {
341 if (strcmp (name, init[i].symbol) == 0)
342 {
343 init[i].value = val;
344 init[i].inited = 1;
345 return;
346 }
347 }
348 abort();
349 }
350
351
352 static void
353 set_pe_subsystem ()
354 {
355 const char *sver;
356 int len;
357 int i;
358 static const struct
359 {
360 const char *name;
361 const int value;
362 const char *entry;
363 }
364 v[] =
365 {
366 { "native", 1, "NtProcessStartup" },
367 #if defined TARGET_IS_mipspe || defined TARGET_IS_armpe
368 { "windows", 2, "WinMainCRTStartup" },
369 #else
370 { "windows", 2, "WinMainCRTStartup" },
371 #endif
372 { "console", 3, "mainCRTStartup" },
373 #if 0
374 /* The Microsoft linker does not recognize this. */
375 { "os2", 5, "" },
376 #endif
377 { "posix", 7, "__PosixProcessStartup"},
378 { "wince", 9, "_WinMainCRTStartup" },
379 { 0, 0, 0 }
380 };
381
382 sver = strchr (optarg, ':');
383 if (sver == NULL)
384 len = strlen (optarg);
385 else
386 {
387 char *end;
388
389 len = sver - optarg;
390 set_pe_name ("__major_subsystem_version__",
391 strtoul (sver + 1, &end, 0));
392 if (*end == '.')
393 set_pe_name ("__minor_subsystem_version__",
394 strtoul (end + 1, &end, 0));
395 if (*end != '\0')
396 einfo (_("%P: warning: bad version number in -subsystem option\n"));
397 }
398
399 for (i = 0; v[i].name; i++)
400 {
401 if (strncmp (optarg, v[i].name, len) == 0
402 && v[i].name[len] == '\0')
403 {
404 const char *initial_symbol_char;
405 const char *entry;
406
407 set_pe_name ("__subsystem__", v[i].value);
408
409 initial_symbol_char = ${INITIAL_SYMBOL_CHAR};
410 if (*initial_symbol_char == '\0')
411 entry = v[i].entry;
412 else
413 {
414 char *alc_entry;
415
416 /* lang_add_entry expects its argument to be permanently
417 allocated, so we don't free this string. */
418 alc_entry = xmalloc (strlen (initial_symbol_char)
419 + strlen (v[i].entry)
420 + 1);
421 strcpy (alc_entry, initial_symbol_char);
422 strcat (alc_entry, v[i].entry);
423 entry = alc_entry;
424 }
425
426 lang_add_entry (entry, 1);
427
428 return;
429 }
430 }
431
432 einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
433 }
434
435
436
437 static void
438 set_pe_value (name)
439 char *name;
440
441 {
442 char *end;
443
444 set_pe_name (name, strtoul (optarg, &end, 0));
445
446 if (end == optarg)
447 einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
448
449 optarg = end;
450 }
451
452 static void
453 set_pe_stack_heap (resname, comname)
454 char *resname;
455 char *comname;
456 {
457 set_pe_value (resname);
458
459 if (*optarg == ',')
460 {
461 optarg++;
462 set_pe_value (comname);
463 }
464 else if (*optarg)
465 einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
466 }
467
468
469
470 static int
471 gld_${EMULATION_NAME}_parse_args(argc, argv)
472 int argc;
473 char **argv;
474 {
475 int longind;
476 int optc;
477 int prevoptind = optind;
478 int prevopterr = opterr;
479 int wanterror;
480 static int lastoptind = -1;
481
482 if (lastoptind != optind)
483 opterr = 0;
484 wanterror = opterr;
485
486 lastoptind = optind;
487
488 optc = getopt_long_only (argc, argv, "-", longopts, &longind);
489 opterr = prevopterr;
490
491 switch (optc)
492 {
493 default:
494 if (wanterror)
495 xexit (1);
496 optind = prevoptind;
497 return 0;
498
499 case OPTION_BASE_FILE:
500 link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
501 if (link_info.base_file == NULL)
502 {
503 /* xgettext:c-format */
504 fprintf (stderr, _("%s: Can't open base file %s\n"),
505 program_name, optarg);
506 xexit (1);
507 }
508 break;
509
510 /* PE options */
511 case OPTION_HEAP:
512 set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
513 break;
514 case OPTION_STACK:
515 set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
516 break;
517 case OPTION_SUBSYSTEM:
518 set_pe_subsystem ();
519 break;
520 case OPTION_MAJOR_OS_VERSION:
521 set_pe_value ("__major_os_version__");
522 break;
523 case OPTION_MINOR_OS_VERSION:
524 set_pe_value ("__minor_os_version__");
525 break;
526 case OPTION_MAJOR_SUBSYSTEM_VERSION:
527 set_pe_value ("__major_subsystem_version__");
528 break;
529 case OPTION_MINOR_SUBSYSTEM_VERSION:
530 set_pe_value ("__minor_subsystem_version__");
531 break;
532 case OPTION_MAJOR_IMAGE_VERSION:
533 set_pe_value ("__major_image_version__");
534 break;
535 case OPTION_MINOR_IMAGE_VERSION:
536 set_pe_value ("__minor_image_version__");
537 break;
538 case OPTION_FILE_ALIGNMENT:
539 set_pe_value ("__file_alignment__");
540 break;
541 case OPTION_SECTION_ALIGNMENT:
542 set_pe_value ("__section_alignment__");
543 break;
544 case OPTION_DLL:
545 set_pe_name ("__dll__", 1);
546 break;
547 case OPTION_IMAGE_BASE:
548 set_pe_value ("__image_base__");
549 break;
550 case OPTION_SUPPORT_OLD_CODE:
551 support_old_code = 1;
552 break;
553 case OPTION_THUMB_ENTRY:
554 thumb_entry_symbol = optarg;
555 break;
556 #ifdef DLL_SUPPORT
557 case OPTION_OUT_DEF:
558 pe_out_def_filename = xstrdup (optarg);
559 break;
560 case OPTION_EXPORT_ALL:
561 pe_dll_export_everything = 1;
562 break;
563 case OPTION_EXCLUDE_SYMBOLS:
564 pe_dll_add_excludes (optarg);
565 break;
566 case OPTION_KILL_ATS:
567 pe_dll_kill_ats = 1;
568 break;
569 case OPTION_STDCALL_ALIASES:
570 pe_dll_stdcall_aliases = 1;
571 break;
572 case OPTION_ENABLE_STDCALL_FIXUP:
573 pe_enable_stdcall_fixup = 1;
574 break;
575 case OPTION_DISABLE_STDCALL_FIXUP:
576 pe_enable_stdcall_fixup = 0;
577 break;
578 case OPTION_IMPLIB_FILENAME:
579 pe_implib_filename = xstrdup (optarg);
580 break;
581 case OPTION_WARN_DUPLICATE_EXPORTS:
582 pe_dll_warn_dup_exports = 1;
583 break;
584 case OPTION_IMP_COMPAT:
585 pe_dll_compat_implib = 1;
586 break;
587 case OPTION_ENABLE_AUTO_IMAGE_BASE:
588 pe_enable_auto_image_base = 1;
589 break;
590 case OPTION_DISABLE_AUTO_IMAGE_BASE:
591 pe_enable_auto_image_base = 0;
592 break;
593 case OPTION_DLL_SEARCH_PREFIX:
594 pe_dll_search_prefix = xstrdup( optarg );
595 break;
596 case OPTION_NO_DEFAULT_EXCLUDES:
597 pe_dll_do_default_excludes = 0;
598 break;
599 case OPTION_DLL_ENABLE_AUTO_IMPORT:
600 link_info.pei386_auto_import = true;
601 break;
602 case OPTION_DLL_DISABLE_AUTO_IMPORT:
603 link_info.pei386_auto_import = false;
604 break;
605 case OPTION_ENABLE_EXTRA_PE_DEBUG:
606 pe_dll_extra_pe_debug = 1;
607 break;
608 #endif
609 }
610 return 1;
611 }
612 \f
613
614 #ifdef DLL_SUPPORT
615 static unsigned long
616 strhash (const char *str)
617 {
618 const unsigned char *s;
619 unsigned long hash;
620 unsigned int c;
621 unsigned int len;
622
623 hash = 0;
624 len = 0;
625 s = (const unsigned char *) str;
626 while ((c = *s++) != '\0')
627 {
628 hash += c + (c << 17);
629 hash ^= hash >> 2;
630 ++len;
631 }
632 hash += len + (len << 17);
633 hash ^= hash >> 2;
634
635 return hash;
636 }
637
638 /* Use the output file to create a image base for relocatable DLLs. */
639 static unsigned long
640 compute_dll_image_base (const char *ofile)
641 {
642 unsigned long hash = strhash (ofile);
643 return 0x60000000 | ((hash << 16) & 0x0FFC0000);
644 }
645 #endif
646
647 /* Assign values to the special symbols before the linker script is
648 read. */
649
650 static void
651 gld_${EMULATION_NAME}_set_symbols ()
652 {
653 /* Run through and invent symbols for all the
654 names and insert the defaults. */
655 int j;
656 lang_statement_list_type *save;
657
658 if (!init[IMAGEBASEOFF].inited)
659 {
660 if (link_info.relocateable)
661 init[IMAGEBASEOFF].value = 0;
662 else if (init[DLLOFF].value || link_info.shared)
663 #ifdef DLL_SUPPORT
664 init[IMAGEBASEOFF].value = (pe_enable_auto_image_base) ?
665 compute_dll_image_base (output_filename) : NT_DLL_IMAGE_BASE;
666 #else
667 init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
668 #endif
669 else
670 init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
671 }
672
673 /* Don't do any symbol assignments if this is a relocateable link. */
674 if (link_info.relocateable)
675 return;
676
677 /* Glue the assignments into the abs section */
678 save = stat_ptr;
679
680 stat_ptr = &(abs_output_section->children);
681
682 for (j = 0; init[j].ptr; j++)
683 {
684 long val = init[j].value;
685 lang_assignment_statement_type *rv;
686 rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
687 if (init[j].size == sizeof(short))
688 *(short *)init[j].ptr = val;
689 else if (init[j].size == sizeof(int))
690 *(int *)init[j].ptr = val;
691 else if (init[j].size == sizeof(long))
692 *(long *)init[j].ptr = val;
693 /* This might be a long long or other special type. */
694 else if (init[j].size == sizeof(bfd_vma))
695 *(bfd_vma *)init[j].ptr = val;
696 else abort();
697 if (j == IMAGEBASEOFF)
698 image_base_statement = rv;
699 }
700 /* Restore the pointer. */
701 stat_ptr = save;
702
703 if (pe.FileAlignment >
704 pe.SectionAlignment)
705 {
706 einfo (_("%P: warning, file alignment > section alignment.\n"));
707 }
708 }
709
710 /* This is called after the linker script and the command line options
711 have been read. */
712
713 static void
714 gld_${EMULATION_NAME}_after_parse ()
715 {
716 /* The Windows libraries are designed for the linker to treat the
717 entry point as an undefined symbol. Otherwise, the .obj that
718 defines mainCRTStartup is brought in because it is the first
719 encountered in libc.lib and it has other symbols in it which will
720 be pulled in by the link process. To avoid this, we act as
721 though the user specified -u with the entry point symbol.
722
723 This function is called after the linker script and command line
724 options have been read, so at this point we know the right entry
725 point. This function is called before the input files are
726 opened, so registering the symbol as undefined will make a
727 difference. */
728
729 if (! link_info.relocateable && entry_symbol != NULL)
730 ldlang_add_undef (entry_symbol);
731 }
732
733 #ifdef DLL_SUPPORT
734 static struct bfd_link_hash_entry *pe_undef_found_sym;
735
736 static boolean
737 pe_undef_cdecl_match (h, string)
738 struct bfd_link_hash_entry *h;
739 PTR string;
740 {
741 int sl;
742 sl = strlen (string); /* silence compiler warning */
743 if (h->type == bfd_link_hash_defined
744 && strncmp (h->root.string, string, sl) == 0
745 && h->root.string[sl] == '@')
746 {
747 pe_undef_found_sym = h;
748 return false;
749 }
750 return true;
751 }
752
753 static void
754 pe_fixup_stdcalls ()
755 {
756 static int gave_warning_message = 0;
757 struct bfd_link_hash_entry *undef, *sym;
758 char *at;
759 if (pe_dll_extra_pe_debug)
760 {
761 printf ("%s\n", __FUNCTION__);
762 }
763
764 for (undef = link_info.hash->undefs; undef; undef=undef->next)
765 if (undef->type == bfd_link_hash_undefined)
766 {
767 at = strchr (undef->root.string, '@');
768 if (at)
769 {
770 /* The symbol is a stdcall symbol, so let's look for a cdecl
771 symbol with the same name and resolve to that */
772 char *cname = xstrdup (undef->root.string);
773 at = strchr (cname, '@');
774 *at = 0;
775 sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1);
776 if (sym && sym->type == bfd_link_hash_defined)
777 {
778 undef->type = bfd_link_hash_defined;
779 undef->u.def.value = sym->u.def.value;
780 undef->u.def.section = sym->u.def.section;
781 if (pe_enable_stdcall_fixup == -1)
782 {
783 einfo (_("Warning: resolving %s by linking to %s\n"),
784 undef->root.string, cname);
785 if (! gave_warning_message)
786 {
787 gave_warning_message = 1;
788 einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
789 einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
790 }
791 }
792 }
793 }
794 else
795 {
796 /* The symbol is a cdecl symbol, so we look for stdcall
797 symbols - which means scanning the whole symbol table */
798 pe_undef_found_sym = 0;
799 bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match,
800 (PTR) undef->root.string);
801 sym = pe_undef_found_sym;
802 if (sym)
803 {
804 undef->type = bfd_link_hash_defined;
805 undef->u.def.value = sym->u.def.value;
806 undef->u.def.section = sym->u.def.section;
807 if (pe_enable_stdcall_fixup == -1)
808 {
809 einfo (_("Warning: resolving %s by linking to %s\n"),
810 undef->root.string, sym->root.string);
811 if (! gave_warning_message)
812 {
813 gave_warning_message = 1;
814 einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
815 einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
816 }
817 }
818 }
819 }
820 }
821 }
822
823 static int
824 make_import_fixup (rel)
825 arelent *rel;
826 {
827 struct symbol_cache_entry *sym = *rel->sym_ptr_ptr;
828 /*
829 bfd *b;
830 */
831
832 if (pe_dll_extra_pe_debug)
833 {
834 printf ("arelent: %s@%#x: add=%li\n", sym->name,
835 (int) rel->address, rel->addend);
836 }
837 pe_create_import_fixup (rel);
838 return 1;
839 }
840
841 char *pe_data_import_dll;
842
843 static void
844 pe_find_data_imports ()
845 {
846 struct bfd_link_hash_entry *undef, *sym;
847 for (undef = link_info.hash->undefs; undef; undef=undef->next)
848 {
849 if (undef->type == bfd_link_hash_undefined)
850 {
851 /* C++ symbols are *long* */
852 char buf[4096];
853 if (pe_dll_extra_pe_debug)
854 {
855 printf ("%s:%s\n", __FUNCTION__, undef->root.string);
856 }
857 sprintf (buf, "__imp_%s", undef->root.string);
858
859 sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
860 if (sym && sym->type == bfd_link_hash_defined)
861 {
862 einfo (_("Warning: resolving %s by linking to %s (auto-import)\n"),
863 undef->root.string, buf);
864 {
865 bfd *b = sym->u.def.section->owner;
866 asymbol **symbols;
867 int nsyms, symsize, i;
868
869 symsize = bfd_get_symtab_upper_bound (b);
870 symbols = (asymbol **) xmalloc (symsize);
871 nsyms = bfd_canonicalize_symtab (b, symbols);
872
873 for (i = 0; i < nsyms; i++)
874 {
875 if (memcmp(symbols[i]->name, "__head_",
876 sizeof ("__head_") - 1))
877 continue;
878 if (pe_dll_extra_pe_debug)
879 {
880 printf ("->%s\n", symbols[i]->name);
881 }
882 pe_data_import_dll = (char*) (symbols[i]->name +
883 sizeof ("__head_") - 1);
884 break;
885 }
886 }
887
888 pe_walk_relocs_of_symbol (&link_info, undef->root.string,
889 make_import_fixup);
890
891 /* let's differentiate it somehow from defined */
892 undef->type = bfd_link_hash_defweak;
893 /* we replace original name with __imp_ prefixed, this
894 1) may trash memory 2) leads to duplicate symbol generation.
895 Still, IMHO it's better than having name poluted. */
896 undef->root.string = sym->root.string;
897 undef->u.def.value = sym->u.def.value;
898 undef->u.def.section = sym->u.def.section;
899 }
900 }
901 }
902 }
903 #endif /* DLL_SUPPORT */
904
905 static boolean
906 pr_sym (h, string)
907 struct bfd_hash_entry *h;
908 PTR string;
909 {
910 if (pe_dll_extra_pe_debug)
911 {
912 printf("+%s\n",h->string);
913 }
914 return true;
915 }
916
917
918 static void
919 gld_${EMULATION_NAME}_after_open ()
920 {
921
922 if (pe_dll_extra_pe_debug)
923 {
924 bfd *a;
925 struct bfd_link_hash_entry *sym;
926 printf ("%s()\n", __FUNCTION__);
927
928 for (sym = link_info.hash->undefs; sym; sym=sym->next)
929 printf ("-%s\n", sym->root.string);
930 bfd_hash_traverse (&link_info.hash->table, pr_sym,NULL);
931
932 for (a = link_info.input_bfds; a; a = a->link_next)
933 {
934 printf("*%s\n",a->filename);
935 }
936 }
937
938 /* Pass the wacky PE command line options into the output bfd.
939 FIXME: This should be done via a function, rather than by
940 including an internal BFD header. */
941
942 if (coff_data (output_bfd) == NULL || coff_data (output_bfd)->pe == NULL)
943 einfo (_("%F%P: PE operations on non PE file.\n"));
944
945 pe_data (output_bfd)->pe_opthdr = pe;
946 pe_data (output_bfd)->dll = init[DLLOFF].value;
947
948 #ifdef DLL_SUPPORT
949 if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */
950 pe_fixup_stdcalls ();
951
952 pe_find_data_imports (output_bfd, &link_info);
953
954 pe_process_import_defs(output_bfd, &link_info);
955 if (link_info.shared)
956 pe_dll_build_sections (output_bfd, &link_info);
957
958 #ifndef TARGET_IS_i386pe
959 #ifndef TARGET_IS_armpe
960 else
961 pe_exe_build_sections (output_bfd, &link_info);
962 #endif
963 #endif
964 #endif
965
966 #if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)
967 if (strstr (bfd_get_target (output_bfd), "arm") == NULL)
968 {
969 /* The arm backend needs special fields in the output hash structure.
970 These will only be created if the output format is an arm format,
971 hence we do not support linking and changing output formats at the
972 same time. Use a link followed by objcopy to change output formats. */
973 einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");
974 return;
975 }
976 {
977 /* Find a BFD that can hold the interworking stubs. */
978 LANG_FOR_EACH_INPUT_STATEMENT (is)
979 {
980 if (bfd_arm_pe_get_bfd_for_interworking (is->the_bfd, & link_info))
981 break;
982 }
983 }
984 #endif
985
986 {
987 /* This next chunk of code tries to detect the case where you have
988 two import libraries for the same DLL (specifically,
989 symbolically linking libm.a and libc.a in cygwin to
990 libcygwin.a). In those cases, it's possible for function
991 thunks from the second implib to be used but without the
992 head/tail objects, causing an improper import table. We detect
993 those cases and rename the "other" import libraries to match
994 the one the head/tail come from, so that the linker will sort
995 things nicely and produce a valid import table. */
996
997 LANG_FOR_EACH_INPUT_STATEMENT (is)
998 {
999 if (is->the_bfd->my_archive)
1000 {
1001 int idata2 = 0, reloc_count=0, is_imp = 0;
1002 asection *sec;
1003
1004 /* See if this is an import library thunk. */
1005 for (sec = is->the_bfd->sections; sec; sec = sec->next)
1006 {
1007 if (strcmp (sec->name, ".idata\$2") == 0)
1008 idata2 = 1;
1009 if (strncmp (sec->name, ".idata\$", 7) == 0)
1010 is_imp = 1;
1011 reloc_count += sec->reloc_count;
1012 }
1013
1014 if (is_imp && !idata2 && reloc_count)
1015 {
1016 /* It is, look for the reference to head and see if it's
1017 from our own library. */
1018 for (sec = is->the_bfd->sections; sec; sec = sec->next)
1019 {
1020 int i;
1021 long symsize;
1022 long relsize;
1023 asymbol **symbols;
1024 arelent **relocs;
1025 int nrelocs;
1026
1027 symsize = bfd_get_symtab_upper_bound (is->the_bfd);
1028 if (symsize < 1)
1029 break;
1030 relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
1031 if (relsize < 1)
1032 break;
1033
1034 symbols = (asymbol **) xmalloc (symsize);
1035 symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
1036 if (symsize < 0)
1037 {
1038 einfo ("%X%P: unable to process symbols: %E");
1039 return;
1040 }
1041
1042 relocs = (arelent **) xmalloc ((size_t) relsize);
1043 nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
1044 relocs, symbols);
1045 if (nrelocs < 0)
1046 {
1047 free (relocs);
1048 einfo ("%X%P: unable to process relocs: %E");
1049 return;
1050 }
1051
1052 for (i = 0; i < nrelocs; i++)
1053 {
1054 struct symbol_cache_entry *s;
1055 struct bfd_link_hash_entry * blhe;
1056 bfd *other_bfd;
1057 char *n;
1058
1059 s = (relocs[i]->sym_ptr_ptr)[0];
1060
1061 if (s->flags & BSF_LOCAL)
1062 continue;
1063
1064 /* Thunk section with reloc to another bfd. */
1065 blhe = bfd_link_hash_lookup (link_info.hash,
1066 s->name,
1067 false, false, true);
1068
1069 if (blhe == NULL
1070 || blhe->type != bfd_link_hash_defined)
1071 continue;
1072
1073 other_bfd = blhe->u.def.section->owner;
1074
1075 if (strcmp (is->the_bfd->my_archive->filename,
1076 other_bfd->my_archive->filename) == 0)
1077 continue;
1078
1079 /* Rename this implib to match the other. */
1080 n = (char *) xmalloc (strlen (other_bfd->my_archive->filename) + 1);
1081
1082 strcpy (n, other_bfd->my_archive->filename);
1083
1084 is->the_bfd->my_archive->filename = n;
1085 }
1086
1087 free (relocs);
1088 /* Note - we do not free the symbols,
1089 they are now cached in the BFD. */
1090 }
1091 }
1092 }
1093 }
1094 }
1095
1096 {
1097 int is_ms_arch = 0;
1098 bfd *cur_arch = 0;
1099 lang_input_statement_type *is2;
1100
1101 /* Careful - this is a shell script. Watch those dollar signs! */
1102 /* Microsoft import libraries have every member named the same,
1103 and not in the right order for us to link them correctly. We
1104 must detect these and rename the members so that they'll link
1105 correctly. There are three types of objects: the head, the
1106 thunks, and the sentinel(s). The head is easy; it's the one
1107 with idata2. We assume that the sentinels won't have relocs,
1108 and the thunks will. It's easier than checking the symbol
1109 table for external references. */
1110 LANG_FOR_EACH_INPUT_STATEMENT (is)
1111 {
1112 if (is->the_bfd->my_archive)
1113 {
1114 bfd *arch = is->the_bfd->my_archive;
1115 if (cur_arch != arch)
1116 {
1117 cur_arch = arch;
1118 is_ms_arch = 1;
1119 for (is2 = is;
1120 is2 && is2->the_bfd->my_archive == arch;
1121 is2 = (lang_input_statement_type *)is2->next)
1122 {
1123 if (strcmp (is->the_bfd->filename, is2->the_bfd->filename))
1124 is_ms_arch = 0;
1125 }
1126 }
1127
1128 if (is_ms_arch)
1129 {
1130 int idata2 = 0, reloc_count=0;
1131 asection *sec;
1132 char *new_name, seq;
1133
1134 for (sec = is->the_bfd->sections; sec; sec = sec->next)
1135 {
1136 if (strcmp (sec->name, ".idata\$2") == 0)
1137 idata2 = 1;
1138 reloc_count += sec->reloc_count;
1139 }
1140
1141 if (idata2) /* .idata2 is the TOC */
1142 seq = 'a';
1143 else if (reloc_count > 0) /* thunks */
1144 seq = 'b';
1145 else /* sentinel */
1146 seq = 'c';
1147
1148 new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
1149 sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
1150 is->the_bfd->filename = new_name;
1151
1152 new_name = xmalloc (strlen (is->filename) + 3);
1153 sprintf (new_name, "%s.%c", is->filename, seq);
1154 is->filename = new_name;
1155 }
1156 }
1157 }
1158 }
1159 }
1160 \f
1161 static void
1162 gld_${EMULATION_NAME}_before_allocation()
1163 {
1164 #ifdef TARGET_IS_ppcpe
1165 /* Here we rummage through the found bfds to collect toc information */
1166 {
1167 LANG_FOR_EACH_INPUT_STATEMENT (is)
1168 {
1169 if (!ppc_process_before_allocation (is->the_bfd, &link_info))
1170 {
1171 /* xgettext:c-format */
1172 einfo (_("Errors encountered processing file %s\n"), is->filename);
1173 }
1174 }
1175 }
1176
1177 /* We have seen it all. Allocate it, and carry on */
1178 ppc_allocate_toc_section (&link_info);
1179 #endif /* TARGET_IS_ppcpe */
1180
1181 #if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)
1182 /* FIXME: we should be able to set the size of the interworking stub
1183 section.
1184
1185 Here we rummage through the found bfds to collect glue
1186 information. FIXME: should this be based on a command line
1187 option? krk@cygnus.com */
1188 {
1189 LANG_FOR_EACH_INPUT_STATEMENT (is)
1190 {
1191 if (! bfd_arm_pe_process_before_allocation
1192 (is->the_bfd, & link_info, support_old_code))
1193 {
1194 /* xgettext:c-format */
1195 einfo (_("Errors encountered processing file %s for interworking"),
1196 is->filename);
1197 }
1198 }
1199 }
1200
1201 /* We have seen it all. Allocate it, and carry on */
1202 bfd_arm_pe_allocate_interworking_sections (& link_info);
1203 #endif /* TARGET_IS_armpe */
1204 }
1205 \f
1206 #ifdef DLL_SUPPORT
1207 /* This is called when an input file isn't recognized as a BFD. We
1208 check here for .DEF files and pull them in automatically. */
1209
1210 static int
1211 saw_option(char *option)
1212 {
1213 int i;
1214 for (i=0; init[i].ptr; i++)
1215 if (strcmp (init[i].symbol, option) == 0)
1216 return init[i].inited;
1217 return 0;
1218 }
1219 #endif /* DLL_SUPPORT */
1220
1221 static boolean
1222 gld_${EMULATION_NAME}_unrecognized_file(entry)
1223 lang_input_statement_type *entry ATTRIBUTE_UNUSED;
1224 {
1225 #ifdef DLL_SUPPORT
1226 const char *ext = entry->filename + strlen (entry->filename) - 4;
1227
1228 if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
1229 {
1230 if (pe_def_file == 0)
1231 pe_def_file = def_file_empty ();
1232 def_file_parse (entry->filename, pe_def_file);
1233 if (pe_def_file)
1234 {
1235 int i, buflen=0, len;
1236 char *buf;
1237 for (i=0; i<pe_def_file->num_exports; i++)
1238 {
1239 len = strlen(pe_def_file->exports[i].internal_name);
1240 if (buflen < len+2)
1241 buflen = len+2;
1242 }
1243 buf = (char *) xmalloc (buflen);
1244 for (i=0; i<pe_def_file->num_exports; i++)
1245 {
1246 struct bfd_link_hash_entry *h;
1247 sprintf(buf, "_%s", pe_def_file->exports[i].internal_name);
1248
1249 h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true);
1250 if (h == (struct bfd_link_hash_entry *) NULL)
1251 einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
1252 if (h->type == bfd_link_hash_new)
1253 {
1254 h->type = bfd_link_hash_undefined;
1255 h->u.undef.abfd = NULL;
1256 bfd_link_add_undef (link_info.hash, h);
1257 }
1258 }
1259 free (buf);
1260
1261 /* def_file_print (stdout, pe_def_file); */
1262 if (pe_def_file->is_dll == 1)
1263 link_info.shared = 1;
1264
1265 if (pe_def_file->base_address != (bfd_vma)(-1))
1266 {
1267 pe.ImageBase =
1268 pe_data (output_bfd)->pe_opthdr.ImageBase =
1269 init[IMAGEBASEOFF].value = pe_def_file->base_address;
1270 init[IMAGEBASEOFF].inited = 1;
1271 if (image_base_statement)
1272 image_base_statement->exp =
1273 exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase));
1274 }
1275
1276 #if 0
1277 /* Not sure if these *should* be set */
1278 if (pe_def_file->version_major != -1)
1279 {
1280 pe.MajorImageVersion = pe_def_file->version_major;
1281 pe.MinorImageVersion = pe_def_file->version_minor;
1282 }
1283 #endif
1284 if (pe_def_file->stack_reserve != -1
1285 && ! saw_option ("__size_of_stack_reserve__"))
1286 {
1287 pe.SizeOfStackReserve = pe_def_file->stack_reserve;
1288 if (pe_def_file->stack_commit != -1)
1289 pe.SizeOfStackCommit = pe_def_file->stack_commit;
1290 }
1291 if (pe_def_file->heap_reserve != -1
1292 && ! saw_option ("__size_of_heap_reserve__"))
1293 {
1294 pe.SizeOfHeapReserve = pe_def_file->heap_reserve;
1295 if (pe_def_file->heap_commit != -1)
1296 pe.SizeOfHeapCommit = pe_def_file->heap_commit;
1297 }
1298 return true;
1299 }
1300 }
1301 #endif
1302 return false;
1303
1304 }
1305
1306 static boolean
1307 gld_${EMULATION_NAME}_recognized_file(entry)
1308 lang_input_statement_type *entry ATTRIBUTE_UNUSED;
1309 {
1310 #ifdef DLL_SUPPORT
1311 #ifdef TARGET_IS_i386pe
1312 pe_dll_id_target ("pei-i386");
1313 #endif
1314 #ifdef TARGET_IS_shpe
1315 pe_dll_id_target ("pei-shl");
1316 #endif
1317 #ifdef TARGET_IS_mipspe
1318 pe_dll_id_target ("pei-mips");
1319 #endif
1320 #ifdef TARGET_IS_armpe
1321 pe_dll_id_target ("pei-arm-little");
1322 #endif
1323 if (bfd_get_format (entry->the_bfd) == bfd_object)
1324 {
1325 const char *ext = entry->filename + strlen (entry->filename) - 4;
1326 if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0)
1327 return pe_implied_import_dll (entry->filename);
1328 }
1329 #endif
1330 return false;
1331 }
1332
1333 static void
1334 gld_${EMULATION_NAME}_finish ()
1335 {
1336 #if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)
1337 struct bfd_link_hash_entry * h;
1338
1339 if (thumb_entry_symbol != NULL)
1340 {
1341 h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true);
1342
1343 if (h != (struct bfd_link_hash_entry *) NULL
1344 && (h->type == bfd_link_hash_defined
1345 || h->type == bfd_link_hash_defweak)
1346 && h->u.def.section->output_section != NULL)
1347 {
1348 static char buffer[32];
1349 bfd_vma val;
1350
1351 /* Special procesing is required for a Thumb entry symbol. The
1352 bottom bit of its address must be set. */
1353 val = (h->u.def.value
1354 + bfd_get_section_vma (output_bfd,
1355 h->u.def.section->output_section)
1356 + h->u.def.section->output_offset);
1357
1358 val |= 1;
1359
1360 /* Now convert this value into a string and store it in entry_symbol
1361 where the lang_finish() function will pick it up. */
1362 buffer[0] = '0';
1363 buffer[1] = 'x';
1364
1365 sprintf_vma (buffer + 2, val);
1366
1367 if (entry_symbol != NULL && entry_from_cmdline)
1368 einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
1369 thumb_entry_symbol, entry_symbol);
1370 entry_symbol = buffer;
1371 }
1372 else
1373 einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
1374 }
1375 #endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) */
1376
1377 #ifdef DLL_SUPPORT
1378 if (link_info.shared)
1379 {
1380 pe_dll_fill_sections (output_bfd, &link_info);
1381 if (pe_implib_filename)
1382 pe_dll_generate_implib (pe_def_file, pe_implib_filename);
1383 }
1384 #if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe)
1385 /* ARM doesn't need relocs. */
1386 else
1387 {
1388 pe_exe_fill_sections (output_bfd, &link_info);
1389 }
1390 #endif
1391
1392 if (pe_out_def_filename)
1393 pe_dll_generate_def_file (pe_out_def_filename);
1394 #endif /* DLL_SUPPORT */
1395
1396 /* I don't know where .idata gets set as code, but it shouldn't be */
1397 {
1398 asection *asec = bfd_get_section_by_name (output_bfd, ".idata");
1399 if (asec)
1400 {
1401 asec->flags &= ~SEC_CODE;
1402 asec->flags |= SEC_DATA;
1403 }
1404 }
1405 }
1406
1407 \f
1408 /* Place an orphan section.
1409
1410 We use this to put sections in a reasonable place in the file, and
1411 to ensure that they are aligned as required.
1412
1413 We handle grouped sections here as well. A section named .foo$nn
1414 goes into the output section .foo. All grouped sections are sorted
1415 by name.
1416
1417 Grouped sections for the default sections are handled by the
1418 default linker script using wildcards, and are sorted by
1419 sort_sections. */
1420
1421 struct orphan_save
1422 {
1423 lang_output_section_statement_type *os;
1424 asection **section;
1425 lang_statement_union_type **stmt;
1426 };
1427
1428 /*ARGSUSED*/
1429 static boolean
1430 gld_${EMULATION_NAME}_place_orphan (file, s)
1431 lang_input_statement_type *file;
1432 asection *s;
1433 {
1434 const char *secname;
1435 char *hold_section_name;
1436 char *dollar = NULL;
1437 const char *ps = NULL;
1438 lang_output_section_statement_type *os;
1439 lang_statement_list_type add_child;
1440
1441 secname = bfd_get_section_name (s->owner, s);
1442
1443 /* Look through the script to see where to place this section. */
1444
1445 hold_section_name = xstrdup (secname);
1446 if (!link_info.relocateable)
1447 {
1448 dollar = strchr (hold_section_name, '$');
1449 if (dollar != NULL)
1450 *dollar = '\0';
1451 }
1452
1453 os = lang_output_section_find (hold_section_name);
1454
1455 lang_list_init (&add_child);
1456
1457 if (os != NULL
1458 && os->bfd_section != NULL
1459 && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
1460 {
1461 wild_doit (&add_child, s, os, file);
1462 }
1463 else
1464 {
1465 struct orphan_save *place;
1466 static struct orphan_save hold_text;
1467 static struct orphan_save hold_rdata;
1468 static struct orphan_save hold_data;
1469 static struct orphan_save hold_bss;
1470 char *outsecname;
1471 lang_statement_list_type *old;
1472 lang_statement_list_type add;
1473 etree_type *address;
1474
1475 /* Try to put the new output section in a reasonable place based
1476 on the section name and section flags. */
1477 #define HAVE_SECTION(hold, name) \
1478 (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
1479
1480 place = NULL;
1481 if ((s->flags & SEC_ALLOC) == 0)
1482 ;
1483 else if ((s->flags & SEC_HAS_CONTENTS) == 0
1484 && HAVE_SECTION (hold_bss, ".bss"))
1485 place = &hold_bss;
1486 else if ((s->flags & SEC_READONLY) == 0
1487 && HAVE_SECTION (hold_data, ".data"))
1488 place = &hold_data;
1489 else if ((s->flags & SEC_CODE) == 0
1490 && (s->flags & SEC_READONLY) != 0
1491 && HAVE_SECTION (hold_rdata, ".rdata"))
1492 place = &hold_rdata;
1493 else if ((s->flags & SEC_READONLY) != 0
1494 && HAVE_SECTION (hold_text, ".text"))
1495 place = &hold_text;
1496
1497 #undef HAVE_SECTION
1498
1499 /* Choose a unique name for the section. This will be needed if
1500 the same section name appears in the input file with
1501 different loadable or allocateable characteristics. */
1502 outsecname = xstrdup (hold_section_name);
1503 if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
1504 {
1505 unsigned int len;
1506 char *newname;
1507 unsigned int i;
1508
1509 len = strlen (outsecname);
1510 newname = xmalloc (len + 5);
1511 strcpy (newname, outsecname);
1512 i = 0;
1513 do
1514 {
1515 sprintf (newname + len, "%d", i);
1516 ++i;
1517 }
1518 while (bfd_get_section_by_name (output_bfd, newname) != NULL);
1519
1520 free (outsecname);
1521 outsecname = newname;
1522 }
1523
1524 /* Start building a list of statements for this section. */
1525 old = stat_ptr;
1526 stat_ptr = &add;
1527 lang_list_init (stat_ptr);
1528
1529 if (config.build_constructors)
1530 {
1531 /* If the name of the section is representable in C, then create
1532 symbols to mark the start and the end of the section. */
1533 for (ps = outsecname; *ps != '\0'; ps++)
1534 if (! isalnum ((unsigned char) *ps) && *ps != '_')
1535 break;
1536 if (*ps == '\0')
1537 {
1538 char *symname;
1539 etree_type *e_align;
1540
1541 symname = (char *) xmalloc (ps - outsecname + sizeof "___start_");
1542 sprintf (symname, "___start_%s", outsecname);
1543 e_align = exp_unop (ALIGN_K,
1544 exp_intop ((bfd_vma) 1 << s->alignment_power));
1545 lang_add_assignment (exp_assop ('=', symname, e_align));
1546 }
1547 }
1548
1549 if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
1550 address = exp_intop ((bfd_vma) 0);
1551 else
1552 {
1553 /* All sections in an executable must be aligned to a page
1554 boundary. */
1555 address = exp_unop (ALIGN_K,
1556 exp_nameop (NAME, "__section_alignment__"));
1557 }
1558
1559 os = lang_enter_output_section_statement (outsecname, address, 0,
1560 (bfd_vma) 0,
1561 (etree_type *) NULL,
1562 (etree_type *) NULL,
1563 (etree_type *) NULL);
1564
1565 wild_doit (&add_child, s, os, file);
1566
1567 lang_leave_output_section_statement
1568 ((bfd_vma) 0, "*default*",
1569 (struct lang_output_section_phdr_list *) NULL, "*default*");
1570
1571 if (config.build_constructors && *ps == '\0')
1572 {
1573 char *symname;
1574
1575 /* lang_leave_ouput_section_statement resets stat_ptr. Put
1576 stat_ptr back where we want it. */
1577 if (place != NULL)
1578 stat_ptr = &add;
1579
1580 symname = (char *) xmalloc (ps - outsecname + sizeof "___stop_");
1581 sprintf (symname, "___stop_%s", outsecname);
1582 lang_add_assignment (exp_assop ('=', symname,
1583 exp_nameop (NAME, ".")));
1584 }
1585
1586 stat_ptr = old;
1587
1588 if (place != NULL)
1589 {
1590 asection *snew, **pps;
1591
1592 snew = os->bfd_section;
1593 if (place->os->bfd_section != NULL || place->section != NULL)
1594 {
1595 /* Shuffle the section to make the output file look neater. */
1596 if (place->section == NULL)
1597 {
1598 #if 0
1599 /* Finding the end of the list is a little tricky. We
1600 make a wild stab at it by comparing section flags. */
1601 flagword first_flags = place->os->bfd_section->flags;
1602 for (pps = &place->os->bfd_section->next;
1603 *pps != NULL && (*pps)->flags == first_flags;
1604 pps = &(*pps)->next)
1605 ;
1606 place->section = pps;
1607 #else
1608 /* Put orphans after the first section on the list. */
1609 place->section = &place->os->bfd_section->next;
1610 #endif
1611 }
1612
1613 /* Unlink the section. */
1614 for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
1615 ;
1616 *pps = snew->next;
1617
1618 /* Now tack it on to the "place->os" section list. */
1619 snew->next = *place->section;
1620 *place->section = snew;
1621 }
1622 place->section = &snew->next; /* Save the end of this list. */
1623
1624 if (place->stmt == NULL)
1625 {
1626 /* Put the new statement list right at the head. */
1627 *add.tail = place->os->header.next;
1628 place->os->header.next = add.head;
1629 }
1630 else
1631 {
1632 /* Put it after the last orphan statement we added. */
1633 *add.tail = *place->stmt;
1634 *place->stmt = add.head;
1635 }
1636 place->stmt = add.tail; /* Save the end of this list. */
1637 }
1638 }
1639
1640 {
1641 lang_statement_union_type **pl = &os->children.head;
1642
1643 if (dollar != NULL)
1644 {
1645 boolean found_dollar;
1646
1647 /* The section name has a '$'. Sort it with the other '$'
1648 sections. */
1649
1650 found_dollar = false;
1651 for ( ; *pl != NULL; pl = &(*pl)->next)
1652 {
1653 lang_input_section_type *ls;
1654 const char *lname;
1655
1656 if ((*pl)->header.type != lang_input_section_enum)
1657 continue;
1658
1659 ls = &(*pl)->input_section;
1660
1661 lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
1662 if (strchr (lname, '$') == NULL)
1663 {
1664 if (found_dollar)
1665 break;
1666 }
1667 else
1668 {
1669 found_dollar = true;
1670 if (strcmp (secname, lname) < 0)
1671 break;
1672 }
1673 }
1674 }
1675
1676 if (add_child.head != NULL)
1677 {
1678 add_child.head->next = *pl;
1679 *pl = add_child.head;
1680 }
1681 }
1682
1683 free (hold_section_name);
1684
1685 return true;
1686 }
1687
1688 static boolean
1689 gld_${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
1690 const char * arch ATTRIBUTE_UNUSED;
1691 search_dirs_type * search;
1692 lang_input_statement_type * entry;
1693 {
1694 const char * filename;
1695 char * string;
1696
1697 if (! entry->is_archive)
1698 return false;
1699
1700 filename = entry->filename;
1701
1702 string = (char *) xmalloc (strlen (search->name)
1703 + strlen (filename)
1704 + sizeof "/lib.a.dll"
1705 #ifdef DLL_SUPPORT
1706 + (pe_dll_search_prefix ? strlen (pe_dll_search_prefix) : 0)
1707 #endif
1708 + 1);
1709
1710 /* Try "libfoo.dll.a" first (preferred explicit import library for dll's */
1711 sprintf (string, "%s/lib%s.dll.a", search->name, filename);
1712
1713 if (! ldfile_try_open_bfd (string, entry))
1714 {
1715 /* Try "foo.dll.a" next (alternate explicit import library for dll's */
1716 sprintf (string, "%s/%s.dll.a", search->name, filename);
1717 if (! ldfile_try_open_bfd (string, entry))
1718 {
1719 /*
1720 Try libfoo.a next. Normally, this would be interpreted as a static
1721 library, but it *could* be an import library. For backwards compatibility,
1722 libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search,
1723 or sometimes errors occur when building legacy packages.
1724
1725 Putting libfoo.a here means that in a failure case (i.e. the library
1726 -lfoo is not found) we will search for libfoo.a twice before
1727 giving up -- once here, and once when searching for a "static" lib.
1728 for a "static" lib.
1729 */
1730 /* Try "libfoo.a" (import lib, or static lib, but must
1731 take precedence over dll's) */
1732 sprintf (string, "%s/lib%s.a", search->name, filename);
1733 if (! ldfile_try_open_bfd (string, entry))
1734 {
1735 #ifdef DLL_SUPPORT
1736 if (pe_dll_search_prefix)
1737 {
1738 /* Try "<prefix>foo.dll" (preferred dll name, if specified) */
1739 sprintf (string, "%s/%s%s.dll", search->name, pe_dll_search_prefix, filename);
1740 if (! ldfile_try_open_bfd (string, entry))
1741 {
1742 /* Try "libfoo.dll" (default preferred dll name) */
1743 sprintf (string, "%s/lib%s.dll", search->name, filename);
1744 if (! ldfile_try_open_bfd (string, entry))
1745 {
1746 /* Finally, try "foo.dll" (alternate dll name) */
1747 sprintf (string, "%s/%s.dll", search->name, filename);
1748 if (! ldfile_try_open_bfd (string, entry))
1749 {
1750 free (string);
1751 return false;
1752 }
1753 }
1754 }
1755 }
1756 else /* pe_dll_search_prefix not specified */
1757 #endif
1758 {
1759 /* Try "libfoo.dll" (preferred dll name) */
1760 sprintf (string, "%s/lib%s.dll", search->name, filename);
1761 if (! ldfile_try_open_bfd (string, entry))
1762 {
1763 /* Finally, try "foo.dll" (alternate dll name) */
1764 sprintf (string, "%s/%s.dll", search->name, filename);
1765 if (! ldfile_try_open_bfd (string, entry))
1766 {
1767 free (string);
1768 return false;
1769 }
1770 }
1771 }
1772 }
1773 }
1774 }
1775
1776 entry->filename = string;
1777
1778 return true;
1779 }
1780
1781 static int
1782 gld_${EMULATION_NAME}_find_potential_libraries (name, entry)
1783 char * name;
1784 lang_input_statement_type * entry;
1785 {
1786 return ldfile_open_file_search (name, entry, "", ".lib");
1787 }
1788 \f
1789 static char *
1790 gld_${EMULATION_NAME}_get_script(isfile)
1791 int *isfile;
1792 EOF
1793 # Scripts compiled in.
1794 # sed commands to quote an ld script as a C string.
1795 sc="-f stringify.sed"
1796
1797 cat >>e${EMULATION_NAME}.c <<EOF
1798 {
1799 *isfile = 0;
1800
1801 if (link_info.relocateable == true && config.build_constructors == true)
1802 return
1803 EOF
1804 sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
1805 echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
1806 sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
1807 echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
1808 sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
1809 echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
1810 sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
1811 echo ' ; else return' >> e${EMULATION_NAME}.c
1812 sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
1813 echo '; }' >> e${EMULATION_NAME}.c
1814
1815 cat >>e${EMULATION_NAME}.c <<EOF
1816
1817
1818 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
1819 {
1820 gld_${EMULATION_NAME}_before_parse,
1821 syslib_default,
1822 hll_default,
1823 gld_${EMULATION_NAME}_after_parse,
1824 gld_${EMULATION_NAME}_after_open,
1825 after_allocation_default,
1826 set_output_arch_default,
1827 ldemul_default_target,
1828 gld_${EMULATION_NAME}_before_allocation,
1829 gld_${EMULATION_NAME}_get_script,
1830 "${EMULATION_NAME}",
1831 "${OUTPUT_FORMAT}",
1832 gld_${EMULATION_NAME}_finish, /* finish */
1833 NULL, /* create output section statements */
1834 gld_${EMULATION_NAME}_open_dynamic_archive,
1835 gld_${EMULATION_NAME}_place_orphan,
1836 gld_${EMULATION_NAME}_set_symbols,
1837 gld_${EMULATION_NAME}_parse_args,
1838 gld_${EMULATION_NAME}_unrecognized_file,
1839 gld_${EMULATION_NAME}_list_options,
1840 gld_${EMULATION_NAME}_recognized_file,
1841 gld_${EMULATION_NAME}_find_potential_libraries
1842 };
1843 EOF
This page took 0.108619 seconds and 5 git commands to generate.