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