OSDN Git Service

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