testsuite: skip confirmation in 'gdb_reinitialize_dir'
[binutils-gdb.git] / binutils / dlltool.c
blob17e9416a7f1eedfdf4acc69dda8a3458504164dd
1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
22 /* This program allows you to build the files necessary to create
23 DLLs to run on a system which understands PE format image files.
24 (eg, Windows NT)
26 See "Peering Inside the PE: A Tour of the Win32 Portable Executable
27 File Format", MSJ 1994, Volume 9 for more information.
28 Also see "Microsoft Portable Executable and Common Object File Format,
29 Specification 4.1" for more information.
31 A DLL contains an export table which contains the information
32 which the runtime loader needs to tie up references from a
33 referencing program.
35 The export table is generated by this program by reading
36 in a .DEF file or scanning the .a and .o files which will be in the
37 DLL. A .o file can contain information in special ".drectve" sections
38 with export information.
40 A DEF file contains any number of the following commands:
43 NAME <name> [ , <base> ]
44 The result is going to be <name>.EXE
46 LIBRARY <name> [ , <base> ]
47 The result is going to be <name>.DLL
49 EXPORTS ( ( ( <name1> [ = <name2> ] )
50 | ( <name1> = <module-name> . <external-name>))
51 [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
52 Declares name1 as an exported symbol from the
53 DLL, with optional ordinal number <integer>.
54 Or declares name1 as an alias (forward) of the function <external-name>
55 in the DLL <module-name>.
57 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
58 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
59 Declares that <external-name> or the exported function whose ordinal number
60 is <integer> is to be imported from the file <module-name>. If
61 <internal-name> is specified then this is the name that the imported
62 function will be refereed to in the body of the DLL.
64 DESCRIPTION <string>
65 Puts <string> into output .exp file in the .rdata section
67 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
68 Generates --stack|--heap <number-reserve>,<number-commit>
69 in the output .drectve section. The linker will
70 see this and act upon it.
72 [CODE|DATA] <attr>+
73 SECTIONS ( <sectionname> <attr>+ )*
74 <attr> = READ | WRITE | EXECUTE | SHARED
75 Generates --attr <sectionname> <attr> in the output
76 .drectve section. The linker will see this and act
77 upon it.
80 A -export:<name> in a .drectve section in an input .o or .a
81 file to this program is equivalent to a EXPORTS <name>
82 in a .DEF file.
86 The program generates output files with the prefix supplied
87 on the command line, or in the def file, or taken from the first
88 supplied argument.
90 The .exp.s file contains the information necessary to export
91 the routines in the DLL. The .lib.s file contains the information
92 necessary to use the DLL's routines from a referencing program.
96 Example:
98 file1.c:
99 asm (".section .drectve");
100 asm (".ascii \"-export:adef\"");
102 void adef (char * s)
104 printf ("hello from the dll %s\n", s);
107 void bdef (char * s)
109 printf ("hello from the dll and the other entry point %s\n", s);
112 file2.c:
113 asm (".section .drectve");
114 asm (".ascii \"-export:cdef\"");
115 asm (".ascii \"-export:ddef\"");
117 void cdef (char * s)
119 printf ("hello from the dll %s\n", s);
122 void ddef (char * s)
124 printf ("hello from the dll and the other entry point %s\n", s);
127 int printf (void)
129 return 9;
132 themain.c:
133 int main (void)
135 cdef ();
136 return 0;
139 thedll.def
141 LIBRARY thedll
142 HEAPSIZE 0x40000, 0x2000
143 EXPORTS bdef @ 20
144 cdef @ 30 NONAME
146 SECTIONS donkey READ WRITE
147 aardvark EXECUTE
149 # Compile up the parts of the dll and the program
151 gcc -c file1.c file2.c themain.c
153 # Optional: put the dll objects into a library
154 # (you don't have to, you could name all the object
155 # files on the dlltool line)
157 ar qcv thedll.in file1.o file2.o
158 ranlib thedll.in
160 # Run this tool over the DLL's .def file and generate an exports
161 # file (thedll.o) and an imports file (thedll.a).
162 # (You may have to use -S to tell dlltool where to find the assembler).
164 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
166 # Build the dll with the library and the export table
168 ld -o thedll.dll thedll.o thedll.in
170 # Link the executable with the import library
172 gcc -o themain.exe themain.o thedll.a
174 This example can be extended if relocations are needed in the DLL:
176 # Compile up the parts of the dll and the program
178 gcc -c file1.c file2.c themain.c
180 # Run this tool over the DLL's .def file and generate an imports file.
182 dlltool --def thedll.def --output-lib thedll.lib
184 # Link the executable with the import library and generate a base file
185 # at the same time
187 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
189 # Run this tool over the DLL's .def file and generate an exports file
190 # which includes the relocations from the base file.
192 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
194 # Build the dll with file1.o, file2.o and the export table
196 ld -o thedll.dll thedll.exp file1.o file2.o */
198 /* .idata section description
200 The .idata section is the import table. It is a collection of several
201 subsections used to keep the pieces for each dll together: .idata$[234567].
202 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
204 .idata$2 = Import Directory Table
205 = array of IMAGE_IMPORT_DESCRIPTOR's.
207 DWORD Import Lookup Table; - pointer to .idata$4
208 DWORD TimeDateStamp; - currently always 0
209 DWORD ForwarderChain; - currently always 0
210 DWORD Name; - pointer to dll's name
211 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
213 .idata$3 = null terminating entry for .idata$2.
215 .idata$4 = Import Lookup Table
216 = array of array of numbers, which has meaning based on its highest bit:
217 - when cleared - pointer to entry in Hint Name Table
218 - when set - 16-bit function's ordinal number (rest of the bits are zeros)
219 Function ordinal number subtracted by Export Directory Table's
220 Ordinal Base is an index entry into the Export Address Table.
221 There is one for each dll being imported from, and each dll's set is
222 terminated by a trailing NULL.
224 .idata$5 = Import Address Table
225 There is one for each dll being imported from, and each dll's set is
226 terminated by a trailing NULL.
227 Initially, this table is identical to the Import Lookup Table. However,
228 at load time, the loader overwrites the entries with the address of the
229 function.
231 .idata$6 = Hint Name Table
232 = Array of { short, asciz } entries, one for each imported function.
233 The `short' is the name hint - index into Export Name Pointer Table.
234 The `asciz` is the name string - value in Export Name Table referenced
235 by some entry in Export Name Pointer Table. Name hint should be the
236 index of that entry in Export Name Pointer Table. It has no connection
237 with the function's ordinal number.
239 .idata$7 = dll name (eg: "kernel32.dll"). */
241 #include "sysdep.h"
242 #include "bfd.h"
243 #include "libiberty.h"
244 #include "getopt.h"
245 #include "demangle.h"
246 #include "dyn-string.h"
247 #include "bucomm.h"
248 #include "dlltool.h"
249 #include "safe-ctype.h"
250 #include "coff-bfd.h"
252 #include <time.h>
253 #include <assert.h>
255 #ifdef DLLTOOL_ARM
256 #include "coff/arm.h"
257 #include "coff/internal.h"
258 #endif
259 #ifdef DLLTOOL_DEFAULT_MX86_64
260 #include "coff/x86_64.h"
261 #endif
262 #ifdef DLLTOOL_DEFAULT_I386
263 #include "coff/i386.h"
264 #endif
266 #ifndef COFF_PAGE_SIZE
267 #define COFF_PAGE_SIZE ((bfd_vma) 4096)
268 #endif
270 #ifndef PAGE_MASK
271 #define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE))
272 #endif
274 #ifndef NAME_MAX
275 #define NAME_MAX 255
276 #endif
278 #ifdef HAVE_SYS_WAIT_H
279 #include <sys/wait.h>
280 #else /* ! HAVE_SYS_WAIT_H */
281 #if ! defined (_WIN32) || defined (__CYGWIN32__)
282 #ifndef WIFEXITED
283 #define WIFEXITED(w) (((w) & 0377) == 0)
284 #endif
285 #ifndef WIFSIGNALED
286 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
287 #endif
288 #ifndef WTERMSIG
289 #define WTERMSIG(w) ((w) & 0177)
290 #endif
291 #ifndef WEXITSTATUS
292 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
293 #endif
294 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
295 #ifndef WIFEXITED
296 #define WIFEXITED(w) (((w) & 0xff) == 0)
297 #endif
298 #ifndef WIFSIGNALED
299 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300 #endif
301 #ifndef WTERMSIG
302 #define WTERMSIG(w) ((w) & 0x7f)
303 #endif
304 #ifndef WEXITSTATUS
305 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
306 #endif
307 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308 #endif /* ! HAVE_SYS_WAIT_H */
310 #define show_allnames 0
312 /* ifunc and ihead data structures: ttk@cygnus.com 1997
314 When IMPORT declarations are encountered in a .def file the
315 function import information is stored in a structure referenced by
316 the global variable IMPORT_LIST. The structure is a linked list
317 containing the names of the dll files each function is imported
318 from and a linked list of functions being imported from that dll
319 file. This roughly parallels the structure of the .idata section
320 in the PE object file.
322 The contents of .def file are interpreted from within the
323 process_def_file function. Every time an IMPORT declaration is
324 encountered, it is broken up into its component parts and passed to
325 def_import. IMPORT_LIST is initialized to NULL in function main. */
327 typedef struct ifunct
329 char * name; /* Name of function being imported. */
330 char * its_name; /* Optional import table symbol name. */
331 int ord; /* Two-byte ordinal value associated with function. */
332 struct ifunct *next;
333 } ifunctype;
335 typedef struct iheadt
337 char * dllname; /* Name of dll file imported from. */
338 long nfuncs; /* Number of functions in list. */
339 struct ifunct *funchead; /* First function in list. */
340 struct ifunct *functail; /* Last function in list. */
341 struct iheadt *next; /* Next dll file in list. */
342 } iheadtype;
344 /* Structure containing all import information as defined in .def file
345 (qv "ihead structure"). */
347 static iheadtype *import_list = NULL;
348 static char *as_name = NULL;
349 static char * as_flags = "";
350 static char *tmp_prefix = NULL;
351 static int no_idata4;
352 static int no_idata5;
353 static char *exp_name;
354 static char *imp_name;
355 static char *delayimp_name;
356 static char *identify_imp_name;
357 static bool identify_strict;
358 static bool deterministic = DEFAULT_AR_DETERMINISTIC;
360 /* Types used to implement a linked list of dllnames associated
361 with the specified import lib. Used by the identify_* code.
362 The head entry is acts as a sentinal node and is always empty
363 (head->dllname is NULL). */
364 typedef struct dll_name_list_node_t
366 char * dllname;
367 struct dll_name_list_node_t * next;
368 } dll_name_list_node_type;
370 typedef struct dll_name_list_t
372 dll_name_list_node_type * head;
373 dll_name_list_node_type * tail;
374 } dll_name_list_type;
376 /* Types used to pass data to iterator functions. */
377 typedef struct symname_search_data_t
379 const char *symname;
380 bool found;
381 } symname_search_data_type;
383 typedef struct identify_data_t
385 dll_name_list_type *list;
386 bool ms_style_implib;
387 } identify_data_type;
390 static char *head_label;
391 static char *imp_name_lab;
392 static char *dll_name;
393 static int dll_name_set_by_exp_name;
394 static int add_indirect = 0;
395 static int add_underscore = 0;
396 static int add_stdcall_underscore = 0;
397 static char *leading_underscore = NULL;
398 static int dontdeltemps = 0;
400 /* TRUE if we should export all symbols. Otherwise, we only export
401 symbols listed in .drectve sections or in the def file. */
402 static bool export_all_symbols;
404 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
405 exporting all symbols. */
406 static bool do_default_excludes = true;
408 static bool use_nul_prefixed_import_tables = false;
410 /* Default symbols to exclude when exporting all the symbols. */
411 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
413 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
414 compatibility to old Cygwin releases. */
415 static bool create_compat_implib;
417 /* TRUE if we have to write PE+ import libraries. */
418 static bool create_for_pep;
420 static char *def_file;
422 extern char * program_name;
424 static int machine;
425 static int killat;
426 static int add_stdcall_alias;
427 static const char *ext_prefix_alias;
428 static int verbose;
429 static FILE *output_def;
430 static FILE *base_file;
432 #ifdef DLLTOOL_DEFAULT_ARM
433 static const char *mname = "arm";
434 #endif
436 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
437 static const char *mname = "arm-wince";
438 #endif
440 #ifdef DLLTOOL_DEFAULT_AARCH64
441 /* arm64 rather than aarch64 to match llvm-dlltool */
442 static const char *mname = "arm64";
443 #endif
445 #ifdef DLLTOOL_DEFAULT_I386
446 static const char *mname = "i386";
447 #endif
449 #ifdef DLLTOOL_DEFAULT_MX86_64
450 static const char *mname = "i386:x86-64";
451 #endif
453 #ifdef DLLTOOL_DEFAULT_SH
454 static const char *mname = "sh";
455 #endif
457 #ifdef DLLTOOL_DEFAULT_MIPS
458 static const char *mname = "mips";
459 #endif
461 #ifdef DLLTOOL_DEFAULT_MCORE
462 static const char * mname = "mcore-le";
463 #endif
465 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
466 static const char * mname = "mcore-elf";
467 static char * mcore_elf_out_file = NULL;
468 static char * mcore_elf_linker = NULL;
469 static char * mcore_elf_linker_flags = NULL;
471 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
472 #endif
474 #ifndef DRECTVE_SECTION_NAME
475 #define DRECTVE_SECTION_NAME ".drectve"
476 #endif
478 /* External name alias numbering starts here. */
479 #define PREFIX_ALIAS_BASE 20000
481 static char *tmp_asm_buf;
482 static char *tmp_head_s_buf;
483 static char *tmp_head_o_buf;
484 static char *tmp_tail_s_buf;
485 static char *tmp_tail_o_buf;
486 static char *tmp_stub_buf;
488 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
489 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
490 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
491 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
492 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
493 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ssnnnnn.o")
495 /* This bit of assembly does jmp * .... */
496 static const unsigned char i386_jtab[] =
498 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
501 static const unsigned char i386_dljtab[] =
503 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
504 0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
505 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
508 static const unsigned char i386_x64_dljtab[] =
510 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
511 0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */
512 0x00, 0x00, 0x00, 0x00,
513 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
516 static const unsigned char arm_jtab[] =
518 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
519 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
520 0, 0, 0, 0
523 static const unsigned char arm_interwork_jtab[] =
525 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
526 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
527 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
528 0, 0, 0, 0
531 static const unsigned char thumb_jtab[] =
533 0x40, 0xb4, /* push {r6} */
534 0x02, 0x4e, /* ldr r6, [pc, #8] */
535 0x36, 0x68, /* ldr r6, [r6] */
536 0xb4, 0x46, /* mov ip, r6 */
537 0x40, 0xbc, /* pop {r6} */
538 0x60, 0x47, /* bx ip */
539 0, 0, 0, 0
542 static const unsigned char mcore_be_jtab[] =
544 0x71, 0x02, /* lrw r1,2 */
545 0x81, 0x01, /* ld.w r1,(r1,0) */
546 0x00, 0xC1, /* jmp r1 */
547 0x12, 0x00, /* nop */
548 0x00, 0x00, 0x00, 0x00 /* <address> */
551 static const unsigned char mcore_le_jtab[] =
553 0x02, 0x71, /* lrw r1,2 */
554 0x01, 0x81, /* ld.w r1,(r1,0) */
555 0xC1, 0x00, /* jmp r1 */
556 0x00, 0x12, /* nop */
557 0x00, 0x00, 0x00, 0x00 /* <address> */
560 static const unsigned char aarch64_jtab[] =
562 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
563 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
564 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
565 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
568 static const char i386_trampoline[] =
569 "\tpushl %%ecx\n"
570 "\tpushl %%edx\n"
571 "\tpushl %%eax\n"
572 "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
573 "\tcall ___delayLoadHelper2@8\n"
574 "\tpopl %%edx\n"
575 "\tpopl %%ecx\n"
576 "\tjmp *%%eax\n";
578 /* Save integer arg regs in parameter space reserved by our caller
579 above the return address. Allocate space for six fp arg regs plus
580 parameter space possibly used by __delayLoadHelper2 plus alignment.
581 We enter with the stack offset from 16-byte alignment by the return
582 address, so allocate 96 + 32 + 8 = 136 bytes. Note that only the
583 first four xmm regs are used to pass fp args, but the first six
584 vector ymm (zmm too?) are used to pass vector args. We are
585 assuming that volatile vector regs are not modified inside
586 __delayLoadHelper2. However, it is known that at least xmm0 and
587 xmm1 are trashed in some versions of Microsoft dlls, and if xmm4 or
588 xmm5 are also used then that would trash the lower bits of ymm4 and
589 ymm5. If it turns out that vector insns with a vex prefix are used
590 then we'll need to save ymm0-5 here but that can't be done without
591 first testing cpuid and xcr0. */
592 static const char i386_x64_trampoline[] =
593 "\tsubq $136, %%rsp\n"
594 "\t.seh_stackalloc 136\n"
595 "\t.seh_endprologue\n"
596 "\tmovq %%rcx, 136+8(%%rsp)\n"
597 "\tmovq %%rdx, 136+16(%%rsp)\n"
598 "\tmovq %%r8, 136+24(%%rsp)\n"
599 "\tmovq %%r9, 136+32(%%rsp)\n"
600 "\tmovaps %%xmm0, 32(%%rsp)\n"
601 "\tmovaps %%xmm1, 48(%%rsp)\n"
602 "\tmovaps %%xmm2, 64(%%rsp)\n"
603 "\tmovaps %%xmm3, 80(%%rsp)\n"
604 "\tmovaps %%xmm4, 96(%%rsp)\n"
605 "\tmovaps %%xmm5, 112(%%rsp)\n"
606 "\tmovq %%rax, %%rdx\n"
607 "\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n"
608 "\tcall __delayLoadHelper2\n"
609 "\tmovq 136+8(%%rsp), %%rcx\n"
610 "\tmovq 136+16(%%rsp), %%rdx\n"
611 "\tmovq 136+24(%%rsp), %%r8\n"
612 "\tmovq 136+32(%%rsp), %%r9\n"
613 "\tmovaps 32(%%rsp), %%xmm0\n"
614 "\tmovaps 48(%%rsp), %%xmm1\n"
615 "\tmovaps 64(%%rsp), %%xmm2\n"
616 "\tmovaps 80(%%rsp), %%xmm3\n"
617 "\tmovaps 96(%%rsp), %%xmm4\n"
618 "\tmovaps 112(%%rsp), %%xmm5\n"
619 "\taddq $136, %%rsp\n"
620 "\tjmp *%%rax\n";
622 struct mac
624 const char *type;
625 const char *how_byte;
626 const char *how_short;
627 const char *how_long;
628 const char *how_asciz;
629 const char *how_comment;
630 const char *how_jump;
631 const char *how_global;
632 const char *how_space;
633 const char *how_align_short;
634 const char *how_align_long;
635 const char *how_default_as_switches;
636 const char *how_bfd_target;
637 enum bfd_architecture how_bfd_arch;
638 const unsigned char *how_jtab;
639 int how_jtab_size; /* Size of the jtab entry. */
640 int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
641 const unsigned char *how_dljtab;
642 int how_dljtab_size; /* Size of the dljtab entry. */
643 int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */
644 int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */
645 int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */
646 bool how_seh;
647 const char *trampoline;
650 static const struct mac
651 mtable[] =
654 #define MARM 0
655 "arm", ".byte", ".short", ".long", ".asciz", "@",
656 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
657 ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32",
658 "pe-arm-little", bfd_arch_arm,
659 arm_jtab, sizeof (arm_jtab), 8,
660 0, 0, 0, 0, 0, false, 0
664 #define M386 1
665 "i386", ".byte", ".short", ".long", ".asciz", "#",
666 "jmp *", ".global", ".space", ".align\t2", ".align\t4", "",
667 "pe-i386",bfd_arch_i386,
668 i386_jtab, sizeof (i386_jtab), 2,
669 i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, false, i386_trampoline
673 #define MTHUMB 2
674 "thumb", ".byte", ".short", ".long", ".asciz", "@",
675 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
676 ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork",
677 "pe-arm-little", bfd_arch_arm,
678 thumb_jtab, sizeof (thumb_jtab), 12,
679 0, 0, 0, 0, 0, false, 0
682 #define MARM_INTERWORK 3
684 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
685 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
686 ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork",
687 "pe-arm-little", bfd_arch_arm,
688 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
689 0, 0, 0, 0, 0, false, 0
693 #define MMCORE_BE 4
694 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
695 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
696 ".global", ".space", ".align\t2", ".align\t4", "",
697 "pe-mcore-big", bfd_arch_mcore,
698 mcore_be_jtab, sizeof (mcore_be_jtab), 8,
699 0, 0, 0, 0, 0, false, 0
703 #define MMCORE_LE 5
704 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
705 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
706 ".global", ".space", ".align\t2", ".align\t4", "-EL",
707 "pe-mcore-little", bfd_arch_mcore,
708 mcore_le_jtab, sizeof (mcore_le_jtab), 8,
709 0, 0, 0, 0, 0, false, 0
713 #define MMCORE_ELF 6
714 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
715 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
716 ".global", ".space", ".align\t2", ".align\t4", "",
717 "elf32-mcore-big", bfd_arch_mcore,
718 mcore_be_jtab, sizeof (mcore_be_jtab), 8,
719 0, 0, 0, 0, 0, false, 0
723 #define MMCORE_ELF_LE 7
724 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
725 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
726 ".global", ".space", ".align\t2", ".align\t4", "-EL",
727 "elf32-mcore-little", bfd_arch_mcore,
728 mcore_le_jtab, sizeof (mcore_le_jtab), 8,
729 0, 0, 0, 0, 0, false, 0
733 #define MARM_WINCE 8
734 "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
735 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
736 ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32",
737 "pe-arm-wince-little", bfd_arch_arm,
738 arm_jtab, sizeof (arm_jtab), 8,
739 0, 0, 0, 0, 0, false, 0
743 #define MX86 9
744 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
745 "jmp *", ".global", ".space", ".align\t2", ".align\t4", "",
746 "pe-x86-64",bfd_arch_i386,
747 i386_jtab, sizeof (i386_jtab), 2,
748 i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, true, i386_x64_trampoline
752 #define MAARCH64 10
753 "arm64", ".byte", ".short", ".long", ".asciz", "//",
754 "bl ", ".global", ".space", ".balign\t2", ".balign\t4", "",
755 "pe-aarch64-little", bfd_arch_aarch64,
756 aarch64_jtab, sizeof (aarch64_jtab), 0,
757 0, 0, 0, 0, 0, false, 0
760 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
763 typedef struct dlist
765 char *text;
766 struct dlist *next;
768 dlist_type;
770 typedef struct export
772 const char *name;
773 const char *internal_name;
774 const char *import_name;
775 const char *its_name;
776 int ordinal;
777 int constant;
778 int noname; /* Don't put name in image file. */
779 int private; /* Don't put reference in import lib. */
780 int data;
781 int hint;
782 int forward; /* Number of forward label, 0 means no forward. */
783 struct export *next;
785 export_type;
787 /* A list of symbols which we should not export. */
789 struct string_list
791 struct string_list *next;
792 char *string;
795 static struct string_list *excludes;
797 /* Forward references. */
798 static char *deduce_name (const char *);
799 static const char *xlate (const char *);
800 static void dll_name_list_free_contents (dll_name_list_node_type *);
801 static void identify_search_archive
802 (bfd *, void (*) (bfd *, bfd *, void *), void *);
803 static void identify_search_member (bfd *, bfd *, void *);
804 static void identify_search_section (bfd *, asection *, void *);
805 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
807 #ifdef DLLTOOL_MCORE_ELF
808 static void mcore_elf_cache_filename (const char *);
809 static void mcore_elf_gen_out_file (void);
810 #endif
812 /* Get current BFD error message. */
813 static inline const char *
814 bfd_get_errmsg (void)
816 return bfd_errmsg (bfd_get_error ());
819 static char *
820 prefix_encode (char *start, unsigned code)
822 static char buf[32];
823 char *p = stpcpy (buf, start);
825 *p++ = "abcdefghijklmnopqrstuvwxyz"[code % 26];
826 while ((code /= 26) != 0);
827 *p = '\0';
828 return buf;
831 static char *
832 dlltmp (char **buf, const char *fmt)
834 if (!*buf)
836 *buf = xmalloc (strlen (tmp_prefix) + 64);
837 sprintf (*buf, fmt, tmp_prefix);
839 return *buf;
842 static void
843 inform (const char * message, ...)
845 va_list args;
847 va_start (args, message);
849 if (!verbose)
850 return;
852 report (message, args);
854 va_end (args);
857 static const char *
858 rvaafter (int mach)
860 switch (mach)
862 case MARM:
863 case M386:
864 case MX86:
865 case MTHUMB:
866 case MARM_INTERWORK:
867 case MMCORE_BE:
868 case MMCORE_LE:
869 case MMCORE_ELF:
870 case MMCORE_ELF_LE:
871 case MARM_WINCE:
872 case MAARCH64:
873 break;
874 default:
875 /* xgettext:c-format */
876 fatal (_("Internal error: Unknown machine type: %d"), mach);
877 break;
879 return "";
882 static const char *
883 rvabefore (int mach)
885 switch (mach)
887 case MARM:
888 case M386:
889 case MX86:
890 case MTHUMB:
891 case MARM_INTERWORK:
892 case MMCORE_BE:
893 case MMCORE_LE:
894 case MMCORE_ELF:
895 case MMCORE_ELF_LE:
896 case MARM_WINCE:
897 case MAARCH64:
898 return ".rva\t";
899 default:
900 /* xgettext:c-format */
901 fatal (_("Internal error: Unknown machine type: %d"), mach);
902 break;
904 return "";
907 static const char *
908 asm_prefix (const char *name)
910 /* Symbol names starting with ? do not have a leading underscore. */
911 if (name && *name == '?')
912 return "";
913 return leading_underscore;
916 #define ASM_BYTE mtable[machine].how_byte
917 #define ASM_SHORT mtable[machine].how_short
918 #define ASM_LONG mtable[machine].how_long
919 #define ASM_TEXT mtable[machine].how_asciz
920 #define ASM_C mtable[machine].how_comment
921 #define ASM_JUMP mtable[machine].how_jump
922 #define ASM_GLOBAL mtable[machine].how_global
923 #define ASM_SPACE mtable[machine].how_space
924 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
925 #define ASM_RVA_BEFORE rvabefore (machine)
926 #define ASM_RVA_AFTER rvaafter (machine)
927 #define ASM_PREFIX(NAME) asm_prefix (NAME)
928 #define ASM_ALIGN_LONG mtable[machine].how_align_long
929 #define HOW_BFD_READ_TARGET 0 /* Always default. */
930 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
931 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
932 #define HOW_JTAB (delay ? mtable[machine].how_dljtab \
933 : mtable[machine].how_jtab)
934 #define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \
935 : mtable[machine].how_jtab_size)
936 #define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \
937 : mtable[machine].how_jtab_roff)
938 #define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
939 #define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
940 #define ASM_SWITCHES mtable[machine].how_default_as_switches
941 #define HOW_SEH mtable[machine].how_seh
943 static char **oav;
945 static void
946 process_def_file (const char *name)
948 FILE *f = fopen (name, FOPEN_RT);
950 if (!f)
951 /* xgettext:c-format */
952 fatal (_("Can't open def file: %s"), name);
954 yyin = f;
956 /* xgettext:c-format */
957 inform (_("Processing def file: %s"), name);
959 yyparse ();
961 inform (_("Processed def file"));
964 /**********************************************************************/
966 /* Communications with the parser. */
968 static int d_nfuncs; /* Number of functions exported. */
969 static int d_named_nfuncs; /* Number of named functions exported. */
970 static int d_low_ord; /* Lowest ordinal index. */
971 static int d_high_ord; /* Highest ordinal index. */
972 static export_type *d_exports; /* List of exported functions. */
973 static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */
974 static dlist_type *d_list; /* Descriptions. */
975 static dlist_type *a_list; /* Stuff to go in directives. */
976 static int d_nforwards = 0; /* Number of forwarded exports. */
978 static int d_is_dll;
979 static int d_is_exe;
981 void
982 yyerror (const char * err ATTRIBUTE_UNUSED)
984 /* xgettext:c-format */
985 non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
988 void
989 def_exports (const char *name, const char *internal_name, int ordinal,
990 int noname, int constant, int data, int private,
991 const char *its_name)
993 struct export *p = (struct export *) xmalloc (sizeof (*p));
995 p->name = name;
996 p->internal_name = internal_name ? internal_name : name;
997 p->its_name = its_name;
998 p->import_name = name;
999 p->ordinal = ordinal;
1000 p->constant = constant;
1001 p->noname = noname;
1002 p->private = private;
1003 p->data = data;
1004 p->next = d_exports;
1005 d_exports = p;
1006 d_nfuncs++;
1008 if (internal_name != NULL
1009 && strchr (internal_name, '.') != NULL)
1010 p->forward = ++d_nforwards;
1011 else
1012 p->forward = 0; /* no forward */
1015 static void
1016 set_dll_name_from_def (const char *name, char is_dll)
1018 const char *image_basename = lbasename (name);
1019 if (image_basename != name)
1020 non_fatal (_("%s: Path components stripped from image name, '%s'."),
1021 def_file, name);
1022 /* Append the default suffix, if none specified. */
1023 if (strchr (image_basename, '.') == 0)
1025 const char * suffix = is_dll ? ".dll" : ".exe";
1027 dll_name = xmalloc (strlen (image_basename) + strlen (suffix) + 1);
1028 sprintf (dll_name, "%s%s", image_basename, suffix);
1030 else
1031 dll_name = xstrdup (image_basename);
1034 void
1035 def_name (const char *name, int base)
1037 /* xgettext:c-format */
1038 inform (_("NAME: %s base: %x"), name, base);
1040 if (d_is_dll)
1041 non_fatal (_("Can't have LIBRARY and NAME"));
1043 if (dll_name_set_by_exp_name && name && *name != 0)
1045 dll_name = NULL;
1046 dll_name_set_by_exp_name = 0;
1048 /* If --dllname not provided, use the one in the DEF file.
1049 FIXME: Is this appropriate for executables? */
1050 if (!dll_name)
1051 set_dll_name_from_def (name, 0);
1052 d_is_exe = 1;
1055 void
1056 def_library (const char *name, int base)
1058 /* xgettext:c-format */
1059 inform (_("LIBRARY: %s base: %x"), name, base);
1061 if (d_is_exe)
1062 non_fatal (_("Can't have LIBRARY and NAME"));
1064 if (dll_name_set_by_exp_name && name && *name != 0)
1066 dll_name = NULL;
1067 dll_name_set_by_exp_name = 0;
1070 /* If --dllname not provided, use the one in the DEF file. */
1071 if (!dll_name)
1072 set_dll_name_from_def (name, 1);
1073 d_is_dll = 1;
1076 void
1077 def_description (const char *desc)
1079 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1080 d->text = xstrdup (desc);
1081 d->next = d_list;
1082 d_list = d;
1085 static void
1086 new_directive (char *dir)
1088 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1089 d->text = xstrdup (dir);
1090 d->next = a_list;
1091 a_list = d;
1094 void
1095 def_heapsize (int reserve, int commit)
1097 char b[200];
1098 if (commit > 0)
1099 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1100 else
1101 sprintf (b, "-heap 0x%x ", reserve);
1102 new_directive (xstrdup (b));
1105 void
1106 def_stacksize (int reserve, int commit)
1108 char b[200];
1109 if (commit > 0)
1110 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1111 else
1112 sprintf (b, "-stack 0x%x ", reserve);
1113 new_directive (xstrdup (b));
1116 /* append_import simply adds the given import definition to the global
1117 import_list. It is used by def_import. */
1119 static void
1120 append_import (const char *symbol_name, const char *dllname, int func_ordinal,
1121 const char *its_name)
1123 iheadtype **pq;
1124 iheadtype *q;
1126 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1128 if (strcmp ((*pq)->dllname, dllname) == 0)
1130 q = *pq;
1131 q->functail->next = xmalloc (sizeof (ifunctype));
1132 q->functail = q->functail->next;
1133 q->functail->ord = func_ordinal;
1134 q->functail->name = xstrdup (symbol_name);
1135 q->functail->its_name = its_name ? xstrdup (its_name) : NULL;
1136 q->functail->next = NULL;
1137 q->nfuncs++;
1138 return;
1142 q = xmalloc (sizeof (iheadtype));
1143 q->dllname = xstrdup (dllname);
1144 q->nfuncs = 1;
1145 q->funchead = xmalloc (sizeof (ifunctype));
1146 q->functail = q->funchead;
1147 q->next = NULL;
1148 q->functail->name = xstrdup (symbol_name);
1149 q->functail->its_name = its_name ? xstrdup (its_name) : NULL;
1150 q->functail->ord = func_ordinal;
1151 q->functail->next = NULL;
1153 *pq = q;
1156 /* def_import is called from within defparse.y when an IMPORT
1157 declaration is encountered. Depending on the form of the
1158 declaration, the module name may or may not need ".dll" to be
1159 appended to it, the name of the function may be stored in internal
1160 or entry, and there may or may not be an ordinal value associated
1161 with it. */
1163 /* A note regarding the parse modes:
1164 In defparse.y we have to accept import declarations which follow
1165 any one of the following forms:
1166 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1167 <func_name_in_app> = <dll_name>.<number>
1168 <dll_name>.<func_name_in_dll>
1169 <dll_name>.<number>
1170 Furthermore, the dll's name may or may not end with ".dll", which
1171 complicates the parsing a little. Normally the dll's name is
1172 passed to def_import() in the "module" parameter, but when it ends
1173 with ".dll" it gets passed in "module" sans ".dll" and that needs
1174 to be reappended.
1176 def_import gets five parameters:
1177 APP_NAME - the name of the function in the application, if
1178 present, or NULL if not present.
1179 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1180 DLLEXT - the extension of the dll, if present, NULL if not present.
1181 ENTRY - the name of the function in the dll, if present, or NULL.
1182 ORD_VAL - the numerical tag of the function in the dll, if present,
1183 or NULL. Exactly one of <entry> or <ord_val> must be
1184 present (i.e., not NULL). */
1186 void
1187 def_import (const char *app_name, const char *module, const char *dllext,
1188 const char *entry, int ord_val, const char *its_name)
1190 const char *application_name;
1191 char *buf = NULL;
1193 if (entry != NULL)
1194 application_name = entry;
1195 else
1197 if (app_name != NULL)
1198 application_name = app_name;
1199 else
1200 application_name = "";
1203 if (dllext != NULL)
1204 module = buf = concat (module, ".", dllext, NULL);
1206 append_import (application_name, module, ord_val, its_name);
1208 free (buf);
1211 void
1212 def_version (int major, int minor)
1214 printf (_("VERSION %d.%d\n"), major, minor);
1217 void
1218 def_section (const char *name, int attr)
1220 char buf[200];
1221 char atts[5];
1222 char *d = atts;
1223 if (attr & 1)
1224 *d++ = 'R';
1226 if (attr & 2)
1227 *d++ = 'W';
1228 if (attr & 4)
1229 *d++ = 'X';
1230 if (attr & 8)
1231 *d++ = 'S';
1232 *d++ = 0;
1233 sprintf (buf, "-attr %s %s", name, atts);
1234 new_directive (xstrdup (buf));
1237 void
1238 def_code (int attr)
1240 def_section ("CODE", attr);
1243 void
1244 def_data (int attr)
1246 def_section ("DATA", attr);
1249 /**********************************************************************/
1251 static void
1252 run (const char *what, char *args)
1254 char *s;
1255 int pid, wait_status;
1256 int i;
1257 const char **argv;
1258 char *errmsg_fmt = NULL, *errmsg_arg = NULL;
1259 char *temp_base = make_temp_file ("");
1261 inform (_("run: %s %s"), what, args);
1263 /* Count the args */
1264 i = 0;
1265 for (s = args; *s; s++)
1266 if (*s == ' ')
1267 i++;
1268 i++;
1269 argv = xmalloc (sizeof (char *) * (i + 3));
1270 i = 0;
1271 argv[i++] = what;
1272 s = args;
1273 while (1)
1275 while (*s == ' ')
1276 ++s;
1277 argv[i++] = s;
1278 while (*s != ' ' && *s != 0)
1279 s++;
1280 if (*s == 0)
1281 break;
1282 *s++ = 0;
1284 argv[i++] = NULL;
1286 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1287 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1288 free (argv);
1290 if (pid == -1)
1292 inform ("%s", strerror (errno));
1294 fatal (errmsg_fmt, errmsg_arg);
1297 pid = pwait (pid, & wait_status, 0);
1299 if (pid == -1)
1301 /* xgettext:c-format */
1302 fatal (_("wait: %s"), strerror (errno));
1304 else if (WIFSIGNALED (wait_status))
1306 /* xgettext:c-format */
1307 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1309 else if (WIFEXITED (wait_status))
1311 if (WEXITSTATUS (wait_status) != 0)
1312 /* xgettext:c-format */
1313 non_fatal (_("%s exited with status %d"),
1314 what, WEXITSTATUS (wait_status));
1316 else
1317 abort ();
1320 /* Look for a list of symbols to export in the .drectve section of
1321 ABFD. Pass each one to def_exports. */
1323 static void
1324 scan_drectve_symbols (bfd *abfd)
1326 asection * s;
1327 int size;
1328 char * buf;
1329 char * p;
1330 char * e;
1332 /* Look for .drectve's */
1333 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1335 if (s == NULL)
1336 return;
1338 size = bfd_section_size (s);
1339 buf = xmalloc (size);
1341 bfd_get_section_contents (abfd, s, buf, 0, size);
1343 /* xgettext:c-format */
1344 inform (_("Sucking in info from %s section in %s"),
1345 DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1347 /* Search for -export: strings. The exported symbols can optionally
1348 have type tags (eg., -export:foo,data), so handle those as well.
1349 Currently only data tag is supported. */
1350 p = buf;
1351 e = buf + size;
1352 while (p < e)
1354 if (p[0] == '-'
1355 && startswith (p, "-export:"))
1357 char * name;
1358 char * c;
1359 flagword flags = BSF_FUNCTION;
1361 p += 8;
1362 /* Do we have a quoted export? */
1363 if (*p == '"')
1365 p++;
1366 name = p;
1367 while (p < e && *p != '"')
1368 ++p;
1370 else
1372 name = p;
1373 while (p < e && *p != ',' && *p != ' ' && *p != '-')
1374 p++;
1376 c = xmalloc (p - name + 1);
1377 memcpy (c, name, p - name);
1378 c[p - name] = 0;
1379 /* Advance over trailing quote. */
1380 if (p < e && *p == '"')
1381 ++p;
1382 if (p < e && *p == ',') /* found type tag. */
1384 char *tag_start = ++p;
1385 while (p < e && *p != ' ' && *p != '-')
1386 p++;
1387 if (startswith (tag_start, "data"))
1388 flags &= ~BSF_FUNCTION;
1391 /* FIXME: The 5th arg is for the `constant' field.
1392 What should it be? Not that it matters since it's not
1393 currently useful. */
1394 def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0, NULL);
1396 if (add_stdcall_alias && strchr (c, '@'))
1398 int lead_at = (*c == '@') ;
1399 char *exported_name = xstrdup (c + lead_at);
1400 char *atsym = strchr (exported_name, '@');
1401 *atsym = '\0';
1402 /* Note: stdcall alias symbols can never be data. */
1403 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0, NULL);
1406 else
1407 p++;
1409 free (buf);
1412 /* Look through the symbols in MINISYMS, and add each one to list of
1413 symbols to export. */
1415 static void
1416 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1417 unsigned int size)
1419 asymbol *store;
1420 bfd_byte *from, *fromend;
1422 store = bfd_make_empty_symbol (abfd);
1423 if (store == NULL)
1424 bfd_fatal (bfd_get_filename (abfd));
1426 from = (bfd_byte *) minisyms;
1427 fromend = from + symcount * size;
1428 for (; from < fromend; from += size)
1430 asymbol *sym;
1431 const char *symbol_name;
1433 sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
1434 if (sym == NULL)
1435 bfd_fatal (bfd_get_filename (abfd));
1437 symbol_name = bfd_asymbol_name (sym);
1438 if (*symbol_name
1439 && *symbol_name == bfd_get_symbol_leading_char (abfd))
1440 ++symbol_name;
1442 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
1443 ! (sym->flags & BSF_FUNCTION), 0, NULL);
1445 if (add_stdcall_alias && strchr (symbol_name, '@'))
1447 int lead_at = (*symbol_name == '@');
1448 char *exported_name = xstrdup (symbol_name + lead_at);
1449 char *atsym = strchr (exported_name, '@');
1450 *atsym = '\0';
1451 /* Note: stdcall alias symbols can never be data. */
1452 def_exports (exported_name, xstrdup (symbol_name),
1453 -1, 0, 0, 0, 0, NULL);
1458 /* Add a list of symbols to exclude. */
1460 static void
1461 add_excludes (const char *new_excludes)
1463 char *local_copy;
1464 char *exclude_string;
1466 local_copy = xstrdup (new_excludes);
1468 exclude_string = strtok (local_copy, ",:");
1469 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1471 struct string_list *new_exclude;
1473 new_exclude = ((struct string_list *)
1474 xmalloc (sizeof (struct string_list)));
1475 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1476 /* Don't add a leading underscore for fastcall symbols. */
1477 if (*exclude_string == '@')
1478 sprintf (new_exclude->string, "%s", exclude_string);
1479 else
1480 sprintf (new_exclude->string, "%s%s", leading_underscore,
1481 exclude_string);
1482 new_exclude->next = excludes;
1483 excludes = new_exclude;
1485 /* xgettext:c-format */
1486 inform (_("Excluding symbol: %s"), exclude_string);
1489 free (local_copy);
1492 /* See if STRING is on the list of symbols to exclude. */
1494 static bool
1495 match_exclude (const char *string)
1497 struct string_list *excl_item;
1499 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1500 if (strcmp (string, excl_item->string) == 0)
1501 return true;
1502 return false;
1505 /* Add the default list of symbols to exclude. */
1507 static void
1508 set_default_excludes (void)
1510 add_excludes (default_excludes);
1513 /* Choose which symbols to export. */
1515 static long
1516 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
1518 bfd_byte *from, *fromend, *to;
1519 asymbol *store;
1521 store = bfd_make_empty_symbol (abfd);
1522 if (store == NULL)
1523 bfd_fatal (bfd_get_filename (abfd));
1525 from = (bfd_byte *) minisyms;
1526 fromend = from + symcount * size;
1527 to = (bfd_byte *) minisyms;
1529 for (; from < fromend; from += size)
1531 int keep = 0;
1532 asymbol *sym;
1534 sym = bfd_minisymbol_to_symbol (abfd, false, (const void *) from, store);
1535 if (sym == NULL)
1536 bfd_fatal (bfd_get_filename (abfd));
1538 /* Check for external and defined only symbols. */
1539 keep = (((sym->flags & BSF_GLOBAL) != 0
1540 || (sym->flags & BSF_WEAK) != 0
1541 || bfd_is_com_section (sym->section))
1542 && ! bfd_is_und_section (sym->section));
1544 keep = keep && ! match_exclude (sym->name);
1546 if (keep)
1548 memcpy (to, from, size);
1549 to += size;
1553 return (to - (bfd_byte *) minisyms) / size;
1556 /* Export all symbols in ABFD, except for ones we were told not to
1557 export. */
1559 static void
1560 scan_all_symbols (bfd *abfd)
1562 long symcount;
1563 void *minisyms;
1564 unsigned int size;
1566 /* Ignore bfds with an import descriptor table. We assume that any
1567 such BFD contains symbols which are exported from another DLL,
1568 and we don't want to reexport them from here. */
1569 if (bfd_get_section_by_name (abfd, ".idata$4"))
1570 return;
1572 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1574 /* xgettext:c-format */
1575 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1576 return;
1579 symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
1580 if (symcount < 0)
1581 bfd_fatal (bfd_get_filename (abfd));
1583 if (symcount == 0)
1585 /* xgettext:c-format */
1586 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1587 return;
1590 /* Discard the symbols we don't want to export. It's OK to do this
1591 in place; we'll free the storage anyway. */
1593 symcount = filter_symbols (abfd, minisyms, symcount, size);
1594 scan_filtered_symbols (abfd, minisyms, symcount, size);
1596 free (minisyms);
1599 /* Look at the object file to decide which symbols to export. */
1601 static void
1602 scan_open_obj_file (bfd *abfd)
1604 if (export_all_symbols)
1605 scan_all_symbols (abfd);
1606 else
1607 scan_drectve_symbols (abfd);
1609 /* FIXME: we ought to read in and block out the base relocations. */
1611 /* xgettext:c-format */
1612 inform (_("Done reading %s"), bfd_get_filename (abfd));
1615 static void
1616 scan_obj_file (const char *filename)
1618 bfd * f = bfd_openr (filename, 0);
1620 if (!f)
1621 /* xgettext:c-format */
1622 fatal (_("Unable to open object file: %s: %s"), filename, bfd_get_errmsg ());
1624 /* xgettext:c-format */
1625 inform (_("Scanning object file %s"), filename);
1627 if (bfd_check_format (f, bfd_archive))
1629 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1630 while (arfile)
1632 bfd *next;
1633 if (bfd_check_format (arfile, bfd_object))
1634 scan_open_obj_file (arfile);
1635 next = bfd_openr_next_archived_file (f, arfile);
1636 bfd_close (arfile);
1637 /* PR 17512: file: 58715298. */
1638 if (next == arfile)
1639 break;
1640 arfile = next;
1643 #ifdef DLLTOOL_MCORE_ELF
1644 if (mcore_elf_out_file)
1645 inform (_("Cannot produce mcore-elf dll from archive file: %s"),
1646 filename);
1647 #endif
1649 else if (bfd_check_format (f, bfd_object))
1651 scan_open_obj_file (f);
1653 #ifdef DLLTOOL_MCORE_ELF
1654 if (mcore_elf_out_file)
1655 mcore_elf_cache_filename (filename);
1656 #endif
1659 bfd_close (f);
1663 static void
1664 dump_def_info (FILE *f)
1666 int i;
1667 export_type *exp;
1668 fprintf (f, "%s ", ASM_C);
1669 for (i = 0; oav[i]; i++)
1670 fprintf (f, "%s ", oav[i]);
1671 fprintf (f, "\n");
1672 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1674 fprintf (f, "%s %d = %s %s @ %d %s%s%s%s%s%s\n",
1675 ASM_C,
1677 exp->name,
1678 exp->internal_name,
1679 exp->ordinal,
1680 exp->noname ? "NONAME " : "",
1681 exp->private ? "PRIVATE " : "",
1682 exp->constant ? "CONSTANT" : "",
1683 exp->data ? "DATA" : "",
1684 exp->its_name ? " ==" : "",
1685 exp->its_name ? exp->its_name : "");
1689 /* Generate the .exp file. */
1691 static int
1692 sfunc (const void *a, const void *b)
1694 if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1695 return 0;
1697 return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
1700 static void
1701 flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1703 int i;
1705 /* Flush this page. */
1706 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1707 ASM_LONG,
1708 (int) page_addr,
1709 ASM_C);
1710 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1711 ASM_LONG,
1712 (on_page * 2) + (on_page & 1) * 2 + 8,
1713 ASM_C);
1715 for (i = 0; i < on_page; i++)
1717 bfd_vma needed = need[i];
1719 if (needed)
1721 if (!create_for_pep)
1723 /* Relocation via HIGHLOW. */
1724 needed = ((needed - page_addr) | 0x3000) & 0xffff;
1726 else
1728 /* Relocation via DIR64. */
1729 needed = ((needed - page_addr) | 0xa000) & 0xffff;
1733 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1736 /* And padding */
1737 if (on_page & 1)
1738 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1741 static void
1742 gen_def_file (void)
1744 int i;
1745 export_type *exp;
1747 inform (_("Adding exports to output file"));
1749 fprintf (output_def, ";");
1750 for (i = 0; oav[i]; i++)
1751 fprintf (output_def, " %s", oav[i]);
1753 fprintf (output_def, "\nEXPORTS\n");
1755 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1757 char *quote = strchr (exp->name, '.') ? "\"" : "";
1758 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1760 if (res)
1762 fprintf (output_def, ";\t%s\n", res);
1763 free (res);
1766 if (strcmp (exp->name, exp->internal_name) == 0)
1768 fprintf (output_def, "\t%s%s%s @ %d%s%s%s%s%s\n",
1769 quote,
1770 exp->name,
1771 quote,
1772 exp->ordinal,
1773 exp->noname ? " NONAME" : "",
1774 exp->private ? "PRIVATE " : "",
1775 exp->data ? " DATA" : "",
1776 exp->its_name ? " ==" : "",
1777 exp->its_name ? exp->its_name : "");
1779 else
1781 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1782 /* char *alias = */
1783 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1784 quote,
1785 exp->name,
1786 quote,
1787 quote1,
1788 exp->internal_name,
1789 quote1,
1790 exp->ordinal,
1791 exp->noname ? " NONAME" : "",
1792 exp->private ? "PRIVATE " : "",
1793 exp->data ? " DATA" : "",
1794 exp->its_name ? " ==" : "",
1795 exp->its_name ? exp->its_name : "");
1799 inform (_("Added exports to output file"));
1802 /* generate_idata_ofile generates the portable assembly source code
1803 for the idata sections. It appends the source code to the end of
1804 the file. */
1806 static void
1807 generate_idata_ofile (FILE *filvar)
1809 iheadtype *headptr;
1810 ifunctype *funcptr;
1811 int headindex;
1812 int funcindex;
1813 int nheads;
1815 if (import_list == NULL)
1816 return;
1818 fprintf (filvar, "%s Import data sections\n", ASM_C);
1819 fprintf (filvar, "\n\t.section\t.idata$2\n");
1820 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1821 fprintf (filvar, "doi_idata:\n");
1823 nheads = 0;
1824 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1826 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1827 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1828 ASM_C, headptr->dllname);
1829 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1830 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1831 fprintf (filvar, "\t%sdllname%d%s\n",
1832 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1833 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1834 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1835 nheads++;
1838 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1839 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1840 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1841 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1842 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1844 fprintf (filvar, "\n\t.section\t.idata$4\n");
1845 headindex = 0;
1846 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1848 fprintf (filvar, "listone%d:\n", headindex);
1849 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1851 if (create_for_pep)
1852 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1853 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1854 ASM_LONG);
1855 else
1856 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1857 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1859 if (create_for_pep)
1860 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1861 else
1862 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1863 headindex++;
1866 fprintf (filvar, "\n\t.section\t.idata$5\n");
1867 headindex = 0;
1868 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1870 fprintf (filvar, "listtwo%d:\n", headindex);
1871 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1873 if (create_for_pep)
1874 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1875 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1876 ASM_LONG);
1877 else
1878 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1879 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1881 if (create_for_pep)
1882 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1883 else
1884 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1885 headindex++;
1888 fprintf (filvar, "\n\t.section\t.idata$6\n");
1889 headindex = 0;
1890 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1892 funcindex = 0;
1893 for (funcptr = headptr->funchead; funcptr != NULL;
1894 funcptr = funcptr->next)
1896 fprintf (filvar, "funcptr%d_%d:\n", headindex, funcindex);
1897 fprintf (filvar, "\t%s\t%d\n", ASM_SHORT, funcptr->ord & 0xFFFF);
1898 fprintf (filvar, "\t%s\t\"%s\"\n", ASM_TEXT,
1899 funcptr->its_name ? funcptr->its_name : funcptr->name);
1900 fprintf (filvar, "\t%s\t0\n", ASM_BYTE);
1901 funcindex++;
1903 headindex++;
1906 fprintf (filvar, "\n\t.section\t.idata$7\n");
1907 headindex = 0;
1908 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1910 fprintf (filvar, "dllname%d:\n", headindex);
1911 fprintf (filvar, "\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1912 fprintf (filvar, "\t%s\t0\n", ASM_BYTE);
1913 headindex++;
1917 /* Assemble the specified file. */
1918 static void
1919 assemble_file (const char * source, const char * dest)
1921 char * cmd;
1923 cmd = xmalloc (strlen (ASM_SWITCHES) + strlen (as_flags)
1924 + strlen (source) + strlen (dest) + 50);
1926 sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1928 run (as_name, cmd);
1929 free (cmd);
1932 static const char * temp_file_to_remove[5];
1933 #define TEMP_EXPORT_FILE 0
1934 #define TEMP_HEAD_FILE 1
1935 #define TEMP_TAIL_FILE 2
1936 #define TEMP_HEAD_O_FILE 3
1937 #define TEMP_TAIL_O_FILE 4
1939 static void
1940 unlink_temp_files (void)
1942 unsigned i;
1944 if (dontdeltemps > 0)
1945 return;
1947 for (i = 0; i < ARRAY_SIZE (temp_file_to_remove); i++)
1949 if (temp_file_to_remove[i])
1951 unlink (temp_file_to_remove[i]);
1952 temp_file_to_remove[i] = NULL;
1957 static void
1958 gen_exp_file (void)
1960 FILE *f;
1961 int i;
1962 export_type *exp;
1963 dlist_type *dl;
1965 /* xgettext:c-format */
1966 inform (_("Generating export file: %s"), exp_name);
1968 f = fopen (TMP_ASM, FOPEN_WT);
1969 if (!f)
1970 /* xgettext:c-format */
1971 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1973 temp_file_to_remove[TEMP_EXPORT_FILE] = TMP_ASM;
1975 /* xgettext:c-format */
1976 inform (_("Opened temporary file: %s"), TMP_ASM);
1978 dump_def_info (f);
1980 if (d_exports)
1982 fprintf (f, "\t.section .edata\n\n");
1983 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1984 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG,
1985 (unsigned long) time(0), ASM_C);
1986 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1987 fprintf (f, "\t%sname%s %s Ptr to name of dll\n",
1988 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1989 fprintf (f, "\t%s %d %s Starting ordinal of exports\n",
1990 ASM_LONG, d_low_ord, ASM_C);
1993 fprintf (f, "\t%s %d %s Number of functions\n",
1994 ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1995 fprintf (f, "\t%s named funcs %d, low ord %d, high ord %d\n",
1996 ASM_C, d_named_nfuncs, d_low_ord, d_high_ord);
1997 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1998 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs,
1999 ASM_C);
2000 fprintf (f, "\t%safuncs%s %s Address of functions\n",
2001 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2003 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
2004 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2006 fprintf (f, "\t%sanords%s %s Address of ordinals\n",
2007 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2009 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
2012 fprintf (f, "%s Export address Table\n", ASM_C);
2013 fprintf (f, "\t%s\n", ASM_ALIGN_LONG);
2014 fprintf (f, "afuncs:\n");
2015 i = d_low_ord;
2017 for (exp = d_exports; exp; exp = exp->next)
2019 if (exp->ordinal != i)
2021 while (i < exp->ordinal)
2023 fprintf (f, "\t%s\t0\n", ASM_LONG);
2024 i++;
2028 if (exp->forward == 0)
2030 if (exp->internal_name[0] == '@')
2031 fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2032 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2033 else
2034 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2035 ASM_PREFIX (exp->internal_name),
2036 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2038 else
2039 fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
2040 exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2041 i++;
2044 fprintf (f, "%s Export Name Pointer Table\n", ASM_C);
2045 fprintf (f, "anames:\n");
2047 for (i = 0; (exp = d_exports_lexically[i]); i++)
2049 if (!exp->noname || show_allnames)
2050 fprintf (f, "\t%sn%d%s\n",
2051 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
2054 fprintf (f, "%s Export Ordinal Table\n", ASM_C);
2055 fprintf (f, "anords:\n");
2056 for (i = 0; (exp = d_exports_lexically[i]); i++)
2058 if (!exp->noname || show_allnames)
2059 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
2062 fprintf (f, "%s Export Name Table\n", ASM_C);
2063 for (i = 0; (exp = d_exports_lexically[i]); i++)
2065 if (!exp->noname || show_allnames)
2066 fprintf (f, "n%d: %s \"%s\"\n",
2067 exp->ordinal, ASM_TEXT,
2068 exp->its_name ? exp->its_name : xlate (exp->name));
2069 if (exp->forward != 0)
2070 fprintf (f, "f%d: %s \"%s\"\n",
2071 exp->forward, ASM_TEXT, exp->internal_name);
2074 if (a_list)
2076 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
2077 for (dl = a_list; dl; dl = dl->next)
2079 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
2083 if (d_list)
2085 fprintf (f, "\t.section .rdata\n");
2086 for (dl = d_list; dl; dl = dl->next)
2088 char *p;
2089 int l;
2091 /* We don't output as ascii because there can
2092 be quote characters in the string. */
2093 l = 0;
2094 for (p = dl->text; *p; p++)
2096 if (l == 0)
2097 fprintf (f, "\t%s\t", ASM_BYTE);
2098 else
2099 fprintf (f, ",");
2100 fprintf (f, "%d", *p);
2101 if (p[1] == 0)
2103 fprintf (f, ",0\n");
2104 break;
2106 if (++l == 10)
2108 fprintf (f, "\n");
2109 l = 0;
2116 /* Add to the output file a way of getting to the exported names
2117 without using the import library. */
2118 if (add_indirect)
2120 fprintf (f, "\t.section\t.rdata\n");
2121 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2122 if (!exp->noname || show_allnames)
2124 /* We use a single underscore for MS compatibility, and a
2125 double underscore for backward compatibility with old
2126 cygwin releases. */
2127 if (create_compat_implib)
2128 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2129 fprintf (f, "\t%s\t_imp_%s%s\n", ASM_GLOBAL,
2130 leading_underscore, exp->name);
2131 if (create_compat_implib)
2132 fprintf (f, "__imp_%s:\n", exp->name);
2133 fprintf (f, "_imp_%s%s:\n", leading_underscore, exp->name);
2134 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
2138 /* Dump the reloc section if a base file is provided. */
2139 if (base_file)
2141 bfd_vma addr;
2142 bfd_vma need[COFF_PAGE_SIZE];
2143 bfd_vma page_addr;
2144 bfd_size_type numbytes;
2145 int num_entries;
2146 bfd_vma *copy;
2147 int j;
2148 int on_page;
2149 fprintf (f, "\t.section\t.init\n");
2150 fprintf (f, "lab:\n");
2152 fseek (base_file, 0, SEEK_END);
2153 numbytes = ftell (base_file);
2154 fseek (base_file, 0, SEEK_SET);
2155 copy = xmalloc (numbytes);
2156 if (fread (copy, 1, numbytes, base_file) < numbytes)
2157 fatal (_("failed to read the number of entries from base file"));
2158 num_entries = numbytes / sizeof (bfd_vma);
2160 fprintf (f, "\t.section\t.reloc\n");
2161 if (num_entries)
2163 int src;
2164 int dst = 0;
2165 bfd_vma last = (bfd_vma) -1;
2166 qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
2167 /* Delete duplicates */
2168 for (src = 0; src < num_entries; src++)
2170 if (last != copy[src])
2171 last = copy[dst++] = copy[src];
2173 num_entries = dst;
2174 addr = copy[0];
2175 page_addr = addr & PAGE_MASK; /* work out the page addr */
2176 on_page = 0;
2177 for (j = 0; j < num_entries; j++)
2179 addr = copy[j];
2180 if ((addr & PAGE_MASK) != page_addr)
2182 flush_page (f, need, page_addr, on_page);
2183 on_page = 0;
2184 page_addr = addr & PAGE_MASK;
2186 need[on_page++] = addr;
2188 flush_page (f, need, page_addr, on_page);
2189 #if 0
2190 fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);
2191 #endif
2195 generate_idata_ofile (f);
2197 fclose (f);
2199 /* Assemble the file. */
2200 assemble_file (TMP_ASM, exp_name);
2202 if (dontdeltemps == 0)
2204 temp_file_to_remove[TEMP_EXPORT_FILE] = NULL;
2205 unlink (TMP_ASM);
2208 inform (_("Generated exports file"));
2211 static const char *
2212 xlate (const char *name)
2214 int lead_at = *name == '@';
2215 int is_stdcall = !lead_at && strchr (name, '@') != NULL;
2217 if (!lead_at && (add_underscore
2218 || (add_stdcall_underscore && is_stdcall)))
2220 char *copy = xmalloc (strlen (name) + 2);
2222 copy[0] = '_';
2223 strcpy (copy + 1, name);
2224 name = copy;
2227 if (killat)
2229 char *p;
2231 name += lead_at;
2232 /* PR 9766: Look for the last @ sign in the name. */
2233 p = strrchr (name, '@');
2234 if (p && ISDIGIT (p[1]))
2235 *p = 0;
2237 return name;
2240 typedef struct
2242 int id;
2243 const char *name;
2244 int flags;
2245 int align;
2246 asection *sec;
2247 asymbol *sym;
2248 asymbol **sympp;
2249 int size;
2250 unsigned char *data;
2251 } sinfo;
2253 #define INIT_SEC_DATA(id, name, flags, align) \
2254 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2256 #define TEXT 0
2257 #define DATA 1
2258 #define BSS 2
2259 #define IDATA7 3
2260 #define IDATA5 4
2261 #define IDATA4 5
2262 #define IDATA6 6
2264 #define NSECS 7
2266 #define TEXT_SEC_FLAGS \
2267 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2268 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2269 #define BSS_SEC_FLAGS SEC_ALLOC
2271 static sinfo secdata[NSECS] =
2273 INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2),
2274 INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2),
2275 INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2),
2276 INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2),
2277 INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2),
2278 INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
2279 INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
2282 /* This is what we're trying to make. We generate the imp symbols with
2283 both single and double underscores, for compatibility.
2285 .text
2286 .global _GetFileVersionInfoSizeW@8
2287 .global __imp_GetFileVersionInfoSizeW@8
2288 _GetFileVersionInfoSizeW@8:
2289 jmp * __imp_GetFileVersionInfoSizeW@8
2290 .section .idata$7 # To force loading of head
2291 .long __version_a_head
2292 # Import Address Table
2293 .section .idata$5
2294 __imp_GetFileVersionInfoSizeW@8:
2295 .rva ID2
2297 # Import Lookup Table
2298 .section .idata$4
2299 .rva ID2
2300 # Hint/Name table
2301 .section .idata$6
2302 ID2: .short 2
2303 .asciz "GetFileVersionInfoSizeW" */
2305 static char *
2306 make_label (const char *prefix, const char *name)
2308 int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2309 char *copy = xmalloc (len + 1);
2311 strcpy (copy, ASM_PREFIX (name));
2312 strcat (copy, prefix);
2313 strcat (copy, name);
2314 return copy;
2317 static char *
2318 make_imp_label (const char *prefix, const char *name)
2320 int len;
2321 char *copy;
2323 if (name[0] == '@')
2325 len = strlen (prefix) + strlen (name);
2326 copy = xmalloc (len + 1);
2327 strcpy (copy, prefix);
2328 strcat (copy, name);
2330 else
2332 len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2333 copy = xmalloc (len + 1);
2334 strcpy (copy, prefix);
2335 strcat (copy, ASM_PREFIX (name));
2336 strcat (copy, name);
2338 return copy;
2341 static bfd *
2342 make_one_lib_file (export_type *exp, int i, int delay)
2344 char *outname = TMP_STUB;
2345 size_t name_len = strlen (outname);
2346 sprintf (outname + name_len - 7, "%05d.o", i);
2348 bfd *abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2349 if (!abfd)
2350 /* xgettext:c-format */
2351 fatal (_("bfd_open failed open stub file: %s: %s"),
2352 outname, bfd_get_errmsg ());
2354 /* xgettext:c-format */
2355 inform (_("Creating stub file: %s"), outname);
2357 bfd_set_format (abfd, bfd_object);
2358 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2360 #ifdef DLLTOOL_ARM
2361 if (machine == MARM_INTERWORK || machine == MTHUMB)
2362 bfd_set_private_flags (abfd, F_INTERWORK);
2363 #endif
2365 /* First make symbols for the sections. */
2366 flagword applicable = bfd_applicable_section_flags (abfd);
2367 #ifndef EXTRA
2368 #define EXTRA 0
2369 #endif
2370 asymbol *ptrs[NSECS + 4 + EXTRA + 1];
2371 int oidx = 0;
2372 for (i = 0; i < NSECS; i++)
2374 sinfo *si = secdata + i;
2376 if (si->id != i)
2377 abort ();
2378 si->sec = bfd_make_section_old_way (abfd, si->name);
2379 bfd_set_section_flags (si->sec, si->flags & applicable);
2381 bfd_set_section_alignment (si->sec, si->align);
2382 si->sec->output_section = si->sec;
2383 si->sym = bfd_make_empty_symbol(abfd);
2384 si->sym->name = si->sec->name;
2385 si->sym->section = si->sec;
2386 si->sym->flags = BSF_LOCAL;
2387 si->sym->value = 0;
2388 ptrs[oidx] = si->sym;
2389 si->sympp = ptrs + oidx;
2390 si->size = 0;
2391 si->data = NULL;
2393 oidx++;
2396 if (! exp->data)
2398 asymbol *exp_label = bfd_make_empty_symbol (abfd);
2399 exp_label->name = make_imp_label ("", exp->name);
2400 exp_label->section = secdata[TEXT].sec;
2401 exp_label->flags = BSF_GLOBAL;
2402 exp_label->value = 0;
2404 #ifdef DLLTOOL_ARM
2405 if (machine == MTHUMB)
2406 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2407 #endif
2408 ptrs[oidx++] = exp_label;
2411 /* Generate imp symbols with one underscore for Microsoft
2412 compatibility, and with two underscores for backward
2413 compatibility with old versions of cygwin. */
2414 asymbol *iname = NULL;
2415 if (create_compat_implib)
2417 iname = bfd_make_empty_symbol (abfd);
2418 iname->name = make_imp_label ("___imp", exp->name);
2419 iname->section = secdata[IDATA5].sec;
2420 iname->flags = BSF_GLOBAL;
2421 iname->value = 0;
2424 asymbol *iname2 = bfd_make_empty_symbol (abfd);
2425 iname2->name = make_imp_label ("__imp_", exp->name);
2426 iname2->section = secdata[IDATA5].sec;
2427 iname2->flags = BSF_GLOBAL;
2428 iname2->value = 0;
2430 asymbol *iname_lab = bfd_make_empty_symbol (abfd);
2431 iname_lab->name = head_label;
2432 iname_lab->section = bfd_und_section_ptr;
2433 iname_lab->flags = 0;
2434 iname_lab->value = 0;
2436 asymbol **iname_pp = ptrs + oidx;
2437 if (create_compat_implib)
2438 ptrs[oidx++] = iname;
2439 ptrs[oidx++] = iname2;
2441 asymbol **iname_lab_pp = ptrs + oidx;
2442 ptrs[oidx++] = iname_lab;
2444 ptrs[oidx] = 0;
2446 for (i = 0; i < NSECS; i++)
2448 sinfo *si = secdata + i;
2449 asection *sec = si->sec;
2450 arelent *rel, *rel2 = 0, *rel3 = 0;
2451 arelent **rpp;
2453 switch (i)
2455 case TEXT:
2456 if (! exp->data)
2458 unsigned int rpp_len;
2460 si->size = HOW_JTAB_SIZE;
2461 si->data = xmalloc (HOW_JTAB_SIZE);
2462 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2464 /* Add the reloc into idata$5. */
2465 rel = xmalloc (sizeof (arelent));
2467 rpp_len = delay ? 4 : 2;
2469 if (machine == MAARCH64)
2470 rpp_len++;
2472 rpp = xmalloc (sizeof (arelent *) * rpp_len);
2473 rpp[0] = rel;
2474 rpp[1] = 0;
2476 rel->address = HOW_JTAB_ROFF;
2477 rel->addend = 0;
2479 if (delay)
2481 rel2 = xmalloc (sizeof (arelent));
2482 rpp[1] = rel2;
2483 rel2->address = HOW_JTAB_ROFF2;
2484 rel2->addend = 0;
2485 rel3 = xmalloc (sizeof (arelent));
2486 rpp[2] = rel3;
2487 rel3->address = HOW_JTAB_ROFF3;
2488 rel3->addend = 0;
2489 rpp[3] = 0;
2492 if (machine == MX86)
2494 rel->howto = bfd_reloc_type_lookup (abfd,
2495 BFD_RELOC_32_PCREL);
2496 rel->sym_ptr_ptr = iname_pp;
2498 else if (machine == MAARCH64)
2500 arelent *rel_add;
2502 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL);
2503 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2505 rel_add = xmalloc (sizeof (arelent));
2506 rel_add->address = 4;
2507 rel_add->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_AARCH64_ADD_LO12);
2508 rel_add->sym_ptr_ptr = secdata[IDATA5].sympp;
2509 rel_add->addend = 0;
2511 rpp[rpp_len - 2] = rel_add;
2512 rpp[rpp_len - 1] = 0;
2514 else
2516 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2517 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2520 if (delay)
2522 if (machine == MX86)
2523 rel2->howto = bfd_reloc_type_lookup (abfd,
2524 BFD_RELOC_32_PCREL);
2525 else
2526 rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2527 rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
2528 rel3->howto = bfd_reloc_type_lookup (abfd,
2529 BFD_RELOC_32_PCREL);
2530 rel3->sym_ptr_ptr = iname_lab_pp;
2533 sec->orelocation = rpp;
2534 sec->reloc_count = rpp_len - 1;
2536 break;
2538 case IDATA5:
2539 if (delay)
2541 si->size = create_for_pep ? 8 : 4;
2542 si->data = xmalloc (si->size);
2543 sec->reloc_count = 1;
2544 memset (si->data, 0, si->size);
2545 /* Point after jmp [__imp_...] instruction. */
2546 si->data[0] = 6;
2547 rel = xmalloc (sizeof (arelent));
2548 rpp = xmalloc (sizeof (arelent *) * 2);
2549 rpp[0] = rel;
2550 rpp[1] = 0;
2551 rel->address = 0;
2552 rel->addend = 0;
2553 if (create_for_pep)
2554 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64);
2555 else
2556 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2557 rel->sym_ptr_ptr = secdata[TEXT].sympp;
2558 sec->orelocation = rpp;
2559 break;
2561 /* Fall through. */
2563 case IDATA4:
2564 /* An idata$4 or idata$5 is one word long, and has an
2565 rva to idata$6. */
2567 if (create_for_pep)
2569 si->data = xmalloc (8);
2570 si->size = 8;
2571 if (exp->noname)
2573 si->data[0] = exp->ordinal ;
2574 si->data[1] = exp->ordinal >> 8;
2575 si->data[2] = exp->ordinal >> 16;
2576 si->data[3] = exp->ordinal >> 24;
2577 si->data[4] = 0;
2578 si->data[5] = 0;
2579 si->data[6] = 0;
2580 si->data[7] = 0x80;
2582 else
2584 sec->reloc_count = 1;
2585 memset (si->data, 0, si->size);
2586 rel = xmalloc (sizeof (arelent));
2587 rpp = xmalloc (sizeof (arelent *) * 2);
2588 rpp[0] = rel;
2589 rpp[1] = 0;
2590 rel->address = 0;
2591 rel->addend = 0;
2592 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2593 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2594 sec->orelocation = rpp;
2597 else
2599 si->data = xmalloc (4);
2600 si->size = 4;
2602 if (exp->noname)
2604 si->data[0] = exp->ordinal ;
2605 si->data[1] = exp->ordinal >> 8;
2606 si->data[2] = exp->ordinal >> 16;
2607 si->data[3] = 0x80;
2609 else
2611 sec->reloc_count = 1;
2612 memset (si->data, 0, si->size);
2613 rel = xmalloc (sizeof (arelent));
2614 rpp = xmalloc (sizeof (arelent *) * 2);
2615 rpp[0] = rel;
2616 rpp[1] = 0;
2617 rel->address = 0;
2618 rel->addend = 0;
2619 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2620 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2621 sec->orelocation = rpp;
2624 break;
2626 case IDATA6:
2627 if (!exp->noname)
2629 /* This used to add 1 to exp->hint. I don't know
2630 why it did that, and it does not match what I see
2631 in programs compiled with the MS tools. */
2632 int idx = exp->hint;
2633 if (exp->its_name)
2634 si->size = strlen (exp->its_name) + 3;
2635 else
2636 si->size = strlen (xlate (exp->import_name)) + 3;
2637 si->data = xmalloc (si->size);
2638 memset (si->data, 0, si->size);
2639 si->data[0] = idx & 0xff;
2640 si->data[1] = idx >> 8;
2641 if (exp->its_name)
2642 strcpy ((char *) si->data + 2, exp->its_name);
2643 else
2644 strcpy ((char *) si->data + 2, xlate (exp->import_name));
2646 break;
2647 case IDATA7:
2648 if (delay)
2649 break;
2650 si->size = 4;
2651 si->data = xmalloc (4);
2652 memset (si->data, 0, si->size);
2653 rel = xmalloc (sizeof (arelent));
2654 rpp = xmalloc (sizeof (arelent *) * 2);
2655 rpp[0] = rel;
2656 rel->address = 0;
2657 rel->addend = 0;
2658 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2659 rel->sym_ptr_ptr = iname_lab_pp;
2660 sec->orelocation = rpp;
2661 sec->reloc_count = 1;
2662 break;
2667 bfd_vma vma = 0;
2668 /* Size up all the sections. */
2669 for (i = 0; i < NSECS; i++)
2671 sinfo *si = secdata + i;
2673 bfd_set_section_size (si->sec, si->size);
2674 bfd_set_section_vma (si->sec, vma);
2677 /* Write them out. */
2678 for (i = 0; i < NSECS; i++)
2680 sinfo *si = secdata + i;
2682 if (i == IDATA5 && no_idata5)
2683 continue;
2685 if (i == IDATA4 && no_idata4)
2686 continue;
2688 bfd_set_section_contents (abfd, si->sec,
2689 si->data, 0,
2690 si->size);
2693 bfd_set_symtab (abfd, ptrs, oidx);
2694 bfd_close (abfd);
2695 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2696 if (!abfd)
2697 /* xgettext:c-format */
2698 fatal (_("bfd_open failed reopen stub file: %s: %s"),
2699 outname, bfd_get_errmsg ());
2701 return abfd;
2704 static bfd *
2705 make_head (void)
2707 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2708 bfd *abfd;
2710 if (f == NULL)
2712 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2713 return NULL;
2716 temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
2718 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2719 fprintf (f, "\t.section\t.idata$2\n");
2721 fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, head_label);
2723 fprintf (f, "%s:\n", head_label);
2725 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2726 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2728 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2729 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2730 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2731 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2732 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2733 ASM_RVA_BEFORE,
2734 imp_name_lab,
2735 ASM_RVA_AFTER,
2736 ASM_C);
2737 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2738 ASM_RVA_BEFORE,
2739 ASM_RVA_AFTER, ASM_C);
2741 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2743 if (!no_idata5)
2745 fprintf (f, "\t.section\t.idata$5\n");
2746 if (use_nul_prefixed_import_tables)
2748 if (create_for_pep)
2749 fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2750 else
2751 fprintf (f, "\t%s\t0\n", ASM_LONG);
2753 fprintf (f, "fthunk:\n");
2756 if (!no_idata4)
2758 fprintf (f, "\t.section\t.idata$4\n");
2759 if (use_nul_prefixed_import_tables)
2761 if (create_for_pep)
2762 fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2763 else
2764 fprintf (f, "\t%s\t0\n", ASM_LONG);
2766 fprintf (f, "hname:\n");
2769 fclose (f);
2771 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2773 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2774 if (abfd == NULL)
2775 /* xgettext:c-format */
2776 fatal (_("failed to open temporary head file: %s: %s"),
2777 TMP_HEAD_O, bfd_get_errmsg ());
2779 temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
2780 return abfd;
2783 static bfd *
2784 make_delay_head (void)
2786 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2787 bfd *abfd;
2789 if (f == NULL)
2791 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2792 return NULL;
2795 temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
2797 /* Output the __tailMerge__xxx function */
2798 fprintf (f, "%s Import trampoline\n", ASM_C);
2799 fprintf (f, "\t.section\t.text\n");
2800 fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, head_label);
2801 if (HOW_SEH)
2802 fprintf (f, "\t.seh_proc\t%s\n", head_label);
2803 fprintf (f, "%s:\n", head_label);
2804 fprintf (f, mtable[machine].trampoline, imp_name_lab);
2805 if (HOW_SEH)
2806 fprintf (f, "\t.seh_endproc\n");
2808 /* Output the delay import descriptor */
2809 fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
2810 fprintf (f, ".section\t.text$2\n");
2811 fprintf (f, "%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
2812 fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
2813 fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
2814 fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n",
2815 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2816 fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
2817 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2818 fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n",
2819 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2820 fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n",
2821 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2822 fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C);
2823 fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C);
2824 fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C);
2826 /* Output the dll_handle */
2827 fprintf (f, "\n.section .data\n");
2828 fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
2829 fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
2830 if (create_for_pep)
2831 fprintf (f, "\t%s\t0\n", ASM_LONG);
2832 fprintf (f, "\n");
2834 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2836 if (!no_idata5)
2838 fprintf (f, "\t.section\t.idata$5\n");
2839 /* NULL terminating list. */
2840 if (create_for_pep)
2841 fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2842 else
2843 fprintf (f, "\t%s\t0\n", ASM_LONG);
2844 fprintf (f, "__IAT_%s:\n", imp_name_lab);
2847 if (!no_idata4)
2849 fprintf (f, "\t.section\t.idata$4\n");
2850 fprintf (f, "\t%s\t0\n", ASM_LONG);
2851 if (create_for_pep)
2852 fprintf (f, "\t%s\t0\n", ASM_LONG);
2853 fprintf (f, "\t.section\t.idata$4\n");
2854 fprintf (f, "__INT_%s:\n", imp_name_lab);
2857 fprintf (f, "\t.section\t.idata$2\n");
2859 fclose (f);
2861 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2863 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2864 if (abfd == NULL)
2865 /* xgettext:c-format */
2866 fatal (_("failed to open temporary head file: %s: %s"),
2867 TMP_HEAD_O, bfd_get_errmsg ());
2869 temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
2870 return abfd;
2873 static bfd *
2874 make_tail (void)
2876 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
2877 bfd *abfd;
2879 if (f == NULL)
2881 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
2882 return NULL;
2885 temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S;
2887 if (!no_idata4)
2889 fprintf (f, "\t.section\t.idata$4\n");
2890 if (create_for_pep)
2891 fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2892 else
2893 fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
2896 if (!no_idata5)
2898 fprintf (f, "\t.section\t.idata$5\n");
2899 if (create_for_pep)
2900 fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2901 else
2902 fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
2905 fprintf (f, "\t.section\t.idata$7\n");
2906 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2907 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2908 imp_name_lab, ASM_TEXT, dll_name);
2910 fclose (f);
2912 assemble_file (TMP_TAIL_S, TMP_TAIL_O);
2914 abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
2915 if (abfd == NULL)
2916 /* xgettext:c-format */
2917 fatal (_("failed to open temporary tail file: %s: %s"),
2918 TMP_TAIL_O, bfd_get_errmsg ());
2920 temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O;
2921 return abfd;
2924 static void
2925 gen_lib_file (int delay)
2927 int i;
2928 export_type *exp;
2929 bfd *ar_head;
2930 bfd *ar_tail;
2931 bfd *outarch;
2932 bfd * head = 0;
2934 unlink (imp_name);
2936 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
2938 if (!outarch)
2939 /* xgettext:c-format */
2940 fatal (_("Can't create .lib file: %s: %s"),
2941 imp_name, bfd_get_errmsg ());
2943 /* xgettext:c-format */
2944 inform (_("Creating library file: %s"), imp_name);
2946 xatexit (unlink_temp_files);
2948 bfd_set_format (outarch, bfd_archive);
2949 outarch->has_armap = 1;
2950 outarch->is_thin_archive = 0;
2952 if (deterministic)
2953 outarch->flags |= BFD_DETERMINISTIC_OUTPUT;
2955 /* Work out a reasonable size of things to put onto one line. */
2956 if (delay)
2958 ar_head = make_delay_head ();
2960 else
2962 ar_head = make_head ();
2964 ar_tail = make_tail();
2966 if (ar_head == NULL || ar_tail == NULL)
2967 return;
2969 for (i = 0; (exp = d_exports_lexically[i]); i++)
2971 bfd *n;
2972 /* Don't add PRIVATE entries to import lib. */
2973 if (exp->private)
2974 continue;
2975 n = make_one_lib_file (exp, i, delay);
2976 n->archive_next = head;
2977 head = n;
2978 if (ext_prefix_alias)
2980 export_type alias_exp;
2982 assert (i < PREFIX_ALIAS_BASE);
2983 alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
2984 alias_exp.internal_name = exp->internal_name;
2985 alias_exp.its_name = exp->its_name;
2986 alias_exp.import_name = exp->name;
2987 alias_exp.ordinal = exp->ordinal;
2988 alias_exp.constant = exp->constant;
2989 alias_exp.noname = exp->noname;
2990 alias_exp.private = exp->private;
2991 alias_exp.data = exp->data;
2992 alias_exp.hint = exp->hint;
2993 alias_exp.forward = exp->forward;
2994 alias_exp.next = exp->next;
2995 n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay);
2996 n->archive_next = head;
2997 head = n;
3001 /* Now stick them all into the archive. */
3002 ar_head->archive_next = head;
3003 ar_tail->archive_next = ar_head;
3004 head = ar_tail;
3006 if (! bfd_set_archive_head (outarch, head))
3007 bfd_fatal ("bfd_set_archive_head");
3009 if (! bfd_close (outarch))
3010 bfd_fatal (imp_name);
3012 while (head != NULL)
3014 bfd *n = head->archive_next;
3015 bfd_close (head);
3016 head = n;
3019 /* Delete all the temp files. */
3020 unlink_temp_files ();
3022 if (dontdeltemps < 2)
3024 char *name = TMP_STUB;
3025 size_t name_len = strlen (name);
3027 for (i = 0; (exp = d_exports_lexically[i]); i++)
3029 /* Don't delete non-existent stubs for PRIVATE entries. */
3030 if (exp->private)
3031 continue;
3032 sprintf (name + name_len - 7, "%05d.o", i);
3033 if (unlink (name) < 0)
3034 /* xgettext:c-format */
3035 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3036 if (ext_prefix_alias)
3038 sprintf (name + name_len - 7, "%05d.o", i + PREFIX_ALIAS_BASE);
3039 if (unlink (name) < 0)
3040 /* xgettext:c-format */
3041 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3046 inform (_("Created lib file"));
3049 /* Append a copy of data (cast to char *) to list. */
3051 static void
3052 dll_name_list_append (dll_name_list_type * list, bfd_byte * data)
3054 dll_name_list_node_type * entry;
3056 /* Error checking. */
3057 if (! list || ! list->tail)
3058 return;
3060 /* Allocate new node. */
3061 entry = ((dll_name_list_node_type *)
3062 xmalloc (sizeof (dll_name_list_node_type)));
3064 /* Initialize its values. */
3065 entry->dllname = xstrdup ((char *) data);
3066 entry->next = NULL;
3068 /* Add to tail, and move tail. */
3069 list->tail->next = entry;
3070 list->tail = entry;
3073 /* Count the number of entries in list. */
3075 static int
3076 dll_name_list_count (dll_name_list_type * list)
3078 dll_name_list_node_type * p;
3079 int count = 0;
3081 /* Error checking. */
3082 if (! list || ! list->head)
3083 return 0;
3085 p = list->head;
3087 while (p && p->next)
3089 count++;
3090 p = p->next;
3092 return count;
3095 /* Print each entry in list to stdout. */
3097 static void
3098 dll_name_list_print (dll_name_list_type * list)
3100 dll_name_list_node_type * p;
3102 /* Error checking. */
3103 if (! list || ! list->head)
3104 return;
3106 p = list->head;
3108 while (p && p->next && p->next->dllname && *p->next->dllname)
3110 printf ("%s\n", p->next->dllname);
3111 p = p->next;
3115 /* Free all entries in list, and list itself. */
3117 static void
3118 dll_name_list_free (dll_name_list_type * list)
3120 if (list)
3122 dll_name_list_free_contents (list->head);
3123 list->head = NULL;
3124 list->tail = NULL;
3125 free (list);
3129 /* Recursive function to free all nodes entry->next->next...
3130 as well as entry itself. */
3132 static void
3133 dll_name_list_free_contents (dll_name_list_node_type * entry)
3135 if (entry)
3137 if (entry->next)
3138 dll_name_list_free_contents (entry->next);
3139 free (entry->dllname);
3140 free (entry);
3144 /* Allocate and initialize a dll_name_list_type object,
3145 including its sentinel node. Caller is responsible
3146 for calling dll_name_list_free when finished with
3147 the list. */
3149 static dll_name_list_type *
3150 dll_name_list_create (void)
3152 /* Allocate list. */
3153 dll_name_list_type * list = xmalloc (sizeof (dll_name_list_type));
3155 /* Allocate and initialize sentinel node. */
3156 list->head = xmalloc (sizeof (dll_name_list_node_type));
3157 list->head->dllname = NULL;
3158 list->head->next = NULL;
3160 /* Bookkeeping for empty list. */
3161 list->tail = list->head;
3163 return list;
3166 /* Search the symbol table of the suppled BFD for a symbol whose name matches
3167 OBJ (where obj is cast to const char *). If found, set global variable
3168 identify_member_contains_symname_result TRUE. It is the caller's
3169 responsibility to set the result variable FALSE before iterating with
3170 this function. */
3172 static void
3173 identify_member_contains_symname (bfd * abfd,
3174 bfd * archive_bfd ATTRIBUTE_UNUSED,
3175 void * obj)
3177 long storage_needed;
3178 asymbol ** symbol_table;
3179 long number_of_symbols;
3180 long i;
3181 symname_search_data_type * search_data = (symname_search_data_type *) obj;
3183 /* If we already found the symbol in a different member,
3184 short circuit. */
3185 if (search_data->found)
3186 return;
3188 storage_needed = bfd_get_symtab_upper_bound (abfd);
3189 if (storage_needed <= 0)
3190 return;
3192 symbol_table = xmalloc (storage_needed);
3193 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
3194 if (number_of_symbols < 0)
3196 free (symbol_table);
3197 return;
3200 for (i = 0; i < number_of_symbols; i++)
3202 if (strncmp (symbol_table[i]->name,
3203 search_data->symname,
3204 strlen (search_data->symname)) == 0)
3206 search_data->found = true;
3207 break;
3210 free (symbol_table);
3213 /* This is the main implementation for the --identify option.
3214 Given the name of an import library in identify_imp_name, first
3215 determine if the import library is a GNU binutils-style one (where
3216 the DLL name is stored in an .idata$7 section), or if it is a
3217 MS-style one (where the DLL name, along with much other data, is
3218 stored in the .idata$6 section). We determine the style of import
3219 library by searching for the DLL-structure symbol inserted by MS
3220 tools: __NULL_IMPORT_DESCRIPTOR.
3222 Once we know which section to search, evaluate each section for the
3223 appropriate properties that indicate it may contain the name of the
3224 associated DLL (this differs depending on the style). Add the contents
3225 of all sections which meet the criteria to a linked list of dll names.
3227 Finally, print them all to stdout. (If --identify-strict, an error is
3228 reported if more than one match was found). */
3230 static void
3231 identify_dll_for_implib (void)
3233 bfd * abfd = NULL;
3234 int count = 0;
3235 identify_data_type identify_data;
3236 symname_search_data_type search_data;
3238 /* Initialize identify_data. */
3239 identify_data.list = dll_name_list_create ();
3240 identify_data.ms_style_implib = false;
3242 /* Initialize search_data. */
3243 search_data.symname = "__NULL_IMPORT_DESCRIPTOR";
3244 search_data.found = false;
3246 if (bfd_init () != BFD_INIT_MAGIC)
3247 fatal (_("fatal error: libbfd ABI mismatch"));
3249 abfd = bfd_openr (identify_imp_name, 0);
3250 if (abfd == NULL)
3251 /* xgettext:c-format */
3252 fatal (_("Can't open .lib file: %s: %s"),
3253 identify_imp_name, bfd_get_errmsg ());
3255 if (! bfd_check_format (abfd, bfd_archive))
3257 if (! bfd_close (abfd))
3258 bfd_fatal (identify_imp_name);
3260 fatal (_("%s is not a library"), identify_imp_name);
3263 /* Detect if this a Microsoft import library. */
3264 identify_search_archive (abfd,
3265 identify_member_contains_symname,
3266 (void *) &search_data);
3267 if (search_data.found)
3268 identify_data.ms_style_implib = true;
3270 /* Rewind the bfd. */
3271 if (! bfd_close (abfd))
3272 bfd_fatal (identify_imp_name);
3273 abfd = bfd_openr (identify_imp_name, 0);
3274 if (abfd == NULL)
3275 bfd_fatal (identify_imp_name);
3277 if (!bfd_check_format (abfd, bfd_archive))
3279 if (!bfd_close (abfd))
3280 bfd_fatal (identify_imp_name);
3282 fatal (_("%s is not a library"), identify_imp_name);
3285 /* Now search for the dll name. */
3286 identify_search_archive (abfd,
3287 identify_search_member,
3288 (void *) &identify_data);
3290 if (! bfd_close (abfd))
3291 bfd_fatal (identify_imp_name);
3293 count = dll_name_list_count (identify_data.list);
3294 if (count > 0)
3296 if (identify_strict && count > 1)
3298 dll_name_list_free (identify_data.list);
3299 identify_data.list = NULL;
3300 fatal (_("Import library `%s' specifies two or more dlls"),
3301 identify_imp_name);
3303 dll_name_list_print (identify_data.list);
3304 dll_name_list_free (identify_data.list);
3305 identify_data.list = NULL;
3307 else
3309 dll_name_list_free (identify_data.list);
3310 identify_data.list = NULL;
3311 fatal (_("Unable to determine dll name for `%s' (not an import library?)"),
3312 identify_imp_name);
3316 /* Loop over all members of the archive, applying the supplied function to
3317 each member that is a bfd_object. The function will be called as if:
3318 func (member_bfd, abfd, user_storage) */
3320 static void
3321 identify_search_archive (bfd * abfd,
3322 void (* operation) (bfd *, bfd *, void *),
3323 void * user_storage)
3325 bfd * arfile = NULL;
3326 bfd * last_arfile = NULL;
3327 char ** matching;
3329 while (1)
3331 arfile = bfd_openr_next_archived_file (abfd, arfile);
3333 if (arfile == NULL)
3335 if (bfd_get_error () != bfd_error_no_more_archived_files)
3336 bfd_fatal (bfd_get_filename (abfd));
3337 break;
3340 if (bfd_check_format_matches (arfile, bfd_object, &matching))
3341 (*operation) (arfile, abfd, user_storage);
3342 else
3344 bfd_nonfatal (bfd_get_filename (arfile));
3345 free (matching);
3348 if (last_arfile != NULL)
3350 bfd_close (last_arfile);
3351 /* PR 17512: file: 8b2168d4. */
3352 if (last_arfile == arfile)
3354 last_arfile = NULL;
3355 break;
3359 last_arfile = arfile;
3362 if (last_arfile != NULL)
3364 bfd_close (last_arfile);
3368 /* Call the identify_search_section() function for each section of this
3369 archive member. */
3371 static void
3372 identify_search_member (bfd *abfd,
3373 bfd *archive_bfd ATTRIBUTE_UNUSED,
3374 void *obj)
3376 bfd_map_over_sections (abfd, identify_search_section, obj);
3379 /* This predicate returns true if section->name matches the desired value.
3380 By default, this is .idata$7 (.idata$6 if the import library is
3381 ms-style). */
3383 static bool
3384 identify_process_section_p (asection * section, bool ms_style_implib)
3386 static const char * SECTION_NAME = ".idata$7";
3387 static const char * MS_SECTION_NAME = ".idata$6";
3389 const char * section_name =
3390 (ms_style_implib ? MS_SECTION_NAME : SECTION_NAME);
3392 if (strcmp (section_name, section->name) == 0)
3393 return true;
3394 return false;
3397 /* If *section has contents and its name is .idata$7 (.idata$6 if
3398 import lib ms-generated) -- and it satisfies several other constraints
3399 -- then add the contents of the section to obj->list. */
3401 static void
3402 identify_search_section (bfd * abfd, asection * section, void * obj)
3404 bfd_byte *data = 0;
3405 bfd_size_type datasize;
3406 identify_data_type * identify_data = (identify_data_type *)obj;
3407 bool ms_style = identify_data->ms_style_implib;
3409 if ((section->flags & SEC_HAS_CONTENTS) == 0)
3410 return;
3412 if (! identify_process_section_p (section, ms_style))
3413 return;
3415 /* Binutils import libs seem distinguish the .idata$7 section that contains
3416 the DLL name from other .idata$7 sections by the absence of the
3417 SEC_RELOC flag. */
3418 if (!ms_style && ((section->flags & SEC_RELOC) == SEC_RELOC))
3419 return;
3421 /* MS import libs seem to distinguish the .idata$6 section
3422 that contains the DLL name from other .idata$6 sections
3423 by the presence of the SEC_DATA flag. */
3424 if (ms_style && ((section->flags & SEC_DATA) == 0))
3425 return;
3427 if ((datasize = bfd_section_size (section)) == 0)
3428 return;
3430 data = (bfd_byte *) xmalloc (datasize + 1);
3431 data[0] = '\0';
3433 bfd_get_section_contents (abfd, section, data, 0, datasize);
3434 data[datasize] = '\0';
3436 /* Use a heuristic to determine if data is a dll name.
3437 Possible to defeat this if (a) the library has MANY
3438 (more than 0x302f) imports, (b) it is an ms-style
3439 import library, but (c) it is buggy, in that the SEC_DATA
3440 flag is set on the "wrong" sections. This heuristic might
3441 also fail to record a valid dll name if the dllname uses
3442 a multibyte or unicode character set (is that valid?).
3444 This heuristic is based on the fact that symbols names in
3445 the chosen section -- as opposed to the dll name -- begin
3446 at offset 2 in the data. The first two bytes are a 16bit
3447 little-endian count, and start at 0x0000. However, the dll
3448 name begins at offset 0 in the data. We assume that the
3449 dll name does not contain unprintable characters. */
3450 if (data[0] != '\0' && ISPRINT (data[0])
3451 && (datasize < 2 || ISPRINT (data[1])))
3452 dll_name_list_append (identify_data->list, data);
3454 free (data);
3457 /* Run through the information gathered from the .o files and the
3458 .def file and work out the best stuff. */
3460 static int
3461 pfunc (const void *a, const void *b)
3463 export_type *ap = *(export_type **) a;
3464 export_type *bp = *(export_type **) b;
3466 if (ap->ordinal == bp->ordinal)
3467 return 0;
3469 /* Unset ordinals go to the bottom. */
3470 if (ap->ordinal == -1)
3471 return 1;
3472 if (bp->ordinal == -1)
3473 return -1;
3474 return (ap->ordinal - bp->ordinal);
3477 static int
3478 nfunc (const void *a, const void *b)
3480 export_type *ap = *(export_type **) a;
3481 export_type *bp = *(export_type **) b;
3482 const char *an = ap->name;
3483 const char *bn = bp->name;
3484 if (ap->its_name)
3485 an = ap->its_name;
3486 if (bp->its_name)
3487 an = bp->its_name;
3488 if (killat)
3490 an = (an[0] == '@') ? an + 1 : an;
3491 bn = (bn[0] == '@') ? bn + 1 : bn;
3494 return (strcmp (an, bn));
3497 static void
3498 remove_null_names (export_type **ptr)
3500 int src;
3501 int dst;
3503 for (dst = src = 0; src < d_nfuncs; src++)
3505 if (ptr[src])
3507 ptr[dst] = ptr[src];
3508 dst++;
3511 d_nfuncs = dst;
3514 static void
3515 process_duplicates (export_type **d_export_vec)
3517 int more = 1;
3518 int i;
3520 while (more)
3522 more = 0;
3523 /* Remove duplicates. */
3524 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3526 for (i = 0; i < d_nfuncs - 1; i++)
3528 if (strcmp (d_export_vec[i]->name,
3529 d_export_vec[i + 1]->name) == 0)
3531 export_type *a = d_export_vec[i];
3532 export_type *b = d_export_vec[i + 1];
3534 more = 1;
3536 /* xgettext:c-format */
3537 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3538 a->name, a->ordinal, b->ordinal);
3540 if (a->ordinal != -1
3541 && b->ordinal != -1)
3542 /* xgettext:c-format */
3543 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3544 a->name);
3546 /* Merge attributes. */
3547 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3548 b->constant |= a->constant;
3549 b->noname |= a->noname;
3550 b->data |= a->data;
3551 d_export_vec[i] = 0;
3554 remove_null_names (d_export_vec);
3558 /* Count the names. */
3559 for (i = 0; i < d_nfuncs; i++)
3560 if (!d_export_vec[i]->noname)
3561 d_named_nfuncs++;
3564 static void
3565 fill_ordinals (export_type **d_export_vec)
3567 int lowest = -1;
3568 int i;
3569 char *ptr;
3570 int size = 65536;
3572 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3574 /* Fill in the unset ordinals with ones from our range. */
3575 ptr = (char *) xmalloc (size);
3577 memset (ptr, 0, size);
3579 /* Mark in our large vector all the numbers that are taken. */
3580 for (i = 0; i < d_nfuncs; i++)
3582 if (d_export_vec[i]->ordinal != -1)
3584 ptr[d_export_vec[i]->ordinal] = 1;
3586 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
3587 lowest = d_export_vec[i]->ordinal;
3591 /* Start at 1 for compatibility with MS toolchain. */
3592 if (lowest == -1)
3593 lowest = 1;
3595 /* Now fill in ordinals where the user wants us to choose. */
3596 for (i = 0; i < d_nfuncs; i++)
3598 if (d_export_vec[i]->ordinal == -1)
3600 int j;
3602 /* First try within or after any user supplied range. */
3603 for (j = lowest; j < size; j++)
3604 if (ptr[j] == 0)
3606 ptr[j] = 1;
3607 d_export_vec[i]->ordinal = j;
3608 goto done;
3611 /* Then try before the range. */
3612 for (j = lowest; j >0; j--)
3613 if (ptr[j] == 0)
3615 ptr[j] = 1;
3616 d_export_vec[i]->ordinal = j;
3617 goto done;
3619 done:;
3623 free (ptr);
3625 /* And resort. */
3626 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3628 /* Work out the lowest and highest ordinal numbers. */
3629 if (d_nfuncs)
3631 if (d_export_vec[0])
3632 d_low_ord = d_export_vec[0]->ordinal;
3633 if (d_export_vec[d_nfuncs-1])
3634 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
3638 static void
3639 mangle_defs (void)
3641 /* First work out the minimum ordinal chosen. */
3642 export_type *exp;
3644 int i;
3645 int hint = 0;
3646 export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
3648 inform (_("Processing definitions"));
3650 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3651 d_export_vec[i] = exp;
3653 process_duplicates (d_export_vec);
3654 fill_ordinals (d_export_vec);
3656 /* Put back the list in the new order. */
3657 d_exports = 0;
3658 for (i = d_nfuncs - 1; i >= 0; i--)
3660 d_export_vec[i]->next = d_exports;
3661 d_exports = d_export_vec[i];
3664 /* Build list in alpha order. */
3665 d_exports_lexically = (export_type **)
3666 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3668 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3669 d_exports_lexically[i] = exp;
3671 d_exports_lexically[i] = 0;
3673 qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
3675 /* Fill exp entries with their hint values. */
3676 for (i = 0; i < d_nfuncs; i++)
3677 if (!d_exports_lexically[i]->noname || show_allnames)
3678 d_exports_lexically[i]->hint = hint++;
3680 inform (_("Processed definitions"));
3683 static void
3684 usage (FILE *file, int status)
3686 /* xgetext:c-format */
3687 fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
3688 /* xgetext:c-format */
3689 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
3690 fprintf (file, _(" possible <machine>: arm[_interwork], arm64, i386, mcore[-elf]{-le|-be}, thumb\n"));
3691 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
3692 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
3693 fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
3694 fprintf (file, _(" --deterministic-libraries\n"));
3695 if (DEFAULT_AR_DETERMINISTIC)
3696 fprintf (file, _(" Use zero for timestamps and uids/gids in output libraries (default)\n"));
3697 else
3698 fprintf (file, _(" Use zero for timestamps and uids/gids in output libraries\n"));
3699 fprintf (file, _(" --non-deterministic-libraries\n"));
3700 if (DEFAULT_AR_DETERMINISTIC)
3701 fprintf (file, _(" Use actual timestamps and uids/gids in output libraries\n"));
3702 else
3703 fprintf (file, _(" Use actual timestamps and uids/gids in output libraries (default)\n"));
3704 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
3705 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3706 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3707 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3708 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
3709 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
3710 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
3711 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
3712 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3713 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3714 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3715 fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3716 fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n"));
3717 fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3718 fprintf (file, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n"));
3719 fprintf (file, _(" --leading-underscore All symbols should be prefixed by an underscore.\n"));
3720 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
3721 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3722 fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3723 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
3724 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3725 fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n"));
3726 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3727 fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3728 fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
3729 fprintf (file, _(" --identify-strict Causes --identify to report error when multiple DLLs.\n"));
3730 fprintf (file, _(" -v --verbose Be verbose.\n"));
3731 fprintf (file, _(" -V --version Display the program version.\n"));
3732 fprintf (file, _(" -h --help Display this information.\n"));
3733 fprintf (file, _(" @<file> Read options from <file>.\n"));
3734 #ifdef DLLTOOL_MCORE_ELF
3735 fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3736 fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n"));
3737 fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3738 #endif
3739 if (REPORT_BUGS_TO[0] && status == 0)
3740 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
3741 exit (status);
3744 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
3745 enum command_line_switch
3747 OPTION_EXPORT_ALL_SYMS = 150,
3748 OPTION_NO_EXPORT_ALL_SYMS,
3749 OPTION_EXCLUDE_SYMS,
3750 OPTION_NO_DEFAULT_EXCLUDES,
3751 OPTION_ADD_STDCALL_UNDERSCORE,
3752 OPTION_USE_NUL_PREFIXED_IMPORT_TABLES,
3753 OPTION_IDENTIFY_STRICT,
3754 OPTION_NO_LEADING_UNDERSCORE,
3755 OPTION_LEADING_UNDERSCORE,
3756 OPTION_DETERMINISTIC_LIBRARIES,
3757 OPTION_NON_DETERMINISTIC_LIBRARIES
3760 static const struct option long_options[] =
3762 {"add-indirect", no_argument, NULL, 'a'},
3763 {"add-stdcall-alias", no_argument, NULL, 'A'},
3764 {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
3765 {"add-underscore", no_argument, NULL, 'U'},
3766 {"as", required_argument, NULL, 'S'},
3767 {"as-flags", required_argument, NULL, 'f'},
3768 {"base-file", required_argument, NULL, 'b'},
3769 {"compat-implib", no_argument, NULL, 'C'},
3770 {"def", required_argument, NULL, 'd'}, /* For compatibility with older versions. */
3771 {"deterministic-libraries", no_argument, NULL, OPTION_DETERMINISTIC_LIBRARIES},
3772 {"dllname", required_argument, NULL, 'D'},
3773 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3774 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
3775 {"ext-prefix-alias", required_argument, NULL, 'p'},
3776 {"help", no_argument, NULL, 'h'},
3777 {"identify", required_argument, NULL, 'I'},
3778 {"identify-strict", no_argument, NULL, OPTION_IDENTIFY_STRICT},
3779 {"input-def", required_argument, NULL, 'd'},
3780 {"kill-at", no_argument, NULL, 'k'},
3781 {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
3782 {"machine", required_argument, NULL, 'm'},
3783 {"mcore-elf", required_argument, NULL, 'M'},
3784 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3785 {"no-delete", no_argument, NULL, 'n'},
3786 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3787 {"no-idata4", no_argument, NULL, 'x'},
3788 {"no-idata5", no_argument, NULL, 'c'},
3789 {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
3790 {"non-deterministic-libraries", no_argument, NULL, OPTION_NON_DETERMINISTIC_LIBRARIES},
3791 {"output-def", required_argument, NULL, 'z'},
3792 {"output-delaylib", required_argument, NULL, 'y'},
3793 {"output-exp", required_argument, NULL, 'e'},
3794 {"output-lib", required_argument, NULL, 'l'},
3795 {"temp-prefix", required_argument, NULL, 't'},
3796 {"use-nul-prefixed-import-tables", no_argument, NULL, OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
3797 {"verbose", no_argument, NULL, 'v'},
3798 {"version", no_argument, NULL, 'V'},
3799 {NULL,0,NULL,0}
3802 int main (int, char **);
3805 main (int ac, char **av)
3807 int c;
3808 int i;
3809 char *firstarg = 0;
3810 program_name = av[0];
3811 oav = av;
3813 #ifdef HAVE_LC_MESSAGES
3814 setlocale (LC_MESSAGES, "");
3815 #endif
3816 setlocale (LC_CTYPE, "");
3817 bindtextdomain (PACKAGE, LOCALEDIR);
3818 textdomain (PACKAGE);
3820 bfd_set_error_program_name (program_name);
3821 expandargv (&ac, &av);
3823 while ((c = getopt_long (ac, av,
3824 #ifdef DLLTOOL_MCORE_ELF
3825 "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:",
3826 #else
3827 "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh",
3828 #endif
3829 long_options, 0))
3830 != EOF)
3832 switch (c)
3834 case OPTION_EXPORT_ALL_SYMS:
3835 export_all_symbols = true;
3836 break;
3837 case OPTION_NO_EXPORT_ALL_SYMS:
3838 export_all_symbols = false;
3839 break;
3840 case OPTION_EXCLUDE_SYMS:
3841 add_excludes (optarg);
3842 break;
3843 case OPTION_NO_DEFAULT_EXCLUDES:
3844 do_default_excludes = false;
3845 break;
3846 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
3847 use_nul_prefixed_import_tables = true;
3848 break;
3849 case OPTION_ADD_STDCALL_UNDERSCORE:
3850 add_stdcall_underscore = 1;
3851 break;
3852 case OPTION_NO_LEADING_UNDERSCORE:
3853 leading_underscore = "";
3854 break;
3855 case OPTION_LEADING_UNDERSCORE:
3856 leading_underscore = "_";
3857 break;
3858 case OPTION_IDENTIFY_STRICT:
3859 identify_strict = 1;
3860 break;
3861 case 'x':
3862 no_idata4 = 1;
3863 break;
3864 case 'c':
3865 no_idata5 = 1;
3866 break;
3867 case 'S':
3868 as_name = optarg;
3869 break;
3870 case 't':
3871 tmp_prefix = optarg;
3872 break;
3873 case 'f':
3874 as_flags = optarg;
3875 break;
3877 /* Ignored for compatibility. */
3878 case 'u':
3879 break;
3880 case 'a':
3881 add_indirect = 1;
3882 break;
3883 case 'z':
3884 output_def = fopen (optarg, FOPEN_WT);
3885 if (!output_def)
3886 /* xgettext:c-format */
3887 fatal (_("Unable to open def-file: %s"), optarg);
3888 break;
3889 case 'D':
3890 dll_name = (char*) lbasename (optarg);
3891 if (dll_name != optarg)
3892 non_fatal (_("Path components stripped from dllname, '%s'."),
3893 optarg);
3894 break;
3895 case 'l':
3896 imp_name = optarg;
3897 break;
3898 case 'e':
3899 exp_name = optarg;
3900 break;
3901 case 'H':
3902 case 'h':
3903 usage (stdout, 0);
3904 break;
3905 case 'm':
3906 mname = optarg;
3907 break;
3908 case 'I':
3909 identify_imp_name = optarg;
3910 break;
3911 case 'v':
3912 verbose = 1;
3913 break;
3914 case 'V':
3915 print_version (program_name);
3916 break;
3917 case 'U':
3918 add_underscore = 1;
3919 break;
3920 case 'k':
3921 killat = 1;
3922 break;
3923 case 'A':
3924 add_stdcall_alias = 1;
3925 break;
3926 case 'p':
3927 ext_prefix_alias = optarg;
3928 break;
3929 case 'd':
3930 def_file = optarg;
3931 break;
3932 case 'n':
3933 dontdeltemps++;
3934 break;
3935 case 'b':
3936 base_file = fopen (optarg, FOPEN_RB);
3938 if (!base_file)
3939 /* xgettext:c-format */
3940 fatal (_("Unable to open base-file: %s"), optarg);
3942 break;
3943 #ifdef DLLTOOL_MCORE_ELF
3944 case 'M':
3945 mcore_elf_out_file = optarg;
3946 break;
3947 case 'L':
3948 mcore_elf_linker = optarg;
3949 break;
3950 case 'F':
3951 mcore_elf_linker_flags = optarg;
3952 break;
3953 #endif
3954 case 'C':
3955 create_compat_implib = 1;
3956 break;
3957 case 'y':
3958 delayimp_name = optarg;
3959 break;
3960 case OPTION_DETERMINISTIC_LIBRARIES:
3961 deterministic = true;
3962 break;
3963 case OPTION_NON_DETERMINISTIC_LIBRARIES:
3964 deterministic = false;
3965 break;
3966 default:
3967 usage (stderr, 1);
3968 break;
3972 for (i = 0; mtable[i].type; i++)
3973 if (strcmp (mtable[i].type, mname) == 0)
3974 break;
3976 if (!mtable[i].type)
3977 /* xgettext:c-format */
3978 fatal (_("Machine '%s' not supported"), mname);
3980 machine = i;
3982 /* Check if we generated PE+. */
3983 create_for_pep = (strcmp (mname, "i386:x86-64") == 0
3984 || strcmp (mname, "arm64") == 0);
3986 /* Check the default underscore */
3987 if (leading_underscore == NULL)
3989 int u;
3990 static char underscore[2];
3991 bfd_get_target_info (mtable[machine].how_bfd_target, NULL,
3992 NULL, &u, NULL);
3993 if (u == -1)
3994 u = 0;
3995 underscore[0] = u;
3996 underscore[1] = 0;
3997 leading_underscore = underscore;
4000 if (!dll_name && exp_name)
4002 /* If we are inferring dll_name from exp_name,
4003 strip off any path components, without emitting
4004 a warning. */
4005 const char* exp_basename = lbasename (exp_name);
4006 const int len = strlen (exp_basename) + 5;
4007 dll_name = xmalloc (len);
4008 strcpy (dll_name, exp_basename);
4009 strcat (dll_name, ".dll");
4010 dll_name_set_by_exp_name = 1;
4013 if (as_name == NULL)
4014 as_name = deduce_name ("as");
4016 /* Don't use the default exclude list if we're reading only the
4017 symbols in the .drectve section. The default excludes are meant
4018 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
4019 if (! export_all_symbols)
4020 do_default_excludes = false;
4022 if (do_default_excludes)
4023 set_default_excludes ();
4025 if (def_file)
4026 process_def_file (def_file);
4028 while (optind < ac)
4030 if (!firstarg)
4031 firstarg = av[optind];
4032 scan_obj_file (av[optind]);
4033 optind++;
4036 if (tmp_prefix == NULL)
4038 /* If possible use a deterministic prefix. */
4039 const char *input = imp_name ? imp_name : delayimp_name;
4040 if (input && strlen (input) + sizeof ("_snnnnn.o") - 1 <= NAME_MAX)
4042 tmp_prefix = xmalloc (strlen (input) + 2);
4043 sprintf (tmp_prefix, "%s_", input);
4044 for (i = 0; tmp_prefix[i]; i++)
4045 if (!ISALNUM (tmp_prefix[i]))
4046 tmp_prefix[i] = '_';
4048 else
4049 tmp_prefix = prefix_encode ("d", getpid ());
4052 mangle_defs ();
4054 if (exp_name)
4055 gen_exp_file ();
4057 if (imp_name)
4059 /* Make imp_name safe for use as a label. */
4060 char *p;
4062 imp_name_lab = xstrdup (imp_name);
4063 for (p = imp_name_lab; *p; p++)
4065 if (!ISALNUM (*p))
4066 *p = '_';
4068 head_label = make_label("_head_", imp_name_lab);
4069 gen_lib_file (0);
4072 if (delayimp_name)
4074 /* Make delayimp_name safe for use as a label. */
4075 char *p;
4077 if (mtable[machine].how_dljtab == 0)
4079 inform (_("Warning, machine type (%d) not supported for "
4080 "delayimport."), machine);
4082 else
4084 killat = 1;
4085 imp_name = delayimp_name;
4086 imp_name_lab = xstrdup (imp_name);
4087 for (p = imp_name_lab; *p; p++)
4089 if (!ISALNUM (*p))
4090 *p = '_';
4092 head_label = make_label("__tailMerge_", imp_name_lab);
4093 gen_lib_file (1);
4097 if (output_def)
4098 gen_def_file ();
4100 if (identify_imp_name)
4102 identify_dll_for_implib ();
4105 #ifdef DLLTOOL_MCORE_ELF
4106 if (mcore_elf_out_file)
4107 mcore_elf_gen_out_file ();
4108 #endif
4110 return 0;
4113 /* Look for the program formed by concatenating PROG_NAME and the
4114 string running from PREFIX to END_PREFIX. If the concatenated
4115 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
4116 appropriate. */
4118 static char *
4119 look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
4121 struct stat s;
4122 char *cmd;
4124 cmd = xmalloc (strlen (prefix)
4125 + strlen (prog_name)
4126 #ifdef HAVE_EXECUTABLE_SUFFIX
4127 + strlen (EXECUTABLE_SUFFIX)
4128 #endif
4129 + 10);
4130 memcpy (cmd, prefix, end_prefix);
4132 strcpy (cmd + end_prefix, prog_name);
4134 if (strchr (cmd, '/') != NULL)
4136 int found;
4138 found = (stat (cmd, &s) == 0
4139 #ifdef HAVE_EXECUTABLE_SUFFIX
4140 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
4141 #endif
4144 if (! found)
4146 /* xgettext:c-format */
4147 inform (_("Tried file: %s"), cmd);
4148 free (cmd);
4149 return NULL;
4153 /* xgettext:c-format */
4154 inform (_("Using file: %s"), cmd);
4156 return cmd;
4159 /* Deduce the name of the program we are want to invoke.
4160 PROG_NAME is the basic name of the program we want to run,
4161 eg "as" or "ld". The catch is that we might want actually
4162 run "i386-pe-as".
4164 If argv[0] contains the full path, then try to find the program
4165 in the same place, with and then without a target-like prefix.
4167 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
4168 deduce_name("as") uses the following search order:
4170 /usr/local/bin/i586-cygwin32-as
4171 /usr/local/bin/as
4174 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
4175 name, it'll try without and then with EXECUTABLE_SUFFIX.
4177 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
4178 as the fallback, but rather return i586-cygwin32-as.
4180 Oh, and given, argv[0] = dlltool, it'll return "as".
4182 Returns a dynamically allocated string. */
4184 static char *
4185 deduce_name (const char *prog_name)
4187 char *cmd;
4188 char *dash, *slash, *cp;
4190 dash = NULL;
4191 slash = NULL;
4192 for (cp = program_name; *cp != '\0'; ++cp)
4194 if (*cp == '-')
4195 dash = cp;
4196 if (
4197 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4198 *cp == ':' || *cp == '\\' ||
4199 #endif
4200 *cp == '/')
4202 slash = cp;
4203 dash = NULL;
4207 cmd = NULL;
4209 if (dash != NULL)
4211 /* First, try looking for a prefixed PROG_NAME in the
4212 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
4213 cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
4216 if (slash != NULL && cmd == NULL)
4218 /* Next, try looking for a PROG_NAME in the same directory as
4219 that of this program. */
4220 cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
4223 if (cmd == NULL)
4225 /* Just return PROG_NAME as is. */
4226 cmd = xstrdup (prog_name);
4229 return cmd;
4232 #ifdef DLLTOOL_MCORE_ELF
4233 typedef struct fname_cache
4235 const char * filename;
4236 struct fname_cache * next;
4238 fname_cache;
4240 static fname_cache fnames;
4242 static void
4243 mcore_elf_cache_filename (const char * filename)
4245 fname_cache * ptr;
4247 ptr = & fnames;
4249 while (ptr->next != NULL)
4250 ptr = ptr->next;
4252 ptr->filename = filename;
4253 ptr->next = (fname_cache *) malloc (sizeof (fname_cache));
4254 if (ptr->next != NULL)
4255 ptr->next->next = NULL;
4258 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
4259 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
4260 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
4262 static void
4263 mcore_elf_gen_out_file (void)
4265 fname_cache * ptr;
4266 dyn_string_t ds;
4268 /* Step one. Run 'ld -r' on the input object files in order to resolve
4269 any internal references and to generate a single .exports section. */
4270 ptr = & fnames;
4272 ds = dyn_string_new (100);
4273 dyn_string_append_cstr (ds, "-r ");
4275 if (mcore_elf_linker_flags != NULL)
4276 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4278 while (ptr->next != NULL)
4280 dyn_string_append_cstr (ds, ptr->filename);
4281 dyn_string_append_cstr (ds, " ");
4283 ptr = ptr->next;
4286 dyn_string_append_cstr (ds, "-o ");
4287 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4289 if (mcore_elf_linker == NULL)
4290 mcore_elf_linker = deduce_name ("ld");
4292 run (mcore_elf_linker, ds->s);
4294 dyn_string_delete (ds);
4296 /* Step two. Create a .exp file and a .lib file from the temporary file.
4297 Do this by recursively invoking dlltool... */
4298 ds = dyn_string_new (100);
4300 dyn_string_append_cstr (ds, "-S ");
4301 dyn_string_append_cstr (ds, as_name);
4303 dyn_string_append_cstr (ds, " -e ");
4304 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4305 dyn_string_append_cstr (ds, " -l ");
4306 dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB);
4307 dyn_string_append_cstr (ds, " " );
4308 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4310 if (verbose)
4311 dyn_string_append_cstr (ds, " -v");
4313 if (dontdeltemps)
4315 dyn_string_append_cstr (ds, " -n");
4317 if (dontdeltemps > 1)
4318 dyn_string_append_cstr (ds, " -n");
4321 /* XXX - FIME: ought to check/copy other command line options as well. */
4322 run (program_name, ds->s);
4324 dyn_string_delete (ds);
4326 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
4327 ds = dyn_string_new (100);
4329 dyn_string_append_cstr (ds, "-shared ");
4331 if (mcore_elf_linker_flags)
4332 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4334 dyn_string_append_cstr (ds, " ");
4335 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4336 dyn_string_append_cstr (ds, " ");
4337 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4338 dyn_string_append_cstr (ds, " -o ");
4339 dyn_string_append_cstr (ds, mcore_elf_out_file);
4341 run (mcore_elf_linker, ds->s);
4343 dyn_string_delete (ds);
4345 if (dontdeltemps == 0)
4346 unlink (MCORE_ELF_TMP_EXP);
4348 if (dontdeltemps < 2)
4349 unlink (MCORE_ELF_TMP_OBJ);
4351 #endif /* DLLTOOL_MCORE_ELF */