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
151 # put them in a library (you don't have to, you
152 # could name all the .os on the dlltool line)
154 ar qcv thedll.in file1.o file2.o
157 # run this tool over the library and the def file
158 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
160 # build the dll with the library with file1.o, file2.o and the export table
161 ld -o thedll.dll thedll.o thedll.in
166 # link the executable with the import library
167 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
171 /* .idata section description
173 The .idata section is the import table. It is a collection of several
174 subsections used to keep the pieces for each dll together: .idata$[234567].
175 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
177 .idata$2 = Import Directory Table
178 = array of IMAGE_IMPORT_DESCRIPTOR's.
180 DWORD Import Lookup Table; - pointer to .idata$4
181 DWORD TimeDateStamp; - currently always 0
182 DWORD ForwarderChain; - currently always 0
183 DWORD Name; - pointer to dll's name
184 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
186 .idata$3 = null terminating entry for .idata$2.
188 .idata$4 = Import Lookup Table
189 = array of array of pointers to hint name table.
190 There is one for each dll being imported from, and each dll's set is
191 terminated by a trailing NULL.
193 .idata$5 = Import Address Table
194 = array of array of pointers to hint name table.
195 There is one for each dll being imported from, and each dll's set is
196 terminated by a trailing NULL.
197 Initially, this table is identical to the Import Lookup Table. However,
198 at load time, the loader overwrites the entries with the address of the
201 .idata$6 = Hint Name Table
202 = Array of { short, asciz } entries, one for each imported function.
203 The `short' is the function's ordinal number.
205 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
208 /* AIX requires this to be the first thing in the file. */
215 #define show_allnames 0
217 #define PAGE_SIZE 4096
218 #define PAGE_MASK (-PAGE_SIZE)
220 #include "libiberty.h"
223 #include "demangle.h"
235 #include "coff/arm.h"
236 #include "coff/internal.h"
239 #ifdef HAVE_SYS_WAIT_H
240 #include <sys/wait.h>
241 #else /* ! HAVE_SYS_WAIT_H */
242 #if ! defined (_WIN32) || defined (__CYGWIN32__)
244 #define WIFEXITED(w) (((w)&0377) == 0)
247 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
250 #define WTERMSIG(w) ((w) & 0177)
253 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
255 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
257 #define WIFEXITED(w) (((w) & 0xff) == 0)
260 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
263 #define WTERMSIG(w) ((w) & 0x7f)
266 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
268 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
269 #endif /* ! HAVE_SYS_WAIT_H */
271 /* ifunc and ihead data structures: ttk@cygnus.com 1997
273 When IMPORT declarations are encountered in a .def file the
274 function import information is stored in a structure referenced by
275 the global variable IMPORT_LIST. The structure is a linked list
276 containing the names of the dll files each function is imported
277 from and a linked list of functions being imported from that dll
278 file. This roughly parallels the structure of the .idata section
279 in the PE object file.
281 The contents of .def file are interpreted from within the
282 process_def_file function. Every time an IMPORT declaration is
283 encountered, it is broken up into its component parts and passed to
284 def_import. IMPORT_LIST is initialized to NULL in function main. */
286 typedef struct ifunct
288 char *name
; /* name of function being imported */
289 int ord
; /* two-byte ordinal value associated with function */
293 typedef struct iheadt
295 char *dllname
; /* name of dll file imported from */
296 long nfuncs
; /* number of functions in list */
297 struct ifunct
*funchead
; /* first function in list */
298 struct ifunct
*functail
; /* last function in list */
299 struct iheadt
*next
; /* next dll file in list */
302 /* Structure containing all import information as defined in .def file
303 (qv "ihead structure"). */
305 static iheadtype
*import_list
= NULL
;
307 static char *as_name
= "as";
308 static char * as_flags
= "";
310 static int no_idata4
;
311 static int no_idata5
;
312 static char *exp_name
;
313 static char *imp_name
;
314 static char *head_label
;
315 static char *imp_name_lab
;
316 static char *dll_name
;
318 static int add_indirect
= 0;
319 static int add_underscore
= 0;
320 static int dontdeltemps
= 0;
323 static int interwork
= 0;
326 /* True if we should export all symbols. Otherwise, we only export
327 symbols listed in .drectve sections or in the def file. */
328 static boolean export_all_symbols
;
330 /* True if we should exclude the symbols in DEFAULT_EXCLUDES when
331 exporting all symbols. */
332 static boolean do_default_excludes
;
334 /* Default symbols to exclude when exporting all the symbols. */
335 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
337 static char *def_file
;
339 extern char * program_name
;
343 static int add_stdcall_alias
;
345 static FILE *output_def
;
346 static FILE *base_file
;
349 static const char *mname
= "beos";
353 static const char *mname
= "arm";
357 static const char *mname
= "i386";
361 static const char *mname
= "ppc";
364 #define PATHMAX 250 /* What's the right name for this ? */
366 #define TMP_ASM "dc.s"
367 #define TMP_HEAD_S "dh.s"
368 #define TMP_HEAD_O "dh.o"
369 #define TMP_TAIL_S "dt.s"
370 #define TMP_TAIL_O "dt.o"
371 #define TMP_STUB "ds"
373 /* This bit of assemly does jmp * ....
374 s set how_jtab_roff to mark where the 32bit abs branch should go */
375 static const unsigned char i386_jtab
[] =
377 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
380 static const unsigned char arm_jtab
[] =
382 0x00, 0xc0, 0x9f, 0xe5,
383 0x00, 0xf0, 0x9c, 0xe5,
387 static const unsigned char thumb_jtab
[] =
398 /* This is the glue sequence for PowerPC PE. There is a */
399 /* tocrel16-tocdefn reloc against the first instruction. */
400 /* We also need a IMGLUE reloc against the glue function */
401 /* to restore the toc saved by the third instruction in */
403 static const unsigned char ppc_jtab
[] =
405 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
406 /* Reloc TOCREL16 __imp_xxx */
407 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
408 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
409 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
410 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
411 0x20, 0x04, 0x80, 0x4E /* bctr */
415 /* the glue instruction, picks up the toc from the stw in */
416 /* the above code: "lwz r2,4(r1)" */
417 static bfd_vma ppc_glue_insn
= 0x80410004;
420 /* The outfile array must be big enough to contain a fully
421 qualified path name, plus an arbitary series of command
422 line switches. We hope that PATH_MAX times two will be
424 static char outfile
[PATHMAX
* 2];
429 const char *how_byte
;
430 const char *how_short
;
431 const char *how_long
;
432 const char *how_asciz
;
433 const char *how_comment
;
434 const char *how_jump
;
435 const char *how_global
;
436 const char *how_space
;
437 const char *how_align_short
;
438 const char *how_align_long
;
439 const char *how_bfd_target
;
440 enum bfd_architecture how_bfd_arch
;
441 const unsigned char *how_jtab
;
442 int how_jtab_size
; /* size of the jtab entry */
443 int how_jtab_roff
; /* offset into it for the ind 32 reloc into idata 5 */
446 static const struct mac
451 "arm", ".byte", ".short", ".long", ".asciz", "@",
452 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
453 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
454 arm_jtab
, sizeof (arm_jtab
), 8
459 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386
,
460 i386_jtab
, sizeof (i386_jtab
), 2
465 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc
,
466 ppc_jtab
, sizeof (ppc_jtab
), 0
471 "thumb", ".byte", ".short", ".long", ".asciz", "@",
472 "push\t{r6, r7}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tstr\tr6, [sp, #4]\n\tpop\t{r6, pc}\n\tnop",
473 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
474 thumb_jtab
, sizeof (thumb_jtab
), 12
487 typedef struct export
490 const char *internal_name
;
500 /* A list of symbols which we should not export. */
504 struct string_list
*next
;
508 static struct string_list
*excludes
;
510 static const char *rvaafter
PARAMS ((int));
511 static const char *rvabefore
PARAMS ((int));
512 static const char *asm_prefix
PARAMS ((int));
513 static void append_import
PARAMS ((const char *, const char *, int));
514 static void run
PARAMS ((const char *, char *));
515 static void scan_drectve_symbols
PARAMS ((bfd
*));
516 static void scan_filtered_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
517 static void add_excludes
PARAMS ((const char *));
518 static boolean match_exclude
PARAMS ((const char *));
519 static void set_default_excludes
PARAMS ((void));
520 static long filter_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
521 static void scan_all_symbols
PARAMS ((bfd
*));
522 static void scan_open_obj_file
PARAMS ((bfd
*));
523 static void scan_obj_file
PARAMS ((const char *));
524 static void dump_def_info
PARAMS ((FILE *));
525 static int sfunc
PARAMS ((const void *, const void *));
526 static void flush_page
PARAMS ((FILE *, long *, int, int));
527 static void gen_def_file
PARAMS ((void));
528 static void generate_idata_ofile
PARAMS ((FILE *));
529 static void gen_exp_file
PARAMS ((void));
530 static const char *xlate
PARAMS ((const char *));
532 static void dump_iat
PARAMS ((FILE *, export_type
*));
534 static char *make_label
PARAMS ((const char *, const char *));
535 static bfd
*make_one_lib_file
PARAMS ((export_type
*, int));
536 static bfd
*make_head
PARAMS ((void));
537 static bfd
*make_tail
PARAMS ((void));
538 static void gen_lib_file
PARAMS ((void));
539 static int pfunc
PARAMS ((const void *, const void *));
540 static int nfunc
PARAMS ((const void *, const void *));
541 static void remove_null_names
PARAMS ((export_type
**));
542 static void dtab
PARAMS ((export_type
**));
543 static void process_duplicates
PARAMS ((export_type
**));
544 static void fill_ordinals
PARAMS ((export_type
**));
545 static int alphafunc
PARAMS ((const void *, const void *));
546 static void mangle_defs
PARAMS ((void));
547 static void usage
PARAMS ((FILE *, int));
548 static void display
PARAMS ((const char *, va_list));
549 static void inform
PARAMS ((const char *, ...));
550 static void warn
PARAMS ((const char *, ...));
553 display (message
, args
)
554 const char * message
;
557 if (program_name
!= NULL
)
558 fprintf (stderr
, "%s: ", program_name
);
560 vfprintf (stderr
, message
, args
);
562 if (message
[strlen (message
) - 1] != '\n')
563 fputc ('\n', stderr
);
569 inform (const char * message
, ...)
571 inform (message
, va_alist
)
572 const char * message
;
582 va_start (args
, message
);
587 display (message
, args
);
594 warn (const char * message
, ...)
596 warn (message
, va_alist
)
597 const char * message
;
604 va_start (args
, message
);
609 display (message
, args
);
626 /* xgettext:c-format */
627 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
645 /* xgettext:c-format */
646 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
665 /* xgettext:c-format */
666 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
672 #define ASM_BYTE mtable[machine].how_byte
673 #define ASM_SHORT mtable[machine].how_short
674 #define ASM_LONG mtable[machine].how_long
675 #define ASM_TEXT mtable[machine].how_asciz
676 #define ASM_C mtable[machine].how_comment
677 #define ASM_JUMP mtable[machine].how_jump
678 #define ASM_GLOBAL mtable[machine].how_global
679 #define ASM_SPACE mtable[machine].how_space
680 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
681 #define ASM_RVA_BEFORE rvabefore(machine)
682 #define ASM_RVA_AFTER rvaafter(machine)
683 #define ASM_PREFIX asm_prefix(machine)
684 #define ASM_ALIGN_LONG mtable[machine].how_align_long
685 #define HOW_BFD_TARGET 0 /* always default*/
686 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
687 #define HOW_JTAB mtable[machine].how_jtab
688 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
689 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
693 process_def_file (name
)
696 FILE *f
= fopen (name
, FOPEN_RT
);
699 /* xgettext:c-format */
700 fatal (_("Can't open def file: %s"), name
);
704 /* xgettext:c-format */
705 inform (_("Processing def file: %s"), name
);
709 inform (_("Processed def file"));
712 /**********************************************************************/
714 /* Communications with the parser */
716 static const char *d_name
; /* Arg to NAME or LIBRARY */
717 static int d_nfuncs
; /* Number of functions exported */
718 static int d_named_nfuncs
; /* Number of named functions exported */
719 static int d_low_ord
; /* Lowest ordinal index */
720 static int d_high_ord
; /* Highest ordinal index */
721 static export_type
*d_exports
; /*list of exported functions */
722 static export_type
**d_exports_lexically
; /* vector of exported functions in alpha order */
723 static dlist_type
*d_list
; /* Descriptions */
724 static dlist_type
*a_list
; /* Stuff to go in directives */
733 /* xgettext:c-format */
734 warn (_("Syntax error in def file %s:%d\n"), def_file
, linenumber
);
740 def_exports (name
, internal_name
, ordinal
, noname
, constant
, data
)
742 const char *internal_name
;
748 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
751 p
->internal_name
= internal_name
? internal_name
: name
;
752 p
->ordinal
= ordinal
;
753 p
->constant
= constant
;
762 def_name (name
, base
)
766 /* xgettext:c-format */
767 inform (_("NAME: %s base: %x"), name
, base
);
770 warn (_("Can't have LIBRARY and NAME\n"));
773 /* if --dllname not provided, use the one in the DEF file.
774 FIXME: Is this appropriate for executables? */
776 dll_name
= xstrdup (name
);
781 def_library (name
, base
)
785 /* xgettext:c-format */
786 inform (_("LIBRARY: %s base: %x"), name
, base
);
789 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name
);
792 /* if --dllname not provided, use the one in the DEF file. */
794 dll_name
= xstrdup (name
);
799 def_description (desc
)
802 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
803 d
->text
= xstrdup (desc
);
812 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
813 d
->text
= xstrdup (dir
);
819 def_heapsize (reserve
, commit
)
825 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
827 sprintf (b
, "-heap 0x%x ", reserve
);
828 new_directive (xstrdup (b
));
832 def_stacksize (reserve
, commit
)
838 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
840 sprintf (b
, "-stack 0x%x ", reserve
);
841 new_directive (xstrdup (b
));
844 /* append_import simply adds the given import definition to the global
845 import_list. It is used by def_import. */
848 append_import (symbol_name
, dll_name
, func_ordinal
)
849 const char *symbol_name
;
850 const char *dll_name
;
856 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
858 if (strcmp ((*pq
)->dllname
, dll_name
) == 0)
861 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
862 q
->functail
= q
->functail
->next
;
863 q
->functail
->ord
= func_ordinal
;
864 q
->functail
->name
= xstrdup (symbol_name
);
865 q
->functail
->next
= NULL
;
871 q
= xmalloc (sizeof (iheadtype
));
872 q
->dllname
= xstrdup (dll_name
);
874 q
->funchead
= xmalloc (sizeof (ifunctype
));
875 q
->functail
= q
->funchead
;
877 q
->functail
->name
= xstrdup (symbol_name
);
878 q
->functail
->ord
= func_ordinal
;
879 q
->functail
->next
= NULL
;
884 /* def_import is called from within defparse.y when an IMPORT
885 declaration is encountered. Depending on the form of the
886 declaration, the module name may or may not need ".dll" to be
887 appended to it, the name of the function may be stored in internal
888 or entry, and there may or may not be an ordinal value associated
891 /* A note regarding the parse modes:
892 In defparse.y we have to accept import declarations which follow
893 any one of the following forms:
894 <func_name_in_app> = <dll_name>.<func_name_in_dll>
895 <func_name_in_app> = <dll_name>.<number>
896 <dll_name>.<func_name_in_dll>
898 Furthermore, the dll's name may or may not end with ".dll", which
899 complicates the parsing a little. Normally the dll's name is
900 passed to def_import() in the "module" parameter, but when it ends
901 with ".dll" it gets passed in "module" sans ".dll" and that needs
904 def_import gets five parameters:
905 APP_NAME - the name of the function in the application, if
906 present, or NULL if not present.
907 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
908 DLLEXT - the extension of the dll, if present, NULL if not present.
909 ENTRY - the name of the function in the dll, if present, or NULL.
910 ORD_VAL - the numerical tag of the function in the dll, if present,
911 or NULL. Exactly one of <entry> or <ord_val> must be
912 present (i.e., not NULL). */
915 def_import (app_name
, module
, dllext
, entry
, ord_val
)
916 const char *app_name
;
922 const char *application_name
;
926 application_name
= entry
;
929 if (app_name
!= NULL
)
930 application_name
= app_name
;
932 application_name
= "";
937 buf
= (char *) alloca (strlen (module
) + strlen (dllext
) + 2);
938 sprintf (buf
, "%s.%s", module
, dllext
);
942 append_import (application_name
, module
, ord_val
);
946 def_version (major
, minor
)
950 printf ("VERSION %d.%d\n", major
, minor
);
954 def_section (name
, attr
)
971 sprintf (buf
, "-attr %s %s", name
, atts
);
972 new_directive (xstrdup (buf
));
980 def_section ("CODE", attr
);
987 def_section ("DATA", attr
);
990 /**********************************************************************/
998 int pid
, wait_status
;
1001 char *errmsg_fmt
, *errmsg_arg
;
1002 char *temp_base
= choose_temp_base ();
1004 inform ("run: %s %s\n", what
, args
);
1006 /* Count the args */
1008 for (s
= args
; *s
; s
++)
1012 argv
= alloca (sizeof (char *) * (i
+ 3));
1021 while (*s
!= ' ' && *s
!= 0)
1029 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1030 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1034 inform (strerror (errno
));
1036 fatal (errmsg_fmt
, errmsg_arg
);
1039 pid
= pwait (pid
, & wait_status
, 0);
1043 /* xgettext:c-format */
1044 fatal (_("wait: %s"), strerror (errno
));
1046 else if (WIFSIGNALED (wait_status
))
1048 /* xgettext:c-format */
1049 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1051 else if (WIFEXITED (wait_status
))
1053 if (WEXITSTATUS (wait_status
) != 0)
1054 /* xgettext:c-format */
1055 warn (_("%s exited with status %d\n"),
1056 what
, WEXITSTATUS (wait_status
));
1062 /* Look for a list of symbols to export in the .drectve section of
1063 ABFD. Pass each one to def_exports. */
1066 scan_drectve_symbols (abfd
)
1075 /* Look for .drectve's */
1076 s
= bfd_get_section_by_name (abfd
, ".drectve");
1081 size
= bfd_get_section_size_before_reloc (s
);
1082 buf
= xmalloc (size
);
1084 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1086 /* xgettext:c-format */
1087 inform (_("Sucking in info from .drective section in %s\n"),
1088 bfd_get_filename (abfd
));
1090 /* Search for -export: strings */
1096 && strncmp (p
, "-export:", 8) == 0)
1103 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1105 c
= xmalloc (p
- name
+ 1);
1106 memcpy (c
, name
, p
- name
);
1109 /* FIXME: The 5th arg is for the `constant' field.
1110 What should it be? Not that it matters since it's not
1111 currently useful. */
1112 def_exports (c
, 0, -1, 0, 0, 0);
1114 if (add_stdcall_alias
&& strchr (c
, '@'))
1116 char *exported_name
= xstrdup (c
);
1117 char *atsym
= strchr (exported_name
, '@');
1119 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0);
1128 /* Look through the symbols in MINISYMS, and add each one to list of
1129 symbols to export. */
1132 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
)
1139 bfd_byte
*from
, *fromend
;
1141 store
= bfd_make_empty_symbol (abfd
);
1143 bfd_fatal (bfd_get_filename (abfd
));
1145 from
= (bfd_byte
*) minisyms
;
1146 fromend
= from
+ symcount
* size
;
1147 for (; from
< fromend
; from
+= size
)
1150 const char *symbol_name
;
1152 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1154 bfd_fatal (bfd_get_filename (abfd
));
1156 symbol_name
= bfd_asymbol_name (sym
);
1157 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1160 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0, 0);
1162 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1164 char *exported_name
= xstrdup (symbol_name
);
1165 char *atsym
= strchr (exported_name
, '@');
1167 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0);
1172 /* Add a list of symbols to exclude. */
1175 add_excludes (new_excludes
)
1176 const char *new_excludes
;
1179 char *exclude_string
;
1181 local_copy
= xstrdup (new_excludes
);
1183 exclude_string
= strtok (local_copy
, ",:");
1184 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1186 struct string_list
*new_exclude
;
1188 new_exclude
= ((struct string_list
*)
1189 xmalloc (sizeof (struct string_list
)));
1190 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1191 /* FIXME: Is it always right to add a leading underscore? */
1192 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1193 new_exclude
->next
= excludes
;
1194 excludes
= new_exclude
;
1196 /* xgettext:c-format */
1197 inform (_("Excluding symbol: %s\n"), exclude_string
);
1203 /* See if STRING is on the list of symbols to exclude. */
1206 match_exclude (string
)
1209 struct string_list
*excl_item
;
1211 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1212 if (strcmp (string
, excl_item
->string
) == 0)
1217 /* Add the default list of symbols to exclude. */
1220 set_default_excludes (void)
1222 add_excludes (default_excludes
);
1225 /* Choose which symbols to export. */
1228 filter_symbols (abfd
, minisyms
, symcount
, size
)
1234 bfd_byte
*from
, *fromend
, *to
;
1237 store
= bfd_make_empty_symbol (abfd
);
1239 bfd_fatal (bfd_get_filename (abfd
));
1241 from
= (bfd_byte
*) minisyms
;
1242 fromend
= from
+ symcount
* size
;
1243 to
= (bfd_byte
*) minisyms
;
1245 for (; from
< fromend
; from
+= size
)
1250 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const PTR
) from
, store
);
1252 bfd_fatal (bfd_get_filename (abfd
));
1254 /* Check for external and defined only symbols. */
1255 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1256 || (sym
->flags
& BSF_WEAK
) != 0
1257 || bfd_is_com_section (sym
->section
))
1258 && ! bfd_is_und_section (sym
->section
));
1260 keep
= keep
&& ! match_exclude (sym
->name
);
1264 memcpy (to
, from
, size
);
1269 return (to
- (bfd_byte
*) minisyms
) / size
;
1272 /* Export all symbols in ABFD, except for ones we were told not to
1276 scan_all_symbols (abfd
)
1283 /* Ignore bfds with an import descriptor table. We assume that any
1284 such BFD contains symbols which are exported from another DLL,
1285 and we don't want to reexport them from here. */
1286 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1289 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1291 /* xgettext:c-format */
1292 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1296 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1298 bfd_fatal (bfd_get_filename (abfd
));
1302 /* xgettext:c-format */
1303 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1307 /* Discard the symbols we don't want to export. It's OK to do this
1308 in place; we'll free the storage anyway. */
1310 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1311 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1316 /* Look at the object file to decide which symbols to export. */
1319 scan_open_obj_file (abfd
)
1322 if (export_all_symbols
)
1323 scan_all_symbols (abfd
);
1325 scan_drectve_symbols (abfd
);
1327 /* FIXME: we ought to read in and block out the base relocations */
1329 /* xgettext:c-format */
1330 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd
));
1334 scan_obj_file (filename
)
1335 const char *filename
;
1337 bfd
* f
= bfd_openr (filename
, 0);
1340 /* xgettext:c-format */
1341 fatal (_("Unable to open object file: %s"), filename
);
1343 /* xgettext:c-format */
1344 inform (_("Scanning object file %s"), filename
);
1346 if (bfd_check_format (f
, bfd_archive
))
1348 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1351 if (bfd_check_format (arfile
, bfd_object
))
1352 scan_open_obj_file (arfile
);
1354 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1357 else if (bfd_check_format (f
, bfd_object
))
1359 scan_open_obj_file (f
);
1365 /**********************************************************************/
1373 fprintf (f
, "%s ", ASM_C
);
1374 for (i
= 0; oav
[i
]; i
++)
1375 fprintf (f
, "%s ", oav
[i
]);
1377 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1379 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1385 exp
->noname
? "NONAME " : "",
1386 exp
->constant
? "CONSTANT" : "",
1387 exp
->data
? "DATA" : "");
1391 /* Generate the .exp file */
1398 return *(const long *) a
- *(const long *) b
;
1402 flush_page (f
, need
, page_addr
, on_page
)
1410 /* Flush this page */
1411 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1415 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1417 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1419 for (i
= 0; i
< on_page
; i
++)
1421 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (need
[i
] - page_addr
) | 0x3000);
1425 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1434 inform (_("Adding exports to output file"));
1436 fprintf (output_def
, ";");
1437 for (i
= 0; oav
[i
]; i
++)
1438 fprintf (output_def
, " %s", oav
[i
]);
1440 fprintf (output_def
, "\nEXPORTS\n");
1442 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1444 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1445 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1447 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1450 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1455 exp
->noname
? " NONAME" : "",
1456 exp
->data
? " DATA" : "",
1461 char *quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1463 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1471 exp
->noname
? " NONAME" : "",
1472 exp
->data
? " DATA" : "",
1479 inform (_("Added exports to output file"));
1482 /* generate_idata_ofile generates the portable assembly source code
1483 for the idata sections. It appends the source code to the end of
1487 generate_idata_ofile (filvar
)
1496 if (import_list
== NULL
)
1499 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1500 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1501 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1502 fprintf (filvar
, "doi_idata:\n");
1505 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1507 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1508 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1509 ASM_C
, headptr
->dllname
);
1510 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1511 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1512 fprintf (filvar
, "\t%sdllname%d%s\n",
1513 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1514 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1515 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1519 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1520 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1521 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1522 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1523 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1525 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1527 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1529 fprintf (filvar
, "listone%d:\n", headindex
);
1530 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1531 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1532 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1533 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1537 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1539 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1541 fprintf (filvar
, "listtwo%d:\n", headindex
);
1542 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1543 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1544 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1545 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1549 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1551 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1554 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1555 funcptr
= funcptr
->next
)
1557 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1558 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1559 ((funcptr
->ord
) & 0xFFFF));
1560 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1561 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1567 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1569 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1571 fprintf (filvar
,"dllname%d:\n", headindex
);
1572 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1573 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1586 /* xgettext:c-format */
1587 inform (_("Generating export file: %s\n"), exp_name
);
1589 f
= fopen (TMP_ASM
, FOPEN_WT
);
1591 /* xgettext:c-format */
1592 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1594 /* xgettext:c-format */
1595 inform (_("Opened temporary file: %s"), TMP_ASM
);
1601 fprintf (f
, "\t.section .edata\n\n");
1602 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1603 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1605 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1606 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1607 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1610 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1611 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1613 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1614 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1615 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1616 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1618 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1619 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1621 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1623 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1626 fprintf(f
,"%s Export address Table\n", ASM_C
);
1627 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1628 fprintf (f
, "afuncs:\n");
1631 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1633 if (exp
->ordinal
!= i
)
1636 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1638 (exp
->ordinal
- i
) * 4,
1640 i
, exp
->ordinal
- 1);
1643 while (i
< exp
->ordinal
)
1645 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1649 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1651 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1655 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1656 fprintf (f
, "anames:\n");
1658 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1660 if (!exp
->noname
|| show_allnames
)
1661 fprintf (f
, "\t%sn%d%s\n",
1662 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1665 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1666 fprintf (f
, "anords:\n");
1667 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1669 if (!exp
->noname
|| show_allnames
)
1670 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1673 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1674 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1675 if (!exp
->noname
|| show_allnames
)
1676 fprintf (f
, "n%d: %s \"%s\"\n",
1677 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1681 fprintf (f
, "\t.section .drectve\n");
1682 for (dl
= a_list
; dl
; dl
= dl
->next
)
1684 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1689 fprintf (f
, "\t.section .rdata\n");
1690 for (dl
= d_list
; dl
; dl
= dl
->next
)
1694 /* We dont output as ascii 'cause there can
1695 be quote characters in the string */
1698 for (p
= dl
->text
; *p
; p
++)
1701 fprintf (f
, "\t%s\t", ASM_BYTE
);
1704 fprintf (f
, "%d", *p
);
1707 fprintf (f
, ",0\n");
1721 /* Add to the output file a way of getting to the exported names
1722 without using the import library. */
1725 fprintf (f
, "\t.section\t.rdata\n");
1726 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1727 if (!exp
->noname
|| show_allnames
)
1729 /* We use a single underscore for MS compatibility, and a
1730 double underscore for backward compatibility with old
1732 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1733 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1734 fprintf (f
, "__imp_%s:\n", exp
->name
);
1735 fprintf (f
, "_imp__%s:\n", exp
->name
);
1736 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1740 /* Dump the reloc section if a base file is provided */
1744 long need
[PAGE_SIZE
];
1751 fprintf (f
, "\t.section\t.init\n");
1752 fprintf (f
, "lab:\n");
1754 fseek (base_file
, 0, SEEK_END
);
1755 numbytes
= ftell (base_file
);
1756 fseek (base_file
, 0, SEEK_SET
);
1757 copy
= xmalloc (numbytes
);
1758 fread (copy
, 1, numbytes
, base_file
);
1759 num_entries
= numbytes
/ sizeof (long);
1762 fprintf (f
, "\t.section\t.reloc\n");
1770 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1771 /* Delete duplcates */
1772 for (src
= 0; src
< num_entries
; src
++)
1774 if (last
!= copy
[src
])
1775 last
= copy
[dst
++] = copy
[src
];
1779 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1781 for (j
= 0; j
< num_entries
; j
++)
1785 if ((addr
& PAGE_MASK
) != page_addr
)
1787 totsize
+= 8 + (on_page
& 1)*2;
1788 flush_page (f
, need
, page_addr
, on_page
);
1790 page_addr
= addr
& PAGE_MASK
;
1792 need
[on_page
++] = addr
;
1795 /* Pad the section to an even 32-byte boundary. This will make
1796 the BeOS loader much happier, and shouldn't matter for other
1798 while ((totsize
+ 8 + (on_page
& 1)*2) % 32 != 0)
1800 /* 0x0000 is an absolute relocation that should be ignored. */
1801 need
[on_page
++] = 0x0000;
1805 flush_page (f
, need
, page_addr
, on_page
);
1807 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1811 generate_idata_ofile (f
);
1815 /* assemble the file */
1816 sprintf (outfile
, "%s -o %s %s", as_flags
, exp_name
, TMP_ASM
);
1820 strcat (outfile
, " -mthumb-interwork");
1823 run (as_name
, outfile
);
1825 if (dontdeltemps
== 0)
1828 inform (_("Generated exports file"));
1837 char *copy
= xmalloc (strlen (name
) + 2);
1839 strcpy (copy
+ 1, name
);
1846 p
= strchr (name
, '@');
1853 /**********************************************************************/
1862 if (exp
->noname
&& !show_allnames
)
1864 fprintf (f
, "\t%s\t0x%08x\n",
1866 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
1870 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
1888 unsigned char *data
;
1903 static sinfo secdata
[NSECS
] =
1905 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2},
1906 { DATA
, ".data", SEC_DATA
, 2},
1907 { BSS
, ".bss", 0, 2},
1908 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1909 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1910 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1911 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1}
1916 /* Sections numbered to make the order the same as other PowerPC NT */
1917 /* compilers. This also keeps funny alignment thingies from happening. */
1930 static sinfo secdata
[NSECS
] =
1932 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
1933 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
1934 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
1935 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1936 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1937 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
1938 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1939 { DATA
, ".data", SEC_DATA
, 2},
1940 { BSS
, ".bss", 0, 2}
1946 This is what we're trying to make. We generate the imp symbols with
1947 both single and double underscores, for compatibility.
1950 .global _GetFileVersionInfoSizeW@8
1951 .global __imp_GetFileVersionInfoSizeW@8
1952 _GetFileVersionInfoSizeW@8:
1953 jmp * __imp_GetFileVersionInfoSizeW@8
1954 .section .idata$7 # To force loading of head
1955 .long __version_a_head
1956 # Import Address Table
1958 __imp_GetFileVersionInfoSizeW@8:
1961 # Import Lookup Table
1967 .asciz "GetFileVersionInfoSizeW"
1970 For the PowerPC, here's the variation on the above scheme:
1972 # Rather than a simple "jmp *", the code to get to the dll function
1975 lwz r11,[tocv]__imp_function_name(r2)
1976 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1985 make_label (prefix
, name
)
1989 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
1990 char *copy
= xmalloc (len
+1 );
1991 strcpy (copy
, ASM_PREFIX
);
1992 strcat (copy
, prefix
);
1993 strcat (copy
, name
);
1998 make_one_lib_file (exp
, i
)
2006 sprintf (outfile
, "%ss%05d.s", prefix
, i
);
2007 f
= fopen (outfile
, FOPEN_WT
);
2008 fprintf (f
, "\t.text\n");
2009 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
2010 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2011 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
2012 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
2013 exp
->name
, ASM_JUMP
, exp
->name
);
2015 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
2016 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
2019 fprintf (f
,"%s Import Address Table\n", ASM_C
);
2021 fprintf (f
, "\t.section .idata$5\n");
2022 fprintf (f
, "__imp_%s:\n", exp
->name
);
2023 fprintf (f
, "_imp__%s:\n", exp
->name
);
2027 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
2028 fprintf (f
, "\t.section .idata$4\n");
2032 if(!exp
->noname
|| show_allnames
)
2034 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
2035 fprintf (f
, "\t.section .idata$6\n");
2036 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
2037 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
2042 sprintf (outfile
, "%s -o %ss%05d.o %ss%d.s",
2043 as_flags
, prefix
, i
, prefix
, i
);
2047 strcat (outfile
, " -mthumb-interwork");
2050 run (as_name
, outfile
);
2055 asymbol
* exp_label
;
2058 asymbol
* iname_lab
;
2059 asymbol
** iname_lab_pp
;
2060 asymbol
** iname_pp
;
2069 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2071 char * outname
= xmalloc (10);
2075 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2077 abfd
= bfd_openw (outname
, HOW_BFD_TARGET
);
2080 /* xgettext:c-format */
2081 fatal (_("bfd_open failed open stub file: %s"), outname
);
2083 /* xgettext:c-format */
2084 inform (_("Creating stub file: %s"), outname
);
2086 bfd_set_format (abfd
, bfd_object
);
2087 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2091 bfd_set_private_flags (abfd
, F_INTERWORK
);
2094 /* First make symbols for the sections */
2095 for (i
= 0; i
< NSECS
; i
++)
2097 sinfo
*si
= secdata
+ i
;
2100 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2101 bfd_set_section_flags (abfd
,
2105 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2106 si
->sec
->output_section
= si
->sec
;
2107 si
->sym
= bfd_make_empty_symbol(abfd
);
2108 si
->sym
->name
= si
->sec
->name
;
2109 si
->sym
->section
= si
->sec
;
2110 si
->sym
->flags
= BSF_LOCAL
;
2112 ptrs
[oidx
] = si
->sym
;
2113 si
->sympp
= ptrs
+ oidx
;
2122 exp_label
= bfd_make_empty_symbol (abfd
);
2123 exp_label
->name
= make_label ("", exp
->name
);
2125 /* On PowerPC, the function name points to a descriptor in
2126 the rdata section, the first element of which is a
2127 pointer to the code (..function_name), and the second
2128 points to the .toc */
2130 if (machine
== MPPC
)
2131 exp_label
->section
= secdata
[RDATA
].sec
;
2134 exp_label
->section
= secdata
[TEXT
].sec
;
2136 exp_label
->flags
= BSF_GLOBAL
;
2137 exp_label
->value
= 0;
2140 if (machine
== MTHUMB
)
2141 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2143 ptrs
[oidx
++] = exp_label
;
2146 /* Generate imp symbols with one underscore for Microsoft
2147 compatibility, and with two underscores for backward
2148 compatibility with old versions of cygwin. */
2149 iname
= bfd_make_empty_symbol(abfd
);
2150 iname
->name
= make_label ("__imp_", exp
->name
);
2151 iname
->section
= secdata
[IDATA5
].sec
;
2152 iname
->flags
= BSF_GLOBAL
;
2155 iname2
= bfd_make_empty_symbol(abfd
);
2156 iname2
->name
= make_label ("_imp__", exp
->name
);
2157 iname2
->section
= secdata
[IDATA5
].sec
;
2158 iname2
->flags
= BSF_GLOBAL
;
2161 iname_lab
= bfd_make_empty_symbol(abfd
);
2163 iname_lab
->name
= head_label
;
2164 iname_lab
->section
= (asection
*)&bfd_und_section
;
2165 iname_lab
->flags
= 0;
2166 iname_lab
->value
= 0;
2169 iname_pp
= ptrs
+ oidx
;
2170 ptrs
[oidx
++] = iname
;
2171 ptrs
[oidx
++] = iname2
;
2173 iname_lab_pp
= ptrs
+ oidx
;
2174 ptrs
[oidx
++] = iname_lab
;
2177 /* The symbol refering to the code (.text) */
2179 asymbol
*function_name
;
2181 function_name
= bfd_make_empty_symbol(abfd
);
2182 function_name
->name
= make_label ("..", exp
->name
);
2183 function_name
->section
= secdata
[TEXT
].sec
;
2184 function_name
->flags
= BSF_GLOBAL
;
2185 function_name
->value
= 0;
2187 fn_pp
= ptrs
+ oidx
;
2188 ptrs
[oidx
++] = function_name
;
2191 /* The .toc symbol */
2193 asymbol
*toc_symbol
; /* The .toc symbol */
2195 toc_symbol
= bfd_make_empty_symbol (abfd
);
2196 toc_symbol
->name
= make_label (".", "toc");
2197 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2198 toc_symbol
->flags
= BSF_GLOBAL
;
2199 toc_symbol
->value
= 0;
2201 toc_pp
= ptrs
+ oidx
;
2202 ptrs
[oidx
++] = toc_symbol
;
2208 for (i
= 0; i
< NSECS
; i
++)
2210 sinfo
*si
= secdata
+ i
;
2211 asection
*sec
= si
->sec
;
2220 si
->size
= HOW_JTAB_SIZE
;
2221 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2222 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2224 /* add the reloc into idata$5 */
2225 rel
= xmalloc (sizeof (arelent
));
2227 rpp
= xmalloc (sizeof (arelent
*) * 2);
2231 rel
->address
= HOW_JTAB_ROFF
;
2234 if (machine
== MPPC
)
2236 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2237 BFD_RELOC_16_GOTOFF
);
2238 rel
->sym_ptr_ptr
= iname_pp
;
2242 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2243 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2245 sec
->orelocation
= rpp
;
2246 sec
->reloc_count
= 1;
2251 /* An idata$4 or idata$5 is one word long, and has an
2254 si
->data
= xmalloc (4);
2259 si
->data
[0] = exp
->ordinal
;
2260 si
->data
[1] = exp
->ordinal
>> 8;
2261 si
->data
[2] = exp
->ordinal
>> 16;
2266 sec
->reloc_count
= 1;
2267 memset (si
->data
, 0, si
->size
);
2268 rel
= xmalloc (sizeof (arelent
));
2269 rpp
= xmalloc (sizeof (arelent
*) * 2);
2274 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2275 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2276 sec
->orelocation
= rpp
;
2284 /* This used to add 1 to exp->hint. I don't know
2285 why it did that, and it does not match what I see
2286 in programs compiled with the MS tools. */
2287 int idx
= exp
->hint
;
2288 si
->size
= strlen (xlate (exp
->name
)) + 3;
2289 si
->data
= xmalloc (si
->size
);
2290 si
->data
[0] = idx
& 0xff;
2291 si
->data
[1] = idx
>> 8;
2292 strcpy (si
->data
+ 2, xlate (exp
->name
));
2297 si
->data
=xmalloc(4);
2298 memset (si
->data
, 0, si
->size
);
2299 rel
= xmalloc (sizeof (arelent
));
2300 rpp
= xmalloc (sizeof (arelent
*) * 2);
2304 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2305 rel
->sym_ptr_ptr
= iname_lab_pp
;
2306 sec
->orelocation
= rpp
;
2307 sec
->reloc_count
= 1;
2313 /* The .pdata section is 5 words long. */
2314 /* Think of it as: */
2317 /* bfd_vma BeginAddress, [0x00] */
2318 /* EndAddress, [0x04] */
2319 /* ExceptionHandler, [0x08] */
2320 /* HandlerData, [0x0c] */
2321 /* PrologEndAddress; [0x10] */
2324 /* So this pdata section setups up this as a glue linkage to
2325 a dll routine. There are a number of house keeping things
2328 1. In the name of glue trickery, the ADDR32 relocs for 0,
2329 4, and 0x10 are set to point to the same place:
2331 2. There is one more reloc needed in the pdata section.
2332 The actual glue instruction to restore the toc on
2333 return is saved as the offset in an IMGLUE reloc.
2334 So we need a total of four relocs for this section.
2336 3. Lastly, the HandlerData field is set to 0x03, to indicate
2337 that this is a glue routine.
2339 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2341 /* alignment must be set to 2**2 or you get extra stuff */
2342 bfd_set_section_alignment(abfd
, sec
, 2);
2345 si
->data
=xmalloc(4 * 5);
2346 memset (si
->data
, 0, si
->size
);
2347 rpp
= xmalloc (sizeof (arelent
*) * 5);
2348 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2349 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2350 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2351 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2354 /* stick the toc reload instruction in the glue reloc */
2355 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2358 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2359 BFD_RELOC_32_GOTOFF
);
2360 imglue
->sym_ptr_ptr
= fn_pp
;
2362 ba_rel
->address
= 0;
2364 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2365 ba_rel
->sym_ptr_ptr
= fn_pp
;
2367 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2368 ea_rel
->address
= 4;
2370 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2371 ea_rel
->sym_ptr_ptr
= fn_pp
;
2373 /* mark it as glue */
2374 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2376 /* mark the prolog end address */
2377 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2378 pea_rel
->address
= 0x10;
2379 pea_rel
->addend
= 0;
2380 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2381 pea_rel
->sym_ptr_ptr
= fn_pp
;
2383 sec
->orelocation
= rpp
;
2384 sec
->reloc_count
= 4;
2388 /* Each external function in a PowerPC PE file has a two word
2389 descriptor consisting of:
2390 1. The address of the code.
2391 2. The address of the appropriate .toc
2392 We use relocs to build this.
2396 si
->data
= xmalloc (8);
2397 memset (si
->data
, 0, si
->size
);
2399 rpp
= xmalloc (sizeof (arelent
*) * 3);
2400 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2401 rpp
[1] = xmalloc (sizeof (arelent
));
2406 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2407 rel
->sym_ptr_ptr
= fn_pp
;
2413 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2414 rel
->sym_ptr_ptr
= toc_pp
;
2416 sec
->orelocation
= rpp
;
2417 sec
->reloc_count
= 2;
2419 #endif /* DLLTOOL_PPC */
2425 /* Size up all the sections */
2426 for (i
= 0; i
< NSECS
; i
++)
2428 sinfo
*si
= secdata
+ i
;
2430 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2431 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2433 /* vma += si->size;*/
2436 /* Write them out */
2437 for (i
= 0; i
< NSECS
; i
++)
2439 sinfo
*si
= secdata
+ i
;
2441 if (i
== IDATA5
&& no_idata5
)
2444 if (i
== IDATA4
&& no_idata4
)
2447 bfd_set_section_contents (abfd
, si
->sec
,
2452 bfd_set_symtab (abfd
, ptrs
, oidx
);
2454 abfd
= bfd_openr (outname
, HOW_BFD_TARGET
);
2463 FILE * f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2465 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2466 fprintf (f
, "\t.section .idata$2\n");
2468 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2470 fprintf (f
, "%s:\n", head_label
);
2472 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2473 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2475 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2476 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2477 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2478 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2479 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2484 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2486 ASM_RVA_AFTER
, ASM_C
);
2488 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2492 fprintf (f
, "\t.section\t.idata$5\n");
2493 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2494 fprintf (f
, "fthunk:\n");
2498 fprintf (f
, "\t.section\t.idata$4\n");
2500 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2501 fprintf (f
, "\t.section .idata$4\n");
2502 fprintf (f
, "hname:\n");
2506 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_HEAD_O
, TMP_HEAD_S
);
2510 strcat (outfile
, " -mthumb-interwork");
2513 run (as_name
, outfile
);
2515 return bfd_openr (TMP_HEAD_O
, HOW_BFD_TARGET
);
2521 FILE * f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2525 fprintf (f
, "\t.section .idata$4\n");
2526 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2530 fprintf (f
, "\t.section .idata$5\n");
2531 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2535 /* Normally, we need to see a null descriptor built in idata$3 to
2536 act as the terminator for the list. The ideal way, I suppose,
2537 would be to mark this section as a comdat type 2 section, so
2538 only one would appear in the final .exe (if our linker supported
2539 comdat, that is) or cause it to be inserted by something else (say
2543 fprintf (f
, "\t.section .idata$3\n");
2544 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2545 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2546 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2547 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2548 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2552 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2553 do too. Original, huh? */
2554 fprintf (f
, "\t.section .idata$6\n");
2556 fprintf (f
, "\t.section .idata$7\n");
2559 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2560 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2561 imp_name_lab
, ASM_TEXT
, dll_name
);
2565 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_TAIL_O
, TMP_TAIL_S
);
2569 strcat (outfile
, " -mthumb-interwork");
2572 run (as_name
, outfile
);
2574 return bfd_openr (TMP_TAIL_O
, HOW_BFD_TARGET
);
2589 outarch
= bfd_openw (imp_name
, HOW_BFD_TARGET
);
2592 /* xgettext:c-format */
2593 fatal (_("Can't open .lib file: %s"), imp_name
);
2595 /* xgettext:c-format */
2596 inform (_("Creating library file: %s\n"), imp_name
);
2598 bfd_set_format (outarch
, bfd_archive
);
2599 outarch
->has_armap
= 1;
2601 /* Work out a reasonable size of things to put onto one line. */
2603 ar_head
= make_head ();
2604 ar_tail
= make_tail();
2606 if (ar_head
== NULL
|| ar_tail
== NULL
)
2609 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2611 bfd
*n
= make_one_lib_file (exp
, i
);
2616 /* Now stick them all into the archive */
2618 ar_head
->next
= head
;
2619 ar_tail
->next
= ar_head
;
2622 if (! bfd_set_archive_head (outarch
, head
))
2623 bfd_fatal ("bfd_set_archive_head");
2625 if (! bfd_close (outarch
))
2626 bfd_fatal (imp_name
);
2628 while (head
!= NULL
)
2630 bfd
*n
= head
->next
;
2635 /* Delete all the temp files */
2637 if (dontdeltemps
== 0)
2639 unlink (TMP_HEAD_O
);
2640 unlink (TMP_HEAD_S
);
2641 unlink (TMP_TAIL_O
);
2642 unlink (TMP_TAIL_S
);
2645 if (dontdeltemps
< 2)
2647 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2649 sprintf (outfile
, "%s%05d.o", TMP_STUB
, i
);
2650 if (unlink (outfile
) < 0)
2651 /* xgettext:c-format */
2652 warn (_("cannot delete %s: %s\n"), outfile
, strerror (errno
));
2656 inform (_("Created lib file"));
2659 /**********************************************************************/
2661 /* Run through the information gathered from the .o files and the
2662 .def file and work out the best stuff */
2668 export_type
*ap
= *(export_type
**) a
;
2669 export_type
*bp
= *(export_type
**) b
;
2670 if (ap
->ordinal
== bp
->ordinal
)
2673 /* unset ordinals go to the bottom */
2674 if (ap
->ordinal
== -1)
2676 if (bp
->ordinal
== -1)
2678 return (ap
->ordinal
- bp
->ordinal
);
2686 export_type
*ap
= *(export_type
**) a
;
2687 export_type
*bp
= *(export_type
**) b
;
2689 return (strcmp (ap
->name
, bp
->name
));
2693 remove_null_names (ptr
)
2698 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2702 ptr
[dst
] = ptr
[src
];
2715 for (i
= 0; i
< d_nfuncs
; i
++)
2719 printf ("%d %s @ %d %s%s%s\n",
2720 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2721 ptr
[i
]->noname
? "NONAME " : "",
2722 ptr
[i
]->constant
? "CONSTANT" : "",
2723 ptr
[i
]->data
? "DATA" : "");
2732 process_duplicates (d_export_vec
)
2733 export_type
**d_export_vec
;
2741 /* Remove duplicates */
2742 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2744 dtab (d_export_vec
);
2745 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2747 if (strcmp (d_export_vec
[i
]->name
,
2748 d_export_vec
[i
+ 1]->name
) == 0)
2751 export_type
*a
= d_export_vec
[i
];
2752 export_type
*b
= d_export_vec
[i
+ 1];
2756 /* xgettext:c-format */
2757 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2758 a
->name
, a
->ordinal
, b
->ordinal
);
2760 if (a
->ordinal
!= -1
2761 && b
->ordinal
!= -1)
2762 /* xgettext:c-format */
2763 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2766 /* Merge attributes */
2767 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2768 b
->constant
|= a
->constant
;
2769 b
->noname
|= a
->noname
;
2771 d_export_vec
[i
] = 0;
2774 dtab (d_export_vec
);
2775 remove_null_names (d_export_vec
);
2776 dtab (d_export_vec
);
2781 /* Count the names */
2782 for (i
= 0; i
< d_nfuncs
; i
++)
2784 if (!d_export_vec
[i
]->noname
)
2790 fill_ordinals (d_export_vec
)
2791 export_type
**d_export_vec
;
2798 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2800 /* fill in the unset ordinals with ones from our range */
2802 ptr
= (char *) xmalloc (size
);
2804 memset (ptr
, 0, size
);
2806 /* Mark in our large vector all the numbers that are taken */
2807 for (i
= 0; i
< d_nfuncs
; i
++)
2809 if (d_export_vec
[i
]->ordinal
!= -1)
2811 ptr
[d_export_vec
[i
]->ordinal
] = 1;
2812 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
2814 lowest
= d_export_vec
[i
]->ordinal
;
2819 /* Start at 1 for compatibility with MS toolchain. */
2823 /* Now fill in ordinals where the user wants us to choose. */
2824 for (i
= 0; i
< d_nfuncs
; i
++)
2826 if (d_export_vec
[i
]->ordinal
== -1)
2830 /* First try within or after any user supplied range. */
2831 for (j
= lowest
; j
< size
; j
++)
2835 d_export_vec
[i
]->ordinal
= j
;
2839 /* Then try before the range. */
2840 for (j
= lowest
; j
>0; j
--)
2844 d_export_vec
[i
]->ordinal
= j
;
2855 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2857 /* Work out the lowest and highest ordinal numbers. */
2860 if (d_export_vec
[0])
2861 d_low_ord
= d_export_vec
[0]->ordinal
;
2862 if (d_export_vec
[d_nfuncs
-1])
2863 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
2872 const export_type
**a
= (const export_type
**) av
;
2873 const export_type
**b
= (const export_type
**) bv
;
2875 return strcmp ((*a
)->name
, (*b
)->name
);
2881 /* First work out the minimum ordinal chosen */
2887 export_type
**d_export_vec
2888 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
2890 inform (_("Processing definitions"));
2892 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2894 d_export_vec
[i
] = exp
;
2897 process_duplicates (d_export_vec
);
2898 fill_ordinals (d_export_vec
);
2900 /* Put back the list in the new order */
2902 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
2904 d_export_vec
[i
]->next
= d_exports
;
2905 d_exports
= d_export_vec
[i
];
2908 /* Build list in alpha order */
2909 d_exports_lexically
= (export_type
**)
2910 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
2912 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2914 d_exports_lexically
[i
] = exp
;
2916 d_exports_lexically
[i
] = 0;
2918 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
2920 /* Fill exp entries with their hint values */
2922 for (i
= 0; i
< d_nfuncs
; i
++)
2924 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
2925 d_exports_lexically
[i
]->hint
= hint
++;
2928 inform (_("Processed definitions"));
2931 /**********************************************************************/
2934 usage (file
, status
)
2938 /* xgetext:c-format */
2939 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
2940 /* xgetext:c-format */
2941 fprintf (file
, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname
);
2942 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
2943 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
2944 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
2945 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2946 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2947 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2948 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
2949 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
2950 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
2951 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
2952 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2953 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2954 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2955 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2956 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
2957 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
2958 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
2959 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
2961 fprintf (file
, _(" -i --interwork Support ARM/Thumb interworking.\n"));
2963 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2964 fprintf (file
, _(" -v --verbose Be verbose.\n"));
2965 fprintf (file
, _(" -V --version Display the program version.\n"));
2966 fprintf (file
, _(" -h --help Display this information.\n"));
2971 #define OPTION_EXPORT_ALL_SYMS 150
2972 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
2973 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
2974 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
2975 #define OPTION_NO_IDATA4 'x'
2976 #define OPTION_NO_IDATA5 'c'
2978 static const struct option long_options
[] =
2980 {"no-delete", no_argument
, NULL
, 'n'},
2981 {"dllname", required_argument
, NULL
, 'D'},
2982 {"no-idata4", no_argument
, NULL
, OPTION_NO_IDATA4
},
2983 {"no-idata5", no_argument
, NULL
, OPTION_NO_IDATA5
},
2984 {"output-exp", required_argument
, NULL
, 'e'},
2985 {"output-def", required_argument
, NULL
, 'z'},
2986 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
2987 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
2988 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
2989 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
2990 {"output-lib", required_argument
, NULL
, 'l'},
2991 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
2992 {"input-def", required_argument
, NULL
, 'd'},
2993 {"add-underscore", no_argument
, NULL
, 'U'},
2994 {"kill-at", no_argument
, NULL
, 'k'},
2995 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
2996 {"verbose", no_argument
, NULL
, 'v'},
2997 {"version", no_argument
, NULL
, 'V'},
2998 {"help", no_argument
, NULL
, 'h'},
2999 {"machine", required_argument
, NULL
, 'm'},
3000 {"add-indirect", no_argument
, NULL
, 'a'},
3001 {"base-file", required_argument
, NULL
, 'b'},
3002 {"as", required_argument
, NULL
, 'S'},
3003 {"as-flags", required_argument
, NULL
, 'f'},
3005 {"interwork", no_argument
, NULL
, 'i'},
3018 program_name
= av
[0];
3021 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3022 setlocale (LC_MESSAGES
, "");
3024 bindtextdomain (PACKAGE
, LOCALEDIR
);
3025 textdomain (PACKAGE
);
3027 while ((c
= getopt_long (ac
, av
, "xcz:S:aD:l:e:nkAvVb:Uh?m:d:f:i",
3033 case OPTION_NO_IDATA4
:
3036 case OPTION_NO_IDATA5
:
3039 case OPTION_EXPORT_ALL_SYMS
:
3040 export_all_symbols
= true;
3042 case OPTION_NO_EXPORT_ALL_SYMS
:
3043 export_all_symbols
= false;
3045 case OPTION_EXCLUDE_SYMS
:
3046 add_excludes (optarg
);
3048 case OPTION_NO_DEFAULT_EXCLUDES
:
3049 do_default_excludes
= false;
3058 /* ignored for compatibility */
3065 output_def
= fopen (optarg
, FOPEN_WT
);
3086 print_version (program_name
);
3095 /* We don't currently define YYDEBUG when building
3107 add_stdcall_alias
= 1;
3116 base_file
= fopen (optarg
, FOPEN_RB
);
3119 /* xgettext:c-format */
3120 fatal (_("Unable to open base-file: %s"), optarg
);
3129 for (i
= 0; mtable
[i
].type
; i
++)
3131 if (strcmp (mtable
[i
].type
, mname
) == 0)
3135 if (!mtable
[i
].type
)
3136 /* xgettext:c-format */
3137 fatal (_("Machine '%s' not supported"), mname
);
3142 /* Always enable interworking for Thumb targets. */
3143 if (machine
== MTHUMB
&& (! interwork
))
3147 if (!dll_name
&& exp_name
)
3149 int len
= strlen (exp_name
) + 5;
3150 dll_name
= xmalloc (len
);
3151 strcpy (dll_name
, exp_name
);
3152 strcat (dll_name
, ".dll");
3155 /* Don't use the default exclude list if we're reading only the
3156 symbols in the .drectve section. The default excludes are meant
3157 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3158 if (! export_all_symbols
)
3159 do_default_excludes
= false;
3161 if (do_default_excludes
)
3162 set_default_excludes ();
3165 process_def_file (def_file
);
3170 firstarg
= av
[optind
];
3171 scan_obj_file (av
[optind
]);
3182 /* Make imp_name safe for use as a label. */
3185 imp_name_lab
= xstrdup (imp_name
);
3186 for (p
= imp_name_lab
; *p
; p
++)
3188 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3191 head_label
= make_label("_head_", imp_name_lab
);