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