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))
278 #ifdef HAVE_SYS_WAIT_H
279 #include <sys/wait.h>
280 #else /* ! HAVE_SYS_WAIT_H */
281 #if ! defined (_WIN32) || defined (__CYGWIN32__)
283 #define WIFEXITED(w) (((w) & 0377) == 0)
286 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
289 #define WTERMSIG(w) ((w) & 0177)
292 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
294 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
296 #define WIFEXITED(w) (((w) & 0xff) == 0)
299 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
302 #define WTERMSIG(w) ((w) & 0x7f)
305 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
307 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308 #endif /* ! HAVE_SYS_WAIT_H */
310 #define show_allnames 0
312 /* ifunc and ihead data structures: ttk@cygnus.com 1997
314 When IMPORT declarations are encountered in a .def file the
315 function import information is stored in a structure referenced by
316 the global variable IMPORT_LIST. The structure is a linked list
317 containing the names of the dll files each function is imported
318 from and a linked list of functions being imported from that dll
319 file. This roughly parallels the structure of the .idata section
320 in the PE object file.
322 The contents of .def file are interpreted from within the
323 process_def_file function. Every time an IMPORT declaration is
324 encountered, it is broken up into its component parts and passed to
325 def_import. IMPORT_LIST is initialized to NULL in function main. */
327 typedef struct ifunct
329 char * name
; /* Name of function being imported. */
330 char * its_name
; /* Optional import table symbol name. */
331 int ord
; /* Two-byte ordinal value associated with function. */
335 typedef struct iheadt
337 char * dllname
; /* Name of dll file imported from. */
338 long nfuncs
; /* Number of functions in list. */
339 struct ifunct
*funchead
; /* First function in list. */
340 struct ifunct
*functail
; /* Last function in list. */
341 struct iheadt
*next
; /* Next dll file in list. */
344 /* Structure containing all import information as defined in .def file
345 (qv "ihead structure"). */
347 static iheadtype
*import_list
= NULL
;
348 static char *as_name
= NULL
;
349 static char * as_flags
= "";
350 static char *tmp_prefix
= NULL
;
351 static int no_idata4
;
352 static int no_idata5
;
353 static char *exp_name
;
354 static char *imp_name
;
355 static char *delayimp_name
;
356 static char *identify_imp_name
;
357 static bool identify_strict
;
358 static bool deterministic
= DEFAULT_AR_DETERMINISTIC
;
360 /* Types used to implement a linked list of dllnames associated
361 with the specified import lib. Used by the identify_* code.
362 The head entry is acts as a sentinal node and is always empty
363 (head->dllname is NULL). */
364 typedef struct dll_name_list_node_t
367 struct dll_name_list_node_t
* next
;
368 } dll_name_list_node_type
;
370 typedef struct dll_name_list_t
372 dll_name_list_node_type
* head
;
373 dll_name_list_node_type
* tail
;
374 } dll_name_list_type
;
376 /* Types used to pass data to iterator functions. */
377 typedef struct symname_search_data_t
381 } symname_search_data_type
;
383 typedef struct identify_data_t
385 dll_name_list_type
*list
;
386 bool ms_style_implib
;
387 } identify_data_type
;
390 static char *head_label
;
391 static char *imp_name_lab
;
392 static char *dll_name
;
393 static int dll_name_set_by_exp_name
;
394 static int add_indirect
= 0;
395 static int add_underscore
= 0;
396 static int add_stdcall_underscore
= 0;
397 static char *leading_underscore
= NULL
;
398 static int dontdeltemps
= 0;
400 /* TRUE if we should export all symbols. Otherwise, we only export
401 symbols listed in .drectve sections or in the def file. */
402 static bool export_all_symbols
;
404 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
405 exporting all symbols. */
406 static bool do_default_excludes
= true;
408 static bool use_nul_prefixed_import_tables
= false;
410 /* Default symbols to exclude when exporting all the symbols. */
411 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
413 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
414 compatibility to old Cygwin releases. */
415 static bool create_compat_implib
;
417 /* TRUE if we have to write PE+ import libraries. */
418 static bool create_for_pep
;
420 static char *def_file
;
422 extern char * program_name
;
426 static int add_stdcall_alias
;
427 static const char *ext_prefix_alias
;
429 static FILE *output_def
;
430 static FILE *base_file
;
432 #ifdef DLLTOOL_DEFAULT_ARM
433 static const char *mname
= "arm";
436 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
437 static const char *mname
= "arm-wince";
440 #ifdef DLLTOOL_DEFAULT_AARCH64
441 /* arm64 rather than aarch64 to match llvm-dlltool */
442 static const char *mname
= "arm64";
445 #ifdef DLLTOOL_DEFAULT_I386
446 static const char *mname
= "i386";
449 #ifdef DLLTOOL_DEFAULT_MX86_64
450 static const char *mname
= "i386:x86-64";
453 #ifdef DLLTOOL_DEFAULT_SH
454 static const char *mname
= "sh";
457 #ifdef DLLTOOL_DEFAULT_MIPS
458 static const char *mname
= "mips";
461 #ifdef DLLTOOL_DEFAULT_MCORE
462 static const char * mname
= "mcore-le";
465 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
466 static const char * mname
= "mcore-elf";
467 static char * mcore_elf_out_file
= NULL
;
468 static char * mcore_elf_linker
= NULL
;
469 static char * mcore_elf_linker_flags
= NULL
;
471 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
474 #ifndef DRECTVE_SECTION_NAME
475 #define DRECTVE_SECTION_NAME ".drectve"
478 /* External name alias numbering starts here. */
479 #define PREFIX_ALIAS_BASE 20000
481 static char *tmp_asm_buf
;
482 static char *tmp_head_s_buf
;
483 static char *tmp_head_o_buf
;
484 static char *tmp_tail_s_buf
;
485 static char *tmp_tail_o_buf
;
486 static char *tmp_stub_buf
;
488 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
489 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
490 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
491 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
492 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
493 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ssnnnnn.o")
495 /* This bit of assembly does jmp * .... */
496 static const unsigned char i386_jtab
[] =
498 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
501 static const unsigned char i386_dljtab
[] =
503 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
504 0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
505 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
508 static const unsigned char i386_x64_dljtab
[] =
510 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
511 0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */
512 0x00, 0x00, 0x00, 0x00,
513 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
516 static const unsigned char arm_jtab
[] =
518 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
519 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
523 static const unsigned char arm_interwork_jtab
[] =
525 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
526 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
527 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
531 static const unsigned char thumb_jtab
[] =
533 0x40, 0xb4, /* push {r6} */
534 0x02, 0x4e, /* ldr r6, [pc, #8] */
535 0x36, 0x68, /* ldr r6, [r6] */
536 0xb4, 0x46, /* mov ip, r6 */
537 0x40, 0xbc, /* pop {r6} */
538 0x60, 0x47, /* bx ip */
542 static const unsigned char mcore_be_jtab
[] =
544 0x71, 0x02, /* lrw r1,2 */
545 0x81, 0x01, /* ld.w r1,(r1,0) */
546 0x00, 0xC1, /* jmp r1 */
547 0x12, 0x00, /* nop */
548 0x00, 0x00, 0x00, 0x00 /* <address> */
551 static const unsigned char mcore_le_jtab
[] =
553 0x02, 0x71, /* lrw r1,2 */
554 0x01, 0x81, /* ld.w r1,(r1,0) */
555 0xC1, 0x00, /* jmp r1 */
556 0x00, 0x12, /* nop */
557 0x00, 0x00, 0x00, 0x00 /* <address> */
560 static const unsigned char aarch64_jtab
[] =
562 0x10, 0x00, 0x00, 0x90, /* adrp x16, 0 */
563 0x10, 0x02, 0x00, 0x91, /* add x16, x16, #0x0 */
564 0x10, 0x02, 0x40, 0xf9, /* ldr x16, [x16] */
565 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
568 static const char i386_trampoline
[] =
572 "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
573 "\tcall ___delayLoadHelper2@8\n"
578 /* Save integer arg regs in parameter space reserved by our caller
579 above the return address. Allocate space for six fp arg regs plus
580 parameter space possibly used by __delayLoadHelper2 plus alignment.
581 We enter with the stack offset from 16-byte alignment by the return
582 address, so allocate 96 + 32 + 8 = 136 bytes. Note that only the
583 first four xmm regs are used to pass fp args, but the first six
584 vector ymm (zmm too?) are used to pass vector args. We are
585 assuming that volatile vector regs are not modified inside
586 __delayLoadHelper2. However, it is known that at least xmm0 and
587 xmm1 are trashed in some versions of Microsoft dlls, and if xmm4 or
588 xmm5 are also used then that would trash the lower bits of ymm4 and
589 ymm5. If it turns out that vector insns with a vex prefix are used
590 then we'll need to save ymm0-5 here but that can't be done without
591 first testing cpuid and xcr0. */
592 static const char i386_x64_trampoline
[] =
593 "\tsubq $136, %%rsp\n"
594 "\t.seh_stackalloc 136\n"
595 "\t.seh_endprologue\n"
596 "\tmovq %%rcx, 136+8(%%rsp)\n"
597 "\tmovq %%rdx, 136+16(%%rsp)\n"
598 "\tmovq %%r8, 136+24(%%rsp)\n"
599 "\tmovq %%r9, 136+32(%%rsp)\n"
600 "\tmovaps %%xmm0, 32(%%rsp)\n"
601 "\tmovaps %%xmm1, 48(%%rsp)\n"
602 "\tmovaps %%xmm2, 64(%%rsp)\n"
603 "\tmovaps %%xmm3, 80(%%rsp)\n"
604 "\tmovaps %%xmm4, 96(%%rsp)\n"
605 "\tmovaps %%xmm5, 112(%%rsp)\n"
606 "\tmovq %%rax, %%rdx\n"
607 "\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n"
608 "\tcall __delayLoadHelper2\n"
609 "\tmovq 136+8(%%rsp), %%rcx\n"
610 "\tmovq 136+16(%%rsp), %%rdx\n"
611 "\tmovq 136+24(%%rsp), %%r8\n"
612 "\tmovq 136+32(%%rsp), %%r9\n"
613 "\tmovaps 32(%%rsp), %%xmm0\n"
614 "\tmovaps 48(%%rsp), %%xmm1\n"
615 "\tmovaps 64(%%rsp), %%xmm2\n"
616 "\tmovaps 80(%%rsp), %%xmm3\n"
617 "\tmovaps 96(%%rsp), %%xmm4\n"
618 "\tmovaps 112(%%rsp), %%xmm5\n"
619 "\taddq $136, %%rsp\n"
625 const char *how_byte
;
626 const char *how_short
;
627 const char *how_long
;
628 const char *how_asciz
;
629 const char *how_comment
;
630 const char *how_jump
;
631 const char *how_global
;
632 const char *how_space
;
633 const char *how_align_short
;
634 const char *how_align_long
;
635 const char *how_default_as_switches
;
636 const char *how_bfd_target
;
637 enum bfd_architecture how_bfd_arch
;
638 const unsigned char *how_jtab
;
639 int how_jtab_size
; /* Size of the jtab entry. */
640 int how_jtab_roff
; /* Offset into it for the ind 32 reloc into idata 5. */
641 const unsigned char *how_dljtab
;
642 int how_dljtab_size
; /* Size of the dljtab entry. */
643 int how_dljtab_roff1
; /* Offset for the ind 32 reloc into idata 5. */
644 int how_dljtab_roff2
; /* Offset for the ind 32 reloc into idata 5. */
645 int how_dljtab_roff3
; /* Offset for the ind 32 reloc into idata 5. */
647 const char *trampoline
;
650 static const struct mac
655 "arm", ".byte", ".short", ".long", ".asciz", "@",
656 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
657 ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32",
658 "pe-arm-little", bfd_arch_arm
,
659 arm_jtab
, sizeof (arm_jtab
), 8,
660 0, 0, 0, 0, 0, false, 0
665 "i386", ".byte", ".short", ".long", ".asciz", "#",
666 "jmp *", ".global", ".space", ".align\t2", ".align\t4", "",
667 "pe-i386",bfd_arch_i386
,
668 i386_jtab
, sizeof (i386_jtab
), 2,
669 i386_dljtab
, sizeof (i386_dljtab
), 2, 7, 12, false, i386_trampoline
674 "thumb", ".byte", ".short", ".long", ".asciz", "@",
675 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
676 ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork",
677 "pe-arm-little", bfd_arch_arm
,
678 thumb_jtab
, sizeof (thumb_jtab
), 12,
679 0, 0, 0, 0, 0, false, 0
682 #define MARM_INTERWORK 3
684 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
685 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
686 ".global", ".space", ".align\t2", ".align\t4", "-mthumb-interwork",
687 "pe-arm-little", bfd_arch_arm
,
688 arm_interwork_jtab
, sizeof (arm_interwork_jtab
), 12,
689 0, 0, 0, 0, 0, false, 0
694 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
695 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
696 ".global", ".space", ".align\t2", ".align\t4", "",
697 "pe-mcore-big", bfd_arch_mcore
,
698 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8,
699 0, 0, 0, 0, 0, false, 0
704 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
705 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
706 ".global", ".space", ".align\t2", ".align\t4", "-EL",
707 "pe-mcore-little", bfd_arch_mcore
,
708 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8,
709 0, 0, 0, 0, 0, false, 0
714 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
715 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
716 ".global", ".space", ".align\t2", ".align\t4", "",
717 "elf32-mcore-big", bfd_arch_mcore
,
718 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8,
719 0, 0, 0, 0, 0, false, 0
723 #define MMCORE_ELF_LE 7
724 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
725 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
726 ".global", ".space", ".align\t2", ".align\t4", "-EL",
727 "elf32-mcore-little", bfd_arch_mcore
,
728 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8,
729 0, 0, 0, 0, 0, false, 0
734 "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
735 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
736 ".global", ".space", ".align\t2", ".align\t4", "-mapcs-32",
737 "pe-arm-wince-little", bfd_arch_arm
,
738 arm_jtab
, sizeof (arm_jtab
), 8,
739 0, 0, 0, 0, 0, false, 0
744 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
745 "jmp *", ".global", ".space", ".align\t2", ".align\t4", "",
746 "pe-x86-64",bfd_arch_i386
,
747 i386_jtab
, sizeof (i386_jtab
), 2,
748 i386_x64_dljtab
, sizeof (i386_x64_dljtab
), 2, 9, 14, true, i386_x64_trampoline
753 "arm64", ".byte", ".short", ".long", ".asciz", "//",
754 "bl ", ".global", ".space", ".balign\t2", ".balign\t4", "",
755 "pe-aarch64-little", bfd_arch_aarch64
,
756 aarch64_jtab
, sizeof (aarch64_jtab
), 0,
757 0, 0, 0, 0, 0, false, 0
760 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
770 typedef struct export
773 const char *internal_name
;
774 const char *import_name
;
775 const char *its_name
;
778 int noname
; /* Don't put name in image file. */
779 int private; /* Don't put reference in import lib. */
782 int forward
; /* Number of forward label, 0 means no forward. */
787 /* A list of symbols which we should not export. */
791 struct string_list
*next
;
795 static struct string_list
*excludes
;
797 /* Forward references. */
798 static char *deduce_name (const char *);
799 static const char *xlate (const char *);
800 static void dll_name_list_free_contents (dll_name_list_node_type
*);
801 static void identify_search_archive
802 (bfd
*, void (*) (bfd
*, bfd
*, void *), void *);
803 static void identify_search_member (bfd
*, bfd
*, void *);
804 static void identify_search_section (bfd
*, asection
*, void *);
805 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1
;
807 #ifdef DLLTOOL_MCORE_ELF
808 static void mcore_elf_cache_filename (const char *);
809 static void mcore_elf_gen_out_file (void);
812 /* Get current BFD error message. */
813 static inline const char *
814 bfd_get_errmsg (void)
816 return bfd_errmsg (bfd_get_error ());
820 prefix_encode (char *start
, unsigned code
)
823 char *p
= stpcpy (buf
, start
);
825 *p
++ = "abcdefghijklmnopqrstuvwxyz"[code
% 26];
826 while ((code
/= 26) != 0);
832 dlltmp (char **buf
, const char *fmt
)
836 *buf
= xmalloc (strlen (tmp_prefix
) + 64);
837 sprintf (*buf
, fmt
, tmp_prefix
);
843 inform (const char * message
, ...)
847 va_start (args
, message
);
852 report (message
, args
);
875 /* xgettext:c-format */
876 fatal (_("Internal error: Unknown machine type: %d"), mach
);
900 /* xgettext:c-format */
901 fatal (_("Internal error: Unknown machine type: %d"), mach
);
908 asm_prefix (const char *name
)
910 /* Symbol names starting with ? do not have a leading underscore. */
911 if (name
&& *name
== '?')
913 return leading_underscore
;
916 #define ASM_BYTE mtable[machine].how_byte
917 #define ASM_SHORT mtable[machine].how_short
918 #define ASM_LONG mtable[machine].how_long
919 #define ASM_TEXT mtable[machine].how_asciz
920 #define ASM_C mtable[machine].how_comment
921 #define ASM_JUMP mtable[machine].how_jump
922 #define ASM_GLOBAL mtable[machine].how_global
923 #define ASM_SPACE mtable[machine].how_space
924 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
925 #define ASM_RVA_BEFORE rvabefore (machine)
926 #define ASM_RVA_AFTER rvaafter (machine)
927 #define ASM_PREFIX(NAME) asm_prefix (NAME)
928 #define ASM_ALIGN_LONG mtable[machine].how_align_long
929 #define HOW_BFD_READ_TARGET 0 /* Always default. */
930 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
931 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
932 #define HOW_JTAB (delay ? mtable[machine].how_dljtab \
933 : mtable[machine].how_jtab)
934 #define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \
935 : mtable[machine].how_jtab_size)
936 #define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \
937 : mtable[machine].how_jtab_roff)
938 #define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
939 #define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
940 #define ASM_SWITCHES mtable[machine].how_default_as_switches
941 #define HOW_SEH mtable[machine].how_seh
946 process_def_file (const char *name
)
948 FILE *f
= fopen (name
, FOPEN_RT
);
951 /* xgettext:c-format */
952 fatal (_("Can't open def file: %s"), name
);
956 /* xgettext:c-format */
957 inform (_("Processing def file: %s"), name
);
961 inform (_("Processed def file"));
964 /**********************************************************************/
966 /* Communications with the parser. */
968 static int d_nfuncs
; /* Number of functions exported. */
969 static int d_named_nfuncs
; /* Number of named functions exported. */
970 static int d_low_ord
; /* Lowest ordinal index. */
971 static int d_high_ord
; /* Highest ordinal index. */
972 static export_type
*d_exports
; /* List of exported functions. */
973 static export_type
**d_exports_lexically
; /* Vector of exported functions in alpha order. */
974 static dlist_type
*d_list
; /* Descriptions. */
975 static dlist_type
*a_list
; /* Stuff to go in directives. */
976 static int d_nforwards
= 0; /* Number of forwarded exports. */
982 yyerror (const char * err ATTRIBUTE_UNUSED
)
984 /* xgettext:c-format */
985 non_fatal (_("Syntax error in def file %s:%d"), def_file
, linenumber
);
989 def_exports (const char *name
, const char *internal_name
, int ordinal
,
990 int noname
, int constant
, int data
, int private,
991 const char *its_name
)
993 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
996 p
->internal_name
= internal_name
? internal_name
: name
;
997 p
->its_name
= its_name
;
998 p
->import_name
= name
;
999 p
->ordinal
= ordinal
;
1000 p
->constant
= constant
;
1002 p
->private = private;
1004 p
->next
= d_exports
;
1008 if (internal_name
!= NULL
1009 && strchr (internal_name
, '.') != NULL
)
1010 p
->forward
= ++d_nforwards
;
1012 p
->forward
= 0; /* no forward */
1016 set_dll_name_from_def (const char *name
, char is_dll
)
1018 const char *image_basename
= lbasename (name
);
1019 if (image_basename
!= name
)
1020 non_fatal (_("%s: Path components stripped from image name, '%s'."),
1022 /* Append the default suffix, if none specified. */
1023 if (strchr (image_basename
, '.') == 0)
1025 const char * suffix
= is_dll
? ".dll" : ".exe";
1027 dll_name
= xmalloc (strlen (image_basename
) + strlen (suffix
) + 1);
1028 sprintf (dll_name
, "%s%s", image_basename
, suffix
);
1031 dll_name
= xstrdup (image_basename
);
1035 def_name (const char *name
, int base
)
1037 /* xgettext:c-format */
1038 inform (_("NAME: %s base: %x"), name
, base
);
1041 non_fatal (_("Can't have LIBRARY and NAME"));
1043 if (dll_name_set_by_exp_name
&& name
&& *name
!= 0)
1046 dll_name_set_by_exp_name
= 0;
1048 /* If --dllname not provided, use the one in the DEF file.
1049 FIXME: Is this appropriate for executables? */
1051 set_dll_name_from_def (name
, 0);
1056 def_library (const char *name
, int base
)
1058 /* xgettext:c-format */
1059 inform (_("LIBRARY: %s base: %x"), name
, base
);
1062 non_fatal (_("Can't have LIBRARY and NAME"));
1064 if (dll_name_set_by_exp_name
&& name
&& *name
!= 0)
1067 dll_name_set_by_exp_name
= 0;
1070 /* If --dllname not provided, use the one in the DEF file. */
1072 set_dll_name_from_def (name
, 1);
1077 def_description (const char *desc
)
1079 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
1080 d
->text
= xstrdup (desc
);
1086 new_directive (char *dir
)
1088 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
1089 d
->text
= xstrdup (dir
);
1095 def_heapsize (int reserve
, int commit
)
1099 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
1101 sprintf (b
, "-heap 0x%x ", reserve
);
1102 new_directive (xstrdup (b
));
1106 def_stacksize (int reserve
, int commit
)
1110 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
1112 sprintf (b
, "-stack 0x%x ", reserve
);
1113 new_directive (xstrdup (b
));
1116 /* append_import simply adds the given import definition to the global
1117 import_list. It is used by def_import. */
1120 append_import (const char *symbol_name
, const char *dllname
, int func_ordinal
,
1121 const char *its_name
)
1126 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
1128 if (strcmp ((*pq
)->dllname
, dllname
) == 0)
1131 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
1132 q
->functail
= q
->functail
->next
;
1133 q
->functail
->ord
= func_ordinal
;
1134 q
->functail
->name
= xstrdup (symbol_name
);
1135 q
->functail
->its_name
= its_name
? xstrdup (its_name
) : NULL
;
1136 q
->functail
->next
= NULL
;
1142 q
= xmalloc (sizeof (iheadtype
));
1143 q
->dllname
= xstrdup (dllname
);
1145 q
->funchead
= xmalloc (sizeof (ifunctype
));
1146 q
->functail
= q
->funchead
;
1148 q
->functail
->name
= xstrdup (symbol_name
);
1149 q
->functail
->its_name
= its_name
? xstrdup (its_name
) : NULL
;
1150 q
->functail
->ord
= func_ordinal
;
1151 q
->functail
->next
= NULL
;
1156 /* def_import is called from within defparse.y when an IMPORT
1157 declaration is encountered. Depending on the form of the
1158 declaration, the module name may or may not need ".dll" to be
1159 appended to it, the name of the function may be stored in internal
1160 or entry, and there may or may not be an ordinal value associated
1163 /* A note regarding the parse modes:
1164 In defparse.y we have to accept import declarations which follow
1165 any one of the following forms:
1166 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1167 <func_name_in_app> = <dll_name>.<number>
1168 <dll_name>.<func_name_in_dll>
1170 Furthermore, the dll's name may or may not end with ".dll", which
1171 complicates the parsing a little. Normally the dll's name is
1172 passed to def_import() in the "module" parameter, but when it ends
1173 with ".dll" it gets passed in "module" sans ".dll" and that needs
1176 def_import gets five parameters:
1177 APP_NAME - the name of the function in the application, if
1178 present, or NULL if not present.
1179 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1180 DLLEXT - the extension of the dll, if present, NULL if not present.
1181 ENTRY - the name of the function in the dll, if present, or NULL.
1182 ORD_VAL - the numerical tag of the function in the dll, if present,
1183 or NULL. Exactly one of <entry> or <ord_val> must be
1184 present (i.e., not NULL). */
1187 def_import (const char *app_name
, const char *module
, const char *dllext
,
1188 const char *entry
, int ord_val
, const char *its_name
)
1190 const char *application_name
;
1194 application_name
= entry
;
1197 if (app_name
!= NULL
)
1198 application_name
= app_name
;
1200 application_name
= "";
1204 module
= buf
= concat (module
, ".", dllext
, NULL
);
1206 append_import (application_name
, module
, ord_val
, its_name
);
1212 def_version (int major
, int minor
)
1214 printf (_("VERSION %d.%d\n"), major
, minor
);
1218 def_section (const char *name
, int attr
)
1233 sprintf (buf
, "-attr %s %s", name
, atts
);
1234 new_directive (xstrdup (buf
));
1240 def_section ("CODE", attr
);
1246 def_section ("DATA", attr
);
1249 /**********************************************************************/
1252 run (const char *what
, char *args
)
1255 int pid
, wait_status
;
1258 char *errmsg_fmt
= NULL
, *errmsg_arg
= NULL
;
1259 char *temp_base
= make_temp_file ("");
1261 inform (_("run: %s %s"), what
, args
);
1263 /* Count the args */
1265 for (s
= args
; *s
; s
++)
1269 argv
= xmalloc (sizeof (char *) * (i
+ 3));
1278 while (*s
!= ' ' && *s
!= 0)
1286 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1287 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1292 inform ("%s", strerror (errno
));
1294 fatal (errmsg_fmt
, errmsg_arg
);
1297 pid
= pwait (pid
, & wait_status
, 0);
1301 /* xgettext:c-format */
1302 fatal (_("wait: %s"), strerror (errno
));
1304 else if (WIFSIGNALED (wait_status
))
1306 /* xgettext:c-format */
1307 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1309 else if (WIFEXITED (wait_status
))
1311 if (WEXITSTATUS (wait_status
) != 0)
1312 /* xgettext:c-format */
1313 non_fatal (_("%s exited with status %d"),
1314 what
, WEXITSTATUS (wait_status
));
1320 /* Look for a list of symbols to export in the .drectve section of
1321 ABFD. Pass each one to def_exports. */
1324 scan_drectve_symbols (bfd
*abfd
)
1332 /* Look for .drectve's */
1333 s
= bfd_get_section_by_name (abfd
, DRECTVE_SECTION_NAME
);
1338 size
= bfd_section_size (s
);
1339 buf
= xmalloc (size
);
1341 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1343 /* xgettext:c-format */
1344 inform (_("Sucking in info from %s section in %s"),
1345 DRECTVE_SECTION_NAME
, bfd_get_filename (abfd
));
1347 /* Search for -export: strings. The exported symbols can optionally
1348 have type tags (eg., -export:foo,data), so handle those as well.
1349 Currently only data tag is supported. */
1355 && startswith (p
, "-export:"))
1359 flagword flags
= BSF_FUNCTION
;
1362 /* Do we have a quoted export? */
1367 while (p
< e
&& *p
!= '"')
1373 while (p
< e
&& *p
!= ',' && *p
!= ' ' && *p
!= '-')
1376 c
= xmalloc (p
- name
+ 1);
1377 memcpy (c
, name
, p
- name
);
1379 /* Advance over trailing quote. */
1380 if (p
< e
&& *p
== '"')
1382 if (p
< e
&& *p
== ',') /* found type tag. */
1384 char *tag_start
= ++p
;
1385 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1387 if (startswith (tag_start
, "data"))
1388 flags
&= ~BSF_FUNCTION
;
1391 /* FIXME: The 5th arg is for the `constant' field.
1392 What should it be? Not that it matters since it's not
1393 currently useful. */
1394 def_exports (c
, 0, -1, 0, 0, ! (flags
& BSF_FUNCTION
), 0, NULL
);
1396 if (add_stdcall_alias
&& strchr (c
, '@'))
1398 int lead_at
= (*c
== '@') ;
1399 char *exported_name
= xstrdup (c
+ lead_at
);
1400 char *atsym
= strchr (exported_name
, '@');
1402 /* Note: stdcall alias symbols can never be data. */
1403 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0, 0, NULL
);
1412 /* Look through the symbols in MINISYMS, and add each one to list of
1413 symbols to export. */
1416 scan_filtered_symbols (bfd
*abfd
, void *minisyms
, long symcount
,
1420 bfd_byte
*from
, *fromend
;
1422 store
= bfd_make_empty_symbol (abfd
);
1424 bfd_fatal (bfd_get_filename (abfd
));
1426 from
= (bfd_byte
*) minisyms
;
1427 fromend
= from
+ symcount
* size
;
1428 for (; from
< fromend
; from
+= size
)
1431 const char *symbol_name
;
1433 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1435 bfd_fatal (bfd_get_filename (abfd
));
1437 symbol_name
= bfd_asymbol_name (sym
);
1439 && *symbol_name
== bfd_get_symbol_leading_char (abfd
))
1442 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0,
1443 ! (sym
->flags
& BSF_FUNCTION
), 0, NULL
);
1445 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1447 int lead_at
= (*symbol_name
== '@');
1448 char *exported_name
= xstrdup (symbol_name
+ lead_at
);
1449 char *atsym
= strchr (exported_name
, '@');
1451 /* Note: stdcall alias symbols can never be data. */
1452 def_exports (exported_name
, xstrdup (symbol_name
),
1453 -1, 0, 0, 0, 0, NULL
);
1458 /* Add a list of symbols to exclude. */
1461 add_excludes (const char *new_excludes
)
1464 char *exclude_string
;
1466 local_copy
= xstrdup (new_excludes
);
1468 exclude_string
= strtok (local_copy
, ",:");
1469 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1471 struct string_list
*new_exclude
;
1473 new_exclude
= ((struct string_list
*)
1474 xmalloc (sizeof (struct string_list
)));
1475 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1476 /* Don't add a leading underscore for fastcall symbols. */
1477 if (*exclude_string
== '@')
1478 sprintf (new_exclude
->string
, "%s", exclude_string
);
1480 sprintf (new_exclude
->string
, "%s%s", leading_underscore
,
1482 new_exclude
->next
= excludes
;
1483 excludes
= new_exclude
;
1485 /* xgettext:c-format */
1486 inform (_("Excluding symbol: %s"), exclude_string
);
1492 /* See if STRING is on the list of symbols to exclude. */
1495 match_exclude (const char *string
)
1497 struct string_list
*excl_item
;
1499 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1500 if (strcmp (string
, excl_item
->string
) == 0)
1505 /* Add the default list of symbols to exclude. */
1508 set_default_excludes (void)
1510 add_excludes (default_excludes
);
1513 /* Choose which symbols to export. */
1516 filter_symbols (bfd
*abfd
, void *minisyms
, long symcount
, unsigned int size
)
1518 bfd_byte
*from
, *fromend
, *to
;
1521 store
= bfd_make_empty_symbol (abfd
);
1523 bfd_fatal (bfd_get_filename (abfd
));
1525 from
= (bfd_byte
*) minisyms
;
1526 fromend
= from
+ symcount
* size
;
1527 to
= (bfd_byte
*) minisyms
;
1529 for (; from
< fromend
; from
+= size
)
1534 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const void *) from
, store
);
1536 bfd_fatal (bfd_get_filename (abfd
));
1538 /* Check for external and defined only symbols. */
1539 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1540 || (sym
->flags
& BSF_WEAK
) != 0
1541 || bfd_is_com_section (sym
->section
))
1542 && ! bfd_is_und_section (sym
->section
));
1544 keep
= keep
&& ! match_exclude (sym
->name
);
1548 memcpy (to
, from
, size
);
1553 return (to
- (bfd_byte
*) minisyms
) / size
;
1556 /* Export all symbols in ABFD, except for ones we were told not to
1560 scan_all_symbols (bfd
*abfd
)
1566 /* Ignore bfds with an import descriptor table. We assume that any
1567 such BFD contains symbols which are exported from another DLL,
1568 and we don't want to reexport them from here. */
1569 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1572 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1574 /* xgettext:c-format */
1575 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1579 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1581 bfd_fatal (bfd_get_filename (abfd
));
1585 /* xgettext:c-format */
1586 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1590 /* Discard the symbols we don't want to export. It's OK to do this
1591 in place; we'll free the storage anyway. */
1593 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1594 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1599 /* Look at the object file to decide which symbols to export. */
1602 scan_open_obj_file (bfd
*abfd
)
1604 if (export_all_symbols
)
1605 scan_all_symbols (abfd
);
1607 scan_drectve_symbols (abfd
);
1609 /* FIXME: we ought to read in and block out the base relocations. */
1611 /* xgettext:c-format */
1612 inform (_("Done reading %s"), bfd_get_filename (abfd
));
1616 scan_obj_file (const char *filename
)
1618 bfd
* f
= bfd_openr (filename
, 0);
1621 /* xgettext:c-format */
1622 fatal (_("Unable to open object file: %s: %s"), filename
, bfd_get_errmsg ());
1624 /* xgettext:c-format */
1625 inform (_("Scanning object file %s"), filename
);
1627 if (bfd_check_format (f
, bfd_archive
))
1629 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1633 if (bfd_check_format (arfile
, bfd_object
))
1634 scan_open_obj_file (arfile
);
1635 next
= bfd_openr_next_archived_file (f
, arfile
);
1637 /* PR 17512: file: 58715298. */
1643 #ifdef DLLTOOL_MCORE_ELF
1644 if (mcore_elf_out_file
)
1645 inform (_("Cannot produce mcore-elf dll from archive file: %s"),
1649 else if (bfd_check_format (f
, bfd_object
))
1651 scan_open_obj_file (f
);
1653 #ifdef DLLTOOL_MCORE_ELF
1654 if (mcore_elf_out_file
)
1655 mcore_elf_cache_filename (filename
);
1664 dump_def_info (FILE *f
)
1668 fprintf (f
, "%s ", ASM_C
);
1669 for (i
= 0; oav
[i
]; i
++)
1670 fprintf (f
, "%s ", oav
[i
]);
1672 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1674 fprintf (f
, "%s %d = %s %s @ %d %s%s%s%s%s%s\n",
1680 exp
->noname
? "NONAME " : "",
1681 exp
->private ? "PRIVATE " : "",
1682 exp
->constant
? "CONSTANT" : "",
1683 exp
->data
? "DATA" : "",
1684 exp
->its_name
? " ==" : "",
1685 exp
->its_name
? exp
->its_name
: "");
1689 /* Generate the .exp file. */
1692 sfunc (const void *a
, const void *b
)
1694 if (*(const bfd_vma
*) a
== *(const bfd_vma
*) b
)
1697 return ((*(const bfd_vma
*) a
> *(const bfd_vma
*) b
) ? 1 : -1);
1701 flush_page (FILE *f
, bfd_vma
*need
, bfd_vma page_addr
, int on_page
)
1705 /* Flush this page. */
1706 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1710 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1712 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1715 for (i
= 0; i
< on_page
; i
++)
1717 bfd_vma needed
= need
[i
];
1721 if (!create_for_pep
)
1723 /* Relocation via HIGHLOW. */
1724 needed
= ((needed
- page_addr
) | 0x3000) & 0xffff;
1728 /* Relocation via DIR64. */
1729 needed
= ((needed
- page_addr
) | 0xa000) & 0xffff;
1733 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (long) needed
);
1738 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1747 inform (_("Adding exports to output file"));
1749 fprintf (output_def
, ";");
1750 for (i
= 0; oav
[i
]; i
++)
1751 fprintf (output_def
, " %s", oav
[i
]);
1753 fprintf (output_def
, "\nEXPORTS\n");
1755 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1757 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1758 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1762 fprintf (output_def
, ";\t%s\n", res
);
1766 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1768 fprintf (output_def
, "\t%s%s%s @ %d%s%s%s%s%s\n",
1773 exp
->noname
? " NONAME" : "",
1774 exp
->private ? "PRIVATE " : "",
1775 exp
->data
? " DATA" : "",
1776 exp
->its_name
? " ==" : "",
1777 exp
->its_name
? exp
->its_name
: "");
1781 char * quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1783 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1791 exp
->noname
? " NONAME" : "",
1792 exp
->private ? "PRIVATE " : "",
1793 exp
->data
? " DATA" : "",
1794 exp
->its_name
? " ==" : "",
1795 exp
->its_name
? exp
->its_name
: "");
1799 inform (_("Added exports to output file"));
1802 /* generate_idata_ofile generates the portable assembly source code
1803 for the idata sections. It appends the source code to the end of
1807 generate_idata_ofile (FILE *filvar
)
1815 if (import_list
== NULL
)
1818 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1819 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1820 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1821 fprintf (filvar
, "doi_idata:\n");
1824 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1826 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1827 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1828 ASM_C
, headptr
->dllname
);
1829 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1830 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1831 fprintf (filvar
, "\t%sdllname%d%s\n",
1832 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1833 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1834 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1838 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1839 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1840 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1841 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1842 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1844 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1846 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1848 fprintf (filvar
, "listone%d:\n", headindex
);
1849 for (funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++)
1852 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1853 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
,
1856 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1857 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1860 fprintf (filvar
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
1862 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
1866 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1868 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1870 fprintf (filvar
, "listtwo%d:\n", headindex
);
1871 for (funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++)
1874 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1875 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
,
1878 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1879 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1882 fprintf (filvar
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
1884 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
1888 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1890 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1893 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1894 funcptr
= funcptr
->next
)
1896 fprintf (filvar
, "funcptr%d_%d:\n", headindex
, funcindex
);
1897 fprintf (filvar
, "\t%s\t%d\n", ASM_SHORT
, funcptr
->ord
& 0xFFFF);
1898 fprintf (filvar
, "\t%s\t\"%s\"\n", ASM_TEXT
,
1899 funcptr
->its_name
? funcptr
->its_name
: funcptr
->name
);
1900 fprintf (filvar
, "\t%s\t0\n", ASM_BYTE
);
1906 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1908 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1910 fprintf (filvar
, "dllname%d:\n", headindex
);
1911 fprintf (filvar
, "\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1912 fprintf (filvar
, "\t%s\t0\n", ASM_BYTE
);
1917 /* Assemble the specified file. */
1919 assemble_file (const char * source
, const char * dest
)
1923 cmd
= xmalloc (strlen (ASM_SWITCHES
) + strlen (as_flags
)
1924 + strlen (source
) + strlen (dest
) + 50);
1926 sprintf (cmd
, "%s %s -o %s %s", ASM_SWITCHES
, as_flags
, dest
, source
);
1932 static const char * temp_file_to_remove
[5];
1933 #define TEMP_EXPORT_FILE 0
1934 #define TEMP_HEAD_FILE 1
1935 #define TEMP_TAIL_FILE 2
1936 #define TEMP_HEAD_O_FILE 3
1937 #define TEMP_TAIL_O_FILE 4
1940 unlink_temp_files (void)
1944 if (dontdeltemps
> 0)
1947 for (i
= 0; i
< ARRAY_SIZE (temp_file_to_remove
); i
++)
1949 if (temp_file_to_remove
[i
])
1951 unlink (temp_file_to_remove
[i
]);
1952 temp_file_to_remove
[i
] = NULL
;
1965 /* xgettext:c-format */
1966 inform (_("Generating export file: %s"), exp_name
);
1968 f
= fopen (TMP_ASM
, FOPEN_WT
);
1970 /* xgettext:c-format */
1971 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1973 temp_file_to_remove
[TEMP_EXPORT_FILE
] = TMP_ASM
;
1975 /* xgettext:c-format */
1976 inform (_("Opened temporary file: %s"), TMP_ASM
);
1982 fprintf (f
, "\t.section .edata\n\n");
1983 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1984 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
,
1985 (unsigned long) time(0), ASM_C
);
1986 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1987 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n",
1988 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1989 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n",
1990 ASM_LONG
, d_low_ord
, ASM_C
);
1993 fprintf (f
, "\t%s %d %s Number of functions\n",
1994 ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1995 fprintf (f
, "\t%s named funcs %d, low ord %d, high ord %d\n",
1996 ASM_C
, d_named_nfuncs
, d_low_ord
, d_high_ord
);
1997 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1998 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
,
2000 fprintf (f
, "\t%safuncs%s %s Address of functions\n",
2001 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2003 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
2004 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2006 fprintf (f
, "\t%sanords%s %s Address of ordinals\n",
2007 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2009 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
2012 fprintf (f
, "%s Export address Table\n", ASM_C
);
2013 fprintf (f
, "\t%s\n", ASM_ALIGN_LONG
);
2014 fprintf (f
, "afuncs:\n");
2017 for (exp
= d_exports
; exp
; exp
= exp
->next
)
2019 if (exp
->ordinal
!= i
)
2021 while (i
< exp
->ordinal
)
2023 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2028 if (exp
->forward
== 0)
2030 if (exp
->internal_name
[0] == '@')
2031 fprintf (f
, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
2032 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2034 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
2035 ASM_PREFIX (exp
->internal_name
),
2036 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2039 fprintf (f
, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE
,
2040 exp
->forward
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
2044 fprintf (f
, "%s Export Name Pointer Table\n", ASM_C
);
2045 fprintf (f
, "anames:\n");
2047 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2049 if (!exp
->noname
|| show_allnames
)
2050 fprintf (f
, "\t%sn%d%s\n",
2051 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
2054 fprintf (f
, "%s Export Ordinal Table\n", ASM_C
);
2055 fprintf (f
, "anords:\n");
2056 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2058 if (!exp
->noname
|| show_allnames
)
2059 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
2062 fprintf (f
, "%s Export Name Table\n", ASM_C
);
2063 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2065 if (!exp
->noname
|| show_allnames
)
2066 fprintf (f
, "n%d: %s \"%s\"\n",
2067 exp
->ordinal
, ASM_TEXT
,
2068 exp
->its_name
? exp
->its_name
: xlate (exp
->name
));
2069 if (exp
->forward
!= 0)
2070 fprintf (f
, "f%d: %s \"%s\"\n",
2071 exp
->forward
, ASM_TEXT
, exp
->internal_name
);
2076 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
2077 for (dl
= a_list
; dl
; dl
= dl
->next
)
2079 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
2085 fprintf (f
, "\t.section .rdata\n");
2086 for (dl
= d_list
; dl
; dl
= dl
->next
)
2091 /* We don't output as ascii because there can
2092 be quote characters in the string. */
2094 for (p
= dl
->text
; *p
; p
++)
2097 fprintf (f
, "\t%s\t", ASM_BYTE
);
2100 fprintf (f
, "%d", *p
);
2103 fprintf (f
, ",0\n");
2116 /* Add to the output file a way of getting to the exported names
2117 without using the import library. */
2120 fprintf (f
, "\t.section\t.rdata\n");
2121 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2122 if (!exp
->noname
|| show_allnames
)
2124 /* We use a single underscore for MS compatibility, and a
2125 double underscore for backward compatibility with old
2127 if (create_compat_implib
)
2128 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2129 fprintf (f
, "\t%s\t_imp_%s%s\n", ASM_GLOBAL
,
2130 leading_underscore
, exp
->name
);
2131 if (create_compat_implib
)
2132 fprintf (f
, "__imp_%s:\n", exp
->name
);
2133 fprintf (f
, "_imp_%s%s:\n", leading_underscore
, exp
->name
);
2134 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
2138 /* Dump the reloc section if a base file is provided. */
2142 bfd_vma need
[COFF_PAGE_SIZE
];
2144 bfd_size_type numbytes
;
2149 fprintf (f
, "\t.section\t.init\n");
2150 fprintf (f
, "lab:\n");
2152 fseek (base_file
, 0, SEEK_END
);
2153 numbytes
= ftell (base_file
);
2154 fseek (base_file
, 0, SEEK_SET
);
2155 copy
= xmalloc (numbytes
);
2156 if (fread (copy
, 1, numbytes
, base_file
) < numbytes
)
2157 fatal (_("failed to read the number of entries from base file"));
2158 num_entries
= numbytes
/ sizeof (bfd_vma
);
2160 fprintf (f
, "\t.section\t.reloc\n");
2165 bfd_vma last
= (bfd_vma
) -1;
2166 qsort (copy
, num_entries
, sizeof (bfd_vma
), sfunc
);
2167 /* Delete duplicates */
2168 for (src
= 0; src
< num_entries
; src
++)
2170 if (last
!= copy
[src
])
2171 last
= copy
[dst
++] = copy
[src
];
2175 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
2177 for (j
= 0; j
< num_entries
; j
++)
2180 if ((addr
& PAGE_MASK
) != page_addr
)
2182 flush_page (f
, need
, page_addr
, on_page
);
2184 page_addr
= addr
& PAGE_MASK
;
2186 need
[on_page
++] = addr
;
2188 flush_page (f
, need
, page_addr
, on_page
);
2190 fprintf (f
, "\t%s\t0,0\t%s End\n", ASM_LONG
, ASM_C
);
2195 generate_idata_ofile (f
);
2199 /* Assemble the file. */
2200 assemble_file (TMP_ASM
, exp_name
);
2202 if (dontdeltemps
== 0)
2204 temp_file_to_remove
[TEMP_EXPORT_FILE
] = NULL
;
2208 inform (_("Generated exports file"));
2212 xlate (const char *name
)
2214 int lead_at
= *name
== '@';
2215 int is_stdcall
= !lead_at
&& strchr (name
, '@') != NULL
;
2217 if (!lead_at
&& (add_underscore
2218 || (add_stdcall_underscore
&& is_stdcall
)))
2220 char *copy
= xmalloc (strlen (name
) + 2);
2223 strcpy (copy
+ 1, name
);
2232 /* PR 9766: Look for the last @ sign in the name. */
2233 p
= strrchr (name
, '@');
2234 if (p
&& ISDIGIT (p
[1]))
2250 unsigned char *data
;
2253 #define INIT_SEC_DATA(id, name, flags, align) \
2254 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2266 #define TEXT_SEC_FLAGS \
2267 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2268 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2269 #define BSS_SEC_FLAGS SEC_ALLOC
2271 static sinfo secdata
[NSECS
] =
2273 INIT_SEC_DATA (TEXT
, ".text", TEXT_SEC_FLAGS
, 2),
2274 INIT_SEC_DATA (DATA
, ".data", DATA_SEC_FLAGS
, 2),
2275 INIT_SEC_DATA (BSS
, ".bss", BSS_SEC_FLAGS
, 2),
2276 INIT_SEC_DATA (IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2),
2277 INIT_SEC_DATA (IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2),
2278 INIT_SEC_DATA (IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2),
2279 INIT_SEC_DATA (IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1)
2282 /* This is what we're trying to make. We generate the imp symbols with
2283 both single and double underscores, for compatibility.
2286 .global _GetFileVersionInfoSizeW@8
2287 .global __imp_GetFileVersionInfoSizeW@8
2288 _GetFileVersionInfoSizeW@8:
2289 jmp * __imp_GetFileVersionInfoSizeW@8
2290 .section .idata$7 # To force loading of head
2291 .long __version_a_head
2292 # Import Address Table
2294 __imp_GetFileVersionInfoSizeW@8:
2297 # Import Lookup Table
2303 .asciz "GetFileVersionInfoSizeW" */
2306 make_label (const char *prefix
, const char *name
)
2308 int len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2309 char *copy
= xmalloc (len
+ 1);
2311 strcpy (copy
, ASM_PREFIX (name
));
2312 strcat (copy
, prefix
);
2313 strcat (copy
, name
);
2318 make_imp_label (const char *prefix
, const char *name
)
2325 len
= strlen (prefix
) + strlen (name
);
2326 copy
= xmalloc (len
+ 1);
2327 strcpy (copy
, prefix
);
2328 strcat (copy
, name
);
2332 len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2333 copy
= xmalloc (len
+ 1);
2334 strcpy (copy
, prefix
);
2335 strcat (copy
, ASM_PREFIX (name
));
2336 strcat (copy
, name
);
2342 make_one_lib_file (export_type
*exp
, int i
, int delay
)
2344 char *outname
= TMP_STUB
;
2345 size_t name_len
= strlen (outname
);
2346 sprintf (outname
+ name_len
- 7, "%05d.o", i
);
2348 bfd
*abfd
= bfd_openw (outname
, HOW_BFD_WRITE_TARGET
);
2350 /* xgettext:c-format */
2351 fatal (_("bfd_open failed open stub file: %s: %s"),
2352 outname
, bfd_get_errmsg ());
2354 /* xgettext:c-format */
2355 inform (_("Creating stub file: %s"), outname
);
2357 bfd_set_format (abfd
, bfd_object
);
2358 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2361 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2362 bfd_set_private_flags (abfd
, F_INTERWORK
);
2365 /* First make symbols for the sections. */
2366 flagword applicable
= bfd_applicable_section_flags (abfd
);
2370 asymbol
*ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2372 for (i
= 0; i
< NSECS
; i
++)
2374 sinfo
*si
= secdata
+ i
;
2378 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2379 bfd_set_section_flags (si
->sec
, si
->flags
& applicable
);
2381 bfd_set_section_alignment (si
->sec
, si
->align
);
2382 si
->sec
->output_section
= si
->sec
;
2383 si
->sym
= bfd_make_empty_symbol(abfd
);
2384 si
->sym
->name
= si
->sec
->name
;
2385 si
->sym
->section
= si
->sec
;
2386 si
->sym
->flags
= BSF_LOCAL
;
2388 ptrs
[oidx
] = si
->sym
;
2389 si
->sympp
= ptrs
+ oidx
;
2398 asymbol
*exp_label
= bfd_make_empty_symbol (abfd
);
2399 exp_label
->name
= make_imp_label ("", exp
->name
);
2400 exp_label
->section
= secdata
[TEXT
].sec
;
2401 exp_label
->flags
= BSF_GLOBAL
;
2402 exp_label
->value
= 0;
2405 if (machine
== MTHUMB
)
2406 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2408 ptrs
[oidx
++] = exp_label
;
2411 /* Generate imp symbols with one underscore for Microsoft
2412 compatibility, and with two underscores for backward
2413 compatibility with old versions of cygwin. */
2414 asymbol
*iname
= NULL
;
2415 if (create_compat_implib
)
2417 iname
= bfd_make_empty_symbol (abfd
);
2418 iname
->name
= make_imp_label ("___imp", exp
->name
);
2419 iname
->section
= secdata
[IDATA5
].sec
;
2420 iname
->flags
= BSF_GLOBAL
;
2424 asymbol
*iname2
= bfd_make_empty_symbol (abfd
);
2425 iname2
->name
= make_imp_label ("__imp_", exp
->name
);
2426 iname2
->section
= secdata
[IDATA5
].sec
;
2427 iname2
->flags
= BSF_GLOBAL
;
2430 asymbol
*iname_lab
= bfd_make_empty_symbol (abfd
);
2431 iname_lab
->name
= head_label
;
2432 iname_lab
->section
= bfd_und_section_ptr
;
2433 iname_lab
->flags
= 0;
2434 iname_lab
->value
= 0;
2436 asymbol
**iname_pp
= ptrs
+ oidx
;
2437 if (create_compat_implib
)
2438 ptrs
[oidx
++] = iname
;
2439 ptrs
[oidx
++] = iname2
;
2441 asymbol
**iname_lab_pp
= ptrs
+ oidx
;
2442 ptrs
[oidx
++] = iname_lab
;
2446 for (i
= 0; i
< NSECS
; i
++)
2448 sinfo
*si
= secdata
+ i
;
2449 asection
*sec
= si
->sec
;
2450 arelent
*rel
, *rel2
= 0, *rel3
= 0;
2458 unsigned int rpp_len
;
2460 si
->size
= HOW_JTAB_SIZE
;
2461 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2462 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2464 /* Add the reloc into idata$5. */
2465 rel
= xmalloc (sizeof (arelent
));
2467 rpp_len
= delay
? 4 : 2;
2469 if (machine
== MAARCH64
)
2472 rpp
= xmalloc (sizeof (arelent
*) * rpp_len
);
2476 rel
->address
= HOW_JTAB_ROFF
;
2481 rel2
= xmalloc (sizeof (arelent
));
2483 rel2
->address
= HOW_JTAB_ROFF2
;
2485 rel3
= xmalloc (sizeof (arelent
));
2487 rel3
->address
= HOW_JTAB_ROFF3
;
2492 if (machine
== MX86
)
2494 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2495 BFD_RELOC_32_PCREL
);
2496 rel
->sym_ptr_ptr
= iname_pp
;
2498 else if (machine
== MAARCH64
)
2502 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
);
2503 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2505 rel_add
= xmalloc (sizeof (arelent
));
2506 rel_add
->address
= 4;
2507 rel_add
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_AARCH64_ADD_LO12
);
2508 rel_add
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2509 rel_add
->addend
= 0;
2511 rpp
[rpp_len
- 2] = rel_add
;
2512 rpp
[rpp_len
- 1] = 0;
2516 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2517 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2522 if (machine
== MX86
)
2523 rel2
->howto
= bfd_reloc_type_lookup (abfd
,
2524 BFD_RELOC_32_PCREL
);
2526 rel2
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2527 rel2
->sym_ptr_ptr
= rel
->sym_ptr_ptr
;
2528 rel3
->howto
= bfd_reloc_type_lookup (abfd
,
2529 BFD_RELOC_32_PCREL
);
2530 rel3
->sym_ptr_ptr
= iname_lab_pp
;
2533 sec
->orelocation
= rpp
;
2534 sec
->reloc_count
= rpp_len
- 1;
2541 si
->size
= create_for_pep
? 8 : 4;
2542 si
->data
= xmalloc (si
->size
);
2543 sec
->reloc_count
= 1;
2544 memset (si
->data
, 0, si
->size
);
2545 /* Point after jmp [__imp_...] instruction. */
2547 rel
= xmalloc (sizeof (arelent
));
2548 rpp
= xmalloc (sizeof (arelent
*) * 2);
2554 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_64
);
2556 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2557 rel
->sym_ptr_ptr
= secdata
[TEXT
].sympp
;
2558 sec
->orelocation
= rpp
;
2564 /* An idata$4 or idata$5 is one word long, and has an
2569 si
->data
= xmalloc (8);
2573 si
->data
[0] = exp
->ordinal
;
2574 si
->data
[1] = exp
->ordinal
>> 8;
2575 si
->data
[2] = exp
->ordinal
>> 16;
2576 si
->data
[3] = exp
->ordinal
>> 24;
2584 sec
->reloc_count
= 1;
2585 memset (si
->data
, 0, si
->size
);
2586 rel
= xmalloc (sizeof (arelent
));
2587 rpp
= xmalloc (sizeof (arelent
*) * 2);
2592 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2593 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2594 sec
->orelocation
= rpp
;
2599 si
->data
= xmalloc (4);
2604 si
->data
[0] = exp
->ordinal
;
2605 si
->data
[1] = exp
->ordinal
>> 8;
2606 si
->data
[2] = exp
->ordinal
>> 16;
2611 sec
->reloc_count
= 1;
2612 memset (si
->data
, 0, si
->size
);
2613 rel
= xmalloc (sizeof (arelent
));
2614 rpp
= xmalloc (sizeof (arelent
*) * 2);
2619 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2620 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2621 sec
->orelocation
= rpp
;
2629 /* This used to add 1 to exp->hint. I don't know
2630 why it did that, and it does not match what I see
2631 in programs compiled with the MS tools. */
2632 int idx
= exp
->hint
;
2634 si
->size
= strlen (exp
->its_name
) + 3;
2636 si
->size
= strlen (xlate (exp
->import_name
)) + 3;
2637 si
->data
= xmalloc (si
->size
);
2638 memset (si
->data
, 0, si
->size
);
2639 si
->data
[0] = idx
& 0xff;
2640 si
->data
[1] = idx
>> 8;
2642 strcpy ((char *) si
->data
+ 2, exp
->its_name
);
2644 strcpy ((char *) si
->data
+ 2, xlate (exp
->import_name
));
2651 si
->data
= xmalloc (4);
2652 memset (si
->data
, 0, si
->size
);
2653 rel
= xmalloc (sizeof (arelent
));
2654 rpp
= xmalloc (sizeof (arelent
*) * 2);
2658 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2659 rel
->sym_ptr_ptr
= iname_lab_pp
;
2660 sec
->orelocation
= rpp
;
2661 sec
->reloc_count
= 1;
2668 /* Size up all the sections. */
2669 for (i
= 0; i
< NSECS
; i
++)
2671 sinfo
*si
= secdata
+ i
;
2673 bfd_set_section_size (si
->sec
, si
->size
);
2674 bfd_set_section_vma (si
->sec
, vma
);
2677 /* Write them out. */
2678 for (i
= 0; i
< NSECS
; i
++)
2680 sinfo
*si
= secdata
+ i
;
2682 if (i
== IDATA5
&& no_idata5
)
2685 if (i
== IDATA4
&& no_idata4
)
2688 bfd_set_section_contents (abfd
, si
->sec
,
2693 bfd_set_symtab (abfd
, ptrs
, oidx
);
2695 abfd
= bfd_openr (outname
, HOW_BFD_READ_TARGET
);
2697 /* xgettext:c-format */
2698 fatal (_("bfd_open failed reopen stub file: %s: %s"),
2699 outname
, bfd_get_errmsg ());
2707 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2712 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2716 temp_file_to_remove
[TEMP_HEAD_FILE
] = TMP_HEAD_S
;
2718 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2719 fprintf (f
, "\t.section\t.idata$2\n");
2721 fprintf (f
, "\t%s\t%s\n", ASM_GLOBAL
, head_label
);
2723 fprintf (f
, "%s:\n", head_label
);
2725 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2726 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2728 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2729 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2730 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2731 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2732 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2737 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2739 ASM_RVA_AFTER
, ASM_C
);
2741 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2745 fprintf (f
, "\t.section\t.idata$5\n");
2746 if (use_nul_prefixed_import_tables
)
2749 fprintf (f
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2751 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2753 fprintf (f
, "fthunk:\n");
2758 fprintf (f
, "\t.section\t.idata$4\n");
2759 if (use_nul_prefixed_import_tables
)
2762 fprintf (f
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2764 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2766 fprintf (f
, "hname:\n");
2771 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2773 abfd
= bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2775 /* xgettext:c-format */
2776 fatal (_("failed to open temporary head file: %s: %s"),
2777 TMP_HEAD_O
, bfd_get_errmsg ());
2779 temp_file_to_remove
[TEMP_HEAD_O_FILE
] = TMP_HEAD_O
;
2784 make_delay_head (void)
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 /* Output the __tailMerge__xxx function */
2798 fprintf (f
, "%s Import trampoline\n", ASM_C
);
2799 fprintf (f
, "\t.section\t.text\n");
2800 fprintf (f
, "\t%s\t%s\n", ASM_GLOBAL
, head_label
);
2802 fprintf (f
, "\t.seh_proc\t%s\n", head_label
);
2803 fprintf (f
, "%s:\n", head_label
);
2804 fprintf (f
, mtable
[machine
].trampoline
, imp_name_lab
);
2806 fprintf (f
, "\t.seh_endproc\n");
2808 /* Output the delay import descriptor */
2809 fprintf (f
, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C
);
2810 fprintf (f
, ".section\t.text$2\n");
2811 fprintf (f
, "%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL
,imp_name_lab
);
2812 fprintf (f
, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab
);
2813 fprintf (f
, "\t%s 1\t%s grAttrs\n", ASM_LONG
, ASM_C
);
2814 fprintf (f
, "\t%s__%s_iname%s\t%s rvaDLLName\n",
2815 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2816 fprintf (f
, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
2817 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2818 fprintf (f
, "\t%s__IAT_%s%s\t%s rvaIAT\n",
2819 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2820 fprintf (f
, "\t%s__INT_%s%s\t%s rvaINT\n",
2821 ASM_RVA_BEFORE
, imp_name_lab
, ASM_RVA_AFTER
, ASM_C
);
2822 fprintf (f
, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG
, ASM_C
);
2823 fprintf (f
, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG
, ASM_C
);
2824 fprintf (f
, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG
, ASM_C
);
2826 /* Output the dll_handle */
2827 fprintf (f
, "\n.section .data\n");
2828 fprintf (f
, "__DLL_HANDLE_%s:\n", imp_name_lab
);
2829 fprintf (f
, "\t%s\t0\t%s Handle\n", ASM_LONG
, ASM_C
);
2831 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2834 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2838 fprintf (f
, "\t.section\t.idata$5\n");
2839 /* NULL terminating list. */
2841 fprintf (f
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2843 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2844 fprintf (f
, "__IAT_%s:\n", imp_name_lab
);
2849 fprintf (f
, "\t.section\t.idata$4\n");
2850 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2852 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2853 fprintf (f
, "\t.section\t.idata$4\n");
2854 fprintf (f
, "__INT_%s:\n", imp_name_lab
);
2857 fprintf (f
, "\t.section\t.idata$2\n");
2861 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2863 abfd
= bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2865 /* xgettext:c-format */
2866 fatal (_("failed to open temporary head file: %s: %s"),
2867 TMP_HEAD_O
, bfd_get_errmsg ());
2869 temp_file_to_remove
[TEMP_HEAD_O_FILE
] = TMP_HEAD_O
;
2876 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2881 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2885 temp_file_to_remove
[TEMP_TAIL_FILE
] = TMP_TAIL_S
;
2889 fprintf (f
, "\t.section\t.idata$4\n");
2891 fprintf (f
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2893 fprintf (f
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
2898 fprintf (f
, "\t.section\t.idata$5\n");
2900 fprintf (f
, "\t%s\t0\n\t%s\t0\n", ASM_LONG
, ASM_LONG
);
2902 fprintf (f
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list. */
2905 fprintf (f
, "\t.section\t.idata$7\n");
2906 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2907 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2908 imp_name_lab
, ASM_TEXT
, dll_name
);
2912 assemble_file (TMP_TAIL_S
, TMP_TAIL_O
);
2914 abfd
= bfd_openr (TMP_TAIL_O
, HOW_BFD_READ_TARGET
);
2916 /* xgettext:c-format */
2917 fatal (_("failed to open temporary tail file: %s: %s"),
2918 TMP_TAIL_O
, bfd_get_errmsg ());
2920 temp_file_to_remove
[TEMP_TAIL_O_FILE
] = TMP_TAIL_O
;
2925 gen_lib_file (int delay
)
2936 outarch
= bfd_openw (imp_name
, HOW_BFD_WRITE_TARGET
);
2939 /* xgettext:c-format */
2940 fatal (_("Can't create .lib file: %s: %s"),
2941 imp_name
, bfd_get_errmsg ());
2943 /* xgettext:c-format */
2944 inform (_("Creating library file: %s"), imp_name
);
2946 xatexit (unlink_temp_files
);
2948 bfd_set_format (outarch
, bfd_archive
);
2949 outarch
->has_armap
= 1;
2950 outarch
->is_thin_archive
= 0;
2953 outarch
->flags
|= BFD_DETERMINISTIC_OUTPUT
;
2955 /* Work out a reasonable size of things to put onto one line. */
2958 ar_head
= make_delay_head ();
2962 ar_head
= make_head ();
2964 ar_tail
= make_tail();
2966 if (ar_head
== NULL
|| ar_tail
== NULL
)
2969 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2972 /* Don't add PRIVATE entries to import lib. */
2975 n
= make_one_lib_file (exp
, i
, delay
);
2976 n
->archive_next
= head
;
2978 if (ext_prefix_alias
)
2980 export_type alias_exp
;
2982 assert (i
< PREFIX_ALIAS_BASE
);
2983 alias_exp
.name
= make_imp_label (ext_prefix_alias
, exp
->name
);
2984 alias_exp
.internal_name
= exp
->internal_name
;
2985 alias_exp
.its_name
= exp
->its_name
;
2986 alias_exp
.import_name
= exp
->name
;
2987 alias_exp
.ordinal
= exp
->ordinal
;
2988 alias_exp
.constant
= exp
->constant
;
2989 alias_exp
.noname
= exp
->noname
;
2990 alias_exp
.private = exp
->private;
2991 alias_exp
.data
= exp
->data
;
2992 alias_exp
.hint
= exp
->hint
;
2993 alias_exp
.forward
= exp
->forward
;
2994 alias_exp
.next
= exp
->next
;
2995 n
= make_one_lib_file (&alias_exp
, i
+ PREFIX_ALIAS_BASE
, delay
);
2996 n
->archive_next
= head
;
3001 /* Now stick them all into the archive. */
3002 ar_head
->archive_next
= head
;
3003 ar_tail
->archive_next
= ar_head
;
3006 if (! bfd_set_archive_head (outarch
, head
))
3007 bfd_fatal ("bfd_set_archive_head");
3009 if (! bfd_close (outarch
))
3010 bfd_fatal (imp_name
);
3012 while (head
!= NULL
)
3014 bfd
*n
= head
->archive_next
;
3019 /* Delete all the temp files. */
3020 unlink_temp_files ();
3022 if (dontdeltemps
< 2)
3024 char *name
= TMP_STUB
;
3025 size_t name_len
= strlen (name
);
3027 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
3029 /* Don't delete non-existent stubs for PRIVATE entries. */
3032 sprintf (name
+ name_len
- 7, "%05d.o", i
);
3033 if (unlink (name
) < 0)
3034 /* xgettext:c-format */
3035 non_fatal (_("cannot delete %s: %s"), name
, strerror (errno
));
3036 if (ext_prefix_alias
)
3038 sprintf (name
+ name_len
- 7, "%05d.o", i
+ PREFIX_ALIAS_BASE
);
3039 if (unlink (name
) < 0)
3040 /* xgettext:c-format */
3041 non_fatal (_("cannot delete %s: %s"), name
, strerror (errno
));
3046 inform (_("Created lib file"));
3049 /* Append a copy of data (cast to char *) to list. */
3052 dll_name_list_append (dll_name_list_type
* list
, bfd_byte
* data
)
3054 dll_name_list_node_type
* entry
;
3056 /* Error checking. */
3057 if (! list
|| ! list
->tail
)
3060 /* Allocate new node. */
3061 entry
= ((dll_name_list_node_type
*)
3062 xmalloc (sizeof (dll_name_list_node_type
)));
3064 /* Initialize its values. */
3065 entry
->dllname
= xstrdup ((char *) data
);
3068 /* Add to tail, and move tail. */
3069 list
->tail
->next
= entry
;
3073 /* Count the number of entries in list. */
3076 dll_name_list_count (dll_name_list_type
* list
)
3078 dll_name_list_node_type
* p
;
3081 /* Error checking. */
3082 if (! list
|| ! list
->head
)
3087 while (p
&& p
->next
)
3095 /* Print each entry in list to stdout. */
3098 dll_name_list_print (dll_name_list_type
* list
)
3100 dll_name_list_node_type
* p
;
3102 /* Error checking. */
3103 if (! list
|| ! list
->head
)
3108 while (p
&& p
->next
&& p
->next
->dllname
&& *p
->next
->dllname
)
3110 printf ("%s\n", p
->next
->dllname
);
3115 /* Free all entries in list, and list itself. */
3118 dll_name_list_free (dll_name_list_type
* list
)
3122 dll_name_list_free_contents (list
->head
);
3129 /* Recursive function to free all nodes entry->next->next...
3130 as well as entry itself. */
3133 dll_name_list_free_contents (dll_name_list_node_type
* entry
)
3138 dll_name_list_free_contents (entry
->next
);
3139 free (entry
->dllname
);
3144 /* Allocate and initialize a dll_name_list_type object,
3145 including its sentinel node. Caller is responsible
3146 for calling dll_name_list_free when finished with
3149 static dll_name_list_type
*
3150 dll_name_list_create (void)
3152 /* Allocate list. */
3153 dll_name_list_type
* list
= xmalloc (sizeof (dll_name_list_type
));
3155 /* Allocate and initialize sentinel node. */
3156 list
->head
= xmalloc (sizeof (dll_name_list_node_type
));
3157 list
->head
->dllname
= NULL
;
3158 list
->head
->next
= NULL
;
3160 /* Bookkeeping for empty list. */
3161 list
->tail
= list
->head
;
3166 /* Search the symbol table of the suppled BFD for a symbol whose name matches
3167 OBJ (where obj is cast to const char *). If found, set global variable
3168 identify_member_contains_symname_result TRUE. It is the caller's
3169 responsibility to set the result variable FALSE before iterating with
3173 identify_member_contains_symname (bfd
* abfd
,
3174 bfd
* archive_bfd ATTRIBUTE_UNUSED
,
3177 long storage_needed
;
3178 asymbol
** symbol_table
;
3179 long number_of_symbols
;
3181 symname_search_data_type
* search_data
= (symname_search_data_type
*) obj
;
3183 /* If we already found the symbol in a different member,
3185 if (search_data
->found
)
3188 storage_needed
= bfd_get_symtab_upper_bound (abfd
);
3189 if (storage_needed
<= 0)
3192 symbol_table
= xmalloc (storage_needed
);
3193 number_of_symbols
= bfd_canonicalize_symtab (abfd
, symbol_table
);
3194 if (number_of_symbols
< 0)
3196 free (symbol_table
);
3200 for (i
= 0; i
< number_of_symbols
; i
++)
3202 if (strncmp (symbol_table
[i
]->name
,
3203 search_data
->symname
,
3204 strlen (search_data
->symname
)) == 0)
3206 search_data
->found
= true;
3210 free (symbol_table
);
3213 /* This is the main implementation for the --identify option.
3214 Given the name of an import library in identify_imp_name, first
3215 determine if the import library is a GNU binutils-style one (where
3216 the DLL name is stored in an .idata$7 section), or if it is a
3217 MS-style one (where the DLL name, along with much other data, is
3218 stored in the .idata$6 section). We determine the style of import
3219 library by searching for the DLL-structure symbol inserted by MS
3220 tools: __NULL_IMPORT_DESCRIPTOR.
3222 Once we know which section to search, evaluate each section for the
3223 appropriate properties that indicate it may contain the name of the
3224 associated DLL (this differs depending on the style). Add the contents
3225 of all sections which meet the criteria to a linked list of dll names.
3227 Finally, print them all to stdout. (If --identify-strict, an error is
3228 reported if more than one match was found). */
3231 identify_dll_for_implib (void)
3235 identify_data_type identify_data
;
3236 symname_search_data_type search_data
;
3238 /* Initialize identify_data. */
3239 identify_data
.list
= dll_name_list_create ();
3240 identify_data
.ms_style_implib
= false;
3242 /* Initialize search_data. */
3243 search_data
.symname
= "__NULL_IMPORT_DESCRIPTOR";
3244 search_data
.found
= false;
3246 if (bfd_init () != BFD_INIT_MAGIC
)
3247 fatal (_("fatal error: libbfd ABI mismatch"));
3249 abfd
= bfd_openr (identify_imp_name
, 0);
3251 /* xgettext:c-format */
3252 fatal (_("Can't open .lib file: %s: %s"),
3253 identify_imp_name
, bfd_get_errmsg ());
3255 if (! bfd_check_format (abfd
, bfd_archive
))
3257 if (! bfd_close (abfd
))
3258 bfd_fatal (identify_imp_name
);
3260 fatal (_("%s is not a library"), identify_imp_name
);
3263 /* Detect if this a Microsoft import library. */
3264 identify_search_archive (abfd
,
3265 identify_member_contains_symname
,
3266 (void *) &search_data
);
3267 if (search_data
.found
)
3268 identify_data
.ms_style_implib
= true;
3270 /* Rewind the bfd. */
3271 if (! bfd_close (abfd
))
3272 bfd_fatal (identify_imp_name
);
3273 abfd
= bfd_openr (identify_imp_name
, 0);
3275 bfd_fatal (identify_imp_name
);
3277 if (!bfd_check_format (abfd
, bfd_archive
))
3279 if (!bfd_close (abfd
))
3280 bfd_fatal (identify_imp_name
);
3282 fatal (_("%s is not a library"), identify_imp_name
);
3285 /* Now search for the dll name. */
3286 identify_search_archive (abfd
,
3287 identify_search_member
,
3288 (void *) &identify_data
);
3290 if (! bfd_close (abfd
))
3291 bfd_fatal (identify_imp_name
);
3293 count
= dll_name_list_count (identify_data
.list
);
3296 if (identify_strict
&& count
> 1)
3298 dll_name_list_free (identify_data
.list
);
3299 identify_data
.list
= NULL
;
3300 fatal (_("Import library `%s' specifies two or more dlls"),
3303 dll_name_list_print (identify_data
.list
);
3304 dll_name_list_free (identify_data
.list
);
3305 identify_data
.list
= NULL
;
3309 dll_name_list_free (identify_data
.list
);
3310 identify_data
.list
= NULL
;
3311 fatal (_("Unable to determine dll name for `%s' (not an import library?)"),
3316 /* Loop over all members of the archive, applying the supplied function to
3317 each member that is a bfd_object. The function will be called as if:
3318 func (member_bfd, abfd, user_storage) */
3321 identify_search_archive (bfd
* abfd
,
3322 void (* operation
) (bfd
*, bfd
*, void *),
3323 void * user_storage
)
3325 bfd
* arfile
= NULL
;
3326 bfd
* last_arfile
= NULL
;
3331 arfile
= bfd_openr_next_archived_file (abfd
, arfile
);
3335 if (bfd_get_error () != bfd_error_no_more_archived_files
)
3336 bfd_fatal (bfd_get_filename (abfd
));
3340 if (bfd_check_format_matches (arfile
, bfd_object
, &matching
))
3341 (*operation
) (arfile
, abfd
, user_storage
);
3344 bfd_nonfatal (bfd_get_filename (arfile
));
3348 if (last_arfile
!= NULL
)
3350 bfd_close (last_arfile
);
3351 /* PR 17512: file: 8b2168d4. */
3352 if (last_arfile
== arfile
)
3359 last_arfile
= arfile
;
3362 if (last_arfile
!= NULL
)
3364 bfd_close (last_arfile
);
3368 /* Call the identify_search_section() function for each section of this
3372 identify_search_member (bfd
*abfd
,
3373 bfd
*archive_bfd ATTRIBUTE_UNUSED
,
3376 bfd_map_over_sections (abfd
, identify_search_section
, obj
);
3379 /* This predicate returns true if section->name matches the desired value.
3380 By default, this is .idata$7 (.idata$6 if the import library is
3384 identify_process_section_p (asection
* section
, bool ms_style_implib
)
3386 static const char * SECTION_NAME
= ".idata$7";
3387 static const char * MS_SECTION_NAME
= ".idata$6";
3389 const char * section_name
=
3390 (ms_style_implib
? MS_SECTION_NAME
: SECTION_NAME
);
3392 if (strcmp (section_name
, section
->name
) == 0)
3397 /* If *section has contents and its name is .idata$7 (.idata$6 if
3398 import lib ms-generated) -- and it satisfies several other constraints
3399 -- then add the contents of the section to obj->list. */
3402 identify_search_section (bfd
* abfd
, asection
* section
, void * obj
)
3405 bfd_size_type datasize
;
3406 identify_data_type
* identify_data
= (identify_data_type
*)obj
;
3407 bool ms_style
= identify_data
->ms_style_implib
;
3409 if ((section
->flags
& SEC_HAS_CONTENTS
) == 0)
3412 if (! identify_process_section_p (section
, ms_style
))
3415 /* Binutils import libs seem distinguish the .idata$7 section that contains
3416 the DLL name from other .idata$7 sections by the absence of the
3418 if (!ms_style
&& ((section
->flags
& SEC_RELOC
) == SEC_RELOC
))
3421 /* MS import libs seem to distinguish the .idata$6 section
3422 that contains the DLL name from other .idata$6 sections
3423 by the presence of the SEC_DATA flag. */
3424 if (ms_style
&& ((section
->flags
& SEC_DATA
) == 0))
3427 if ((datasize
= bfd_section_size (section
)) == 0)
3430 data
= (bfd_byte
*) xmalloc (datasize
+ 1);
3433 bfd_get_section_contents (abfd
, section
, data
, 0, datasize
);
3434 data
[datasize
] = '\0';
3436 /* Use a heuristic to determine if data is a dll name.
3437 Possible to defeat this if (a) the library has MANY
3438 (more than 0x302f) imports, (b) it is an ms-style
3439 import library, but (c) it is buggy, in that the SEC_DATA
3440 flag is set on the "wrong" sections. This heuristic might
3441 also fail to record a valid dll name if the dllname uses
3442 a multibyte or unicode character set (is that valid?).
3444 This heuristic is based on the fact that symbols names in
3445 the chosen section -- as opposed to the dll name -- begin
3446 at offset 2 in the data. The first two bytes are a 16bit
3447 little-endian count, and start at 0x0000. However, the dll
3448 name begins at offset 0 in the data. We assume that the
3449 dll name does not contain unprintable characters. */
3450 if (data
[0] != '\0' && ISPRINT (data
[0])
3451 && (datasize
< 2 || ISPRINT (data
[1])))
3452 dll_name_list_append (identify_data
->list
, data
);
3457 /* Run through the information gathered from the .o files and the
3458 .def file and work out the best stuff. */
3461 pfunc (const void *a
, const void *b
)
3463 export_type
*ap
= *(export_type
**) a
;
3464 export_type
*bp
= *(export_type
**) b
;
3466 if (ap
->ordinal
== bp
->ordinal
)
3469 /* Unset ordinals go to the bottom. */
3470 if (ap
->ordinal
== -1)
3472 if (bp
->ordinal
== -1)
3474 return (ap
->ordinal
- bp
->ordinal
);
3478 nfunc (const void *a
, const void *b
)
3480 export_type
*ap
= *(export_type
**) a
;
3481 export_type
*bp
= *(export_type
**) b
;
3482 const char *an
= ap
->name
;
3483 const char *bn
= bp
->name
;
3490 an
= (an
[0] == '@') ? an
+ 1 : an
;
3491 bn
= (bn
[0] == '@') ? bn
+ 1 : bn
;
3494 return (strcmp (an
, bn
));
3498 remove_null_names (export_type
**ptr
)
3503 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
3507 ptr
[dst
] = ptr
[src
];
3515 process_duplicates (export_type
**d_export_vec
)
3523 /* Remove duplicates. */
3524 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
3526 for (i
= 0; i
< d_nfuncs
- 1; i
++)
3528 if (strcmp (d_export_vec
[i
]->name
,
3529 d_export_vec
[i
+ 1]->name
) == 0)
3531 export_type
*a
= d_export_vec
[i
];
3532 export_type
*b
= d_export_vec
[i
+ 1];
3536 /* xgettext:c-format */
3537 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3538 a
->name
, a
->ordinal
, b
->ordinal
);
3540 if (a
->ordinal
!= -1
3541 && b
->ordinal
!= -1)
3542 /* xgettext:c-format */
3543 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3546 /* Merge attributes. */
3547 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
3548 b
->constant
|= a
->constant
;
3549 b
->noname
|= a
->noname
;
3551 d_export_vec
[i
] = 0;
3554 remove_null_names (d_export_vec
);
3558 /* Count the names. */
3559 for (i
= 0; i
< d_nfuncs
; i
++)
3560 if (!d_export_vec
[i
]->noname
)
3565 fill_ordinals (export_type
**d_export_vec
)
3572 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3574 /* Fill in the unset ordinals with ones from our range. */
3575 ptr
= (char *) xmalloc (size
);
3577 memset (ptr
, 0, size
);
3579 /* Mark in our large vector all the numbers that are taken. */
3580 for (i
= 0; i
< d_nfuncs
; i
++)
3582 if (d_export_vec
[i
]->ordinal
!= -1)
3584 ptr
[d_export_vec
[i
]->ordinal
] = 1;
3586 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
3587 lowest
= d_export_vec
[i
]->ordinal
;
3591 /* Start at 1 for compatibility with MS toolchain. */
3595 /* Now fill in ordinals where the user wants us to choose. */
3596 for (i
= 0; i
< d_nfuncs
; i
++)
3598 if (d_export_vec
[i
]->ordinal
== -1)
3602 /* First try within or after any user supplied range. */
3603 for (j
= lowest
; j
< size
; j
++)
3607 d_export_vec
[i
]->ordinal
= j
;
3611 /* Then try before the range. */
3612 for (j
= lowest
; j
>0; j
--)
3616 d_export_vec
[i
]->ordinal
= j
;
3626 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3628 /* Work out the lowest and highest ordinal numbers. */
3631 if (d_export_vec
[0])
3632 d_low_ord
= d_export_vec
[0]->ordinal
;
3633 if (d_export_vec
[d_nfuncs
-1])
3634 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3641 /* First work out the minimum ordinal chosen. */
3646 export_type
**d_export_vec
= xmalloc (sizeof (export_type
*) * d_nfuncs
);
3648 inform (_("Processing definitions"));
3650 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3651 d_export_vec
[i
] = exp
;
3653 process_duplicates (d_export_vec
);
3654 fill_ordinals (d_export_vec
);
3656 /* Put back the list in the new order. */
3658 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3660 d_export_vec
[i
]->next
= d_exports
;
3661 d_exports
= d_export_vec
[i
];
3664 /* Build list in alpha order. */
3665 d_exports_lexically
= (export_type
**)
3666 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3668 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3669 d_exports_lexically
[i
] = exp
;
3671 d_exports_lexically
[i
] = 0;
3673 qsort (d_exports_lexically
, i
, sizeof (export_type
*), nfunc
);
3675 /* Fill exp entries with their hint values. */
3676 for (i
= 0; i
< d_nfuncs
; i
++)
3677 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3678 d_exports_lexically
[i
]->hint
= hint
++;
3680 inform (_("Processed definitions"));
3684 usage (FILE *file
, int status
)
3686 /* xgetext:c-format */
3687 fprintf (file
, _("Usage %s <option(s)> <object-file(s)>\n"), program_name
);
3688 /* xgetext:c-format */
3689 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3690 fprintf (file
, _(" possible <machine>: arm[_interwork], arm64, i386, mcore[-elf]{-le|-be}, thumb\n"));
3691 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3692 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3693 fprintf (file
, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
3694 fprintf (file
, _(" --deterministic-libraries\n"));
3695 if (DEFAULT_AR_DETERMINISTIC
)
3696 fprintf (file
, _(" Use zero for timestamps and uids/gids in output libraries (default)\n"));
3698 fprintf (file
, _(" Use zero for timestamps and uids/gids in output libraries\n"));
3699 fprintf (file
, _(" --non-deterministic-libraries\n"));
3700 if (DEFAULT_AR_DETERMINISTIC
)
3701 fprintf (file
, _(" Use actual timestamps and uids/gids in output libraries\n"));
3703 fprintf (file
, _(" Use actual timestamps and uids/gids in output libraries (default)\n"));
3704 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3705 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3706 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3707 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3708 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3709 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3710 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3711 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3712 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3713 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3714 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3715 fprintf (file
, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3716 fprintf (file
, _(" -U --add-underscore Add underscores to all symbols in interface library.\n"));
3717 fprintf (file
, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3718 fprintf (file
, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n"));
3719 fprintf (file
, _(" --leading-underscore All symbols should be prefixed by an underscore.\n"));
3720 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3721 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3722 fprintf (file
, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3723 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3724 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3725 fprintf (file
, _(" -C --compat-implib Create backward compatible import library.\n"));
3726 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3727 fprintf (file
, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3728 fprintf (file
, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
3729 fprintf (file
, _(" --identify-strict Causes --identify to report error when multiple DLLs.\n"));
3730 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3731 fprintf (file
, _(" -V --version Display the program version.\n"));
3732 fprintf (file
, _(" -h --help Display this information.\n"));
3733 fprintf (file
, _(" @<file> Read options from <file>.\n"));
3734 #ifdef DLLTOOL_MCORE_ELF
3735 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3736 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3737 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3739 if (REPORT_BUGS_TO
[0] && status
== 0)
3740 fprintf (file
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
3744 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
3745 enum command_line_switch
3747 OPTION_EXPORT_ALL_SYMS
= 150,
3748 OPTION_NO_EXPORT_ALL_SYMS
,
3749 OPTION_EXCLUDE_SYMS
,
3750 OPTION_NO_DEFAULT_EXCLUDES
,
3751 OPTION_ADD_STDCALL_UNDERSCORE
,
3752 OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
,
3753 OPTION_IDENTIFY_STRICT
,
3754 OPTION_NO_LEADING_UNDERSCORE
,
3755 OPTION_LEADING_UNDERSCORE
,
3756 OPTION_DETERMINISTIC_LIBRARIES
,
3757 OPTION_NON_DETERMINISTIC_LIBRARIES
3760 static const struct option long_options
[] =
3762 {"add-indirect", no_argument
, NULL
, 'a'},
3763 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3764 {"add-stdcall-underscore", no_argument
, NULL
, OPTION_ADD_STDCALL_UNDERSCORE
},
3765 {"add-underscore", no_argument
, NULL
, 'U'},
3766 {"as", required_argument
, NULL
, 'S'},
3767 {"as-flags", required_argument
, NULL
, 'f'},
3768 {"base-file", required_argument
, NULL
, 'b'},
3769 {"compat-implib", no_argument
, NULL
, 'C'},
3770 {"def", required_argument
, NULL
, 'd'}, /* For compatibility with older versions. */
3771 {"deterministic-libraries", no_argument
, NULL
, OPTION_DETERMINISTIC_LIBRARIES
},
3772 {"dllname", required_argument
, NULL
, 'D'},
3773 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3774 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3775 {"ext-prefix-alias", required_argument
, NULL
, 'p'},
3776 {"help", no_argument
, NULL
, 'h'},
3777 {"identify", required_argument
, NULL
, 'I'},
3778 {"identify-strict", no_argument
, NULL
, OPTION_IDENTIFY_STRICT
},
3779 {"input-def", required_argument
, NULL
, 'd'},
3780 {"kill-at", no_argument
, NULL
, 'k'},
3781 {"leading-underscore", no_argument
, NULL
, OPTION_LEADING_UNDERSCORE
},
3782 {"machine", required_argument
, NULL
, 'm'},
3783 {"mcore-elf", required_argument
, NULL
, 'M'},
3784 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3785 {"no-delete", no_argument
, NULL
, 'n'},
3786 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3787 {"no-idata4", no_argument
, NULL
, 'x'},
3788 {"no-idata5", no_argument
, NULL
, 'c'},
3789 {"no-leading-underscore", no_argument
, NULL
, OPTION_NO_LEADING_UNDERSCORE
},
3790 {"non-deterministic-libraries", no_argument
, NULL
, OPTION_NON_DETERMINISTIC_LIBRARIES
},
3791 {"output-def", required_argument
, NULL
, 'z'},
3792 {"output-delaylib", required_argument
, NULL
, 'y'},
3793 {"output-exp", required_argument
, NULL
, 'e'},
3794 {"output-lib", required_argument
, NULL
, 'l'},
3795 {"temp-prefix", required_argument
, NULL
, 't'},
3796 {"use-nul-prefixed-import-tables", no_argument
, NULL
, OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
},
3797 {"verbose", no_argument
, NULL
, 'v'},
3798 {"version", no_argument
, NULL
, 'V'},
3802 int main (int, char **);
3805 main (int ac
, char **av
)
3810 program_name
= av
[0];
3813 #ifdef HAVE_LC_MESSAGES
3814 setlocale (LC_MESSAGES
, "");
3816 setlocale (LC_CTYPE
, "");
3817 bindtextdomain (PACKAGE
, LOCALEDIR
);
3818 textdomain (PACKAGE
);
3820 bfd_set_error_program_name (program_name
);
3821 expandargv (&ac
, &av
);
3823 while ((c
= getopt_long (ac
, av
,
3824 #ifdef DLLTOOL_MCORE_ELF
3825 "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:",
3827 "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh",
3834 case OPTION_EXPORT_ALL_SYMS
:
3835 export_all_symbols
= true;
3837 case OPTION_NO_EXPORT_ALL_SYMS
:
3838 export_all_symbols
= false;
3840 case OPTION_EXCLUDE_SYMS
:
3841 add_excludes (optarg
);
3843 case OPTION_NO_DEFAULT_EXCLUDES
:
3844 do_default_excludes
= false;
3846 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES
:
3847 use_nul_prefixed_import_tables
= true;
3849 case OPTION_ADD_STDCALL_UNDERSCORE
:
3850 add_stdcall_underscore
= 1;
3852 case OPTION_NO_LEADING_UNDERSCORE
:
3853 leading_underscore
= "";
3855 case OPTION_LEADING_UNDERSCORE
:
3856 leading_underscore
= "_";
3858 case OPTION_IDENTIFY_STRICT
:
3859 identify_strict
= 1;
3871 tmp_prefix
= optarg
;
3877 /* Ignored for compatibility. */
3884 output_def
= fopen (optarg
, FOPEN_WT
);
3886 /* xgettext:c-format */
3887 fatal (_("Unable to open def-file: %s"), optarg
);
3890 dll_name
= (char*) lbasename (optarg
);
3891 if (dll_name
!= optarg
)
3892 non_fatal (_("Path components stripped from dllname, '%s'."),
3909 identify_imp_name
= optarg
;
3915 print_version (program_name
);
3924 add_stdcall_alias
= 1;
3927 ext_prefix_alias
= optarg
;
3936 base_file
= fopen (optarg
, FOPEN_RB
);
3939 /* xgettext:c-format */
3940 fatal (_("Unable to open base-file: %s"), optarg
);
3943 #ifdef DLLTOOL_MCORE_ELF
3945 mcore_elf_out_file
= optarg
;
3948 mcore_elf_linker
= optarg
;
3951 mcore_elf_linker_flags
= optarg
;
3955 create_compat_implib
= 1;
3958 delayimp_name
= optarg
;
3960 case OPTION_DETERMINISTIC_LIBRARIES
:
3961 deterministic
= true;
3963 case OPTION_NON_DETERMINISTIC_LIBRARIES
:
3964 deterministic
= false;
3972 for (i
= 0; mtable
[i
].type
; i
++)
3973 if (strcmp (mtable
[i
].type
, mname
) == 0)
3976 if (!mtable
[i
].type
)
3977 /* xgettext:c-format */
3978 fatal (_("Machine '%s' not supported"), mname
);
3982 /* Check if we generated PE+. */
3983 create_for_pep
= (strcmp (mname
, "i386:x86-64") == 0
3984 || strcmp (mname
, "arm64") == 0);
3986 /* Check the default underscore */
3987 if (leading_underscore
== NULL
)
3990 static char underscore
[2];
3991 bfd_get_target_info (mtable
[machine
].how_bfd_target
, NULL
,
3997 leading_underscore
= underscore
;
4000 if (!dll_name
&& exp_name
)
4002 /* If we are inferring dll_name from exp_name,
4003 strip off any path components, without emitting
4005 const char* exp_basename
= lbasename (exp_name
);
4006 const int len
= strlen (exp_basename
) + 5;
4007 dll_name
= xmalloc (len
);
4008 strcpy (dll_name
, exp_basename
);
4009 strcat (dll_name
, ".dll");
4010 dll_name_set_by_exp_name
= 1;
4013 if (as_name
== NULL
)
4014 as_name
= deduce_name ("as");
4016 /* Don't use the default exclude list if we're reading only the
4017 symbols in the .drectve section. The default excludes are meant
4018 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
4019 if (! export_all_symbols
)
4020 do_default_excludes
= false;
4022 if (do_default_excludes
)
4023 set_default_excludes ();
4026 process_def_file (def_file
);
4031 firstarg
= av
[optind
];
4032 scan_obj_file (av
[optind
]);
4036 if (tmp_prefix
== NULL
)
4038 /* If possible use a deterministic prefix. */
4039 const char *input
= imp_name
? imp_name
: delayimp_name
;
4040 if (input
&& strlen (input
) + sizeof ("_snnnnn.o") - 1 <= NAME_MAX
)
4042 tmp_prefix
= xmalloc (strlen (input
) + 2);
4043 sprintf (tmp_prefix
, "%s_", input
);
4044 for (i
= 0; tmp_prefix
[i
]; i
++)
4045 if (!ISALNUM (tmp_prefix
[i
]))
4046 tmp_prefix
[i
] = '_';
4049 tmp_prefix
= prefix_encode ("d", getpid ());
4059 /* Make imp_name safe for use as a label. */
4062 imp_name_lab
= xstrdup (imp_name
);
4063 for (p
= imp_name_lab
; *p
; p
++)
4068 head_label
= make_label("_head_", imp_name_lab
);
4074 /* Make delayimp_name safe for use as a label. */
4077 if (mtable
[machine
].how_dljtab
== 0)
4079 inform (_("Warning, machine type (%d) not supported for "
4080 "delayimport."), machine
);
4085 imp_name
= delayimp_name
;
4086 imp_name_lab
= xstrdup (imp_name
);
4087 for (p
= imp_name_lab
; *p
; p
++)
4092 head_label
= make_label("__tailMerge_", imp_name_lab
);
4100 if (identify_imp_name
)
4102 identify_dll_for_implib ();
4105 #ifdef DLLTOOL_MCORE_ELF
4106 if (mcore_elf_out_file
)
4107 mcore_elf_gen_out_file ();
4113 /* Look for the program formed by concatenating PROG_NAME and the
4114 string running from PREFIX to END_PREFIX. If the concatenated
4115 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
4119 look_for_prog (const char *prog_name
, const char *prefix
, int end_prefix
)
4124 cmd
= xmalloc (strlen (prefix
)
4125 + strlen (prog_name
)
4126 #ifdef HAVE_EXECUTABLE_SUFFIX
4127 + strlen (EXECUTABLE_SUFFIX
)
4130 memcpy (cmd
, prefix
, end_prefix
);
4132 strcpy (cmd
+ end_prefix
, prog_name
);
4134 if (strchr (cmd
, '/') != NULL
)
4138 found
= (stat (cmd
, &s
) == 0
4139 #ifdef HAVE_EXECUTABLE_SUFFIX
4140 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
4146 /* xgettext:c-format */
4147 inform (_("Tried file: %s"), cmd
);
4153 /* xgettext:c-format */
4154 inform (_("Using file: %s"), cmd
);
4159 /* Deduce the name of the program we are want to invoke.
4160 PROG_NAME is the basic name of the program we want to run,
4161 eg "as" or "ld". The catch is that we might want actually
4164 If argv[0] contains the full path, then try to find the program
4165 in the same place, with and then without a target-like prefix.
4167 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
4168 deduce_name("as") uses the following search order:
4170 /usr/local/bin/i586-cygwin32-as
4174 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
4175 name, it'll try without and then with EXECUTABLE_SUFFIX.
4177 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
4178 as the fallback, but rather return i586-cygwin32-as.
4180 Oh, and given, argv[0] = dlltool, it'll return "as".
4182 Returns a dynamically allocated string. */
4185 deduce_name (const char *prog_name
)
4188 char *dash
, *slash
, *cp
;
4192 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
4197 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4198 *cp
== ':' || *cp
== '\\' ||
4211 /* First, try looking for a prefixed PROG_NAME in the
4212 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
4213 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
4216 if (slash
!= NULL
&& cmd
== NULL
)
4218 /* Next, try looking for a PROG_NAME in the same directory as
4219 that of this program. */
4220 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
4225 /* Just return PROG_NAME as is. */
4226 cmd
= xstrdup (prog_name
);
4232 #ifdef DLLTOOL_MCORE_ELF
4233 typedef struct fname_cache
4235 const char * filename
;
4236 struct fname_cache
* next
;
4240 static fname_cache fnames
;
4243 mcore_elf_cache_filename (const char * filename
)
4249 while (ptr
->next
!= NULL
)
4252 ptr
->filename
= filename
;
4253 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
4254 if (ptr
->next
!= NULL
)
4255 ptr
->next
->next
= NULL
;
4258 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
4259 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
4260 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
4263 mcore_elf_gen_out_file (void)
4268 /* Step one. Run 'ld -r' on the input object files in order to resolve
4269 any internal references and to generate a single .exports section. */
4272 ds
= dyn_string_new (100);
4273 dyn_string_append_cstr (ds
, "-r ");
4275 if (mcore_elf_linker_flags
!= NULL
)
4276 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
4278 while (ptr
->next
!= NULL
)
4280 dyn_string_append_cstr (ds
, ptr
->filename
);
4281 dyn_string_append_cstr (ds
, " ");
4286 dyn_string_append_cstr (ds
, "-o ");
4287 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4289 if (mcore_elf_linker
== NULL
)
4290 mcore_elf_linker
= deduce_name ("ld");
4292 run (mcore_elf_linker
, ds
->s
);
4294 dyn_string_delete (ds
);
4296 /* Step two. Create a .exp file and a .lib file from the temporary file.
4297 Do this by recursively invoking dlltool... */
4298 ds
= dyn_string_new (100);
4300 dyn_string_append_cstr (ds
, "-S ");
4301 dyn_string_append_cstr (ds
, as_name
);
4303 dyn_string_append_cstr (ds
, " -e ");
4304 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
4305 dyn_string_append_cstr (ds
, " -l ");
4306 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_LIB
);
4307 dyn_string_append_cstr (ds
, " " );
4308 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4311 dyn_string_append_cstr (ds
, " -v");
4315 dyn_string_append_cstr (ds
, " -n");
4317 if (dontdeltemps
> 1)
4318 dyn_string_append_cstr (ds
, " -n");
4321 /* XXX - FIME: ought to check/copy other command line options as well. */
4322 run (program_name
, ds
->s
);
4324 dyn_string_delete (ds
);
4326 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
4327 ds
= dyn_string_new (100);
4329 dyn_string_append_cstr (ds
, "-shared ");
4331 if (mcore_elf_linker_flags
)
4332 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
4334 dyn_string_append_cstr (ds
, " ");
4335 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
4336 dyn_string_append_cstr (ds
, " ");
4337 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
4338 dyn_string_append_cstr (ds
, " -o ");
4339 dyn_string_append_cstr (ds
, mcore_elf_out_file
);
4341 run (mcore_elf_linker
, ds
->s
);
4343 dyn_string_delete (ds
);
4345 if (dontdeltemps
== 0)
4346 unlink (MCORE_ELF_TMP_EXP
);
4348 if (dontdeltemps
< 2)
4349 unlink (MCORE_ELF_TMP_OBJ
);
4351 #endif /* DLLTOOL_MCORE_ELF */