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