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