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