1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 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> ] )
51 | ( <name1> = <module-name> . <external-name>))
52 [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
53 Declares name1 as an exported symbol from the
54 DLL, with optional ordinal number <integer>.
55 Or declares name1 as an alias (forward) of the function <external-name>
56 in the DLL <module-name>.
58 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
59 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
60 Declares that <external-name> or the exported function whoes ordinal number
61 is <integer> is to be imported from the file <module-name>. If
62 <internal-name> is specified then this is the name that the imported
63 function will be refereed to in the body of the DLL.
66 Puts <string> into output .exp file in the .rdata section
68 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
69 Generates --stack|--heap <number-reserve>,<number-commit>
70 in the output .drectve section. The linker will
71 see this and act upon it.
74 SECTIONS ( <sectionname> <attr>+ )*
75 <attr> = READ | WRITE | EXECUTE | SHARED
76 Generates --attr <sectionname> <attr> in the output
77 .drectve section. The linker will see this and act
81 A -export:<name> in a .drectve section in an input .o or .a
82 file to this program is equivalent to a EXPORTS <name>
87 The program generates output files with the prefix supplied
88 on the command line, or in the def file, or taken from the first
91 The .exp.s file contains the information necessary to export
92 the routines in the DLL. The .lib.s file contains the information
93 necessary to use the DLL's routines from a referencing program.
100 asm (".section .drectve");
101 asm (".ascii \"-export:adef\"");
105 printf ("hello from the dll %s\n", s);
110 printf ("hello from the dll and the other entry point %s\n", s);
114 asm (".section .drectve");
115 asm (".ascii \"-export:cdef\"");
116 asm (".ascii \"-export:ddef\"");
120 printf ("hello from the dll %s\n", s);
125 printf ("hello from the dll and the other entry point %s\n", s);
143 HEAPSIZE 0x40000, 0x2000
147 SECTIONS donkey READ WRITE
150 # Compile up the parts of the dll and the program
152 gcc -c file1.c file2.c themain.c
154 # Optional: put the dll objects into a library
155 # (you don't have to, you could name all the object
156 # files on the dlltool line)
158 ar qcv thedll.in file1.o file2.o
161 # Run this tool over the DLL's .def file and generate an exports
162 # file (thedll.o) and an imports file (thedll.a).
163 # (You may have to use -S to tell dlltool where to find the assembler).
165 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
167 # Build the dll with the library and the export table
169 ld -o thedll.dll thedll.o thedll.in
171 # Link the executable with the import library
173 gcc -o themain.exe themain.o thedll.a
175 This example can be extended if relocations are needed in the DLL:
177 # Compile up the parts of the dll and the program
179 gcc -c file1.c file2.c themain.c
181 # Run this tool over the DLL's .def file and generate an imports file.
183 dlltool --def thedll.def --output-lib thedll.lib
185 # Link the executable with the import library and generate a base file
188 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
190 # Run this tool over the DLL's .def file and generate an exports file
191 # which includes the relocations from the base file.
193 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
195 # Build the dll with file1.o, file2.o and the export table
197 ld -o thedll.dll thedll.exp file1.o file2.o */
199 /* .idata section description
201 The .idata section is the import table. It is a collection of several
202 subsections used to keep the pieces for each dll together: .idata$[234567].
203 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
205 .idata$2 = Import Directory Table
206 = array of IMAGE_IMPORT_DESCRIPTOR's.
208 DWORD Import Lookup Table; - pointer to .idata$4
209 DWORD TimeDateStamp; - currently always 0
210 DWORD ForwarderChain; - currently always 0
211 DWORD Name; - pointer to dll's name
212 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
214 .idata$3 = null terminating entry for .idata$2.
216 .idata$4 = Import Lookup Table
217 = array of array of pointers to hint name table.
218 There is one for each dll being imported from, and each dll's set is
219 terminated by a trailing NULL.
221 .idata$5 = Import Address Table
222 = array of array of pointers to hint name table.
223 There is one for each dll being imported from, and each dll's set is
224 terminated by a trailing NULL.
225 Initially, this table is identical to the Import Lookup Table. However,
226 at load time, the loader overwrites the entries with the address of the
229 .idata$6 = Hint Name Table
230 = Array of { short, asciz } entries, one for each imported function.
231 The `short' is the function's ordinal number.
233 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
235 /* AIX requires this to be the first thing in the file. */
242 #define show_allnames 0
244 #define PAGE_SIZE 4096
245 #define PAGE_MASK (-PAGE_SIZE)
247 #include "libiberty.h"
250 #include "demangle.h"
251 #include "dyn-string.h"
253 #include "safe-ctype.h"
256 #include <sys/stat.h>
258 #ifdef ANSI_PROTOTYPES
265 #include "coff/arm.h"
266 #include "coff/internal.h"
269 /* Forward references. */
270 static char *look_for_prog (const char *, const char *, int);
271 static char *deduce_name (const char *);
273 #ifdef DLLTOOL_MCORE_ELF
274 static void mcore_elf_cache_filename (char *);
275 static void mcore_elf_gen_out_file (void);
278 #ifdef HAVE_SYS_WAIT_H
279 #include <sys/wait.h>
280 #else /* ! HAVE_SYS_WAIT_H */
281 #if ! defined (_WIN32) || defined (__CYGWIN32__)
283 #define WIFEXITED(w) (((w) & 0377) == 0)
286 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
289 #define WTERMSIG(w) ((w) & 0177)
292 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
294 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
296 #define WIFEXITED(w) (((w) & 0xff) == 0)
299 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
302 #define WTERMSIG(w) ((w) & 0x7f)
305 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
307 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308 #endif /* ! HAVE_SYS_WAIT_H */
310 /* ifunc and ihead data structures: ttk@cygnus.com 1997
312 When IMPORT declarations are encountered in a .def file the
313 function import information is stored in a structure referenced by
314 the global variable IMPORT_LIST. The structure is a linked list
315 containing the names of the dll files each function is imported
316 from and a linked list of functions being imported from that dll
317 file. This roughly parallels the structure of the .idata section
318 in the PE object file.
320 The contents of .def file are interpreted from within the
321 process_def_file function. Every time an IMPORT declaration is
322 encountered, it is broken up into its component parts and passed to
323 def_import. IMPORT_LIST is initialized to NULL in function main. */
325 typedef struct ifunct
327 char * name
; /* Name of function being imported. */
328 int ord
; /* Two-byte ordinal value associated with function. */
332 typedef struct iheadt
334 char *dllname
; /* Name of dll file imported from. */
335 long nfuncs
; /* Number of functions in list. */
336 struct ifunct
*funchead
; /* First function in list. */
337 struct ifunct
*functail
; /* Last function in list. */
338 struct iheadt
*next
; /* Next dll file in list. */
341 /* Structure containing all import information as defined in .def file
342 (qv "ihead structure"). */
344 static iheadtype
*import_list
= NULL
;
346 static char *as_name
= NULL
;
347 static char * as_flags
= "";
349 static char *tmp_prefix
;
351 static int no_idata4
;
352 static int no_idata5
;
353 static char *exp_name
;
354 static char *imp_name
;
355 static char *head_label
;
356 static char *imp_name_lab
;
357 static char *dll_name
;
359 static int add_indirect
= 0;
360 static int add_underscore
= 0;
361 static int dontdeltemps
= 0;
363 /* TRUE if we should export all symbols. Otherwise, we only export
364 symbols listed in .drectve sections or in the def file. */
365 static bfd_boolean export_all_symbols
;
367 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
368 exporting all symbols. */
369 static bfd_boolean do_default_excludes
= TRUE
;
371 /* Default symbols to exclude when exporting all the symbols. */
372 static const char *default_excludes
= "DllMain@12,DllEntryPoint@0,impure_ptr";
374 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
375 compatibility to old Cygwin releases. */
376 static bfd_boolean create_compat_implib
;
378 static char *def_file
;
380 extern char * program_name
;
384 static int add_stdcall_alias
;
386 static FILE *output_def
;
387 static FILE *base_file
;
390 #ifdef DLLTOOL_ARM_EPOC
391 static const char *mname
= "arm-epoc";
393 static const char *mname
= "arm";
398 static const char *mname
= "i386";
402 static const char *mname
= "ppc";
406 static const char *mname
= "sh";
410 static const char *mname
= "mips";
414 static const char * mname
= "mcore-le";
417 #ifdef DLLTOOL_MCORE_ELF
418 static const char * mname
= "mcore-elf";
419 static char * mcore_elf_out_file
= NULL
;
420 static char * mcore_elf_linker
= NULL
;
421 static char * mcore_elf_linker_flags
= NULL
;
423 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
426 #ifndef DRECTVE_SECTION_NAME
427 #define DRECTVE_SECTION_NAME ".drectve"
430 #define PATHMAX 250 /* What's the right name for this ? */
433 char *tmp_head_s_buf
;
434 char *tmp_head_o_buf
;
435 char *tmp_tail_s_buf
;
436 char *tmp_tail_o_buf
;
439 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
440 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
441 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
442 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
443 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
444 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ss")
446 /* This bit of assembly does jmp * .... */
447 static const unsigned char i386_jtab
[] =
449 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
452 static const unsigned char arm_jtab
[] =
454 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
455 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
459 static const unsigned char arm_interwork_jtab
[] =
461 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
462 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
463 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
467 static const unsigned char thumb_jtab
[] =
469 0x40, 0xb4, /* push {r6} */
470 0x02, 0x4e, /* ldr r6, [pc, #8] */
471 0x36, 0x68, /* ldr r6, [r6] */
472 0xb4, 0x46, /* mov ip, r6 */
473 0x40, 0xbc, /* pop {r6} */
474 0x60, 0x47, /* bx ip */
478 static const unsigned char mcore_be_jtab
[] =
480 0x71, 0x02, /* lrw r1,2 */
481 0x81, 0x01, /* ld.w r1,(r1,0) */
482 0x00, 0xC1, /* jmp r1 */
483 0x12, 0x00, /* nop */
484 0x00, 0x00, 0x00, 0x00 /* <address> */
487 static const unsigned char mcore_le_jtab
[] =
489 0x02, 0x71, /* lrw r1,2 */
490 0x01, 0x81, /* ld.w r1,(r1,0) */
491 0xC1, 0x00, /* jmp r1 */
492 0x00, 0x12, /* nop */
493 0x00, 0x00, 0x00, 0x00 /* <address> */
496 /* This is the glue sequence for PowerPC PE. There is a
497 tocrel16-tocdefn reloc against the first instruction.
498 We also need a IMGLUE reloc against the glue function
499 to restore the toc saved by the third instruction in
501 static const unsigned char ppc_jtab
[] =
503 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
504 /* Reloc TOCREL16 __imp_xxx */
505 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
506 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
507 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
508 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
509 0x20, 0x04, 0x80, 0x4E /* bctr */
513 /* The glue instruction, picks up the toc from the stw in
514 the above code: "lwz r2,4(r1)". */
515 static bfd_vma ppc_glue_insn
= 0x80410004;
521 const char *how_byte
;
522 const char *how_short
;
523 const char *how_long
;
524 const char *how_asciz
;
525 const char *how_comment
;
526 const char *how_jump
;
527 const char *how_global
;
528 const char *how_space
;
529 const char *how_align_short
;
530 const char *how_align_long
;
531 const char *how_default_as_switches
;
532 const char *how_bfd_target
;
533 enum bfd_architecture how_bfd_arch
;
534 const unsigned char *how_jtab
;
535 int how_jtab_size
; /* Size of the jtab entry. */
536 int how_jtab_roff
; /* Offset into it for the ind 32 reloc into idata 5. */
539 static const struct mac
544 "arm", ".byte", ".short", ".long", ".asciz", "@",
545 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
546 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
547 "pe-arm-little", bfd_arch_arm
,
548 arm_jtab
, sizeof (arm_jtab
), 8
553 "i386", ".byte", ".short", ".long", ".asciz", "#",
554 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
555 "pe-i386",bfd_arch_i386
,
556 i386_jtab
, sizeof (i386_jtab
), 2
561 "ppc", ".byte", ".short", ".long", ".asciz", "#",
562 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
563 "pe-powerpcle",bfd_arch_powerpc
,
564 ppc_jtab
, sizeof (ppc_jtab
), 0
569 "thumb", ".byte", ".short", ".long", ".asciz", "@",
570 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
571 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
572 "pe-arm-little", bfd_arch_arm
,
573 thumb_jtab
, sizeof (thumb_jtab
), 12
576 #define MARM_INTERWORK 4
578 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
579 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
580 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
581 "pe-arm-little", bfd_arch_arm
,
582 arm_interwork_jtab
, sizeof (arm_interwork_jtab
), 12
587 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
588 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
589 ".global", ".space", ".align\t2",".align\t4", "",
590 "pe-mcore-big", bfd_arch_mcore
,
591 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
596 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
597 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
598 ".global", ".space", ".align\t2",".align\t4", "-EL",
599 "pe-mcore-little", bfd_arch_mcore
,
600 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
605 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
606 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
607 ".global", ".space", ".align\t2",".align\t4", "",
608 "elf32-mcore-big", bfd_arch_mcore
,
609 mcore_be_jtab
, sizeof (mcore_be_jtab
), 8
613 #define MMCORE_ELF_LE 8
614 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
615 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
616 ".global", ".space", ".align\t2",".align\t4", "-EL",
617 "elf32-mcore-little", bfd_arch_mcore
,
618 mcore_le_jtab
, sizeof (mcore_le_jtab
), 8
623 "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
624 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
625 ".global", ".space", ".align\t2",".align\t4", "",
626 "epoc-pe-arm-little", bfd_arch_arm
,
627 arm_jtab
, sizeof (arm_jtab
), 8
630 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
640 typedef struct export
643 const char *internal_name
;
646 int noname
; /* Don't put name in image file. */
647 int private; /* Don't put reference in import lib. */
650 int forward
; /* Number of forward label, 0 means no forward. */
655 /* A list of symbols which we should not export. */
659 struct string_list
*next
;
663 static struct string_list
*excludes
;
665 static const char *rvaafter (int);
666 static const char *rvabefore (int);
667 static const char *asm_prefix (int, const char *);
668 static void process_def_file (const char *);
669 static void new_directive (char *);
670 static void append_import (const char *, const char *, int);
671 static void run (const char *, char *);
672 static void scan_drectve_symbols (bfd
*);
673 static void scan_filtered_symbols (bfd
*, void *, long, unsigned int);
674 static void add_excludes (const char *);
675 static bfd_boolean
match_exclude (const char *);
676 static void set_default_excludes (void);
677 static long filter_symbols (bfd
*, void *, long, unsigned int);
678 static void scan_all_symbols (bfd
*);
679 static void scan_open_obj_file (bfd
*);
680 static void scan_obj_file (const char *);
681 static void dump_def_info (FILE *);
682 static int sfunc (const void *, const void *);
683 static void flush_page (FILE *, long *, int, int);
684 static void gen_def_file (void);
685 static void generate_idata_ofile (FILE *);
686 static void assemble_file (const char *, const char *);
687 static void gen_exp_file (void);
688 static const char *xlate (const char *);
690 static void dump_iat (FILE *, export_type
*);
692 static char *make_label (const char *, const char *);
693 static char *make_imp_label (const char *, const char *);
694 static bfd
*make_one_lib_file (export_type
*, int);
695 static bfd
*make_head (void);
696 static bfd
*make_tail (void);
697 static void gen_lib_file (void);
698 static int pfunc (const void *, const void *);
699 static int nfunc (const void *, const void *);
700 static void remove_null_names (export_type
**);
701 static void dtab (export_type
**);
702 static void process_duplicates (export_type
**);
703 static void fill_ordinals (export_type
**);
704 static int alphafunc (const void *, const void *);
705 static void mangle_defs (void);
706 static void usage (FILE *, int);
707 static void inform (const char *, ...);
710 prefix_encode (char *start
, unsigned code
)
712 static char alpha
[26] = "abcdefghijklmnopqrstuvwxyz";
716 p
= strchr (buf
, '\0');
718 *p
++ = alpha
[code
% sizeof (alpha
)];
719 while ((code
/= sizeof (alpha
)) != 0);
725 dlltmp (char **buf
, const char *fmt
)
729 *buf
= malloc (strlen (tmp_prefix
) + 64);
730 sprintf (*buf
, fmt
, tmp_prefix
);
736 inform
VPARAMS ((const char * message
, ...))
738 VA_OPEN (args
, message
);
739 VA_FIXEDARG (args
, const char *, message
);
744 report (message
, args
);
750 rvaafter (int machine
)
766 /* xgettext:c-format */
767 fatal (_("Internal error: Unknown machine type: %d"), machine
);
774 rvabefore (int machine
)
790 /* xgettext:c-format */
791 fatal (_("Internal error: Unknown machine type: %d"), machine
);
798 asm_prefix (int machine
, const char *name
)
813 /* Symbol names starting with ? do not have a leading underscore. */
814 if (name
&& *name
== '?')
819 /* xgettext:c-format */
820 fatal (_("Internal error: Unknown machine type: %d"), machine
);
826 #define ASM_BYTE mtable[machine].how_byte
827 #define ASM_SHORT mtable[machine].how_short
828 #define ASM_LONG mtable[machine].how_long
829 #define ASM_TEXT mtable[machine].how_asciz
830 #define ASM_C mtable[machine].how_comment
831 #define ASM_JUMP mtable[machine].how_jump
832 #define ASM_GLOBAL mtable[machine].how_global
833 #define ASM_SPACE mtable[machine].how_space
834 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
835 #define ASM_RVA_BEFORE rvabefore (machine)
836 #define ASM_RVA_AFTER rvaafter (machine)
837 #define ASM_PREFIX(NAME) asm_prefix (machine, (NAME))
838 #define ASM_ALIGN_LONG mtable[machine].how_align_long
839 #define HOW_BFD_READ_TARGET 0 /* Always default. */
840 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
841 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
842 #define HOW_JTAB mtable[machine].how_jtab
843 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
844 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
845 #define ASM_SWITCHES mtable[machine].how_default_as_switches
850 process_def_file (const char *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. */
881 static int d_nforwards
= 0; /* Number of forwarded exports. */
887 yyerror (const char * err ATTRIBUTE_UNUSED
)
889 /* xgettext:c-format */
890 non_fatal (_("Syntax error in def file %s:%d"), def_file
, linenumber
);
896 def_exports (const char *name
, const char *internal_name
, int ordinal
,
897 int noname
, int constant
, int data
, int private)
899 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
902 p
->internal_name
= internal_name
? internal_name
: name
;
903 p
->ordinal
= ordinal
;
904 p
->constant
= constant
;
906 p
->private = private;
912 if ((internal_name
!= NULL
)
913 && (strchr (internal_name
, '.') != NULL
))
914 p
->forward
= ++d_nforwards
;
916 p
->forward
= 0; /* no forward */
920 def_name (const char *name
, int base
)
922 /* xgettext:c-format */
923 inform (_("NAME: %s base: %x"), name
, base
);
926 non_fatal (_("Can't have LIBRARY and NAME"));
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 (const char *name
, int base
)
939 /* xgettext:c-format */
940 inform (_("LIBRARY: %s base: %x"), name
, base
);
943 non_fatal (_("Can't have LIBRARY and NAME"));
946 /* If --dllname not provided, use the one in the DEF file. */
948 dll_name
= xstrdup (name
);
953 def_description (const char *desc
)
955 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
956 d
->text
= xstrdup (desc
);
962 new_directive (char *dir
)
964 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
965 d
->text
= xstrdup (dir
);
971 def_heapsize (int reserve
, int commit
)
975 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
977 sprintf (b
, "-heap 0x%x ", reserve
);
978 new_directive (xstrdup (b
));
982 def_stacksize (int reserve
, int commit
)
986 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
988 sprintf (b
, "-stack 0x%x ", reserve
);
989 new_directive (xstrdup (b
));
992 /* append_import simply adds the given import definition to the global
993 import_list. It is used by def_import. */
996 append_import (const char *symbol_name
, const char *dll_name
, int func_ordinal
)
1001 for (pq
= &import_list
; *pq
!= NULL
; pq
= &(*pq
)->next
)
1003 if (strcmp ((*pq
)->dllname
, dll_name
) == 0)
1006 q
->functail
->next
= xmalloc (sizeof (ifunctype
));
1007 q
->functail
= q
->functail
->next
;
1008 q
->functail
->ord
= func_ordinal
;
1009 q
->functail
->name
= xstrdup (symbol_name
);
1010 q
->functail
->next
= NULL
;
1016 q
= xmalloc (sizeof (iheadtype
));
1017 q
->dllname
= xstrdup (dll_name
);
1019 q
->funchead
= xmalloc (sizeof (ifunctype
));
1020 q
->functail
= q
->funchead
;
1022 q
->functail
->name
= xstrdup (symbol_name
);
1023 q
->functail
->ord
= func_ordinal
;
1024 q
->functail
->next
= NULL
;
1029 /* def_import is called from within defparse.y when an IMPORT
1030 declaration is encountered. Depending on the form of the
1031 declaration, the module name may or may not need ".dll" to be
1032 appended to it, the name of the function may be stored in internal
1033 or entry, and there may or may not be an ordinal value associated
1036 /* A note regarding the parse modes:
1037 In defparse.y we have to accept import declarations which follow
1038 any one of the following forms:
1039 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1040 <func_name_in_app> = <dll_name>.<number>
1041 <dll_name>.<func_name_in_dll>
1043 Furthermore, the dll's name may or may not end with ".dll", which
1044 complicates the parsing a little. Normally the dll's name is
1045 passed to def_import() in the "module" parameter, but when it ends
1046 with ".dll" it gets passed in "module" sans ".dll" and that needs
1049 def_import gets five parameters:
1050 APP_NAME - the name of the function in the application, if
1051 present, or NULL if not present.
1052 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1053 DLLEXT - the extension of the dll, if present, NULL if not present.
1054 ENTRY - the name of the function in the dll, if present, or NULL.
1055 ORD_VAL - the numerical tag of the function in the dll, if present,
1056 or NULL. Exactly one of <entry> or <ord_val> must be
1057 present (i.e., not NULL). */
1060 def_import (const char *app_name
, const char *module
, const char *dllext
,
1061 const char *entry
, int ord_val
)
1063 const char *application_name
;
1067 application_name
= entry
;
1070 if (app_name
!= NULL
)
1071 application_name
= app_name
;
1073 application_name
= "";
1078 buf
= (char *) alloca (strlen (module
) + strlen (dllext
) + 2);
1079 sprintf (buf
, "%s.%s", module
, dllext
);
1083 append_import (application_name
, module
, ord_val
);
1087 def_version (int major
, int minor
)
1089 printf ("VERSION %d.%d\n", major
, minor
);
1093 def_section (const char *name
, int attr
)
1108 sprintf (buf
, "-attr %s %s", name
, atts
);
1109 new_directive (xstrdup (buf
));
1116 def_section ("CODE", attr
);
1122 def_section ("DATA", attr
);
1125 /**********************************************************************/
1128 run (const char *what
, char *args
)
1131 int pid
, wait_status
;
1134 char *errmsg_fmt
, *errmsg_arg
;
1135 char *temp_base
= choose_temp_base ();
1137 inform ("run: %s %s", what
, args
);
1139 /* Count the args */
1141 for (s
= args
; *s
; s
++)
1145 argv
= alloca (sizeof (char *) * (i
+ 3));
1154 while (*s
!= ' ' && *s
!= 0)
1162 pid
= pexecute (argv
[0], (char * const *) argv
, program_name
, temp_base
,
1163 &errmsg_fmt
, &errmsg_arg
, PEXECUTE_ONE
| PEXECUTE_SEARCH
);
1167 inform (strerror (errno
));
1169 fatal (errmsg_fmt
, errmsg_arg
);
1172 pid
= pwait (pid
, & wait_status
, 0);
1176 /* xgettext:c-format */
1177 fatal (_("wait: %s"), strerror (errno
));
1179 else if (WIFSIGNALED (wait_status
))
1181 /* xgettext:c-format */
1182 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status
));
1184 else if (WIFEXITED (wait_status
))
1186 if (WEXITSTATUS (wait_status
) != 0)
1187 /* xgettext:c-format */
1188 non_fatal (_("%s exited with status %d"),
1189 what
, WEXITSTATUS (wait_status
));
1195 /* Look for a list of symbols to export in the .drectve section of
1196 ABFD. Pass each one to def_exports. */
1199 scan_drectve_symbols (bfd
*abfd
)
1207 /* Look for .drectve's */
1208 s
= bfd_get_section_by_name (abfd
, DRECTVE_SECTION_NAME
);
1213 size
= bfd_get_section_size (s
);
1214 buf
= xmalloc (size
);
1216 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
1218 /* xgettext:c-format */
1219 inform (_("Sucking in info from %s section in %s"),
1220 DRECTVE_SECTION_NAME
, bfd_get_filename (abfd
));
1222 /* Search for -export: strings. The exported symbols can optionally
1223 have type tags (eg., -export:foo,data), so handle those as well.
1224 Currently only data tag is supported. */
1230 && strncmp (p
, "-export:", 8) == 0)
1234 flagword flags
= BSF_FUNCTION
;
1238 while (p
< e
&& *p
!= ',' && *p
!= ' ' && *p
!= '-')
1240 c
= xmalloc (p
- name
+ 1);
1241 memcpy (c
, name
, p
- name
);
1243 if (p
< e
&& *p
== ',') /* found type tag. */
1245 char *tag_start
= ++p
;
1246 while (p
< e
&& *p
!= ' ' && *p
!= '-')
1248 if (strncmp (tag_start
, "data", 4) == 0)
1249 flags
&= ~BSF_FUNCTION
;
1252 /* FIXME: The 5th arg is for the `constant' field.
1253 What should it be? Not that it matters since it's not
1254 currently useful. */
1255 def_exports (c
, 0, -1, 0, 0, ! (flags
& BSF_FUNCTION
), 0);
1257 if (add_stdcall_alias
&& strchr (c
, '@'))
1259 int lead_at
= (*c
== '@') ;
1260 char *exported_name
= xstrdup (c
+ lead_at
);
1261 char *atsym
= strchr (exported_name
, '@');
1263 /* Note: stdcall alias symbols can never be data. */
1264 def_exports (exported_name
, xstrdup (c
), -1, 0, 0, 0, 0);
1273 /* Look through the symbols in MINISYMS, and add each one to list of
1274 symbols to export. */
1277 scan_filtered_symbols (bfd
*abfd
, void *minisyms
, long symcount
,
1281 bfd_byte
*from
, *fromend
;
1283 store
= bfd_make_empty_symbol (abfd
);
1285 bfd_fatal (bfd_get_filename (abfd
));
1287 from
= (bfd_byte
*) minisyms
;
1288 fromend
= from
+ symcount
* size
;
1289 for (; from
< fromend
; from
+= size
)
1292 const char *symbol_name
;
1294 sym
= bfd_minisymbol_to_symbol (abfd
, FALSE
, from
, store
);
1296 bfd_fatal (bfd_get_filename (abfd
));
1298 symbol_name
= bfd_asymbol_name (sym
);
1299 if (bfd_get_symbol_leading_char (abfd
) == symbol_name
[0])
1302 def_exports (xstrdup (symbol_name
) , 0, -1, 0, 0,
1303 ! (sym
->flags
& BSF_FUNCTION
), 0);
1305 if (add_stdcall_alias
&& strchr (symbol_name
, '@'))
1307 int lead_at
= (*symbol_name
== '@');
1308 char *exported_name
= xstrdup (symbol_name
+ lead_at
);
1309 char *atsym
= strchr (exported_name
, '@');
1311 /* Note: stdcall alias symbols can never be data. */
1312 def_exports (exported_name
, xstrdup (symbol_name
), -1, 0, 0, 0, 0);
1317 /* Add a list of symbols to exclude. */
1320 add_excludes (const char *new_excludes
)
1323 char *exclude_string
;
1325 local_copy
= xstrdup (new_excludes
);
1327 exclude_string
= strtok (local_copy
, ",:");
1328 for (; exclude_string
; exclude_string
= strtok (NULL
, ",:"))
1330 struct string_list
*new_exclude
;
1332 new_exclude
= ((struct string_list
*)
1333 xmalloc (sizeof (struct string_list
)));
1334 new_exclude
->string
= (char *) xmalloc (strlen (exclude_string
) + 2);
1335 /* Don't add a leading underscore for fastcall symbols. */
1336 if (*exclude_string
== '@')
1337 sprintf (new_exclude
->string
, "%s", exclude_string
);
1339 sprintf (new_exclude
->string
, "_%s", exclude_string
);
1340 new_exclude
->next
= excludes
;
1341 excludes
= new_exclude
;
1343 /* xgettext:c-format */
1344 inform (_("Excluding symbol: %s"), exclude_string
);
1350 /* See if STRING is on the list of symbols to exclude. */
1353 match_exclude (const char *string
)
1355 struct string_list
*excl_item
;
1357 for (excl_item
= excludes
; excl_item
; excl_item
= excl_item
->next
)
1358 if (strcmp (string
, excl_item
->string
) == 0)
1363 /* Add the default list of symbols to exclude. */
1366 set_default_excludes (void)
1368 add_excludes (default_excludes
);
1371 /* Choose which symbols to export. */
1374 filter_symbols (bfd
*abfd
, void *minisyms
, long symcount
, unsigned int size
)
1376 bfd_byte
*from
, *fromend
, *to
;
1379 store
= bfd_make_empty_symbol (abfd
);
1381 bfd_fatal (bfd_get_filename (abfd
));
1383 from
= (bfd_byte
*) minisyms
;
1384 fromend
= from
+ symcount
* size
;
1385 to
= (bfd_byte
*) minisyms
;
1387 for (; from
< fromend
; from
+= size
)
1392 sym
= bfd_minisymbol_to_symbol (abfd
, FALSE
, (const void *) from
, store
);
1394 bfd_fatal (bfd_get_filename (abfd
));
1396 /* Check for external and defined only symbols. */
1397 keep
= (((sym
->flags
& BSF_GLOBAL
) != 0
1398 || (sym
->flags
& BSF_WEAK
) != 0
1399 || bfd_is_com_section (sym
->section
))
1400 && ! bfd_is_und_section (sym
->section
));
1402 keep
= keep
&& ! match_exclude (sym
->name
);
1406 memcpy (to
, from
, size
);
1411 return (to
- (bfd_byte
*) minisyms
) / size
;
1414 /* Export all symbols in ABFD, except for ones we were told not to
1418 scan_all_symbols (bfd
*abfd
)
1424 /* Ignore bfds with an import descriptor table. We assume that any
1425 such BFD contains symbols which are exported from another DLL,
1426 and we don't want to reexport them from here. */
1427 if (bfd_get_section_by_name (abfd
, ".idata$4"))
1430 if (! (bfd_get_file_flags (abfd
) & HAS_SYMS
))
1432 /* xgettext:c-format */
1433 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1437 symcount
= bfd_read_minisymbols (abfd
, FALSE
, &minisyms
, &size
);
1439 bfd_fatal (bfd_get_filename (abfd
));
1443 /* xgettext:c-format */
1444 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd
));
1448 /* Discard the symbols we don't want to export. It's OK to do this
1449 in place; we'll free the storage anyway. */
1451 symcount
= filter_symbols (abfd
, minisyms
, symcount
, size
);
1452 scan_filtered_symbols (abfd
, minisyms
, symcount
, size
);
1457 /* Look at the object file to decide which symbols to export. */
1460 scan_open_obj_file (bfd
*abfd
)
1462 if (export_all_symbols
)
1463 scan_all_symbols (abfd
);
1465 scan_drectve_symbols (abfd
);
1467 /* FIXME: we ought to read in and block out the base relocations. */
1469 /* xgettext:c-format */
1470 inform (_("Done reading %s"), bfd_get_filename (abfd
));
1474 scan_obj_file (const char *filename
)
1476 bfd
* f
= bfd_openr (filename
, 0);
1479 /* xgettext:c-format */
1480 fatal (_("Unable to open object file: %s"), filename
);
1482 /* xgettext:c-format */
1483 inform (_("Scanning object file %s"), filename
);
1485 if (bfd_check_format (f
, bfd_archive
))
1487 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
1490 if (bfd_check_format (arfile
, bfd_object
))
1491 scan_open_obj_file (arfile
);
1493 arfile
= bfd_openr_next_archived_file (f
, arfile
);
1496 #ifdef DLLTOOL_MCORE_ELF
1497 if (mcore_elf_out_file
)
1498 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename
);
1501 else if (bfd_check_format (f
, bfd_object
))
1503 scan_open_obj_file (f
);
1505 #ifdef DLLTOOL_MCORE_ELF
1506 if (mcore_elf_out_file
)
1507 mcore_elf_cache_filename ((char *) filename
);
1514 /**********************************************************************/
1517 dump_def_info (FILE *f
)
1521 fprintf (f
, "%s ", ASM_C
);
1522 for (i
= 0; oav
[i
]; i
++)
1523 fprintf (f
, "%s ", oav
[i
]);
1525 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1527 fprintf (f
, "%s %d = %s %s @ %d %s%s%s%s\n",
1533 exp
->noname
? "NONAME " : "",
1534 exp
->private ? "PRIVATE " : "",
1535 exp
->constant
? "CONSTANT" : "",
1536 exp
->data
? "DATA" : "");
1540 /* Generate the .exp file. */
1543 sfunc (const void *a
, const void *b
)
1545 return *(const long *) a
- *(const long *) b
;
1549 flush_page (FILE *f
, long *need
, int page_addr
, int on_page
)
1553 /* Flush this page. */
1554 fprintf (f
, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1558 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
1560 (on_page
* 2) + (on_page
& 1) * 2 + 8,
1563 for (i
= 0; i
< on_page
; i
++)
1565 long needed
= need
[i
];
1568 needed
= ((needed
- page_addr
) | 0x3000) & 0xffff;
1570 fprintf (f
, "\t%s\t0x%lx\n", ASM_SHORT
, needed
);
1575 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
1584 inform (_("Adding exports to output file"));
1586 fprintf (output_def
, ";");
1587 for (i
= 0; oav
[i
]; i
++)
1588 fprintf (output_def
, " %s", oav
[i
]);
1590 fprintf (output_def
, "\nEXPORTS\n");
1592 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1594 char *quote
= strchr (exp
->name
, '.') ? "\"" : "";
1595 char *res
= cplus_demangle (exp
->internal_name
, DMGL_ANSI
| DMGL_PARAMS
);
1599 fprintf (output_def
,";\t%s\n", res
);
1603 if (strcmp (exp
->name
, exp
->internal_name
) == 0)
1605 fprintf (output_def
, "\t%s%s%s @ %d%s%s%s\n",
1610 exp
->noname
? " NONAME" : "",
1611 exp
->private ? "PRIVATE " : "",
1612 exp
->data
? " DATA" : "");
1616 char * quote1
= strchr (exp
->internal_name
, '.') ? "\"" : "";
1618 fprintf (output_def
, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
1626 exp
->noname
? " NONAME" : "",
1627 exp
->private ? "PRIVATE " : "",
1628 exp
->data
? " DATA" : "");
1632 inform (_("Added exports to output file"));
1635 /* generate_idata_ofile generates the portable assembly source code
1636 for the idata sections. It appends the source code to the end of
1640 generate_idata_ofile (FILE *filvar
)
1648 if (import_list
== NULL
)
1651 fprintf (filvar
, "%s Import data sections\n", ASM_C
);
1652 fprintf (filvar
, "\n\t.section\t.idata$2\n");
1653 fprintf (filvar
, "\t%s\tdoi_idata\n", ASM_GLOBAL
);
1654 fprintf (filvar
, "doi_idata:\n");
1657 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1659 fprintf (filvar
, "\t%slistone%d%s\t%s %s\n",
1660 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
,
1661 ASM_C
, headptr
->dllname
);
1662 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1663 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1664 fprintf (filvar
, "\t%sdllname%d%s\n",
1665 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1666 fprintf (filvar
, "\t%slisttwo%d%s\n\n",
1667 ASM_RVA_BEFORE
, nheads
, ASM_RVA_AFTER
);
1671 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL record at */
1672 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* end of idata$2 */
1673 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* section */
1674 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1675 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
);
1677 fprintf (filvar
, "\n\t.section\t.idata$4\n");
1679 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1681 fprintf (filvar
, "listone%d:\n", headindex
);
1682 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1683 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1684 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1685 fprintf (filvar
,"\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1689 fprintf (filvar
, "\n\t.section\t.idata$5\n");
1691 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1693 fprintf (filvar
, "listtwo%d:\n", headindex
);
1694 for ( funcindex
= 0; funcindex
< headptr
->nfuncs
; funcindex
++ )
1695 fprintf (filvar
, "\t%sfuncptr%d_%d%s\n",
1696 ASM_RVA_BEFORE
, headindex
, funcindex
, ASM_RVA_AFTER
);
1697 fprintf (filvar
, "\t%s\t0\n", ASM_LONG
); /* NULL terminating list */
1701 fprintf (filvar
, "\n\t.section\t.idata$6\n");
1703 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1706 for (funcptr
= headptr
->funchead
; funcptr
!= NULL
;
1707 funcptr
= funcptr
->next
)
1709 fprintf (filvar
,"funcptr%d_%d:\n", headindex
, funcindex
);
1710 fprintf (filvar
,"\t%s\t%d\n", ASM_SHORT
,
1711 ((funcptr
->ord
) & 0xFFFF));
1712 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, funcptr
->name
);
1713 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1719 fprintf (filvar
, "\n\t.section\t.idata$7\n");
1721 for (headptr
= import_list
; headptr
!= NULL
; headptr
= headptr
->next
)
1723 fprintf (filvar
,"dllname%d:\n", headindex
);
1724 fprintf (filvar
,"\t%s\t\"%s\"\n", ASM_TEXT
, headptr
->dllname
);
1725 fprintf (filvar
,"\t%s\t0\n", ASM_BYTE
);
1730 /* Assemble the specified file. */
1732 assemble_file (const char * source
, const char * dest
)
1736 cmd
= (char *) alloca (strlen (ASM_SWITCHES
) + strlen (as_flags
)
1737 + strlen (source
) + strlen (dest
) + 50);
1739 sprintf (cmd
, "%s %s -o %s %s", ASM_SWITCHES
, as_flags
, dest
, source
);
1752 /* xgettext:c-format */
1753 inform (_("Generating export file: %s"), exp_name
);
1755 f
= fopen (TMP_ASM
, FOPEN_WT
);
1757 /* xgettext:c-format */
1758 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM
);
1760 /* xgettext:c-format */
1761 inform (_("Opened temporary file: %s"), TMP_ASM
);
1767 fprintf (f
, "\t.section .edata\n\n");
1768 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
1769 fprintf (f
, "\t%s 0x%lx %s Time and date\n", ASM_LONG
, (long) time(0),
1771 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
1772 fprintf (f
, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1773 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_low_ord
, ASM_C
);
1776 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_high_ord
- d_low_ord
+ 1, ASM_C
);
1777 fprintf(f
,"\t%s named funcs %d, low ord %d, high ord %d\n",
1779 d_named_nfuncs
, d_low_ord
, d_high_ord
);
1780 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
,
1781 show_allnames
? d_high_ord
- d_low_ord
+ 1 : d_named_nfuncs
, ASM_C
);
1782 fprintf (f
, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1784 fprintf (f
, "\t%sanames%s %s Address of Name Pointer Table\n",
1785 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1787 fprintf (f
, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
1789 fprintf (f
, "name: %s \"%s\"\n", ASM_TEXT
, dll_name
);
1792 fprintf(f
,"%s Export address Table\n", ASM_C
);
1793 fprintf(f
,"\t%s\n", ASM_ALIGN_LONG
);
1794 fprintf (f
, "afuncs:\n");
1797 for (exp
= d_exports
; exp
; exp
= exp
->next
)
1799 if (exp
->ordinal
!= i
)
1802 fprintf (f
, "\t%s\t%d\t%s %d..%d missing\n",
1804 (exp
->ordinal
- i
) * 4,
1806 i
, exp
->ordinal
- 1);
1809 while (i
< exp
->ordinal
)
1811 fprintf(f
,"\t%s\t0\n", ASM_LONG
);
1816 if (exp
->forward
== 0)
1818 if (exp
->internal_name
[0] == '@')
1819 fprintf (f
, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1820 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1822 fprintf (f
, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE
,
1823 ASM_PREFIX (exp
->internal_name
),
1824 exp
->internal_name
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1827 fprintf (f
, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE
,
1828 exp
->forward
, ASM_RVA_AFTER
, ASM_C
, exp
->ordinal
);
1832 fprintf (f
,"%s Export Name Pointer Table\n", ASM_C
);
1833 fprintf (f
, "anames:\n");
1835 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1837 if (!exp
->noname
|| show_allnames
)
1838 fprintf (f
, "\t%sn%d%s\n",
1839 ASM_RVA_BEFORE
, exp
->ordinal
, ASM_RVA_AFTER
);
1842 fprintf (f
,"%s Export Oridinal Table\n", ASM_C
);
1843 fprintf (f
, "anords:\n");
1844 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1846 if (!exp
->noname
|| show_allnames
)
1847 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_low_ord
);
1850 fprintf(f
,"%s Export Name Table\n", ASM_C
);
1851 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
1853 if (!exp
->noname
|| show_allnames
)
1854 fprintf (f
, "n%d: %s \"%s\"\n",
1855 exp
->ordinal
, ASM_TEXT
, xlate (exp
->name
));
1856 if (exp
->forward
!= 0)
1857 fprintf (f
, "f%d: %s \"%s\"\n",
1858 exp
->forward
, ASM_TEXT
, exp
->internal_name
);
1863 fprintf (f
, "\t.section %s\n", DRECTVE_SECTION_NAME
);
1864 for (dl
= a_list
; dl
; dl
= dl
->next
)
1866 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
1872 fprintf (f
, "\t.section .rdata\n");
1873 for (dl
= d_list
; dl
; dl
= dl
->next
)
1878 /* We don't output as ascii because there can
1879 be quote characters in the string. */
1881 for (p
= dl
->text
; *p
; p
++)
1884 fprintf (f
, "\t%s\t", ASM_BYTE
);
1887 fprintf (f
, "%d", *p
);
1890 fprintf (f
, ",0\n");
1904 /* Add to the output file a way of getting to the exported names
1905 without using the import library. */
1908 fprintf (f
, "\t.section\t.rdata\n");
1909 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1910 if (!exp
->noname
|| show_allnames
)
1912 /* We use a single underscore for MS compatibility, and a
1913 double underscore for backward compatibility with old
1915 if (create_compat_implib
)
1916 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
1917 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
1918 if (create_compat_implib
)
1919 fprintf (f
, "__imp_%s:\n", exp
->name
);
1920 fprintf (f
, "_imp__%s:\n", exp
->name
);
1921 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, exp
->name
);
1925 /* Dump the reloc section if a base file is provided. */
1929 long need
[PAGE_SIZE
];
1936 fprintf (f
, "\t.section\t.init\n");
1937 fprintf (f
, "lab:\n");
1939 fseek (base_file
, 0, SEEK_END
);
1940 numbytes
= ftell (base_file
);
1941 fseek (base_file
, 0, SEEK_SET
);
1942 copy
= xmalloc (numbytes
);
1943 fread (copy
, 1, numbytes
, base_file
);
1944 num_entries
= numbytes
/ sizeof (long);
1947 fprintf (f
, "\t.section\t.reloc\n");
1953 qsort (copy
, num_entries
, sizeof (long), sfunc
);
1954 /* Delete duplicates */
1955 for (src
= 0; src
< num_entries
; src
++)
1957 if (last
!= copy
[src
])
1958 last
= copy
[dst
++] = copy
[src
];
1962 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
1964 for (j
= 0; j
< num_entries
; j
++)
1967 if ((addr
& PAGE_MASK
) != page_addr
)
1969 flush_page (f
, need
, page_addr
, on_page
);
1971 page_addr
= addr
& PAGE_MASK
;
1973 need
[on_page
++] = addr
;
1975 flush_page (f
, need
, page_addr
, on_page
);
1977 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1981 generate_idata_ofile (f
);
1985 /* Assemble the file. */
1986 assemble_file (TMP_ASM
, exp_name
);
1988 if (dontdeltemps
== 0)
1991 inform (_("Generated exports file"));
1995 xlate (const char *name
)
1997 int lead_at
= (*name
== '@');
1999 if (add_underscore
&& !lead_at
)
2001 char *copy
= xmalloc (strlen (name
) + 2);
2004 strcpy (copy
+ 1, name
);
2013 p
= strchr (name
, '@');
2020 /**********************************************************************/
2025 dump_iat (FILE *f
, export_type
*exp
)
2027 if (exp
->noname
&& !show_allnames
)
2029 fprintf (f
, "\t%s\t0x%08x\n",
2031 exp
->ordinal
| 0x80000000); /* hint or orindal ?? */
2035 fprintf (f
, "\t%sID%d%s\n", ASM_RVA_BEFORE
,
2053 unsigned char *data
;
2068 #define TEXT_SEC_FLAGS \
2069 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2070 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2071 #define BSS_SEC_FLAGS SEC_ALLOC
2073 #define INIT_SEC_DATA(id, name, flags, align) \
2074 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2075 static sinfo secdata
[NSECS
] =
2077 INIT_SEC_DATA (TEXT
, ".text", TEXT_SEC_FLAGS
, 2),
2078 INIT_SEC_DATA (DATA
, ".data", DATA_SEC_FLAGS
, 2),
2079 INIT_SEC_DATA (BSS
, ".bss", BSS_SEC_FLAGS
, 2),
2080 INIT_SEC_DATA (IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2),
2081 INIT_SEC_DATA (IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2),
2082 INIT_SEC_DATA (IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2),
2083 INIT_SEC_DATA (IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1)
2088 /* Sections numbered to make the order the same as other PowerPC NT
2089 compilers. This also keeps funny alignment thingies from happening. */
2102 static sinfo secdata
[NSECS
] =
2104 { TEXT
, ".text", SEC_CODE
| SEC_HAS_CONTENTS
, 3},
2105 { PDATA
, ".pdata", SEC_HAS_CONTENTS
, 2},
2106 { RDATA
, ".reldata", SEC_HAS_CONTENTS
, 2},
2107 { IDATA5
, ".idata$5", SEC_HAS_CONTENTS
, 2},
2108 { IDATA4
, ".idata$4", SEC_HAS_CONTENTS
, 2},
2109 { IDATA6
, ".idata$6", SEC_HAS_CONTENTS
, 1},
2110 { IDATA7
, ".idata$7", SEC_HAS_CONTENTS
, 2},
2111 { DATA
, ".data", SEC_DATA
, 2},
2112 { BSS
, ".bss", 0, 2}
2117 /* This is what we're trying to make. We generate the imp symbols with
2118 both single and double underscores, for compatibility.
2121 .global _GetFileVersionInfoSizeW@8
2122 .global __imp_GetFileVersionInfoSizeW@8
2123 _GetFileVersionInfoSizeW@8:
2124 jmp * __imp_GetFileVersionInfoSizeW@8
2125 .section .idata$7 # To force loading of head
2126 .long __version_a_head
2127 # Import Address Table
2129 __imp_GetFileVersionInfoSizeW@8:
2132 # Import Lookup Table
2138 .asciz "GetFileVersionInfoSizeW"
2141 For the PowerPC, here's the variation on the above scheme:
2143 # Rather than a simple "jmp *", the code to get to the dll function
2146 lwz r11,[tocv]__imp_function_name(r2)
2147 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2155 make_label (const char *prefix
, const char *name
)
2157 int len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2158 char *copy
= xmalloc (len
+ 1);
2160 strcpy (copy
, ASM_PREFIX (name
));
2161 strcat (copy
, prefix
);
2162 strcat (copy
, name
);
2167 make_imp_label (const char *prefix
, const char *name
)
2174 len
= strlen (prefix
) + strlen (name
);
2175 copy
= xmalloc (len
+ 1);
2176 strcpy (copy
, prefix
);
2177 strcat (copy
, name
);
2181 len
= strlen (ASM_PREFIX (name
)) + strlen (prefix
) + strlen (name
);
2182 copy
= xmalloc (len
+ 1);
2183 strcpy (copy
, prefix
);
2184 strcat (copy
, ASM_PREFIX (name
));
2185 strcat (copy
, name
);
2191 make_one_lib_file (export_type
*exp
, int i
)
2197 const char *prefix
= "d";
2200 name
= (char *) alloca (strlen (prefix
) + 10);
2201 sprintf (name
, "%ss%05d.s", prefix
, i
);
2202 f
= fopen (name
, FOPEN_WT
);
2203 fprintf (f
, "\t.text\n");
2204 fprintf (f
, "\t%s\t%s%s\n", ASM_GLOBAL
, ASM_PREFIX (exp
->name
), exp
->name
);
2205 if (create_compat_implib
)
2206 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
2207 fprintf (f
, "\t%s\t_imp__%s\n", ASM_GLOBAL
, exp
->name
);
2208 if (create_compat_implib
)
2209 fprintf (f
, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX (exp
->name
),
2210 exp
->name
, ASM_JUMP
, exp
->name
);
2212 fprintf (f
, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C
);
2213 fprintf (f
, "\t%s\t%s\n", ASM_LONG
, head_label
);
2216 fprintf (f
,"%s Import Address Table\n", ASM_C
);
2218 fprintf (f
, "\t.section .idata$5\n");
2219 if (create_compat_implib
)
2220 fprintf (f
, "__imp_%s:\n", exp
->name
);
2221 fprintf (f
, "_imp__%s:\n", exp
->name
);
2225 fprintf (f
, "\n%s Import Lookup Table\n", ASM_C
);
2226 fprintf (f
, "\t.section .idata$4\n");
2230 if(!exp
->noname
|| show_allnames
)
2232 fprintf (f
, "%s Hint/Name table\n", ASM_C
);
2233 fprintf (f
, "\t.section .idata$6\n");
2234 fprintf (f
, "ID%d:\t%s\t%d\n", exp
->ordinal
, ASM_SHORT
, exp
->hint
);
2235 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
2240 dest
= (char *) alloca (strlen (prefix
) + 10);
2241 sprintf (dest
, "%ss%05d.o", prefix
, i
);
2242 assemble_file (name
, dest
);
2247 asymbol
* exp_label
;
2248 asymbol
* iname
= 0;
2250 asymbol
* iname_lab
;
2251 asymbol
** iname_lab_pp
;
2252 asymbol
** iname_pp
;
2261 asymbol
* ptrs
[NSECS
+ 4 + EXTRA
+ 1];
2262 flagword applicable
;
2264 char * outname
= xmalloc (strlen (TMP_STUB
) + 10);
2268 sprintf (outname
, "%s%05d.o", TMP_STUB
, i
);
2270 abfd
= bfd_openw (outname
, HOW_BFD_WRITE_TARGET
);
2273 /* xgettext:c-format */
2274 fatal (_("bfd_open failed open stub file: %s"), outname
);
2276 /* xgettext:c-format */
2277 inform (_("Creating stub file: %s"), outname
);
2279 bfd_set_format (abfd
, bfd_object
);
2280 bfd_set_arch_mach (abfd
, HOW_BFD_ARCH
, 0);
2283 if (machine
== MARM_INTERWORK
|| machine
== MTHUMB
)
2284 bfd_set_private_flags (abfd
, F_INTERWORK
);
2287 applicable
= bfd_applicable_section_flags (abfd
);
2289 /* First make symbols for the sections. */
2290 for (i
= 0; i
< NSECS
; i
++)
2292 sinfo
*si
= secdata
+ i
;
2295 si
->sec
= bfd_make_section_old_way (abfd
, si
->name
);
2296 bfd_set_section_flags (abfd
,
2298 si
->flags
& applicable
);
2300 bfd_set_section_alignment(abfd
, si
->sec
, si
->align
);
2301 si
->sec
->output_section
= si
->sec
;
2302 si
->sym
= bfd_make_empty_symbol(abfd
);
2303 si
->sym
->name
= si
->sec
->name
;
2304 si
->sym
->section
= si
->sec
;
2305 si
->sym
->flags
= BSF_LOCAL
;
2307 ptrs
[oidx
] = si
->sym
;
2308 si
->sympp
= ptrs
+ oidx
;
2317 exp_label
= bfd_make_empty_symbol (abfd
);
2318 exp_label
->name
= make_imp_label ("", exp
->name
);
2320 /* On PowerPC, the function name points to a descriptor in
2321 the rdata section, the first element of which is a
2322 pointer to the code (..function_name), and the second
2323 points to the .toc. */
2325 if (machine
== MPPC
)
2326 exp_label
->section
= secdata
[RDATA
].sec
;
2329 exp_label
->section
= secdata
[TEXT
].sec
;
2331 exp_label
->flags
= BSF_GLOBAL
;
2332 exp_label
->value
= 0;
2335 if (machine
== MTHUMB
)
2336 bfd_coff_set_symbol_class (abfd
, exp_label
, C_THUMBEXTFUNC
);
2338 ptrs
[oidx
++] = exp_label
;
2341 /* Generate imp symbols with one underscore for Microsoft
2342 compatibility, and with two underscores for backward
2343 compatibility with old versions of cygwin. */
2344 if (create_compat_implib
)
2346 iname
= bfd_make_empty_symbol (abfd
);
2347 iname
->name
= make_imp_label ("___imp", exp
->name
);
2348 iname
->section
= secdata
[IDATA5
].sec
;
2349 iname
->flags
= BSF_GLOBAL
;
2353 iname2
= bfd_make_empty_symbol (abfd
);
2354 iname2
->name
= make_imp_label ("__imp_", exp
->name
);
2355 iname2
->section
= secdata
[IDATA5
].sec
;
2356 iname2
->flags
= BSF_GLOBAL
;
2359 iname_lab
= bfd_make_empty_symbol(abfd
);
2361 iname_lab
->name
= head_label
;
2362 iname_lab
->section
= (asection
*)&bfd_und_section
;
2363 iname_lab
->flags
= 0;
2364 iname_lab
->value
= 0;
2366 iname_pp
= ptrs
+ oidx
;
2367 if (create_compat_implib
)
2368 ptrs
[oidx
++] = iname
;
2369 ptrs
[oidx
++] = iname2
;
2371 iname_lab_pp
= ptrs
+ oidx
;
2372 ptrs
[oidx
++] = iname_lab
;
2375 /* The symbol referring to the code (.text). */
2377 asymbol
*function_name
;
2379 function_name
= bfd_make_empty_symbol(abfd
);
2380 function_name
->name
= make_label ("..", exp
->name
);
2381 function_name
->section
= secdata
[TEXT
].sec
;
2382 function_name
->flags
= BSF_GLOBAL
;
2383 function_name
->value
= 0;
2385 fn_pp
= ptrs
+ oidx
;
2386 ptrs
[oidx
++] = function_name
;
2389 /* The .toc symbol. */
2391 asymbol
*toc_symbol
;
2393 toc_symbol
= bfd_make_empty_symbol (abfd
);
2394 toc_symbol
->name
= make_label (".", "toc");
2395 toc_symbol
->section
= (asection
*)&bfd_und_section
;
2396 toc_symbol
->flags
= BSF_GLOBAL
;
2397 toc_symbol
->value
= 0;
2399 toc_pp
= ptrs
+ oidx
;
2400 ptrs
[oidx
++] = toc_symbol
;
2406 for (i
= 0; i
< NSECS
; i
++)
2408 sinfo
*si
= secdata
+ i
;
2409 asection
*sec
= si
->sec
;
2418 si
->size
= HOW_JTAB_SIZE
;
2419 si
->data
= xmalloc (HOW_JTAB_SIZE
);
2420 memcpy (si
->data
, HOW_JTAB
, HOW_JTAB_SIZE
);
2422 /* add the reloc into idata$5 */
2423 rel
= xmalloc (sizeof (arelent
));
2425 rpp
= xmalloc (sizeof (arelent
*) * 2);
2429 rel
->address
= HOW_JTAB_ROFF
;
2432 if (machine
== MPPC
)
2434 rel
->howto
= bfd_reloc_type_lookup (abfd
,
2435 BFD_RELOC_16_GOTOFF
);
2436 rel
->sym_ptr_ptr
= iname_pp
;
2440 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2441 rel
->sym_ptr_ptr
= secdata
[IDATA5
].sympp
;
2443 sec
->orelocation
= rpp
;
2444 sec
->reloc_count
= 1;
2449 /* An idata$4 or idata$5 is one word long, and has an
2452 si
->data
= xmalloc (4);
2457 si
->data
[0] = exp
->ordinal
;
2458 si
->data
[1] = exp
->ordinal
>> 8;
2459 si
->data
[2] = exp
->ordinal
>> 16;
2464 sec
->reloc_count
= 1;
2465 memset (si
->data
, 0, si
->size
);
2466 rel
= xmalloc (sizeof (arelent
));
2467 rpp
= xmalloc (sizeof (arelent
*) * 2);
2472 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2473 rel
->sym_ptr_ptr
= secdata
[IDATA6
].sympp
;
2474 sec
->orelocation
= rpp
;
2482 /* This used to add 1 to exp->hint. I don't know
2483 why it did that, and it does not match what I see
2484 in programs compiled with the MS tools. */
2485 int idx
= exp
->hint
;
2486 si
->size
= strlen (xlate (exp
->name
)) + 3;
2487 si
->data
= xmalloc (si
->size
);
2488 si
->data
[0] = idx
& 0xff;
2489 si
->data
[1] = idx
>> 8;
2490 strcpy (si
->data
+ 2, xlate (exp
->name
));
2495 si
->data
=xmalloc (4);
2496 memset (si
->data
, 0, si
->size
);
2497 rel
= xmalloc (sizeof (arelent
));
2498 rpp
= xmalloc (sizeof (arelent
*) * 2);
2502 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_RVA
);
2503 rel
->sym_ptr_ptr
= iname_lab_pp
;
2504 sec
->orelocation
= rpp
;
2505 sec
->reloc_count
= 1;
2511 /* The .pdata section is 5 words long.
2515 bfd_vma BeginAddress, [0x00]
2517 ExceptionHandler, [0x08]
2519 PrologEndAddress; [0x10]
2522 /* So this pdata section setups up this as a glue linkage to
2523 a dll routine. There are a number of house keeping things
2526 1. In the name of glue trickery, the ADDR32 relocs for 0,
2527 4, and 0x10 are set to point to the same place:
2529 2. There is one more reloc needed in the pdata section.
2530 The actual glue instruction to restore the toc on
2531 return is saved as the offset in an IMGLUE reloc.
2532 So we need a total of four relocs for this section.
2534 3. Lastly, the HandlerData field is set to 0x03, to indicate
2535 that this is a glue routine. */
2536 arelent
*imglue
, *ba_rel
, *ea_rel
, *pea_rel
;
2538 /* Alignment must be set to 2**2 or you get extra stuff. */
2539 bfd_set_section_alignment(abfd
, sec
, 2);
2542 si
->data
= xmalloc (si
->size
);
2543 memset (si
->data
, 0, si
->size
);
2544 rpp
= xmalloc (sizeof (arelent
*) * 5);
2545 rpp
[0] = imglue
= xmalloc (sizeof (arelent
));
2546 rpp
[1] = ba_rel
= xmalloc (sizeof (arelent
));
2547 rpp
[2] = ea_rel
= xmalloc (sizeof (arelent
));
2548 rpp
[3] = pea_rel
= xmalloc (sizeof (arelent
));
2551 /* Stick the toc reload instruction in the glue reloc. */
2552 bfd_put_32(abfd
, ppc_glue_insn
, (char *) &imglue
->address
);
2555 imglue
->howto
= bfd_reloc_type_lookup (abfd
,
2556 BFD_RELOC_32_GOTOFF
);
2557 imglue
->sym_ptr_ptr
= fn_pp
;
2559 ba_rel
->address
= 0;
2561 ba_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2562 ba_rel
->sym_ptr_ptr
= fn_pp
;
2564 bfd_put_32 (abfd
, 0x18, si
->data
+ 0x04);
2565 ea_rel
->address
= 4;
2567 ea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2568 ea_rel
->sym_ptr_ptr
= fn_pp
;
2570 /* Mark it as glue. */
2571 bfd_put_32 (abfd
, 0x03, si
->data
+ 0x0c);
2573 /* Mark the prolog end address. */
2574 bfd_put_32 (abfd
, 0x0D, si
->data
+ 0x10);
2575 pea_rel
->address
= 0x10;
2576 pea_rel
->addend
= 0;
2577 pea_rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2578 pea_rel
->sym_ptr_ptr
= fn_pp
;
2580 sec
->orelocation
= rpp
;
2581 sec
->reloc_count
= 4;
2585 /* Each external function in a PowerPC PE file has a two word
2586 descriptor consisting of:
2587 1. The address of the code.
2588 2. The address of the appropriate .toc
2589 We use relocs to build this. */
2591 si
->data
= xmalloc (8);
2592 memset (si
->data
, 0, si
->size
);
2594 rpp
= xmalloc (sizeof (arelent
*) * 3);
2595 rpp
[0] = rel
= xmalloc (sizeof (arelent
));
2596 rpp
[1] = xmalloc (sizeof (arelent
));
2601 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2602 rel
->sym_ptr_ptr
= fn_pp
;
2608 rel
->howto
= bfd_reloc_type_lookup (abfd
, BFD_RELOC_32
);
2609 rel
->sym_ptr_ptr
= toc_pp
;
2611 sec
->orelocation
= rpp
;
2612 sec
->reloc_count
= 2;
2614 #endif /* DLLTOOL_PPC */
2620 /* Size up all the sections. */
2621 for (i
= 0; i
< NSECS
; i
++)
2623 sinfo
*si
= secdata
+ i
;
2625 bfd_set_section_size (abfd
, si
->sec
, si
->size
);
2626 bfd_set_section_vma (abfd
, si
->sec
, vma
);
2628 /* vma += si->size;*/
2631 /* Write them out. */
2632 for (i
= 0; i
< NSECS
; i
++)
2634 sinfo
*si
= secdata
+ i
;
2636 if (i
== IDATA5
&& no_idata5
)
2639 if (i
== IDATA4
&& no_idata4
)
2642 bfd_set_section_contents (abfd
, si
->sec
,
2647 bfd_set_symtab (abfd
, ptrs
, oidx
);
2649 abfd
= bfd_openr (outname
, HOW_BFD_READ_TARGET
);
2658 FILE *f
= fopen (TMP_HEAD_S
, FOPEN_WT
);
2662 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S
);
2666 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
2667 fprintf (f
, "\t.section .idata$2\n");
2669 fprintf(f
,"\t%s\t%s\n", ASM_GLOBAL
,head_label
);
2671 fprintf (f
, "%s:\n", head_label
);
2673 fprintf (f
, "\t%shname%s\t%sPtr to image import by name list\n",
2674 ASM_RVA_BEFORE
, ASM_RVA_AFTER
, ASM_C
);
2676 fprintf (f
, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C
);
2677 fprintf (f
, "\t%sdoesn't load DLLs when this is set.\n", ASM_C
);
2678 fprintf (f
, "\t%s\t0\t%s loaded time\n", ASM_LONG
, ASM_C
);
2679 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
2680 fprintf (f
, "\t%s__%s_iname%s\t%s imported dll's name\n",
2685 fprintf (f
, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2687 ASM_RVA_AFTER
, ASM_C
);
2689 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
2693 fprintf (f
, "\t.section\t.idata$5\n");
2694 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2695 fprintf (f
, "fthunk:\n");
2700 fprintf (f
, "\t.section\t.idata$4\n");
2702 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2703 fprintf (f
, "\t.section .idata$4\n");
2704 fprintf (f
, "hname:\n");
2709 assemble_file (TMP_HEAD_S
, TMP_HEAD_O
);
2711 return bfd_openr (TMP_HEAD_O
, HOW_BFD_READ_TARGET
);
2717 FILE *f
= fopen (TMP_TAIL_S
, FOPEN_WT
);
2721 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S
);
2727 fprintf (f
, "\t.section .idata$4\n");
2728 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2733 fprintf (f
, "\t.section .idata$5\n");
2734 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2738 /* Normally, we need to see a null descriptor built in idata$3 to
2739 act as the terminator for the list. The ideal way, I suppose,
2740 would be to mark this section as a comdat type 2 section, so
2741 only one would appear in the final .exe (if our linker supported
2742 comdat, that is) or cause it to be inserted by something else (say
2745 fprintf (f
, "\t.section .idata$3\n");
2746 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2747 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2748 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2749 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2750 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
2754 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2755 do too. Original, huh? */
2756 fprintf (f
, "\t.section .idata$6\n");
2758 fprintf (f
, "\t.section .idata$7\n");
2761 fprintf (f
, "\t%s\t__%s_iname\n", ASM_GLOBAL
, imp_name_lab
);
2762 fprintf (f
, "__%s_iname:\t%s\t\"%s\"\n",
2763 imp_name_lab
, ASM_TEXT
, dll_name
);
2767 assemble_file (TMP_TAIL_S
, TMP_TAIL_O
);
2769 return bfd_openr (TMP_TAIL_O
, HOW_BFD_READ_TARGET
);
2784 outarch
= bfd_openw (imp_name
, HOW_BFD_WRITE_TARGET
);
2787 /* xgettext:c-format */
2788 fatal (_("Can't open .lib file: %s"), imp_name
);
2790 /* xgettext:c-format */
2791 inform (_("Creating library file: %s"), imp_name
);
2793 bfd_set_format (outarch
, bfd_archive
);
2794 outarch
->has_armap
= 1;
2796 /* Work out a reasonable size of things to put onto one line. */
2797 ar_head
= make_head ();
2798 ar_tail
= make_tail();
2800 if (ar_head
== NULL
|| ar_tail
== NULL
)
2803 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2806 /* Don't add PRIVATE entries to import lib. */
2809 n
= make_one_lib_file (exp
, i
);
2814 /* Now stick them all into the archive. */
2815 ar_head
->next
= head
;
2816 ar_tail
->next
= ar_head
;
2819 if (! bfd_set_archive_head (outarch
, head
))
2820 bfd_fatal ("bfd_set_archive_head");
2822 if (! bfd_close (outarch
))
2823 bfd_fatal (imp_name
);
2825 while (head
!= NULL
)
2827 bfd
*n
= head
->next
;
2832 /* Delete all the temp files. */
2833 if (dontdeltemps
== 0)
2835 unlink (TMP_HEAD_O
);
2836 unlink (TMP_HEAD_S
);
2837 unlink (TMP_TAIL_O
);
2838 unlink (TMP_TAIL_S
);
2841 if (dontdeltemps
< 2)
2845 name
= (char *) alloca (strlen (TMP_STUB
) + 10);
2846 for (i
= 0; (exp
= d_exports_lexically
[i
]); i
++)
2848 /* Don't delete non-existent stubs for PRIVATE entries. */
2851 sprintf (name
, "%s%05d.o", TMP_STUB
, i
);
2852 if (unlink (name
) < 0)
2853 /* xgettext:c-format */
2854 non_fatal (_("cannot delete %s: %s"), name
, strerror (errno
));
2858 inform (_("Created lib file"));
2861 /* Run through the information gathered from the .o files and the
2862 .def file and work out the best stuff. */
2865 pfunc (const void *a
, const void *b
)
2867 export_type
*ap
= *(export_type
**) a
;
2868 export_type
*bp
= *(export_type
**) b
;
2869 if (ap
->ordinal
== bp
->ordinal
)
2872 /* Unset ordinals go to the bottom. */
2873 if (ap
->ordinal
== -1)
2875 if (bp
->ordinal
== -1)
2877 return (ap
->ordinal
- bp
->ordinal
);
2881 nfunc (const void *a
, const void *b
)
2883 export_type
*ap
= *(export_type
**) a
;
2884 export_type
*bp
= *(export_type
**) b
;
2886 return (strcmp (ap
->name
, bp
->name
));
2890 remove_null_names (export_type
**ptr
)
2895 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
2899 ptr
[dst
] = ptr
[src
];
2907 dtab (export_type
**ptr ATTRIBUTE_UNUSED
)
2911 for (i
= 0; i
< d_nfuncs
; i
++)
2915 printf ("%d %s @ %d %s%s%s\n",
2916 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
2917 ptr
[i
]->noname
? "NONAME " : "",
2918 ptr
[i
]->constant
? "CONSTANT" : "",
2919 ptr
[i
]->data
? "DATA" : "");
2928 process_duplicates (export_type
**d_export_vec
)
2936 /* Remove duplicates. */
2937 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
2939 dtab (d_export_vec
);
2940 for (i
= 0; i
< d_nfuncs
- 1; i
++)
2942 if (strcmp (d_export_vec
[i
]->name
,
2943 d_export_vec
[i
+ 1]->name
) == 0)
2945 export_type
*a
= d_export_vec
[i
];
2946 export_type
*b
= d_export_vec
[i
+ 1];
2950 /* xgettext:c-format */
2951 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
2952 a
->name
, a
->ordinal
, b
->ordinal
);
2954 if (a
->ordinal
!= -1
2955 && b
->ordinal
!= -1)
2956 /* xgettext:c-format */
2957 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2960 /* Merge attributes. */
2961 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
2962 b
->constant
|= a
->constant
;
2963 b
->noname
|= a
->noname
;
2965 d_export_vec
[i
] = 0;
2968 dtab (d_export_vec
);
2969 remove_null_names (d_export_vec
);
2970 dtab (d_export_vec
);
2974 /* Count the names. */
2975 for (i
= 0; i
< d_nfuncs
; i
++)
2976 if (!d_export_vec
[i
]->noname
)
2981 fill_ordinals (export_type
**d_export_vec
)
2988 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
2990 /* Fill in the unset ordinals with ones from our range. */
2991 ptr
= (char *) xmalloc (size
);
2993 memset (ptr
, 0, size
);
2995 /* Mark in our large vector all the numbers that are taken. */
2996 for (i
= 0; i
< d_nfuncs
; i
++)
2998 if (d_export_vec
[i
]->ordinal
!= -1)
3000 ptr
[d_export_vec
[i
]->ordinal
] = 1;
3002 if (lowest
== -1 || d_export_vec
[i
]->ordinal
< lowest
)
3003 lowest
= d_export_vec
[i
]->ordinal
;
3007 /* Start at 1 for compatibility with MS toolchain. */
3011 /* Now fill in ordinals where the user wants us to choose. */
3012 for (i
= 0; i
< d_nfuncs
; i
++)
3014 if (d_export_vec
[i
]->ordinal
== -1)
3018 /* First try within or after any user supplied range. */
3019 for (j
= lowest
; j
< size
; j
++)
3023 d_export_vec
[i
]->ordinal
= j
;
3027 /* Then try before the range. */
3028 for (j
= lowest
; j
>0; j
--)
3032 d_export_vec
[i
]->ordinal
= j
;
3042 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
3044 /* Work out the lowest and highest ordinal numbers. */
3047 if (d_export_vec
[0])
3048 d_low_ord
= d_export_vec
[0]->ordinal
;
3049 if (d_export_vec
[d_nfuncs
-1])
3050 d_high_ord
= d_export_vec
[d_nfuncs
-1]->ordinal
;
3055 alphafunc (const void *av
, const void *bv
)
3057 const export_type
**a
= (const export_type
**) av
;
3058 const export_type
**b
= (const export_type
**) bv
;
3060 return strcmp ((*a
)->name
, (*b
)->name
);
3066 /* First work out the minimum ordinal chosen. */
3071 export_type
**d_export_vec
= xmalloc (sizeof (export_type
*) * d_nfuncs
);
3073 inform (_("Processing definitions"));
3075 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3076 d_export_vec
[i
] = exp
;
3078 process_duplicates (d_export_vec
);
3079 fill_ordinals (d_export_vec
);
3081 /* Put back the list in the new order. */
3083 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
3085 d_export_vec
[i
]->next
= d_exports
;
3086 d_exports
= d_export_vec
[i
];
3089 /* Build list in alpha order. */
3090 d_exports_lexically
= (export_type
**)
3091 xmalloc (sizeof (export_type
*) * (d_nfuncs
+ 1));
3093 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
3094 d_exports_lexically
[i
] = exp
;
3096 d_exports_lexically
[i
] = 0;
3098 qsort (d_exports_lexically
, i
, sizeof (export_type
*), alphafunc
);
3100 /* Fill exp entries with their hint values. */
3101 for (i
= 0; i
< d_nfuncs
; i
++)
3102 if (!d_exports_lexically
[i
]->noname
|| show_allnames
)
3103 d_exports_lexically
[i
]->hint
= hint
++;
3105 inform (_("Processed definitions"));
3109 usage (FILE *file
, int status
)
3111 /* xgetext:c-format */
3112 fprintf (file
, _("Usage %s <option(s)> <object-file(s)>\n"), program_name
);
3113 /* xgetext:c-format */
3114 fprintf (file
, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname
);
3115 fprintf (file
, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
3116 fprintf (file
, _(" -e --output-exp <outname> Generate an export file.\n"));
3117 fprintf (file
, _(" -l --output-lib <outname> Generate an interface library.\n"));
3118 fprintf (file
, _(" -a --add-indirect Add dll indirects to export file.\n"));
3119 fprintf (file
, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3120 fprintf (file
, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3121 fprintf (file
, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3122 fprintf (file
, _(" --export-all-symbols Export all symbols to .def\n"));
3123 fprintf (file
, _(" --no-export-all-symbols Only export listed symbols\n"));
3124 fprintf (file
, _(" --exclude-symbols <list> Don't export <list>\n"));
3125 fprintf (file
, _(" --no-default-excludes Clear default exclude symbols\n"));
3126 fprintf (file
, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3127 fprintf (file
, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3128 fprintf (file
, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3129 fprintf (file
, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
3130 fprintf (file
, _(" -k --kill-at Kill @<n> from exported names.\n"));
3131 fprintf (file
, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3132 fprintf (file
, _(" -S --as <name> Use <name> for assembler.\n"));
3133 fprintf (file
, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3134 fprintf (file
, _(" -C --compat-implib Create backward compatible import library.\n"));
3135 fprintf (file
, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3136 fprintf (file
, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3137 fprintf (file
, _(" -v --verbose Be verbose.\n"));
3138 fprintf (file
, _(" -V --version Display the program version.\n"));
3139 fprintf (file
, _(" -h --help Display this information.\n"));
3140 #ifdef DLLTOOL_MCORE_ELF
3141 fprintf (file
, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3142 fprintf (file
, _(" -L --linker <name> Use <name> as the linker.\n"));
3143 fprintf (file
, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3148 #define OPTION_EXPORT_ALL_SYMS 150
3149 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3150 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3151 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3153 static const struct option long_options
[] =
3155 {"no-delete", no_argument
, NULL
, 'n'},
3156 {"dllname", required_argument
, NULL
, 'D'},
3157 {"no-idata4", no_argument
, NULL
, 'x'},
3158 {"no-idata5", no_argument
, NULL
, 'c'},
3159 {"output-exp", required_argument
, NULL
, 'e'},
3160 {"output-def", required_argument
, NULL
, 'z'},
3161 {"export-all-symbols", no_argument
, NULL
, OPTION_EXPORT_ALL_SYMS
},
3162 {"no-export-all-symbols", no_argument
, NULL
, OPTION_NO_EXPORT_ALL_SYMS
},
3163 {"exclude-symbols", required_argument
, NULL
, OPTION_EXCLUDE_SYMS
},
3164 {"no-default-excludes", no_argument
, NULL
, OPTION_NO_DEFAULT_EXCLUDES
},
3165 {"output-lib", required_argument
, NULL
, 'l'},
3166 {"def", required_argument
, NULL
, 'd'}, /* for compatibility with older versions */
3167 {"input-def", required_argument
, NULL
, 'd'},
3168 {"add-underscore", no_argument
, NULL
, 'U'},
3169 {"kill-at", no_argument
, NULL
, 'k'},
3170 {"add-stdcall-alias", no_argument
, NULL
, 'A'},
3171 {"verbose", no_argument
, NULL
, 'v'},
3172 {"version", no_argument
, NULL
, 'V'},
3173 {"help", no_argument
, NULL
, 'h'},
3174 {"machine", required_argument
, NULL
, 'm'},
3175 {"add-indirect", no_argument
, NULL
, 'a'},
3176 {"base-file", required_argument
, NULL
, 'b'},
3177 {"as", required_argument
, NULL
, 'S'},
3178 {"as-flags", required_argument
, NULL
, 'f'},
3179 {"mcore-elf", required_argument
, NULL
, 'M'},
3180 {"compat-implib", no_argument
, NULL
, 'C'},
3181 {"temp-prefix", required_argument
, NULL
, 't'},
3185 int main (int, char **);
3188 main (int ac
, char **av
)
3193 program_name
= av
[0];
3196 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3197 setlocale (LC_MESSAGES
, "");
3199 #if defined (HAVE_SETLOCALE)
3200 setlocale (LC_CTYPE
, "");
3202 bindtextdomain (PACKAGE
, LOCALEDIR
);
3203 textdomain (PACKAGE
);
3205 while ((c
= getopt_long (ac
, av
,
3206 #ifdef DLLTOOL_MCORE_ELF
3207 "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHhM:L:F:",
3209 "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHh",
3216 case OPTION_EXPORT_ALL_SYMS
:
3217 export_all_symbols
= TRUE
;
3219 case OPTION_NO_EXPORT_ALL_SYMS
:
3220 export_all_symbols
= FALSE
;
3222 case OPTION_EXCLUDE_SYMS
:
3223 add_excludes (optarg
);
3225 case OPTION_NO_DEFAULT_EXCLUDES
:
3226 do_default_excludes
= FALSE
;
3238 tmp_prefix
= optarg
;
3244 /* Ignored for compatibility. */
3251 output_def
= fopen (optarg
, FOPEN_WT
);
3273 print_version (program_name
);
3282 add_stdcall_alias
= 1;
3291 base_file
= fopen (optarg
, FOPEN_RB
);
3294 /* xgettext:c-format */
3295 fatal (_("Unable to open base-file: %s"), optarg
);
3298 #ifdef DLLTOOL_MCORE_ELF
3300 mcore_elf_out_file
= optarg
;
3303 mcore_elf_linker
= optarg
;
3306 mcore_elf_linker_flags
= optarg
;
3310 create_compat_implib
= 1;
3319 tmp_prefix
= prefix_encode ("d", getpid ());
3321 for (i
= 0; mtable
[i
].type
; i
++)
3322 if (strcmp (mtable
[i
].type
, mname
) == 0)
3325 if (!mtable
[i
].type
)
3326 /* xgettext:c-format */
3327 fatal (_("Machine '%s' not supported"), mname
);
3331 if (!dll_name
&& exp_name
)
3333 int len
= strlen (exp_name
) + 5;
3334 dll_name
= xmalloc (len
);
3335 strcpy (dll_name
, exp_name
);
3336 strcat (dll_name
, ".dll");
3339 if (as_name
== NULL
)
3340 as_name
= deduce_name ("as");
3342 /* Don't use the default exclude list if we're reading only the
3343 symbols in the .drectve section. The default excludes are meant
3344 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
3345 if (! export_all_symbols
)
3346 do_default_excludes
= FALSE
;
3348 if (do_default_excludes
)
3349 set_default_excludes ();
3352 process_def_file (def_file
);
3357 firstarg
= av
[optind
];
3358 scan_obj_file (av
[optind
]);
3369 /* Make imp_name safe for use as a label. */
3372 imp_name_lab
= xstrdup (imp_name
);
3373 for (p
= imp_name_lab
; *p
; p
++)
3378 head_label
= make_label("_head_", imp_name_lab
);
3385 #ifdef DLLTOOL_MCORE_ELF
3386 if (mcore_elf_out_file
)
3387 mcore_elf_gen_out_file ();
3393 /* Look for the program formed by concatenating PROG_NAME and the
3394 string running from PREFIX to END_PREFIX. If the concatenated
3395 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
3399 look_for_prog (const char *prog_name
, const char *prefix
, int end_prefix
)
3404 cmd
= xmalloc (strlen (prefix
)
3405 + strlen (prog_name
)
3406 #ifdef HAVE_EXECUTABLE_SUFFIX
3407 + strlen (EXECUTABLE_SUFFIX
)
3410 strcpy (cmd
, prefix
);
3412 sprintf (cmd
+ end_prefix
, "%s", prog_name
);
3414 if (strchr (cmd
, '/') != NULL
)
3418 found
= (stat (cmd
, &s
) == 0
3419 #ifdef HAVE_EXECUTABLE_SUFFIX
3420 || stat (strcat (cmd
, EXECUTABLE_SUFFIX
), &s
) == 0
3426 /* xgettext:c-format */
3427 inform (_("Tried file: %s"), cmd
);
3433 /* xgettext:c-format */
3434 inform (_("Using file: %s"), cmd
);
3439 /* Deduce the name of the program we are want to invoke.
3440 PROG_NAME is the basic name of the program we want to run,
3441 eg "as" or "ld". The catch is that we might want actually
3442 run "i386-pe-as" or "ppc-pe-ld".
3444 If argv[0] contains the full path, then try to find the program
3445 in the same place, with and then without a target-like prefix.
3447 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
3448 deduce_name("as") uses the following search order:
3450 /usr/local/bin/i586-cygwin32-as
3454 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3455 name, it'll try without and then with EXECUTABLE_SUFFIX.
3457 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3458 as the fallback, but rather return i586-cygwin32-as.
3460 Oh, and given, argv[0] = dlltool, it'll return "as".
3462 Returns a dynamically allocated string. */
3465 deduce_name (const char *prog_name
)
3468 char *dash
, *slash
, *cp
;
3472 for (cp
= program_name
; *cp
!= '\0'; ++cp
)
3477 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3478 *cp
== ':' || *cp
== '\\' ||
3491 /* First, try looking for a prefixed PROG_NAME in the
3492 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
3493 cmd
= look_for_prog (prog_name
, program_name
, dash
- program_name
+ 1);
3496 if (slash
!= NULL
&& cmd
== NULL
)
3498 /* Next, try looking for a PROG_NAME in the same directory as
3499 that of this program. */
3500 cmd
= look_for_prog (prog_name
, program_name
, slash
- program_name
+ 1);
3505 /* Just return PROG_NAME as is. */
3506 cmd
= xstrdup (prog_name
);
3512 #ifdef DLLTOOL_MCORE_ELF
3513 typedef struct fname_cache
3516 struct fname_cache
* next
;
3520 static fname_cache fnames
;
3523 mcore_elf_cache_filename (char * filename
)
3529 while (ptr
->next
!= NULL
)
3532 ptr
->filename
= filename
;
3533 ptr
->next
= (fname_cache
*) malloc (sizeof (fname_cache
));
3534 if (ptr
->next
!= NULL
)
3535 ptr
->next
->next
= NULL
;
3538 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3539 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3540 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3543 mcore_elf_gen_out_file (void)
3548 /* Step one. Run 'ld -r' on the input object files in order to resolve
3549 any internal references and to generate a single .exports section. */
3552 ds
= dyn_string_new (100);
3553 dyn_string_append_cstr (ds
, "-r ");
3555 if (mcore_elf_linker_flags
!= NULL
)
3556 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
3558 while (ptr
->next
!= NULL
)
3560 dyn_string_append_cstr (ds
, ptr
->filename
);
3561 dyn_string_append_cstr (ds
, " ");
3566 dyn_string_append_cstr (ds
, "-o ");
3567 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
3569 if (mcore_elf_linker
== NULL
)
3570 mcore_elf_linker
= deduce_name ("ld");
3572 run (mcore_elf_linker
, ds
->s
);
3574 dyn_string_delete (ds
);
3576 /* Step two. Create a .exp file and a .lib file from the temporary file.
3577 Do this by recursively invoking dlltool... */
3578 ds
= dyn_string_new (100);
3580 dyn_string_append_cstr (ds
, "-S ");
3581 dyn_string_append_cstr (ds
, as_name
);
3583 dyn_string_append_cstr (ds
, " -e ");
3584 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
3585 dyn_string_append_cstr (ds
, " -l ");
3586 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_LIB
);
3587 dyn_string_append_cstr (ds
, " " );
3588 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
3591 dyn_string_append_cstr (ds
, " -v");
3595 dyn_string_append_cstr (ds
, " -n");
3597 if (dontdeltemps
> 1)
3598 dyn_string_append_cstr (ds
, " -n");
3601 /* XXX - FIME: ought to check/copy other command line options as well. */
3602 run (program_name
, ds
->s
);
3604 dyn_string_delete (ds
);
3606 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
3607 ds
= dyn_string_new (100);
3609 dyn_string_append_cstr (ds
, "-shared ");
3611 if (mcore_elf_linker_flags
)
3612 dyn_string_append_cstr (ds
, mcore_elf_linker_flags
);
3614 dyn_string_append_cstr (ds
, " ");
3615 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_EXP
);
3616 dyn_string_append_cstr (ds
, " ");
3617 dyn_string_append_cstr (ds
, MCORE_ELF_TMP_OBJ
);
3618 dyn_string_append_cstr (ds
, " -o ");
3619 dyn_string_append_cstr (ds
, mcore_elf_out_file
);
3621 run (mcore_elf_linker
, ds
->s
);
3623 dyn_string_delete (ds
);
3625 if (dontdeltemps
== 0)
3626 unlink (MCORE_ELF_TMP_EXP
);
3628 if (dontdeltemps
< 2)
3629 unlink (MCORE_ELF_TMP_OBJ
);
3631 #endif /* DLLTOOL_MCORE_ELF */