1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995, 96, 97, 98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 This program allows you to build the files necessary to create
24 DLLs to run on a system which understands PE format image files.
27 See "Peering Inside the PE: A Tour of the Win32 Portable Executable
28 File Format", MSJ 1994, Volume 9 for more information.
29 Also see "Microsoft Portable Executable and Common Object File Format,
30 Specification 4.1" for more information.
32 A DLL contains an export table which contains the information
33 which the runtime loader needs to tie up references from a
36 The export table is generated by this program by reading
37 in a .DEF file or scanning the .a and .o files which will be in the
38 DLL. A .o file can contain information in special ".drectve" sections
39 with export information.
41 A DEF file contains any number of the following commands:
44 NAME <name> [ , <base> ]
45 The result is going to be <name>.EXE
47 LIBRARY <name> [ , <base> ]
48 The result is going to be <name>.DLL
50 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
51 Declares name1 as an exported symbol from the
52 DLL, with optional ordinal number <integer>
54 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
55 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
56 Declares that <external-name> or the exported function whoes ordinal number
57 is <integer> is to be imported from the file <module-name>. If
58 <internal-name> is specified then this is the name that the imported
59 function will be refered to in the body of the DLL.
62 Puts <string> into output .exp file in the .rdata section
64 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
65 Generates --stack|--heap <number-reserve>,<number-commit>
66 in the output .drectve section. The linker will
67 see this and act upon it.
70 SECTIONS ( <sectionname> <attr>+ )*
71 <attr> = READ | WRITE | EXECUTE | SHARED
72 Generates --attr <sectionname> <attr> in the output
73 .drectve section. The linker will see this and act
77 A -export:<name> in a .drectve section in an input .o or .a
78 file to this program is equivalent to a EXPORTS <name>
83 The program generates output files with the prefix supplied
84 on the command line, or in the def file, or taken from the first
87 The .exp.s file contains the information necessary to export
88 the routines in the DLL. The .lib.s file contains the information
89 necessary to use the DLL's routines from a referencing program.
96 asm (".section .drectve");
97 asm (".ascii \"-export:adef\"");
101 printf ("hello from the dll %s\n", s);
106 printf ("hello from the dll and the other entry point %s\n", s);
110 asm (".section .drectve");
111 asm (".ascii \"-export:cdef\"");
112 asm (".ascii \"-export:ddef\"");
116 printf ("hello from the dll %s\n", s);
121 printf ("hello from the dll and the other entry point %s\n", s);
139 HEAPSIZE 0x40000, 0x2000
143 SECTIONS donkey READ WRITE
146 # compile up the parts of the dll
151 # put them in a library (you don't have to, you
152 # could name all the .os on the dlltool line)
154 ar qcv thedll.in file1.o file2.o
157 # run this tool over the library and the def file
158 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
160 # build the dll with the library with file1.o, file2.o and the export table
161 ld -o thedll.dll thedll.o thedll.in
166 # link the executable with the import library
167 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
171 /* .idata section description
173 The .idata section is the import table. It is a collection of several
174 subsections used to keep the pieces for each dll together: .idata$[234567].
175 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
177 .idata$2 = Import Directory Table
178 = array of IMAGE_IMPORT_DESCRIPTOR's.
180 DWORD Import Lookup Table; - pointer to .idata$4
181 DWORD TimeDateStamp; - currently always 0
182 DWORD ForwarderChain; - currently always 0
183 DWORD Name; - pointer to dll's name
184 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
186 .idata$3 = null terminating entry for .idata$2.
188 .idata$4 = Import Lookup Table
189 = array of array of pointers to hint name table.
190 There is one for each dll being imported from, and each dll's set is
191 terminated by a trailing NULL.
193 .idata$5 = Import Address Table
194 = array of array of pointers to hint name table.
195 There is one for each dll being imported from, and each dll's set is
196 terminated by a trailing NULL.
197 Initially, this table is identical to the Import Lookup Table. However,
198 at load time, the loader overwrites the entries with the address of the
201 .idata$6 = Hint Name Table
202 = Array of { short, asciz } entries, one for each imported function.
203 The `short' is the function's ordinal number.
205 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
208 /* AIX requires this to be the first thing in the file. */
215 #define show_allnames 0
217 #define PAGE_SIZE 4096
218 #define PAGE_MASK (-PAGE_SIZE)
220 #include "libiberty.h"
223 #include "demangle.h"
235 #include "coff/arm.h"
236 #include "coff/internal.h"
239 #ifdef HAVE_SYS_WAIT_H
240 #include <sys/wait.h>
241 #else /* ! HAVE_SYS_WAIT_H */
242 #if ! defined (_WIN32) || defined (__CYGWIN32__)
244 #define WIFEXITED(w) (((w)&0377) == 0)
247 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
250 #define WTERMSIG(w) ((w) & 0177)
253 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
255 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
257 #define WIFEXITED(w) (((w) & 0xff) == 0)
260 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
263 #define WTERMSIG(w) ((w) & 0x7f)
266 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
268 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
269 #endif /* ! HAVE_SYS_WAIT_H */
271 /* ifunc and ihead data structures: ttk@cygnus.com 1997
273 When IMPORT declarations are encountered in a .def file the
274 function import information is stored in a structure referenced by
275 the global variable IMPORT_LIST. The structure is a linked list
276 containing the names of the dll files each function is imported
277 from and a linked list of functions being imported from that dll
278 file. This roughly parallels the structure of the .idata section
279 in the PE object file.
281 The contents of .def file are interpreted from within the
282 process_def_file function. Every time an IMPORT declaration is
283 encountered, it is broken up into its component parts and passed to
284 def_import. IMPORT_LIST is initialized to NULL in function main. */
286 typedef struct ifunct
288 char *name; /* name of function being imported */
289 int ord; /* two-byte ordinal value associated with function */
293 typedef struct iheadt
295 char *dllname; /* name of dll file imported from */
296 long nfuncs; /* number of functions in list */
297 struct ifunct *funchead; /* first function in list */
298 struct ifunct *functail; /* last function in list */
299 struct iheadt *next; /* next dll file in list */
302 /* Structure containing all import information as defined in .def file
303 (qv "ihead structure"). */
305 static iheadtype *import_list = NULL;
307 static char *as_name = "as";
308 static char * as_flags = "";
310 static int no_idata4;
311 static int no_idata5;
312 static char *exp_name;
313 static char *imp_name;
314 static char *head_label;
315 static char *imp_name_lab;
316 static char *dll_name;
318 static int add_indirect = 0;
319 static int add_underscore = 0;
320 static int dontdeltemps = 0;
322 /* True if we should export all symbols. Otherwise, we only export
323 symbols listed in .drectve sections or in the def file. */
324 static boolean export_all_symbols;
326 /* True if we should exclude the symbols in DEFAULT_EXCLUDES when
327 exporting all symbols. */
328 static boolean do_default_excludes;
330 /* Default symbols to exclude when exporting all the symbols. */
331 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
333 static char *def_file;
335 extern char * program_name;
339 static int add_stdcall_alias;
341 static FILE *output_def;
342 static FILE *base_file;
345 static const char *mname = "beos";
349 static const char *mname = "arm";
353 static const char *mname = "i386";
357 static const char *mname = "ppc";
360 #define PATHMAX 250 /* What's the right name for this ? */
362 #define TMP_ASM "dc.s"
363 #define TMP_HEAD_S "dh.s"
364 #define TMP_HEAD_O "dh.o"
365 #define TMP_TAIL_S "dt.s"
366 #define TMP_TAIL_O "dt.o"
367 #define TMP_STUB "ds"
369 /* This bit of assemly does jmp * ....
370 s set how_jtab_roff to mark where the 32bit abs branch should go */
371 static const unsigned char i386_jtab[] =
373 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
376 static const unsigned char arm_jtab[] =
378 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
379 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
383 static const unsigned char arm_interwork_jtab[] =
385 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
386 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
387 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
391 static const unsigned char thumb_jtab[] =
393 0x40, 0xb4, /* push {r6} */
394 0x02, 0x4e, /* ldr r6, [pc, #8] */
395 0x36, 0x68, /* ldr r6, [r6] */
396 0xb4, 0x46, /* mov ip, r6 */
397 0x40, 0xbc, /* pop {r6} */
398 0x60, 0x47, /* bx ip */
402 /* This is the glue sequence for PowerPC PE. There is a */
403 /* tocrel16-tocdefn reloc against the first instruction. */
404 /* We also need a IMGLUE reloc against the glue function */
405 /* to restore the toc saved by the third instruction in */
407 static const unsigned char ppc_jtab[] =
409 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
410 /* Reloc TOCREL16 __imp_xxx */
411 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
412 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
413 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
414 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
415 0x20, 0x04, 0x80, 0x4E /* bctr */
419 /* the glue instruction, picks up the toc from the stw in */
420 /* the above code: "lwz r2,4(r1)" */
421 static bfd_vma ppc_glue_insn = 0x80410004;
424 /* The outfile array must be big enough to contain a fully
425 qualified path name, plus an arbitary series of command
426 line switches. We hope that PATH_MAX times two will be
428 static char outfile [PATHMAX * 2];
433 const char *how_byte;
434 const char *how_short;
435 const char *how_long;
436 const char *how_asciz;
437 const char *how_comment;
438 const char *how_jump;
439 const char *how_global;
440 const char *how_space;
441 const char *how_align_short;
442 const char *how_align_long;
443 const char *how_bfd_target;
444 enum bfd_architecture how_bfd_arch;
445 const unsigned char *how_jtab;
446 int how_jtab_size; /* size of the jtab entry */
447 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
450 static const struct mac
455 "arm", ".byte", ".short", ".long", ".asciz", "@",
456 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
457 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
458 arm_jtab, sizeof (arm_jtab), 8
463 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
464 i386_jtab, sizeof (i386_jtab), 2
469 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
470 ppc_jtab, sizeof (ppc_jtab), 0
475 "thumb", ".byte", ".short", ".long", ".asciz", "@",
476 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
477 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
478 thumb_jtab, sizeof (thumb_jtab), 12
481 #define MARM_INTERWORK 4
483 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
484 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
485 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
486 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
499 typedef struct export
502 const char *internal_name;
512 /* A list of symbols which we should not export. */
516 struct string_list *next;
520 static struct string_list *excludes;
522 static const char *rvaafter PARAMS ((int));
523 static const char *rvabefore PARAMS ((int));
524 static const char *asm_prefix PARAMS ((int));
525 static void append_import PARAMS ((const char *, const char *, int));
526 static void run PARAMS ((const char *, char *));
527 static void scan_drectve_symbols PARAMS ((bfd *));
528 static void scan_filtered_symbols PARAMS ((bfd *, PTR, long, unsigned int));
529 static void add_excludes PARAMS ((const char *));
530 static boolean match_exclude PARAMS ((const char *));
531 static void set_default_excludes PARAMS ((void));
532 static long filter_symbols PARAMS ((bfd *, PTR, long, unsigned int));
533 static void scan_all_symbols PARAMS ((bfd *));
534 static void scan_open_obj_file PARAMS ((bfd *));
535 static void scan_obj_file PARAMS ((const char *));
536 static void dump_def_info PARAMS ((FILE *));
537 static int sfunc PARAMS ((const void *, const void *));
538 static void flush_page PARAMS ((FILE *, long *, int, int));
539 static void gen_def_file PARAMS ((void));
540 static void generate_idata_ofile PARAMS ((FILE *));
541 static void gen_exp_file PARAMS ((void));
542 static const char *xlate PARAMS ((const char *));
544 static void dump_iat PARAMS ((FILE *, export_type *));
546 static char *make_label PARAMS ((const char *, const char *));
547 static bfd *make_one_lib_file PARAMS ((export_type *, int));
548 static bfd *make_head PARAMS ((void));
549 static bfd *make_tail PARAMS ((void));
550 static void gen_lib_file PARAMS ((void));
551 static int pfunc PARAMS ((const void *, const void *));
552 static int nfunc PARAMS ((const void *, const void *));
553 static void remove_null_names PARAMS ((export_type **));
554 static void dtab PARAMS ((export_type **));
555 static void process_duplicates PARAMS ((export_type **));
556 static void fill_ordinals PARAMS ((export_type **));
557 static int alphafunc PARAMS ((const void *, const void *));
558 static void mangle_defs PARAMS ((void));
559 static void usage PARAMS ((FILE *, int));
560 static void display PARAMS ((const char *, va_list));
561 static void inform PARAMS ((const char *, ...));
562 static void warn PARAMS ((const char *, ...));
565 display (message, args)
566 const char * message;
569 if (program_name != NULL)
570 fprintf (stderr, "%s: ", program_name);
572 vfprintf (stderr, message, args);
574 if (message [strlen (message) - 1] != '\n')
575 fputc ('\n', stderr);
581 inform (const char * message, ...)
583 inform (message, va_alist)
584 const char * message;
594 va_start (args, message);
599 display (message, args);
606 warn (const char * message, ...)
608 warn (message, va_alist)
609 const char * message;
616 va_start (args, message);
621 display (message, args);
639 /* xgettext:c-format */
640 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
659 /* xgettext:c-format */
660 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
680 /* xgettext:c-format */
681 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
687 #define ASM_BYTE mtable[machine].how_byte
688 #define ASM_SHORT mtable[machine].how_short
689 #define ASM_LONG mtable[machine].how_long
690 #define ASM_TEXT mtable[machine].how_asciz
691 #define ASM_C mtable[machine].how_comment
692 #define ASM_JUMP mtable[machine].how_jump
693 #define ASM_GLOBAL mtable[machine].how_global
694 #define ASM_SPACE mtable[machine].how_space
695 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
696 #define ASM_RVA_BEFORE rvabefore(machine)
697 #define ASM_RVA_AFTER rvaafter(machine)
698 #define ASM_PREFIX asm_prefix(machine)
699 #define ASM_ALIGN_LONG mtable[machine].how_align_long
700 #define HOW_BFD_TARGET 0 /* always default*/
701 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
702 #define HOW_JTAB mtable[machine].how_jtab
703 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
704 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
708 process_def_file (name)
711 FILE *f = fopen (name, FOPEN_RT);
714 /* xgettext:c-format */
715 fatal (_("Can't open def file: %s"), name);
719 /* xgettext:c-format */
720 inform (_("Processing def file: %s"), name);
724 inform (_("Processed def file"));
727 /**********************************************************************/
729 /* Communications with the parser */
731 static const char *d_name; /* Arg to NAME or LIBRARY */
732 static int d_nfuncs; /* Number of functions exported */
733 static int d_named_nfuncs; /* Number of named functions exported */
734 static int d_low_ord; /* Lowest ordinal index */
735 static int d_high_ord; /* Highest ordinal index */
736 static export_type *d_exports; /*list of exported functions */
737 static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
738 static dlist_type *d_list; /* Descriptions */
739 static dlist_type *a_list; /* Stuff to go in directives */
748 /* xgettext:c-format */
749 warn (_("Syntax error in def file %s:%d\n"), def_file, linenumber);
755 def_exports (name, internal_name, ordinal, noname, constant, data)
757 const char *internal_name;
763 struct export *p = (struct export *) xmalloc (sizeof (*p));
766 p->internal_name = internal_name ? internal_name : name;
767 p->ordinal = ordinal;
768 p->constant = constant;
777 def_name (name, base)
781 /* xgettext:c-format */
782 inform (_("NAME: %s base: %x"), name, base);
785 warn (_("Can't have LIBRARY and NAME\n"));
788 /* if --dllname not provided, use the one in the DEF file.
789 FIXME: Is this appropriate for executables? */
791 dll_name = xstrdup (name);
796 def_library (name, base)
800 /* xgettext:c-format */
801 inform (_("LIBRARY: %s base: %x"), name, base);
804 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name);
807 /* if --dllname not provided, use the one in the DEF file. */
809 dll_name = xstrdup (name);
814 def_description (desc)
817 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
818 d->text = xstrdup (desc);
827 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
828 d->text = xstrdup (dir);
834 def_heapsize (reserve, commit)
840 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
842 sprintf (b, "-heap 0x%x ", reserve);
843 new_directive (xstrdup (b));
847 def_stacksize (reserve, commit)
853 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
855 sprintf (b, "-stack 0x%x ", reserve);
856 new_directive (xstrdup (b));
859 /* append_import simply adds the given import definition to the global
860 import_list. It is used by def_import. */
863 append_import (symbol_name, dll_name, func_ordinal)
864 const char *symbol_name;
865 const char *dll_name;
871 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
873 if (strcmp ((*pq)->dllname, dll_name) == 0)
876 q->functail->next = xmalloc (sizeof (ifunctype));
877 q->functail = q->functail->next;
878 q->functail->ord = func_ordinal;
879 q->functail->name = xstrdup (symbol_name);
880 q->functail->next = NULL;
886 q = xmalloc (sizeof (iheadtype));
887 q->dllname = xstrdup (dll_name);
889 q->funchead = xmalloc (sizeof (ifunctype));
890 q->functail = q->funchead;
892 q->functail->name = xstrdup (symbol_name);
893 q->functail->ord = func_ordinal;
894 q->functail->next = NULL;
899 /* def_import is called from within defparse.y when an IMPORT
900 declaration is encountered. Depending on the form of the
901 declaration, the module name may or may not need ".dll" to be
902 appended to it, the name of the function may be stored in internal
903 or entry, and there may or may not be an ordinal value associated
906 /* A note regarding the parse modes:
907 In defparse.y we have to accept import declarations which follow
908 any one of the following forms:
909 <func_name_in_app> = <dll_name>.<func_name_in_dll>
910 <func_name_in_app> = <dll_name>.<number>
911 <dll_name>.<func_name_in_dll>
913 Furthermore, the dll's name may or may not end with ".dll", which
914 complicates the parsing a little. Normally the dll's name is
915 passed to def_import() in the "module" parameter, but when it ends
916 with ".dll" it gets passed in "module" sans ".dll" and that needs
919 def_import gets five parameters:
920 APP_NAME - the name of the function in the application, if
921 present, or NULL if not present.
922 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
923 DLLEXT - the extension of the dll, if present, NULL if not present.
924 ENTRY - the name of the function in the dll, if present, or NULL.
925 ORD_VAL - the numerical tag of the function in the dll, if present,
926 or NULL. Exactly one of <entry> or <ord_val> must be
927 present (i.e., not NULL). */
930 def_import (app_name, module, dllext, entry, ord_val)
931 const char *app_name;
937 const char *application_name;
941 application_name = entry;
944 if (app_name != NULL)
945 application_name = app_name;
947 application_name = "";
952 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
953 sprintf (buf, "%s.%s", module, dllext);
957 append_import (application_name, module, ord_val);
961 def_version (major, minor)
965 printf ("VERSION %d.%d\n", major, minor);
969 def_section (name, attr)
986 sprintf (buf, "-attr %s %s", name, atts);
987 new_directive (xstrdup (buf));
995 def_section ("CODE", attr);
1002 def_section ("DATA", attr);
1005 /**********************************************************************/
1013 int pid, wait_status;
1016 char *errmsg_fmt, *errmsg_arg;
1017 char *temp_base = choose_temp_base ();
1019 inform ("run: %s %s\n", what, args);
1021 /* Count the args */
1023 for (s = args; *s; s++)
1027 argv = alloca (sizeof (char *) * (i + 3));
1036 while (*s != ' ' && *s != 0)
1044 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1045 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1049 inform (strerror (errno));
1051 fatal (errmsg_fmt, errmsg_arg);
1054 pid = pwait (pid, & wait_status, 0);
1058 /* xgettext:c-format */
1059 fatal (_("wait: %s"), strerror (errno));
1061 else if (WIFSIGNALED (wait_status))
1063 /* xgettext:c-format */
1064 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1066 else if (WIFEXITED (wait_status))
1068 if (WEXITSTATUS (wait_status) != 0)
1069 /* xgettext:c-format */
1070 warn (_("%s exited with status %d\n"),
1071 what, WEXITSTATUS (wait_status));
1077 /* Look for a list of symbols to export in the .drectve section of
1078 ABFD. Pass each one to def_exports. */
1081 scan_drectve_symbols (abfd)
1090 /* Look for .drectve's */
1091 s = bfd_get_section_by_name (abfd, ".drectve");
1096 size = bfd_get_section_size_before_reloc (s);
1097 buf = xmalloc (size);
1099 bfd_get_section_contents (abfd, s, buf, 0, size);
1101 /* xgettext:c-format */
1102 inform (_("Sucking in info from .drective section in %s\n"),
1103 bfd_get_filename (abfd));
1105 /* Search for -export: strings */
1111 && strncmp (p, "-export:", 8) == 0)
1118 while (p < e && *p != ' ' && *p != '-')
1120 c = xmalloc (p - name + 1);
1121 memcpy (c, name, p - name);
1124 /* FIXME: The 5th arg is for the `constant' field.
1125 What should it be? Not that it matters since it's not
1126 currently useful. */
1127 def_exports (c, 0, -1, 0, 0, 0);
1129 if (add_stdcall_alias && strchr (c, '@'))
1131 char *exported_name = xstrdup (c);
1132 char *atsym = strchr (exported_name, '@');
1134 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0);
1143 /* Look through the symbols in MINISYMS, and add each one to list of
1144 symbols to export. */
1147 scan_filtered_symbols (abfd, minisyms, symcount, size)
1154 bfd_byte *from, *fromend;
1156 store = bfd_make_empty_symbol (abfd);
1158 bfd_fatal (bfd_get_filename (abfd));
1160 from = (bfd_byte *) minisyms;
1161 fromend = from + symcount * size;
1162 for (; from < fromend; from += size)
1165 const char *symbol_name;
1167 sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
1169 bfd_fatal (bfd_get_filename (abfd));
1171 symbol_name = bfd_asymbol_name (sym);
1172 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1175 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0);
1177 if (add_stdcall_alias && strchr (symbol_name, '@'))
1179 char *exported_name = xstrdup (symbol_name);
1180 char *atsym = strchr (exported_name, '@');
1182 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0);
1187 /* Add a list of symbols to exclude. */
1190 add_excludes (new_excludes)
1191 const char *new_excludes;
1194 char *exclude_string;
1196 local_copy = xstrdup (new_excludes);
1198 exclude_string = strtok (local_copy, ",:");
1199 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1201 struct string_list *new_exclude;
1203 new_exclude = ((struct string_list *)
1204 xmalloc (sizeof (struct string_list)));
1205 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1206 /* FIXME: Is it always right to add a leading underscore? */
1207 sprintf (new_exclude->string, "_%s", exclude_string);
1208 new_exclude->next = excludes;
1209 excludes = new_exclude;
1211 /* xgettext:c-format */
1212 inform (_("Excluding symbol: %s\n"), exclude_string);
1218 /* See if STRING is on the list of symbols to exclude. */
1221 match_exclude (string)
1224 struct string_list *excl_item;
1226 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1227 if (strcmp (string, excl_item->string) == 0)
1232 /* Add the default list of symbols to exclude. */
1235 set_default_excludes (void)
1237 add_excludes (default_excludes);
1240 /* Choose which symbols to export. */
1243 filter_symbols (abfd, minisyms, symcount, size)
1249 bfd_byte *from, *fromend, *to;
1252 store = bfd_make_empty_symbol (abfd);
1254 bfd_fatal (bfd_get_filename (abfd));
1256 from = (bfd_byte *) minisyms;
1257 fromend = from + symcount * size;
1258 to = (bfd_byte *) minisyms;
1260 for (; from < fromend; from += size)
1265 sym = bfd_minisymbol_to_symbol (abfd, false, (const PTR) from, store);
1267 bfd_fatal (bfd_get_filename (abfd));
1269 /* Check for external and defined only symbols. */
1270 keep = (((sym->flags & BSF_GLOBAL) != 0
1271 || (sym->flags & BSF_WEAK) != 0
1272 || bfd_is_com_section (sym->section))
1273 && ! bfd_is_und_section (sym->section));
1275 keep = keep && ! match_exclude (sym->name);
1279 memcpy (to, from, size);
1284 return (to - (bfd_byte *) minisyms) / size;
1287 /* Export all symbols in ABFD, except for ones we were told not to
1291 scan_all_symbols (abfd)
1298 /* Ignore bfds with an import descriptor table. We assume that any
1299 such BFD contains symbols which are exported from another DLL,
1300 and we don't want to reexport them from here. */
1301 if (bfd_get_section_by_name (abfd, ".idata$4"))
1304 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1306 /* xgettext:c-format */
1307 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1311 symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
1313 bfd_fatal (bfd_get_filename (abfd));
1317 /* xgettext:c-format */
1318 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1322 /* Discard the symbols we don't want to export. It's OK to do this
1323 in place; we'll free the storage anyway. */
1325 symcount = filter_symbols (abfd, minisyms, symcount, size);
1326 scan_filtered_symbols (abfd, minisyms, symcount, size);
1331 /* Look at the object file to decide which symbols to export. */
1334 scan_open_obj_file (abfd)
1337 if (export_all_symbols)
1338 scan_all_symbols (abfd);
1340 scan_drectve_symbols (abfd);
1342 /* FIXME: we ought to read in and block out the base relocations */
1344 /* xgettext:c-format */
1345 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
1349 scan_obj_file (filename)
1350 const char *filename;
1352 bfd * f = bfd_openr (filename, 0);
1355 /* xgettext:c-format */
1356 fatal (_("Unable to open object file: %s"), filename);
1358 /* xgettext:c-format */
1359 inform (_("Scanning object file %s"), filename);
1361 if (bfd_check_format (f, bfd_archive))
1363 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1366 if (bfd_check_format (arfile, bfd_object))
1367 scan_open_obj_file (arfile);
1369 arfile = bfd_openr_next_archived_file (f, arfile);
1372 else if (bfd_check_format (f, bfd_object))
1374 scan_open_obj_file (f);
1380 /**********************************************************************/
1388 fprintf (f, "%s ", ASM_C);
1389 for (i = 0; oav[i]; i++)
1390 fprintf (f, "%s ", oav[i]);
1392 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1394 fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
1400 exp->noname ? "NONAME " : "",
1401 exp->constant ? "CONSTANT" : "",
1402 exp->data ? "DATA" : "");
1406 /* Generate the .exp file */
1413 return *(const long *) a - *(const long *) b;
1417 flush_page (f, need, page_addr, on_page)
1425 /* Flush this page */
1426 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1430 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1432 (on_page * 2) + (on_page & 1) * 2 + 8,
1434 for (i = 0; i < on_page; i++)
1436 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
1440 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1449 inform (_("Adding exports to output file"));
1451 fprintf (output_def, ";");
1452 for (i = 0; oav[i]; i++)
1453 fprintf (output_def, " %s", oav[i]);
1455 fprintf (output_def, "\nEXPORTS\n");
1457 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1459 char *quote = strchr (exp->name, '.') ? "\"" : "";
1460 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1462 if (strcmp (exp->name, exp->internal_name) == 0)
1465 fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
1470 exp->noname ? " NONAME" : "",
1471 exp->data ? " DATA" : "",
1476 char *quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1478 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1486 exp->noname ? " NONAME" : "",
1487 exp->data ? " DATA" : "",
1494 inform (_("Added exports to output file"));
1497 /* generate_idata_ofile generates the portable assembly source code
1498 for the idata sections. It appends the source code to the end of
1502 generate_idata_ofile (filvar)
1511 if (import_list == NULL)
1514 fprintf (filvar, "%s Import data sections\n", ASM_C);
1515 fprintf (filvar, "\n\t.section\t.idata$2\n");
1516 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1517 fprintf (filvar, "doi_idata:\n");
1520 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1522 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1523 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1524 ASM_C, headptr->dllname);
1525 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1526 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1527 fprintf (filvar, "\t%sdllname%d%s\n",
1528 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1529 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1530 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1534 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1535 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1536 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1537 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1538 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1540 fprintf (filvar, "\n\t.section\t.idata$4\n");
1542 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1544 fprintf (filvar, "listone%d:\n", headindex);
1545 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1546 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1547 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1548 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1552 fprintf (filvar, "\n\t.section\t.idata$5\n");
1554 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1556 fprintf (filvar, "listtwo%d:\n", headindex);
1557 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1558 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1559 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1560 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1564 fprintf (filvar, "\n\t.section\t.idata$6\n");
1566 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1569 for (funcptr = headptr->funchead; funcptr != NULL;
1570 funcptr = funcptr->next)
1572 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1573 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1574 ((funcptr->ord) & 0xFFFF));
1575 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1576 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1582 fprintf (filvar, "\n\t.section\t.idata$7\n");
1584 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1586 fprintf (filvar,"dllname%d:\n", headindex);
1587 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1588 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1601 /* xgettext:c-format */
1602 inform (_("Generating export file: %s\n"), exp_name);
1604 f = fopen (TMP_ASM, FOPEN_WT);
1606 /* xgettext:c-format */
1607 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1609 /* xgettext:c-format */
1610 inform (_("Opened temporary file: %s"), TMP_ASM);
1616 fprintf (f, "\t.section .edata\n\n");
1617 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1618 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
1620 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1621 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1622 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1625 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1626 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1628 d_named_nfuncs, d_low_ord, d_high_ord);
1629 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1630 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1631 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1633 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1634 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1636 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1638 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1641 fprintf(f,"%s Export address Table\n", ASM_C);
1642 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1643 fprintf (f, "afuncs:\n");
1646 for (exp = d_exports; exp; exp = exp->next)
1648 if (exp->ordinal != i)
1651 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1653 (exp->ordinal - i) * 4,
1655 i, exp->ordinal - 1);
1658 while (i < exp->ordinal)
1660 fprintf(f,"\t%s\t0\n", ASM_LONG);
1664 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1666 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1670 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1671 fprintf (f, "anames:\n");
1673 for (i = 0; (exp = d_exports_lexically[i]); i++)
1675 if (!exp->noname || show_allnames)
1676 fprintf (f, "\t%sn%d%s\n",
1677 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1680 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1681 fprintf (f, "anords:\n");
1682 for (i = 0; (exp = d_exports_lexically[i]); i++)
1684 if (!exp->noname || show_allnames)
1685 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1688 fprintf(f,"%s Export Name Table\n", ASM_C);
1689 for (i = 0; (exp = d_exports_lexically[i]); i++)
1690 if (!exp->noname || show_allnames)
1691 fprintf (f, "n%d: %s \"%s\"\n",
1692 exp->ordinal, ASM_TEXT, exp->name);
1696 fprintf (f, "\t.section .drectve\n");
1697 for (dl = a_list; dl; dl = dl->next)
1699 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1704 fprintf (f, "\t.section .rdata\n");
1705 for (dl = d_list; dl; dl = dl->next)
1709 /* We dont output as ascii 'cause there can
1710 be quote characters in the string */
1713 for (p = dl->text; *p; p++)
1716 fprintf (f, "\t%s\t", ASM_BYTE);
1719 fprintf (f, "%d", *p);
1722 fprintf (f, ",0\n");
1736 /* Add to the output file a way of getting to the exported names
1737 without using the import library. */
1740 fprintf (f, "\t.section\t.rdata\n");
1741 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1742 if (!exp->noname || show_allnames)
1744 /* We use a single underscore for MS compatibility, and a
1745 double underscore for backward compatibility with old
1747 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1748 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1749 fprintf (f, "__imp_%s:\n", exp->name);
1750 fprintf (f, "_imp__%s:\n", exp->name);
1751 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1755 /* Dump the reloc section if a base file is provided */
1759 long need[PAGE_SIZE];
1766 fprintf (f, "\t.section\t.init\n");
1767 fprintf (f, "lab:\n");
1769 fseek (base_file, 0, SEEK_END);
1770 numbytes = ftell (base_file);
1771 fseek (base_file, 0, SEEK_SET);
1772 copy = xmalloc (numbytes);
1773 fread (copy, 1, numbytes, base_file);
1774 num_entries = numbytes / sizeof (long);
1777 fprintf (f, "\t.section\t.reloc\n");
1785 qsort (copy, num_entries, sizeof (long), sfunc);
1786 /* Delete duplcates */
1787 for (src = 0; src < num_entries; src++)
1789 if (last != copy[src])
1790 last = copy[dst++] = copy[src];
1794 page_addr = addr & PAGE_MASK; /* work out the page addr */
1796 for (j = 0; j < num_entries; j++)
1800 if ((addr & PAGE_MASK) != page_addr)
1802 totsize += 8 + (on_page & 1)*2;
1803 flush_page (f, need, page_addr, on_page);
1805 page_addr = addr & PAGE_MASK;
1807 need[on_page++] = addr;
1810 /* Pad the section to an even 32-byte boundary. This will make
1811 the BeOS loader much happier, and shouldn't matter for other
1813 while ((totsize + 8 + (on_page & 1)*2) % 32 != 0)
1815 /* 0x0000 is an absolute relocation that should be ignored. */
1816 need[on_page++] = 0x0000;
1820 flush_page (f, need, page_addr, on_page);
1822 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1826 generate_idata_ofile (f);
1830 /* assemble the file */
1831 sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
1834 if (machine == MARM_INTERWORK || machine == MTHUMB)
1835 strcat (outfile, " -mthumb-interwork");
1838 run (as_name, outfile);
1840 if (dontdeltemps == 0)
1843 inform (_("Generated exports file"));
1852 char *copy = xmalloc (strlen (name) + 2);
1854 strcpy (copy + 1, name);
1861 p = strchr (name, '@');
1868 /**********************************************************************/
1877 if (exp->noname && !show_allnames )
1879 fprintf (f, "\t%s\t0x%08x\n",
1881 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1885 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1903 unsigned char *data;
1918 static sinfo secdata[NSECS] =
1920 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
1921 { DATA, ".data", SEC_DATA, 2},
1922 { BSS, ".bss", 0, 2},
1923 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1924 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1925 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1926 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1931 /* Sections numbered to make the order the same as other PowerPC NT */
1932 /* compilers. This also keeps funny alignment thingies from happening. */
1945 static sinfo secdata[NSECS] =
1947 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1948 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
1949 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
1950 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1951 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1952 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1953 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1954 { DATA, ".data", SEC_DATA, 2},
1955 { BSS, ".bss", 0, 2}
1961 This is what we're trying to make. We generate the imp symbols with
1962 both single and double underscores, for compatibility.
1965 .global _GetFileVersionInfoSizeW@8
1966 .global __imp_GetFileVersionInfoSizeW@8
1967 _GetFileVersionInfoSizeW@8:
1968 jmp * __imp_GetFileVersionInfoSizeW@8
1969 .section .idata$7 # To force loading of head
1970 .long __version_a_head
1971 # Import Address Table
1973 __imp_GetFileVersionInfoSizeW@8:
1976 # Import Lookup Table
1982 .asciz "GetFileVersionInfoSizeW"
1985 For the PowerPC, here's the variation on the above scheme:
1987 # Rather than a simple "jmp *", the code to get to the dll function
1990 lwz r11,[tocv]__imp_function_name(r2)
1991 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2000 make_label (prefix, name)
2004 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
2005 char *copy = xmalloc (len +1 );
2006 strcpy (copy, ASM_PREFIX);
2007 strcat (copy, prefix);
2008 strcat (copy, name);
2013 make_one_lib_file (exp, i)
2021 sprintf (outfile, "%ss%05d.s", prefix, i);
2022 f = fopen (outfile, FOPEN_WT);
2023 fprintf (f, "\t.text\n");
2024 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
2025 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2026 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
2027 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
2028 exp->name, ASM_JUMP, exp->name);
2030 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
2031 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
2034 fprintf (f,"%s Import Address Table\n", ASM_C);
2036 fprintf (f, "\t.section .idata$5\n");
2037 fprintf (f, "__imp_%s:\n", exp->name);
2038 fprintf (f, "_imp__%s:\n", exp->name);
2042 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
2043 fprintf (f, "\t.section .idata$4\n");
2047 if(!exp->noname || show_allnames)
2049 fprintf (f, "%s Hint/Name table\n", ASM_C);
2050 fprintf (f, "\t.section .idata$6\n");
2051 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
2052 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
2057 sprintf (outfile, "%s -o %ss%05d.o %ss%d.s",
2058 as_flags, prefix, i, prefix, i);
2061 if (machine == MARM_INTERWORK || machine == MTHUMB)
2062 strcat (outfile, " -mthumb-interwork");
2065 run (as_name, outfile);
2070 asymbol * exp_label;
2073 asymbol * iname_lab;
2074 asymbol ** iname_lab_pp;
2075 asymbol ** iname_pp;
2084 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2086 char * outname = xmalloc (10);
2090 sprintf (outname, "%s%05d.o", TMP_STUB, i);
2092 abfd = bfd_openw (outname, HOW_BFD_TARGET);
2095 /* xgettext:c-format */
2096 fatal (_("bfd_open failed open stub file: %s"), outname);
2098 /* xgettext:c-format */
2099 inform (_("Creating stub file: %s"), outname);
2101 bfd_set_format (abfd, bfd_object);
2102 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2105 if (machine == MARM_INTERWORK || machine == MTHUMB)
2106 bfd_set_private_flags (abfd, F_INTERWORK);
2109 /* First make symbols for the sections */
2110 for (i = 0; i < NSECS; i++)
2112 sinfo *si = secdata + i;
2115 si->sec = bfd_make_section_old_way (abfd, si->name);
2116 bfd_set_section_flags (abfd,
2120 bfd_set_section_alignment(abfd, si->sec, si->align);
2121 si->sec->output_section = si->sec;
2122 si->sym = bfd_make_empty_symbol(abfd);
2123 si->sym->name = si->sec->name;
2124 si->sym->section = si->sec;
2125 si->sym->flags = BSF_LOCAL;
2127 ptrs[oidx] = si->sym;
2128 si->sympp = ptrs + oidx;
2137 exp_label = bfd_make_empty_symbol (abfd);
2138 exp_label->name = make_label ("", exp->name);
2140 /* On PowerPC, the function name points to a descriptor in
2141 the rdata section, the first element of which is a
2142 pointer to the code (..function_name), and the second
2143 points to the .toc */
2145 if (machine == MPPC)
2146 exp_label->section = secdata[RDATA].sec;
2149 exp_label->section = secdata[TEXT].sec;
2151 exp_label->flags = BSF_GLOBAL;
2152 exp_label->value = 0;
2155 if (machine == MTHUMB)
2156 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2158 ptrs[oidx++] = exp_label;
2161 /* Generate imp symbols with one underscore for Microsoft
2162 compatibility, and with two underscores for backward
2163 compatibility with old versions of cygwin. */
2164 iname = bfd_make_empty_symbol(abfd);
2165 iname->name = make_label ("__imp_", exp->name);
2166 iname->section = secdata[IDATA5].sec;
2167 iname->flags = BSF_GLOBAL;
2170 iname2 = bfd_make_empty_symbol(abfd);
2171 iname2->name = make_label ("_imp__", exp->name);
2172 iname2->section = secdata[IDATA5].sec;
2173 iname2->flags = BSF_GLOBAL;
2176 iname_lab = bfd_make_empty_symbol(abfd);
2178 iname_lab->name = head_label;
2179 iname_lab->section = (asection *)&bfd_und_section;
2180 iname_lab->flags = 0;
2181 iname_lab->value = 0;
2184 iname_pp = ptrs + oidx;
2185 ptrs[oidx++] = iname;
2186 ptrs[oidx++] = iname2;
2188 iname_lab_pp = ptrs + oidx;
2189 ptrs[oidx++] = iname_lab;
2192 /* The symbol refering to the code (.text) */
2194 asymbol *function_name;
2196 function_name = bfd_make_empty_symbol(abfd);
2197 function_name->name = make_label ("..", exp->name);
2198 function_name->section = secdata[TEXT].sec;
2199 function_name->flags = BSF_GLOBAL;
2200 function_name->value = 0;
2202 fn_pp = ptrs + oidx;
2203 ptrs[oidx++] = function_name;
2206 /* The .toc symbol */
2208 asymbol *toc_symbol; /* The .toc symbol */
2210 toc_symbol = bfd_make_empty_symbol (abfd);
2211 toc_symbol->name = make_label (".", "toc");
2212 toc_symbol->section = (asection *)&bfd_und_section;
2213 toc_symbol->flags = BSF_GLOBAL;
2214 toc_symbol->value = 0;
2216 toc_pp = ptrs + oidx;
2217 ptrs[oidx++] = toc_symbol;
2223 for (i = 0; i < NSECS; i++)
2225 sinfo *si = secdata + i;
2226 asection *sec = si->sec;
2235 si->size = HOW_JTAB_SIZE;
2236 si->data = xmalloc (HOW_JTAB_SIZE);
2237 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2239 /* add the reloc into idata$5 */
2240 rel = xmalloc (sizeof (arelent));
2242 rpp = xmalloc (sizeof (arelent *) * 2);
2246 rel->address = HOW_JTAB_ROFF;
2249 if (machine == MPPC)
2251 rel->howto = bfd_reloc_type_lookup (abfd,
2252 BFD_RELOC_16_GOTOFF);
2253 rel->sym_ptr_ptr = iname_pp;
2257 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2258 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2260 sec->orelocation = rpp;
2261 sec->reloc_count = 1;
2266 /* An idata$4 or idata$5 is one word long, and has an
2269 si->data = xmalloc (4);
2274 si->data[0] = exp->ordinal ;
2275 si->data[1] = exp->ordinal >> 8;
2276 si->data[2] = exp->ordinal >> 16;
2281 sec->reloc_count = 1;
2282 memset (si->data, 0, si->size);
2283 rel = xmalloc (sizeof (arelent));
2284 rpp = xmalloc (sizeof (arelent *) * 2);
2289 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2290 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2291 sec->orelocation = rpp;
2299 /* This used to add 1 to exp->hint. I don't know
2300 why it did that, and it does not match what I see
2301 in programs compiled with the MS tools. */
2302 int idx = exp->hint;
2303 si->size = strlen (xlate (exp->name)) + 3;
2304 si->data = xmalloc (si->size);
2305 si->data[0] = idx & 0xff;
2306 si->data[1] = idx >> 8;
2307 strcpy (si->data + 2, xlate (exp->name));
2312 si->data =xmalloc(4);
2313 memset (si->data, 0, si->size);
2314 rel = xmalloc (sizeof (arelent));
2315 rpp = xmalloc (sizeof (arelent *) * 2);
2319 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2320 rel->sym_ptr_ptr = iname_lab_pp;
2321 sec->orelocation = rpp;
2322 sec->reloc_count = 1;
2328 /* The .pdata section is 5 words long. */
2329 /* Think of it as: */
2332 /* bfd_vma BeginAddress, [0x00] */
2333 /* EndAddress, [0x04] */
2334 /* ExceptionHandler, [0x08] */
2335 /* HandlerData, [0x0c] */
2336 /* PrologEndAddress; [0x10] */
2339 /* So this pdata section setups up this as a glue linkage to
2340 a dll routine. There are a number of house keeping things
2343 1. In the name of glue trickery, the ADDR32 relocs for 0,
2344 4, and 0x10 are set to point to the same place:
2346 2. There is one more reloc needed in the pdata section.
2347 The actual glue instruction to restore the toc on
2348 return is saved as the offset in an IMGLUE reloc.
2349 So we need a total of four relocs for this section.
2351 3. Lastly, the HandlerData field is set to 0x03, to indicate
2352 that this is a glue routine.
2354 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2356 /* alignment must be set to 2**2 or you get extra stuff */
2357 bfd_set_section_alignment(abfd, sec, 2);
2360 si->data =xmalloc(4 * 5);
2361 memset (si->data, 0, si->size);
2362 rpp = xmalloc (sizeof (arelent *) * 5);
2363 rpp[0] = imglue = xmalloc (sizeof (arelent));
2364 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2365 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2366 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2369 /* stick the toc reload instruction in the glue reloc */
2370 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2373 imglue->howto = bfd_reloc_type_lookup (abfd,
2374 BFD_RELOC_32_GOTOFF);
2375 imglue->sym_ptr_ptr = fn_pp;
2377 ba_rel->address = 0;
2379 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2380 ba_rel->sym_ptr_ptr = fn_pp;
2382 bfd_put_32(abfd, 0x18, si->data + 0x04);
2383 ea_rel->address = 4;
2385 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2386 ea_rel->sym_ptr_ptr = fn_pp;
2388 /* mark it as glue */
2389 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2391 /* mark the prolog end address */
2392 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2393 pea_rel->address = 0x10;
2394 pea_rel->addend = 0;
2395 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2396 pea_rel->sym_ptr_ptr = fn_pp;
2398 sec->orelocation = rpp;
2399 sec->reloc_count = 4;
2403 /* Each external function in a PowerPC PE file has a two word
2404 descriptor consisting of:
2405 1. The address of the code.
2406 2. The address of the appropriate .toc
2407 We use relocs to build this.
2411 si->data = xmalloc (8);
2412 memset (si->data, 0, si->size);
2414 rpp = xmalloc (sizeof (arelent *) * 3);
2415 rpp[0] = rel = xmalloc (sizeof (arelent));
2416 rpp[1] = xmalloc (sizeof (arelent));
2421 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2422 rel->sym_ptr_ptr = fn_pp;
2428 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2429 rel->sym_ptr_ptr = toc_pp;
2431 sec->orelocation = rpp;
2432 sec->reloc_count = 2;
2434 #endif /* DLLTOOL_PPC */
2440 /* Size up all the sections */
2441 for (i = 0; i < NSECS; i++)
2443 sinfo *si = secdata + i;
2445 bfd_set_section_size (abfd, si->sec, si->size);
2446 bfd_set_section_vma (abfd, si->sec, vma);
2448 /* vma += si->size;*/
2451 /* Write them out */
2452 for (i = 0; i < NSECS; i++)
2454 sinfo *si = secdata + i;
2456 if (i == IDATA5 && no_idata5)
2459 if (i == IDATA4 && no_idata4)
2462 bfd_set_section_contents (abfd, si->sec,
2467 bfd_set_symtab (abfd, ptrs, oidx);
2469 abfd = bfd_openr (outname, HOW_BFD_TARGET);
2478 FILE * f = fopen (TMP_HEAD_S, FOPEN_WT);
2480 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2481 fprintf (f, "\t.section .idata$2\n");
2483 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2485 fprintf (f, "%s:\n", head_label);
2487 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2488 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2490 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2491 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2492 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2493 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2494 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2499 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2501 ASM_RVA_AFTER, ASM_C);
2503 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2507 fprintf (f, "\t.section\t.idata$5\n");
2508 fprintf (f, "\t%s\t0\n", ASM_LONG);
2509 fprintf (f, "fthunk:\n");
2513 fprintf (f, "\t.section\t.idata$4\n");
2515 fprintf (f, "\t%s\t0\n", ASM_LONG);
2516 fprintf (f, "\t.section .idata$4\n");
2517 fprintf (f, "hname:\n");
2521 sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
2524 if (machine == MARM_INTERWORK || machine == MTHUMB)
2525 strcat (outfile, " -mthumb-interwork");
2528 run (as_name, outfile);
2530 return bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
2536 FILE * f = fopen (TMP_TAIL_S, FOPEN_WT);
2540 fprintf (f, "\t.section .idata$4\n");
2541 fprintf (f, "\t%s\t0\n", ASM_LONG);
2545 fprintf (f, "\t.section .idata$5\n");
2546 fprintf (f, "\t%s\t0\n", ASM_LONG);
2550 /* Normally, we need to see a null descriptor built in idata$3 to
2551 act as the terminator for the list. The ideal way, I suppose,
2552 would be to mark this section as a comdat type 2 section, so
2553 only one would appear in the final .exe (if our linker supported
2554 comdat, that is) or cause it to be inserted by something else (say
2558 fprintf (f, "\t.section .idata$3\n");
2559 fprintf (f, "\t%s\t0\n", ASM_LONG);
2560 fprintf (f, "\t%s\t0\n", ASM_LONG);
2561 fprintf (f, "\t%s\t0\n", ASM_LONG);
2562 fprintf (f, "\t%s\t0\n", ASM_LONG);
2563 fprintf (f, "\t%s\t0\n", ASM_LONG);
2567 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2568 do too. Original, huh? */
2569 fprintf (f, "\t.section .idata$6\n");
2571 fprintf (f, "\t.section .idata$7\n");
2574 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2575 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2576 imp_name_lab, ASM_TEXT, dll_name);
2580 sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
2583 if (machine == MARM_INTERWORK || MTHUMB)
2584 strcat (outfile, " -mthumb-interwork");
2587 run (as_name, outfile);
2589 return bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
2604 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2607 /* xgettext:c-format */
2608 fatal (_("Can't open .lib file: %s"), imp_name);
2610 /* xgettext:c-format */
2611 inform (_("Creating library file: %s\n"), imp_name);
2613 bfd_set_format (outarch, bfd_archive);
2614 outarch->has_armap = 1;
2616 /* Work out a reasonable size of things to put onto one line. */
2618 ar_head = make_head ();
2619 ar_tail = make_tail();
2621 if (ar_head == NULL || ar_tail == NULL)
2624 for (i = 0; (exp = d_exports_lexically[i]); i++)
2626 bfd *n = make_one_lib_file (exp, i);
2631 /* Now stick them all into the archive */
2633 ar_head->next = head;
2634 ar_tail->next = ar_head;
2637 if (! bfd_set_archive_head (outarch, head))
2638 bfd_fatal ("bfd_set_archive_head");
2640 if (! bfd_close (outarch))
2641 bfd_fatal (imp_name);
2643 while (head != NULL)
2645 bfd *n = head->next;
2650 /* Delete all the temp files */
2652 if (dontdeltemps == 0)
2654 unlink (TMP_HEAD_O);
2655 unlink (TMP_HEAD_S);
2656 unlink (TMP_TAIL_O);
2657 unlink (TMP_TAIL_S);
2660 if (dontdeltemps < 2)
2662 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2664 sprintf (outfile, "%s%05d.o", TMP_STUB, i);
2665 if (unlink (outfile) < 0)
2666 /* xgettext:c-format */
2667 warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
2671 inform (_("Created lib file"));
2674 /**********************************************************************/
2676 /* Run through the information gathered from the .o files and the
2677 .def file and work out the best stuff */
2683 export_type *ap = *(export_type **) a;
2684 export_type *bp = *(export_type **) b;
2685 if (ap->ordinal == bp->ordinal)
2688 /* unset ordinals go to the bottom */
2689 if (ap->ordinal == -1)
2691 if (bp->ordinal == -1)
2693 return (ap->ordinal - bp->ordinal);
2701 export_type *ap = *(export_type **) a;
2702 export_type *bp = *(export_type **) b;
2704 return (strcmp (ap->name, bp->name));
2708 remove_null_names (ptr)
2713 for (dst = src = 0; src < d_nfuncs; src++)
2717 ptr[dst] = ptr[src];
2730 for (i = 0; i < d_nfuncs; i++)
2734 printf ("%d %s @ %d %s%s%s\n",
2735 i, ptr[i]->name, ptr[i]->ordinal,
2736 ptr[i]->noname ? "NONAME " : "",
2737 ptr[i]->constant ? "CONSTANT" : "",
2738 ptr[i]->data ? "DATA" : "");
2747 process_duplicates (d_export_vec)
2748 export_type **d_export_vec;
2756 /* Remove duplicates */
2757 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2759 dtab (d_export_vec);
2760 for (i = 0; i < d_nfuncs - 1; i++)
2762 if (strcmp (d_export_vec[i]->name,
2763 d_export_vec[i + 1]->name) == 0)
2766 export_type *a = d_export_vec[i];
2767 export_type *b = d_export_vec[i + 1];
2771 /* xgettext:c-format */
2772 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2773 a->name, a->ordinal, b->ordinal);
2775 if (a->ordinal != -1
2776 && b->ordinal != -1)
2777 /* xgettext:c-format */
2778 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2781 /* Merge attributes */
2782 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2783 b->constant |= a->constant;
2784 b->noname |= a->noname;
2786 d_export_vec[i] = 0;
2789 dtab (d_export_vec);
2790 remove_null_names (d_export_vec);
2791 dtab (d_export_vec);
2796 /* Count the names */
2797 for (i = 0; i < d_nfuncs; i++)
2799 if (!d_export_vec[i]->noname)
2805 fill_ordinals (d_export_vec)
2806 export_type **d_export_vec;
2813 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2815 /* fill in the unset ordinals with ones from our range */
2817 ptr = (char *) xmalloc (size);
2819 memset (ptr, 0, size);
2821 /* Mark in our large vector all the numbers that are taken */
2822 for (i = 0; i < d_nfuncs; i++)
2824 if (d_export_vec[i]->ordinal != -1)
2826 ptr[d_export_vec[i]->ordinal] = 1;
2827 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2829 lowest = d_export_vec[i]->ordinal;
2834 /* Start at 1 for compatibility with MS toolchain. */
2838 /* Now fill in ordinals where the user wants us to choose. */
2839 for (i = 0; i < d_nfuncs; i++)
2841 if (d_export_vec[i]->ordinal == -1)
2845 /* First try within or after any user supplied range. */
2846 for (j = lowest; j < size; j++)
2850 d_export_vec[i]->ordinal = j;
2854 /* Then try before the range. */
2855 for (j = lowest; j >0; j--)
2859 d_export_vec[i]->ordinal = j;
2870 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2872 /* Work out the lowest and highest ordinal numbers. */
2875 if (d_export_vec[0])
2876 d_low_ord = d_export_vec[0]->ordinal;
2877 if (d_export_vec[d_nfuncs-1])
2878 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2887 const export_type **a = (const export_type **) av;
2888 const export_type **b = (const export_type **) bv;
2890 return strcmp ((*a)->name, (*b)->name);
2896 /* First work out the minimum ordinal chosen */
2902 export_type **d_export_vec
2903 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2905 inform (_("Processing definitions"));
2907 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2909 d_export_vec[i] = exp;
2912 process_duplicates (d_export_vec);
2913 fill_ordinals (d_export_vec);
2915 /* Put back the list in the new order */
2917 for (i = d_nfuncs - 1; i >= 0; i--)
2919 d_export_vec[i]->next = d_exports;
2920 d_exports = d_export_vec[i];
2923 /* Build list in alpha order */
2924 d_exports_lexically = (export_type **)
2925 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
2927 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2929 d_exports_lexically[i] = exp;
2931 d_exports_lexically[i] = 0;
2933 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2935 /* Fill exp entries with their hint values */
2937 for (i = 0; i < d_nfuncs; i++)
2939 if (!d_exports_lexically[i]->noname || show_allnames)
2940 d_exports_lexically[i]->hint = hint++;
2943 inform (_("Processed definitions"));
2946 /**********************************************************************/
2949 usage (file, status)
2953 /* xgetext:c-format */
2954 fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
2955 /* xgetext:c-format */
2956 fprintf (file, _(" -m --machine <machine> Create {arm, arm_interwork, i386, ppc, thumb} DLL. [default: %s]\n"), mname);
2957 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
2958 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
2959 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
2960 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
2961 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
2962 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
2963 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
2964 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
2965 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
2966 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
2967 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
2968 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
2969 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
2970 fprintf (file, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
2971 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
2972 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
2973 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
2974 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
2975 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
2976 fprintf (file, _(" -v --verbose Be verbose.\n"));
2977 fprintf (file, _(" -V --version Display the program version.\n"));
2978 fprintf (file, _(" -h --help Display this information.\n"));
2983 #define OPTION_EXPORT_ALL_SYMS 150
2984 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
2985 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
2986 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
2987 #define OPTION_NO_IDATA4 'x'
2988 #define OPTION_NO_IDATA5 'c'
2990 static const struct option long_options[] =
2992 {"no-delete", no_argument, NULL, 'n'},
2993 {"dllname", required_argument, NULL, 'D'},
2994 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2995 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2996 {"output-exp", required_argument, NULL, 'e'},
2997 {"output-def", required_argument, NULL, 'z'},
2998 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
2999 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3000 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3001 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3002 {"output-lib", required_argument, NULL, 'l'},
3003 {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
3004 {"input-def", required_argument, NULL, 'd'},
3005 {"add-underscore", no_argument, NULL, 'U'},
3006 {"kill-at", no_argument, NULL, 'k'},
3007 {"add-stdcall-alias", no_argument, NULL, 'A'},
3008 {"verbose", no_argument, NULL, 'v'},
3009 {"version", no_argument, NULL, 'V'},
3010 {"help", no_argument, NULL, 'h'},
3011 {"machine", required_argument, NULL, 'm'},
3012 {"add-indirect", no_argument, NULL, 'a'},
3013 {"base-file", required_argument, NULL, 'b'},
3014 {"as", required_argument, NULL, 'S'},
3015 {"as-flags", required_argument, NULL, 'f'},
3027 program_name = av[0];
3030 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3031 setlocale (LC_MESSAGES, "");
3033 bindtextdomain (PACKAGE, LOCALEDIR);
3034 textdomain (PACKAGE);
3036 while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkAvVb:Uh?m:d:f:i",
3042 case OPTION_NO_IDATA4:
3045 case OPTION_NO_IDATA5:
3048 case OPTION_EXPORT_ALL_SYMS:
3049 export_all_symbols = true;
3051 case OPTION_NO_EXPORT_ALL_SYMS:
3052 export_all_symbols = false;
3054 case OPTION_EXCLUDE_SYMS:
3055 add_excludes (optarg);
3057 case OPTION_NO_DEFAULT_EXCLUDES:
3058 do_default_excludes = false;
3067 /* ignored for compatibility */
3074 output_def = fopen (optarg, FOPEN_WT);
3095 print_version (program_name);
3099 /* We don't currently define YYDEBUG when building
3111 add_stdcall_alias = 1;
3120 base_file = fopen (optarg, FOPEN_RB);
3123 /* xgettext:c-format */
3124 fatal (_("Unable to open base-file: %s"), optarg);
3133 for (i = 0; mtable[i].type; i++)
3135 if (strcmp (mtable[i].type, mname) == 0)
3139 if (!mtable[i].type)
3140 /* xgettext:c-format */
3141 fatal (_("Machine '%s' not supported"), mname);
3145 if (!dll_name && exp_name)
3147 int len = strlen (exp_name) + 5;
3148 dll_name = xmalloc (len);
3149 strcpy (dll_name, exp_name);
3150 strcat (dll_name, ".dll");
3153 /* Don't use the default exclude list if we're reading only the
3154 symbols in the .drectve section. The default excludes are meant
3155 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3156 if (! export_all_symbols)
3157 do_default_excludes = false;
3159 if (do_default_excludes)
3160 set_default_excludes ();
3163 process_def_file (def_file);
3168 firstarg = av[optind];
3169 scan_obj_file (av[optind]);
3180 /* Make imp_name safe for use as a label. */
3183 imp_name_lab = xstrdup (imp_name);
3184 for (p = imp_name_lab; *p; p++)
3186 if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
3189 head_label = make_label("_head_", imp_name_lab);