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