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