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