2009-01-08 Kai Tietz <kai.tietz@onevision.com>
[external/binutils.git] / binutils / dlltool.c
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 Free Software Foundation, Inc.
4
5    This file is part of GNU Binutils.
6
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.
11
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.
16
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.  */
21
22
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)
26
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.
31
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.
35
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.
40
41    A DEF file contains any number of the following commands:
42
43
44    NAME <name> [ , <base> ]
45    The result is going to be <name>.EXE
46
47    LIBRARY <name> [ , <base> ]
48    The result is going to be <name>.DLL
49
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>.
57
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.
64
65    DESCRIPTION <string>
66    Puts <string> into output .exp file in the .rdata section
67
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.
72
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.
79
80
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.
84
85
86
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.
90
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.
94
95
96
97    Example:
98
99  file1.c:
100    asm (".section .drectve");
101    asm (".ascii \"-export:adef\"");
102
103    void adef (char * s)
104    {
105      printf ("hello from the dll %s\n", s);
106    }
107
108    void bdef (char * s)
109    {
110      printf ("hello from the dll and the other entry point %s\n", s);
111    }
112
113  file2.c:
114    asm (".section .drectve");
115    asm (".ascii \"-export:cdef\"");
116    asm (".ascii \"-export:ddef\"");
117
118    void cdef (char * s)
119    {
120      printf ("hello from the dll %s\n", s);
121    }
122
123    void ddef (char * s)
124    {
125      printf ("hello from the dll and the other entry point %s\n", s);
126    }
127
128    int printf (void)
129    {
130      return 9;
131    }
132
133  themain.c:
134    int main (void)
135    {
136      cdef ();
137      return 0;
138    }
139
140  thedll.def
141
142    LIBRARY thedll
143    HEAPSIZE 0x40000, 0x2000
144    EXPORTS bdef @ 20
145            cdef @ 30 NONAME
146
147    SECTIONS donkey READ WRITE
148    aardvark EXECUTE
149
150  # Compile up the parts of the dll and the program
151
152    gcc -c file1.c file2.c themain.c
153
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)
157
158    ar  qcv thedll.in file1.o file2.o
159    ranlib thedll.in
160
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).
164
165    dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
166
167  # Build the dll with the library and the export table
168
169    ld -o thedll.dll thedll.o thedll.in
170
171  # Link the executable with the import library
172
173    gcc -o themain.exe themain.o thedll.a
174
175  This example can be extended if relocations are needed in the DLL:
176
177  # Compile up the parts of the dll and the program
178
179    gcc -c file1.c file2.c themain.c
180
181  # Run this tool over the DLL's .def file and generate an imports file.
182
183    dlltool --def thedll.def --output-lib thedll.lib
184
185  # Link the executable with the import library and generate a base file
186  # at the same time
187
188    gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
189
190  # Run this tool over the DLL's .def file and generate an exports file
191  # which includes the relocations from the base file.
192
193    dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
194
195  # Build the dll with file1.o, file2.o and the export table
196
197    ld -o thedll.dll thedll.exp file1.o file2.o  */
198
199 /* .idata section description
200
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.
204
205    .idata$2 = Import Directory Table
206    = array of IMAGE_IMPORT_DESCRIPTOR's.
207
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
213
214    .idata$3 = null terminating entry for .idata$2.
215
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.
220
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.
228
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.
232
233    .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc).  */
234
235 /* AIX requires this to be the first thing in the file.  */
236 #ifndef __GNUC__
237 # ifdef _AIX
238  #pragma alloca
239 #endif
240 #endif
241
242 #define show_allnames 0
243
244 #define PAGE_SIZE ((bfd_vma) 4096)
245 #define PAGE_MASK ((bfd_vma) (-4096))
246 #include "sysdep.h"
247 #include "bfd.h"
248 #include "libiberty.h"
249 #include "getopt.h"
250 #include "demangle.h"
251 #include "dyn-string.h"
252 #include "bucomm.h"
253 #include "dlltool.h"
254 #include "safe-ctype.h"
255
256 #include <time.h>
257 #include <sys/stat.h>
258 #include <stdarg.h>
259 #include <assert.h>
260
261 #ifdef DLLTOOL_ARM
262 #include "coff/arm.h"
263 #include "coff/internal.h"
264 #endif
265 #ifdef DLLTOOL_MX86_64
266 #include "coff/x86_64.h"
267 #endif
268
269 /* Forward references.  */
270 static char *look_for_prog (const char *, const char *, int);
271 static char *deduce_name (const char *);
272
273 #ifdef DLLTOOL_MCORE_ELF
274 static void mcore_elf_cache_filename (const char *);
275 static void mcore_elf_gen_out_file (void);
276 #endif
277
278 #ifdef HAVE_SYS_WAIT_H
279 #include <sys/wait.h>
280 #else /* ! HAVE_SYS_WAIT_H */
281 #if ! defined (_WIN32) || defined (__CYGWIN32__)
282 #ifndef WIFEXITED
283 #define WIFEXITED(w)    (((w) & 0377) == 0)
284 #endif
285 #ifndef WIFSIGNALED
286 #define WIFSIGNALED(w)  (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
287 #endif
288 #ifndef WTERMSIG
289 #define WTERMSIG(w)     ((w) & 0177)
290 #endif
291 #ifndef WEXITSTATUS
292 #define WEXITSTATUS(w)  (((w) >> 8) & 0377)
293 #endif
294 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
295 #ifndef WIFEXITED
296 #define WIFEXITED(w)    (((w) & 0xff) == 0)
297 #endif
298 #ifndef WIFSIGNALED
299 #define WIFSIGNALED(w)  (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300 #endif
301 #ifndef WTERMSIG
302 #define WTERMSIG(w)     ((w) & 0x7f)
303 #endif
304 #ifndef WEXITSTATUS
305 #define WEXITSTATUS(w)  (((w) & 0xff00) >> 8)
306 #endif
307 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308 #endif /* ! HAVE_SYS_WAIT_H */
309
310 /* ifunc and ihead data structures: ttk@cygnus.com 1997
311
312    When IMPORT declarations are encountered in a .def file the
313    function import information is stored in a structure referenced by
314    the global variable IMPORT_LIST.  The structure is a linked list
315    containing the names of the dll files each function is imported
316    from and a linked list of functions being imported from that dll
317    file.  This roughly parallels the structure of the .idata section
318    in the PE object file.
319
320    The contents of .def file are interpreted from within the
321    process_def_file function.  Every time an IMPORT declaration is
322    encountered, it is broken up into its component parts and passed to
323    def_import.  IMPORT_LIST is initialized to NULL in function main.  */
324
325 typedef struct ifunct
326 {
327   char *         name;   /* Name of function being imported.  */
328   int            ord;    /* Two-byte ordinal value associated with function.  */
329   struct ifunct *next;
330 } ifunctype;
331
332 typedef struct iheadt
333 {
334   char          *dllname;  /* Name of dll file imported from.  */
335   long           nfuncs;   /* Number of functions in list.  */
336   struct ifunct *funchead; /* First function in list.  */
337   struct ifunct *functail; /* Last  function in list.  */
338   struct iheadt *next;     /* Next dll file in list.  */
339 } iheadtype;
340
341 /* Structure containing all import information as defined in .def file
342    (qv "ihead structure").  */
343
344 static iheadtype *import_list = NULL;
345
346 static char *as_name = NULL;
347 static char * as_flags = "";
348
349 static char *tmp_prefix;
350
351 static int no_idata4;
352 static int no_idata5;
353 static char *exp_name;
354 static char *imp_name;
355 static char *identify_imp_name;
356 static char *identify_dll_name;
357 static char *head_label;
358 static char *imp_name_lab;
359 static char *dll_name;
360
361 static int add_indirect = 0;
362 static int add_underscore = 0;
363 static int add_stdcall_underscore = 0;
364 static int dontdeltemps = 0;
365
366 /* TRUE if we should export all symbols.  Otherwise, we only export
367    symbols listed in .drectve sections or in the def file.  */
368 static bfd_boolean export_all_symbols;
369
370 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
371    exporting all symbols.  */
372 static bfd_boolean do_default_excludes = TRUE;
373
374 static bfd_boolean use_nul_prefixed_import_tables = FALSE;
375
376 /* Default symbols to exclude when exporting all the symbols.  */
377 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
378
379 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
380    compatibility to old Cygwin releases.  */
381 static bfd_boolean create_compat_implib;
382
383 static char *def_file;
384
385 extern char * program_name;
386
387 static int machine;
388 static int killat;
389 static int add_stdcall_alias;
390 static const char *ext_prefix_alias;
391 static int verbose;
392 static FILE *output_def;
393 static FILE *base_file;
394
395 #ifdef DLLTOOL_DEFAULT_ARM
396 static const char *mname = "arm";
397 #endif
398
399 #ifdef DLLTOOL_DEFAULT_ARM_EPOC
400 static const char *mname = "arm-epoc";
401 #endif
402
403 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
404 static const char *mname = "arm-wince";
405 #endif
406
407 #ifdef DLLTOOL_DEFAULT_I386
408 static const char *mname = "i386";
409 #endif
410
411 #ifdef DLLTOOL_DEFAULT_MX86_64
412 static const char *mname = "i386:x86-64";
413 #endif
414
415 #ifdef DLLTOOL_DEFAULT_PPC
416 static const char *mname = "ppc";
417 #endif
418
419 #ifdef DLLTOOL_DEFAULT_SH
420 static const char *mname = "sh";
421 #endif
422
423 #ifdef DLLTOOL_DEFAULT_MIPS
424 static const char *mname = "mips";
425 #endif
426
427 #ifdef DLLTOOL_DEFAULT_MCORE
428 static const char * mname = "mcore-le";
429 #endif
430
431 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
432 static const char * mname = "mcore-elf";
433 static char * mcore_elf_out_file = NULL;
434 static char * mcore_elf_linker   = NULL;
435 static char * mcore_elf_linker_flags = NULL;
436
437 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
438 #endif
439
440 #ifndef DRECTVE_SECTION_NAME
441 #define DRECTVE_SECTION_NAME ".drectve"
442 #endif
443
444 /* What's the right name for this ?  */
445 #define PATHMAX 250             
446
447 /* External name alias numbering starts here.  */
448 #define PREFIX_ALIAS_BASE       20000
449
450 char *tmp_asm_buf;
451 char *tmp_head_s_buf;
452 char *tmp_head_o_buf;
453 char *tmp_tail_s_buf;
454 char *tmp_tail_o_buf;
455 char *tmp_stub_buf;
456
457 #define TMP_ASM         dlltmp (&tmp_asm_buf, "%sc.s")
458 #define TMP_HEAD_S      dlltmp (&tmp_head_s_buf, "%sh.s")
459 #define TMP_HEAD_O      dlltmp (&tmp_head_o_buf, "%sh.o")
460 #define TMP_TAIL_S      dlltmp (&tmp_tail_s_buf, "%st.s")
461 #define TMP_TAIL_O      dlltmp (&tmp_tail_o_buf, "%st.o")
462 #define TMP_STUB        dlltmp (&tmp_stub_buf, "%ss")
463
464 /* This bit of assembly does jmp * ....  */
465 static const unsigned char i386_jtab[] =
466 {
467   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
468 };
469
470 static const unsigned char arm_jtab[] =
471 {
472   0x00, 0xc0, 0x9f, 0xe5,       /* ldr  ip, [pc] */
473   0x00, 0xf0, 0x9c, 0xe5,       /* ldr  pc, [ip] */
474   0,    0,    0,    0
475 };
476
477 static const unsigned char arm_interwork_jtab[] =
478 {
479   0x04, 0xc0, 0x9f, 0xe5,       /* ldr  ip, [pc] */
480   0x00, 0xc0, 0x9c, 0xe5,       /* ldr  ip, [ip] */
481   0x1c, 0xff, 0x2f, 0xe1,       /* bx   ip       */
482   0,    0,    0,    0
483 };
484
485 static const unsigned char thumb_jtab[] =
486 {
487   0x40, 0xb4,           /* push {r6}         */
488   0x02, 0x4e,           /* ldr  r6, [pc, #8] */
489   0x36, 0x68,           /* ldr  r6, [r6]     */
490   0xb4, 0x46,           /* mov  ip, r6       */
491   0x40, 0xbc,           /* pop  {r6}         */
492   0x60, 0x47,           /* bx   ip           */
493   0,    0,    0,    0
494 };
495
496 static const unsigned char mcore_be_jtab[] =
497 {
498   0x71, 0x02,            /* lrw r1,2       */
499   0x81, 0x01,            /* ld.w r1,(r1,0) */
500   0x00, 0xC1,            /* jmp r1         */
501   0x12, 0x00,            /* nop            */
502   0x00, 0x00, 0x00, 0x00 /* <address>      */
503 };
504
505 static const unsigned char mcore_le_jtab[] =
506 {
507   0x02, 0x71,            /* lrw r1,2       */
508   0x01, 0x81,            /* ld.w r1,(r1,0) */
509   0xC1, 0x00,            /* jmp r1         */
510   0x00, 0x12,            /* nop            */
511   0x00, 0x00, 0x00, 0x00 /* <address>      */
512 };
513
514 /* This is the glue sequence for PowerPC PE. There is a
515    tocrel16-tocdefn reloc against the first instruction.
516    We also need a IMGLUE reloc against the glue function
517    to restore the toc saved by the third instruction in
518    the glue.  */
519 static const unsigned char ppc_jtab[] =
520 {
521   0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2)               */
522                           /*   Reloc TOCREL16 __imp_xxx  */
523   0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11)              */
524   0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1)                */
525   0xA6, 0x03, 0x89, 0x7D, /* mtctr r12                   */
526   0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11)               */
527   0x20, 0x04, 0x80, 0x4E  /* bctr                        */
528 };
529
530 #ifdef DLLTOOL_PPC
531 /* The glue instruction, picks up the toc from the stw in
532    the above code: "lwz r2,4(r1)".  */
533 static bfd_vma ppc_glue_insn = 0x80410004;
534 #endif
535
536 struct mac
537   {
538     const char *type;
539     const char *how_byte;
540     const char *how_short;
541     const char *how_long;
542     const char *how_asciz;
543     const char *how_comment;
544     const char *how_jump;
545     const char *how_global;
546     const char *how_space;
547     const char *how_align_short;
548     const char *how_align_long;
549     const char *how_default_as_switches;
550     const char *how_bfd_target;
551     enum bfd_architecture how_bfd_arch;
552     const unsigned char *how_jtab;
553     int how_jtab_size; /* Size of the jtab entry.  */
554     int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5.  */
555   };
556
557 static const struct mac
558 mtable[] =
559 {
560   {
561 #define MARM 0
562     "arm", ".byte", ".short", ".long", ".asciz", "@",
563     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
564     ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
565     "pe-arm-little", bfd_arch_arm,
566     arm_jtab, sizeof (arm_jtab), 8
567   }
568   ,
569   {
570 #define M386 1
571     "i386", ".byte", ".short", ".long", ".asciz", "#",
572     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
573     "pe-i386",bfd_arch_i386,
574     i386_jtab, sizeof (i386_jtab), 2
575   }
576   ,
577   {
578 #define MPPC 2
579     "ppc", ".byte", ".short", ".long", ".asciz", "#",
580     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
581     "pe-powerpcle",bfd_arch_powerpc,
582     ppc_jtab, sizeof (ppc_jtab), 0
583   }
584   ,
585   {
586 #define MTHUMB 3
587     "thumb", ".byte", ".short", ".long", ".asciz", "@",
588     "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
589     ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
590     "pe-arm-little", bfd_arch_arm,
591     thumb_jtab, sizeof (thumb_jtab), 12
592   }
593   ,
594 #define MARM_INTERWORK 4
595   {
596     "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
597     "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
598     ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
599     "pe-arm-little", bfd_arch_arm,
600     arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
601   }
602   ,
603   {
604 #define MMCORE_BE 5
605     "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
606     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
607     ".global", ".space", ".align\t2",".align\t4", "",
608     "pe-mcore-big", bfd_arch_mcore,
609     mcore_be_jtab, sizeof (mcore_be_jtab), 8
610   }
611   ,
612   {
613 #define MMCORE_LE 6
614     "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
615     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
616     ".global", ".space", ".align\t2",".align\t4", "-EL",
617     "pe-mcore-little", bfd_arch_mcore,
618     mcore_le_jtab, sizeof (mcore_le_jtab), 8
619   }
620   ,
621   {
622 #define MMCORE_ELF 7
623     "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
624     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
625     ".global", ".space", ".align\t2",".align\t4", "",
626     "elf32-mcore-big", bfd_arch_mcore,
627     mcore_be_jtab, sizeof (mcore_be_jtab), 8
628   }
629   ,
630   {
631 #define MMCORE_ELF_LE 8
632     "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
633     "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
634     ".global", ".space", ".align\t2",".align\t4", "-EL",
635     "elf32-mcore-little", bfd_arch_mcore,
636     mcore_le_jtab, sizeof (mcore_le_jtab), 8
637   }
638   ,
639   {
640 #define MARM_EPOC 9
641     "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
642     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
643     ".global", ".space", ".align\t2",".align\t4", "",
644     "epoc-pe-arm-little", bfd_arch_arm,
645     arm_jtab, sizeof (arm_jtab), 8
646   }
647   ,
648   {
649 #define MARM_WINCE 10
650     "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
651     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
652     ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
653     "pe-arm-wince-little", bfd_arch_arm,
654     arm_jtab, sizeof (arm_jtab), 8
655   }
656   ,
657   {
658 #define MX86 11
659     "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
660     "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
661     "pe-x86-64",bfd_arch_i386,
662     i386_jtab, sizeof (i386_jtab), 2
663   }
664   ,
665   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
666 };
667
668 typedef struct dlist
669 {
670   char *text;
671   struct dlist *next;
672 }
673 dlist_type;
674
675 typedef struct export
676   {
677     const char *name;
678     const char *internal_name;
679     const char *import_name;
680     int ordinal;
681     int constant;
682     int noname;         /* Don't put name in image file.  */
683     int private;        /* Don't put reference in import lib.  */
684     int data;
685     int hint;
686     int forward;        /* Number of forward label, 0 means no forward.  */
687     struct export *next;
688   }
689 export_type;
690
691 /* A list of symbols which we should not export.  */
692
693 struct string_list
694 {
695   struct string_list *next;
696   char *string;
697 };
698
699 static struct string_list *excludes;
700
701 static const char *rvaafter (int);
702 static const char *rvabefore (int);
703 static const char *asm_prefix (int, const char *);
704 static void process_def_file (const char *);
705 static void new_directive (char *);
706 static void append_import (const char *, const char *, int);
707 static void run (const char *, char *);
708 static void scan_drectve_symbols (bfd *);
709 static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
710 static void add_excludes (const char *);
711 static bfd_boolean match_exclude (const char *);
712 static void set_default_excludes (void);
713 static long filter_symbols (bfd *, void *, long, unsigned int);
714 static void scan_all_symbols (bfd *);
715 static void scan_open_obj_file (bfd *);
716 static void scan_obj_file (const char *);
717 static void dump_def_info (FILE *);
718 static int sfunc (const void *, const void *);
719 static void flush_page (FILE *, bfd_vma *, bfd_vma, int);
720 static void gen_def_file (void);
721 static void generate_idata_ofile (FILE *);
722 static void assemble_file (const char *, const char *);
723 static void gen_exp_file (void);
724 static const char *xlate (const char *);
725 static char *make_label (const char *, const char *);
726 static char *make_imp_label (const char *, const char *);
727 static bfd *make_one_lib_file (export_type *, int);
728 static bfd *make_head (void);
729 static bfd *make_tail (void);
730 static void gen_lib_file (void);
731 static void identify_dll_for_implib (void);
732 static void identify_search_archive (bfd*);
733 static void identify_search_member (bfd*, bfd*);
734 static bfd_boolean identify_process_section_p (asection *);
735 static void identify_search_section (bfd *, asection *, void *);
736 static int pfunc (const void *, const void *);
737 static int nfunc (const void *, const void *);
738 static void remove_null_names (export_type **);
739 static void process_duplicates (export_type **);
740 static void fill_ordinals (export_type **);
741 static void mangle_defs (void);
742 static void usage (FILE *, int);
743 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
744 static void set_dll_name_from_def (const char *);
745
746 static char *
747 prefix_encode (char *start, unsigned code)
748 {
749   static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
750   static char buf[32];
751   char *p;
752   strcpy (buf, start);
753   p = strchr (buf, '\0');
754   do
755     *p++ = alpha[code % sizeof (alpha)];
756   while ((code /= sizeof (alpha)) != 0);
757   *p = '\0';
758   return buf;
759 }
760
761 static char *
762 dlltmp (char **buf, const char *fmt)
763 {
764   if (!*buf)
765     {
766       *buf = malloc (strlen (tmp_prefix) + 64);
767       sprintf (*buf, fmt, tmp_prefix);
768     }
769   return *buf;
770 }
771
772 static void
773 inform VPARAMS ((const char * message, ...))
774 {
775   VA_OPEN (args, message);
776   VA_FIXEDARG (args, const char *, message);
777
778   if (!verbose)
779     return;
780
781   report (message, args);
782
783   VA_CLOSE (args);
784 }
785
786 static const char *
787 rvaafter (int machine)
788 {
789   switch (machine)
790     {
791     case MARM:
792     case M386:
793     case MX86:
794     case MPPC:
795     case MTHUMB:
796     case MARM_INTERWORK:
797     case MMCORE_BE:
798     case MMCORE_LE:
799     case MMCORE_ELF:
800     case MMCORE_ELF_LE:
801     case MARM_EPOC:
802     case MARM_WINCE:
803       break;
804     default:
805       /* xgettext:c-format */
806       fatal (_("Internal error: Unknown machine type: %d"), machine);
807       break;
808     }
809   return "";
810 }
811
812 static const char *
813 rvabefore (int machine)
814 {
815   switch (machine)
816     {
817     case MARM:
818     case M386:
819     case MX86:
820     case MPPC:
821     case MTHUMB:
822     case MARM_INTERWORK:
823     case MMCORE_BE:
824     case MMCORE_LE:
825     case MMCORE_ELF:
826     case MMCORE_ELF_LE:
827     case MARM_EPOC:
828     case MARM_WINCE:
829       return ".rva\t";
830     default:
831       /* xgettext:c-format */
832       fatal (_("Internal error: Unknown machine type: %d"), machine);
833       break;
834     }
835   return "";
836 }
837
838 static const char *
839 asm_prefix (int machine, const char *name)
840 {
841   switch (machine)
842     {
843     case MARM:
844     case MPPC:
845     case MTHUMB:
846     case MARM_INTERWORK:
847     case MMCORE_BE:
848     case MMCORE_LE:
849     case MMCORE_ELF:
850     case MMCORE_ELF_LE:
851     case MARM_EPOC:
852     case MARM_WINCE:
853       break;
854     case M386:
855     case MX86:
856       /* Symbol names starting with ? do not have a leading underscore. */
857       if (name && *name == '?')
858         break;
859       else
860         return "_";
861     default:
862       /* xgettext:c-format */
863       fatal (_("Internal error: Unknown machine type: %d"), machine);
864       break;
865     }
866   return "";
867 }
868
869 #define ASM_BYTE                mtable[machine].how_byte
870 #define ASM_SHORT               mtable[machine].how_short
871 #define ASM_LONG                mtable[machine].how_long
872 #define ASM_TEXT                mtable[machine].how_asciz
873 #define ASM_C                   mtable[machine].how_comment
874 #define ASM_JUMP                mtable[machine].how_jump
875 #define ASM_GLOBAL              mtable[machine].how_global
876 #define ASM_SPACE               mtable[machine].how_space
877 #define ASM_ALIGN_SHORT         mtable[machine].how_align_short
878 #define ASM_RVA_BEFORE          rvabefore (machine)
879 #define ASM_RVA_AFTER           rvaafter (machine)
880 #define ASM_PREFIX(NAME)        asm_prefix (machine, (NAME))
881 #define ASM_ALIGN_LONG          mtable[machine].how_align_long
882 #define HOW_BFD_READ_TARGET     0  /* Always default.  */
883 #define HOW_BFD_WRITE_TARGET    mtable[machine].how_bfd_target
884 #define HOW_BFD_ARCH            mtable[machine].how_bfd_arch
885 #define HOW_JTAB                mtable[machine].how_jtab
886 #define HOW_JTAB_SIZE           mtable[machine].how_jtab_size
887 #define HOW_JTAB_ROFF           mtable[machine].how_jtab_roff
888 #define ASM_SWITCHES            mtable[machine].how_default_as_switches
889
890 static char **oav;
891
892 static void
893 process_def_file (const char *name)
894 {
895   FILE *f = fopen (name, FOPEN_RT);
896
897   if (!f)
898     /* xgettext:c-format */
899     fatal (_("Can't open def file: %s"), name);
900
901   yyin = f;
902
903   /* xgettext:c-format */
904   inform (_("Processing def file: %s"), name);
905
906   yyparse ();
907
908   inform (_("Processed def file"));
909 }
910
911 /**********************************************************************/
912
913 /* Communications with the parser.  */
914
915 static int d_nfuncs;            /* Number of functions exported.  */
916 static int d_named_nfuncs;      /* Number of named functions exported.  */
917 static int d_low_ord;           /* Lowest ordinal index.  */
918 static int d_high_ord;          /* Highest ordinal index.  */
919 static export_type *d_exports;  /* List of exported functions.  */
920 static export_type **d_exports_lexically;  /* Vector of exported functions in alpha order.  */
921 static dlist_type *d_list;      /* Descriptions.  */
922 static dlist_type *a_list;      /* Stuff to go in directives.  */
923 static int d_nforwards = 0;     /* Number of forwarded exports.  */
924
925 static int d_is_dll;
926 static int d_is_exe;
927
928 int
929 yyerror (const char * err ATTRIBUTE_UNUSED)
930 {
931   /* xgettext:c-format */
932   non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
933
934   return 0;
935 }
936
937 void
938 def_exports (const char *name, const char *internal_name, int ordinal,
939              int noname, int constant, int data, int private)
940 {
941   struct export *p = (struct export *) xmalloc (sizeof (*p));
942
943   p->name = name;
944   p->internal_name = internal_name ? internal_name : name;
945   p->import_name = name;
946   p->ordinal = ordinal;
947   p->constant = constant;
948   p->noname = noname;
949   p->private = private;
950   p->data = data;
951   p->next = d_exports;
952   d_exports = p;
953   d_nfuncs++;
954
955   if ((internal_name != NULL)
956       && (strchr (internal_name, '.') != NULL))
957     p->forward = ++d_nforwards;
958   else
959     p->forward = 0; /* no forward */
960 }
961
962 static void
963 set_dll_name_from_def (const char * name)
964 {
965   const char* image_basename = lbasename (name);
966   if (image_basename != name)
967     non_fatal (_("%s: Path components stripped from image name, '%s'."),
968               def_file, name);
969   dll_name = xstrdup (image_basename);
970 }
971
972 void
973 def_name (const char *name, int base)
974 {
975   /* xgettext:c-format */
976   inform (_("NAME: %s base: %x"), name, base);
977
978   if (d_is_dll)
979     non_fatal (_("Can't have LIBRARY and NAME"));
980
981   /* If --dllname not provided, use the one in the DEF file.
982      FIXME: Is this appropriate for executables?  */
983   if (! dll_name)
984     set_dll_name_from_def (name);
985   d_is_exe = 1;
986 }
987
988 void
989 def_library (const char *name, int base)
990 {
991   /* xgettext:c-format */
992   inform (_("LIBRARY: %s base: %x"), name, base);
993
994   if (d_is_exe)
995     non_fatal (_("Can't have LIBRARY and NAME"));
996
997   /* If --dllname not provided, use the one in the DEF file.  */
998   if (! dll_name)
999     set_dll_name_from_def (name);
1000   d_is_dll = 1;
1001 }
1002
1003 void
1004 def_description (const char *desc)
1005 {
1006   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1007   d->text = xstrdup (desc);
1008   d->next = d_list;
1009   d_list = d;
1010 }
1011
1012 static void
1013 new_directive (char *dir)
1014 {
1015   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1016   d->text = xstrdup (dir);
1017   d->next = a_list;
1018   a_list = d;
1019 }
1020
1021 void
1022 def_heapsize (int reserve, int commit)
1023 {
1024   char b[200];
1025   if (commit > 0)
1026     sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1027   else
1028     sprintf (b, "-heap 0x%x ", reserve);
1029   new_directive (xstrdup (b));
1030 }
1031
1032 void
1033 def_stacksize (int reserve, int commit)
1034 {
1035   char b[200];
1036   if (commit > 0)
1037     sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1038   else
1039     sprintf (b, "-stack 0x%x ", reserve);
1040   new_directive (xstrdup (b));
1041 }
1042
1043 /* append_import simply adds the given import definition to the global
1044    import_list.  It is used by def_import.  */
1045
1046 static void
1047 append_import (const char *symbol_name, const char *dll_name, int func_ordinal)
1048 {
1049   iheadtype **pq;
1050   iheadtype *q;
1051
1052   for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1053     {
1054       if (strcmp ((*pq)->dllname, dll_name) == 0)
1055         {
1056           q = *pq;
1057           q->functail->next = xmalloc (sizeof (ifunctype));
1058           q->functail = q->functail->next;
1059           q->functail->ord  = func_ordinal;
1060           q->functail->name = xstrdup (symbol_name);
1061           q->functail->next = NULL;
1062           q->nfuncs++;
1063           return;
1064         }
1065     }
1066
1067   q = xmalloc (sizeof (iheadtype));
1068   q->dllname = xstrdup (dll_name);
1069   q->nfuncs = 1;
1070   q->funchead = xmalloc (sizeof (ifunctype));
1071   q->functail = q->funchead;
1072   q->next = NULL;
1073   q->functail->name = xstrdup (symbol_name);
1074   q->functail->ord  = func_ordinal;
1075   q->functail->next = NULL;
1076
1077   *pq = q;
1078 }
1079
1080 /* def_import is called from within defparse.y when an IMPORT
1081    declaration is encountered.  Depending on the form of the
1082    declaration, the module name may or may not need ".dll" to be
1083    appended to it, the name of the function may be stored in internal
1084    or entry, and there may or may not be an ordinal value associated
1085    with it.  */
1086
1087 /* A note regarding the parse modes:
1088    In defparse.y we have to accept import declarations which follow
1089    any one of the following forms:
1090      <func_name_in_app> = <dll_name>.<func_name_in_dll>
1091      <func_name_in_app> = <dll_name>.<number>
1092      <dll_name>.<func_name_in_dll>
1093      <dll_name>.<number>
1094    Furthermore, the dll's name may or may not end with ".dll", which
1095    complicates the parsing a little.  Normally the dll's name is
1096    passed to def_import() in the "module" parameter, but when it ends
1097    with ".dll" it gets passed in "module" sans ".dll" and that needs
1098    to be reappended.
1099
1100   def_import gets five parameters:
1101   APP_NAME - the name of the function in the application, if
1102              present, or NULL if not present.
1103   MODULE   - the name of the dll, possibly sans extension (ie, '.dll').
1104   DLLEXT   - the extension of the dll, if present, NULL if not present.
1105   ENTRY    - the name of the function in the dll, if present, or NULL.
1106   ORD_VAL  - the numerical tag of the function in the dll, if present,
1107              or NULL.  Exactly one of <entry> or <ord_val> must be
1108              present (i.e., not NULL).  */
1109
1110 void
1111 def_import (const char *app_name, const char *module, const char *dllext,
1112             const char *entry, int ord_val)
1113 {
1114   const char *application_name;
1115   char *buf;
1116
1117   if (entry != NULL)
1118     application_name = entry;
1119   else
1120     {
1121       if (app_name != NULL)
1122         application_name = app_name;
1123       else
1124         application_name = "";
1125     }
1126
1127   if (dllext != NULL)
1128     {
1129       buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
1130       sprintf (buf, "%s.%s", module, dllext);
1131       module = buf;
1132     }
1133
1134   append_import (application_name, module, ord_val);
1135 }
1136
1137 void
1138 def_version (int major, int minor)
1139 {
1140   printf ("VERSION %d.%d\n", major, minor);
1141 }
1142
1143 void
1144 def_section (const char *name, int attr)
1145 {
1146   char buf[200];
1147   char atts[5];
1148   char *d = atts;
1149   if (attr & 1)
1150     *d++ = 'R';
1151
1152   if (attr & 2)
1153     *d++ = 'W';
1154   if (attr & 4)
1155     *d++ = 'X';
1156   if (attr & 8)
1157     *d++ = 'S';
1158   *d++ = 0;
1159   sprintf (buf, "-attr %s %s", name, atts);
1160   new_directive (xstrdup (buf));
1161 }
1162
1163 void
1164 def_code (int attr)
1165 {
1166
1167   def_section ("CODE", attr);
1168 }
1169
1170 void
1171 def_data (int attr)
1172 {
1173   def_section ("DATA", attr);
1174 }
1175
1176 /**********************************************************************/
1177
1178 static void
1179 run (const char *what, char *args)
1180 {
1181   char *s;
1182   int pid, wait_status;
1183   int i;
1184   const char **argv;
1185   char *errmsg_fmt, *errmsg_arg;
1186   char *temp_base = choose_temp_base ();
1187
1188   inform ("run: %s %s", what, args);
1189
1190   /* Count the args */
1191   i = 0;
1192   for (s = args; *s; s++)
1193     if (*s == ' ')
1194       i++;
1195   i++;
1196   argv = alloca (sizeof (char *) * (i + 3));
1197   i = 0;
1198   argv[i++] = what;
1199   s = args;
1200   while (1)
1201     {
1202       while (*s == ' ')
1203         ++s;
1204       argv[i++] = s;
1205       while (*s != ' ' && *s != 0)
1206         s++;
1207       if (*s == 0)
1208         break;
1209       *s++ = 0;
1210     }
1211   argv[i++] = NULL;
1212
1213   pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1214                   &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1215
1216   if (pid == -1)
1217     {
1218       inform ("%s", strerror (errno));
1219
1220       fatal (errmsg_fmt, errmsg_arg);
1221     }
1222
1223   pid = pwait (pid, & wait_status, 0);
1224
1225   if (pid == -1)
1226     {
1227       /* xgettext:c-format */
1228       fatal (_("wait: %s"), strerror (errno));
1229     }
1230   else if (WIFSIGNALED (wait_status))
1231     {
1232       /* xgettext:c-format */
1233       fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1234     }
1235   else if (WIFEXITED (wait_status))
1236     {
1237       if (WEXITSTATUS (wait_status) != 0)
1238         /* xgettext:c-format */
1239         non_fatal (_("%s exited with status %d"),
1240                    what, WEXITSTATUS (wait_status));
1241     }
1242   else
1243     abort ();
1244 }
1245
1246 /* Look for a list of symbols to export in the .drectve section of
1247    ABFD.  Pass each one to def_exports.  */
1248
1249 static void
1250 scan_drectve_symbols (bfd *abfd)
1251 {
1252   asection * s;
1253   int        size;
1254   char *     buf;
1255   char *     p;
1256   char *     e;
1257
1258   /* Look for .drectve's */
1259   s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1260
1261   if (s == NULL)
1262     return;
1263
1264   size = bfd_get_section_size (s);
1265   buf  = xmalloc (size);
1266
1267   bfd_get_section_contents (abfd, s, buf, 0, size);
1268
1269   /* xgettext:c-format */
1270   inform (_("Sucking in info from %s section in %s"),
1271           DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1272
1273   /* Search for -export: strings. The exported symbols can optionally
1274      have type tags (eg., -export:foo,data), so handle those as well.
1275      Currently only data tag is supported.  */
1276   p = buf;
1277   e = buf + size;
1278   while (p < e)
1279     {
1280       if (p[0] == '-'
1281           && CONST_STRNEQ (p, "-export:"))
1282         {
1283           char * name;
1284           char * c;
1285           flagword flags = BSF_FUNCTION;
1286
1287           p += 8;
1288           name = p;
1289           while (p < e && *p != ',' && *p != ' ' && *p != '-')
1290             p++;
1291           c = xmalloc (p - name + 1);
1292           memcpy (c, name, p - name);
1293           c[p - name] = 0;
1294           if (p < e && *p == ',')       /* found type tag.  */
1295             {
1296               char *tag_start = ++p;
1297               while (p < e && *p != ' ' && *p != '-')
1298                 p++;
1299               if (CONST_STRNEQ (tag_start, "data"))
1300                 flags &= ~BSF_FUNCTION;
1301             }
1302
1303           /* FIXME: The 5th arg is for the `constant' field.
1304              What should it be?  Not that it matters since it's not
1305              currently useful.  */
1306           def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0);
1307
1308           if (add_stdcall_alias && strchr (c, '@'))
1309             {
1310               int lead_at = (*c == '@') ;
1311               char *exported_name = xstrdup (c + lead_at);
1312               char *atsym = strchr (exported_name, '@');
1313               *atsym = '\0';
1314               /* Note: stdcall alias symbols can never be data.  */
1315               def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0);
1316             }
1317         }
1318       else
1319         p++;
1320     }
1321   free (buf);
1322 }
1323
1324 /* Look through the symbols in MINISYMS, and add each one to list of
1325    symbols to export.  */
1326
1327 static void
1328 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1329                        unsigned int size)
1330 {
1331   asymbol *store;
1332   bfd_byte *from, *fromend;
1333
1334   store = bfd_make_empty_symbol (abfd);
1335   if (store == NULL)
1336     bfd_fatal (bfd_get_filename (abfd));
1337
1338   from = (bfd_byte *) minisyms;
1339   fromend = from + symcount * size;
1340   for (; from < fromend; from += size)
1341     {
1342       asymbol *sym;
1343       const char *symbol_name;
1344
1345       sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
1346       if (sym == NULL)
1347         bfd_fatal (bfd_get_filename (abfd));
1348
1349       symbol_name = bfd_asymbol_name (sym);
1350       if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1351         ++symbol_name;
1352
1353       def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
1354                    ! (sym->flags & BSF_FUNCTION), 0);
1355
1356       if (add_stdcall_alias && strchr (symbol_name, '@'))
1357         {
1358           int lead_at = (*symbol_name == '@');
1359           char *exported_name = xstrdup (symbol_name + lead_at);
1360           char *atsym = strchr (exported_name, '@');
1361           *atsym = '\0';
1362           /* Note: stdcall alias symbols can never be data.  */
1363           def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0);
1364         }
1365     }
1366 }
1367
1368 /* Add a list of symbols to exclude.  */
1369
1370 static void
1371 add_excludes (const char *new_excludes)
1372 {
1373   char *local_copy;
1374   char *exclude_string;
1375
1376   local_copy = xstrdup (new_excludes);
1377
1378   exclude_string = strtok (local_copy, ",:");
1379   for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1380     {
1381       struct string_list *new_exclude;
1382
1383       new_exclude = ((struct string_list *)
1384                      xmalloc (sizeof (struct string_list)));
1385       new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1386       /* Don't add a leading underscore for fastcall symbols.  */
1387       if (*exclude_string == '@')
1388         sprintf (new_exclude->string, "%s", exclude_string);
1389       else
1390         sprintf (new_exclude->string, "_%s", exclude_string);
1391       new_exclude->next = excludes;
1392       excludes = new_exclude;
1393
1394       /* xgettext:c-format */
1395       inform (_("Excluding symbol: %s"), exclude_string);
1396     }
1397
1398   free (local_copy);
1399 }
1400
1401 /* See if STRING is on the list of symbols to exclude.  */
1402
1403 static bfd_boolean
1404 match_exclude (const char *string)
1405 {
1406   struct string_list *excl_item;
1407
1408   for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1409     if (strcmp (string, excl_item->string) == 0)
1410       return TRUE;
1411   return FALSE;
1412 }
1413
1414 /* Add the default list of symbols to exclude.  */
1415
1416 static void
1417 set_default_excludes (void)
1418 {
1419   add_excludes (default_excludes);
1420 }
1421
1422 /* Choose which symbols to export.  */
1423
1424 static long
1425 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
1426 {
1427   bfd_byte *from, *fromend, *to;
1428   asymbol *store;
1429
1430   store = bfd_make_empty_symbol (abfd);
1431   if (store == NULL)
1432     bfd_fatal (bfd_get_filename (abfd));
1433
1434   from = (bfd_byte *) minisyms;
1435   fromend = from + symcount * size;
1436   to = (bfd_byte *) minisyms;
1437
1438   for (; from < fromend; from += size)
1439     {
1440       int keep = 0;
1441       asymbol *sym;
1442
1443       sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
1444       if (sym == NULL)
1445         bfd_fatal (bfd_get_filename (abfd));
1446
1447       /* Check for external and defined only symbols.  */
1448       keep = (((sym->flags & BSF_GLOBAL) != 0
1449                || (sym->flags & BSF_WEAK) != 0
1450                || bfd_is_com_section (sym->section))
1451               && ! bfd_is_und_section (sym->section));
1452
1453       keep = keep && ! match_exclude (sym->name);
1454
1455       if (keep)
1456         {
1457           memcpy (to, from, size);
1458           to += size;
1459         }
1460     }
1461
1462   return (to - (bfd_byte *) minisyms) / size;
1463 }
1464
1465 /* Export all symbols in ABFD, except for ones we were told not to
1466    export.  */
1467
1468 static void
1469 scan_all_symbols (bfd *abfd)
1470 {
1471   long symcount;
1472   void *minisyms;
1473   unsigned int size;
1474
1475   /* Ignore bfds with an import descriptor table.  We assume that any
1476      such BFD contains symbols which are exported from another DLL,
1477      and we don't want to reexport them from here.  */
1478   if (bfd_get_section_by_name (abfd, ".idata$4"))
1479     return;
1480
1481   if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1482     {
1483       /* xgettext:c-format */
1484       non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1485       return;
1486     }
1487
1488   symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
1489   if (symcount < 0)
1490     bfd_fatal (bfd_get_filename (abfd));
1491
1492   if (symcount == 0)
1493     {
1494       /* xgettext:c-format */
1495       non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1496       return;
1497     }
1498
1499   /* Discard the symbols we don't want to export.  It's OK to do this
1500      in place; we'll free the storage anyway.  */
1501
1502   symcount = filter_symbols (abfd, minisyms, symcount, size);
1503   scan_filtered_symbols (abfd, minisyms, symcount, size);
1504
1505   free (minisyms);
1506 }
1507
1508 /* Look at the object file to decide which symbols to export.  */
1509
1510 static void
1511 scan_open_obj_file (bfd *abfd)
1512 {
1513   if (export_all_symbols)
1514     scan_all_symbols (abfd);
1515   else
1516     scan_drectve_symbols (abfd);
1517
1518   /* FIXME: we ought to read in and block out the base relocations.  */
1519
1520   /* xgettext:c-format */
1521   inform (_("Done reading %s"), bfd_get_filename (abfd));
1522 }
1523
1524 static void
1525 scan_obj_file (const char *filename)
1526 {
1527   bfd * f = bfd_openr (filename, 0);
1528
1529   if (!f)
1530     /* xgettext:c-format */
1531     fatal (_("Unable to open object file: %s"), filename);
1532
1533   /* xgettext:c-format */
1534   inform (_("Scanning object file %s"), filename);
1535
1536   if (bfd_check_format (f, bfd_archive))
1537     {
1538       bfd *arfile = bfd_openr_next_archived_file (f, 0);
1539       while (arfile)
1540         {
1541           if (bfd_check_format (arfile, bfd_object))
1542             scan_open_obj_file (arfile);
1543           bfd_close (arfile);
1544           arfile = bfd_openr_next_archived_file (f, arfile);
1545         }
1546
1547 #ifdef DLLTOOL_MCORE_ELF
1548       if (mcore_elf_out_file)
1549         inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);
1550 #endif
1551     }
1552   else if (bfd_check_format (f, bfd_object))
1553     {
1554       scan_open_obj_file (f);
1555
1556 #ifdef DLLTOOL_MCORE_ELF
1557       if (mcore_elf_out_file)
1558         mcore_elf_cache_filename (filename);
1559 #endif
1560     }
1561
1562   bfd_close (f);
1563 }
1564
1565 /**********************************************************************/
1566
1567 static void
1568 dump_def_info (FILE *f)
1569 {
1570   int i;
1571   export_type *exp;
1572   fprintf (f, "%s ", ASM_C);
1573   for (i = 0; oav[i]; i++)
1574     fprintf (f, "%s ", oav[i]);
1575   fprintf (f, "\n");
1576   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1577     {
1578       fprintf (f, "%s  %d = %s %s @ %d %s%s%s%s\n",
1579                ASM_C,
1580                i,
1581                exp->name,
1582                exp->internal_name,
1583                exp->ordinal,
1584                exp->noname ? "NONAME " : "",
1585                exp->private ? "PRIVATE " : "",
1586                exp->constant ? "CONSTANT" : "",
1587                exp->data ? "DATA" : "");
1588     }
1589 }
1590
1591 /* Generate the .exp file.  */
1592
1593 static int
1594 sfunc (const void *a, const void *b)
1595 {
1596   if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1597     return 0;
1598
1599   return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
1600 }
1601
1602 static void
1603 flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1604 {
1605   int i;
1606
1607   /* Flush this page.  */
1608   fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1609            ASM_LONG,
1610            (int) page_addr,
1611            ASM_C);
1612   fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1613            ASM_LONG,
1614            (on_page * 2) + (on_page & 1) * 2 + 8,
1615            ASM_C);
1616
1617   for (i = 0; i < on_page; i++)
1618     {
1619       bfd_vma needed = need[i];
1620
1621       if (needed)
1622         {
1623 #ifndef DLLTOOL_MX86_64
1624           /* Relocation via HIGHLOW.  */
1625           needed = ((needed - page_addr) | 0x3000) & 0xffff;
1626 #else
1627           /* Relocation via DIR64.  */
1628           needed = ((needed - page_addr) | 0xa000) & 0xffff;
1629 #endif
1630         }
1631
1632       fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1633     }
1634
1635   /* And padding */
1636   if (on_page & 1)
1637     fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1638 }
1639
1640 static void
1641 gen_def_file (void)
1642 {
1643   int i;
1644   export_type *exp;
1645
1646   inform (_("Adding exports to output file"));
1647
1648   fprintf (output_def, ";");
1649   for (i = 0; oav[i]; i++)
1650     fprintf (output_def, " %s", oav[i]);
1651
1652   fprintf (output_def, "\nEXPORTS\n");
1653
1654   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1655     {
1656       char *quote = strchr (exp->name, '.') ? "\"" : "";
1657       char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1658
1659       if (res)
1660         {
1661           fprintf (output_def,";\t%s\n", res);
1662           free (res);
1663         }
1664
1665       if (strcmp (exp->name, exp->internal_name) == 0)
1666         {
1667           fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n",
1668                    quote,
1669                    exp->name,
1670                    quote,
1671                    exp->ordinal,
1672                    exp->noname ? " NONAME" : "",
1673                    exp->private ? "PRIVATE " : "",
1674                    exp->data ? " DATA" : "");
1675         }
1676       else
1677         {
1678           char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1679           /* char *alias =  */
1680           fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
1681                    quote,
1682                    exp->name,
1683                    quote,
1684                    quote1,
1685                    exp->internal_name,
1686                    quote1,
1687                    exp->ordinal,
1688                    exp->noname ? " NONAME" : "",
1689                    exp->private ? "PRIVATE " : "",
1690                    exp->data ? " DATA" : "");
1691         }
1692     }
1693
1694   inform (_("Added exports to output file"));
1695 }
1696
1697 /* generate_idata_ofile generates the portable assembly source code
1698    for the idata sections.  It appends the source code to the end of
1699    the file.  */
1700
1701 static void
1702 generate_idata_ofile (FILE *filvar)
1703 {
1704   iheadtype *headptr;
1705   ifunctype *funcptr;
1706   int        headindex;
1707   int        funcindex;
1708   int        nheads;
1709
1710   if (import_list == NULL)
1711     return;
1712
1713   fprintf (filvar, "%s Import data sections\n", ASM_C);
1714   fprintf (filvar, "\n\t.section\t.idata$2\n");
1715   fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1716   fprintf (filvar, "doi_idata:\n");
1717
1718   nheads = 0;
1719   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1720     {
1721       fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1722                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1723                ASM_C, headptr->dllname);
1724       fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1725       fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1726       fprintf (filvar, "\t%sdllname%d%s\n",
1727                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1728       fprintf (filvar, "\t%slisttwo%d%s\n\n",
1729                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1730       nheads++;
1731     }
1732
1733   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1734   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1735   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section        */
1736   fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1737   fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1738
1739   fprintf (filvar, "\n\t.section\t.idata$4\n");
1740   headindex = 0;
1741   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1742     {
1743       fprintf (filvar, "listone%d:\n", headindex);
1744       for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1745 #ifdef DLLTOOL_MX86_64
1746         fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1747                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
1748 #else
1749         fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1750                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1751 #endif
1752 #ifdef DLLTOOL_MX86_64
1753       fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list.  */
1754 #else
1755       fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
1756 #endif
1757       headindex++;
1758     }
1759
1760   fprintf (filvar, "\n\t.section\t.idata$5\n");
1761   headindex = 0;
1762   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1763     {
1764       fprintf (filvar, "listtwo%d:\n", headindex);
1765       for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1766 #ifdef DLLTOOL_MX86_64
1767         fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1768                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
1769 #else
1770         fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1771                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1772 #endif
1773 #ifdef DLLTOOL_MX86_64
1774       fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list.  */
1775 #else
1776       fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
1777 #endif
1778       headindex++;
1779     }
1780
1781   fprintf (filvar, "\n\t.section\t.idata$6\n");
1782   headindex = 0;
1783   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1784     {
1785       funcindex = 0;
1786       for (funcptr = headptr->funchead; funcptr != NULL;
1787            funcptr = funcptr->next)
1788         {
1789           fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1790           fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1791                    ((funcptr->ord) & 0xFFFF));
1792           fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1793           fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1794           funcindex++;
1795         }
1796       headindex++;
1797     }
1798
1799   fprintf (filvar, "\n\t.section\t.idata$7\n");
1800   headindex = 0;
1801   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1802     {
1803       fprintf (filvar,"dllname%d:\n", headindex);
1804       fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1805       fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1806       headindex++;
1807     }
1808 }
1809
1810 /* Assemble the specified file.  */
1811 static void
1812 assemble_file (const char * source, const char * dest)
1813 {
1814   char * cmd;
1815
1816   cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags)
1817                          + strlen (source) + strlen (dest) + 50);
1818
1819   sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1820
1821   run (as_name, cmd);
1822 }
1823
1824 static void
1825 gen_exp_file (void)
1826 {
1827   FILE *f;
1828   int i;
1829   export_type *exp;
1830   dlist_type *dl;
1831
1832   /* xgettext:c-format */
1833   inform (_("Generating export file: %s"), exp_name);
1834
1835   f = fopen (TMP_ASM, FOPEN_WT);
1836   if (!f)
1837     /* xgettext:c-format */
1838     fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1839
1840   /* xgettext:c-format */
1841   inform (_("Opened temporary file: %s"), TMP_ASM);
1842
1843   dump_def_info (f);
1844
1845   if (d_exports)
1846     {
1847       fprintf (f, "\t.section   .edata\n\n");
1848       fprintf (f, "\t%s 0       %s Allways 0\n", ASM_LONG, ASM_C);
1849       fprintf (f, "\t%s 0x%lx   %s Time and date\n", ASM_LONG,
1850                (unsigned long) time(0), ASM_C);
1851       fprintf (f, "\t%s 0       %s Major and Minor version\n", ASM_LONG, ASM_C);
1852       fprintf (f, "\t%sname%s   %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1853       fprintf (f, "\t%s %d      %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1854
1855
1856       fprintf (f, "\t%s %d      %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1857       fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1858               ASM_C,
1859               d_named_nfuncs, d_low_ord, d_high_ord);
1860       fprintf (f, "\t%s %d      %s Number of names\n", ASM_LONG,
1861                show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1862       fprintf (f, "\t%safuncs%s  %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1863
1864       fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1865                ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1866
1867       fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1868
1869       fprintf (f, "name:        %s      \"%s\"\n", ASM_TEXT, dll_name);
1870
1871
1872       fprintf(f,"%s Export address Table\n", ASM_C);
1873       fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1874       fprintf (f, "afuncs:\n");
1875       i = d_low_ord;
1876
1877       for (exp = d_exports; exp; exp = exp->next)
1878         {
1879           if (exp->ordinal != i)
1880             {
1881               while (i < exp->ordinal)
1882                 {
1883                   fprintf(f,"\t%s\t0\n", ASM_LONG);
1884                   i++;
1885                 }
1886             }
1887
1888           if (exp->forward == 0)
1889             {
1890               if (exp->internal_name[0] == '@')
1891                 fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1892                          exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1893               else
1894                 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1895                          ASM_PREFIX (exp->internal_name),
1896                          exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1897             }
1898           else
1899             fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
1900                      exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1901           i++;
1902         }
1903
1904       fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1905       fprintf (f, "anames:\n");
1906
1907       for (i = 0; (exp = d_exports_lexically[i]); i++)
1908         {
1909           if (!exp->noname || show_allnames)
1910             fprintf (f, "\t%sn%d%s\n",
1911                      ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1912         }
1913
1914       fprintf (f,"%s Export Ordinal Table\n", ASM_C);
1915       fprintf (f, "anords:\n");
1916       for (i = 0; (exp = d_exports_lexically[i]); i++)
1917         {
1918           if (!exp->noname || show_allnames)
1919             fprintf (f, "\t%s   %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1920         }
1921
1922       fprintf(f,"%s Export Name Table\n", ASM_C);
1923       for (i = 0; (exp = d_exports_lexically[i]); i++)
1924         {
1925           if (!exp->noname || show_allnames)
1926             fprintf (f, "n%d:   %s      \"%s\"\n",
1927                      exp->ordinal, ASM_TEXT, xlate (exp->name));
1928           if (exp->forward != 0)
1929             fprintf (f, "f%d:   %s      \"%s\"\n",
1930                      exp->forward, ASM_TEXT, exp->internal_name);
1931         }
1932
1933       if (a_list)
1934         {
1935           fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
1936           for (dl = a_list; dl; dl = dl->next)
1937             {
1938               fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1939             }
1940         }
1941
1942       if (d_list)
1943         {
1944           fprintf (f, "\t.section .rdata\n");
1945           for (dl = d_list; dl; dl = dl->next)
1946             {
1947               char *p;
1948               int l;
1949
1950               /* We don't output as ascii because there can
1951                  be quote characters in the string.  */
1952               l = 0;
1953               for (p = dl->text; *p; p++)
1954                 {
1955                   if (l == 0)
1956                     fprintf (f, "\t%s\t", ASM_BYTE);
1957                   else
1958                     fprintf (f, ",");
1959                   fprintf (f, "%d", *p);
1960                   if (p[1] == 0)
1961                     {
1962                       fprintf (f, ",0\n");
1963                       break;
1964                     }
1965                   if (++l == 10)
1966                     {
1967                       fprintf (f, "\n");
1968                       l = 0;
1969                     }
1970                 }
1971             }
1972         }
1973     }
1974
1975
1976   /* Add to the output file a way of getting to the exported names
1977      without using the import library.  */
1978   if (add_indirect)
1979     {
1980       fprintf (f, "\t.section\t.rdata\n");
1981       for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1982         if (!exp->noname || show_allnames)
1983           {
1984             /* We use a single underscore for MS compatibility, and a
1985                double underscore for backward compatibility with old
1986                cygwin releases.  */
1987             if (create_compat_implib)
1988               fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1989             fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1990             if (create_compat_implib)
1991               fprintf (f, "__imp_%s:\n", exp->name);
1992             fprintf (f, "_imp__%s:\n", exp->name);
1993             fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1994           }
1995     }
1996
1997   /* Dump the reloc section if a base file is provided.  */
1998   if (base_file)
1999     {
2000       bfd_vma addr;
2001       bfd_vma need[PAGE_SIZE];
2002       bfd_vma page_addr;
2003       bfd_size_type numbytes;
2004       int num_entries;
2005       bfd_vma *copy;
2006       int j;
2007       int on_page;
2008       fprintf (f, "\t.section\t.init\n");
2009       fprintf (f, "lab:\n");
2010
2011       fseek (base_file, 0, SEEK_END);
2012       numbytes = ftell (base_file);
2013       fseek (base_file, 0, SEEK_SET);
2014       copy = xmalloc (numbytes);
2015       if (fread (copy, 1, numbytes, base_file) < numbytes)
2016         fatal (_("failed to read the number of entries from base file"));
2017       num_entries = numbytes / sizeof (bfd_vma);
2018
2019
2020       fprintf (f, "\t.section\t.reloc\n");
2021       if (num_entries)
2022         {
2023           int src;
2024           int dst = 0;
2025           bfd_vma last = (bfd_vma) -1;
2026           qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
2027           /* Delete duplicates */
2028           for (src = 0; src < num_entries; src++)
2029             {
2030               if (last != copy[src])
2031                 last = copy[dst++] = copy[src];
2032             }
2033           num_entries = dst;
2034           addr = copy[0];
2035           page_addr = addr & PAGE_MASK;         /* work out the page addr */
2036           on_page = 0;
2037           for (j = 0; j < num_entries; j++)
2038             {
2039               addr = copy[j];
2040               if ((addr & PAGE_MASK) != page_addr)
2041                 {
2042                   flush_page (f, need, page_addr, on_page);
2043                   on_page = 0;
2044                   page_addr = addr & PAGE_MASK;
2045                 }
2046               need[on_page++] = addr;
2047             }
2048           flush_page (f, need, page_addr, on_page);
2049
2050 /*        fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2051         }
2052     }
2053
2054   generate_idata_ofile (f);
2055
2056   fclose (f);
2057
2058   /* Assemble the file.  */
2059   assemble_file (TMP_ASM, exp_name);
2060
2061   if (dontdeltemps == 0)
2062     unlink (TMP_ASM);
2063
2064   inform (_("Generated exports file"));
2065 }
2066
2067 static const char *
2068 xlate (const char *name)
2069 {
2070   int lead_at = (*name == '@');
2071
2072   if (!lead_at && (add_underscore
2073                    || (add_stdcall_underscore
2074                        && strchr (name, '@'))))
2075     {
2076       char *copy = xmalloc (strlen (name) + 2);
2077
2078       copy[0] = '_';
2079       strcpy (copy + 1, name);
2080       name = copy;
2081     }
2082
2083   if (killat)
2084     {
2085       char *p;
2086
2087       name += lead_at;
2088       p = strchr (name, '@');
2089       if (p)
2090         *p = 0;
2091     }
2092   return name;
2093 }
2094
2095 typedef struct
2096 {
2097   int id;
2098   const char *name;
2099   int flags;
2100   int align;
2101   asection *sec;
2102   asymbol *sym;
2103   asymbol **sympp;
2104   int size;
2105   unsigned char *data;
2106 } sinfo;
2107
2108 #ifndef DLLTOOL_PPC
2109
2110 #define TEXT 0
2111 #define DATA 1
2112 #define BSS 2
2113 #define IDATA7 3
2114 #define IDATA5 4
2115 #define IDATA4 5
2116 #define IDATA6 6
2117
2118 #define NSECS 7
2119
2120 #define TEXT_SEC_FLAGS   \
2121         (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2122 #define DATA_SEC_FLAGS   (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2123 #define BSS_SEC_FLAGS     SEC_ALLOC
2124
2125 #define INIT_SEC_DATA(id, name, flags, align) \
2126         { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2127 static sinfo secdata[NSECS] =
2128 {
2129   INIT_SEC_DATA (TEXT,   ".text",    TEXT_SEC_FLAGS,   2),
2130   INIT_SEC_DATA (DATA,   ".data",    DATA_SEC_FLAGS,   2),
2131   INIT_SEC_DATA (BSS,    ".bss",     BSS_SEC_FLAGS,    2),
2132   INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2),
2133   INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2),
2134   INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
2135   INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
2136 };
2137
2138 #else
2139
2140 /* Sections numbered to make the order the same as other PowerPC NT
2141    compilers. This also keeps funny alignment thingies from happening.  */
2142 #define TEXT   0
2143 #define PDATA  1
2144 #define RDATA  2
2145 #define IDATA5 3
2146 #define IDATA4 4
2147 #define IDATA6 5
2148 #define IDATA7 6
2149 #define DATA   7
2150 #define BSS    8
2151
2152 #define NSECS 9
2153
2154 static sinfo secdata[NSECS] =
2155 {
2156   { TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 3},
2157   { PDATA,  ".pdata",   SEC_HAS_CONTENTS,            2},
2158   { RDATA,  ".reldata", SEC_HAS_CONTENTS,            2},
2159   { IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2},
2160   { IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2},
2161   { IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1},
2162   { IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2},
2163   { DATA,   ".data",    SEC_DATA,                    2},
2164   { BSS,    ".bss",     0,                           2}
2165 };
2166
2167 #endif
2168
2169 /* This is what we're trying to make.  We generate the imp symbols with
2170    both single and double underscores, for compatibility.
2171
2172         .text
2173         .global _GetFileVersionInfoSizeW@8
2174         .global __imp_GetFileVersionInfoSizeW@8
2175 _GetFileVersionInfoSizeW@8:
2176         jmp *   __imp_GetFileVersionInfoSizeW@8
2177         .section        .idata$7        # To force loading of head
2178         .long   __version_a_head
2179 # Import Address Table
2180         .section        .idata$5
2181 __imp_GetFileVersionInfoSizeW@8:
2182         .rva    ID2
2183
2184 # Import Lookup Table
2185         .section        .idata$4
2186         .rva    ID2
2187 # Hint/Name table
2188         .section        .idata$6
2189 ID2:    .short  2
2190         .asciz  "GetFileVersionInfoSizeW"
2191
2192
2193    For the PowerPC, here's the variation on the above scheme:
2194
2195 # Rather than a simple "jmp *", the code to get to the dll function
2196 # looks like:
2197          .text
2198          lwz    r11,[tocv]__imp_function_name(r2)
2199 #                  RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2200          lwz    r12,0(r11)
2201          stw    r2,4(r1)
2202          mtctr  r12
2203          lwz    r2,4(r11)
2204          bctr  */
2205
2206 static char *
2207 make_label (const char *prefix, const char *name)
2208 {
2209   int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2210   char *copy = xmalloc (len + 1);
2211
2212   strcpy (copy, ASM_PREFIX (name));
2213   strcat (copy, prefix);
2214   strcat (copy, name);
2215   return copy;
2216 }
2217
2218 static char *
2219 make_imp_label (const char *prefix, const char *name)
2220 {
2221   int len;
2222   char *copy;
2223
2224   if (name[0] == '@')
2225     {
2226       len = strlen (prefix) + strlen (name);
2227       copy = xmalloc (len + 1);
2228       strcpy (copy, prefix);
2229       strcat (copy, name);
2230     }
2231   else
2232     {
2233       len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2234       copy = xmalloc (len + 1);
2235       strcpy (copy, prefix);
2236       strcat (copy, ASM_PREFIX (name));
2237       strcat (copy, name);
2238     }
2239   return copy;
2240 }
2241
2242 static bfd *
2243 make_one_lib_file (export_type *exp, int i)
2244 {
2245   bfd *      abfd;
2246   asymbol *  exp_label;
2247   asymbol *  iname = 0;
2248   asymbol *  iname2;
2249   asymbol *  iname_lab;
2250   asymbol ** iname_lab_pp;
2251   asymbol ** iname_pp;
2252 #ifdef DLLTOOL_PPC
2253   asymbol ** fn_pp;
2254   asymbol ** toc_pp;
2255 #define EXTRA    2
2256 #endif
2257 #ifndef EXTRA
2258 #define EXTRA    0
2259 #endif
2260   asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
2261   flagword   applicable;
2262   char *     outname = xmalloc (strlen (TMP_STUB) + 10);
2263   int        oidx = 0;
2264
2265
2266   sprintf (outname, "%s%05d.o", TMP_STUB, i);
2267
2268   abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2269
2270   if (!abfd)
2271     /* xgettext:c-format */
2272     fatal (_("bfd_open failed open stub file: %s"), outname);
2273
2274   /* xgettext:c-format */
2275   inform (_("Creating stub file: %s"), outname);
2276
2277   bfd_set_format (abfd, bfd_object);
2278   bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2279
2280 #ifdef DLLTOOL_ARM
2281   if (machine == MARM_INTERWORK || machine == MTHUMB)
2282     bfd_set_private_flags (abfd, F_INTERWORK);
2283 #endif
2284
2285   applicable = bfd_applicable_section_flags (abfd);
2286
2287   /* First make symbols for the sections.  */
2288   for (i = 0; i < NSECS; i++)
2289     {
2290       sinfo *si = secdata + i;
2291
2292       if (si->id != i)
2293         abort();
2294       si->sec = bfd_make_section_old_way (abfd, si->name);
2295       bfd_set_section_flags (abfd,
2296                              si->sec,
2297                              si->flags & applicable);
2298
2299       bfd_set_section_alignment(abfd, si->sec, si->align);
2300       si->sec->output_section = si->sec;
2301       si->sym = bfd_make_empty_symbol(abfd);
2302       si->sym->name = si->sec->name;
2303       si->sym->section = si->sec;
2304       si->sym->flags = BSF_LOCAL;
2305       si->sym->value = 0;
2306       ptrs[oidx] = si->sym;
2307       si->sympp = ptrs + oidx;
2308       si->size = 0;
2309       si->data = NULL;
2310
2311       oidx++;
2312     }
2313
2314   if (! exp->data)
2315     {
2316       exp_label = bfd_make_empty_symbol (abfd);
2317       exp_label->name = make_imp_label ("", exp->name);
2318
2319       /* On PowerPC, the function name points to a descriptor in
2320          the rdata section, the first element of which is a
2321          pointer to the code (..function_name), and the second
2322          points to the .toc.  */
2323 #ifdef DLLTOOL_PPC
2324       if (machine == MPPC)
2325         exp_label->section = secdata[RDATA].sec;
2326       else
2327 #endif
2328         exp_label->section = secdata[TEXT].sec;
2329
2330       exp_label->flags = BSF_GLOBAL;
2331       exp_label->value = 0;
2332
2333 #ifdef DLLTOOL_ARM
2334       if (machine == MTHUMB)
2335         bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2336 #endif
2337       ptrs[oidx++] = exp_label;
2338     }
2339
2340   /* Generate imp symbols with one underscore for Microsoft
2341      compatibility, and with two underscores for backward
2342      compatibility with old versions of cygwin.  */
2343   if (create_compat_implib)
2344     {
2345       iname = bfd_make_empty_symbol (abfd);
2346       iname->name = make_imp_label ("___imp", exp->name);
2347       iname->section = secdata[IDATA5].sec;
2348       iname->flags = BSF_GLOBAL;
2349       iname->value = 0;
2350     }
2351
2352   iname2 = bfd_make_empty_symbol (abfd);
2353   iname2->name = make_imp_label ("__imp_", exp->name);
2354   iname2->section = secdata[IDATA5].sec;
2355   iname2->flags = BSF_GLOBAL;
2356   iname2->value = 0;
2357
2358   iname_lab = bfd_make_empty_symbol (abfd);
2359
2360   iname_lab->name = head_label;
2361   iname_lab->section = (asection *) &bfd_und_section;
2362   iname_lab->flags = 0;
2363   iname_lab->value = 0;
2364
2365   iname_pp = ptrs + oidx;
2366   if (create_compat_implib)
2367     ptrs[oidx++] = iname;
2368   ptrs[oidx++] = iname2;
2369
2370   iname_lab_pp = ptrs + oidx;
2371   ptrs[oidx++] = iname_lab;
2372
2373 #ifdef DLLTOOL_PPC
2374   /* The symbol referring to the code (.text).  */
2375   {
2376     asymbol *function_name;
2377
2378     function_name = bfd_make_empty_symbol(abfd);
2379     function_name->name = make_label ("..", exp->name);
2380     function_name->section = secdata[TEXT].sec;
2381     function_name->flags = BSF_GLOBAL;
2382     function_name->value = 0;
2383
2384     fn_pp = ptrs + oidx;
2385     ptrs[oidx++] = function_name;
2386   }
2387
2388   /* The .toc symbol.  */
2389   {
2390     asymbol *toc_symbol;
2391
2392     toc_symbol = bfd_make_empty_symbol (abfd);
2393     toc_symbol->name = make_label (".", "toc");
2394     toc_symbol->section = (asection *)&bfd_und_section;
2395     toc_symbol->flags = BSF_GLOBAL;
2396     toc_symbol->value = 0;
2397
2398     toc_pp = ptrs + oidx;
2399     ptrs[oidx++] = toc_symbol;
2400   }
2401 #endif
2402
2403   ptrs[oidx] = 0;
2404
2405   for (i = 0; i < NSECS; i++)
2406     {
2407       sinfo *si = secdata + i;
2408       asection *sec = si->sec;
2409       arelent *rel;
2410       arelent **rpp;
2411
2412       switch (i)
2413         {
2414         case TEXT:
2415           if (! exp->data)
2416             {
2417               si->size = HOW_JTAB_SIZE;
2418               si->data = xmalloc (HOW_JTAB_SIZE);
2419               memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2420
2421               /* Add the reloc into idata$5.  */
2422               rel = xmalloc (sizeof (arelent));
2423
2424               rpp = xmalloc (sizeof (arelent *) * 2);
2425               rpp[0] = rel;
2426               rpp[1] = 0;
2427
2428               rel->address = HOW_JTAB_ROFF;
2429               rel->addend = 0;
2430
2431               if (machine == MPPC)
2432                 {
2433                   rel->howto = bfd_reloc_type_lookup (abfd,
2434                                                       BFD_RELOC_16_GOTOFF);
2435                   rel->sym_ptr_ptr = iname_pp;
2436                 }
2437               else if (machine == MX86)
2438                 {
2439                   rel->howto = bfd_reloc_type_lookup (abfd,
2440                                                       BFD_RELOC_32_PCREL);
2441                   rel->sym_ptr_ptr = iname_pp;
2442                 }
2443               else
2444                 {
2445                   rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2446                   rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2447                 }
2448               sec->orelocation = rpp;
2449               sec->reloc_count = 1;
2450             }
2451           break;
2452         case IDATA4:
2453         case IDATA5:
2454           /* An idata$4 or idata$5 is one word long, and has an
2455              rva to idata$6.  */
2456
2457 #ifdef DLLTOOL_MX86_64
2458           si->data = xmalloc (8);
2459           si->size = 8;
2460
2461           if (exp->noname)
2462             {
2463               si->data[0] = exp->ordinal ;
2464               si->data[1] = exp->ordinal >> 8;
2465               si->data[2] = exp->ordinal >> 16;
2466               si->data[3] = exp->ordinal >> 24;
2467               si->data[4] = 0;
2468               si->data[5] = 0;
2469               si->data[6] = 0;
2470               si->data[7] = 0x80;
2471             }
2472           else
2473             {
2474               sec->reloc_count = 1;
2475               memset (si->data, 0, si->size);
2476               rel = xmalloc (sizeof (arelent));
2477               rpp = xmalloc (sizeof (arelent *) * 2);
2478               rpp[0] = rel;
2479               rpp[1] = 0;
2480               rel->address = 0;
2481               rel->addend = 0;
2482               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2483               rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2484               sec->orelocation = rpp;
2485             }
2486 #else
2487           si->data = xmalloc (4);
2488           si->size = 4;
2489
2490           if (exp->noname)
2491             {
2492               si->data[0] = exp->ordinal ;
2493               si->data[1] = exp->ordinal >> 8;
2494               si->data[2] = exp->ordinal >> 16;
2495               si->data[3] = 0x80;
2496             }
2497           else
2498             {
2499               sec->reloc_count = 1;
2500               memset (si->data, 0, si->size);
2501               rel = xmalloc (sizeof (arelent));
2502               rpp = xmalloc (sizeof (arelent *) * 2);
2503               rpp[0] = rel;
2504               rpp[1] = 0;
2505               rel->address = 0;
2506               rel->addend = 0;
2507               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2508               rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2509               sec->orelocation = rpp;
2510             }
2511 #endif
2512           break;
2513
2514         case IDATA6:
2515           if (!exp->noname)
2516             {
2517               /* This used to add 1 to exp->hint.  I don't know
2518                  why it did that, and it does not match what I see
2519                  in programs compiled with the MS tools.  */
2520               int idx = exp->hint;
2521               si->size = strlen (xlate (exp->import_name)) + 3;
2522               si->data = xmalloc (si->size);
2523               si->data[0] = idx & 0xff;
2524               si->data[1] = idx >> 8;
2525               strcpy ((char *) si->data + 2, xlate (exp->import_name));
2526             }
2527           break;
2528         case IDATA7:
2529           si->size = 4;
2530           si->data = xmalloc (4);
2531           memset (si->data, 0, si->size);
2532           rel = xmalloc (sizeof (arelent));
2533           rpp = xmalloc (sizeof (arelent *) * 2);
2534           rpp[0] = rel;
2535           rel->address = 0;
2536           rel->addend = 0;
2537           rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2538           rel->sym_ptr_ptr = iname_lab_pp;
2539           sec->orelocation = rpp;
2540           sec->reloc_count = 1;
2541           break;
2542
2543 #ifdef DLLTOOL_PPC
2544         case PDATA:
2545           {
2546             /* The .pdata section is 5 words long.
2547                Think of it as:
2548                struct
2549                {
2550                bfd_vma BeginAddress,     [0x00]
2551                EndAddress,       [0x04]
2552                ExceptionHandler, [0x08]
2553                HandlerData,      [0x0c]
2554                PrologEndAddress; [0x10]
2555                };  */
2556
2557             /* So this pdata section setups up this as a glue linkage to
2558                a dll routine. There are a number of house keeping things
2559                we need to do:
2560
2561                1. In the name of glue trickery, the ADDR32 relocs for 0,
2562                4, and 0x10 are set to point to the same place:
2563                "..function_name".
2564                2. There is one more reloc needed in the pdata section.
2565                The actual glue instruction to restore the toc on
2566                return is saved as the offset in an IMGLUE reloc.
2567                So we need a total of four relocs for this section.
2568
2569                3. Lastly, the HandlerData field is set to 0x03, to indicate
2570                that this is a glue routine.  */
2571             arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2572
2573             /* Alignment must be set to 2**2 or you get extra stuff.  */
2574             bfd_set_section_alignment(abfd, sec, 2);
2575
2576             si->size = 4 * 5;
2577             si->data = xmalloc (si->size);
2578             memset (si->data, 0, si->size);
2579             rpp = xmalloc (sizeof (arelent *) * 5);
2580             rpp[0] = imglue  = xmalloc (sizeof (arelent));
2581             rpp[1] = ba_rel  = xmalloc (sizeof (arelent));
2582             rpp[2] = ea_rel  = xmalloc (sizeof (arelent));
2583             rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2584             rpp[4] = 0;
2585
2586             /* Stick the toc reload instruction in the glue reloc.  */
2587             bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2588
2589             imglue->addend = 0;
2590             imglue->howto = bfd_reloc_type_lookup (abfd,
2591                                                    BFD_RELOC_32_GOTOFF);
2592             imglue->sym_ptr_ptr = fn_pp;
2593
2594             ba_rel->address = 0;
2595             ba_rel->addend = 0;
2596             ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2597             ba_rel->sym_ptr_ptr = fn_pp;
2598
2599             bfd_put_32 (abfd, 0x18, si->data + 0x04);
2600             ea_rel->address = 4;
2601             ea_rel->addend = 0;
2602             ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2603             ea_rel->sym_ptr_ptr = fn_pp;
2604
2605             /* Mark it as glue.  */
2606             bfd_put_32 (abfd, 0x03, si->data + 0x0c);
2607
2608             /* Mark the prolog end address.  */
2609             bfd_put_32 (abfd, 0x0D, si->data + 0x10);
2610             pea_rel->address = 0x10;
2611             pea_rel->addend = 0;
2612             pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2613             pea_rel->sym_ptr_ptr = fn_pp;
2614
2615             sec->orelocation = rpp;
2616             sec->reloc_count = 4;
2617             break;
2618           }
2619         case RDATA:
2620           /* Each external function in a PowerPC PE file has a two word
2621              descriptor consisting of:
2622              1. The address of the code.
2623              2. The address of the appropriate .toc
2624              We use relocs to build this.  */
2625           si->size = 8;
2626           si->data = xmalloc (8);
2627           memset (si->data, 0, si->size);
2628
2629           rpp = xmalloc (sizeof (arelent *) * 3);
2630           rpp[0] = rel = xmalloc (sizeof (arelent));
2631           rpp[1] = xmalloc (sizeof (arelent));
2632           rpp[2] = 0;
2633
2634           rel->address = 0;
2635           rel->addend = 0;
2636           rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2637           rel->sym_ptr_ptr = fn_pp;
2638
2639           rel = rpp[1];
2640
2641           rel->address = 4;
2642           rel->addend = 0;
2643           rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2644           rel->sym_ptr_ptr = toc_pp;
2645
2646           sec->orelocation = rpp;
2647           sec->reloc_count = 2;
2648           break;
2649 #endif /* DLLTOOL_PPC */
2650         }
2651     }
2652
2653   {
2654     bfd_vma vma = 0;
2655     /* Size up all the sections.  */
2656     for (i = 0; i < NSECS; i++)
2657       {
2658         sinfo *si = secdata + i;
2659
2660         bfd_set_section_size (abfd, si->sec, si->size);
2661         bfd_set_section_vma (abfd, si->sec, vma);
2662       }
2663   }
2664   /* Write them out.  */
2665   for (i = 0; i < NSECS; i++)
2666     {
2667       sinfo *si = secdata + i;
2668
2669       if (i == IDATA5 && no_idata5)
2670         continue;
2671
2672       if (i == IDATA4 && no_idata4)
2673         continue;
2674
2675       bfd_set_section_contents (abfd, si->sec,
2676                                 si->data, 0,
2677                                 si->size);
2678     }
2679
2680   bfd_set_symtab (abfd, ptrs, oidx);
2681   bfd_close (abfd);
2682   abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2683   return abfd;
2684 }
2685
2686 static bfd *
2687 make_head (void)
2688 {
2689   FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2690
2691   if (f == NULL)
2692     {
2693       fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2694       return NULL;
2695     }
2696
2697   fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2698   fprintf (f, "\t.section       .idata$2\n");
2699
2700   fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2701
2702   fprintf (f, "%s:\n", head_label);
2703
2704   fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2705            ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2706
2707   fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2708   fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2709   fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2710   fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2711   fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2712            ASM_RVA_BEFORE,
2713            imp_name_lab,
2714            ASM_RVA_AFTER,
2715            ASM_C);
2716   fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2717            ASM_RVA_BEFORE,
2718            ASM_RVA_AFTER, ASM_C);
2719
2720   fprintf (f, "%sStuff for compatibility\n", ASM_C);
2721
2722   if (!no_idata5)
2723     {
2724       fprintf (f, "\t.section\t.idata$5\n");
2725       if (use_nul_prefixed_import_tables)
2726         {
2727 #ifdef DLLTOOL_MX86_64
2728           fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2729 #else
2730           fprintf (f,"\t%s\t0\n", ASM_LONG);
2731 #endif
2732         }
2733       fprintf (f, "fthunk:\n");
2734     }
2735
2736   if (!no_idata4)
2737     {
2738       fprintf (f, "\t.section\t.idata$4\n");
2739       if (use_nul_prefixed_import_tables)
2740         {
2741 #ifdef DLLTOOL_MX86_64
2742           fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2743 #else
2744           fprintf (f,"\t%s\t0\n", ASM_LONG);
2745 #endif
2746         }
2747       fprintf (f, "hname:\n");
2748     }
2749
2750   fclose (f);
2751
2752   assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2753
2754   return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2755 }
2756
2757 static bfd *
2758 make_tail (void)
2759 {
2760   FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
2761
2762   if (f == NULL)
2763     {
2764       fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
2765       return NULL;
2766     }
2767
2768   if (!no_idata4)
2769     {
2770       fprintf (f, "\t.section   .idata$4\n");
2771 #ifdef DLLTOOL_MX86_64
2772       fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list.  */
2773 #else
2774       fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
2775 #endif
2776     }
2777
2778   if (!no_idata5)
2779     {
2780       fprintf (f, "\t.section   .idata$5\n");
2781 #ifdef DLLTOOL_MX86_64
2782       fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list.  */
2783 #else
2784       fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
2785 #endif
2786     }
2787
2788 #ifdef DLLTOOL_PPC
2789   /* Normally, we need to see a null descriptor built in idata$3 to
2790      act as the terminator for the list. The ideal way, I suppose,
2791      would be to mark this section as a comdat type 2 section, so
2792      only one would appear in the final .exe (if our linker supported
2793      comdat, that is) or cause it to be inserted by something else (say
2794      crt0).  */
2795
2796   fprintf (f, "\t.section       .idata$3\n");
2797   fprintf (f, "\t%s\t0\n", ASM_LONG);
2798   fprintf (f, "\t%s\t0\n", ASM_LONG);
2799   fprintf (f, "\t%s\t0\n", ASM_LONG);
2800   fprintf (f, "\t%s\t0\n", ASM_LONG);
2801   fprintf (f, "\t%s\t0\n", ASM_LONG);
2802 #endif
2803
2804 #ifdef DLLTOOL_PPC
2805   /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2806      do too. Original, huh?  */
2807   fprintf (f, "\t.section       .idata$6\n");
2808 #else
2809   fprintf (f, "\t.section       .idata$7\n");
2810 #endif
2811
2812   fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2813   fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2814            imp_name_lab, ASM_TEXT, dll_name);
2815
2816   fclose (f);
2817
2818   assemble_file (TMP_TAIL_S, TMP_TAIL_O);
2819
2820   return bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
2821 }
2822
2823 static void
2824 gen_lib_file (void)
2825 {
2826   int i;
2827   export_type *exp;
2828   bfd *ar_head;
2829   bfd *ar_tail;
2830   bfd *outarch;
2831   bfd * head  = 0;
2832
2833   unlink (imp_name);
2834
2835   outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
2836
2837   if (!outarch)
2838     /* xgettext:c-format */
2839     fatal (_("Can't open .lib file: %s"), imp_name);
2840
2841   /* xgettext:c-format */
2842   inform (_("Creating library file: %s"), imp_name);
2843
2844   bfd_set_format (outarch, bfd_archive);
2845   outarch->has_armap = 1;
2846   outarch->is_thin_archive = 0;
2847
2848   /* Work out a reasonable size of things to put onto one line.  */
2849   ar_head = make_head ();
2850   ar_tail = make_tail();
2851
2852   if (ar_head == NULL || ar_tail == NULL)
2853     return;
2854
2855   for (i = 0; (exp = d_exports_lexically[i]); i++)
2856     {
2857       bfd *n;
2858       /* Don't add PRIVATE entries to import lib.  */
2859       if (exp->private)
2860         continue;
2861       n = make_one_lib_file (exp, i);
2862       n->archive_next = head;
2863       head = n;
2864       if (ext_prefix_alias)
2865         {
2866           export_type alias_exp;
2867
2868           assert (i < PREFIX_ALIAS_BASE);
2869           alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
2870           alias_exp.internal_name = exp->internal_name;
2871           alias_exp.import_name = exp->name;
2872           alias_exp.ordinal = exp->ordinal;
2873           alias_exp.constant = exp->constant;
2874           alias_exp.noname = exp->noname;
2875           alias_exp.private = exp->private;
2876           alias_exp.data = exp->data;
2877           alias_exp.hint = exp->hint;
2878           alias_exp.forward = exp->forward;
2879           alias_exp.next = exp->next;
2880           n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE);
2881           n->archive_next = head;
2882           head = n;
2883         }
2884     }
2885
2886   /* Now stick them all into the archive.  */
2887   ar_head->archive_next = head;
2888   ar_tail->archive_next = ar_head;
2889   head = ar_tail;
2890
2891   if (! bfd_set_archive_head (outarch, head))
2892     bfd_fatal ("bfd_set_archive_head");
2893
2894   if (! bfd_close (outarch))
2895     bfd_fatal (imp_name);
2896
2897   while (head != NULL)
2898     {
2899       bfd *n = head->archive_next;
2900       bfd_close (head);
2901       head = n;
2902     }
2903
2904   /* Delete all the temp files.  */
2905   if (dontdeltemps == 0)
2906     {
2907       unlink (TMP_HEAD_O);
2908       unlink (TMP_HEAD_S);
2909       unlink (TMP_TAIL_O);
2910       unlink (TMP_TAIL_S);
2911     }
2912
2913   if (dontdeltemps < 2)
2914     {
2915       char *name;
2916
2917       name = (char *) alloca (strlen (TMP_STUB) + 10);
2918       for (i = 0; (exp = d_exports_lexically[i]); i++)
2919         {
2920           /* Don't delete non-existent stubs for PRIVATE entries.  */
2921           if (exp->private)
2922             continue;
2923           sprintf (name, "%s%05d.o", TMP_STUB, i);
2924           if (unlink (name) < 0)
2925             /* xgettext:c-format */
2926             non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
2927           if (ext_prefix_alias)
2928             {
2929               sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
2930               if (unlink (name) < 0)
2931                 /* xgettext:c-format */
2932                 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
2933             }
2934         }
2935     }
2936
2937   inform (_("Created lib file"));
2938 }
2939
2940 /* identify_dll_for_implib
2941
2942    This is the main implementation for the --identify option.
2943    Given the name of an import library in identify_imp_name,
2944    search all archive members for an .idata$7 section
2945    (.idata$6 on PPC). This section will consist of a single
2946    char* constant, indicating the name of the DLL represented
2947    by the import library.
2948
2949    It is possible to construct an import library that has
2950    two members with a non-empty .idata$7 section, but these
2951    are not often seen in normal operation.  In this case,
2952    an error is flagged.
2953 */   
2954 static void 
2955 identify_dll_for_implib (void)
2956 {
2957   bfd* abfd = NULL;
2958
2959   bfd_init ();
2960
2961   abfd = bfd_openr (identify_imp_name, 0);
2962   if (abfd == NULL)
2963     {
2964       bfd_fatal (identify_imp_name);
2965     }
2966   if (!bfd_check_format (abfd, bfd_archive))
2967     {
2968       if (!bfd_close (abfd))
2969         bfd_fatal (identify_imp_name);
2970
2971       fatal ("%s is not a library", identify_imp_name);
2972     }
2973
2974   identify_search_archive (abfd);
2975
2976   if (!bfd_close (abfd))
2977     bfd_fatal (identify_imp_name);
2978
2979   if (identify_dll_name && *identify_dll_name)
2980     {
2981       printf ("%s\n",identify_dll_name);
2982       free (identify_dll_name);
2983       identify_dll_name = NULL;
2984     }
2985   else
2986     {
2987       fatal ("Unable to determine dll name for %s (not an import library?)", identify_imp_name);
2988     }
2989 }
2990
2991 /* identify_search_archive
2992
2993    Loop over all members of the archive, inspecting 
2994    each for the presence of an .idata$7 (.idata$6 on PPC)
2995    section with non-empty contents.
2996 */   
2997 static void
2998 identify_search_archive (bfd* abfd)
2999 {
3000   bfd *arfile = NULL;
3001   bfd *last_arfile = NULL;
3002   char **matching;
3003
3004   while (1)
3005     {
3006       arfile = bfd_openr_next_archived_file (abfd, arfile);
3007
3008       if (arfile == NULL)
3009         {
3010           if (bfd_get_error () != bfd_error_no_more_archived_files)
3011             bfd_fatal (bfd_get_filename (abfd));
3012           break;
3013         }
3014       if (bfd_check_format_matches (arfile, bfd_object, &matching))
3015         {
3016           identify_search_member (arfile, abfd);
3017         }
3018       else
3019         {
3020           bfd_nonfatal (bfd_get_filename (arfile));
3021           free (matching);
3022         }
3023       if (last_arfile != NULL)
3024         {
3025           bfd_close (last_arfile);
3026         }
3027       last_arfile = arfile;
3028     }
3029
3030   if (last_arfile != NULL)
3031     {
3032       bfd_close (last_arfile);
3033     }
3034 }
3035
3036 /* identify_search_member
3037
3038    Search all sections of an archive member for the 
3039    one with section name of .idata$7 (.idata$6 on PPC)
3040    and non-empty contents.
3041 */   
3042 static void
3043 identify_search_member (bfd* abfd, bfd* archive_bfd ATTRIBUTE_UNUSED)
3044 {
3045   bfd_map_over_sections (abfd, identify_search_section, NULL);
3046 }
3047
3048 /* identify_process_section_p
3049
3050    This predicate returns true if section->name
3051    is .idata$7 (.idata$6 on PPC).
3052 */   
3053 static bfd_boolean
3054 identify_process_section_p (asection * section)
3055 {
3056   static const char * SECTION_NAME =
3057 #ifdef DLLTOOL_PPC
3058   /* dllname is stored in idata$6 on PPC */
3059   ".idata$6";
3060 #else
3061   ".idata$7";
3062 #endif
3063
3064   if (strcmp (SECTION_NAME, section->name) == 0)
3065     return TRUE;
3066   return FALSE;
3067 }
3068
3069 /* identify_search_section
3070
3071    If *section has contents and its name is .idata$7
3072    (.data$6 on PPC) then store the contents in 
3073    identify_dll_name as an xmalloc'ed array.
3074
3075    However, if identify_dll_name already has
3076    a value, flag an error. We don't know how to handle
3077    import libraries that directly reference more than
3078    one DLL. (This is different than forwarded symbols.
3079    Such import libraries are not seen in normal operation,
3080    and must be specifically constructed.)
3081 */   
3082 static void
3083 identify_search_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
3084 {
3085   bfd_byte *data = 0;
3086   bfd_size_type datasize;
3087
3088   if ((section->flags & SEC_HAS_CONTENTS) == 0)
3089     return;
3090
3091   if (! identify_process_section_p (section))
3092     return;
3093
3094   if ((datasize = bfd_section_size (abfd, section)) == 0)
3095     return;
3096
3097   data = (bfd_byte*) xmalloc (datasize + 1);
3098   data[0] = '\0';
3099
3100   bfd_get_section_contents (abfd, section, data, 0, datasize);
3101   data[datasize] = '\0';
3102
3103   if (data[0] != '\0')
3104     {
3105       if (identify_dll_name != NULL)
3106         {
3107           if (*identify_dll_name != '\0')
3108             {
3109               /* The import library specifies two different DLLs.
3110                  Treat this as an error. */
3111               fatal ("Import library `%s' specifies two or more dlls: `%s' and `%s'",
3112                      identify_imp_name, identify_dll_name, data);
3113             }
3114           else
3115             {
3116               /* For some reason memory was allocated, but the
3117                  contents were empty. Free the memory and continue. */
3118               free (identify_dll_name);
3119             }
3120         }
3121       identify_dll_name = xstrdup ((char*) data);
3122     }
3123
3124   free (data);
3125 }
3126
3127 /* Run through the information gathered from the .o files and the
3128    .def file and work out the best stuff.  */
3129
3130 static int
3131 pfunc (const void *a, const void *b)
3132 {
3133   export_type *ap = *(export_type **) a;
3134   export_type *bp = *(export_type **) b;
3135   if (ap->ordinal == bp->ordinal)
3136     return 0;
3137
3138   /* Unset ordinals go to the bottom.  */
3139   if (ap->ordinal == -1)
3140     return 1;
3141   if (bp->ordinal == -1)
3142     return -1;
3143   return (ap->ordinal - bp->ordinal);
3144 }
3145
3146 static int
3147 nfunc (const void *a, const void *b)
3148 {
3149   export_type *ap = *(export_type **) a;
3150   export_type *bp = *(export_type **) b;
3151   const char *an = ap->name;
3152   const char *bn = bp->name;
3153
3154   if (killat)
3155     {
3156       an = (an[0] == '@') ? an + 1 : an;
3157       bn = (bn[0] == '@') ? bn + 1 : bn;
3158     }
3159
3160   return (strcmp (an, bn));
3161 }
3162
3163 static void
3164 remove_null_names (export_type **ptr)
3165 {
3166   int src;
3167   int dst;
3168
3169   for (dst = src = 0; src < d_nfuncs; src++)
3170     {
3171       if (ptr[src])
3172         {
3173           ptr[dst] = ptr[src];
3174           dst++;
3175         }
3176     }
3177   d_nfuncs = dst;
3178 }
3179
3180 static void
3181 process_duplicates (export_type **d_export_vec)
3182 {
3183   int more = 1;
3184   int i;
3185
3186   while (more)
3187     {
3188       more = 0;
3189       /* Remove duplicates.  */
3190       qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3191
3192       for (i = 0; i < d_nfuncs - 1; i++)
3193         {
3194           if (strcmp (d_export_vec[i]->name,
3195                       d_export_vec[i + 1]->name) == 0)
3196             {
3197               export_type *a = d_export_vec[i];
3198               export_type *b = d_export_vec[i + 1];
3199
3200               more = 1;
3201
3202               /* xgettext:c-format */
3203               inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3204                       a->name, a->ordinal, b->ordinal);
3205
3206               if (a->ordinal != -1
3207                   && b->ordinal != -1)
3208                 /* xgettext:c-format */
3209                 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3210                       a->name);
3211
3212               /* Merge attributes.  */
3213               b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3214               b->constant |= a->constant;
3215               b->noname |= a->noname;
3216               b->data |= a->data;
3217               d_export_vec[i] = 0;
3218             }
3219
3220           remove_null_names (d_export_vec);
3221         }
3222     }
3223
3224   /* Count the names.  */
3225   for (i = 0; i < d_nfuncs; i++)
3226     if (!d_export_vec[i]->noname)
3227       d_named_nfuncs++;
3228 }
3229
3230 static void
3231 fill_ordinals (export_type **d_export_vec)
3232 {
3233   int lowest = -1;
3234   int i;
3235   char *ptr;
3236   int size = 65536;
3237
3238   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3239
3240   /* Fill in the unset ordinals with ones from our range.  */
3241   ptr = (char *) xmalloc (size);
3242
3243   memset (ptr, 0, size);
3244
3245   /* Mark in our large vector all the numbers that are taken.  */
3246   for (i = 0; i < d_nfuncs; i++)
3247     {
3248       if (d_export_vec[i]->ordinal != -1)
3249         {
3250           ptr[d_export_vec[i]->ordinal] = 1;
3251
3252           if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
3253             lowest = d_export_vec[i]->ordinal;
3254         }
3255     }
3256
3257   /* Start at 1 for compatibility with MS toolchain.  */
3258   if (lowest == -1)
3259     lowest = 1;
3260
3261   /* Now fill in ordinals where the user wants us to choose.  */
3262   for (i = 0; i < d_nfuncs; i++)
3263     {
3264       if (d_export_vec[i]->ordinal == -1)
3265         {
3266           int j;
3267
3268           /* First try within or after any user supplied range.  */
3269           for (j = lowest; j < size; j++)
3270             if (ptr[j] == 0)
3271               {
3272                 ptr[j] = 1;
3273                 d_export_vec[i]->ordinal = j;
3274                 goto done;
3275               }
3276
3277           /* Then try before the range.  */
3278           for (j = lowest; j >0; j--)
3279             if (ptr[j] == 0)
3280               {
3281                 ptr[j] = 1;
3282                 d_export_vec[i]->ordinal = j;
3283                 goto done;
3284               }
3285         done:;
3286         }
3287     }
3288
3289   free (ptr);
3290
3291   /* And resort.  */
3292   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3293
3294   /* Work out the lowest and highest ordinal numbers.  */
3295   if (d_nfuncs)
3296     {
3297       if (d_export_vec[0])
3298         d_low_ord = d_export_vec[0]->ordinal;
3299       if (d_export_vec[d_nfuncs-1])
3300         d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
3301     }
3302 }
3303
3304 static void
3305 mangle_defs (void)
3306 {
3307   /* First work out the minimum ordinal chosen.  */
3308   export_type *exp;
3309
3310   int i;
3311   int hint = 0;
3312   export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
3313
3314   inform (_("Processing definitions"));
3315
3316   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3317     d_export_vec[i] = exp;
3318
3319   process_duplicates (d_export_vec);
3320   fill_ordinals (d_export_vec);
3321
3322   /* Put back the list in the new order.  */
3323   d_exports = 0;
3324   for (i = d_nfuncs - 1; i >= 0; i--)
3325     {
3326       d_export_vec[i]->next = d_exports;
3327       d_exports = d_export_vec[i];
3328     }
3329
3330   /* Build list in alpha order.  */
3331   d_exports_lexically = (export_type **)
3332     xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3333
3334   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3335     d_exports_lexically[i] = exp;
3336
3337   d_exports_lexically[i] = 0;
3338
3339   qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
3340
3341   /* Fill exp entries with their hint values.  */
3342   for (i = 0; i < d_nfuncs; i++)
3343     if (!d_exports_lexically[i]->noname || show_allnames)
3344       d_exports_lexically[i]->hint = hint++;
3345
3346   inform (_("Processed definitions"));
3347 }
3348
3349 static void
3350 usage (FILE *file, int status)
3351 {
3352   /* xgetext:c-format */
3353   fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
3354   /* xgetext:c-format */
3355   fprintf (file, _("   -m --machine <machine>    Create as DLL for <machine>.  [default: %s]\n"), mname);
3356   fprintf (file, _("        possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
3357   fprintf (file, _("   -e --output-exp <outname> Generate an export file.\n"));
3358   fprintf (file, _("   -l --output-lib <outname> Generate an interface library.\n"));
3359   fprintf (file, _("   -a --add-indirect         Add dll indirects to export file.\n"));
3360   fprintf (file, _("   -D --dllname <name>       Name of input dll to put into interface lib.\n"));
3361   fprintf (file, _("   -d --input-def <deffile>  Name of .def file to be read in.\n"));
3362   fprintf (file, _("   -z --output-def <deffile> Name of .def file to be created.\n"));
3363   fprintf (file, _("      --export-all-symbols   Export all symbols to .def\n"));
3364   fprintf (file, _("      --no-export-all-symbols  Only export listed symbols\n"));
3365   fprintf (file, _("      --exclude-symbols <list> Don't export <list>\n"));
3366   fprintf (file, _("      --no-default-excludes  Clear default exclude symbols\n"));
3367   fprintf (file, _("   -b --base-file <basefile> Read linker generated base file.\n"));
3368   fprintf (file, _("   -x --no-idata4            Don't generate idata$4 section.\n"));
3369   fprintf (file, _("   -c --no-idata5            Don't generate idata$5 section.\n"));
3370   fprintf (file, _("      --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3371   fprintf (file, _("   -U --add-underscore       Add underscores to all symbols in interface library.\n"));
3372   fprintf (file, _("      --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3373   fprintf (file, _("   -k --kill-at              Kill @<n> from exported names.\n"));
3374   fprintf (file, _("   -A --add-stdcall-alias    Add aliases without @<n>.\n"));
3375   fprintf (file, _("   -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3376   fprintf (file, _("   -S --as <name>            Use <name> for assembler.\n"));
3377   fprintf (file, _("   -f --as-flags <flags>     Pass <flags> to the assembler.\n"));
3378   fprintf (file, _("   -C --compat-implib        Create backward compatible import library.\n"));
3379   fprintf (file, _("   -n --no-delete            Keep temp files (repeat for extra preservation).\n"));
3380   fprintf (file, _("   -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3381   fprintf (file, _("   -I --identify <implib>    Report the name of the DLL associated with <implib>.\n"));
3382   fprintf (file, _("   -v --verbose              Be verbose.\n"));
3383   fprintf (file, _("   -V --version              Display the program version.\n"));
3384   fprintf (file, _("   -h --help                 Display this information.\n"));
3385   fprintf (file, _("   @<file>                   Read options from <file>.\n"));
3386 #ifdef DLLTOOL_MCORE_ELF
3387   fprintf (file, _("   -M --mcore-elf <outname>  Process mcore-elf object files into <outname>.\n"));
3388   fprintf (file, _("   -L --linker <name>        Use <name> as the linker.\n"));
3389   fprintf (file, _("   -F --linker-flags <flags> Pass <flags> to the linker.\n"));
3390 #endif
3391   if (REPORT_BUGS_TO[0] && status == 0)
3392     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
3393   exit (status);
3394 }
3395
3396 #define OPTION_EXPORT_ALL_SYMS          150
3397 #define OPTION_NO_EXPORT_ALL_SYMS       (OPTION_EXPORT_ALL_SYMS + 1)
3398 #define OPTION_EXCLUDE_SYMS             (OPTION_NO_EXPORT_ALL_SYMS + 1)
3399 #define OPTION_NO_DEFAULT_EXCLUDES      (OPTION_EXCLUDE_SYMS + 1)
3400 #define OPTION_ADD_STDCALL_UNDERSCORE   (OPTION_NO_DEFAULT_EXCLUDES + 1)
3401 #define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \
3402   (OPTION_ADD_STDCALL_UNDERSCORE + 1)
3403
3404 static const struct option long_options[] =
3405 {
3406   {"no-delete", no_argument, NULL, 'n'},
3407   {"dllname", required_argument, NULL, 'D'},
3408   {"no-idata4", no_argument, NULL, 'x'},
3409   {"no-idata5", no_argument, NULL, 'c'},
3410   {"use-nul-prefixed-import-tables", no_argument, NULL,
3411    OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
3412   {"output-exp", required_argument, NULL, 'e'},
3413   {"output-def", required_argument, NULL, 'z'},
3414   {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
3415   {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
3416   {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
3417   {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
3418   {"output-lib", required_argument, NULL, 'l'},
3419   {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
3420   {"input-def", required_argument, NULL, 'd'},
3421   {"add-underscore", no_argument, NULL, 'U'},
3422   {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
3423   {"kill-at", no_argument, NULL, 'k'},
3424   {"add-stdcall-alias", no_argument, NULL, 'A'},
3425   {"ext-prefix-alias", required_argument, NULL, 'p'},
3426   {"identify", required_argument, NULL, 'I'},
3427   {"verbose", no_argument, NULL, 'v'},
3428   {"version", no_argument, NULL, 'V'},
3429   {"help", no_argument, NULL, 'h'},
3430   {"machine", required_argument, NULL, 'm'},
3431   {"add-indirect", no_argument, NULL, 'a'},
3432   {"base-file", required_argument, NULL, 'b'},
3433   {"as", required_argument, NULL, 'S'},
3434   {"as-flags", required_argument, NULL, 'f'},
3435   {"mcore-elf", required_argument, NULL, 'M'},
3436   {"compat-implib", no_argument, NULL, 'C'},
3437   {"temp-prefix", required_argument, NULL, 't'},
3438   {NULL,0,NULL,0}
3439 };
3440
3441 int main (int, char **);
3442
3443 int
3444 main (int ac, char **av)
3445 {
3446   int c;
3447   int i;
3448   char *firstarg = 0;
3449   program_name = av[0];
3450   oav = av;
3451
3452 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3453   setlocale (LC_MESSAGES, "");
3454 #endif
3455 #if defined (HAVE_SETLOCALE)
3456   setlocale (LC_CTYPE, "");
3457 #endif
3458   bindtextdomain (PACKAGE, LOCALEDIR);
3459   textdomain (PACKAGE);
3460
3461   expandargv (&ac, &av);
3462
3463   while ((c = getopt_long (ac, av,
3464 #ifdef DLLTOOL_MCORE_ELF
3465                            "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
3466 #else
3467                            "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
3468 #endif
3469                            long_options, 0))
3470          != EOF)
3471     {
3472       switch (c)
3473         {
3474         case OPTION_EXPORT_ALL_SYMS:
3475           export_all_symbols = TRUE;
3476           break;
3477         case OPTION_NO_EXPORT_ALL_SYMS:
3478           export_all_symbols = FALSE;
3479           break;
3480         case OPTION_EXCLUDE_SYMS:
3481           add_excludes (optarg);
3482           break;
3483         case OPTION_NO_DEFAULT_EXCLUDES:
3484           do_default_excludes = FALSE;
3485           break;
3486         case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
3487           use_nul_prefixed_import_tables = TRUE;
3488           break;
3489         case OPTION_ADD_STDCALL_UNDERSCORE:
3490           add_stdcall_underscore = 1;
3491           break;
3492         case 'x':
3493           no_idata4 = 1;
3494           break;
3495         case 'c':
3496           no_idata5 = 1;
3497           break;
3498         case 'S':
3499           as_name = optarg;
3500           break;
3501         case 't':
3502           tmp_prefix = optarg;
3503           break;
3504         case 'f':
3505           as_flags = optarg;
3506           break;
3507
3508           /* Ignored for compatibility.  */
3509         case 'u':
3510           break;
3511         case 'a':
3512           add_indirect = 1;
3513           break;
3514         case 'z':
3515           output_def = fopen (optarg, FOPEN_WT);
3516           break;
3517         case 'D':
3518           dll_name = (char*) lbasename (optarg);
3519           if (dll_name != optarg)
3520             non_fatal (_("Path components stripped from dllname, '%s'."),
3521                          optarg);
3522           break;
3523         case 'l':
3524           imp_name = optarg;
3525           break;
3526         case 'e':
3527           exp_name = optarg;
3528           break;
3529         case 'H':
3530         case 'h':
3531           usage (stdout, 0);
3532           break;
3533         case 'm':
3534           mname = optarg;
3535           break;
3536         case 'I':
3537           identify_imp_name = optarg;
3538           break;
3539         case 'v':
3540           verbose = 1;
3541           break;
3542         case 'V':
3543           print_version (program_name);
3544           break;
3545         case 'U':
3546           add_underscore = 1;
3547           break;
3548         case 'k':
3549           killat = 1;
3550           break;
3551         case 'A':
3552           add_stdcall_alias = 1;
3553           break;
3554         case 'p':
3555           ext_prefix_alias = optarg;
3556           break;
3557         case 'd':
3558           def_file = optarg;
3559           break;
3560         case 'n':
3561           dontdeltemps++;
3562           break;
3563         case 'b':
3564           base_file = fopen (optarg, FOPEN_RB);
3565
3566           if (!base_file)
3567             /* xgettext:c-format */
3568             fatal (_("Unable to open base-file: %s"), optarg);
3569
3570           break;
3571 #ifdef DLLTOOL_MCORE_ELF
3572         case 'M':
3573           mcore_elf_out_file = optarg;
3574           break;
3575         case 'L':
3576           mcore_elf_linker = optarg;
3577           break;
3578         case 'F':
3579           mcore_elf_linker_flags = optarg;
3580           break;
3581 #endif
3582         case 'C':
3583           create_compat_implib = 1;
3584           break;
3585         default:
3586           usage (stderr, 1);
3587           break;
3588         }
3589     }
3590
3591   if (!tmp_prefix)
3592     tmp_prefix = prefix_encode ("d", getpid ());
3593
3594   for (i = 0; mtable[i].type; i++)
3595     if (strcmp (mtable[i].type, mname) == 0)
3596       break;
3597
3598   if (!mtable[i].type)
3599     /* xgettext:c-format */
3600     fatal (_("Machine '%s' not supported"), mname);
3601
3602   machine = i;
3603
3604   if (!dll_name && exp_name)
3605     {
3606       /* If we are inferring dll_name from exp_name,
3607          strip off any path components, without emitting
3608          a warning.  */  
3609       const char* exp_basename = lbasename (exp_name); 
3610       const int len = strlen (exp_basename) + 5;
3611       dll_name = xmalloc (len);
3612       strcpy (dll_name, exp_basename);
3613       strcat (dll_name, ".dll");
3614     }
3615
3616   if (as_name == NULL)
3617     as_name = deduce_name ("as");
3618
3619   /* Don't use the default exclude list if we're reading only the
3620      symbols in the .drectve section.  The default excludes are meant
3621      to avoid exporting DLL entry point and Cygwin32 impure_ptr.  */
3622   if (! export_all_symbols)
3623     do_default_excludes = FALSE;
3624
3625   if (do_default_excludes)
3626     set_default_excludes ();
3627
3628   if (def_file)
3629     process_def_file (def_file);
3630
3631   while (optind < ac)
3632     {
3633       if (!firstarg)
3634         firstarg = av[optind];
3635       scan_obj_file (av[optind]);
3636       optind++;
3637     }
3638
3639   mangle_defs ();
3640
3641   if (exp_name)
3642     gen_exp_file ();
3643
3644   if (imp_name)
3645     {
3646       /* Make imp_name safe for use as a label.  */
3647       char *p;
3648
3649       imp_name_lab = xstrdup (imp_name);
3650       for (p = imp_name_lab; *p; p++)
3651         {
3652           if (!ISALNUM (*p))
3653             *p = '_';
3654         }
3655       head_label = make_label("_head_", imp_name_lab);
3656       gen_lib_file ();
3657     }
3658
3659   if (output_def)
3660     gen_def_file ();
3661
3662   if (identify_imp_name)
3663     {
3664       identify_dll_for_implib ();
3665     }
3666
3667 #ifdef DLLTOOL_MCORE_ELF
3668   if (mcore_elf_out_file)
3669     mcore_elf_gen_out_file ();
3670 #endif
3671
3672   return 0;
3673 }
3674
3675 /* Look for the program formed by concatenating PROG_NAME and the
3676    string running from PREFIX to END_PREFIX.  If the concatenated
3677    string contains a '/', try appending EXECUTABLE_SUFFIX if it is
3678    appropriate.  */
3679
3680 static char *
3681 look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
3682 {
3683   struct stat s;
3684   char *cmd;
3685
3686   cmd = xmalloc (strlen (prefix)
3687                  + strlen (prog_name)
3688 #ifdef HAVE_EXECUTABLE_SUFFIX
3689                  + strlen (EXECUTABLE_SUFFIX)
3690 #endif
3691                  + 10);
3692   strcpy (cmd, prefix);
3693
3694   sprintf (cmd + end_prefix, "%s", prog_name);
3695
3696   if (strchr (cmd, '/') != NULL)
3697     {
3698       int found;
3699
3700       found = (stat (cmd, &s) == 0
3701 #ifdef HAVE_EXECUTABLE_SUFFIX
3702                || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
3703 #endif
3704                );
3705
3706       if (! found)
3707         {
3708           /* xgettext:c-format */
3709           inform (_("Tried file: %s"), cmd);
3710           free (cmd);
3711           return NULL;
3712         }
3713     }
3714
3715   /* xgettext:c-format */
3716   inform (_("Using file: %s"), cmd);
3717
3718   return cmd;
3719 }
3720
3721 /* Deduce the name of the program we are want to invoke.
3722    PROG_NAME is the basic name of the program we want to run,
3723    eg "as" or "ld".  The catch is that we might want actually
3724    run "i386-pe-as" or "ppc-pe-ld".
3725
3726    If argv[0] contains the full path, then try to find the program
3727    in the same place, with and then without a target-like prefix.
3728
3729    Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
3730    deduce_name("as") uses the following search order:
3731
3732      /usr/local/bin/i586-cygwin32-as
3733      /usr/local/bin/as
3734      as
3735
3736    If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
3737    name, it'll try without and then with EXECUTABLE_SUFFIX.
3738
3739    Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
3740    as the fallback, but rather return i586-cygwin32-as.
3741
3742    Oh, and given, argv[0] = dlltool, it'll return "as".
3743
3744    Returns a dynamically allocated string.  */
3745
3746 static char *
3747 deduce_name (const char *prog_name)
3748 {
3749   char *cmd;
3750   char *dash, *slash, *cp;
3751
3752   dash = NULL;
3753   slash = NULL;
3754   for (cp = program_name; *cp != '\0'; ++cp)
3755     {
3756       if (*cp == '-')
3757         dash = cp;
3758       if (
3759 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
3760           *cp == ':' || *cp == '\\' ||
3761 #endif
3762           *cp == '/')
3763         {
3764           slash = cp;
3765           dash = NULL;
3766         }
3767     }
3768
3769   cmd = NULL;
3770
3771   if (dash != NULL)
3772     {
3773       /* First, try looking for a prefixed PROG_NAME in the
3774          PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME.  */
3775       cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
3776     }
3777
3778   if (slash != NULL && cmd == NULL)
3779     {
3780       /* Next, try looking for a PROG_NAME in the same directory as
3781          that of this program.  */
3782       cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
3783     }
3784
3785   if (cmd == NULL)
3786     {
3787       /* Just return PROG_NAME as is.  */
3788       cmd = xstrdup (prog_name);
3789     }
3790
3791   return cmd;
3792 }
3793
3794 #ifdef DLLTOOL_MCORE_ELF
3795 typedef struct fname_cache
3796 {
3797   const char *         filename;
3798   struct fname_cache * next;
3799 }
3800 fname_cache;
3801
3802 static fname_cache fnames;
3803
3804 static void
3805 mcore_elf_cache_filename (const char * filename)
3806 {
3807   fname_cache * ptr;
3808
3809   ptr = & fnames;
3810
3811   while (ptr->next != NULL)
3812     ptr = ptr->next;
3813
3814   ptr->filename = filename;
3815   ptr->next     = (fname_cache *) malloc (sizeof (fname_cache));
3816   if (ptr->next != NULL)
3817     ptr->next->next = NULL;
3818 }
3819
3820 #define MCORE_ELF_TMP_OBJ "mcoreelf.o"
3821 #define MCORE_ELF_TMP_EXP "mcoreelf.exp"
3822 #define MCORE_ELF_TMP_LIB "mcoreelf.lib"
3823
3824 static void
3825 mcore_elf_gen_out_file (void)
3826 {
3827   fname_cache * ptr;
3828   dyn_string_t ds;
3829
3830   /* Step one.  Run 'ld -r' on the input object files in order to resolve
3831      any internal references and to generate a single .exports section.  */
3832   ptr = & fnames;
3833
3834   ds = dyn_string_new (100);
3835   dyn_string_append_cstr (ds, "-r ");
3836
3837   if (mcore_elf_linker_flags != NULL)
3838     dyn_string_append_cstr (ds, mcore_elf_linker_flags);
3839
3840   while (ptr->next != NULL)
3841     {
3842       dyn_string_append_cstr (ds, ptr->filename);
3843       dyn_string_append_cstr (ds, " ");
3844
3845       ptr = ptr->next;
3846     }
3847
3848   dyn_string_append_cstr (ds, "-o ");
3849   dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
3850
3851   if (mcore_elf_linker == NULL)
3852     mcore_elf_linker = deduce_name ("ld");
3853
3854   run (mcore_elf_linker, ds->s);
3855
3856   dyn_string_delete (ds);
3857
3858   /* Step two. Create a .exp file and a .lib file from the temporary file.
3859      Do this by recursively invoking dlltool...  */
3860   ds = dyn_string_new (100);
3861
3862   dyn_string_append_cstr (ds, "-S ");
3863   dyn_string_append_cstr (ds, as_name);
3864
3865   dyn_string_append_cstr (ds, " -e ");
3866   dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
3867   dyn_string_append_cstr (ds, " -l ");
3868   dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB);
3869   dyn_string_append_cstr (ds, " " );
3870   dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
3871
3872   if (verbose)
3873     dyn_string_append_cstr (ds, " -v");
3874
3875   if (dontdeltemps)
3876     {
3877       dyn_string_append_cstr (ds, " -n");
3878
3879       if (dontdeltemps > 1)
3880         dyn_string_append_cstr (ds, " -n");
3881     }
3882
3883   /* XXX - FIME: ought to check/copy other command line options as well.  */
3884   run (program_name, ds->s);
3885
3886   dyn_string_delete (ds);
3887
3888   /* Step four. Feed the .exp and object files to ld -shared to create the dll.  */
3889   ds = dyn_string_new (100);
3890
3891   dyn_string_append_cstr (ds, "-shared ");
3892
3893   if (mcore_elf_linker_flags)
3894     dyn_string_append_cstr (ds, mcore_elf_linker_flags);
3895
3896   dyn_string_append_cstr (ds, " ");
3897   dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
3898   dyn_string_append_cstr (ds, " ");
3899   dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
3900   dyn_string_append_cstr (ds, " -o ");
3901   dyn_string_append_cstr (ds, mcore_elf_out_file);
3902
3903   run (mcore_elf_linker, ds->s);
3904
3905   dyn_string_delete (ds);
3906
3907   if (dontdeltemps == 0)
3908     unlink (MCORE_ELF_TMP_EXP);
3909
3910   if (dontdeltemps < 2)
3911     unlink (MCORE_ELF_TMP_OBJ);
3912 }
3913 #endif /* DLLTOOL_MCORE_ELF */