1 1.1 christos /* dlltool.c -- tool to generate stuff for PE style DLLs 2 1.10 christos Copyright (C) 1995-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GNU Binutils. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos 22 1.1 christos /* This program allows you to build the files necessary to create 23 1.1 christos DLLs to run on a system which understands PE format image files. 24 1.1 christos (eg, Windows NT) 25 1.1 christos 26 1.1 christos See "Peering Inside the PE: A Tour of the Win32 Portable Executable 27 1.1 christos File Format", MSJ 1994, Volume 9 for more information. 28 1.1 christos Also see "Microsoft Portable Executable and Common Object File Format, 29 1.1 christos Specification 4.1" for more information. 30 1.1 christos 31 1.1 christos A DLL contains an export table which contains the information 32 1.1 christos which the runtime loader needs to tie up references from a 33 1.1 christos referencing program. 34 1.1 christos 35 1.1 christos The export table is generated by this program by reading 36 1.1 christos in a .DEF file or scanning the .a and .o files which will be in the 37 1.1 christos DLL. A .o file can contain information in special ".drectve" sections 38 1.1 christos with export information. 39 1.1 christos 40 1.1 christos A DEF file contains any number of the following commands: 41 1.1 christos 42 1.1 christos 43 1.1 christos NAME <name> [ , <base> ] 44 1.1 christos The result is going to be <name>.EXE 45 1.1 christos 46 1.1 christos LIBRARY <name> [ , <base> ] 47 1.1 christos The result is going to be <name>.DLL 48 1.1 christos 49 1.1 christos EXPORTS ( ( ( <name1> [ = <name2> ] ) 50 1.1 christos | ( <name1> = <module-name> . <external-name>)) 51 1.1 christos [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) * 52 1.1 christos Declares name1 as an exported symbol from the 53 1.1 christos DLL, with optional ordinal number <integer>. 54 1.1 christos Or declares name1 as an alias (forward) of the function <external-name> 55 1.1 christos in the DLL <module-name>. 56 1.1 christos 57 1.1 christos IMPORTS ( ( <internal-name> = <module-name> . <integer> ) 58 1.1 christos | ( [ <internal-name> = ] <module-name> . <external-name> )) * 59 1.1 christos Declares that <external-name> or the exported function whose ordinal number 60 1.1 christos is <integer> is to be imported from the file <module-name>. If 61 1.1 christos <internal-name> is specified then this is the name that the imported 62 1.1 christos function will be refereed to in the body of the DLL. 63 1.1 christos 64 1.1 christos DESCRIPTION <string> 65 1.1 christos Puts <string> into output .exp file in the .rdata section 66 1.1 christos 67 1.1 christos [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ] 68 1.1 christos Generates --stack|--heap <number-reserve>,<number-commit> 69 1.1 christos in the output .drectve section. The linker will 70 1.1 christos see this and act upon it. 71 1.1 christos 72 1.1 christos [CODE|DATA] <attr>+ 73 1.1 christos SECTIONS ( <sectionname> <attr>+ )* 74 1.1 christos <attr> = READ | WRITE | EXECUTE | SHARED 75 1.1 christos Generates --attr <sectionname> <attr> in the output 76 1.1 christos .drectve section. The linker will see this and act 77 1.1 christos upon it. 78 1.1 christos 79 1.1 christos 80 1.1 christos A -export:<name> in a .drectve section in an input .o or .a 81 1.1 christos file to this program is equivalent to a EXPORTS <name> 82 1.1 christos in a .DEF file. 83 1.1 christos 84 1.1 christos 85 1.1 christos 86 1.1 christos The program generates output files with the prefix supplied 87 1.1 christos on the command line, or in the def file, or taken from the first 88 1.1 christos supplied argument. 89 1.1 christos 90 1.1 christos The .exp.s file contains the information necessary to export 91 1.1 christos the routines in the DLL. The .lib.s file contains the information 92 1.1 christos necessary to use the DLL's routines from a referencing program. 93 1.1 christos 94 1.1 christos 95 1.1 christos 96 1.1 christos Example: 97 1.1 christos 98 1.1 christos file1.c: 99 1.1 christos asm (".section .drectve"); 100 1.1 christos asm (".ascii \"-export:adef\""); 101 1.1 christos 102 1.1 christos void adef (char * s) 103 1.1 christos { 104 1.1 christos printf ("hello from the dll %s\n", s); 105 1.1 christos } 106 1.1 christos 107 1.1 christos void bdef (char * s) 108 1.1 christos { 109 1.1 christos printf ("hello from the dll and the other entry point %s\n", s); 110 1.1 christos } 111 1.1 christos 112 1.1 christos file2.c: 113 1.1 christos asm (".section .drectve"); 114 1.1 christos asm (".ascii \"-export:cdef\""); 115 1.1 christos asm (".ascii \"-export:ddef\""); 116 1.1 christos 117 1.1 christos void cdef (char * s) 118 1.1 christos { 119 1.1 christos printf ("hello from the dll %s\n", s); 120 1.1 christos } 121 1.1 christos 122 1.1 christos void ddef (char * s) 123 1.1 christos { 124 1.1 christos printf ("hello from the dll and the other entry point %s\n", s); 125 1.1 christos } 126 1.1 christos 127 1.1 christos int printf (void) 128 1.1 christos { 129 1.1 christos return 9; 130 1.1 christos } 131 1.1 christos 132 1.1 christos themain.c: 133 1.1 christos int main (void) 134 1.1 christos { 135 1.1 christos cdef (); 136 1.1 christos return 0; 137 1.1 christos } 138 1.1 christos 139 1.1 christos thedll.def 140 1.1 christos 141 1.1 christos LIBRARY thedll 142 1.1 christos HEAPSIZE 0x40000, 0x2000 143 1.1 christos EXPORTS bdef @ 20 144 1.1 christos cdef @ 30 NONAME 145 1.1 christos 146 1.1 christos SECTIONS donkey READ WRITE 147 1.1 christos aardvark EXECUTE 148 1.1 christos 149 1.1 christos # Compile up the parts of the dll and the program 150 1.1 christos 151 1.1 christos gcc -c file1.c file2.c themain.c 152 1.1 christos 153 1.1 christos # Optional: put the dll objects into a library 154 1.1 christos # (you don't have to, you could name all the object 155 1.1 christos # files on the dlltool line) 156 1.1 christos 157 1.1 christos ar qcv thedll.in file1.o file2.o 158 1.1 christos ranlib thedll.in 159 1.1 christos 160 1.1 christos # Run this tool over the DLL's .def file and generate an exports 161 1.1 christos # file (thedll.o) and an imports file (thedll.a). 162 1.1 christos # (You may have to use -S to tell dlltool where to find the assembler). 163 1.1 christos 164 1.1 christos dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a 165 1.1 christos 166 1.1 christos # Build the dll with the library and the export table 167 1.1 christos 168 1.1 christos ld -o thedll.dll thedll.o thedll.in 169 1.1 christos 170 1.1 christos # Link the executable with the import library 171 1.1 christos 172 1.1 christos gcc -o themain.exe themain.o thedll.a 173 1.1 christos 174 1.1 christos This example can be extended if relocations are needed in the DLL: 175 1.1 christos 176 1.1 christos # Compile up the parts of the dll and the program 177 1.1 christos 178 1.1 christos gcc -c file1.c file2.c themain.c 179 1.1 christos 180 1.1 christos # Run this tool over the DLL's .def file and generate an imports file. 181 1.1 christos 182 1.1 christos dlltool --def thedll.def --output-lib thedll.lib 183 1.1 christos 184 1.1 christos # Link the executable with the import library and generate a base file 185 1.1 christos # at the same time 186 1.1 christos 187 1.1 christos gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base 188 1.1 christos 189 1.1 christos # Run this tool over the DLL's .def file and generate an exports file 190 1.1 christos # which includes the relocations from the base file. 191 1.1 christos 192 1.1 christos dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp 193 1.1 christos 194 1.1 christos # Build the dll with file1.o, file2.o and the export table 195 1.1 christos 196 1.1 christos ld -o thedll.dll thedll.exp file1.o file2.o */ 197 1.1 christos 198 1.1 christos /* .idata section description 199 1.1 christos 200 1.1 christos The .idata section is the import table. It is a collection of several 201 1.1 christos subsections used to keep the pieces for each dll together: .idata$[234567]. 202 1.1 christos IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc. 203 1.1 christos 204 1.1 christos .idata$2 = Import Directory Table 205 1.1 christos = array of IMAGE_IMPORT_DESCRIPTOR's. 206 1.1 christos 207 1.1 christos DWORD Import Lookup Table; - pointer to .idata$4 208 1.1 christos DWORD TimeDateStamp; - currently always 0 209 1.1 christos DWORD ForwarderChain; - currently always 0 210 1.1 christos DWORD Name; - pointer to dll's name 211 1.1 christos PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5 212 1.1 christos 213 1.1 christos .idata$3 = null terminating entry for .idata$2. 214 1.1 christos 215 1.1 christos .idata$4 = Import Lookup Table 216 1.10 christos = array of array of numbers, which has meaning based on its highest bit: 217 1.10 christos - when cleared - pointer to entry in Hint Name Table 218 1.10 christos - when set - 16-bit function's ordinal number (rest of the bits are zeros) 219 1.10 christos Function ordinal number subtracted by Export Directory Table's 220 1.10 christos Ordinal Base is an index entry into the Export Address Table. 221 1.1 christos There is one for each dll being imported from, and each dll's set is 222 1.1 christos terminated by a trailing NULL. 223 1.1 christos 224 1.1 christos .idata$5 = Import Address Table 225 1.1 christos There is one for each dll being imported from, and each dll's set is 226 1.1 christos terminated by a trailing NULL. 227 1.1 christos Initially, this table is identical to the Import Lookup Table. However, 228 1.1 christos at load time, the loader overwrites the entries with the address of the 229 1.1 christos function. 230 1.1 christos 231 1.1 christos .idata$6 = Hint Name Table 232 1.1 christos = Array of { short, asciz } entries, one for each imported function. 233 1.10 christos The `short' is the name hint - index into Export Name Pointer Table. 234 1.10 christos The `asciz` is the name string - value in Export Name Table referenced 235 1.10 christos by some entry in Export Name Pointer Table. Name hint should be the 236 1.10 christos index of that entry in Export Name Pointer Table. It has no connection 237 1.10 christos with the function's ordinal number. 238 1.1 christos 239 1.8 christos .idata$7 = dll name (eg: "kernel32.dll"). */ 240 1.1 christos 241 1.1 christos #include "sysdep.h" 242 1.1 christos #include "bfd.h" 243 1.1 christos #include "libiberty.h" 244 1.1 christos #include "getopt.h" 245 1.1 christos #include "demangle.h" 246 1.1 christos #include "dyn-string.h" 247 1.1 christos #include "bucomm.h" 248 1.1 christos #include "dlltool.h" 249 1.1 christos #include "safe-ctype.h" 250 1.7 christos #include "coff-bfd.h" 251 1.1 christos 252 1.1 christos #include <time.h> 253 1.1 christos #include <assert.h> 254 1.1 christos 255 1.1 christos #ifdef DLLTOOL_ARM 256 1.1 christos #include "coff/arm.h" 257 1.1 christos #include "coff/internal.h" 258 1.1 christos #endif 259 1.1 christos #ifdef DLLTOOL_DEFAULT_MX86_64 260 1.1 christos #include "coff/x86_64.h" 261 1.1 christos #endif 262 1.1 christos #ifdef DLLTOOL_DEFAULT_I386 263 1.1 christos #include "coff/i386.h" 264 1.1 christos #endif 265 1.1 christos 266 1.1 christos #ifndef COFF_PAGE_SIZE 267 1.1 christos #define COFF_PAGE_SIZE ((bfd_vma) 4096) 268 1.1 christos #endif 269 1.1 christos 270 1.1 christos #ifndef PAGE_MASK 271 1.1 christos #define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE)) 272 1.1 christos #endif 273 1.1 christos 274 1.10 christos #ifndef NAME_MAX 275 1.10 christos #define NAME_MAX 255 276 1.1 christos #endif 277 1.1 christos 278 1.1 christos #ifdef HAVE_SYS_WAIT_H 279 1.1 christos #include <sys/wait.h> 280 1.1 christos #else /* ! HAVE_SYS_WAIT_H */ 281 1.1 christos #if ! defined (_WIN32) || defined (__CYGWIN32__) 282 1.1 christos #ifndef WIFEXITED 283 1.1 christos #define WIFEXITED(w) (((w) & 0377) == 0) 284 1.1 christos #endif 285 1.1 christos #ifndef WIFSIGNALED 286 1.1 christos #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0) 287 1.1 christos #endif 288 1.1 christos #ifndef WTERMSIG 289 1.1 christos #define WTERMSIG(w) ((w) & 0177) 290 1.1 christos #endif 291 1.1 christos #ifndef WEXITSTATUS 292 1.1 christos #define WEXITSTATUS(w) (((w) >> 8) & 0377) 293 1.1 christos #endif 294 1.1 christos #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */ 295 1.1 christos #ifndef WIFEXITED 296 1.1 christos #define WIFEXITED(w) (((w) & 0xff) == 0) 297 1.1 christos #endif 298 1.1 christos #ifndef WIFSIGNALED 299 1.1 christos #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f) 300 1.1 christos #endif 301 1.1 christos #ifndef WTERMSIG 302 1.1 christos #define WTERMSIG(w) ((w) & 0x7f) 303 1.1 christos #endif 304 1.1 christos #ifndef WEXITSTATUS 305 1.1 christos #define WEXITSTATUS(w) (((w) & 0xff00) >> 8) 306 1.1 christos #endif 307 1.1 christos #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */ 308 1.1 christos #endif /* ! HAVE_SYS_WAIT_H */ 309 1.1 christos 310 1.1 christos #define show_allnames 0 311 1.1 christos 312 1.1 christos /* ifunc and ihead data structures: ttk (at) cygnus.com 1997 313 1.1 christos 314 1.1 christos When IMPORT declarations are encountered in a .def file the 315 1.1 christos function import information is stored in a structure referenced by 316 1.1 christos the global variable IMPORT_LIST. The structure is a linked list 317 1.1 christos containing the names of the dll files each function is imported 318 1.1 christos from and a linked list of functions being imported from that dll 319 1.1 christos file. This roughly parallels the structure of the .idata section 320 1.1 christos in the PE object file. 321 1.1 christos 322 1.1 christos The contents of .def file are interpreted from within the 323 1.1 christos process_def_file function. Every time an IMPORT declaration is 324 1.1 christos encountered, it is broken up into its component parts and passed to 325 1.1 christos def_import. IMPORT_LIST is initialized to NULL in function main. */ 326 1.1 christos 327 1.1 christos typedef struct ifunct 328 1.1 christos { 329 1.10 christos const char * name; /* Name of function being imported. */ 330 1.10 christos const char *its_name; /* Optional import table symbol name. */ 331 1.10 christos int ord; /* Two-byte ordinal value associated with function. */ 332 1.1 christos struct ifunct *next; 333 1.1 christos } ifunctype; 334 1.1 christos 335 1.1 christos typedef struct iheadt 336 1.1 christos { 337 1.10 christos const char * dllname; /* Name of dll file imported from. */ 338 1.10 christos long nfuncs; /* Number of functions in list. */ 339 1.1 christos struct ifunct *funchead; /* First function in list. */ 340 1.1 christos struct ifunct *functail; /* Last function in list. */ 341 1.1 christos struct iheadt *next; /* Next dll file in list. */ 342 1.1 christos } iheadtype; 343 1.1 christos 344 1.1 christos /* Structure containing all import information as defined in .def file 345 1.1 christos (qv "ihead structure"). */ 346 1.1 christos 347 1.1 christos static iheadtype *import_list = NULL; 348 1.1 christos static char *as_name = NULL; 349 1.1 christos static char * as_flags = ""; 350 1.8 christos static char *tmp_prefix = NULL; 351 1.1 christos static int no_idata4; 352 1.1 christos static int no_idata5; 353 1.1 christos static char *exp_name; 354 1.1 christos static char *imp_name; 355 1.1 christos static char *delayimp_name; 356 1.1 christos static char *identify_imp_name; 357 1.8 christos static bool identify_strict; 358 1.9 christos static bool deterministic = DEFAULT_AR_DETERMINISTIC; 359 1.1 christos 360 1.1 christos /* Types used to implement a linked list of dllnames associated 361 1.1 christos with the specified import lib. Used by the identify_* code. 362 1.1 christos The head entry is acts as a sentinal node and is always empty 363 1.1 christos (head->dllname is NULL). */ 364 1.1 christos typedef struct dll_name_list_node_t 365 1.1 christos { 366 1.10 christos char * dllname; 367 1.1 christos struct dll_name_list_node_t * next; 368 1.1 christos } dll_name_list_node_type; 369 1.1 christos 370 1.1 christos typedef struct dll_name_list_t 371 1.1 christos { 372 1.1 christos dll_name_list_node_type * head; 373 1.1 christos dll_name_list_node_type * tail; 374 1.3 christos } dll_name_list_type; 375 1.1 christos 376 1.1 christos /* Types used to pass data to iterator functions. */ 377 1.1 christos typedef struct symname_search_data_t 378 1.1 christos { 379 1.8 christos const char *symname; 380 1.8 christos bool found; 381 1.1 christos } symname_search_data_type; 382 1.1 christos 383 1.1 christos typedef struct identify_data_t 384 1.1 christos { 385 1.8 christos dll_name_list_type *list; 386 1.8 christos bool ms_style_implib; 387 1.3 christos } identify_data_type; 388 1.1 christos 389 1.1 christos 390 1.1 christos static char *head_label; 391 1.1 christos static char *imp_name_lab; 392 1.1 christos static char *dll_name; 393 1.1 christos static int dll_name_set_by_exp_name; 394 1.1 christos static int add_indirect = 0; 395 1.1 christos static int add_underscore = 0; 396 1.1 christos static int add_stdcall_underscore = 0; 397 1.10 christos static char *leading_underscore = NULL; 398 1.1 christos static int dontdeltemps = 0; 399 1.1 christos 400 1.1 christos /* TRUE if we should export all symbols. Otherwise, we only export 401 1.1 christos symbols listed in .drectve sections or in the def file. */ 402 1.8 christos static bool export_all_symbols; 403 1.1 christos 404 1.1 christos /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when 405 1.1 christos exporting all symbols. */ 406 1.8 christos static bool do_default_excludes = true; 407 1.1 christos 408 1.8 christos static bool use_nul_prefixed_import_tables = false; 409 1.1 christos 410 1.1 christos /* Default symbols to exclude when exporting all the symbols. */ 411 1.1 christos static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr"; 412 1.1 christos 413 1.1 christos /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward 414 1.1 christos compatibility to old Cygwin releases. */ 415 1.8 christos static bool create_compat_implib; 416 1.1 christos 417 1.1 christos /* TRUE if we have to write PE+ import libraries. */ 418 1.8 christos static bool create_for_pep; 419 1.1 christos 420 1.1 christos static char *def_file; 421 1.1 christos 422 1.1 christos extern char * program_name; 423 1.1 christos 424 1.1 christos static int machine; 425 1.1 christos static int killat; 426 1.1 christos static int add_stdcall_alias; 427 1.1 christos static const char *ext_prefix_alias; 428 1.1 christos static int verbose; 429 1.1 christos static FILE *output_def; 430 1.1 christos static FILE *base_file; 431 1.1 christos 432 1.1 christos #ifdef DLLTOOL_DEFAULT_ARM 433 1.1 christos static const char *mname = "arm"; 434 1.1 christos #endif 435 1.1 christos 436 1.1 christos #ifdef DLLTOOL_DEFAULT_ARM_WINCE 437 1.1 christos static const char *mname = "arm-wince"; 438 1.1 christos #endif 439 1.1 christos 440 1.9 christos #ifdef DLLTOOL_DEFAULT_AARCH64 441 1.9 christos /* arm64 rather than aarch64 to match llvm-dlltool */ 442 1.9 christos static const char *mname = "arm64"; 443 1.9 christos #endif 444 1.9 christos 445 1.1 christos #ifdef DLLTOOL_DEFAULT_I386 446 1.1 christos static const char *mname = "i386"; 447 1.1 christos #endif 448 1.1 christos 449 1.1 christos #ifdef DLLTOOL_DEFAULT_MX86_64 450 1.1 christos static const char *mname = "i386:x86-64"; 451 1.1 christos #endif 452 1.1 christos 453 1.1 christos #ifdef DLLTOOL_DEFAULT_SH 454 1.1 christos static const char *mname = "sh"; 455 1.1 christos #endif 456 1.1 christos 457 1.1 christos #ifdef DLLTOOL_DEFAULT_MIPS 458 1.1 christos static const char *mname = "mips"; 459 1.1 christos #endif 460 1.1 christos 461 1.1 christos #ifdef DLLTOOL_DEFAULT_MCORE 462 1.1 christos static const char * mname = "mcore-le"; 463 1.1 christos #endif 464 1.1 christos 465 1.1 christos #ifdef DLLTOOL_DEFAULT_MCORE_ELF 466 1.1 christos static const char * mname = "mcore-elf"; 467 1.1 christos static char * mcore_elf_out_file = NULL; 468 1.1 christos static char * mcore_elf_linker = NULL; 469 1.1 christos static char * mcore_elf_linker_flags = NULL; 470 1.1 christos 471 1.1 christos #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve") 472 1.1 christos #endif 473 1.1 christos 474 1.1 christos #ifndef DRECTVE_SECTION_NAME 475 1.1 christos #define DRECTVE_SECTION_NAME ".drectve" 476 1.1 christos #endif 477 1.1 christos 478 1.1 christos /* External name alias numbering starts here. */ 479 1.1 christos #define PREFIX_ALIAS_BASE 20000 480 1.1 christos 481 1.10 christos static char *tmp_asm_buf; 482 1.10 christos static char *tmp_head_s_buf; 483 1.10 christos static char *tmp_head_o_buf; 484 1.10 christos static char *tmp_tail_s_buf; 485 1.10 christos static char *tmp_tail_o_buf; 486 1.10 christos static char *tmp_stub_buf; 487 1.1 christos 488 1.1 christos #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s") 489 1.1 christos #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s") 490 1.1 christos #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o") 491 1.1 christos #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s") 492 1.1 christos #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o") 493 1.10 christos #define TMP_STUB dlltmp (&tmp_stub_buf, "%ssnnnnn.o") 494 1.1 christos 495 1.1 christos /* This bit of assembly does jmp * .... */ 496 1.1 christos static const unsigned char i386_jtab[] = 497 1.1 christos { 498 1.1 christos 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 499 1.1 christos }; 500 1.1 christos 501 1.1 christos static const unsigned char i386_dljtab[] = 502 1.1 christos { 503 1.10 christos 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */ 504 1.10 christos 0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */ 505 1.10 christos 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */ 506 1.1 christos }; 507 1.1 christos 508 1.1 christos static const unsigned char i386_x64_dljtab[] = 509 1.1 christos { 510 1.10 christos 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */ 511 1.10 christos 0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */ 512 1.10 christos 0x00, 0x00, 0x00, 0x00, 513 1.10 christos 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */ 514 1.1 christos }; 515 1.1 christos 516 1.1 christos static const unsigned char arm_jtab[] = 517 1.1 christos { 518 1.1 christos 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 519 1.1 christos 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */ 520 1.10 christos 0, 0, 0, 0 521 1.1 christos }; 522 1.1 christos 523 1.1 christos static const unsigned char arm_interwork_jtab[] = 524 1.1 christos { 525 1.10 christos 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 526 1.10 christos 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */ 527 1.10 christos 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */ 528 1.10 christos 0, 0, 0, 0 529 1.1 christos }; 530 1.1 christos 531 1.1 christos static const unsigned char thumb_jtab[] = 532 1.1 christos { 533 1.10 christos 0x40, 0xb4, /* push {r6} */ 534 1.10 christos 0x02, 0x4e, /* ldr r6, [pc, #8] */ 535 1.10 christos 0x36, 0x68, /* ldr r6, [r6] */ 536 1.10 christos 0xb4, 0x46, /* mov ip, r6 */ 537 1.10 christos 0x40, 0xbc, /* pop {r6} */ 538 1.10 christos 0x60, 0x47, /* bx ip */ 539 1.10 christos 0, 0, 0, 0 540 1.1 christos }; 541 1.1 christos 542 1.1 christos static const unsigned char mcore_be_jtab[] = 543 1.1 christos { 544 1.10 christos 0x71, 0x02, /* lrw r1,2 */ 545 1.10 christos 0x81, 0x01, /* ld.w r1,(r1,0) */ 546 1.10 christos 0x00, 0xC1, /* jmp r1 */ 547 1.10 christos 0x12, 0x00, /* nop */ 548 1.10 christos 0x00, 0x00, 0x00, 0x00 /* <address> */ 549 1.1 christos }; 550 1.1 christos 551 1.1 christos static const unsigned char mcore_le_jtab[] = 552 1.1 christos { 553 1.10 christos 0x02, 0x71, /* lrw r1,2 */ 554 1.10 christos 0x01, 0x81, /* ld.w r1,(r1,0) */ 555 1.10 christos 0xC1, 0x00, /* jmp r1 */ 556 1.10 christos 0x00, 0x12, /* nop */ 557 1.10 christos 0x00, 0x00, 0x00, 0x00 /* <address> */ 558 1.1 christos }; 559 1.1 christos 560 1.9 christos static const unsigned char aarch64_jtab[] = 561 1.9 christos { 562 1.10 christos 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */ 563 1.9 christos 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */ 564 1.10 christos 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */ 565 1.10 christos 0x00, 0x02, 0x1f, 0xd6 /* br x16 */ 566 1.9 christos }; 567 1.9 christos 568 1.3 christos static const char i386_trampoline[] = 569 1.1 christos "\tpushl %%ecx\n" 570 1.1 christos "\tpushl %%edx\n" 571 1.1 christos "\tpushl %%eax\n" 572 1.1 christos "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n" 573 1.1 christos "\tcall ___delayLoadHelper2@8\n" 574 1.1 christos "\tpopl %%edx\n" 575 1.1 christos "\tpopl %%ecx\n" 576 1.1 christos "\tjmp *%%eax\n"; 577 1.1 christos 578 1.9 christos /* Save integer arg regs in parameter space reserved by our caller 579 1.9 christos above the return address. Allocate space for six fp arg regs plus 580 1.9 christos parameter space possibly used by __delayLoadHelper2 plus alignment. 581 1.9 christos We enter with the stack offset from 16-byte alignment by the return 582 1.9 christos address, so allocate 96 + 32 + 8 = 136 bytes. Note that only the 583 1.9 christos first four xmm regs are used to pass fp args, but the first six 584 1.9 christos vector ymm (zmm too?) are used to pass vector args. We are 585 1.9 christos assuming that volatile vector regs are not modified inside 586 1.9 christos __delayLoadHelper2. However, it is known that at least xmm0 and 587 1.9 christos xmm1 are trashed in some versions of Microsoft dlls, and if xmm4 or 588 1.9 christos xmm5 are also used then that would trash the lower bits of ymm4 and 589 1.9 christos ymm5. If it turns out that vector insns with a vex prefix are used 590 1.9 christos then we'll need to save ymm0-5 here but that can't be done without 591 1.9 christos first testing cpuid and xcr0. */ 592 1.3 christos static const char i386_x64_trampoline[] = 593 1.9 christos "\tsubq $136, %%rsp\n" 594 1.9 christos "\t.seh_stackalloc 136\n" 595 1.8 christos "\t.seh_endprologue\n" 596 1.9 christos "\tmovq %%rcx, 136+8(%%rsp)\n" 597 1.9 christos "\tmovq %%rdx, 136+16(%%rsp)\n" 598 1.9 christos "\tmovq %%r8, 136+24(%%rsp)\n" 599 1.9 christos "\tmovq %%r9, 136+32(%%rsp)\n" 600 1.9 christos "\tmovaps %%xmm0, 32(%%rsp)\n" 601 1.9 christos "\tmovaps %%xmm1, 48(%%rsp)\n" 602 1.9 christos "\tmovaps %%xmm2, 64(%%rsp)\n" 603 1.9 christos "\tmovaps %%xmm3, 80(%%rsp)\n" 604 1.9 christos "\tmovaps %%xmm4, 96(%%rsp)\n" 605 1.9 christos "\tmovaps %%xmm5, 112(%%rsp)\n" 606 1.9 christos "\tmovq %%rax, %%rdx\n" 607 1.9 christos "\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n" 608 1.1 christos "\tcall __delayLoadHelper2\n" 609 1.9 christos "\tmovq 136+8(%%rsp), %%rcx\n" 610 1.9 christos "\tmovq 136+16(%%rsp), %%rdx\n" 611 1.9 christos "\tmovq 136+24(%%rsp), %%r8\n" 612 1.9 christos "\tmovq 136+32(%%rsp), %%r9\n" 613 1.9 christos "\tmovaps 32(%%rsp), %%xmm0\n" 614 1.9 christos "\tmovaps 48(%%rsp), %%xmm1\n" 615 1.9 christos "\tmovaps 64(%%rsp), %%xmm2\n" 616 1.9 christos "\tmovaps 80(%%rsp), %%xmm3\n" 617 1.9 christos "\tmovaps 96(%%rsp), %%xmm4\n" 618 1.9 christos "\tmovaps 112(%%rsp), %%xmm5\n" 619 1.9 christos "\taddq $136, %%rsp\n" 620 1.1 christos "\tjmp *%%rax\n"; 621 1.1 christos 622 1.1 christos struct mac 623 1.1 christos { 624 1.1 christos const char *type; 625 1.1 christos const char *how_byte; 626 1.1 christos const char *how_short; 627 1.1 christos const char *how_long; 628 1.1 christos const char *how_asciz; 629 1.1 christos const char *how_comment; 630 1.1 christos const char *how_jump; 631 1.1 christos const char *how_global; 632 1.1 christos const char *how_space; 633 1.1 christos const char *how_align_short; 634 1.1 christos const char *how_align_long; 635 1.1 christos const char *how_default_as_switches; 636 1.1 christos const char *how_bfd_target; 637 1.1 christos enum bfd_architecture how_bfd_arch; 638 1.1 christos const unsigned char *how_jtab; 639 1.1 christos int how_jtab_size; /* Size of the jtab entry. */ 640 1.1 christos int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */ 641 1.1 christos const unsigned char *how_dljtab; 642 1.1 christos int how_dljtab_size; /* Size of the dljtab entry. */ 643 1.1 christos int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */ 644 1.1 christos int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */ 645 1.1 christos int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */ 646 1.8 christos bool how_seh; 647 1.1 christos const char *trampoline; 648 1.1 christos }; 649 1.1 christos 650 1.1 christos static const struct mac 651 1.1 christos mtable[] = 652 1.1 christos { 653 1.1 christos { 654 1.1 christos #define MARM 0 655 1.1 christos "arm", ".byte", ".short", ".long", ".asciz", "@", 656 1.1 christos "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", 657 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32", 658 1.1 christos "pe-arm-little", bfd_arch_arm, 659 1.1 christos arm_jtab, sizeof (arm_jtab), 8, 660 1.8 christos 0, 0, 0, 0, 0, false, 0 661 1.1 christos } 662 1.1 christos , 663 1.1 christos { 664 1.1 christos #define M386 1 665 1.1 christos "i386", ".byte", ".short", ".long", ".asciz", "#", 666 1.10 christos "jmp *", ".global", ".space", ".align\t2", ".align\t4", "", 667 1.1 christos "pe-i386",bfd_arch_i386, 668 1.1 christos i386_jtab, sizeof (i386_jtab), 2, 669 1.8 christos i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, false, i386_trampoline 670 1.1 christos } 671 1.1 christos , 672 1.1 christos { 673 1.8 christos #define MTHUMB 2 674 1.1 christos "thumb", ".byte", ".short", ".long", ".asciz", "@", 675 1.1 christos "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip", 676 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork", 677 1.1 christos "pe-arm-little", bfd_arch_arm, 678 1.1 christos thumb_jtab, sizeof (thumb_jtab), 12, 679 1.8 christos 0, 0, 0, 0, 0, false, 0 680 1.1 christos } 681 1.1 christos , 682 1.8 christos #define MARM_INTERWORK 3 683 1.1 christos { 684 1.1 christos "arm_interwork", ".byte", ".short", ".long", ".asciz", "@", 685 1.1 christos "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long", 686 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork", 687 1.1 christos "pe-arm-little", bfd_arch_arm, 688 1.1 christos arm_interwork_jtab, sizeof (arm_interwork_jtab), 12, 689 1.8 christos 0, 0, 0, 0, 0, false, 0 690 1.1 christos } 691 1.1 christos , 692 1.1 christos { 693 1.8 christos #define MMCORE_BE 4 694 1.1 christos "mcore-be", ".byte", ".short", ".long", ".asciz", "//", 695 1.1 christos "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 696 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "", 697 1.1 christos "pe-mcore-big", bfd_arch_mcore, 698 1.1 christos mcore_be_jtab, sizeof (mcore_be_jtab), 8, 699 1.8 christos 0, 0, 0, 0, 0, false, 0 700 1.1 christos } 701 1.1 christos , 702 1.1 christos { 703 1.8 christos #define MMCORE_LE 5 704 1.1 christos "mcore-le", ".byte", ".short", ".long", ".asciz", "//", 705 1.1 christos "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 706 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-EL", 707 1.1 christos "pe-mcore-little", bfd_arch_mcore, 708 1.1 christos mcore_le_jtab, sizeof (mcore_le_jtab), 8, 709 1.8 christos 0, 0, 0, 0, 0, false, 0 710 1.1 christos } 711 1.1 christos , 712 1.1 christos { 713 1.8 christos #define MMCORE_ELF 6 714 1.1 christos "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//", 715 1.1 christos "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 716 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "", 717 1.1 christos "elf32-mcore-big", bfd_arch_mcore, 718 1.1 christos mcore_be_jtab, sizeof (mcore_be_jtab), 8, 719 1.8 christos 0, 0, 0, 0, 0, false, 0 720 1.1 christos } 721 1.1 christos , 722 1.1 christos { 723 1.8 christos #define MMCORE_ELF_LE 7 724 1.1 christos "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//", 725 1.1 christos "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 726 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-EL", 727 1.1 christos "elf32-mcore-little", bfd_arch_mcore, 728 1.1 christos mcore_le_jtab, sizeof (mcore_le_jtab), 8, 729 1.8 christos 0, 0, 0, 0, 0, false, 0 730 1.1 christos } 731 1.1 christos , 732 1.1 christos { 733 1.8 christos #define MARM_WINCE 8 734 1.1 christos "arm-wince", ".byte", ".short", ".long", ".asciz", "@", 735 1.1 christos "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", 736 1.10 christos ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32", 737 1.1 christos "pe-arm-wince-little", bfd_arch_arm, 738 1.1 christos arm_jtab, sizeof (arm_jtab), 8, 739 1.8 christos 0, 0, 0, 0, 0, false, 0 740 1.1 christos } 741 1.1 christos , 742 1.1 christos { 743 1.8 christos #define MX86 9 744 1.1 christos "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#", 745 1.10 christos "jmp *", ".global", ".space", ".align\t2", ".align\t4", "", 746 1.1 christos "pe-x86-64",bfd_arch_i386, 747 1.1 christos i386_jtab, sizeof (i386_jtab), 2, 748 1.8 christos i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, true, i386_x64_trampoline 749 1.1 christos } 750 1.1 christos , 751 1.9 christos { 752 1.9 christos #define MAARCH64 10 753 1.9 christos "arm64", ".byte", ".short", ".long", ".asciz", "//", 754 1.9 christos "bl ", ".global", ".space", ".balign\t2", ".balign\t4", "", 755 1.9 christos "pe-aarch64-little", bfd_arch_aarch64, 756 1.9 christos aarch64_jtab, sizeof (aarch64_jtab), 0, 757 1.9 christos 0, 0, 0, 0, 0, false, 0 758 1.9 christos } 759 1.9 christos , 760 1.8 christos { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 761 1.1 christos }; 762 1.1 christos 763 1.1 christos typedef struct dlist 764 1.1 christos { 765 1.10 christos const char *text; 766 1.1 christos struct dlist *next; 767 1.1 christos } 768 1.1 christos dlist_type; 769 1.1 christos 770 1.1 christos typedef struct export 771 1.1 christos { 772 1.1 christos const char *name; 773 1.1 christos const char *internal_name; 774 1.1 christos const char *import_name; 775 1.1 christos const char *its_name; 776 1.1 christos int ordinal; 777 1.1 christos int constant; 778 1.1 christos int noname; /* Don't put name in image file. */ 779 1.10 christos int private; /* Don't put reference in import lib. */ 780 1.1 christos int data; 781 1.10 christos int hint; 782 1.10 christos int forward; /* Number of forward label, 0 means no forward. */ 783 1.1 christos struct export *next; 784 1.1 christos } 785 1.1 christos export_type; 786 1.1 christos 787 1.1 christos /* A list of symbols which we should not export. */ 788 1.1 christos 789 1.1 christos struct string_list 790 1.1 christos { 791 1.1 christos struct string_list *next; 792 1.1 christos char *string; 793 1.1 christos }; 794 1.1 christos 795 1.1 christos static struct string_list *excludes; 796 1.1 christos 797 1.10 christos /* Forward references. */ 798 1.10 christos static char *deduce_name (const char *); 799 1.10 christos static char *xlate (const char *); 800 1.1 christos static void dll_name_list_free_contents (dll_name_list_node_type *); 801 1.1 christos static void identify_search_archive 802 1.1 christos (bfd *, void (*) (bfd *, bfd *, void *), void *); 803 1.1 christos static void identify_search_member (bfd *, bfd *, void *); 804 1.1 christos static void identify_search_section (bfd *, asection *, void *); 805 1.10 christos static void inform (const char *, ...) ATTRIBUTE_PRINTF_1; 806 1.10 christos 807 1.10 christos #ifdef DLLTOOL_MCORE_ELF 808 1.10 christos static void mcore_elf_cache_filename (const char *); 809 1.10 christos static void mcore_elf_gen_out_file (void); 810 1.10 christos #endif 811 1.1 christos 812 1.10 christos /* Get current BFD error message. */ 813 1.10 christos static inline const char * 814 1.10 christos bfd_get_errmsg (void) 815 1.10 christos { 816 1.10 christos return bfd_errmsg (bfd_get_error ()); 817 1.10 christos } 818 1.1 christos 819 1.1 christos static char * 820 1.1 christos prefix_encode (char *start, unsigned code) 821 1.1 christos { 822 1.1 christos static char buf[32]; 823 1.10 christos char *p = stpcpy (buf, start); 824 1.1 christos do 825 1.10 christos *p++ = "abcdefghijklmnopqrstuvwxyz"[code % 26]; 826 1.10 christos while ((code /= 26) != 0); 827 1.1 christos *p = '\0'; 828 1.1 christos return buf; 829 1.1 christos } 830 1.1 christos 831 1.1 christos static char * 832 1.1 christos dlltmp (char **buf, const char *fmt) 833 1.1 christos { 834 1.1 christos if (!*buf) 835 1.1 christos { 836 1.10 christos *buf = xmalloc (strlen (tmp_prefix) + 64); 837 1.1 christos sprintf (*buf, fmt, tmp_prefix); 838 1.1 christos } 839 1.1 christos return *buf; 840 1.1 christos } 841 1.1 christos 842 1.1 christos static void 843 1.3 christos inform (const char * message, ...) 844 1.1 christos { 845 1.3 christos va_list args; 846 1.3 christos 847 1.3 christos va_start (args, message); 848 1.1 christos 849 1.1 christos if (!verbose) 850 1.1 christos return; 851 1.1 christos 852 1.1 christos report (message, args); 853 1.1 christos 854 1.3 christos va_end (args); 855 1.1 christos } 856 1.1 christos 857 1.1 christos static const char * 858 1.1 christos rvaafter (int mach) 859 1.1 christos { 860 1.1 christos switch (mach) 861 1.1 christos { 862 1.1 christos case MARM: 863 1.1 christos case M386: 864 1.1 christos case MX86: 865 1.1 christos case MTHUMB: 866 1.1 christos case MARM_INTERWORK: 867 1.1 christos case MMCORE_BE: 868 1.1 christos case MMCORE_LE: 869 1.1 christos case MMCORE_ELF: 870 1.1 christos case MMCORE_ELF_LE: 871 1.1 christos case MARM_WINCE: 872 1.9 christos case MAARCH64: 873 1.1 christos break; 874 1.1 christos default: 875 1.1 christos /* xgettext:c-format */ 876 1.1 christos fatal (_("Internal error: Unknown machine type: %d"), mach); 877 1.1 christos break; 878 1.1 christos } 879 1.1 christos return ""; 880 1.1 christos } 881 1.1 christos 882 1.1 christos static const char * 883 1.1 christos rvabefore (int mach) 884 1.1 christos { 885 1.1 christos switch (mach) 886 1.1 christos { 887 1.1 christos case MARM: 888 1.1 christos case M386: 889 1.1 christos case MX86: 890 1.1 christos case MTHUMB: 891 1.1 christos case MARM_INTERWORK: 892 1.1 christos case MMCORE_BE: 893 1.1 christos case MMCORE_LE: 894 1.1 christos case MMCORE_ELF: 895 1.1 christos case MMCORE_ELF_LE: 896 1.1 christos case MARM_WINCE: 897 1.9 christos case MAARCH64: 898 1.1 christos return ".rva\t"; 899 1.1 christos default: 900 1.1 christos /* xgettext:c-format */ 901 1.1 christos fatal (_("Internal error: Unknown machine type: %d"), mach); 902 1.1 christos break; 903 1.1 christos } 904 1.1 christos return ""; 905 1.1 christos } 906 1.1 christos 907 1.1 christos static const char * 908 1.10 christos asm_prefix (const char *name) 909 1.1 christos { 910 1.10 christos /* Symbol names starting with ? do not have a leading underscore. */ 911 1.10 christos if (name && *name == '?') 912 1.10 christos return ""; 913 1.10 christos return leading_underscore; 914 1.1 christos } 915 1.1 christos 916 1.1 christos #define ASM_BYTE mtable[machine].how_byte 917 1.1 christos #define ASM_SHORT mtable[machine].how_short 918 1.1 christos #define ASM_LONG mtable[machine].how_long 919 1.1 christos #define ASM_TEXT mtable[machine].how_asciz 920 1.1 christos #define ASM_C mtable[machine].how_comment 921 1.1 christos #define ASM_JUMP mtable[machine].how_jump 922 1.1 christos #define ASM_GLOBAL mtable[machine].how_global 923 1.1 christos #define ASM_SPACE mtable[machine].how_space 924 1.1 christos #define ASM_ALIGN_SHORT mtable[machine].how_align_short 925 1.1 christos #define ASM_RVA_BEFORE rvabefore (machine) 926 1.1 christos #define ASM_RVA_AFTER rvaafter (machine) 927 1.10 christos #define ASM_PREFIX(NAME) asm_prefix (NAME) 928 1.1 christos #define ASM_ALIGN_LONG mtable[machine].how_align_long 929 1.1 christos #define HOW_BFD_READ_TARGET 0 /* Always default. */ 930 1.1 christos #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target 931 1.1 christos #define HOW_BFD_ARCH mtable[machine].how_bfd_arch 932 1.1 christos #define HOW_JTAB (delay ? mtable[machine].how_dljtab \ 933 1.1 christos : mtable[machine].how_jtab) 934 1.1 christos #define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \ 935 1.1 christos : mtable[machine].how_jtab_size) 936 1.1 christos #define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \ 937 1.1 christos : mtable[machine].how_jtab_roff) 938 1.1 christos #define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0) 939 1.1 christos #define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0) 940 1.1 christos #define ASM_SWITCHES mtable[machine].how_default_as_switches 941 1.8 christos #define HOW_SEH mtable[machine].how_seh 942 1.1 christos 943 1.1 christos static char **oav; 944 1.1 christos 945 1.1 christos static void 946 1.1 christos process_def_file (const char *name) 947 1.1 christos { 948 1.1 christos FILE *f = fopen (name, FOPEN_RT); 949 1.1 christos 950 1.1 christos if (!f) 951 1.1 christos /* xgettext:c-format */ 952 1.1 christos fatal (_("Can't open def file: %s"), name); 953 1.1 christos 954 1.1 christos yyin = f; 955 1.1 christos 956 1.1 christos /* xgettext:c-format */ 957 1.1 christos inform (_("Processing def file: %s"), name); 958 1.1 christos 959 1.1 christos yyparse (); 960 1.1 christos 961 1.1 christos inform (_("Processed def file")); 962 1.1 christos } 963 1.1 christos 964 1.1 christos /**********************************************************************/ 965 1.1 christos 966 1.1 christos /* Communications with the parser. */ 967 1.1 christos 968 1.1 christos static int d_nfuncs; /* Number of functions exported. */ 969 1.1 christos static int d_named_nfuncs; /* Number of named functions exported. */ 970 1.1 christos static int d_low_ord; /* Lowest ordinal index. */ 971 1.1 christos static int d_high_ord; /* Highest ordinal index. */ 972 1.1 christos static export_type *d_exports; /* List of exported functions. */ 973 1.1 christos static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */ 974 1.1 christos static dlist_type *d_list; /* Descriptions. */ 975 1.1 christos static dlist_type *a_list; /* Stuff to go in directives. */ 976 1.1 christos static int d_nforwards = 0; /* Number of forwarded exports. */ 977 1.1 christos 978 1.1 christos static int d_is_dll; 979 1.1 christos static int d_is_exe; 980 1.1 christos 981 1.8 christos void 982 1.1 christos yyerror (const char * err ATTRIBUTE_UNUSED) 983 1.1 christos { 984 1.1 christos /* xgettext:c-format */ 985 1.1 christos non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber); 986 1.1 christos } 987 1.1 christos 988 1.1 christos void 989 1.1 christos def_exports (const char *name, const char *internal_name, int ordinal, 990 1.1 christos int noname, int constant, int data, int private, 991 1.1 christos const char *its_name) 992 1.1 christos { 993 1.1 christos struct export *p = (struct export *) xmalloc (sizeof (*p)); 994 1.1 christos 995 1.1 christos p->name = name; 996 1.1 christos p->internal_name = internal_name ? internal_name : name; 997 1.1 christos p->its_name = its_name; 998 1.1 christos p->import_name = name; 999 1.1 christos p->ordinal = ordinal; 1000 1.1 christos p->constant = constant; 1001 1.1 christos p->noname = noname; 1002 1.1 christos p->private = private; 1003 1.1 christos p->data = data; 1004 1.1 christos p->next = d_exports; 1005 1.1 christos d_exports = p; 1006 1.1 christos d_nfuncs++; 1007 1.1 christos 1008 1.10 christos if (internal_name != NULL 1009 1.10 christos && strchr (internal_name, '.') != NULL) 1010 1.1 christos p->forward = ++d_nforwards; 1011 1.1 christos else 1012 1.1 christos p->forward = 0; /* no forward */ 1013 1.1 christos } 1014 1.1 christos 1015 1.1 christos static void 1016 1.1 christos set_dll_name_from_def (const char *name, char is_dll) 1017 1.1 christos { 1018 1.1 christos const char *image_basename = lbasename (name); 1019 1.1 christos if (image_basename != name) 1020 1.1 christos non_fatal (_("%s: Path components stripped from image name, '%s'."), 1021 1.10 christos def_file, name); 1022 1.3 christos /* Append the default suffix, if none specified. */ 1023 1.1 christos if (strchr (image_basename, '.') == 0) 1024 1.10 christos dll_name = xasprintf ("%s%s", image_basename, is_dll ? ".dll" : ".exe"); 1025 1.1 christos else 1026 1.1 christos dll_name = xstrdup (image_basename); 1027 1.1 christos } 1028 1.1 christos 1029 1.1 christos void 1030 1.1 christos def_name (const char *name, int base) 1031 1.1 christos { 1032 1.1 christos /* xgettext:c-format */ 1033 1.1 christos inform (_("NAME: %s base: %x"), name, base); 1034 1.1 christos 1035 1.1 christos if (d_is_dll) 1036 1.1 christos non_fatal (_("Can't have LIBRARY and NAME")); 1037 1.1 christos 1038 1.1 christos if (dll_name_set_by_exp_name && name && *name != 0) 1039 1.1 christos { 1040 1.10 christos free (dll_name); 1041 1.1 christos dll_name = NULL; 1042 1.1 christos dll_name_set_by_exp_name = 0; 1043 1.1 christos } 1044 1.1 christos /* If --dllname not provided, use the one in the DEF file. 1045 1.1 christos FIXME: Is this appropriate for executables? */ 1046 1.1 christos if (!dll_name) 1047 1.1 christos set_dll_name_from_def (name, 0); 1048 1.10 christos free ((char *) name); 1049 1.1 christos d_is_exe = 1; 1050 1.1 christos } 1051 1.1 christos 1052 1.1 christos void 1053 1.1 christos def_library (const char *name, int base) 1054 1.1 christos { 1055 1.1 christos /* xgettext:c-format */ 1056 1.1 christos inform (_("LIBRARY: %s base: %x"), name, base); 1057 1.1 christos 1058 1.1 christos if (d_is_exe) 1059 1.1 christos non_fatal (_("Can't have LIBRARY and NAME")); 1060 1.1 christos 1061 1.1 christos if (dll_name_set_by_exp_name && name && *name != 0) 1062 1.1 christos { 1063 1.10 christos free (dll_name); 1064 1.1 christos dll_name = NULL; 1065 1.1 christos dll_name_set_by_exp_name = 0; 1066 1.1 christos } 1067 1.1 christos 1068 1.1 christos /* If --dllname not provided, use the one in the DEF file. */ 1069 1.1 christos if (!dll_name) 1070 1.1 christos set_dll_name_from_def (name, 1); 1071 1.10 christos free ((char *) name); 1072 1.1 christos d_is_dll = 1; 1073 1.1 christos } 1074 1.1 christos 1075 1.1 christos void 1076 1.1 christos def_description (const char *desc) 1077 1.1 christos { 1078 1.1 christos dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); 1079 1.10 christos d->text = desc; 1080 1.1 christos d->next = d_list; 1081 1.1 christos d_list = d; 1082 1.1 christos } 1083 1.1 christos 1084 1.1 christos static void 1085 1.1 christos new_directive (char *dir) 1086 1.1 christos { 1087 1.1 christos dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); 1088 1.10 christos d->text = dir; 1089 1.1 christos d->next = a_list; 1090 1.1 christos a_list = d; 1091 1.1 christos } 1092 1.1 christos 1093 1.1 christos void 1094 1.1 christos def_heapsize (int reserve, int commit) 1095 1.1 christos { 1096 1.10 christos char *s; 1097 1.1 christos if (commit > 0) 1098 1.10 christos s = xasprintf ("-heap 0x%x,0x%x ", reserve, commit); 1099 1.1 christos else 1100 1.10 christos s = xasprintf ("-heap 0x%x ", reserve); 1101 1.10 christos new_directive (s); 1102 1.1 christos } 1103 1.1 christos 1104 1.1 christos void 1105 1.1 christos def_stacksize (int reserve, int commit) 1106 1.1 christos { 1107 1.10 christos char *s; 1108 1.1 christos if (commit > 0) 1109 1.10 christos s = xasprintf ("-stack 0x%x,0x%x ", reserve, commit); 1110 1.1 christos else 1111 1.10 christos s = xasprintf ( "-stack 0x%x ", reserve); 1112 1.10 christos new_directive (s); 1113 1.1 christos } 1114 1.1 christos 1115 1.1 christos /* append_import simply adds the given import definition to the global 1116 1.1 christos import_list. It is used by def_import. */ 1117 1.1 christos 1118 1.1 christos static void 1119 1.1 christos append_import (const char *symbol_name, const char *dllname, int func_ordinal, 1120 1.1 christos const char *its_name) 1121 1.1 christos { 1122 1.1 christos iheadtype **pq; 1123 1.1 christos iheadtype *q; 1124 1.1 christos 1125 1.1 christos for (pq = &import_list; *pq != NULL; pq = &(*pq)->next) 1126 1.1 christos { 1127 1.1 christos if (strcmp ((*pq)->dllname, dllname) == 0) 1128 1.1 christos { 1129 1.1 christos q = *pq; 1130 1.1 christos q->functail->next = xmalloc (sizeof (ifunctype)); 1131 1.1 christos q->functail = q->functail->next; 1132 1.1 christos q->functail->ord = func_ordinal; 1133 1.10 christos q->functail->name = symbol_name; 1134 1.10 christos q->functail->its_name = its_name; 1135 1.1 christos q->functail->next = NULL; 1136 1.1 christos q->nfuncs++; 1137 1.1 christos return; 1138 1.1 christos } 1139 1.1 christos } 1140 1.1 christos 1141 1.1 christos q = xmalloc (sizeof (iheadtype)); 1142 1.10 christos q->dllname = dllname; 1143 1.1 christos q->nfuncs = 1; 1144 1.1 christos q->funchead = xmalloc (sizeof (ifunctype)); 1145 1.1 christos q->functail = q->funchead; 1146 1.1 christos q->next = NULL; 1147 1.10 christos q->functail->name = symbol_name; 1148 1.10 christos q->functail->its_name = its_name; 1149 1.1 christos q->functail->ord = func_ordinal; 1150 1.1 christos q->functail->next = NULL; 1151 1.1 christos 1152 1.1 christos *pq = q; 1153 1.1 christos } 1154 1.1 christos 1155 1.1 christos /* def_import is called from within defparse.y when an IMPORT 1156 1.1 christos declaration is encountered. Depending on the form of the 1157 1.1 christos declaration, the module name may or may not need ".dll" to be 1158 1.1 christos appended to it, the name of the function may be stored in internal 1159 1.1 christos or entry, and there may or may not be an ordinal value associated 1160 1.1 christos with it. */ 1161 1.1 christos 1162 1.1 christos /* A note regarding the parse modes: 1163 1.1 christos In defparse.y we have to accept import declarations which follow 1164 1.1 christos any one of the following forms: 1165 1.1 christos <func_name_in_app> = <dll_name>.<func_name_in_dll> 1166 1.1 christos <func_name_in_app> = <dll_name>.<number> 1167 1.1 christos <dll_name>.<func_name_in_dll> 1168 1.1 christos <dll_name>.<number> 1169 1.1 christos Furthermore, the dll's name may or may not end with ".dll", which 1170 1.1 christos complicates the parsing a little. Normally the dll's name is 1171 1.1 christos passed to def_import() in the "module" parameter, but when it ends 1172 1.1 christos with ".dll" it gets passed in "module" sans ".dll" and that needs 1173 1.1 christos to be reappended. 1174 1.1 christos 1175 1.1 christos def_import gets five parameters: 1176 1.1 christos APP_NAME - the name of the function in the application, if 1177 1.1 christos present, or NULL if not present. 1178 1.1 christos MODULE - the name of the dll, possibly sans extension (ie, '.dll'). 1179 1.1 christos DLLEXT - the extension of the dll, if present, NULL if not present. 1180 1.1 christos ENTRY - the name of the function in the dll, if present, or NULL. 1181 1.1 christos ORD_VAL - the numerical tag of the function in the dll, if present, 1182 1.1 christos or NULL. Exactly one of <entry> or <ord_val> must be 1183 1.1 christos present (i.e., not NULL). */ 1184 1.1 christos 1185 1.1 christos void 1186 1.1 christos def_import (const char *app_name, const char *module, const char *dllext, 1187 1.1 christos const char *entry, int ord_val, const char *its_name) 1188 1.1 christos { 1189 1.1 christos const char *application_name; 1190 1.1 christos 1191 1.1 christos if (entry != NULL) 1192 1.1 christos application_name = entry; 1193 1.1 christos else 1194 1.1 christos { 1195 1.1 christos if (app_name != NULL) 1196 1.1 christos application_name = app_name; 1197 1.1 christos else 1198 1.1 christos application_name = ""; 1199 1.1 christos } 1200 1.1 christos 1201 1.10 christos const char *mod_name = module; 1202 1.1 christos if (dllext != NULL) 1203 1.10 christos { 1204 1.10 christos mod_name = concat (module, ".", dllext, NULL); 1205 1.10 christos free ((char *) module); 1206 1.10 christos } 1207 1.1 christos 1208 1.10 christos append_import (application_name, mod_name, ord_val, its_name); 1209 1.1 christos } 1210 1.1 christos 1211 1.1 christos void 1212 1.1 christos def_version (int major, int minor) 1213 1.1 christos { 1214 1.1 christos printf (_("VERSION %d.%d\n"), major, minor); 1215 1.1 christos } 1216 1.1 christos 1217 1.1 christos void 1218 1.1 christos def_section (const char *name, int attr) 1219 1.1 christos { 1220 1.1 christos char atts[5]; 1221 1.1 christos char *d = atts; 1222 1.1 christos if (attr & 1) 1223 1.1 christos *d++ = 'R'; 1224 1.1 christos if (attr & 2) 1225 1.1 christos *d++ = 'W'; 1226 1.1 christos if (attr & 4) 1227 1.1 christos *d++ = 'X'; 1228 1.1 christos if (attr & 8) 1229 1.1 christos *d++ = 'S'; 1230 1.1 christos *d++ = 0; 1231 1.10 christos char *s = xasprintf ("-attr %s %s", name, atts); 1232 1.10 christos new_directive (s); 1233 1.1 christos } 1234 1.1 christos 1235 1.1 christos void 1236 1.1 christos def_code (int attr) 1237 1.1 christos { 1238 1.1 christos def_section ("CODE", attr); 1239 1.1 christos } 1240 1.1 christos 1241 1.1 christos void 1242 1.1 christos def_data (int attr) 1243 1.1 christos { 1244 1.1 christos def_section ("DATA", attr); 1245 1.1 christos } 1246 1.1 christos 1247 1.1 christos /**********************************************************************/ 1248 1.1 christos 1249 1.1 christos static void 1250 1.1 christos run (const char *what, char *args) 1251 1.1 christos { 1252 1.1 christos char *s; 1253 1.1 christos int pid, wait_status; 1254 1.1 christos int i; 1255 1.1 christos const char **argv; 1256 1.8 christos char *errmsg_fmt = NULL, *errmsg_arg = NULL; 1257 1.9 christos char *temp_base = make_temp_file (""); 1258 1.1 christos 1259 1.1 christos inform (_("run: %s %s"), what, args); 1260 1.1 christos 1261 1.1 christos /* Count the args */ 1262 1.1 christos i = 0; 1263 1.1 christos for (s = args; *s; s++) 1264 1.1 christos if (*s == ' ') 1265 1.1 christos i++; 1266 1.1 christos i++; 1267 1.5 christos argv = xmalloc (sizeof (char *) * (i + 3)); 1268 1.1 christos i = 0; 1269 1.1 christos argv[i++] = what; 1270 1.1 christos s = args; 1271 1.1 christos while (1) 1272 1.1 christos { 1273 1.1 christos while (*s == ' ') 1274 1.1 christos ++s; 1275 1.1 christos argv[i++] = s; 1276 1.1 christos while (*s != ' ' && *s != 0) 1277 1.1 christos s++; 1278 1.1 christos if (*s == 0) 1279 1.1 christos break; 1280 1.1 christos *s++ = 0; 1281 1.1 christos } 1282 1.1 christos argv[i++] = NULL; 1283 1.1 christos 1284 1.1 christos pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, 1285 1.1 christos &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); 1286 1.8 christos free (argv); 1287 1.10 christos free (temp_base); 1288 1.1 christos 1289 1.1 christos if (pid == -1) 1290 1.1 christos { 1291 1.1 christos inform ("%s", strerror (errno)); 1292 1.1 christos 1293 1.1 christos fatal (errmsg_fmt, errmsg_arg); 1294 1.1 christos } 1295 1.1 christos 1296 1.1 christos pid = pwait (pid, & wait_status, 0); 1297 1.1 christos 1298 1.1 christos if (pid == -1) 1299 1.1 christos { 1300 1.1 christos /* xgettext:c-format */ 1301 1.1 christos fatal (_("wait: %s"), strerror (errno)); 1302 1.1 christos } 1303 1.1 christos else if (WIFSIGNALED (wait_status)) 1304 1.1 christos { 1305 1.1 christos /* xgettext:c-format */ 1306 1.1 christos fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status)); 1307 1.1 christos } 1308 1.1 christos else if (WIFEXITED (wait_status)) 1309 1.1 christos { 1310 1.1 christos if (WEXITSTATUS (wait_status) != 0) 1311 1.1 christos /* xgettext:c-format */ 1312 1.1 christos non_fatal (_("%s exited with status %d"), 1313 1.1 christos what, WEXITSTATUS (wait_status)); 1314 1.1 christos } 1315 1.1 christos else 1316 1.1 christos abort (); 1317 1.1 christos } 1318 1.1 christos 1319 1.1 christos /* Look for a list of symbols to export in the .drectve section of 1320 1.1 christos ABFD. Pass each one to def_exports. */ 1321 1.1 christos 1322 1.1 christos static void 1323 1.1 christos scan_drectve_symbols (bfd *abfd) 1324 1.1 christos { 1325 1.1 christos /* Look for .drectve's */ 1326 1.10 christos asection *s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME); 1327 1.1 christos if (s == NULL) 1328 1.1 christos return; 1329 1.1 christos 1330 1.10 christos bfd_byte *buf; 1331 1.10 christos if (!bfd_malloc_and_get_section (abfd, s, &buf)) 1332 1.10 christos return; 1333 1.1 christos 1334 1.1 christos /* xgettext:c-format */ 1335 1.1 christos inform (_("Sucking in info from %s section in %s"), 1336 1.1 christos DRECTVE_SECTION_NAME, bfd_get_filename (abfd)); 1337 1.1 christos 1338 1.1 christos /* Search for -export: strings. The exported symbols can optionally 1339 1.1 christos have type tags (eg., -export:foo,data), so handle those as well. 1340 1.1 christos Currently only data tag is supported. */ 1341 1.10 christos const char *p = (const char *) buf; 1342 1.10 christos const char *e = (const char *) buf + bfd_section_size (s); 1343 1.1 christos while (p < e) 1344 1.1 christos { 1345 1.1 christos if (p[0] == '-' 1346 1.8 christos && startswith (p, "-export:")) 1347 1.1 christos { 1348 1.10 christos const char *name; 1349 1.10 christos char *c; 1350 1.1 christos flagword flags = BSF_FUNCTION; 1351 1.1 christos 1352 1.1 christos p += 8; 1353 1.1 christos /* Do we have a quoted export? */ 1354 1.1 christos if (*p == '"') 1355 1.1 christos { 1356 1.1 christos p++; 1357 1.1 christos name = p; 1358 1.1 christos while (p < e && *p != '"') 1359 1.1 christos ++p; 1360 1.1 christos } 1361 1.1 christos else 1362 1.1 christos { 1363 1.1 christos name = p; 1364 1.1 christos while (p < e && *p != ',' && *p != ' ' && *p != '-') 1365 1.1 christos p++; 1366 1.1 christos } 1367 1.10 christos c = xmemdup (name, p - name, p - name + 1); 1368 1.1 christos /* Advance over trailing quote. */ 1369 1.1 christos if (p < e && *p == '"') 1370 1.1 christos ++p; 1371 1.1 christos if (p < e && *p == ',') /* found type tag. */ 1372 1.1 christos { 1373 1.10 christos const char *tag_start = ++p; 1374 1.1 christos while (p < e && *p != ' ' && *p != '-') 1375 1.1 christos p++; 1376 1.8 christos if (startswith (tag_start, "data")) 1377 1.1 christos flags &= ~BSF_FUNCTION; 1378 1.1 christos } 1379 1.1 christos 1380 1.1 christos /* FIXME: The 5th arg is for the `constant' field. 1381 1.1 christos What should it be? Not that it matters since it's not 1382 1.1 christos currently useful. */ 1383 1.1 christos def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0, NULL); 1384 1.1 christos 1385 1.1 christos if (add_stdcall_alias && strchr (c, '@')) 1386 1.1 christos { 1387 1.1 christos int lead_at = (*c == '@') ; 1388 1.1 christos char *exported_name = xstrdup (c + lead_at); 1389 1.1 christos char *atsym = strchr (exported_name, '@'); 1390 1.10 christos if (atsym) 1391 1.10 christos *atsym = '\0'; 1392 1.1 christos /* Note: stdcall alias symbols can never be data. */ 1393 1.10 christos def_exports (exported_name, c, -1, 0, 0, 0, 0, NULL); 1394 1.1 christos } 1395 1.1 christos } 1396 1.1 christos else 1397 1.1 christos p++; 1398 1.1 christos } 1399 1.1 christos free (buf); 1400 1.1 christos } 1401 1.1 christos 1402 1.1 christos /* Look through the symbols in MINISYMS, and add each one to list of 1403 1.1 christos symbols to export. */ 1404 1.1 christos 1405 1.1 christos static void 1406 1.1 christos scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, 1407 1.1 christos unsigned int size) 1408 1.1 christos { 1409 1.1 christos asymbol *store; 1410 1.1 christos bfd_byte *from, *fromend; 1411 1.1 christos 1412 1.1 christos store = bfd_make_empty_symbol (abfd); 1413 1.1 christos if (store == NULL) 1414 1.1 christos bfd_fatal (bfd_get_filename (abfd)); 1415 1.1 christos 1416 1.1 christos from = (bfd_byte *) minisyms; 1417 1.1 christos fromend = from + symcount * size; 1418 1.1 christos for (; from < fromend; from += size) 1419 1.1 christos { 1420 1.1 christos asymbol *sym; 1421 1.1 christos const char *symbol_name; 1422 1.1 christos 1423 1.8 christos sym = bfd_minisymbol_to_symbol (abfd, false, from, store); 1424 1.1 christos if (sym == NULL) 1425 1.1 christos bfd_fatal (bfd_get_filename (abfd)); 1426 1.1 christos 1427 1.1 christos symbol_name = bfd_asymbol_name (sym); 1428 1.9 christos if (*symbol_name 1429 1.9 christos && *symbol_name == bfd_get_symbol_leading_char (abfd)) 1430 1.1 christos ++symbol_name; 1431 1.1 christos 1432 1.10 christos def_exports (symbol_name , 0, -1, 0, 0, 1433 1.1 christos ! (sym->flags & BSF_FUNCTION), 0, NULL); 1434 1.1 christos 1435 1.1 christos if (add_stdcall_alias && strchr (symbol_name, '@')) 1436 1.10 christos { 1437 1.1 christos int lead_at = (*symbol_name == '@'); 1438 1.1 christos char *exported_name = xstrdup (symbol_name + lead_at); 1439 1.1 christos char *atsym = strchr (exported_name, '@'); 1440 1.10 christos if (atsym) 1441 1.10 christos *atsym = '\0'; 1442 1.1 christos /* Note: stdcall alias symbols can never be data. */ 1443 1.10 christos def_exports (exported_name, symbol_name, 1444 1.10 christos -1, 0, 0, 0, 0, NULL); 1445 1.1 christos } 1446 1.1 christos } 1447 1.1 christos } 1448 1.1 christos 1449 1.1 christos /* Add a list of symbols to exclude. */ 1450 1.1 christos 1451 1.1 christos static void 1452 1.1 christos add_excludes (const char *new_excludes) 1453 1.1 christos { 1454 1.1 christos char *local_copy; 1455 1.1 christos char *exclude_string; 1456 1.1 christos 1457 1.1 christos local_copy = xstrdup (new_excludes); 1458 1.1 christos 1459 1.1 christos exclude_string = strtok (local_copy, ",:"); 1460 1.1 christos for (; exclude_string; exclude_string = strtok (NULL, ",:")) 1461 1.1 christos { 1462 1.10 christos struct string_list *new_exclude = xmalloc (sizeof (*new_exclude)); 1463 1.1 christos /* Don't add a leading underscore for fastcall symbols. */ 1464 1.1 christos if (*exclude_string == '@') 1465 1.10 christos new_exclude->string = xstrdup (exclude_string); 1466 1.1 christos else 1467 1.10 christos new_exclude->string = xasprintf ("%s%s", leading_underscore, 1468 1.10 christos exclude_string); 1469 1.1 christos new_exclude->next = excludes; 1470 1.1 christos excludes = new_exclude; 1471 1.1 christos 1472 1.1 christos /* xgettext:c-format */ 1473 1.1 christos inform (_("Excluding symbol: %s"), exclude_string); 1474 1.1 christos } 1475 1.1 christos 1476 1.1 christos free (local_copy); 1477 1.1 christos } 1478 1.1 christos 1479 1.1 christos /* See if STRING is on the list of symbols to exclude. */ 1480 1.1 christos 1481 1.8 christos static bool 1482 1.1 christos match_exclude (const char *string) 1483 1.1 christos { 1484 1.1 christos struct string_list *excl_item; 1485 1.1 christos 1486 1.1 christos for (excl_item = excludes; excl_item; excl_item = excl_item->next) 1487 1.1 christos if (strcmp (string, excl_item->string) == 0) 1488 1.8 christos return true; 1489 1.8 christos return false; 1490 1.1 christos } 1491 1.1 christos 1492 1.1 christos /* Add the default list of symbols to exclude. */ 1493 1.1 christos 1494 1.1 christos static void 1495 1.1 christos set_default_excludes (void) 1496 1.1 christos { 1497 1.1 christos add_excludes (default_excludes); 1498 1.1 christos } 1499 1.1 christos 1500 1.1 christos /* Choose which symbols to export. */ 1501 1.1 christos 1502 1.1 christos static long 1503 1.1 christos filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size) 1504 1.1 christos { 1505 1.1 christos bfd_byte *from, *fromend, *to; 1506 1.1 christos asymbol *store; 1507 1.1 christos 1508 1.1 christos store = bfd_make_empty_symbol (abfd); 1509 1.1 christos if (store == NULL) 1510 1.1 christos bfd_fatal (bfd_get_filename (abfd)); 1511 1.1 christos 1512 1.1 christos from = (bfd_byte *) minisyms; 1513 1.1 christos fromend = from + symcount * size; 1514 1.1 christos to = (bfd_byte *) minisyms; 1515 1.1 christos 1516 1.1 christos for (; from < fromend; from += size) 1517 1.1 christos { 1518 1.1 christos int keep = 0; 1519 1.1 christos asymbol *sym; 1520 1.1 christos 1521 1.8 christos sym = bfd_minisymbol_to_symbol (abfd, false, (const void *) from, store); 1522 1.1 christos if (sym == NULL) 1523 1.1 christos bfd_fatal (bfd_get_filename (abfd)); 1524 1.1 christos 1525 1.1 christos /* Check for external and defined only symbols. */ 1526 1.1 christos keep = (((sym->flags & BSF_GLOBAL) != 0 1527 1.1 christos || (sym->flags & BSF_WEAK) != 0 1528 1.1 christos || bfd_is_com_section (sym->section)) 1529 1.1 christos && ! bfd_is_und_section (sym->section)); 1530 1.1 christos 1531 1.1 christos keep = keep && ! match_exclude (sym->name); 1532 1.1 christos 1533 1.1 christos if (keep) 1534 1.1 christos { 1535 1.1 christos memcpy (to, from, size); 1536 1.1 christos to += size; 1537 1.1 christos } 1538 1.1 christos } 1539 1.1 christos 1540 1.1 christos return (to - (bfd_byte *) minisyms) / size; 1541 1.1 christos } 1542 1.1 christos 1543 1.1 christos /* Export all symbols in ABFD, except for ones we were told not to 1544 1.1 christos export. */ 1545 1.1 christos 1546 1.1 christos static void 1547 1.1 christos scan_all_symbols (bfd *abfd) 1548 1.1 christos { 1549 1.1 christos long symcount; 1550 1.1 christos void *minisyms; 1551 1.1 christos unsigned int size; 1552 1.1 christos 1553 1.1 christos /* Ignore bfds with an import descriptor table. We assume that any 1554 1.1 christos such BFD contains symbols which are exported from another DLL, 1555 1.1 christos and we don't want to reexport them from here. */ 1556 1.1 christos if (bfd_get_section_by_name (abfd, ".idata$4")) 1557 1.1 christos return; 1558 1.1 christos 1559 1.1 christos if (! (bfd_get_file_flags (abfd) & HAS_SYMS)) 1560 1.1 christos { 1561 1.1 christos /* xgettext:c-format */ 1562 1.1 christos non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 1563 1.1 christos return; 1564 1.1 christos } 1565 1.1 christos 1566 1.8 christos symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size); 1567 1.1 christos if (symcount < 0) 1568 1.1 christos bfd_fatal (bfd_get_filename (abfd)); 1569 1.1 christos 1570 1.1 christos if (symcount == 0) 1571 1.1 christos { 1572 1.1 christos /* xgettext:c-format */ 1573 1.1 christos non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 1574 1.1 christos return; 1575 1.1 christos } 1576 1.1 christos 1577 1.1 christos /* Discard the symbols we don't want to export. It's OK to do this 1578 1.1 christos in place; we'll free the storage anyway. */ 1579 1.1 christos 1580 1.1 christos symcount = filter_symbols (abfd, minisyms, symcount, size); 1581 1.1 christos scan_filtered_symbols (abfd, minisyms, symcount, size); 1582 1.1 christos 1583 1.1 christos free (minisyms); 1584 1.1 christos } 1585 1.1 christos 1586 1.1 christos /* Look at the object file to decide which symbols to export. */ 1587 1.1 christos 1588 1.1 christos static void 1589 1.1 christos scan_open_obj_file (bfd *abfd) 1590 1.1 christos { 1591 1.1 christos if (export_all_symbols) 1592 1.1 christos scan_all_symbols (abfd); 1593 1.1 christos else 1594 1.1 christos scan_drectve_symbols (abfd); 1595 1.1 christos 1596 1.1 christos /* FIXME: we ought to read in and block out the base relocations. */ 1597 1.1 christos 1598 1.1 christos /* xgettext:c-format */ 1599 1.1 christos inform (_("Done reading %s"), bfd_get_filename (abfd)); 1600 1.1 christos } 1601 1.1 christos 1602 1.1 christos static void 1603 1.1 christos scan_obj_file (const char *filename) 1604 1.1 christos { 1605 1.1 christos bfd * f = bfd_openr (filename, 0); 1606 1.1 christos 1607 1.1 christos if (!f) 1608 1.1 christos /* xgettext:c-format */ 1609 1.1 christos fatal (_("Unable to open object file: %s: %s"), filename, bfd_get_errmsg ()); 1610 1.1 christos 1611 1.1 christos /* xgettext:c-format */ 1612 1.1 christos inform (_("Scanning object file %s"), filename); 1613 1.1 christos 1614 1.1 christos if (bfd_check_format (f, bfd_archive)) 1615 1.1 christos { 1616 1.1 christos bfd *arfile = bfd_openr_next_archived_file (f, 0); 1617 1.1 christos while (arfile) 1618 1.1 christos { 1619 1.3 christos bfd *next; 1620 1.1 christos if (bfd_check_format (arfile, bfd_object)) 1621 1.1 christos scan_open_obj_file (arfile); 1622 1.3 christos next = bfd_openr_next_archived_file (f, arfile); 1623 1.1 christos bfd_close (arfile); 1624 1.3 christos /* PR 17512: file: 58715298. */ 1625 1.3 christos if (next == arfile) 1626 1.3 christos break; 1627 1.3 christos arfile = next; 1628 1.1 christos } 1629 1.1 christos 1630 1.1 christos #ifdef DLLTOOL_MCORE_ELF 1631 1.1 christos if (mcore_elf_out_file) 1632 1.10 christos inform (_("Cannot produce mcore-elf dll from archive file: %s"), 1633 1.10 christos filename); 1634 1.1 christos #endif 1635 1.1 christos } 1636 1.1 christos else if (bfd_check_format (f, bfd_object)) 1637 1.1 christos { 1638 1.1 christos scan_open_obj_file (f); 1639 1.1 christos 1640 1.1 christos #ifdef DLLTOOL_MCORE_ELF 1641 1.1 christos if (mcore_elf_out_file) 1642 1.1 christos mcore_elf_cache_filename (filename); 1643 1.1 christos #endif 1644 1.1 christos } 1645 1.1 christos 1646 1.1 christos bfd_close (f); 1647 1.1 christos } 1648 1.1 christos 1649 1.1 christos 1650 1.1 christos static void 1652 1.1 christos dump_def_info (FILE *f) 1653 1.1 christos { 1654 1.1 christos int i; 1655 1.1 christos export_type *exp; 1656 1.1 christos fprintf (f, "%s ", ASM_C); 1657 1.1 christos for (i = 0; oav[i]; i++) 1658 1.1 christos fprintf (f, "%s ", oav[i]); 1659 1.1 christos fprintf (f, "\n"); 1660 1.1 christos for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 1661 1.1 christos { 1662 1.1 christos fprintf (f, "%s %d = %s %s @ %d %s%s%s%s%s%s\n", 1663 1.1 christos ASM_C, 1664 1.1 christos i, 1665 1.1 christos exp->name, 1666 1.1 christos exp->internal_name, 1667 1.1 christos exp->ordinal, 1668 1.1 christos exp->noname ? "NONAME " : "", 1669 1.1 christos exp->private ? "PRIVATE " : "", 1670 1.1 christos exp->constant ? "CONSTANT" : "", 1671 1.1 christos exp->data ? "DATA" : "", 1672 1.1 christos exp->its_name ? " ==" : "", 1673 1.1 christos exp->its_name ? exp->its_name : ""); 1674 1.1 christos } 1675 1.1 christos } 1676 1.1 christos 1677 1.1 christos /* Generate the .exp file. */ 1678 1.1 christos 1679 1.1 christos static int 1680 1.1 christos sfunc (const void *a, const void *b) 1681 1.1 christos { 1682 1.1 christos if (*(const bfd_vma *) a == *(const bfd_vma *) b) 1683 1.1 christos return 0; 1684 1.1 christos 1685 1.1 christos return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1); 1686 1.1 christos } 1687 1.1 christos 1688 1.1 christos static void 1689 1.1 christos flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page) 1690 1.1 christos { 1691 1.1 christos int i; 1692 1.1 christos 1693 1.1 christos /* Flush this page. */ 1694 1.1 christos fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n", 1695 1.1 christos ASM_LONG, 1696 1.1 christos (int) page_addr, 1697 1.1 christos ASM_C); 1698 1.1 christos fprintf (f, "\t%s\t0x%x\t%s Size of block\n", 1699 1.1 christos ASM_LONG, 1700 1.1 christos (on_page * 2) + (on_page & 1) * 2 + 8, 1701 1.1 christos ASM_C); 1702 1.1 christos 1703 1.1 christos for (i = 0; i < on_page; i++) 1704 1.1 christos { 1705 1.1 christos bfd_vma needed = need[i]; 1706 1.1 christos 1707 1.10 christos if (needed) 1708 1.1 christos { 1709 1.1 christos if (!create_for_pep) 1710 1.1 christos { 1711 1.1 christos /* Relocation via HIGHLOW. */ 1712 1.1 christos needed = ((needed - page_addr) | 0x3000) & 0xffff; 1713 1.1 christos } 1714 1.1 christos else 1715 1.1 christos { 1716 1.1 christos /* Relocation via DIR64. */ 1717 1.1 christos needed = ((needed - page_addr) | 0xa000) & 0xffff; 1718 1.1 christos } 1719 1.1 christos } 1720 1.1 christos 1721 1.1 christos fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed); 1722 1.1 christos } 1723 1.1 christos 1724 1.1 christos /* And padding */ 1725 1.1 christos if (on_page & 1) 1726 1.1 christos fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000); 1727 1.1 christos } 1728 1.1 christos 1729 1.1 christos static void 1730 1.1 christos gen_def_file (void) 1731 1.1 christos { 1732 1.1 christos int i; 1733 1.1 christos export_type *exp; 1734 1.1 christos 1735 1.1 christos inform (_("Adding exports to output file")); 1736 1.1 christos 1737 1.1 christos fprintf (output_def, ";"); 1738 1.1 christos for (i = 0; oav[i]; i++) 1739 1.1 christos fprintf (output_def, " %s", oav[i]); 1740 1.1 christos 1741 1.1 christos fprintf (output_def, "\nEXPORTS\n"); 1742 1.1 christos 1743 1.1 christos for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 1744 1.1 christos { 1745 1.1 christos char *quote = strchr (exp->name, '.') ? "\"" : ""; 1746 1.1 christos char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS); 1747 1.1 christos 1748 1.1 christos if (res) 1749 1.10 christos { 1750 1.1 christos fprintf (output_def, ";\t%s\n", res); 1751 1.1 christos free (res); 1752 1.1 christos } 1753 1.1 christos 1754 1.1 christos if (strcmp (exp->name, exp->internal_name) == 0) 1755 1.1 christos { 1756 1.1 christos fprintf (output_def, "\t%s%s%s @ %d%s%s%s%s%s\n", 1757 1.1 christos quote, 1758 1.1 christos exp->name, 1759 1.1 christos quote, 1760 1.1 christos exp->ordinal, 1761 1.1 christos exp->noname ? " NONAME" : "", 1762 1.1 christos exp->private ? "PRIVATE " : "", 1763 1.1 christos exp->data ? " DATA" : "", 1764 1.1 christos exp->its_name ? " ==" : "", 1765 1.1 christos exp->its_name ? exp->its_name : ""); 1766 1.1 christos } 1767 1.1 christos else 1768 1.1 christos { 1769 1.1 christos char * quote1 = strchr (exp->internal_name, '.') ? "\"" : ""; 1770 1.1 christos /* char *alias = */ 1771 1.1 christos fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n", 1772 1.1 christos quote, 1773 1.1 christos exp->name, 1774 1.1 christos quote, 1775 1.1 christos quote1, 1776 1.1 christos exp->internal_name, 1777 1.1 christos quote1, 1778 1.1 christos exp->ordinal, 1779 1.1 christos exp->noname ? " NONAME" : "", 1780 1.1 christos exp->private ? "PRIVATE " : "", 1781 1.1 christos exp->data ? " DATA" : "", 1782 1.1 christos exp->its_name ? " ==" : "", 1783 1.1 christos exp->its_name ? exp->its_name : ""); 1784 1.1 christos } 1785 1.1 christos } 1786 1.1 christos 1787 1.1 christos inform (_("Added exports to output file")); 1788 1.1 christos } 1789 1.1 christos 1790 1.1 christos /* generate_idata_ofile generates the portable assembly source code 1791 1.1 christos for the idata sections. It appends the source code to the end of 1792 1.1 christos the file. */ 1793 1.1 christos 1794 1.1 christos static void 1795 1.1 christos generate_idata_ofile (FILE *filvar) 1796 1.1 christos { 1797 1.1 christos iheadtype *headptr; 1798 1.1 christos ifunctype *funcptr; 1799 1.1 christos int headindex; 1800 1.1 christos int funcindex; 1801 1.1 christos int nheads; 1802 1.1 christos 1803 1.1 christos if (import_list == NULL) 1804 1.1 christos return; 1805 1.1 christos 1806 1.1 christos fprintf (filvar, "%s Import data sections\n", ASM_C); 1807 1.1 christos fprintf (filvar, "\n\t.section\t.idata$2\n"); 1808 1.1 christos fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL); 1809 1.1 christos fprintf (filvar, "doi_idata:\n"); 1810 1.1 christos 1811 1.1 christos nheads = 0; 1812 1.1 christos for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1813 1.1 christos { 1814 1.1 christos fprintf (filvar, "\t%slistone%d%s\t%s %s\n", 1815 1.1 christos ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER, 1816 1.1 christos ASM_C, headptr->dllname); 1817 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1818 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1819 1.1 christos fprintf (filvar, "\t%sdllname%d%s\n", 1820 1.1 christos ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER); 1821 1.1 christos fprintf (filvar, "\t%slisttwo%d%s\n\n", 1822 1.1 christos ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER); 1823 1.1 christos nheads++; 1824 1.1 christos } 1825 1.1 christos 1826 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */ 1827 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */ 1828 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */ 1829 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1830 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1831 1.1 christos 1832 1.1 christos fprintf (filvar, "\n\t.section\t.idata$4\n"); 1833 1.1 christos headindex = 0; 1834 1.1 christos for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1835 1.1 christos { 1836 1.1 christos fprintf (filvar, "listone%d:\n", headindex); 1837 1.10 christos for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++) 1838 1.1 christos { 1839 1.1 christos if (create_for_pep) 1840 1.1 christos fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n", 1841 1.1 christos ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER, 1842 1.1 christos ASM_LONG); 1843 1.1 christos else 1844 1.1 christos fprintf (filvar, "\t%sfuncptr%d_%d%s\n", 1845 1.10 christos ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER); 1846 1.1 christos } 1847 1.1 christos if (create_for_pep) 1848 1.1 christos fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 1849 1.1 christos else 1850 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 1851 1.1 christos headindex++; 1852 1.1 christos } 1853 1.1 christos 1854 1.1 christos fprintf (filvar, "\n\t.section\t.idata$5\n"); 1855 1.1 christos headindex = 0; 1856 1.1 christos for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1857 1.1 christos { 1858 1.1 christos fprintf (filvar, "listtwo%d:\n", headindex); 1859 1.10 christos for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++) 1860 1.1 christos { 1861 1.1 christos if (create_for_pep) 1862 1.1 christos fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n", 1863 1.1 christos ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER, 1864 1.1 christos ASM_LONG); 1865 1.1 christos else 1866 1.1 christos fprintf (filvar, "\t%sfuncptr%d_%d%s\n", 1867 1.10 christos ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER); 1868 1.1 christos } 1869 1.1 christos if (create_for_pep) 1870 1.1 christos fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 1871 1.1 christos else 1872 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 1873 1.1 christos headindex++; 1874 1.1 christos } 1875 1.1 christos 1876 1.1 christos fprintf (filvar, "\n\t.section\t.idata$6\n"); 1877 1.1 christos headindex = 0; 1878 1.1 christos for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1879 1.1 christos { 1880 1.1 christos funcindex = 0; 1881 1.1 christos for (funcptr = headptr->funchead; funcptr != NULL; 1882 1.1 christos funcptr = funcptr->next) 1883 1.10 christos { 1884 1.10 christos fprintf (filvar, "funcptr%d_%d:\n", headindex, funcindex); 1885 1.10 christos fprintf (filvar, "\t%s\t%d\n", ASM_SHORT, funcptr->ord & 0xFFFF); 1886 1.10 christos fprintf (filvar, "\t%s\t\"%s\"\n", ASM_TEXT, 1887 1.10 christos funcptr->its_name ? funcptr->its_name : funcptr->name); 1888 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_BYTE); 1889 1.1 christos funcindex++; 1890 1.1 christos } 1891 1.1 christos headindex++; 1892 1.1 christos } 1893 1.1 christos 1894 1.1 christos fprintf (filvar, "\n\t.section\t.idata$7\n"); 1895 1.1 christos headindex = 0; 1896 1.1 christos for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1897 1.10 christos { 1898 1.10 christos fprintf (filvar, "dllname%d:\n", headindex); 1899 1.10 christos fprintf (filvar, "\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname); 1900 1.1 christos fprintf (filvar, "\t%s\t0\n", ASM_BYTE); 1901 1.1 christos headindex++; 1902 1.1 christos } 1903 1.1 christos } 1904 1.1 christos 1905 1.1 christos /* Assemble the specified file. */ 1906 1.1 christos static void 1907 1.1 christos assemble_file (const char * source, const char * dest) 1908 1.10 christos { 1909 1.10 christos char *cmd = xasprintf ("%s %s -o %s %s", 1910 1.1 christos ASM_SWITCHES, as_flags, dest, source); 1911 1.5 christos run (as_name, cmd); 1912 1.1 christos free (cmd); 1913 1.1 christos } 1914 1.3 christos 1915 1.3 christos static const char * temp_file_to_remove[5]; 1916 1.3 christos #define TEMP_EXPORT_FILE 0 1917 1.3 christos #define TEMP_HEAD_FILE 1 1918 1.3 christos #define TEMP_TAIL_FILE 2 1919 1.3 christos #define TEMP_HEAD_O_FILE 3 1920 1.3 christos #define TEMP_TAIL_O_FILE 4 1921 1.3 christos 1922 1.3 christos static void 1923 1.3 christos unlink_temp_files (void) 1924 1.3 christos { 1925 1.3 christos unsigned i; 1926 1.3 christos 1927 1.3 christos if (dontdeltemps > 0) 1928 1.3 christos return; 1929 1.3 christos 1930 1.3 christos for (i = 0; i < ARRAY_SIZE (temp_file_to_remove); i++) 1931 1.3 christos { 1932 1.3 christos if (temp_file_to_remove[i]) 1933 1.3 christos { 1934 1.3 christos unlink (temp_file_to_remove[i]); 1935 1.3 christos temp_file_to_remove[i] = NULL; 1936 1.3 christos } 1937 1.3 christos } 1938 1.3 christos } 1939 1.1 christos 1940 1.1 christos static void 1941 1.1 christos gen_exp_file (void) 1942 1.1 christos { 1943 1.1 christos FILE *f; 1944 1.1 christos int i; 1945 1.1 christos export_type *exp; 1946 1.1 christos dlist_type *dl; 1947 1.1 christos 1948 1.1 christos /* xgettext:c-format */ 1949 1.1 christos inform (_("Generating export file: %s"), exp_name); 1950 1.1 christos 1951 1.1 christos f = fopen (TMP_ASM, FOPEN_WT); 1952 1.1 christos if (!f) 1953 1.1 christos /* xgettext:c-format */ 1954 1.1 christos fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM); 1955 1.3 christos 1956 1.3 christos temp_file_to_remove[TEMP_EXPORT_FILE] = TMP_ASM; 1957 1.1 christos 1958 1.1 christos /* xgettext:c-format */ 1959 1.1 christos inform (_("Opened temporary file: %s"), TMP_ASM); 1960 1.1 christos 1961 1.1 christos dump_def_info (f); 1962 1.1 christos 1963 1.1 christos if (d_exports) 1964 1.1 christos { 1965 1.1 christos fprintf (f, "\t.section .edata\n\n"); 1966 1.1 christos fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C); 1967 1.1 christos fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, 1968 1.1 christos (unsigned long) time(0), ASM_C); 1969 1.10 christos fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C); 1970 1.10 christos fprintf (f, "\t%sname%s %s Ptr to name of dll\n", 1971 1.10 christos ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1972 1.10 christos fprintf (f, "\t%s %d %s Starting ordinal of exports\n", 1973 1.1 christos ASM_LONG, d_low_ord, ASM_C); 1974 1.1 christos 1975 1.10 christos 1976 1.10 christos fprintf (f, "\t%s %d %s Number of functions\n", 1977 1.10 christos ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C); 1978 1.10 christos fprintf (f, "\t%s named funcs %d, low ord %d, high ord %d\n", 1979 1.1 christos ASM_C, d_named_nfuncs, d_low_ord, d_high_ord); 1980 1.10 christos fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, 1981 1.10 christos show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, 1982 1.10 christos ASM_C); 1983 1.10 christos fprintf (f, "\t%safuncs%s %s Address of functions\n", 1984 1.1 christos ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1985 1.1 christos 1986 1.1 christos fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n", 1987 1.1 christos ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1988 1.10 christos 1989 1.10 christos fprintf (f, "\t%sanords%s %s Address of ordinals\n", 1990 1.1 christos ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1991 1.1 christos 1992 1.1 christos fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name); 1993 1.1 christos 1994 1.10 christos 1995 1.10 christos fprintf (f, "%s Export address Table\n", ASM_C); 1996 1.1 christos fprintf (f, "\t%s\n", ASM_ALIGN_LONG); 1997 1.1 christos fprintf (f, "afuncs:\n"); 1998 1.1 christos i = d_low_ord; 1999 1.1 christos 2000 1.1 christos for (exp = d_exports; exp; exp = exp->next) 2001 1.1 christos { 2002 1.1 christos if (exp->ordinal != i) 2003 1.1 christos { 2004 1.1 christos while (i < exp->ordinal) 2005 1.10 christos { 2006 1.1 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2007 1.1 christos i++; 2008 1.1 christos } 2009 1.1 christos } 2010 1.1 christos 2011 1.1 christos if (exp->forward == 0) 2012 1.1 christos { 2013 1.1 christos if (exp->internal_name[0] == '@') 2014 1.1 christos fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE, 2015 1.1 christos exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); 2016 1.1 christos else 2017 1.1 christos fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE, 2018 1.1 christos ASM_PREFIX (exp->internal_name), 2019 1.1 christos exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); 2020 1.1 christos } 2021 1.1 christos else 2022 1.1 christos fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE, 2023 1.1 christos exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal); 2024 1.1 christos i++; 2025 1.1 christos } 2026 1.10 christos 2027 1.1 christos fprintf (f, "%s Export Name Pointer Table\n", ASM_C); 2028 1.1 christos fprintf (f, "anames:\n"); 2029 1.1 christos 2030 1.1 christos for (i = 0; (exp = d_exports_lexically[i]); i++) 2031 1.1 christos { 2032 1.1 christos if (!exp->noname || show_allnames) 2033 1.1 christos fprintf (f, "\t%sn%d%s\n", 2034 1.1 christos ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER); 2035 1.1 christos } 2036 1.10 christos 2037 1.1 christos fprintf (f, "%s Export Ordinal Table\n", ASM_C); 2038 1.1 christos fprintf (f, "anords:\n"); 2039 1.1 christos for (i = 0; (exp = d_exports_lexically[i]); i++) 2040 1.1 christos { 2041 1.1 christos if (!exp->noname || show_allnames) 2042 1.1 christos fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord); 2043 1.1 christos } 2044 1.10 christos 2045 1.1 christos fprintf (f, "%s Export Name Table\n", ASM_C); 2046 1.1 christos for (i = 0; (exp = d_exports_lexically[i]); i++) 2047 1.1 christos { 2048 1.10 christos if (!exp->noname || show_allnames) 2049 1.10 christos { 2050 1.10 christos const char *xname = (exp->its_name ? exp->its_name 2051 1.10 christos : xlate (exp->name)); 2052 1.10 christos fprintf (f, "n%d: %s \"%s\"\n", 2053 1.10 christos exp->ordinal, ASM_TEXT, xname); 2054 1.10 christos if (!exp->its_name) 2055 1.10 christos free ((char *) xname); 2056 1.1 christos } 2057 1.1 christos if (exp->forward != 0) 2058 1.1 christos fprintf (f, "f%d: %s \"%s\"\n", 2059 1.1 christos exp->forward, ASM_TEXT, exp->internal_name); 2060 1.1 christos } 2061 1.1 christos 2062 1.1 christos if (a_list) 2063 1.1 christos { 2064 1.1 christos fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME); 2065 1.1 christos for (dl = a_list; dl; dl = dl->next) 2066 1.1 christos { 2067 1.1 christos fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text); 2068 1.1 christos } 2069 1.1 christos } 2070 1.1 christos 2071 1.1 christos if (d_list) 2072 1.1 christos { 2073 1.1 christos fprintf (f, "\t.section .rdata\n"); 2074 1.1 christos for (dl = d_list; dl; dl = dl->next) 2075 1.10 christos { 2076 1.1 christos const char *p; 2077 1.1 christos int l; 2078 1.1 christos 2079 1.10 christos /* We don't output as ascii because there can 2080 1.1 christos be quote characters in the string. */ 2081 1.1 christos l = 0; 2082 1.1 christos for (p = dl->text; *p; p++) 2083 1.1 christos { 2084 1.1 christos if (l == 0) 2085 1.1 christos fprintf (f, "\t%s\t", ASM_BYTE); 2086 1.1 christos else 2087 1.1 christos fprintf (f, ","); 2088 1.1 christos fprintf (f, "%d", *p); 2089 1.1 christos if (p[1] == 0) 2090 1.1 christos { 2091 1.1 christos fprintf (f, ",0\n"); 2092 1.1 christos break; 2093 1.1 christos } 2094 1.1 christos if (++l == 10) 2095 1.1 christos { 2096 1.1 christos fprintf (f, "\n"); 2097 1.1 christos l = 0; 2098 1.1 christos } 2099 1.1 christos } 2100 1.1 christos } 2101 1.1 christos } 2102 1.1 christos } 2103 1.1 christos 2104 1.1 christos /* Add to the output file a way of getting to the exported names 2105 1.1 christos without using the import library. */ 2106 1.1 christos if (add_indirect) 2107 1.1 christos { 2108 1.1 christos fprintf (f, "\t.section\t.rdata\n"); 2109 1.1 christos for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 2110 1.1 christos if (!exp->noname || show_allnames) 2111 1.1 christos { 2112 1.10 christos /* We use a single underscore for MS compatibility, and a 2113 1.10 christos double underscore for backward compatibility with old 2114 1.1 christos cygwin releases. */ 2115 1.1 christos if (create_compat_implib) 2116 1.1 christos fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name); 2117 1.10 christos fprintf (f, "\t%s\t_imp_%s%s\n", ASM_GLOBAL, 2118 1.1 christos leading_underscore, exp->name); 2119 1.1 christos if (create_compat_implib) 2120 1.10 christos fprintf (f, "__imp_%s:\n", exp->name); 2121 1.1 christos fprintf (f, "_imp_%s%s:\n", leading_underscore, exp->name); 2122 1.1 christos fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name); 2123 1.1 christos } 2124 1.1 christos } 2125 1.1 christos 2126 1.1 christos /* Dump the reloc section if a base file is provided. */ 2127 1.1 christos if (base_file) 2128 1.1 christos { 2129 1.1 christos bfd_vma addr; 2130 1.1 christos bfd_vma need[COFF_PAGE_SIZE]; 2131 1.1 christos bfd_vma page_addr; 2132 1.1 christos bfd_size_type numbytes; 2133 1.1 christos int num_entries; 2134 1.1 christos bfd_vma *copy; 2135 1.1 christos int j; 2136 1.1 christos int on_page; 2137 1.1 christos fprintf (f, "\t.section\t.init\n"); 2138 1.1 christos fprintf (f, "lab:\n"); 2139 1.1 christos 2140 1.1 christos fseek (base_file, 0, SEEK_END); 2141 1.1 christos numbytes = ftell (base_file); 2142 1.1 christos fseek (base_file, 0, SEEK_SET); 2143 1.1 christos copy = xmalloc (numbytes); 2144 1.1 christos if (fread (copy, 1, numbytes, base_file) < numbytes) 2145 1.1 christos fatal (_("failed to read the number of entries from base file")); 2146 1.1 christos num_entries = numbytes / sizeof (bfd_vma); 2147 1.1 christos 2148 1.1 christos fprintf (f, "\t.section\t.reloc\n"); 2149 1.1 christos if (num_entries) 2150 1.1 christos { 2151 1.1 christos int src; 2152 1.1 christos int dst = 0; 2153 1.1 christos bfd_vma last = (bfd_vma) -1; 2154 1.1 christos qsort (copy, num_entries, sizeof (bfd_vma), sfunc); 2155 1.1 christos /* Delete duplicates */ 2156 1.1 christos for (src = 0; src < num_entries; src++) 2157 1.1 christos { 2158 1.1 christos if (last != copy[src]) 2159 1.1 christos last = copy[dst++] = copy[src]; 2160 1.1 christos } 2161 1.1 christos num_entries = dst; 2162 1.1 christos addr = copy[0]; 2163 1.1 christos page_addr = addr & PAGE_MASK; /* work out the page addr */ 2164 1.1 christos on_page = 0; 2165 1.1 christos for (j = 0; j < num_entries; j++) 2166 1.1 christos { 2167 1.1 christos addr = copy[j]; 2168 1.1 christos if ((addr & PAGE_MASK) != page_addr) 2169 1.1 christos { 2170 1.1 christos flush_page (f, need, page_addr, on_page); 2171 1.1 christos on_page = 0; 2172 1.1 christos page_addr = addr & PAGE_MASK; 2173 1.1 christos } 2174 1.1 christos need[on_page++] = addr; 2175 1.1 christos } 2176 1.10 christos flush_page (f, need, page_addr, on_page); 2177 1.10 christos #if 0 2178 1.10 christos fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C); 2179 1.1 christos #endif 2180 1.10 christos } 2181 1.1 christos free (copy); 2182 1.1 christos } 2183 1.1 christos 2184 1.1 christos generate_idata_ofile (f); 2185 1.1 christos 2186 1.1 christos fclose (f); 2187 1.1 christos 2188 1.1 christos /* Assemble the file. */ 2189 1.1 christos assemble_file (TMP_ASM, exp_name); 2190 1.1 christos 2191 1.3 christos if (dontdeltemps == 0) 2192 1.3 christos { 2193 1.3 christos temp_file_to_remove[TEMP_EXPORT_FILE] = NULL; 2194 1.3 christos unlink (TMP_ASM); 2195 1.1 christos } 2196 1.1 christos 2197 1.1 christos inform (_("Generated exports file")); 2198 1.1 christos } 2199 1.10 christos 2200 1.1 christos static char * 2201 1.1 christos xlate (const char *name) 2202 1.10 christos { 2203 1.10 christos int lead_at = *name == '@'; 2204 1.10 christos int is_stdcall = !lead_at && strchr (name, '@') != NULL; 2205 1.1 christos char *copy; 2206 1.1 christos 2207 1.1 christos if (!lead_at && (add_underscore 2208 1.10 christos || (add_stdcall_underscore && is_stdcall))) 2209 1.10 christos copy = xasprintf ("_%s", name); 2210 1.10 christos else 2211 1.1 christos copy = xstrdup (name + (killat ? lead_at : 0)); 2212 1.1 christos 2213 1.1 christos if (killat) 2214 1.1 christos { 2215 1.10 christos /* PR 9766: Look for the last @ sign in the name. */ 2216 1.1 christos char *p = strrchr (copy, '@'); 2217 1.1 christos if (p && ISDIGIT (p[1])) 2218 1.1 christos *p = 0; 2219 1.10 christos } 2220 1.1 christos return copy; 2221 1.1 christos } 2222 1.1 christos 2223 1.1 christos typedef struct 2224 1.1 christos { 2225 1.1 christos int id; 2226 1.1 christos const char *name; 2227 1.1 christos int flags; 2228 1.1 christos int align; 2229 1.1 christos asection *sec; 2230 1.1 christos asymbol *sym; 2231 1.1 christos asymbol **sympp; 2232 1.1 christos int size; 2233 1.1 christos unsigned char *data; 2234 1.1 christos } sinfo; 2235 1.3 christos 2236 1.10 christos #define INIT_SEC_DATA(id, name, flags, align) \ 2237 1.3 christos { id, name, flags, align, NULL, NULL, NULL, 0, NULL } 2238 1.1 christos 2239 1.1 christos #define TEXT 0 2240 1.1 christos #define DATA 1 2241 1.1 christos #define BSS 2 2242 1.1 christos #define IDATA7 3 2243 1.1 christos #define IDATA5 4 2244 1.1 christos #define IDATA4 5 2245 1.1 christos #define IDATA6 6 2246 1.1 christos 2247 1.1 christos #define NSECS 7 2248 1.1 christos 2249 1.10 christos #define TEXT_SEC_FLAGS \ 2250 1.1 christos (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS) 2251 1.1 christos #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA) 2252 1.1 christos #define BSS_SEC_FLAGS SEC_ALLOC 2253 1.10 christos 2254 1.1 christos static sinfo secdata_plain[NSECS] = 2255 1.1 christos { 2256 1.1 christos INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), 2257 1.1 christos INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), 2258 1.1 christos INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2), 2259 1.1 christos INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2), 2260 1.1 christos INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2), 2261 1.1 christos INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2), 2262 1.1 christos INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1) 2263 1.1 christos }; 2264 1.10 christos 2265 1.10 christos static sinfo secdata_delay[NSECS] = 2266 1.10 christos { 2267 1.10 christos INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), 2268 1.10 christos INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), 2269 1.10 christos INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2), 2270 1.10 christos INIT_SEC_DATA (IDATA7, ".didat$7", SEC_HAS_CONTENTS, 2), 2271 1.10 christos INIT_SEC_DATA (IDATA5, ".didat$5", SEC_HAS_CONTENTS, 2), 2272 1.10 christos INIT_SEC_DATA (IDATA4, ".didat$4", SEC_HAS_CONTENTS, 2), 2273 1.10 christos INIT_SEC_DATA (IDATA6, ".didat$6", SEC_HAS_CONTENTS, 1) 2274 1.10 christos }; 2275 1.1 christos 2276 1.1 christos /* This is what we're trying to make. We generate the imp symbols with 2277 1.1 christos both single and double underscores, for compatibility. 2278 1.1 christos 2279 1.1 christos .text 2280 1.1 christos .global _GetFileVersionInfoSizeW@8 2281 1.1 christos .global __imp_GetFileVersionInfoSizeW@8 2282 1.1 christos _GetFileVersionInfoSizeW@8: 2283 1.1 christos jmp * __imp_GetFileVersionInfoSizeW@8 2284 1.1 christos .section .idata$7 # To force loading of head 2285 1.1 christos .long __version_a_head 2286 1.1 christos # Import Address Table 2287 1.1 christos .section .idata$5 2288 1.1 christos __imp_GetFileVersionInfoSizeW@8: 2289 1.1 christos .rva ID2 2290 1.1 christos 2291 1.1 christos # Import Lookup Table 2292 1.1 christos .section .idata$4 2293 1.1 christos .rva ID2 2294 1.1 christos # Hint/Name table 2295 1.1 christos .section .idata$6 2296 1.8 christos ID2: .short 2 2297 1.1 christos .asciz "GetFileVersionInfoSizeW" */ 2298 1.1 christos 2299 1.1 christos static char * 2300 1.1 christos make_label (const char *prefix, const char *name) 2301 1.1 christos { 2302 1.1 christos int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); 2303 1.1 christos char *copy = xmalloc (len + 1); 2304 1.1 christos 2305 1.1 christos strcpy (copy, ASM_PREFIX (name)); 2306 1.1 christos strcat (copy, prefix); 2307 1.1 christos strcat (copy, name); 2308 1.1 christos return copy; 2309 1.1 christos } 2310 1.1 christos 2311 1.10 christos static char * 2312 1.1 christos make_imp_label (bfd *abfd, const char *prefix, const char *name) 2313 1.1 christos { 2314 1.1 christos int len; 2315 1.1 christos char *copy; 2316 1.1 christos 2317 1.1 christos if (name[0] == '@') 2318 1.1 christos { 2319 1.10 christos len = strlen (prefix) + strlen (name); 2320 1.1 christos copy = bfd_xalloc (abfd, len + 1); 2321 1.1 christos strcpy (copy, prefix); 2322 1.1 christos strcat (copy, name); 2323 1.1 christos } 2324 1.1 christos else 2325 1.1 christos { 2326 1.10 christos len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); 2327 1.1 christos copy = bfd_xalloc (abfd, len + 1); 2328 1.1 christos strcpy (copy, prefix); 2329 1.1 christos strcat (copy, ASM_PREFIX (name)); 2330 1.1 christos strcat (copy, name); 2331 1.1 christos } 2332 1.1 christos return copy; 2333 1.1 christos } 2334 1.1 christos 2335 1.1 christos static bfd * 2336 1.1 christos make_one_lib_file (export_type *exp, int i, int delay) 2337 1.10 christos { 2338 1.10 christos sinfo *const secdata = delay ? secdata_delay : secdata_plain; 2339 1.10 christos char *outname = TMP_STUB; 2340 1.10 christos size_t name_len = strlen (outname); 2341 1.1 christos sprintf (outname + name_len - 7, "%05d.o", i); 2342 1.10 christos 2343 1.1 christos bfd *abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET); 2344 1.1 christos if (!abfd) 2345 1.1 christos /* xgettext:c-format */ 2346 1.1 christos fatal (_("bfd_open failed open stub file: %s: %s"), 2347 1.1 christos outname, bfd_get_errmsg ()); 2348 1.1 christos 2349 1.1 christos /* xgettext:c-format */ 2350 1.1 christos inform (_("Creating stub file: %s"), outname); 2351 1.1 christos 2352 1.1 christos bfd_set_format (abfd, bfd_object); 2353 1.1 christos bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0); 2354 1.1 christos 2355 1.1 christos #ifdef DLLTOOL_ARM 2356 1.1 christos if (machine == MARM_INTERWORK || machine == MTHUMB) 2357 1.1 christos bfd_set_private_flags (abfd, F_INTERWORK); 2358 1.1 christos #endif 2359 1.1 christos 2360 1.10 christos /* First make symbols for the sections. */ 2361 1.10 christos flagword applicable = bfd_applicable_section_flags (abfd); 2362 1.10 christos #ifndef EXTRA 2363 1.10 christos #define EXTRA 0 2364 1.10 christos #endif 2365 1.10 christos asymbol *ptrs[NSECS + 4 + EXTRA + 1]; 2366 1.1 christos int oidx = 0; 2367 1.1 christos for (i = 0; i < NSECS; i++) 2368 1.1 christos { 2369 1.1 christos sinfo *si = secdata + i; 2370 1.1 christos 2371 1.1 christos if (si->id != i) 2372 1.1 christos abort (); 2373 1.7 christos si->sec = bfd_make_section_old_way (abfd, si->name); 2374 1.1 christos bfd_set_section_flags (si->sec, si->flags & applicable); 2375 1.7 christos 2376 1.1 christos bfd_set_section_alignment (si->sec, si->align); 2377 1.1 christos si->sec->output_section = si->sec; 2378 1.1 christos si->sym = bfd_make_empty_symbol(abfd); 2379 1.1 christos si->sym->name = si->sec->name; 2380 1.1 christos si->sym->section = si->sec; 2381 1.1 christos si->sym->flags = BSF_LOCAL; 2382 1.1 christos si->sym->value = 0; 2383 1.1 christos ptrs[oidx] = si->sym; 2384 1.1 christos si->sympp = ptrs + oidx; 2385 1.1 christos si->size = 0; 2386 1.1 christos si->data = NULL; 2387 1.1 christos 2388 1.1 christos oidx++; 2389 1.1 christos } 2390 1.1 christos 2391 1.1 christos if (! exp->data) 2392 1.10 christos { 2393 1.10 christos asymbol *exp_label = bfd_make_empty_symbol (abfd); 2394 1.8 christos exp_label->name = make_imp_label (abfd, "", exp->name); 2395 1.1 christos exp_label->section = secdata[TEXT].sec; 2396 1.1 christos exp_label->flags = BSF_GLOBAL; 2397 1.1 christos exp_label->value = 0; 2398 1.1 christos 2399 1.1 christos #ifdef DLLTOOL_ARM 2400 1.1 christos if (machine == MTHUMB) 2401 1.1 christos bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC); 2402 1.1 christos #endif 2403 1.1 christos ptrs[oidx++] = exp_label; 2404 1.1 christos } 2405 1.1 christos 2406 1.1 christos /* Generate imp symbols with one underscore for Microsoft 2407 1.1 christos compatibility, and with two underscores for backward 2408 1.10 christos compatibility with old versions of cygwin. */ 2409 1.1 christos asymbol *iname = NULL; 2410 1.1 christos if (create_compat_implib) 2411 1.1 christos { 2412 1.10 christos iname = bfd_make_empty_symbol (abfd); 2413 1.1 christos iname->name = make_imp_label (abfd, "___imp", exp->name); 2414 1.1 christos iname->section = secdata[IDATA5].sec; 2415 1.1 christos iname->flags = BSF_GLOBAL; 2416 1.1 christos iname->value = 0; 2417 1.1 christos } 2418 1.10 christos 2419 1.10 christos asymbol *iname2 = bfd_make_empty_symbol (abfd); 2420 1.1 christos iname2->name = make_imp_label (abfd, "__imp_", exp->name); 2421 1.1 christos iname2->section = secdata[IDATA5].sec; 2422 1.1 christos iname2->flags = BSF_GLOBAL; 2423 1.1 christos iname2->value = 0; 2424 1.10 christos 2425 1.1 christos asymbol *iname_lab = bfd_make_empty_symbol (abfd); 2426 1.1 christos iname_lab->name = head_label; 2427 1.1 christos iname_lab->section = bfd_und_section_ptr; 2428 1.1 christos iname_lab->flags = 0; 2429 1.1 christos iname_lab->value = 0; 2430 1.10 christos 2431 1.1 christos asymbol **iname_pp = ptrs + oidx; 2432 1.1 christos if (create_compat_implib) 2433 1.1 christos ptrs[oidx++] = iname; 2434 1.1 christos ptrs[oidx++] = iname2; 2435 1.10 christos 2436 1.1 christos asymbol **iname_lab_pp = ptrs + oidx; 2437 1.1 christos ptrs[oidx++] = iname_lab; 2438 1.1 christos 2439 1.1 christos ptrs[oidx] = 0; 2440 1.1 christos 2441 1.1 christos for (i = 0; i < NSECS; i++) 2442 1.1 christos { 2443 1.1 christos sinfo *si = secdata + i; 2444 1.1 christos asection *sec = si->sec; 2445 1.1 christos arelent *rel, *rel2 = 0, *rel3 = 0; 2446 1.1 christos arelent **rpp; 2447 1.1 christos 2448 1.1 christos switch (i) 2449 1.1 christos { 2450 1.1 christos case TEXT: 2451 1.1 christos if (! exp->data) 2452 1.9 christos { 2453 1.9 christos unsigned int rpp_len; 2454 1.1 christos 2455 1.10 christos si->size = HOW_JTAB_SIZE; 2456 1.1 christos si->data = bfd_xalloc (abfd, HOW_JTAB_SIZE); 2457 1.1 christos memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE); 2458 1.1 christos 2459 1.10 christos /* Add the reloc into idata$5. */ 2460 1.1 christos rel = bfd_xalloc (abfd, sizeof (arelent)); 2461 1.9 christos 2462 1.9 christos rpp_len = delay ? 4 : 2; 2463 1.9 christos 2464 1.9 christos if (machine == MAARCH64) 2465 1.9 christos rpp_len++; 2466 1.10 christos 2467 1.1 christos rpp = bfd_xalloc (abfd, sizeof (arelent *) * rpp_len); 2468 1.1 christos rpp[0] = rel; 2469 1.1 christos rpp[1] = 0; 2470 1.1 christos 2471 1.1 christos rel->address = HOW_JTAB_ROFF; 2472 1.1 christos rel->addend = 0; 2473 1.1 christos 2474 1.10 christos if (delay) 2475 1.10 christos { 2476 1.10 christos rel2 = bfd_xalloc (abfd, sizeof (arelent)); 2477 1.10 christos rpp[1] = rel2; 2478 1.10 christos rel2->address = HOW_JTAB_ROFF2; 2479 1.10 christos rel2->addend = 0; 2480 1.10 christos rel3 = bfd_xalloc (abfd, sizeof (arelent)); 2481 1.10 christos rpp[2] = rel3; 2482 1.10 christos rel3->address = HOW_JTAB_ROFF3; 2483 1.10 christos rel3->addend = 0; 2484 1.10 christos rpp[3] = 0; 2485 1.1 christos } 2486 1.8 christos 2487 1.1 christos if (machine == MX86) 2488 1.1 christos { 2489 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, 2490 1.1 christos BFD_RELOC_32_PCREL); 2491 1.1 christos rel->sym_ptr_ptr = iname_pp; 2492 1.9 christos } 2493 1.9 christos else if (machine == MAARCH64) 2494 1.9 christos { 2495 1.9 christos arelent *rel_add; 2496 1.9 christos 2497 1.9 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL); 2498 1.9 christos rel->sym_ptr_ptr = secdata[IDATA5].sympp; 2499 1.10 christos 2500 1.9 christos rel_add = bfd_xalloc (abfd, sizeof (arelent)); 2501 1.9 christos rel_add->address = 4; 2502 1.9 christos rel_add->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADD_LO12); 2503 1.9 christos rel_add->sym_ptr_ptr = secdata[IDATA5].sympp; 2504 1.9 christos rel_add->addend = 0; 2505 1.9 christos 2506 1.9 christos rpp[rpp_len - 2] = rel_add; 2507 1.9 christos rpp[rpp_len - 1] = 0; 2508 1.1 christos } 2509 1.1 christos else 2510 1.1 christos { 2511 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2512 1.1 christos rel->sym_ptr_ptr = secdata[IDATA5].sympp; 2513 1.1 christos } 2514 1.1 christos 2515 1.10 christos if (delay) 2516 1.1 christos { 2517 1.10 christos if (machine == MX86) 2518 1.10 christos rel2->howto = bfd_reloc_type_lookup (abfd, 2519 1.10 christos BFD_RELOC_32_PCREL); 2520 1.10 christos else 2521 1.10 christos rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2522 1.10 christos rel2->sym_ptr_ptr = rel->sym_ptr_ptr; 2523 1.1 christos rel3->howto = bfd_reloc_type_lookup (abfd, 2524 1.10 christos BFD_RELOC_32_PCREL); 2525 1.10 christos rel3->sym_ptr_ptr = iname_lab_pp; 2526 1.1 christos } 2527 1.1 christos 2528 1.9 christos sec->orelocation = rpp; 2529 1.1 christos sec->reloc_count = rpp_len - 1; 2530 1.1 christos } 2531 1.1 christos break; 2532 1.1 christos 2533 1.1 christos case IDATA5: 2534 1.1 christos if (delay) 2535 1.1 christos { 2536 1.10 christos si->size = create_for_pep ? 8 : 4; 2537 1.1 christos si->data = bfd_xalloc (abfd, si->size); 2538 1.1 christos sec->reloc_count = 1; 2539 1.1 christos memset (si->data, 0, si->size); 2540 1.1 christos /* Point after jmp [__imp_...] instruction. */ 2541 1.10 christos si->data[0] = 6; 2542 1.10 christos rel = bfd_xalloc (abfd, sizeof (arelent)); 2543 1.1 christos rpp = bfd_xalloc (abfd, sizeof (arelent *) * 2); 2544 1.1 christos rpp[0] = rel; 2545 1.1 christos rpp[1] = 0; 2546 1.1 christos rel->address = 0; 2547 1.1 christos rel->addend = 0; 2548 1.10 christos if (create_for_pep) 2549 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64); 2550 1.10 christos else 2551 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2552 1.1 christos rel->sym_ptr_ptr = secdata[TEXT].sympp; 2553 1.1 christos sec->orelocation = rpp; 2554 1.1 christos break; 2555 1.6 christos } 2556 1.6 christos /* Fall through. */ 2557 1.1 christos 2558 1.1 christos case IDATA4: 2559 1.1 christos /* An idata$4 or idata$5 is one word long, and has an 2560 1.1 christos rva to idata$6. */ 2561 1.1 christos 2562 1.1 christos if (create_for_pep) 2563 1.10 christos { 2564 1.1 christos si->data = bfd_xalloc (abfd, 8); 2565 1.1 christos si->size = 8; 2566 1.10 christos if (exp->noname) 2567 1.1 christos { 2568 1.1 christos si->data[0] = exp->ordinal ; 2569 1.1 christos si->data[1] = exp->ordinal >> 8; 2570 1.1 christos si->data[2] = exp->ordinal >> 16; 2571 1.1 christos si->data[3] = exp->ordinal >> 24; 2572 1.1 christos si->data[4] = 0; 2573 1.1 christos si->data[5] = 0; 2574 1.1 christos si->data[6] = 0; 2575 1.10 christos si->data[7] = 0x80; 2576 1.1 christos } 2577 1.10 christos else 2578 1.1 christos { 2579 1.1 christos sec->reloc_count = 1; 2580 1.10 christos memset (si->data, 0, si->size); 2581 1.10 christos rel = bfd_xalloc (abfd, sizeof (arelent)); 2582 1.1 christos rpp = bfd_xalloc (abfd, sizeof (arelent *) * 2); 2583 1.1 christos rpp[0] = rel; 2584 1.1 christos rpp[1] = 0; 2585 1.1 christos rel->address = 0; 2586 1.1 christos rel->addend = 0; 2587 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA); 2588 1.1 christos rel->sym_ptr_ptr = secdata[IDATA6].sympp; 2589 1.10 christos sec->orelocation = rpp; 2590 1.1 christos } 2591 1.1 christos } 2592 1.1 christos else 2593 1.10 christos { 2594 1.1 christos si->data = bfd_xalloc (abfd, 4); 2595 1.3 christos si->size = 4; 2596 1.1 christos 2597 1.10 christos if (exp->noname) 2598 1.1 christos { 2599 1.1 christos si->data[0] = exp->ordinal ; 2600 1.1 christos si->data[1] = exp->ordinal >> 8; 2601 1.1 christos si->data[2] = exp->ordinal >> 16; 2602 1.10 christos si->data[3] = 0x80; 2603 1.1 christos } 2604 1.10 christos else 2605 1.1 christos { 2606 1.1 christos sec->reloc_count = 1; 2607 1.10 christos memset (si->data, 0, si->size); 2608 1.10 christos rel = bfd_xalloc (abfd, sizeof (arelent)); 2609 1.1 christos rpp = bfd_xalloc (abfd, sizeof (arelent *) * 2); 2610 1.1 christos rpp[0] = rel; 2611 1.1 christos rpp[1] = 0; 2612 1.1 christos rel->address = 0; 2613 1.1 christos rel->addend = 0; 2614 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA); 2615 1.1 christos rel->sym_ptr_ptr = secdata[IDATA6].sympp; 2616 1.10 christos sec->orelocation = rpp; 2617 1.1 christos } 2618 1.1 christos } 2619 1.1 christos break; 2620 1.1 christos 2621 1.1 christos case IDATA6: 2622 1.1 christos if (!exp->noname) 2623 1.10 christos { 2624 1.10 christos /* This used to add 1 to exp->hint. I don't know 2625 1.10 christos why it did that, and it does not match what I see 2626 1.10 christos in programs compiled with the MS tools. */ 2627 1.10 christos int idx = exp->hint; 2628 1.10 christos const char *xname = (exp->its_name ? exp->its_name 2629 1.10 christos : xlate (exp->import_name)); 2630 1.10 christos si->size = strlen (xname) + 3; 2631 1.1 christos si->data = bfd_xalloc (abfd, si->size); 2632 1.1 christos si->data[0] = idx & 0xff; 2633 1.10 christos si->data[1] = idx >> 8; 2634 1.10 christos memcpy (si->data + 2, xname, si->size - 2); 2635 1.10 christos if (!exp->its_name) 2636 1.1 christos free ((char *) xname); 2637 1.1 christos } 2638 1.1 christos break; 2639 1.1 christos case IDATA7: 2640 1.1 christos if (delay) 2641 1.1 christos break; 2642 1.10 christos si->size = 4; 2643 1.1 christos si->data = bfd_xalloc (abfd, 4); 2644 1.10 christos memset (si->data, 0, si->size); 2645 1.10 christos rel = bfd_xalloc (abfd, sizeof (arelent)); 2646 1.1 christos rpp = bfd_xalloc (abfd, sizeof (arelent *) * 2); 2647 1.1 christos rpp[0] = rel; 2648 1.1 christos rel->address = 0; 2649 1.1 christos rel->addend = 0; 2650 1.1 christos rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA); 2651 1.1 christos rel->sym_ptr_ptr = iname_lab_pp; 2652 1.1 christos sec->orelocation = rpp; 2653 1.1 christos sec->reloc_count = 1; 2654 1.1 christos break; 2655 1.1 christos } 2656 1.1 christos } 2657 1.1 christos 2658 1.1 christos { 2659 1.1 christos bfd_vma vma = 0; 2660 1.1 christos /* Size up all the sections. */ 2661 1.1 christos for (i = 0; i < NSECS; i++) 2662 1.1 christos { 2663 1.1 christos sinfo *si = secdata + i; 2664 1.7 christos 2665 1.7 christos bfd_set_section_size (si->sec, si->size); 2666 1.1 christos bfd_set_section_vma (si->sec, vma); 2667 1.1 christos } 2668 1.1 christos } 2669 1.1 christos /* Write them out. */ 2670 1.1 christos for (i = 0; i < NSECS; i++) 2671 1.1 christos { 2672 1.1 christos sinfo *si = secdata + i; 2673 1.1 christos 2674 1.1 christos if (i == IDATA5 && no_idata5) 2675 1.1 christos continue; 2676 1.1 christos 2677 1.1 christos if (i == IDATA4 && no_idata4) 2678 1.1 christos continue; 2679 1.1 christos 2680 1.1 christos bfd_set_section_contents (abfd, si->sec, 2681 1.1 christos si->data, 0, 2682 1.1 christos si->size); 2683 1.1 christos } 2684 1.1 christos 2685 1.1 christos bfd_set_symtab (abfd, ptrs, oidx); 2686 1.1 christos bfd_close (abfd); 2687 1.1 christos abfd = bfd_openr (outname, HOW_BFD_READ_TARGET); 2688 1.1 christos if (!abfd) 2689 1.1 christos /* xgettext:c-format */ 2690 1.1 christos fatal (_("bfd_open failed reopen stub file: %s: %s"), 2691 1.3 christos outname, bfd_get_errmsg ()); 2692 1.1 christos 2693 1.1 christos return abfd; 2694 1.1 christos } 2695 1.1 christos 2696 1.1 christos static bfd * 2697 1.1 christos make_head (void) 2698 1.1 christos { 2699 1.1 christos FILE *f = fopen (TMP_HEAD_S, FOPEN_WT); 2700 1.1 christos bfd *abfd; 2701 1.1 christos 2702 1.1 christos if (f == NULL) 2703 1.1 christos { 2704 1.1 christos fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S); 2705 1.1 christos return NULL; 2706 1.1 christos } 2707 1.3 christos 2708 1.3 christos temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S; 2709 1.1 christos 2710 1.1 christos fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C); 2711 1.1 christos fprintf (f, "\t.section\t.idata$2\n"); 2712 1.10 christos 2713 1.1 christos fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, head_label); 2714 1.1 christos 2715 1.1 christos fprintf (f, "%s:\n", head_label); 2716 1.1 christos 2717 1.1 christos fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n", 2718 1.1 christos ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 2719 1.1 christos 2720 1.1 christos fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C); 2721 1.1 christos fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C); 2722 1.1 christos fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C); 2723 1.1 christos fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C); 2724 1.1 christos fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n", 2725 1.1 christos ASM_RVA_BEFORE, 2726 1.1 christos imp_name_lab, 2727 1.1 christos ASM_RVA_AFTER, 2728 1.1 christos ASM_C); 2729 1.1 christos fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n", 2730 1.1 christos ASM_RVA_BEFORE, 2731 1.1 christos ASM_RVA_AFTER, ASM_C); 2732 1.1 christos 2733 1.1 christos fprintf (f, "%sStuff for compatibility\n", ASM_C); 2734 1.1 christos 2735 1.1 christos if (!no_idata5) 2736 1.1 christos { 2737 1.1 christos fprintf (f, "\t.section\t.idata$5\n"); 2738 1.10 christos if (use_nul_prefixed_import_tables) 2739 1.1 christos { 2740 1.10 christos if (create_for_pep) 2741 1.1 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2742 1.10 christos else 2743 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2744 1.1 christos } 2745 1.1 christos fprintf (f, "fthunk:\n"); 2746 1.1 christos } 2747 1.1 christos 2748 1.1 christos if (!no_idata4) 2749 1.1 christos { 2750 1.1 christos fprintf (f, "\t.section\t.idata$4\n"); 2751 1.10 christos if (use_nul_prefixed_import_tables) 2752 1.1 christos { 2753 1.10 christos if (create_for_pep) 2754 1.1 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2755 1.10 christos else 2756 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2757 1.1 christos } 2758 1.1 christos fprintf (f, "hname:\n"); 2759 1.1 christos } 2760 1.1 christos 2761 1.1 christos fclose (f); 2762 1.1 christos 2763 1.1 christos assemble_file (TMP_HEAD_S, TMP_HEAD_O); 2764 1.1 christos 2765 1.1 christos abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET); 2766 1.1 christos if (abfd == NULL) 2767 1.1 christos /* xgettext:c-format */ 2768 1.1 christos fatal (_("failed to open temporary head file: %s: %s"), 2769 1.1 christos TMP_HEAD_O, bfd_get_errmsg ()); 2770 1.3 christos 2771 1.1 christos temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O; 2772 1.1 christos return abfd; 2773 1.1 christos } 2774 1.10 christos 2775 1.1 christos static bfd * 2776 1.1 christos make_delay_head (void) 2777 1.1 christos { 2778 1.1 christos FILE *f = fopen (TMP_HEAD_S, FOPEN_WT); 2779 1.1 christos bfd *abfd; 2780 1.1 christos 2781 1.1 christos if (f == NULL) 2782 1.1 christos { 2783 1.1 christos fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S); 2784 1.1 christos return NULL; 2785 1.1 christos } 2786 1.3 christos 2787 1.3 christos temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S; 2788 1.1 christos 2789 1.1 christos /* Output the __tailMerge__xxx function */ 2790 1.1 christos fprintf (f, "%s Import trampoline\n", ASM_C); 2791 1.10 christos fprintf (f, "\t.section\t.text\n"); 2792 1.8 christos fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, head_label); 2793 1.8 christos if (HOW_SEH) 2794 1.1 christos fprintf (f, "\t.seh_proc\t%s\n", head_label); 2795 1.1 christos fprintf (f, "%s:\n", head_label); 2796 1.8 christos fprintf (f, mtable[machine].trampoline, imp_name_lab); 2797 1.8 christos if (HOW_SEH) 2798 1.1 christos fprintf (f, "\t.seh_endproc\n"); 2799 1.1 christos 2800 1.1 christos /* Output the delay import descriptor */ 2801 1.10 christos fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C); 2802 1.10 christos fprintf (f, ".section\t.didat$2\n"); 2803 1.1 christos fprintf (f, "%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab); 2804 1.1 christos fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab); 2805 1.1 christos fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C); 2806 1.1 christos fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n", 2807 1.1 christos ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C); 2808 1.1 christos fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n", 2809 1.1 christos ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C); 2810 1.1 christos fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n", 2811 1.1 christos ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C); 2812 1.1 christos fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n", 2813 1.1 christos ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C); 2814 1.1 christos fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C); 2815 1.1 christos fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C); 2816 1.1 christos fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C); 2817 1.1 christos 2818 1.1 christos /* Output the dll_handle */ 2819 1.1 christos fprintf (f, "\n.section .data\n"); 2820 1.1 christos fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab); 2821 1.1 christos fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C); 2822 1.1 christos if (create_for_pep) 2823 1.1 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2824 1.1 christos fprintf (f, "\n"); 2825 1.1 christos 2826 1.1 christos fprintf (f, "%sStuff for compatibility\n", ASM_C); 2827 1.1 christos 2828 1.1 christos if (!no_idata5) 2829 1.10 christos { 2830 1.10 christos fprintf (f, "\t.section\t.didat$5\n"); 2831 1.10 christos if (use_nul_prefixed_import_tables) 2832 1.10 christos { 2833 1.10 christos if (create_for_pep) 2834 1.10 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2835 1.10 christos else 2836 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2837 1.1 christos } 2838 1.1 christos fprintf (f, "__IAT_%s:\n", imp_name_lab); 2839 1.1 christos } 2840 1.1 christos 2841 1.1 christos if (!no_idata4) 2842 1.10 christos { 2843 1.10 christos fprintf (f, "\t.section\t.didat$4\n"); 2844 1.10 christos if (use_nul_prefixed_import_tables) 2845 1.10 christos { 2846 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2847 1.10 christos if (create_for_pep) 2848 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); 2849 1.1 christos } 2850 1.1 christos fprintf (f, "__INT_%s:\n", imp_name_lab); 2851 1.1 christos } 2852 1.1 christos 2853 1.1 christos fclose (f); 2854 1.1 christos 2855 1.1 christos assemble_file (TMP_HEAD_S, TMP_HEAD_O); 2856 1.1 christos 2857 1.1 christos abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET); 2858 1.1 christos if (abfd == NULL) 2859 1.1 christos /* xgettext:c-format */ 2860 1.1 christos fatal (_("failed to open temporary head file: %s: %s"), 2861 1.1 christos TMP_HEAD_O, bfd_get_errmsg ()); 2862 1.3 christos 2863 1.1 christos temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O; 2864 1.1 christos return abfd; 2865 1.1 christos } 2866 1.1 christos 2867 1.1 christos static bfd * 2868 1.1 christos make_tail (void) 2869 1.1 christos { 2870 1.1 christos FILE *f = fopen (TMP_TAIL_S, FOPEN_WT); 2871 1.1 christos bfd *abfd; 2872 1.1 christos 2873 1.1 christos if (f == NULL) 2874 1.1 christos { 2875 1.1 christos fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S); 2876 1.1 christos return NULL; 2877 1.1 christos } 2878 1.3 christos 2879 1.3 christos temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S; 2880 1.1 christos 2881 1.1 christos if (!no_idata4) 2882 1.1 christos { 2883 1.1 christos fprintf (f, "\t.section\t.idata$4\n"); 2884 1.10 christos if (create_for_pep) 2885 1.1 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2886 1.10 christos else 2887 1.1 christos fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 2888 1.1 christos } 2889 1.1 christos 2890 1.1 christos if (!no_idata5) 2891 1.1 christos { 2892 1.1 christos fprintf (f, "\t.section\t.idata$5\n"); 2893 1.10 christos if (create_for_pep) 2894 1.1 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2895 1.10 christos else 2896 1.1 christos fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 2897 1.1 christos } 2898 1.1 christos 2899 1.1 christos fprintf (f, "\t.section\t.idata$7\n"); 2900 1.1 christos fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab); 2901 1.1 christos fprintf (f, "__%s_iname:\t%s\t\"%s\"\n", 2902 1.1 christos imp_name_lab, ASM_TEXT, dll_name); 2903 1.1 christos 2904 1.1 christos fclose (f); 2905 1.1 christos 2906 1.1 christos assemble_file (TMP_TAIL_S, TMP_TAIL_O); 2907 1.1 christos 2908 1.1 christos abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET); 2909 1.1 christos if (abfd == NULL) 2910 1.1 christos /* xgettext:c-format */ 2911 1.1 christos fatal (_("failed to open temporary tail file: %s: %s"), 2912 1.1 christos TMP_TAIL_O, bfd_get_errmsg ()); 2913 1.3 christos 2914 1.1 christos temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O; 2915 1.1 christos return abfd; 2916 1.1 christos } 2917 1.10 christos 2918 1.10 christos static bfd * 2919 1.10 christos make_delay_tail (void) 2920 1.10 christos { 2921 1.10 christos FILE *f = fopen (TMP_TAIL_S, FOPEN_WT); 2922 1.10 christos bfd *abfd; 2923 1.10 christos 2924 1.10 christos if (f == NULL) 2925 1.10 christos { 2926 1.10 christos fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S); 2927 1.10 christos return NULL; 2928 1.10 christos } 2929 1.10 christos 2930 1.10 christos temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S; 2931 1.10 christos 2932 1.10 christos if (!no_idata4) 2933 1.10 christos { 2934 1.10 christos fprintf (f, "\t.section\t.didat$4\n"); 2935 1.10 christos if (create_for_pep) 2936 1.10 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2937 1.10 christos else 2938 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 2939 1.10 christos } 2940 1.10 christos 2941 1.10 christos if (!no_idata5) 2942 1.10 christos { 2943 1.10 christos fprintf (f, "\t.section\t.didat$5\n"); 2944 1.10 christos if (create_for_pep) 2945 1.10 christos fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); 2946 1.10 christos else 2947 1.10 christos fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ 2948 1.10 christos } 2949 1.10 christos 2950 1.10 christos fprintf (f, "\t.section\t.didat$7\n"); 2951 1.10 christos fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab); 2952 1.10 christos fprintf (f, "__%s_iname:\t%s\t\"%s\"\n", 2953 1.10 christos imp_name_lab, ASM_TEXT, dll_name); 2954 1.10 christos 2955 1.10 christos fclose (f); 2956 1.10 christos 2957 1.10 christos assemble_file (TMP_TAIL_S, TMP_TAIL_O); 2958 1.10 christos 2959 1.10 christos abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET); 2960 1.10 christos if (abfd == NULL) 2961 1.10 christos /* xgettext:c-format */ 2962 1.10 christos fatal (_("failed to open temporary tail file: %s: %s"), 2963 1.10 christos TMP_TAIL_O, bfd_get_errmsg ()); 2964 1.10 christos 2965 1.10 christos temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O; 2966 1.10 christos return abfd; 2967 1.10 christos } 2968 1.1 christos 2969 1.1 christos static void 2970 1.1 christos gen_lib_file (int delay) 2971 1.1 christos { 2972 1.1 christos int i; 2973 1.1 christos export_type *exp; 2974 1.1 christos bfd *ar_head; 2975 1.1 christos bfd *ar_tail; 2976 1.1 christos bfd *outarch; 2977 1.1 christos bfd * head = 0; 2978 1.1 christos 2979 1.1 christos unlink (imp_name); 2980 1.1 christos 2981 1.1 christos outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET); 2982 1.1 christos 2983 1.1 christos if (!outarch) 2984 1.1 christos /* xgettext:c-format */ 2985 1.1 christos fatal (_("Can't create .lib file: %s: %s"), 2986 1.1 christos imp_name, bfd_get_errmsg ()); 2987 1.1 christos 2988 1.1 christos /* xgettext:c-format */ 2989 1.1 christos inform (_("Creating library file: %s"), imp_name); 2990 1.3 christos 2991 1.3 christos xatexit (unlink_temp_files); 2992 1.1 christos 2993 1.1 christos bfd_set_format (outarch, bfd_archive); 2994 1.1 christos outarch->has_armap = 1; 2995 1.1 christos outarch->is_thin_archive = 0; 2996 1.9 christos 2997 1.9 christos if (deterministic) 2998 1.9 christos outarch->flags |= BFD_DETERMINISTIC_OUTPUT; 2999 1.1 christos 3000 1.1 christos /* Work out a reasonable size of things to put onto one line. */ 3001 1.1 christos if (delay) 3002 1.1 christos { 3003 1.10 christos ar_head = make_delay_head (); 3004 1.1 christos ar_tail = make_delay_tail(); 3005 1.1 christos } 3006 1.1 christos else 3007 1.1 christos { 3008 1.10 christos ar_head = make_head (); 3009 1.1 christos ar_tail = make_tail(); 3010 1.1 christos } 3011 1.1 christos 3012 1.1 christos if (ar_head == NULL || ar_tail == NULL) 3013 1.1 christos return; 3014 1.1 christos 3015 1.1 christos for (i = 0; (exp = d_exports_lexically[i]); i++) 3016 1.1 christos { 3017 1.1 christos bfd *n; 3018 1.1 christos /* Don't add PRIVATE entries to import lib. */ 3019 1.1 christos if (exp->private) 3020 1.1 christos continue; 3021 1.1 christos n = make_one_lib_file (exp, i, delay); 3022 1.1 christos n->archive_next = head; 3023 1.1 christos head = n; 3024 1.1 christos if (ext_prefix_alias) 3025 1.1 christos { 3026 1.1 christos export_type alias_exp; 3027 1.1 christos 3028 1.10 christos assert (i < PREFIX_ALIAS_BASE); 3029 1.1 christos alias_exp.name = make_imp_label (outarch, ext_prefix_alias, exp->name); 3030 1.1 christos alias_exp.internal_name = exp->internal_name; 3031 1.1 christos alias_exp.its_name = exp->its_name; 3032 1.1 christos alias_exp.import_name = exp->name; 3033 1.1 christos alias_exp.ordinal = exp->ordinal; 3034 1.1 christos alias_exp.constant = exp->constant; 3035 1.1 christos alias_exp.noname = exp->noname; 3036 1.1 christos alias_exp.private = exp->private; 3037 1.10 christos alias_exp.data = exp->data; 3038 1.1 christos alias_exp.hint = exp->hint; 3039 1.1 christos alias_exp.forward = exp->forward; 3040 1.1 christos alias_exp.next = exp->next; 3041 1.1 christos n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay); 3042 1.1 christos n->archive_next = head; 3043 1.1 christos head = n; 3044 1.1 christos } 3045 1.1 christos } 3046 1.1 christos 3047 1.1 christos /* Now stick them all into the archive. */ 3048 1.1 christos ar_head->archive_next = head; 3049 1.1 christos ar_tail->archive_next = ar_head; 3050 1.1 christos head = ar_tail; 3051 1.1 christos 3052 1.1 christos if (! bfd_set_archive_head (outarch, head)) 3053 1.1 christos bfd_fatal ("bfd_set_archive_head"); 3054 1.1 christos 3055 1.1 christos if (! bfd_close (outarch)) 3056 1.1 christos bfd_fatal (imp_name); 3057 1.1 christos 3058 1.3 christos /* Delete all the temp files. */ 3059 1.1 christos unlink_temp_files (); 3060 1.1 christos 3061 1.1 christos if (dontdeltemps < 2) 3062 1.10 christos { 3063 1.10 christos char *name = TMP_STUB; 3064 1.1 christos size_t name_len = strlen (name); 3065 1.1 christos 3066 1.1 christos for (i = 0; (exp = d_exports_lexically[i]); i++) 3067 1.1 christos { 3068 1.10 christos /* Don't delete non-existent stubs for PRIVATE entries. */ 3069 1.1 christos if (exp->private) 3070 1.10 christos continue; 3071 1.1 christos sprintf (name + name_len - 7, "%05d.o", i); 3072 1.1 christos if (unlink (name) < 0) 3073 1.1 christos /* xgettext:c-format */ 3074 1.1 christos non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); 3075 1.1 christos if (ext_prefix_alias) 3076 1.10 christos { 3077 1.1 christos sprintf (name + name_len - 7, "%05d.o", i + PREFIX_ALIAS_BASE); 3078 1.1 christos if (unlink (name) < 0) 3079 1.1 christos /* xgettext:c-format */ 3080 1.1 christos non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); 3081 1.1 christos } 3082 1.1 christos } 3083 1.1 christos } 3084 1.1 christos 3085 1.1 christos inform (_("Created lib file")); 3086 1.1 christos } 3087 1.1 christos 3088 1.1 christos /* Append a copy of data (cast to char *) to list. */ 3089 1.1 christos 3090 1.1 christos static void 3091 1.1 christos dll_name_list_append (dll_name_list_type * list, bfd_byte * data) 3092 1.1 christos { 3093 1.1 christos dll_name_list_node_type * entry; 3094 1.1 christos 3095 1.1 christos /* Error checking. */ 3096 1.1 christos if (! list || ! list->tail) 3097 1.1 christos return; 3098 1.1 christos 3099 1.1 christos /* Allocate new node. */ 3100 1.1 christos entry = ((dll_name_list_node_type *) 3101 1.1 christos xmalloc (sizeof (dll_name_list_node_type))); 3102 1.1 christos 3103 1.1 christos /* Initialize its values. */ 3104 1.1 christos entry->dllname = xstrdup ((char *) data); 3105 1.1 christos entry->next = NULL; 3106 1.1 christos 3107 1.1 christos /* Add to tail, and move tail. */ 3108 1.1 christos list->tail->next = entry; 3109 1.1 christos list->tail = entry; 3110 1.1 christos } 3111 1.1 christos 3112 1.1 christos /* Count the number of entries in list. */ 3113 1.3 christos 3114 1.1 christos static int 3115 1.1 christos dll_name_list_count (dll_name_list_type * list) 3116 1.1 christos { 3117 1.1 christos dll_name_list_node_type * p; 3118 1.1 christos int count = 0; 3119 1.1 christos 3120 1.1 christos /* Error checking. */ 3121 1.1 christos if (! list || ! list->head) 3122 1.1 christos return 0; 3123 1.1 christos 3124 1.1 christos p = list->head; 3125 1.1 christos 3126 1.1 christos while (p && p->next) 3127 1.1 christos { 3128 1.1 christos count++; 3129 1.1 christos p = p->next; 3130 1.1 christos } 3131 1.1 christos return count; 3132 1.1 christos } 3133 1.1 christos 3134 1.1 christos /* Print each entry in list to stdout. */ 3135 1.3 christos 3136 1.1 christos static void 3137 1.1 christos dll_name_list_print (dll_name_list_type * list) 3138 1.1 christos { 3139 1.1 christos dll_name_list_node_type * p; 3140 1.1 christos 3141 1.1 christos /* Error checking. */ 3142 1.1 christos if (! list || ! list->head) 3143 1.1 christos return; 3144 1.1 christos 3145 1.1 christos p = list->head; 3146 1.10 christos 3147 1.1 christos while (p && p->next && p->next->dllname && *p->next->dllname) 3148 1.1 christos { 3149 1.1 christos printf ("%s\n", p->next->dllname); 3150 1.1 christos p = p->next; 3151 1.1 christos } 3152 1.1 christos } 3153 1.1 christos 3154 1.1 christos /* Free all entries in list, and list itself. */ 3155 1.1 christos 3156 1.1 christos static void 3157 1.1 christos dll_name_list_free (dll_name_list_type * list) 3158 1.1 christos { 3159 1.1 christos if (list) 3160 1.1 christos { 3161 1.1 christos dll_name_list_free_contents (list->head); 3162 1.1 christos list->head = NULL; 3163 1.1 christos list->tail = NULL; 3164 1.1 christos free (list); 3165 1.1 christos } 3166 1.1 christos } 3167 1.1 christos 3168 1.1 christos /* Recursive function to free all nodes entry->next->next... 3169 1.1 christos as well as entry itself. */ 3170 1.3 christos 3171 1.1 christos static void 3172 1.1 christos dll_name_list_free_contents (dll_name_list_node_type * entry) 3173 1.10 christos { 3174 1.1 christos while (entry) 3175 1.10 christos { 3176 1.8 christos dll_name_list_node_type *next = entry->next; 3177 1.1 christos free (entry->dllname); 3178 1.10 christos free (entry); 3179 1.1 christos entry = next; 3180 1.1 christos } 3181 1.1 christos } 3182 1.1 christos 3183 1.1 christos /* Allocate and initialize a dll_name_list_type object, 3184 1.3 christos including its sentinel node. Caller is responsible 3185 1.1 christos for calling dll_name_list_free when finished with 3186 1.1 christos the list. */ 3187 1.1 christos 3188 1.1 christos static dll_name_list_type * 3189 1.1 christos dll_name_list_create (void) 3190 1.1 christos { 3191 1.1 christos /* Allocate list. */ 3192 1.1 christos dll_name_list_type * list = xmalloc (sizeof (dll_name_list_type)); 3193 1.1 christos 3194 1.1 christos /* Allocate and initialize sentinel node. */ 3195 1.1 christos list->head = xmalloc (sizeof (dll_name_list_node_type)); 3196 1.1 christos list->head->dllname = NULL; 3197 1.1 christos list->head->next = NULL; 3198 1.1 christos 3199 1.1 christos /* Bookkeeping for empty list. */ 3200 1.1 christos list->tail = list->head; 3201 1.1 christos 3202 1.1 christos return list; 3203 1.1 christos } 3204 1.1 christos 3205 1.1 christos /* Search the symbol table of the suppled BFD for a symbol whose name matches 3206 1.1 christos OBJ (where obj is cast to const char *). If found, set global variable 3207 1.1 christos identify_member_contains_symname_result TRUE. It is the caller's 3208 1.3 christos responsibility to set the result variable FALSE before iterating with 3209 1.1 christos this function. */ 3210 1.3 christos 3211 1.1 christos static void 3212 1.1 christos identify_member_contains_symname (bfd * abfd, 3213 1.1 christos bfd * archive_bfd ATTRIBUTE_UNUSED, 3214 1.1 christos void * obj) 3215 1.1 christos { 3216 1.1 christos long storage_needed; 3217 1.1 christos asymbol ** symbol_table; 3218 1.1 christos long number_of_symbols; 3219 1.1 christos long i; 3220 1.1 christos symname_search_data_type * search_data = (symname_search_data_type *) obj; 3221 1.1 christos 3222 1.1 christos /* If we already found the symbol in a different member, 3223 1.1 christos short circuit. */ 3224 1.1 christos if (search_data->found) 3225 1.1 christos return; 3226 1.1 christos 3227 1.1 christos storage_needed = bfd_get_symtab_upper_bound (abfd); 3228 1.1 christos if (storage_needed <= 0) 3229 1.1 christos return; 3230 1.1 christos 3231 1.1 christos symbol_table = xmalloc (storage_needed); 3232 1.1 christos number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); 3233 1.1 christos if (number_of_symbols < 0) 3234 1.1 christos { 3235 1.1 christos free (symbol_table); 3236 1.1 christos return; 3237 1.1 christos } 3238 1.1 christos 3239 1.1 christos for (i = 0; i < number_of_symbols; i++) 3240 1.1 christos { 3241 1.10 christos if (strncmp (symbol_table[i]->name, 3242 1.10 christos search_data->symname, 3243 1.1 christos strlen (search_data->symname)) == 0) 3244 1.8 christos { 3245 1.1 christos search_data->found = true; 3246 1.1 christos break; 3247 1.1 christos } 3248 1.1 christos } 3249 1.1 christos free (symbol_table); 3250 1.1 christos } 3251 1.1 christos 3252 1.8 christos /* This is the main implementation for the --identify option. 3253 1.8 christos Given the name of an import library in identify_imp_name, first 3254 1.8 christos determine if the import library is a GNU binutils-style one (where 3255 1.8 christos the DLL name is stored in an .idata$7 section), or if it is a 3256 1.8 christos MS-style one (where the DLL name, along with much other data, is 3257 1.8 christos stored in the .idata$6 section). We determine the style of import 3258 1.8 christos library by searching for the DLL-structure symbol inserted by MS 3259 1.1 christos tools: __NULL_IMPORT_DESCRIPTOR. 3260 1.1 christos 3261 1.1 christos Once we know which section to search, evaluate each section for the 3262 1.1 christos appropriate properties that indicate it may contain the name of the 3263 1.1 christos associated DLL (this differs depending on the style). Add the contents 3264 1.1 christos of all sections which meet the criteria to a linked list of dll names. 3265 1.1 christos 3266 1.3 christos Finally, print them all to stdout. (If --identify-strict, an error is 3267 1.1 christos reported if more than one match was found). */ 3268 1.3 christos 3269 1.1 christos static void 3270 1.1 christos identify_dll_for_implib (void) 3271 1.1 christos { 3272 1.1 christos bfd * abfd = NULL; 3273 1.1 christos int count = 0; 3274 1.1 christos identify_data_type identify_data; 3275 1.1 christos symname_search_data_type search_data; 3276 1.1 christos 3277 1.1 christos /* Initialize identify_data. */ 3278 1.8 christos identify_data.list = dll_name_list_create (); 3279 1.1 christos identify_data.ms_style_implib = false; 3280 1.1 christos 3281 1.1 christos /* Initialize search_data. */ 3282 1.8 christos search_data.symname = "__NULL_IMPORT_DESCRIPTOR"; 3283 1.1 christos search_data.found = false; 3284 1.7 christos 3285 1.7 christos if (bfd_init () != BFD_INIT_MAGIC) 3286 1.1 christos fatal (_("fatal error: libbfd ABI mismatch")); 3287 1.1 christos 3288 1.1 christos abfd = bfd_openr (identify_imp_name, 0); 3289 1.1 christos if (abfd == NULL) 3290 1.1 christos /* xgettext:c-format */ 3291 1.1 christos fatal (_("Can't open .lib file: %s: %s"), 3292 1.1 christos identify_imp_name, bfd_get_errmsg ()); 3293 1.1 christos 3294 1.1 christos if (! bfd_check_format (abfd, bfd_archive)) 3295 1.1 christos { 3296 1.10 christos if (! bfd_close (abfd)) 3297 1.1 christos bfd_fatal (identify_imp_name); 3298 1.1 christos 3299 1.1 christos fatal (_("%s is not a library"), identify_imp_name); 3300 1.1 christos } 3301 1.1 christos 3302 1.1 christos /* Detect if this a Microsoft import library. */ 3303 1.1 christos identify_search_archive (abfd, 3304 1.10 christos identify_member_contains_symname, 3305 1.1 christos (void *) &search_data); 3306 1.8 christos if (search_data.found) 3307 1.3 christos identify_data.ms_style_implib = true; 3308 1.1 christos 3309 1.1 christos /* Rewind the bfd. */ 3310 1.1 christos if (! bfd_close (abfd)) 3311 1.1 christos bfd_fatal (identify_imp_name); 3312 1.1 christos abfd = bfd_openr (identify_imp_name, 0); 3313 1.1 christos if (abfd == NULL) 3314 1.1 christos bfd_fatal (identify_imp_name); 3315 1.1 christos 3316 1.1 christos if (!bfd_check_format (abfd, bfd_archive)) 3317 1.1 christos { 3318 1.10 christos if (!bfd_close (abfd)) 3319 1.1 christos bfd_fatal (identify_imp_name); 3320 1.1 christos 3321 1.1 christos fatal (_("%s is not a library"), identify_imp_name); 3322 1.3 christos } 3323 1.1 christos 3324 1.1 christos /* Now search for the dll name. */ 3325 1.1 christos identify_search_archive (abfd, 3326 1.10 christos identify_search_member, 3327 1.1 christos (void *) &identify_data); 3328 1.1 christos 3329 1.1 christos if (! bfd_close (abfd)) 3330 1.1 christos bfd_fatal (identify_imp_name); 3331 1.1 christos 3332 1.1 christos count = dll_name_list_count (identify_data.list); 3333 1.1 christos if (count > 0) 3334 1.1 christos { 3335 1.10 christos if (identify_strict && count > 1) 3336 1.10 christos { 3337 1.10 christos dll_name_list_free (identify_data.list); 3338 1.10 christos identify_data.list = NULL; 3339 1.1 christos fatal (_("Import library `%s' specifies two or more dlls"), 3340 1.10 christos identify_imp_name); 3341 1.1 christos } 3342 1.1 christos dll_name_list_print (identify_data.list); 3343 1.1 christos dll_name_list_free (identify_data.list); 3344 1.1 christos identify_data.list = NULL; 3345 1.1 christos } 3346 1.1 christos else 3347 1.1 christos { 3348 1.1 christos dll_name_list_free (identify_data.list); 3349 1.1 christos identify_data.list = NULL; 3350 1.1 christos fatal (_("Unable to determine dll name for `%s' (not an import library?)"), 3351 1.1 christos identify_imp_name); 3352 1.1 christos } 3353 1.1 christos } 3354 1.1 christos 3355 1.1 christos /* Loop over all members of the archive, applying the supplied function to 3356 1.3 christos each member that is a bfd_object. The function will be called as if: 3357 1.1 christos func (member_bfd, abfd, user_storage) */ 3358 1.1 christos 3359 1.3 christos static void 3360 1.1 christos identify_search_archive (bfd * abfd, 3361 1.1 christos void (* operation) (bfd *, bfd *, void *), 3362 1.1 christos void * user_storage) 3363 1.10 christos { 3364 1.1 christos bfd *last_arfile = NULL; 3365 1.1 christos 3366 1.1 christos while (1) 3367 1.10 christos { 3368 1.10 christos bfd *arfile = bfd_openr_next_archived_file (abfd, last_arfile); 3369 1.10 christos if (arfile == NULL 3370 1.10 christos || arfile == last_arfile) 3371 1.10 christos { 3372 1.10 christos if (arfile != NULL) 3373 1.10 christos bfd_set_error (bfd_error_malformed_archive); 3374 1.10 christos if (bfd_get_error () != bfd_error_no_more_archived_files) 3375 1.10 christos bfd_fatal (bfd_get_filename (abfd)); 3376 1.10 christos break; 3377 1.1 christos } 3378 1.10 christos 3379 1.10 christos if (last_arfile != NULL) 3380 1.1 christos bfd_close (last_arfile); 3381 1.10 christos 3382 1.1 christos char **matching; 3383 1.1 christos if (bfd_check_format_matches (arfile, bfd_object, &matching)) 3384 1.1 christos (*operation) (arfile, abfd, user_storage); 3385 1.3 christos else 3386 1.10 christos { 3387 1.10 christos bfd_nonfatal (bfd_get_filename (arfile)); 3388 1.3 christos free (matching); 3389 1.1 christos } 3390 1.1 christos 3391 1.1 christos last_arfile = arfile; 3392 1.1 christos } 3393 1.1 christos 3394 1.10 christos if (last_arfile != NULL) 3395 1.1 christos bfd_close (last_arfile); 3396 1.1 christos } 3397 1.1 christos 3398 1.3 christos /* Call the identify_search_section() function for each section of this 3399 1.1 christos archive member. */ 3400 1.1 christos 3401 1.1 christos static void 3402 1.1 christos identify_search_member (bfd *abfd, 3403 1.1 christos bfd *archive_bfd ATTRIBUTE_UNUSED, 3404 1.1 christos void *obj) 3405 1.1 christos { 3406 1.1 christos bfd_map_over_sections (abfd, identify_search_section, obj); 3407 1.1 christos } 3408 1.1 christos 3409 1.8 christos /* This predicate returns true if section->name matches the desired value. 3410 1.8 christos By default, this is .idata$7 (.idata$6 if the import library is 3411 1.1 christos ms-style). */ 3412 1.8 christos 3413 1.8 christos static bool 3414 1.1 christos identify_process_section_p (asection * section, bool ms_style_implib) 3415 1.8 christos { 3416 1.1 christos static const char * SECTION_NAME = ".idata$7"; 3417 1.3 christos static const char * MS_SECTION_NAME = ".idata$6"; 3418 1.1 christos 3419 1.1 christos const char * section_name = 3420 1.3 christos (ms_style_implib ? MS_SECTION_NAME : SECTION_NAME); 3421 1.1 christos 3422 1.8 christos if (strcmp (section_name, section->name) == 0) 3423 1.8 christos return true; 3424 1.1 christos return false; 3425 1.1 christos } 3426 1.8 christos 3427 1.1 christos /* If *section has contents and its name is .idata$7 (.idata$6 if 3428 1.1 christos import lib ms-generated) -- and it satisfies several other constraints 3429 1.1 christos -- then add the contents of the section to obj->list. */ 3430 1.1 christos 3431 1.1 christos static void 3432 1.1 christos identify_search_section (bfd * abfd, asection * section, void * obj) 3433 1.1 christos { 3434 1.1 christos bfd_byte *data = 0; 3435 1.1 christos bfd_size_type datasize; 3436 1.8 christos identify_data_type * identify_data = (identify_data_type *)obj; 3437 1.1 christos bool ms_style = identify_data->ms_style_implib; 3438 1.1 christos 3439 1.1 christos if ((section->flags & SEC_HAS_CONTENTS) == 0) 3440 1.1 christos return; 3441 1.1 christos 3442 1.1 christos if (! identify_process_section_p (section, ms_style)) 3443 1.1 christos return; 3444 1.1 christos 3445 1.1 christos /* Binutils import libs seem distinguish the .idata$7 section that contains 3446 1.1 christos the DLL name from other .idata$7 sections by the absence of the 3447 1.1 christos SEC_RELOC flag. */ 3448 1.1 christos if (!ms_style && ((section->flags & SEC_RELOC) == SEC_RELOC)) 3449 1.1 christos return; 3450 1.1 christos 3451 1.1 christos /* MS import libs seem to distinguish the .idata$6 section 3452 1.1 christos that contains the DLL name from other .idata$6 sections 3453 1.1 christos by the presence of the SEC_DATA flag. */ 3454 1.1 christos if (ms_style && ((section->flags & SEC_DATA) == 0)) 3455 1.1 christos return; 3456 1.7 christos 3457 1.1 christos if ((datasize = bfd_section_size (section)) == 0) 3458 1.1 christos return; 3459 1.1 christos 3460 1.1 christos data = (bfd_byte *) xmalloc (datasize + 1); 3461 1.1 christos data[0] = '\0'; 3462 1.1 christos 3463 1.1 christos bfd_get_section_contents (abfd, section, data, 0, datasize); 3464 1.1 christos data[datasize] = '\0'; 3465 1.1 christos 3466 1.1 christos /* Use a heuristic to determine if data is a dll name. 3467 1.3 christos Possible to defeat this if (a) the library has MANY 3468 1.1 christos (more than 0x302f) imports, (b) it is an ms-style 3469 1.1 christos import library, but (c) it is buggy, in that the SEC_DATA 3470 1.1 christos flag is set on the "wrong" sections. This heuristic might 3471 1.1 christos also fail to record a valid dll name if the dllname uses 3472 1.1 christos a multibyte or unicode character set (is that valid?). 3473 1.1 christos 3474 1.1 christos This heuristic is based on the fact that symbols names in 3475 1.1 christos the chosen section -- as opposed to the dll name -- begin 3476 1.1 christos at offset 2 in the data. The first two bytes are a 16bit 3477 1.1 christos little-endian count, and start at 0x0000. However, the dll 3478 1.1 christos name begins at offset 0 in the data. We assume that the 3479 1.1 christos dll name does not contain unprintable characters. */ 3480 1.10 christos if (data[0] != '\0' && ISPRINT (data[0]) 3481 1.1 christos && (datasize < 2 || ISPRINT (data[1]))) 3482 1.1 christos dll_name_list_append (identify_data->list, data); 3483 1.1 christos 3484 1.1 christos free (data); 3485 1.1 christos } 3486 1.1 christos 3487 1.1 christos /* Run through the information gathered from the .o files and the 3488 1.1 christos .def file and work out the best stuff. */ 3489 1.1 christos 3490 1.1 christos static int 3491 1.1 christos pfunc (const void *a, const void *b) 3492 1.1 christos { 3493 1.1 christos export_type *ap = *(export_type **) a; 3494 1.1 christos export_type *bp = *(export_type **) b; 3495 1.1 christos 3496 1.1 christos if (ap->ordinal == bp->ordinal) 3497 1.1 christos return 0; 3498 1.1 christos 3499 1.1 christos /* Unset ordinals go to the bottom. */ 3500 1.1 christos if (ap->ordinal == -1) 3501 1.1 christos return 1; 3502 1.1 christos if (bp->ordinal == -1) 3503 1.1 christos return -1; 3504 1.1 christos return (ap->ordinal - bp->ordinal); 3505 1.1 christos } 3506 1.1 christos 3507 1.1 christos static int 3508 1.1 christos nfunc (const void *a, const void *b) 3509 1.1 christos { 3510 1.1 christos export_type *ap = *(export_type **) a; 3511 1.1 christos export_type *bp = *(export_type **) b; 3512 1.1 christos const char *an = ap->name; 3513 1.1 christos const char *bn = bp->name; 3514 1.1 christos if (ap->its_name) 3515 1.1 christos an = ap->its_name; 3516 1.1 christos if (bp->its_name) 3517 1.1 christos an = bp->its_name; 3518 1.1 christos if (killat) 3519 1.1 christos { 3520 1.1 christos an = (an[0] == '@') ? an + 1 : an; 3521 1.1 christos bn = (bn[0] == '@') ? bn + 1 : bn; 3522 1.1 christos } 3523 1.1 christos 3524 1.1 christos return (strcmp (an, bn)); 3525 1.1 christos } 3526 1.1 christos 3527 1.1 christos static void 3528 1.1 christos remove_null_names (export_type **ptr) 3529 1.1 christos { 3530 1.1 christos int src; 3531 1.1 christos int dst; 3532 1.1 christos 3533 1.1 christos for (dst = src = 0; src < d_nfuncs; src++) 3534 1.1 christos { 3535 1.1 christos if (ptr[src]) 3536 1.1 christos { 3537 1.1 christos ptr[dst] = ptr[src]; 3538 1.1 christos dst++; 3539 1.1 christos } 3540 1.1 christos } 3541 1.1 christos d_nfuncs = dst; 3542 1.1 christos } 3543 1.1 christos 3544 1.1 christos static void 3545 1.1 christos process_duplicates (export_type **d_export_vec) 3546 1.1 christos { 3547 1.1 christos int more = 1; 3548 1.1 christos int i; 3549 1.1 christos 3550 1.1 christos while (more) 3551 1.1 christos { 3552 1.1 christos more = 0; 3553 1.1 christos /* Remove duplicates. */ 3554 1.1 christos qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc); 3555 1.1 christos 3556 1.1 christos for (i = 0; i < d_nfuncs - 1; i++) 3557 1.1 christos { 3558 1.1 christos if (strcmp (d_export_vec[i]->name, 3559 1.1 christos d_export_vec[i + 1]->name) == 0) 3560 1.1 christos { 3561 1.1 christos export_type *a = d_export_vec[i]; 3562 1.1 christos export_type *b = d_export_vec[i + 1]; 3563 1.1 christos 3564 1.1 christos more = 1; 3565 1.1 christos 3566 1.1 christos /* xgettext:c-format */ 3567 1.1 christos inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"), 3568 1.1 christos a->name, a->ordinal, b->ordinal); 3569 1.1 christos 3570 1.1 christos if (a->ordinal != -1 3571 1.1 christos && b->ordinal != -1) 3572 1.1 christos /* xgettext:c-format */ 3573 1.10 christos fatal (_("Error, duplicate EXPORT with ordinals: %s"), 3574 1.1 christos a->name); 3575 1.1 christos 3576 1.1 christos /* Merge attributes. */ 3577 1.1 christos b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal; 3578 1.1 christos b->constant |= a->constant; 3579 1.1 christos b->noname |= a->noname; 3580 1.1 christos b->data |= a->data; 3581 1.1 christos d_export_vec[i] = 0; 3582 1.1 christos } 3583 1.1 christos 3584 1.1 christos remove_null_names (d_export_vec); 3585 1.1 christos } 3586 1.1 christos } 3587 1.1 christos 3588 1.1 christos /* Count the names. */ 3589 1.1 christos for (i = 0; i < d_nfuncs; i++) 3590 1.1 christos if (!d_export_vec[i]->noname) 3591 1.1 christos d_named_nfuncs++; 3592 1.1 christos } 3593 1.1 christos 3594 1.1 christos static void 3595 1.1 christos fill_ordinals (export_type **d_export_vec) 3596 1.1 christos { 3597 1.1 christos int lowest = -1; 3598 1.1 christos int i; 3599 1.1 christos char *ptr; 3600 1.1 christos int size = 65536; 3601 1.1 christos 3602 1.1 christos qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); 3603 1.1 christos 3604 1.1 christos /* Fill in the unset ordinals with ones from our range. */ 3605 1.1 christos ptr = (char *) xmalloc (size); 3606 1.1 christos 3607 1.1 christos memset (ptr, 0, size); 3608 1.1 christos 3609 1.1 christos /* Mark in our large vector all the numbers that are taken. */ 3610 1.1 christos for (i = 0; i < d_nfuncs; i++) 3611 1.1 christos { 3612 1.1 christos if (d_export_vec[i]->ordinal != -1) 3613 1.1 christos { 3614 1.1 christos ptr[d_export_vec[i]->ordinal] = 1; 3615 1.1 christos 3616 1.1 christos if (lowest == -1 || d_export_vec[i]->ordinal < lowest) 3617 1.1 christos lowest = d_export_vec[i]->ordinal; 3618 1.1 christos } 3619 1.1 christos } 3620 1.1 christos 3621 1.1 christos /* Start at 1 for compatibility with MS toolchain. */ 3622 1.1 christos if (lowest == -1) 3623 1.1 christos lowest = 1; 3624 1.1 christos 3625 1.1 christos /* Now fill in ordinals where the user wants us to choose. */ 3626 1.1 christos for (i = 0; i < d_nfuncs; i++) 3627 1.1 christos { 3628 1.1 christos if (d_export_vec[i]->ordinal == -1) 3629 1.1 christos { 3630 1.1 christos int j; 3631 1.1 christos 3632 1.1 christos /* First try within or after any user supplied range. */ 3633 1.1 christos for (j = lowest; j < size; j++) 3634 1.1 christos if (ptr[j] == 0) 3635 1.1 christos { 3636 1.1 christos ptr[j] = 1; 3637 1.1 christos d_export_vec[i]->ordinal = j; 3638 1.1 christos goto done; 3639 1.1 christos } 3640 1.1 christos 3641 1.1 christos /* Then try before the range. */ 3642 1.1 christos for (j = lowest; j >0; j--) 3643 1.1 christos if (ptr[j] == 0) 3644 1.1 christos { 3645 1.1 christos ptr[j] = 1; 3646 1.1 christos d_export_vec[i]->ordinal = j; 3647 1.1 christos goto done; 3648 1.1 christos } 3649 1.1 christos done:; 3650 1.1 christos } 3651 1.1 christos } 3652 1.1 christos 3653 1.1 christos free (ptr); 3654 1.1 christos 3655 1.1 christos /* And resort. */ 3656 1.1 christos qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); 3657 1.1 christos 3658 1.1 christos /* Work out the lowest and highest ordinal numbers. */ 3659 1.1 christos if (d_nfuncs) 3660 1.1 christos { 3661 1.1 christos if (d_export_vec[0]) 3662 1.1 christos d_low_ord = d_export_vec[0]->ordinal; 3663 1.1 christos if (d_export_vec[d_nfuncs-1]) 3664 1.1 christos d_high_ord = d_export_vec[d_nfuncs-1]->ordinal; 3665 1.1 christos } 3666 1.1 christos } 3667 1.1 christos 3668 1.1 christos static void 3669 1.1 christos mangle_defs (void) 3670 1.1 christos { 3671 1.1 christos /* First work out the minimum ordinal chosen. */ 3672 1.10 christos export_type *exp; 3673 1.10 christos 3674 1.10 christos int i; 3675 1.6 christos int hint = 0; 3676 1.1 christos export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs); 3677 1.1 christos 3678 1.1 christos inform (_("Processing definitions")); 3679 1.1 christos 3680 1.1 christos for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 3681 1.1 christos d_export_vec[i] = exp; 3682 1.1 christos 3683 1.1 christos process_duplicates (d_export_vec); 3684 1.1 christos fill_ordinals (d_export_vec); 3685 1.1 christos 3686 1.1 christos /* Put back the list in the new order. */ 3687 1.1 christos d_exports = 0; 3688 1.1 christos for (i = d_nfuncs - 1; i >= 0; i--) 3689 1.1 christos { 3690 1.1 christos d_export_vec[i]->next = d_exports; 3691 1.1 christos d_exports = d_export_vec[i]; 3692 1.10 christos } 3693 1.1 christos free (d_export_vec); 3694 1.1 christos 3695 1.1 christos /* Build list in alpha order. */ 3696 1.1 christos d_exports_lexically = (export_type **) 3697 1.1 christos xmalloc (sizeof (export_type *) * (d_nfuncs + 1)); 3698 1.1 christos 3699 1.1 christos for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 3700 1.1 christos d_exports_lexically[i] = exp; 3701 1.1 christos 3702 1.1 christos d_exports_lexically[i] = 0; 3703 1.1 christos 3704 1.1 christos qsort (d_exports_lexically, i, sizeof (export_type *), nfunc); 3705 1.10 christos 3706 1.10 christos /* Fill exp entries with their hint values. */ 3707 1.10 christos for (i = 0; i < d_nfuncs; i++) 3708 1.10 christos if (!d_exports_lexically[i]->noname || show_allnames) 3709 1.10 christos d_exports_lexically[i]->hint = hint++; 3710 1.1 christos 3711 1.1 christos inform (_("Processed definitions")); 3712 1.1 christos } 3713 1.1 christos 3714 1.1 christos static void 3715 1.1 christos usage (FILE *file, int status) 3716 1.1 christos { 3717 1.1 christos /* xgetext:c-format */ 3718 1.1 christos fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name); 3719 1.1 christos /* xgetext:c-format */ 3720 1.9 christos fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname); 3721 1.1 christos fprintf (file, _(" possible <machine>: arm[_interwork], arm64, i386, mcore[-elf]{-le|-be}, thumb\n")); 3722 1.1 christos fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n")); 3723 1.1 christos fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n")); 3724 1.9 christos fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n")); 3725 1.9 christos fprintf (file, _(" --deterministic-libraries\n")); 3726 1.9 christos if (DEFAULT_AR_DETERMINISTIC) 3727 1.9 christos fprintf (file, _(" Use zero for timestamps and uids/gids in output libraries (default)\n")); 3728 1.9 christos else 3729 1.9 christos fprintf (file, _(" Use zero for timestamps and uids/gids in output libraries\n")); 3730 1.9 christos fprintf (file, _(" --non-deterministic-libraries\n")); 3731 1.9 christos if (DEFAULT_AR_DETERMINISTIC) 3732 1.9 christos fprintf (file, _(" Use actual timestamps and uids/gids in output libraries\n")); 3733 1.9 christos else 3734 1.1 christos fprintf (file, _(" Use actual timestamps and uids/gids in output libraries (default)\n")); 3735 1.1 christos fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n")); 3736 1.1 christos fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n")); 3737 1.1 christos fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n")); 3738 1.1 christos fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n")); 3739 1.1 christos fprintf (file, _(" --export-all-symbols Export all symbols to .def\n")); 3740 1.1 christos fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n")); 3741 1.1 christos fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n")); 3742 1.1 christos fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n")); 3743 1.1 christos fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n")); 3744 1.1 christos fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n")); 3745 1.1 christos fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n")); 3746 1.1 christos fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n")); 3747 1.1 christos fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n")); 3748 1.1 christos fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n")); 3749 1.1 christos fprintf (file, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n")); 3750 1.1 christos fprintf (file, _(" --leading-underscore All symbols should be prefixed by an underscore.\n")); 3751 1.1 christos fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n")); 3752 1.1 christos fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n")); 3753 1.1 christos fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n")); 3754 1.1 christos fprintf (file, _(" -S --as <name> Use <name> for assembler.\n")); 3755 1.1 christos fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n")); 3756 1.1 christos fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n")); 3757 1.1 christos fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n")); 3758 1.1 christos fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n")); 3759 1.1 christos fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n")); 3760 1.1 christos fprintf (file, _(" --identify-strict Causes --identify to report error when multiple DLLs.\n")); 3761 1.1 christos fprintf (file, _(" -v --verbose Be verbose.\n")); 3762 1.1 christos fprintf (file, _(" -V --version Display the program version.\n")); 3763 1.1 christos fprintf (file, _(" -h --help Display this information.\n")); 3764 1.1 christos fprintf (file, _(" @<file> Read options from <file>.\n")); 3765 1.1 christos #ifdef DLLTOOL_MCORE_ELF 3766 1.1 christos fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n")); 3767 1.1 christos fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n")); 3768 1.1 christos fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n")); 3769 1.1 christos #endif 3770 1.1 christos if (REPORT_BUGS_TO[0] && status == 0) 3771 1.1 christos fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO); 3772 1.1 christos exit (status); 3773 1.1 christos } 3774 1.9 christos 3775 1.9 christos /* 150 isn't special; it's just an arbitrary non-ASCII char value. */ 3776 1.9 christos enum command_line_switch 3777 1.9 christos { 3778 1.9 christos OPTION_EXPORT_ALL_SYMS = 150, 3779 1.9 christos OPTION_NO_EXPORT_ALL_SYMS, 3780 1.9 christos OPTION_EXCLUDE_SYMS, 3781 1.9 christos OPTION_NO_DEFAULT_EXCLUDES, 3782 1.9 christos OPTION_ADD_STDCALL_UNDERSCORE, 3783 1.9 christos OPTION_USE_NUL_PREFIXED_IMPORT_TABLES, 3784 1.9 christos OPTION_IDENTIFY_STRICT, 3785 1.9 christos OPTION_NO_LEADING_UNDERSCORE, 3786 1.9 christos OPTION_LEADING_UNDERSCORE, 3787 1.9 christos OPTION_DETERMINISTIC_LIBRARIES, 3788 1.9 christos OPTION_NON_DETERMINISTIC_LIBRARIES 3789 1.1 christos }; 3790 1.1 christos 3791 1.1 christos static const struct option long_options[] = 3792 1.9 christos { 3793 1.9 christos {"add-indirect", no_argument, NULL, 'a'}, 3794 1.9 christos {"add-stdcall-alias", no_argument, NULL, 'A'}, 3795 1.9 christos {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE}, 3796 1.9 christos {"add-underscore", no_argument, NULL, 'U'}, 3797 1.9 christos {"as", required_argument, NULL, 'S'}, 3798 1.9 christos {"as-flags", required_argument, NULL, 'f'}, 3799 1.9 christos {"base-file", required_argument, NULL, 'b'}, 3800 1.9 christos {"compat-implib", no_argument, NULL, 'C'}, 3801 1.9 christos {"def", required_argument, NULL, 'd'}, /* For compatibility with older versions. */ 3802 1.1 christos {"deterministic-libraries", no_argument, NULL, OPTION_DETERMINISTIC_LIBRARIES}, 3803 1.9 christos {"dllname", required_argument, NULL, 'D'}, 3804 1.1 christos {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS}, 3805 1.1 christos {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS}, 3806 1.9 christos {"ext-prefix-alias", required_argument, NULL, 'p'}, 3807 1.1 christos {"help", no_argument, NULL, 'h'}, 3808 1.1 christos {"identify", required_argument, NULL, 'I'}, 3809 1.9 christos {"identify-strict", no_argument, NULL, OPTION_IDENTIFY_STRICT}, 3810 1.9 christos {"input-def", required_argument, NULL, 'd'}, 3811 1.9 christos {"kill-at", no_argument, NULL, 'k'}, 3812 1.1 christos {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE}, 3813 1.1 christos {"machine", required_argument, NULL, 'm'}, 3814 1.9 christos {"mcore-elf", required_argument, NULL, 'M'}, 3815 1.9 christos {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES}, 3816 1.9 christos {"no-delete", no_argument, NULL, 'n'}, 3817 1.9 christos {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS}, 3818 1.9 christos {"no-idata4", no_argument, NULL, 'x'}, 3819 1.9 christos {"no-idata5", no_argument, NULL, 'c'}, 3820 1.9 christos {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE}, 3821 1.9 christos {"non-deterministic-libraries", no_argument, NULL, OPTION_NON_DETERMINISTIC_LIBRARIES}, 3822 1.9 christos {"output-def", required_argument, NULL, 'z'}, 3823 1.9 christos {"output-delaylib", required_argument, NULL, 'y'}, 3824 1.9 christos {"output-exp", required_argument, NULL, 'e'}, 3825 1.1 christos {"output-lib", required_argument, NULL, 'l'}, 3826 1.9 christos {"temp-prefix", required_argument, NULL, 't'}, 3827 1.9 christos {"use-nul-prefixed-import-tables", no_argument, NULL, OPTION_USE_NUL_PREFIXED_IMPORT_TABLES}, 3828 1.9 christos {"verbose", no_argument, NULL, 'v'}, 3829 1.1 christos {"version", no_argument, NULL, 'V'}, 3830 1.1 christos {NULL,0,NULL,0} 3831 1.1 christos }; 3832 1.1 christos 3833 1.1 christos int main (int, char **); 3834 1.1 christos 3835 1.1 christos int 3836 1.1 christos main (int ac, char **av) 3837 1.1 christos { 3838 1.1 christos int c; 3839 1.1 christos int i; 3840 1.1 christos char *firstarg = 0; 3841 1.1 christos program_name = av[0]; 3842 1.1 christos oav = av; 3843 1.8 christos 3844 1.1 christos #ifdef HAVE_LC_MESSAGES 3845 1.1 christos setlocale (LC_MESSAGES, ""); 3846 1.1 christos #endif 3847 1.1 christos setlocale (LC_CTYPE, ""); 3848 1.1 christos bindtextdomain (PACKAGE, LOCALEDIR); 3849 1.1 christos textdomain (PACKAGE); 3850 1.3 christos 3851 1.1 christos bfd_set_error_program_name (program_name); 3852 1.1 christos expandargv (&ac, &av); 3853 1.1 christos 3854 1.1 christos while ((c = getopt_long (ac, av, 3855 1.10 christos #ifdef DLLTOOL_MCORE_ELF 3856 1.1 christos "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:", 3857 1.10 christos #else 3858 1.1 christos "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh", 3859 1.1 christos #endif 3860 1.1 christos long_options, 0)) 3861 1.1 christos != EOF) 3862 1.1 christos { 3863 1.1 christos switch (c) 3864 1.1 christos { 3865 1.8 christos case OPTION_EXPORT_ALL_SYMS: 3866 1.1 christos export_all_symbols = true; 3867 1.1 christos break; 3868 1.8 christos case OPTION_NO_EXPORT_ALL_SYMS: 3869 1.1 christos export_all_symbols = false; 3870 1.1 christos break; 3871 1.1 christos case OPTION_EXCLUDE_SYMS: 3872 1.1 christos add_excludes (optarg); 3873 1.1 christos break; 3874 1.8 christos case OPTION_NO_DEFAULT_EXCLUDES: 3875 1.1 christos do_default_excludes = false; 3876 1.1 christos break; 3877 1.8 christos case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES: 3878 1.1 christos use_nul_prefixed_import_tables = true; 3879 1.1 christos break; 3880 1.1 christos case OPTION_ADD_STDCALL_UNDERSCORE: 3881 1.1 christos add_stdcall_underscore = 1; 3882 1.1 christos break; 3883 1.10 christos case OPTION_NO_LEADING_UNDERSCORE: 3884 1.1 christos leading_underscore = ""; 3885 1.1 christos break; 3886 1.10 christos case OPTION_LEADING_UNDERSCORE: 3887 1.1 christos leading_underscore = "_"; 3888 1.1 christos break; 3889 1.1 christos case OPTION_IDENTIFY_STRICT: 3890 1.1 christos identify_strict = 1; 3891 1.1 christos break; 3892 1.1 christos case 'x': 3893 1.1 christos no_idata4 = 1; 3894 1.1 christos break; 3895 1.1 christos case 'c': 3896 1.1 christos no_idata5 = 1; 3897 1.1 christos break; 3898 1.1 christos case 'S': 3899 1.1 christos as_name = optarg; 3900 1.1 christos break; 3901 1.1 christos case 't': 3902 1.1 christos tmp_prefix = optarg; 3903 1.1 christos break; 3904 1.1 christos case 'f': 3905 1.1 christos as_flags = optarg; 3906 1.1 christos break; 3907 1.1 christos 3908 1.1 christos /* Ignored for compatibility. */ 3909 1.1 christos case 'u': 3910 1.1 christos break; 3911 1.1 christos case 'a': 3912 1.1 christos add_indirect = 1; 3913 1.1 christos break; 3914 1.1 christos case 'z': 3915 1.3 christos output_def = fopen (optarg, FOPEN_WT); 3916 1.3 christos if (!output_def) 3917 1.3 christos /* xgettext:c-format */ 3918 1.1 christos fatal (_("Unable to open def-file: %s"), optarg); 3919 1.1 christos break; 3920 1.1 christos case 'D': 3921 1.1 christos dll_name = (char*) lbasename (optarg); 3922 1.1 christos if (dll_name != optarg) 3923 1.10 christos non_fatal (_("Path components stripped from dllname, '%s'."), 3924 1.1 christos optarg); 3925 1.1 christos break; 3926 1.1 christos case 'l': 3927 1.1 christos imp_name = optarg; 3928 1.1 christos break; 3929 1.1 christos case 'e': 3930 1.1 christos exp_name = optarg; 3931 1.1 christos break; 3932 1.1 christos case 'H': 3933 1.1 christos case 'h': 3934 1.1 christos usage (stdout, 0); 3935 1.1 christos break; 3936 1.1 christos case 'm': 3937 1.1 christos mname = optarg; 3938 1.1 christos break; 3939 1.1 christos case 'I': 3940 1.1 christos identify_imp_name = optarg; 3941 1.1 christos break; 3942 1.1 christos case 'v': 3943 1.1 christos verbose = 1; 3944 1.1 christos break; 3945 1.1 christos case 'V': 3946 1.1 christos print_version (program_name); 3947 1.1 christos break; 3948 1.1 christos case 'U': 3949 1.1 christos add_underscore = 1; 3950 1.1 christos break; 3951 1.1 christos case 'k': 3952 1.1 christos killat = 1; 3953 1.1 christos break; 3954 1.1 christos case 'A': 3955 1.1 christos add_stdcall_alias = 1; 3956 1.1 christos break; 3957 1.1 christos case 'p': 3958 1.1 christos ext_prefix_alias = optarg; 3959 1.1 christos break; 3960 1.1 christos case 'd': 3961 1.1 christos def_file = optarg; 3962 1.1 christos break; 3963 1.1 christos case 'n': 3964 1.1 christos dontdeltemps++; 3965 1.1 christos break; 3966 1.1 christos case 'b': 3967 1.1 christos base_file = fopen (optarg, FOPEN_RB); 3968 1.1 christos 3969 1.1 christos if (!base_file) 3970 1.1 christos /* xgettext:c-format */ 3971 1.1 christos fatal (_("Unable to open base-file: %s"), optarg); 3972 1.1 christos 3973 1.1 christos break; 3974 1.1 christos #ifdef DLLTOOL_MCORE_ELF 3975 1.1 christos case 'M': 3976 1.1 christos mcore_elf_out_file = optarg; 3977 1.1 christos break; 3978 1.1 christos case 'L': 3979 1.1 christos mcore_elf_linker = optarg; 3980 1.1 christos break; 3981 1.1 christos case 'F': 3982 1.1 christos mcore_elf_linker_flags = optarg; 3983 1.1 christos break; 3984 1.1 christos #endif 3985 1.1 christos case 'C': 3986 1.1 christos create_compat_implib = 1; 3987 1.1 christos break; 3988 1.1 christos case 'y': 3989 1.1 christos delayimp_name = optarg; 3990 1.9 christos break; 3991 1.9 christos case OPTION_DETERMINISTIC_LIBRARIES: 3992 1.9 christos deterministic = true; 3993 1.9 christos break; 3994 1.9 christos case OPTION_NON_DETERMINISTIC_LIBRARIES: 3995 1.9 christos deterministic = false; 3996 1.1 christos break; 3997 1.1 christos default: 3998 1.1 christos usage (stderr, 1); 3999 1.1 christos break; 4000 1.1 christos } 4001 1.1 christos } 4002 1.1 christos 4003 1.1 christos for (i = 0; mtable[i].type; i++) 4004 1.1 christos if (strcmp (mtable[i].type, mname) == 0) 4005 1.1 christos break; 4006 1.1 christos 4007 1.1 christos if (!mtable[i].type) 4008 1.1 christos /* xgettext:c-format */ 4009 1.1 christos fatal (_("Machine '%s' not supported"), mname); 4010 1.1 christos 4011 1.1 christos machine = i; 4012 1.1 christos 4013 1.10 christos /* Check if we generated PE+. */ 4014 1.10 christos create_for_pep = (strcmp (mname, "i386:x86-64") == 0 4015 1.1 christos || strcmp (mname, "arm64") == 0); 4016 1.10 christos 4017 1.10 christos /* Check the default underscore */ 4018 1.10 christos if (leading_underscore == NULL) 4019 1.10 christos { 4020 1.10 christos int u; 4021 1.1 christos static char underscore[2]; 4022 1.10 christos bfd_get_target_info (mtable[machine].how_bfd_target, NULL, 4023 1.10 christos NULL, &u, NULL); 4024 1.10 christos if (u == -1) 4025 1.10 christos u = 0; 4026 1.10 christos underscore[0] = u; 4027 1.10 christos underscore[1] = 0; 4028 1.10 christos leading_underscore = underscore; 4029 1.1 christos } 4030 1.1 christos 4031 1.1 christos if (!dll_name && exp_name) 4032 1.1 christos { 4033 1.10 christos /* If we are inferring dll_name from exp_name, 4034 1.10 christos strip off any path components, without emitting 4035 1.3 christos a warning. */ 4036 1.1 christos const char* exp_basename = lbasename (exp_name); 4037 1.1 christos const int len = strlen (exp_basename) + 5; 4038 1.1 christos dll_name = xmalloc (len); 4039 1.1 christos strcpy (dll_name, exp_basename); 4040 1.1 christos strcat (dll_name, ".dll"); 4041 1.1 christos dll_name_set_by_exp_name = 1; 4042 1.1 christos } 4043 1.1 christos 4044 1.1 christos if (as_name == NULL) 4045 1.1 christos as_name = deduce_name ("as"); 4046 1.1 christos 4047 1.1 christos /* Don't use the default exclude list if we're reading only the 4048 1.1 christos symbols in the .drectve section. The default excludes are meant 4049 1.1 christos to avoid exporting DLL entry point and Cygwin32 impure_ptr. */ 4050 1.8 christos if (! export_all_symbols) 4051 1.1 christos do_default_excludes = false; 4052 1.1 christos 4053 1.1 christos if (do_default_excludes) 4054 1.1 christos set_default_excludes (); 4055 1.1 christos 4056 1.1 christos if (def_file) 4057 1.1 christos process_def_file (def_file); 4058 1.1 christos 4059 1.1 christos while (optind < ac) 4060 1.1 christos { 4061 1.1 christos if (!firstarg) 4062 1.1 christos firstarg = av[optind]; 4063 1.1 christos scan_obj_file (av[optind]); 4064 1.1 christos optind++; 4065 1.1 christos } 4066 1.8 christos 4067 1.8 christos if (tmp_prefix == NULL) 4068 1.8 christos { 4069 1.10 christos /* If possible use a deterministic prefix. */ 4070 1.10 christos const char *input = imp_name ? imp_name : delayimp_name; 4071 1.10 christos if (input && strlen (input) + sizeof ("_snnnnn.o") - 1 <= NAME_MAX) 4072 1.10 christos { 4073 1.10 christos tmp_prefix = xasprintf ("%s_", input); 4074 1.10 christos for (i = 0; tmp_prefix[i]; i++) 4075 1.10 christos if (!ISALNUM (tmp_prefix[i])) 4076 1.10 christos tmp_prefix[i] = '_'; 4077 1.8 christos } 4078 1.10 christos else 4079 1.8 christos tmp_prefix = prefix_encode ("d", getpid ()); 4080 1.8 christos } 4081 1.1 christos 4082 1.1 christos mangle_defs (); 4083 1.1 christos 4084 1.1 christos if (exp_name) 4085 1.1 christos gen_exp_file (); 4086 1.1 christos 4087 1.1 christos if (imp_name) 4088 1.1 christos { 4089 1.1 christos /* Make imp_name safe for use as a label. */ 4090 1.1 christos char *p; 4091 1.1 christos 4092 1.1 christos imp_name_lab = xstrdup (imp_name); 4093 1.1 christos for (p = imp_name_lab; *p; p++) 4094 1.1 christos { 4095 1.1 christos if (!ISALNUM (*p)) 4096 1.1 christos *p = '_'; 4097 1.10 christos } 4098 1.1 christos head_label = make_label ("_head_", imp_name_lab); 4099 1.1 christos gen_lib_file (0); 4100 1.1 christos } 4101 1.1 christos 4102 1.1 christos if (delayimp_name) 4103 1.1 christos { 4104 1.1 christos /* Make delayimp_name safe for use as a label. */ 4105 1.1 christos char *p; 4106 1.1 christos 4107 1.10 christos if (mtable[machine].how_dljtab == 0) 4108 1.10 christos { 4109 1.10 christos inform (_("Warning, machine type (%d) not supported for " 4110 1.10 christos "delayimport."), machine); 4111 1.1 christos } 4112 1.10 christos else 4113 1.10 christos { 4114 1.10 christos killat = 1; 4115 1.10 christos imp_name = delayimp_name; 4116 1.10 christos imp_name_lab = xstrdup (imp_name); 4117 1.10 christos for (p = imp_name_lab; *p; p++) 4118 1.10 christos { 4119 1.10 christos if (!ISALNUM (*p)) 4120 1.10 christos *p = '_'; 4121 1.10 christos } 4122 1.10 christos head_label = make_label ("__tailMerge_", imp_name_lab); 4123 1.10 christos gen_lib_file (1); 4124 1.1 christos } 4125 1.1 christos } 4126 1.1 christos 4127 1.1 christos if (output_def) 4128 1.1 christos gen_def_file (); 4129 1.1 christos 4130 1.1 christos if (identify_imp_name) 4131 1.1 christos { 4132 1.1 christos identify_dll_for_implib (); 4133 1.1 christos } 4134 1.1 christos 4135 1.1 christos #ifdef DLLTOOL_MCORE_ELF 4136 1.1 christos if (mcore_elf_out_file) 4137 1.1 christos mcore_elf_gen_out_file (); 4138 1.1 christos #endif 4139 1.1 christos 4140 1.1 christos return 0; 4141 1.1 christos } 4142 1.1 christos 4143 1.1 christos /* Look for the program formed by concatenating PROG_NAME and the 4144 1.1 christos string running from PREFIX to END_PREFIX. If the concatenated 4145 1.1 christos string contains a '/', try appending EXECUTABLE_SUFFIX if it is 4146 1.1 christos appropriate. */ 4147 1.1 christos 4148 1.1 christos static char * 4149 1.1 christos look_for_prog (const char *prog_name, const char *prefix, int end_prefix) 4150 1.1 christos { 4151 1.1 christos struct stat s; 4152 1.1 christos char *cmd; 4153 1.1 christos 4154 1.1 christos cmd = xmalloc (strlen (prefix) 4155 1.1 christos + strlen (prog_name) 4156 1.1 christos #ifdef HAVE_EXECUTABLE_SUFFIX 4157 1.1 christos + strlen (EXECUTABLE_SUFFIX) 4158 1.1 christos #endif 4159 1.9 christos + 10); 4160 1.1 christos memcpy (cmd, prefix, end_prefix); 4161 1.9 christos 4162 1.1 christos strcpy (cmd + end_prefix, prog_name); 4163 1.1 christos 4164 1.1 christos if (strchr (cmd, '/') != NULL) 4165 1.1 christos { 4166 1.1 christos int found; 4167 1.1 christos 4168 1.1 christos found = (stat (cmd, &s) == 0 4169 1.1 christos #ifdef HAVE_EXECUTABLE_SUFFIX 4170 1.1 christos || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0 4171 1.1 christos #endif 4172 1.1 christos ); 4173 1.1 christos 4174 1.1 christos if (! found) 4175 1.1 christos { 4176 1.1 christos /* xgettext:c-format */ 4177 1.1 christos inform (_("Tried file: %s"), cmd); 4178 1.1 christos free (cmd); 4179 1.1 christos return NULL; 4180 1.1 christos } 4181 1.1 christos } 4182 1.1 christos 4183 1.1 christos /* xgettext:c-format */ 4184 1.1 christos inform (_("Using file: %s"), cmd); 4185 1.1 christos 4186 1.1 christos return cmd; 4187 1.1 christos } 4188 1.1 christos 4189 1.1 christos /* Deduce the name of the program we are want to invoke. 4190 1.1 christos PROG_NAME is the basic name of the program we want to run, 4191 1.8 christos eg "as" or "ld". The catch is that we might want actually 4192 1.1 christos run "i386-pe-as". 4193 1.1 christos 4194 1.1 christos If argv[0] contains the full path, then try to find the program 4195 1.1 christos in the same place, with and then without a target-like prefix. 4196 1.1 christos 4197 1.1 christos Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool, 4198 1.1 christos deduce_name("as") uses the following search order: 4199 1.1 christos 4200 1.1 christos /usr/local/bin/i586-cygwin32-as 4201 1.1 christos /usr/local/bin/as 4202 1.1 christos as 4203 1.1 christos 4204 1.1 christos If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each 4205 1.1 christos name, it'll try without and then with EXECUTABLE_SUFFIX. 4206 1.1 christos 4207 1.1 christos Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as" 4208 1.1 christos as the fallback, but rather return i586-cygwin32-as. 4209 1.1 christos 4210 1.1 christos Oh, and given, argv[0] = dlltool, it'll return "as". 4211 1.1 christos 4212 1.1 christos Returns a dynamically allocated string. */ 4213 1.1 christos 4214 1.1 christos static char * 4215 1.1 christos deduce_name (const char *prog_name) 4216 1.1 christos { 4217 1.1 christos char *cmd; 4218 1.1 christos char *dash, *slash, *cp; 4219 1.1 christos 4220 1.1 christos dash = NULL; 4221 1.1 christos slash = NULL; 4222 1.1 christos for (cp = program_name; *cp != '\0'; ++cp) 4223 1.1 christos { 4224 1.1 christos if (*cp == '-') 4225 1.1 christos dash = cp; 4226 1.1 christos if ( 4227 1.1 christos #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) 4228 1.1 christos *cp == ':' || *cp == '\\' || 4229 1.1 christos #endif 4230 1.1 christos *cp == '/') 4231 1.1 christos { 4232 1.1 christos slash = cp; 4233 1.1 christos dash = NULL; 4234 1.1 christos } 4235 1.1 christos } 4236 1.1 christos 4237 1.1 christos cmd = NULL; 4238 1.1 christos 4239 1.1 christos if (dash != NULL) 4240 1.1 christos { 4241 1.10 christos /* First, try looking for a prefixed PROG_NAME in the 4242 1.1 christos PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */ 4243 1.1 christos cmd = look_for_prog (prog_name, program_name, dash - program_name + 1); 4244 1.1 christos } 4245 1.1 christos 4246 1.1 christos if (slash != NULL && cmd == NULL) 4247 1.1 christos { 4248 1.10 christos /* Next, try looking for a PROG_NAME in the same directory as 4249 1.1 christos that of this program. */ 4250 1.1 christos cmd = look_for_prog (prog_name, program_name, slash - program_name + 1); 4251 1.1 christos } 4252 1.1 christos 4253 1.1 christos if (cmd == NULL) 4254 1.1 christos { 4255 1.1 christos /* Just return PROG_NAME as is. */ 4256 1.1 christos cmd = xstrdup (prog_name); 4257 1.1 christos } 4258 1.1 christos 4259 1.1 christos return cmd; 4260 1.1 christos } 4261 1.1 christos 4262 1.1 christos #ifdef DLLTOOL_MCORE_ELF 4263 1.1 christos typedef struct fname_cache 4264 1.1 christos { 4265 1.1 christos const char * filename; 4266 1.1 christos struct fname_cache * next; 4267 1.1 christos } 4268 1.1 christos fname_cache; 4269 1.1 christos 4270 1.1 christos static fname_cache fnames; 4271 1.1 christos 4272 1.1 christos static void 4273 1.1 christos mcore_elf_cache_filename (const char * filename) 4274 1.1 christos { 4275 1.1 christos fname_cache * ptr; 4276 1.1 christos 4277 1.1 christos ptr = & fnames; 4278 1.1 christos 4279 1.1 christos while (ptr->next != NULL) 4280 1.1 christos ptr = ptr->next; 4281 1.1 christos 4282 1.1 christos ptr->filename = filename; 4283 1.1 christos ptr->next = (fname_cache *) malloc (sizeof (fname_cache)); 4284 1.1 christos if (ptr->next != NULL) 4285 1.1 christos ptr->next->next = NULL; 4286 1.1 christos } 4287 1.1 christos 4288 1.1 christos #define MCORE_ELF_TMP_OBJ "mcoreelf.o" 4289 1.1 christos #define MCORE_ELF_TMP_EXP "mcoreelf.exp" 4290 1.1 christos #define MCORE_ELF_TMP_LIB "mcoreelf.lib" 4291 1.1 christos 4292 1.1 christos static void 4293 1.1 christos mcore_elf_gen_out_file (void) 4294 1.1 christos { 4295 1.1 christos fname_cache * ptr; 4296 1.1 christos dyn_string_t ds; 4297 1.1 christos 4298 1.1 christos /* Step one. Run 'ld -r' on the input object files in order to resolve 4299 1.1 christos any internal references and to generate a single .exports section. */ 4300 1.1 christos ptr = & fnames; 4301 1.1 christos 4302 1.1 christos ds = dyn_string_new (100); 4303 1.1 christos dyn_string_append_cstr (ds, "-r "); 4304 1.1 christos 4305 1.1 christos if (mcore_elf_linker_flags != NULL) 4306 1.1 christos dyn_string_append_cstr (ds, mcore_elf_linker_flags); 4307 1.1 christos 4308 1.1 christos while (ptr->next != NULL) 4309 1.1 christos { 4310 1.1 christos dyn_string_append_cstr (ds, ptr->filename); 4311 1.1 christos dyn_string_append_cstr (ds, " "); 4312 1.1 christos 4313 1.1 christos ptr = ptr->next; 4314 1.1 christos } 4315 1.1 christos 4316 1.1 christos dyn_string_append_cstr (ds, "-o "); 4317 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 4318 1.1 christos 4319 1.1 christos if (mcore_elf_linker == NULL) 4320 1.1 christos mcore_elf_linker = deduce_name ("ld"); 4321 1.1 christos 4322 1.1 christos run (mcore_elf_linker, ds->s); 4323 1.1 christos 4324 1.1 christos dyn_string_delete (ds); 4325 1.1 christos 4326 1.1 christos /* Step two. Create a .exp file and a .lib file from the temporary file. 4327 1.1 christos Do this by recursively invoking dlltool... */ 4328 1.1 christos ds = dyn_string_new (100); 4329 1.1 christos 4330 1.1 christos dyn_string_append_cstr (ds, "-S "); 4331 1.1 christos dyn_string_append_cstr (ds, as_name); 4332 1.1 christos 4333 1.1 christos dyn_string_append_cstr (ds, " -e "); 4334 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP); 4335 1.1 christos dyn_string_append_cstr (ds, " -l "); 4336 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB); 4337 1.1 christos dyn_string_append_cstr (ds, " " ); 4338 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 4339 1.1 christos 4340 1.1 christos if (verbose) 4341 1.1 christos dyn_string_append_cstr (ds, " -v"); 4342 1.1 christos 4343 1.1 christos if (dontdeltemps) 4344 1.1 christos { 4345 1.1 christos dyn_string_append_cstr (ds, " -n"); 4346 1.1 christos 4347 1.1 christos if (dontdeltemps > 1) 4348 1.1 christos dyn_string_append_cstr (ds, " -n"); 4349 1.1 christos } 4350 1.1 christos 4351 1.1 christos /* XXX - FIME: ought to check/copy other command line options as well. */ 4352 1.1 christos run (program_name, ds->s); 4353 1.1 christos 4354 1.1 christos dyn_string_delete (ds); 4355 1.1 christos 4356 1.1 christos /* Step four. Feed the .exp and object files to ld -shared to create the dll. */ 4357 1.1 christos ds = dyn_string_new (100); 4358 1.1 christos 4359 1.1 christos dyn_string_append_cstr (ds, "-shared "); 4360 1.1 christos 4361 1.1 christos if (mcore_elf_linker_flags) 4362 1.1 christos dyn_string_append_cstr (ds, mcore_elf_linker_flags); 4363 1.1 christos 4364 1.1 christos dyn_string_append_cstr (ds, " "); 4365 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP); 4366 1.1 christos dyn_string_append_cstr (ds, " "); 4367 1.1 christos dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 4368 1.1 christos dyn_string_append_cstr (ds, " -o "); 4369 1.1 christos dyn_string_append_cstr (ds, mcore_elf_out_file); 4370 1.1 christos 4371 1.1 christos run (mcore_elf_linker, ds->s); 4372 1.1 christos 4373 1.1 christos dyn_string_delete (ds); 4374 1.1 christos 4375 1.1 christos if (dontdeltemps == 0) 4376 1.1 christos unlink (MCORE_ELF_TMP_EXP); 4377 1.1 christos 4378 1.1 christos if (dontdeltemps < 2) 4379 1.1 christos unlink (MCORE_ELF_TMP_OBJ); 4380 1.1 christos } 4381 #endif /* DLLTOOL_MCORE_ELF */ 4382