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