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