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