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