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