1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995, 96, 97, 1998 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
;
344 static FILE *output_def
;
345 static FILE *base_file
;
348 static const char *mname
= "arm";
352 static const char *mname
= "i386";
356 static const char *mname
= "ppc";
359 #define PATHMAX 250 /* What's the right name for this ? */
361 #define TMP_ASM "dc.s"
362 #define TMP_HEAD_S "dh.s"
363 #define TMP_HEAD_O "dh.o"
364 #define TMP_TAIL_S "dt.s"
365 #define TMP_TAIL_O "dt.o"
366 #define TMP_STUB "ds"
368 /* This bit of assemly does jmp * ....
369 s set how_jtab_roff to mark where the 32bit abs branch should go */
370 static const unsigned char i386_jtab
[] =
372 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
375 static const unsigned char arm_jtab
[] =
377 0x00, 0xc0, 0x9f, 0xe5,
378 0x00, 0xf0, 0x9c, 0xe5,
382 static const unsigned char thumb_jtab
[] =
393 /* This is the glue sequence for PowerPC PE. There is a */
394 /* tocrel16-tocdefn reloc against the first instruction. */
395 /* We also need a IMGLUE reloc against the glue function */
396 /* to restore the toc saved by the third instruction in */
398 static const unsigned char ppc_jtab
[] =
400 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
401 /* Reloc TOCREL16 __imp_xxx */
402 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
403 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
404 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
405 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
406 0x20, 0x04, 0x80, 0x4E /* bctr */
410 /* the glue instruction, picks up the toc from the stw in */
411 /* the above code: "lwz r2,4(r1)" */
412 static bfd_vma ppc_glue_insn
= 0x80410004;
415 /* The outfile array must be big enough to contain a fully
416 qualified path name, plus an arbitary series of command
417 line switches. We hope that PATH_MAX times two will be
419 static char outfile
[PATHMAX
* 2];
424 const char *how_byte
;
425 const char *how_short
;
426 const char *how_long
;
427 const char *how_asciz
;
428 const char *how_comment
;
429 const char *how_jump
;
430 const char *how_global
;
431 const char *how_space
;
432 const char *how_align_short
;
433 const char *how_align_long
;
434 const char *how_bfd_target
;
435 enum bfd_architecture how_bfd_arch
;
436 const unsigned char *how_jtab
;
437 int how_jtab_size
; /* size of the jtab entry */
438 int how_jtab_roff
; /* offset into it for the ind 32 reloc into idata 5 */
441 static const struct mac
446 "arm", ".byte", ".short", ".long", ".asciz", "@",
447 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
448 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
449 arm_jtab
, sizeof (arm_jtab
), 8
454 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386
,
455 i386_jtab
, sizeof (i386_jtab
), 2
460 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc
,
461 ppc_jtab
, sizeof (ppc_jtab
), 0
466 "thumb", ".byte", ".short", ".long", ".asciz", "@",
467 "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",
468 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm
,
469 thumb_jtab
, sizeof (thumb_jtab
), 12
482 typedef struct export
485 const char *internal_name
;
495 /* A list of symbols which we should not export. */
499 struct string_list
*next
;
503 static struct string_list
*excludes
;
505 static const char *rvaafter
PARAMS ((int));
506 static const char *rvabefore
PARAMS ((int));
507 static const char *asm_prefix
PARAMS ((int));
508 static void append_import
PARAMS ((const char *, const char *, int));
509 static void run
PARAMS ((const char *, char *));
510 static void scan_drectve_symbols
PARAMS ((bfd
*));
511 static void scan_filtered_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
512 static void add_excludes
PARAMS ((const char *));
513 static boolean match_exclude
PARAMS ((const char *));
514 static void set_default_excludes
PARAMS ((void));
515 static long filter_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
516 static void scan_all_symbols
PARAMS ((bfd
*));
517 static void scan_open_obj_file
PARAMS ((bfd
*));
518 static void scan_obj_file
PARAMS ((const char *));
519 static void dump_def_info
PARAMS ((FILE *));
520 static int sfunc
PARAMS ((const void *, const void *));
521 static void flush_page
PARAMS ((FILE *, long *, int, int));
522 static void gen_def_file
PARAMS ((void));
523 static void generate_idata_ofile
PARAMS ((FILE *));
524 static void gen_exp_file
PARAMS ((void));
525 static const char *xlate
PARAMS ((const char *));
527 static void dump_iat
PARAMS ((FILE *, export_type
*));
529 static char *make_label
PARAMS ((const char *, const char *));
530 static bfd
*make_one_lib_file
PARAMS ((export_type
*, int));
531 static bfd
*make_head
PARAMS ((void));
532 static bfd
*make_tail
PARAMS ((void));
533 static void gen_lib_file
PARAMS ((void));
534 static int pfunc
PARAMS ((const void *, const void *));
535 static int nfunc
PARAMS ((const void *, const void *));
536 static void remove_null_names
PARAMS ((export_type
**));
537 static void dtab
PARAMS ((export_type
**));
538 static void process_duplicates
PARAMS ((export_type
**));
539 static void fill_ordinals
PARAMS ((export_type
**));
540 static int alphafunc
PARAMS ((const void *, const void *));
541 static void mangle_defs
PARAMS ((void));
542 static void usage
PARAMS ((FILE *, int));
543 static void display
PARAMS ((const char *, va_list));
544 static void inform
PARAMS ((const char *, ...));
545 static void warn
PARAMS ((const char *, ...));
548 display (message
, args
)
549 const char * message
;
552 if (program_name
!= NULL
)
553 fprintf (stderr
, "%s: ", program_name
);
555 vfprintf (stderr
, message
, args
);
557 if (message
[strlen (message
) - 1] != '\n')
558 fputc ('\n', stderr
);
564 inform (const char * message
, ...)
566 inform (message
, va_alist
)
567 const char * message
;
577 va_start (args
, message
);
582 display (message
, args
);
589 warn (const char * message
, ...)
591 warn (message
, va_alist
)
592 const char * message
;
599 va_start (args
, message
);
604 display (message
, args
);
621 /* xgettext:c-format */
622 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
640 /* xgettext:c-format */
641 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
660 /* xgettext:c-format */
661 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
667 #define ASM_BYTE mtable[machine].how_byte
668 #define ASM_SHORT mtable[machine].how_short
669 #define ASM_LONG mtable[machine].how_long
670 #define ASM_TEXT mtable[machine].how_asciz
671 #define ASM_C mtable[machine].how_comment
672 #define ASM_JUMP mtable[machine].how_jump
673 #define ASM_GLOBAL mtable[machine].how_global
674 #define ASM_SPACE mtable[machine].how_space
675 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
676 #define ASM_RVA_BEFORE rvabefore(machine)
677 #define ASM_RVA_AFTER rvaafter(machine)
678 #define ASM_PREFIX asm_prefix(machine)
679 #define ASM_ALIGN_LONG mtable[machine].how_align_long
680 #define HOW_BFD_TARGET 0 /* always default*/
681 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
682 #define HOW_JTAB mtable[machine].how_jtab
683 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
684 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
688 process_def_file (name
)
691 FILE *f
= fopen (name
, FOPEN_RT
);
694 /* xgettext:c-format */
695 fatal (_("Can't open def file: %s"), name
);
699 /* xgettext:c-format */
700 inform (_("Processing def file: %s"), name
);
704 inform (_("Processed def file"));
707 /**********************************************************************/
709 /* Communications with the parser */
711 static const char *d_name
; /* Arg to NAME or LIBRARY */
712 static int d_nfuncs
; /* Number of functions exported */
713 static int d_named_nfuncs
; /* Number of named functions exported */
714 static int d_low_ord
; /* Lowest ordinal index */
715 static int d_high_ord
; /* Highest ordinal index */
716 static export_type
*d_exports
; /*list of exported functions */
717 static export_type
**d_exports_lexically
; /* vector of exported functions in alpha order */
718 static dlist_type
*d_list
; /* Descriptions */
719 static dlist_type
*a_list
; /* Stuff to go in directives */
728 /* xgettext:c-format */
729 warn (_("Syntax error in def file %s:%d\n"), def_file
, linenumber
);
735 def_exports (name
, internal_name
, ordinal
, noname
, constant
, data
)
737 const char *internal_name
;
743 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
746 p
->internal_name
= internal_name
? internal_name
: name
;
747 p
->ordinal
= ordinal
;
748 p
->constant
= constant
;
757 def_name (name
, base
)
761 /* xgettext:c-format */
762 inform (_("NAME: %s base: %x"), name
, base
);
765 warn (_("Can't have LIBRARY and NAME\n"));
772 def_library (name
, base
)
776 /* xgettext:c-format */
777 inform (_("LIBRARY: %s base: %x"), name
, base
);
780 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name
);
787 def_description (desc
)
790 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
791 d
->text
= xstrdup (desc
);
800 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
801 d
->text
= xstrdup (dir
);
807 def_heapsize (reserve
, commit
)
813 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
815 sprintf (b
, "-heap 0x%x ", reserve
);
816 new_directive (xstrdup (b
));
820 def_stacksize (reserve
, commit
)
826 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
828 sprintf (b
, "-stack 0x%x ", reserve
);
829 new_directive (xstrdup (b
));
832 /* append_import simply adds the given import definition to the global
833 import_list. It is used by def_import. */
836 append_import (symbol_name
, dll_name
, func_ordinal
)
837 const char *symbol_name
;
838 const char *dll_name
;
844 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
846 if (strcmp ((*pq
)->dllname
, dll_name
) == 0)
849 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
850 q
->functail
= q
->functail
->next
;
851 q
->functail
->ord
= func_ordinal
;
852 q
->functail
->name
= xstrdup (symbol_name
);
853 q
->functail
->next
= NULL
;
859 q
= xmalloc (sizeof (iheadtype
));
860 q
->dllname
= xstrdup (dll_name
);
862 q
->funchead
= xmalloc (sizeof (ifunctype
));
863 q
->functail
= q
->funchead
;
865 q
->functail
->name
= xstrdup (symbol_name
);
866 q
->functail
->ord
= func_ordinal
;
867 q
->functail
->next
= NULL
;
872 /* def_import is called from within defparse.y when an IMPORT
873 declaration is encountered. Depending on the form of the
874 declaration, the module name may or may not need ".dll" to be
875 appended to it, the name of the function may be stored in internal
876 or entry, and there may or may not be an ordinal value associated
879 /* A note regarding the parse modes:
880 In defparse.y we have to accept import declarations which follow
881 any one of the following forms:
882 <func_name_in_app> = <dll_name>.<func_name_in_dll>
883 <func_name_in_app> = <dll_name>.<number>
884 <dll_name>.<func_name_in_dll>
886 Furthermore, the dll's name may or may not end with ".dll", which
887 complicates the parsing a little. Normally the dll's name is
888 passed to def_import() in the "module" parameter, but when it ends
889 with ".dll" it gets passed in "module" sans ".dll" and that needs
892 def_import gets five parameters:
893 APP_NAME - the name of the function in the application, if
894 present, or NULL if not present.
895 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
896 DLLEXT - the extension of the dll, if present, NULL if not present.
897 ENTRY - the name of the function in the dll, if present, or NULL.
898 ORD_VAL - the numerical tag of the function in the dll, if present,
899 or NULL. Exactly one of <entry> or <ord_val> must be
900 present (i.e., not NULL). */
903 def_import (app_name
, module
, dllext
, entry
, ord_val
)
904 const char *app_name
;
910 const char *application_name
;
914 application_name
= entry
;
917 if (app_name
!= NULL
)
918 application_name
= app_name
;
920 application_name
= "";
925 buf
= (char *) alloca (strlen (module
) + strlen (dllext
) + 2);
926 sprintf (buf
, "%s.%s", module
, dllext
);
930 append_import (application_name
, module
, ord_val
);
934 def_version (major
, minor
)
938 printf ("VERSION %d.%d\n", major
, minor
);
942 def_section (name
, attr
)
959 sprintf (buf
, "-attr %s %s", name
, atts
);
960 new_directive (xstrdup (buf
));
968 def_section ("CODE", attr
);
975 def_section ("DATA", attr
);
978 /**********************************************************************/
986 int pid
, wait_status
;
989 char *errmsg_fmt
, *errmsg_arg
;
990 char *temp_base
= choose_temp_base ();
992 inform ("run: %s %s\n", what
, args
);
996 for (s
= args
; *s
; s
++)
1000 argv
= alloca (sizeof (char *) * (i
+ 3));
1009 while (*s
!= ' ' && *s
!= 0)
1017 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1018 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1022 inform (strerror (errno
));
1024 fatal (errmsg_fmt
, errmsg_arg
);
1027 pid
= pwait (pid
, & wait_status
, 0);
1031 /* xgettext:c-format */
1032 fatal (_("wait: %s"), strerror (errno
));
1034 else if (WIFSIGNALED (wait_status
))
1036 /* xgettext:c-format */
1037 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1039 else if (WIFEXITED (wait_status
))
1041 if (WEXITSTATUS (wait_status
) != 0)
1042 /* xgettext:c-format */
1043 warn (_("%s exited with status %d\n"),
1044 what
, WEXITSTATUS (wait_status
));
1050 /* Look for a list of symbols to export in the .drectve section of
1051 ABFD. Pass each one to def_exports. */
1054 scan_drectve_symbols (abfd
)
1063 /* Look for .drectve's */
1064 s
= bfd_get_section_by_name (abfd
, ".drectve");
1069 size
= bfd_get_section_size_before_reloc (s
);
1070 buf
= xmalloc (size
);
1072 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1074 /* xgettext:c-format */
1075 inform (_("Sucking in info from .drective section in %s\n"),
1076 bfd_get_filename (abfd
));
1078 /* Search for -export: strings */
1084 && strncmp (p
, "-export:", 8) == 0)
1091 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1093 c
= xmalloc (p
- name
+ 1);
1094 memcpy (c
, name
, p
- name
);
1096 /* FIXME: The 5th arg is for the `constant' field.
1097 What should it be? Not that it matters since it's not
1098 currently useful. */
1099 def_exports (c
, 0, -1, 0, 0, 0);
1107 /* Look through the symbols in MINISYMS, and add each one to list of
1108 symbols to export. */
1111 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
)
1118 bfd_byte
*from
, *fromend
;
1120 store
= bfd_make_empty_symbol (abfd
);
1122 bfd_fatal (bfd_get_filename (abfd
));
1124 from
= (bfd_byte
*) minisyms
;
1125 fromend
= from
+ symcount
* size
;
1126 for (; from
< fromend
; from
+= size
)
1129 const char *symbol_name
;
1131 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1133 bfd_fatal (bfd_get_filename (abfd
));
1135 symbol_name
= bfd_asymbol_name (sym
);
1136 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1139 def_exports (xstrdup (symbol_name
), 0, -1, 0, 0, 0);
1143 /* Add a list of symbols to exclude. */
1146 add_excludes (new_excludes
)
1147 const char *new_excludes
;
1150 char *exclude_string
;
1152 local_copy
= xstrdup (new_excludes
);
1154 exclude_string
= strtok (local_copy
, ",:");
1155 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1157 struct string_list
*new_exclude
;
1159 new_exclude
= ((struct string_list
*)
1160 xmalloc (sizeof (struct string_list
)));
1161 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1162 /* FIXME: Is it always right to add a leading underscore? */
1163 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1164 new_exclude
->next
= excludes
;
1165 excludes
= new_exclude
;
1167 /* xgettext:c-format */
1168 inform (_("Excluding symbol: %s\n"), exclude_string
);
1174 /* See if STRING is on the list of symbols to exclude. */
1177 match_exclude (string
)
1180 struct string_list
*excl_item
;
1182 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1183 if (strcmp (string
, excl_item
->string
) == 0)
1188 /* Add the default list of symbols to exclude. */
1191 set_default_excludes (void)
1193 add_excludes (default_excludes
);
1196 /* Choose which symbols to export. */
1199 filter_symbols (abfd
, minisyms
, symcount
, size
)
1205 bfd_byte
*from
, *fromend
, *to
;
1208 store
= bfd_make_empty_symbol (abfd
);
1210 bfd_fatal (bfd_get_filename (abfd
));
1212 from
= (bfd_byte
*) minisyms
;
1213 fromend
= from
+ symcount
* size
;
1214 to
= (bfd_byte
*) minisyms
;
1216 for (; from
< fromend
; from
+= size
)
1221 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const PTR
) from
, store
);
1223 bfd_fatal (bfd_get_filename (abfd
));
1225 /* Check for external and defined only symbols. */
1226 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1227 || (sym
->flags
& BSF_WEAK
) != 0
1228 || bfd_is_com_section (sym
->section
))
1229 && ! bfd_is_und_section (sym
->section
));
1231 keep
= keep
&& ! match_exclude (sym
->name
);
1235 memcpy (to
, from
, size
);
1240 return (to
- (bfd_byte
*) minisyms
) / size
;
1243 /* Export all symbols in ABFD, except for ones we were told not to
1247 scan_all_symbols (abfd
)
1254 /* Ignore bfds with an import descriptor table. We assume that any
1255 such BFD contains symbols which are exported from another DLL,
1256 and we don't want to reexport them from here. */
1257 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1260 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1262 /* xgettext:c-format */
1263 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1267 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1269 bfd_fatal (bfd_get_filename (abfd
));
1273 /* xgettext:c-format */
1274 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1278 /* Discard the symbols we don't want to export. It's OK to do this
1279 in place; we'll free the storage anyway. */
1281 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1282 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1287 /* Look at the object file to decide which symbols to export. */
1290 scan_open_obj_file (abfd
)
1293 if (export_all_symbols
)
1294 scan_all_symbols (abfd
);
1296 scan_drectve_symbols (abfd
);
1298 /* FIXME: we ought to read in and block out the base relocations */
1300 /* xgettext:c-format */
1301 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd
));
1305 scan_obj_file (filename
)
1306 const char *filename
;
1308 bfd
* f
= bfd_openr (filename
, 0);
1311 /* xgettext:c-format */
1312 fatal (_("Unable to open object file: %s"), filename
);
1314 /* xgettext:c-format */
1315 inform (_("Scanning object file %s"), filename
);
1317 if (bfd_check_format (f
, bfd_archive
))
1319 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1322 if (bfd_check_format (arfile
, bfd_object
))
1323 scan_open_obj_file (arfile
);
1325 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1328 else if (bfd_check_format (f
, bfd_object
))
1330 scan_open_obj_file (f
);
1336 /**********************************************************************/
1344 fprintf (f
, "%s ", ASM_C
);
1345 for (i
= 0; oav
[i
]; i
++)
1346 fprintf (f
, "%s ", oav
[i
]);
1348 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1350 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1356 exp
->noname
? "NONAME " : "",
1357 exp
->constant
? "CONSTANT" : "",
1358 exp
->data
? "DATA" : "");
1362 /* Generate the .exp file */
1369 return *(const long *) a
- *(const long *) b
;
1373 flush_page (f
, need
, page_addr
, on_page
)
1381 /* Flush this page */
1382 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1386 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1388 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1390 for (i
= 0; i
< on_page
; i
++)
1392 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (need
[i
] - page_addr
) | 0x3000);
1396 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1405 inform (_("Adding exports to output file"));
1407 fprintf (output_def
, ";");
1408 for (i
= 0; oav
[i
]; i
++)
1409 fprintf (output_def
, " %s", oav
[i
]);
1411 fprintf (output_def
, "\nEXPORTS\n");
1413 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1415 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1416 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1418 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1423 exp
->noname
? " NONAME" : "",
1424 exp
->data
? " DATA" : "",
1430 inform (_("Added exports to output file"));
1433 /* generate_idata_ofile generates the portable assembly source code
1434 for the idata sections. It appends the source code to the end of
1438 generate_idata_ofile (filvar
)
1447 if (import_list
== NULL
)
1450 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1451 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1452 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1453 fprintf (filvar
, "doi_idata:\n");
1456 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1458 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1459 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1460 ASM_C
, headptr
->dllname
);
1461 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1462 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1463 fprintf (filvar
, "\t%sdllname%d%s\n",
1464 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1465 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1466 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1470 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1471 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1472 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1473 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1474 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1476 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1478 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1480 fprintf (filvar
, "listone%d:\n", headindex
);
1481 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1482 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1483 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1484 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1488 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1490 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1492 fprintf (filvar
, "listtwo%d:\n", headindex
);
1493 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1494 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1495 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1496 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1500 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1502 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1505 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1506 funcptr
= funcptr
->next
)
1508 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1509 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1510 ((funcptr
->ord
) & 0xFFFF));
1511 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1512 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1518 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1520 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1522 fprintf (filvar
,"dllname%d:\n", headindex
);
1523 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1524 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1537 /* xgettext:c-format */
1538 inform (_("Generating export file: %s\n"), exp_name
);
1540 f
= fopen (TMP_ASM
, FOPEN_WT
);
1542 /* xgettext:c-format */
1543 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1545 /* xgettext:c-format */
1546 inform (_("Opened temporary file: %s"), TMP_ASM
);
1552 fprintf (f
, "\t.section .edata\n\n");
1553 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1554 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1556 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1557 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1558 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1561 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1562 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1564 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1565 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1566 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1567 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1569 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1570 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1572 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1574 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1577 fprintf(f
,"%s Export address Table\n", ASM_C
);
1578 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1579 fprintf (f
, "afuncs:\n");
1582 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1584 if (exp
->ordinal
!= i
)
1587 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1589 (exp
->ordinal
- i
) * 4,
1591 i
, exp
->ordinal
- 1);
1594 while (i
< exp
->ordinal
)
1596 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1600 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1602 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1606 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1607 fprintf (f
, "anames:\n");
1609 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1611 if (!exp
->noname
|| show_allnames
)
1612 fprintf (f
, "\t%sn%d%s\n",
1613 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1616 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1617 fprintf (f
, "anords:\n");
1618 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1620 if (!exp
->noname
|| show_allnames
)
1621 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1624 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1625 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1626 if (!exp
->noname
|| show_allnames
)
1627 fprintf (f
, "n%d: %s \"%s\"\n",
1628 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1632 fprintf (f
, "\t.section .drectve\n");
1633 for (dl
= a_list
; dl
; dl
= dl
->next
)
1635 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1640 fprintf (f
, "\t.section .rdata\n");
1641 for (dl
= d_list
; dl
; dl
= dl
->next
)
1645 /* We dont output as ascii 'cause there can
1646 be quote characters in the string */
1649 for (p
= dl
->text
; *p
; p
++)
1652 fprintf (f
, "\t%s\t", ASM_BYTE
);
1655 fprintf (f
, "%d", *p
);
1658 fprintf (f
, ",0\n");
1672 /* Add to the output file a way of getting to the exported names
1673 without using the import library. */
1676 fprintf (f
, "\t.section\t.rdata\n");
1677 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1678 if (!exp
->noname
|| show_allnames
)
1680 /* We use a single underscore for MS compatibility, and a
1681 double underscore for backward compatibility with old
1683 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1684 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1685 fprintf (f
, "__imp_%s:\n", exp
->name
);
1686 fprintf (f
, "_imp__%s:\n", exp
->name
);
1687 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1691 /* Dump the reloc section if a base file is provided */
1695 long need
[PAGE_SIZE
];
1702 fprintf (f
, "\t.section\t.init\n");
1703 fprintf (f
, "lab:\n");
1705 fseek (base_file
, 0, SEEK_END
);
1706 numbytes
= ftell (base_file
);
1707 fseek (base_file
, 0, SEEK_SET
);
1708 copy
= xmalloc (numbytes
);
1709 fread (copy
, 1, numbytes
, base_file
);
1710 num_entries
= numbytes
/ sizeof (long);
1713 fprintf (f
, "\t.section\t.reloc\n");
1719 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1720 /* Delete duplcates */
1721 for (src
= 0; src
< num_entries
; src
++)
1723 if (last
!= copy
[src
])
1724 last
= copy
[dst
++] = copy
[src
];
1728 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1730 for (j
= 0; j
< num_entries
; j
++)
1733 if ((addr
& PAGE_MASK
) != page_addr
)
1735 flush_page (f
, need
, page_addr
, on_page
);
1737 page_addr
= addr
& PAGE_MASK
;
1739 need
[on_page
++] = addr
;
1741 flush_page (f
, need
, page_addr
, on_page
);
1743 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1747 generate_idata_ofile (f
);
1751 /* assemble the file */
1752 sprintf (outfile
, "%s -o %s %s", as_flags
, exp_name
, TMP_ASM
);
1756 strcat (outfile
, " -mthumb-interwork");
1759 run (as_name
, outfile
);
1761 if (dontdeltemps
== 0)
1764 inform (_("Generated exports file"));
1773 char *copy
= xmalloc (strlen (name
) + 2);
1775 strcpy (copy
+ 1, name
);
1782 p
= strchr (name
, '@');
1789 /**********************************************************************/
1798 if (exp
->noname
&& !show_allnames
)
1800 fprintf (f
, "\t%s\t0x%08x\n",
1802 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
1806 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
1824 unsigned char *data
;
1839 static sinfo secdata
[NSECS
] =
1841 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2},
1842 { DATA
, ".data", SEC_DATA
, 2},
1843 { BSS
, ".bss", 0, 2},
1844 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1845 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1846 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1847 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1}
1852 /* Sections numbered to make the order the same as other PowerPC NT */
1853 /* compilers. This also keeps funny alignment thingies from happening. */
1866 static sinfo secdata
[NSECS
] =
1868 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
1869 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
1870 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
1871 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1872 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1873 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
1874 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1875 { DATA
, ".data", SEC_DATA
, 2},
1876 { BSS
, ".bss", 0, 2}
1882 This is what we're trying to make. We generate the imp symbols with
1883 both single and double underscores, for compatibility.
1886 .global _GetFileVersionInfoSizeW@8
1887 .global __imp_GetFileVersionInfoSizeW@8
1888 _GetFileVersionInfoSizeW@8:
1889 jmp * __imp_GetFileVersionInfoSizeW@8
1890 .section .idata$7 # To force loading of head
1891 .long __version_a_head
1892 # Import Address Table
1894 __imp_GetFileVersionInfoSizeW@8:
1897 # Import Lookup Table
1903 .asciz "GetFileVersionInfoSizeW"
1906 For the PowerPC, here's the variation on the above scheme:
1908 # Rather than a simple "jmp *", the code to get to the dll function
1911 lwz r11,[tocv]__imp_function_name(r2)
1912 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1921 make_label (prefix
, name
)
1925 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
1926 char *copy
= xmalloc (len
+1 );
1927 strcpy (copy
, ASM_PREFIX
);
1928 strcat (copy
, prefix
);
1929 strcat (copy
, name
);
1934 make_one_lib_file (exp
, i
)
1942 sprintf (outfile
, "%ss%d.s", prefix
, i
);
1943 f
= fopen (outfile
, FOPEN_WT
);
1944 fprintf (f
, "\t.text\n");
1945 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
1946 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1947 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1948 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
1949 exp
->name
, ASM_JUMP
, exp
->name
);
1951 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
1952 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
1955 fprintf (f
,"%s Import Address Table\n", ASM_C
);
1957 fprintf (f
, "\t.section .idata$5\n");
1958 fprintf (f
, "__imp_%s:\n", exp
->name
);
1959 fprintf (f
, "_imp__%s:\n", exp
->name
);
1963 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
1964 fprintf (f
, "\t.section .idata$4\n");
1968 if(!exp
->noname
|| show_allnames
)
1970 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
1971 fprintf (f
, "\t.section .idata$6\n");
1972 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
1973 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
1978 sprintf (outfile
, "%s -o %ss%d.o %ss%d.s",
1979 as_flags
, prefix
, i
, prefix
, i
);
1983 strcat (outfile
, " -mthumb-interwork");
1986 run (as_name
, outfile
);
1991 asymbol
* exp_label
;
1994 asymbol
* iname_lab
;
1995 asymbol
** iname_lab_pp
;
1996 asymbol
** iname_pp
;
2005 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2007 char * outname
= xmalloc (10);
2011 sprintf (outname
, "%s%d.o", TMP_STUB
, i
);
2013 abfd
= bfd_openw (outname
, HOW_BFD_TARGET
);
2016 /* xgettext:c-format */
2017 fatal (_("bfd_open failed open stub file: %s"), outname
);
2019 /* xgettext:c-format */
2020 inform (_("Creating stub file: %s"), outname
);
2022 bfd_set_format (abfd
, bfd_object
);
2023 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2027 bfd_set_private_flags (abfd
, F_INTERWORK
);
2030 /* First make symbols for the sections */
2031 for (i
= 0; i
< NSECS
; i
++)
2033 sinfo
*si
= secdata
+ i
;
2036 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2037 bfd_set_section_flags (abfd
,
2041 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2042 si
->sec
->output_section
= si
->sec
;
2043 si
->sym
= bfd_make_empty_symbol(abfd
);
2044 si
->sym
->name
= si
->sec
->name
;
2045 si
->sym
->section
= si
->sec
;
2046 si
->sym
->flags
= BSF_LOCAL
;
2048 ptrs
[oidx
] = si
->sym
;
2049 si
->sympp
= ptrs
+ oidx
;
2058 exp_label
= bfd_make_empty_symbol (abfd
);
2059 exp_label
->name
= make_label ("", exp
->name
);
2061 /* On PowerPC, the function name points to a descriptor in
2062 the rdata section, the first element of which is a
2063 pointer to the code (..function_name), and the second
2064 points to the .toc */
2066 if (machine
== MPPC
)
2067 exp_label
->section
= secdata
[RDATA
].sec
;
2070 exp_label
->section
= secdata
[TEXT
].sec
;
2072 exp_label
->flags
= BSF_GLOBAL
;
2073 exp_label
->value
= 0;
2076 if (machine
== MTHUMB
)
2077 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXT
);
2079 ptrs
[oidx
++] = exp_label
;
2082 /* Generate imp symbols with one underscore for Microsoft
2083 compatibility, and with two underscores for backward
2084 compatibility with old versions of cygwin. */
2085 iname
= bfd_make_empty_symbol(abfd
);
2086 iname
->name
= make_label ("__imp_", exp
->name
);
2087 iname
->section
= secdata
[IDATA5
].sec
;
2088 iname
->flags
= BSF_GLOBAL
;
2091 iname2
= bfd_make_empty_symbol(abfd
);
2092 iname2
->name
= make_label ("_imp__", exp
->name
);
2093 iname2
->section
= secdata
[IDATA5
].sec
;
2094 iname2
->flags
= BSF_GLOBAL
;
2097 iname_lab
= bfd_make_empty_symbol(abfd
);
2099 iname_lab
->name
= head_label
;
2100 iname_lab
->section
= (asection
*)&bfd_und_section
;
2101 iname_lab
->flags
= 0;
2102 iname_lab
->value
= 0;
2105 iname_pp
= ptrs
+ oidx
;
2106 ptrs
[oidx
++] = iname
;
2107 ptrs
[oidx
++] = iname2
;
2109 iname_lab_pp
= ptrs
+ oidx
;
2110 ptrs
[oidx
++] = iname_lab
;
2113 /* The symbol refering to the code (.text) */
2115 asymbol
*function_name
;
2117 function_name
= bfd_make_empty_symbol(abfd
);
2118 function_name
->name
= make_label ("..", exp
->name
);
2119 function_name
->section
= secdata
[TEXT
].sec
;
2120 function_name
->flags
= BSF_GLOBAL
;
2121 function_name
->value
= 0;
2123 fn_pp
= ptrs
+ oidx
;
2124 ptrs
[oidx
++] = function_name
;
2127 /* The .toc symbol */
2129 asymbol
*toc_symbol
; /* The .toc symbol */
2131 toc_symbol
= bfd_make_empty_symbol (abfd
);
2132 toc_symbol
->name
= make_label (".", "toc");
2133 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2134 toc_symbol
->flags
= BSF_GLOBAL
;
2135 toc_symbol
->value
= 0;
2137 toc_pp
= ptrs
+ oidx
;
2138 ptrs
[oidx
++] = toc_symbol
;
2144 for (i
= 0; i
< NSECS
; i
++)
2146 sinfo
*si
= secdata
+ i
;
2147 asection
*sec
= si
->sec
;
2156 si
->size
= HOW_JTAB_SIZE
;
2157 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2158 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2160 /* add the reloc into idata$5 */
2161 rel
= xmalloc (sizeof (arelent
));
2163 rpp
= xmalloc (sizeof (arelent
*) * 2);
2167 rel
->address
= HOW_JTAB_ROFF
;
2170 if (machine
== MPPC
)
2172 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2173 BFD_RELOC_16_GOTOFF
);
2174 rel
->sym_ptr_ptr
= iname_pp
;
2178 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2179 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2181 sec
->orelocation
= rpp
;
2182 sec
->reloc_count
= 1;
2187 /* An idata$4 or idata$5 is one word long, and has an
2190 si
->data
= xmalloc (4);
2195 si
->data
[0] = exp
->ordinal
;
2196 si
->data
[1] = exp
->ordinal
>> 8;
2197 si
->data
[2] = exp
->ordinal
>> 16;
2202 sec
->reloc_count
= 1;
2203 memset (si
->data
, 0, si
->size
);
2204 rel
= xmalloc (sizeof (arelent
));
2205 rpp
= xmalloc (sizeof (arelent
*) * 2);
2210 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2211 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2212 sec
->orelocation
= rpp
;
2220 /* This used to add 1 to exp->hint. I don't know
2221 why it did that, and it does not match what I see
2222 in programs compiled with the MS tools. */
2223 int idx
= exp
->hint
;
2224 si
->size
= strlen (xlate (exp
->name
)) + 3;
2225 si
->data
= xmalloc (si
->size
);
2226 si
->data
[0] = idx
& 0xff;
2227 si
->data
[1] = idx
>> 8;
2228 strcpy (si
->data
+ 2, xlate (exp
->name
));
2233 si
->data
=xmalloc(4);
2234 memset (si
->data
, 0, si
->size
);
2235 rel
= xmalloc (sizeof (arelent
));
2236 rpp
= xmalloc (sizeof (arelent
*) * 2);
2240 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2241 rel
->sym_ptr_ptr
= iname_lab_pp
;
2242 sec
->orelocation
= rpp
;
2243 sec
->reloc_count
= 1;
2249 /* The .pdata section is 5 words long. */
2250 /* Think of it as: */
2253 /* bfd_vma BeginAddress, [0x00] */
2254 /* EndAddress, [0x04] */
2255 /* ExceptionHandler, [0x08] */
2256 /* HandlerData, [0x0c] */
2257 /* PrologEndAddress; [0x10] */
2260 /* So this pdata section setups up this as a glue linkage to
2261 a dll routine. There are a number of house keeping things
2264 1. In the name of glue trickery, the ADDR32 relocs for 0,
2265 4, and 0x10 are set to point to the same place:
2267 2. There is one more reloc needed in the pdata section.
2268 The actual glue instruction to restore the toc on
2269 return is saved as the offset in an IMGLUE reloc.
2270 So we need a total of four relocs for this section.
2272 3. Lastly, the HandlerData field is set to 0x03, to indicate
2273 that this is a glue routine.
2275 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2277 /* alignment must be set to 2**2 or you get extra stuff */
2278 bfd_set_section_alignment(abfd
, sec
, 2);
2281 si
->data
=xmalloc(4 * 5);
2282 memset (si
->data
, 0, si
->size
);
2283 rpp
= xmalloc (sizeof (arelent
*) * 5);
2284 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2285 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2286 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2287 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2290 /* stick the toc reload instruction in the glue reloc */
2291 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2294 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2295 BFD_RELOC_32_GOTOFF
);
2296 imglue
->sym_ptr_ptr
= fn_pp
;
2298 ba_rel
->address
= 0;
2300 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2301 ba_rel
->sym_ptr_ptr
= fn_pp
;
2303 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2304 ea_rel
->address
= 4;
2306 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2307 ea_rel
->sym_ptr_ptr
= fn_pp
;
2309 /* mark it as glue */
2310 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2312 /* mark the prolog end address */
2313 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2314 pea_rel
->address
= 0x10;
2315 pea_rel
->addend
= 0;
2316 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2317 pea_rel
->sym_ptr_ptr
= fn_pp
;
2319 sec
->orelocation
= rpp
;
2320 sec
->reloc_count
= 4;
2324 /* Each external function in a PowerPC PE file has a two word
2325 descriptor consisting of:
2326 1. The address of the code.
2327 2. The address of the appropriate .toc
2328 We use relocs to build this.
2332 si
->data
= xmalloc (8);
2333 memset (si
->data
, 0, si
->size
);
2335 rpp
= xmalloc (sizeof (arelent
*) * 3);
2336 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2337 rpp
[1] = xmalloc (sizeof (arelent
));
2342 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2343 rel
->sym_ptr_ptr
= fn_pp
;
2349 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2350 rel
->sym_ptr_ptr
= toc_pp
;
2352 sec
->orelocation
= rpp
;
2353 sec
->reloc_count
= 2;
2355 #endif /* DLLTOOL_PPC */
2361 /* Size up all the sections */
2362 for (i
= 0; i
< NSECS
; i
++)
2364 sinfo
*si
= secdata
+ i
;
2366 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2367 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2369 /* vma += si->size;*/
2372 /* Write them out */
2373 for (i
= 0; i
< NSECS
; i
++)
2375 sinfo
*si
= secdata
+ i
;
2377 if (i
== IDATA5
&& no_idata5
)
2380 if (i
== IDATA4
&& no_idata4
)
2383 bfd_set_section_contents (abfd
, si
->sec
,
2388 bfd_set_symtab (abfd
, ptrs
, oidx
);
2390 abfd
= bfd_openr (outname
, HOW_BFD_TARGET
);
2399 FILE * f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2401 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2402 fprintf (f
, "\t.section .idata$2\n");
2404 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2406 fprintf (f
, "%s:\n", head_label
);
2408 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2409 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2411 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2412 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2413 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2414 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2415 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2420 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2422 ASM_RVA_AFTER
, ASM_C
);
2424 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2428 fprintf (f
, "\t.section\t.idata$5\n");
2429 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2430 fprintf (f
, "fthunk:\n");
2434 fprintf (f
, "\t.section\t.idata$4\n");
2436 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2437 fprintf (f
, "\t.section .idata$4\n");
2438 fprintf (f
, "hname:\n");
2442 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_HEAD_O
, TMP_HEAD_S
);
2446 strcat (outfile
, " -mthumb-interwork");
2449 run (as_name
, outfile
);
2451 return bfd_openr (TMP_HEAD_O
, HOW_BFD_TARGET
);
2457 FILE * f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2461 fprintf (f
, "\t.section .idata$4\n");
2462 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2466 fprintf (f
, "\t.section .idata$5\n");
2467 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2471 /* Normally, we need to see a null descriptor built in idata$3 to
2472 act as the terminator for the list. The ideal way, I suppose,
2473 would be to mark this section as a comdat type 2 section, so
2474 only one would appear in the final .exe (if our linker supported
2475 comdat, that is) or cause it to be inserted by something else (say
2479 fprintf (f
, "\t.section .idata$3\n");
2480 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2481 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2482 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2483 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2484 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2488 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2489 do too. Original, huh? */
2490 fprintf (f
, "\t.section .idata$6\n");
2492 fprintf (f
, "\t.section .idata$7\n");
2495 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2496 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2497 imp_name_lab
, ASM_TEXT
, dll_name
);
2501 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_TAIL_O
, TMP_TAIL_S
);
2505 strcat (outfile
, " -mthumb-interwork");
2508 run (as_name
, outfile
);
2510 return bfd_openr (TMP_TAIL_O
, HOW_BFD_TARGET
);
2525 outarch
= bfd_openw (imp_name
, HOW_BFD_TARGET
);
2528 /* xgettext:c-format */
2529 fatal (_("Can't open .lib file: %s"), imp_name
);
2531 /* xgettext:c-format */
2532 inform (_("Creating library file: %s\n"), imp_name
);
2534 bfd_set_format (outarch
, bfd_archive
);
2535 outarch
->has_armap
= 1;
2537 /* Work out a reasonable size of things to put onto one line. */
2539 ar_head
= make_head ();
2540 ar_tail
= make_tail();
2542 if (ar_head
== NULL
|| ar_tail
== NULL
)
2545 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2547 bfd
*n
= make_one_lib_file (exp
, i
);
2552 /* Now stick them all into the archive */
2554 ar_head
->next
= head
;
2555 ar_tail
->next
= ar_head
;
2558 if (! bfd_set_archive_head (outarch
, head
))
2559 bfd_fatal ("bfd_set_archive_head");
2561 if (! bfd_close (outarch
))
2562 bfd_fatal (imp_name
);
2564 while (head
!= NULL
)
2566 bfd
*n
= head
->next
;
2571 /* Delete all the temp files */
2573 if (dontdeltemps
== 0)
2575 unlink (TMP_HEAD_O
);
2576 unlink (TMP_HEAD_S
);
2577 unlink (TMP_TAIL_O
);
2578 unlink (TMP_TAIL_S
);
2581 if (dontdeltemps
< 2)
2583 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2585 sprintf (outfile
, "%s%d.o", TMP_STUB
, i
);
2586 if (unlink (outfile
) < 0)
2587 /* xgettext:c-format */
2588 warn (_("cannot delete %s: %s\n"), outfile
, strerror (errno
));
2592 inform (_("Created lib file"));
2595 /**********************************************************************/
2597 /* Run through the information gathered from the .o files and the
2598 .def file and work out the best stuff */
2604 export_type
*ap
= *(export_type
**) a
;
2605 export_type
*bp
= *(export_type
**) b
;
2606 if (ap
->ordinal
== bp
->ordinal
)
2609 /* unset ordinals go to the bottom */
2610 if (ap
->ordinal
== -1)
2612 if (bp
->ordinal
== -1)
2614 return (ap
->ordinal
- bp
->ordinal
);
2622 export_type
*ap
= *(export_type
**) a
;
2623 export_type
*bp
= *(export_type
**) b
;
2625 return (strcmp (ap
->name
, bp
->name
));
2629 remove_null_names (ptr
)
2634 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2638 ptr
[dst
] = ptr
[src
];
2651 for (i
= 0; i
< d_nfuncs
; i
++)
2655 printf ("%d %s @ %d %s%s%s\n",
2656 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2657 ptr
[i
]->noname
? "NONAME " : "",
2658 ptr
[i
]->constant
? "CONSTANT" : "",
2659 ptr
[i
]->data
? "DATA" : "");
2668 process_duplicates (d_export_vec
)
2669 export_type
**d_export_vec
;
2677 /* Remove duplicates */
2678 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2680 dtab (d_export_vec
);
2681 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2683 if (strcmp (d_export_vec
[i
]->name
,
2684 d_export_vec
[i
+ 1]->name
) == 0)
2687 export_type
*a
= d_export_vec
[i
];
2688 export_type
*b
= d_export_vec
[i
+ 1];
2692 /* xgettext:c-format */
2693 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2694 a
->name
, a
->ordinal
, b
->ordinal
);
2696 if (a
->ordinal
!= -1
2697 && b
->ordinal
!= -1)
2698 /* xgettext:c-format */
2699 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2702 /* Merge attributes */
2703 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2704 b
->constant
|= a
->constant
;
2705 b
->noname
|= a
->noname
;
2707 d_export_vec
[i
] = 0;
2710 dtab (d_export_vec
);
2711 remove_null_names (d_export_vec
);
2712 dtab (d_export_vec
);
2717 /* Count the names */
2718 for (i
= 0; i
< d_nfuncs
; i
++)
2720 if (!d_export_vec
[i
]->noname
)
2726 fill_ordinals (d_export_vec
)
2727 export_type
**d_export_vec
;
2734 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2736 /* fill in the unset ordinals with ones from our range */
2738 ptr
= (char *) xmalloc (size
);
2740 memset (ptr
, 0, size
);
2742 /* Mark in our large vector all the numbers that are taken */
2743 for (i
= 0; i
< d_nfuncs
; i
++)
2745 if (d_export_vec
[i
]->ordinal
!= -1)
2747 ptr
[d_export_vec
[i
]->ordinal
] = 1;
2748 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
2750 lowest
= d_export_vec
[i
]->ordinal
;
2755 /* Start at 1 for compatibility with MS toolchain. */
2759 /* Now fill in ordinals where the user wants us to choose. */
2760 for (i
= 0; i
< d_nfuncs
; i
++)
2762 if (d_export_vec
[i
]->ordinal
== -1)
2766 /* First try within or after any user supplied range. */
2767 for (j
= lowest
; j
< size
; j
++)
2771 d_export_vec
[i
]->ordinal
= j
;
2775 /* Then try before the range. */
2776 for (j
= lowest
; j
>0; j
--)
2780 d_export_vec
[i
]->ordinal
= j
;
2791 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2793 /* Work out the lowest and highest ordinal numbers. */
2796 if (d_export_vec
[0])
2797 d_low_ord
= d_export_vec
[0]->ordinal
;
2798 if (d_export_vec
[d_nfuncs
-1])
2799 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
2808 const export_type
**a
= (const export_type
**) av
;
2809 const export_type
**b
= (const export_type
**) bv
;
2811 return strcmp ((*a
)->name
, (*b
)->name
);
2817 /* First work out the minimum ordinal chosen */
2823 export_type
**d_export_vec
2824 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
2826 inform (_("Processing definitions"));
2828 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2830 d_export_vec
[i
] = exp
;
2833 process_duplicates (d_export_vec
);
2834 fill_ordinals (d_export_vec
);
2836 /* Put back the list in the new order */
2838 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
2840 d_export_vec
[i
]->next
= d_exports
;
2841 d_exports
= d_export_vec
[i
];
2844 /* Build list in alpha order */
2845 d_exports_lexically
= (export_type
**)
2846 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
2848 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2850 d_exports_lexically
[i
] = exp
;
2852 d_exports_lexically
[i
] = 0;
2854 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
2856 /* Fill exp entries with their hint values */
2858 for (i
= 0; i
< d_nfuncs
; i
++)
2860 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
2861 d_exports_lexically
[i
]->hint
= hint
++;
2864 inform (_("Processed definitions"));
2867 /**********************************************************************/
2870 usage (file
, status
)
2874 /* xgetext:c-format */
2875 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
2876 /* xgetext:c-format */
2877 fprintf (file
, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname
);
2878 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
2879 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
2880 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
2881 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2882 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2883 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2884 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
2885 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
2886 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
2887 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
2888 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2889 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2890 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2891 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2892 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
2893 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
2894 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
2896 fprintf (file
, _(" -i --interwork Support ARM/Thumb interworking.\n"));
2898 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2899 fprintf (file
, _(" -v --verbose Be verbose.\n"));
2900 fprintf (file
, _(" -V --version Display the program version.\n"));
2901 fprintf (file
, _(" -h --help Display this information.\n"));
2906 #define OPTION_EXPORT_ALL_SYMS 150
2907 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
2908 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
2909 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
2910 #define OPTION_NO_IDATA4 'x'
2911 #define OPTION_NO_IDATA5 'c'
2913 static const struct option long_options
[] =
2915 {"no-delete", no_argument
, NULL
, 'n'},
2916 {"dllname", required_argument
, NULL
, 'D'},
2917 {"no-idata4", no_argument
, NULL
, OPTION_NO_IDATA4
},
2918 {"no-idata5", no_argument
, NULL
, OPTION_NO_IDATA5
},
2919 {"output-exp", required_argument
, NULL
, 'e'},
2920 {"output-def", required_argument
, NULL
, 'z'},
2921 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
2922 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
2923 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
2924 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
2925 {"output-lib", required_argument
, NULL
, 'l'},
2926 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
2927 {"input-def", required_argument
, NULL
, 'd'},
2928 {"add-underscore", no_argument
, NULL
, 'U'},
2929 {"kill-at", no_argument
, NULL
, 'k'},
2930 {"verbose", no_argument
, NULL
, 'v'},
2931 {"version", no_argument
, NULL
, 'V'},
2932 {"help", no_argument
, NULL
, 'h'},
2933 {"machine", required_argument
, NULL
, 'm'},
2934 {"add-indirect", no_argument
, NULL
, 'a'},
2935 {"base-file", required_argument
, NULL
, 'b'},
2936 {"as", required_argument
, NULL
, 'S'},
2937 {"as-flags", required_argument
, NULL
, 'f'},
2939 {"interwork", no_argument
, NULL
, 'i'},
2952 program_name
= av
[0];
2955 #ifdef HAVE_SETLOCALE
2956 setlocale (LC_MESSAGES
, "");
2958 bindtextdomain (PACKAGE
, LOCALEDIR
);
2959 textdomain (PACKAGE
);
2961 while ((c
= getopt_long (ac
, av
, "xcz:S:aD:l:e:nkvVb:Uh?m:d:f:i",
2967 case OPTION_NO_IDATA4
:
2970 case OPTION_NO_IDATA5
:
2973 case OPTION_EXPORT_ALL_SYMS
:
2974 export_all_symbols
= true;
2976 case OPTION_NO_EXPORT_ALL_SYMS
:
2977 export_all_symbols
= false;
2979 case OPTION_EXCLUDE_SYMS
:
2980 add_excludes (optarg
);
2982 case OPTION_NO_DEFAULT_EXCLUDES
:
2983 do_default_excludes
= false;
2992 /* ignored for compatibility */
2999 output_def
= fopen (optarg
, FOPEN_WT
);
3020 print_version (program_name
);
3029 /* We don't currently define YYDEBUG when building
3047 base_file
= fopen (optarg
, FOPEN_RB
);
3050 /* xgettext:c-format */
3051 fatal (_("Unable to open base-file: %s"), optarg
);
3060 for (i
= 0; mtable
[i
].type
; i
++)
3062 if (strcmp (mtable
[i
].type
, mname
) == 0)
3066 if (!mtable
[i
].type
)
3067 /* xgettext:c-format */
3068 fatal (_("Machine '%s' not supported"), mname
);
3073 /* Always enable interworking for Thumb targets. */
3074 if (machine
== MTHUMB
&& (! interwork
))
3078 if (!dll_name
&& exp_name
)
3080 int len
= strlen (exp_name
) + 5;
3081 dll_name
= xmalloc (len
);
3082 strcpy (dll_name
, exp_name
);
3083 strcat (dll_name
, ".dll");
3086 /* Don't use the default exclude list if we're reading only the
3087 symbols in the .drectve section. The default excludes are meant
3088 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3089 if (! export_all_symbols
)
3090 do_default_excludes
= false;
3092 if (do_default_excludes
)
3093 set_default_excludes ();
3096 process_def_file (def_file
);
3101 firstarg
= av
[optind
];
3102 scan_obj_file (av
[optind
]);
3113 /* Make imp_name safe for use as a label. */
3116 imp_name_lab
= xstrdup (imp_name
);
3117 for (p
= imp_name_lab
; *p
; p
++)
3119 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3122 head_label
= make_label("_head_", imp_name_lab
);