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. The exported symbols can optionally
1207 have type tags (eg., -export:foo,data), so handle those as well.
1208 Currently only data tag is supported. */
1214 && strncmp (p
, "-export:", 8) == 0)
1218 flagword flags
= BSF_FUNCTION
;
1222 while (p
< e
&& *p
!= ',' && *p
!= ' ' && *p
!= '-')
1224 c
= xmalloc (p
- name
+ 1);
1225 memcpy (c
, name
, p
- name
);
1227 if (p
< e
&& *p
== ',') /* found type tag. */
1229 char *tag_start
= ++p
;
1230 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1232 if (strncmp (tag_start
, "data", 4) == 0)
1233 flags
&= ~BSF_FUNCTION
;
1237 /* FIXME: The 5th arg is for the `constant' field.
1238 What should it be? Not that it matters since it's not
1239 currently useful. */
1240 def_exports (c
, 0, -1, 0, 0, ! (flags
& BSF_FUNCTION
));
1242 if (add_stdcall_alias
&& strchr (c
, '@'))
1244 char *exported_name
= xstrdup (c
);
1245 char *atsym
= strchr (exported_name
, '@');
1247 /* Note: stdcall alias symbols can never be data. */
1248 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0);
1257 /* Look through the symbols in MINISYMS, and add each one to list of
1258 symbols to export. */
1261 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
)
1268 bfd_byte
*from
, *fromend
;
1270 store
= bfd_make_empty_symbol (abfd
);
1272 bfd_fatal (bfd_get_filename (abfd
));
1274 from
= (bfd_byte
*) minisyms
;
1275 fromend
= from
+ symcount
* size
;
1276 for (; from
< fromend
; from
+= size
)
1279 const char *symbol_name
;
1281 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1283 bfd_fatal (bfd_get_filename (abfd
));
1285 symbol_name
= bfd_asymbol_name (sym
);
1286 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1289 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0,
1290 ! (sym
->flags
& BSF_FUNCTION
));
1292 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1294 char *exported_name
= xstrdup (symbol_name
);
1295 char *atsym
= strchr (exported_name
, '@');
1297 /* Note: stdcall alias symbols can never be data. */
1298 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0);
1303 /* Add a list of symbols to exclude. */
1306 add_excludes (new_excludes
)
1307 const char *new_excludes
;
1310 char *exclude_string
;
1312 local_copy
= xstrdup (new_excludes
);
1314 exclude_string
= strtok (local_copy
, ",:");
1315 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1317 struct string_list
*new_exclude
;
1319 new_exclude
= ((struct string_list
*)
1320 xmalloc (sizeof (struct string_list
)));
1321 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1322 /* FIXME: Is it always right to add a leading underscore? */
1323 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1324 new_exclude
->next
= excludes
;
1325 excludes
= new_exclude
;
1327 /* xgettext:c-format */
1328 inform (_("Excluding symbol: %s\n"), exclude_string
);
1334 /* See if STRING is on the list of symbols to exclude. */
1337 match_exclude (string
)
1340 struct string_list
*excl_item
;
1342 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1343 if (strcmp (string
, excl_item
->string
) == 0)
1348 /* Add the default list of symbols to exclude. */
1351 set_default_excludes (void)
1353 add_excludes (default_excludes
);
1356 /* Choose which symbols to export. */
1359 filter_symbols (abfd
, minisyms
, symcount
, size
)
1365 bfd_byte
*from
, *fromend
, *to
;
1368 store
= bfd_make_empty_symbol (abfd
);
1370 bfd_fatal (bfd_get_filename (abfd
));
1372 from
= (bfd_byte
*) minisyms
;
1373 fromend
= from
+ symcount
* size
;
1374 to
= (bfd_byte
*) minisyms
;
1376 for (; from
< fromend
; from
+= size
)
1381 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const PTR
) from
, store
);
1383 bfd_fatal (bfd_get_filename (abfd
));
1385 /* Check for external and defined only symbols. */
1386 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1387 || (sym
->flags
& BSF_WEAK
) != 0
1388 || bfd_is_com_section (sym
->section
))
1389 && ! bfd_is_und_section (sym
->section
));
1391 keep
= keep
&& ! match_exclude (sym
->name
);
1395 memcpy (to
, from
, size
);
1400 return (to
- (bfd_byte
*) minisyms
) / size
;
1403 /* Export all symbols in ABFD, except for ones we were told not to
1407 scan_all_symbols (abfd
)
1414 /* Ignore bfds with an import descriptor table. We assume that any
1415 such BFD contains symbols which are exported from another DLL,
1416 and we don't want to reexport them from here. */
1417 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1420 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1422 /* xgettext:c-format */
1423 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1427 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1429 bfd_fatal (bfd_get_filename (abfd
));
1433 /* xgettext:c-format */
1434 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1438 /* Discard the symbols we don't want to export. It's OK to do this
1439 in place; we'll free the storage anyway. */
1441 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1442 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1447 /* Look at the object file to decide which symbols to export. */
1450 scan_open_obj_file (abfd
)
1453 if (export_all_symbols
)
1454 scan_all_symbols (abfd
);
1456 scan_drectve_symbols (abfd
);
1458 /* FIXME: we ought to read in and block out the base relocations */
1460 /* xgettext:c-format */
1461 inform (_("Done reading %s\n"), bfd_get_filename (abfd
));
1465 scan_obj_file (filename
)
1466 const char *filename
;
1468 bfd
* f
= bfd_openr (filename
, 0);
1471 /* xgettext:c-format */
1472 fatal (_("Unable to open object file: %s"), filename
);
1474 /* xgettext:c-format */
1475 inform (_("Scanning object file %s"), filename
);
1477 if (bfd_check_format (f
, bfd_archive
))
1479 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1482 if (bfd_check_format (arfile
, bfd_object
))
1483 scan_open_obj_file (arfile
);
1485 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1488 #ifdef DLLTOOL_MCORE_ELF
1489 if (mcore_elf_out_file
)
1490 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename
);
1493 else if (bfd_check_format (f
, bfd_object
))
1495 scan_open_obj_file (f
);
1497 #ifdef DLLTOOL_MCORE_ELF
1498 if (mcore_elf_out_file
)
1499 mcore_elf_cache_filename ((char *) filename
);
1506 /**********************************************************************/
1514 fprintf (f
, "%s ", ASM_C
);
1515 for (i
= 0; oav
[i
]; i
++)
1516 fprintf (f
, "%s ", oav
[i
]);
1518 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1520 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1526 exp
->noname
? "NONAME " : "",
1527 exp
->constant
? "CONSTANT" : "",
1528 exp
->data
? "DATA" : "");
1532 /* Generate the .exp file */
1539 return *(const long *) a
- *(const long *) b
;
1543 flush_page (f
, need
, page_addr
, on_page
)
1551 /* Flush this page */
1552 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1556 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1558 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1560 for (i
= 0; i
< on_page
; i
++)
1562 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (need
[i
] - page_addr
) | 0x3000);
1566 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1575 inform (_("Adding exports to output file"));
1577 fprintf (output_def
, ";");
1578 for (i
= 0; oav
[i
]; i
++)
1579 fprintf (output_def
, " %s", oav
[i
]);
1581 fprintf (output_def
, "\nEXPORTS\n");
1583 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1585 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1586 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1588 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1591 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1596 exp
->noname
? " NONAME" : "",
1597 exp
->data
? " DATA" : "",
1602 char *quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1604 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1612 exp
->noname
? " NONAME" : "",
1613 exp
->data
? " DATA" : "",
1620 inform (_("Added exports to output file"));
1623 /* generate_idata_ofile generates the portable assembly source code
1624 for the idata sections. It appends the source code to the end of
1628 generate_idata_ofile (filvar
)
1637 if (import_list
== NULL
)
1640 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1641 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1642 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1643 fprintf (filvar
, "doi_idata:\n");
1646 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1648 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1649 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1650 ASM_C
, headptr
->dllname
);
1651 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1652 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1653 fprintf (filvar
, "\t%sdllname%d%s\n",
1654 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1655 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1656 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1660 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1661 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1662 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1663 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1664 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1666 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1668 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1670 fprintf (filvar
, "listone%d:\n", headindex
);
1671 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1672 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1673 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1674 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1678 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1680 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1682 fprintf (filvar
, "listtwo%d:\n", headindex
);
1683 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1684 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1685 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1686 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1690 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1692 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1695 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1696 funcptr
= funcptr
->next
)
1698 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1699 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1700 ((funcptr
->ord
) & 0xFFFF));
1701 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1702 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1708 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1710 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1712 fprintf (filvar
,"dllname%d:\n", headindex
);
1713 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1714 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1728 /* xgettext:c-format */
1729 inform (_("Generating export file: %s\n"), exp_name
);
1731 f
= fopen (TMP_ASM
, FOPEN_WT
);
1733 /* xgettext:c-format */
1734 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1736 /* xgettext:c-format */
1737 inform (_("Opened temporary file: %s"), TMP_ASM
);
1743 fprintf (f
, "\t.section .edata\n\n");
1744 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1745 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1747 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1748 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1749 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1752 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1753 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1755 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1756 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1757 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1758 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1760 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1761 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1763 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1765 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1768 fprintf(f
,"%s Export address Table\n", ASM_C
);
1769 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1770 fprintf (f
, "afuncs:\n");
1773 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1775 if (exp
->ordinal
!= i
)
1778 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1780 (exp
->ordinal
- i
) * 4,
1782 i
, exp
->ordinal
- 1);
1785 while (i
< exp
->ordinal
)
1787 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1791 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1793 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1797 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1798 fprintf (f
, "anames:\n");
1800 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1802 if (!exp
->noname
|| show_allnames
)
1803 fprintf (f
, "\t%sn%d%s\n",
1804 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1807 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1808 fprintf (f
, "anords:\n");
1809 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1811 if (!exp
->noname
|| show_allnames
)
1812 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1815 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1816 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1817 if (!exp
->noname
|| show_allnames
)
1818 fprintf (f
, "n%d: %s \"%s\"\n",
1819 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1823 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
1824 for (dl
= a_list
; dl
; dl
= dl
->next
)
1826 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1832 fprintf (f
, "\t.section .rdata\n");
1833 for (dl
= d_list
; dl
; dl
= dl
->next
)
1837 /* We dont output as ascii 'cause there can
1838 be quote characters in the string */
1841 for (p
= dl
->text
; *p
; p
++)
1844 fprintf (f
, "\t%s\t", ASM_BYTE
);
1847 fprintf (f
, "%d", *p
);
1850 fprintf (f
, ",0\n");
1864 /* Add to the output file a way of getting to the exported names
1865 without using the import library. */
1868 fprintf (f
, "\t.section\t.rdata\n");
1869 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1870 if (!exp
->noname
|| show_allnames
)
1872 /* We use a single underscore for MS compatibility, and a
1873 double underscore for backward compatibility with old
1875 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1876 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1877 fprintf (f
, "__imp_%s:\n", exp
->name
);
1878 fprintf (f
, "_imp__%s:\n", exp
->name
);
1879 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1883 /* Dump the reloc section if a base file is provided */
1887 long need
[PAGE_SIZE
];
1894 fprintf (f
, "\t.section\t.init\n");
1895 fprintf (f
, "lab:\n");
1897 fseek (base_file
, 0, SEEK_END
);
1898 numbytes
= ftell (base_file
);
1899 fseek (base_file
, 0, SEEK_SET
);
1900 copy
= xmalloc (numbytes
);
1901 fread (copy
, 1, numbytes
, base_file
);
1902 num_entries
= numbytes
/ sizeof (long);
1905 fprintf (f
, "\t.section\t.reloc\n");
1911 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1912 /* Delete duplcates */
1913 for (src
= 0; src
< num_entries
; src
++)
1915 if (last
!= copy
[src
])
1916 last
= copy
[dst
++] = copy
[src
];
1920 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1922 for (j
= 0; j
< num_entries
; j
++)
1925 if ((addr
& PAGE_MASK
) != page_addr
)
1927 flush_page (f
, need
, page_addr
, on_page
);
1929 page_addr
= addr
& PAGE_MASK
;
1931 need
[on_page
++] = addr
;
1933 flush_page (f
, need
, page_addr
, on_page
);
1935 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1939 generate_idata_ofile (f
);
1943 /* assemble the file */
1944 cmd
= (char *) alloca (strlen (as_flags
) + strlen (exp_name
)
1945 + sizeof TMP_ASM
+ 50);
1946 sprintf (cmd
, "%s -o %s %s", as_flags
, exp_name
, TMP_ASM
);
1949 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
1950 strcat (cmd
, " -mthumb-interwork");
1955 if (dontdeltemps
== 0)
1958 inform (_("Generated exports file"));
1967 char *copy
= xmalloc (strlen (name
) + 2);
1969 strcpy (copy
+ 1, name
);
1976 p
= strchr (name
, '@');
1983 /**********************************************************************/
1992 if (exp
->noname
&& !show_allnames
)
1994 fprintf (f
, "\t%s\t0x%08x\n",
1996 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
2000 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
2018 unsigned char *data
;
2033 static sinfo secdata
[NSECS
] =
2035 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2},
2036 { DATA
, ".data", SEC_DATA
, 2},
2037 { BSS
, ".bss", 0, 2},
2038 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2039 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2040 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2041 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1}
2046 /* Sections numbered to make the order the same as other PowerPC NT */
2047 /* compilers. This also keeps funny alignment thingies from happening. */
2060 static sinfo secdata
[NSECS
] =
2062 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
2063 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
2064 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
2065 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2066 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2067 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
2068 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2069 { DATA
, ".data", SEC_DATA
, 2},
2070 { BSS
, ".bss", 0, 2}
2076 This is what we're trying to make. We generate the imp symbols with
2077 both single and double underscores, for compatibility.
2080 .global _GetFileVersionInfoSizeW@8
2081 .global __imp_GetFileVersionInfoSizeW@8
2082 _GetFileVersionInfoSizeW@8:
2083 jmp * __imp_GetFileVersionInfoSizeW@8
2084 .section .idata$7 # To force loading of head
2085 .long __version_a_head
2086 # Import Address Table
2088 __imp_GetFileVersionInfoSizeW@8:
2091 # Import Lookup Table
2097 .asciz "GetFileVersionInfoSizeW"
2100 For the PowerPC, here's the variation on the above scheme:
2102 # Rather than a simple "jmp *", the code to get to the dll function
2105 lwz r11,[tocv]__imp_function_name(r2)
2106 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2115 make_label (prefix
, name
)
2119 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
2120 char *copy
= xmalloc (len
+1 );
2121 strcpy (copy
, ASM_PREFIX
);
2122 strcat (copy
, prefix
);
2123 strcat (copy
, name
);
2128 make_one_lib_file (exp
, i
)
2136 const char *prefix
= "d";
2139 name
= (char *) alloca (strlen (prefix
) + 10);
2140 sprintf (name
, "%ss%05d.s", prefix
, i
);
2141 f
= fopen (name
, FOPEN_WT
);
2142 fprintf (f
, "\t.text\n");
2143 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
2144 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2145 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
2146 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
2147 exp
->name
, ASM_JUMP
, exp
->name
);
2149 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
2150 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
2153 fprintf (f
,"%s Import Address Table\n", ASM_C
);
2155 fprintf (f
, "\t.section .idata$5\n");
2156 fprintf (f
, "__imp_%s:\n", exp
->name
);
2157 fprintf (f
, "_imp__%s:\n", exp
->name
);
2161 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
2162 fprintf (f
, "\t.section .idata$4\n");
2166 if(!exp
->noname
|| show_allnames
)
2168 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
2169 fprintf (f
, "\t.section .idata$6\n");
2170 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
2171 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
2176 cmd
= (char *) alloca (strlen (as_flags
) + 2 * strlen (prefix
) + 50);
2177 sprintf (cmd
, "%s -o %ss%05d.o %ss%d.s",
2178 as_flags
, prefix
, i
, prefix
, i
);
2181 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2182 strcat (cmd
, " -mthumb-interwork");
2190 asymbol
* exp_label
;
2193 asymbol
* iname_lab
;
2194 asymbol
** iname_lab_pp
;
2195 asymbol
** iname_pp
;
2204 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2206 char * outname
= xmalloc (10);
2210 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2212 abfd
= bfd_openw (outname
, HOW_BFD_TARGET
);
2215 /* xgettext:c-format */
2216 fatal (_("bfd_open failed open stub file: %s"), outname
);
2218 /* xgettext:c-format */
2219 inform (_("Creating stub file: %s"), outname
);
2221 bfd_set_format (abfd
, bfd_object
);
2222 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2225 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2226 bfd_set_private_flags (abfd
, F_INTERWORK
);
2229 /* First make symbols for the sections */
2230 for (i
= 0; i
< NSECS
; i
++)
2232 sinfo
*si
= secdata
+ i
;
2235 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2236 bfd_set_section_flags (abfd
,
2240 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2241 si
->sec
->output_section
= si
->sec
;
2242 si
->sym
= bfd_make_empty_symbol(abfd
);
2243 si
->sym
->name
= si
->sec
->name
;
2244 si
->sym
->section
= si
->sec
;
2245 si
->sym
->flags
= BSF_LOCAL
;
2247 ptrs
[oidx
] = si
->sym
;
2248 si
->sympp
= ptrs
+ oidx
;
2257 exp_label
= bfd_make_empty_symbol (abfd
);
2258 exp_label
->name
= make_label ("", exp
->name
);
2260 /* On PowerPC, the function name points to a descriptor in
2261 the rdata section, the first element of which is a
2262 pointer to the code (..function_name), and the second
2263 points to the .toc */
2265 if (machine
== MPPC
)
2266 exp_label
->section
= secdata
[RDATA
].sec
;
2269 exp_label
->section
= secdata
[TEXT
].sec
;
2271 exp_label
->flags
= BSF_GLOBAL
;
2272 exp_label
->value
= 0;
2275 if (machine
== MTHUMB
)
2276 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2278 ptrs
[oidx
++] = exp_label
;
2281 /* Generate imp symbols with one underscore for Microsoft
2282 compatibility, and with two underscores for backward
2283 compatibility with old versions of cygwin. */
2284 iname
= bfd_make_empty_symbol(abfd
);
2285 iname
->name
= make_label ("__imp_", exp
->name
);
2286 iname
->section
= secdata
[IDATA5
].sec
;
2287 iname
->flags
= BSF_GLOBAL
;
2290 iname2
= bfd_make_empty_symbol(abfd
);
2291 iname2
->name
= make_label ("_imp__", exp
->name
);
2292 iname2
->section
= secdata
[IDATA5
].sec
;
2293 iname2
->flags
= BSF_GLOBAL
;
2296 iname_lab
= bfd_make_empty_symbol(abfd
);
2298 iname_lab
->name
= head_label
;
2299 iname_lab
->section
= (asection
*)&bfd_und_section
;
2300 iname_lab
->flags
= 0;
2301 iname_lab
->value
= 0;
2304 iname_pp
= ptrs
+ oidx
;
2305 ptrs
[oidx
++] = iname
;
2306 ptrs
[oidx
++] = iname2
;
2308 iname_lab_pp
= ptrs
+ oidx
;
2309 ptrs
[oidx
++] = iname_lab
;
2312 /* The symbol refering to the code (.text) */
2314 asymbol
*function_name
;
2316 function_name
= bfd_make_empty_symbol(abfd
);
2317 function_name
->name
= make_label ("..", exp
->name
);
2318 function_name
->section
= secdata
[TEXT
].sec
;
2319 function_name
->flags
= BSF_GLOBAL
;
2320 function_name
->value
= 0;
2322 fn_pp
= ptrs
+ oidx
;
2323 ptrs
[oidx
++] = function_name
;
2326 /* The .toc symbol */
2328 asymbol
*toc_symbol
; /* The .toc symbol */
2330 toc_symbol
= bfd_make_empty_symbol (abfd
);
2331 toc_symbol
->name
= make_label (".", "toc");
2332 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2333 toc_symbol
->flags
= BSF_GLOBAL
;
2334 toc_symbol
->value
= 0;
2336 toc_pp
= ptrs
+ oidx
;
2337 ptrs
[oidx
++] = toc_symbol
;
2343 for (i
= 0; i
< NSECS
; i
++)
2345 sinfo
*si
= secdata
+ i
;
2346 asection
*sec
= si
->sec
;
2355 si
->size
= HOW_JTAB_SIZE
;
2356 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2357 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2359 /* add the reloc into idata$5 */
2360 rel
= xmalloc (sizeof (arelent
));
2362 rpp
= xmalloc (sizeof (arelent
*) * 2);
2366 rel
->address
= HOW_JTAB_ROFF
;
2369 if (machine
== MPPC
)
2371 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2372 BFD_RELOC_16_GOTOFF
);
2373 rel
->sym_ptr_ptr
= iname_pp
;
2377 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2378 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2380 sec
->orelocation
= rpp
;
2381 sec
->reloc_count
= 1;
2386 /* An idata$4 or idata$5 is one word long, and has an
2389 si
->data
= xmalloc (4);
2394 si
->data
[0] = exp
->ordinal
;
2395 si
->data
[1] = exp
->ordinal
>> 8;
2396 si
->data
[2] = exp
->ordinal
>> 16;
2401 sec
->reloc_count
= 1;
2402 memset (si
->data
, 0, si
->size
);
2403 rel
= xmalloc (sizeof (arelent
));
2404 rpp
= xmalloc (sizeof (arelent
*) * 2);
2409 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2410 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2411 sec
->orelocation
= rpp
;
2419 /* This used to add 1 to exp->hint. I don't know
2420 why it did that, and it does not match what I see
2421 in programs compiled with the MS tools. */
2422 int idx
= exp
->hint
;
2423 si
->size
= strlen (xlate (exp
->name
)) + 3;
2424 si
->data
= xmalloc (si
->size
);
2425 si
->data
[0] = idx
& 0xff;
2426 si
->data
[1] = idx
>> 8;
2427 strcpy (si
->data
+ 2, xlate (exp
->name
));
2432 si
->data
=xmalloc(4);
2433 memset (si
->data
, 0, si
->size
);
2434 rel
= xmalloc (sizeof (arelent
));
2435 rpp
= xmalloc (sizeof (arelent
*) * 2);
2439 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2440 rel
->sym_ptr_ptr
= iname_lab_pp
;
2441 sec
->orelocation
= rpp
;
2442 sec
->reloc_count
= 1;
2448 /* The .pdata section is 5 words long. */
2449 /* Think of it as: */
2452 /* bfd_vma BeginAddress, [0x00] */
2453 /* EndAddress, [0x04] */
2454 /* ExceptionHandler, [0x08] */
2455 /* HandlerData, [0x0c] */
2456 /* PrologEndAddress; [0x10] */
2459 /* So this pdata section setups up this as a glue linkage to
2460 a dll routine. There are a number of house keeping things
2463 1. In the name of glue trickery, the ADDR32 relocs for 0,
2464 4, and 0x10 are set to point to the same place:
2466 2. There is one more reloc needed in the pdata section.
2467 The actual glue instruction to restore the toc on
2468 return is saved as the offset in an IMGLUE reloc.
2469 So we need a total of four relocs for this section.
2471 3. Lastly, the HandlerData field is set to 0x03, to indicate
2472 that this is a glue routine.
2474 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2476 /* alignment must be set to 2**2 or you get extra stuff */
2477 bfd_set_section_alignment(abfd
, sec
, 2);
2480 si
->data
=xmalloc(4 * 5);
2481 memset (si
->data
, 0, si
->size
);
2482 rpp
= xmalloc (sizeof (arelent
*) * 5);
2483 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2484 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2485 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2486 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2489 /* stick the toc reload instruction in the glue reloc */
2490 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2493 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2494 BFD_RELOC_32_GOTOFF
);
2495 imglue
->sym_ptr_ptr
= fn_pp
;
2497 ba_rel
->address
= 0;
2499 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2500 ba_rel
->sym_ptr_ptr
= fn_pp
;
2502 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2503 ea_rel
->address
= 4;
2505 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2506 ea_rel
->sym_ptr_ptr
= fn_pp
;
2508 /* mark it as glue */
2509 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2511 /* mark the prolog end address */
2512 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2513 pea_rel
->address
= 0x10;
2514 pea_rel
->addend
= 0;
2515 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2516 pea_rel
->sym_ptr_ptr
= fn_pp
;
2518 sec
->orelocation
= rpp
;
2519 sec
->reloc_count
= 4;
2523 /* Each external function in a PowerPC PE file has a two word
2524 descriptor consisting of:
2525 1. The address of the code.
2526 2. The address of the appropriate .toc
2527 We use relocs to build this.
2531 si
->data
= xmalloc (8);
2532 memset (si
->data
, 0, si
->size
);
2534 rpp
= xmalloc (sizeof (arelent
*) * 3);
2535 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2536 rpp
[1] = xmalloc (sizeof (arelent
));
2541 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2542 rel
->sym_ptr_ptr
= fn_pp
;
2548 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2549 rel
->sym_ptr_ptr
= toc_pp
;
2551 sec
->orelocation
= rpp
;
2552 sec
->reloc_count
= 2;
2554 #endif /* DLLTOOL_PPC */
2560 /* Size up all the sections */
2561 for (i
= 0; i
< NSECS
; i
++)
2563 sinfo
*si
= secdata
+ i
;
2565 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2566 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2568 /* vma += si->size;*/
2571 /* Write them out */
2572 for (i
= 0; i
< NSECS
; i
++)
2574 sinfo
*si
= secdata
+ i
;
2576 if (i
== IDATA5
&& no_idata5
)
2579 if (i
== IDATA4
&& no_idata4
)
2582 bfd_set_section_contents (abfd
, si
->sec
,
2587 bfd_set_symtab (abfd
, ptrs
, oidx
);
2589 abfd
= bfd_openr (outname
, HOW_BFD_TARGET
);
2598 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2603 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2607 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2608 fprintf (f
, "\t.section .idata$2\n");
2610 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2612 fprintf (f
, "%s:\n", head_label
);
2614 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2615 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2617 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2618 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2619 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2620 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2621 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2626 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2628 ASM_RVA_AFTER
, ASM_C
);
2630 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2634 fprintf (f
, "\t.section\t.idata$5\n");
2635 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2636 fprintf (f
, "fthunk:\n");
2641 fprintf (f
, "\t.section\t.idata$4\n");
2643 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2644 fprintf (f
, "\t.section .idata$4\n");
2645 fprintf (f
, "hname:\n");
2650 cmd
= (char *) alloca (strlen (as_flags
) + sizeof TMP_HEAD_O
2651 + sizeof TMP_HEAD_S
+ 50);
2652 sprintf (cmd
, "%s -o %s %s", as_flags
, TMP_HEAD_O
, TMP_HEAD_S
);
2655 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2656 strcat (cmd
, " -mthumb-interwork");
2661 return bfd_openr (TMP_HEAD_O
, HOW_BFD_TARGET
);
2667 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2672 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2678 fprintf (f
, "\t.section .idata$4\n");
2679 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2684 fprintf (f
, "\t.section .idata$5\n");
2685 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2689 /* Normally, we need to see a null descriptor built in idata$3 to
2690 act as the terminator for the list. The ideal way, I suppose,
2691 would be to mark this section as a comdat type 2 section, so
2692 only one would appear in the final .exe (if our linker supported
2693 comdat, that is) or cause it to be inserted by something else (say
2697 fprintf (f
, "\t.section .idata$3\n");
2698 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2699 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2700 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2701 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2702 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2706 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2707 do too. Original, huh? */
2708 fprintf (f
, "\t.section .idata$6\n");
2710 fprintf (f
, "\t.section .idata$7\n");
2713 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2714 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2715 imp_name_lab
, ASM_TEXT
, dll_name
);
2719 cmd
= (char *) alloca (strlen (as_flags
) + sizeof TMP_TAIL_O
2720 + sizeof TMP_TAIL_S
+ 50);
2721 sprintf (cmd
, "%s -o %s %s", as_flags
, TMP_TAIL_O
, TMP_TAIL_S
);
2724 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2725 strcat (cmd
, " -mthumb-interwork");
2730 return bfd_openr (TMP_TAIL_O
, HOW_BFD_TARGET
);
2745 outarch
= bfd_openw (imp_name
, HOW_BFD_TARGET
);
2748 /* xgettext:c-format */
2749 fatal (_("Can't open .lib file: %s"), imp_name
);
2751 /* xgettext:c-format */
2752 inform (_("Creating library file: %s\n"), imp_name
);
2754 bfd_set_format (outarch
, bfd_archive
);
2755 outarch
->has_armap
= 1;
2757 /* Work out a reasonable size of things to put onto one line. */
2759 ar_head
= make_head ();
2760 ar_tail
= make_tail();
2762 if (ar_head
== NULL
|| ar_tail
== NULL
)
2765 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2767 bfd
*n
= make_one_lib_file (exp
, i
);
2772 /* Now stick them all into the archive */
2774 ar_head
->next
= head
;
2775 ar_tail
->next
= ar_head
;
2778 if (! bfd_set_archive_head (outarch
, head
))
2779 bfd_fatal ("bfd_set_archive_head");
2781 if (! bfd_close (outarch
))
2782 bfd_fatal (imp_name
);
2784 while (head
!= NULL
)
2786 bfd
*n
= head
->next
;
2791 /* Delete all the temp files */
2793 if (dontdeltemps
== 0)
2795 unlink (TMP_HEAD_O
);
2796 unlink (TMP_HEAD_S
);
2797 unlink (TMP_TAIL_O
);
2798 unlink (TMP_TAIL_S
);
2801 if (dontdeltemps
< 2)
2805 name
= (char *) alloca (sizeof TMP_STUB
+ 10);
2806 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2808 sprintf (name
, "%s%05d.o", TMP_STUB
, i
);
2809 if (unlink (name
) < 0)
2810 /* xgettext:c-format */
2811 warn (_("cannot delete %s: %s\n"), name
, strerror (errno
));
2815 inform (_("Created lib file"));
2818 /**********************************************************************/
2820 /* Run through the information gathered from the .o files and the
2821 .def file and work out the best stuff */
2827 export_type
*ap
= *(export_type
**) a
;
2828 export_type
*bp
= *(export_type
**) b
;
2829 if (ap
->ordinal
== bp
->ordinal
)
2832 /* unset ordinals go to the bottom */
2833 if (ap
->ordinal
== -1)
2835 if (bp
->ordinal
== -1)
2837 return (ap
->ordinal
- bp
->ordinal
);
2845 export_type
*ap
= *(export_type
**) a
;
2846 export_type
*bp
= *(export_type
**) b
;
2848 return (strcmp (ap
->name
, bp
->name
));
2852 remove_null_names (ptr
)
2857 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2861 ptr
[dst
] = ptr
[src
];
2874 for (i
= 0; i
< d_nfuncs
; i
++)
2878 printf ("%d %s @ %d %s%s%s\n",
2879 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2880 ptr
[i
]->noname
? "NONAME " : "",
2881 ptr
[i
]->constant
? "CONSTANT" : "",
2882 ptr
[i
]->data
? "DATA" : "");
2891 process_duplicates (d_export_vec
)
2892 export_type
**d_export_vec
;
2900 /* Remove duplicates */
2901 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2903 dtab (d_export_vec
);
2904 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2906 if (strcmp (d_export_vec
[i
]->name
,
2907 d_export_vec
[i
+ 1]->name
) == 0)
2910 export_type
*a
= d_export_vec
[i
];
2911 export_type
*b
= d_export_vec
[i
+ 1];
2915 /* xgettext:c-format */
2916 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2917 a
->name
, a
->ordinal
, b
->ordinal
);
2919 if (a
->ordinal
!= -1
2920 && b
->ordinal
!= -1)
2921 /* xgettext:c-format */
2922 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2925 /* Merge attributes */
2926 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2927 b
->constant
|= a
->constant
;
2928 b
->noname
|= a
->noname
;
2930 d_export_vec
[i
] = 0;
2933 dtab (d_export_vec
);
2934 remove_null_names (d_export_vec
);
2935 dtab (d_export_vec
);
2940 /* Count the names */
2941 for (i
= 0; i
< d_nfuncs
; i
++)
2943 if (!d_export_vec
[i
]->noname
)
2949 fill_ordinals (d_export_vec
)
2950 export_type
**d_export_vec
;
2957 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2959 /* fill in the unset ordinals with ones from our range */
2961 ptr
= (char *) xmalloc (size
);
2963 memset (ptr
, 0, size
);
2965 /* Mark in our large vector all the numbers that are taken */
2966 for (i
= 0; i
< d_nfuncs
; i
++)
2968 if (d_export_vec
[i
]->ordinal
!= -1)
2970 ptr
[d_export_vec
[i
]->ordinal
] = 1;
2971 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
2973 lowest
= d_export_vec
[i
]->ordinal
;
2978 /* Start at 1 for compatibility with MS toolchain. */
2982 /* Now fill in ordinals where the user wants us to choose. */
2983 for (i
= 0; i
< d_nfuncs
; i
++)
2985 if (d_export_vec
[i
]->ordinal
== -1)
2989 /* First try within or after any user supplied range. */
2990 for (j
= lowest
; j
< size
; j
++)
2994 d_export_vec
[i
]->ordinal
= j
;
2998 /* Then try before the range. */
2999 for (j
= lowest
; j
>0; j
--)
3003 d_export_vec
[i
]->ordinal
= j
;
3014 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3016 /* Work out the lowest and highest ordinal numbers. */
3019 if (d_export_vec
[0])
3020 d_low_ord
= d_export_vec
[0]->ordinal
;
3021 if (d_export_vec
[d_nfuncs
-1])
3022 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3031 const export_type
**a
= (const export_type
**) av
;
3032 const export_type
**b
= (const export_type
**) bv
;
3034 return strcmp ((*a
)->name
, (*b
)->name
);
3040 /* First work out the minimum ordinal chosen */
3046 export_type
**d_export_vec
3047 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
3049 inform (_("Processing definitions"));
3051 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3053 d_export_vec
[i
] = exp
;
3056 process_duplicates (d_export_vec
);
3057 fill_ordinals (d_export_vec
);
3059 /* Put back the list in the new order */
3061 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3063 d_export_vec
[i
]->next
= d_exports
;
3064 d_exports
= d_export_vec
[i
];
3067 /* Build list in alpha order */
3068 d_exports_lexically
= (export_type
**)
3069 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3071 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3073 d_exports_lexically
[i
] = exp
;
3075 d_exports_lexically
[i
] = 0;
3077 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
3079 /* Fill exp entries with their hint values */
3081 for (i
= 0; i
< d_nfuncs
; i
++)
3083 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3084 d_exports_lexically
[i
]->hint
= hint
++;
3087 inform (_("Processed definitions"));
3090 /**********************************************************************/
3093 usage (file
, status
)
3097 /* xgetext:c-format */
3098 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
3099 /* xgetext:c-format */
3100 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3101 fprintf (file
, _(" possible <machine>: arm[_interwork], i386, mcore[-elf][-le], ppc, thumb\n"));
3102 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3103 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3104 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3105 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3106 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3107 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3108 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3109 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3110 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3111 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3112 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3113 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3114 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3115 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
3116 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3117 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3118 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3119 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3120 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3121 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3122 fprintf (file
, _(" -V --version Display the program version.\n"));
3123 fprintf (file
, _(" -h --help Display this information.\n"));
3124 #ifdef DLLTOOL_MCORE_ELF
3125 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3126 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3127 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3132 #define OPTION_EXPORT_ALL_SYMS 150
3133 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3134 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3135 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3137 static const struct option long_options
[] =
3139 {"no-delete", no_argument
, NULL
, 'n'},
3140 {"dllname", required_argument
, NULL
, 'D'},
3141 {"no-idata4", no_argument
, NULL
, 'x'},
3142 {"no-idata5", no_argument
, NULL
, 'c'},
3143 {"output-exp", required_argument
, NULL
, 'e'},
3144 {"output-def", required_argument
, NULL
, 'z'},
3145 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3146 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3147 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3148 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3149 {"output-lib", required_argument
, NULL
, 'l'},
3150 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
3151 {"input-def", required_argument
, NULL
, 'd'},
3152 {"add-underscore", no_argument
, NULL
, 'U'},
3153 {"kill-at", no_argument
, NULL
, 'k'},
3154 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3155 {"verbose", no_argument
, NULL
, 'v'},
3156 {"version", no_argument
, NULL
, 'V'},
3157 {"help", no_argument
, NULL
, 'h'},
3158 {"machine", required_argument
, NULL
, 'm'},
3159 {"add-indirect", no_argument
, NULL
, 'a'},
3160 {"base-file", required_argument
, NULL
, 'b'},
3161 {"as", required_argument
, NULL
, 'S'},
3162 {"as-flags", required_argument
, NULL
, 'f'},
3163 {"mcore-elf", required_argument
, NULL
, 'M'},
3175 program_name
= av
[0];
3178 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3179 setlocale (LC_MESSAGES
, "");
3181 bindtextdomain (PACKAGE
, LOCALEDIR
);
3182 textdomain (PACKAGE
);
3184 while ((c
= getopt_long (ac
, av
,
3185 #ifdef DLLTOOL_MCORE_ELF
3186 "m:e:l:aD:d:z:b:xcuUkAS:f:nvVhM:L:F:",
3188 "m:e:l:aD:d:z:b:xcuUkAS:f:nvVh",
3195 case OPTION_EXPORT_ALL_SYMS
:
3196 export_all_symbols
= true;
3198 case OPTION_NO_EXPORT_ALL_SYMS
:
3199 export_all_symbols
= false;
3201 case OPTION_EXCLUDE_SYMS
:
3202 add_excludes (optarg
);
3204 case OPTION_NO_DEFAULT_EXCLUDES
:
3205 do_default_excludes
= false;
3220 /* ignored for compatibility */
3227 output_def
= fopen (optarg
, FOPEN_WT
);
3248 print_version (program_name
);
3257 add_stdcall_alias
= 1;
3266 base_file
= fopen (optarg
, FOPEN_RB
);
3269 /* xgettext:c-format */
3270 fatal (_("Unable to open base-file: %s"), optarg
);
3273 #ifdef DLLTOOL_MCORE_ELF
3275 mcore_elf_out_file
= optarg
;
3278 mcore_elf_linker
= optarg
;
3281 mcore_elf_linker_flags
= optarg
;
3290 for (i
= 0; mtable
[i
].type
; i
++)
3291 if (strcmp (mtable
[i
].type
, mname
) == 0)
3294 if (!mtable
[i
].type
)
3295 /* xgettext:c-format */
3296 fatal (_("Machine '%s' not supported"), mname
);
3300 if (!dll_name
&& exp_name
)
3302 int len
= strlen (exp_name
) + 5;
3303 dll_name
= xmalloc (len
);
3304 strcpy (dll_name
, exp_name
);
3305 strcat (dll_name
, ".dll");
3308 if (as_name
== NULL
)
3309 as_name
= deduce_name ("as");
3311 /* Don't use the default exclude list if we're reading only the
3312 symbols in the .drectve section. The default excludes are meant
3313 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3314 if (! export_all_symbols
)
3315 do_default_excludes
= false;
3317 if (do_default_excludes
)
3318 set_default_excludes ();
3321 process_def_file (def_file
);
3326 firstarg
= av
[optind
];
3327 scan_obj_file (av
[optind
]);
3338 /* Make imp_name safe for use as a label. */
3341 imp_name_lab
= xstrdup (imp_name
);
3342 for (p
= imp_name_lab
; *p
; p
++)
3344 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3347 head_label
= make_label("_head_", imp_name_lab
);
3354 #ifdef DLLTOOL_MCORE_ELF
3355 if (mcore_elf_out_file
)
3356 mcore_elf_gen_out_file ();
3362 /* Look for the program formed by concatenating PROG_NAME and the
3363 string running from PREFIX to END_PREFIX. If the concatenated
3364 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
3368 look_for_prog (prog_name
, prefix
, end_prefix
)
3369 const char *prog_name
;
3376 cmd
= xmalloc (strlen (prefix
)
3377 + strlen (prog_name
)
3378 #ifdef HAVE_EXECUTABLE_SUFFIX
3379 + strlen (EXECUTABLE_SUFFIX
)
3382 strcpy (cmd
, prefix
);
3384 sprintf (cmd
+ end_prefix
, "%s", prog_name
);
3386 if (strchr (cmd
, '/') != NULL
)
3390 found
= (stat (cmd
, &s
) == 0
3391 #ifdef HAVE_EXECUTABLE_SUFFIX
3392 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
3398 /* xgettext:c-format */
3399 inform (_("Tried file: %s"), cmd
);
3405 /* xgettext:c-format */
3406 inform (_("Using file: %s"), cmd
);
3411 /* Deduce the name of the program we are want to invoke.
3412 PROG_NAME is the basic name of the program we want to run,
3413 eg "as" or "ld". The catch is that we might want actually
3414 run "i386-pe-as" or "ppc-pe-ld".
3416 If argv[0] contains the full path, then try to find the program
3417 in the same place, with and then without a target-like prefix.
3419 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
3420 deduce_name("as") uses the following search order:
3422 /usr/local/bin/i586-cygwin32-as
3426 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3427 name, it'll try without and then with EXECUTABLE_SUFFIX.
3429 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3430 as the fallback, but rather return i586-cygwin32-as.
3432 Oh, and given, argv[0] = dlltool, it'll return "as".
3434 Returns a dynamically allocated string. */
3437 deduce_name (prog_name
)
3438 const char *prog_name
;
3441 char *dash
, *slash
, *cp
;
3445 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
3450 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3451 *cp
== ':' || *cp
== '\\' ||
3464 /* First, try looking for a prefixed PROG_NAME in the
3465 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
3466 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
3469 if (slash
!= NULL
&& cmd
== NULL
)
3471 /* Next, try looking for a PROG_NAME in the same directory as
3472 that of this program. */
3473 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
3478 /* Just return PROG_NAME as is. */
3479 cmd
= xstrdup (prog_name
);
3485 #ifdef DLLTOOL_MCORE_ELF
3486 typedef struct fname_cache
3489 struct fname_cache
* next
;
3493 static fname_cache fnames
;
3496 mcore_elf_cache_filename (char * filename
)
3502 while (ptr
->next
!= NULL
)
3505 ptr
->filename
= filename
;
3506 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
3507 if (ptr
->next
!= NULL
)
3508 ptr
->next
->next
= NULL
;
3511 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3512 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3513 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3516 mcore_elf_gen_out_file (void)
3521 /* Step one. Run 'ld -r' on the input object files in order to resolve
3522 any internal references and to generate a single .exports section. */
3525 ds
= dyn_string_new (100);
3526 dyn_string_append (ds
, "-r ");
3528 if (mcore_elf_linker_flags
!= NULL
)
3529 dyn_string_append (ds
, mcore_elf_linker_flags
);
3531 while (ptr
->next
!= NULL
)
3533 dyn_string_append (ds
, ptr
->filename
);
3534 dyn_string_append (ds
, " ");
3539 dyn_string_append (ds
, "-o ");
3540 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3542 if (mcore_elf_linker
== NULL
)
3543 mcore_elf_linker
= deduce_name ("ld");
3545 run (mcore_elf_linker
, ds
->s
);
3547 dyn_string_delete (ds
);
3549 /* Step two. Create a .exp file and a .lib file from the temporary file.
3550 Do this by recursively invoking dlltool....*/
3551 ds
= dyn_string_new (100);
3553 dyn_string_append (ds
, "-S ");
3554 dyn_string_append (ds
, as_name
);
3556 dyn_string_append (ds
, " -e ");
3557 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3558 dyn_string_append (ds
, " -l ");
3559 dyn_string_append (ds
, MCORE_ELF_TMP_LIB
);
3560 dyn_string_append (ds
, " " );
3561 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3564 dyn_string_append (ds
, " -v");
3568 dyn_string_append (ds
, " -n");
3570 if (dontdeltemps
> 1)
3571 dyn_string_append (ds
, " -n");
3574 /* XXX - FIME: ought to check/copy other command line options as well. */
3576 run (program_name
, ds
->s
);
3578 dyn_string_delete (ds
);
3580 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
3581 ds
= dyn_string_new (100);
3583 dyn_string_append (ds
, "-shared ");
3585 if (mcore_elf_linker_flags
)
3586 dyn_string_append (ds
, mcore_elf_linker_flags
);
3588 dyn_string_append (ds
, " ");
3589 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3590 dyn_string_append (ds
, " ");
3591 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3592 dyn_string_append (ds
, " -o ");
3593 dyn_string_append (ds
, mcore_elf_out_file
);
3595 run (mcore_elf_linker
, ds
->s
);
3597 dyn_string_delete (ds
);
3599 if (dontdeltemps
== 0)
3600 unlink (MCORE_ELF_TMP_EXP
);
3602 if (dontdeltemps
< 2)
3603 unlink (MCORE_ELF_TMP_OBJ
);
3605 #endif /* DLLTOOL_MCORE_ELF */