1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995, 96, 97, 98, 1999 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 2 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., 59 Temple Place - Suite 330, Boston, MA
23 This program allows you to build the files necessary to create
24 DLLs to run on a system which understands PE format image files.
27 See "Peering Inside the PE: A Tour of the Win32 Portable Executable
28 File Format", MSJ 1994, Volume 9 for more information.
29 Also see "Microsoft Portable Executable and Common Object File Format,
30 Specification 4.1" for more information.
32 A DLL contains an export table which contains the information
33 which the runtime loader needs to tie up references from a
36 The export table is generated by this program by reading
37 in a .DEF file or scanning the .a and .o files which will be in the
38 DLL. A .o file can contain information in special ".drectve" sections
39 with export information.
41 A DEF file contains any number of the following commands:
44 NAME <name> [ , <base> ]
45 The result is going to be <name>.EXE
47 LIBRARY <name> [ , <base> ]
48 The result is going to be <name>.DLL
50 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
51 Declares name1 as an exported symbol from the
52 DLL, with optional ordinal number <integer>
54 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
55 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
56 Declares that <external-name> or the exported function whoes ordinal number
57 is <integer> is to be imported from the file <module-name>. If
58 <internal-name> is specified then this is the name that the imported
59 function will be refered to in the body of the DLL.
62 Puts <string> into output .exp file in the .rdata section
64 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
65 Generates --stack|--heap <number-reserve>,<number-commit>
66 in the output .drectve section. The linker will
67 see this and act upon it.
70 SECTIONS ( <sectionname> <attr>+ )*
71 <attr> = READ | WRITE | EXECUTE | SHARED
72 Generates --attr <sectionname> <attr> in the output
73 .drectve section. The linker will see this and act
77 A -export:<name> in a .drectve section in an input .o or .a
78 file to this program is equivalent to a EXPORTS <name>
83 The program generates output files with the prefix supplied
84 on the command line, or in the def file, or taken from the first
87 The .exp.s file contains the information necessary to export
88 the routines in the DLL. The .lib.s file contains the information
89 necessary to use the DLL's routines from a referencing program.
96 asm (".section .drectve");
97 asm (".ascii \"-export:adef\"");
101 printf ("hello from the dll %s\n", s);
106 printf ("hello from the dll and the other entry point %s\n", s);
110 asm (".section .drectve");
111 asm (".ascii \"-export:cdef\"");
112 asm (".ascii \"-export:ddef\"");
116 printf ("hello from the dll %s\n", s);
121 printf ("hello from the dll and the other entry point %s\n", s);
139 HEAPSIZE 0x40000, 0x2000
143 SECTIONS donkey READ WRITE
146 # Compile up the parts of the dll and the program
148 gcc -c file1.c file2.c themain.c
150 # Optional: put the dll objects into a library
151 # (you don't have to, you could name all the object
152 # files on the dlltool line)
154 ar qcv thedll.in file1.o file2.o
157 # Run this tool over the DLL's .def file and generate an exports
158 # file (thedll.o) and an imports file (thedll.a).
159 # (You may have to use -S to tell dlltool where to find the assembler).
161 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
163 # Build the dll with the library and the export table
165 ld -o thedll.dll thedll.o thedll.in
167 # Link the executable with the import library
169 gcc -o themain.exe themain.o thedll.a
171 This example can be extended if relocations are needed in the DLL:
173 # Compile up the parts of the dll and the program
175 gcc -c file1.c file2.c themain.c
177 # Run this tool over the DLL's .def file and generate an imports file.
179 dlltool --def thedll.def --output-lib thedll.lib
181 # Link the executable with the import library and generate a base file
184 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
186 # Run this tool over the DLL's .def file and generate an exports file
187 # which includes the relocations from the base file.
189 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
191 # Build the dll with file1.o, file2.o and the export table
193 ld -o thedll.dll thedll.exp file1.o file2.o
196 /* .idata section description
198 The .idata section is the import table. It is a collection of several
199 subsections used to keep the pieces for each dll together: .idata$[234567].
200 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
202 .idata$2 = Import Directory Table
203 = array of IMAGE_IMPORT_DESCRIPTOR's.
205 DWORD Import Lookup Table; - pointer to .idata$4
206 DWORD TimeDateStamp; - currently always 0
207 DWORD ForwarderChain; - currently always 0
208 DWORD Name; - pointer to dll's name
209 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
211 .idata$3 = null terminating entry for .idata$2.
213 .idata$4 = Import Lookup Table
214 = array of array of pointers to hint name table.
215 There is one for each dll being imported from, and each dll's set is
216 terminated by a trailing NULL.
218 .idata$5 = Import Address Table
219 = array of array of pointers to hint name table.
220 There is one for each dll being imported from, and each dll's set is
221 terminated by a trailing NULL.
222 Initially, this table is identical to the Import Lookup Table. However,
223 at load time, the loader overwrites the entries with the address of the
226 .idata$6 = Hint Name Table
227 = Array of { short, asciz } entries, one for each imported function.
228 The `short' is the function's ordinal number.
230 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
233 /* AIX requires this to be the first thing in the file. */
240 #define show_allnames 0
242 #define PAGE_SIZE 4096
243 #define PAGE_MASK (-PAGE_SIZE)
245 #include "libiberty.h"
248 #include "demangle.h"
249 #include "dyn-string.h"
254 #include <sys/stat.h>
256 #ifdef ANSI_PROTOTYPES
263 #include "coff/arm.h"
264 #include "coff/internal.h"
267 /* Forward references. */
268 static char *look_for_prog
PARAMS ((const char *, const char *, int));
269 static char *deduce_name
PARAMS ((const char *));
271 #ifdef DLLTOOL_MCORE_ELF
272 static void mcore_elf_cache_filename (char *);
273 static void mcore_elf_gen_out_file (void);
276 #ifdef HAVE_SYS_WAIT_H
277 #include <sys/wait.h>
278 #else /* ! HAVE_SYS_WAIT_H */
279 #if ! defined (_WIN32) || defined (__CYGWIN32__)
281 #define WIFEXITED(w) (((w)&0377) == 0)
284 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
287 #define WTERMSIG(w) ((w) & 0177)
290 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
292 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
294 #define WIFEXITED(w) (((w) & 0xff) == 0)
297 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300 #define WTERMSIG(w) ((w) & 0x7f)
303 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
305 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
306 #endif /* ! HAVE_SYS_WAIT_H */
308 /* ifunc and ihead data structures: ttk@cygnus.com 1997
310 When IMPORT declarations are encountered in a .def file the
311 function import information is stored in a structure referenced by
312 the global variable IMPORT_LIST. The structure is a linked list
313 containing the names of the dll files each function is imported
314 from and a linked list of functions being imported from that dll
315 file. This roughly parallels the structure of the .idata section
316 in the PE object file.
318 The contents of .def file are interpreted from within the
319 process_def_file function. Every time an IMPORT declaration is
320 encountered, it is broken up into its component parts and passed to
321 def_import. IMPORT_LIST is initialized to NULL in function main. */
323 typedef struct ifunct
325 char *name
; /* name of function being imported */
326 int ord
; /* two-byte ordinal value associated with function */
330 typedef struct iheadt
332 char *dllname
; /* name of dll file imported from */
333 long nfuncs
; /* number of functions in list */
334 struct ifunct
*funchead
; /* first function in list */
335 struct ifunct
*functail
; /* last function in list */
336 struct iheadt
*next
; /* next dll file in list */
339 /* Structure containing all import information as defined in .def file
340 (qv "ihead structure"). */
342 static iheadtype
*import_list
= NULL
;
344 static char *as_name
= NULL
;
345 static char * as_flags
= "";
347 static int no_idata4
;
348 static int no_idata5
;
349 static char *exp_name
;
350 static char *imp_name
;
351 static char *head_label
;
352 static char *imp_name_lab
;
353 static char *dll_name
;
355 static int add_indirect
= 0;
356 static int add_underscore
= 0;
357 static int dontdeltemps
= 0;
359 /* True if we should export all symbols. Otherwise, we only export
360 symbols listed in .drectve sections or in the def file. */
361 static boolean export_all_symbols
;
363 /* True if we should exclude the symbols in DEFAULT_EXCLUDES when
364 exporting all symbols. */
365 static boolean do_default_excludes
;
367 /* Default symbols to exclude when exporting all the symbols. */
368 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
370 static char *def_file
;
372 extern char * program_name
;
376 static int add_stdcall_alias
;
378 static FILE *output_def
;
379 static FILE *base_file
;
382 static const char *mname
= "arm";
386 static const char *mname
= "i386";
390 static const char *mname
= "ppc";
394 static const char * mname
= "mcore";
397 #ifdef DLLTOOL_MCORE_ELF
398 static const char * mname
= "mcore-elf";
399 static char * mcore_elf_out_file
= NULL
;
400 static char * mcore_elf_linker
= NULL
;
401 static char * mcore_elf_linker_flags
= NULL
;
403 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
406 #ifndef DRECTVE_SECTION_NAME
407 #define DRECTVE_SECTION_NAME ".drectve"
410 #define PATHMAX 250 /* What's the right name for this ? */
412 #define TMP_ASM "dc.s"
413 #define TMP_HEAD_S "dh.s"
414 #define TMP_HEAD_O "dh.o"
415 #define TMP_TAIL_S "dt.s"
416 #define TMP_TAIL_O "dt.o"
417 #define TMP_STUB "ds"
419 /* This bit of assemly does jmp * .... */
420 static const unsigned char i386_jtab
[] =
422 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
425 static const unsigned char arm_jtab
[] =
427 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
428 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
432 static const unsigned char arm_interwork_jtab
[] =
434 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
435 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
436 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
440 static const unsigned char thumb_jtab
[] =
442 0x40, 0xb4, /* push {r6} */
443 0x02, 0x4e, /* ldr r6, [pc, #8] */
444 0x36, 0x68, /* ldr r6, [r6] */
445 0xb4, 0x46, /* mov ip, r6 */
446 0x40, 0xbc, /* pop {r6} */
447 0x60, 0x47, /* bx ip */
451 static const unsigned char mcore_be_jtab
[] =
453 0x70, 0x01, /* jmpi 1 */
454 0x12, 0x11, /* nop */
455 0x00, 0x00, 0x00, 0x00 /* <address> */
458 static const unsigned char mcore_le_jtab
[] =
460 0x01, 0x70, /* jmpi 1 */
461 0x11, 0x12, /* nop */
462 0x00, 0x00, 0x00, 0x00 /* <address> */
465 /* This is the glue sequence for PowerPC PE. There is a */
466 /* tocrel16-tocdefn reloc against the first instruction. */
467 /* We also need a IMGLUE reloc against the glue function */
468 /* to restore the toc saved by the third instruction in */
470 static const unsigned char ppc_jtab
[] =
472 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
473 /* Reloc TOCREL16 __imp_xxx */
474 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
475 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
476 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
477 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
478 0x20, 0x04, 0x80, 0x4E /* bctr */
482 /* the glue instruction, picks up the toc from the stw in */
483 /* the above code: "lwz r2,4(r1)" */
484 static bfd_vma ppc_glue_insn
= 0x80410004;
490 const char *how_byte
;
491 const char *how_short
;
492 const char *how_long
;
493 const char *how_asciz
;
494 const char *how_comment
;
495 const char *how_jump
;
496 const char *how_global
;
497 const char *how_space
;
498 const char *how_align_short
;
499 const char *how_align_long
;
500 const char *how_bfd_target
;
501 enum bfd_architecture how_bfd_arch
;
502 const unsigned char *how_jtab
;
503 int how_jtab_size
; /* size of the jtab entry */
504 int how_jtab_roff
; /* offset into it for the ind 32 reloc into idata 5 */
507 static const struct mac
512 "arm", ".byte", ".short", ".long", ".asciz", "@",
513 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
514 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
515 arm_jtab
, sizeof (arm_jtab
), 8
520 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386
,
521 i386_jtab
, sizeof (i386_jtab
), 2
526 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc
,
527 ppc_jtab
, sizeof (ppc_jtab
), 0
532 "thumb", ".byte", ".short", ".long", ".asciz", "@",
533 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
534 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
535 thumb_jtab
, sizeof (thumb_jtab
), 12
538 #define MARM_INTERWORK 4
540 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
541 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
542 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
543 arm_interwork_jtab
, sizeof (arm_interwork_jtab
), 12
548 "mcore", ".byte", ".short", ".long", ".asciz", "//",
549 "jmpi\t1\n\tnop\n\t.long",
550 ".global", ".space", ".align\t2",".align\t4","pe-mcore-big", bfd_arch_mcore
,
551 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
556 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
557 "jmpi\t1\n\tnop\n\t.long",
558 ".global", ".space", ".align\t2",".align\t4","pe-mcore-little", bfd_arch_mcore
,
559 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
564 "mcore-elf", ".byte", ".short", ".long", ".asciz", "//",
565 "jmpi\t1\n\tnop\n\t.long",
566 ".global", ".space", ".align\t2",".align\t4","elf32-mcore-big", bfd_arch_mcore
,
567 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
571 #define MMCORE_ELF_LE 8
572 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
573 "jmpi\t1\n\tnop\n\t.long",
574 ".global", ".space", ".align\t2",".align\t4","elf32-mcore-little", bfd_arch_mcore
,
575 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
588 typedef struct export
591 const char *internal_name
;
601 /* A list of symbols which we should not export. */
605 struct string_list
*next
;
609 static struct string_list
*excludes
;
611 static const char *rvaafter
PARAMS ((int));
612 static const char *rvabefore
PARAMS ((int));
613 static const char *asm_prefix
PARAMS ((int));
614 static void append_import
PARAMS ((const char *, const char *, int));
615 static void run
PARAMS ((const char *, char *));
616 static void scan_drectve_symbols
PARAMS ((bfd
*));
617 static void scan_filtered_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
618 static void add_excludes
PARAMS ((const char *));
619 static boolean match_exclude
PARAMS ((const char *));
620 static void set_default_excludes
PARAMS ((void));
621 static long filter_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
622 static void scan_all_symbols
PARAMS ((bfd
*));
623 static void scan_open_obj_file
PARAMS ((bfd
*));
624 static void scan_obj_file
PARAMS ((const char *));
625 static void dump_def_info
PARAMS ((FILE *));
626 static int sfunc
PARAMS ((const void *, const void *));
627 static void flush_page
PARAMS ((FILE *, long *, int, int));
628 static void gen_def_file
PARAMS ((void));
629 static void generate_idata_ofile
PARAMS ((FILE *));
630 static void gen_exp_file
PARAMS ((void));
631 static const char *xlate
PARAMS ((const char *));
633 static void dump_iat
PARAMS ((FILE *, export_type
*));
635 static char *make_label
PARAMS ((const char *, const char *));
636 static bfd
*make_one_lib_file
PARAMS ((export_type
*, int));
637 static bfd
*make_head
PARAMS ((void));
638 static bfd
*make_tail
PARAMS ((void));
639 static void gen_lib_file
PARAMS ((void));
640 static int pfunc
PARAMS ((const void *, const void *));
641 static int nfunc
PARAMS ((const void *, const void *));
642 static void remove_null_names
PARAMS ((export_type
**));
643 static void dtab
PARAMS ((export_type
**));
644 static void process_duplicates
PARAMS ((export_type
**));
645 static void fill_ordinals
PARAMS ((export_type
**));
646 static int alphafunc
PARAMS ((const void *, const void *));
647 static void mangle_defs
PARAMS ((void));
648 static void usage
PARAMS ((FILE *, int));
649 static void display
PARAMS ((const char *, va_list));
650 static void inform
PARAMS ((const char *, ...));
651 static void warn
PARAMS ((const char *, ...));
654 display (message
, args
)
655 const char * message
;
658 if (program_name
!= NULL
)
659 fprintf (stderr
, "%s: ", program_name
);
661 vfprintf (stderr
, message
, args
);
663 if (message
[strlen (message
) - 1] != '\n')
664 fputc ('\n', stderr
);
670 inform (const char * message
, ...)
672 inform (message
, va_alist
)
673 const char * message
;
683 va_start (args
, message
);
688 display (message
, args
);
695 warn (const char * message
, ...)
697 warn (message
, va_alist
)
698 const char * message
;
705 va_start (args
, message
);
710 display (message
, args
);
732 /* xgettext:c-format */
733 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
756 /* xgettext:c-format */
757 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
781 /* xgettext:c-format */
782 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
788 #define ASM_BYTE mtable[machine].how_byte
789 #define ASM_SHORT mtable[machine].how_short
790 #define ASM_LONG mtable[machine].how_long
791 #define ASM_TEXT mtable[machine].how_asciz
792 #define ASM_C mtable[machine].how_comment
793 #define ASM_JUMP mtable[machine].how_jump
794 #define ASM_GLOBAL mtable[machine].how_global
795 #define ASM_SPACE mtable[machine].how_space
796 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
797 #define ASM_RVA_BEFORE rvabefore(machine)
798 #define ASM_RVA_AFTER rvaafter(machine)
799 #define ASM_PREFIX asm_prefix(machine)
800 #define ASM_ALIGN_LONG mtable[machine].how_align_long
801 #define HOW_BFD_TARGET 0 /* always default*/
802 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
803 #define HOW_JTAB mtable[machine].how_jtab
804 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
805 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
809 process_def_file (name
)
812 FILE *f
= fopen (name
, FOPEN_RT
);
815 /* xgettext:c-format */
816 fatal (_("Can't open def file: %s"), name
);
820 /* xgettext:c-format */
821 inform (_("Processing def file: %s"), name
);
825 inform (_("Processed def file"));
828 /**********************************************************************/
830 /* Communications with the parser */
832 static const char *d_name
; /* Arg to NAME or LIBRARY */
833 static int d_nfuncs
; /* Number of functions exported */
834 static int d_named_nfuncs
; /* Number of named functions exported */
835 static int d_low_ord
; /* Lowest ordinal index */
836 static int d_high_ord
; /* Highest ordinal index */
837 static export_type
*d_exports
; /*list of exported functions */
838 static export_type
**d_exports_lexically
; /* vector of exported functions in alpha order */
839 static dlist_type
*d_list
; /* Descriptions */
840 static dlist_type
*a_list
; /* Stuff to go in directives */
849 /* xgettext:c-format */
850 warn (_("Syntax error in def file %s:%d\n"), def_file
, linenumber
);
856 def_exports (name
, internal_name
, ordinal
, noname
, constant
, data
)
858 const char *internal_name
;
864 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
867 p
->internal_name
= internal_name
? internal_name
: name
;
868 p
->ordinal
= ordinal
;
869 p
->constant
= constant
;
878 def_name (name
, base
)
882 /* xgettext:c-format */
883 inform (_("NAME: %s base: %x"), name
, base
);
886 warn (_("Can't have LIBRARY and NAME\n"));
889 /* if --dllname not provided, use the one in the DEF file.
890 FIXME: Is this appropriate for executables? */
892 dll_name
= xstrdup (name
);
897 def_library (name
, base
)
901 /* xgettext:c-format */
902 inform (_("LIBRARY: %s base: %x"), name
, base
);
905 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name
);
908 /* if --dllname not provided, use the one in the DEF file. */
910 dll_name
= xstrdup (name
);
915 def_description (desc
)
918 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
919 d
->text
= xstrdup (desc
);
928 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
929 d
->text
= xstrdup (dir
);
935 def_heapsize (reserve
, commit
)
941 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
943 sprintf (b
, "-heap 0x%x ", reserve
);
944 new_directive (xstrdup (b
));
948 def_stacksize (reserve
, commit
)
954 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
956 sprintf (b
, "-stack 0x%x ", reserve
);
957 new_directive (xstrdup (b
));
960 /* append_import simply adds the given import definition to the global
961 import_list. It is used by def_import. */
964 append_import (symbol_name
, dll_name
, func_ordinal
)
965 const char *symbol_name
;
966 const char *dll_name
;
972 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
974 if (strcmp ((*pq
)->dllname
, dll_name
) == 0)
977 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
978 q
->functail
= q
->functail
->next
;
979 q
->functail
->ord
= func_ordinal
;
980 q
->functail
->name
= xstrdup (symbol_name
);
981 q
->functail
->next
= NULL
;
987 q
= xmalloc (sizeof (iheadtype
));
988 q
->dllname
= xstrdup (dll_name
);
990 q
->funchead
= xmalloc (sizeof (ifunctype
));
991 q
->functail
= q
->funchead
;
993 q
->functail
->name
= xstrdup (symbol_name
);
994 q
->functail
->ord
= func_ordinal
;
995 q
->functail
->next
= NULL
;
1000 /* def_import is called from within defparse.y when an IMPORT
1001 declaration is encountered. Depending on the form of the
1002 declaration, the module name may or may not need ".dll" to be
1003 appended to it, the name of the function may be stored in internal
1004 or entry, and there may or may not be an ordinal value associated
1007 /* A note regarding the parse modes:
1008 In defparse.y we have to accept import declarations which follow
1009 any one of the following forms:
1010 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1011 <func_name_in_app> = <dll_name>.<number>
1012 <dll_name>.<func_name_in_dll>
1014 Furthermore, the dll's name may or may not end with ".dll", which
1015 complicates the parsing a little. Normally the dll's name is
1016 passed to def_import() in the "module" parameter, but when it ends
1017 with ".dll" it gets passed in "module" sans ".dll" and that needs
1020 def_import gets five parameters:
1021 APP_NAME - the name of the function in the application, if
1022 present, or NULL if not present.
1023 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1024 DLLEXT - the extension of the dll, if present, NULL if not present.
1025 ENTRY - the name of the function in the dll, if present, or NULL.
1026 ORD_VAL - the numerical tag of the function in the dll, if present,
1027 or NULL. Exactly one of <entry> or <ord_val> must be
1028 present (i.e., not NULL). */
1031 def_import (app_name
, module
, dllext
, entry
, ord_val
)
1032 const char *app_name
;
1038 const char *application_name
;
1042 application_name
= entry
;
1045 if (app_name
!= NULL
)
1046 application_name
= app_name
;
1048 application_name
= "";
1053 buf
= (char *) alloca (strlen (module
) + strlen (dllext
) + 2);
1054 sprintf (buf
, "%s.%s", module
, dllext
);
1058 append_import (application_name
, module
, ord_val
);
1062 def_version (major
, minor
)
1066 printf ("VERSION %d.%d\n", major
, minor
);
1070 def_section (name
, attr
)
1087 sprintf (buf
, "-attr %s %s", name
, atts
);
1088 new_directive (xstrdup (buf
));
1096 def_section ("CODE", attr
);
1103 def_section ("DATA", attr
);
1106 /**********************************************************************/
1114 int pid
, wait_status
;
1117 char *errmsg_fmt
, *errmsg_arg
;
1118 char *temp_base
= choose_temp_base ();
1120 inform ("run: %s %s\n", what
, args
);
1122 /* Count the args */
1124 for (s
= args
; *s
; s
++)
1128 argv
= alloca (sizeof (char *) * (i
+ 3));
1137 while (*s
!= ' ' && *s
!= 0)
1145 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1146 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1150 inform (strerror (errno
));
1152 fatal (errmsg_fmt
, errmsg_arg
);
1155 pid
= pwait (pid
, & wait_status
, 0);
1159 /* xgettext:c-format */
1160 fatal (_("wait: %s"), strerror (errno
));
1162 else if (WIFSIGNALED (wait_status
))
1164 /* xgettext:c-format */
1165 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1167 else if (WIFEXITED (wait_status
))
1169 if (WEXITSTATUS (wait_status
) != 0)
1170 /* xgettext:c-format */
1171 warn (_("%s exited with status %d\n"),
1172 what
, WEXITSTATUS (wait_status
));
1178 /* Look for a list of symbols to export in the .drectve section of
1179 ABFD. Pass each one to def_exports. */
1182 scan_drectve_symbols (abfd
)
1191 /* Look for .drectve's */
1192 s
= bfd_get_section_by_name (abfd
, DRECTVE_SECTION_NAME
);
1197 size
= bfd_get_section_size_before_reloc (s
);
1198 buf
= xmalloc (size
);
1200 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1202 /* xgettext:c-format */
1203 inform (_("Sucking in info from %s section in %s\n"),
1204 DRECTVE_SECTION_NAME
, bfd_get_filename (abfd
));
1206 /* Search for -export: strings */
1212 && strncmp (p
, "-export:", 8) == 0)
1219 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1221 c
= xmalloc (p
- name
+ 1);
1222 memcpy (c
, name
, p
- name
);
1225 /* FIXME: The 5th arg is for the `constant' field.
1226 What should it be? Not that it matters since it's not
1227 currently useful. */
1228 def_exports (c
, 0, -1, 0, 0, 0);
1230 if (add_stdcall_alias
&& strchr (c
, '@'))
1232 char *exported_name
= xstrdup (c
);
1233 char *atsym
= strchr (exported_name
, '@');
1235 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0);
1244 /* Look through the symbols in MINISYMS, and add each one to list of
1245 symbols to export. */
1248 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
)
1255 bfd_byte
*from
, *fromend
;
1257 store
= bfd_make_empty_symbol (abfd
);
1259 bfd_fatal (bfd_get_filename (abfd
));
1261 from
= (bfd_byte
*) minisyms
;
1262 fromend
= from
+ symcount
* size
;
1263 for (; from
< fromend
; from
+= size
)
1266 const char *symbol_name
;
1268 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1270 bfd_fatal (bfd_get_filename (abfd
));
1272 symbol_name
= bfd_asymbol_name (sym
);
1273 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1276 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0, 0);
1278 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1280 char *exported_name
= xstrdup (symbol_name
);
1281 char *atsym
= strchr (exported_name
, '@');
1283 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0);
1288 /* Add a list of symbols to exclude. */
1291 add_excludes (new_excludes
)
1292 const char *new_excludes
;
1295 char *exclude_string
;
1297 local_copy
= xstrdup (new_excludes
);
1299 exclude_string
= strtok (local_copy
, ",:");
1300 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1302 struct string_list
*new_exclude
;
1304 new_exclude
= ((struct string_list
*)
1305 xmalloc (sizeof (struct string_list
)));
1306 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1307 /* FIXME: Is it always right to add a leading underscore? */
1308 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1309 new_exclude
->next
= excludes
;
1310 excludes
= new_exclude
;
1312 /* xgettext:c-format */
1313 inform (_("Excluding symbol: %s\n"), exclude_string
);
1319 /* See if STRING is on the list of symbols to exclude. */
1322 match_exclude (string
)
1325 struct string_list
*excl_item
;
1327 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1328 if (strcmp (string
, excl_item
->string
) == 0)
1333 /* Add the default list of symbols to exclude. */
1336 set_default_excludes (void)
1338 add_excludes (default_excludes
);
1341 /* Choose which symbols to export. */
1344 filter_symbols (abfd
, minisyms
, symcount
, size
)
1350 bfd_byte
*from
, *fromend
, *to
;
1353 store
= bfd_make_empty_symbol (abfd
);
1355 bfd_fatal (bfd_get_filename (abfd
));
1357 from
= (bfd_byte
*) minisyms
;
1358 fromend
= from
+ symcount
* size
;
1359 to
= (bfd_byte
*) minisyms
;
1361 for (; from
< fromend
; from
+= size
)
1366 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const PTR
) from
, store
);
1368 bfd_fatal (bfd_get_filename (abfd
));
1370 /* Check for external and defined only symbols. */
1371 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1372 || (sym
->flags
& BSF_WEAK
) != 0
1373 || bfd_is_com_section (sym
->section
))
1374 && ! bfd_is_und_section (sym
->section
));
1376 keep
= keep
&& ! match_exclude (sym
->name
);
1380 memcpy (to
, from
, size
);
1385 return (to
- (bfd_byte
*) minisyms
) / size
;
1388 /* Export all symbols in ABFD, except for ones we were told not to
1392 scan_all_symbols (abfd
)
1399 /* Ignore bfds with an import descriptor table. We assume that any
1400 such BFD contains symbols which are exported from another DLL,
1401 and we don't want to reexport them from here. */
1402 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1405 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1407 /* xgettext:c-format */
1408 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1412 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1414 bfd_fatal (bfd_get_filename (abfd
));
1418 /* xgettext:c-format */
1419 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1423 /* Discard the symbols we don't want to export. It's OK to do this
1424 in place; we'll free the storage anyway. */
1426 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1427 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1432 /* Look at the object file to decide which symbols to export. */
1435 scan_open_obj_file (abfd
)
1438 if (export_all_symbols
)
1439 scan_all_symbols (abfd
);
1441 scan_drectve_symbols (abfd
);
1443 /* FIXME: we ought to read in and block out the base relocations */
1445 /* xgettext:c-format */
1446 inform (_("Done reading %s\n"), bfd_get_filename (abfd
));
1450 scan_obj_file (filename
)
1451 const char *filename
;
1453 bfd
* f
= bfd_openr (filename
, 0);
1456 /* xgettext:c-format */
1457 fatal (_("Unable to open object file: %s"), filename
);
1459 /* xgettext:c-format */
1460 inform (_("Scanning object file %s"), filename
);
1462 if (bfd_check_format (f
, bfd_archive
))
1464 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1467 if (bfd_check_format (arfile
, bfd_object
))
1468 scan_open_obj_file (arfile
);
1470 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1473 #ifdef DLLTOOL_MCORE_ELF
1474 if (mcore_elf_out_file
)
1475 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename
);
1478 else if (bfd_check_format (f
, bfd_object
))
1480 scan_open_obj_file (f
);
1482 #ifdef DLLTOOL_MCORE_ELF
1483 if (mcore_elf_out_file
)
1484 mcore_elf_cache_filename ((char *) filename
);
1491 /**********************************************************************/
1499 fprintf (f
, "%s ", ASM_C
);
1500 for (i
= 0; oav
[i
]; i
++)
1501 fprintf (f
, "%s ", oav
[i
]);
1503 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1505 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1511 exp
->noname
? "NONAME " : "",
1512 exp
->constant
? "CONSTANT" : "",
1513 exp
->data
? "DATA" : "");
1517 /* Generate the .exp file */
1524 return *(const long *) a
- *(const long *) b
;
1528 flush_page (f
, need
, page_addr
, on_page
)
1536 /* Flush this page */
1537 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1541 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1543 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1545 for (i
= 0; i
< on_page
; i
++)
1547 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (need
[i
] - page_addr
) | 0x3000);
1551 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1560 inform (_("Adding exports to output file"));
1562 fprintf (output_def
, ";");
1563 for (i
= 0; oav
[i
]; i
++)
1564 fprintf (output_def
, " %s", oav
[i
]);
1566 fprintf (output_def
, "\nEXPORTS\n");
1568 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1570 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1571 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1573 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1576 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1581 exp
->noname
? " NONAME" : "",
1582 exp
->data
? " DATA" : "",
1587 char *quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1589 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1597 exp
->noname
? " NONAME" : "",
1598 exp
->data
? " DATA" : "",
1605 inform (_("Added exports to output file"));
1608 /* generate_idata_ofile generates the portable assembly source code
1609 for the idata sections. It appends the source code to the end of
1613 generate_idata_ofile (filvar
)
1622 if (import_list
== NULL
)
1625 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1626 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1627 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1628 fprintf (filvar
, "doi_idata:\n");
1631 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1633 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1634 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1635 ASM_C
, headptr
->dllname
);
1636 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1637 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1638 fprintf (filvar
, "\t%sdllname%d%s\n",
1639 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1640 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1641 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1645 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1646 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1647 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1648 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1649 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1651 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1653 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1655 fprintf (filvar
, "listone%d:\n", headindex
);
1656 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1657 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1658 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1659 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1663 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1665 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1667 fprintf (filvar
, "listtwo%d:\n", headindex
);
1668 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1669 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1670 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1671 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1675 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1677 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1680 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1681 funcptr
= funcptr
->next
)
1683 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1684 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1685 ((funcptr
->ord
) & 0xFFFF));
1686 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1687 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1693 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1695 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1697 fprintf (filvar
,"dllname%d:\n", headindex
);
1698 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1699 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1713 /* xgettext:c-format */
1714 inform (_("Generating export file: %s\n"), exp_name
);
1716 f
= fopen (TMP_ASM
, FOPEN_WT
);
1718 /* xgettext:c-format */
1719 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1721 /* xgettext:c-format */
1722 inform (_("Opened temporary file: %s"), TMP_ASM
);
1728 fprintf (f
, "\t.section .edata\n\n");
1729 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1730 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1732 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1733 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1734 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1737 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1738 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1740 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1741 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1742 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1743 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1745 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1746 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1748 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1750 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1753 fprintf(f
,"%s Export address Table\n", ASM_C
);
1754 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1755 fprintf (f
, "afuncs:\n");
1758 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1760 if (exp
->ordinal
!= i
)
1763 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1765 (exp
->ordinal
- i
) * 4,
1767 i
, exp
->ordinal
- 1);
1770 while (i
< exp
->ordinal
)
1772 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1776 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1778 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1782 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1783 fprintf (f
, "anames:\n");
1785 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1787 if (!exp
->noname
|| show_allnames
)
1788 fprintf (f
, "\t%sn%d%s\n",
1789 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1792 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1793 fprintf (f
, "anords:\n");
1794 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1796 if (!exp
->noname
|| show_allnames
)
1797 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1800 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1801 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1802 if (!exp
->noname
|| show_allnames
)
1803 fprintf (f
, "n%d: %s \"%s\"\n",
1804 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1808 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
1809 for (dl
= a_list
; dl
; dl
= dl
->next
)
1811 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1817 fprintf (f
, "\t.section .rdata\n");
1818 for (dl
= d_list
; dl
; dl
= dl
->next
)
1822 /* We dont output as ascii 'cause there can
1823 be quote characters in the string */
1826 for (p
= dl
->text
; *p
; p
++)
1829 fprintf (f
, "\t%s\t", ASM_BYTE
);
1832 fprintf (f
, "%d", *p
);
1835 fprintf (f
, ",0\n");
1849 /* Add to the output file a way of getting to the exported names
1850 without using the import library. */
1853 fprintf (f
, "\t.section\t.rdata\n");
1854 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1855 if (!exp
->noname
|| show_allnames
)
1857 /* We use a single underscore for MS compatibility, and a
1858 double underscore for backward compatibility with old
1860 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1861 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1862 fprintf (f
, "__imp_%s:\n", exp
->name
);
1863 fprintf (f
, "_imp__%s:\n", exp
->name
);
1864 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1868 /* Dump the reloc section if a base file is provided */
1872 long need
[PAGE_SIZE
];
1879 fprintf (f
, "\t.section\t.init\n");
1880 fprintf (f
, "lab:\n");
1882 fseek (base_file
, 0, SEEK_END
);
1883 numbytes
= ftell (base_file
);
1884 fseek (base_file
, 0, SEEK_SET
);
1885 copy
= xmalloc (numbytes
);
1886 fread (copy
, 1, numbytes
, base_file
);
1887 num_entries
= numbytes
/ sizeof (long);
1890 fprintf (f
, "\t.section\t.reloc\n");
1896 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1897 /* Delete duplcates */
1898 for (src
= 0; src
< num_entries
; src
++)
1900 if (last
!= copy
[src
])
1901 last
= copy
[dst
++] = copy
[src
];
1905 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1907 for (j
= 0; j
< num_entries
; j
++)
1910 if ((addr
& PAGE_MASK
) != page_addr
)
1912 flush_page (f
, need
, page_addr
, on_page
);
1914 page_addr
= addr
& PAGE_MASK
;
1916 need
[on_page
++] = addr
;
1918 flush_page (f
, need
, page_addr
, on_page
);
1920 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1924 generate_idata_ofile (f
);
1928 /* assemble the file */
1929 cmd
= (char *) alloca (strlen (as_flags
) + strlen (exp_name
)
1930 + sizeof TMP_ASM
+ 50);
1931 sprintf (cmd
, "%s -o %s %s", as_flags
, exp_name
, TMP_ASM
);
1934 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
1935 strcat (cmd
, " -mthumb-interwork");
1940 if (dontdeltemps
== 0)
1943 inform (_("Generated exports file"));
1952 char *copy
= xmalloc (strlen (name
) + 2);
1954 strcpy (copy
+ 1, name
);
1961 p
= strchr (name
, '@');
1968 /**********************************************************************/
1977 if (exp
->noname
&& !show_allnames
)
1979 fprintf (f
, "\t%s\t0x%08x\n",
1981 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
1985 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
2003 unsigned char *data
;
2018 static sinfo secdata
[NSECS
] =
2020 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2},
2021 { DATA
, ".data", SEC_DATA
, 2},
2022 { BSS
, ".bss", 0, 2},
2023 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2024 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2025 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2026 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1}
2031 /* Sections numbered to make the order the same as other PowerPC NT */
2032 /* compilers. This also keeps funny alignment thingies from happening. */
2045 static sinfo secdata
[NSECS
] =
2047 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
2048 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
2049 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
2050 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2051 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2052 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
2053 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2054 { DATA
, ".data", SEC_DATA
, 2},
2055 { BSS
, ".bss", 0, 2}
2061 This is what we're trying to make. We generate the imp symbols with
2062 both single and double underscores, for compatibility.
2065 .global _GetFileVersionInfoSizeW@8
2066 .global __imp_GetFileVersionInfoSizeW@8
2067 _GetFileVersionInfoSizeW@8:
2068 jmp * __imp_GetFileVersionInfoSizeW@8
2069 .section .idata$7 # To force loading of head
2070 .long __version_a_head
2071 # Import Address Table
2073 __imp_GetFileVersionInfoSizeW@8:
2076 # Import Lookup Table
2082 .asciz "GetFileVersionInfoSizeW"
2085 For the PowerPC, here's the variation on the above scheme:
2087 # Rather than a simple "jmp *", the code to get to the dll function
2090 lwz r11,[tocv]__imp_function_name(r2)
2091 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2100 make_label (prefix
, name
)
2104 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
2105 char *copy
= xmalloc (len
+1 );
2106 strcpy (copy
, ASM_PREFIX
);
2107 strcat (copy
, prefix
);
2108 strcat (copy
, name
);
2113 make_one_lib_file (exp
, i
)
2121 const char *prefix
= "d";
2124 name
= (char *) alloca (strlen (prefix
) + 10);
2125 sprintf (name
, "%ss%05d.s", prefix
, i
);
2126 f
= fopen (name
, FOPEN_WT
);
2127 fprintf (f
, "\t.text\n");
2128 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
2129 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2130 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
2131 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
2132 exp
->name
, ASM_JUMP
, exp
->name
);
2134 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
2135 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
2138 fprintf (f
,"%s Import Address Table\n", ASM_C
);
2140 fprintf (f
, "\t.section .idata$5\n");
2141 fprintf (f
, "__imp_%s:\n", exp
->name
);
2142 fprintf (f
, "_imp__%s:\n", exp
->name
);
2146 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
2147 fprintf (f
, "\t.section .idata$4\n");
2151 if(!exp
->noname
|| show_allnames
)
2153 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
2154 fprintf (f
, "\t.section .idata$6\n");
2155 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
2156 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
2161 cmd
= (char *) alloca (strlen (as_flags
) + 2 * strlen (prefix
) + 50);
2162 sprintf (cmd
, "%s -o %ss%05d.o %ss%d.s",
2163 as_flags
, prefix
, i
, prefix
, i
);
2166 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2167 strcat (cmd
, " -mthumb-interwork");
2175 asymbol
* exp_label
;
2178 asymbol
* iname_lab
;
2179 asymbol
** iname_lab_pp
;
2180 asymbol
** iname_pp
;
2189 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2191 char * outname
= xmalloc (10);
2195 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2197 abfd
= bfd_openw (outname
, HOW_BFD_TARGET
);
2200 /* xgettext:c-format */
2201 fatal (_("bfd_open failed open stub file: %s"), outname
);
2203 /* xgettext:c-format */
2204 inform (_("Creating stub file: %s"), outname
);
2206 bfd_set_format (abfd
, bfd_object
);
2207 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2210 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2211 bfd_set_private_flags (abfd
, F_INTERWORK
);
2214 /* First make symbols for the sections */
2215 for (i
= 0; i
< NSECS
; i
++)
2217 sinfo
*si
= secdata
+ i
;
2220 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2221 bfd_set_section_flags (abfd
,
2225 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2226 si
->sec
->output_section
= si
->sec
;
2227 si
->sym
= bfd_make_empty_symbol(abfd
);
2228 si
->sym
->name
= si
->sec
->name
;
2229 si
->sym
->section
= si
->sec
;
2230 si
->sym
->flags
= BSF_LOCAL
;
2232 ptrs
[oidx
] = si
->sym
;
2233 si
->sympp
= ptrs
+ oidx
;
2242 exp_label
= bfd_make_empty_symbol (abfd
);
2243 exp_label
->name
= make_label ("", exp
->name
);
2245 /* On PowerPC, the function name points to a descriptor in
2246 the rdata section, the first element of which is a
2247 pointer to the code (..function_name), and the second
2248 points to the .toc */
2250 if (machine
== MPPC
)
2251 exp_label
->section
= secdata
[RDATA
].sec
;
2254 exp_label
->section
= secdata
[TEXT
].sec
;
2256 exp_label
->flags
= BSF_GLOBAL
;
2257 exp_label
->value
= 0;
2260 if (machine
== MTHUMB
)
2261 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2263 ptrs
[oidx
++] = exp_label
;
2266 /* Generate imp symbols with one underscore for Microsoft
2267 compatibility, and with two underscores for backward
2268 compatibility with old versions of cygwin. */
2269 iname
= bfd_make_empty_symbol(abfd
);
2270 iname
->name
= make_label ("__imp_", exp
->name
);
2271 iname
->section
= secdata
[IDATA5
].sec
;
2272 iname
->flags
= BSF_GLOBAL
;
2275 iname2
= bfd_make_empty_symbol(abfd
);
2276 iname2
->name
= make_label ("_imp__", exp
->name
);
2277 iname2
->section
= secdata
[IDATA5
].sec
;
2278 iname2
->flags
= BSF_GLOBAL
;
2281 iname_lab
= bfd_make_empty_symbol(abfd
);
2283 iname_lab
->name
= head_label
;
2284 iname_lab
->section
= (asection
*)&bfd_und_section
;
2285 iname_lab
->flags
= 0;
2286 iname_lab
->value
= 0;
2289 iname_pp
= ptrs
+ oidx
;
2290 ptrs
[oidx
++] = iname
;
2291 ptrs
[oidx
++] = iname2
;
2293 iname_lab_pp
= ptrs
+ oidx
;
2294 ptrs
[oidx
++] = iname_lab
;
2297 /* The symbol refering to the code (.text) */
2299 asymbol
*function_name
;
2301 function_name
= bfd_make_empty_symbol(abfd
);
2302 function_name
->name
= make_label ("..", exp
->name
);
2303 function_name
->section
= secdata
[TEXT
].sec
;
2304 function_name
->flags
= BSF_GLOBAL
;
2305 function_name
->value
= 0;
2307 fn_pp
= ptrs
+ oidx
;
2308 ptrs
[oidx
++] = function_name
;
2311 /* The .toc symbol */
2313 asymbol
*toc_symbol
; /* The .toc symbol */
2315 toc_symbol
= bfd_make_empty_symbol (abfd
);
2316 toc_symbol
->name
= make_label (".", "toc");
2317 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2318 toc_symbol
->flags
= BSF_GLOBAL
;
2319 toc_symbol
->value
= 0;
2321 toc_pp
= ptrs
+ oidx
;
2322 ptrs
[oidx
++] = toc_symbol
;
2328 for (i
= 0; i
< NSECS
; i
++)
2330 sinfo
*si
= secdata
+ i
;
2331 asection
*sec
= si
->sec
;
2340 si
->size
= HOW_JTAB_SIZE
;
2341 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2342 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2344 /* add the reloc into idata$5 */
2345 rel
= xmalloc (sizeof (arelent
));
2347 rpp
= xmalloc (sizeof (arelent
*) * 2);
2351 rel
->address
= HOW_JTAB_ROFF
;
2354 if (machine
== MPPC
)
2356 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2357 BFD_RELOC_16_GOTOFF
);
2358 rel
->sym_ptr_ptr
= iname_pp
;
2362 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2363 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2365 sec
->orelocation
= rpp
;
2366 sec
->reloc_count
= 1;
2371 /* An idata$4 or idata$5 is one word long, and has an
2374 si
->data
= xmalloc (4);
2379 si
->data
[0] = exp
->ordinal
;
2380 si
->data
[1] = exp
->ordinal
>> 8;
2381 si
->data
[2] = exp
->ordinal
>> 16;
2386 sec
->reloc_count
= 1;
2387 memset (si
->data
, 0, si
->size
);
2388 rel
= xmalloc (sizeof (arelent
));
2389 rpp
= xmalloc (sizeof (arelent
*) * 2);
2394 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2395 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2396 sec
->orelocation
= rpp
;
2404 /* This used to add 1 to exp->hint. I don't know
2405 why it did that, and it does not match what I see
2406 in programs compiled with the MS tools. */
2407 int idx
= exp
->hint
;
2408 si
->size
= strlen (xlate (exp
->name
)) + 3;
2409 si
->data
= xmalloc (si
->size
);
2410 si
->data
[0] = idx
& 0xff;
2411 si
->data
[1] = idx
>> 8;
2412 strcpy (si
->data
+ 2, xlate (exp
->name
));
2417 si
->data
=xmalloc(4);
2418 memset (si
->data
, 0, si
->size
);
2419 rel
= xmalloc (sizeof (arelent
));
2420 rpp
= xmalloc (sizeof (arelent
*) * 2);
2424 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2425 rel
->sym_ptr_ptr
= iname_lab_pp
;
2426 sec
->orelocation
= rpp
;
2427 sec
->reloc_count
= 1;
2433 /* The .pdata section is 5 words long. */
2434 /* Think of it as: */
2437 /* bfd_vma BeginAddress, [0x00] */
2438 /* EndAddress, [0x04] */
2439 /* ExceptionHandler, [0x08] */
2440 /* HandlerData, [0x0c] */
2441 /* PrologEndAddress; [0x10] */
2444 /* So this pdata section setups up this as a glue linkage to
2445 a dll routine. There are a number of house keeping things
2448 1. In the name of glue trickery, the ADDR32 relocs for 0,
2449 4, and 0x10 are set to point to the same place:
2451 2. There is one more reloc needed in the pdata section.
2452 The actual glue instruction to restore the toc on
2453 return is saved as the offset in an IMGLUE reloc.
2454 So we need a total of four relocs for this section.
2456 3. Lastly, the HandlerData field is set to 0x03, to indicate
2457 that this is a glue routine.
2459 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2461 /* alignment must be set to 2**2 or you get extra stuff */
2462 bfd_set_section_alignment(abfd
, sec
, 2);
2465 si
->data
=xmalloc(4 * 5);
2466 memset (si
->data
, 0, si
->size
);
2467 rpp
= xmalloc (sizeof (arelent
*) * 5);
2468 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2469 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2470 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2471 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2474 /* stick the toc reload instruction in the glue reloc */
2475 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2478 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2479 BFD_RELOC_32_GOTOFF
);
2480 imglue
->sym_ptr_ptr
= fn_pp
;
2482 ba_rel
->address
= 0;
2484 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2485 ba_rel
->sym_ptr_ptr
= fn_pp
;
2487 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2488 ea_rel
->address
= 4;
2490 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2491 ea_rel
->sym_ptr_ptr
= fn_pp
;
2493 /* mark it as glue */
2494 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2496 /* mark the prolog end address */
2497 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2498 pea_rel
->address
= 0x10;
2499 pea_rel
->addend
= 0;
2500 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2501 pea_rel
->sym_ptr_ptr
= fn_pp
;
2503 sec
->orelocation
= rpp
;
2504 sec
->reloc_count
= 4;
2508 /* Each external function in a PowerPC PE file has a two word
2509 descriptor consisting of:
2510 1. The address of the code.
2511 2. The address of the appropriate .toc
2512 We use relocs to build this.
2516 si
->data
= xmalloc (8);
2517 memset (si
->data
, 0, si
->size
);
2519 rpp
= xmalloc (sizeof (arelent
*) * 3);
2520 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2521 rpp
[1] = xmalloc (sizeof (arelent
));
2526 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2527 rel
->sym_ptr_ptr
= fn_pp
;
2533 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2534 rel
->sym_ptr_ptr
= toc_pp
;
2536 sec
->orelocation
= rpp
;
2537 sec
->reloc_count
= 2;
2539 #endif /* DLLTOOL_PPC */
2545 /* Size up all the sections */
2546 for (i
= 0; i
< NSECS
; i
++)
2548 sinfo
*si
= secdata
+ i
;
2550 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2551 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2553 /* vma += si->size;*/
2556 /* Write them out */
2557 for (i
= 0; i
< NSECS
; i
++)
2559 sinfo
*si
= secdata
+ i
;
2561 if (i
== IDATA5
&& no_idata5
)
2564 if (i
== IDATA4
&& no_idata4
)
2567 bfd_set_section_contents (abfd
, si
->sec
,
2572 bfd_set_symtab (abfd
, ptrs
, oidx
);
2574 abfd
= bfd_openr (outname
, HOW_BFD_TARGET
);
2583 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2588 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2592 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2593 fprintf (f
, "\t.section .idata$2\n");
2595 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2597 fprintf (f
, "%s:\n", head_label
);
2599 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2600 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2602 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2603 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2604 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2605 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2606 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2611 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2613 ASM_RVA_AFTER
, ASM_C
);
2615 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2619 fprintf (f
, "\t.section\t.idata$5\n");
2620 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2621 fprintf (f
, "fthunk:\n");
2626 fprintf (f
, "\t.section\t.idata$4\n");
2628 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2629 fprintf (f
, "\t.section .idata$4\n");
2630 fprintf (f
, "hname:\n");
2635 cmd
= (char *) alloca (strlen (as_flags
) + sizeof TMP_HEAD_O
2636 + sizeof TMP_HEAD_S
+ 50);
2637 sprintf (cmd
, "%s -o %s %s", as_flags
, TMP_HEAD_O
, TMP_HEAD_S
);
2640 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2641 strcat (cmd
, " -mthumb-interwork");
2646 return bfd_openr (TMP_HEAD_O
, HOW_BFD_TARGET
);
2652 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2657 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2663 fprintf (f
, "\t.section .idata$4\n");
2664 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2669 fprintf (f
, "\t.section .idata$5\n");
2670 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2674 /* Normally, we need to see a null descriptor built in idata$3 to
2675 act as the terminator for the list. The ideal way, I suppose,
2676 would be to mark this section as a comdat type 2 section, so
2677 only one would appear in the final .exe (if our linker supported
2678 comdat, that is) or cause it to be inserted by something else (say
2682 fprintf (f
, "\t.section .idata$3\n");
2683 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2684 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2685 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2686 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2687 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2691 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2692 do too. Original, huh? */
2693 fprintf (f
, "\t.section .idata$6\n");
2695 fprintf (f
, "\t.section .idata$7\n");
2698 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2699 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2700 imp_name_lab
, ASM_TEXT
, dll_name
);
2704 cmd
= (char *) alloca (strlen (as_flags
) + sizeof TMP_TAIL_O
2705 + sizeof TMP_TAIL_S
+ 50);
2706 sprintf (cmd
, "%s -o %s %s", as_flags
, TMP_TAIL_O
, TMP_TAIL_S
);
2709 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2710 strcat (cmd
, " -mthumb-interwork");
2715 return bfd_openr (TMP_TAIL_O
, HOW_BFD_TARGET
);
2730 outarch
= bfd_openw (imp_name
, HOW_BFD_TARGET
);
2733 /* xgettext:c-format */
2734 fatal (_("Can't open .lib file: %s"), imp_name
);
2736 /* xgettext:c-format */
2737 inform (_("Creating library file: %s\n"), imp_name
);
2739 bfd_set_format (outarch
, bfd_archive
);
2740 outarch
->has_armap
= 1;
2742 /* Work out a reasonable size of things to put onto one line. */
2744 ar_head
= make_head ();
2745 ar_tail
= make_tail();
2747 if (ar_head
== NULL
|| ar_tail
== NULL
)
2750 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2752 bfd
*n
= make_one_lib_file (exp
, i
);
2757 /* Now stick them all into the archive */
2759 ar_head
->next
= head
;
2760 ar_tail
->next
= ar_head
;
2763 if (! bfd_set_archive_head (outarch
, head
))
2764 bfd_fatal ("bfd_set_archive_head");
2766 if (! bfd_close (outarch
))
2767 bfd_fatal (imp_name
);
2769 while (head
!= NULL
)
2771 bfd
*n
= head
->next
;
2776 /* Delete all the temp files */
2778 if (dontdeltemps
== 0)
2780 unlink (TMP_HEAD_O
);
2781 unlink (TMP_HEAD_S
);
2782 unlink (TMP_TAIL_O
);
2783 unlink (TMP_TAIL_S
);
2786 if (dontdeltemps
< 2)
2790 name
= (char *) alloca (sizeof TMP_STUB
+ 10);
2791 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2793 sprintf (name
, "%s%05d.o", TMP_STUB
, i
);
2794 if (unlink (name
) < 0)
2795 /* xgettext:c-format */
2796 warn (_("cannot delete %s: %s\n"), name
, strerror (errno
));
2800 inform (_("Created lib file"));
2803 /**********************************************************************/
2805 /* Run through the information gathered from the .o files and the
2806 .def file and work out the best stuff */
2812 export_type
*ap
= *(export_type
**) a
;
2813 export_type
*bp
= *(export_type
**) b
;
2814 if (ap
->ordinal
== bp
->ordinal
)
2817 /* unset ordinals go to the bottom */
2818 if (ap
->ordinal
== -1)
2820 if (bp
->ordinal
== -1)
2822 return (ap
->ordinal
- bp
->ordinal
);
2830 export_type
*ap
= *(export_type
**) a
;
2831 export_type
*bp
= *(export_type
**) b
;
2833 return (strcmp (ap
->name
, bp
->name
));
2837 remove_null_names (ptr
)
2842 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2846 ptr
[dst
] = ptr
[src
];
2859 for (i
= 0; i
< d_nfuncs
; i
++)
2863 printf ("%d %s @ %d %s%s%s\n",
2864 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2865 ptr
[i
]->noname
? "NONAME " : "",
2866 ptr
[i
]->constant
? "CONSTANT" : "",
2867 ptr
[i
]->data
? "DATA" : "");
2876 process_duplicates (d_export_vec
)
2877 export_type
**d_export_vec
;
2885 /* Remove duplicates */
2886 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2888 dtab (d_export_vec
);
2889 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2891 if (strcmp (d_export_vec
[i
]->name
,
2892 d_export_vec
[i
+ 1]->name
) == 0)
2895 export_type
*a
= d_export_vec
[i
];
2896 export_type
*b
= d_export_vec
[i
+ 1];
2900 /* xgettext:c-format */
2901 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2902 a
->name
, a
->ordinal
, b
->ordinal
);
2904 if (a
->ordinal
!= -1
2905 && b
->ordinal
!= -1)
2906 /* xgettext:c-format */
2907 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2910 /* Merge attributes */
2911 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2912 b
->constant
|= a
->constant
;
2913 b
->noname
|= a
->noname
;
2915 d_export_vec
[i
] = 0;
2918 dtab (d_export_vec
);
2919 remove_null_names (d_export_vec
);
2920 dtab (d_export_vec
);
2925 /* Count the names */
2926 for (i
= 0; i
< d_nfuncs
; i
++)
2928 if (!d_export_vec
[i
]->noname
)
2934 fill_ordinals (d_export_vec
)
2935 export_type
**d_export_vec
;
2942 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2944 /* fill in the unset ordinals with ones from our range */
2946 ptr
= (char *) xmalloc (size
);
2948 memset (ptr
, 0, size
);
2950 /* Mark in our large vector all the numbers that are taken */
2951 for (i
= 0; i
< d_nfuncs
; i
++)
2953 if (d_export_vec
[i
]->ordinal
!= -1)
2955 ptr
[d_export_vec
[i
]->ordinal
] = 1;
2956 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
2958 lowest
= d_export_vec
[i
]->ordinal
;
2963 /* Start at 1 for compatibility with MS toolchain. */
2967 /* Now fill in ordinals where the user wants us to choose. */
2968 for (i
= 0; i
< d_nfuncs
; i
++)
2970 if (d_export_vec
[i
]->ordinal
== -1)
2974 /* First try within or after any user supplied range. */
2975 for (j
= lowest
; j
< size
; j
++)
2979 d_export_vec
[i
]->ordinal
= j
;
2983 /* Then try before the range. */
2984 for (j
= lowest
; j
>0; j
--)
2988 d_export_vec
[i
]->ordinal
= j
;
2999 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3001 /* Work out the lowest and highest ordinal numbers. */
3004 if (d_export_vec
[0])
3005 d_low_ord
= d_export_vec
[0]->ordinal
;
3006 if (d_export_vec
[d_nfuncs
-1])
3007 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3016 const export_type
**a
= (const export_type
**) av
;
3017 const export_type
**b
= (const export_type
**) bv
;
3019 return strcmp ((*a
)->name
, (*b
)->name
);
3025 /* First work out the minimum ordinal chosen */
3031 export_type
**d_export_vec
3032 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
3034 inform (_("Processing definitions"));
3036 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3038 d_export_vec
[i
] = exp
;
3041 process_duplicates (d_export_vec
);
3042 fill_ordinals (d_export_vec
);
3044 /* Put back the list in the new order */
3046 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3048 d_export_vec
[i
]->next
= d_exports
;
3049 d_exports
= d_export_vec
[i
];
3052 /* Build list in alpha order */
3053 d_exports_lexically
= (export_type
**)
3054 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3056 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3058 d_exports_lexically
[i
] = exp
;
3060 d_exports_lexically
[i
] = 0;
3062 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
3064 /* Fill exp entries with their hint values */
3066 for (i
= 0; i
< d_nfuncs
; i
++)
3068 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3069 d_exports_lexically
[i
]->hint
= hint
++;
3072 inform (_("Processed definitions"));
3075 /**********************************************************************/
3078 usage (file
, status
)
3082 /* xgetext:c-format */
3083 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
3084 /* xgetext:c-format */
3085 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3086 fprintf (file
, _(" possible <machine>: arm[_interwork], i386, mcore[-elf][-le], ppc, thumb\n"));
3087 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3088 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3089 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3090 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3091 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3092 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3093 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3094 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3095 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3096 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3097 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3098 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3099 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3100 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
3101 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3102 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3103 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3104 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3105 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3106 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3107 fprintf (file
, _(" -V --version Display the program version.\n"));
3108 fprintf (file
, _(" -h --help Display this information.\n"));
3109 #ifdef DLLTOOL_MCORE_ELF
3110 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3111 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3112 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3117 #define OPTION_EXPORT_ALL_SYMS 150
3118 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3119 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3120 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3122 static const struct option long_options
[] =
3124 {"no-delete", no_argument
, NULL
, 'n'},
3125 {"dllname", required_argument
, NULL
, 'D'},
3126 {"no-idata4", no_argument
, NULL
, 'x'},
3127 {"no-idata5", no_argument
, NULL
, 'c'},
3128 {"output-exp", required_argument
, NULL
, 'e'},
3129 {"output-def", required_argument
, NULL
, 'z'},
3130 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3131 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3132 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3133 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3134 {"output-lib", required_argument
, NULL
, 'l'},
3135 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
3136 {"input-def", required_argument
, NULL
, 'd'},
3137 {"add-underscore", no_argument
, NULL
, 'U'},
3138 {"kill-at", no_argument
, NULL
, 'k'},
3139 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3140 {"verbose", no_argument
, NULL
, 'v'},
3141 {"version", no_argument
, NULL
, 'V'},
3142 {"help", no_argument
, NULL
, 'h'},
3143 {"machine", required_argument
, NULL
, 'm'},
3144 {"add-indirect", no_argument
, NULL
, 'a'},
3145 {"base-file", required_argument
, NULL
, 'b'},
3146 {"as", required_argument
, NULL
, 'S'},
3147 {"as-flags", required_argument
, NULL
, 'f'},
3148 {"mcore-elf", required_argument
, NULL
, 'M'},
3160 program_name
= av
[0];
3163 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3164 setlocale (LC_MESSAGES
, "");
3166 bindtextdomain (PACKAGE
, LOCALEDIR
);
3167 textdomain (PACKAGE
);
3169 while ((c
= getopt_long (ac
, av
,
3170 #ifdef DLLTOOL_MCORE_ELF
3171 "m:e:l:aD:d:z:b:xcuUkAS:f:nvVhM:L:F:",
3173 "m:e:l:aD:d:z:b:xcuUkAS:f:nvVh",
3180 case OPTION_EXPORT_ALL_SYMS
:
3181 export_all_symbols
= true;
3183 case OPTION_NO_EXPORT_ALL_SYMS
:
3184 export_all_symbols
= false;
3186 case OPTION_EXCLUDE_SYMS
:
3187 add_excludes (optarg
);
3189 case OPTION_NO_DEFAULT_EXCLUDES
:
3190 do_default_excludes
= false;
3205 /* ignored for compatibility */
3212 output_def
= fopen (optarg
, FOPEN_WT
);
3233 print_version (program_name
);
3242 add_stdcall_alias
= 1;
3251 base_file
= fopen (optarg
, FOPEN_RB
);
3254 /* xgettext:c-format */
3255 fatal (_("Unable to open base-file: %s"), optarg
);
3258 #ifdef DLLTOOL_MCORE_ELF
3260 mcore_elf_out_file
= optarg
;
3263 mcore_elf_linker
= optarg
;
3266 mcore_elf_linker_flags
= optarg
;
3275 for (i
= 0; mtable
[i
].type
; i
++)
3276 if (strcmp (mtable
[i
].type
, mname
) == 0)
3279 if (!mtable
[i
].type
)
3280 /* xgettext:c-format */
3281 fatal (_("Machine '%s' not supported"), mname
);
3285 if (!dll_name
&& exp_name
)
3287 int len
= strlen (exp_name
) + 5;
3288 dll_name
= xmalloc (len
);
3289 strcpy (dll_name
, exp_name
);
3290 strcat (dll_name
, ".dll");
3293 if (as_name
== NULL
)
3294 as_name
= deduce_name ("as");
3296 /* Don't use the default exclude list if we're reading only the
3297 symbols in the .drectve section. The default excludes are meant
3298 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3299 if (! export_all_symbols
)
3300 do_default_excludes
= false;
3302 if (do_default_excludes
)
3303 set_default_excludes ();
3306 process_def_file (def_file
);
3311 firstarg
= av
[optind
];
3312 scan_obj_file (av
[optind
]);
3323 /* Make imp_name safe for use as a label. */
3326 imp_name_lab
= xstrdup (imp_name
);
3327 for (p
= imp_name_lab
; *p
; p
++)
3329 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3332 head_label
= make_label("_head_", imp_name_lab
);
3339 #ifdef DLLTOOL_MCORE_ELF
3340 if (mcore_elf_out_file
)
3341 mcore_elf_gen_out_file ();
3347 /* Look for the program formed by concatenating PROG_NAME and the
3348 string running from PREFIX to END_PREFIX. If the concatenated
3349 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
3353 look_for_prog (prog_name
, prefix
, end_prefix
)
3354 const char *prog_name
;
3361 cmd
= xmalloc (strlen (prefix
)
3362 + strlen (prog_name
)
3363 #ifdef HAVE_EXECUTABLE_SUFFIX
3364 + strlen (EXECUTABLE_SUFFIX
)
3367 strcpy (cmd
, prefix
);
3369 sprintf (cmd
+ end_prefix
, "%s", prog_name
);
3371 if (strchr (cmd
, '/') != NULL
)
3375 found
= (stat (cmd
, &s
) == 0
3376 #ifdef HAVE_EXECUTABLE_SUFFIX
3377 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
3383 /* xgettext:c-format */
3384 inform (_("Tried file: %s"), cmd
);
3390 /* xgettext:c-format */
3391 inform (_("Using file: %s"), cmd
);
3396 /* Deduce the name of the program we are want to invoke.
3397 PROG_NAME is the basic name of the program we want to run,
3398 eg "as" or "ld". The catch is that we might want actually
3399 run "i386-pe-as" or "ppc-pe-ld".
3401 If argv[0] contains the full path, then try to find the program
3402 in the same place, with and then without a target-like prefix.
3404 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
3405 deduce_name("as") uses the following search order:
3407 /usr/local/bin/i586-cygwin32-as
3411 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3412 name, it'll try without and then with EXECUTABLE_SUFFIX.
3414 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3415 as the fallback, but rather return i586-cygwin32-as.
3417 Oh, and given, argv[0] = dlltool, it'll return "as".
3419 Returns a dynamically allocated string. */
3422 deduce_name (prog_name
)
3423 const char *prog_name
;
3426 char *dash
, *slash
, *cp
;
3430 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
3435 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3436 *cp
== ':' || *cp
== '\\' ||
3449 /* First, try looking for a prefixed PROG_NAME in the
3450 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
3451 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
3454 if (slash
!= NULL
&& cmd
== NULL
)
3456 /* Next, try looking for a PROG_NAME in the same directory as
3457 that of this program. */
3458 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
3463 /* Just return PROG_NAME as is. */
3464 cmd
= xstrdup (prog_name
);
3470 #ifdef DLLTOOL_MCORE_ELF
3471 typedef struct fname_cache
3474 struct fname_cache
* next
;
3478 static fname_cache fnames
;
3481 mcore_elf_cache_filename (char * filename
)
3487 while (ptr
->next
!= NULL
)
3490 ptr
->filename
= filename
;
3491 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
3492 if (ptr
->next
!= NULL
)
3493 ptr
->next
->next
= NULL
;
3496 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3497 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3498 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3501 mcore_elf_gen_out_file (void)
3506 /* Step one. Run 'ld -r' on the input object files in order to resolve
3507 any internal references and to generate a single .exports section. */
3510 ds
= dyn_string_new (100);
3511 dyn_string_append (ds
, "-r ");
3513 if (mcore_elf_linker_flags
!= NULL
)
3514 dyn_string_append (ds
, mcore_elf_linker_flags
);
3516 while (ptr
->next
!= NULL
)
3518 dyn_string_append (ds
, ptr
->filename
);
3519 dyn_string_append (ds
, " ");
3524 dyn_string_append (ds
, "-o ");
3525 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3527 if (mcore_elf_linker
== NULL
)
3528 mcore_elf_linker
= deduce_name ("ld");
3530 run (mcore_elf_linker
, ds
->s
);
3532 dyn_string_delete (ds
);
3534 /* Step two. Create a .exp file and a .lib file from the temporary file.
3535 Do this by recursively invoking dlltool....*/
3536 ds
= dyn_string_new (100);
3538 dyn_string_append (ds
, "-S ");
3539 dyn_string_append (ds
, as_name
);
3541 dyn_string_append (ds
, " -e ");
3542 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3543 dyn_string_append (ds
, " -l ");
3544 dyn_string_append (ds
, MCORE_ELF_TMP_LIB
);
3545 dyn_string_append (ds
, " " );
3546 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3549 dyn_string_append (ds
, " -v");
3553 dyn_string_append (ds
, " -n");
3555 if (dontdeltemps
> 1)
3556 dyn_string_append (ds
, " -n");
3559 /* XXX - FIME: ought to check/copy other command line options as well. */
3561 run (program_name
, ds
->s
);
3563 dyn_string_delete (ds
);
3565 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
3566 ds
= dyn_string_new (100);
3568 dyn_string_append (ds
, "-shared ");
3570 if (mcore_elf_linker_flags
)
3571 dyn_string_append (ds
, mcore_elf_linker_flags
);
3573 dyn_string_append (ds
, " ");
3574 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3575 dyn_string_append (ds
, " ");
3576 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3577 dyn_string_append (ds
, " -o ");
3578 dyn_string_append (ds
, mcore_elf_out_file
);
3580 run (mcore_elf_linker
, ds
->s
);
3582 dyn_string_delete (ds
);
3584 if (dontdeltemps
== 0)
3585 unlink (MCORE_ELF_TMP_EXP
);
3587 if (dontdeltemps
< 2)
3588 unlink (MCORE_ELF_TMP_OBJ
);
3590 #endif /* DLLTOOL_MCORE_ELF */