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