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