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