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 gcc -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";
361 static const char * mname = "mcore";
364 #ifdef DLLTOOL_MCORE_ELF
365 static const char * mname = "mcore-elf";
366 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
369 #ifndef DRECTVE_SECTION_NAME
370 #define DRECTVE_SECTION_NAME ".drectve"
373 #define PATHMAX 250 /* What's the right name for this ? */
375 #define TMP_ASM "dc.s"
376 #define TMP_HEAD_S "dh.s"
377 #define TMP_HEAD_O "dh.o"
378 #define TMP_TAIL_S "dt.s"
379 #define TMP_TAIL_O "dt.o"
380 #define TMP_STUB "ds"
382 /* This bit of assemly does jmp * .... */
383 static const unsigned char i386_jtab[] =
385 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
388 static const unsigned char arm_jtab[] =
390 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
391 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
395 static const unsigned char arm_interwork_jtab[] =
397 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
398 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
399 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
403 static const unsigned char thumb_jtab[] =
405 0x40, 0xb4, /* push {r6} */
406 0x02, 0x4e, /* ldr r6, [pc, #8] */
407 0x36, 0x68, /* ldr r6, [r6] */
408 0xb4, 0x46, /* mov ip, r6 */
409 0x40, 0xbc, /* pop {r6} */
410 0x60, 0x47, /* bx ip */
414 static const unsigned char mcore_be_jtab[] =
416 0x70, 0x01, /* jmpi 1 */
417 0x12, 0x11, /* nop */
418 0x00, 0x00, 0x00, 0x00 /* <address> */
421 static const unsigned char mcore_le_jtab[] =
423 0x01, 0x70, /* jmpi 1 */
424 0x11, 0x12, /* nop */
425 0x00, 0x00, 0x00, 0x00 /* <address> */
428 /* This is the glue sequence for PowerPC PE. There is a */
429 /* tocrel16-tocdefn reloc against the first instruction. */
430 /* We also need a IMGLUE reloc against the glue function */
431 /* to restore the toc saved by the third instruction in */
433 static const unsigned char ppc_jtab[] =
435 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
436 /* Reloc TOCREL16 __imp_xxx */
437 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
438 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
439 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
440 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
441 0x20, 0x04, 0x80, 0x4E /* bctr */
445 /* the glue instruction, picks up the toc from the stw in */
446 /* the above code: "lwz r2,4(r1)" */
447 static bfd_vma ppc_glue_insn = 0x80410004;
450 /* The outfile array must be big enough to contain a fully
451 qualified path name, plus an arbitary series of command
452 line switches. We hope that PATH_MAX times two will be
454 static char outfile [PATHMAX * 2];
459 const char *how_byte;
460 const char *how_short;
461 const char *how_long;
462 const char *how_asciz;
463 const char *how_comment;
464 const char *how_jump;
465 const char *how_global;
466 const char *how_space;
467 const char *how_align_short;
468 const char *how_align_long;
469 const char *how_bfd_target;
470 enum bfd_architecture how_bfd_arch;
471 const unsigned char *how_jtab;
472 int how_jtab_size; /* size of the jtab entry */
473 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
476 static const struct mac
481 "arm", ".byte", ".short", ".long", ".asciz", "@",
482 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
483 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
484 arm_jtab, sizeof (arm_jtab), 8
489 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
490 i386_jtab, sizeof (i386_jtab), 2
495 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
496 ppc_jtab, sizeof (ppc_jtab), 0
501 "thumb", ".byte", ".short", ".long", ".asciz", "@",
502 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
503 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
504 thumb_jtab, sizeof (thumb_jtab), 12
507 #define MARM_INTERWORK 4
509 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
510 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
511 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
512 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
517 "mcore", ".byte", ".short", ".long", ".asciz", "//",
518 "jmpi\t1\n\tnop\n\t.long",
519 ".global", ".space", ".align\t2",".align\t4","pe-mcore-big", bfd_arch_mcore,
520 mcore_be_jtab, sizeof (mcore_be_jtab), 8
525 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
526 "jmpi\t1\n\tnop\n\t.long",
527 ".global", ".space", ".align\t2",".align\t4","pe-mcore-little", bfd_arch_mcore,
528 mcore_le_jtab, sizeof (mcore_le_jtab), 8
533 "mcore-elf", ".byte", ".short", ".long", ".asciz", "//",
534 "jmpi\t1\n\tnop\n\t.long",
535 ".global", ".space", ".align\t2",".align\t4","elf32-mcore-big", bfd_arch_mcore,
536 mcore_be_jtab, sizeof (mcore_be_jtab), 8
540 #define MMCORE_ELF_LE 8
541 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
542 "jmpi\t1\n\tnop\n\t.long",
543 ".global", ".space", ".align\t2",".align\t4","elf32-mcore-little", bfd_arch_mcore,
544 mcore_le_jtab, sizeof (mcore_le_jtab), 8
557 typedef struct export
560 const char *internal_name;
570 /* A list of symbols which we should not export. */
574 struct string_list *next;
578 static struct string_list *excludes;
580 static const char *rvaafter PARAMS ((int));
581 static const char *rvabefore PARAMS ((int));
582 static const char *asm_prefix PARAMS ((int));
583 static void append_import PARAMS ((const char *, const char *, int));
584 static void run PARAMS ((const char *, char *));
585 static void scan_drectve_symbols PARAMS ((bfd *));
586 static void scan_filtered_symbols PARAMS ((bfd *, PTR, long, unsigned int));
587 static void add_excludes PARAMS ((const char *));
588 static boolean match_exclude PARAMS ((const char *));
589 static void set_default_excludes PARAMS ((void));
590 static long filter_symbols PARAMS ((bfd *, PTR, long, unsigned int));
591 static void scan_all_symbols PARAMS ((bfd *));
592 static void scan_open_obj_file PARAMS ((bfd *));
593 static void scan_obj_file PARAMS ((const char *));
594 static void dump_def_info PARAMS ((FILE *));
595 static int sfunc PARAMS ((const void *, const void *));
596 static void flush_page PARAMS ((FILE *, long *, int, int));
597 static void gen_def_file PARAMS ((void));
598 static void generate_idata_ofile PARAMS ((FILE *));
599 static void gen_exp_file PARAMS ((void));
600 static const char *xlate PARAMS ((const char *));
602 static void dump_iat PARAMS ((FILE *, export_type *));
604 static char *make_label PARAMS ((const char *, const char *));
605 static bfd *make_one_lib_file PARAMS ((export_type *, int));
606 static bfd *make_head PARAMS ((void));
607 static bfd *make_tail PARAMS ((void));
608 static void gen_lib_file PARAMS ((void));
609 static int pfunc PARAMS ((const void *, const void *));
610 static int nfunc PARAMS ((const void *, const void *));
611 static void remove_null_names PARAMS ((export_type **));
612 static void dtab PARAMS ((export_type **));
613 static void process_duplicates PARAMS ((export_type **));
614 static void fill_ordinals PARAMS ((export_type **));
615 static int alphafunc PARAMS ((const void *, const void *));
616 static void mangle_defs PARAMS ((void));
617 static void usage PARAMS ((FILE *, int));
618 static void display PARAMS ((const char *, va_list));
619 static void inform PARAMS ((const char *, ...));
620 static void warn PARAMS ((const char *, ...));
623 display (message, args)
624 const char * message;
627 if (program_name != NULL)
628 fprintf (stderr, "%s: ", program_name);
630 vfprintf (stderr, message, args);
632 if (message [strlen (message) - 1] != '\n')
633 fputc ('\n', stderr);
639 inform (const char * message, ...)
641 inform (message, va_alist)
642 const char * message;
652 va_start (args, message);
657 display (message, args);
664 warn (const char * message, ...)
666 warn (message, va_alist)
667 const char * message;
674 va_start (args, message);
679 display (message, args);
701 /* xgettext:c-format */
702 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
725 /* xgettext:c-format */
726 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
750 /* xgettext:c-format */
751 fatal (_("Internal error: Unknown machine type: %d\n"), machine);
757 #define ASM_BYTE mtable[machine].how_byte
758 #define ASM_SHORT mtable[machine].how_short
759 #define ASM_LONG mtable[machine].how_long
760 #define ASM_TEXT mtable[machine].how_asciz
761 #define ASM_C mtable[machine].how_comment
762 #define ASM_JUMP mtable[machine].how_jump
763 #define ASM_GLOBAL mtable[machine].how_global
764 #define ASM_SPACE mtable[machine].how_space
765 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
766 #define ASM_RVA_BEFORE rvabefore(machine)
767 #define ASM_RVA_AFTER rvaafter(machine)
768 #define ASM_PREFIX asm_prefix(machine)
769 #define ASM_ALIGN_LONG mtable[machine].how_align_long
770 #define HOW_BFD_TARGET 0 /* always default*/
771 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
772 #define HOW_JTAB mtable[machine].how_jtab
773 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
774 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
778 process_def_file (name)
781 FILE *f = fopen (name, FOPEN_RT);
784 /* xgettext:c-format */
785 fatal (_("Can't open def file: %s"), name);
789 /* xgettext:c-format */
790 inform (_("Processing def file: %s"), name);
794 inform (_("Processed def file"));
797 /**********************************************************************/
799 /* Communications with the parser */
801 static const char *d_name; /* Arg to NAME or LIBRARY */
802 static int d_nfuncs; /* Number of functions exported */
803 static int d_named_nfuncs; /* Number of named functions exported */
804 static int d_low_ord; /* Lowest ordinal index */
805 static int d_high_ord; /* Highest ordinal index */
806 static export_type *d_exports; /*list of exported functions */
807 static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
808 static dlist_type *d_list; /* Descriptions */
809 static dlist_type *a_list; /* Stuff to go in directives */
818 /* xgettext:c-format */
819 warn (_("Syntax error in def file %s:%d\n"), def_file, linenumber);
825 def_exports (name, internal_name, ordinal, noname, constant, data)
827 const char *internal_name;
833 struct export *p = (struct export *) xmalloc (sizeof (*p));
836 p->internal_name = internal_name ? internal_name : name;
837 p->ordinal = ordinal;
838 p->constant = constant;
847 def_name (name, base)
851 /* xgettext:c-format */
852 inform (_("NAME: %s base: %x"), name, base);
855 warn (_("Can't have LIBRARY and NAME\n"));
858 /* if --dllname not provided, use the one in the DEF file.
859 FIXME: Is this appropriate for executables? */
861 dll_name = xstrdup (name);
866 def_library (name, base)
870 /* xgettext:c-format */
871 inform (_("LIBRARY: %s base: %x"), name, base);
874 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name);
877 /* if --dllname not provided, use the one in the DEF file. */
879 dll_name = xstrdup (name);
884 def_description (desc)
887 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
888 d->text = xstrdup (desc);
897 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
898 d->text = xstrdup (dir);
904 def_heapsize (reserve, commit)
910 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
912 sprintf (b, "-heap 0x%x ", reserve);
913 new_directive (xstrdup (b));
917 def_stacksize (reserve, commit)
923 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
925 sprintf (b, "-stack 0x%x ", reserve);
926 new_directive (xstrdup (b));
929 /* append_import simply adds the given import definition to the global
930 import_list. It is used by def_import. */
933 append_import (symbol_name, dll_name, func_ordinal)
934 const char *symbol_name;
935 const char *dll_name;
941 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
943 if (strcmp ((*pq)->dllname, dll_name) == 0)
946 q->functail->next = xmalloc (sizeof (ifunctype));
947 q->functail = q->functail->next;
948 q->functail->ord = func_ordinal;
949 q->functail->name = xstrdup (symbol_name);
950 q->functail->next = NULL;
956 q = xmalloc (sizeof (iheadtype));
957 q->dllname = xstrdup (dll_name);
959 q->funchead = xmalloc (sizeof (ifunctype));
960 q->functail = q->funchead;
962 q->functail->name = xstrdup (symbol_name);
963 q->functail->ord = func_ordinal;
964 q->functail->next = NULL;
969 /* def_import is called from within defparse.y when an IMPORT
970 declaration is encountered. Depending on the form of the
971 declaration, the module name may or may not need ".dll" to be
972 appended to it, the name of the function may be stored in internal
973 or entry, and there may or may not be an ordinal value associated
976 /* A note regarding the parse modes:
977 In defparse.y we have to accept import declarations which follow
978 any one of the following forms:
979 <func_name_in_app> = <dll_name>.<func_name_in_dll>
980 <func_name_in_app> = <dll_name>.<number>
981 <dll_name>.<func_name_in_dll>
983 Furthermore, the dll's name may or may not end with ".dll", which
984 complicates the parsing a little. Normally the dll's name is
985 passed to def_import() in the "module" parameter, but when it ends
986 with ".dll" it gets passed in "module" sans ".dll" and that needs
989 def_import gets five parameters:
990 APP_NAME - the name of the function in the application, if
991 present, or NULL if not present.
992 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
993 DLLEXT - the extension of the dll, if present, NULL if not present.
994 ENTRY - the name of the function in the dll, if present, or NULL.
995 ORD_VAL - the numerical tag of the function in the dll, if present,
996 or NULL. Exactly one of <entry> or <ord_val> must be
997 present (i.e., not NULL). */
1000 def_import (app_name, module, dllext, entry, ord_val)
1001 const char *app_name;
1007 const char *application_name;
1011 application_name = entry;
1014 if (app_name != NULL)
1015 application_name = app_name;
1017 application_name = "";
1022 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
1023 sprintf (buf, "%s.%s", module, dllext);
1027 append_import (application_name, module, ord_val);
1031 def_version (major, minor)
1035 printf ("VERSION %d.%d\n", major, minor);
1039 def_section (name, attr)
1056 sprintf (buf, "-attr %s %s", name, atts);
1057 new_directive (xstrdup (buf));
1065 def_section ("CODE", attr);
1072 def_section ("DATA", attr);
1075 /**********************************************************************/
1083 int pid, wait_status;
1086 char *errmsg_fmt, *errmsg_arg;
1087 char *temp_base = choose_temp_base ();
1089 inform ("run: %s %s\n", what, args);
1091 /* Count the args */
1093 for (s = args; *s; s++)
1097 argv = alloca (sizeof (char *) * (i + 3));
1106 while (*s != ' ' && *s != 0)
1114 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1115 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1119 inform (strerror (errno));
1121 fatal (errmsg_fmt, errmsg_arg);
1124 pid = pwait (pid, & wait_status, 0);
1128 /* xgettext:c-format */
1129 fatal (_("wait: %s"), strerror (errno));
1131 else if (WIFSIGNALED (wait_status))
1133 /* xgettext:c-format */
1134 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1136 else if (WIFEXITED (wait_status))
1138 if (WEXITSTATUS (wait_status) != 0)
1139 /* xgettext:c-format */
1140 warn (_("%s exited with status %d\n"),
1141 what, WEXITSTATUS (wait_status));
1147 /* Look for a list of symbols to export in the .drectve section of
1148 ABFD. Pass each one to def_exports. */
1151 scan_drectve_symbols (abfd)
1160 /* Look for .drectve's */
1161 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1166 size = bfd_get_section_size_before_reloc (s);
1167 buf = xmalloc (size);
1169 bfd_get_section_contents (abfd, s, buf, 0, size);
1171 /* xgettext:c-format */
1172 inform (_("Sucking in info from %s section in %s\n"),
1173 DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1175 /* Search for -export: strings */
1181 && strncmp (p, "-export:", 8) == 0)
1188 while (p < e && *p != ' ' && *p != '-')
1190 c = xmalloc (p - name + 1);
1191 memcpy (c, name, p - name);
1194 /* FIXME: The 5th arg is for the `constant' field.
1195 What should it be? Not that it matters since it's not
1196 currently useful. */
1197 def_exports (c, 0, -1, 0, 0, 0);
1199 if (add_stdcall_alias && strchr (c, '@'))
1201 char *exported_name = xstrdup (c);
1202 char *atsym = strchr (exported_name, '@');
1204 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0);
1213 /* Look through the symbols in MINISYMS, and add each one to list of
1214 symbols to export. */
1217 scan_filtered_symbols (abfd, minisyms, symcount, size)
1224 bfd_byte *from, *fromend;
1226 store = bfd_make_empty_symbol (abfd);
1228 bfd_fatal (bfd_get_filename (abfd));
1230 from = (bfd_byte *) minisyms;
1231 fromend = from + symcount * size;
1232 for (; from < fromend; from += size)
1235 const char *symbol_name;
1237 sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
1239 bfd_fatal (bfd_get_filename (abfd));
1241 symbol_name = bfd_asymbol_name (sym);
1242 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1245 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0);
1247 if (add_stdcall_alias && strchr (symbol_name, '@'))
1249 char *exported_name = xstrdup (symbol_name);
1250 char *atsym = strchr (exported_name, '@');
1252 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0);
1257 /* Add a list of symbols to exclude. */
1260 add_excludes (new_excludes)
1261 const char *new_excludes;
1264 char *exclude_string;
1266 local_copy = xstrdup (new_excludes);
1268 exclude_string = strtok (local_copy, ",:");
1269 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1271 struct string_list *new_exclude;
1273 new_exclude = ((struct string_list *)
1274 xmalloc (sizeof (struct string_list)));
1275 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1276 /* FIXME: Is it always right to add a leading underscore? */
1277 sprintf (new_exclude->string, "_%s", exclude_string);
1278 new_exclude->next = excludes;
1279 excludes = new_exclude;
1281 /* xgettext:c-format */
1282 inform (_("Excluding symbol: %s\n"), exclude_string);
1288 /* See if STRING is on the list of symbols to exclude. */
1291 match_exclude (string)
1294 struct string_list *excl_item;
1296 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1297 if (strcmp (string, excl_item->string) == 0)
1302 /* Add the default list of symbols to exclude. */
1305 set_default_excludes (void)
1307 add_excludes (default_excludes);
1310 /* Choose which symbols to export. */
1313 filter_symbols (abfd, minisyms, symcount, size)
1319 bfd_byte *from, *fromend, *to;
1322 store = bfd_make_empty_symbol (abfd);
1324 bfd_fatal (bfd_get_filename (abfd));
1326 from = (bfd_byte *) minisyms;
1327 fromend = from + symcount * size;
1328 to = (bfd_byte *) minisyms;
1330 for (; from < fromend; from += size)
1335 sym = bfd_minisymbol_to_symbol (abfd, false, (const PTR) from, store);
1337 bfd_fatal (bfd_get_filename (abfd));
1339 /* Check for external and defined only symbols. */
1340 keep = (((sym->flags & BSF_GLOBAL) != 0
1341 || (sym->flags & BSF_WEAK) != 0
1342 || bfd_is_com_section (sym->section))
1343 && ! bfd_is_und_section (sym->section));
1345 keep = keep && ! match_exclude (sym->name);
1349 memcpy (to, from, size);
1354 return (to - (bfd_byte *) minisyms) / size;
1357 /* Export all symbols in ABFD, except for ones we were told not to
1361 scan_all_symbols (abfd)
1368 /* Ignore bfds with an import descriptor table. We assume that any
1369 such BFD contains symbols which are exported from another DLL,
1370 and we don't want to reexport them from here. */
1371 if (bfd_get_section_by_name (abfd, ".idata$4"))
1374 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1376 /* xgettext:c-format */
1377 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1381 symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
1383 bfd_fatal (bfd_get_filename (abfd));
1387 /* xgettext:c-format */
1388 warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1392 /* Discard the symbols we don't want to export. It's OK to do this
1393 in place; we'll free the storage anyway. */
1395 symcount = filter_symbols (abfd, minisyms, symcount, size);
1396 scan_filtered_symbols (abfd, minisyms, symcount, size);
1401 /* Look at the object file to decide which symbols to export. */
1404 scan_open_obj_file (abfd)
1407 if (export_all_symbols)
1408 scan_all_symbols (abfd);
1410 scan_drectve_symbols (abfd);
1412 /* FIXME: we ought to read in and block out the base relocations */
1414 /* xgettext:c-format */
1415 inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
1419 scan_obj_file (filename)
1420 const char *filename;
1422 bfd * f = bfd_openr (filename, 0);
1425 /* xgettext:c-format */
1426 fatal (_("Unable to open object file: %s"), filename);
1428 /* xgettext:c-format */
1429 inform (_("Scanning object file %s"), filename);
1431 if (bfd_check_format (f, bfd_archive))
1433 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1436 if (bfd_check_format (arfile, bfd_object))
1437 scan_open_obj_file (arfile);
1439 arfile = bfd_openr_next_archived_file (f, arfile);
1442 else if (bfd_check_format (f, bfd_object))
1444 scan_open_obj_file (f);
1450 /**********************************************************************/
1458 fprintf (f, "%s ", ASM_C);
1459 for (i = 0; oav[i]; i++)
1460 fprintf (f, "%s ", oav[i]);
1462 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1464 fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
1470 exp->noname ? "NONAME " : "",
1471 exp->constant ? "CONSTANT" : "",
1472 exp->data ? "DATA" : "");
1476 /* Generate the .exp file */
1483 return *(const long *) a - *(const long *) b;
1487 flush_page (f, need, page_addr, on_page)
1495 /* Flush this page */
1496 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1500 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1502 (on_page * 2) + (on_page & 1) * 2 + 8,
1504 for (i = 0; i < on_page; i++)
1506 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
1510 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1519 inform (_("Adding exports to output file"));
1521 fprintf (output_def, ";");
1522 for (i = 0; oav[i]; i++)
1523 fprintf (output_def, " %s", oav[i]);
1525 fprintf (output_def, "\nEXPORTS\n");
1527 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1529 char *quote = strchr (exp->name, '.') ? "\"" : "";
1530 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1532 if (strcmp (exp->name, exp->internal_name) == 0)
1535 fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
1540 exp->noname ? " NONAME" : "",
1541 exp->data ? " DATA" : "",
1546 char *quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1548 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1556 exp->noname ? " NONAME" : "",
1557 exp->data ? " DATA" : "",
1564 inform (_("Added exports to output file"));
1567 /* generate_idata_ofile generates the portable assembly source code
1568 for the idata sections. It appends the source code to the end of
1572 generate_idata_ofile (filvar)
1581 if (import_list == NULL)
1584 fprintf (filvar, "%s Import data sections\n", ASM_C);
1585 fprintf (filvar, "\n\t.section\t.idata$2\n");
1586 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1587 fprintf (filvar, "doi_idata:\n");
1590 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1592 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1593 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1594 ASM_C, headptr->dllname);
1595 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1596 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1597 fprintf (filvar, "\t%sdllname%d%s\n",
1598 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1599 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1600 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1604 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1605 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1606 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1607 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1608 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1610 fprintf (filvar, "\n\t.section\t.idata$4\n");
1612 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1614 fprintf (filvar, "listone%d:\n", headindex);
1615 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1616 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1617 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1618 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1622 fprintf (filvar, "\n\t.section\t.idata$5\n");
1624 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1626 fprintf (filvar, "listtwo%d:\n", headindex);
1627 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1628 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1629 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1630 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1634 fprintf (filvar, "\n\t.section\t.idata$6\n");
1636 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1639 for (funcptr = headptr->funchead; funcptr != NULL;
1640 funcptr = funcptr->next)
1642 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1643 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1644 ((funcptr->ord) & 0xFFFF));
1645 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1646 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1652 fprintf (filvar, "\n\t.section\t.idata$7\n");
1654 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1656 fprintf (filvar,"dllname%d:\n", headindex);
1657 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1658 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1671 /* xgettext:c-format */
1672 inform (_("Generating export file: %s\n"), exp_name);
1674 f = fopen (TMP_ASM, FOPEN_WT);
1676 /* xgettext:c-format */
1677 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1679 /* xgettext:c-format */
1680 inform (_("Opened temporary file: %s"), TMP_ASM);
1686 fprintf (f, "\t.section .edata\n\n");
1687 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1688 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
1690 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1691 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1692 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1695 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1696 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1698 d_named_nfuncs, d_low_ord, d_high_ord);
1699 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
1700 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1701 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1703 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1704 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1706 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1708 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
1711 fprintf(f,"%s Export address Table\n", ASM_C);
1712 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1713 fprintf (f, "afuncs:\n");
1716 for (exp = d_exports; exp; exp = exp->next)
1718 if (exp->ordinal != i)
1721 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1723 (exp->ordinal - i) * 4,
1725 i, exp->ordinal - 1);
1728 while (i < exp->ordinal)
1730 fprintf(f,"\t%s\t0\n", ASM_LONG);
1734 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1736 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1740 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1741 fprintf (f, "anames:\n");
1743 for (i = 0; (exp = d_exports_lexically[i]); i++)
1745 if (!exp->noname || show_allnames)
1746 fprintf (f, "\t%sn%d%s\n",
1747 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1750 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1751 fprintf (f, "anords:\n");
1752 for (i = 0; (exp = d_exports_lexically[i]); i++)
1754 if (!exp->noname || show_allnames)
1755 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1758 fprintf(f,"%s Export Name Table\n", ASM_C);
1759 for (i = 0; (exp = d_exports_lexically[i]); i++)
1760 if (!exp->noname || show_allnames)
1761 fprintf (f, "n%d: %s \"%s\"\n",
1762 exp->ordinal, ASM_TEXT, exp->name);
1766 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
1767 for (dl = a_list; dl; dl = dl->next)
1769 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1775 fprintf (f, "\t.section .rdata\n");
1776 for (dl = d_list; dl; dl = dl->next)
1780 /* We dont output as ascii 'cause there can
1781 be quote characters in the string */
1784 for (p = dl->text; *p; p++)
1787 fprintf (f, "\t%s\t", ASM_BYTE);
1790 fprintf (f, "%d", *p);
1793 fprintf (f, ",0\n");
1807 /* Add to the output file a way of getting to the exported names
1808 without using the import library. */
1811 fprintf (f, "\t.section\t.rdata\n");
1812 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1813 if (!exp->noname || show_allnames)
1815 /* We use a single underscore for MS compatibility, and a
1816 double underscore for backward compatibility with old
1818 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1819 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1820 fprintf (f, "__imp_%s:\n", exp->name);
1821 fprintf (f, "_imp__%s:\n", exp->name);
1822 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1826 /* Dump the reloc section if a base file is provided */
1830 long need[PAGE_SIZE];
1837 fprintf (f, "\t.section\t.init\n");
1838 fprintf (f, "lab:\n");
1840 fseek (base_file, 0, SEEK_END);
1841 numbytes = ftell (base_file);
1842 fseek (base_file, 0, SEEK_SET);
1843 copy = xmalloc (numbytes);
1844 fread (copy, 1, numbytes, base_file);
1845 num_entries = numbytes / sizeof (long);
1848 fprintf (f, "\t.section\t.reloc\n");
1856 qsort (copy, num_entries, sizeof (long), sfunc);
1857 /* Delete duplcates */
1858 for (src = 0; src < num_entries; src++)
1860 if (last != copy[src])
1861 last = copy[dst++] = copy[src];
1865 page_addr = addr & PAGE_MASK; /* work out the page addr */
1867 for (j = 0; j < num_entries; j++)
1871 if ((addr & PAGE_MASK) != page_addr)
1873 totsize += 8 + (on_page & 1)*2;
1874 flush_page (f, need, page_addr, on_page);
1876 page_addr = addr & PAGE_MASK;
1878 need[on_page++] = addr;
1881 /* Pad the section to an even 32-byte boundary. This will make
1882 the BeOS loader much happier, and shouldn't matter for other
1884 while ((totsize + 8 + (on_page & 1)*2) % 32 != 0)
1886 /* 0x0000 is an absolute relocation that should be ignored. */
1887 need[on_page++] = 0x0000;
1891 flush_page (f, need, page_addr, on_page);
1893 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1897 generate_idata_ofile (f);
1901 /* assemble the file */
1902 sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
1905 if (machine == MARM_INTERWORK || machine == MTHUMB)
1906 strcat (outfile, " -mthumb-interwork");
1909 run (as_name, outfile);
1911 if (dontdeltemps == 0)
1914 inform (_("Generated exports file"));
1923 char *copy = xmalloc (strlen (name) + 2);
1925 strcpy (copy + 1, name);
1932 p = strchr (name, '@');
1939 /**********************************************************************/
1948 if (exp->noname && !show_allnames )
1950 fprintf (f, "\t%s\t0x%08x\n",
1952 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1956 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1974 unsigned char *data;
1989 static sinfo secdata[NSECS] =
1991 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
1992 { DATA, ".data", SEC_DATA, 2},
1993 { BSS, ".bss", 0, 2},
1994 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1995 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1996 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1997 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
2002 /* Sections numbered to make the order the same as other PowerPC NT */
2003 /* compilers. This also keeps funny alignment thingies from happening. */
2016 static sinfo secdata[NSECS] =
2018 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
2019 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
2020 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
2021 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
2022 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
2023 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
2024 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
2025 { DATA, ".data", SEC_DATA, 2},
2026 { BSS, ".bss", 0, 2}
2032 This is what we're trying to make. We generate the imp symbols with
2033 both single and double underscores, for compatibility.
2036 .global _GetFileVersionInfoSizeW@8
2037 .global __imp_GetFileVersionInfoSizeW@8
2038 _GetFileVersionInfoSizeW@8:
2039 jmp * __imp_GetFileVersionInfoSizeW@8
2040 .section .idata$7 # To force loading of head
2041 .long __version_a_head
2042 # Import Address Table
2044 __imp_GetFileVersionInfoSizeW@8:
2047 # Import Lookup Table
2053 .asciz "GetFileVersionInfoSizeW"
2056 For the PowerPC, here's the variation on the above scheme:
2058 # Rather than a simple "jmp *", the code to get to the dll function
2061 lwz r11,[tocv]__imp_function_name(r2)
2062 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2071 make_label (prefix, name)
2075 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
2076 char *copy = xmalloc (len +1 );
2077 strcpy (copy, ASM_PREFIX);
2078 strcat (copy, prefix);
2079 strcat (copy, name);
2084 make_one_lib_file (exp, i)
2092 sprintf (outfile, "%ss%05d.s", prefix, i);
2093 f = fopen (outfile, FOPEN_WT);
2094 fprintf (f, "\t.text\n");
2095 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
2096 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2097 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
2098 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
2099 exp->name, ASM_JUMP, exp->name);
2101 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
2102 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
2105 fprintf (f,"%s Import Address Table\n", ASM_C);
2107 fprintf (f, "\t.section .idata$5\n");
2108 fprintf (f, "__imp_%s:\n", exp->name);
2109 fprintf (f, "_imp__%s:\n", exp->name);
2113 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
2114 fprintf (f, "\t.section .idata$4\n");
2118 if(!exp->noname || show_allnames)
2120 fprintf (f, "%s Hint/Name table\n", ASM_C);
2121 fprintf (f, "\t.section .idata$6\n");
2122 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
2123 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
2128 sprintf (outfile, "%s -o %ss%05d.o %ss%d.s",
2129 as_flags, prefix, i, prefix, i);
2132 if (machine == MARM_INTERWORK || machine == MTHUMB)
2133 strcat (outfile, " -mthumb-interwork");
2136 run (as_name, outfile);
2141 asymbol * exp_label;
2144 asymbol * iname_lab;
2145 asymbol ** iname_lab_pp;
2146 asymbol ** iname_pp;
2155 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2157 char * outname = xmalloc (10);
2161 sprintf (outname, "%s%05d.o", TMP_STUB, i);
2163 abfd = bfd_openw (outname, HOW_BFD_TARGET);
2166 /* xgettext:c-format */
2167 fatal (_("bfd_open failed open stub file: %s"), outname);
2169 /* xgettext:c-format */
2170 inform (_("Creating stub file: %s"), outname);
2172 bfd_set_format (abfd, bfd_object);
2173 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2176 if (machine == MARM_INTERWORK || machine == MTHUMB)
2177 bfd_set_private_flags (abfd, F_INTERWORK);
2180 /* First make symbols for the sections */
2181 for (i = 0; i < NSECS; i++)
2183 sinfo *si = secdata + i;
2186 si->sec = bfd_make_section_old_way (abfd, si->name);
2187 bfd_set_section_flags (abfd,
2191 bfd_set_section_alignment(abfd, si->sec, si->align);
2192 si->sec->output_section = si->sec;
2193 si->sym = bfd_make_empty_symbol(abfd);
2194 si->sym->name = si->sec->name;
2195 si->sym->section = si->sec;
2196 si->sym->flags = BSF_LOCAL;
2198 ptrs[oidx] = si->sym;
2199 si->sympp = ptrs + oidx;
2208 exp_label = bfd_make_empty_symbol (abfd);
2209 exp_label->name = make_label ("", exp->name);
2211 /* On PowerPC, the function name points to a descriptor in
2212 the rdata section, the first element of which is a
2213 pointer to the code (..function_name), and the second
2214 points to the .toc */
2216 if (machine == MPPC)
2217 exp_label->section = secdata[RDATA].sec;
2220 exp_label->section = secdata[TEXT].sec;
2222 exp_label->flags = BSF_GLOBAL;
2223 exp_label->value = 0;
2226 if (machine == MTHUMB)
2227 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2229 ptrs[oidx++] = exp_label;
2232 /* Generate imp symbols with one underscore for Microsoft
2233 compatibility, and with two underscores for backward
2234 compatibility with old versions of cygwin. */
2235 iname = bfd_make_empty_symbol(abfd);
2236 iname->name = make_label ("__imp_", exp->name);
2237 iname->section = secdata[IDATA5].sec;
2238 iname->flags = BSF_GLOBAL;
2241 iname2 = bfd_make_empty_symbol(abfd);
2242 iname2->name = make_label ("_imp__", exp->name);
2243 iname2->section = secdata[IDATA5].sec;
2244 iname2->flags = BSF_GLOBAL;
2247 iname_lab = bfd_make_empty_symbol(abfd);
2249 iname_lab->name = head_label;
2250 iname_lab->section = (asection *)&bfd_und_section;
2251 iname_lab->flags = 0;
2252 iname_lab->value = 0;
2255 iname_pp = ptrs + oidx;
2256 ptrs[oidx++] = iname;
2257 ptrs[oidx++] = iname2;
2259 iname_lab_pp = ptrs + oidx;
2260 ptrs[oidx++] = iname_lab;
2263 /* The symbol refering to the code (.text) */
2265 asymbol *function_name;
2267 function_name = bfd_make_empty_symbol(abfd);
2268 function_name->name = make_label ("..", exp->name);
2269 function_name->section = secdata[TEXT].sec;
2270 function_name->flags = BSF_GLOBAL;
2271 function_name->value = 0;
2273 fn_pp = ptrs + oidx;
2274 ptrs[oidx++] = function_name;
2277 /* The .toc symbol */
2279 asymbol *toc_symbol; /* The .toc symbol */
2281 toc_symbol = bfd_make_empty_symbol (abfd);
2282 toc_symbol->name = make_label (".", "toc");
2283 toc_symbol->section = (asection *)&bfd_und_section;
2284 toc_symbol->flags = BSF_GLOBAL;
2285 toc_symbol->value = 0;
2287 toc_pp = ptrs + oidx;
2288 ptrs[oidx++] = toc_symbol;
2294 for (i = 0; i < NSECS; i++)
2296 sinfo *si = secdata + i;
2297 asection *sec = si->sec;
2306 si->size = HOW_JTAB_SIZE;
2307 si->data = xmalloc (HOW_JTAB_SIZE);
2308 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2310 /* add the reloc into idata$5 */
2311 rel = xmalloc (sizeof (arelent));
2313 rpp = xmalloc (sizeof (arelent *) * 2);
2317 rel->address = HOW_JTAB_ROFF;
2320 if (machine == MPPC)
2322 rel->howto = bfd_reloc_type_lookup (abfd,
2323 BFD_RELOC_16_GOTOFF);
2324 rel->sym_ptr_ptr = iname_pp;
2328 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2329 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2331 sec->orelocation = rpp;
2332 sec->reloc_count = 1;
2337 /* An idata$4 or idata$5 is one word long, and has an
2340 si->data = xmalloc (4);
2345 si->data[0] = exp->ordinal ;
2346 si->data[1] = exp->ordinal >> 8;
2347 si->data[2] = exp->ordinal >> 16;
2352 sec->reloc_count = 1;
2353 memset (si->data, 0, si->size);
2354 rel = xmalloc (sizeof (arelent));
2355 rpp = xmalloc (sizeof (arelent *) * 2);
2360 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2361 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2362 sec->orelocation = rpp;
2370 /* This used to add 1 to exp->hint. I don't know
2371 why it did that, and it does not match what I see
2372 in programs compiled with the MS tools. */
2373 int idx = exp->hint;
2374 si->size = strlen (xlate (exp->name)) + 3;
2375 si->data = xmalloc (si->size);
2376 si->data[0] = idx & 0xff;
2377 si->data[1] = idx >> 8;
2378 strcpy (si->data + 2, xlate (exp->name));
2383 si->data =xmalloc(4);
2384 memset (si->data, 0, si->size);
2385 rel = xmalloc (sizeof (arelent));
2386 rpp = xmalloc (sizeof (arelent *) * 2);
2390 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2391 rel->sym_ptr_ptr = iname_lab_pp;
2392 sec->orelocation = rpp;
2393 sec->reloc_count = 1;
2399 /* The .pdata section is 5 words long. */
2400 /* Think of it as: */
2403 /* bfd_vma BeginAddress, [0x00] */
2404 /* EndAddress, [0x04] */
2405 /* ExceptionHandler, [0x08] */
2406 /* HandlerData, [0x0c] */
2407 /* PrologEndAddress; [0x10] */
2410 /* So this pdata section setups up this as a glue linkage to
2411 a dll routine. There are a number of house keeping things
2414 1. In the name of glue trickery, the ADDR32 relocs for 0,
2415 4, and 0x10 are set to point to the same place:
2417 2. There is one more reloc needed in the pdata section.
2418 The actual glue instruction to restore the toc on
2419 return is saved as the offset in an IMGLUE reloc.
2420 So we need a total of four relocs for this section.
2422 3. Lastly, the HandlerData field is set to 0x03, to indicate
2423 that this is a glue routine.
2425 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2427 /* alignment must be set to 2**2 or you get extra stuff */
2428 bfd_set_section_alignment(abfd, sec, 2);
2431 si->data =xmalloc(4 * 5);
2432 memset (si->data, 0, si->size);
2433 rpp = xmalloc (sizeof (arelent *) * 5);
2434 rpp[0] = imglue = xmalloc (sizeof (arelent));
2435 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2436 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2437 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2440 /* stick the toc reload instruction in the glue reloc */
2441 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2444 imglue->howto = bfd_reloc_type_lookup (abfd,
2445 BFD_RELOC_32_GOTOFF);
2446 imglue->sym_ptr_ptr = fn_pp;
2448 ba_rel->address = 0;
2450 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2451 ba_rel->sym_ptr_ptr = fn_pp;
2453 bfd_put_32(abfd, 0x18, si->data + 0x04);
2454 ea_rel->address = 4;
2456 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2457 ea_rel->sym_ptr_ptr = fn_pp;
2459 /* mark it as glue */
2460 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2462 /* mark the prolog end address */
2463 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2464 pea_rel->address = 0x10;
2465 pea_rel->addend = 0;
2466 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2467 pea_rel->sym_ptr_ptr = fn_pp;
2469 sec->orelocation = rpp;
2470 sec->reloc_count = 4;
2474 /* Each external function in a PowerPC PE file has a two word
2475 descriptor consisting of:
2476 1. The address of the code.
2477 2. The address of the appropriate .toc
2478 We use relocs to build this.
2482 si->data = xmalloc (8);
2483 memset (si->data, 0, si->size);
2485 rpp = xmalloc (sizeof (arelent *) * 3);
2486 rpp[0] = rel = xmalloc (sizeof (arelent));
2487 rpp[1] = xmalloc (sizeof (arelent));
2492 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2493 rel->sym_ptr_ptr = fn_pp;
2499 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2500 rel->sym_ptr_ptr = toc_pp;
2502 sec->orelocation = rpp;
2503 sec->reloc_count = 2;
2505 #endif /* DLLTOOL_PPC */
2511 /* Size up all the sections */
2512 for (i = 0; i < NSECS; i++)
2514 sinfo *si = secdata + i;
2516 bfd_set_section_size (abfd, si->sec, si->size);
2517 bfd_set_section_vma (abfd, si->sec, vma);
2519 /* vma += si->size;*/
2522 /* Write them out */
2523 for (i = 0; i < NSECS; i++)
2525 sinfo *si = secdata + i;
2527 if (i == IDATA5 && no_idata5)
2530 if (i == IDATA4 && no_idata4)
2533 bfd_set_section_contents (abfd, si->sec,
2538 bfd_set_symtab (abfd, ptrs, oidx);
2540 abfd = bfd_openr (outname, HOW_BFD_TARGET);
2549 FILE * f = fopen (TMP_HEAD_S, FOPEN_WT);
2553 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2557 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2558 fprintf (f, "\t.section .idata$2\n");
2560 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2562 fprintf (f, "%s:\n", head_label);
2564 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2565 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2567 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2568 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2569 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2570 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2571 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2576 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2578 ASM_RVA_AFTER, ASM_C);
2580 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2584 fprintf (f, "\t.section\t.idata$5\n");
2585 fprintf (f, "\t%s\t0\n", ASM_LONG);
2586 fprintf (f, "fthunk:\n");
2591 fprintf (f, "\t.section\t.idata$4\n");
2593 fprintf (f, "\t%s\t0\n", ASM_LONG);
2594 fprintf (f, "\t.section .idata$4\n");
2595 fprintf (f, "hname:\n");
2600 sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
2603 if (machine == MARM_INTERWORK || machine == MTHUMB)
2604 strcat (outfile, " -mthumb-interwork");
2607 run (as_name, outfile);
2609 return bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
2615 FILE * f = fopen (TMP_TAIL_S, FOPEN_WT);
2619 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
2625 fprintf (f, "\t.section .idata$4\n");
2626 fprintf (f, "\t%s\t0\n", ASM_LONG);
2631 fprintf (f, "\t.section .idata$5\n");
2632 fprintf (f, "\t%s\t0\n", ASM_LONG);
2636 /* Normally, we need to see a null descriptor built in idata$3 to
2637 act as the terminator for the list. The ideal way, I suppose,
2638 would be to mark this section as a comdat type 2 section, so
2639 only one would appear in the final .exe (if our linker supported
2640 comdat, that is) or cause it to be inserted by something else (say
2644 fprintf (f, "\t.section .idata$3\n");
2645 fprintf (f, "\t%s\t0\n", ASM_LONG);
2646 fprintf (f, "\t%s\t0\n", ASM_LONG);
2647 fprintf (f, "\t%s\t0\n", ASM_LONG);
2648 fprintf (f, "\t%s\t0\n", ASM_LONG);
2649 fprintf (f, "\t%s\t0\n", ASM_LONG);
2653 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2654 do too. Original, huh? */
2655 fprintf (f, "\t.section .idata$6\n");
2657 fprintf (f, "\t.section .idata$7\n");
2660 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2661 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2662 imp_name_lab, ASM_TEXT, dll_name);
2666 sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
2669 if (machine == MARM_INTERWORK || MTHUMB)
2670 strcat (outfile, " -mthumb-interwork");
2673 run (as_name, outfile);
2675 return bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
2690 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2693 /* xgettext:c-format */
2694 fatal (_("Can't open .lib file: %s"), imp_name);
2696 /* xgettext:c-format */
2697 inform (_("Creating library file: %s\n"), imp_name);
2699 bfd_set_format (outarch, bfd_archive);
2700 outarch->has_armap = 1;
2702 /* Work out a reasonable size of things to put onto one line. */
2704 ar_head = make_head ();
2705 ar_tail = make_tail();
2707 if (ar_head == NULL || ar_tail == NULL)
2710 for (i = 0; (exp = d_exports_lexically[i]); i++)
2712 bfd *n = make_one_lib_file (exp, i);
2717 /* Now stick them all into the archive */
2719 ar_head->next = head;
2720 ar_tail->next = ar_head;
2723 if (! bfd_set_archive_head (outarch, head))
2724 bfd_fatal ("bfd_set_archive_head");
2726 if (! bfd_close (outarch))
2727 bfd_fatal (imp_name);
2729 while (head != NULL)
2731 bfd *n = head->next;
2736 /* Delete all the temp files */
2738 if (dontdeltemps == 0)
2740 unlink (TMP_HEAD_O);
2741 unlink (TMP_HEAD_S);
2742 unlink (TMP_TAIL_O);
2743 unlink (TMP_TAIL_S);
2746 if (dontdeltemps < 2)
2748 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2750 sprintf (outfile, "%s%05d.o", TMP_STUB, i);
2751 if (unlink (outfile) < 0)
2752 /* xgettext:c-format */
2753 warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
2757 inform (_("Created lib file"));
2760 /**********************************************************************/
2762 /* Run through the information gathered from the .o files and the
2763 .def file and work out the best stuff */
2769 export_type *ap = *(export_type **) a;
2770 export_type *bp = *(export_type **) b;
2771 if (ap->ordinal == bp->ordinal)
2774 /* unset ordinals go to the bottom */
2775 if (ap->ordinal == -1)
2777 if (bp->ordinal == -1)
2779 return (ap->ordinal - bp->ordinal);
2787 export_type *ap = *(export_type **) a;
2788 export_type *bp = *(export_type **) b;
2790 return (strcmp (ap->name, bp->name));
2794 remove_null_names (ptr)
2799 for (dst = src = 0; src < d_nfuncs; src++)
2803 ptr[dst] = ptr[src];
2816 for (i = 0; i < d_nfuncs; i++)
2820 printf ("%d %s @ %d %s%s%s\n",
2821 i, ptr[i]->name, ptr[i]->ordinal,
2822 ptr[i]->noname ? "NONAME " : "",
2823 ptr[i]->constant ? "CONSTANT" : "",
2824 ptr[i]->data ? "DATA" : "");
2833 process_duplicates (d_export_vec)
2834 export_type **d_export_vec;
2842 /* Remove duplicates */
2843 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2845 dtab (d_export_vec);
2846 for (i = 0; i < d_nfuncs - 1; i++)
2848 if (strcmp (d_export_vec[i]->name,
2849 d_export_vec[i + 1]->name) == 0)
2852 export_type *a = d_export_vec[i];
2853 export_type *b = d_export_vec[i + 1];
2857 /* xgettext:c-format */
2858 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2859 a->name, a->ordinal, b->ordinal);
2861 if (a->ordinal != -1
2862 && b->ordinal != -1)
2863 /* xgettext:c-format */
2864 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2867 /* Merge attributes */
2868 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2869 b->constant |= a->constant;
2870 b->noname |= a->noname;
2872 d_export_vec[i] = 0;
2875 dtab (d_export_vec);
2876 remove_null_names (d_export_vec);
2877 dtab (d_export_vec);
2882 /* Count the names */
2883 for (i = 0; i < d_nfuncs; i++)
2885 if (!d_export_vec[i]->noname)
2891 fill_ordinals (d_export_vec)
2892 export_type **d_export_vec;
2899 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2901 /* fill in the unset ordinals with ones from our range */
2903 ptr = (char *) xmalloc (size);
2905 memset (ptr, 0, size);
2907 /* Mark in our large vector all the numbers that are taken */
2908 for (i = 0; i < d_nfuncs; i++)
2910 if (d_export_vec[i]->ordinal != -1)
2912 ptr[d_export_vec[i]->ordinal] = 1;
2913 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2915 lowest = d_export_vec[i]->ordinal;
2920 /* Start at 1 for compatibility with MS toolchain. */
2924 /* Now fill in ordinals where the user wants us to choose. */
2925 for (i = 0; i < d_nfuncs; i++)
2927 if (d_export_vec[i]->ordinal == -1)
2931 /* First try within or after any user supplied range. */
2932 for (j = lowest; j < size; j++)
2936 d_export_vec[i]->ordinal = j;
2940 /* Then try before the range. */
2941 for (j = lowest; j >0; j--)
2945 d_export_vec[i]->ordinal = j;
2956 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2958 /* Work out the lowest and highest ordinal numbers. */
2961 if (d_export_vec[0])
2962 d_low_ord = d_export_vec[0]->ordinal;
2963 if (d_export_vec[d_nfuncs-1])
2964 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2973 const export_type **a = (const export_type **) av;
2974 const export_type **b = (const export_type **) bv;
2976 return strcmp ((*a)->name, (*b)->name);
2982 /* First work out the minimum ordinal chosen */
2988 export_type **d_export_vec
2989 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2991 inform (_("Processing definitions"));
2993 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2995 d_export_vec[i] = exp;
2998 process_duplicates (d_export_vec);
2999 fill_ordinals (d_export_vec);
3001 /* Put back the list in the new order */
3003 for (i = d_nfuncs - 1; i >= 0; i--)
3005 d_export_vec[i]->next = d_exports;
3006 d_exports = d_export_vec[i];
3009 /* Build list in alpha order */
3010 d_exports_lexically = (export_type **)
3011 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3013 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3015 d_exports_lexically[i] = exp;
3017 d_exports_lexically[i] = 0;
3019 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
3021 /* Fill exp entries with their hint values */
3023 for (i = 0; i < d_nfuncs; i++)
3025 if (!d_exports_lexically[i]->noname || show_allnames)
3026 d_exports_lexically[i]->hint = hint++;
3029 inform (_("Processed definitions"));
3032 /**********************************************************************/
3035 usage (file, status)
3039 /* xgetext:c-format */
3040 fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
3041 /* xgetext:c-format */
3042 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
3043 fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf][-le], ppc, thumb\n"));
3044 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
3045 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
3046 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
3047 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3048 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3049 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3050 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
3051 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
3052 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
3053 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
3054 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3055 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3056 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3057 fprintf (file, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
3058 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
3059 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3060 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
3061 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3062 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3063 fprintf (file, _(" -v --verbose Be verbose.\n"));
3064 fprintf (file, _(" -V --version Display the program version.\n"));
3065 fprintf (file, _(" -h --help Display this information.\n"));
3070 #define OPTION_EXPORT_ALL_SYMS 150
3071 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3072 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3073 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3074 #define OPTION_NO_IDATA4 'x'
3075 #define OPTION_NO_IDATA5 'c'
3077 static const struct option long_options[] =
3079 {"no-delete", no_argument, NULL, 'n'},
3080 {"dllname", required_argument, NULL, 'D'},
3081 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
3082 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
3083 {"output-exp", required_argument, NULL, 'e'},
3084 {"output-def", required_argument, NULL, 'z'},
3085 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
3086 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3087 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3088 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3089 {"output-lib", required_argument, NULL, 'l'},
3090 {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
3091 {"input-def", required_argument, NULL, 'd'},
3092 {"add-underscore", no_argument, NULL, 'U'},
3093 {"kill-at", no_argument, NULL, 'k'},
3094 {"add-stdcall-alias", no_argument, NULL, 'A'},
3095 {"verbose", no_argument, NULL, 'v'},
3096 {"version", no_argument, NULL, 'V'},
3097 {"help", no_argument, NULL, 'h'},
3098 {"machine", required_argument, NULL, 'm'},
3099 {"add-indirect", no_argument, NULL, 'a'},
3100 {"base-file", required_argument, NULL, 'b'},
3101 {"as", required_argument, NULL, 'S'},
3102 {"as-flags", required_argument, NULL, 'f'},
3114 program_name = av[0];
3117 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3118 setlocale (LC_MESSAGES, "");
3120 bindtextdomain (PACKAGE, LOCALEDIR);
3121 textdomain (PACKAGE);
3123 while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkAvVb:Uh?m:d:f:i",
3129 case OPTION_NO_IDATA4:
3132 case OPTION_NO_IDATA5:
3135 case OPTION_EXPORT_ALL_SYMS:
3136 export_all_symbols = true;
3138 case OPTION_NO_EXPORT_ALL_SYMS:
3139 export_all_symbols = false;
3141 case OPTION_EXCLUDE_SYMS:
3142 add_excludes (optarg);
3144 case OPTION_NO_DEFAULT_EXCLUDES:
3145 do_default_excludes = false;
3154 /* ignored for compatibility */
3161 output_def = fopen (optarg, FOPEN_WT);
3182 print_version (program_name);
3186 /* We don't currently define YYDEBUG when building
3198 add_stdcall_alias = 1;
3207 base_file = fopen (optarg, FOPEN_RB);
3210 /* xgettext:c-format */
3211 fatal (_("Unable to open base-file: %s"), optarg);
3220 for (i = 0; mtable[i].type; i++)
3222 if (strcmp (mtable[i].type, mname) == 0)
3226 if (!mtable[i].type)
3227 /* xgettext:c-format */
3228 fatal (_("Machine '%s' not supported"), mname);
3232 if (!dll_name && exp_name)
3234 int len = strlen (exp_name) + 5;
3235 dll_name = xmalloc (len);
3236 strcpy (dll_name, exp_name);
3237 strcat (dll_name, ".dll");
3240 /* Don't use the default exclude list if we're reading only the
3241 symbols in the .drectve section. The default excludes are meant
3242 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3243 if (! export_all_symbols)
3244 do_default_excludes = false;
3246 if (do_default_excludes)
3247 set_default_excludes ();
3250 process_def_file (def_file);
3255 firstarg = av[optind];
3256 scan_obj_file (av[optind]);
3267 /* Make imp_name safe for use as a label. */
3270 imp_name_lab = xstrdup (imp_name);
3271 for (p = imp_name_lab; *p; p++)
3273 if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
3276 head_label = make_label("_head_", imp_name_lab);