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 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1256 /* xgettext:c-format */
1257 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1261 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1263 bfd_fatal (bfd_get_filename (abfd
));
1267 /* xgettext:c-format */
1268 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1272 /* Discard the symbols we don't want to export. It's OK to do this
1273 in place; we'll free the storage anyway. */
1275 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1276 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1281 /* Look at the object file to decide which symbols to export. */
1284 scan_open_obj_file (abfd
)
1287 if (export_all_symbols
)
1288 scan_all_symbols (abfd
);
1290 scan_drectve_symbols (abfd
);
1292 /* FIXME: we ought to read in and block out the base relocations */
1294 /* xgettext:c-format */
1295 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd
));
1299 scan_obj_file (filename
)
1300 const char *filename
;
1302 bfd
* f
= bfd_openr (filename
, 0);
1305 /* xgettext:c-format */
1306 fatal (_("Unable to open object file: %s"), filename
);
1308 /* xgettext:c-format */
1309 inform (_("Scanning object file %s"), filename
);
1311 if (bfd_check_format (f
, bfd_archive
))
1313 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1316 if (bfd_check_format (arfile
, bfd_object
))
1317 scan_open_obj_file (arfile
);
1319 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1322 else if (bfd_check_format (f
, bfd_object
))
1324 scan_open_obj_file (f
);
1330 /**********************************************************************/
1338 fprintf (f
, "%s ", ASM_C
);
1339 for (i
= 0; oav
[i
]; i
++)
1340 fprintf (f
, "%s ", oav
[i
]);
1342 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1344 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1350 exp
->noname
? "NONAME " : "",
1351 exp
->constant
? "CONSTANT" : "",
1352 exp
->data
? "DATA" : "");
1356 /* Generate the .exp file */
1363 return *(const long *) a
- *(const long *) b
;
1367 flush_page (f
, need
, page_addr
, on_page
)
1375 /* Flush this page */
1376 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1380 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1382 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1384 for (i
= 0; i
< on_page
; i
++)
1386 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, (need
[i
] - page_addr
) | 0x3000);
1390 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1399 inform (_("Adding exports to output file"));
1401 fprintf (output_def
, ";");
1402 for (i
= 0; oav
[i
]; i
++)
1403 fprintf (output_def
, " %s", oav
[i
]);
1405 fprintf (output_def
, "\nEXPORTS\n");
1407 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1409 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1410 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1412 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1417 exp
->noname
? " NONAME" : "",
1418 exp
->data
? " DATA" : "",
1424 inform (_("Added exports to output file"));
1427 /* generate_idata_ofile generates the portable assembly source code
1428 for the idata sections. It appends the source code to the end of
1432 generate_idata_ofile (filvar
)
1441 if (import_list
== NULL
)
1444 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1445 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1446 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1447 fprintf (filvar
, "doi_idata:\n");
1450 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1452 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1453 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1454 ASM_C
, headptr
->dllname
);
1455 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1456 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1457 fprintf (filvar
, "\t%sdllname%d%s\n",
1458 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1459 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1460 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1464 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1465 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1466 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1467 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1468 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1470 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1472 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1474 fprintf (filvar
, "listone%d:\n", headindex
);
1475 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1476 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1477 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1478 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1482 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1484 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1486 fprintf (filvar
, "listtwo%d:\n", headindex
);
1487 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1488 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1489 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1490 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1494 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1496 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1499 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1500 funcptr
= funcptr
->next
)
1502 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1503 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1504 ((funcptr
->ord
) & 0xFFFF));
1505 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1506 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1512 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1514 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1516 fprintf (filvar
,"dllname%d:\n", headindex
);
1517 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1518 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1531 /* xgettext:c-format */
1532 inform (_("Generating export file: %s\n"), exp_name
);
1534 f
= fopen (TMP_ASM
, FOPEN_WT
);
1536 /* xgettext:c-format */
1537 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1539 /* xgettext:c-format */
1540 inform (_("Opened temporary file: %s"), TMP_ASM
);
1546 fprintf (f
, "\t.section .edata\n\n");
1547 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1548 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1550 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1551 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1552 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1555 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1556 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1558 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1559 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1560 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1561 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1563 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1564 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1566 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1568 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1571 fprintf(f
,"%s Export address Table\n", ASM_C
);
1572 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1573 fprintf (f
, "afuncs:\n");
1576 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1578 if (exp
->ordinal
!= i
)
1581 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1583 (exp
->ordinal
- i
) * 4,
1585 i
, exp
->ordinal
- 1);
1588 while (i
< exp
->ordinal
)
1590 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1594 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1596 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1600 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1601 fprintf (f
, "anames:\n");
1603 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1605 if (!exp
->noname
|| show_allnames
)
1606 fprintf (f
, "\t%sn%d%s\n",
1607 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1610 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1611 fprintf (f
, "anords:\n");
1612 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1614 if (!exp
->noname
|| show_allnames
)
1615 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1618 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1619 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1620 if (!exp
->noname
|| show_allnames
)
1621 fprintf (f
, "n%d: %s \"%s\"\n",
1622 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1626 fprintf (f
, "\t.section .drectve\n");
1627 for (dl
= a_list
; dl
; dl
= dl
->next
)
1629 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1634 fprintf (f
, "\t.section .rdata\n");
1635 for (dl
= d_list
; dl
; dl
= dl
->next
)
1639 /* We dont output as ascii 'cause there can
1640 be quote characters in the string */
1643 for (p
= dl
->text
; *p
; p
++)
1646 fprintf (f
, "\t%s\t", ASM_BYTE
);
1649 fprintf (f
, "%d", *p
);
1652 fprintf (f
, ",0\n");
1666 /* Add to the output file a way of getting to the exported names
1667 without using the import library. */
1670 fprintf (f
, "\t.section\t.rdata\n");
1671 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1672 if (!exp
->noname
|| show_allnames
)
1674 /* We use a single underscore for MS compatibility, and a
1675 double underscore for backward compatibility with old
1677 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1678 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1679 fprintf (f
, "__imp_%s:\n", exp
->name
);
1680 fprintf (f
, "_imp__%s:\n", exp
->name
);
1681 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1685 /* Dump the reloc section if a base file is provided */
1689 long need
[PAGE_SIZE
];
1696 fprintf (f
, "\t.section\t.init\n");
1697 fprintf (f
, "lab:\n");
1699 fseek (base_file
, 0, SEEK_END
);
1700 numbytes
= ftell (base_file
);
1701 fseek (base_file
, 0, SEEK_SET
);
1702 copy
= xmalloc (numbytes
);
1703 fread (copy
, 1, numbytes
, base_file
);
1704 num_entries
= numbytes
/ sizeof (long);
1707 fprintf (f
, "\t.section\t.reloc\n");
1713 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1714 /* Delete duplcates */
1715 for (src
= 0; src
< num_entries
; src
++)
1717 if (last
!= copy
[src
])
1718 last
= copy
[dst
++] = copy
[src
];
1722 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1724 for (j
= 0; j
< num_entries
; j
++)
1727 if ((addr
& PAGE_MASK
) != page_addr
)
1729 flush_page (f
, need
, page_addr
, on_page
);
1731 page_addr
= addr
& PAGE_MASK
;
1733 need
[on_page
++] = addr
;
1735 flush_page (f
, need
, page_addr
, on_page
);
1737 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1741 generate_idata_ofile (f
);
1745 /* assemble the file */
1746 sprintf (outfile
, "%s -o %s %s", as_flags
, exp_name
, TMP_ASM
);
1750 strcat (outfile
, " -mthumb-interwork");
1753 run (as_name
, outfile
);
1755 if (dontdeltemps
== 0)
1758 inform (_("Generated exports file"));
1767 char *copy
= xmalloc (strlen (name
) + 2);
1769 strcpy (copy
+ 1, name
);
1776 p
= strchr (name
, '@');
1783 /**********************************************************************/
1792 if (exp
->noname
&& !show_allnames
)
1794 fprintf (f
, "\t%s\t0x%08x\n",
1796 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
1800 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
1818 unsigned char *data
;
1833 static sinfo secdata
[NSECS
] =
1835 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2},
1836 { DATA
, ".data", SEC_DATA
, 2},
1837 { BSS
, ".bss", 0, 2},
1838 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1839 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1840 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1841 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1}
1846 /* Sections numbered to make the order the same as other PowerPC NT */
1847 /* compilers. This also keeps funny alignment thingies from happening. */
1860 static sinfo secdata
[NSECS
] =
1862 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
1863 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
1864 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
1865 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
1866 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
1867 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
1868 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
1869 { DATA
, ".data", SEC_DATA
, 2},
1870 { BSS
, ".bss", 0, 2}
1876 This is what we're trying to make. We generate the imp symbols with
1877 both single and double underscores, for compatibility.
1880 .global _GetFileVersionInfoSizeW@8
1881 .global __imp_GetFileVersionInfoSizeW@8
1882 _GetFileVersionInfoSizeW@8:
1883 jmp * __imp_GetFileVersionInfoSizeW@8
1884 .section .idata$7 # To force loading of head
1885 .long __version_a_head
1886 # Import Address Table
1888 __imp_GetFileVersionInfoSizeW@8:
1891 # Import Lookup Table
1897 .asciz "GetFileVersionInfoSizeW"
1900 For the PowerPC, here's the variation on the above scheme:
1902 # Rather than a simple "jmp *", the code to get to the dll function
1905 lwz r11,[tocv]__imp_function_name(r2)
1906 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1915 make_label (prefix
, name
)
1919 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
1920 char *copy
= xmalloc (len
+1 );
1921 strcpy (copy
, ASM_PREFIX
);
1922 strcat (copy
, prefix
);
1923 strcat (copy
, name
);
1928 make_one_lib_file (exp
, i
)
1936 sprintf (outfile
, "%ss%d.s", prefix
, i
);
1937 f
= fopen (outfile
, FOPEN_WT
);
1938 fprintf (f
, "\t.text\n");
1939 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
1940 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1941 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1942 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
1943 exp
->name
, ASM_JUMP
, exp
->name
);
1945 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
1946 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
1949 fprintf (f
,"%s Import Address Table\n", ASM_C
);
1951 fprintf (f
, "\t.section .idata$5\n");
1952 fprintf (f
, "__imp_%s:\n", exp
->name
);
1953 fprintf (f
, "_imp__%s:\n", exp
->name
);
1957 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
1958 fprintf (f
, "\t.section .idata$4\n");
1962 if(!exp
->noname
|| show_allnames
)
1964 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
1965 fprintf (f
, "\t.section .idata$6\n");
1966 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
1967 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
1972 sprintf (outfile
, "%s -o %ss%d.o %ss%d.s",
1973 as_flags
, prefix
, i
, prefix
, i
);
1977 strcat (outfile
, " -mthumb-interwork");
1980 run (as_name
, outfile
);
1985 asymbol
* exp_label
;
1988 asymbol
* iname_lab
;
1989 asymbol
** iname_lab_pp
;
1990 asymbol
** iname_pp
;
1999 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2001 char * outname
= xmalloc (10);
2005 sprintf (outname
, "%s%d.o", TMP_STUB
, i
);
2007 abfd
= bfd_openw (outname
, HOW_BFD_TARGET
);
2010 /* xgettext:c-format */
2011 fatal (_("bfd_open failed open stub file: %s"), outname
);
2013 /* xgettext:c-format */
2014 inform (_("Creating stub file: %s"), outname
);
2016 bfd_set_format (abfd
, bfd_object
);
2017 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2021 bfd_set_private_flags (abfd
, F_INTERWORK
);
2024 /* First make symbols for the sections */
2025 for (i
= 0; i
< NSECS
; i
++)
2027 sinfo
*si
= secdata
+ i
;
2030 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2031 bfd_set_section_flags (abfd
,
2035 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2036 si
->sec
->output_section
= si
->sec
;
2037 si
->sym
= bfd_make_empty_symbol(abfd
);
2038 si
->sym
->name
= si
->sec
->name
;
2039 si
->sym
->section
= si
->sec
;
2040 si
->sym
->flags
= BSF_LOCAL
;
2042 ptrs
[oidx
] = si
->sym
;
2043 si
->sympp
= ptrs
+ oidx
;
2052 exp_label
= bfd_make_empty_symbol (abfd
);
2053 exp_label
->name
= make_label ("", exp
->name
);
2055 /* On PowerPC, the function name points to a descriptor in
2056 the rdata section, the first element of which is a
2057 pointer to the code (..function_name), and the second
2058 points to the .toc */
2060 if (machine
== MPPC
)
2061 exp_label
->section
= secdata
[RDATA
].sec
;
2064 exp_label
->section
= secdata
[TEXT
].sec
;
2066 exp_label
->flags
= BSF_GLOBAL
;
2067 exp_label
->value
= 0;
2070 if (machine
== MTHUMB
)
2071 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXT
);
2073 ptrs
[oidx
++] = exp_label
;
2076 /* Generate imp symbols with one underscore for Microsoft
2077 compatibility, and with two underscores for backward
2078 compatibility with old versions of cygwin. */
2079 iname
= bfd_make_empty_symbol(abfd
);
2080 iname
->name
= make_label ("__imp_", exp
->name
);
2081 iname
->section
= secdata
[IDATA5
].sec
;
2082 iname
->flags
= BSF_GLOBAL
;
2085 iname2
= bfd_make_empty_symbol(abfd
);
2086 iname2
->name
= make_label ("_imp__", exp
->name
);
2087 iname2
->section
= secdata
[IDATA5
].sec
;
2088 iname2
->flags
= BSF_GLOBAL
;
2091 iname_lab
= bfd_make_empty_symbol(abfd
);
2093 iname_lab
->name
= head_label
;
2094 iname_lab
->section
= (asection
*)&bfd_und_section
;
2095 iname_lab
->flags
= 0;
2096 iname_lab
->value
= 0;
2099 iname_pp
= ptrs
+ oidx
;
2100 ptrs
[oidx
++] = iname
;
2101 ptrs
[oidx
++] = iname2
;
2103 iname_lab_pp
= ptrs
+ oidx
;
2104 ptrs
[oidx
++] = iname_lab
;
2107 /* The symbol refering to the code (.text) */
2109 asymbol
*function_name
;
2111 function_name
= bfd_make_empty_symbol(abfd
);
2112 function_name
->name
= make_label ("..", exp
->name
);
2113 function_name
->section
= secdata
[TEXT
].sec
;
2114 function_name
->flags
= BSF_GLOBAL
;
2115 function_name
->value
= 0;
2117 fn_pp
= ptrs
+ oidx
;
2118 ptrs
[oidx
++] = function_name
;
2121 /* The .toc symbol */
2123 asymbol
*toc_symbol
; /* The .toc symbol */
2125 toc_symbol
= bfd_make_empty_symbol (abfd
);
2126 toc_symbol
->name
= make_label (".", "toc");
2127 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2128 toc_symbol
->flags
= BSF_GLOBAL
;
2129 toc_symbol
->value
= 0;
2131 toc_pp
= ptrs
+ oidx
;
2132 ptrs
[oidx
++] = toc_symbol
;
2138 for (i
= 0; i
< NSECS
; i
++)
2140 sinfo
*si
= secdata
+ i
;
2141 asection
*sec
= si
->sec
;
2150 si
->size
= HOW_JTAB_SIZE
;
2151 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2152 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2154 /* add the reloc into idata$5 */
2155 rel
= xmalloc (sizeof (arelent
));
2157 rpp
= xmalloc (sizeof (arelent
*) * 2);
2161 rel
->address
= HOW_JTAB_ROFF
;
2164 if (machine
== MPPC
)
2166 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2167 BFD_RELOC_16_GOTOFF
);
2168 rel
->sym_ptr_ptr
= iname_pp
;
2172 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2173 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2175 sec
->orelocation
= rpp
;
2176 sec
->reloc_count
= 1;
2181 /* An idata$4 or idata$5 is one word long, and has an
2184 si
->data
= xmalloc (4);
2189 si
->data
[0] = exp
->ordinal
;
2190 si
->data
[1] = exp
->ordinal
>> 8;
2191 si
->data
[2] = exp
->ordinal
>> 16;
2196 sec
->reloc_count
= 1;
2197 memset (si
->data
, 0, si
->size
);
2198 rel
= xmalloc (sizeof (arelent
));
2199 rpp
= xmalloc (sizeof (arelent
*) * 2);
2204 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2205 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2206 sec
->orelocation
= rpp
;
2214 /* This used to add 1 to exp->hint. I don't know
2215 why it did that, and it does not match what I see
2216 in programs compiled with the MS tools. */
2217 int idx
= exp
->hint
;
2218 si
->size
= strlen (xlate (exp
->name
)) + 3;
2219 si
->data
= xmalloc (si
->size
);
2220 si
->data
[0] = idx
& 0xff;
2221 si
->data
[1] = idx
>> 8;
2222 strcpy (si
->data
+ 2, xlate (exp
->name
));
2227 si
->data
=xmalloc(4);
2228 memset (si
->data
, 0, si
->size
);
2229 rel
= xmalloc (sizeof (arelent
));
2230 rpp
= xmalloc (sizeof (arelent
*) * 2);
2234 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2235 rel
->sym_ptr_ptr
= iname_lab_pp
;
2236 sec
->orelocation
= rpp
;
2237 sec
->reloc_count
= 1;
2243 /* The .pdata section is 5 words long. */
2244 /* Think of it as: */
2247 /* bfd_vma BeginAddress, [0x00] */
2248 /* EndAddress, [0x04] */
2249 /* ExceptionHandler, [0x08] */
2250 /* HandlerData, [0x0c] */
2251 /* PrologEndAddress; [0x10] */
2254 /* So this pdata section setups up this as a glue linkage to
2255 a dll routine. There are a number of house keeping things
2258 1. In the name of glue trickery, the ADDR32 relocs for 0,
2259 4, and 0x10 are set to point to the same place:
2261 2. There is one more reloc needed in the pdata section.
2262 The actual glue instruction to restore the toc on
2263 return is saved as the offset in an IMGLUE reloc.
2264 So we need a total of four relocs for this section.
2266 3. Lastly, the HandlerData field is set to 0x03, to indicate
2267 that this is a glue routine.
2269 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2271 /* alignment must be set to 2**2 or you get extra stuff */
2272 bfd_set_section_alignment(abfd
, sec
, 2);
2275 si
->data
=xmalloc(4 * 5);
2276 memset (si
->data
, 0, si
->size
);
2277 rpp
= xmalloc (sizeof (arelent
*) * 5);
2278 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2279 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2280 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2281 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2284 /* stick the toc reload instruction in the glue reloc */
2285 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2288 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2289 BFD_RELOC_32_GOTOFF
);
2290 imglue
->sym_ptr_ptr
= fn_pp
;
2292 ba_rel
->address
= 0;
2294 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2295 ba_rel
->sym_ptr_ptr
= fn_pp
;
2297 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2298 ea_rel
->address
= 4;
2300 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2301 ea_rel
->sym_ptr_ptr
= fn_pp
;
2303 /* mark it as glue */
2304 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2306 /* mark the prolog end address */
2307 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2308 pea_rel
->address
= 0x10;
2309 pea_rel
->addend
= 0;
2310 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2311 pea_rel
->sym_ptr_ptr
= fn_pp
;
2313 sec
->orelocation
= rpp
;
2314 sec
->reloc_count
= 4;
2318 /* Each external function in a PowerPC PE file has a two word
2319 descriptor consisting of:
2320 1. The address of the code.
2321 2. The address of the appropriate .toc
2322 We use relocs to build this.
2326 si
->data
= xmalloc (8);
2327 memset (si
->data
, 0, si
->size
);
2329 rpp
= xmalloc (sizeof (arelent
*) * 3);
2330 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2331 rpp
[1] = xmalloc (sizeof (arelent
));
2336 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2337 rel
->sym_ptr_ptr
= fn_pp
;
2343 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2344 rel
->sym_ptr_ptr
= toc_pp
;
2346 sec
->orelocation
= rpp
;
2347 sec
->reloc_count
= 2;
2349 #endif /* DLLTOOL_PPC */
2355 /* Size up all the sections */
2356 for (i
= 0; i
< NSECS
; i
++)
2358 sinfo
*si
= secdata
+ i
;
2360 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2361 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2363 /* vma += si->size;*/
2366 /* Write them out */
2367 for (i
= 0; i
< NSECS
; i
++)
2369 sinfo
*si
= secdata
+ i
;
2371 if (i
== IDATA5
&& no_idata5
)
2374 if (i
== IDATA4
&& no_idata4
)
2377 bfd_set_section_contents (abfd
, si
->sec
,
2382 bfd_set_symtab (abfd
, ptrs
, oidx
);
2384 abfd
= bfd_openr (outname
, HOW_BFD_TARGET
);
2393 FILE * f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2395 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2396 fprintf (f
, "\t.section .idata$2\n");
2398 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2400 fprintf (f
, "%s:\n", head_label
);
2402 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2403 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2405 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2406 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2407 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2408 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2409 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2414 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2416 ASM_RVA_AFTER
, ASM_C
);
2418 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2422 fprintf (f
, "\t.section\t.idata$5\n");
2423 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2424 fprintf (f
, "fthunk:\n");
2428 fprintf (f
, "\t.section\t.idata$4\n");
2430 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2431 fprintf (f
, "\t.section .idata$4\n");
2432 fprintf (f
, "hname:\n");
2436 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_HEAD_O
, TMP_HEAD_S
);
2440 strcat (outfile
, " -mthumb-interwork");
2443 run (as_name
, outfile
);
2445 return bfd_openr (TMP_HEAD_O
, HOW_BFD_TARGET
);
2451 FILE * f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2455 fprintf (f
, "\t.section .idata$4\n");
2456 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2460 fprintf (f
, "\t.section .idata$5\n");
2461 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2465 /* Normally, we need to see a null descriptor built in idata$3 to
2466 act as the terminator for the list. The ideal way, I suppose,
2467 would be to mark this section as a comdat type 2 section, so
2468 only one would appear in the final .exe (if our linker supported
2469 comdat, that is) or cause it to be inserted by something else (say
2473 fprintf (f
, "\t.section .idata$3\n");
2474 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2475 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2476 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2477 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2478 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2482 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2483 do too. Original, huh? */
2484 fprintf (f
, "\t.section .idata$6\n");
2486 fprintf (f
, "\t.section .idata$7\n");
2489 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2490 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2491 imp_name_lab
, ASM_TEXT
, dll_name
);
2495 sprintf (outfile
, "%s -o %s %s", as_flags
, TMP_TAIL_O
, TMP_TAIL_S
);
2499 strcat (outfile
, " -mthumb-interwork");
2502 run (as_name
, outfile
);
2504 return bfd_openr (TMP_TAIL_O
, HOW_BFD_TARGET
);
2519 outarch
= bfd_openw (imp_name
, HOW_BFD_TARGET
);
2522 /* xgettext:c-format */
2523 fatal (_("Can't open .lib file: %s"), imp_name
);
2525 /* xgettext:c-format */
2526 inform (_("Creating library file: %s\n"), imp_name
);
2528 bfd_set_format (outarch
, bfd_archive
);
2529 outarch
->has_armap
= 1;
2531 /* Work out a reasonable size of things to put onto one line. */
2533 ar_head
= make_head ();
2534 ar_tail
= make_tail();
2536 if (ar_head
== NULL
|| ar_tail
== NULL
)
2539 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2541 bfd
*n
= make_one_lib_file (exp
, i
);
2546 /* Now stick them all into the archive */
2548 ar_head
->next
= head
;
2549 ar_tail
->next
= ar_head
;
2552 if (! bfd_set_archive_head (outarch
, head
))
2553 bfd_fatal ("bfd_set_archive_head");
2555 if (! bfd_close (outarch
))
2556 bfd_fatal (imp_name
);
2558 while (head
!= NULL
)
2560 bfd
*n
= head
->next
;
2565 /* Delete all the temp files */
2567 if (dontdeltemps
== 0)
2569 unlink (TMP_HEAD_O
);
2570 unlink (TMP_HEAD_S
);
2571 unlink (TMP_TAIL_O
);
2572 unlink (TMP_TAIL_S
);
2575 if (dontdeltemps
< 2)
2577 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2579 sprintf (outfile
, "%s%d.o", TMP_STUB
, i
);
2580 if (unlink (outfile
) < 0)
2581 /* xgettext:c-format */
2582 warn (_("cannot delete %s: %s\n"), outfile
, strerror (errno
));
2586 inform (_("Created lib file"));
2589 /**********************************************************************/
2591 /* Run through the information gathered from the .o files and the
2592 .def file and work out the best stuff */
2598 export_type
*ap
= *(export_type
**) a
;
2599 export_type
*bp
= *(export_type
**) b
;
2600 if (ap
->ordinal
== bp
->ordinal
)
2603 /* unset ordinals go to the bottom */
2604 if (ap
->ordinal
== -1)
2606 if (bp
->ordinal
== -1)
2608 return (ap
->ordinal
- bp
->ordinal
);
2616 export_type
*ap
= *(export_type
**) a
;
2617 export_type
*bp
= *(export_type
**) b
;
2619 return (strcmp (ap
->name
, bp
->name
));
2623 remove_null_names (ptr
)
2628 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2632 ptr
[dst
] = ptr
[src
];
2645 for (i
= 0; i
< d_nfuncs
; i
++)
2649 printf ("%d %s @ %d %s%s%s\n",
2650 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2651 ptr
[i
]->noname
? "NONAME " : "",
2652 ptr
[i
]->constant
? "CONSTANT" : "",
2653 ptr
[i
]->data
? "DATA" : "");
2662 process_duplicates (d_export_vec
)
2663 export_type
**d_export_vec
;
2671 /* Remove duplicates */
2672 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2674 dtab (d_export_vec
);
2675 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2677 if (strcmp (d_export_vec
[i
]->name
,
2678 d_export_vec
[i
+ 1]->name
) == 0)
2681 export_type
*a
= d_export_vec
[i
];
2682 export_type
*b
= d_export_vec
[i
+ 1];
2686 /* xgettext:c-format */
2687 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2688 a
->name
, a
->ordinal
, b
->ordinal
);
2690 if (a
->ordinal
!= -1
2691 && b
->ordinal
!= -1)
2692 /* xgettext:c-format */
2693 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2696 /* Merge attributes */
2697 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2698 b
->constant
|= a
->constant
;
2699 b
->noname
|= a
->noname
;
2701 d_export_vec
[i
] = 0;
2704 dtab (d_export_vec
);
2705 remove_null_names (d_export_vec
);
2706 dtab (d_export_vec
);
2711 /* Count the names */
2712 for (i
= 0; i
< d_nfuncs
; i
++)
2714 if (!d_export_vec
[i
]->noname
)
2720 fill_ordinals (d_export_vec
)
2721 export_type
**d_export_vec
;
2728 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2730 /* fill in the unset ordinals with ones from our range */
2732 ptr
= (char *) xmalloc (size
);
2734 memset (ptr
, 0, size
);
2736 /* Mark in our large vector all the numbers that are taken */
2737 for (i
= 0; i
< d_nfuncs
; i
++)
2739 if (d_export_vec
[i
]->ordinal
!= -1)
2741 ptr
[d_export_vec
[i
]->ordinal
] = 1;
2742 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
2744 lowest
= d_export_vec
[i
]->ordinal
;
2749 /* Start at 1 for compatibility with MS toolchain. */
2753 /* Now fill in ordinals where the user wants us to choose. */
2754 for (i
= 0; i
< d_nfuncs
; i
++)
2756 if (d_export_vec
[i
]->ordinal
== -1)
2760 /* First try within or after any user supplied range. */
2761 for (j
= lowest
; j
< size
; j
++)
2765 d_export_vec
[i
]->ordinal
= j
;
2769 /* Then try before the range. */
2770 for (j
= lowest
; j
>0; j
--)
2774 d_export_vec
[i
]->ordinal
= j
;
2785 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2787 /* Work out the lowest and highest ordinal numbers. */
2790 if (d_export_vec
[0])
2791 d_low_ord
= d_export_vec
[0]->ordinal
;
2792 if (d_export_vec
[d_nfuncs
-1])
2793 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
2802 const export_type
**a
= (const export_type
**) av
;
2803 const export_type
**b
= (const export_type
**) bv
;
2805 return strcmp ((*a
)->name
, (*b
)->name
);
2811 /* First work out the minimum ordinal chosen */
2817 export_type
**d_export_vec
2818 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
2820 inform (_("Processing definitions"));
2822 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2824 d_export_vec
[i
] = exp
;
2827 process_duplicates (d_export_vec
);
2828 fill_ordinals (d_export_vec
);
2830 /* Put back the list in the new order */
2832 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
2834 d_export_vec
[i
]->next
= d_exports
;
2835 d_exports
= d_export_vec
[i
];
2838 /* Build list in alpha order */
2839 d_exports_lexically
= (export_type
**)
2840 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
2842 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2844 d_exports_lexically
[i
] = exp
;
2846 d_exports_lexically
[i
] = 0;
2848 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
2850 /* Fill exp entries with their hint values */
2852 for (i
= 0; i
< d_nfuncs
; i
++)
2854 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
2855 d_exports_lexically
[i
]->hint
= hint
++;
2858 inform (_("Processed definitions"));
2861 /**********************************************************************/
2864 usage (file
, status
)
2868 /* xgetext:c-format */
2869 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
2870 /* xgetext:c-format */
2871 fprintf (file
, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname
);
2872 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
2873 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
2874 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
2875 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2876 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2877 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2878 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
2879 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
2880 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
2881 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
2882 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2883 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2884 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2885 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2886 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
2887 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
2888 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
2890 fprintf (file
, _(" -i --interwork Support ARM/Thumb interworking.\n"));
2892 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2893 fprintf (file
, _(" -v --verbose Be verbose.\n"));
2894 fprintf (file
, _(" -V --version Display the program version.\n"));
2895 fprintf (file
, _(" -h --help Display this information.\n"));
2900 #define OPTION_EXPORT_ALL_SYMS 150
2901 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
2902 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
2903 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
2904 #define OPTION_NO_IDATA4 'x'
2905 #define OPTION_NO_IDATA5 'c'
2907 static const struct option long_options
[] =
2909 {"no-delete", no_argument
, NULL
, 'n'},
2910 {"dllname", required_argument
, NULL
, 'D'},
2911 {"no-idata4", no_argument
, NULL
, OPTION_NO_IDATA4
},
2912 {"no-idata5", no_argument
, NULL
, OPTION_NO_IDATA5
},
2913 {"output-exp", required_argument
, NULL
, 'e'},
2914 {"output-def", required_argument
, NULL
, 'z'},
2915 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
2916 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
2917 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
2918 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
2919 {"output-lib", required_argument
, NULL
, 'l'},
2920 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
2921 {"input-def", required_argument
, NULL
, 'd'},
2922 {"add-underscore", no_argument
, NULL
, 'U'},
2923 {"kill-at", no_argument
, NULL
, 'k'},
2924 {"verbose", no_argument
, NULL
, 'v'},
2925 {"version", no_argument
, NULL
, 'V'},
2926 {"help", no_argument
, NULL
, 'h'},
2927 {"machine", required_argument
, NULL
, 'm'},
2928 {"add-indirect", no_argument
, NULL
, 'a'},
2929 {"base-file", required_argument
, NULL
, 'b'},
2930 {"as", required_argument
, NULL
, 'S'},
2931 {"as-flags", required_argument
, NULL
, 'f'},
2933 {"interwork", no_argument
, NULL
, 'i'},
2946 program_name
= av
[0];
2949 #ifdef HAVE_SETLOCALE
2950 setlocale (LC_MESSAGES
, "");
2952 bindtextdomain (PACKAGE
, LOCALEDIR
);
2953 textdomain (PACKAGE
);
2955 while ((c
= getopt_long (ac
, av
, "xcz:S:aD:l:e:nkvVb:Uh?m:d:f:i",
2961 case OPTION_NO_IDATA4
:
2964 case OPTION_NO_IDATA5
:
2967 case OPTION_EXPORT_ALL_SYMS
:
2968 export_all_symbols
= true;
2970 case OPTION_NO_EXPORT_ALL_SYMS
:
2971 export_all_symbols
= false;
2973 case OPTION_EXCLUDE_SYMS
:
2974 add_excludes (optarg
);
2976 case OPTION_NO_DEFAULT_EXCLUDES
:
2977 do_default_excludes
= false;
2986 /* ignored for compatibility */
2993 output_def
= fopen (optarg
, FOPEN_WT
);
3014 print_version (program_name
);
3023 /* We don't currently define YYDEBUG when building
3041 base_file
= fopen (optarg
, FOPEN_RB
);
3044 /* xgettext:c-format */
3045 fatal (_("Unable to open base-file: %s"), optarg
);
3054 for (i
= 0; mtable
[i
].type
; i
++)
3056 if (strcmp (mtable
[i
].type
, mname
) == 0)
3060 if (!mtable
[i
].type
)
3061 /* xgettext:c-format */
3062 fatal (_("Machine '%s' not supported"), mname
);
3067 /* Always enable interworking for Thumb targets. */
3068 if (machine
== MTHUMB
&& (! interwork
))
3072 if (!dll_name
&& exp_name
)
3074 int len
= strlen (exp_name
) + 5;
3075 dll_name
= xmalloc (len
);
3076 strcpy (dll_name
, exp_name
);
3077 strcat (dll_name
, ".dll");
3080 /* Don't use the default exclude list if we're reading only the
3081 symbols in the .drectve section. The default excludes are meant
3082 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3083 if (! export_all_symbols
)
3084 do_default_excludes
= false;
3086 if (do_default_excludes
)
3087 set_default_excludes ();
3090 process_def_file (def_file
);
3095 firstarg
= av
[optind
];
3096 scan_obj_file (av
[optind
]);
3107 /* Make imp_name safe for use as a label. */
3110 imp_name_lab
= xstrdup (imp_name
);
3111 for (p
= imp_name_lab
; *p
; p
++)
3113 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3116 head_label
= make_label("_head_", imp_name_lab
);