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
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.
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
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.
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.
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
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>
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
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.
99 asm (".section .drectve");
100 asm (".ascii \"-export:adef\"");
104 printf ("hello from the dll %s\n", s);
109 printf ("hello from the dll and the other entry point %s\n", s);
113 asm (".section .drectve");
114 asm (".ascii \"-export:cdef\"");
115 asm (".ascii \"-export:ddef\"");
119 printf ("hello from the dll %s\n", s);
124 printf ("hello from the dll and the other entry point %s\n", s);
142 HEAPSIZE 0x40000, 0x2000
146 SECTIONS donkey READ WRITE
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
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
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
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"). */
243 #include "libiberty.h"
245 #include "demangle.h"
246 #include "dyn-string.h"
249 #include "safe-ctype.h"
250 #include "coff-bfd.h"
256 #include "coff/arm.h"
257 #include "coff/internal.h"
259 #ifdef DLLTOOL_DEFAULT_MX86_64
260 #include "coff/x86_64.h"
262 #ifdef DLLTOOL_DEFAULT_I386
263 #include "coff/i386.h"
266 #ifndef COFF_PAGE_SIZE
267 #define COFF_PAGE_SIZE ((bfd_vma) 4096)
271 #define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE))
274 /* Get current BFD error message. */
275 #define bfd_get_errmsg() (bfd_errmsg (bfd_get_error ()))
277 /* Forward references. */
278 static char *look_for_prog (const char *, const char *, int);
279 static char *deduce_name (const char *);
281 #ifdef DLLTOOL_MCORE_ELF
282 static void mcore_elf_cache_filename (const char *);
283 static void mcore_elf_gen_out_file (void);
286 #ifdef HAVE_SYS_WAIT_H
287 #include <sys/wait.h>
288 #else /* ! HAVE_SYS_WAIT_H */
289 #if ! defined (_WIN32) || defined (__CYGWIN32__)
291 #define WIFEXITED(w) (((w) & 0377) == 0)
294 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
297 #define WTERMSIG(w) ((w) & 0177)
300 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
302 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
304 #define WIFEXITED(w) (((w) & 0xff) == 0)
307 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
310 #define WTERMSIG(w) ((w) & 0x7f)
313 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
315 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
316 #endif /* ! HAVE_SYS_WAIT_H */
318 #define show_allnames 0
320 /* ifunc and ihead data structures: ttk@cygnus.com 1997
322 When IMPORT declarations are encountered in a .def file the
323 function import information is stored in a structure referenced by
324 the global variable IMPORT_LIST. The structure is a linked list
325 containing the names of the dll files each function is imported
326 from and a linked list of functions being imported from that dll
327 file. This roughly parallels the structure of the .idata section
328 in the PE object file.
330 The contents of .def file are interpreted from within the
331 process_def_file function. Every time an IMPORT declaration is
332 encountered, it is broken up into its component parts and passed to
333 def_import. IMPORT_LIST is initialized to NULL in function main. */
335 typedef struct ifunct
337 char * name
; /* Name of function being imported. */
338 char * its_name
; /* Optional import table symbol name. */
339 int ord
; /* Two-byte ordinal value associated with function. */
343 typedef struct iheadt
345 char * dllname
; /* Name of dll file imported from. */
346 long nfuncs
; /* Number of functions in list. */
347 struct ifunct
*funchead
; /* First function in list. */
348 struct ifunct
*functail
; /* Last function in list. */
349 struct iheadt
*next
; /* Next dll file in list. */
352 /* Structure containing all import information as defined in .def file
353 (qv "ihead structure"). */
355 static iheadtype
*import_list
= NULL
;
356 static char *as_name
= NULL
;
357 static char * as_flags
= "";
358 static char *tmp_prefix
= NULL
;
359 static int no_idata4
;
360 static int no_idata5
;
361 static char *exp_name
;
362 static char *imp_name
;
363 static char *delayimp_name
;
364 static char *identify_imp_name
;
365 static bool identify_strict
;
366 static bool deterministic
= DEFAULT_AR_DETERMINISTIC
;
368 /* Types used to implement a linked list of dllnames associated
369 with the specified import lib. Used by the identify_* code.
370 The head entry is acts as a sentinal node and is always empty
371 (head->dllname is NULL). */
372 typedef struct dll_name_list_node_t
375 struct dll_name_list_node_t
* next
;
376 } dll_name_list_node_type
;
378 typedef struct dll_name_list_t
380 dll_name_list_node_type
* head
;
381 dll_name_list_node_type
* tail
;
382 } dll_name_list_type
;
384 /* Types used to pass data to iterator functions. */
385 typedef struct symname_search_data_t
389 } symname_search_data_type
;
391 typedef struct identify_data_t
393 dll_name_list_type
*list
;
394 bool ms_style_implib
;
395 } identify_data_type
;
398 static char *head_label
;
399 static char *imp_name_lab
;
400 static char *dll_name
;
401 static int dll_name_set_by_exp_name
;
402 static int add_indirect
= 0;
403 static int add_underscore
= 0;
404 static int add_stdcall_underscore
= 0;
405 /* This variable can hold three different values. The value
406 -1 (default) means that default underscoring should be used,
407 zero means that no underscoring should be done, and one
408 indicates that underscoring should be done. */
409 static int leading_underscore
= -1;
410 static int dontdeltemps
= 0;
412 /* TRUE if we should export all symbols. Otherwise, we only export
413 symbols listed in .drectve sections or in the def file. */
414 static bool export_all_symbols
;
416 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
417 exporting all symbols. */
418 static bool do_default_excludes
= true;
420 static bool use_nul_prefixed_import_tables
= false;
422 /* Default symbols to exclude when exporting all the symbols. */
423 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
425 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
426 compatibility to old Cygwin releases. */
427 static bool create_compat_implib
;
429 /* TRUE if we have to write PE+ import libraries. */
430 static bool create_for_pep
;
432 static char *def_file
;
434 extern char * program_name
;
438 static int add_stdcall_alias
;
439 static const char *ext_prefix_alias
;
441 static FILE *output_def
;
442 static FILE *base_file
;
444 #ifdef DLLTOOL_DEFAULT_ARM
445 static const char *mname
= "arm";
448 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
449 static const char *mname
= "arm-wince";
452 #ifdef DLLTOOL_DEFAULT_AARCH64
453 /* arm64 rather than aarch64 to match llvm-dlltool */
454 static const char *mname
= "arm64";
457 #ifdef DLLTOOL_DEFAULT_I386
458 static const char *mname
= "i386";
461 #ifdef DLLTOOL_DEFAULT_MX86_64
462 static const char *mname
= "i386:x86-64";
465 #ifdef DLLTOOL_DEFAULT_SH
466 static const char *mname
= "sh";
469 #ifdef DLLTOOL_DEFAULT_MIPS
470 static const char *mname
= "mips";
473 #ifdef DLLTOOL_DEFAULT_MCORE
474 static const char * mname
= "mcore-le";
477 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
478 static const char * mname
= "mcore-elf";
479 static char * mcore_elf_out_file
= NULL
;
480 static char * mcore_elf_linker
= NULL
;
481 static char * mcore_elf_linker_flags
= NULL
;
483 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
486 #ifndef DRECTVE_SECTION_NAME
487 #define DRECTVE_SECTION_NAME ".drectve"
490 /* What's the right name for this ? */
493 /* External name alias numbering starts here. */
494 #define PREFIX_ALIAS_BASE 20000
497 char *tmp_head_s_buf
;
498 char *tmp_head_o_buf
;
499 char *tmp_tail_s_buf
;
500 char *tmp_tail_o_buf
;
503 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
504 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
505 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
506 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
507 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
508 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ss")
510 /* This bit of assembly does jmp * .... */
511 static const unsigned char i386_jtab
[] =
513 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
516 static const unsigned char i386_dljtab
[] =
518 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
519 0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
520 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
523 static const unsigned char i386_x64_dljtab
[] =
525 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
526 0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */
527 0x00, 0x00, 0x00, 0x00,
528 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
531 static const unsigned char arm_jtab
[] =
533 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
534 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
538 static const unsigned char arm_interwork_jtab
[] =
540 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
541 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
542 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
546 static const unsigned char thumb_jtab
[] =
548 0x40, 0xb4, /* push {r6} */
549 0x02, 0x4e, /* ldr r6, [pc, #8] */
550 0x36, 0x68, /* ldr r6, [r6] */
551 0xb4, 0x46, /* mov ip, r6 */
552 0x40, 0xbc, /* pop {r6} */
553 0x60, 0x47, /* bx ip */
557 static const unsigned char mcore_be_jtab
[] =
559 0x71, 0x02, /* lrw r1,2 */
560 0x81, 0x01, /* ld.w r1,(r1,0) */
561 0x00, 0xC1, /* jmp r1 */
562 0x12, 0x00, /* nop */
563 0x00, 0x00, 0x00, 0x00 /* <address> */
566 static const unsigned char mcore_le_jtab
[] =
568 0x02, 0x71, /* lrw r1,2 */
569 0x01, 0x81, /* ld.w r1,(r1,0) */
570 0xC1, 0x00, /* jmp r1 */
571 0x00, 0x12, /* nop */
572 0x00, 0x00, 0x00, 0x00 /* <address> */
575 static const unsigned char aarch64_jtab
[] =
577 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
578 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
579 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
580 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
583 static const char i386_trampoline
[] =
587 "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
588 "\tcall ___delayLoadHelper2@8\n"
593 /* Save integer arg regs in parameter space reserved by our caller
594 above the return address. Allocate space for six fp arg regs plus
595 parameter space possibly used by __delayLoadHelper2 plus alignment.
596 We enter with the stack offset from 16-byte alignment by the return
597 address, so allocate 96 + 32 + 8 = 136 bytes. Note that only the
598 first four xmm regs are used to pass fp args, but the first six
599 vector ymm (zmm too?) are used to pass vector args. We are
600 assuming that volatile vector regs are not modified inside
601 __delayLoadHelper2. However, it is known that at least xmm0 and
602 xmm1 are trashed in some versions of Microsoft dlls, and if xmm4 or
603 xmm5 are also used then that would trash the lower bits of ymm4 and
604 ymm5. If it turns out that vector insns with a vex prefix are used
605 then we'll need to save ymm0-5 here but that can't be done without
606 first testing cpuid and xcr0. */
607 static const char i386_x64_trampoline
[] =
608 "\tsubq $136, %%rsp\n"
609 "\t.seh_stackalloc 136\n"
610 "\t.seh_endprologue\n"
611 "\tmovq %%rcx, 136+8(%%rsp)\n"
612 "\tmovq %%rdx, 136+16(%%rsp)\n"
613 "\tmovq %%r8, 136+24(%%rsp)\n"
614 "\tmovq %%r9, 136+32(%%rsp)\n"
615 "\tmovaps %%xmm0, 32(%%rsp)\n"
616 "\tmovaps %%xmm1, 48(%%rsp)\n"
617 "\tmovaps %%xmm2, 64(%%rsp)\n"
618 "\tmovaps %%xmm3, 80(%%rsp)\n"
619 "\tmovaps %%xmm4, 96(%%rsp)\n"
620 "\tmovaps %%xmm5, 112(%%rsp)\n"
621 "\tmovq %%rax, %%rdx\n"
622 "\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n"
623 "\tcall __delayLoadHelper2\n"
624 "\tmovq 136+8(%%rsp), %%rcx\n"
625 "\tmovq 136+16(%%rsp), %%rdx\n"
626 "\tmovq 136+24(%%rsp), %%r8\n"
627 "\tmovq 136+32(%%rsp), %%r9\n"
628 "\tmovaps 32(%%rsp), %%xmm0\n"
629 "\tmovaps 48(%%rsp), %%xmm1\n"
630 "\tmovaps 64(%%rsp), %%xmm2\n"
631 "\tmovaps 80(%%rsp), %%xmm3\n"
632 "\tmovaps 96(%%rsp), %%xmm4\n"
633 "\tmovaps 112(%%rsp), %%xmm5\n"
634 "\taddq $136, %%rsp\n"
640 const char *how_byte
;
641 const char *how_short
;
642 const char *how_long
;
643 const char *how_asciz
;
644 const char *how_comment
;
645 const char *how_jump
;
646 const char *how_global
;
647 const char *how_space
;
648 const char *how_align_short
;
649 const char *how_align_long
;
650 const char *how_default_as_switches
;
651 const char *how_bfd_target
;
652 enum bfd_architecture how_bfd_arch
;
653 const unsigned char *how_jtab
;
654 int how_jtab_size
; /* Size of the jtab entry. */
655 int how_jtab_roff
; /* Offset into it for the ind 32 reloc into idata 5. */
656 const unsigned char *how_dljtab
;
657 int how_dljtab_size
; /* Size of the dljtab entry. */
658 int how_dljtab_roff1
; /* Offset for the ind 32 reloc into idata 5. */
659 int how_dljtab_roff2
; /* Offset for the ind 32 reloc into idata 5. */
660 int how_dljtab_roff3
; /* Offset for the ind 32 reloc into idata 5. */
662 const char *trampoline
;
665 static const struct mac
670 "arm", ".byte", ".short", ".long", ".asciz", "@",
671 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
672 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
673 "pe-arm-little", bfd_arch_arm
,
674 arm_jtab
, sizeof (arm_jtab
), 8,
675 0, 0, 0, 0, 0, false, 0
680 "i386", ".byte", ".short", ".long", ".asciz", "#",
681 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
682 "pe-i386",bfd_arch_i386
,
683 i386_jtab
, sizeof (i386_jtab
), 2,
684 i386_dljtab
, sizeof (i386_dljtab
), 2, 7, 12, false, i386_trampoline
689 "thumb", ".byte", ".short", ".long", ".asciz", "@",
690 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
691 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
692 "pe-arm-little", bfd_arch_arm
,
693 thumb_jtab
, sizeof (thumb_jtab
), 12,
694 0, 0, 0, 0, 0, false, 0
697 #define MARM_INTERWORK 3
699 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
700 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
701 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
702 "pe-arm-little", bfd_arch_arm
,
703 arm_interwork_jtab
, sizeof (arm_interwork_jtab
), 12,
704 0, 0, 0, 0, 0, false, 0
709 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
710 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
711 ".global", ".space", ".align\t2",".align\t4", "",
712 "pe-mcore-big", bfd_arch_mcore
,
713 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8,
714 0, 0, 0, 0, 0, false, 0
719 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
720 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
721 ".global", ".space", ".align\t2",".align\t4", "-EL",
722 "pe-mcore-little", bfd_arch_mcore
,
723 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8,
724 0, 0, 0, 0, 0, false, 0
729 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
730 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
731 ".global", ".space", ".align\t2",".align\t4", "",
732 "elf32-mcore-big", bfd_arch_mcore
,
733 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8,
734 0, 0, 0, 0, 0, false, 0
738 #define MMCORE_ELF_LE 7
739 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
740 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
741 ".global", ".space", ".align\t2",".align\t4", "-EL",
742 "elf32-mcore-little", bfd_arch_mcore
,
743 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8,
744 0, 0, 0, 0, 0, false, 0
749 "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
750 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
751 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
752 "pe-arm-wince-little", bfd_arch_arm
,
753 arm_jtab
, sizeof (arm_jtab
), 8,
754 0, 0, 0, 0, 0, false, 0
759 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
760 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
761 "pe-x86-64",bfd_arch_i386
,
762 i386_jtab
, sizeof (i386_jtab
), 2,
763 i386_x64_dljtab
, sizeof (i386_x64_dljtab
), 2, 9, 14, true, i386_x64_trampoline
768 "arm64", ".byte", ".short", ".long", ".asciz", "//",
769 "bl ", ".global", ".space", ".balign\t2", ".balign\t4", "",
770 "pe-aarch64-little", bfd_arch_aarch64
,
771 aarch64_jtab
, sizeof (aarch64_jtab
), 0,
772 0, 0, 0, 0, 0, false, 0
775 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
785 typedef struct export
788 const char *internal_name
;
789 const char *import_name
;
790 const char *its_name
;
793 int noname
; /* Don't put name in image file. */
794 int private; /* Don't put reference in import lib. */
797 int forward
; /* Number of forward label, 0 means no forward. */
802 /* A list of symbols which we should not export. */
806 struct string_list
*next
;
810 static struct string_list
*excludes
;
812 static const char *rvaafter (int);
813 static const char *rvabefore (int);
814 static const char *asm_prefix (int, const char *);
815 static void process_def_file (const char *);
816 static void new_directive (char *);
817 static void append_import (const char *, const char *, int, const char *);
818 static void run (const char *, char *);
819 static void scan_drectve_symbols (bfd
*);
820 static void scan_filtered_symbols (bfd
*, void *, long, unsigned int);
821 static void add_excludes (const char *);
822 static bool match_exclude (const char *);
823 static void set_default_excludes (void);
824 static long filter_symbols (bfd
*, void *, long, unsigned int);
825 static void scan_all_symbols (bfd
*);
826 static void scan_open_obj_file (bfd
*);
827 static void scan_obj_file (const char *);
828 static void dump_def_info (FILE *);
829 static int sfunc (const void *, const void *);
830 static void flush_page (FILE *, bfd_vma
*, bfd_vma
, int);
831 static void gen_def_file (void);
832 static void generate_idata_ofile (FILE *);
833 static void assemble_file (const char *, const char *);
834 static void gen_exp_file (void);
835 static const char *xlate (const char *);
836 static char *make_label (const char *, const char *);
837 static char *make_imp_label (const char *, const char *);
838 static bfd
*make_one_lib_file (export_type
*, int, int);
839 static bfd
*make_head (void);
840 static bfd
*make_tail (void);
841 static bfd
*make_delay_head (void);
842 static void gen_lib_file (int);
843 static void dll_name_list_append (dll_name_list_type
*, bfd_byte
*);
844 static int dll_name_list_count (dll_name_list_type
*);
845 static void dll_name_list_print (dll_name_list_type
*);
846 static void dll_name_list_free_contents (dll_name_list_node_type
*);
847 static void dll_name_list_free (dll_name_list_type
*);
848 static dll_name_list_type
* dll_name_list_create (void);
849 static void identify_dll_for_implib (void);
850 static void identify_search_archive
851 (bfd
*, void (*) (bfd
*, bfd
*, void *), void *);
852 static void identify_search_member (bfd
*, bfd
*, void *);
853 static bool identify_process_section_p (asection
*, bool);
854 static void identify_search_section (bfd
*, asection
*, void *);
855 static void identify_member_contains_symname (bfd
*, bfd
*, void *);
857 static int pfunc (const void *, const void *);
858 static int nfunc (const void *, const void *);
859 static void remove_null_names (export_type
**);
860 static void process_duplicates (export_type
**);
861 static void fill_ordinals (export_type
**);
862 static void mangle_defs (void);
863 static void usage (FILE *, int);
864 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1
;
865 static void set_dll_name_from_def (const char *name
, char is_dll
);
868 prefix_encode (char *start
, unsigned code
)
870 static char alpha
[26] = "abcdefghijklmnopqrstuvwxyz";
874 p
= strchr (buf
, '\0');
876 *p
++ = alpha
[code
% sizeof (alpha
)];
877 while ((code
/= sizeof (alpha
)) != 0);
883 dlltmp (char **buf
, const char *fmt
)
887 *buf
= xmalloc (strlen (tmp_prefix
) + 64);
888 sprintf (*buf
, fmt
, tmp_prefix
);
894 inform (const char * message
, ...)
898 va_start (args
, message
);
903 report (message
, args
);
926 /* xgettext:c-format */
927 fatal (_("Internal error: Unknown machine type: %d"), mach
);
951 /* xgettext:c-format */
952 fatal (_("Internal error: Unknown machine type: %d"), mach
);
959 asm_prefix (int mach
, const char *name
)
975 /* Symbol names starting with ? do not have a leading underscore. */
976 if ((name
&& *name
== '?') || leading_underscore
== 0)
981 /* xgettext:c-format */
982 fatal (_("Internal error: Unknown machine type: %d"), mach
);
988 #define ASM_BYTE mtable[machine].how_byte
989 #define ASM_SHORT mtable[machine].how_short
990 #define ASM_LONG mtable[machine].how_long
991 #define ASM_TEXT mtable[machine].how_asciz
992 #define ASM_C mtable[machine].how_comment
993 #define ASM_JUMP mtable[machine].how_jump
994 #define ASM_GLOBAL mtable[machine].how_global
995 #define ASM_SPACE mtable[machine].how_space
996 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
997 #define ASM_RVA_BEFORE rvabefore (machine)
998 #define ASM_RVA_AFTER rvaafter (machine)
999 #define ASM_PREFIX(NAME) asm_prefix (machine, (NAME))
1000 #define ASM_ALIGN_LONG mtable[machine].how_align_long
1001 #define HOW_BFD_READ_TARGET 0 /* Always default. */
1002 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
1003 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
1004 #define HOW_JTAB (delay ? mtable[machine].how_dljtab \
1005 : mtable[machine].how_jtab)
1006 #define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \
1007 : mtable[machine].how_jtab_size)
1008 #define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \
1009 : mtable[machine].how_jtab_roff)
1010 #define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
1011 #define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
1012 #define ASM_SWITCHES mtable[machine].how_default_as_switches
1013 #define HOW_SEH mtable[machine].how_seh
1018 process_def_file (const char *name
)
1020 FILE *f
= fopen (name
, FOPEN_RT
);
1023 /* xgettext:c-format */
1024 fatal (_("Can't open def file: %s"), name
);
1028 /* xgettext:c-format */
1029 inform (_("Processing def file: %s"), name
);
1033 inform (_("Processed def file"));
1036 /**********************************************************************/
1038 /* Communications with the parser. */
1040 static int d_nfuncs
; /* Number of functions exported. */
1041 static int d_named_nfuncs
; /* Number of named functions exported. */
1042 static int d_low_ord
; /* Lowest ordinal index. */
1043 static int d_high_ord
; /* Highest ordinal index. */
1044 static export_type
*d_exports
; /* List of exported functions. */
1045 static export_type
**d_exports_lexically
; /* Vector of exported functions in alpha order. */
1046 static dlist_type
*d_list
; /* Descriptions. */
1047 static dlist_type
*a_list
; /* Stuff to go in directives. */
1048 static int d_nforwards
= 0; /* Number of forwarded exports. */
1050 static int d_is_dll
;
1051 static int d_is_exe
;
1054 yyerror (const char * err ATTRIBUTE_UNUSED
)
1056 /* xgettext:c-format */
1057 non_fatal (_("Syntax error in def file %s:%d"), def_file
, linenumber
);
1061 def_exports (const char *name
, const char *internal_name
, int ordinal
,
1062 int noname
, int constant
, int data
, int private,
1063 const char *its_name
)
1065 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
1068 p
->internal_name
= internal_name
? internal_name
: name
;
1069 p
->its_name
= its_name
;
1070 p
->import_name
= name
;
1071 p
->ordinal
= ordinal
;
1072 p
->constant
= constant
;
1074 p
->private = private;
1076 p
->next
= d_exports
;
1080 if ((internal_name
!= NULL
)
1081 && (strchr (internal_name
, '.') != NULL
))
1082 p
->forward
= ++d_nforwards
;
1084 p
->forward
= 0; /* no forward */
1088 set_dll_name_from_def (const char *name
, char is_dll
)
1090 const char *image_basename
= lbasename (name
);
1091 if (image_basename
!= name
)
1092 non_fatal (_("%s: Path components stripped from image name, '%s'."),
1094 /* Append the default suffix, if none specified. */
1095 if (strchr (image_basename
, '.') == 0)
1097 const char * suffix
= is_dll
? ".dll" : ".exe";
1099 dll_name
= xmalloc (strlen (image_basename
) + strlen (suffix
) + 1);
1100 sprintf (dll_name
, "%s%s", image_basename
, suffix
);
1103 dll_name
= xstrdup (image_basename
);
1107 def_name (const char *name
, int base
)
1109 /* xgettext:c-format */
1110 inform (_("NAME: %s base: %x"), name
, base
);
1113 non_fatal (_("Can't have LIBRARY and NAME"));
1115 if (dll_name_set_by_exp_name
&& name
&& *name
!= 0)
1118 dll_name_set_by_exp_name
= 0;
1120 /* If --dllname not provided, use the one in the DEF file.
1121 FIXME: Is this appropriate for executables? */
1123 set_dll_name_from_def (name
, 0);
1128 def_library (const char *name
, int base
)
1130 /* xgettext:c-format */
1131 inform (_("LIBRARY: %s base: %x"), name
, base
);
1134 non_fatal (_("Can't have LIBRARY and NAME"));
1136 if (dll_name_set_by_exp_name
&& name
&& *name
!= 0)
1139 dll_name_set_by_exp_name
= 0;
1142 /* If --dllname not provided, use the one in the DEF file. */
1144 set_dll_name_from_def (name
, 1);
1149 def_description (const char *desc
)
1151 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
1152 d
->text
= xstrdup (desc
);
1158 new_directive (char *dir
)
1160 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
1161 d
->text
= xstrdup (dir
);
1167 def_heapsize (int reserve
, int commit
)
1171 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
1173 sprintf (b
, "-heap 0x%x ", reserve
);
1174 new_directive (xstrdup (b
));
1178 def_stacksize (int reserve
, int commit
)
1182 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
1184 sprintf (b
, "-stack 0x%x ", reserve
);
1185 new_directive (xstrdup (b
));
1188 /* append_import simply adds the given import definition to the global
1189 import_list. It is used by def_import. */
1192 append_import (const char *symbol_name
, const char *dllname
, int func_ordinal
,
1193 const char *its_name
)
1198 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
1200 if (strcmp ((*pq
)->dllname
, dllname
) == 0)
1203 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
1204 q
->functail
= q
->functail
->next
;
1205 q
->functail
->ord
= func_ordinal
;
1206 q
->functail
->name
= xstrdup (symbol_name
);
1207 q
->functail
->its_name
= (its_name
? xstrdup (its_name
) : NULL
);
1208 q
->functail
->next
= NULL
;
1214 q
= xmalloc (sizeof (iheadtype
));
1215 q
->dllname
= xstrdup (dllname
);
1217 q
->funchead
= xmalloc (sizeof (ifunctype
));
1218 q
->functail
= q
->funchead
;
1220 q
->functail
->name
= xstrdup (symbol_name
);
1221 q
->functail
->its_name
= (its_name
? xstrdup (its_name
) : NULL
);
1222 q
->functail
->ord
= func_ordinal
;
1223 q
->functail
->next
= NULL
;
1228 /* def_import is called from within defparse.y when an IMPORT
1229 declaration is encountered. Depending on the form of the
1230 declaration, the module name may or may not need ".dll" to be
1231 appended to it, the name of the function may be stored in internal
1232 or entry, and there may or may not be an ordinal value associated
1235 /* A note regarding the parse modes:
1236 In defparse.y we have to accept import declarations which follow
1237 any one of the following forms:
1238 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1239 <func_name_in_app> = <dll_name>.<number>
1240 <dll_name>.<func_name_in_dll>
1242 Furthermore, the dll's name may or may not end with ".dll", which
1243 complicates the parsing a little. Normally the dll's name is
1244 passed to def_import() in the "module" parameter, but when it ends
1245 with ".dll" it gets passed in "module" sans ".dll" and that needs
1248 def_import gets five parameters:
1249 APP_NAME - the name of the function in the application, if
1250 present, or NULL if not present.
1251 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1252 DLLEXT - the extension of the dll, if present, NULL if not present.
1253 ENTRY - the name of the function in the dll, if present, or NULL.
1254 ORD_VAL - the numerical tag of the function in the dll, if present,
1255 or NULL. Exactly one of <entry> or <ord_val> must be
1256 present (i.e., not NULL). */
1259 def_import (const char *app_name
, const char *module
, const char *dllext
,
1260 const char *entry
, int ord_val
, const char *its_name
)
1262 const char *application_name
;
1266 application_name
= entry
;
1269 if (app_name
!= NULL
)
1270 application_name
= app_name
;
1272 application_name
= "";
1276 module
= buf
= concat (module
, ".", dllext
, NULL
);
1278 append_import (application_name
, module
, ord_val
, its_name
);
1284 def_version (int major
, int minor
)
1286 printf (_("VERSION %d.%d\n"), major
, minor
);
1290 def_section (const char *name
, int attr
)
1305 sprintf (buf
, "-attr %s %s", name
, atts
);
1306 new_directive (xstrdup (buf
));
1313 def_section ("CODE", attr
);
1319 def_section ("DATA", attr
);
1322 /**********************************************************************/
1325 run (const char *what
, char *args
)
1328 int pid
, wait_status
;
1331 char *errmsg_fmt
= NULL
, *errmsg_arg
= NULL
;
1332 char *temp_base
= make_temp_file ("");
1334 inform (_("run: %s %s"), what
, args
);
1336 /* Count the args */
1338 for (s
= args
; *s
; s
++)
1342 argv
= xmalloc (sizeof (char *) * (i
+ 3));
1351 while (*s
!= ' ' && *s
!= 0)
1359 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1360 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1365 inform ("%s", strerror (errno
));
1367 fatal (errmsg_fmt
, errmsg_arg
);
1370 pid
= pwait (pid
, & wait_status
, 0);
1374 /* xgettext:c-format */
1375 fatal (_("wait: %s"), strerror (errno
));
1377 else if (WIFSIGNALED (wait_status
))
1379 /* xgettext:c-format */
1380 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1382 else if (WIFEXITED (wait_status
))
1384 if (WEXITSTATUS (wait_status
) != 0)
1385 /* xgettext:c-format */
1386 non_fatal (_("%s exited with status %d"),
1387 what
, WEXITSTATUS (wait_status
));
1393 /* Look for a list of symbols to export in the .drectve section of
1394 ABFD. Pass each one to def_exports. */
1397 scan_drectve_symbols (bfd
*abfd
)
1405 /* Look for .drectve's */
1406 s
= bfd_get_section_by_name (abfd
, DRECTVE_SECTION_NAME
);
1411 size
= bfd_section_size (s
);
1412 buf
= xmalloc (size
);
1414 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1416 /* xgettext:c-format */
1417 inform (_("Sucking in info from %s section in %s"),
1418 DRECTVE_SECTION_NAME
, bfd_get_filename (abfd
));
1420 /* Search for -export: strings. The exported symbols can optionally
1421 have type tags (eg., -export:foo,data), so handle those as well.
1422 Currently only data tag is supported. */
1428 && startswith (p
, "-export:"))
1432 flagword flags
= BSF_FUNCTION
;
1435 /* Do we have a quoted export? */
1440 while (p
< e
&& *p
!= '"')
1446 while (p
< e
&& *p
!= ',' && *p
!= ' ' && *p
!= '-')
1449 c
= xmalloc (p
- name
+ 1);
1450 memcpy (c
, name
, p
- name
);
1452 /* Advance over trailing quote. */
1453 if (p
< e
&& *p
== '"')
1455 if (p
< e
&& *p
== ',') /* found type tag. */
1457 char *tag_start
= ++p
;
1458 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1460 if (startswith (tag_start
, "data"))
1461 flags
&= ~BSF_FUNCTION
;
1464 /* FIXME: The 5th arg is for the `constant' field.
1465 What should it be? Not that it matters since it's not
1466 currently useful. */
1467 def_exports (c
, 0, -1, 0, 0, ! (flags
& BSF_FUNCTION
), 0, NULL
);
1469 if (add_stdcall_alias
&& strchr (c
, '@'))
1471 int lead_at
= (*c
== '@') ;
1472 char *exported_name
= xstrdup (c
+ lead_at
);
1473 char *atsym
= strchr (exported_name
, '@');
1475 /* Note: stdcall alias symbols can never be data. */
1476 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0, 0, NULL
);
1485 /* Look through the symbols in MINISYMS, and add each one to list of
1486 symbols to export. */
1489 scan_filtered_symbols (bfd
*abfd
, void *minisyms
, long symcount
,
1493 bfd_byte
*from
, *fromend
;
1495 store
= bfd_make_empty_symbol (abfd
);
1497 bfd_fatal (bfd_get_filename (abfd
));
1499 from
= (bfd_byte
*) minisyms
;
1500 fromend
= from
+ symcount
* size
;
1501 for (; from
< fromend
; from
+= size
)
1504 const char *symbol_name
;
1506 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1508 bfd_fatal (bfd_get_filename (abfd
));
1510 symbol_name
= bfd_asymbol_name (sym
);
1512 && *symbol_name
== bfd_get_symbol_leading_char (abfd
))
1515 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0,
1516 ! (sym
->flags
& BSF_FUNCTION
), 0, NULL
);
1518 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1520 int lead_at
= (*symbol_name
== '@');
1521 char *exported_name
= xstrdup (symbol_name
+ lead_at
);
1522 char *atsym
= strchr (exported_name
, '@');
1524 /* Note: stdcall alias symbols can never be data. */
1525 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0, 0, NULL
);
1530 /* Add a list of symbols to exclude. */
1533 add_excludes (const char *new_excludes
)
1536 char *exclude_string
;
1538 local_copy
= xstrdup (new_excludes
);
1540 exclude_string
= strtok (local_copy
, ",:");
1541 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1543 struct string_list
*new_exclude
;
1545 new_exclude
= ((struct string_list
*)
1546 xmalloc (sizeof (struct string_list
)));
1547 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1548 /* Don't add a leading underscore for fastcall symbols. */
1549 if (*exclude_string
== '@')
1550 sprintf (new_exclude
->string
, "%s", exclude_string
);
1552 sprintf (new_exclude
->string
, "%s%s", (!leading_underscore
? "" : "_"),
1554 new_exclude
->next
= excludes
;
1555 excludes
= new_exclude
;
1557 /* xgettext:c-format */
1558 inform (_("Excluding symbol: %s"), exclude_string
);
1564 /* See if STRING is on the list of symbols to exclude. */
1567 match_exclude (const char *string
)
1569 struct string_list
*excl_item
;
1571 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1572 if (strcmp (string
, excl_item
->string
) == 0)
1577 /* Add the default list of symbols to exclude. */
1580 set_default_excludes (void)
1582 add_excludes (default_excludes
);
1585 /* Choose which symbols to export. */
1588 filter_symbols (bfd
*abfd
, void *minisyms
, long symcount
, unsigned int size
)
1590 bfd_byte
*from
, *fromend
, *to
;
1593 store
= bfd_make_empty_symbol (abfd
);
1595 bfd_fatal (bfd_get_filename (abfd
));
1597 from
= (bfd_byte
*) minisyms
;
1598 fromend
= from
+ symcount
* size
;
1599 to
= (bfd_byte
*) minisyms
;
1601 for (; from
< fromend
; from
+= size
)
1606 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const void *) from
, store
);
1608 bfd_fatal (bfd_get_filename (abfd
));
1610 /* Check for external and defined only symbols. */
1611 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1612 || (sym
->flags
& BSF_WEAK
) != 0
1613 || bfd_is_com_section (sym
->section
))
1614 && ! bfd_is_und_section (sym
->section
));
1616 keep
= keep
&& ! match_exclude (sym
->name
);
1620 memcpy (to
, from
, size
);
1625 return (to
- (bfd_byte
*) minisyms
) / size
;
1628 /* Export all symbols in ABFD, except for ones we were told not to
1632 scan_all_symbols (bfd
*abfd
)
1638 /* Ignore bfds with an import descriptor table. We assume that any
1639 such BFD contains symbols which are exported from another DLL,
1640 and we don't want to reexport them from here. */
1641 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1644 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1646 /* xgettext:c-format */
1647 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1651 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1653 bfd_fatal (bfd_get_filename (abfd
));
1657 /* xgettext:c-format */
1658 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1662 /* Discard the symbols we don't want to export. It's OK to do this
1663 in place; we'll free the storage anyway. */
1665 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1666 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1671 /* Look at the object file to decide which symbols to export. */
1674 scan_open_obj_file (bfd
*abfd
)
1676 if (export_all_symbols
)
1677 scan_all_symbols (abfd
);
1679 scan_drectve_symbols (abfd
);
1681 /* FIXME: we ought to read in and block out the base relocations. */
1683 /* xgettext:c-format */
1684 inform (_("Done reading %s"), bfd_get_filename (abfd
));
1688 scan_obj_file (const char *filename
)
1690 bfd
* f
= bfd_openr (filename
, 0);
1693 /* xgettext:c-format */
1694 fatal (_("Unable to open object file: %s: %s"), filename
, bfd_get_errmsg ());
1696 /* xgettext:c-format */
1697 inform (_("Scanning object file %s"), filename
);
1699 if (bfd_check_format (f
, bfd_archive
))
1701 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1705 if (bfd_check_format (arfile
, bfd_object
))
1706 scan_open_obj_file (arfile
);
1707 next
= bfd_openr_next_archived_file (f
, arfile
);
1709 /* PR 17512: file: 58715298. */
1715 #ifdef DLLTOOL_MCORE_ELF
1716 if (mcore_elf_out_file
)
1717 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename
);
1720 else if (bfd_check_format (f
, bfd_object
))
1722 scan_open_obj_file (f
);
1724 #ifdef DLLTOOL_MCORE_ELF
1725 if (mcore_elf_out_file
)
1726 mcore_elf_cache_filename (filename
);
1736 dump_def_info (FILE *f
)
1740 fprintf (f
, "%s ", ASM_C
);
1741 for (i
= 0; oav
[i
]; i
++)
1742 fprintf (f
, "%s ", oav
[i
]);
1744 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1746 fprintf (f
, "%s %d = %s %s @ %d %s%s%s%s%s%s\n",
1752 exp
->noname
? "NONAME " : "",
1753 exp
->private ? "PRIVATE " : "",
1754 exp
->constant
? "CONSTANT" : "",
1755 exp
->data
? "DATA" : "",
1756 exp
->its_name
? " ==" : "",
1757 exp
->its_name
? exp
->its_name
: "");
1761 /* Generate the .exp file. */
1764 sfunc (const void *a
, const void *b
)
1766 if (*(const bfd_vma
*) a
== *(const bfd_vma
*) b
)
1769 return ((*(const bfd_vma
*) a
> *(const bfd_vma
*) b
) ? 1 : -1);
1773 flush_page (FILE *f
, bfd_vma
*need
, bfd_vma page_addr
, int on_page
)
1777 /* Flush this page. */
1778 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1782 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1784 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1787 for (i
= 0; i
< on_page
; i
++)
1789 bfd_vma needed
= need
[i
];
1793 if (!create_for_pep
)
1795 /* Relocation via HIGHLOW. */
1796 needed
= ((needed
- page_addr
) | 0x3000) & 0xffff;
1800 /* Relocation via DIR64. */
1801 needed
= ((needed
- page_addr
) | 0xa000) & 0xffff;
1805 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (long) needed
);
1810 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1819 inform (_("Adding exports to output file"));
1821 fprintf (output_def
, ";");
1822 for (i
= 0; oav
[i
]; i
++)
1823 fprintf (output_def
, " %s", oav
[i
]);
1825 fprintf (output_def
, "\nEXPORTS\n");
1827 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1829 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1830 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1834 fprintf (output_def
,";\t%s\n", res
);
1838 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1840 fprintf (output_def
, "\t%s%s%s @ %d%s%s%s%s%s\n",
1845 exp
->noname
? " NONAME" : "",
1846 exp
->private ? "PRIVATE " : "",
1847 exp
->data
? " DATA" : "",
1848 exp
->its_name
? " ==" : "",
1849 exp
->its_name
? exp
->its_name
: "");
1853 char * quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1855 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1863 exp
->noname
? " NONAME" : "",
1864 exp
->private ? "PRIVATE " : "",
1865 exp
->data
? " DATA" : "",
1866 exp
->its_name
? " ==" : "",
1867 exp
->its_name
? exp
->its_name
: "");
1871 inform (_("Added exports to output file"));
1874 /* generate_idata_ofile generates the portable assembly source code
1875 for the idata sections. It appends the source code to the end of
1879 generate_idata_ofile (FILE *filvar
)
1887 if (import_list
== NULL
)
1890 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1891 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1892 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1893 fprintf (filvar
, "doi_idata:\n");
1896 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1898 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1899 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1900 ASM_C
, headptr
->dllname
);
1901 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1902 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1903 fprintf (filvar
, "\t%sdllname%d%s\n",
1904 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1905 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1906 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1910 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1911 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1912 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1913 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1914 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1916 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1918 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1920 fprintf (filvar
, "listone%d:\n", headindex
);
1921 for (funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++)
1924 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1925 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
,
1928 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1929 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1932 fprintf (filvar
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
1934 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
1938 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1940 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1942 fprintf (filvar
, "listtwo%d:\n", headindex
);
1943 for (funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++)
1946 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1947 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
,
1950 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1951 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1954 fprintf (filvar
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
1956 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
1960 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1962 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1965 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1966 funcptr
= funcptr
->next
)
1968 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1969 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1970 ((funcptr
->ord
) & 0xFFFF));
1971 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
,
1972 (funcptr
->its_name
? funcptr
->its_name
: funcptr
->name
));
1973 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1979 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1981 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1983 fprintf (filvar
,"dllname%d:\n", headindex
);
1984 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1985 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1990 /* Assemble the specified file. */
1992 assemble_file (const char * source
, const char * dest
)
1996 cmd
= xmalloc (strlen (ASM_SWITCHES
) + strlen (as_flags
)
1997 + strlen (source
) + strlen (dest
) + 50);
1999 sprintf (cmd
, "%s %s -o %s %s", ASM_SWITCHES
, as_flags
, dest
, source
);
2005 static const char * temp_file_to_remove
[5];
2006 #define TEMP_EXPORT_FILE 0
2007 #define TEMP_HEAD_FILE 1
2008 #define TEMP_TAIL_FILE 2
2009 #define TEMP_HEAD_O_FILE 3
2010 #define TEMP_TAIL_O_FILE 4
2013 unlink_temp_files (void)
2017 if (dontdeltemps
> 0)
2020 for (i
= 0; i
< ARRAY_SIZE (temp_file_to_remove
); i
++)
2022 if (temp_file_to_remove
[i
])
2024 unlink (temp_file_to_remove
[i
]);
2025 temp_file_to_remove
[i
] = NULL
;
2038 /* xgettext:c-format */
2039 inform (_("Generating export file: %s"), exp_name
);
2041 f
= fopen (TMP_ASM
, FOPEN_WT
);
2043 /* xgettext:c-format */
2044 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
2046 temp_file_to_remove
[TEMP_EXPORT_FILE
] = TMP_ASM
;
2048 /* xgettext:c-format */
2049 inform (_("Opened temporary file: %s"), TMP_ASM
);
2055 fprintf (f
, "\t.section .edata\n\n");
2056 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
2057 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
,
2058 (unsigned long) time(0), ASM_C
);
2059 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
2060 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2061 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
2064 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
2065 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
2067 d_named_nfuncs
, d_low_ord
, d_high_ord
);
2068 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
2069 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
2070 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2072 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
2073 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2075 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2077 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
2080 fprintf(f
,"%s Export address Table\n", ASM_C
);
2081 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
2082 fprintf (f
, "afuncs:\n");
2085 for (exp
= d_exports
; exp
; exp
= exp
->next
)
2087 if (exp
->ordinal
!= i
)
2089 while (i
< exp
->ordinal
)
2091 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
2096 if (exp
->forward
== 0)
2098 if (exp
->internal_name
[0] == '@')
2099 fprintf (f
, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
2100 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2102 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
2103 ASM_PREFIX (exp
->internal_name
),
2104 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2107 fprintf (f
, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE
,
2108 exp
->forward
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2112 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
2113 fprintf (f
, "anames:\n");
2115 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2117 if (!exp
->noname
|| show_allnames
)
2118 fprintf (f
, "\t%sn%d%s\n",
2119 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
2122 fprintf (f
,"%s Export Ordinal Table\n", ASM_C
);
2123 fprintf (f
, "anords:\n");
2124 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2126 if (!exp
->noname
|| show_allnames
)
2127 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
2130 fprintf(f
,"%s Export Name Table\n", ASM_C
);
2131 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2133 if (!exp
->noname
|| show_allnames
)
2134 fprintf (f
, "n%d: %s \"%s\"\n",
2135 exp
->ordinal
, ASM_TEXT
,
2136 (exp
->its_name
? exp
->its_name
: xlate (exp
->name
)));
2137 if (exp
->forward
!= 0)
2138 fprintf (f
, "f%d: %s \"%s\"\n",
2139 exp
->forward
, ASM_TEXT
, exp
->internal_name
);
2144 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
2145 for (dl
= a_list
; dl
; dl
= dl
->next
)
2147 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
2153 fprintf (f
, "\t.section .rdata\n");
2154 for (dl
= d_list
; dl
; dl
= dl
->next
)
2159 /* We don't output as ascii because there can
2160 be quote characters in the string. */
2162 for (p
= dl
->text
; *p
; p
++)
2165 fprintf (f
, "\t%s\t", ASM_BYTE
);
2168 fprintf (f
, "%d", *p
);
2171 fprintf (f
, ",0\n");
2184 /* Add to the output file a way of getting to the exported names
2185 without using the import library. */
2188 fprintf (f
, "\t.section\t.rdata\n");
2189 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2190 if (!exp
->noname
|| show_allnames
)
2192 /* We use a single underscore for MS compatibility, and a
2193 double underscore for backward compatibility with old
2195 if (create_compat_implib
)
2196 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2197 fprintf (f
, "\t%s\t_imp_%s%s\n", ASM_GLOBAL
,
2198 (!leading_underscore
? "" : "_"), exp
->name
);
2199 if (create_compat_implib
)
2200 fprintf (f
, "__imp_%s:\n", exp
->name
);
2201 fprintf (f
, "_imp_%s%s:\n", (!leading_underscore
? "" : "_"), exp
->name
);
2202 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
2206 /* Dump the reloc section if a base file is provided. */
2210 bfd_vma need
[COFF_PAGE_SIZE
];
2212 bfd_size_type numbytes
;
2217 fprintf (f
, "\t.section\t.init\n");
2218 fprintf (f
, "lab:\n");
2220 fseek (base_file
, 0, SEEK_END
);
2221 numbytes
= ftell (base_file
);
2222 fseek (base_file
, 0, SEEK_SET
);
2223 copy
= xmalloc (numbytes
);
2224 if (fread (copy
, 1, numbytes
, base_file
) < numbytes
)
2225 fatal (_("failed to read the number of entries from base file"));
2226 num_entries
= numbytes
/ sizeof (bfd_vma
);
2229 fprintf (f
, "\t.section\t.reloc\n");
2234 bfd_vma last
= (bfd_vma
) -1;
2235 qsort (copy
, num_entries
, sizeof (bfd_vma
), sfunc
);
2236 /* Delete duplicates */
2237 for (src
= 0; src
< num_entries
; src
++)
2239 if (last
!= copy
[src
])
2240 last
= copy
[dst
++] = copy
[src
];
2244 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
2246 for (j
= 0; j
< num_entries
; j
++)
2249 if ((addr
& PAGE_MASK
) != page_addr
)
2251 flush_page (f
, need
, page_addr
, on_page
);
2253 page_addr
= addr
& PAGE_MASK
;
2255 need
[on_page
++] = addr
;
2257 flush_page (f
, need
, page_addr
, on_page
);
2259 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2263 generate_idata_ofile (f
);
2267 /* Assemble the file. */
2268 assemble_file (TMP_ASM
, exp_name
);
2270 if (dontdeltemps
== 0)
2272 temp_file_to_remove
[TEMP_EXPORT_FILE
] = NULL
;
2276 inform (_("Generated exports file"));
2280 xlate (const char *name
)
2282 int lead_at
= (*name
== '@');
2283 int is_stdcall
= (!lead_at
&& strchr (name
, '@') != NULL
);
2285 if (!lead_at
&& (add_underscore
2286 || (add_stdcall_underscore
&& is_stdcall
)))
2288 char *copy
= xmalloc (strlen (name
) + 2);
2291 strcpy (copy
+ 1, name
);
2300 /* PR 9766: Look for the last @ sign in the name. */
2301 p
= strrchr (name
, '@');
2302 if (p
&& ISDIGIT (p
[1]))
2318 unsigned char *data
;
2321 #define INIT_SEC_DATA(id, name, flags, align) \
2322 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2334 #define TEXT_SEC_FLAGS \
2335 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2336 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2337 #define BSS_SEC_FLAGS SEC_ALLOC
2339 static sinfo secdata
[NSECS
] =
2341 INIT_SEC_DATA (TEXT
, ".text", TEXT_SEC_FLAGS
, 2),
2342 INIT_SEC_DATA (DATA
, ".data", DATA_SEC_FLAGS
, 2),
2343 INIT_SEC_DATA (BSS
, ".bss", BSS_SEC_FLAGS
, 2),
2344 INIT_SEC_DATA (IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2),
2345 INIT_SEC_DATA (IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2),
2346 INIT_SEC_DATA (IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2),
2347 INIT_SEC_DATA (IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1)
2350 /* This is what we're trying to make. We generate the imp symbols with
2351 both single and double underscores, for compatibility.
2354 .global _GetFileVersionInfoSizeW@8
2355 .global __imp_GetFileVersionInfoSizeW@8
2356 _GetFileVersionInfoSizeW@8:
2357 jmp * __imp_GetFileVersionInfoSizeW@8
2358 .section .idata$7 # To force loading of head
2359 .long __version_a_head
2360 # Import Address Table
2362 __imp_GetFileVersionInfoSizeW@8:
2365 # Import Lookup Table
2371 .asciz "GetFileVersionInfoSizeW" */
2374 make_label (const char *prefix
, const char *name
)
2376 int len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2377 char *copy
= xmalloc (len
+ 1);
2379 strcpy (copy
, ASM_PREFIX (name
));
2380 strcat (copy
, prefix
);
2381 strcat (copy
, name
);
2386 make_imp_label (const char *prefix
, const char *name
)
2393 len
= strlen (prefix
) + strlen (name
);
2394 copy
= xmalloc (len
+ 1);
2395 strcpy (copy
, prefix
);
2396 strcat (copy
, name
);
2400 len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2401 copy
= xmalloc (len
+ 1);
2402 strcpy (copy
, prefix
);
2403 strcat (copy
, ASM_PREFIX (name
));
2404 strcat (copy
, name
);
2410 make_one_lib_file (export_type
*exp
, int i
, int delay
)
2413 asymbol
* exp_label
;
2414 asymbol
* iname
= 0;
2416 asymbol
* iname_lab
;
2417 asymbol
** iname_lab_pp
;
2418 asymbol
** iname_pp
;
2422 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2423 flagword applicable
;
2424 char * outname
= xmalloc (strlen (TMP_STUB
) + 10);
2428 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2430 abfd
= bfd_openw (outname
, HOW_BFD_WRITE_TARGET
);
2433 /* xgettext:c-format */
2434 fatal (_("bfd_open failed open stub file: %s: %s"),
2435 outname
, bfd_get_errmsg ());
2437 /* xgettext:c-format */
2438 inform (_("Creating stub file: %s"), outname
);
2440 bfd_set_format (abfd
, bfd_object
);
2441 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2444 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2445 bfd_set_private_flags (abfd
, F_INTERWORK
);
2448 applicable
= bfd_applicable_section_flags (abfd
);
2450 /* First make symbols for the sections. */
2451 for (i
= 0; i
< NSECS
; i
++)
2453 sinfo
*si
= secdata
+ i
;
2457 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2458 bfd_set_section_flags (si
->sec
, si
->flags
& applicable
);
2460 bfd_set_section_alignment (si
->sec
, si
->align
);
2461 si
->sec
->output_section
= si
->sec
;
2462 si
->sym
= bfd_make_empty_symbol(abfd
);
2463 si
->sym
->name
= si
->sec
->name
;
2464 si
->sym
->section
= si
->sec
;
2465 si
->sym
->flags
= BSF_LOCAL
;
2467 ptrs
[oidx
] = si
->sym
;
2468 si
->sympp
= ptrs
+ oidx
;
2477 exp_label
= bfd_make_empty_symbol (abfd
);
2478 exp_label
->name
= make_imp_label ("", exp
->name
);
2479 exp_label
->section
= secdata
[TEXT
].sec
;
2480 exp_label
->flags
= BSF_GLOBAL
;
2481 exp_label
->value
= 0;
2484 if (machine
== MTHUMB
)
2485 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2487 ptrs
[oidx
++] = exp_label
;
2490 /* Generate imp symbols with one underscore for Microsoft
2491 compatibility, and with two underscores for backward
2492 compatibility with old versions of cygwin. */
2493 if (create_compat_implib
)
2495 iname
= bfd_make_empty_symbol (abfd
);
2496 iname
->name
= make_imp_label ("___imp", exp
->name
);
2497 iname
->section
= secdata
[IDATA5
].sec
;
2498 iname
->flags
= BSF_GLOBAL
;
2502 iname2
= bfd_make_empty_symbol (abfd
);
2503 iname2
->name
= make_imp_label ("__imp_", exp
->name
);
2504 iname2
->section
= secdata
[IDATA5
].sec
;
2505 iname2
->flags
= BSF_GLOBAL
;
2508 iname_lab
= bfd_make_empty_symbol (abfd
);
2510 iname_lab
->name
= head_label
;
2511 iname_lab
->section
= bfd_und_section_ptr
;
2512 iname_lab
->flags
= 0;
2513 iname_lab
->value
= 0;
2515 iname_pp
= ptrs
+ oidx
;
2516 if (create_compat_implib
)
2517 ptrs
[oidx
++] = iname
;
2518 ptrs
[oidx
++] = iname2
;
2520 iname_lab_pp
= ptrs
+ oidx
;
2521 ptrs
[oidx
++] = iname_lab
;
2525 for (i
= 0; i
< NSECS
; i
++)
2527 sinfo
*si
= secdata
+ i
;
2528 asection
*sec
= si
->sec
;
2529 arelent
*rel
, *rel2
= 0, *rel3
= 0;
2537 unsigned int rpp_len
;
2539 si
->size
= HOW_JTAB_SIZE
;
2540 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2541 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2543 /* Add the reloc into idata$5. */
2544 rel
= xmalloc (sizeof (arelent
));
2546 rpp_len
= delay
? 4 : 2;
2548 if (machine
== MAARCH64
)
2551 rpp
= xmalloc (sizeof (arelent
*) * rpp_len
);
2555 rel
->address
= HOW_JTAB_ROFF
;
2560 rel2
= xmalloc (sizeof (arelent
));
2562 rel2
->address
= HOW_JTAB_ROFF2
;
2564 rel3
= xmalloc (sizeof (arelent
));
2566 rel3
->address
= HOW_JTAB_ROFF3
;
2571 if (machine
== MX86
)
2573 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2574 BFD_RELOC_32_PCREL
);
2575 rel
->sym_ptr_ptr
= iname_pp
;
2577 else if (machine
== MAARCH64
)
2581 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
);
2582 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2584 rel_add
= xmalloc (sizeof (arelent
));
2585 rel_add
->address
= 4;
2586 rel_add
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_AARCH64_ADD_LO12
);
2587 rel_add
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2588 rel_add
->addend
= 0;
2590 rpp
[rpp_len
- 2] = rel_add
;
2591 rpp
[rpp_len
- 1] = 0;
2595 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2596 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2601 if (machine
== MX86
)
2602 rel2
->howto
= bfd_reloc_type_lookup (abfd
,
2603 BFD_RELOC_32_PCREL
);
2605 rel2
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2606 rel2
->sym_ptr_ptr
= rel
->sym_ptr_ptr
;
2607 rel3
->howto
= bfd_reloc_type_lookup (abfd
,
2608 BFD_RELOC_32_PCREL
);
2609 rel3
->sym_ptr_ptr
= iname_lab_pp
;
2612 sec
->orelocation
= rpp
;
2613 sec
->reloc_count
= rpp_len
- 1;
2620 si
->size
= create_for_pep
? 8 : 4;
2621 si
->data
= xmalloc (si
->size
);
2622 sec
->reloc_count
= 1;
2623 memset (si
->data
, 0, si
->size
);
2624 /* Point after jmp [__imp_...] instruction. */
2626 rel
= xmalloc (sizeof (arelent
));
2627 rpp
= xmalloc (sizeof (arelent
*) * 2);
2633 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_64
);
2635 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2636 rel
->sym_ptr_ptr
= secdata
[TEXT
].sympp
;
2637 sec
->orelocation
= rpp
;
2643 /* An idata$4 or idata$5 is one word long, and has an
2648 si
->data
= xmalloc (8);
2652 si
->data
[0] = exp
->ordinal
;
2653 si
->data
[1] = exp
->ordinal
>> 8;
2654 si
->data
[2] = exp
->ordinal
>> 16;
2655 si
->data
[3] = exp
->ordinal
>> 24;
2663 sec
->reloc_count
= 1;
2664 memset (si
->data
, 0, si
->size
);
2665 rel
= xmalloc (sizeof (arelent
));
2666 rpp
= xmalloc (sizeof (arelent
*) * 2);
2671 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2672 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2673 sec
->orelocation
= rpp
;
2678 si
->data
= xmalloc (4);
2683 si
->data
[0] = exp
->ordinal
;
2684 si
->data
[1] = exp
->ordinal
>> 8;
2685 si
->data
[2] = exp
->ordinal
>> 16;
2690 sec
->reloc_count
= 1;
2691 memset (si
->data
, 0, si
->size
);
2692 rel
= xmalloc (sizeof (arelent
));
2693 rpp
= xmalloc (sizeof (arelent
*) * 2);
2698 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2699 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2700 sec
->orelocation
= rpp
;
2708 /* This used to add 1 to exp->hint. I don't know
2709 why it did that, and it does not match what I see
2710 in programs compiled with the MS tools. */
2711 int idx
= exp
->hint
;
2713 si
->size
= strlen (exp
->its_name
) + 3;
2715 si
->size
= strlen (xlate (exp
->import_name
)) + 3;
2716 si
->data
= xmalloc (si
->size
);
2717 memset (si
->data
, 0, si
->size
);
2718 si
->data
[0] = idx
& 0xff;
2719 si
->data
[1] = idx
>> 8;
2721 strcpy ((char *) si
->data
+ 2, exp
->its_name
);
2723 strcpy ((char *) si
->data
+ 2, xlate (exp
->import_name
));
2730 si
->data
= xmalloc (4);
2731 memset (si
->data
, 0, si
->size
);
2732 rel
= xmalloc (sizeof (arelent
));
2733 rpp
= xmalloc (sizeof (arelent
*) * 2);
2737 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2738 rel
->sym_ptr_ptr
= iname_lab_pp
;
2739 sec
->orelocation
= rpp
;
2740 sec
->reloc_count
= 1;
2747 /* Size up all the sections. */
2748 for (i
= 0; i
< NSECS
; i
++)
2750 sinfo
*si
= secdata
+ i
;
2752 bfd_set_section_size (si
->sec
, si
->size
);
2753 bfd_set_section_vma (si
->sec
, vma
);
2756 /* Write them out. */
2757 for (i
= 0; i
< NSECS
; i
++)
2759 sinfo
*si
= secdata
+ i
;
2761 if (i
== IDATA5
&& no_idata5
)
2764 if (i
== IDATA4
&& no_idata4
)
2767 bfd_set_section_contents (abfd
, si
->sec
,
2772 bfd_set_symtab (abfd
, ptrs
, oidx
);
2774 abfd
= bfd_openr (outname
, HOW_BFD_READ_TARGET
);
2776 /* xgettext:c-format */
2777 fatal (_("bfd_open failed reopen stub file: %s: %s"),
2778 outname
, bfd_get_errmsg ());
2786 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2791 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2795 temp_file_to_remove
[TEMP_HEAD_FILE
] = TMP_HEAD_S
;
2797 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2798 fprintf (f
, "\t.section\t.idata$2\n");
2800 fprintf (f
,"\t%s\t%s\n", ASM_GLOBAL
, head_label
);
2802 fprintf (f
, "%s:\n", head_label
);
2804 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2805 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2807 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2808 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2809 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2810 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2811 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2816 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2818 ASM_RVA_AFTER
, ASM_C
);
2820 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2824 fprintf (f
, "\t.section\t.idata$5\n");
2825 if (use_nul_prefixed_import_tables
)
2828 fprintf (f
,"\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2830 fprintf (f
,"\t%s\t0\n", ASM_LONG
);
2832 fprintf (f
, "fthunk:\n");
2837 fprintf (f
, "\t.section\t.idata$4\n");
2838 if (use_nul_prefixed_import_tables
)
2841 fprintf (f
,"\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2843 fprintf (f
,"\t%s\t0\n", ASM_LONG
);
2845 fprintf (f
, "hname:\n");
2850 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2852 abfd
= bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2854 /* xgettext:c-format */
2855 fatal (_("failed to open temporary head file: %s: %s"),
2856 TMP_HEAD_O
, bfd_get_errmsg ());
2858 temp_file_to_remove
[TEMP_HEAD_O_FILE
] = TMP_HEAD_O
;
2863 make_delay_head (void)
2865 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2870 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2874 temp_file_to_remove
[TEMP_HEAD_FILE
] = TMP_HEAD_S
;
2876 /* Output the __tailMerge__xxx function */
2877 fprintf (f
, "%s Import trampoline\n", ASM_C
);
2878 fprintf (f
, "\t.section\t.text\n");
2879 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
, head_label
);
2881 fprintf (f
, "\t.seh_proc\t%s\n", head_label
);
2882 fprintf (f
, "%s:\n", head_label
);
2883 fprintf (f
, mtable
[machine
].trampoline
, imp_name_lab
);
2885 fprintf (f
, "\t.seh_endproc\n");
2887 /* Output the delay import descriptor */
2888 fprintf (f
, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C
);
2889 fprintf (f
, ".section\t.text$2\n");
2890 fprintf (f
,"%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL
,imp_name_lab
);
2891 fprintf (f
, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab
);
2892 fprintf (f
, "\t%s 1\t%s grAttrs\n", ASM_LONG
, ASM_C
);
2893 fprintf (f
, "\t%s__%s_iname%s\t%s rvaDLLName\n",
2894 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2895 fprintf (f
, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
2896 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2897 fprintf (f
, "\t%s__IAT_%s%s\t%s rvaIAT\n",
2898 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2899 fprintf (f
, "\t%s__INT_%s%s\t%s rvaINT\n",
2900 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2901 fprintf (f
, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG
, ASM_C
);
2902 fprintf (f
, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG
, ASM_C
);
2903 fprintf (f
, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG
, ASM_C
);
2905 /* Output the dll_handle */
2906 fprintf (f
, "\n.section .data\n");
2907 fprintf (f
, "__DLL_HANDLE_%s:\n", imp_name_lab
);
2908 fprintf (f
, "\t%s\t0\t%s Handle\n", ASM_LONG
, ASM_C
);
2910 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2913 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2917 fprintf (f
, "\t.section\t.idata$5\n");
2918 /* NULL terminating list. */
2920 fprintf (f
,"\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2922 fprintf (f
,"\t%s\t0\n", ASM_LONG
);
2923 fprintf (f
, "__IAT_%s:\n", imp_name_lab
);
2928 fprintf (f
, "\t.section\t.idata$4\n");
2929 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2931 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2932 fprintf (f
, "\t.section\t.idata$4\n");
2933 fprintf (f
, "__INT_%s:\n", imp_name_lab
);
2936 fprintf (f
, "\t.section\t.idata$2\n");
2940 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2942 abfd
= bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2944 /* xgettext:c-format */
2945 fatal (_("failed to open temporary head file: %s: %s"),
2946 TMP_HEAD_O
, bfd_get_errmsg ());
2948 temp_file_to_remove
[TEMP_HEAD_O_FILE
] = TMP_HEAD_O
;
2955 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2960 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2964 temp_file_to_remove
[TEMP_TAIL_FILE
] = TMP_TAIL_S
;
2968 fprintf (f
, "\t.section\t.idata$4\n");
2970 fprintf (f
,"\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2972 fprintf (f
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
2977 fprintf (f
, "\t.section\t.idata$5\n");
2979 fprintf (f
,"\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2981 fprintf (f
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
2984 fprintf (f
, "\t.section\t.idata$7\n");
2985 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2986 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2987 imp_name_lab
, ASM_TEXT
, dll_name
);
2991 assemble_file (TMP_TAIL_S
, TMP_TAIL_O
);
2993 abfd
= bfd_openr (TMP_TAIL_O
, HOW_BFD_READ_TARGET
);
2995 /* xgettext:c-format */
2996 fatal (_("failed to open temporary tail file: %s: %s"),
2997 TMP_TAIL_O
, bfd_get_errmsg ());
2999 temp_file_to_remove
[TEMP_TAIL_O_FILE
] = TMP_TAIL_O
;
3004 gen_lib_file (int delay
)
3015 outarch
= bfd_openw (imp_name
, HOW_BFD_WRITE_TARGET
);
3018 /* xgettext:c-format */
3019 fatal (_("Can't create .lib file: %s: %s"),
3020 imp_name
, bfd_get_errmsg ());
3022 /* xgettext:c-format */
3023 inform (_("Creating library file: %s"), imp_name
);
3025 xatexit (unlink_temp_files
);
3027 bfd_set_format (outarch
, bfd_archive
);
3028 outarch
->has_armap
= 1;
3029 outarch
->is_thin_archive
= 0;
3032 outarch
->flags
|= BFD_DETERMINISTIC_OUTPUT
;
3034 /* Work out a reasonable size of things to put onto one line. */
3037 ar_head
= make_delay_head ();
3041 ar_head
= make_head ();
3043 ar_tail
= make_tail();
3045 if (ar_head
== NULL
|| ar_tail
== NULL
)
3048 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
3051 /* Don't add PRIVATE entries to import lib. */
3054 n
= make_one_lib_file (exp
, i
, delay
);
3055 n
->archive_next
= head
;
3057 if (ext_prefix_alias
)
3059 export_type alias_exp
;
3061 assert (i
< PREFIX_ALIAS_BASE
);
3062 alias_exp
.name
= make_imp_label (ext_prefix_alias
, exp
->name
);
3063 alias_exp
.internal_name
= exp
->internal_name
;
3064 alias_exp
.its_name
= exp
->its_name
;
3065 alias_exp
.import_name
= exp
->name
;
3066 alias_exp
.ordinal
= exp
->ordinal
;
3067 alias_exp
.constant
= exp
->constant
;
3068 alias_exp
.noname
= exp
->noname
;
3069 alias_exp
.private = exp
->private;
3070 alias_exp
.data
= exp
->data
;
3071 alias_exp
.hint
= exp
->hint
;
3072 alias_exp
.forward
= exp
->forward
;
3073 alias_exp
.next
= exp
->next
;
3074 n
= make_one_lib_file (&alias_exp
, i
+ PREFIX_ALIAS_BASE
, delay
);
3075 n
->archive_next
= head
;
3080 /* Now stick them all into the archive. */
3081 ar_head
->archive_next
= head
;
3082 ar_tail
->archive_next
= ar_head
;
3085 if (! bfd_set_archive_head (outarch
, head
))
3086 bfd_fatal ("bfd_set_archive_head");
3088 if (! bfd_close (outarch
))
3089 bfd_fatal (imp_name
);
3091 while (head
!= NULL
)
3093 bfd
*n
= head
->archive_next
;
3098 /* Delete all the temp files. */
3099 unlink_temp_files ();
3101 if (dontdeltemps
< 2)
3104 size_t stub_len
= strlen (TMP_STUB
);
3106 name
= xmalloc (stub_len
+ 10);
3107 memcpy (name
, TMP_STUB
, stub_len
);
3108 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
3110 /* Don't delete non-existent stubs for PRIVATE entries. */
3113 sprintf (name
+ stub_len
, "%05d.o", i
);
3114 if (unlink (name
) < 0)
3115 /* xgettext:c-format */
3116 non_fatal (_("cannot delete %s: %s"), name
, strerror (errno
));
3117 if (ext_prefix_alias
)
3119 sprintf (name
+ stub_len
, "%05d.o", i
+ PREFIX_ALIAS_BASE
);
3120 if (unlink (name
) < 0)
3121 /* xgettext:c-format */
3122 non_fatal (_("cannot delete %s: %s"), name
, strerror (errno
));
3128 inform (_("Created lib file"));
3131 /* Append a copy of data (cast to char *) to list. */
3134 dll_name_list_append (dll_name_list_type
* list
, bfd_byte
* data
)
3136 dll_name_list_node_type
* entry
;
3138 /* Error checking. */
3139 if (! list
|| ! list
->tail
)
3142 /* Allocate new node. */
3143 entry
= ((dll_name_list_node_type
*)
3144 xmalloc (sizeof (dll_name_list_node_type
)));
3146 /* Initialize its values. */
3147 entry
->dllname
= xstrdup ((char *) data
);
3150 /* Add to tail, and move tail. */
3151 list
->tail
->next
= entry
;
3155 /* Count the number of entries in list. */
3158 dll_name_list_count (dll_name_list_type
* list
)
3160 dll_name_list_node_type
* p
;
3163 /* Error checking. */
3164 if (! list
|| ! list
->head
)
3169 while (p
&& p
->next
)
3177 /* Print each entry in list to stdout. */
3180 dll_name_list_print (dll_name_list_type
* list
)
3182 dll_name_list_node_type
* p
;
3184 /* Error checking. */
3185 if (! list
|| ! list
->head
)
3190 while (p
&& p
->next
&& p
->next
->dllname
&& *(p
->next
->dllname
))
3192 printf ("%s\n", p
->next
->dllname
);
3197 /* Free all entries in list, and list itself. */
3200 dll_name_list_free (dll_name_list_type
* list
)
3204 dll_name_list_free_contents (list
->head
);
3211 /* Recursive function to free all nodes entry->next->next...
3212 as well as entry itself. */
3215 dll_name_list_free_contents (dll_name_list_node_type
* entry
)
3220 dll_name_list_free_contents (entry
->next
);
3221 free (entry
->dllname
);
3226 /* Allocate and initialize a dll_name_list_type object,
3227 including its sentinel node. Caller is responsible
3228 for calling dll_name_list_free when finished with
3231 static dll_name_list_type
*
3232 dll_name_list_create (void)
3234 /* Allocate list. */
3235 dll_name_list_type
* list
= xmalloc (sizeof (dll_name_list_type
));
3237 /* Allocate and initialize sentinel node. */
3238 list
->head
= xmalloc (sizeof (dll_name_list_node_type
));
3239 list
->head
->dllname
= NULL
;
3240 list
->head
->next
= NULL
;
3242 /* Bookkeeping for empty list. */
3243 list
->tail
= list
->head
;
3248 /* Search the symbol table of the suppled BFD for a symbol whose name matches
3249 OBJ (where obj is cast to const char *). If found, set global variable
3250 identify_member_contains_symname_result TRUE. It is the caller's
3251 responsibility to set the result variable FALSE before iterating with
3255 identify_member_contains_symname (bfd
* abfd
,
3256 bfd
* archive_bfd ATTRIBUTE_UNUSED
,
3259 long storage_needed
;
3260 asymbol
** symbol_table
;
3261 long number_of_symbols
;
3263 symname_search_data_type
* search_data
= (symname_search_data_type
*) obj
;
3265 /* If we already found the symbol in a different member,
3267 if (search_data
->found
)
3270 storage_needed
= bfd_get_symtab_upper_bound (abfd
);
3271 if (storage_needed
<= 0)
3274 symbol_table
= xmalloc (storage_needed
);
3275 number_of_symbols
= bfd_canonicalize_symtab (abfd
, symbol_table
);
3276 if (number_of_symbols
< 0)
3278 free (symbol_table
);
3282 for (i
= 0; i
< number_of_symbols
; i
++)
3284 if (strncmp (symbol_table
[i
]->name
,
3285 search_data
->symname
,
3286 strlen (search_data
->symname
)) == 0)
3288 search_data
->found
= true;
3292 free (symbol_table
);
3295 /* This is the main implementation for the --identify option.
3296 Given the name of an import library in identify_imp_name, first
3297 determine if the import library is a GNU binutils-style one (where
3298 the DLL name is stored in an .idata$7 section), or if it is a
3299 MS-style one (where the DLL name, along with much other data, is
3300 stored in the .idata$6 section). We determine the style of import
3301 library by searching for the DLL-structure symbol inserted by MS
3302 tools: __NULL_IMPORT_DESCRIPTOR.
3304 Once we know which section to search, evaluate each section for the
3305 appropriate properties that indicate it may contain the name of the
3306 associated DLL (this differs depending on the style). Add the contents
3307 of all sections which meet the criteria to a linked list of dll names.
3309 Finally, print them all to stdout. (If --identify-strict, an error is
3310 reported if more than one match was found). */
3313 identify_dll_for_implib (void)
3317 identify_data_type identify_data
;
3318 symname_search_data_type search_data
;
3320 /* Initialize identify_data. */
3321 identify_data
.list
= dll_name_list_create ();
3322 identify_data
.ms_style_implib
= false;
3324 /* Initialize search_data. */
3325 search_data
.symname
= "__NULL_IMPORT_DESCRIPTOR";
3326 search_data
.found
= false;
3328 if (bfd_init () != BFD_INIT_MAGIC
)
3329 fatal (_("fatal error: libbfd ABI mismatch"));
3331 abfd
= bfd_openr (identify_imp_name
, 0);
3333 /* xgettext:c-format */
3334 fatal (_("Can't open .lib file: %s: %s"),
3335 identify_imp_name
, bfd_get_errmsg ());
3337 if (! bfd_check_format (abfd
, bfd_archive
))
3339 if (! bfd_close (abfd
))
3340 bfd_fatal (identify_imp_name
);
3342 fatal (_("%s is not a library"), identify_imp_name
);
3345 /* Detect if this a Microsoft import library. */
3346 identify_search_archive (abfd
,
3347 identify_member_contains_symname
,
3348 (void *)(& search_data
));
3349 if (search_data
.found
)
3350 identify_data
.ms_style_implib
= true;
3352 /* Rewind the bfd. */
3353 if (! bfd_close (abfd
))
3354 bfd_fatal (identify_imp_name
);
3355 abfd
= bfd_openr (identify_imp_name
, 0);
3357 bfd_fatal (identify_imp_name
);
3359 if (!bfd_check_format (abfd
, bfd_archive
))
3361 if (!bfd_close (abfd
))
3362 bfd_fatal (identify_imp_name
);
3364 fatal (_("%s is not a library"), identify_imp_name
);
3367 /* Now search for the dll name. */
3368 identify_search_archive (abfd
,
3369 identify_search_member
,
3370 (void *)(& identify_data
));
3372 if (! bfd_close (abfd
))
3373 bfd_fatal (identify_imp_name
);
3375 count
= dll_name_list_count (identify_data
.list
);
3378 if (identify_strict
&& count
> 1)
3380 dll_name_list_free (identify_data
.list
);
3381 identify_data
.list
= NULL
;
3382 fatal (_("Import library `%s' specifies two or more dlls"),
3385 dll_name_list_print (identify_data
.list
);
3386 dll_name_list_free (identify_data
.list
);
3387 identify_data
.list
= NULL
;
3391 dll_name_list_free (identify_data
.list
);
3392 identify_data
.list
= NULL
;
3393 fatal (_("Unable to determine dll name for `%s' (not an import library?)"),
3398 /* Loop over all members of the archive, applying the supplied function to
3399 each member that is a bfd_object. The function will be called as if:
3400 func (member_bfd, abfd, user_storage) */
3403 identify_search_archive (bfd
* abfd
,
3404 void (* operation
) (bfd
*, bfd
*, void *),
3405 void * user_storage
)
3407 bfd
* arfile
= NULL
;
3408 bfd
* last_arfile
= NULL
;
3413 arfile
= bfd_openr_next_archived_file (abfd
, arfile
);
3417 if (bfd_get_error () != bfd_error_no_more_archived_files
)
3418 bfd_fatal (bfd_get_filename (abfd
));
3422 if (bfd_check_format_matches (arfile
, bfd_object
, &matching
))
3423 (*operation
) (arfile
, abfd
, user_storage
);
3426 bfd_nonfatal (bfd_get_filename (arfile
));
3430 if (last_arfile
!= NULL
)
3432 bfd_close (last_arfile
);
3433 /* PR 17512: file: 8b2168d4. */
3434 if (last_arfile
== arfile
)
3441 last_arfile
= arfile
;
3444 if (last_arfile
!= NULL
)
3446 bfd_close (last_arfile
);
3450 /* Call the identify_search_section() function for each section of this
3454 identify_search_member (bfd
*abfd
,
3455 bfd
*archive_bfd ATTRIBUTE_UNUSED
,
3458 bfd_map_over_sections (abfd
, identify_search_section
, obj
);
3461 /* This predicate returns true if section->name matches the desired value.
3462 By default, this is .idata$7 (.idata$6 if the import library is
3466 identify_process_section_p (asection
* section
, bool ms_style_implib
)
3468 static const char * SECTION_NAME
= ".idata$7";
3469 static const char * MS_SECTION_NAME
= ".idata$6";
3471 const char * section_name
=
3472 (ms_style_implib
? MS_SECTION_NAME
: SECTION_NAME
);
3474 if (strcmp (section_name
, section
->name
) == 0)
3479 /* If *section has contents and its name is .idata$7 (.idata$6 if
3480 import lib ms-generated) -- and it satisfies several other constraints
3481 -- then add the contents of the section to obj->list. */
3484 identify_search_section (bfd
* abfd
, asection
* section
, void * obj
)
3487 bfd_size_type datasize
;
3488 identify_data_type
* identify_data
= (identify_data_type
*)obj
;
3489 bool ms_style
= identify_data
->ms_style_implib
;
3491 if ((section
->flags
& SEC_HAS_CONTENTS
) == 0)
3494 if (! identify_process_section_p (section
, ms_style
))
3497 /* Binutils import libs seem distinguish the .idata$7 section that contains
3498 the DLL name from other .idata$7 sections by the absence of the
3500 if (!ms_style
&& ((section
->flags
& SEC_RELOC
) == SEC_RELOC
))
3503 /* MS import libs seem to distinguish the .idata$6 section
3504 that contains the DLL name from other .idata$6 sections
3505 by the presence of the SEC_DATA flag. */
3506 if (ms_style
&& ((section
->flags
& SEC_DATA
) == 0))
3509 if ((datasize
= bfd_section_size (section
)) == 0)
3512 data
= (bfd_byte
*) xmalloc (datasize
+ 1);
3515 bfd_get_section_contents (abfd
, section
, data
, 0, datasize
);
3516 data
[datasize
] = '\0';
3518 /* Use a heuristic to determine if data is a dll name.
3519 Possible to defeat this if (a) the library has MANY
3520 (more than 0x302f) imports, (b) it is an ms-style
3521 import library, but (c) it is buggy, in that the SEC_DATA
3522 flag is set on the "wrong" sections. This heuristic might
3523 also fail to record a valid dll name if the dllname uses
3524 a multibyte or unicode character set (is that valid?).
3526 This heuristic is based on the fact that symbols names in
3527 the chosen section -- as opposed to the dll name -- begin
3528 at offset 2 in the data. The first two bytes are a 16bit
3529 little-endian count, and start at 0x0000. However, the dll
3530 name begins at offset 0 in the data. We assume that the
3531 dll name does not contain unprintable characters. */
3532 if (data
[0] != '\0' && ISPRINT (data
[0])
3533 && ((datasize
< 2) || ISPRINT (data
[1])))
3534 dll_name_list_append (identify_data
->list
, data
);
3539 /* Run through the information gathered from the .o files and the
3540 .def file and work out the best stuff. */
3543 pfunc (const void *a
, const void *b
)
3545 export_type
*ap
= *(export_type
**) a
;
3546 export_type
*bp
= *(export_type
**) b
;
3548 if (ap
->ordinal
== bp
->ordinal
)
3551 /* Unset ordinals go to the bottom. */
3552 if (ap
->ordinal
== -1)
3554 if (bp
->ordinal
== -1)
3556 return (ap
->ordinal
- bp
->ordinal
);
3560 nfunc (const void *a
, const void *b
)
3562 export_type
*ap
= *(export_type
**) a
;
3563 export_type
*bp
= *(export_type
**) b
;
3564 const char *an
= ap
->name
;
3565 const char *bn
= bp
->name
;
3572 an
= (an
[0] == '@') ? an
+ 1 : an
;
3573 bn
= (bn
[0] == '@') ? bn
+ 1 : bn
;
3576 return (strcmp (an
, bn
));
3580 remove_null_names (export_type
**ptr
)
3585 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
3589 ptr
[dst
] = ptr
[src
];
3597 process_duplicates (export_type
**d_export_vec
)
3605 /* Remove duplicates. */
3606 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
3608 for (i
= 0; i
< d_nfuncs
- 1; i
++)
3610 if (strcmp (d_export_vec
[i
]->name
,
3611 d_export_vec
[i
+ 1]->name
) == 0)
3613 export_type
*a
= d_export_vec
[i
];
3614 export_type
*b
= d_export_vec
[i
+ 1];
3618 /* xgettext:c-format */
3619 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3620 a
->name
, a
->ordinal
, b
->ordinal
);
3622 if (a
->ordinal
!= -1
3623 && b
->ordinal
!= -1)
3624 /* xgettext:c-format */
3625 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3628 /* Merge attributes. */
3629 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
3630 b
->constant
|= a
->constant
;
3631 b
->noname
|= a
->noname
;
3633 d_export_vec
[i
] = 0;
3636 remove_null_names (d_export_vec
);
3640 /* Count the names. */
3641 for (i
= 0; i
< d_nfuncs
; i
++)
3642 if (!d_export_vec
[i
]->noname
)
3647 fill_ordinals (export_type
**d_export_vec
)
3654 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3656 /* Fill in the unset ordinals with ones from our range. */
3657 ptr
= (char *) xmalloc (size
);
3659 memset (ptr
, 0, size
);
3661 /* Mark in our large vector all the numbers that are taken. */
3662 for (i
= 0; i
< d_nfuncs
; i
++)
3664 if (d_export_vec
[i
]->ordinal
!= -1)
3666 ptr
[d_export_vec
[i
]->ordinal
] = 1;
3668 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
3669 lowest
= d_export_vec
[i
]->ordinal
;
3673 /* Start at 1 for compatibility with MS toolchain. */
3677 /* Now fill in ordinals where the user wants us to choose. */
3678 for (i
= 0; i
< d_nfuncs
; i
++)
3680 if (d_export_vec
[i
]->ordinal
== -1)
3684 /* First try within or after any user supplied range. */
3685 for (j
= lowest
; j
< size
; j
++)
3689 d_export_vec
[i
]->ordinal
= j
;
3693 /* Then try before the range. */
3694 for (j
= lowest
; j
>0; j
--)
3698 d_export_vec
[i
]->ordinal
= j
;
3708 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3710 /* Work out the lowest and highest ordinal numbers. */
3713 if (d_export_vec
[0])
3714 d_low_ord
= d_export_vec
[0]->ordinal
;
3715 if (d_export_vec
[d_nfuncs
-1])
3716 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3723 /* First work out the minimum ordinal chosen. */
3728 export_type
**d_export_vec
= xmalloc (sizeof (export_type
*) * d_nfuncs
);
3730 inform (_("Processing definitions"));
3732 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3733 d_export_vec
[i
] = exp
;
3735 process_duplicates (d_export_vec
);
3736 fill_ordinals (d_export_vec
);
3738 /* Put back the list in the new order. */
3740 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3742 d_export_vec
[i
]->next
= d_exports
;
3743 d_exports
= d_export_vec
[i
];
3746 /* Build list in alpha order. */
3747 d_exports_lexically
= (export_type
**)
3748 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3750 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3751 d_exports_lexically
[i
] = exp
;
3753 d_exports_lexically
[i
] = 0;
3755 qsort (d_exports_lexically
, i
, sizeof (export_type
*), nfunc
);
3757 /* Fill exp entries with their hint values. */
3758 for (i
= 0; i
< d_nfuncs
; i
++)
3759 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3760 d_exports_lexically
[i
]->hint
= hint
++;
3762 inform (_("Processed definitions"));
3766 usage (FILE *file
, int status
)
3768 /* xgetext:c-format */
3769 fprintf (file
, _("Usage %s <option(s)> <object-file(s)>\n"), program_name
);
3770 /* xgetext:c-format */
3771 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3772 fprintf (file
, _(" possible <machine>: arm[_interwork], arm64, i386, mcore[-elf]{-le|-be}, thumb\n"));
3773 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3774 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3775 fprintf (file
, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
3776 fprintf (file
, _(" --deterministic-libraries\n"));
3777 if (DEFAULT_AR_DETERMINISTIC
)
3778 fprintf (file
, _(" Use zero for timestamps and uids/gids in output libraries (default)\n"));
3780 fprintf (file
, _(" Use zero for timestamps and uids/gids in output libraries\n"));
3781 fprintf (file
, _(" --non-deterministic-libraries\n"));
3782 if (DEFAULT_AR_DETERMINISTIC
)
3783 fprintf (file
, _(" Use actual timestamps and uids/gids in output libraries\n"));
3785 fprintf (file
, _(" Use actual timestamps and uids/gids in output libraries (default)\n"));
3786 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3787 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3788 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3789 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3790 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3791 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3792 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3793 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3794 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3795 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3796 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3797 fprintf (file
, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3798 fprintf (file
, _(" -U --add-underscore Add underscores to all symbols in interface library.\n"));
3799 fprintf (file
, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3800 fprintf (file
, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n"));
3801 fprintf (file
, _(" --leading-underscore All symbols should be prefixed by an underscore.\n"));
3802 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3803 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3804 fprintf (file
, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3805 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3806 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3807 fprintf (file
, _(" -C --compat-implib Create backward compatible import library.\n"));
3808 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3809 fprintf (file
, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3810 fprintf (file
, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
3811 fprintf (file
, _(" --identify-strict Causes --identify to report error when multiple DLLs.\n"));
3812 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3813 fprintf (file
, _(" -V --version Display the program version.\n"));
3814 fprintf (file
, _(" -h --help Display this information.\n"));
3815 fprintf (file
, _(" @<file> Read options from <file>.\n"));
3816 #ifdef DLLTOOL_MCORE_ELF
3817 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3818 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3819 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3821 if (REPORT_BUGS_TO
[0] && status
== 0)
3822 fprintf (file
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
3826 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
3827 enum command_line_switch
3829 OPTION_EXPORT_ALL_SYMS
= 150,
3830 OPTION_NO_EXPORT_ALL_SYMS
,
3831 OPTION_EXCLUDE_SYMS
,
3832 OPTION_NO_DEFAULT_EXCLUDES
,
3833 OPTION_ADD_STDCALL_UNDERSCORE
,
3834 OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
,
3835 OPTION_IDENTIFY_STRICT
,
3836 OPTION_NO_LEADING_UNDERSCORE
,
3837 OPTION_LEADING_UNDERSCORE
,
3838 OPTION_DETERMINISTIC_LIBRARIES
,
3839 OPTION_NON_DETERMINISTIC_LIBRARIES
3842 static const struct option long_options
[] =
3844 {"add-indirect", no_argument
, NULL
, 'a'},
3845 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3846 {"add-stdcall-underscore", no_argument
, NULL
, OPTION_ADD_STDCALL_UNDERSCORE
},
3847 {"add-underscore", no_argument
, NULL
, 'U'},
3848 {"as", required_argument
, NULL
, 'S'},
3849 {"as-flags", required_argument
, NULL
, 'f'},
3850 {"base-file", required_argument
, NULL
, 'b'},
3851 {"compat-implib", no_argument
, NULL
, 'C'},
3852 {"def", required_argument
, NULL
, 'd'}, /* For compatibility with older versions. */
3853 {"deterministic-libraries", no_argument
, NULL
, OPTION_DETERMINISTIC_LIBRARIES
},
3854 {"dllname", required_argument
, NULL
, 'D'},
3855 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3856 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3857 {"ext-prefix-alias", required_argument
, NULL
, 'p'},
3858 {"help", no_argument
, NULL
, 'h'},
3859 {"identify", required_argument
, NULL
, 'I'},
3860 {"identify-strict", no_argument
, NULL
, OPTION_IDENTIFY_STRICT
},
3861 {"input-def", required_argument
, NULL
, 'd'},
3862 {"kill-at", no_argument
, NULL
, 'k'},
3863 {"leading-underscore", no_argument
, NULL
, OPTION_LEADING_UNDERSCORE
},
3864 {"machine", required_argument
, NULL
, 'm'},
3865 {"mcore-elf", required_argument
, NULL
, 'M'},
3866 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3867 {"no-delete", no_argument
, NULL
, 'n'},
3868 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3869 {"no-idata4", no_argument
, NULL
, 'x'},
3870 {"no-idata5", no_argument
, NULL
, 'c'},
3871 {"no-leading-underscore", no_argument
, NULL
, OPTION_NO_LEADING_UNDERSCORE
},
3872 {"non-deterministic-libraries", no_argument
, NULL
, OPTION_NON_DETERMINISTIC_LIBRARIES
},
3873 {"output-def", required_argument
, NULL
, 'z'},
3874 {"output-delaylib", required_argument
, NULL
, 'y'},
3875 {"output-exp", required_argument
, NULL
, 'e'},
3876 {"output-lib", required_argument
, NULL
, 'l'},
3877 {"temp-prefix", required_argument
, NULL
, 't'},
3878 {"use-nul-prefixed-import-tables", no_argument
, NULL
, OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
},
3879 {"verbose", no_argument
, NULL
, 'v'},
3880 {"version", no_argument
, NULL
, 'V'},
3884 int main (int, char **);
3887 main (int ac
, char **av
)
3892 program_name
= av
[0];
3895 #ifdef HAVE_LC_MESSAGES
3896 setlocale (LC_MESSAGES
, "");
3898 setlocale (LC_CTYPE
, "");
3899 bindtextdomain (PACKAGE
, LOCALEDIR
);
3900 textdomain (PACKAGE
);
3902 bfd_set_error_program_name (program_name
);
3903 expandargv (&ac
, &av
);
3905 while ((c
= getopt_long (ac
, av
,
3906 #ifdef DLLTOOL_MCORE_ELF
3907 "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:",
3909 "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh",
3916 case OPTION_EXPORT_ALL_SYMS
:
3917 export_all_symbols
= true;
3919 case OPTION_NO_EXPORT_ALL_SYMS
:
3920 export_all_symbols
= false;
3922 case OPTION_EXCLUDE_SYMS
:
3923 add_excludes (optarg
);
3925 case OPTION_NO_DEFAULT_EXCLUDES
:
3926 do_default_excludes
= false;
3928 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
:
3929 use_nul_prefixed_import_tables
= true;
3931 case OPTION_ADD_STDCALL_UNDERSCORE
:
3932 add_stdcall_underscore
= 1;
3934 case OPTION_NO_LEADING_UNDERSCORE
:
3935 leading_underscore
= 0;
3937 case OPTION_LEADING_UNDERSCORE
:
3938 leading_underscore
= 1;
3940 case OPTION_IDENTIFY_STRICT
:
3941 identify_strict
= 1;
3953 tmp_prefix
= optarg
;
3959 /* Ignored for compatibility. */
3966 output_def
= fopen (optarg
, FOPEN_WT
);
3968 /* xgettext:c-format */
3969 fatal (_("Unable to open def-file: %s"), optarg
);
3972 dll_name
= (char*) lbasename (optarg
);
3973 if (dll_name
!= optarg
)
3974 non_fatal (_("Path components stripped from dllname, '%s'."),
3991 identify_imp_name
= optarg
;
3997 print_version (program_name
);
4006 add_stdcall_alias
= 1;
4009 ext_prefix_alias
= optarg
;
4018 base_file
= fopen (optarg
, FOPEN_RB
);
4021 /* xgettext:c-format */
4022 fatal (_("Unable to open base-file: %s"), optarg
);
4025 #ifdef DLLTOOL_MCORE_ELF
4027 mcore_elf_out_file
= optarg
;
4030 mcore_elf_linker
= optarg
;
4033 mcore_elf_linker_flags
= optarg
;
4037 create_compat_implib
= 1;
4040 delayimp_name
= optarg
;
4042 case OPTION_DETERMINISTIC_LIBRARIES
:
4043 deterministic
= true;
4045 case OPTION_NON_DETERMINISTIC_LIBRARIES
:
4046 deterministic
= false;
4054 for (i
= 0; mtable
[i
].type
; i
++)
4055 if (strcmp (mtable
[i
].type
, mname
) == 0)
4058 if (!mtable
[i
].type
)
4059 /* xgettext:c-format */
4060 fatal (_("Machine '%s' not supported"), mname
);
4064 /* Check if we generated PE+. */
4065 create_for_pep
= strcmp (mname
, "i386:x86-64") == 0 ||
4066 strcmp (mname
, "arm64") == 0;
4069 /* Check the default underscore */
4070 int u
= leading_underscore
; /* Underscoring mode. -1 for use default. */
4072 bfd_get_target_info (mtable
[machine
].how_bfd_target
, NULL
,
4075 leading_underscore
= u
!= 0;
4078 if (!dll_name
&& exp_name
)
4080 /* If we are inferring dll_name from exp_name,
4081 strip off any path components, without emitting
4083 const char* exp_basename
= lbasename (exp_name
);
4084 const int len
= strlen (exp_basename
) + 5;
4085 dll_name
= xmalloc (len
);
4086 strcpy (dll_name
, exp_basename
);
4087 strcat (dll_name
, ".dll");
4088 dll_name_set_by_exp_name
= 1;
4091 if (as_name
== NULL
)
4092 as_name
= deduce_name ("as");
4094 /* Don't use the default exclude list if we're reading only the
4095 symbols in the .drectve section. The default excludes are meant
4096 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
4097 if (! export_all_symbols
)
4098 do_default_excludes
= false;
4100 if (do_default_excludes
)
4101 set_default_excludes ();
4104 process_def_file (def_file
);
4109 firstarg
= av
[optind
];
4110 scan_obj_file (av
[optind
]);
4114 if (tmp_prefix
== NULL
)
4116 /* If possible use a deterministic prefix. */
4117 if (imp_name
|| delayimp_name
)
4119 const char *input
= imp_name
? imp_name
: delayimp_name
;
4120 tmp_prefix
= xmalloc (strlen (input
) + 2);
4121 sprintf (tmp_prefix
, "%s_", input
);
4122 for (i
= 0; tmp_prefix
[i
]; i
++)
4123 if (!ISALNUM (tmp_prefix
[i
]))
4124 tmp_prefix
[i
] = '_';
4128 tmp_prefix
= prefix_encode ("d", getpid ());
4139 /* Make imp_name safe for use as a label. */
4142 imp_name_lab
= xstrdup (imp_name
);
4143 for (p
= imp_name_lab
; *p
; p
++)
4148 head_label
= make_label("_head_", imp_name_lab
);
4154 /* Make delayimp_name safe for use as a label. */
4157 if (mtable
[machine
].how_dljtab
== 0)
4159 inform (_("Warning, machine type (%d) not supported for "
4160 "delayimport."), machine
);
4165 imp_name
= delayimp_name
;
4166 imp_name_lab
= xstrdup (imp_name
);
4167 for (p
= imp_name_lab
; *p
; p
++)
4172 head_label
= make_label("__tailMerge_", imp_name_lab
);
4180 if (identify_imp_name
)
4182 identify_dll_for_implib ();
4185 #ifdef DLLTOOL_MCORE_ELF
4186 if (mcore_elf_out_file
)
4187 mcore_elf_gen_out_file ();
4193 /* Look for the program formed by concatenating PROG_NAME and the
4194 string running from PREFIX to END_PREFIX. If the concatenated
4195 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
4199 look_for_prog (const char *prog_name
, const char *prefix
, int end_prefix
)
4204 cmd
= xmalloc (strlen (prefix
)
4205 + strlen (prog_name
)
4206 #ifdef HAVE_EXECUTABLE_SUFFIX
4207 + strlen (EXECUTABLE_SUFFIX
)
4210 memcpy (cmd
, prefix
, end_prefix
);
4212 strcpy (cmd
+ end_prefix
, prog_name
);
4214 if (strchr (cmd
, '/') != NULL
)
4218 found
= (stat (cmd
, &s
) == 0
4219 #ifdef HAVE_EXECUTABLE_SUFFIX
4220 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
4226 /* xgettext:c-format */
4227 inform (_("Tried file: %s"), cmd
);
4233 /* xgettext:c-format */
4234 inform (_("Using file: %s"), cmd
);
4239 /* Deduce the name of the program we are want to invoke.
4240 PROG_NAME is the basic name of the program we want to run,
4241 eg "as" or "ld". The catch is that we might want actually
4244 If argv[0] contains the full path, then try to find the program
4245 in the same place, with and then without a target-like prefix.
4247 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
4248 deduce_name("as") uses the following search order:
4250 /usr/local/bin/i586-cygwin32-as
4254 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
4255 name, it'll try without and then with EXECUTABLE_SUFFIX.
4257 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
4258 as the fallback, but rather return i586-cygwin32-as.
4260 Oh, and given, argv[0] = dlltool, it'll return "as".
4262 Returns a dynamically allocated string. */
4265 deduce_name (const char *prog_name
)
4268 char *dash
, *slash
, *cp
;
4272 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
4277 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4278 *cp
== ':' || *cp
== '\\' ||
4291 /* First, try looking for a prefixed PROG_NAME in the
4292 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
4293 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
4296 if (slash
!= NULL
&& cmd
== NULL
)
4298 /* Next, try looking for a PROG_NAME in the same directory as
4299 that of this program. */
4300 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
4305 /* Just return PROG_NAME as is. */
4306 cmd
= xstrdup (prog_name
);
4312 #ifdef DLLTOOL_MCORE_ELF
4313 typedef struct fname_cache
4315 const char * filename
;
4316 struct fname_cache
* next
;
4320 static fname_cache fnames
;
4323 mcore_elf_cache_filename (const char * filename
)
4329 while (ptr
->next
!= NULL
)
4332 ptr
->filename
= filename
;
4333 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
4334 if (ptr
->next
!= NULL
)
4335 ptr
->next
->next
= NULL
;
4338 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
4339 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
4340 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
4343 mcore_elf_gen_out_file (void)
4348 /* Step one. Run 'ld -r' on the input object files in order to resolve
4349 any internal references and to generate a single .exports section. */
4352 ds
= dyn_string_new (100);
4353 dyn_string_append_cstr (ds
, "-r ");
4355 if (mcore_elf_linker_flags
!= NULL
)
4356 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
4358 while (ptr
->next
!= NULL
)
4360 dyn_string_append_cstr (ds
, ptr
->filename
);
4361 dyn_string_append_cstr (ds
, " ");
4366 dyn_string_append_cstr (ds
, "-o ");
4367 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4369 if (mcore_elf_linker
== NULL
)
4370 mcore_elf_linker
= deduce_name ("ld");
4372 run (mcore_elf_linker
, ds
->s
);
4374 dyn_string_delete (ds
);
4376 /* Step two. Create a .exp file and a .lib file from the temporary file.
4377 Do this by recursively invoking dlltool... */
4378 ds
= dyn_string_new (100);
4380 dyn_string_append_cstr (ds
, "-S ");
4381 dyn_string_append_cstr (ds
, as_name
);
4383 dyn_string_append_cstr (ds
, " -e ");
4384 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
4385 dyn_string_append_cstr (ds
, " -l ");
4386 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_LIB
);
4387 dyn_string_append_cstr (ds
, " " );
4388 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4391 dyn_string_append_cstr (ds
, " -v");
4395 dyn_string_append_cstr (ds
, " -n");
4397 if (dontdeltemps
> 1)
4398 dyn_string_append_cstr (ds
, " -n");
4401 /* XXX - FIME: ought to check/copy other command line options as well. */
4402 run (program_name
, ds
->s
);
4404 dyn_string_delete (ds
);
4406 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
4407 ds
= dyn_string_new (100);
4409 dyn_string_append_cstr (ds
, "-shared ");
4411 if (mcore_elf_linker_flags
)
4412 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
4414 dyn_string_append_cstr (ds
, " ");
4415 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
4416 dyn_string_append_cstr (ds
, " ");
4417 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4418 dyn_string_append_cstr (ds
, " -o ");
4419 dyn_string_append_cstr (ds
, mcore_elf_out_file
);
4421 run (mcore_elf_linker
, ds
->s
);
4423 dyn_string_delete (ds
);
4425 if (dontdeltemps
== 0)
4426 unlink (MCORE_ELF_TMP_EXP
);
4428 if (dontdeltemps
< 2)
4429 unlink (MCORE_ELF_TMP_OBJ
);
4431 #endif /* DLLTOOL_MCORE_ELF */