OSDN Git Service

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