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