* binutils-all/dlltool.exp: Add setup_xfail.
[binutils.git] / binutils / dlltool.c
blob33101fc2b17a2cf4f0a7804b1d8bea81a9b30a07
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
20 02110-1301, USA. */
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.
25 (eg, Windows NT)
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
34 referencing program.
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.
65 DESCRIPTION <string>
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.
73 [CODE|DATA] <attr>+
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
78 upon it.
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>
83 in a .DEF file.
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
89 supplied argument.
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.
97 Example:
99 file1.c:
100 asm (".section .drectve");
101 asm (".ascii \"-export:adef\"");
103 void adef (char * s)
105 printf ("hello from the dll %s\n", s);
108 void bdef (char * s)
110 printf ("hello from the dll and the other entry point %s\n", s);
113 file2.c:
114 asm (".section .drectve");
115 asm (".ascii \"-export:cdef\"");
116 asm (".ascii \"-export:ddef\"");
118 void cdef (char * s)
120 printf ("hello from the dll %s\n", s);
123 void ddef (char * s)
125 printf ("hello from the dll and the other entry point %s\n", s);
128 int printf (void)
130 return 9;
133 themain.c:
134 int main (void)
136 cdef ();
137 return 0;
140 thedll.def
142 LIBRARY thedll
143 HEAPSIZE 0x40000, 0x2000
144 EXPORTS bdef @ 20
145 cdef @ 30 NONAME
147 SECTIONS donkey READ WRITE
148 aardvark EXECUTE
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
159 ranlib thedll.in
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
186 # at the same time
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
227 function.
229 .idata$6 = Hint Name Table
230 = Array of { short, asciz } entries, one for each imported function.
231 The `short' is the function's ordinal number.
233 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
235 #include "sysdep.h"
236 #include "bfd.h"
237 #include "libiberty.h"
238 #include "getopt.h"
239 #include "demangle.h"
240 #include "dyn-string.h"
241 #include "bucomm.h"
242 #include "dlltool.h"
243 #include "safe-ctype.h"
245 #include <time.h>
246 #include <assert.h>
248 #ifdef DLLTOOL_ARM
249 #include "coff/arm.h"
250 #include "coff/internal.h"
251 #endif
252 #ifdef DLLTOOL_DEFAULT_MX86_64
253 #include "coff/x86_64.h"
254 #endif
255 #ifdef DLLTOOL_DEFAULT_I386
256 #include "coff/i386.h"
257 #endif
259 #ifndef COFF_PAGE_SIZE
260 #define COFF_PAGE_SIZE ((bfd_vma) 4096)
261 #endif
263 #ifndef PAGE_MASK
264 #define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE))
265 #endif
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);
277 #endif
279 #ifdef HAVE_SYS_WAIT_H
280 #include <sys/wait.h>
281 #else /* ! HAVE_SYS_WAIT_H */
282 #if ! defined (_WIN32) || defined (__CYGWIN32__)
283 #ifndef WIFEXITED
284 #define WIFEXITED(w) (((w) & 0377) == 0)
285 #endif
286 #ifndef WIFSIGNALED
287 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
288 #endif
289 #ifndef WTERMSIG
290 #define WTERMSIG(w) ((w) & 0177)
291 #endif
292 #ifndef WEXITSTATUS
293 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
294 #endif
295 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
296 #ifndef WIFEXITED
297 #define WIFEXITED(w) (((w) & 0xff) == 0)
298 #endif
299 #ifndef WIFSIGNALED
300 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
301 #endif
302 #ifndef WTERMSIG
303 #define WTERMSIG(w) ((w) & 0x7f)
304 #endif
305 #ifndef WEXITSTATUS
306 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
307 #endif
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. */
333 struct ifunct *next;
334 } ifunctype;
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. */
343 } iheadtype;
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
366 char * dllname;
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;
380 bfd_boolean found;
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;
428 static int machine;
429 static int killat;
430 static int add_stdcall_alias;
431 static const char *ext_prefix_alias;
432 static int verbose;
433 static FILE *output_def;
434 static FILE *base_file;
436 #ifdef DLLTOOL_DEFAULT_ARM
437 static const char *mname = "arm";
438 #endif
440 #ifdef DLLTOOL_DEFAULT_ARM_EPOC
441 static const char *mname = "arm-epoc";
442 #endif
444 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
445 static const char *mname = "arm-wince";
446 #endif
448 #ifdef DLLTOOL_DEFAULT_I386
449 static const char *mname = "i386";
450 #endif
452 #ifdef DLLTOOL_DEFAULT_MX86_64
453 static const char *mname = "i386:x86-64";
454 #endif
456 #ifdef DLLTOOL_DEFAULT_PPC
457 static const char *mname = "ppc";
458 #endif
460 #ifdef DLLTOOL_DEFAULT_SH
461 static const char *mname = "sh";
462 #endif
464 #ifdef DLLTOOL_DEFAULT_MIPS
465 static const char *mname = "mips";
466 #endif
468 #ifdef DLLTOOL_DEFAULT_MCORE
469 static const char * mname = "mcore-le";
470 #endif
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")
479 #endif
481 #ifndef DRECTVE_SECTION_NAME
482 #define DRECTVE_SECTION_NAME ".drectve"
483 #endif
485 /* What's the right name for this ? */
486 #define PATHMAX 250
488 /* External name alias numbering starts here. */
489 #define PREFIX_ALIAS_BASE 20000
491 char *tmp_asm_buf;
492 char *tmp_head_s_buf;
493 char *tmp_head_o_buf;
494 char *tmp_tail_s_buf;
495 char *tmp_tail_o_buf;
496 char *tmp_stub_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] */
522 0, 0, 0, 0
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 */
530 0, 0, 0, 0
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 */
541 0, 0, 0, 0
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
566 the glue. */
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 */
578 #ifdef DLLTOOL_PPC
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;
582 #endif
584 static const char i386_trampoline[] =
585 "\tpushl %%ecx\n"
586 "\tpushl %%edx\n"
587 "\tpushl %%eax\n"
588 "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
589 "\tcall ___delayLoadHelper2@8\n"
590 "\tpopl %%edx\n"
591 "\tpopl %%ecx\n"
592 "\tjmp *%%eax\n";
594 struct mac
596 const char *type;
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
622 mtable[] =
625 #define MARM 0
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,
631 0, 0, 0, 0, 0, 0
635 #define M386 1
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
644 #define MPPC 2
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,
649 0, 0, 0, 0, 0, 0
653 #define MTHUMB 3
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,
659 0, 0, 0, 0, 0, 0
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,
669 0, 0, 0, 0, 0, 0
673 #define MMCORE_BE 5
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,
679 0, 0, 0, 0, 0, 0
683 #define MMCORE_LE 6
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,
689 0, 0, 0, 0, 0, 0
693 #define MMCORE_ELF 7
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,
699 0, 0, 0, 0, 0, 0
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,
709 0, 0, 0, 0, 0, 0
713 #define MARM_EPOC 9
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,
719 0, 0, 0, 0, 0, 0
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,
729 0, 0, 0, 0, 0, 0
733 #define MX86 11
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 }
744 typedef struct dlist
746 char *text;
747 struct dlist *next;
749 dlist_type;
751 typedef struct export
753 const char *name;
754 const char *internal_name;
755 const char *import_name;
756 const char *its_name;
757 int ordinal;
758 int constant;
759 int noname; /* Don't put name in image file. */
760 int private; /* Don't put reference in import lib. */
761 int data;
762 int hint;
763 int forward; /* Number of forward label, 0 means no forward. */
764 struct export *next;
766 export_type;
768 /* A list of symbols which we should not export. */
770 struct string_list
772 struct string_list *next;
773 char *string;
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);
833 static char *
834 prefix_encode (char *start, unsigned code)
836 static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
837 static char buf[32];
838 char *p;
839 strcpy (buf, start);
840 p = strchr (buf, '\0');
842 *p++ = alpha[code % sizeof (alpha)];
843 while ((code /= sizeof (alpha)) != 0);
844 *p = '\0';
845 return buf;
848 static char *
849 dlltmp (char **buf, const char *fmt)
851 if (!*buf)
853 *buf = malloc (strlen (tmp_prefix) + 64);
854 sprintf (*buf, fmt, tmp_prefix);
856 return *buf;
859 static void
860 inform VPARAMS ((const char * message, ...))
862 VA_OPEN (args, message);
863 VA_FIXEDARG (args, const char *, message);
865 if (!verbose)
866 return;
868 report (message, args);
870 VA_CLOSE (args);
873 static const char *
874 rvaafter (int mach)
876 switch (mach)
878 case MARM:
879 case M386:
880 case MX86:
881 case MPPC:
882 case MTHUMB:
883 case MARM_INTERWORK:
884 case MMCORE_BE:
885 case MMCORE_LE:
886 case MMCORE_ELF:
887 case MMCORE_ELF_LE:
888 case MARM_EPOC:
889 case MARM_WINCE:
890 break;
891 default:
892 /* xgettext:c-format */
893 fatal (_("Internal error: Unknown machine type: %d"), mach);
894 break;
896 return "";
899 static const char *
900 rvabefore (int mach)
902 switch (mach)
904 case MARM:
905 case M386:
906 case MX86:
907 case MPPC:
908 case MTHUMB:
909 case MARM_INTERWORK:
910 case MMCORE_BE:
911 case MMCORE_LE:
912 case MMCORE_ELF:
913 case MMCORE_ELF_LE:
914 case MARM_EPOC:
915 case MARM_WINCE:
916 return ".rva\t";
917 default:
918 /* xgettext:c-format */
919 fatal (_("Internal error: Unknown machine type: %d"), mach);
920 break;
922 return "";
925 static const char *
926 asm_prefix (int mach, const char *name)
928 switch (mach)
930 case MARM:
931 case MPPC:
932 case MTHUMB:
933 case MARM_INTERWORK:
934 case MMCORE_BE:
935 case MMCORE_LE:
936 case MMCORE_ELF:
937 case MMCORE_ELF_LE:
938 case MARM_EPOC:
939 case MARM_WINCE:
940 break;
941 case M386:
942 case MX86:
943 /* Symbol names starting with ? do not have a leading underscore. */
944 if ((name && *name == '?') || leading_underscore == 0)
945 break;
946 else
947 return "_";
948 default:
949 /* xgettext:c-format */
950 fatal (_("Internal error: Unknown machine type: %d"), mach);
951 break;
953 return "";
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
982 static char **oav;
984 static void
985 process_def_file (const char *name)
987 FILE *f = fopen (name, FOPEN_RT);
989 if (!f)
990 /* xgettext:c-format */
991 fatal (_("Can't open def file: %s"), name);
993 yyin = f;
995 /* xgettext:c-format */
996 inform (_("Processing def file: %s"), name);
998 yyparse ();
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);
1026 return 0;
1029 void
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));
1036 p->name = name;
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;
1042 p->noname = noname;
1043 p->private = private;
1044 p->data = data;
1045 p->next = d_exports;
1046 d_exports = p;
1047 d_nfuncs++;
1049 if ((internal_name != NULL)
1050 && (strchr (internal_name, '.') != NULL))
1051 p->forward = ++d_nforwards;
1052 else
1053 p->forward = 0; /* no forward */
1056 static void
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'."),
1062 def_file, name);
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);
1071 else
1072 dll_name = xstrdup (image_basename);
1075 void
1076 def_name (const char *name, int base)
1078 /* xgettext:c-format */
1079 inform (_("NAME: %s base: %x"), name, base);
1081 if (d_is_dll)
1082 non_fatal (_("Can't have LIBRARY and NAME"));
1084 if (dll_name_set_by_exp_name && name && *name != 0)
1086 dll_name = NULL;
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? */
1091 if (!dll_name)
1092 set_dll_name_from_def (name, 0);
1093 d_is_exe = 1;
1096 void
1097 def_library (const char *name, int base)
1099 /* xgettext:c-format */
1100 inform (_("LIBRARY: %s base: %x"), name, base);
1102 if (d_is_exe)
1103 non_fatal (_("Can't have LIBRARY and NAME"));
1105 if (dll_name_set_by_exp_name && name && *name != 0)
1107 dll_name = NULL;
1108 dll_name_set_by_exp_name = 0;
1111 /* If --dllname not provided, use the one in the DEF file. */
1112 if (!dll_name)
1113 set_dll_name_from_def (name, 1);
1114 d_is_dll = 1;
1117 void
1118 def_description (const char *desc)
1120 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1121 d->text = xstrdup (desc);
1122 d->next = d_list;
1123 d_list = d;
1126 static void
1127 new_directive (char *dir)
1129 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1130 d->text = xstrdup (dir);
1131 d->next = a_list;
1132 a_list = d;
1135 void
1136 def_heapsize (int reserve, int commit)
1138 char b[200];
1139 if (commit > 0)
1140 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1141 else
1142 sprintf (b, "-heap 0x%x ", reserve);
1143 new_directive (xstrdup (b));
1146 void
1147 def_stacksize (int reserve, int commit)
1149 char b[200];
1150 if (commit > 0)
1151 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1152 else
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. */
1160 static void
1161 append_import (const char *symbol_name, const char *dllname, int func_ordinal,
1162 const char *its_name)
1164 iheadtype **pq;
1165 iheadtype *q;
1167 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1169 if (strcmp ((*pq)->dllname, dllname) == 0)
1171 q = *pq;
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;
1178 q->nfuncs++;
1179 return;
1183 q = xmalloc (sizeof (iheadtype));
1184 q->dllname = xstrdup (dllname);
1185 q->nfuncs = 1;
1186 q->funchead = xmalloc (sizeof (ifunctype));
1187 q->functail = q->funchead;
1188 q->next = NULL;
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;
1194 *pq = q;
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
1202 with it. */
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>
1210 <dll_name>.<number>
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
1215 to be reappended.
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). */
1227 void
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;
1232 char *buf;
1234 if (entry != NULL)
1235 application_name = entry;
1236 else
1238 if (app_name != NULL)
1239 application_name = app_name;
1240 else
1241 application_name = "";
1244 if (dllext != NULL)
1246 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
1247 sprintf (buf, "%s.%s", module, dllext);
1248 module = buf;
1251 append_import (application_name, module, ord_val, its_name);
1254 void
1255 def_version (int major, int minor)
1257 printf (_("VERSION %d.%d\n"), major, minor);
1260 void
1261 def_section (const char *name, int attr)
1263 char buf[200];
1264 char atts[5];
1265 char *d = atts;
1266 if (attr & 1)
1267 *d++ = 'R';
1269 if (attr & 2)
1270 *d++ = 'W';
1271 if (attr & 4)
1272 *d++ = 'X';
1273 if (attr & 8)
1274 *d++ = 'S';
1275 *d++ = 0;
1276 sprintf (buf, "-attr %s %s", name, atts);
1277 new_directive (xstrdup (buf));
1280 void
1281 def_code (int attr)
1284 def_section ("CODE", attr);
1287 void
1288 def_data (int attr)
1290 def_section ("DATA", attr);
1293 /**********************************************************************/
1295 static void
1296 run (const char *what, char *args)
1298 char *s;
1299 int pid, wait_status;
1300 int i;
1301 const char **argv;
1302 char *errmsg_fmt, *errmsg_arg;
1303 char *temp_base = choose_temp_base ();
1305 inform (_("run: %s %s"), what, args);
1307 /* Count the args */
1308 i = 0;
1309 for (s = args; *s; s++)
1310 if (*s == ' ')
1311 i++;
1312 i++;
1313 argv = alloca (sizeof (char *) * (i + 3));
1314 i = 0;
1315 argv[i++] = what;
1316 s = args;
1317 while (1)
1319 while (*s == ' ')
1320 ++s;
1321 argv[i++] = s;
1322 while (*s != ' ' && *s != 0)
1323 s++;
1324 if (*s == 0)
1325 break;
1326 *s++ = 0;
1328 argv[i++] = NULL;
1330 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1331 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1333 if (pid == -1)
1335 inform ("%s", strerror (errno));
1337 fatal (errmsg_fmt, errmsg_arg);
1340 pid = pwait (pid, & wait_status, 0);
1342 if (pid == -1)
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));
1359 else
1360 abort ();
1363 /* Look for a list of symbols to export in the .drectve section of
1364 ABFD. Pass each one to def_exports. */
1366 static void
1367 scan_drectve_symbols (bfd *abfd)
1369 asection * s;
1370 int size;
1371 char * buf;
1372 char * p;
1373 char * e;
1375 /* Look for .drectve's */
1376 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1378 if (s == NULL)
1379 return;
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. */
1393 p = buf;
1394 e = buf + size;
1395 while (p < e)
1397 if (p[0] == '-'
1398 && CONST_STRNEQ (p, "-export:"))
1400 char * name;
1401 char * c;
1402 flagword flags = BSF_FUNCTION;
1404 p += 8;
1405 /* Do we have a quoted export? */
1406 if (*p == '"')
1408 p++;
1409 name = p;
1410 while (p < e && *p != '"')
1411 ++p;
1413 else
1415 name = p;
1416 while (p < e && *p != ',' && *p != ' ' && *p != '-')
1417 p++;
1419 c = xmalloc (p - name + 1);
1420 memcpy (c, name, p - name);
1421 c[p - name] = 0;
1422 /* Advance over trailing quote. */
1423 if (p < e && *p == '"')
1424 ++p;
1425 if (p < e && *p == ',') /* found type tag. */
1427 char *tag_start = ++p;
1428 while (p < e && *p != ' ' && *p != '-')
1429 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, '@');
1444 *atsym = '\0';
1445 /* Note: stdcall alias symbols can never be data. */
1446 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0, NULL);
1449 else
1450 p++;
1452 free (buf);
1455 /* Look through the symbols in MINISYMS, and add each one to list of
1456 symbols to export. */
1458 static void
1459 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1460 unsigned int size)
1462 asymbol *store;
1463 bfd_byte *from, *fromend;
1465 store = bfd_make_empty_symbol (abfd);
1466 if (store == NULL)
1467 bfd_fatal (bfd_get_filename (abfd));
1469 from = (bfd_byte *) minisyms;
1470 fromend = from + symcount * size;
1471 for (; from < fromend; from += size)
1473 asymbol *sym;
1474 const char *symbol_name;
1476 sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
1477 if (sym == NULL)
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])
1482 ++symbol_name;
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, '@');
1492 *atsym = '\0';
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. */
1501 static void
1502 add_excludes (const char *new_excludes)
1504 char *local_copy;
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);
1520 else
1521 sprintf (new_exclude->string, "%s%s", (!leading_underscore ? "" : "_"),
1522 exclude_string);
1523 new_exclude->next = excludes;
1524 excludes = new_exclude;
1526 /* xgettext:c-format */
1527 inform (_("Excluding symbol: %s"), exclude_string);
1530 free (local_copy);
1533 /* See if STRING is on the list of symbols to exclude. */
1535 static bfd_boolean
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)
1542 return TRUE;
1543 return FALSE;
1546 /* Add the default list of symbols to exclude. */
1548 static void
1549 set_default_excludes (void)
1551 add_excludes (default_excludes);
1554 /* Choose which symbols to export. */
1556 static long
1557 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
1559 bfd_byte *from, *fromend, *to;
1560 asymbol *store;
1562 store = bfd_make_empty_symbol (abfd);
1563 if (store == NULL)
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)
1572 int keep = 0;
1573 asymbol *sym;
1575 sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
1576 if (sym == NULL)
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);
1587 if (keep)
1589 memcpy (to, from, size);
1590 to += size;
1594 return (to - (bfd_byte *) minisyms) / size;
1597 /* Export all symbols in ABFD, except for ones we were told not to
1598 export. */
1600 static void
1601 scan_all_symbols (bfd *abfd)
1603 long symcount;
1604 void *minisyms;
1605 unsigned int size;
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"))
1611 return;
1613 if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1615 /* xgettext:c-format */
1616 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1617 return;
1620 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
1621 if (symcount < 0)
1622 bfd_fatal (bfd_get_filename (abfd));
1624 if (symcount == 0)
1626 /* xgettext:c-format */
1627 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1628 return;
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);
1637 free (minisyms);
1640 /* Look at the object file to decide which symbols to export. */
1642 static void
1643 scan_open_obj_file (bfd *abfd)
1645 if (export_all_symbols)
1646 scan_all_symbols (abfd);
1647 else
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));
1656 static void
1657 scan_obj_file (const char *filename)
1659 bfd * f = bfd_openr (filename, 0);
1661 if (!f)
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);
1671 while (arfile)
1673 if (bfd_check_format (arfile, bfd_object))
1674 scan_open_obj_file (arfile);
1675 bfd_close (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);
1682 #endif
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);
1691 #endif
1694 bfd_close (f);
1699 static void
1700 dump_def_info (FILE *f)
1702 int i;
1703 export_type *exp;
1704 fprintf (f, "%s ", ASM_C);
1705 for (i = 0; oav[i]; i++)
1706 fprintf (f, "%s ", oav[i]);
1707 fprintf (f, "\n");
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",
1711 ASM_C,
1713 exp->name,
1714 exp->internal_name,
1715 exp->ordinal,
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. */
1727 static int
1728 sfunc (const void *a, const void *b)
1730 if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1731 return 0;
1733 return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
1736 static void
1737 flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1739 int i;
1741 /* Flush this page. */
1742 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1743 ASM_LONG,
1744 (int) page_addr,
1745 ASM_C);
1746 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1747 ASM_LONG,
1748 (on_page * 2) + (on_page & 1) * 2 + 8,
1749 ASM_C);
1751 for (i = 0; i < on_page; i++)
1753 bfd_vma needed = need[i];
1755 if (needed)
1757 if (!create_for_pep)
1759 /* Relocation via HIGHLOW. */
1760 needed = ((needed - page_addr) | 0x3000) & 0xffff;
1762 else
1764 /* Relocation via DIR64. */
1765 needed = ((needed - page_addr) | 0xa000) & 0xffff;
1769 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1772 /* And padding */
1773 if (on_page & 1)
1774 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1777 static void
1778 gen_def_file (void)
1780 int i;
1781 export_type *exp;
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);
1796 if (res)
1798 fprintf (output_def,";\t%s\n", res);
1799 free (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",
1805 quote,
1806 exp->name,
1807 quote,
1808 exp->ordinal,
1809 exp->noname ? " NONAME" : "",
1810 exp->private ? "PRIVATE " : "",
1811 exp->data ? " DATA" : "",
1812 exp->its_name ? " ==" : "",
1813 exp->its_name ? exp->its_name : "");
1815 else
1817 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1818 /* char *alias = */
1819 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1820 quote,
1821 exp->name,
1822 quote,
1823 quote1,
1824 exp->internal_name,
1825 quote1,
1826 exp->ordinal,
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
1840 the file. */
1842 static void
1843 generate_idata_ofile (FILE *filvar)
1845 iheadtype *headptr;
1846 ifunctype *funcptr;
1847 int headindex;
1848 int funcindex;
1849 int nheads;
1851 if (import_list == NULL)
1852 return;
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");
1859 nheads = 0;
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);
1871 nheads++;
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");
1881 headindex = 0;
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++)
1887 if (create_for_pep)
1888 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1889 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1890 ASM_LONG);
1891 else
1892 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1893 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1895 if (create_for_pep)
1896 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1897 else
1898 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1899 headindex++;
1902 fprintf (filvar, "\n\t.section\t.idata$5\n");
1903 headindex = 0;
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++)
1909 if (create_for_pep)
1910 fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1911 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1912 ASM_LONG);
1913 else
1914 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1915 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1917 if (create_for_pep)
1918 fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1919 else
1920 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
1921 headindex++;
1924 fprintf (filvar, "\n\t.section\t.idata$6\n");
1925 headindex = 0;
1926 for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1928 funcindex = 0;
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);
1938 funcindex++;
1940 headindex++;
1943 fprintf (filvar, "\n\t.section\t.idata$7\n");
1944 headindex = 0;
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);
1950 headindex++;
1954 /* Assemble the specified file. */
1955 static void
1956 assemble_file (const char * source, const char * dest)
1958 char * cmd;
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);
1965 run (as_name, cmd);
1968 static void
1969 gen_exp_file (void)
1971 FILE *f;
1972 int i;
1973 export_type *exp;
1974 dlist_type *dl;
1976 /* xgettext:c-format */
1977 inform (_("Generating export file: %s"), exp_name);
1979 f = fopen (TMP_ASM, FOPEN_WT);
1980 if (!f)
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);
1987 dump_def_info (f);
1989 if (d_exports)
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",
2002 ASM_C,
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");
2019 i = d_low_ord;
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);
2028 i++;
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);
2037 else
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);
2042 else
2043 fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
2044 exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2045 i++;
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);
2078 if (a_list)
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);
2087 if (d_list)
2089 fprintf (f, "\t.section .rdata\n");
2090 for (dl = d_list; dl; dl = dl->next)
2092 char *p;
2093 int l;
2095 /* We don't output as ascii because there can
2096 be quote characters in the string. */
2097 l = 0;
2098 for (p = dl->text; *p; p++)
2100 if (l == 0)
2101 fprintf (f, "\t%s\t", ASM_BYTE);
2102 else
2103 fprintf (f, ",");
2104 fprintf (f, "%d", *p);
2105 if (p[1] == 0)
2107 fprintf (f, ",0\n");
2108 break;
2110 if (++l == 10)
2112 fprintf (f, "\n");
2113 l = 0;
2121 /* Add to the output file a way of getting to the exported names
2122 without using the import library. */
2123 if (add_indirect)
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
2131 cygwin releases. */
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. */
2144 if (base_file)
2146 bfd_vma addr;
2147 bfd_vma need[COFF_PAGE_SIZE];
2148 bfd_vma page_addr;
2149 bfd_size_type numbytes;
2150 int num_entries;
2151 bfd_vma *copy;
2152 int j;
2153 int on_page;
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");
2167 if (num_entries)
2169 int src;
2170 int dst = 0;
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];
2179 num_entries = dst;
2180 addr = copy[0];
2181 page_addr = addr & PAGE_MASK; /* work out the page addr */
2182 on_page = 0;
2183 for (j = 0; j < num_entries; j++)
2185 addr = copy[j];
2186 if ((addr & PAGE_MASK) != page_addr)
2188 flush_page (f, need, page_addr, on_page);
2189 on_page = 0;
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);
2202 fclose (f);
2204 /* Assemble the file. */
2205 assemble_file (TMP_ASM, exp_name);
2207 if (dontdeltemps == 0)
2208 unlink (TMP_ASM);
2210 inform (_("Generated exports file"));
2213 static const char *
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);
2224 copy[0] = '_';
2225 strcpy (copy + 1, name);
2226 name = copy;
2229 if (killat)
2231 char *p;
2233 name += lead_at;
2234 /* PR 9766: Look for the last @ sign in the name. */
2235 p = strrchr (name, '@');
2236 if (p && ISDIGIT (p[1]))
2237 *p = 0;
2239 return name;
2242 typedef struct
2244 int id;
2245 const char *name;
2246 int flags;
2247 int align;
2248 asection *sec;
2249 asymbol *sym;
2250 asymbol **sympp;
2251 int size;
2252 unsigned char *data;
2253 } sinfo;
2255 #ifndef DLLTOOL_PPC
2257 #define TEXT 0
2258 #define DATA 1
2259 #define BSS 2
2260 #define IDATA7 3
2261 #define IDATA5 4
2262 #define IDATA4 5
2263 #define IDATA6 6
2265 #define NSECS 7
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)
2285 #else
2287 /* Sections numbered to make the order the same as other PowerPC NT
2288 compilers. This also keeps funny alignment thingies from happening. */
2289 #define TEXT 0
2290 #define PDATA 1
2291 #define RDATA 2
2292 #define IDATA5 3
2293 #define IDATA4 4
2294 #define IDATA6 5
2295 #define IDATA7 6
2296 #define DATA 7
2297 #define BSS 8
2299 #define NSECS 9
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}
2314 #endif
2316 /* This is what we're trying to make. We generate the imp symbols with
2317 both single and double underscores, for compatibility.
2319 .text
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
2327 .section .idata$5
2328 __imp_GetFileVersionInfoSizeW@8:
2329 .rva ID2
2331 # Import Lookup Table
2332 .section .idata$4
2333 .rva ID2
2334 # Hint/Name table
2335 .section .idata$6
2336 ID2: .short 2
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
2343 # looks like:
2344 .text
2345 lwz r11,[tocv]__imp_function_name(r2)
2346 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2347 lwz r12,0(r11)
2348 stw r2,4(r1)
2349 mtctr r12
2350 lwz r2,4(r11)
2351 bctr */
2353 static char *
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);
2362 return copy;
2365 static char *
2366 make_imp_label (const char *prefix, const char *name)
2368 int len;
2369 char *copy;
2371 if (name[0] == '@')
2373 len = strlen (prefix) + strlen (name);
2374 copy = xmalloc (len + 1);
2375 strcpy (copy, prefix);
2376 strcat (copy, name);
2378 else
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);
2386 return copy;
2389 static bfd *
2390 make_one_lib_file (export_type *exp, int i, int delay)
2392 bfd * abfd;
2393 asymbol * exp_label;
2394 asymbol * iname = 0;
2395 asymbol * iname2;
2396 asymbol * iname_lab;
2397 asymbol ** iname_lab_pp;
2398 asymbol ** iname_pp;
2399 #ifdef DLLTOOL_PPC
2400 asymbol ** fn_pp;
2401 asymbol ** toc_pp;
2402 #define EXTRA 2
2403 #endif
2404 #ifndef EXTRA
2405 #define EXTRA 0
2406 #endif
2407 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2408 flagword applicable;
2409 char * outname = xmalloc (strlen (TMP_STUB) + 10);
2410 int oidx = 0;
2413 sprintf (outname, "%s%05d.o", TMP_STUB, i);
2415 abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2417 if (!abfd)
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);
2428 #ifdef DLLTOOL_ARM
2429 if (machine == MARM_INTERWORK || machine == MTHUMB)
2430 bfd_set_private_flags (abfd, F_INTERWORK);
2431 #endif
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;
2440 if (si->id != i)
2441 abort ();
2442 si->sec = bfd_make_section_old_way (abfd, si->name);
2443 bfd_set_section_flags (abfd,
2444 si->sec,
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;
2453 si->sym->value = 0;
2454 ptrs[oidx] = si->sym;
2455 si->sympp = ptrs + oidx;
2456 si->size = 0;
2457 si->data = NULL;
2459 oidx++;
2462 if (! exp->data)
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. */
2471 #ifdef DLLTOOL_PPC
2472 if (machine == MPPC)
2473 exp_label->section = secdata[RDATA].sec;
2474 else
2475 #endif
2476 exp_label->section = secdata[TEXT].sec;
2478 exp_label->flags = BSF_GLOBAL;
2479 exp_label->value = 0;
2481 #ifdef DLLTOOL_ARM
2482 if (machine == MTHUMB)
2483 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2484 #endif
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;
2497 iname->value = 0;
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;
2504 iname2->value = 0;
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;
2521 #ifdef DLLTOOL_PPC
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;
2549 #endif
2551 ptrs[oidx] = 0;
2553 for (i = 0; i < NSECS; i++)
2555 sinfo *si = secdata + i;
2556 asection *sec = si->sec;
2557 arelent *rel, *rel2 = 0, *rel3 = 0;
2558 arelent **rpp;
2560 switch (i)
2562 case TEXT:
2563 if (! exp->data)
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));
2573 rpp[0] = rel;
2574 rpp[1] = 0;
2576 rel->address = HOW_JTAB_ROFF;
2577 rel->addend = 0;
2579 if (delay)
2581 rel2 = xmalloc (sizeof (arelent));
2582 rpp[1] = rel2;
2583 rel2->address = HOW_JTAB_ROFF2;
2584 rel2->addend = 0;
2585 rel3 = xmalloc (sizeof (arelent));
2586 rpp[2] = rel3;
2587 rel3->address = HOW_JTAB_ROFF3;
2588 rel3->addend = 0;
2589 rpp[3] = 0;
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;
2604 else
2606 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2607 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2610 if (delay)
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;
2621 break;
2623 case IDATA5:
2624 if (delay)
2626 si->data = xmalloc (4);
2627 si->size = 4;
2628 sec->reloc_count = 1;
2629 memset (si->data, 0, si->size);
2630 si->data[0] = 6;
2631 rel = xmalloc (sizeof (arelent));
2632 rpp = xmalloc (sizeof (arelent *) * 2);
2633 rpp[0] = rel;
2634 rpp[1] = 0;
2635 rel->address = 0;
2636 rel->addend = 0;
2637 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2638 rel->sym_ptr_ptr = secdata[TEXT].sympp;
2639 sec->orelocation = rpp;
2640 break;
2642 /* else fall through */
2643 case IDATA4:
2644 /* An idata$4 or idata$5 is one word long, and has an
2645 rva to idata$6. */
2647 if (create_for_pep)
2649 si->data = xmalloc (8);
2650 si->size = 8;
2651 if (exp->noname)
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;
2657 si->data[4] = 0;
2658 si->data[5] = 0;
2659 si->data[6] = 0;
2660 si->data[7] = 0x80;
2662 else
2664 sec->reloc_count = 1;
2665 memset (si->data, 0, si->size);
2666 rel = xmalloc (sizeof (arelent));
2667 rpp = xmalloc (sizeof (arelent *) * 2);
2668 rpp[0] = rel;
2669 rpp[1] = 0;
2670 rel->address = 0;
2671 rel->addend = 0;
2672 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2673 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2674 sec->orelocation = rpp;
2677 else
2679 si->data = xmalloc (4);
2680 si->size = 4;
2682 if (exp->noname)
2684 si->data[0] = exp->ordinal ;
2685 si->data[1] = exp->ordinal >> 8;
2686 si->data[2] = exp->ordinal >> 16;
2687 si->data[3] = 0x80;
2689 else
2691 sec->reloc_count = 1;
2692 memset (si->data, 0, si->size);
2693 rel = xmalloc (sizeof (arelent));
2694 rpp = xmalloc (sizeof (arelent *) * 2);
2695 rpp[0] = rel;
2696 rpp[1] = 0;
2697 rel->address = 0;
2698 rel->addend = 0;
2699 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2700 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2701 sec->orelocation = rpp;
2704 break;
2706 case IDATA6:
2707 if (!exp->noname)
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;
2713 if (exp->its_name)
2714 si->size = strlen (exp->its_name) + 3;
2715 else
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;
2720 if (exp->its_name)
2721 strcpy ((char *) si->data + 2, exp->its_name);
2722 else
2723 strcpy ((char *) si->data + 2, xlate (exp->import_name));
2725 break;
2726 case IDATA7:
2727 if (delay)
2728 break;
2729 si->size = 4;
2730 si->data = xmalloc (4);
2731 memset (si->data, 0, si->size);
2732 rel = xmalloc (sizeof (arelent));
2733 rpp = xmalloc (sizeof (arelent *) * 2);
2734 rpp[0] = rel;
2735 rel->address = 0;
2736 rel->addend = 0;
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;
2741 break;
2743 #ifdef DLLTOOL_PPC
2744 case PDATA:
2746 /* The .pdata section is 5 words long.
2747 Think of it as:
2748 struct
2750 bfd_vma BeginAddress, [0x00]
2751 EndAddress, [0x04]
2752 ExceptionHandler, [0x08]
2753 HandlerData, [0x0c]
2754 PrologEndAddress; [0x10]
2755 }; */
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
2759 we need to do:
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:
2763 "..function_name".
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);
2776 si->size = 4 * 5;
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));
2784 rpp[4] = 0;
2786 /* Stick the toc reload instruction in the glue reloc. */
2787 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2789 imglue->addend = 0;
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;
2795 ba_rel->addend = 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;
2801 ea_rel->addend = 0;
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;
2817 break;
2819 case RDATA:
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. */
2825 si->size = 8;
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));
2832 rpp[2] = 0;
2834 rel->address = 0;
2835 rel->addend = 0;
2836 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2837 rel->sym_ptr_ptr = fn_pp;
2839 rel = rpp[1];
2841 rel->address = 4;
2842 rel->addend = 0;
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;
2848 break;
2849 #endif /* DLLTOOL_PPC */
2854 bfd_vma vma = 0;
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)
2870 continue;
2872 if (i == IDATA4 && no_idata4)
2873 continue;
2875 bfd_set_section_contents (abfd, si->sec,
2876 si->data, 0,
2877 si->size);
2880 bfd_set_symtab (abfd, ptrs, oidx);
2881 bfd_close (abfd);
2882 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2883 if (!abfd)
2884 /* xgettext:c-format */
2885 fatal (_("bfd_open failed reopen stub file: %s: %s"),
2886 outname, bfd_get_errmsg ());
2888 return abfd;
2891 static bfd *
2892 make_head (void)
2894 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2895 bfd *abfd;
2897 if (f == NULL)
2899 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2900 return NULL;
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",
2918 ASM_RVA_BEFORE,
2919 imp_name_lab,
2920 ASM_RVA_AFTER,
2921 ASM_C);
2922 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2923 ASM_RVA_BEFORE,
2924 ASM_RVA_AFTER, ASM_C);
2926 fprintf (f, "%sStuff for compatibility\n", ASM_C);
2928 if (!no_idata5)
2930 fprintf (f, "\t.section\t.idata$5\n");
2931 if (use_nul_prefixed_import_tables)
2933 if (create_for_pep)
2934 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2935 else
2936 fprintf (f,"\t%s\t0\n", ASM_LONG);
2938 fprintf (f, "fthunk:\n");
2941 if (!no_idata4)
2943 fprintf (f, "\t.section\t.idata$4\n");
2944 if (use_nul_prefixed_import_tables)
2946 if (create_for_pep)
2947 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2948 else
2949 fprintf (f,"\t%s\t0\n", ASM_LONG);
2951 fprintf (f, "hname:\n");
2954 fclose (f);
2956 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2958 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2959 if (abfd == NULL)
2960 /* xgettext:c-format */
2961 fatal (_("failed to open temporary head file: %s: %s"),
2962 TMP_HEAD_O, bfd_get_errmsg ());
2964 return abfd;
2967 bfd *
2968 make_delay_head (void)
2970 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2971 bfd *abfd;
2973 if (f == NULL)
2975 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2976 return NULL;
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);
3008 fprintf (f, "\n");
3010 fprintf (f, "%sStuff for compatibility\n", ASM_C);
3012 if (!no_idata5)
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);
3018 #else
3019 fprintf (f,"\t%s\t0\n", ASM_LONG);
3020 #endif
3021 fprintf (f, "__IAT_%s:\n", imp_name_lab);
3024 if (!no_idata4)
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");
3034 fclose (f);
3036 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
3038 abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
3039 if (abfd == NULL)
3040 /* xgettext:c-format */
3041 fatal (_("failed to open temporary head file: %s: %s"),
3042 TMP_HEAD_O, bfd_get_errmsg ());
3044 return abfd;
3047 static bfd *
3048 make_tail (void)
3050 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
3051 bfd *abfd;
3053 if (f == NULL)
3055 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
3056 return NULL;
3059 if (!no_idata4)
3061 fprintf (f, "\t.section\t.idata$4\n");
3062 if (create_for_pep)
3063 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3064 else
3065 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
3068 if (!no_idata5)
3070 fprintf (f, "\t.section\t.idata$5\n");
3071 if (create_for_pep)
3072 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3073 else
3074 fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
3077 #ifdef DLLTOOL_PPC
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
3083 crt0). */
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);
3091 #endif
3093 #ifdef DLLTOOL_PPC
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");
3097 #else
3098 fprintf (f, "\t.section\t.idata$7\n");
3099 #endif
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);
3105 fclose (f);
3107 assemble_file (TMP_TAIL_S, TMP_TAIL_O);
3109 abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
3110 if (abfd == NULL)
3111 /* xgettext:c-format */
3112 fatal (_("failed to open temporary tail file: %s: %s"),
3113 TMP_TAIL_O, bfd_get_errmsg ());
3115 return abfd;
3118 static void
3119 gen_lib_file (int delay)
3121 int i;
3122 export_type *exp;
3123 bfd *ar_head;
3124 bfd *ar_tail;
3125 bfd *outarch;
3126 bfd * head = 0;
3128 unlink (imp_name);
3130 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
3132 if (!outarch)
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. */
3145 if (delay)
3147 ar_head = make_delay_head ();
3149 else
3151 ar_head = make_head ();
3153 ar_tail = make_tail();
3155 if (ar_head == NULL || ar_tail == NULL)
3156 return;
3158 for (i = 0; (exp = d_exports_lexically[i]); i++)
3160 bfd *n;
3161 /* Don't add PRIVATE entries to import lib. */
3162 if (exp->private)
3163 continue;
3164 n = make_one_lib_file (exp, i, delay);
3165 n->archive_next = head;
3166 head = n;
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;
3186 head = n;
3190 /* Now stick them all into the archive. */
3191 ar_head->archive_next = head;
3192 ar_tail->archive_next = ar_head;
3193 head = ar_tail;
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;
3204 bfd_close (head);
3205 head = n;
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)
3219 char *name;
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. */
3225 if (exp->private)
3226 continue;
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. */
3246 static void
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)
3253 return;
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);
3261 entry->next = NULL;
3263 /* Add to tail, and move tail. */
3264 list->tail->next = entry;
3265 list->tail = entry;
3268 /* Count the number of entries in list. */
3270 static int
3271 dll_name_list_count (dll_name_list_type * list)
3273 dll_name_list_node_type * p;
3274 int count = 0;
3276 /* Error checking. */
3277 if (! list || ! list->head)
3278 return 0;
3280 p = list->head;
3282 while (p && p->next)
3284 count++;
3285 p = p->next;
3287 return count;
3290 /* Print each entry in list to stdout. */
3292 static void
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)
3299 return;
3301 p = list->head;
3303 while (p && p->next && p->next->dllname && *(p->next->dllname))
3305 printf ("%s\n", p->next->dllname);
3306 p = p->next;
3310 /* Free all entries in list, and list itself. */
3312 static void
3313 dll_name_list_free (dll_name_list_type * list)
3315 if (list)
3317 dll_name_list_free_contents (list->head);
3318 list->head = NULL;
3319 list->tail = NULL;
3320 free (list);
3324 /* Recursive function to free all nodes entry->next->next...
3325 as well as entry itself. */
3327 static void
3328 dll_name_list_free_contents (dll_name_list_node_type * entry)
3330 if (entry)
3332 if (entry->next)
3334 dll_name_list_free_contents (entry->next);
3335 entry->next = NULL;
3337 if (entry->dllname)
3339 free (entry->dllname);
3340 entry->dllname = NULL;
3342 free (entry);
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
3349 the list. */
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;
3365 return list;
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
3372 this function. */
3374 static void
3375 identify_member_contains_symname (bfd * abfd,
3376 bfd * archive_bfd ATTRIBUTE_UNUSED,
3377 void * obj)
3379 long storage_needed;
3380 asymbol ** symbol_table;
3381 long number_of_symbols;
3382 long i;
3383 symname_search_data_type * search_data = (symname_search_data_type *) obj;
3385 /* If we already found the symbol in a different member,
3386 short circuit. */
3387 if (search_data->found)
3388 return;
3390 storage_needed = bfd_get_symtab_upper_bound (abfd);
3391 if (storage_needed <= 0)
3392 return;
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);
3399 return;
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;
3409 break;
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). */
3432 static void
3433 identify_dll_for_implib (void)
3435 bfd * abfd = NULL;
3436 int count = 0;
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;
3448 bfd_init ();
3450 abfd = bfd_openr (identify_imp_name, 0);
3451 if (abfd == NULL)
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);
3475 if (abfd == NULL)
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);
3495 if (count > 0)
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"),
3502 identify_imp_name);
3504 dll_name_list_print (identify_data.list);
3505 dll_name_list_free (identify_data.list);
3506 identify_data.list = NULL;
3508 else
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?)"),
3513 identify_imp_name);
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) */
3521 static void
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;
3528 char ** matching;
3530 while (1)
3532 arfile = bfd_openr_next_archived_file (abfd, arfile);
3534 if (arfile == NULL)
3536 if (bfd_get_error () != bfd_error_no_more_archived_files)
3537 bfd_fatal (bfd_get_filename (abfd));
3538 break;
3541 if (bfd_check_format_matches (arfile, bfd_object, &matching))
3542 (*operation) (arfile, abfd, user_storage);
3543 else
3545 bfd_nonfatal (bfd_get_filename (arfile));
3546 free (matching);
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
3562 archive member. */
3564 static void
3565 identify_search_member (bfd *abfd,
3566 bfd *archive_bfd ATTRIBUTE_UNUSED,
3567 void *obj)
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). */
3576 static bfd_boolean
3577 identify_process_section_p (asection * section, bfd_boolean ms_style_implib)
3579 static const char * SECTION_NAME =
3580 #ifdef DLLTOOL_PPC
3581 /* dllname is stored in idata$6 on PPC */
3582 ".idata$6";
3583 #else
3584 ".idata$7";
3585 #endif
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)
3592 return TRUE;
3593 return FALSE;
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. */
3600 static void
3601 identify_search_section (bfd * abfd, asection * section, void * obj)
3603 bfd_byte *data = 0;
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)
3609 return;
3611 if (! identify_process_section_p (section, ms_style))
3612 return;
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
3616 SEC_RELOC flag. */
3617 if (!ms_style && ((section->flags & SEC_RELOC) == SEC_RELOC))
3618 return;
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))
3624 return;
3626 if ((datasize = bfd_section_size (abfd, section)) == 0)
3627 return;
3629 data = (bfd_byte *) xmalloc (datasize + 1);
3630 data[0] = '\0';
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);
3653 free (data);
3656 /* Run through the information gathered from the .o files and the
3657 .def file and work out the best stuff. */
3659 static int
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)
3666 return 0;
3668 /* Unset ordinals go to the bottom. */
3669 if (ap->ordinal == -1)
3670 return 1;
3671 if (bp->ordinal == -1)
3672 return -1;
3673 return (ap->ordinal - bp->ordinal);
3676 static int
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;
3683 if (ap->its_name)
3684 an = ap->its_name;
3685 if (bp->its_name)
3686 an = bp->its_name;
3687 if (killat)
3689 an = (an[0] == '@') ? an + 1 : an;
3690 bn = (bn[0] == '@') ? bn + 1 : bn;
3693 return (strcmp (an, bn));
3696 static void
3697 remove_null_names (export_type **ptr)
3699 int src;
3700 int dst;
3702 for (dst = src = 0; src < d_nfuncs; src++)
3704 if (ptr[src])
3706 ptr[dst] = ptr[src];
3707 dst++;
3710 d_nfuncs = dst;
3713 static void
3714 process_duplicates (export_type **d_export_vec)
3716 int more = 1;
3717 int i;
3719 while (more)
3721 more = 0;
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];
3733 more = 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"),
3743 a->name);
3745 /* Merge attributes. */
3746 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3747 b->constant |= a->constant;
3748 b->noname |= a->noname;
3749 b->data |= a->data;
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)
3760 d_named_nfuncs++;
3763 static void
3764 fill_ordinals (export_type **d_export_vec)
3766 int lowest = -1;
3767 int i;
3768 char *ptr;
3769 int size = 65536;
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. */
3791 if (lowest == -1)
3792 lowest = 1;
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)
3799 int j;
3801 /* First try within or after any user supplied range. */
3802 for (j = lowest; j < size; j++)
3803 if (ptr[j] == 0)
3805 ptr[j] = 1;
3806 d_export_vec[i]->ordinal = j;
3807 goto done;
3810 /* Then try before the range. */
3811 for (j = lowest; j >0; j--)
3812 if (ptr[j] == 0)
3814 ptr[j] = 1;
3815 d_export_vec[i]->ordinal = j;
3816 goto done;
3818 done:;
3822 free (ptr);
3824 /* And resort. */
3825 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3827 /* Work out the lowest and highest ordinal numbers. */
3828 if (d_nfuncs)
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;
3837 static void
3838 mangle_defs (void)
3840 /* First work out the minimum ordinal chosen. */
3841 export_type *exp;
3843 int i;
3844 int hint = 0;
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. */
3856 d_exports = 0;
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"));
3882 static void
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"));
3927 #endif
3928 if (REPORT_BUGS_TO[0] && status == 0)
3929 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
3930 exit (status);
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'},
3982 {NULL,0,NULL,0}
3985 int main (int, char **);
3988 main (int ac, char **av)
3990 int c;
3991 int i;
3992 char *firstarg = 0;
3993 program_name = av[0];
3994 oav = av;
3996 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3997 setlocale (LC_MESSAGES, "");
3998 #endif
3999 #if defined (HAVE_SETLOCALE)
4000 setlocale (LC_CTYPE, "");
4001 #endif
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:",
4010 #else
4011 "m:e:l:y:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
4012 #endif
4013 long_options, 0))
4014 != EOF)
4016 switch (c)
4018 case OPTION_EXPORT_ALL_SYMS:
4019 export_all_symbols = TRUE;
4020 break;
4021 case OPTION_NO_EXPORT_ALL_SYMS:
4022 export_all_symbols = FALSE;
4023 break;
4024 case OPTION_EXCLUDE_SYMS:
4025 add_excludes (optarg);
4026 break;
4027 case OPTION_NO_DEFAULT_EXCLUDES:
4028 do_default_excludes = FALSE;
4029 break;
4030 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
4031 use_nul_prefixed_import_tables = TRUE;
4032 break;
4033 case OPTION_ADD_STDCALL_UNDERSCORE:
4034 add_stdcall_underscore = 1;
4035 break;
4036 case OPTION_NO_LEADING_UNDERSCORE:
4037 leading_underscore = 0;
4038 break;
4039 case OPTION_LEADING_UNDERSCORE:
4040 leading_underscore = 1;
4041 break;
4042 case OPTION_IDENTIFY_STRICT:
4043 identify_strict = 1;
4044 break;
4045 case 'x':
4046 no_idata4 = 1;
4047 break;
4048 case 'c':
4049 no_idata5 = 1;
4050 break;
4051 case 'S':
4052 as_name = optarg;
4053 break;
4054 case 't':
4055 tmp_prefix = optarg;
4056 break;
4057 case 'f':
4058 as_flags = optarg;
4059 break;
4061 /* Ignored for compatibility. */
4062 case 'u':
4063 break;
4064 case 'a':
4065 add_indirect = 1;
4066 break;
4067 case 'z':
4068 output_def = fopen (optarg, FOPEN_WT);
4069 break;
4070 case 'D':
4071 dll_name = (char*) lbasename (optarg);
4072 if (dll_name != optarg)
4073 non_fatal (_("Path components stripped from dllname, '%s'."),
4074 optarg);
4075 break;
4076 case 'l':
4077 imp_name = optarg;
4078 break;
4079 case 'e':
4080 exp_name = optarg;
4081 break;
4082 case 'H':
4083 case 'h':
4084 usage (stdout, 0);
4085 break;
4086 case 'm':
4087 mname = optarg;
4088 break;
4089 case 'I':
4090 identify_imp_name = optarg;
4091 break;
4092 case 'v':
4093 verbose = 1;
4094 break;
4095 case 'V':
4096 print_version (program_name);
4097 break;
4098 case 'U':
4099 add_underscore = 1;
4100 break;
4101 case 'k':
4102 killat = 1;
4103 break;
4104 case 'A':
4105 add_stdcall_alias = 1;
4106 break;
4107 case 'p':
4108 ext_prefix_alias = optarg;
4109 break;
4110 case 'd':
4111 def_file = optarg;
4112 break;
4113 case 'n':
4114 dontdeltemps++;
4115 break;
4116 case 'b':
4117 base_file = fopen (optarg, FOPEN_RB);
4119 if (!base_file)
4120 /* xgettext:c-format */
4121 fatal (_("Unable to open base-file: %s"), optarg);
4123 break;
4124 #ifdef DLLTOOL_MCORE_ELF
4125 case 'M':
4126 mcore_elf_out_file = optarg;
4127 break;
4128 case 'L':
4129 mcore_elf_linker = optarg;
4130 break;
4131 case 'F':
4132 mcore_elf_linker_flags = optarg;
4133 break;
4134 #endif
4135 case 'C':
4136 create_compat_implib = 1;
4137 break;
4138 case 'y':
4139 delayimp_name = optarg;
4140 break;
4141 default:
4142 usage (stderr, 1);
4143 break;
4147 if (!tmp_prefix)
4148 tmp_prefix = prefix_encode ("d", getpid ());
4150 for (i = 0; mtable[i].type; i++)
4151 if (strcmp (mtable[i].type, mname) == 0)
4152 break;
4154 if (!mtable[i].type)
4155 /* xgettext:c-format */
4156 fatal (_("Machine '%s' not supported"), mname);
4158 machine = i;
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. */
4166 if (u == -1)
4167 bfd_get_target_info (mtable[machine].how_bfd_target, NULL,
4168 NULL, &u, NULL);
4169 if (u != -1)
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
4177 a warning. */
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 ();
4198 if (def_file)
4199 process_def_file (def_file);
4201 while (optind < ac)
4203 if (!firstarg)
4204 firstarg = av[optind];
4205 scan_obj_file (av[optind]);
4206 optind++;
4209 mangle_defs ();
4211 if (exp_name)
4212 gen_exp_file ();
4214 if (imp_name)
4216 /* Make imp_name safe for use as a label. */
4217 char *p;
4219 imp_name_lab = xstrdup (imp_name);
4220 for (p = imp_name_lab; *p; p++)
4222 if (!ISALNUM (*p))
4223 *p = '_';
4225 head_label = make_label("_head_", imp_name_lab);
4226 gen_lib_file (0);
4229 if (delayimp_name)
4231 /* Make delayimp_name safe for use as a label. */
4232 char *p;
4234 if (mtable[machine].how_dljtab == 0)
4236 inform (_("Warning, machine type (%d) not supported for "
4237 "delayimport."), machine);
4239 else
4241 killat = 1;
4242 imp_name = delayimp_name;
4243 imp_name_lab = xstrdup (imp_name);
4244 for (p = imp_name_lab; *p; p++)
4246 if (!ISALNUM (*p))
4247 *p = '_';
4249 head_label = make_label("__tailMerge_", imp_name_lab);
4250 gen_lib_file (1);
4254 if (output_def)
4255 gen_def_file ();
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 ();
4265 #endif
4267 return 0;
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
4273 appropriate. */
4275 static char *
4276 look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
4278 struct stat s;
4279 char *cmd;
4281 cmd = xmalloc (strlen (prefix)
4282 + strlen (prog_name)
4283 #ifdef HAVE_EXECUTABLE_SUFFIX
4284 + strlen (EXECUTABLE_SUFFIX)
4285 #endif
4286 + 10);
4287 strcpy (cmd, prefix);
4289 sprintf (cmd + end_prefix, "%s", prog_name);
4291 if (strchr (cmd, '/') != NULL)
4293 int found;
4295 found = (stat (cmd, &s) == 0
4296 #ifdef HAVE_EXECUTABLE_SUFFIX
4297 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
4298 #endif
4301 if (! found)
4303 /* xgettext:c-format */
4304 inform (_("Tried file: %s"), cmd);
4305 free (cmd);
4306 return NULL;
4310 /* xgettext:c-format */
4311 inform (_("Using file: %s"), cmd);
4313 return 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
4328 /usr/local/bin/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. */
4341 static char *
4342 deduce_name (const char *prog_name)
4344 char *cmd;
4345 char *dash, *slash, *cp;
4347 dash = NULL;
4348 slash = NULL;
4349 for (cp = program_name; *cp != '\0'; ++cp)
4351 if (*cp == '-')
4352 dash = cp;
4353 if (
4354 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4355 *cp == ':' || *cp == '\\' ||
4356 #endif
4357 *cp == '/')
4359 slash = cp;
4360 dash = NULL;
4364 cmd = NULL;
4366 if (dash != NULL)
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);
4380 if (cmd == NULL)
4382 /* Just return PROG_NAME as is. */
4383 cmd = xstrdup (prog_name);
4386 return cmd;
4389 #ifdef DLLTOOL_MCORE_ELF
4390 typedef struct fname_cache
4392 const char * filename;
4393 struct fname_cache * next;
4395 fname_cache;
4397 static fname_cache fnames;
4399 static void
4400 mcore_elf_cache_filename (const char * filename)
4402 fname_cache * ptr;
4404 ptr = & fnames;
4406 while (ptr->next != NULL)
4407 ptr = ptr->next;
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"
4419 static void
4420 mcore_elf_gen_out_file (void)
4422 fname_cache * ptr;
4423 dyn_string_t ds;
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. */
4427 ptr = & fnames;
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, " ");
4440 ptr = ptr->next;
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);
4467 if (verbose)
4468 dyn_string_append_cstr (ds, " -v");
4470 if (dontdeltemps)
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 */