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