1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995, 96, 97, 98, 99, 2000 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 and the program
148 gcc -c file1.c file2.c themain.c
150 # Optional: put the dll objects into a library
151 # (you don't have to, you could name all the object
152 # files on the dlltool line)
154 ar qcv thedll.in file1.o file2.o
157 # Run this tool over the DLL's .def file and generate an exports
158 # file (thedll.o) and an imports file (thedll.a).
159 # (You may have to use -S to tell dlltool where to find the assembler).
161 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
163 # Build the dll with the library and the export table
165 ld -o thedll.dll thedll.o thedll.in
167 # Link the executable with the import library
169 gcc -o themain.exe themain.o thedll.a
171 This example can be extended if relocations are needed in the DLL:
173 # Compile up the parts of the dll and the program
175 gcc -c file1.c file2.c themain.c
177 # Run this tool over the DLL's .def file and generate an imports file.
179 dlltool --def thedll.def --output-lib thedll.lib
181 # Link the executable with the import library and generate a base file
184 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
186 # Run this tool over the DLL's .def file and generate an exports file
187 # which includes the relocations from the base file.
189 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
191 # Build the dll with file1.o, file2.o and the export table
193 ld -o thedll.dll thedll.exp file1.o file2.o
196 /* .idata section description
198 The .idata section is the import table. It is a collection of several
199 subsections used to keep the pieces for each dll together: .idata$[234567].
200 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
202 .idata$2 = Import Directory Table
203 = array of IMAGE_IMPORT_DESCRIPTOR's.
205 DWORD Import Lookup Table; - pointer to .idata$4
206 DWORD TimeDateStamp; - currently always 0
207 DWORD ForwarderChain; - currently always 0
208 DWORD Name; - pointer to dll's name
209 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
211 .idata$3 = null terminating entry for .idata$2.
213 .idata$4 = Import Lookup Table
214 = array of array of pointers to hint name table.
215 There is one for each dll being imported from, and each dll's set is
216 terminated by a trailing NULL.
218 .idata$5 = Import Address Table
219 = array of array of pointers to hint name table.
220 There is one for each dll being imported from, and each dll's set is
221 terminated by a trailing NULL.
222 Initially, this table is identical to the Import Lookup Table. However,
223 at load time, the loader overwrites the entries with the address of the
226 .idata$6 = Hint Name Table
227 = Array of { short, asciz } entries, one for each imported function.
228 The `short' is the function's ordinal number.
230 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
233 /* AIX requires this to be the first thing in the file. */
240 #define show_allnames 0
242 #define PAGE_SIZE 4096
243 #define PAGE_MASK (-PAGE_SIZE)
245 #include "libiberty.h"
248 #include "demangle.h"
249 #include "dyn-string.h"
254 #include <sys/stat.h>
256 #ifdef ANSI_PROTOTYPES
263 #include "coff/arm.h"
264 #include "coff/internal.h"
267 /* Forward references. */
268 static char *look_for_prog
PARAMS ((const char *, const char *, int));
269 static char *deduce_name
PARAMS ((const char *));
271 #ifdef DLLTOOL_MCORE_ELF
272 static void mcore_elf_cache_filename (char *);
273 static void mcore_elf_gen_out_file (void);
276 #ifdef HAVE_SYS_WAIT_H
277 #include <sys/wait.h>
278 #else /* ! HAVE_SYS_WAIT_H */
279 #if ! defined (_WIN32) || defined (__CYGWIN32__)
281 #define WIFEXITED(w) (((w)&0377) == 0)
284 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
287 #define WTERMSIG(w) ((w) & 0177)
290 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
292 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
294 #define WIFEXITED(w) (((w) & 0xff) == 0)
297 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300 #define WTERMSIG(w) ((w) & 0x7f)
303 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
305 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
306 #endif /* ! HAVE_SYS_WAIT_H */
308 /* ifunc and ihead data structures: ttk@cygnus.com 1997
310 When IMPORT declarations are encountered in a .def file the
311 function import information is stored in a structure referenced by
312 the global variable IMPORT_LIST. The structure is a linked list
313 containing the names of the dll files each function is imported
314 from and a linked list of functions being imported from that dll
315 file. This roughly parallels the structure of the .idata section
316 in the PE object file.
318 The contents of .def file are interpreted from within the
319 process_def_file function. Every time an IMPORT declaration is
320 encountered, it is broken up into its component parts and passed to
321 def_import. IMPORT_LIST is initialized to NULL in function main. */
323 typedef struct ifunct
325 char *name
; /* name of function being imported */
326 int ord
; /* two-byte ordinal value associated with function */
330 typedef struct iheadt
332 char *dllname
; /* name of dll file imported from */
333 long nfuncs
; /* number of functions in list */
334 struct ifunct
*funchead
; /* first function in list */
335 struct ifunct
*functail
; /* last function in list */
336 struct iheadt
*next
; /* next dll file in list */
339 /* Structure containing all import information as defined in .def file
340 (qv "ihead structure"). */
342 static iheadtype
*import_list
= NULL
;
344 static char *as_name
= NULL
;
345 static char * as_flags
= "";
347 static int no_idata4
;
348 static int no_idata5
;
349 static char *exp_name
;
350 static char *imp_name
;
351 static char *head_label
;
352 static char *imp_name_lab
;
353 static char *dll_name
;
355 static int add_indirect
= 0;
356 static int add_underscore
= 0;
357 static int dontdeltemps
= 0;
359 /* True if we should export all symbols. Otherwise, we only export
360 symbols listed in .drectve sections or in the def file. */
361 static boolean export_all_symbols
;
363 /* True if we should exclude the symbols in DEFAULT_EXCLUDES when
364 exporting all symbols. */
365 static boolean do_default_excludes
;
367 /* Default symbols to exclude when exporting all the symbols. */
368 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
370 /* True if we should add __imp_<SYMBOL> to import libraries for backward
371 compatibility to old Cygwin releases. */
372 static boolean create_compat_implib
;
374 static char *def_file
;
376 extern char * program_name
;
380 static int add_stdcall_alias
;
382 static FILE *output_def
;
383 static FILE *base_file
;
386 static const char *mname
= "arm";
390 static const char *mname
= "i386";
394 static const char *mname
= "ppc";
398 static const char *mname
= "sh";
402 static const char *mname
= "mips";
406 static const char * mname
= "mcore-le";
409 #ifdef DLLTOOL_MCORE_ELF
410 static const char * mname
= "mcore-elf";
411 static char * mcore_elf_out_file
= NULL
;
412 static char * mcore_elf_linker
= NULL
;
413 static char * mcore_elf_linker_flags
= NULL
;
415 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
418 #ifndef DRECTVE_SECTION_NAME
419 #define DRECTVE_SECTION_NAME ".drectve"
422 #define PATHMAX 250 /* What's the right name for this ? */
424 #define TMP_ASM "dc.s"
425 #define TMP_HEAD_S "dh.s"
426 #define TMP_HEAD_O "dh.o"
427 #define TMP_TAIL_S "dt.s"
428 #define TMP_TAIL_O "dt.o"
429 #define TMP_STUB "ds"
431 /* This bit of assemly does jmp * .... */
432 static const unsigned char i386_jtab
[] =
434 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
437 static const unsigned char arm_jtab
[] =
439 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
440 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
444 static const unsigned char arm_interwork_jtab
[] =
446 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
447 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
448 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
452 static const unsigned char thumb_jtab
[] =
454 0x40, 0xb4, /* push {r6} */
455 0x02, 0x4e, /* ldr r6, [pc, #8] */
456 0x36, 0x68, /* ldr r6, [r6] */
457 0xb4, 0x46, /* mov ip, r6 */
458 0x40, 0xbc, /* pop {r6} */
459 0x60, 0x47, /* bx ip */
463 static const unsigned char mcore_be_jtab
[] =
465 0x71, 0x02, /* lrw r1,2 */
466 0x81, 0x01, /* ld.w r1,(r1,0) */
467 0x00, 0xC1, /* jmp r1 */
468 0x12, 0x00, /* nop */
469 0x00, 0x00, 0x00, 0x00 /* <address> */
472 static const unsigned char mcore_le_jtab
[] =
474 0x02, 0x71, /* lrw r1,2 */
475 0x01, 0x81, /* ld.w r1,(r1,0) */
476 0xC1, 0x00, /* jmp r1 */
477 0x00, 0x12, /* nop */
478 0x00, 0x00, 0x00, 0x00 /* <address> */
481 /* This is the glue sequence for PowerPC PE. There is a */
482 /* tocrel16-tocdefn reloc against the first instruction. */
483 /* We also need a IMGLUE reloc against the glue function */
484 /* to restore the toc saved by the third instruction in */
486 static const unsigned char ppc_jtab
[] =
488 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
489 /* Reloc TOCREL16 __imp_xxx */
490 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
491 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
492 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
493 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
494 0x20, 0x04, 0x80, 0x4E /* bctr */
498 /* the glue instruction, picks up the toc from the stw in */
499 /* the above code: "lwz r2,4(r1)" */
500 static bfd_vma ppc_glue_insn
= 0x80410004;
506 const char *how_byte
;
507 const char *how_short
;
508 const char *how_long
;
509 const char *how_asciz
;
510 const char *how_comment
;
511 const char *how_jump
;
512 const char *how_global
;
513 const char *how_space
;
514 const char *how_align_short
;
515 const char *how_align_long
;
516 const char *how_default_as_switches
;
517 const char *how_bfd_target
;
518 enum bfd_architecture how_bfd_arch
;
519 const unsigned char *how_jtab
;
520 int how_jtab_size
; /* size of the jtab entry */
521 int how_jtab_roff
; /* offset into it for the ind 32 reloc into idata 5 */
524 static const struct mac
529 "arm", ".byte", ".short", ".long", ".asciz", "@",
530 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
531 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
532 "pe-arm-little", bfd_arch_arm
,
533 arm_jtab
, sizeof (arm_jtab
), 8
538 "i386", ".byte", ".short", ".long", ".asciz", "#",
539 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
540 "pe-i386",bfd_arch_i386
,
541 i386_jtab
, sizeof (i386_jtab
), 2
546 "ppc", ".byte", ".short", ".long", ".asciz", "#",
547 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
548 "pe-powerpcle",bfd_arch_powerpc
,
549 ppc_jtab
, sizeof (ppc_jtab
), 0
554 "thumb", ".byte", ".short", ".long", ".asciz", "@",
555 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
556 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
557 "pe-arm-little", bfd_arch_arm
,
558 thumb_jtab
, sizeof (thumb_jtab
), 12
561 #define MARM_INTERWORK 4
563 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
564 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
565 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
566 "pe-arm-little", bfd_arch_arm
,
567 arm_interwork_jtab
, sizeof (arm_interwork_jtab
), 12
572 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
573 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
574 ".global", ".space", ".align\t2",".align\t4", "",
575 "pe-mcore-big", bfd_arch_mcore
,
576 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
581 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
582 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
583 ".global", ".space", ".align\t2",".align\t4", "-EL",
584 "pe-mcore-little", bfd_arch_mcore
,
585 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
590 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
591 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
592 ".global", ".space", ".align\t2",".align\t4", "",
593 "elf32-mcore-big", bfd_arch_mcore
,
594 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
598 #define MMCORE_ELF_LE 8
599 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
600 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
601 ".global", ".space", ".align\t2",".align\t4", "-EL",
602 "elf32-mcore-little", bfd_arch_mcore
,
603 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
608 "arm", ".byte", ".short", ".long", ".asciz", "@",
609 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
610 ".global", ".space", ".align\t2",".align\t4", "",
611 "epoc-pe-arm-little", bfd_arch_arm
,
612 arm_jtab
, sizeof (arm_jtab
), 8
615 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
625 typedef struct export
628 const char *internal_name
;
638 /* A list of symbols which we should not export. */
642 struct string_list
*next
;
646 static struct string_list
*excludes
;
648 static const char *rvaafter
PARAMS ((int));
649 static const char *rvabefore
PARAMS ((int));
650 static const char *asm_prefix
PARAMS ((int));
651 static void append_import
PARAMS ((const char *, const char *, int));
652 static void run
PARAMS ((const char *, char *));
653 static void scan_drectve_symbols
PARAMS ((bfd
*));
654 static void scan_filtered_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
655 static void add_excludes
PARAMS ((const char *));
656 static boolean match_exclude
PARAMS ((const char *));
657 static void set_default_excludes
PARAMS ((void));
658 static long filter_symbols
PARAMS ((bfd
*, PTR
, long, unsigned int));
659 static void scan_all_symbols
PARAMS ((bfd
*));
660 static void scan_open_obj_file
PARAMS ((bfd
*));
661 static void scan_obj_file
PARAMS ((const char *));
662 static void dump_def_info
PARAMS ((FILE *));
663 static int sfunc
PARAMS ((const void *, const void *));
664 static void flush_page
PARAMS ((FILE *, long *, int, int));
665 static void gen_def_file
PARAMS ((void));
666 static void generate_idata_ofile
PARAMS ((FILE *));
667 static void gen_exp_file
PARAMS ((void));
668 static const char *xlate
PARAMS ((const char *));
670 static void dump_iat
PARAMS ((FILE *, export_type
*));
672 static char *make_label
PARAMS ((const char *, const char *));
673 static bfd
*make_one_lib_file
PARAMS ((export_type
*, int));
674 static bfd
*make_head
PARAMS ((void));
675 static bfd
*make_tail
PARAMS ((void));
676 static void gen_lib_file
PARAMS ((void));
677 static int pfunc
PARAMS ((const void *, const void *));
678 static int nfunc
PARAMS ((const void *, const void *));
679 static void remove_null_names
PARAMS ((export_type
**));
680 static void dtab
PARAMS ((export_type
**));
681 static void process_duplicates
PARAMS ((export_type
**));
682 static void fill_ordinals
PARAMS ((export_type
**));
683 static int alphafunc
PARAMS ((const void *, const void *));
684 static void mangle_defs
PARAMS ((void));
685 static void usage
PARAMS ((FILE *, int));
686 static void display
PARAMS ((const char *, va_list));
687 static void inform
PARAMS ((const char *, ...));
688 static void warn
PARAMS ((const char *, ...));
691 display (message
, args
)
692 const char * message
;
695 if (program_name
!= NULL
)
696 fprintf (stderr
, "%s: ", program_name
);
698 vfprintf (stderr
, message
, args
);
700 if (message
[strlen (message
) - 1] != '\n')
701 fputc ('\n', stderr
);
707 inform (const char * message
, ...)
709 inform (message
, va_alist
)
710 const char * message
;
720 va_start (args
, message
);
725 display (message
, args
);
732 warn (const char * message
, ...)
734 warn (message
, va_alist
)
735 const char * message
;
742 va_start (args
, message
);
747 display (message
, args
);
769 /* xgettext:c-format */
770 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
793 /* xgettext:c-format */
794 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
818 /* xgettext:c-format */
819 fatal (_("Internal error: Unknown machine type: %d\n"), machine
);
825 #define ASM_BYTE mtable[machine].how_byte
826 #define ASM_SHORT mtable[machine].how_short
827 #define ASM_LONG mtable[machine].how_long
828 #define ASM_TEXT mtable[machine].how_asciz
829 #define ASM_C mtable[machine].how_comment
830 #define ASM_JUMP mtable[machine].how_jump
831 #define ASM_GLOBAL mtable[machine].how_global
832 #define ASM_SPACE mtable[machine].how_space
833 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
834 #define ASM_RVA_BEFORE rvabefore(machine)
835 #define ASM_RVA_AFTER rvaafter(machine)
836 #define ASM_PREFIX asm_prefix(machine)
837 #define ASM_ALIGN_LONG mtable[machine].how_align_long
838 #define HOW_BFD_READ_TARGET 0 /* always default*/
839 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
840 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
841 #define HOW_JTAB mtable[machine].how_jtab
842 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
843 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
844 #define ASM_SWITCHES mtable[machine].how_default_as_switches
849 process_def_file (name
)
852 FILE *f
= fopen (name
, FOPEN_RT
);
855 /* xgettext:c-format */
856 fatal (_("Can't open def file: %s"), name
);
860 /* xgettext:c-format */
861 inform (_("Processing def file: %s"), name
);
865 inform (_("Processed def file"));
868 /**********************************************************************/
870 /* Communications with the parser */
872 static const char *d_name
; /* Arg to NAME or LIBRARY */
873 static int d_nfuncs
; /* Number of functions exported */
874 static int d_named_nfuncs
; /* Number of named functions exported */
875 static int d_low_ord
; /* Lowest ordinal index */
876 static int d_high_ord
; /* Highest ordinal index */
877 static export_type
*d_exports
; /*list of exported functions */
878 static export_type
**d_exports_lexically
; /* vector of exported functions in alpha order */
879 static dlist_type
*d_list
; /* Descriptions */
880 static dlist_type
*a_list
; /* Stuff to go in directives */
887 const char * err ATTRIBUTE_UNUSED
;
889 /* xgettext:c-format */
890 warn (_("Syntax error in def file %s:%d\n"), def_file
, linenumber
);
896 def_exports (name
, internal_name
, ordinal
, noname
, constant
, data
)
898 const char *internal_name
;
904 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
907 p
->internal_name
= internal_name
? internal_name
: name
;
908 p
->ordinal
= ordinal
;
909 p
->constant
= constant
;
918 def_name (name
, base
)
922 /* xgettext:c-format */
923 inform (_("NAME: %s base: %x"), name
, base
);
926 warn (_("Can't have LIBRARY and NAME\n"));
929 /* if --dllname not provided, use the one in the DEF file.
930 FIXME: Is this appropriate for executables? */
932 dll_name
= xstrdup (name
);
937 def_library (name
, base
)
941 /* xgettext:c-format */
942 inform (_("LIBRARY: %s base: %x"), name
, base
);
945 warn (_("%s: Can't have LIBRARY and NAME\n"), program_name
);
948 /* if --dllname not provided, use the one in the DEF file. */
950 dll_name
= xstrdup (name
);
955 def_description (desc
)
958 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
959 d
->text
= xstrdup (desc
);
968 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
969 d
->text
= xstrdup (dir
);
975 def_heapsize (reserve
, commit
)
981 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
983 sprintf (b
, "-heap 0x%x ", reserve
);
984 new_directive (xstrdup (b
));
988 def_stacksize (reserve
, commit
)
994 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
996 sprintf (b
, "-stack 0x%x ", reserve
);
997 new_directive (xstrdup (b
));
1000 /* append_import simply adds the given import definition to the global
1001 import_list. It is used by def_import. */
1004 append_import (symbol_name
, dll_name
, func_ordinal
)
1005 const char *symbol_name
;
1006 const char *dll_name
;
1012 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
1014 if (strcmp ((*pq
)->dllname
, dll_name
) == 0)
1017 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
1018 q
->functail
= q
->functail
->next
;
1019 q
->functail
->ord
= func_ordinal
;
1020 q
->functail
->name
= xstrdup (symbol_name
);
1021 q
->functail
->next
= NULL
;
1027 q
= xmalloc (sizeof (iheadtype
));
1028 q
->dllname
= xstrdup (dll_name
);
1030 q
->funchead
= xmalloc (sizeof (ifunctype
));
1031 q
->functail
= q
->funchead
;
1033 q
->functail
->name
= xstrdup (symbol_name
);
1034 q
->functail
->ord
= func_ordinal
;
1035 q
->functail
->next
= NULL
;
1040 /* def_import is called from within defparse.y when an IMPORT
1041 declaration is encountered. Depending on the form of the
1042 declaration, the module name may or may not need ".dll" to be
1043 appended to it, the name of the function may be stored in internal
1044 or entry, and there may or may not be an ordinal value associated
1047 /* A note regarding the parse modes:
1048 In defparse.y we have to accept import declarations which follow
1049 any one of the following forms:
1050 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1051 <func_name_in_app> = <dll_name>.<number>
1052 <dll_name>.<func_name_in_dll>
1054 Furthermore, the dll's name may or may not end with ".dll", which
1055 complicates the parsing a little. Normally the dll's name is
1056 passed to def_import() in the "module" parameter, but when it ends
1057 with ".dll" it gets passed in "module" sans ".dll" and that needs
1060 def_import gets five parameters:
1061 APP_NAME - the name of the function in the application, if
1062 present, or NULL if not present.
1063 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1064 DLLEXT - the extension of the dll, if present, NULL if not present.
1065 ENTRY - the name of the function in the dll, if present, or NULL.
1066 ORD_VAL - the numerical tag of the function in the dll, if present,
1067 or NULL. Exactly one of <entry> or <ord_val> must be
1068 present (i.e., not NULL). */
1071 def_import (app_name
, module
, dllext
, entry
, ord_val
)
1072 const char *app_name
;
1078 const char *application_name
;
1082 application_name
= entry
;
1085 if (app_name
!= NULL
)
1086 application_name
= app_name
;
1088 application_name
= "";
1093 buf
= (char *) alloca (strlen (module
) + strlen (dllext
) + 2);
1094 sprintf (buf
, "%s.%s", module
, dllext
);
1098 append_import (application_name
, module
, ord_val
);
1102 def_version (major
, minor
)
1106 printf ("VERSION %d.%d\n", major
, minor
);
1110 def_section (name
, attr
)
1127 sprintf (buf
, "-attr %s %s", name
, atts
);
1128 new_directive (xstrdup (buf
));
1136 def_section ("CODE", attr
);
1143 def_section ("DATA", attr
);
1146 /**********************************************************************/
1154 int pid
, wait_status
;
1157 char *errmsg_fmt
, *errmsg_arg
;
1158 char *temp_base
= choose_temp_base ();
1160 inform ("run: %s %s\n", what
, args
);
1162 /* Count the args */
1164 for (s
= args
; *s
; s
++)
1168 argv
= alloca (sizeof (char *) * (i
+ 3));
1177 while (*s
!= ' ' && *s
!= 0)
1185 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1186 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1190 inform (strerror (errno
));
1192 fatal (errmsg_fmt
, errmsg_arg
);
1195 pid
= pwait (pid
, & wait_status
, 0);
1199 /* xgettext:c-format */
1200 fatal (_("wait: %s"), strerror (errno
));
1202 else if (WIFSIGNALED (wait_status
))
1204 /* xgettext:c-format */
1205 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1207 else if (WIFEXITED (wait_status
))
1209 if (WEXITSTATUS (wait_status
) != 0)
1210 /* xgettext:c-format */
1211 warn (_("%s exited with status %d\n"),
1212 what
, WEXITSTATUS (wait_status
));
1218 /* Look for a list of symbols to export in the .drectve section of
1219 ABFD. Pass each one to def_exports. */
1222 scan_drectve_symbols (abfd
)
1231 /* Look for .drectve's */
1232 s
= bfd_get_section_by_name (abfd
, DRECTVE_SECTION_NAME
);
1237 size
= bfd_get_section_size_before_reloc (s
);
1238 buf
= xmalloc (size
);
1240 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1242 /* xgettext:c-format */
1243 inform (_("Sucking in info from %s section in %s\n"),
1244 DRECTVE_SECTION_NAME
, bfd_get_filename (abfd
));
1246 /* Search for -export: strings. The exported symbols can optionally
1247 have type tags (eg., -export:foo,data), so handle those as well.
1248 Currently only data tag is supported. */
1254 && strncmp (p
, "-export:", 8) == 0)
1258 flagword flags
= BSF_FUNCTION
;
1262 while (p
< e
&& *p
!= ',' && *p
!= ' ' && *p
!= '-')
1264 c
= xmalloc (p
- name
+ 1);
1265 memcpy (c
, name
, p
- name
);
1267 if (p
< e
&& *p
== ',') /* found type tag. */
1269 char *tag_start
= ++p
;
1270 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1272 if (strncmp (tag_start
, "data", 4) == 0)
1273 flags
&= ~BSF_FUNCTION
;
1276 /* FIXME: The 5th arg is for the `constant' field.
1277 What should it be? Not that it matters since it's not
1278 currently useful. */
1279 def_exports (c
, 0, -1, 0, 0, ! (flags
& BSF_FUNCTION
));
1281 if (add_stdcall_alias
&& strchr (c
, '@'))
1283 char *exported_name
= xstrdup (c
);
1284 char *atsym
= strchr (exported_name
, '@');
1286 /* Note: stdcall alias symbols can never be data. */
1287 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0);
1296 /* Look through the symbols in MINISYMS, and add each one to list of
1297 symbols to export. */
1300 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
)
1307 bfd_byte
*from
, *fromend
;
1309 store
= bfd_make_empty_symbol (abfd
);
1311 bfd_fatal (bfd_get_filename (abfd
));
1313 from
= (bfd_byte
*) minisyms
;
1314 fromend
= from
+ symcount
* size
;
1315 for (; from
< fromend
; from
+= size
)
1318 const char *symbol_name
;
1320 sym
= bfd_minisymbol_to_symbol (abfd
, false, from
, store
);
1322 bfd_fatal (bfd_get_filename (abfd
));
1324 symbol_name
= bfd_asymbol_name (sym
);
1325 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1328 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0,
1329 ! (sym
->flags
& BSF_FUNCTION
));
1331 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1333 char *exported_name
= xstrdup (symbol_name
);
1334 char *atsym
= strchr (exported_name
, '@');
1336 /* Note: stdcall alias symbols can never be data. */
1337 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0);
1342 /* Add a list of symbols to exclude. */
1345 add_excludes (new_excludes
)
1346 const char *new_excludes
;
1349 char *exclude_string
;
1351 local_copy
= xstrdup (new_excludes
);
1353 exclude_string
= strtok (local_copy
, ",:");
1354 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1356 struct string_list
*new_exclude
;
1358 new_exclude
= ((struct string_list
*)
1359 xmalloc (sizeof (struct string_list
)));
1360 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1361 /* FIXME: Is it always right to add a leading underscore? */
1362 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1363 new_exclude
->next
= excludes
;
1364 excludes
= new_exclude
;
1366 /* xgettext:c-format */
1367 inform (_("Excluding symbol: %s\n"), exclude_string
);
1373 /* See if STRING is on the list of symbols to exclude. */
1376 match_exclude (string
)
1379 struct string_list
*excl_item
;
1381 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1382 if (strcmp (string
, excl_item
->string
) == 0)
1387 /* Add the default list of symbols to exclude. */
1390 set_default_excludes (void)
1392 add_excludes (default_excludes
);
1395 /* Choose which symbols to export. */
1398 filter_symbols (abfd
, minisyms
, symcount
, size
)
1404 bfd_byte
*from
, *fromend
, *to
;
1407 store
= bfd_make_empty_symbol (abfd
);
1409 bfd_fatal (bfd_get_filename (abfd
));
1411 from
= (bfd_byte
*) minisyms
;
1412 fromend
= from
+ symcount
* size
;
1413 to
= (bfd_byte
*) minisyms
;
1415 for (; from
< fromend
; from
+= size
)
1420 sym
= bfd_minisymbol_to_symbol (abfd
, false, (const PTR
) from
, store
);
1422 bfd_fatal (bfd_get_filename (abfd
));
1424 /* Check for external and defined only symbols. */
1425 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1426 || (sym
->flags
& BSF_WEAK
) != 0
1427 || bfd_is_com_section (sym
->section
))
1428 && ! bfd_is_und_section (sym
->section
));
1430 keep
= keep
&& ! match_exclude (sym
->name
);
1434 memcpy (to
, from
, size
);
1439 return (to
- (bfd_byte
*) minisyms
) / size
;
1442 /* Export all symbols in ABFD, except for ones we were told not to
1446 scan_all_symbols (abfd
)
1453 /* Ignore bfds with an import descriptor table. We assume that any
1454 such BFD contains symbols which are exported from another DLL,
1455 and we don't want to reexport them from here. */
1456 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1459 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1461 /* xgettext:c-format */
1462 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1466 symcount
= bfd_read_minisymbols (abfd
, false, &minisyms
, &size
);
1468 bfd_fatal (bfd_get_filename (abfd
));
1472 /* xgettext:c-format */
1473 warn (_("%s: no symbols\n"), bfd_get_filename (abfd
));
1477 /* Discard the symbols we don't want to export. It's OK to do this
1478 in place; we'll free the storage anyway. */
1480 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1481 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1486 /* Look at the object file to decide which symbols to export. */
1489 scan_open_obj_file (abfd
)
1492 if (export_all_symbols
)
1493 scan_all_symbols (abfd
);
1495 scan_drectve_symbols (abfd
);
1497 /* FIXME: we ought to read in and block out the base relocations */
1499 /* xgettext:c-format */
1500 inform (_("Done reading %s\n"), bfd_get_filename (abfd
));
1504 scan_obj_file (filename
)
1505 const char *filename
;
1507 bfd
* f
= bfd_openr (filename
, 0);
1510 /* xgettext:c-format */
1511 fatal (_("Unable to open object file: %s"), filename
);
1513 /* xgettext:c-format */
1514 inform (_("Scanning object file %s"), filename
);
1516 if (bfd_check_format (f
, bfd_archive
))
1518 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1521 if (bfd_check_format (arfile
, bfd_object
))
1522 scan_open_obj_file (arfile
);
1524 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1527 #ifdef DLLTOOL_MCORE_ELF
1528 if (mcore_elf_out_file
)
1529 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename
);
1532 else if (bfd_check_format (f
, bfd_object
))
1534 scan_open_obj_file (f
);
1536 #ifdef DLLTOOL_MCORE_ELF
1537 if (mcore_elf_out_file
)
1538 mcore_elf_cache_filename ((char *) filename
);
1545 /**********************************************************************/
1553 fprintf (f
, "%s ", ASM_C
);
1554 for (i
= 0; oav
[i
]; i
++)
1555 fprintf (f
, "%s ", oav
[i
]);
1557 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1559 fprintf (f
, "%s %d = %s %s @ %d %s%s%s\n",
1565 exp
->noname
? "NONAME " : "",
1566 exp
->constant
? "CONSTANT" : "",
1567 exp
->data
? "DATA" : "");
1571 /* Generate the .exp file */
1578 return *(const long *) a
- *(const long *) b
;
1582 flush_page (f
, need
, page_addr
, on_page
)
1590 /* Flush this page */
1591 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1595 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1597 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1600 for (i
= 0; i
< on_page
; i
++)
1602 long needed
= need
[i
];
1605 needed
= ((needed
- page_addr
) | 0x3000) & 0xffff;
1607 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, needed
);
1612 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1621 inform (_("Adding exports to output file"));
1623 fprintf (output_def
, ";");
1624 for (i
= 0; oav
[i
]; i
++)
1625 fprintf (output_def
, " %s", oav
[i
]);
1627 fprintf (output_def
, "\nEXPORTS\n");
1629 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1631 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1632 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1634 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1637 fprintf (output_def
, "\t%s%s%s @ %d%s%s ; %s\n",
1642 exp
->noname
? " NONAME" : "",
1643 exp
->data
? " DATA" : "",
1648 char *quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1650 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
1658 exp
->noname
? " NONAME" : "",
1659 exp
->data
? " DATA" : "",
1666 inform (_("Added exports to output file"));
1669 /* generate_idata_ofile generates the portable assembly source code
1670 for the idata sections. It appends the source code to the end of
1674 generate_idata_ofile (filvar
)
1683 if (import_list
== NULL
)
1686 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1687 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1688 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1689 fprintf (filvar
, "doi_idata:\n");
1692 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1694 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1695 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1696 ASM_C
, headptr
->dllname
);
1697 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1698 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1699 fprintf (filvar
, "\t%sdllname%d%s\n",
1700 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1701 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1702 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1706 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1707 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1708 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1709 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1710 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1712 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1714 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1716 fprintf (filvar
, "listone%d:\n", headindex
);
1717 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1718 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1719 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1720 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1724 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1726 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1728 fprintf (filvar
, "listtwo%d:\n", headindex
);
1729 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1730 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1731 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1732 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1736 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1738 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1741 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1742 funcptr
= funcptr
->next
)
1744 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1745 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1746 ((funcptr
->ord
) & 0xFFFF));
1747 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1748 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1754 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1756 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1758 fprintf (filvar
,"dllname%d:\n", headindex
);
1759 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1760 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1765 /* Assemble the specified file. */
1767 assemble_file (source
, dest
)
1768 const char * source
;
1773 cmd
= (char *) alloca (strlen (ASM_SWITCHES
) + strlen (as_flags
)
1774 + strlen (source
) + strlen (dest
) + 50);
1776 sprintf (cmd
, "%s %s -o %s %s", ASM_SWITCHES
, as_flags
, dest
, source
);
1789 /* xgettext:c-format */
1790 inform (_("Generating export file: %s\n"), exp_name
);
1792 f
= fopen (TMP_ASM
, FOPEN_WT
);
1794 /* xgettext:c-format */
1795 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1797 /* xgettext:c-format */
1798 inform (_("Opened temporary file: %s"), TMP_ASM
);
1804 fprintf (f
, "\t.section .edata\n\n");
1805 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1806 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1808 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1809 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1810 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1813 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1814 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1816 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1817 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1818 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1819 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1821 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1822 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1824 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1826 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1829 fprintf(f
,"%s Export address Table\n", ASM_C
);
1830 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1831 fprintf (f
, "afuncs:\n");
1834 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1836 if (exp
->ordinal
!= i
)
1839 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1841 (exp
->ordinal
- i
) * 4,
1843 i
, exp
->ordinal
- 1);
1846 while (i
< exp
->ordinal
)
1848 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1852 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1854 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1858 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1859 fprintf (f
, "anames:\n");
1861 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1863 if (!exp
->noname
|| show_allnames
)
1864 fprintf (f
, "\t%sn%d%s\n",
1865 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1868 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1869 fprintf (f
, "anords:\n");
1870 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1872 if (!exp
->noname
|| show_allnames
)
1873 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1876 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1877 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1878 if (!exp
->noname
|| show_allnames
)
1879 fprintf (f
, "n%d: %s \"%s\"\n",
1880 exp
->ordinal
, ASM_TEXT
, exp
->name
);
1884 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
1885 for (dl
= a_list
; dl
; dl
= dl
->next
)
1887 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1893 fprintf (f
, "\t.section .rdata\n");
1894 for (dl
= d_list
; dl
; dl
= dl
->next
)
1899 /* We don't output as ascii because there can
1900 be quote characters in the string. */
1902 for (p
= dl
->text
; *p
; p
++)
1905 fprintf (f
, "\t%s\t", ASM_BYTE
);
1908 fprintf (f
, "%d", *p
);
1911 fprintf (f
, ",0\n");
1925 /* Add to the output file a way of getting to the exported names
1926 without using the import library. */
1929 fprintf (f
, "\t.section\t.rdata\n");
1930 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1931 if (!exp
->noname
|| show_allnames
)
1933 /* We use a single underscore for MS compatibility, and a
1934 double underscore for backward compatibility with old
1936 if (create_compat_implib
)
1937 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1938 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1939 if (create_compat_implib
)
1940 fprintf (f
, "__imp_%s:\n", exp
->name
);
1941 fprintf (f
, "_imp__%s:\n", exp
->name
);
1942 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1946 /* Dump the reloc section if a base file is provided */
1950 long need
[PAGE_SIZE
];
1957 fprintf (f
, "\t.section\t.init\n");
1958 fprintf (f
, "lab:\n");
1960 fseek (base_file
, 0, SEEK_END
);
1961 numbytes
= ftell (base_file
);
1962 fseek (base_file
, 0, SEEK_SET
);
1963 copy
= xmalloc (numbytes
);
1964 fread (copy
, 1, numbytes
, base_file
);
1965 num_entries
= numbytes
/ sizeof (long);
1968 fprintf (f
, "\t.section\t.reloc\n");
1974 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1975 /* Delete duplcates */
1976 for (src
= 0; src
< num_entries
; src
++)
1978 if (last
!= copy
[src
])
1979 last
= copy
[dst
++] = copy
[src
];
1983 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1985 for (j
= 0; j
< num_entries
; j
++)
1988 if ((addr
& PAGE_MASK
) != page_addr
)
1990 flush_page (f
, need
, page_addr
, on_page
);
1992 page_addr
= addr
& PAGE_MASK
;
1994 need
[on_page
++] = addr
;
1996 flush_page (f
, need
, page_addr
, on_page
);
1998 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2002 generate_idata_ofile (f
);
2006 /* assemble the file */
2007 assemble_file (TMP_ASM
, exp_name
);
2009 if (dontdeltemps
== 0)
2012 inform (_("Generated exports file"));
2021 char *copy
= xmalloc (strlen (name
) + 2);
2023 strcpy (copy
+ 1, name
);
2030 p
= strchr (name
, '@');
2037 /**********************************************************************/
2046 if (exp
->noname
&& !show_allnames
)
2048 fprintf (f
, "\t%s\t0x%08x\n",
2050 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
2054 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
2072 unsigned char *data
;
2087 #define INIT_SEC_DATA(id, name, flags, align) { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2088 static sinfo secdata
[NSECS
] =
2090 INIT_SEC_DATA (TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 2),
2091 INIT_SEC_DATA (DATA
, ".data", SEC_DATA
, 2),
2092 INIT_SEC_DATA (BSS
, ".bss", 0, 2),
2093 INIT_SEC_DATA (IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2),
2094 INIT_SEC_DATA (IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2),
2095 INIT_SEC_DATA (IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2),
2096 INIT_SEC_DATA (IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1)
2101 /* Sections numbered to make the order the same as other PowerPC NT */
2102 /* compilers. This also keeps funny alignment thingies from happening. */
2115 static sinfo secdata
[NSECS
] =
2117 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
2118 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
2119 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
2120 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2121 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2122 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
2123 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2124 { DATA
, ".data", SEC_DATA
, 2},
2125 { BSS
, ".bss", 0, 2}
2131 This is what we're trying to make. We generate the imp symbols with
2132 both single and double underscores, for compatibility.
2135 .global _GetFileVersionInfoSizeW@8
2136 .global __imp_GetFileVersionInfoSizeW@8
2137 _GetFileVersionInfoSizeW@8:
2138 jmp * __imp_GetFileVersionInfoSizeW@8
2139 .section .idata$7 # To force loading of head
2140 .long __version_a_head
2141 # Import Address Table
2143 __imp_GetFileVersionInfoSizeW@8:
2146 # Import Lookup Table
2152 .asciz "GetFileVersionInfoSizeW"
2155 For the PowerPC, here's the variation on the above scheme:
2157 # Rather than a simple "jmp *", the code to get to the dll function
2160 lwz r11,[tocv]__imp_function_name(r2)
2161 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2170 make_label (prefix
, name
)
2174 int len
= strlen (ASM_PREFIX
) + strlen (prefix
) + strlen (name
);
2175 char *copy
= xmalloc (len
+1 );
2176 strcpy (copy
, ASM_PREFIX
);
2177 strcat (copy
, prefix
);
2178 strcat (copy
, name
);
2183 make_one_lib_file (exp
, i
)
2191 const char *prefix
= "d";
2194 name
= (char *) alloca (strlen (prefix
) + 10);
2195 sprintf (name
, "%ss%05d.s", prefix
, i
);
2196 f
= fopen (name
, FOPEN_WT
);
2197 fprintf (f
, "\t.text\n");
2198 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX
, exp
->name
);
2199 if (create_compat_implib
)
2200 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2201 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
2202 if (create_compat_implib
)
2203 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX
,
2204 exp
->name
, ASM_JUMP
, exp
->name
);
2206 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
2207 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
2210 fprintf (f
,"%s Import Address Table\n", ASM_C
);
2212 fprintf (f
, "\t.section .idata$5\n");
2213 if (create_compat_implib
)
2214 fprintf (f
, "__imp_%s:\n", exp
->name
);
2215 fprintf (f
, "_imp__%s:\n", exp
->name
);
2219 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
2220 fprintf (f
, "\t.section .idata$4\n");
2224 if(!exp
->noname
|| show_allnames
)
2226 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
2227 fprintf (f
, "\t.section .idata$6\n");
2228 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
2229 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
2234 dest
= (char *) alloca (strlen (prefix
) + 10);
2235 sprintf (dest
, "%ss%05d.o", prefix
, i
);
2236 assemble_file (name
, dest
);
2241 asymbol
* exp_label
;
2244 asymbol
* iname_lab
;
2245 asymbol
** iname_lab_pp
;
2246 asymbol
** iname_pp
;
2255 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2257 char * outname
= xmalloc (10);
2261 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2263 abfd
= bfd_openw (outname
, HOW_BFD_WRITE_TARGET
);
2266 /* xgettext:c-format */
2267 fatal (_("bfd_open failed open stub file: %s"), outname
);
2269 /* xgettext:c-format */
2270 inform (_("Creating stub file: %s"), outname
);
2272 bfd_set_format (abfd
, bfd_object
);
2273 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2276 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2277 bfd_set_private_flags (abfd
, F_INTERWORK
);
2280 /* First make symbols for the sections */
2281 for (i
= 0; i
< NSECS
; i
++)
2283 sinfo
*si
= secdata
+ i
;
2286 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2287 bfd_set_section_flags (abfd
,
2291 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2292 si
->sec
->output_section
= si
->sec
;
2293 si
->sym
= bfd_make_empty_symbol(abfd
);
2294 si
->sym
->name
= si
->sec
->name
;
2295 si
->sym
->section
= si
->sec
;
2296 si
->sym
->flags
= BSF_LOCAL
;
2298 ptrs
[oidx
] = si
->sym
;
2299 si
->sympp
= ptrs
+ oidx
;
2308 exp_label
= bfd_make_empty_symbol (abfd
);
2309 exp_label
->name
= make_label ("", exp
->name
);
2311 /* On PowerPC, the function name points to a descriptor in
2312 the rdata section, the first element of which is a
2313 pointer to the code (..function_name), and the second
2314 points to the .toc */
2316 if (machine
== MPPC
)
2317 exp_label
->section
= secdata
[RDATA
].sec
;
2320 exp_label
->section
= secdata
[TEXT
].sec
;
2322 exp_label
->flags
= BSF_GLOBAL
;
2323 exp_label
->value
= 0;
2326 if (machine
== MTHUMB
)
2327 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2329 ptrs
[oidx
++] = exp_label
;
2332 /* Generate imp symbols with one underscore for Microsoft
2333 compatibility, and with two underscores for backward
2334 compatibility with old versions of cygwin. */
2335 if (create_compat_implib
)
2337 iname
= bfd_make_empty_symbol (abfd
);
2338 iname
->name
= make_label ("__imp_", exp
->name
);
2339 iname
->section
= secdata
[IDATA5
].sec
;
2340 iname
->flags
= BSF_GLOBAL
;
2344 iname2
= bfd_make_empty_symbol (abfd
);
2345 iname2
->name
= make_label ("_imp__", exp
->name
);
2346 iname2
->section
= secdata
[IDATA5
].sec
;
2347 iname2
->flags
= BSF_GLOBAL
;
2350 iname_lab
= bfd_make_empty_symbol(abfd
);
2352 iname_lab
->name
= head_label
;
2353 iname_lab
->section
= (asection
*)&bfd_und_section
;
2354 iname_lab
->flags
= 0;
2355 iname_lab
->value
= 0;
2358 iname_pp
= ptrs
+ oidx
;
2359 if (create_compat_implib
)
2360 ptrs
[oidx
++] = iname
;
2361 ptrs
[oidx
++] = iname2
;
2363 iname_lab_pp
= ptrs
+ oidx
;
2364 ptrs
[oidx
++] = iname_lab
;
2367 /* The symbol refering to the code (.text) */
2369 asymbol
*function_name
;
2371 function_name
= bfd_make_empty_symbol(abfd
);
2372 function_name
->name
= make_label ("..", exp
->name
);
2373 function_name
->section
= secdata
[TEXT
].sec
;
2374 function_name
->flags
= BSF_GLOBAL
;
2375 function_name
->value
= 0;
2377 fn_pp
= ptrs
+ oidx
;
2378 ptrs
[oidx
++] = function_name
;
2381 /* The .toc symbol */
2383 asymbol
*toc_symbol
; /* The .toc symbol */
2385 toc_symbol
= bfd_make_empty_symbol (abfd
);
2386 toc_symbol
->name
= make_label (".", "toc");
2387 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2388 toc_symbol
->flags
= BSF_GLOBAL
;
2389 toc_symbol
->value
= 0;
2391 toc_pp
= ptrs
+ oidx
;
2392 ptrs
[oidx
++] = toc_symbol
;
2398 for (i
= 0; i
< NSECS
; i
++)
2400 sinfo
*si
= secdata
+ i
;
2401 asection
*sec
= si
->sec
;
2410 si
->size
= HOW_JTAB_SIZE
;
2411 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2412 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2414 /* add the reloc into idata$5 */
2415 rel
= xmalloc (sizeof (arelent
));
2417 rpp
= xmalloc (sizeof (arelent
*) * 2);
2421 rel
->address
= HOW_JTAB_ROFF
;
2424 if (machine
== MPPC
)
2426 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2427 BFD_RELOC_16_GOTOFF
);
2428 rel
->sym_ptr_ptr
= iname_pp
;
2432 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2433 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2435 sec
->orelocation
= rpp
;
2436 sec
->reloc_count
= 1;
2441 /* An idata$4 or idata$5 is one word long, and has an
2444 si
->data
= xmalloc (4);
2449 si
->data
[0] = exp
->ordinal
;
2450 si
->data
[1] = exp
->ordinal
>> 8;
2451 si
->data
[2] = exp
->ordinal
>> 16;
2456 sec
->reloc_count
= 1;
2457 memset (si
->data
, 0, si
->size
);
2458 rel
= xmalloc (sizeof (arelent
));
2459 rpp
= xmalloc (sizeof (arelent
*) * 2);
2464 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2465 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2466 sec
->orelocation
= rpp
;
2474 /* This used to add 1 to exp->hint. I don't know
2475 why it did that, and it does not match what I see
2476 in programs compiled with the MS tools. */
2477 int idx
= exp
->hint
;
2478 si
->size
= strlen (xlate (exp
->name
)) + 3;
2479 si
->data
= xmalloc (si
->size
);
2480 si
->data
[0] = idx
& 0xff;
2481 si
->data
[1] = idx
>> 8;
2482 strcpy (si
->data
+ 2, xlate (exp
->name
));
2487 si
->data
=xmalloc(4);
2488 memset (si
->data
, 0, si
->size
);
2489 rel
= xmalloc (sizeof (arelent
));
2490 rpp
= xmalloc (sizeof (arelent
*) * 2);
2494 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2495 rel
->sym_ptr_ptr
= iname_lab_pp
;
2496 sec
->orelocation
= rpp
;
2497 sec
->reloc_count
= 1;
2503 /* The .pdata section is 5 words long. */
2504 /* Think of it as: */
2507 /* bfd_vma BeginAddress, [0x00] */
2508 /* EndAddress, [0x04] */
2509 /* ExceptionHandler, [0x08] */
2510 /* HandlerData, [0x0c] */
2511 /* PrologEndAddress; [0x10] */
2514 /* So this pdata section setups up this as a glue linkage to
2515 a dll routine. There are a number of house keeping things
2518 1. In the name of glue trickery, the ADDR32 relocs for 0,
2519 4, and 0x10 are set to point to the same place:
2521 2. There is one more reloc needed in the pdata section.
2522 The actual glue instruction to restore the toc on
2523 return is saved as the offset in an IMGLUE reloc.
2524 So we need a total of four relocs for this section.
2526 3. Lastly, the HandlerData field is set to 0x03, to indicate
2527 that this is a glue routine.
2529 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2531 /* alignment must be set to 2**2 or you get extra stuff */
2532 bfd_set_section_alignment(abfd
, sec
, 2);
2535 si
->data
=xmalloc(4 * 5);
2536 memset (si
->data
, 0, si
->size
);
2537 rpp
= xmalloc (sizeof (arelent
*) * 5);
2538 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2539 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2540 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2541 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2544 /* stick the toc reload instruction in the glue reloc */
2545 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2548 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2549 BFD_RELOC_32_GOTOFF
);
2550 imglue
->sym_ptr_ptr
= fn_pp
;
2552 ba_rel
->address
= 0;
2554 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2555 ba_rel
->sym_ptr_ptr
= fn_pp
;
2557 bfd_put_32(abfd
, 0x18, si
->data
+ 0x04);
2558 ea_rel
->address
= 4;
2560 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2561 ea_rel
->sym_ptr_ptr
= fn_pp
;
2563 /* mark it as glue */
2564 bfd_put_32(abfd
, 0x03, si
->data
+ 0x0c);
2566 /* mark the prolog end address */
2567 bfd_put_32(abfd
, 0x0D, si
->data
+ 0x10);
2568 pea_rel
->address
= 0x10;
2569 pea_rel
->addend
= 0;
2570 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2571 pea_rel
->sym_ptr_ptr
= fn_pp
;
2573 sec
->orelocation
= rpp
;
2574 sec
->reloc_count
= 4;
2578 /* Each external function in a PowerPC PE file has a two word
2579 descriptor consisting of:
2580 1. The address of the code.
2581 2. The address of the appropriate .toc
2582 We use relocs to build this.
2586 si
->data
= xmalloc (8);
2587 memset (si
->data
, 0, si
->size
);
2589 rpp
= xmalloc (sizeof (arelent
*) * 3);
2590 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2591 rpp
[1] = xmalloc (sizeof (arelent
));
2596 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2597 rel
->sym_ptr_ptr
= fn_pp
;
2603 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2604 rel
->sym_ptr_ptr
= toc_pp
;
2606 sec
->orelocation
= rpp
;
2607 sec
->reloc_count
= 2;
2609 #endif /* DLLTOOL_PPC */
2615 /* Size up all the sections */
2616 for (i
= 0; i
< NSECS
; i
++)
2618 sinfo
*si
= secdata
+ i
;
2620 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2621 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2623 /* vma += si->size;*/
2626 /* Write them out */
2627 for (i
= 0; i
< NSECS
; i
++)
2629 sinfo
*si
= secdata
+ i
;
2631 if (i
== IDATA5
&& no_idata5
)
2634 if (i
== IDATA4
&& no_idata4
)
2637 bfd_set_section_contents (abfd
, si
->sec
,
2642 bfd_set_symtab (abfd
, ptrs
, oidx
);
2644 abfd
= bfd_openr (outname
, HOW_BFD_READ_TARGET
);
2653 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2657 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2661 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2662 fprintf (f
, "\t.section .idata$2\n");
2664 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2666 fprintf (f
, "%s:\n", head_label
);
2668 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2669 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2671 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2672 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2673 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2674 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2675 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2680 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2682 ASM_RVA_AFTER
, ASM_C
);
2684 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2688 fprintf (f
, "\t.section\t.idata$5\n");
2689 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2690 fprintf (f
, "fthunk:\n");
2695 fprintf (f
, "\t.section\t.idata$4\n");
2697 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2698 fprintf (f
, "\t.section .idata$4\n");
2699 fprintf (f
, "hname:\n");
2704 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2706 return bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2712 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2716 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2722 fprintf (f
, "\t.section .idata$4\n");
2723 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2728 fprintf (f
, "\t.section .idata$5\n");
2729 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2733 /* Normally, we need to see a null descriptor built in idata$3 to
2734 act as the terminator for the list. The ideal way, I suppose,
2735 would be to mark this section as a comdat type 2 section, so
2736 only one would appear in the final .exe (if our linker supported
2737 comdat, that is) or cause it to be inserted by something else (say
2741 fprintf (f
, "\t.section .idata$3\n");
2742 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2743 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2744 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2745 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2746 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2750 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2751 do too. Original, huh? */
2752 fprintf (f
, "\t.section .idata$6\n");
2754 fprintf (f
, "\t.section .idata$7\n");
2757 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2758 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2759 imp_name_lab
, ASM_TEXT
, dll_name
);
2763 assemble_file (TMP_TAIL_S
, TMP_TAIL_O
);
2765 return bfd_openr (TMP_TAIL_O
, HOW_BFD_READ_TARGET
);
2780 outarch
= bfd_openw (imp_name
, HOW_BFD_WRITE_TARGET
);
2783 /* xgettext:c-format */
2784 fatal (_("Can't open .lib file: %s"), imp_name
);
2786 /* xgettext:c-format */
2787 inform (_("Creating library file: %s\n"), imp_name
);
2789 bfd_set_format (outarch
, bfd_archive
);
2790 outarch
->has_armap
= 1;
2792 /* Work out a reasonable size of things to put onto one line. */
2794 ar_head
= make_head ();
2795 ar_tail
= make_tail();
2797 if (ar_head
== NULL
|| ar_tail
== NULL
)
2800 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2802 bfd
*n
= make_one_lib_file (exp
, i
);
2807 /* Now stick them all into the archive */
2809 ar_head
->next
= head
;
2810 ar_tail
->next
= ar_head
;
2813 if (! bfd_set_archive_head (outarch
, head
))
2814 bfd_fatal ("bfd_set_archive_head");
2816 if (! bfd_close (outarch
))
2817 bfd_fatal (imp_name
);
2819 while (head
!= NULL
)
2821 bfd
*n
= head
->next
;
2826 /* Delete all the temp files */
2828 if (dontdeltemps
== 0)
2830 unlink (TMP_HEAD_O
);
2831 unlink (TMP_HEAD_S
);
2832 unlink (TMP_TAIL_O
);
2833 unlink (TMP_TAIL_S
);
2836 if (dontdeltemps
< 2)
2840 name
= (char *) alloca (sizeof TMP_STUB
+ 10);
2841 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
2843 sprintf (name
, "%s%05d.o", TMP_STUB
, i
);
2844 if (unlink (name
) < 0)
2845 /* xgettext:c-format */
2846 warn (_("cannot delete %s: %s\n"), name
, strerror (errno
));
2850 inform (_("Created lib file"));
2853 /**********************************************************************/
2855 /* Run through the information gathered from the .o files and the
2856 .def file and work out the best stuff */
2862 export_type
*ap
= *(export_type
**) a
;
2863 export_type
*bp
= *(export_type
**) b
;
2864 if (ap
->ordinal
== bp
->ordinal
)
2867 /* unset ordinals go to the bottom */
2868 if (ap
->ordinal
== -1)
2870 if (bp
->ordinal
== -1)
2872 return (ap
->ordinal
- bp
->ordinal
);
2880 export_type
*ap
= *(export_type
**) a
;
2881 export_type
*bp
= *(export_type
**) b
;
2883 return (strcmp (ap
->name
, bp
->name
));
2887 remove_null_names (ptr
)
2892 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2896 ptr
[dst
] = ptr
[src
];
2913 for (i
= 0; i
< d_nfuncs
; i
++)
2917 printf ("%d %s @ %d %s%s%s\n",
2918 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2919 ptr
[i
]->noname
? "NONAME " : "",
2920 ptr
[i
]->constant
? "CONSTANT" : "",
2921 ptr
[i
]->data
? "DATA" : "");
2930 process_duplicates (d_export_vec
)
2931 export_type
**d_export_vec
;
2939 /* Remove duplicates */
2940 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2942 dtab (d_export_vec
);
2943 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2945 if (strcmp (d_export_vec
[i
]->name
,
2946 d_export_vec
[i
+ 1]->name
) == 0)
2949 export_type
*a
= d_export_vec
[i
];
2950 export_type
*b
= d_export_vec
[i
+ 1];
2954 /* xgettext:c-format */
2955 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2956 a
->name
, a
->ordinal
, b
->ordinal
);
2958 if (a
->ordinal
!= -1
2959 && b
->ordinal
!= -1)
2960 /* xgettext:c-format */
2961 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2964 /* Merge attributes */
2965 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2966 b
->constant
|= a
->constant
;
2967 b
->noname
|= a
->noname
;
2969 d_export_vec
[i
] = 0;
2972 dtab (d_export_vec
);
2973 remove_null_names (d_export_vec
);
2974 dtab (d_export_vec
);
2979 /* Count the names */
2980 for (i
= 0; i
< d_nfuncs
; i
++)
2982 if (!d_export_vec
[i
]->noname
)
2988 fill_ordinals (d_export_vec
)
2989 export_type
**d_export_vec
;
2996 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2998 /* fill in the unset ordinals with ones from our range */
3000 ptr
= (char *) xmalloc (size
);
3002 memset (ptr
, 0, size
);
3004 /* Mark in our large vector all the numbers that are taken */
3005 for (i
= 0; i
< d_nfuncs
; i
++)
3007 if (d_export_vec
[i
]->ordinal
!= -1)
3009 ptr
[d_export_vec
[i
]->ordinal
] = 1;
3010 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
3012 lowest
= d_export_vec
[i
]->ordinal
;
3017 /* Start at 1 for compatibility with MS toolchain. */
3021 /* Now fill in ordinals where the user wants us to choose. */
3022 for (i
= 0; i
< d_nfuncs
; i
++)
3024 if (d_export_vec
[i
]->ordinal
== -1)
3028 /* First try within or after any user supplied range. */
3029 for (j
= lowest
; j
< size
; j
++)
3033 d_export_vec
[i
]->ordinal
= j
;
3037 /* Then try before the range. */
3038 for (j
= lowest
; j
>0; j
--)
3042 d_export_vec
[i
]->ordinal
= j
;
3053 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3055 /* Work out the lowest and highest ordinal numbers. */
3058 if (d_export_vec
[0])
3059 d_low_ord
= d_export_vec
[0]->ordinal
;
3060 if (d_export_vec
[d_nfuncs
-1])
3061 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3070 const export_type
**a
= (const export_type
**) av
;
3071 const export_type
**b
= (const export_type
**) bv
;
3073 return strcmp ((*a
)->name
, (*b
)->name
);
3079 /* First work out the minimum ordinal chosen */
3085 export_type
**d_export_vec
3086 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
3088 inform (_("Processing definitions"));
3090 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3092 d_export_vec
[i
] = exp
;
3095 process_duplicates (d_export_vec
);
3096 fill_ordinals (d_export_vec
);
3098 /* Put back the list in the new order */
3100 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3102 d_export_vec
[i
]->next
= d_exports
;
3103 d_exports
= d_export_vec
[i
];
3106 /* Build list in alpha order */
3107 d_exports_lexically
= (export_type
**)
3108 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3110 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3112 d_exports_lexically
[i
] = exp
;
3114 d_exports_lexically
[i
] = 0;
3116 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
3118 /* Fill exp entries with their hint values */
3120 for (i
= 0; i
< d_nfuncs
; i
++)
3122 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3123 d_exports_lexically
[i
]->hint
= hint
++;
3126 inform (_("Processed definitions"));
3129 /**********************************************************************/
3132 usage (file
, status
)
3136 /* xgetext:c-format */
3137 fprintf (file
, _("Usage %s <options> <object-files>\n"), program_name
);
3138 /* xgetext:c-format */
3139 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3140 fprintf (file
, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
3141 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3142 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3143 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3144 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3145 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3146 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3147 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3148 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3149 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3150 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3151 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3152 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3153 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3154 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
3155 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3156 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3157 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3158 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3159 fprintf (file
, _(" -C --compat-implib Create backward compatible import library.\n"));
3160 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3161 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3162 fprintf (file
, _(" -V --version Display the program version.\n"));
3163 fprintf (file
, _(" -h --help Display this information.\n"));
3164 #ifdef DLLTOOL_MCORE_ELF
3165 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3166 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3167 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3172 #define OPTION_EXPORT_ALL_SYMS 150
3173 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3174 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3175 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3177 static const struct option long_options
[] =
3179 {"no-delete", no_argument
, NULL
, 'n'},
3180 {"dllname", required_argument
, NULL
, 'D'},
3181 {"no-idata4", no_argument
, NULL
, 'x'},
3182 {"no-idata5", no_argument
, NULL
, 'c'},
3183 {"output-exp", required_argument
, NULL
, 'e'},
3184 {"output-def", required_argument
, NULL
, 'z'},
3185 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3186 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3187 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3188 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3189 {"output-lib", required_argument
, NULL
, 'l'},
3190 {"def", required_argument
, NULL
, 'd'}, /* for compatiblity with older versions */
3191 {"input-def", required_argument
, NULL
, 'd'},
3192 {"add-underscore", no_argument
, NULL
, 'U'},
3193 {"kill-at", no_argument
, NULL
, 'k'},
3194 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3195 {"verbose", no_argument
, NULL
, 'v'},
3196 {"version", no_argument
, NULL
, 'V'},
3197 {"help", no_argument
, NULL
, 'h'},
3198 {"machine", required_argument
, NULL
, 'm'},
3199 {"add-indirect", no_argument
, NULL
, 'a'},
3200 {"base-file", required_argument
, NULL
, 'b'},
3201 {"as", required_argument
, NULL
, 'S'},
3202 {"as-flags", required_argument
, NULL
, 'f'},
3203 {"mcore-elf", required_argument
, NULL
, 'M'},
3204 {"compat-implib", no_argument
, NULL
, 'C'},
3216 program_name
= av
[0];
3219 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3220 setlocale (LC_MESSAGES
, "");
3222 bindtextdomain (PACKAGE
, LOCALEDIR
);
3223 textdomain (PACKAGE
);
3225 while ((c
= getopt_long (ac
, av
,
3226 #ifdef DLLTOOL_MCORE_ELF
3227 "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVhM:L:F:",
3229 "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVh",
3236 case OPTION_EXPORT_ALL_SYMS
:
3237 export_all_symbols
= true;
3239 case OPTION_NO_EXPORT_ALL_SYMS
:
3240 export_all_symbols
= false;
3242 case OPTION_EXCLUDE_SYMS
:
3243 add_excludes (optarg
);
3245 case OPTION_NO_DEFAULT_EXCLUDES
:
3246 do_default_excludes
= false;
3261 /* ignored for compatibility */
3268 output_def
= fopen (optarg
, FOPEN_WT
);
3289 print_version (program_name
);
3298 add_stdcall_alias
= 1;
3307 base_file
= fopen (optarg
, FOPEN_RB
);
3310 /* xgettext:c-format */
3311 fatal (_("Unable to open base-file: %s"), optarg
);
3314 #ifdef DLLTOOL_MCORE_ELF
3316 mcore_elf_out_file
= optarg
;
3319 mcore_elf_linker
= optarg
;
3322 mcore_elf_linker_flags
= optarg
;
3326 create_compat_implib
= 1;
3334 for (i
= 0; mtable
[i
].type
; i
++)
3335 if (strcmp (mtable
[i
].type
, mname
) == 0)
3338 if (!mtable
[i
].type
)
3339 /* xgettext:c-format */
3340 fatal (_("Machine '%s' not supported"), mname
);
3344 if (!dll_name
&& exp_name
)
3346 int len
= strlen (exp_name
) + 5;
3347 dll_name
= xmalloc (len
);
3348 strcpy (dll_name
, exp_name
);
3349 strcat (dll_name
, ".dll");
3352 if (as_name
== NULL
)
3353 as_name
= deduce_name ("as");
3355 /* Don't use the default exclude list if we're reading only the
3356 symbols in the .drectve section. The default excludes are meant
3357 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3358 if (! export_all_symbols
)
3359 do_default_excludes
= false;
3361 if (do_default_excludes
)
3362 set_default_excludes ();
3365 process_def_file (def_file
);
3370 firstarg
= av
[optind
];
3371 scan_obj_file (av
[optind
]);
3382 /* Make imp_name safe for use as a label. */
3385 imp_name_lab
= xstrdup (imp_name
);
3386 for (p
= imp_name_lab
; *p
; p
++)
3388 if (!isalpha ((unsigned char) *p
) && !isdigit ((unsigned char) *p
))
3391 head_label
= make_label("_head_", imp_name_lab
);
3398 #ifdef DLLTOOL_MCORE_ELF
3399 if (mcore_elf_out_file
)
3400 mcore_elf_gen_out_file ();
3406 /* Look for the program formed by concatenating PROG_NAME and the
3407 string running from PREFIX to END_PREFIX. If the concatenated
3408 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
3412 look_for_prog (prog_name
, prefix
, end_prefix
)
3413 const char *prog_name
;
3420 cmd
= xmalloc (strlen (prefix
)
3421 + strlen (prog_name
)
3422 #ifdef HAVE_EXECUTABLE_SUFFIX
3423 + strlen (EXECUTABLE_SUFFIX
)
3426 strcpy (cmd
, prefix
);
3428 sprintf (cmd
+ end_prefix
, "%s", prog_name
);
3430 if (strchr (cmd
, '/') != NULL
)
3434 found
= (stat (cmd
, &s
) == 0
3435 #ifdef HAVE_EXECUTABLE_SUFFIX
3436 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
3442 /* xgettext:c-format */
3443 inform (_("Tried file: %s"), cmd
);
3449 /* xgettext:c-format */
3450 inform (_("Using file: %s"), cmd
);
3455 /* Deduce the name of the program we are want to invoke.
3456 PROG_NAME is the basic name of the program we want to run,
3457 eg "as" or "ld". The catch is that we might want actually
3458 run "i386-pe-as" or "ppc-pe-ld".
3460 If argv[0] contains the full path, then try to find the program
3461 in the same place, with and then without a target-like prefix.
3463 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
3464 deduce_name("as") uses the following search order:
3466 /usr/local/bin/i586-cygwin32-as
3470 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3471 name, it'll try without and then with EXECUTABLE_SUFFIX.
3473 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3474 as the fallback, but rather return i586-cygwin32-as.
3476 Oh, and given, argv[0] = dlltool, it'll return "as".
3478 Returns a dynamically allocated string. */
3481 deduce_name (prog_name
)
3482 const char *prog_name
;
3485 char *dash
, *slash
, *cp
;
3489 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
3494 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3495 *cp
== ':' || *cp
== '\\' ||
3508 /* First, try looking for a prefixed PROG_NAME in the
3509 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
3510 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
3513 if (slash
!= NULL
&& cmd
== NULL
)
3515 /* Next, try looking for a PROG_NAME in the same directory as
3516 that of this program. */
3517 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
3522 /* Just return PROG_NAME as is. */
3523 cmd
= xstrdup (prog_name
);
3529 #ifdef DLLTOOL_MCORE_ELF
3530 typedef struct fname_cache
3533 struct fname_cache
* next
;
3537 static fname_cache fnames
;
3540 mcore_elf_cache_filename (char * filename
)
3546 while (ptr
->next
!= NULL
)
3549 ptr
->filename
= filename
;
3550 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
3551 if (ptr
->next
!= NULL
)
3552 ptr
->next
->next
= NULL
;
3555 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3556 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3557 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3560 mcore_elf_gen_out_file (void)
3565 /* Step one. Run 'ld -r' on the input object files in order to resolve
3566 any internal references and to generate a single .exports section. */
3569 ds
= dyn_string_new (100);
3570 dyn_string_append (ds
, "-r ");
3572 if (mcore_elf_linker_flags
!= NULL
)
3573 dyn_string_append (ds
, mcore_elf_linker_flags
);
3575 while (ptr
->next
!= NULL
)
3577 dyn_string_append (ds
, ptr
->filename
);
3578 dyn_string_append (ds
, " ");
3583 dyn_string_append (ds
, "-o ");
3584 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3586 if (mcore_elf_linker
== NULL
)
3587 mcore_elf_linker
= deduce_name ("ld");
3589 run (mcore_elf_linker
, ds
->s
);
3591 dyn_string_delete (ds
);
3593 /* Step two. Create a .exp file and a .lib file from the temporary file.
3594 Do this by recursively invoking dlltool....*/
3595 ds
= dyn_string_new (100);
3597 dyn_string_append (ds
, "-S ");
3598 dyn_string_append (ds
, as_name
);
3600 dyn_string_append (ds
, " -e ");
3601 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3602 dyn_string_append (ds
, " -l ");
3603 dyn_string_append (ds
, MCORE_ELF_TMP_LIB
);
3604 dyn_string_append (ds
, " " );
3605 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3608 dyn_string_append (ds
, " -v");
3612 dyn_string_append (ds
, " -n");
3614 if (dontdeltemps
> 1)
3615 dyn_string_append (ds
, " -n");
3618 /* XXX - FIME: ought to check/copy other command line options as well. */
3620 run (program_name
, ds
->s
);
3622 dyn_string_delete (ds
);
3624 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
3625 ds
= dyn_string_new (100);
3627 dyn_string_append (ds
, "-shared ");
3629 if (mcore_elf_linker_flags
)
3630 dyn_string_append (ds
, mcore_elf_linker_flags
);
3632 dyn_string_append (ds
, " ");
3633 dyn_string_append (ds
, MCORE_ELF_TMP_EXP
);
3634 dyn_string_append (ds
, " ");
3635 dyn_string_append (ds
, MCORE_ELF_TMP_OBJ
);
3636 dyn_string_append (ds
, " -o ");
3637 dyn_string_append (ds
, mcore_elf_out_file
);
3639 run (mcore_elf_linker
, ds
->s
);
3641 dyn_string_delete (ds
);
3643 if (dontdeltemps
== 0)
3644 unlink (MCORE_ELF_TMP_EXP
);
3646 if (dontdeltemps
< 2)
3647 unlink (MCORE_ELF_TMP_OBJ
);
3649 #endif /* DLLTOOL_MCORE_ELF */