OSDN Git Service

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