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