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