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