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