1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008, 2009, 2011, 2012 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 3 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., 51 Franklin Street - Fifth Floor, 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 whose 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). */
237 #include "libiberty.h"
239 #include "demangle.h"
240 #include "dyn-string.h"
243 #include "safe-ctype.h"
249 #include "coff/arm.h"
250 #include "coff/internal.h"
252 #ifdef DLLTOOL_DEFAULT_MX86_64
253 #include "coff/x86_64.h"
255 #ifdef DLLTOOL_DEFAULT_I386
256 #include "coff/i386.h"
259 #ifndef COFF_PAGE_SIZE
260 #define COFF_PAGE_SIZE ((bfd_vma) 4096)
264 #define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE))
267 /* Get current BFD error message. */
268 #define bfd_get_errmsg() (bfd_errmsg (bfd_get_error ()))
270 /* Forward references. */
271 static char *look_for_prog (const char *, const char *, int);
272 static char *deduce_name (const char *);
274 #ifdef DLLTOOL_MCORE_ELF
275 static void mcore_elf_cache_filename (const char *);
276 static void mcore_elf_gen_out_file (void);
279 #ifdef HAVE_SYS_WAIT_H
280 #include <sys/wait.h>
281 #else /* ! HAVE_SYS_WAIT_H */
282 #if ! defined (_WIN32) || defined (__CYGWIN32__)
284 #define WIFEXITED(w) (((w) & 0377) == 0)
287 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
290 #define WTERMSIG(w) ((w) & 0177)
293 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
295 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
297 #define WIFEXITED(w) (((w) & 0xff) == 0)
300 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
303 #define WTERMSIG(w) ((w) & 0x7f)
306 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
308 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
309 #endif /* ! HAVE_SYS_WAIT_H */
311 #define show_allnames 0
313 /* ifunc and ihead data structures: ttk@cygnus.com 1997
315 When IMPORT declarations are encountered in a .def file the
316 function import information is stored in a structure referenced by
317 the global variable IMPORT_LIST. The structure is a linked list
318 containing the names of the dll files each function is imported
319 from and a linked list of functions being imported from that dll
320 file. This roughly parallels the structure of the .idata section
321 in the PE object file.
323 The contents of .def file are interpreted from within the
324 process_def_file function. Every time an IMPORT declaration is
325 encountered, it is broken up into its component parts and passed to
326 def_import. IMPORT_LIST is initialized to NULL in function main. */
328 typedef struct ifunct
330 char * name; /* Name of function being imported. */
331 char * its_name; /* Optional import table symbol name. */
332 int ord; /* Two-byte ordinal value associated with function. */
336 typedef struct iheadt
338 char * dllname; /* Name of dll file imported from. */
339 long nfuncs; /* Number of functions in list. */
340 struct ifunct *funchead; /* First function in list. */
341 struct ifunct *functail; /* Last function in list. */
342 struct iheadt *next; /* Next dll file in list. */
345 /* Structure containing all import information as defined in .def file
346 (qv "ihead structure"). */
348 static iheadtype *import_list = NULL;
349 static char *as_name = NULL;
350 static char * as_flags = "";
351 static char *tmp_prefix;
352 static int no_idata4;
353 static int no_idata5;
354 static char *exp_name;
355 static char *imp_name;
356 static char *delayimp_name;
357 static char *identify_imp_name;
358 static bfd_boolean identify_strict;
360 /* Types used to implement a linked list of dllnames associated
361 with the specified import lib. Used by the identify_* code.
362 The head entry is acts as a sentinal node and is always empty
363 (head->dllname is NULL). */
364 typedef struct dll_name_list_node_t
367 struct dll_name_list_node_t * next;
368 } dll_name_list_node_type;
370 typedef struct dll_name_list_t
372 dll_name_list_node_type * head;
373 dll_name_list_node_type * tail;
374 } dll_name_list_type;
376 /* Types used to pass data to iterator functions. */
377 typedef struct symname_search_data_t
379 const char * symname;
381 } symname_search_data_type;
383 typedef struct identify_data_t
385 dll_name_list_type * list;
386 bfd_boolean ms_style_implib;
387 } identify_data_type;
390 static char *head_label;
391 static char *imp_name_lab;
392 static char *dll_name;
393 static int dll_name_set_by_exp_name;
394 static int add_indirect = 0;
395 static int add_underscore = 0;
396 static int add_stdcall_underscore = 0;
397 /* This variable can hold three different values. The value
398 -1 (default) means that default underscoring should be used,
399 zero means that no underscoring should be done, and one
400 indicates that underscoring should be done. */
401 static int leading_underscore = -1;
402 static int dontdeltemps = 0;
404 /* TRUE if we should export all symbols. Otherwise, we only export
405 symbols listed in .drectve sections or in the def file. */
406 static bfd_boolean export_all_symbols;
408 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
409 exporting all symbols. */
410 static bfd_boolean do_default_excludes = TRUE;
412 static bfd_boolean use_nul_prefixed_import_tables = FALSE;
414 /* Default symbols to exclude when exporting all the symbols. */
415 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
417 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
418 compatibility to old Cygwin releases. */
419 static bfd_boolean create_compat_implib;
421 /* TRUE if we have to write PE+ import libraries. */
422 static bfd_boolean create_for_pep;
424 static char *def_file;
426 extern char * program_name;
430 static int add_stdcall_alias;
431 static const char *ext_prefix_alias;
433 static FILE *output_def;
434 static FILE *base_file;
436 #ifdef DLLTOOL_DEFAULT_ARM
437 static const char *mname = "arm";
440 #ifdef DLLTOOL_DEFAULT_ARM_EPOC
441 static const char *mname = "arm-epoc";
444 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
445 static const char *mname = "arm-wince";
448 #ifdef DLLTOOL_DEFAULT_I386
449 static const char *mname = "i386";
452 #ifdef DLLTOOL_DEFAULT_MX86_64
453 static const char *mname = "i386:x86-64";
456 #ifdef DLLTOOL_DEFAULT_PPC
457 static const char *mname = "ppc";
460 #ifdef DLLTOOL_DEFAULT_SH
461 static const char *mname = "sh";
464 #ifdef DLLTOOL_DEFAULT_MIPS
465 static const char *mname = "mips";
468 #ifdef DLLTOOL_DEFAULT_MCORE
469 static const char * mname = "mcore-le";
472 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
473 static const char * mname = "mcore-elf";
474 static char * mcore_elf_out_file = NULL;
475 static char * mcore_elf_linker = NULL;
476 static char * mcore_elf_linker_flags = NULL;
478 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
481 #ifndef DRECTVE_SECTION_NAME
482 #define DRECTVE_SECTION_NAME ".drectve"
485 /* What's the right name for this ? */
488 /* External name alias numbering starts here. */
489 #define PREFIX_ALIAS_BASE 20000
492 char *tmp_head_s_buf;
493 char *tmp_head_o_buf;
494 char *tmp_tail_s_buf;
495 char *tmp_tail_o_buf;
498 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s")
499 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s")
500 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o")
501 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s")
502 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o")
503 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ss")
505 /* This bit of assembly does jmp * .... */
506 static const unsigned char i386_jtab[] =
508 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
511 static const unsigned char i386_dljtab[] =
513 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
514 0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
515 0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
518 static const unsigned char arm_jtab[] =
520 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
521 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
525 static const unsigned char arm_interwork_jtab[] =
527 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
528 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */
529 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */
533 static const unsigned char thumb_jtab[] =
535 0x40, 0xb4, /* push {r6} */
536 0x02, 0x4e, /* ldr r6, [pc, #8] */
537 0x36, 0x68, /* ldr r6, [r6] */
538 0xb4, 0x46, /* mov ip, r6 */
539 0x40, 0xbc, /* pop {r6} */
540 0x60, 0x47, /* bx ip */
544 static const unsigned char mcore_be_jtab[] =
546 0x71, 0x02, /* lrw r1,2 */
547 0x81, 0x01, /* ld.w r1,(r1,0) */
548 0x00, 0xC1, /* jmp r1 */
549 0x12, 0x00, /* nop */
550 0x00, 0x00, 0x00, 0x00 /* <address> */
553 static const unsigned char mcore_le_jtab[] =
555 0x02, 0x71, /* lrw r1,2 */
556 0x01, 0x81, /* ld.w r1,(r1,0) */
557 0xC1, 0x00, /* jmp r1 */
558 0x00, 0x12, /* nop */
559 0x00, 0x00, 0x00, 0x00 /* <address> */
562 /* This is the glue sequence for PowerPC PE. There is a
563 tocrel16-tocdefn reloc against the first instruction.
564 We also need a IMGLUE reloc against the glue function
565 to restore the toc saved by the third instruction in
567 static const unsigned char ppc_jtab[] =
569 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
570 /* Reloc TOCREL16 __imp_xxx */
571 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
572 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
573 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
574 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
575 0x20, 0x04, 0x80, 0x4E /* bctr */
579 /* The glue instruction, picks up the toc from the stw in
580 the above code: "lwz r2,4(r1)". */
581 static bfd_vma ppc_glue_insn = 0x80410004;
584 static const char i386_trampoline[] =
588 "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
589 "\tcall ___delayLoadHelper2@8\n"
597 const char *how_byte;
598 const char *how_short;
599 const char *how_long;
600 const char *how_asciz;
601 const char *how_comment;
602 const char *how_jump;
603 const char *how_global;
604 const char *how_space;
605 const char *how_align_short;
606 const char *how_align_long;
607 const char *how_default_as_switches;
608 const char *how_bfd_target;
609 enum bfd_architecture how_bfd_arch;
610 const unsigned char *how_jtab;
611 int how_jtab_size; /* Size of the jtab entry. */
612 int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
613 const unsigned char *how_dljtab;
614 int how_dljtab_size; /* Size of the dljtab entry. */
615 int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */
616 int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */
617 int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */
618 const char *trampoline;
621 static const struct mac
626 "arm", ".byte", ".short", ".long", ".asciz", "@",
627 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
628 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
629 "pe-arm-little", bfd_arch_arm,
630 arm_jtab, sizeof (arm_jtab), 8,
636 "i386", ".byte", ".short", ".long", ".asciz", "#",
637 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
638 "pe-i386",bfd_arch_i386,
639 i386_jtab, sizeof (i386_jtab), 2,
640 i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
645 "ppc", ".byte", ".short", ".long", ".asciz", "#",
646 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
647 "pe-powerpcle",bfd_arch_powerpc,
648 ppc_jtab, sizeof (ppc_jtab), 0,
654 "thumb", ".byte", ".short", ".long", ".asciz", "@",
655 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
656 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
657 "pe-arm-little", bfd_arch_arm,
658 thumb_jtab, sizeof (thumb_jtab), 12,
662 #define MARM_INTERWORK 4
664 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
665 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
666 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
667 "pe-arm-little", bfd_arch_arm,
668 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
674 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
675 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
676 ".global", ".space", ".align\t2",".align\t4", "",
677 "pe-mcore-big", bfd_arch_mcore,
678 mcore_be_jtab, sizeof (mcore_be_jtab), 8,
684 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
685 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
686 ".global", ".space", ".align\t2",".align\t4", "-EL",
687 "pe-mcore-little", bfd_arch_mcore,
688 mcore_le_jtab, sizeof (mcore_le_jtab), 8,
694 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
695 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
696 ".global", ".space", ".align\t2",".align\t4", "",
697 "elf32-mcore-big", bfd_arch_mcore,
698 mcore_be_jtab, sizeof (mcore_be_jtab), 8,
703 #define MMCORE_ELF_LE 8
704 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
705 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
706 ".global", ".space", ".align\t2",".align\t4", "-EL",
707 "elf32-mcore-little", bfd_arch_mcore,
708 mcore_le_jtab, sizeof (mcore_le_jtab), 8,
714 "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
715 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
716 ".global", ".space", ".align\t2",".align\t4", "",
717 "epoc-pe-arm-little", bfd_arch_arm,
718 arm_jtab, sizeof (arm_jtab), 8,
723 #define MARM_WINCE 10
724 "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
725 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
726 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
727 "pe-arm-wince-little", bfd_arch_arm,
728 arm_jtab, sizeof (arm_jtab), 8,
734 "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
735 "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
736 "pe-x86-64",bfd_arch_i386,
737 i386_jtab, sizeof (i386_jtab), 2,
738 i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
741 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
751 typedef struct export
754 const char *internal_name;
755 const char *import_name;
756 const char *its_name;
759 int noname; /* Don't put name in image file. */
760 int private; /* Don't put reference in import lib. */
763 int forward; /* Number of forward label, 0 means no forward. */
768 /* A list of symbols which we should not export. */
772 struct string_list *next;
776 static struct string_list *excludes;
778 static const char *rvaafter (int);
779 static const char *rvabefore (int);
780 static const char *asm_prefix (int, const char *);
781 static void process_def_file (const char *);
782 static void new_directive (char *);
783 static void append_import (const char *, const char *, int, const char *);
784 static void run (const char *, char *);
785 static void scan_drectve_symbols (bfd *);
786 static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
787 static void add_excludes (const char *);
788 static bfd_boolean match_exclude (const char *);
789 static void set_default_excludes (void);
790 static long filter_symbols (bfd *, void *, long, unsigned int);
791 static void scan_all_symbols (bfd *);
792 static void scan_open_obj_file (bfd *);
793 static void scan_obj_file (const char *);
794 static void dump_def_info (FILE *);
795 static int sfunc (const void *, const void *);
796 static void flush_page (FILE *, bfd_vma *, bfd_vma, int);
797 static void gen_def_file (void);
798 static void generate_idata_ofile (FILE *);
799 static void assemble_file (const char *, const char *);
800 static void gen_exp_file (void);
801 static const char *xlate (const char *);
802 static char *make_label (const char *, const char *);
803 static char *make_imp_label (const char *, const char *);
804 static bfd *make_one_lib_file (export_type *, int, int);
805 static bfd *make_head (void);
806 static bfd *make_tail (void);
807 static bfd *make_delay_head (void);
808 static void gen_lib_file (int);
809 static void dll_name_list_append (dll_name_list_type *, bfd_byte *);
810 static int dll_name_list_count (dll_name_list_type *);
811 static void dll_name_list_print (dll_name_list_type *);
812 static void dll_name_list_free_contents (dll_name_list_node_type *);
813 static void dll_name_list_free (dll_name_list_type *);
814 static dll_name_list_type * dll_name_list_create (void);
815 static void identify_dll_for_implib (void);
816 static void identify_search_archive
817 (bfd *, void (*) (bfd *, bfd *, void *), void *);
818 static void identify_search_member (bfd *, bfd *, void *);
819 static bfd_boolean identify_process_section_p (asection *, bfd_boolean);
820 static void identify_search_section (bfd *, asection *, void *);
821 static void identify_member_contains_symname (bfd *, bfd *, void *);
823 static int pfunc (const void *, const void *);
824 static int nfunc (const void *, const void *);
825 static void remove_null_names (export_type **);
826 static void process_duplicates (export_type **);
827 static void fill_ordinals (export_type **);
828 static void mangle_defs (void);
829 static void usage (FILE *, int);
830 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
831 static void set_dll_name_from_def (const char *name, char is_dll);
834 prefix_encode (char *start, unsigned code)
836 static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
840 p = strchr (buf, '\0');
842 *p++ = alpha[code % sizeof (alpha)];
843 while ((code /= sizeof (alpha)) != 0);
849 dlltmp (char **buf, const char *fmt)
853 *buf = malloc (strlen (tmp_prefix) + 64);
854 sprintf (*buf, fmt, tmp_prefix);
860 inform VPARAMS ((const char * message, ...))
862 VA_OPEN (args, message);
863 VA_FIXEDARG (args, const char *, message);
868 report (message, args);
892 /* xgettext:c-format */
893 fatal (_("Internal error: Unknown machine type: %d"), mach);
918 /* xgettext:c-format */
919 fatal (_("Internal error: Unknown machine type: %d"), mach);
926 asm_prefix (int mach, const char *name)
943 /* Symbol names starting with ? do not have a leading underscore. */
944 if ((name && *name == '?') || leading_underscore == 0)
949 /* xgettext:c-format */
950 fatal (_("Internal error: Unknown machine type: %d"), mach);
956 #define ASM_BYTE mtable[machine].how_byte
957 #define ASM_SHORT mtable[machine].how_short
958 #define ASM_LONG mtable[machine].how_long
959 #define ASM_TEXT mtable[machine].how_asciz
960 #define ASM_C mtable[machine].how_comment
961 #define ASM_JUMP mtable[machine].how_jump
962 #define ASM_GLOBAL mtable[machine].how_global
963 #define ASM_SPACE mtable[machine].how_space
964 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
965 #define ASM_RVA_BEFORE rvabefore (machine)
966 #define ASM_RVA_AFTER rvaafter (machine)
967 #define ASM_PREFIX(NAME) asm_prefix (machine, (NAME))
968 #define ASM_ALIGN_LONG mtable[machine].how_align_long
969 #define HOW_BFD_READ_TARGET 0 /* Always default. */
970 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
971 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
972 #define HOW_JTAB (delay ? mtable[machine].how_dljtab \
973 : mtable[machine].how_jtab)
974 #define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \
975 : mtable[machine].how_jtab_size)
976 #define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \
977 : mtable[machine].how_jtab_roff)
978 #define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
979 #define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
980 #define ASM_SWITCHES mtable[machine].how_default_as_switches
985 process_def_file (const char *name)
987 FILE *f = fopen (name, FOPEN_RT);
990 /* xgettext:c-format */
991 fatal (_("Can't open def file: %s"), name);
995 /* xgettext:c-format */
996 inform (_("Processing def file: %s"), name);
1000 inform (_("Processed def file"));
1003 /**********************************************************************/
1005 /* Communications with the parser. */
1007 static int d_nfuncs; /* Number of functions exported. */
1008 static int d_named_nfuncs; /* Number of named functions exported. */
1009 static int d_low_ord; /* Lowest ordinal index. */
1010 static int d_high_ord; /* Highest ordinal index. */
1011 static export_type *d_exports; /* List of exported functions. */
1012 static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */
1013 static dlist_type *d_list; /* Descriptions. */
1014 static dlist_type *a_list; /* Stuff to go in directives. */
1015 static int d_nforwards = 0; /* Number of forwarded exports. */
1017 static int d_is_dll;
1018 static int d_is_exe;
1021 yyerror (const char * err ATTRIBUTE_UNUSED)
1023 /* xgettext:c-format */
1024 non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
1030 def_exports (const char *name, const char *internal_name, int ordinal,
1031 int noname, int constant, int data, int private,
1032 const char *its_name)
1034 struct export *p = (struct export *) xmalloc (sizeof (*p));
1037 p->internal_name = internal_name ? internal_name : name;
1038 p->its_name = its_name;
1039 p->import_name = name;
1040 p->ordinal = ordinal;
1041 p->constant = constant;
1043 p->private = private;
1045 p->next = d_exports;
1049 if ((internal_name != NULL)
1050 && (strchr (internal_name, '.') != NULL))
1051 p->forward = ++d_nforwards;
1053 p->forward = 0; /* no forward */
1057 set_dll_name_from_def (const char *name, char is_dll)
1059 const char *image_basename = lbasename (name);
1060 if (image_basename != name)
1061 non_fatal (_("%s: Path components stripped from image name, '%s'."),
1063 /* Append the default suffix, if none specified. */
1064 if (strchr (image_basename, '.') == 0)
1066 const char * suffix = is_dll ? ".dll" : ".exe";
1068 dll_name = xmalloc (strlen (image_basename) + strlen (suffix) + 1);
1069 sprintf (dll_name, "%s%s", image_basename, suffix);
1072 dll_name = xstrdup (image_basename);
1076 def_name (const char *name, int base)
1078 /* xgettext:c-format */
1079 inform (_("NAME: %s base: %x"), name, base);
1082 non_fatal (_("Can't have LIBRARY and NAME"));
1084 if (dll_name_set_by_exp_name && name && *name != 0)
1087 dll_name_set_by_exp_name = 0;
1089 /* If --dllname not provided, use the one in the DEF file.
1090 FIXME: Is this appropriate for executables? */
1092 set_dll_name_from_def (name, 0);
1097 def_library (const char *name, int base)
1099 /* xgettext:c-format */
1100 inform (_("LIBRARY: %s base: %x"), name, base);
1103 non_fatal (_("Can't have LIBRARY and NAME"));
1105 if (dll_name_set_by_exp_name && name && *name != 0)
1108 dll_name_set_by_exp_name = 0;
1111 /* If --dllname not provided, use the one in the DEF file. */
1113 set_dll_name_from_def (name, 1);
1118 def_description (const char *desc)
1120 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1121 d->text = xstrdup (desc);
1127 new_directive (char *dir)
1129 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1130 d->text = xstrdup (dir);
1136 def_heapsize (int reserve, int commit)
1140 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1142 sprintf (b, "-heap 0x%x ", reserve);
1143 new_directive (xstrdup (b));
1147 def_stacksize (int reserve, int commit)
1151 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1153 sprintf (b, "-stack 0x%x ", reserve);
1154 new_directive (xstrdup (b));
1157 /* append_import simply adds the given import definition to the global
1158 import_list. It is used by def_import. */
1161 append_import (const char *symbol_name, const char *dllname, int func_ordinal,
1162 const char *its_name)
1167 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1169 if (strcmp ((*pq)->dllname, dllname) == 0)
1172 q->functail->next = xmalloc (sizeof (ifunctype));
1173 q->functail = q->functail->next;
1174 q->functail->ord = func_ordinal;
1175 q->functail->name = xstrdup (symbol_name);
1176 q->functail->its_name = (its_name ? xstrdup (its_name) : NULL);
1177 q->functail->next = NULL;
1183 q = xmalloc (sizeof (iheadtype));
1184 q->dllname = xstrdup (dllname);
1186 q->funchead = xmalloc (sizeof (ifunctype));
1187 q->functail = q->funchead;
1189 q->functail->name = xstrdup (symbol_name);
1190 q->functail->its_name = (its_name ? xstrdup (its_name) : NULL);
1191 q->functail->ord = func_ordinal;
1192 q->functail->next = NULL;
1197 /* def_import is called from within defparse.y when an IMPORT
1198 declaration is encountered. Depending on the form of the
1199 declaration, the module name may or may not need ".dll" to be
1200 appended to it, the name of the function may be stored in internal
1201 or entry, and there may or may not be an ordinal value associated
1204 /* A note regarding the parse modes:
1205 In defparse.y we have to accept import declarations which follow
1206 any one of the following forms:
1207 <func_name_in_app> = <dll_name>.<func_name_in_dll>
1208 <func_name_in_app> = <dll_name>.<number>
1209 <dll_name>.<func_name_in_dll>
1211 Furthermore, the dll's name may or may not end with ".dll", which
1212 complicates the parsing a little. Normally the dll's name is
1213 passed to def_import() in the "module" parameter, but when it ends
1214 with ".dll" it gets passed in "module" sans ".dll" and that needs
1217 def_import gets five parameters:
1218 APP_NAME - the name of the function in the application, if
1219 present, or NULL if not present.
1220 MODULE - the name of the dll, possibly sans extension (ie, '.dll').
1221 DLLEXT - the extension of the dll, if present, NULL if not present.
1222 ENTRY - the name of the function in the dll, if present, or NULL.
1223 ORD_VAL - the numerical tag of the function in the dll, if present,
1224 or NULL. Exactly one of <entry> or <ord_val> must be
1225 present (i.e., not NULL). */
1228 def_import (const char *app_name, const char *module, const char *dllext,
1229 const char *entry, int ord_val, const char *its_name)
1231 const char *application_name;
1235 application_name = entry;
1238 if (app_name != NULL)
1239 application_name = app_name;
1241 application_name = "";
1246 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
1247 sprintf (buf, "%s.%s", module, dllext);
1251 append_import (application_name, module, ord_val, its_name);
1255 def_version (int major, int minor)
1257 printf (_("VERSION %d.%d\n"), major, minor);
1261 def_section (const char *name, int attr)
1276 sprintf (buf, "-attr %s %s", name, atts);
1277 new_directive (xstrdup (buf));
1284 def_section ("CODE", attr);
1290 def_section ("DATA", attr);
1293 /**********************************************************************/
1296 run (const char *what, char *args)
1299 int pid, wait_status;
1302 char *errmsg_fmt, *errmsg_arg;
1303 char *temp_base = choose_temp_base ();
1305 inform (_("run: %s %s"), what, args);
1307 /* Count the args */
1309 for (s = args; *s; s++)
1313 argv = alloca (sizeof (char *) * (i + 3));
1322 while (*s != ' ' && *s != 0)
1330 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1331 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1335 inform ("%s", strerror (errno));
1337 fatal (errmsg_fmt, errmsg_arg);
1340 pid = pwait (pid, & wait_status, 0);
1344 /* xgettext:c-format */
1345 fatal (_("wait: %s"), strerror (errno));
1347 else if (WIFSIGNALED (wait_status))
1349 /* xgettext:c-format */
1350 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1352 else if (WIFEXITED (wait_status))
1354 if (WEXITSTATUS (wait_status) != 0)
1355 /* xgettext:c-format */
1356 non_fatal (_("%s exited with status %d"),
1357 what, WEXITSTATUS (wait_status));
1363 /* Look for a list of symbols to export in the .drectve section of
1364 ABFD. Pass each one to def_exports. */
1367 scan_drectve_symbols (bfd *abfd)
1375 /* Look for .drectve's */
1376 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1381 size = bfd_get_section_size (s);
1382 buf = xmalloc (size);
1384 bfd_get_section_contents (abfd, s, buf, 0, size);
1386 /* xgettext:c-format */
1387 inform (_("Sucking in info from %s section in %s"),
1388 DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1390 /* Search for -export: strings. The exported symbols can optionally
1391 have type tags (eg., -export:foo,data), so handle those as well.
1392 Currently only data tag is supported. */
1398 && CONST_STRNEQ (p, "-export:"))
1402 flagword flags = BSF_FUNCTION;
1405 /* Do we have a quoted export? */
1410 while (p < e && *p != '"')
1416 while (p < e && *p != ',' && *p != ' ' && *p != '-')
1419 c = xmalloc (p - name + 1);
1420 memcpy (c, name, p - name);
1422 /* Advance over trailing quote. */
1423 if (p < e && *p == '"')
1425 if (p < e && *p == ',') /* found type tag. */
1427 char *tag_start = ++p;
1428 while (p < e && *p != ' ' && *p != '-')
1430 if (CONST_STRNEQ (tag_start, "data"))
1431 flags &= ~BSF_FUNCTION;
1434 /* FIXME: The 5th arg is for the `constant' field.
1435 What should it be? Not that it matters since it's not
1436 currently useful. */
1437 def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0, NULL);
1439 if (add_stdcall_alias && strchr (c, '@'))
1441 int lead_at = (*c == '@') ;
1442 char *exported_name = xstrdup (c + lead_at);
1443 char *atsym = strchr (exported_name, '@');
1445 /* Note: stdcall alias symbols can never be data. */
1446 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0, NULL);
1455 /* Look through the symbols in MINISYMS, and add each one to list of
1456 symbols to export. */
1459 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1463 bfd_byte *from, *fromend;
1465 store = bfd_make_empty_symbol (abfd);
1467 bfd_fatal (bfd_get_filename (abfd));
1469 from = (bfd_byte *) minisyms;
1470 fromend = from + symcount * size;
1471 for (; from < fromend; from += size)
1474 const char *symbol_name;
1476 sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
1478 bfd_fatal (bfd_get_filename (abfd));
1480 symbol_name = bfd_asymbol_name (sym);
1481 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1484 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
1485 ! (sym->flags & BSF_FUNCTION), 0, NULL);
1487 if (add_stdcall_alias && strchr (symbol_name, '@'))
1489 int lead_at = (*symbol_name == '@');
1490 char *exported_name = xstrdup (symbol_name + lead_at);
1491 char *atsym = strchr (exported_name, '@');
1493 /* Note: stdcall alias symbols can never be data. */
1494 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0, NULL);
1499 /* Add a list of symbols to exclude. */
1502 add_excludes (const char *new_excludes)
1505 char *exclude_string;
1507 local_copy = xstrdup (new_excludes);
1509 exclude_string = strtok (local_copy, ",:");
1510 for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1512 struct string_list *new_exclude;
1514 new_exclude = ((struct string_list *)
1515 xmalloc (sizeof (struct string_list)));
1516 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1517 /* Don't add a leading underscore for fastcall symbols. */
1518 if (*exclude_string == '@')
1519 sprintf (new_exclude->string, "%s", exclude_string);
1521 sprintf (new_exclude->string, "%s%s", (!leading_underscore ? "" : "_"),
1523 new_exclude->next = excludes;
1524 excludes = new_exclude;
1526 /* xgettext:c-format */
1527 inform (_("Excluding symbol: %s"), exclude_string);
1533 /* See if STRING is on the list of symbols to exclude. */
1536 match_exclude (const char *string)
1538 struct string_list *excl_item;
1540 for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1541 if (strcmp (string, excl_item->string) == 0)
1546 /* Add the default list of symbols to exclude. */
1549 set_default_excludes (void)
1551 add_excludes (default_excludes);
1554 /* Choose which symbols to export. */
1557 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
1559 bfd_byte *from, *fromend, *to;
1562 store = bfd_make_empty_symbol (abfd);
1564 bfd_fatal (bfd_get_filename (abfd));
1566 from = (bfd_byte *) minisyms;
1567 fromend = from + symcount * size;
1568 to = (bfd_byte *) minisyms;
1570 for (; from < fromend; from += size)
1575 sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
1577 bfd_fatal (bfd_get_filename (abfd));
1579 /* Check for external and defined only symbols. */
1580 keep = (((sym->flags & BSF_GLOBAL) != 0
1581 || (sym->flags & BSF_WEAK) != 0
1582 || bfd_is_com_section (sym->section))
1583 && ! bfd_is_und_section (sym->section));
1585 keep = keep && ! match_exclude (sym->name);
1589 memcpy (to, from, size);
1594 return (to - (bfd_byte *) minisyms) / size;
1597 /* Export all symbols in ABFD, except for ones we were told not to
1601 scan_all_symbols (bfd *abfd)
1607 /* Ignore bfds with an import descriptor table. We assume that any
1608 such BFD contains symbols which are exported from another DLL,
1609 and we don't want to reexport them from here. */
1610 if (bfd_get_section_by_name (abfd, ".idata$4"))
1613 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1615 /* xgettext:c-format */
1616 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1620 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
1622 bfd_fatal (bfd_get_filename (abfd));
1626 /* xgettext:c-format */
1627 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1631 /* Discard the symbols we don't want to export. It's OK to do this
1632 in place; we'll free the storage anyway. */
1634 symcount = filter_symbols (abfd, minisyms, symcount, size);
1635 scan_filtered_symbols (abfd, minisyms, symcount, size);
1640 /* Look at the object file to decide which symbols to export. */
1643 scan_open_obj_file (bfd *abfd)
1645 if (export_all_symbols)
1646 scan_all_symbols (abfd);
1648 scan_drectve_symbols (abfd);
1650 /* FIXME: we ought to read in and block out the base relocations. */
1652 /* xgettext:c-format */
1653 inform (_("Done reading %s"), bfd_get_filename (abfd));
1657 scan_obj_file (const char *filename)
1659 bfd * f = bfd_openr (filename, 0);
1662 /* xgettext:c-format */
1663 fatal (_("Unable to open object file: %s: %s"), filename, bfd_get_errmsg ());
1665 /* xgettext:c-format */
1666 inform (_("Scanning object file %s"), filename);
1668 if (bfd_check_format (f, bfd_archive))
1670 bfd *arfile = bfd_openr_next_archived_file (f, 0);
1673 if (bfd_check_format (arfile, bfd_object))
1674 scan_open_obj_file (arfile);
1676 arfile = bfd_openr_next_archived_file (f, arfile);
1679 #ifdef DLLTOOL_MCORE_ELF
1680 if (mcore_elf_out_file)
1681 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);
1684 else if (bfd_check_format (f, bfd_object))
1686 scan_open_obj_file (f);
1688 #ifdef DLLTOOL_MCORE_ELF
1689 if (mcore_elf_out_file)
1690 mcore_elf_cache_filename (filename);
1700 dump_def_info (FILE *f)
1704 fprintf (f, "%s ", ASM_C);
1705 for (i = 0; oav[i]; i++)
1706 fprintf (f, "%s ", oav[i]);
1708 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1710 fprintf (f, "%s %d = %s %s @ %d %s%s%s%s%s%s\n",
1716 exp->noname ? "NONAME " : "",
1717 exp->private ? "PRIVATE " : "",
1718 exp->constant ? "CONSTANT" : "",
1719 exp->data ? "DATA" : "",
1720 exp->its_name ? " ==" : "",
1721 exp->its_name ? exp->its_name : "");
1725 /* Generate the .exp file. */
1728 sfunc (const void *a, const void *b)
1730 if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1733 return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
1737 flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1741 /* Flush this page. */
1742 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1746 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1748 (on_page * 2) + (on_page & 1) * 2 + 8,
1751 for (i = 0; i < on_page; i++)
1753 bfd_vma needed = need[i];
1757 if (!create_for_pep)
1759 /* Relocation via HIGHLOW. */
1760 needed = ((needed - page_addr) | 0x3000) & 0xffff;
1764 /* Relocation via DIR64. */
1765 needed = ((needed - page_addr) | 0xa000) & 0xffff;
1769 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1774 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1783 inform (_("Adding exports to output file"));
1785 fprintf (output_def, ";");
1786 for (i = 0; oav[i]; i++)
1787 fprintf (output_def, " %s", oav[i]);
1789 fprintf (output_def, "\nEXPORTS\n");
1791 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1793 char *quote = strchr (exp->name, '.') ? "\"" : "";
1794 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1798 fprintf (output_def,";\t%s\n", res);
1802 if (strcmp (exp->name, exp->internal_name) == 0)
1804 fprintf (output_def, "\t%s%s%s @ %d%s%s%s%s%s\n",
1809 exp->noname ? " NONAME" : "",
1810 exp->private ? "PRIVATE " : "",
1811 exp->data ? " DATA" : "",
1812 exp->its_name ? " ==" : "",
1813 exp->its_name ? exp->its_name : "");
1817 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1819 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1827 exp->noname ? " NONAME" : "",
1828 exp->private ? "PRIVATE " : "",
1829 exp->data ? " DATA" : "",
1830 exp->its_name ? " ==" : "",
1831 exp->its_name ? exp->its_name : "");
1835 inform (_("Added exports to output file"));
1838 /* generate_idata_ofile generates the portable assembly source code
1839 for the idata sections. It appends the source code to the end of
1843 generate_idata_ofile (FILE *filvar)
1851 if (import_list == NULL)
1854 fprintf (filvar, "%s Import data sections\n", ASM_C);
1855 fprintf (filvar, "\n\t.section\t.idata$2\n");
1856 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1857 fprintf (filvar, "doi_idata:\n");
1860 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1862 fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1863 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1864 ASM_C, headptr->dllname);
1865 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1866 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1867 fprintf (filvar, "\t%sdllname%d%s\n",
1868 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1869 fprintf (filvar, "\t%slisttwo%d%s\n\n",
1870 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1874 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1875 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1876 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
1877 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1878 fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1880 fprintf (filvar, "\n\t.section\t.idata$4\n");
1882 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1884 fprintf (filvar, "listone%d:\n", headindex);
1885 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1888 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1889 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1892 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1893 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1896 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1898 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1902 fprintf (filvar, "\n\t.section\t.idata$5\n");
1904 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1906 fprintf (filvar, "listtwo%d:\n", headindex);
1907 for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1910 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1911 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1914 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1915 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1918 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1920 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1924 fprintf (filvar, "\n\t.section\t.idata$6\n");
1926 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1929 for (funcptr = headptr->funchead; funcptr != NULL;
1930 funcptr = funcptr->next)
1932 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1933 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1934 ((funcptr->ord) & 0xFFFF));
1935 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT,
1936 (funcptr->its_name ? funcptr->its_name : funcptr->name));
1937 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1943 fprintf (filvar, "\n\t.section\t.idata$7\n");
1945 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1947 fprintf (filvar,"dllname%d:\n", headindex);
1948 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1949 fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1954 /* Assemble the specified file. */
1956 assemble_file (const char * source, const char * dest)
1960 cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags)
1961 + strlen (source) + strlen (dest) + 50);
1963 sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1976 /* xgettext:c-format */
1977 inform (_("Generating export file: %s"), exp_name);
1979 f = fopen (TMP_ASM, FOPEN_WT);
1981 /* xgettext:c-format */
1982 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1984 /* xgettext:c-format */
1985 inform (_("Opened temporary file: %s"), TMP_ASM);
1991 fprintf (f, "\t.section .edata\n\n");
1992 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
1993 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG,
1994 (unsigned long) time(0), ASM_C);
1995 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
1996 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1997 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
2000 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
2001 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
2003 d_named_nfuncs, d_low_ord, d_high_ord);
2004 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
2005 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
2006 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2008 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
2009 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2011 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2013 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
2016 fprintf(f,"%s Export address Table\n", ASM_C);
2017 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
2018 fprintf (f, "afuncs:\n");
2021 for (exp = d_exports; exp; exp = exp->next)
2023 if (exp->ordinal != i)
2025 while (i < exp->ordinal)
2027 fprintf(f,"\t%s\t0\n", ASM_LONG);
2032 if (exp->forward == 0)
2034 if (exp->internal_name[0] == '@')
2035 fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2036 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2038 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2039 ASM_PREFIX (exp->internal_name),
2040 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2043 fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
2044 exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2048 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
2049 fprintf (f, "anames:\n");
2051 for (i = 0; (exp = d_exports_lexically[i]); i++)
2053 if (!exp->noname || show_allnames)
2054 fprintf (f, "\t%sn%d%s\n",
2055 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
2058 fprintf (f,"%s Export Ordinal Table\n", ASM_C);
2059 fprintf (f, "anords:\n");
2060 for (i = 0; (exp = d_exports_lexically[i]); i++)
2062 if (!exp->noname || show_allnames)
2063 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
2066 fprintf(f,"%s Export Name Table\n", ASM_C);
2067 for (i = 0; (exp = d_exports_lexically[i]); i++)
2069 if (!exp->noname || show_allnames)
2070 fprintf (f, "n%d: %s \"%s\"\n",
2071 exp->ordinal, ASM_TEXT,
2072 (exp->its_name ? exp->its_name : xlate (exp->name)));
2073 if (exp->forward != 0)
2074 fprintf (f, "f%d: %s \"%s\"\n",
2075 exp->forward, ASM_TEXT, exp->internal_name);
2080 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
2081 for (dl = a_list; dl; dl = dl->next)
2083 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
2089 fprintf (f, "\t.section .rdata\n");
2090 for (dl = d_list; dl; dl = dl->next)
2095 /* We don't output as ascii because there can
2096 be quote characters in the string. */
2098 for (p = dl->text; *p; p++)
2101 fprintf (f, "\t%s\t", ASM_BYTE);
2104 fprintf (f, "%d", *p);
2107 fprintf (f, ",0\n");
2121 /* Add to the output file a way of getting to the exported names
2122 without using the import library. */
2125 fprintf (f, "\t.section\t.rdata\n");
2126 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2127 if (!exp->noname || show_allnames)
2129 /* We use a single underscore for MS compatibility, and a
2130 double underscore for backward compatibility with old
2132 if (create_compat_implib)
2133 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2134 fprintf (f, "\t%s\t_imp_%s%s\n", ASM_GLOBAL,
2135 (!leading_underscore ? "" : "_"), exp->name);
2136 if (create_compat_implib)
2137 fprintf (f, "__imp_%s:\n", exp->name);
2138 fprintf (f, "_imp_%s%s:\n", (!leading_underscore ? "" : "_"), exp->name);
2139 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
2143 /* Dump the reloc section if a base file is provided. */
2147 bfd_vma need[COFF_PAGE_SIZE];
2149 bfd_size_type numbytes;
2154 fprintf (f, "\t.section\t.init\n");
2155 fprintf (f, "lab:\n");
2157 fseek (base_file, 0, SEEK_END);
2158 numbytes = ftell (base_file);
2159 fseek (base_file, 0, SEEK_SET);
2160 copy = xmalloc (numbytes);
2161 if (fread (copy, 1, numbytes, base_file) < numbytes)
2162 fatal (_("failed to read the number of entries from base file"));
2163 num_entries = numbytes / sizeof (bfd_vma);
2166 fprintf (f, "\t.section\t.reloc\n");
2171 bfd_vma last = (bfd_vma) -1;
2172 qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
2173 /* Delete duplicates */
2174 for (src = 0; src < num_entries; src++)
2176 if (last != copy[src])
2177 last = copy[dst++] = copy[src];
2181 page_addr = addr & PAGE_MASK; /* work out the page addr */
2183 for (j = 0; j < num_entries; j++)
2186 if ((addr & PAGE_MASK) != page_addr)
2188 flush_page (f, need, page_addr, on_page);
2190 page_addr = addr & PAGE_MASK;
2192 need[on_page++] = addr;
2194 flush_page (f, need, page_addr, on_page);
2196 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2200 generate_idata_ofile (f);
2204 /* Assemble the file. */
2205 assemble_file (TMP_ASM, exp_name);
2207 if (dontdeltemps == 0)
2210 inform (_("Generated exports file"));
2214 xlate (const char *name)
2216 int lead_at = (*name == '@');
2217 int is_stdcall = (!lead_at && strchr (name, '@') != NULL);
2219 if (!lead_at && (add_underscore
2220 || (add_stdcall_underscore && is_stdcall)))
2222 char *copy = xmalloc (strlen (name) + 2);
2225 strcpy (copy + 1, name);
2234 /* PR 9766: Look for the last @ sign in the name. */
2235 p = strrchr (name, '@');
2236 if (p && ISDIGIT (p[1]))
2252 unsigned char *data;
2267 #define TEXT_SEC_FLAGS \
2268 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2269 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2270 #define BSS_SEC_FLAGS SEC_ALLOC
2272 #define INIT_SEC_DATA(id, name, flags, align) \
2273 { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2274 static sinfo secdata[NSECS] =
2276 INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2),
2277 INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2),
2278 INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2),
2279 INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2),
2280 INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2),
2281 INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
2282 INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
2287 /* Sections numbered to make the order the same as other PowerPC NT
2288 compilers. This also keeps funny alignment thingies from happening. */
2301 static sinfo secdata[NSECS] =
2303 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
2304 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
2305 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
2306 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
2307 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
2308 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
2309 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
2310 { DATA, ".data", SEC_DATA, 2},
2311 { BSS, ".bss", 0, 2}
2316 /* This is what we're trying to make. We generate the imp symbols with
2317 both single and double underscores, for compatibility.
2320 .global _GetFileVersionInfoSizeW@8
2321 .global __imp_GetFileVersionInfoSizeW@8
2322 _GetFileVersionInfoSizeW@8:
2323 jmp * __imp_GetFileVersionInfoSizeW@8
2324 .section .idata$7 # To force loading of head
2325 .long __version_a_head
2326 # Import Address Table
2328 __imp_GetFileVersionInfoSizeW@8:
2331 # Import Lookup Table
2337 .asciz "GetFileVersionInfoSizeW"
2340 For the PowerPC, here's the variation on the above scheme:
2342 # Rather than a simple "jmp *", the code to get to the dll function
2345 lwz r11,[tocv]__imp_function_name(r2)
2346 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2354 make_label (const char *prefix, const char *name)
2356 int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2357 char *copy = xmalloc (len + 1);
2359 strcpy (copy, ASM_PREFIX (name));
2360 strcat (copy, prefix);
2361 strcat (copy, name);
2366 make_imp_label (const char *prefix, const char *name)
2373 len = strlen (prefix) + strlen (name);
2374 copy = xmalloc (len + 1);
2375 strcpy (copy, prefix);
2376 strcat (copy, name);
2380 len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2381 copy = xmalloc (len + 1);
2382 strcpy (copy, prefix);
2383 strcat (copy, ASM_PREFIX (name));
2384 strcat (copy, name);
2390 make_one_lib_file (export_type *exp, int i, int delay)
2393 asymbol * exp_label;
2394 asymbol * iname = 0;
2396 asymbol * iname_lab;
2397 asymbol ** iname_lab_pp;
2398 asymbol ** iname_pp;
2407 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2408 flagword applicable;
2409 char * outname = xmalloc (strlen (TMP_STUB) + 10);
2413 sprintf (outname, "%s%05d.o", TMP_STUB, i);
2415 abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2418 /* xgettext:c-format */
2419 fatal (_("bfd_open failed open stub file: %s: %s"),
2420 outname, bfd_get_errmsg ());
2422 /* xgettext:c-format */
2423 inform (_("Creating stub file: %s"), outname);
2425 bfd_set_format (abfd, bfd_object);
2426 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2429 if (machine == MARM_INTERWORK || machine == MTHUMB)
2430 bfd_set_private_flags (abfd, F_INTERWORK);
2433 applicable = bfd_applicable_section_flags (abfd);
2435 /* First make symbols for the sections. */
2436 for (i = 0; i < NSECS; i++)
2438 sinfo *si = secdata + i;
2442 si->sec = bfd_make_section_old_way (abfd, si->name);
2443 bfd_set_section_flags (abfd,
2445 si->flags & applicable);
2447 bfd_set_section_alignment(abfd, si->sec, si->align);
2448 si->sec->output_section = si->sec;
2449 si->sym = bfd_make_empty_symbol(abfd);
2450 si->sym->name = si->sec->name;
2451 si->sym->section = si->sec;
2452 si->sym->flags = BSF_LOCAL;
2454 ptrs[oidx] = si->sym;
2455 si->sympp = ptrs + oidx;
2464 exp_label = bfd_make_empty_symbol (abfd);
2465 exp_label->name = make_imp_label ("", exp->name);
2467 /* On PowerPC, the function name points to a descriptor in
2468 the rdata section, the first element of which is a
2469 pointer to the code (..function_name), and the second
2470 points to the .toc. */
2472 if (machine == MPPC)
2473 exp_label->section = secdata[RDATA].sec;
2476 exp_label->section = secdata[TEXT].sec;
2478 exp_label->flags = BSF_GLOBAL;
2479 exp_label->value = 0;
2482 if (machine == MTHUMB)
2483 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2485 ptrs[oidx++] = exp_label;
2488 /* Generate imp symbols with one underscore for Microsoft
2489 compatibility, and with two underscores for backward
2490 compatibility with old versions of cygwin. */
2491 if (create_compat_implib)
2493 iname = bfd_make_empty_symbol (abfd);
2494 iname->name = make_imp_label ("___imp", exp->name);
2495 iname->section = secdata[IDATA5].sec;
2496 iname->flags = BSF_GLOBAL;
2500 iname2 = bfd_make_empty_symbol (abfd);
2501 iname2->name = make_imp_label ("__imp_", exp->name);
2502 iname2->section = secdata[IDATA5].sec;
2503 iname2->flags = BSF_GLOBAL;
2506 iname_lab = bfd_make_empty_symbol (abfd);
2508 iname_lab->name = head_label;
2509 iname_lab->section = (asection *) &bfd_und_section;
2510 iname_lab->flags = 0;
2511 iname_lab->value = 0;
2513 iname_pp = ptrs + oidx;
2514 if (create_compat_implib)
2515 ptrs[oidx++] = iname;
2516 ptrs[oidx++] = iname2;
2518 iname_lab_pp = ptrs + oidx;
2519 ptrs[oidx++] = iname_lab;
2522 /* The symbol referring to the code (.text). */
2524 asymbol *function_name;
2526 function_name = bfd_make_empty_symbol(abfd);
2527 function_name->name = make_label ("..", exp->name);
2528 function_name->section = secdata[TEXT].sec;
2529 function_name->flags = BSF_GLOBAL;
2530 function_name->value = 0;
2532 fn_pp = ptrs + oidx;
2533 ptrs[oidx++] = function_name;
2536 /* The .toc symbol. */
2538 asymbol *toc_symbol;
2540 toc_symbol = bfd_make_empty_symbol (abfd);
2541 toc_symbol->name = make_label (".", "toc");
2542 toc_symbol->section = (asection *)&bfd_und_section;
2543 toc_symbol->flags = BSF_GLOBAL;
2544 toc_symbol->value = 0;
2546 toc_pp = ptrs + oidx;
2547 ptrs[oidx++] = toc_symbol;
2553 for (i = 0; i < NSECS; i++)
2555 sinfo *si = secdata + i;
2556 asection *sec = si->sec;
2557 arelent *rel, *rel2 = 0, *rel3 = 0;
2565 si->size = HOW_JTAB_SIZE;
2566 si->data = xmalloc (HOW_JTAB_SIZE);
2567 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2569 /* Add the reloc into idata$5. */
2570 rel = xmalloc (sizeof (arelent));
2572 rpp = xmalloc (sizeof (arelent *) * (delay ? 4 : 2));
2576 rel->address = HOW_JTAB_ROFF;
2581 rel2 = xmalloc (sizeof (arelent));
2583 rel2->address = HOW_JTAB_ROFF2;
2585 rel3 = xmalloc (sizeof (arelent));
2587 rel3->address = HOW_JTAB_ROFF3;
2592 if (machine == MPPC)
2594 rel->howto = bfd_reloc_type_lookup (abfd,
2595 BFD_RELOC_16_GOTOFF);
2596 rel->sym_ptr_ptr = iname_pp;
2598 else if (machine == MX86)
2600 rel->howto = bfd_reloc_type_lookup (abfd,
2601 BFD_RELOC_32_PCREL);
2602 rel->sym_ptr_ptr = iname_pp;
2606 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2607 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2612 rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2613 rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
2614 rel3->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32_PCREL);
2615 rel3->sym_ptr_ptr = iname_lab_pp;
2618 sec->orelocation = rpp;
2619 sec->reloc_count = delay ? 3 : 1;
2626 si->data = xmalloc (4);
2628 sec->reloc_count = 1;
2629 memset (si->data, 0, si->size);
2631 rel = xmalloc (sizeof (arelent));
2632 rpp = xmalloc (sizeof (arelent *) * 2);
2637 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2638 rel->sym_ptr_ptr = secdata[TEXT].sympp;
2639 sec->orelocation = rpp;
2642 /* else fall through */
2644 /* An idata$4 or idata$5 is one word long, and has an
2649 si->data = xmalloc (8);
2653 si->data[0] = exp->ordinal ;
2654 si->data[1] = exp->ordinal >> 8;
2655 si->data[2] = exp->ordinal >> 16;
2656 si->data[3] = exp->ordinal >> 24;
2664 sec->reloc_count = 1;
2665 memset (si->data, 0, si->size);
2666 rel = xmalloc (sizeof (arelent));
2667 rpp = xmalloc (sizeof (arelent *) * 2);
2672 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2673 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2674 sec->orelocation = rpp;
2679 si->data = xmalloc (4);
2684 si->data[0] = exp->ordinal ;
2685 si->data[1] = exp->ordinal >> 8;
2686 si->data[2] = exp->ordinal >> 16;
2691 sec->reloc_count = 1;
2692 memset (si->data, 0, si->size);
2693 rel = xmalloc (sizeof (arelent));
2694 rpp = xmalloc (sizeof (arelent *) * 2);
2699 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2700 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2701 sec->orelocation = rpp;
2709 /* This used to add 1 to exp->hint. I don't know
2710 why it did that, and it does not match what I see
2711 in programs compiled with the MS tools. */
2712 int idx = exp->hint;
2714 si->size = strlen (exp->its_name) + 3;
2716 si->size = strlen (xlate (exp->import_name)) + 3;
2717 si->data = xmalloc (si->size);
2718 si->data[0] = idx & 0xff;
2719 si->data[1] = idx >> 8;
2721 strcpy ((char *) si->data + 2, exp->its_name);
2723 strcpy ((char *) si->data + 2, xlate (exp->import_name));
2730 si->data = xmalloc (4);
2731 memset (si->data, 0, si->size);
2732 rel = xmalloc (sizeof (arelent));
2733 rpp = xmalloc (sizeof (arelent *) * 2);
2737 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2738 rel->sym_ptr_ptr = iname_lab_pp;
2739 sec->orelocation = rpp;
2740 sec->reloc_count = 1;
2746 /* The .pdata section is 5 words long.
2750 bfd_vma BeginAddress, [0x00]
2752 ExceptionHandler, [0x08]
2754 PrologEndAddress; [0x10]
2757 /* So this pdata section setups up this as a glue linkage to
2758 a dll routine. There are a number of house keeping things
2761 1. In the name of glue trickery, the ADDR32 relocs for 0,
2762 4, and 0x10 are set to point to the same place:
2764 2. There is one more reloc needed in the pdata section.
2765 The actual glue instruction to restore the toc on
2766 return is saved as the offset in an IMGLUE reloc.
2767 So we need a total of four relocs for this section.
2769 3. Lastly, the HandlerData field is set to 0x03, to indicate
2770 that this is a glue routine. */
2771 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2773 /* Alignment must be set to 2**2 or you get extra stuff. */
2774 bfd_set_section_alignment(abfd, sec, 2);
2777 si->data = xmalloc (si->size);
2778 memset (si->data, 0, si->size);
2779 rpp = xmalloc (sizeof (arelent *) * 5);
2780 rpp[0] = imglue = xmalloc (sizeof (arelent));
2781 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
2782 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
2783 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2786 /* Stick the toc reload instruction in the glue reloc. */
2787 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2790 imglue->howto = bfd_reloc_type_lookup (abfd,
2791 BFD_RELOC_32_GOTOFF);
2792 imglue->sym_ptr_ptr = fn_pp;
2794 ba_rel->address = 0;
2796 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2797 ba_rel->sym_ptr_ptr = fn_pp;
2799 bfd_put_32 (abfd, 0x18, si->data + 0x04);
2800 ea_rel->address = 4;
2802 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2803 ea_rel->sym_ptr_ptr = fn_pp;
2805 /* Mark it as glue. */
2806 bfd_put_32 (abfd, 0x03, si->data + 0x0c);
2808 /* Mark the prolog end address. */
2809 bfd_put_32 (abfd, 0x0D, si->data + 0x10);
2810 pea_rel->address = 0x10;
2811 pea_rel->addend = 0;
2812 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2813 pea_rel->sym_ptr_ptr = fn_pp;
2815 sec->orelocation = rpp;
2816 sec->reloc_count = 4;
2820 /* Each external function in a PowerPC PE file has a two word
2821 descriptor consisting of:
2822 1. The address of the code.
2823 2. The address of the appropriate .toc
2824 We use relocs to build this. */
2826 si->data = xmalloc (8);
2827 memset (si->data, 0, si->size);
2829 rpp = xmalloc (sizeof (arelent *) * 3);
2830 rpp[0] = rel = xmalloc (sizeof (arelent));
2831 rpp[1] = xmalloc (sizeof (arelent));
2836 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2837 rel->sym_ptr_ptr = fn_pp;
2843 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2844 rel->sym_ptr_ptr = toc_pp;
2846 sec->orelocation = rpp;
2847 sec->reloc_count = 2;
2849 #endif /* DLLTOOL_PPC */
2855 /* Size up all the sections. */
2856 for (i = 0; i < NSECS; i++)
2858 sinfo *si = secdata + i;
2860 bfd_set_section_size (abfd, si->sec, si->size);
2861 bfd_set_section_vma (abfd, si->sec, vma);
2864 /* Write them out. */
2865 for (i = 0; i < NSECS; i++)
2867 sinfo *si = secdata + i;
2869 if (i == IDATA5 && no_idata5)
2872 if (i == IDATA4 && no_idata4)
2875 bfd_set_section_contents (abfd, si->sec,
2880 bfd_set_symtab (abfd, ptrs, oidx);
2882 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2884 /* xgettext:c-format */
2885 fatal (_("bfd_open failed reopen stub file: %s: %s"),
2886 outname, bfd_get_errmsg ());
2894 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2899 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2903 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2904 fprintf (f, "\t.section\t.idata$2\n");
2906 fprintf (f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
2908 fprintf (f, "%s:\n", head_label);
2910 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2911 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2913 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2914 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2915 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2916 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2917 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2922 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2924 ASM_RVA_AFTER, ASM_C);
2926 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2930 fprintf (f, "\t.section\t.idata$5\n");
2931 if (use_nul_prefixed_import_tables)
2934 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2936 fprintf (f,"\t%s\t0\n", ASM_LONG);
2938 fprintf (f, "fthunk:\n");
2943 fprintf (f, "\t.section\t.idata$4\n");
2944 if (use_nul_prefixed_import_tables)
2947 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2949 fprintf (f,"\t%s\t0\n", ASM_LONG);
2951 fprintf (f, "hname:\n");
2956 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2958 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2960 /* xgettext:c-format */
2961 fatal (_("failed to open temporary head file: %s: %s"),
2962 TMP_HEAD_O, bfd_get_errmsg ());
2968 make_delay_head (void)
2970 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2975 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2979 /* Output the __tailMerge__xxx function */
2980 fprintf (f, "%s Import trampoline\n", ASM_C);
2981 fprintf (f, "\t.section\t.text\n");
2982 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
2983 fprintf (f, "%s:\n", head_label);
2984 fprintf (f, mtable[machine].trampoline, imp_name_lab);
2986 /* Output the delay import descriptor */
2987 fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
2988 fprintf (f, ".section\t.text$2\n");
2989 fprintf (f,"%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
2990 fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
2991 fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
2992 fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n",
2993 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2994 fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
2995 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2996 fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n",
2997 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
2998 fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n",
2999 ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
3000 fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C);
3001 fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C);
3002 fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C);
3004 /* Output the dll_handle */
3005 fprintf (f, "\n.section .data\n");
3006 fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
3007 fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
3010 fprintf (f, "%sStuff for compatibility\n", ASM_C);
3014 fprintf (f, "\t.section\t.idata$5\n");
3015 /* NULL terminating list. */
3016 #ifdef DLLTOOL_MX86_64
3017 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3019 fprintf (f,"\t%s\t0\n", ASM_LONG);
3021 fprintf (f, "__IAT_%s:\n", imp_name_lab);
3026 fprintf (f, "\t.section\t.idata$4\n");
3027 fprintf (f, "\t%s\t0\n", ASM_LONG);
3028 fprintf (f, "\t.section\t.idata$4\n");
3029 fprintf (f, "__INT_%s:\n", imp_name_lab);
3032 fprintf (f, "\t.section\t.idata$2\n");
3036 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
3038 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
3040 /* xgettext:c-format */
3041 fatal (_("failed to open temporary head file: %s: %s"),
3042 TMP_HEAD_O, bfd_get_errmsg ());
3050 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
3055 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
3061 fprintf (f, "\t.section\t.idata$4\n");
3063 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3065 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
3070 fprintf (f, "\t.section\t.idata$5\n");
3072 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3074 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
3078 /* Normally, we need to see a null descriptor built in idata$3 to
3079 act as the terminator for the list. The ideal way, I suppose,
3080 would be to mark this section as a comdat type 2 section, so
3081 only one would appear in the final .exe (if our linker supported
3082 comdat, that is) or cause it to be inserted by something else (say
3085 fprintf (f, "\t.section\t.idata$3\n");
3086 fprintf (f, "\t%s\t0\n", ASM_LONG);
3087 fprintf (f, "\t%s\t0\n", ASM_LONG);
3088 fprintf (f, "\t%s\t0\n", ASM_LONG);
3089 fprintf (f, "\t%s\t0\n", ASM_LONG);
3090 fprintf (f, "\t%s\t0\n", ASM_LONG);
3094 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
3095 do too. Original, huh? */
3096 fprintf (f, "\t.section\t.idata$6\n");
3098 fprintf (f, "\t.section\t.idata$7\n");
3101 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
3102 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
3103 imp_name_lab, ASM_TEXT, dll_name);
3107 assemble_file (TMP_TAIL_S, TMP_TAIL_O);
3109 abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
3111 /* xgettext:c-format */
3112 fatal (_("failed to open temporary tail file: %s: %s"),
3113 TMP_TAIL_O, bfd_get_errmsg ());
3119 gen_lib_file (int delay)
3130 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
3133 /* xgettext:c-format */
3134 fatal (_("Can't create .lib file: %s: %s"),
3135 imp_name, bfd_get_errmsg ());
3137 /* xgettext:c-format */
3138 inform (_("Creating library file: %s"), imp_name);
3140 bfd_set_format (outarch, bfd_archive);
3141 outarch->has_armap = 1;
3142 outarch->is_thin_archive = 0;
3144 /* Work out a reasonable size of things to put onto one line. */
3147 ar_head = make_delay_head ();
3151 ar_head = make_head ();
3153 ar_tail = make_tail();
3155 if (ar_head == NULL || ar_tail == NULL)
3158 for (i = 0; (exp = d_exports_lexically[i]); i++)
3161 /* Don't add PRIVATE entries to import lib. */
3164 n = make_one_lib_file (exp, i, delay);
3165 n->archive_next = head;
3167 if (ext_prefix_alias)
3169 export_type alias_exp;
3171 assert (i < PREFIX_ALIAS_BASE);
3172 alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
3173 alias_exp.internal_name = exp->internal_name;
3174 alias_exp.its_name = exp->its_name;
3175 alias_exp.import_name = exp->name;
3176 alias_exp.ordinal = exp->ordinal;
3177 alias_exp.constant = exp->constant;
3178 alias_exp.noname = exp->noname;
3179 alias_exp.private = exp->private;
3180 alias_exp.data = exp->data;
3181 alias_exp.hint = exp->hint;
3182 alias_exp.forward = exp->forward;
3183 alias_exp.next = exp->next;
3184 n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay);
3185 n->archive_next = head;
3190 /* Now stick them all into the archive. */
3191 ar_head->archive_next = head;
3192 ar_tail->archive_next = ar_head;
3195 if (! bfd_set_archive_head (outarch, head))
3196 bfd_fatal ("bfd_set_archive_head");
3198 if (! bfd_close (outarch))
3199 bfd_fatal (imp_name);
3201 while (head != NULL)
3203 bfd *n = head->archive_next;
3208 /* Delete all the temp files. */
3209 if (dontdeltemps == 0)
3211 unlink (TMP_HEAD_O);
3212 unlink (TMP_HEAD_S);
3213 unlink (TMP_TAIL_O);
3214 unlink (TMP_TAIL_S);
3217 if (dontdeltemps < 2)
3221 name = (char *) alloca (strlen (TMP_STUB) + 10);
3222 for (i = 0; (exp = d_exports_lexically[i]); i++)
3224 /* Don't delete non-existent stubs for PRIVATE entries. */
3227 sprintf (name, "%s%05d.o", TMP_STUB, i);
3228 if (unlink (name) < 0)
3229 /* xgettext:c-format */
3230 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3231 if (ext_prefix_alias)
3233 sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
3234 if (unlink (name) < 0)
3235 /* xgettext:c-format */
3236 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3241 inform (_("Created lib file"));
3244 /* Append a copy of data (cast to char *) to list. */
3247 dll_name_list_append (dll_name_list_type * list, bfd_byte * data)
3249 dll_name_list_node_type * entry;
3251 /* Error checking. */
3252 if (! list || ! list->tail)
3255 /* Allocate new node. */
3256 entry = ((dll_name_list_node_type *)
3257 xmalloc (sizeof (dll_name_list_node_type)));
3259 /* Initialize its values. */
3260 entry->dllname = xstrdup ((char *) data);
3263 /* Add to tail, and move tail. */
3264 list->tail->next = entry;
3268 /* Count the number of entries in list. */
3271 dll_name_list_count (dll_name_list_type * list)
3273 dll_name_list_node_type * p;
3276 /* Error checking. */
3277 if (! list || ! list->head)
3282 while (p && p->next)
3290 /* Print each entry in list to stdout. */
3293 dll_name_list_print (dll_name_list_type * list)
3295 dll_name_list_node_type * p;
3297 /* Error checking. */
3298 if (! list || ! list->head)
3303 while (p && p->next && p->next->dllname && *(p->next->dllname))
3305 printf ("%s\n", p->next->dllname);
3310 /* Free all entries in list, and list itself. */
3313 dll_name_list_free (dll_name_list_type * list)
3317 dll_name_list_free_contents (list->head);
3324 /* Recursive function to free all nodes entry->next->next...
3325 as well as entry itself. */
3328 dll_name_list_free_contents (dll_name_list_node_type * entry)
3334 dll_name_list_free_contents (entry->next);
3339 free (entry->dllname);
3340 entry->dllname = NULL;
3346 /* Allocate and initialize a dll_name_list_type object,
3347 including its sentinel node. Caller is responsible
3348 for calling dll_name_list_free when finished with
3351 static dll_name_list_type *
3352 dll_name_list_create (void)
3354 /* Allocate list. */
3355 dll_name_list_type * list = xmalloc (sizeof (dll_name_list_type));
3357 /* Allocate and initialize sentinel node. */
3358 list->head = xmalloc (sizeof (dll_name_list_node_type));
3359 list->head->dllname = NULL;
3360 list->head->next = NULL;
3362 /* Bookkeeping for empty list. */
3363 list->tail = list->head;
3368 /* Search the symbol table of the suppled BFD for a symbol whose name matches
3369 OBJ (where obj is cast to const char *). If found, set global variable
3370 identify_member_contains_symname_result TRUE. It is the caller's
3371 responsibility to set the result variable FALSE before iterating with
3375 identify_member_contains_symname (bfd * abfd,
3376 bfd * archive_bfd ATTRIBUTE_UNUSED,
3379 long storage_needed;
3380 asymbol ** symbol_table;
3381 long number_of_symbols;
3383 symname_search_data_type * search_data = (symname_search_data_type *) obj;
3385 /* If we already found the symbol in a different member,
3387 if (search_data->found)
3390 storage_needed = bfd_get_symtab_upper_bound (abfd);
3391 if (storage_needed <= 0)
3394 symbol_table = xmalloc (storage_needed);
3395 number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
3396 if (number_of_symbols < 0)
3398 free (symbol_table);
3402 for (i = 0; i < number_of_symbols; i++)
3404 if (strncmp (symbol_table[i]->name,
3405 search_data->symname,
3406 strlen (search_data->symname)) == 0)
3408 search_data->found = TRUE;
3412 free (symbol_table);
3415 /* This is the main implementation for the --identify option.
3416 Given the name of an import library in identify_imp_name, first determine
3417 if the import library is a GNU binutils-style one (where the DLL name is
3418 stored in an .idata$7 (.idata$6 on PPC) section, or if it is a MS-style
3419 one (where the DLL name, along with much other data, is stored in the
3420 .idata$6 section). We determine the style of import library by searching
3421 for the DLL-structure symbol inserted by MS tools:
3422 __NULL_IMPORT_DESCRIPTOR.
3424 Once we know which section to search, evaluate each section for the
3425 appropriate properties that indicate it may contain the name of the
3426 associated DLL (this differs depending on the style). Add the contents
3427 of all sections which meet the criteria to a linked list of dll names.
3429 Finally, print them all to stdout. (If --identify-strict, an error is
3430 reported if more than one match was found). */
3433 identify_dll_for_implib (void)
3437 identify_data_type identify_data;
3438 symname_search_data_type search_data;
3440 /* Initialize identify_data. */
3441 identify_data.list = dll_name_list_create ();
3442 identify_data.ms_style_implib = FALSE;
3444 /* Initialize search_data. */
3445 search_data.symname = "__NULL_IMPORT_DESCRIPTOR";
3446 search_data.found = FALSE;
3450 abfd = bfd_openr (identify_imp_name, 0);
3452 /* xgettext:c-format */
3453 fatal (_("Can't open .lib file: %s: %s"),
3454 identify_imp_name, bfd_get_errmsg ());
3456 if (! bfd_check_format (abfd, bfd_archive))
3458 if (! bfd_close (abfd))
3459 bfd_fatal (identify_imp_name);
3461 fatal (_("%s is not a library"), identify_imp_name);
3464 /* Detect if this a Microsoft import library. */
3465 identify_search_archive (abfd,
3466 identify_member_contains_symname,
3467 (void *)(& search_data));
3468 if (search_data.found)
3469 identify_data.ms_style_implib = TRUE;
3471 /* Rewind the bfd. */
3472 if (! bfd_close (abfd))
3473 bfd_fatal (identify_imp_name);
3474 abfd = bfd_openr (identify_imp_name, 0);
3476 bfd_fatal (identify_imp_name);
3478 if (!bfd_check_format (abfd, bfd_archive))
3480 if (!bfd_close (abfd))
3481 bfd_fatal (identify_imp_name);
3483 fatal (_("%s is not a library"), identify_imp_name);
3486 /* Now search for the dll name. */
3487 identify_search_archive (abfd,
3488 identify_search_member,
3489 (void *)(& identify_data));
3491 if (! bfd_close (abfd))
3492 bfd_fatal (identify_imp_name);
3494 count = dll_name_list_count (identify_data.list);
3497 if (identify_strict && count > 1)
3499 dll_name_list_free (identify_data.list);
3500 identify_data.list = NULL;
3501 fatal (_("Import library `%s' specifies two or more dlls"),
3504 dll_name_list_print (identify_data.list);
3505 dll_name_list_free (identify_data.list);
3506 identify_data.list = NULL;
3510 dll_name_list_free (identify_data.list);
3511 identify_data.list = NULL;
3512 fatal (_("Unable to determine dll name for `%s' (not an import library?)"),
3517 /* Loop over all members of the archive, applying the supplied function to
3518 each member that is a bfd_object. The function will be called as if:
3519 func (member_bfd, abfd, user_storage) */
3522 identify_search_archive (bfd * abfd,
3523 void (* operation) (bfd *, bfd *, void *),
3524 void * user_storage)
3526 bfd * arfile = NULL;
3527 bfd * last_arfile = NULL;
3532 arfile = bfd_openr_next_archived_file (abfd, arfile);
3536 if (bfd_get_error () != bfd_error_no_more_archived_files)
3537 bfd_fatal (bfd_get_filename (abfd));
3541 if (bfd_check_format_matches (arfile, bfd_object, &matching))
3542 (*operation) (arfile, abfd, user_storage);
3545 bfd_nonfatal (bfd_get_filename (arfile));
3549 if (last_arfile != NULL)
3550 bfd_close (last_arfile);
3552 last_arfile = arfile;
3555 if (last_arfile != NULL)
3557 bfd_close (last_arfile);
3561 /* Call the identify_search_section() function for each section of this
3565 identify_search_member (bfd *abfd,
3566 bfd *archive_bfd ATTRIBUTE_UNUSED,
3569 bfd_map_over_sections (abfd, identify_search_section, obj);
3572 /* This predicate returns true if section->name matches the desired value.
3573 By default, this is .idata$7 (.idata$6 on PPC, or if the import
3574 library is ms-style). */
3577 identify_process_section_p (asection * section, bfd_boolean ms_style_implib)
3579 static const char * SECTION_NAME =
3581 /* dllname is stored in idata$6 on PPC */
3586 static const char * MS_SECTION_NAME = ".idata$6";
3588 const char * section_name =
3589 (ms_style_implib ? MS_SECTION_NAME : SECTION_NAME);
3591 if (strcmp (section_name, section->name) == 0)
3596 /* If *section has contents and its name is .idata$7 (.data$6 on PPC or if
3597 import lib ms-generated) -- and it satisfies several other constraints
3598 -- then add the contents of the section to obj->list. */
3601 identify_search_section (bfd * abfd, asection * section, void * obj)
3604 bfd_size_type datasize;
3605 identify_data_type * identify_data = (identify_data_type *)obj;
3606 bfd_boolean ms_style = identify_data->ms_style_implib;
3608 if ((section->flags & SEC_HAS_CONTENTS) == 0)
3611 if (! identify_process_section_p (section, ms_style))
3614 /* Binutils import libs seem distinguish the .idata$7 section that contains
3615 the DLL name from other .idata$7 sections by the absence of the
3617 if (!ms_style && ((section->flags & SEC_RELOC) == SEC_RELOC))
3620 /* MS import libs seem to distinguish the .idata$6 section
3621 that contains the DLL name from other .idata$6 sections
3622 by the presence of the SEC_DATA flag. */
3623 if (ms_style && ((section->flags & SEC_DATA) == 0))
3626 if ((datasize = bfd_section_size (abfd, section)) == 0)
3629 data = (bfd_byte *) xmalloc (datasize + 1);
3632 bfd_get_section_contents (abfd, section, data, 0, datasize);
3633 data[datasize] = '\0';
3635 /* Use a heuristic to determine if data is a dll name.
3636 Possible to defeat this if (a) the library has MANY
3637 (more than 0x302f) imports, (b) it is an ms-style
3638 import library, but (c) it is buggy, in that the SEC_DATA
3639 flag is set on the "wrong" sections. This heuristic might
3640 also fail to record a valid dll name if the dllname uses
3641 a multibyte or unicode character set (is that valid?).
3643 This heuristic is based on the fact that symbols names in
3644 the chosen section -- as opposed to the dll name -- begin
3645 at offset 2 in the data. The first two bytes are a 16bit
3646 little-endian count, and start at 0x0000. However, the dll
3647 name begins at offset 0 in the data. We assume that the
3648 dll name does not contain unprintable characters. */
3649 if (data[0] != '\0' && ISPRINT (data[0])
3650 && ((datasize < 2) || ISPRINT (data[1])))
3651 dll_name_list_append (identify_data->list, data);
3656 /* Run through the information gathered from the .o files and the
3657 .def file and work out the best stuff. */
3660 pfunc (const void *a, const void *b)
3662 export_type *ap = *(export_type **) a;
3663 export_type *bp = *(export_type **) b;
3665 if (ap->ordinal == bp->ordinal)
3668 /* Unset ordinals go to the bottom. */
3669 if (ap->ordinal == -1)
3671 if (bp->ordinal == -1)
3673 return (ap->ordinal - bp->ordinal);
3677 nfunc (const void *a, const void *b)
3679 export_type *ap = *(export_type **) a;
3680 export_type *bp = *(export_type **) b;
3681 const char *an = ap->name;
3682 const char *bn = bp->name;
3689 an = (an[0] == '@') ? an + 1 : an;
3690 bn = (bn[0] == '@') ? bn + 1 : bn;
3693 return (strcmp (an, bn));
3697 remove_null_names (export_type **ptr)
3702 for (dst = src = 0; src < d_nfuncs; src++)
3706 ptr[dst] = ptr[src];
3714 process_duplicates (export_type **d_export_vec)
3722 /* Remove duplicates. */
3723 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3725 for (i = 0; i < d_nfuncs - 1; i++)
3727 if (strcmp (d_export_vec[i]->name,
3728 d_export_vec[i + 1]->name) == 0)
3730 export_type *a = d_export_vec[i];
3731 export_type *b = d_export_vec[i + 1];
3735 /* xgettext:c-format */
3736 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3737 a->name, a->ordinal, b->ordinal);
3739 if (a->ordinal != -1
3740 && b->ordinal != -1)
3741 /* xgettext:c-format */
3742 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3745 /* Merge attributes. */
3746 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3747 b->constant |= a->constant;
3748 b->noname |= a->noname;
3750 d_export_vec[i] = 0;
3753 remove_null_names (d_export_vec);
3757 /* Count the names. */
3758 for (i = 0; i < d_nfuncs; i++)
3759 if (!d_export_vec[i]->noname)
3764 fill_ordinals (export_type **d_export_vec)
3771 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3773 /* Fill in the unset ordinals with ones from our range. */
3774 ptr = (char *) xmalloc (size);
3776 memset (ptr, 0, size);
3778 /* Mark in our large vector all the numbers that are taken. */
3779 for (i = 0; i < d_nfuncs; i++)
3781 if (d_export_vec[i]->ordinal != -1)
3783 ptr[d_export_vec[i]->ordinal] = 1;
3785 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
3786 lowest = d_export_vec[i]->ordinal;
3790 /* Start at 1 for compatibility with MS toolchain. */
3794 /* Now fill in ordinals where the user wants us to choose. */
3795 for (i = 0; i < d_nfuncs; i++)
3797 if (d_export_vec[i]->ordinal == -1)
3801 /* First try within or after any user supplied range. */
3802 for (j = lowest; j < size; j++)
3806 d_export_vec[i]->ordinal = j;
3810 /* Then try before the range. */
3811 for (j = lowest; j >0; j--)
3815 d_export_vec[i]->ordinal = j;
3825 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3827 /* Work out the lowest and highest ordinal numbers. */
3830 if (d_export_vec[0])
3831 d_low_ord = d_export_vec[0]->ordinal;
3832 if (d_export_vec[d_nfuncs-1])
3833 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
3840 /* First work out the minimum ordinal chosen. */
3845 export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
3847 inform (_("Processing definitions"));
3849 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3850 d_export_vec[i] = exp;
3852 process_duplicates (d_export_vec);
3853 fill_ordinals (d_export_vec);
3855 /* Put back the list in the new order. */
3857 for (i = d_nfuncs - 1; i >= 0; i--)
3859 d_export_vec[i]->next = d_exports;
3860 d_exports = d_export_vec[i];
3863 /* Build list in alpha order. */
3864 d_exports_lexically = (export_type **)
3865 xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3867 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3868 d_exports_lexically[i] = exp;
3870 d_exports_lexically[i] = 0;
3872 qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
3874 /* Fill exp entries with their hint values. */
3875 for (i = 0; i < d_nfuncs; i++)
3876 if (!d_exports_lexically[i]->noname || show_allnames)
3877 d_exports_lexically[i]->hint = hint++;
3879 inform (_("Processed definitions"));
3883 usage (FILE *file, int status)
3885 /* xgetext:c-format */
3886 fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
3887 /* xgetext:c-format */
3888 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
3889 fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
3890 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
3891 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
3892 fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
3893 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
3894 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
3895 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
3896 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
3897 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
3898 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
3899 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
3900 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
3901 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
3902 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
3903 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
3904 fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3905 fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n"));
3906 fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3907 fprintf (file, _(" --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n"));
3908 fprintf (file, _(" --leading-underscore All symbols should be prefixed by an underscore.\n"));
3909 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
3910 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3911 fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3912 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
3913 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3914 fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n"));
3915 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3916 fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3917 fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
3918 fprintf (file, _(" --identify-strict Causes --identify to report error when multiple DLLs.\n"));
3919 fprintf (file, _(" -v --verbose Be verbose.\n"));
3920 fprintf (file, _(" -V --version Display the program version.\n"));
3921 fprintf (file, _(" -h --help Display this information.\n"));
3922 fprintf (file, _(" @<file> Read options from <file>.\n"));
3923 #ifdef DLLTOOL_MCORE_ELF
3924 fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
3925 fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n"));
3926 fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3928 if (REPORT_BUGS_TO[0] && status == 0)
3929 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
3933 #define OPTION_EXPORT_ALL_SYMS 150
3934 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
3935 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
3936 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
3937 #define OPTION_ADD_STDCALL_UNDERSCORE (OPTION_NO_DEFAULT_EXCLUDES + 1)
3938 #define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \
3939 (OPTION_ADD_STDCALL_UNDERSCORE + 1)
3940 #define OPTION_IDENTIFY_STRICT (OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
3941 #define OPTION_NO_LEADING_UNDERSCORE (OPTION_IDENTIFY_STRICT + 1)
3942 #define OPTION_LEADING_UNDERSCORE (OPTION_NO_LEADING_UNDERSCORE + 1)
3944 static const struct option long_options[] =
3946 {"no-delete", no_argument, NULL, 'n'},
3947 {"dllname", required_argument, NULL, 'D'},
3948 {"no-idata4", no_argument, NULL, 'x'},
3949 {"no-idata5", no_argument, NULL, 'c'},
3950 {"use-nul-prefixed-import-tables", no_argument, NULL,
3951 OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
3952 {"output-exp", required_argument, NULL, 'e'},
3953 {"output-def", required_argument, NULL, 'z'},
3954 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
3955 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3956 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3957 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3958 {"output-lib", required_argument, NULL, 'l'},
3959 {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
3960 {"input-def", required_argument, NULL, 'd'},
3961 {"add-underscore", no_argument, NULL, 'U'},
3962 {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
3963 {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
3964 {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
3965 {"kill-at", no_argument, NULL, 'k'},
3966 {"add-stdcall-alias", no_argument, NULL, 'A'},
3967 {"ext-prefix-alias", required_argument, NULL, 'p'},
3968 {"identify", required_argument, NULL, 'I'},
3969 {"identify-strict", no_argument, NULL, OPTION_IDENTIFY_STRICT},
3970 {"verbose", no_argument, NULL, 'v'},
3971 {"version", no_argument, NULL, 'V'},
3972 {"help", no_argument, NULL, 'h'},
3973 {"machine", required_argument, NULL, 'm'},
3974 {"add-indirect", no_argument, NULL, 'a'},
3975 {"base-file", required_argument, NULL, 'b'},
3976 {"as", required_argument, NULL, 'S'},
3977 {"as-flags", required_argument, NULL, 'f'},
3978 {"mcore-elf", required_argument, NULL, 'M'},
3979 {"compat-implib", no_argument, NULL, 'C'},
3980 {"temp-prefix", required_argument, NULL, 't'},
3981 {"output-delaylib", required_argument, NULL, 'y'},
3985 int main (int, char **);
3988 main (int ac, char **av)
3993 program_name = av[0];
3996 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3997 setlocale (LC_MESSAGES, "");
3999 #if defined (HAVE_SETLOCALE)
4000 setlocale (LC_CTYPE, "");
4002 bindtextdomain (PACKAGE, LOCALEDIR);
4003 textdomain (PACKAGE);
4005 expandargv (&ac, &av);
4007 while ((c = getopt_long (ac, av,
4008 #ifdef DLLTOOL_MCORE_ELF
4009 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
4011 "m:e:l:y:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
4018 case OPTION_EXPORT_ALL_SYMS:
4019 export_all_symbols = TRUE;
4021 case OPTION_NO_EXPORT_ALL_SYMS:
4022 export_all_symbols = FALSE;
4024 case OPTION_EXCLUDE_SYMS:
4025 add_excludes (optarg);
4027 case OPTION_NO_DEFAULT_EXCLUDES:
4028 do_default_excludes = FALSE;
4030 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
4031 use_nul_prefixed_import_tables = TRUE;
4033 case OPTION_ADD_STDCALL_UNDERSCORE:
4034 add_stdcall_underscore = 1;
4036 case OPTION_NO_LEADING_UNDERSCORE:
4037 leading_underscore = 0;
4039 case OPTION_LEADING_UNDERSCORE:
4040 leading_underscore = 1;
4042 case OPTION_IDENTIFY_STRICT:
4043 identify_strict = 1;
4055 tmp_prefix = optarg;
4061 /* Ignored for compatibility. */
4068 output_def = fopen (optarg, FOPEN_WT);
4071 dll_name = (char*) lbasename (optarg);
4072 if (dll_name != optarg)
4073 non_fatal (_("Path components stripped from dllname, '%s'."),
4090 identify_imp_name = optarg;
4096 print_version (program_name);
4105 add_stdcall_alias = 1;
4108 ext_prefix_alias = optarg;
4117 base_file = fopen (optarg, FOPEN_RB);
4120 /* xgettext:c-format */
4121 fatal (_("Unable to open base-file: %s"), optarg);
4124 #ifdef DLLTOOL_MCORE_ELF
4126 mcore_elf_out_file = optarg;
4129 mcore_elf_linker = optarg;
4132 mcore_elf_linker_flags = optarg;
4136 create_compat_implib = 1;
4139 delayimp_name = optarg;
4148 tmp_prefix = prefix_encode ("d", getpid ());
4150 for (i = 0; mtable[i].type; i++)
4151 if (strcmp (mtable[i].type, mname) == 0)
4154 if (!mtable[i].type)
4155 /* xgettext:c-format */
4156 fatal (_("Machine '%s' not supported"), mname);
4160 /* Check if we generated PE+. */
4161 create_for_pep = strcmp (mname, "i386:x86-64") == 0;
4164 /* Check the default underscore */
4165 int u = leading_underscore; /* Underscoring mode. -1 for use default. */
4167 bfd_get_target_info (mtable[machine].how_bfd_target, NULL,
4170 leading_underscore = (u != 0 ? TRUE : FALSE);
4173 if (!dll_name && exp_name)
4175 /* If we are inferring dll_name from exp_name,
4176 strip off any path components, without emitting
4178 const char* exp_basename = lbasename (exp_name);
4179 const int len = strlen (exp_basename) + 5;
4180 dll_name = xmalloc (len);
4181 strcpy (dll_name, exp_basename);
4182 strcat (dll_name, ".dll");
4183 dll_name_set_by_exp_name = 1;
4186 if (as_name == NULL)
4187 as_name = deduce_name ("as");
4189 /* Don't use the default exclude list if we're reading only the
4190 symbols in the .drectve section. The default excludes are meant
4191 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
4192 if (! export_all_symbols)
4193 do_default_excludes = FALSE;
4195 if (do_default_excludes)
4196 set_default_excludes ();
4199 process_def_file (def_file);
4204 firstarg = av[optind];
4205 scan_obj_file (av[optind]);
4216 /* Make imp_name safe for use as a label. */
4219 imp_name_lab = xstrdup (imp_name);
4220 for (p = imp_name_lab; *p; p++)
4225 head_label = make_label("_head_", imp_name_lab);
4231 /* Make delayimp_name safe for use as a label. */
4234 if (mtable[machine].how_dljtab == 0)
4236 inform (_("Warning, machine type (%d) not supported for "
4237 "delayimport."), machine);
4242 imp_name = delayimp_name;
4243 imp_name_lab = xstrdup (imp_name);
4244 for (p = imp_name_lab; *p; p++)
4249 head_label = make_label("__tailMerge_", imp_name_lab);
4257 if (identify_imp_name)
4259 identify_dll_for_implib ();
4262 #ifdef DLLTOOL_MCORE_ELF
4263 if (mcore_elf_out_file)
4264 mcore_elf_gen_out_file ();
4270 /* Look for the program formed by concatenating PROG_NAME and the
4271 string running from PREFIX to END_PREFIX. If the concatenated
4272 string contains a '/', try appending EXECUTABLE_SUFFIX if it is
4276 look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
4281 cmd = xmalloc (strlen (prefix)
4282 + strlen (prog_name)
4283 #ifdef HAVE_EXECUTABLE_SUFFIX
4284 + strlen (EXECUTABLE_SUFFIX)
4287 strcpy (cmd, prefix);
4289 sprintf (cmd + end_prefix, "%s", prog_name);
4291 if (strchr (cmd, '/') != NULL)
4295 found = (stat (cmd, &s) == 0
4296 #ifdef HAVE_EXECUTABLE_SUFFIX
4297 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
4303 /* xgettext:c-format */
4304 inform (_("Tried file: %s"), cmd);
4310 /* xgettext:c-format */
4311 inform (_("Using file: %s"), cmd);
4316 /* Deduce the name of the program we are want to invoke.
4317 PROG_NAME is the basic name of the program we want to run,
4318 eg "as" or "ld". The catch is that we might want actually
4319 run "i386-pe-as" or "ppc-pe-ld".
4321 If argv[0] contains the full path, then try to find the program
4322 in the same place, with and then without a target-like prefix.
4324 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
4325 deduce_name("as") uses the following search order:
4327 /usr/local/bin/i586-cygwin32-as
4331 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
4332 name, it'll try without and then with EXECUTABLE_SUFFIX.
4334 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
4335 as the fallback, but rather return i586-cygwin32-as.
4337 Oh, and given, argv[0] = dlltool, it'll return "as".
4339 Returns a dynamically allocated string. */
4342 deduce_name (const char *prog_name)
4345 char *dash, *slash, *cp;
4349 for (cp = program_name; *cp != '\0'; ++cp)
4354 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4355 *cp == ':' || *cp == '\\' ||
4368 /* First, try looking for a prefixed PROG_NAME in the
4369 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */
4370 cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
4373 if (slash != NULL && cmd == NULL)
4375 /* Next, try looking for a PROG_NAME in the same directory as
4376 that of this program. */
4377 cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
4382 /* Just return PROG_NAME as is. */
4383 cmd = xstrdup (prog_name);
4389 #ifdef DLLTOOL_MCORE_ELF
4390 typedef struct fname_cache
4392 const char * filename;
4393 struct fname_cache * next;
4397 static fname_cache fnames;
4400 mcore_elf_cache_filename (const char * filename)
4406 while (ptr->next != NULL)
4409 ptr->filename = filename;
4410 ptr->next = (fname_cache *) malloc (sizeof (fname_cache));
4411 if (ptr->next != NULL)
4412 ptr->next->next = NULL;
4415 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
4416 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
4417 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
4420 mcore_elf_gen_out_file (void)
4425 /* Step one. Run 'ld -r' on the input object files in order to resolve
4426 any internal references and to generate a single .exports section. */
4429 ds = dyn_string_new (100);
4430 dyn_string_append_cstr (ds, "-r ");
4432 if (mcore_elf_linker_flags != NULL)
4433 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4435 while (ptr->next != NULL)
4437 dyn_string_append_cstr (ds, ptr->filename);
4438 dyn_string_append_cstr (ds, " ");
4443 dyn_string_append_cstr (ds, "-o ");
4444 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4446 if (mcore_elf_linker == NULL)
4447 mcore_elf_linker = deduce_name ("ld");
4449 run (mcore_elf_linker, ds->s);
4451 dyn_string_delete (ds);
4453 /* Step two. Create a .exp file and a .lib file from the temporary file.
4454 Do this by recursively invoking dlltool... */
4455 ds = dyn_string_new (100);
4457 dyn_string_append_cstr (ds, "-S ");
4458 dyn_string_append_cstr (ds, as_name);
4460 dyn_string_append_cstr (ds, " -e ");
4461 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4462 dyn_string_append_cstr (ds, " -l ");
4463 dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB);
4464 dyn_string_append_cstr (ds, " " );
4465 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4468 dyn_string_append_cstr (ds, " -v");
4472 dyn_string_append_cstr (ds, " -n");
4474 if (dontdeltemps > 1)
4475 dyn_string_append_cstr (ds, " -n");
4478 /* XXX - FIME: ought to check/copy other command line options as well. */
4479 run (program_name, ds->s);
4481 dyn_string_delete (ds);
4483 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
4484 ds = dyn_string_new (100);
4486 dyn_string_append_cstr (ds, "-shared ");
4488 if (mcore_elf_linker_flags)
4489 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4491 dyn_string_append_cstr (ds, " ");
4492 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4493 dyn_string_append_cstr (ds, " ");
4494 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4495 dyn_string_append_cstr (ds, " -o ");
4496 dyn_string_append_cstr (ds, mcore_elf_out_file);
4498 run (mcore_elf_linker, ds->s);
4500 dyn_string_delete (ds);
4502 if (dontdeltemps == 0)
4503 unlink (MCORE_ELF_TMP_EXP);
4505 if (dontdeltemps < 2)
4506 unlink (MCORE_ELF_TMP_OBJ);
4508 #endif /* DLLTOOL_MCORE_ELF */