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