1/* dlltool.c -- tool to generate stuff for PE style DLLs
2   Copyright (C) 1995-2017 Free Software Foundation, Inc.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19   02110-1301, USA.  */
20
21
22/* This program allows you to build the files necessary to create
23   DLLs to run on a system which understands PE format image files.
24   (eg, Windows NT)
25
26   See "Peering Inside the PE: A Tour of the Win32 Portable Executable
27   File Format", MSJ 1994, Volume 9 for more information.
28   Also see "Microsoft Portable Executable and Common Object File Format,
29   Specification 4.1" for more information.
30
31   A DLL contains an export table which contains the information
32   which the runtime loader needs to tie up references from a
33   referencing program.
34
35   The export table is generated by this program by reading
36   in a .DEF file or scanning the .a and .o files which will be in the
37   DLL.  A .o file can contain information in special  ".drectve" sections
38   with export information.
39
40   A DEF file contains any number of the following commands:
41
42
43   NAME <name> [ , <base> ]
44   The result is going to be <name>.EXE
45
46   LIBRARY <name> [ , <base> ]
47   The result is going to be <name>.DLL
48
49   EXPORTS  ( (  ( <name1> [ = <name2> ] )
50               | ( <name1> = <module-name> . <external-name>))
51            [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
52   Declares name1 as an exported symbol from the
53   DLL, with optional ordinal number <integer>.
54   Or declares name1 as an alias (forward) of the function <external-name>
55   in the DLL <module-name>.
56
57   IMPORTS  (  (   <internal-name> =   <module-name> . <integer> )
58             | ( [ <internal-name> = ] <module-name> . <external-name> )) *
59   Declares that <external-name> or the exported function whose ordinal number
60   is <integer> is to be imported from the file <module-name>.  If
61   <internal-name> is specified then this is the name that the imported
62   function will be refereed to in the body of the DLL.
63
64   DESCRIPTION <string>
65   Puts <string> into output .exp file in the .rdata section
66
67   [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
68   Generates --stack|--heap <number-reserve>,<number-commit>
69   in the output .drectve section.  The linker will
70   see this and act upon it.
71
72   [CODE|DATA] <attr>+
73   SECTIONS ( <sectionname> <attr>+ )*
74   <attr> = READ | WRITE | EXECUTE | SHARED
75   Generates --attr <sectionname> <attr> in the output
76   .drectve section.  The linker will see this and act
77   upon it.
78
79
80   A -export:<name> in a .drectve section in an input .o or .a
81   file to this program is equivalent to a EXPORTS <name>
82   in a .DEF file.
83
84
85
86   The program generates output files with the prefix supplied
87   on the command line, or in the def file, or taken from the first
88   supplied argument.
89
90   The .exp.s file contains the information necessary to export
91   the routines in the DLL.  The .lib.s file contains the information
92   necessary to use the DLL's routines from a referencing program.
93
94
95
96   Example:
97
98 file1.c:
99   asm (".section .drectve");
100   asm (".ascii \"-export:adef\"");
101
102   void adef (char * s)
103   {
104     printf ("hello from the dll %s\n", s);
105   }
106
107   void bdef (char * s)
108   {
109     printf ("hello from the dll and the other entry point %s\n", s);
110   }
111
112 file2.c:
113   asm (".section .drectve");
114   asm (".ascii \"-export:cdef\"");
115   asm (".ascii \"-export:ddef\"");
116
117   void cdef (char * s)
118   {
119     printf ("hello from the dll %s\n", s);
120   }
121
122   void ddef (char * s)
123   {
124     printf ("hello from the dll and the other entry point %s\n", s);
125   }
126
127   int printf (void)
128   {
129     return 9;
130   }
131
132 themain.c:
133   int main (void)
134   {
135     cdef ();
136     return 0;
137   }
138
139 thedll.def
140
141   LIBRARY thedll
142   HEAPSIZE 0x40000, 0x2000
143   EXPORTS bdef @ 20
144           cdef @ 30 NONAME
145
146   SECTIONS donkey READ WRITE
147   aardvark EXECUTE
148
149 # Compile up the parts of the dll and the program
150
151   gcc -c file1.c file2.c themain.c
152
153 # Optional: put the dll objects into a library
154 # (you don't have to, you could name all the object
155 # files on the dlltool line)
156
157   ar  qcv thedll.in file1.o file2.o
158   ranlib thedll.in
159
160 # Run this tool over the DLL's .def file and generate an exports
161 # file (thedll.o) and an imports file (thedll.a).
162 # (You may have to use -S to tell dlltool where to find the assembler).
163
164   dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
165
166 # Build the dll with the library and the export table
167
168   ld -o thedll.dll thedll.o thedll.in
169
170 # Link the executable with the import library
171
172   gcc -o themain.exe themain.o thedll.a
173
174 This example can be extended if relocations are needed in the DLL:
175
176 # Compile up the parts of the dll and the program
177
178   gcc -c file1.c file2.c themain.c
179
180 # Run this tool over the DLL's .def file and generate an imports file.
181
182   dlltool --def thedll.def --output-lib thedll.lib
183
184 # Link the executable with the import library and generate a base file
185 # at the same time
186
187   gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base
188
189 # Run this tool over the DLL's .def file and generate an exports file
190 # which includes the relocations from the base file.
191
192   dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp
193
194 # Build the dll with file1.o, file2.o and the export table
195
196   ld -o thedll.dll thedll.exp file1.o file2.o  */
197
198/* .idata section description
199
200   The .idata section is the import table.  It is a collection of several
201   subsections used to keep the pieces for each dll together: .idata$[234567].
202   IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
203
204   .idata$2 = Import Directory Table
205   = array of IMAGE_IMPORT_DESCRIPTOR's.
206
207	DWORD   Import Lookup Table;  - pointer to .idata$4
208	DWORD   TimeDateStamp;        - currently always 0
209	DWORD   ForwarderChain;       - currently always 0
210	DWORD   Name;                 - pointer to dll's name
211	PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
212
213   .idata$3 = null terminating entry for .idata$2.
214
215   .idata$4 = Import Lookup Table
216   = array of array of pointers to hint name table.
217   There is one for each dll being imported from, and each dll's set is
218   terminated by a trailing NULL.
219
220   .idata$5 = Import Address Table
221   = array of array of pointers to hint name table.
222   There is one for each dll being imported from, and each dll's set is
223   terminated by a trailing NULL.
224   Initially, this table is identical to the Import Lookup Table.  However,
225   at load time, the loader overwrites the entries with the address of the
226   function.
227
228   .idata$6 = Hint Name Table
229   = Array of { short, asciz } entries, one for each imported function.
230   The `short' is the function's ordinal number.
231
232   .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc).  */
233
234#include "sysdep.h"
235#include "bfd.h"
236#include "libiberty.h"
237#include "getopt.h"
238#include "demangle.h"
239#include "dyn-string.h"
240#include "bucomm.h"
241#include "dlltool.h"
242#include "safe-ctype.h"
243
244#include <time.h>
245#include <assert.h>
246
247#ifdef DLLTOOL_ARM
248#include "coff/arm.h"
249#include "coff/internal.h"
250#endif
251#ifdef DLLTOOL_DEFAULT_MX86_64
252#include "coff/x86_64.h"
253#endif
254#ifdef DLLTOOL_DEFAULT_I386
255#include "coff/i386.h"
256#endif
257
258#ifndef COFF_PAGE_SIZE
259#define COFF_PAGE_SIZE ((bfd_vma) 4096)
260#endif
261
262#ifndef PAGE_MASK
263#define PAGE_MASK ((bfd_vma) (- COFF_PAGE_SIZE))
264#endif
265
266/* Get current BFD error message.  */
267#define bfd_get_errmsg() (bfd_errmsg (bfd_get_error ()))
268
269/* Forward references.  */
270static char *look_for_prog (const char *, const char *, int);
271static char *deduce_name (const char *);
272
273#ifdef DLLTOOL_MCORE_ELF
274static void mcore_elf_cache_filename (const char *);
275static void mcore_elf_gen_out_file (void);
276#endif
277
278#ifdef HAVE_SYS_WAIT_H
279#include <sys/wait.h>
280#else /* ! HAVE_SYS_WAIT_H */
281#if ! defined (_WIN32) || defined (__CYGWIN32__)
282#ifndef WIFEXITED
283#define WIFEXITED(w)	(((w) & 0377) == 0)
284#endif
285#ifndef WIFSIGNALED
286#define WIFSIGNALED(w)	(((w) & 0377) != 0177 && ((w) & ~0377) == 0)
287#endif
288#ifndef WTERMSIG
289#define WTERMSIG(w)	((w) & 0177)
290#endif
291#ifndef WEXITSTATUS
292#define WEXITSTATUS(w)	(((w) >> 8) & 0377)
293#endif
294#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
295#ifndef WIFEXITED
296#define WIFEXITED(w)	(((w) & 0xff) == 0)
297#endif
298#ifndef WIFSIGNALED
299#define WIFSIGNALED(w)	(((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
300#endif
301#ifndef WTERMSIG
302#define WTERMSIG(w)	((w) & 0x7f)
303#endif
304#ifndef WEXITSTATUS
305#define WEXITSTATUS(w)	(((w) & 0xff00) >> 8)
306#endif
307#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
308#endif /* ! HAVE_SYS_WAIT_H */
309
310#define show_allnames 0
311
312/* ifunc and ihead data structures: ttk@cygnus.com 1997
313
314   When IMPORT declarations are encountered in a .def file the
315   function import information is stored in a structure referenced by
316   the global variable IMPORT_LIST.  The structure is a linked list
317   containing the names of the dll files each function is imported
318   from and a linked list of functions being imported from that dll
319   file.  This roughly parallels the structure of the .idata section
320   in the PE object file.
321
322   The contents of .def file are interpreted from within the
323   process_def_file function.  Every time an IMPORT declaration is
324   encountered, it is broken up into its component parts and passed to
325   def_import.  IMPORT_LIST is initialized to NULL in function main.  */
326
327typedef struct ifunct
328{
329  char *         name;   /* Name of function being imported.  */
330  char *     its_name;	 /* Optional import table symbol name.  */
331  int            ord;    /* Two-byte ordinal value associated with function.  */
332  struct ifunct *next;
333} ifunctype;
334
335typedef struct iheadt
336{
337  char *         dllname;  /* Name of dll file imported from.  */
338  long           nfuncs;   /* Number of functions in list.  */
339  struct ifunct *funchead; /* First function in list.  */
340  struct ifunct *functail; /* Last  function in list.  */
341  struct iheadt *next;     /* Next dll file in list.  */
342} iheadtype;
343
344/* Structure containing all import information as defined in .def file
345   (qv "ihead structure").  */
346
347static iheadtype *import_list = NULL;
348static char *as_name = NULL;
349static char * as_flags = "";
350static char *tmp_prefix;
351static int no_idata4;
352static int no_idata5;
353static char *exp_name;
354static char *imp_name;
355static char *delayimp_name;
356static char *identify_imp_name;
357static bfd_boolean identify_strict;
358
359/* Types used to implement a linked list of dllnames associated
360   with the specified import lib. Used by the identify_* code.
361   The head entry is acts as a sentinal node and is always empty
362   (head->dllname is NULL).  */
363typedef struct dll_name_list_node_t
364{
365  char *                        dllname;
366  struct dll_name_list_node_t * next;
367} dll_name_list_node_type;
368
369typedef struct dll_name_list_t
370{
371  dll_name_list_node_type * head;
372  dll_name_list_node_type * tail;
373} dll_name_list_type;
374
375/* Types used to pass data to iterator functions.  */
376typedef struct symname_search_data_t
377{
378  const char * symname;
379  bfd_boolean  found;
380} symname_search_data_type;
381
382typedef struct identify_data_t
383{
384   dll_name_list_type * list;
385   bfd_boolean          ms_style_implib;
386} identify_data_type;
387
388
389static char *head_label;
390static char *imp_name_lab;
391static char *dll_name;
392static int dll_name_set_by_exp_name;
393static int add_indirect = 0;
394static int add_underscore = 0;
395static int add_stdcall_underscore = 0;
396/* This variable can hold three different values. The value
397   -1 (default) means that default underscoring should be used,
398   zero means that no underscoring should be done, and one
399   indicates that underscoring should be done.  */
400static int leading_underscore = -1;
401static int dontdeltemps = 0;
402
403/* TRUE if we should export all symbols.  Otherwise, we only export
404   symbols listed in .drectve sections or in the def file.  */
405static bfd_boolean export_all_symbols;
406
407/* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
408   exporting all symbols.  */
409static bfd_boolean do_default_excludes = TRUE;
410
411static bfd_boolean use_nul_prefixed_import_tables = FALSE;
412
413/* Default symbols to exclude when exporting all the symbols.  */
414static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
415
416/* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
417   compatibility to old Cygwin releases.  */
418static bfd_boolean create_compat_implib;
419
420/* TRUE if we have to write PE+ import libraries.  */
421static bfd_boolean create_for_pep;
422
423static char *def_file;
424
425extern char * program_name;
426
427static int machine;
428static int killat;
429static int add_stdcall_alias;
430static const char *ext_prefix_alias;
431static int verbose;
432static FILE *output_def;
433static FILE *base_file;
434
435#ifdef DLLTOOL_DEFAULT_ARM
436static const char *mname = "arm";
437#endif
438
439#ifdef DLLTOOL_DEFAULT_ARM_EPOC
440static const char *mname = "arm-epoc";
441#endif
442
443#ifdef DLLTOOL_DEFAULT_ARM_WINCE
444static const char *mname = "arm-wince";
445#endif
446
447#ifdef DLLTOOL_DEFAULT_I386
448static const char *mname = "i386";
449#endif
450
451#ifdef DLLTOOL_DEFAULT_MX86_64
452static const char *mname = "i386:x86-64";
453#endif
454
455#ifdef DLLTOOL_DEFAULT_PPC
456static const char *mname = "ppc";
457#endif
458
459#ifdef DLLTOOL_DEFAULT_SH
460static const char *mname = "sh";
461#endif
462
463#ifdef DLLTOOL_DEFAULT_MIPS
464static const char *mname = "mips";
465#endif
466
467#ifdef DLLTOOL_DEFAULT_MCORE
468static const char * mname = "mcore-le";
469#endif
470
471#ifdef DLLTOOL_DEFAULT_MCORE_ELF
472static const char * mname = "mcore-elf";
473static char * mcore_elf_out_file = NULL;
474static char * mcore_elf_linker   = NULL;
475static char * mcore_elf_linker_flags = NULL;
476
477#define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
478#endif
479
480#ifndef DRECTVE_SECTION_NAME
481#define DRECTVE_SECTION_NAME ".drectve"
482#endif
483
484/* What's the right name for this ?  */
485#define PATHMAX 250
486
487/* External name alias numbering starts here.  */
488#define PREFIX_ALIAS_BASE	20000
489
490char *tmp_asm_buf;
491char *tmp_head_s_buf;
492char *tmp_head_o_buf;
493char *tmp_tail_s_buf;
494char *tmp_tail_o_buf;
495char *tmp_stub_buf;
496
497#define TMP_ASM		dlltmp (&tmp_asm_buf, "%sc.s")
498#define TMP_HEAD_S	dlltmp (&tmp_head_s_buf, "%sh.s")
499#define TMP_HEAD_O	dlltmp (&tmp_head_o_buf, "%sh.o")
500#define TMP_TAIL_S	dlltmp (&tmp_tail_s_buf, "%st.s")
501#define TMP_TAIL_O	dlltmp (&tmp_tail_o_buf, "%st.o")
502#define TMP_STUB	dlltmp (&tmp_stub_buf, "%ss")
503
504/* This bit of assembly does jmp * ....  */
505static const unsigned char i386_jtab[] =
506{
507  0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
508};
509
510static const unsigned char i386_dljtab[] =
511{
512  0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function             */
513  0xB8, 0x00, 0x00, 0x00, 0x00,       /* mov eax, offset __imp__function */
514  0xE9, 0x00, 0x00, 0x00, 0x00        /* jmp __tailMerge__dllname        */
515};
516
517static const unsigned char i386_x64_dljtab[] =
518{
519  0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function             */
520  0x48, 0x8d, 0x05,		      /* leaq rax, (__imp__function) */
521        0x00, 0x00, 0x00, 0x00,
522  0xE9, 0x00, 0x00, 0x00, 0x00        /* jmp __tailMerge__dllname        */
523};
524
525static const unsigned char arm_jtab[] =
526{
527  0x00, 0xc0, 0x9f, 0xe5,	/* ldr  ip, [pc] */
528  0x00, 0xf0, 0x9c, 0xe5,	/* ldr  pc, [ip] */
529  0,    0,    0,    0
530};
531
532static const unsigned char arm_interwork_jtab[] =
533{
534  0x04, 0xc0, 0x9f, 0xe5,	/* ldr  ip, [pc] */
535  0x00, 0xc0, 0x9c, 0xe5,	/* ldr  ip, [ip] */
536  0x1c, 0xff, 0x2f, 0xe1,	/* bx   ip       */
537  0,    0,    0,    0
538};
539
540static const unsigned char thumb_jtab[] =
541{
542  0x40, 0xb4,           /* push {r6}         */
543  0x02, 0x4e,           /* ldr  r6, [pc, #8] */
544  0x36, 0x68,           /* ldr  r6, [r6]     */
545  0xb4, 0x46,           /* mov  ip, r6       */
546  0x40, 0xbc,           /* pop  {r6}         */
547  0x60, 0x47,           /* bx   ip           */
548  0,    0,    0,    0
549};
550
551static const unsigned char mcore_be_jtab[] =
552{
553  0x71, 0x02,            /* lrw r1,2       */
554  0x81, 0x01,            /* ld.w r1,(r1,0) */
555  0x00, 0xC1,            /* jmp r1         */
556  0x12, 0x00,            /* nop            */
557  0x00, 0x00, 0x00, 0x00 /* <address>      */
558};
559
560static const unsigned char mcore_le_jtab[] =
561{
562  0x02, 0x71,            /* lrw r1,2       */
563  0x01, 0x81,            /* ld.w r1,(r1,0) */
564  0xC1, 0x00,            /* jmp r1         */
565  0x00, 0x12,            /* nop            */
566  0x00, 0x00, 0x00, 0x00 /* <address>      */
567};
568
569/* This is the glue sequence for PowerPC PE. There is a
570   tocrel16-tocdefn reloc against the first instruction.
571   We also need a IMGLUE reloc against the glue function
572   to restore the toc saved by the third instruction in
573   the glue.  */
574static const unsigned char ppc_jtab[] =
575{
576  0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2)               */
577                          /*   Reloc TOCREL16 __imp_xxx  */
578  0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11)              */
579  0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1)                */
580  0xA6, 0x03, 0x89, 0x7D, /* mtctr r12                   */
581  0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11)               */
582  0x20, 0x04, 0x80, 0x4E  /* bctr                        */
583};
584
585#ifdef DLLTOOL_PPC
586/* The glue instruction, picks up the toc from the stw in
587   the above code: "lwz r2,4(r1)".  */
588static bfd_vma ppc_glue_insn = 0x80410004;
589#endif
590
591static const char i386_trampoline[] =
592  "\tpushl %%ecx\n"
593  "\tpushl %%edx\n"
594  "\tpushl %%eax\n"
595  "\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
596  "\tcall ___delayLoadHelper2@8\n"
597  "\tpopl %%edx\n"
598  "\tpopl %%ecx\n"
599  "\tjmp *%%eax\n";
600
601static const char i386_x64_trampoline[] =
602  "\tpushq %%rcx\n"
603  "\tpushq %%rdx\n"
604  "\tpushq %%r8\n"
605  "\tpushq %%r9\n"
606  "\tsubq  $40, %%rsp\n"
607  "\tmovq  %%rax, %%rdx\n"
608  "\tleaq  __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n"
609  "\tcall __delayLoadHelper2\n"
610  "\taddq  $40, %%rsp\n"
611  "\tpopq %%r9\n"
612  "\tpopq %%r8\n"
613  "\tpopq %%rdx\n"
614  "\tpopq %%rcx\n"
615  "\tjmp *%%rax\n";
616
617struct mac
618{
619  const char *type;
620  const char *how_byte;
621  const char *how_short;
622  const char *how_long;
623  const char *how_asciz;
624  const char *how_comment;
625  const char *how_jump;
626  const char *how_global;
627  const char *how_space;
628  const char *how_align_short;
629  const char *how_align_long;
630  const char *how_default_as_switches;
631  const char *how_bfd_target;
632  enum bfd_architecture how_bfd_arch;
633  const unsigned char *how_jtab;
634  int how_jtab_size; /* Size of the jtab entry.  */
635  int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5.  */
636  const unsigned char *how_dljtab;
637  int how_dljtab_size; /* Size of the dljtab entry.  */
638  int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5.  */
639  int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5.  */
640  int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5.  */
641  const char *trampoline;
642};
643
644static const struct mac
645mtable[] =
646{
647  {
648#define MARM 0
649    "arm", ".byte", ".short", ".long", ".asciz", "@",
650    "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
651    ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
652    "pe-arm-little", bfd_arch_arm,
653    arm_jtab, sizeof (arm_jtab), 8,
654    0, 0, 0, 0, 0, 0
655  }
656  ,
657  {
658#define M386 1
659    "i386", ".byte", ".short", ".long", ".asciz", "#",
660    "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
661    "pe-i386",bfd_arch_i386,
662    i386_jtab, sizeof (i386_jtab), 2,
663    i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
664  }
665  ,
666  {
667#define MPPC 2
668    "ppc", ".byte", ".short", ".long", ".asciz", "#",
669    "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
670    "pe-powerpcle",bfd_arch_powerpc,
671    ppc_jtab, sizeof (ppc_jtab), 0,
672    0, 0, 0, 0, 0, 0
673  }
674  ,
675  {
676#define MTHUMB 3
677    "thumb", ".byte", ".short", ".long", ".asciz", "@",
678    "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
679    ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
680    "pe-arm-little", bfd_arch_arm,
681    thumb_jtab, sizeof (thumb_jtab), 12,
682    0, 0, 0, 0, 0, 0
683  }
684  ,
685#define MARM_INTERWORK 4
686  {
687    "arm_interwork", ".byte", ".short", ".long", ".asciz", "@",
688    "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
689    ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
690    "pe-arm-little", bfd_arch_arm,
691    arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
692    0, 0, 0, 0, 0, 0
693  }
694  ,
695  {
696#define MMCORE_BE 5
697    "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
698    "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
699    ".global", ".space", ".align\t2",".align\t4", "",
700    "pe-mcore-big", bfd_arch_mcore,
701    mcore_be_jtab, sizeof (mcore_be_jtab), 8,
702    0, 0, 0, 0, 0, 0
703  }
704  ,
705  {
706#define MMCORE_LE 6
707    "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
708    "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
709    ".global", ".space", ".align\t2",".align\t4", "-EL",
710    "pe-mcore-little", bfd_arch_mcore,
711    mcore_le_jtab, sizeof (mcore_le_jtab), 8,
712    0, 0, 0, 0, 0, 0
713  }
714  ,
715  {
716#define MMCORE_ELF 7
717    "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
718    "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
719    ".global", ".space", ".align\t2",".align\t4", "",
720    "elf32-mcore-big", bfd_arch_mcore,
721    mcore_be_jtab, sizeof (mcore_be_jtab), 8,
722    0, 0, 0, 0, 0, 0
723  }
724  ,
725  {
726#define MMCORE_ELF_LE 8
727    "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
728    "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
729    ".global", ".space", ".align\t2",".align\t4", "-EL",
730    "elf32-mcore-little", bfd_arch_mcore,
731    mcore_le_jtab, sizeof (mcore_le_jtab), 8,
732    0, 0, 0, 0, 0, 0
733  }
734  ,
735  {
736#define MARM_EPOC 9
737    "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
738    "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
739    ".global", ".space", ".align\t2",".align\t4", "",
740    "epoc-pe-arm-little", bfd_arch_arm,
741    arm_jtab, sizeof (arm_jtab), 8,
742    0, 0, 0, 0, 0, 0
743  }
744  ,
745  {
746#define MARM_WINCE 10
747    "arm-wince", ".byte", ".short", ".long", ".asciz", "@",
748    "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
749    ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
750    "pe-arm-wince-little", bfd_arch_arm,
751    arm_jtab, sizeof (arm_jtab), 8,
752    0, 0, 0, 0, 0, 0
753  }
754  ,
755  {
756#define MX86 11
757    "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
758    "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
759    "pe-x86-64",bfd_arch_i386,
760    i386_jtab, sizeof (i386_jtab), 2,
761    i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, i386_x64_trampoline
762  }
763  ,
764  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
765};
766
767typedef struct dlist
768{
769  char *text;
770  struct dlist *next;
771}
772dlist_type;
773
774typedef struct export
775{
776  const char *name;
777  const char *internal_name;
778  const char *import_name;
779  const char *its_name;
780  int ordinal;
781  int constant;
782  int noname;		/* Don't put name in image file.  */
783  int private;		/* Don't put reference in import lib.  */
784  int data;
785  int forward;		/* Number of forward label, 0 means no forward.  */
786  struct export *next;
787}
788export_type;
789
790/* A list of symbols which we should not export.  */
791
792struct string_list
793{
794  struct string_list *next;
795  char *string;
796};
797
798static struct string_list *excludes;
799
800static const char *rvaafter (int);
801static const char *rvabefore (int);
802static const char *asm_prefix (int, const char *);
803static void process_def_file (const char *);
804static void new_directive (char *);
805static void append_import (const char *, const char *, int, const char *);
806static void run (const char *, char *);
807static void scan_drectve_symbols (bfd *);
808static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
809static void add_excludes (const char *);
810static bfd_boolean match_exclude (const char *);
811static void set_default_excludes (void);
812static long filter_symbols (bfd *, void *, long, unsigned int);
813static void scan_all_symbols (bfd *);
814static void scan_open_obj_file (bfd *);
815static void scan_obj_file (const char *);
816static void dump_def_info (FILE *);
817static int sfunc (const void *, const void *);
818static void flush_page (FILE *, bfd_vma *, bfd_vma, int);
819static void gen_def_file (void);
820static void generate_idata_ofile (FILE *);
821static void assemble_file (const char *, const char *);
822static void gen_exp_file (void);
823static const char *xlate (const char *);
824static char *make_label (const char *, const char *);
825static char *make_imp_label (const char *, const char *);
826static bfd *make_one_lib_file (export_type *, int, int);
827static bfd *make_head (void);
828static bfd *make_tail (void);
829static bfd *make_delay_head (void);
830static void gen_lib_file (int);
831static void dll_name_list_append (dll_name_list_type *, bfd_byte *);
832static int  dll_name_list_count (dll_name_list_type *);
833static void dll_name_list_print (dll_name_list_type *);
834static void dll_name_list_free_contents (dll_name_list_node_type *);
835static void dll_name_list_free (dll_name_list_type *);
836static dll_name_list_type * dll_name_list_create (void);
837static void identify_dll_for_implib (void);
838static void identify_search_archive
839  (bfd *, void (*) (bfd *, bfd *, void *),  void *);
840static void identify_search_member (bfd *, bfd *, void *);
841static bfd_boolean identify_process_section_p (asection *, bfd_boolean);
842static void identify_search_section (bfd *, asection *, void *);
843static void identify_member_contains_symname (bfd *, bfd  *, void *);
844
845static int pfunc (const void *, const void *);
846static int nfunc (const void *, const void *);
847static void remove_null_names (export_type **);
848static void process_duplicates (export_type **);
849static void fill_ordinals (export_type **);
850static void mangle_defs (void);
851static void usage (FILE *, int);
852static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
853static void set_dll_name_from_def (const char *name, char is_dll);
854
855static char *
856prefix_encode (char *start, unsigned code)
857{
858  static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
859  static char buf[32];
860  char *p;
861  strcpy (buf, start);
862  p = strchr (buf, '\0');
863  do
864    *p++ = alpha[code % sizeof (alpha)];
865  while ((code /= sizeof (alpha)) != 0);
866  *p = '\0';
867  return buf;
868}
869
870static char *
871dlltmp (char **buf, const char *fmt)
872{
873  if (!*buf)
874    {
875      *buf = malloc (strlen (tmp_prefix) + 64);
876      sprintf (*buf, fmt, tmp_prefix);
877    }
878  return *buf;
879}
880
881static void
882inform (const char * message, ...)
883{
884  va_list args;
885
886  va_start (args, message);
887
888  if (!verbose)
889    return;
890
891  report (message, args);
892
893  va_end (args);
894}
895
896static const char *
897rvaafter (int mach)
898{
899  switch (mach)
900    {
901    case MARM:
902    case M386:
903    case MX86:
904    case MPPC:
905    case MTHUMB:
906    case MARM_INTERWORK:
907    case MMCORE_BE:
908    case MMCORE_LE:
909    case MMCORE_ELF:
910    case MMCORE_ELF_LE:
911    case MARM_EPOC:
912    case MARM_WINCE:
913      break;
914    default:
915      /* xgettext:c-format */
916      fatal (_("Internal error: Unknown machine type: %d"), mach);
917      break;
918    }
919  return "";
920}
921
922static const char *
923rvabefore (int mach)
924{
925  switch (mach)
926    {
927    case MARM:
928    case M386:
929    case MX86:
930    case MPPC:
931    case MTHUMB:
932    case MARM_INTERWORK:
933    case MMCORE_BE:
934    case MMCORE_LE:
935    case MMCORE_ELF:
936    case MMCORE_ELF_LE:
937    case MARM_EPOC:
938    case MARM_WINCE:
939      return ".rva\t";
940    default:
941      /* xgettext:c-format */
942      fatal (_("Internal error: Unknown machine type: %d"), mach);
943      break;
944    }
945  return "";
946}
947
948static const char *
949asm_prefix (int mach, const char *name)
950{
951  switch (mach)
952    {
953    case MARM:
954    case MPPC:
955    case MTHUMB:
956    case MARM_INTERWORK:
957    case MMCORE_BE:
958    case MMCORE_LE:
959    case MMCORE_ELF:
960    case MMCORE_ELF_LE:
961    case MARM_EPOC:
962    case MARM_WINCE:
963      break;
964    case M386:
965    case MX86:
966      /* Symbol names starting with ? do not have a leading underscore. */
967      if ((name && *name == '?') || leading_underscore == 0)
968        break;
969      else
970        return "_";
971    default:
972      /* xgettext:c-format */
973      fatal (_("Internal error: Unknown machine type: %d"), mach);
974      break;
975    }
976  return "";
977}
978
979#define ASM_BYTE		mtable[machine].how_byte
980#define ASM_SHORT		mtable[machine].how_short
981#define ASM_LONG		mtable[machine].how_long
982#define ASM_TEXT		mtable[machine].how_asciz
983#define ASM_C			mtable[machine].how_comment
984#define ASM_JUMP		mtable[machine].how_jump
985#define ASM_GLOBAL		mtable[machine].how_global
986#define ASM_SPACE		mtable[machine].how_space
987#define ASM_ALIGN_SHORT		mtable[machine].how_align_short
988#define ASM_RVA_BEFORE		rvabefore (machine)
989#define ASM_RVA_AFTER		rvaafter (machine)
990#define ASM_PREFIX(NAME)	asm_prefix (machine, (NAME))
991#define ASM_ALIGN_LONG  	mtable[machine].how_align_long
992#define HOW_BFD_READ_TARGET	0  /* Always default.  */
993#define HOW_BFD_WRITE_TARGET	mtable[machine].how_bfd_target
994#define HOW_BFD_ARCH		mtable[machine].how_bfd_arch
995#define HOW_JTAB		(delay ? mtable[machine].how_dljtab \
996					: mtable[machine].how_jtab)
997#define HOW_JTAB_SIZE		(delay ? mtable[machine].how_dljtab_size \
998					: mtable[machine].how_jtab_size)
999#define HOW_JTAB_ROFF		(delay ? mtable[machine].how_dljtab_roff1 \
1000					: mtable[machine].how_jtab_roff)
1001#define HOW_JTAB_ROFF2		(delay ? mtable[machine].how_dljtab_roff2 : 0)
1002#define HOW_JTAB_ROFF3		(delay ? mtable[machine].how_dljtab_roff3 : 0)
1003#define ASM_SWITCHES		mtable[machine].how_default_as_switches
1004
1005static char **oav;
1006
1007static void
1008process_def_file (const char *name)
1009{
1010  FILE *f = fopen (name, FOPEN_RT);
1011
1012  if (!f)
1013    /* xgettext:c-format */
1014    fatal (_("Can't open def file: %s"), name);
1015
1016  yyin = f;
1017
1018  /* xgettext:c-format */
1019  inform (_("Processing def file: %s"), name);
1020
1021  yyparse ();
1022
1023  inform (_("Processed def file"));
1024}
1025
1026/**********************************************************************/
1027
1028/* Communications with the parser.  */
1029
1030static int d_nfuncs;		/* Number of functions exported.  */
1031static int d_named_nfuncs;	/* Number of named functions exported.  */
1032static int d_low_ord;		/* Lowest ordinal index.  */
1033static int d_high_ord;		/* Highest ordinal index.  */
1034static export_type *d_exports;	/* List of exported functions.  */
1035static export_type **d_exports_lexically;  /* Vector of exported functions in alpha order.  */
1036static dlist_type *d_list;	/* Descriptions.  */
1037static dlist_type *a_list;	/* Stuff to go in directives.  */
1038static int d_nforwards = 0;	/* Number of forwarded exports.  */
1039
1040static int d_is_dll;
1041static int d_is_exe;
1042
1043int
1044yyerror (const char * err ATTRIBUTE_UNUSED)
1045{
1046  /* xgettext:c-format */
1047  non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
1048
1049  return 0;
1050}
1051
1052void
1053def_exports (const char *name, const char *internal_name, int ordinal,
1054	     int noname, int constant, int data, int private,
1055	     const char *its_name)
1056{
1057  struct export *p = (struct export *) xmalloc (sizeof (*p));
1058
1059  p->name = name;
1060  p->internal_name = internal_name ? internal_name : name;
1061  p->its_name = its_name;
1062  p->import_name = name;
1063  p->ordinal = ordinal;
1064  p->constant = constant;
1065  p->noname = noname;
1066  p->private = private;
1067  p->data = data;
1068  p->next = d_exports;
1069  d_exports = p;
1070  d_nfuncs++;
1071
1072  if ((internal_name != NULL)
1073      && (strchr (internal_name, '.') != NULL))
1074    p->forward = ++d_nforwards;
1075  else
1076    p->forward = 0; /* no forward */
1077}
1078
1079static void
1080set_dll_name_from_def (const char *name, char is_dll)
1081{
1082  const char *image_basename = lbasename (name);
1083  if (image_basename != name)
1084    non_fatal (_("%s: Path components stripped from image name, '%s'."),
1085	      def_file, name);
1086  /* Append the default suffix, if none specified.  */
1087  if (strchr (image_basename, '.') == 0)
1088    {
1089      const char * suffix = is_dll ? ".dll" : ".exe";
1090
1091      dll_name = xmalloc (strlen (image_basename) + strlen (suffix) + 1);
1092      sprintf (dll_name, "%s%s", image_basename, suffix);
1093    }
1094  else
1095    dll_name = xstrdup (image_basename);
1096}
1097
1098void
1099def_name (const char *name, int base)
1100{
1101  /* xgettext:c-format */
1102  inform (_("NAME: %s base: %x"), name, base);
1103
1104  if (d_is_dll)
1105    non_fatal (_("Can't have LIBRARY and NAME"));
1106
1107  if (dll_name_set_by_exp_name && name && *name != 0)
1108    {
1109      dll_name = NULL;
1110      dll_name_set_by_exp_name = 0;
1111    }
1112  /* If --dllname not provided, use the one in the DEF file.
1113     FIXME: Is this appropriate for executables?  */
1114  if (!dll_name)
1115    set_dll_name_from_def (name, 0);
1116  d_is_exe = 1;
1117}
1118
1119void
1120def_library (const char *name, int base)
1121{
1122  /* xgettext:c-format */
1123  inform (_("LIBRARY: %s base: %x"), name, base);
1124
1125  if (d_is_exe)
1126    non_fatal (_("Can't have LIBRARY and NAME"));
1127
1128  if (dll_name_set_by_exp_name && name && *name != 0)
1129    {
1130      dll_name = NULL;
1131      dll_name_set_by_exp_name = 0;
1132    }
1133
1134  /* If --dllname not provided, use the one in the DEF file.  */
1135  if (!dll_name)
1136    set_dll_name_from_def (name, 1);
1137  d_is_dll = 1;
1138}
1139
1140void
1141def_description (const char *desc)
1142{
1143  dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1144  d->text = xstrdup (desc);
1145  d->next = d_list;
1146  d_list = d;
1147}
1148
1149static void
1150new_directive (char *dir)
1151{
1152  dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
1153  d->text = xstrdup (dir);
1154  d->next = a_list;
1155  a_list = d;
1156}
1157
1158void
1159def_heapsize (int reserve, int commit)
1160{
1161  char b[200];
1162  if (commit > 0)
1163    sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
1164  else
1165    sprintf (b, "-heap 0x%x ", reserve);
1166  new_directive (xstrdup (b));
1167}
1168
1169void
1170def_stacksize (int reserve, int commit)
1171{
1172  char b[200];
1173  if (commit > 0)
1174    sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
1175  else
1176    sprintf (b, "-stack 0x%x ", reserve);
1177  new_directive (xstrdup (b));
1178}
1179
1180/* append_import simply adds the given import definition to the global
1181   import_list.  It is used by def_import.  */
1182
1183static void
1184append_import (const char *symbol_name, const char *dllname, int func_ordinal,
1185	       const char *its_name)
1186{
1187  iheadtype **pq;
1188  iheadtype *q;
1189
1190  for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
1191    {
1192      if (strcmp ((*pq)->dllname, dllname) == 0)
1193	{
1194	  q = *pq;
1195	  q->functail->next = xmalloc (sizeof (ifunctype));
1196	  q->functail = q->functail->next;
1197	  q->functail->ord  = func_ordinal;
1198	  q->functail->name = xstrdup (symbol_name);
1199	  q->functail->its_name = (its_name ? xstrdup (its_name) : NULL);
1200	  q->functail->next = NULL;
1201	  q->nfuncs++;
1202	  return;
1203	}
1204    }
1205
1206  q = xmalloc (sizeof (iheadtype));
1207  q->dllname = xstrdup (dllname);
1208  q->nfuncs = 1;
1209  q->funchead = xmalloc (sizeof (ifunctype));
1210  q->functail = q->funchead;
1211  q->next = NULL;
1212  q->functail->name = xstrdup (symbol_name);
1213  q->functail->its_name = (its_name ? xstrdup (its_name) : NULL);
1214  q->functail->ord  = func_ordinal;
1215  q->functail->next = NULL;
1216
1217  *pq = q;
1218}
1219
1220/* def_import is called from within defparse.y when an IMPORT
1221   declaration is encountered.  Depending on the form of the
1222   declaration, the module name may or may not need ".dll" to be
1223   appended to it, the name of the function may be stored in internal
1224   or entry, and there may or may not be an ordinal value associated
1225   with it.  */
1226
1227/* A note regarding the parse modes:
1228   In defparse.y we have to accept import declarations which follow
1229   any one of the following forms:
1230     <func_name_in_app> = <dll_name>.<func_name_in_dll>
1231     <func_name_in_app> = <dll_name>.<number>
1232     <dll_name>.<func_name_in_dll>
1233     <dll_name>.<number>
1234   Furthermore, the dll's name may or may not end with ".dll", which
1235   complicates the parsing a little.  Normally the dll's name is
1236   passed to def_import() in the "module" parameter, but when it ends
1237   with ".dll" it gets passed in "module" sans ".dll" and that needs
1238   to be reappended.
1239
1240  def_import gets five parameters:
1241  APP_NAME - the name of the function in the application, if
1242             present, or NULL if not present.
1243  MODULE   - the name of the dll, possibly sans extension (ie, '.dll').
1244  DLLEXT   - the extension of the dll, if present, NULL if not present.
1245  ENTRY    - the name of the function in the dll, if present, or NULL.
1246  ORD_VAL  - the numerical tag of the function in the dll, if present,
1247             or NULL.  Exactly one of <entry> or <ord_val> must be
1248             present (i.e., not NULL).  */
1249
1250void
1251def_import (const char *app_name, const char *module, const char *dllext,
1252	    const char *entry, int ord_val, const char *its_name)
1253{
1254  const char *application_name;
1255  char *buf = NULL;
1256
1257  if (entry != NULL)
1258    application_name = entry;
1259  else
1260    {
1261      if (app_name != NULL)
1262	application_name = app_name;
1263      else
1264	application_name = "";
1265    }
1266
1267  if (dllext != NULL)
1268    module = buf = concat (module, ".", dllext, NULL);
1269
1270  append_import (application_name, module, ord_val, its_name);
1271
1272  if (buf)
1273    free (buf);
1274}
1275
1276void
1277def_version (int major, int minor)
1278{
1279  printf (_("VERSION %d.%d\n"), major, minor);
1280}
1281
1282void
1283def_section (const char *name, int attr)
1284{
1285  char buf[200];
1286  char atts[5];
1287  char *d = atts;
1288  if (attr & 1)
1289    *d++ = 'R';
1290
1291  if (attr & 2)
1292    *d++ = 'W';
1293  if (attr & 4)
1294    *d++ = 'X';
1295  if (attr & 8)
1296    *d++ = 'S';
1297  *d++ = 0;
1298  sprintf (buf, "-attr %s %s", name, atts);
1299  new_directive (xstrdup (buf));
1300}
1301
1302void
1303def_code (int attr)
1304{
1305
1306  def_section ("CODE", attr);
1307}
1308
1309void
1310def_data (int attr)
1311{
1312  def_section ("DATA", attr);
1313}
1314
1315/**********************************************************************/
1316
1317static void
1318run (const char *what, char *args)
1319{
1320  char *s;
1321  int pid, wait_status;
1322  int i;
1323  const char **argv;
1324  char *errmsg_fmt, *errmsg_arg;
1325  char *temp_base = choose_temp_base ();
1326
1327  inform (_("run: %s %s"), what, args);
1328
1329  /* Count the args */
1330  i = 0;
1331  for (s = args; *s; s++)
1332    if (*s == ' ')
1333      i++;
1334  i++;
1335  argv = xmalloc (sizeof (char *) * (i + 3));
1336  i = 0;
1337  argv[i++] = what;
1338  s = args;
1339  while (1)
1340    {
1341      while (*s == ' ')
1342	++s;
1343      argv[i++] = s;
1344      while (*s != ' ' && *s != 0)
1345	s++;
1346      if (*s == 0)
1347	break;
1348      *s++ = 0;
1349    }
1350  argv[i++] = NULL;
1351
1352  pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
1353		  &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
1354  free(argv);
1355
1356  if (pid == -1)
1357    {
1358      inform ("%s", strerror (errno));
1359
1360      fatal (errmsg_fmt, errmsg_arg);
1361    }
1362
1363  pid = pwait (pid, & wait_status, 0);
1364
1365  if (pid == -1)
1366    {
1367      /* xgettext:c-format */
1368      fatal (_("wait: %s"), strerror (errno));
1369    }
1370  else if (WIFSIGNALED (wait_status))
1371    {
1372      /* xgettext:c-format */
1373      fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
1374    }
1375  else if (WIFEXITED (wait_status))
1376    {
1377      if (WEXITSTATUS (wait_status) != 0)
1378	/* xgettext:c-format */
1379	non_fatal (_("%s exited with status %d"),
1380		   what, WEXITSTATUS (wait_status));
1381    }
1382  else
1383    abort ();
1384}
1385
1386/* Look for a list of symbols to export in the .drectve section of
1387   ABFD.  Pass each one to def_exports.  */
1388
1389static void
1390scan_drectve_symbols (bfd *abfd)
1391{
1392  asection * s;
1393  int        size;
1394  char *     buf;
1395  char *     p;
1396  char *     e;
1397
1398  /* Look for .drectve's */
1399  s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1400
1401  if (s == NULL)
1402    return;
1403
1404  size = bfd_get_section_size (s);
1405  buf  = xmalloc (size);
1406
1407  bfd_get_section_contents (abfd, s, buf, 0, size);
1408
1409  /* xgettext:c-format */
1410  inform (_("Sucking in info from %s section in %s"),
1411	  DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1412
1413  /* Search for -export: strings. The exported symbols can optionally
1414     have type tags (eg., -export:foo,data), so handle those as well.
1415     Currently only data tag is supported.  */
1416  p = buf;
1417  e = buf + size;
1418  while (p < e)
1419    {
1420      if (p[0] == '-'
1421	  && CONST_STRNEQ (p, "-export:"))
1422	{
1423	  char * name;
1424	  char * c;
1425	  flagword flags = BSF_FUNCTION;
1426
1427	  p += 8;
1428	  /* Do we have a quoted export?  */
1429	  if (*p == '"')
1430	    {
1431	      p++;
1432	      name = p;
1433	      while (p < e && *p != '"')
1434		++p;
1435	    }
1436	  else
1437	    {
1438	      name = p;
1439	      while (p < e && *p != ',' && *p != ' ' && *p != '-')
1440		p++;
1441	    }
1442	  c = xmalloc (p - name + 1);
1443	  memcpy (c, name, p - name);
1444	  c[p - name] = 0;
1445	  /* Advance over trailing quote.  */
1446	  if (p < e && *p == '"')
1447	    ++p;
1448	  if (p < e && *p == ',')       /* found type tag.  */
1449	    {
1450	      char *tag_start = ++p;
1451	      while (p < e && *p != ' ' && *p != '-')
1452		p++;
1453	      if (CONST_STRNEQ (tag_start, "data"))
1454		flags &= ~BSF_FUNCTION;
1455	    }
1456
1457	  /* FIXME: The 5th arg is for the `constant' field.
1458	     What should it be?  Not that it matters since it's not
1459	     currently useful.  */
1460	  def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0, NULL);
1461
1462	  if (add_stdcall_alias && strchr (c, '@'))
1463	    {
1464	      int lead_at = (*c == '@') ;
1465	      char *exported_name = xstrdup (c + lead_at);
1466	      char *atsym = strchr (exported_name, '@');
1467	      *atsym = '\0';
1468	      /* Note: stdcall alias symbols can never be data.  */
1469	      def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0, NULL);
1470	    }
1471	}
1472      else
1473	p++;
1474    }
1475  free (buf);
1476}
1477
1478/* Look through the symbols in MINISYMS, and add each one to list of
1479   symbols to export.  */
1480
1481static void
1482scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1483		       unsigned int size)
1484{
1485  asymbol *store;
1486  bfd_byte *from, *fromend;
1487
1488  store = bfd_make_empty_symbol (abfd);
1489  if (store == NULL)
1490    bfd_fatal (bfd_get_filename (abfd));
1491
1492  from = (bfd_byte *) minisyms;
1493  fromend = from + symcount * size;
1494  for (; from < fromend; from += size)
1495    {
1496      asymbol *sym;
1497      const char *symbol_name;
1498
1499      sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
1500      if (sym == NULL)
1501	bfd_fatal (bfd_get_filename (abfd));
1502
1503      symbol_name = bfd_asymbol_name (sym);
1504      if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
1505	++symbol_name;
1506
1507      def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
1508		   ! (sym->flags & BSF_FUNCTION), 0, NULL);
1509
1510      if (add_stdcall_alias && strchr (symbol_name, '@'))
1511        {
1512	  int lead_at = (*symbol_name == '@');
1513	  char *exported_name = xstrdup (symbol_name + lead_at);
1514	  char *atsym = strchr (exported_name, '@');
1515	  *atsym = '\0';
1516	  /* Note: stdcall alias symbols can never be data.  */
1517	  def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0, NULL);
1518	}
1519    }
1520}
1521
1522/* Add a list of symbols to exclude.  */
1523
1524static void
1525add_excludes (const char *new_excludes)
1526{
1527  char *local_copy;
1528  char *exclude_string;
1529
1530  local_copy = xstrdup (new_excludes);
1531
1532  exclude_string = strtok (local_copy, ",:");
1533  for (; exclude_string; exclude_string = strtok (NULL, ",:"))
1534    {
1535      struct string_list *new_exclude;
1536
1537      new_exclude = ((struct string_list *)
1538		     xmalloc (sizeof (struct string_list)));
1539      new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
1540      /* Don't add a leading underscore for fastcall symbols.  */
1541      if (*exclude_string == '@')
1542	sprintf (new_exclude->string, "%s", exclude_string);
1543      else
1544	sprintf (new_exclude->string, "%s%s", (!leading_underscore ? "" : "_"),
1545		 exclude_string);
1546      new_exclude->next = excludes;
1547      excludes = new_exclude;
1548
1549      /* xgettext:c-format */
1550      inform (_("Excluding symbol: %s"), exclude_string);
1551    }
1552
1553  free (local_copy);
1554}
1555
1556/* See if STRING is on the list of symbols to exclude.  */
1557
1558static bfd_boolean
1559match_exclude (const char *string)
1560{
1561  struct string_list *excl_item;
1562
1563  for (excl_item = excludes; excl_item; excl_item = excl_item->next)
1564    if (strcmp (string, excl_item->string) == 0)
1565      return TRUE;
1566  return FALSE;
1567}
1568
1569/* Add the default list of symbols to exclude.  */
1570
1571static void
1572set_default_excludes (void)
1573{
1574  add_excludes (default_excludes);
1575}
1576
1577/* Choose which symbols to export.  */
1578
1579static long
1580filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
1581{
1582  bfd_byte *from, *fromend, *to;
1583  asymbol *store;
1584
1585  store = bfd_make_empty_symbol (abfd);
1586  if (store == NULL)
1587    bfd_fatal (bfd_get_filename (abfd));
1588
1589  from = (bfd_byte *) minisyms;
1590  fromend = from + symcount * size;
1591  to = (bfd_byte *) minisyms;
1592
1593  for (; from < fromend; from += size)
1594    {
1595      int keep = 0;
1596      asymbol *sym;
1597
1598      sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
1599      if (sym == NULL)
1600	bfd_fatal (bfd_get_filename (abfd));
1601
1602      /* Check for external and defined only symbols.  */
1603      keep = (((sym->flags & BSF_GLOBAL) != 0
1604	       || (sym->flags & BSF_WEAK) != 0
1605	       || bfd_is_com_section (sym->section))
1606	      && ! bfd_is_und_section (sym->section));
1607
1608      keep = keep && ! match_exclude (sym->name);
1609
1610      if (keep)
1611	{
1612	  memcpy (to, from, size);
1613	  to += size;
1614	}
1615    }
1616
1617  return (to - (bfd_byte *) minisyms) / size;
1618}
1619
1620/* Export all symbols in ABFD, except for ones we were told not to
1621   export.  */
1622
1623static void
1624scan_all_symbols (bfd *abfd)
1625{
1626  long symcount;
1627  void *minisyms;
1628  unsigned int size;
1629
1630  /* Ignore bfds with an import descriptor table.  We assume that any
1631     such BFD contains symbols which are exported from another DLL,
1632     and we don't want to reexport them from here.  */
1633  if (bfd_get_section_by_name (abfd, ".idata$4"))
1634    return;
1635
1636  if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1637    {
1638      /* xgettext:c-format */
1639      non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1640      return;
1641    }
1642
1643  symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
1644  if (symcount < 0)
1645    bfd_fatal (bfd_get_filename (abfd));
1646
1647  if (symcount == 0)
1648    {
1649      /* xgettext:c-format */
1650      non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1651      return;
1652    }
1653
1654  /* Discard the symbols we don't want to export.  It's OK to do this
1655     in place; we'll free the storage anyway.  */
1656
1657  symcount = filter_symbols (abfd, minisyms, symcount, size);
1658  scan_filtered_symbols (abfd, minisyms, symcount, size);
1659
1660  free (minisyms);
1661}
1662
1663/* Look at the object file to decide which symbols to export.  */
1664
1665static void
1666scan_open_obj_file (bfd *abfd)
1667{
1668  if (export_all_symbols)
1669    scan_all_symbols (abfd);
1670  else
1671    scan_drectve_symbols (abfd);
1672
1673  /* FIXME: we ought to read in and block out the base relocations.  */
1674
1675  /* xgettext:c-format */
1676  inform (_("Done reading %s"), bfd_get_filename (abfd));
1677}
1678
1679static void
1680scan_obj_file (const char *filename)
1681{
1682  bfd * f = bfd_openr (filename, 0);
1683
1684  if (!f)
1685    /* xgettext:c-format */
1686    fatal (_("Unable to open object file: %s: %s"), filename, bfd_get_errmsg ());
1687
1688  /* xgettext:c-format */
1689  inform (_("Scanning object file %s"), filename);
1690
1691  if (bfd_check_format (f, bfd_archive))
1692    {
1693      bfd *arfile = bfd_openr_next_archived_file (f, 0);
1694      while (arfile)
1695	{
1696	  bfd *next;
1697	  if (bfd_check_format (arfile, bfd_object))
1698	    scan_open_obj_file (arfile);
1699	  next = bfd_openr_next_archived_file (f, arfile);
1700	  bfd_close (arfile);
1701	  /* PR 17512: file: 58715298.  */
1702	  if (next == arfile)
1703	    break;
1704	  arfile = next;
1705	}
1706
1707#ifdef DLLTOOL_MCORE_ELF
1708      if (mcore_elf_out_file)
1709	inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);
1710#endif
1711    }
1712  else if (bfd_check_format (f, bfd_object))
1713    {
1714      scan_open_obj_file (f);
1715
1716#ifdef DLLTOOL_MCORE_ELF
1717      if (mcore_elf_out_file)
1718	mcore_elf_cache_filename (filename);
1719#endif
1720    }
1721
1722  bfd_close (f);
1723}
1724
1725
1726
1727static void
1728dump_def_info (FILE *f)
1729{
1730  int i;
1731  export_type *exp;
1732  fprintf (f, "%s ", ASM_C);
1733  for (i = 0; oav[i]; i++)
1734    fprintf (f, "%s ", oav[i]);
1735  fprintf (f, "\n");
1736  for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1737    {
1738      fprintf (f, "%s  %d = %s %s @ %d %s%s%s%s%s%s\n",
1739	       ASM_C,
1740	       i,
1741	       exp->name,
1742	       exp->internal_name,
1743	       exp->ordinal,
1744	       exp->noname ? "NONAME " : "",
1745	       exp->private ? "PRIVATE " : "",
1746	       exp->constant ? "CONSTANT" : "",
1747	       exp->data ? "DATA" : "",
1748	       exp->its_name ? " ==" : "",
1749	       exp->its_name ? exp->its_name : "");
1750    }
1751}
1752
1753/* Generate the .exp file.  */
1754
1755static int
1756sfunc (const void *a, const void *b)
1757{
1758  if (*(const bfd_vma *) a == *(const bfd_vma *) b)
1759    return 0;
1760
1761  return ((*(const bfd_vma *) a > *(const bfd_vma *) b) ? 1 : -1);
1762}
1763
1764static void
1765flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1766{
1767  int i;
1768
1769  /* Flush this page.  */
1770  fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1771	   ASM_LONG,
1772	   (int) page_addr,
1773	   ASM_C);
1774  fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1775	   ASM_LONG,
1776	   (on_page * 2) + (on_page & 1) * 2 + 8,
1777	   ASM_C);
1778
1779  for (i = 0; i < on_page; i++)
1780    {
1781      bfd_vma needed = need[i];
1782
1783      if (needed)
1784        {
1785	  if (!create_for_pep)
1786	    {
1787	      /* Relocation via HIGHLOW.  */
1788	      needed = ((needed - page_addr) | 0x3000) & 0xffff;
1789	    }
1790	  else
1791	    {
1792	      /* Relocation via DIR64.  */
1793	      needed = ((needed - page_addr) | 0xa000) & 0xffff;
1794	    }
1795	}
1796
1797      fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1798    }
1799
1800  /* And padding */
1801  if (on_page & 1)
1802    fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1803}
1804
1805static void
1806gen_def_file (void)
1807{
1808  int i;
1809  export_type *exp;
1810
1811  inform (_("Adding exports to output file"));
1812
1813  fprintf (output_def, ";");
1814  for (i = 0; oav[i]; i++)
1815    fprintf (output_def, " %s", oav[i]);
1816
1817  fprintf (output_def, "\nEXPORTS\n");
1818
1819  for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1820    {
1821      char *quote = strchr (exp->name, '.') ? "\"" : "";
1822      char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1823
1824      if (res)
1825	{
1826	  fprintf (output_def,";\t%s\n", res);
1827	  free (res);
1828	}
1829
1830      if (strcmp (exp->name, exp->internal_name) == 0)
1831	{
1832	  fprintf (output_def, "\t%s%s%s @ %d%s%s%s%s%s\n",
1833		   quote,
1834		   exp->name,
1835		   quote,
1836		   exp->ordinal,
1837		   exp->noname ? " NONAME" : "",
1838		   exp->private ? "PRIVATE " : "",
1839		   exp->data ? " DATA" : "",
1840		   exp->its_name ? " ==" : "",
1841		   exp->its_name ? exp->its_name : "");
1842	}
1843      else
1844	{
1845	  char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1846	  /* char *alias =  */
1847	  fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s%s%s\n",
1848		   quote,
1849		   exp->name,
1850		   quote,
1851		   quote1,
1852		   exp->internal_name,
1853		   quote1,
1854		   exp->ordinal,
1855		   exp->noname ? " NONAME" : "",
1856		   exp->private ? "PRIVATE " : "",
1857		   exp->data ? " DATA" : "",
1858		   exp->its_name ? " ==" : "",
1859		   exp->its_name ? exp->its_name : "");
1860	}
1861    }
1862
1863  inform (_("Added exports to output file"));
1864}
1865
1866/* generate_idata_ofile generates the portable assembly source code
1867   for the idata sections.  It appends the source code to the end of
1868   the file.  */
1869
1870static void
1871generate_idata_ofile (FILE *filvar)
1872{
1873  iheadtype *headptr;
1874  ifunctype *funcptr;
1875  int        headindex;
1876  int        funcindex;
1877  int	     nheads;
1878
1879  if (import_list == NULL)
1880    return;
1881
1882  fprintf (filvar, "%s Import data sections\n", ASM_C);
1883  fprintf (filvar, "\n\t.section\t.idata$2\n");
1884  fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1885  fprintf (filvar, "doi_idata:\n");
1886
1887  nheads = 0;
1888  for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1889    {
1890      fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1891	       ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1892	       ASM_C, headptr->dllname);
1893      fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1894      fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1895      fprintf (filvar, "\t%sdllname%d%s\n",
1896	       ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1897      fprintf (filvar, "\t%slisttwo%d%s\n\n",
1898	       ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1899      nheads++;
1900    }
1901
1902  fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1903  fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1904  fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section        */
1905  fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1906  fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1907
1908  fprintf (filvar, "\n\t.section\t.idata$4\n");
1909  headindex = 0;
1910  for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1911    {
1912      fprintf (filvar, "listone%d:\n", headindex);
1913      for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1914        {
1915	  if (create_for_pep)
1916	    fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1917		     ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1918		     ASM_LONG);
1919	  else
1920	    fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1921		     ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1922        }
1923      if (create_for_pep)
1924	fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1925      else
1926	fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
1927      headindex++;
1928    }
1929
1930  fprintf (filvar, "\n\t.section\t.idata$5\n");
1931  headindex = 0;
1932  for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1933    {
1934      fprintf (filvar, "listtwo%d:\n", headindex);
1935      for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
1936        {
1937	  if (create_for_pep)
1938	    fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
1939		     ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,
1940		     ASM_LONG);
1941	  else
1942	    fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1943		     ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1944        }
1945      if (create_for_pep)
1946	fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
1947      else
1948	fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
1949      headindex++;
1950    }
1951
1952  fprintf (filvar, "\n\t.section\t.idata$6\n");
1953  headindex = 0;
1954  for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1955    {
1956      funcindex = 0;
1957      for (funcptr = headptr->funchead; funcptr != NULL;
1958	   funcptr = funcptr->next)
1959	{
1960	  fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1961	  fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1962		   ((funcptr->ord) & 0xFFFF));
1963	  fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT,
1964	    (funcptr->its_name ? funcptr->its_name : funcptr->name));
1965	  fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1966	  funcindex++;
1967	}
1968      headindex++;
1969    }
1970
1971  fprintf (filvar, "\n\t.section\t.idata$7\n");
1972  headindex = 0;
1973  for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1974    {
1975      fprintf (filvar,"dllname%d:\n", headindex);
1976      fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1977      fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1978      headindex++;
1979    }
1980}
1981
1982/* Assemble the specified file.  */
1983static void
1984assemble_file (const char * source, const char * dest)
1985{
1986  char * cmd;
1987
1988  cmd = xmalloc (strlen (ASM_SWITCHES) + strlen (as_flags)
1989		 + strlen (source) + strlen (dest) + 50);
1990
1991  sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1992
1993  run (as_name, cmd);
1994  free (cmd);
1995}
1996
1997static const char * temp_file_to_remove[5];
1998#define TEMP_EXPORT_FILE 0
1999#define TEMP_HEAD_FILE   1
2000#define TEMP_TAIL_FILE   2
2001#define TEMP_HEAD_O_FILE 3
2002#define TEMP_TAIL_O_FILE 4
2003
2004static void
2005unlink_temp_files (void)
2006{
2007  unsigned i;
2008
2009  if (dontdeltemps > 0)
2010    return;
2011
2012  for (i = 0; i < ARRAY_SIZE (temp_file_to_remove); i++)
2013    {
2014      if (temp_file_to_remove[i])
2015	{
2016	  unlink (temp_file_to_remove[i]);
2017	  temp_file_to_remove[i] = NULL;
2018	}
2019    }
2020}
2021
2022static void
2023gen_exp_file (void)
2024{
2025  FILE *f;
2026  int i;
2027  export_type *exp;
2028  dlist_type *dl;
2029
2030  /* xgettext:c-format */
2031  inform (_("Generating export file: %s"), exp_name);
2032
2033  f = fopen (TMP_ASM, FOPEN_WT);
2034  if (!f)
2035    /* xgettext:c-format */
2036    fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
2037
2038  temp_file_to_remove[TEMP_EXPORT_FILE] = TMP_ASM;
2039
2040  /* xgettext:c-format */
2041  inform (_("Opened temporary file: %s"), TMP_ASM);
2042
2043  dump_def_info (f);
2044
2045  if (d_exports)
2046    {
2047      fprintf (f, "\t.section	.edata\n\n");
2048      fprintf (f, "\t%s	0	%s Allways 0\n", ASM_LONG, ASM_C);
2049      fprintf (f, "\t%s	0x%lx	%s Time and date\n", ASM_LONG,
2050	       (unsigned long) time(0), ASM_C);
2051      fprintf (f, "\t%s	0	%s Major and Minor version\n", ASM_LONG, ASM_C);
2052      fprintf (f, "\t%sname%s	%s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2053      fprintf (f, "\t%s	%d	%s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
2054
2055
2056      fprintf (f, "\t%s	%d	%s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
2057      fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
2058	      ASM_C,
2059	      d_named_nfuncs, d_low_ord, d_high_ord);
2060      fprintf (f, "\t%s	%d	%s Number of names\n", ASM_LONG,
2061	       show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
2062      fprintf (f, "\t%safuncs%s  %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2063
2064      fprintf (f, "\t%sanames%s	%s Address of Name Pointer Table\n",
2065	       ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2066
2067      fprintf (f, "\t%sanords%s	%s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2068
2069      fprintf (f, "name:	%s	\"%s\"\n", ASM_TEXT, dll_name);
2070
2071
2072      fprintf(f,"%s Export address Table\n", ASM_C);
2073      fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
2074      fprintf (f, "afuncs:\n");
2075      i = d_low_ord;
2076
2077      for (exp = d_exports; exp; exp = exp->next)
2078	{
2079	  if (exp->ordinal != i)
2080	    {
2081	      while (i < exp->ordinal)
2082		{
2083		  fprintf(f,"\t%s\t0\n", ASM_LONG);
2084		  i++;
2085		}
2086	    }
2087
2088	  if (exp->forward == 0)
2089	    {
2090	      if (exp->internal_name[0] == '@')
2091		fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2092			 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2093	      else
2094		fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
2095			 ASM_PREFIX (exp->internal_name),
2096			 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2097	    }
2098	  else
2099	    fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE,
2100		     exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal);
2101	  i++;
2102	}
2103
2104      fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
2105      fprintf (f, "anames:\n");
2106
2107      for (i = 0; (exp = d_exports_lexically[i]); i++)
2108	{
2109	  if (!exp->noname || show_allnames)
2110	    fprintf (f, "\t%sn%d%s\n",
2111		     ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
2112	}
2113
2114      fprintf (f,"%s Export Ordinal Table\n", ASM_C);
2115      fprintf (f, "anords:\n");
2116      for (i = 0; (exp = d_exports_lexically[i]); i++)
2117	{
2118	  if (!exp->noname || show_allnames)
2119	    fprintf (f, "\t%s	%d\n", ASM_SHORT, exp->ordinal - d_low_ord);
2120	}
2121
2122      fprintf(f,"%s Export Name Table\n", ASM_C);
2123      for (i = 0; (exp = d_exports_lexically[i]); i++)
2124	{
2125	  if (!exp->noname || show_allnames)
2126	    fprintf (f, "n%d:	%s	\"%s\"\n",
2127		     exp->ordinal, ASM_TEXT,
2128		     (exp->its_name ? exp->its_name : xlate (exp->name)));
2129	  if (exp->forward != 0)
2130	    fprintf (f, "f%d:	%s	\"%s\"\n",
2131		     exp->forward, ASM_TEXT, exp->internal_name);
2132	}
2133
2134      if (a_list)
2135	{
2136	  fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
2137	  for (dl = a_list; dl; dl = dl->next)
2138	    {
2139	      fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
2140	    }
2141	}
2142
2143      if (d_list)
2144	{
2145	  fprintf (f, "\t.section .rdata\n");
2146	  for (dl = d_list; dl; dl = dl->next)
2147	    {
2148	      char *p;
2149	      int l;
2150
2151	      /* We don't output as ascii because there can
2152	         be quote characters in the string.  */
2153	      l = 0;
2154	      for (p = dl->text; *p; p++)
2155		{
2156		  if (l == 0)
2157		    fprintf (f, "\t%s\t", ASM_BYTE);
2158		  else
2159		    fprintf (f, ",");
2160		  fprintf (f, "%d", *p);
2161		  if (p[1] == 0)
2162		    {
2163		      fprintf (f, ",0\n");
2164		      break;
2165		    }
2166		  if (++l == 10)
2167		    {
2168		      fprintf (f, "\n");
2169		      l = 0;
2170		    }
2171		}
2172	    }
2173	}
2174    }
2175
2176  /* Add to the output file a way of getting to the exported names
2177     without using the import library.  */
2178  if (add_indirect)
2179    {
2180      fprintf (f, "\t.section\t.rdata\n");
2181      for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2182	if (!exp->noname || show_allnames)
2183	  {
2184	    /* We use a single underscore for MS compatibility, and a
2185               double underscore for backward compatibility with old
2186               cygwin releases.  */
2187	    if (create_compat_implib)
2188	      fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2189	    fprintf (f, "\t%s\t_imp_%s%s\n", ASM_GLOBAL,
2190	    	     (!leading_underscore ? "" : "_"), exp->name);
2191	    if (create_compat_implib)
2192	      fprintf (f, "__imp_%s:\n", exp->name);
2193	    fprintf (f, "_imp_%s%s:\n", (!leading_underscore ? "" : "_"), exp->name);
2194	    fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
2195	  }
2196    }
2197
2198  /* Dump the reloc section if a base file is provided.  */
2199  if (base_file)
2200    {
2201      bfd_vma addr;
2202      bfd_vma need[COFF_PAGE_SIZE];
2203      bfd_vma page_addr;
2204      bfd_size_type numbytes;
2205      int num_entries;
2206      bfd_vma *copy;
2207      int j;
2208      int on_page;
2209      fprintf (f, "\t.section\t.init\n");
2210      fprintf (f, "lab:\n");
2211
2212      fseek (base_file, 0, SEEK_END);
2213      numbytes = ftell (base_file);
2214      fseek (base_file, 0, SEEK_SET);
2215      copy = xmalloc (numbytes);
2216      if (fread (copy, 1, numbytes, base_file) < numbytes)
2217	fatal (_("failed to read the number of entries from base file"));
2218      num_entries = numbytes / sizeof (bfd_vma);
2219
2220
2221      fprintf (f, "\t.section\t.reloc\n");
2222      if (num_entries)
2223	{
2224	  int src;
2225	  int dst = 0;
2226	  bfd_vma last = (bfd_vma) -1;
2227	  qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
2228	  /* Delete duplicates */
2229	  for (src = 0; src < num_entries; src++)
2230	    {
2231	      if (last != copy[src])
2232		last = copy[dst++] = copy[src];
2233	    }
2234	  num_entries = dst;
2235	  addr = copy[0];
2236	  page_addr = addr & PAGE_MASK;		/* work out the page addr */
2237	  on_page = 0;
2238	  for (j = 0; j < num_entries; j++)
2239	    {
2240	      addr = copy[j];
2241	      if ((addr & PAGE_MASK) != page_addr)
2242		{
2243		  flush_page (f, need, page_addr, on_page);
2244		  on_page = 0;
2245		  page_addr = addr & PAGE_MASK;
2246		}
2247	      need[on_page++] = addr;
2248	    }
2249	  flush_page (f, need, page_addr, on_page);
2250
2251/*	  fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2252	}
2253    }
2254
2255  generate_idata_ofile (f);
2256
2257  fclose (f);
2258
2259  /* Assemble the file.  */
2260  assemble_file (TMP_ASM, exp_name);
2261
2262  if (dontdeltemps == 0)
2263    {
2264      temp_file_to_remove[TEMP_EXPORT_FILE] = NULL;
2265      unlink (TMP_ASM);
2266    }
2267
2268  inform (_("Generated exports file"));
2269}
2270
2271static const char *
2272xlate (const char *name)
2273{
2274  int lead_at = (*name == '@');
2275  int is_stdcall = (!lead_at && strchr (name, '@') != NULL);
2276
2277  if (!lead_at && (add_underscore
2278		   || (add_stdcall_underscore && is_stdcall)))
2279    {
2280      char *copy = xmalloc (strlen (name) + 2);
2281
2282      copy[0] = '_';
2283      strcpy (copy + 1, name);
2284      name = copy;
2285    }
2286
2287  if (killat)
2288    {
2289      char *p;
2290
2291      name += lead_at;
2292      /* PR 9766: Look for the last @ sign in the name.  */
2293      p = strrchr (name, '@');
2294      if (p && ISDIGIT (p[1]))
2295	*p = 0;
2296    }
2297  return name;
2298}
2299
2300typedef struct
2301{
2302  int id;
2303  const char *name;
2304  int flags;
2305  int align;
2306  asection *sec;
2307  asymbol *sym;
2308  asymbol **sympp;
2309  int size;
2310  unsigned char *data;
2311} sinfo;
2312
2313#define INIT_SEC_DATA(id, name, flags, align) \
2314        { id, name, flags, align, NULL, NULL, NULL, 0, NULL }
2315
2316#ifndef DLLTOOL_PPC
2317
2318#define TEXT 0
2319#define DATA 1
2320#define BSS 2
2321#define IDATA7 3
2322#define IDATA5 4
2323#define IDATA4 5
2324#define IDATA6 6
2325
2326#define NSECS 7
2327
2328#define TEXT_SEC_FLAGS   \
2329        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS)
2330#define DATA_SEC_FLAGS   (SEC_ALLOC | SEC_LOAD | SEC_DATA)
2331#define BSS_SEC_FLAGS     SEC_ALLOC
2332
2333static sinfo secdata[NSECS] =
2334{
2335  INIT_SEC_DATA (TEXT,   ".text",    TEXT_SEC_FLAGS,   2),
2336  INIT_SEC_DATA (DATA,   ".data",    DATA_SEC_FLAGS,   2),
2337  INIT_SEC_DATA (BSS,    ".bss",     BSS_SEC_FLAGS,    2),
2338  INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2),
2339  INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2),
2340  INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
2341  INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1)
2342};
2343
2344#else
2345
2346/* Sections numbered to make the order the same as other PowerPC NT
2347   compilers. This also keeps funny alignment thingies from happening.  */
2348#define TEXT   0
2349#define PDATA  1
2350#define RDATA  2
2351#define IDATA5 3
2352#define IDATA4 4
2353#define IDATA6 5
2354#define IDATA7 6
2355#define DATA   7
2356#define BSS    8
2357
2358#define NSECS 9
2359
2360static sinfo secdata[NSECS] =
2361{
2362  INIT_SEC_DATA (TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 3),
2363  INIT_SEC_DATA (PDATA,  ".pdata",   SEC_HAS_CONTENTS,            2),
2364  INIT_SEC_DATA (RDATA,  ".reldata", SEC_HAS_CONTENTS,            2),
2365  INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2),
2366  INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2),
2367  INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1),
2368  INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2),
2369  INIT_SEC_DATA (DATA,   ".data",    SEC_DATA,                    2),
2370  INIT_SEC_DATA (BSS,    ".bss",     0,                           2)
2371};
2372
2373#endif
2374
2375/* This is what we're trying to make.  We generate the imp symbols with
2376   both single and double underscores, for compatibility.
2377
2378	.text
2379	.global	_GetFileVersionInfoSizeW@8
2380	.global	__imp_GetFileVersionInfoSizeW@8
2381_GetFileVersionInfoSizeW@8:
2382	jmp *	__imp_GetFileVersionInfoSizeW@8
2383	.section	.idata$7	# To force loading of head
2384	.long	__version_a_head
2385# Import Address Table
2386	.section	.idata$5
2387__imp_GetFileVersionInfoSizeW@8:
2388	.rva	ID2
2389
2390# Import Lookup Table
2391	.section	.idata$4
2392	.rva	ID2
2393# Hint/Name table
2394	.section	.idata$6
2395ID2:	.short	2
2396	.asciz	"GetFileVersionInfoSizeW"
2397
2398
2399   For the PowerPC, here's the variation on the above scheme:
2400
2401# Rather than a simple "jmp *", the code to get to the dll function
2402# looks like:
2403         .text
2404         lwz	r11,[tocv]__imp_function_name(r2)
2405#		   RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
2406         lwz	r12,0(r11)
2407	 stw	r2,4(r1)
2408	 mtctr	r12
2409	 lwz	r2,4(r11)
2410	 bctr  */
2411
2412static char *
2413make_label (const char *prefix, const char *name)
2414{
2415  int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2416  char *copy = xmalloc (len + 1);
2417
2418  strcpy (copy, ASM_PREFIX (name));
2419  strcat (copy, prefix);
2420  strcat (copy, name);
2421  return copy;
2422}
2423
2424static char *
2425make_imp_label (const char *prefix, const char *name)
2426{
2427  int len;
2428  char *copy;
2429
2430  if (name[0] == '@')
2431    {
2432      len = strlen (prefix) + strlen (name);
2433      copy = xmalloc (len + 1);
2434      strcpy (copy, prefix);
2435      strcat (copy, name);
2436    }
2437  else
2438    {
2439      len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2440      copy = xmalloc (len + 1);
2441      strcpy (copy, prefix);
2442      strcat (copy, ASM_PREFIX (name));
2443      strcat (copy, name);
2444    }
2445  return copy;
2446}
2447
2448static bfd *
2449make_one_lib_file (export_type *exp, int i, int delay)
2450{
2451  bfd *      abfd;
2452  asymbol *  exp_label;
2453  asymbol *  iname = 0;
2454  asymbol *  iname2;
2455  asymbol *  iname_lab;
2456  asymbol ** iname_lab_pp;
2457  asymbol ** iname_pp;
2458#ifdef DLLTOOL_PPC
2459  asymbol ** fn_pp;
2460  asymbol ** toc_pp;
2461#define EXTRA	 2
2462#endif
2463#ifndef EXTRA
2464#define EXTRA    0
2465#endif
2466  asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
2467  flagword   applicable;
2468  char *     outname = xmalloc (strlen (TMP_STUB) + 10);
2469  int        oidx = 0;
2470
2471
2472  sprintf (outname, "%s%05d.o", TMP_STUB, i);
2473
2474  abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2475
2476  if (!abfd)
2477    /* xgettext:c-format */
2478    fatal (_("bfd_open failed open stub file: %s: %s"),
2479	   outname, bfd_get_errmsg ());
2480
2481  /* xgettext:c-format */
2482  inform (_("Creating stub file: %s"), outname);
2483
2484  bfd_set_format (abfd, bfd_object);
2485  bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2486
2487#ifdef DLLTOOL_ARM
2488  if (machine == MARM_INTERWORK || machine == MTHUMB)
2489    bfd_set_private_flags (abfd, F_INTERWORK);
2490#endif
2491
2492  applicable = bfd_applicable_section_flags (abfd);
2493
2494  /* First make symbols for the sections.  */
2495  for (i = 0; i < NSECS; i++)
2496    {
2497      sinfo *si = secdata + i;
2498
2499      if (si->id != i)
2500	abort ();
2501      si->sec = bfd_make_section_old_way (abfd, si->name);
2502      bfd_set_section_flags (abfd,
2503			     si->sec,
2504			     si->flags & applicable);
2505
2506      bfd_set_section_alignment(abfd, si->sec, si->align);
2507      si->sec->output_section = si->sec;
2508      si->sym = bfd_make_empty_symbol(abfd);
2509      si->sym->name = si->sec->name;
2510      si->sym->section = si->sec;
2511      si->sym->flags = BSF_LOCAL;
2512      si->sym->value = 0;
2513      ptrs[oidx] = si->sym;
2514      si->sympp = ptrs + oidx;
2515      si->size = 0;
2516      si->data = NULL;
2517
2518      oidx++;
2519    }
2520
2521  if (! exp->data)
2522    {
2523      exp_label = bfd_make_empty_symbol (abfd);
2524      exp_label->name = make_imp_label ("", exp->name);
2525
2526      /* On PowerPC, the function name points to a descriptor in
2527	 the rdata section, the first element of which is a
2528	 pointer to the code (..function_name), and the second
2529	 points to the .toc.  */
2530#ifdef DLLTOOL_PPC
2531      if (machine == MPPC)
2532	exp_label->section = secdata[RDATA].sec;
2533      else
2534#endif
2535	exp_label->section = secdata[TEXT].sec;
2536
2537      exp_label->flags = BSF_GLOBAL;
2538      exp_label->value = 0;
2539
2540#ifdef DLLTOOL_ARM
2541      if (machine == MTHUMB)
2542	bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2543#endif
2544      ptrs[oidx++] = exp_label;
2545    }
2546
2547  /* Generate imp symbols with one underscore for Microsoft
2548     compatibility, and with two underscores for backward
2549     compatibility with old versions of cygwin.  */
2550  if (create_compat_implib)
2551    {
2552      iname = bfd_make_empty_symbol (abfd);
2553      iname->name = make_imp_label ("___imp", exp->name);
2554      iname->section = secdata[IDATA5].sec;
2555      iname->flags = BSF_GLOBAL;
2556      iname->value = 0;
2557    }
2558
2559  iname2 = bfd_make_empty_symbol (abfd);
2560  iname2->name = make_imp_label ("__imp_", exp->name);
2561  iname2->section = secdata[IDATA5].sec;
2562  iname2->flags = BSF_GLOBAL;
2563  iname2->value = 0;
2564
2565  iname_lab = bfd_make_empty_symbol (abfd);
2566
2567  iname_lab->name = head_label;
2568  iname_lab->section = bfd_und_section_ptr;
2569  iname_lab->flags = 0;
2570  iname_lab->value = 0;
2571
2572  iname_pp = ptrs + oidx;
2573  if (create_compat_implib)
2574    ptrs[oidx++] = iname;
2575  ptrs[oidx++] = iname2;
2576
2577  iname_lab_pp = ptrs + oidx;
2578  ptrs[oidx++] = iname_lab;
2579
2580#ifdef DLLTOOL_PPC
2581  /* The symbol referring to the code (.text).  */
2582  {
2583    asymbol *function_name;
2584
2585    function_name = bfd_make_empty_symbol(abfd);
2586    function_name->name = make_label ("..", exp->name);
2587    function_name->section = secdata[TEXT].sec;
2588    function_name->flags = BSF_GLOBAL;
2589    function_name->value = 0;
2590
2591    fn_pp = ptrs + oidx;
2592    ptrs[oidx++] = function_name;
2593  }
2594
2595  /* The .toc symbol.  */
2596  {
2597    asymbol *toc_symbol;
2598
2599    toc_symbol = bfd_make_empty_symbol (abfd);
2600    toc_symbol->name = make_label (".", "toc");
2601    toc_symbol->section = bfd_und_section_ptr;
2602    toc_symbol->flags = BSF_GLOBAL;
2603    toc_symbol->value = 0;
2604
2605    toc_pp = ptrs + oidx;
2606    ptrs[oidx++] = toc_symbol;
2607  }
2608#endif
2609
2610  ptrs[oidx] = 0;
2611
2612  for (i = 0; i < NSECS; i++)
2613    {
2614      sinfo *si = secdata + i;
2615      asection *sec = si->sec;
2616      arelent *rel, *rel2 = 0, *rel3 = 0;
2617      arelent **rpp;
2618
2619      switch (i)
2620	{
2621	case TEXT:
2622	  if (! exp->data)
2623	    {
2624	      si->size = HOW_JTAB_SIZE;
2625	      si->data = xmalloc (HOW_JTAB_SIZE);
2626	      memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2627
2628	      /* Add the reloc into idata$5.  */
2629	      rel = xmalloc (sizeof (arelent));
2630
2631	      rpp = xmalloc (sizeof (arelent *) * (delay ? 4 : 2));
2632	      rpp[0] = rel;
2633	      rpp[1] = 0;
2634
2635	      rel->address = HOW_JTAB_ROFF;
2636	      rel->addend = 0;
2637
2638	      if (delay)
2639	        {
2640	          rel2 = xmalloc (sizeof (arelent));
2641	          rpp[1] = rel2;
2642	          rel2->address = HOW_JTAB_ROFF2;
2643	          rel2->addend = 0;
2644	          rel3 = xmalloc (sizeof (arelent));
2645	          rpp[2] = rel3;
2646	          rel3->address = HOW_JTAB_ROFF3;
2647	          rel3->addend = 0;
2648	          rpp[3] = 0;
2649	        }
2650
2651	      if (machine == MPPC)
2652		{
2653		  rel->howto = bfd_reloc_type_lookup (abfd,
2654						      BFD_RELOC_16_GOTOFF);
2655		  rel->sym_ptr_ptr = iname_pp;
2656		}
2657	      else if (machine == MX86)
2658		{
2659		  rel->howto = bfd_reloc_type_lookup (abfd,
2660						      BFD_RELOC_32_PCREL);
2661		  rel->sym_ptr_ptr = iname_pp;
2662		}
2663	      else
2664		{
2665		  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2666		  rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2667		}
2668
2669	      if (delay)
2670	        {
2671		  if (machine == MX86)
2672		   rel2->howto = bfd_reloc_type_lookup (abfd,
2673							BFD_RELOC_32_PCREL);
2674	          else
2675	            rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2676	          rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
2677	          rel3->howto = bfd_reloc_type_lookup (abfd,
2678						       BFD_RELOC_32_PCREL);
2679	          rel3->sym_ptr_ptr = iname_lab_pp;
2680	        }
2681
2682	      sec->orelocation = rpp;
2683	      sec->reloc_count = delay ? 3 : 1;
2684	    }
2685	  break;
2686
2687	case IDATA5:
2688	  if (delay)
2689	    {
2690	      si->size = create_for_pep ? 8 : 4;
2691	      si->data = xmalloc (si->size);
2692	      sec->reloc_count = 1;
2693	      memset (si->data, 0, si->size);
2694	      /* Point after jmp [__imp_...] instruction.  */
2695	      si->data[0] = 6;
2696	      rel = xmalloc (sizeof (arelent));
2697	      rpp = xmalloc (sizeof (arelent *) * 2);
2698	      rpp[0] = rel;
2699	      rpp[1] = 0;
2700	      rel->address = 0;
2701	      rel->addend = 0;
2702	      if (create_for_pep)
2703	        rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64);
2704	      else
2705	        rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2706	      rel->sym_ptr_ptr = secdata[TEXT].sympp;
2707	      sec->orelocation = rpp;
2708	      break;
2709	    }
2710	  /* Fall through.  */
2711
2712	case IDATA4:
2713	  /* An idata$4 or idata$5 is one word long, and has an
2714	     rva to idata$6.  */
2715
2716	  if (create_for_pep)
2717	    {
2718	      si->data = xmalloc (8);
2719	      si->size = 8;
2720	      if (exp->noname)
2721	        {
2722		  si->data[0] = exp->ordinal ;
2723		  si->data[1] = exp->ordinal >> 8;
2724		  si->data[2] = exp->ordinal >> 16;
2725		  si->data[3] = exp->ordinal >> 24;
2726		  si->data[4] = 0;
2727		  si->data[5] = 0;
2728		  si->data[6] = 0;
2729		  si->data[7] = 0x80;
2730	        }
2731	      else
2732	        {
2733		  sec->reloc_count = 1;
2734		  memset (si->data, 0, si->size);
2735		  rel = xmalloc (sizeof (arelent));
2736		  rpp = xmalloc (sizeof (arelent *) * 2);
2737		  rpp[0] = rel;
2738		  rpp[1] = 0;
2739		  rel->address = 0;
2740		  rel->addend = 0;
2741		  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2742		  rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2743		  sec->orelocation = rpp;
2744	        }
2745	    }
2746	  else
2747	    {
2748	      si->data = xmalloc (4);
2749	      si->size = 4;
2750
2751	      if (exp->noname)
2752	        {
2753		  si->data[0] = exp->ordinal ;
2754		  si->data[1] = exp->ordinal >> 8;
2755		  si->data[2] = exp->ordinal >> 16;
2756		  si->data[3] = 0x80;
2757	        }
2758	      else
2759	        {
2760		  sec->reloc_count = 1;
2761		  memset (si->data, 0, si->size);
2762		  rel = xmalloc (sizeof (arelent));
2763		  rpp = xmalloc (sizeof (arelent *) * 2);
2764		  rpp[0] = rel;
2765		  rpp[1] = 0;
2766		  rel->address = 0;
2767		  rel->addend = 0;
2768		  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2769		  rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2770		  sec->orelocation = rpp;
2771	      }
2772	    }
2773	  break;
2774
2775	case IDATA6:
2776	  if (!exp->noname)
2777	    {
2778	      int idx = exp->ordinal;
2779
2780	      if (exp->its_name)
2781	        si->size = strlen (exp->its_name) + 3;
2782	      else
2783	        si->size = strlen (xlate (exp->import_name)) + 3;
2784	      si->data = xmalloc (si->size);
2785	      memset (si->data, 0, si->size);
2786	      si->data[0] = idx & 0xff;
2787	      si->data[1] = idx >> 8;
2788	      if (exp->its_name)
2789		strcpy ((char *) si->data + 2, exp->its_name);
2790	      else
2791		strcpy ((char *) si->data + 2, xlate (exp->import_name));
2792	    }
2793	  break;
2794	case IDATA7:
2795	  if (delay)
2796	    break;
2797	  si->size = 4;
2798	  si->data = xmalloc (4);
2799	  memset (si->data, 0, si->size);
2800	  rel = xmalloc (sizeof (arelent));
2801	  rpp = xmalloc (sizeof (arelent *) * 2);
2802	  rpp[0] = rel;
2803	  rel->address = 0;
2804	  rel->addend = 0;
2805	  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2806	  rel->sym_ptr_ptr = iname_lab_pp;
2807	  sec->orelocation = rpp;
2808	  sec->reloc_count = 1;
2809	  break;
2810
2811#ifdef DLLTOOL_PPC
2812	case PDATA:
2813	  {
2814	    /* The .pdata section is 5 words long.
2815	       Think of it as:
2816	       struct
2817	       {
2818	       bfd_vma BeginAddress,     [0x00]
2819	       EndAddress,       [0x04]
2820	       ExceptionHandler, [0x08]
2821	       HandlerData,      [0x0c]
2822	       PrologEndAddress; [0x10]
2823	       };  */
2824
2825	    /* So this pdata section setups up this as a glue linkage to
2826	       a dll routine. There are a number of house keeping things
2827	       we need to do:
2828
2829	       1. In the name of glue trickery, the ADDR32 relocs for 0,
2830	       4, and 0x10 are set to point to the same place:
2831	       "..function_name".
2832	       2. There is one more reloc needed in the pdata section.
2833	       The actual glue instruction to restore the toc on
2834	       return is saved as the offset in an IMGLUE reloc.
2835	       So we need a total of four relocs for this section.
2836
2837	       3. Lastly, the HandlerData field is set to 0x03, to indicate
2838	       that this is a glue routine.  */
2839	    arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2840
2841	    /* Alignment must be set to 2**2 or you get extra stuff.  */
2842	    bfd_set_section_alignment(abfd, sec, 2);
2843
2844	    si->size = 4 * 5;
2845	    si->data = xmalloc (si->size);
2846	    memset (si->data, 0, si->size);
2847	    rpp = xmalloc (sizeof (arelent *) * 5);
2848	    rpp[0] = imglue  = xmalloc (sizeof (arelent));
2849	    rpp[1] = ba_rel  = xmalloc (sizeof (arelent));
2850	    rpp[2] = ea_rel  = xmalloc (sizeof (arelent));
2851	    rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2852	    rpp[4] = 0;
2853
2854	    /* Stick the toc reload instruction in the glue reloc.  */
2855	    bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2856
2857	    imglue->addend = 0;
2858	    imglue->howto = bfd_reloc_type_lookup (abfd,
2859						   BFD_RELOC_32_GOTOFF);
2860	    imglue->sym_ptr_ptr = fn_pp;
2861
2862	    ba_rel->address = 0;
2863	    ba_rel->addend = 0;
2864	    ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2865	    ba_rel->sym_ptr_ptr = fn_pp;
2866
2867	    bfd_put_32 (abfd, 0x18, si->data + 0x04);
2868	    ea_rel->address = 4;
2869	    ea_rel->addend = 0;
2870	    ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2871	    ea_rel->sym_ptr_ptr = fn_pp;
2872
2873	    /* Mark it as glue.  */
2874	    bfd_put_32 (abfd, 0x03, si->data + 0x0c);
2875
2876	    /* Mark the prolog end address.  */
2877	    bfd_put_32 (abfd, 0x0D, si->data + 0x10);
2878	    pea_rel->address = 0x10;
2879	    pea_rel->addend = 0;
2880	    pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2881	    pea_rel->sym_ptr_ptr = fn_pp;
2882
2883	    sec->orelocation = rpp;
2884	    sec->reloc_count = 4;
2885	    break;
2886	  }
2887	case RDATA:
2888	  /* Each external function in a PowerPC PE file has a two word
2889	     descriptor consisting of:
2890	     1. The address of the code.
2891	     2. The address of the appropriate .toc
2892	     We use relocs to build this.  */
2893	  si->size = 8;
2894	  si->data = xmalloc (8);
2895	  memset (si->data, 0, si->size);
2896
2897	  rpp = xmalloc (sizeof (arelent *) * 3);
2898	  rpp[0] = rel = xmalloc (sizeof (arelent));
2899	  rpp[1] = xmalloc (sizeof (arelent));
2900	  rpp[2] = 0;
2901
2902	  rel->address = 0;
2903	  rel->addend = 0;
2904	  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2905	  rel->sym_ptr_ptr = fn_pp;
2906
2907	  rel = rpp[1];
2908
2909	  rel->address = 4;
2910	  rel->addend = 0;
2911	  rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2912	  rel->sym_ptr_ptr = toc_pp;
2913
2914	  sec->orelocation = rpp;
2915	  sec->reloc_count = 2;
2916	  break;
2917#endif /* DLLTOOL_PPC */
2918	}
2919    }
2920
2921  {
2922    bfd_vma vma = 0;
2923    /* Size up all the sections.  */
2924    for (i = 0; i < NSECS; i++)
2925      {
2926	sinfo *si = secdata + i;
2927
2928	bfd_set_section_size (abfd, si->sec, si->size);
2929	bfd_set_section_vma (abfd, si->sec, vma);
2930      }
2931  }
2932  /* Write them out.  */
2933  for (i = 0; i < NSECS; i++)
2934    {
2935      sinfo *si = secdata + i;
2936
2937      if (i == IDATA5 && no_idata5)
2938	continue;
2939
2940      if (i == IDATA4 && no_idata4)
2941	continue;
2942
2943      bfd_set_section_contents (abfd, si->sec,
2944				si->data, 0,
2945				si->size);
2946    }
2947
2948  bfd_set_symtab (abfd, ptrs, oidx);
2949  bfd_close (abfd);
2950  abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2951  if (!abfd)
2952    /* xgettext:c-format */
2953    fatal (_("bfd_open failed reopen stub file: %s: %s"),
2954	   outname, bfd_get_errmsg ());
2955
2956  return abfd;
2957}
2958
2959static bfd *
2960make_head (void)
2961{
2962  FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2963  bfd *abfd;
2964
2965  if (f == NULL)
2966    {
2967      fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2968      return NULL;
2969    }
2970
2971  temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
2972
2973  fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2974  fprintf (f, "\t.section\t.idata$2\n");
2975
2976  fprintf (f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
2977
2978  fprintf (f, "%s:\n", head_label);
2979
2980  fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2981	   ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2982
2983  fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2984  fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2985  fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2986  fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2987  fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2988	   ASM_RVA_BEFORE,
2989	   imp_name_lab,
2990	   ASM_RVA_AFTER,
2991	   ASM_C);
2992  fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2993	   ASM_RVA_BEFORE,
2994	   ASM_RVA_AFTER, ASM_C);
2995
2996  fprintf (f, "%sStuff for compatibility\n", ASM_C);
2997
2998  if (!no_idata5)
2999    {
3000      fprintf (f, "\t.section\t.idata$5\n");
3001      if (use_nul_prefixed_import_tables)
3002        {
3003	  if (create_for_pep)
3004	    fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3005	  else
3006	    fprintf (f,"\t%s\t0\n", ASM_LONG);
3007        }
3008      fprintf (f, "fthunk:\n");
3009    }
3010
3011  if (!no_idata4)
3012    {
3013      fprintf (f, "\t.section\t.idata$4\n");
3014      if (use_nul_prefixed_import_tables)
3015        {
3016	  if (create_for_pep)
3017	    fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3018	  else
3019	    fprintf (f,"\t%s\t0\n", ASM_LONG);
3020        }
3021      fprintf (f, "hname:\n");
3022    }
3023
3024  fclose (f);
3025
3026  assemble_file (TMP_HEAD_S, TMP_HEAD_O);
3027
3028  abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
3029  if (abfd == NULL)
3030    /* xgettext:c-format */
3031    fatal (_("failed to open temporary head file: %s: %s"),
3032	   TMP_HEAD_O, bfd_get_errmsg ());
3033
3034  temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
3035  return abfd;
3036}
3037
3038bfd *
3039make_delay_head (void)
3040{
3041  FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
3042  bfd *abfd;
3043
3044  if (f == NULL)
3045    {
3046      fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
3047      return NULL;
3048    }
3049
3050  temp_file_to_remove[TEMP_HEAD_FILE] = TMP_HEAD_S;
3051
3052  /* Output the __tailMerge__xxx function */
3053  fprintf (f, "%s Import trampoline\n", ASM_C);
3054  fprintf (f, "\t.section\t.text\n");
3055  fprintf(f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
3056  fprintf (f, "%s:\n", head_label);
3057  fprintf (f, mtable[machine].trampoline, imp_name_lab);
3058
3059  /* Output the delay import descriptor */
3060  fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
3061  fprintf (f, ".section\t.text$2\n");
3062  fprintf (f,"%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
3063  fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
3064  fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
3065  fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n",
3066	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
3067  fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
3068	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
3069  fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n",
3070	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
3071  fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n",
3072	   ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
3073  fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C);
3074  fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C);
3075  fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C);
3076
3077  /* Output the dll_handle */
3078  fprintf (f, "\n.section .data\n");
3079  fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
3080  fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
3081  if (create_for_pep)
3082    fprintf (f, "\t%s\t0\n", ASM_LONG);
3083  fprintf (f, "\n");
3084
3085  fprintf (f, "%sStuff for compatibility\n", ASM_C);
3086
3087  if (!no_idata5)
3088    {
3089      fprintf (f, "\t.section\t.idata$5\n");
3090      /* NULL terminating list.  */
3091      if (create_for_pep)
3092        fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3093      else
3094        fprintf (f,"\t%s\t0\n", ASM_LONG);
3095      fprintf (f, "__IAT_%s:\n", imp_name_lab);
3096    }
3097
3098  if (!no_idata4)
3099    {
3100      fprintf (f, "\t.section\t.idata$4\n");
3101      fprintf (f, "\t%s\t0\n", ASM_LONG);
3102      if (create_for_pep)
3103        fprintf (f, "\t%s\t0\n", ASM_LONG);
3104      fprintf (f, "\t.section\t.idata$4\n");
3105      fprintf (f, "__INT_%s:\n", imp_name_lab);
3106    }
3107
3108  fprintf (f, "\t.section\t.idata$2\n");
3109
3110  fclose (f);
3111
3112  assemble_file (TMP_HEAD_S, TMP_HEAD_O);
3113
3114  abfd = bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
3115  if (abfd == NULL)
3116    /* xgettext:c-format */
3117    fatal (_("failed to open temporary head file: %s: %s"),
3118	   TMP_HEAD_O, bfd_get_errmsg ());
3119
3120  temp_file_to_remove[TEMP_HEAD_O_FILE] = TMP_HEAD_O;
3121  return abfd;
3122}
3123
3124static bfd *
3125make_tail (void)
3126{
3127  FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
3128  bfd *abfd;
3129
3130  if (f == NULL)
3131    {
3132      fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
3133      return NULL;
3134    }
3135
3136  temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S;
3137
3138  if (!no_idata4)
3139    {
3140      fprintf (f, "\t.section\t.idata$4\n");
3141      if (create_for_pep)
3142	fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3143      else
3144	fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
3145    }
3146
3147  if (!no_idata5)
3148    {
3149      fprintf (f, "\t.section\t.idata$5\n");
3150      if (create_for_pep)
3151	fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
3152      else
3153	fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list.  */
3154    }
3155
3156#ifdef DLLTOOL_PPC
3157  /* Normally, we need to see a null descriptor built in idata$3 to
3158     act as the terminator for the list. The ideal way, I suppose,
3159     would be to mark this section as a comdat type 2 section, so
3160     only one would appear in the final .exe (if our linker supported
3161     comdat, that is) or cause it to be inserted by something else (say
3162     crt0).  */
3163
3164  fprintf (f, "\t.section\t.idata$3\n");
3165  fprintf (f, "\t%s\t0\n", ASM_LONG);
3166  fprintf (f, "\t%s\t0\n", ASM_LONG);
3167  fprintf (f, "\t%s\t0\n", ASM_LONG);
3168  fprintf (f, "\t%s\t0\n", ASM_LONG);
3169  fprintf (f, "\t%s\t0\n", ASM_LONG);
3170#endif
3171
3172#ifdef DLLTOOL_PPC
3173  /* Other PowerPC NT compilers use idata$6 for the dllname, so I
3174     do too. Original, huh?  */
3175  fprintf (f, "\t.section\t.idata$6\n");
3176#else
3177  fprintf (f, "\t.section\t.idata$7\n");
3178#endif
3179
3180  fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
3181  fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
3182	   imp_name_lab, ASM_TEXT, dll_name);
3183
3184  fclose (f);
3185
3186  assemble_file (TMP_TAIL_S, TMP_TAIL_O);
3187
3188  abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
3189  if (abfd == NULL)
3190    /* xgettext:c-format */
3191    fatal (_("failed to open temporary tail file: %s: %s"),
3192	   TMP_TAIL_O, bfd_get_errmsg ());
3193
3194  temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O;
3195  return abfd;
3196}
3197
3198static void
3199gen_lib_file (int delay)
3200{
3201  int i;
3202  export_type *exp;
3203  bfd *ar_head;
3204  bfd *ar_tail;
3205  bfd *outarch;
3206  bfd * head  = 0;
3207
3208  unlink (imp_name);
3209
3210  outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
3211
3212  if (!outarch)
3213    /* xgettext:c-format */
3214    fatal (_("Can't create .lib file: %s: %s"),
3215	   imp_name, bfd_get_errmsg ());
3216
3217  /* xgettext:c-format */
3218  inform (_("Creating library file: %s"), imp_name);
3219
3220  xatexit (unlink_temp_files);
3221
3222  bfd_set_format (outarch, bfd_archive);
3223  outarch->has_armap = 1;
3224  outarch->is_thin_archive = 0;
3225
3226  /* Work out a reasonable size of things to put onto one line.  */
3227  if (delay)
3228    {
3229      ar_head = make_delay_head ();
3230    }
3231  else
3232    {
3233      ar_head = make_head ();
3234    }
3235  ar_tail = make_tail();
3236
3237  if (ar_head == NULL || ar_tail == NULL)
3238    return;
3239
3240  for (i = 0; (exp = d_exports_lexically[i]); i++)
3241    {
3242      bfd *n;
3243      /* Don't add PRIVATE entries to import lib.  */
3244      if (exp->private)
3245	continue;
3246      n = make_one_lib_file (exp, i, delay);
3247      n->archive_next = head;
3248      head = n;
3249      if (ext_prefix_alias)
3250	{
3251	  export_type alias_exp;
3252
3253	  assert (i < PREFIX_ALIAS_BASE);
3254	  alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
3255	  alias_exp.internal_name = exp->internal_name;
3256	  alias_exp.its_name = exp->its_name;
3257	  alias_exp.import_name = exp->name;
3258	  alias_exp.ordinal = exp->ordinal;
3259	  alias_exp.constant = exp->constant;
3260	  alias_exp.noname = exp->noname;
3261	  alias_exp.private = exp->private;
3262	  alias_exp.data = exp->data;
3263	  alias_exp.forward = exp->forward;
3264	  alias_exp.next = exp->next;
3265	  n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay);
3266	  n->archive_next = head;
3267	  head = n;
3268	}
3269    }
3270
3271  /* Now stick them all into the archive.  */
3272  ar_head->archive_next = head;
3273  ar_tail->archive_next = ar_head;
3274  head = ar_tail;
3275
3276  if (! bfd_set_archive_head (outarch, head))
3277    bfd_fatal ("bfd_set_archive_head");
3278
3279  if (! bfd_close (outarch))
3280    bfd_fatal (imp_name);
3281
3282  while (head != NULL)
3283    {
3284      bfd *n = head->archive_next;
3285      bfd_close (head);
3286      head = n;
3287    }
3288
3289  /* Delete all the temp files.  */
3290  unlink_temp_files ();
3291
3292  if (dontdeltemps < 2)
3293    {
3294      char *name;
3295
3296      name = xmalloc (strlen (TMP_STUB) + 10);
3297      for (i = 0; (exp = d_exports_lexically[i]); i++)
3298	{
3299	  /* Don't delete non-existent stubs for PRIVATE entries.  */
3300          if (exp->private)
3301	    continue;
3302	  sprintf (name, "%s%05d.o", TMP_STUB, i);
3303	  if (unlink (name) < 0)
3304	    /* xgettext:c-format */
3305	    non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3306	  if (ext_prefix_alias)
3307	    {
3308	      sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
3309	      if (unlink (name) < 0)
3310		/* xgettext:c-format */
3311		non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
3312	    }
3313	}
3314      free (name);
3315    }
3316
3317  inform (_("Created lib file"));
3318}
3319
3320/* Append a copy of data (cast to char *) to list.  */
3321
3322static void
3323dll_name_list_append (dll_name_list_type * list, bfd_byte * data)
3324{
3325  dll_name_list_node_type * entry;
3326
3327  /* Error checking.  */
3328  if (! list || ! list->tail)
3329    return;
3330
3331  /* Allocate new node.  */
3332  entry = ((dll_name_list_node_type *)
3333	   xmalloc (sizeof (dll_name_list_node_type)));
3334
3335  /* Initialize its values.  */
3336  entry->dllname = xstrdup ((char *) data);
3337  entry->next = NULL;
3338
3339  /* Add to tail, and move tail.  */
3340  list->tail->next = entry;
3341  list->tail = entry;
3342}
3343
3344/* Count the number of entries in list.  */
3345
3346static int
3347dll_name_list_count (dll_name_list_type * list)
3348{
3349  dll_name_list_node_type * p;
3350  int count = 0;
3351
3352  /* Error checking.  */
3353  if (! list || ! list->head)
3354    return 0;
3355
3356  p = list->head;
3357
3358  while (p && p->next)
3359    {
3360      count++;
3361      p = p->next;
3362    }
3363  return count;
3364}
3365
3366/* Print each entry in list to stdout.  */
3367
3368static void
3369dll_name_list_print (dll_name_list_type * list)
3370{
3371  dll_name_list_node_type * p;
3372
3373  /* Error checking.  */
3374  if (! list || ! list->head)
3375    return;
3376
3377  p = list->head;
3378
3379  while (p && p->next && p->next->dllname && *(p->next->dllname))
3380    {
3381      printf ("%s\n", p->next->dllname);
3382      p = p->next;
3383    }
3384}
3385
3386/* Free all entries in list, and list itself.  */
3387
3388static void
3389dll_name_list_free (dll_name_list_type * list)
3390{
3391  if (list)
3392    {
3393      dll_name_list_free_contents (list->head);
3394      list->head = NULL;
3395      list->tail = NULL;
3396      free (list);
3397    }
3398}
3399
3400/* Recursive function to free all nodes entry->next->next...
3401   as well as entry itself.  */
3402
3403static void
3404dll_name_list_free_contents (dll_name_list_node_type * entry)
3405{
3406  if (entry)
3407    {
3408      if (entry->next)
3409        {
3410          dll_name_list_free_contents (entry->next);
3411          entry->next = NULL;
3412        }
3413      if (entry->dllname)
3414        {
3415          free (entry->dllname);
3416          entry->dllname = NULL;
3417        }
3418      free (entry);
3419    }
3420}
3421
3422/* Allocate and initialize a dll_name_list_type object,
3423   including its sentinel node.  Caller is responsible
3424   for calling dll_name_list_free when finished with
3425   the list.  */
3426
3427static dll_name_list_type *
3428dll_name_list_create (void)
3429{
3430  /* Allocate list.  */
3431  dll_name_list_type * list = xmalloc (sizeof (dll_name_list_type));
3432
3433  /* Allocate and initialize sentinel node.  */
3434  list->head = xmalloc (sizeof (dll_name_list_node_type));
3435  list->head->dllname = NULL;
3436  list->head->next = NULL;
3437
3438  /* Bookkeeping for empty list.  */
3439  list->tail = list->head;
3440
3441  return list;
3442}
3443
3444/* Search the symbol table of the suppled BFD for a symbol whose name matches
3445   OBJ (where obj is cast to const char *).  If found, set global variable
3446   identify_member_contains_symname_result TRUE.  It is the caller's
3447   responsibility to set the result variable FALSE before iterating with
3448   this function.  */
3449
3450static void
3451identify_member_contains_symname (bfd  * abfd,
3452				  bfd  * archive_bfd ATTRIBUTE_UNUSED,
3453				  void * obj)
3454{
3455  long storage_needed;
3456  asymbol ** symbol_table;
3457  long number_of_symbols;
3458  long i;
3459  symname_search_data_type * search_data = (symname_search_data_type *) obj;
3460
3461  /* If we already found the symbol in a different member,
3462     short circuit.  */
3463  if (search_data->found)
3464    return;
3465
3466  storage_needed = bfd_get_symtab_upper_bound (abfd);
3467  if (storage_needed <= 0)
3468    return;
3469
3470  symbol_table = xmalloc (storage_needed);
3471  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
3472  if (number_of_symbols < 0)
3473    {
3474      free (symbol_table);
3475      return;
3476    }
3477
3478  for (i = 0; i < number_of_symbols; i++)
3479    {
3480      if (strncmp (symbol_table[i]->name,
3481                   search_data->symname,
3482                   strlen (search_data->symname)) == 0)
3483	{
3484	  search_data->found = TRUE;
3485	  break;
3486	}
3487    }
3488  free (symbol_table);
3489}
3490
3491/* This is the main implementation for the --identify option.
3492   Given the name of an import library in identify_imp_name, first determine
3493   if the import library is a GNU binutils-style one (where the DLL name is
3494   stored in an .idata$7 (.idata$6 on PPC) section, or if it is a MS-style
3495   one (where the DLL name, along with much other data, is stored in the
3496   .idata$6 section). We determine the style of import library by searching
3497   for the DLL-structure symbol inserted by MS tools:
3498   __NULL_IMPORT_DESCRIPTOR.
3499
3500   Once we know which section to search, evaluate each section for the
3501   appropriate properties that indicate it may contain the name of the
3502   associated DLL (this differs depending on the style).  Add the contents
3503   of all sections which meet the criteria to a linked list of dll names.
3504
3505   Finally, print them all to stdout. (If --identify-strict, an error is
3506   reported if more than one match was found).  */
3507
3508static void
3509identify_dll_for_implib (void)
3510{
3511  bfd * abfd = NULL;
3512  int count = 0;
3513  identify_data_type identify_data;
3514  symname_search_data_type search_data;
3515
3516  /* Initialize identify_data.  */
3517  identify_data.list = dll_name_list_create ();
3518  identify_data.ms_style_implib = FALSE;
3519
3520  /* Initialize search_data.  */
3521  search_data.symname = "__NULL_IMPORT_DESCRIPTOR";
3522  search_data.found = FALSE;
3523
3524  bfd_init ();
3525
3526  abfd = bfd_openr (identify_imp_name, 0);
3527  if (abfd == NULL)
3528    /* xgettext:c-format */
3529    fatal (_("Can't open .lib file: %s: %s"),
3530	   identify_imp_name, bfd_get_errmsg ());
3531
3532  if (! bfd_check_format (abfd, bfd_archive))
3533    {
3534      if (! bfd_close (abfd))
3535        bfd_fatal (identify_imp_name);
3536
3537      fatal (_("%s is not a library"), identify_imp_name);
3538    }
3539
3540  /* Detect if this a Microsoft import library.  */
3541  identify_search_archive (abfd,
3542			   identify_member_contains_symname,
3543			   (void *)(& search_data));
3544  if (search_data.found)
3545    identify_data.ms_style_implib = TRUE;
3546
3547  /* Rewind the bfd.  */
3548  if (! bfd_close (abfd))
3549    bfd_fatal (identify_imp_name);
3550  abfd = bfd_openr (identify_imp_name, 0);
3551  if (abfd == NULL)
3552    bfd_fatal (identify_imp_name);
3553
3554  if (!bfd_check_format (abfd, bfd_archive))
3555    {
3556      if (!bfd_close (abfd))
3557        bfd_fatal (identify_imp_name);
3558
3559      fatal (_("%s is not a library"), identify_imp_name);
3560    }
3561
3562  /* Now search for the dll name.  */
3563  identify_search_archive (abfd,
3564			   identify_search_member,
3565			   (void *)(& identify_data));
3566
3567  if (! bfd_close (abfd))
3568    bfd_fatal (identify_imp_name);
3569
3570  count = dll_name_list_count (identify_data.list);
3571  if (count > 0)
3572    {
3573      if (identify_strict && count > 1)
3574        {
3575          dll_name_list_free (identify_data.list);
3576          identify_data.list = NULL;
3577          fatal (_("Import library `%s' specifies two or more dlls"),
3578		 identify_imp_name);
3579        }
3580      dll_name_list_print (identify_data.list);
3581      dll_name_list_free (identify_data.list);
3582      identify_data.list = NULL;
3583    }
3584  else
3585    {
3586      dll_name_list_free (identify_data.list);
3587      identify_data.list = NULL;
3588      fatal (_("Unable to determine dll name for `%s' (not an import library?)"),
3589	     identify_imp_name);
3590    }
3591}
3592
3593/* Loop over all members of the archive, applying the supplied function to
3594   each member that is a bfd_object.  The function will be called as if:
3595      func (member_bfd, abfd, user_storage)  */
3596
3597static void
3598identify_search_archive (bfd * abfd,
3599			 void (* operation) (bfd *, bfd *, void *),
3600			 void * user_storage)
3601{
3602  bfd *   arfile = NULL;
3603  bfd *   last_arfile = NULL;
3604  char ** matching;
3605
3606  while (1)
3607    {
3608      arfile = bfd_openr_next_archived_file (abfd, arfile);
3609
3610      if (arfile == NULL)
3611        {
3612          if (bfd_get_error () != bfd_error_no_more_archived_files)
3613            bfd_fatal (bfd_get_filename (abfd));
3614          break;
3615        }
3616
3617      if (bfd_check_format_matches (arfile, bfd_object, &matching))
3618	(*operation) (arfile, abfd, user_storage);
3619      else
3620        {
3621          bfd_nonfatal (bfd_get_filename (arfile));
3622          free (matching);
3623        }
3624
3625      if (last_arfile != NULL)
3626	{
3627	  bfd_close (last_arfile);
3628	  /* PR 17512: file: 8b2168d4.  */
3629	  if (last_arfile == arfile)
3630	    {
3631	      last_arfile = NULL;
3632	      break;
3633	    }
3634	}
3635
3636      last_arfile = arfile;
3637    }
3638
3639  if (last_arfile != NULL)
3640    {
3641      bfd_close (last_arfile);
3642    }
3643}
3644
3645/* Call the identify_search_section() function for each section of this
3646   archive member.  */
3647
3648static void
3649identify_search_member (bfd  *abfd,
3650			bfd  *archive_bfd ATTRIBUTE_UNUSED,
3651			void *obj)
3652{
3653  bfd_map_over_sections (abfd, identify_search_section, obj);
3654}
3655
3656/* This predicate returns true if section->name matches the desired value.
3657   By default, this is .idata$7 (.idata$6 on PPC, or if the import
3658   library is ms-style).  */
3659
3660static bfd_boolean
3661identify_process_section_p (asection * section, bfd_boolean ms_style_implib)
3662{
3663  static const char * SECTION_NAME =
3664#ifdef DLLTOOL_PPC
3665  /* dllname is stored in idata$6 on PPC */
3666  ".idata$6";
3667#else
3668  ".idata$7";
3669#endif
3670  static const char * MS_SECTION_NAME = ".idata$6";
3671
3672  const char * section_name =
3673    (ms_style_implib ? MS_SECTION_NAME : SECTION_NAME);
3674
3675  if (strcmp (section_name, section->name) == 0)
3676    return TRUE;
3677  return FALSE;
3678}
3679
3680/* If *section has contents and its name is .idata$7 (.data$6 on PPC or if
3681   import lib ms-generated) -- and it satisfies several other constraints
3682   -- then add the contents of the section to obj->list.  */
3683
3684static void
3685identify_search_section (bfd * abfd, asection * section, void * obj)
3686{
3687  bfd_byte *data = 0;
3688  bfd_size_type datasize;
3689  identify_data_type * identify_data = (identify_data_type *)obj;
3690  bfd_boolean ms_style = identify_data->ms_style_implib;
3691
3692  if ((section->flags & SEC_HAS_CONTENTS) == 0)
3693    return;
3694
3695  if (! identify_process_section_p (section, ms_style))
3696    return;
3697
3698  /* Binutils import libs seem distinguish the .idata$7 section that contains
3699     the DLL name from other .idata$7 sections by the absence of the
3700     SEC_RELOC flag.  */
3701  if (!ms_style && ((section->flags & SEC_RELOC) == SEC_RELOC))
3702    return;
3703
3704  /* MS import libs seem to distinguish the .idata$6 section
3705     that contains the DLL name from other .idata$6 sections
3706     by the presence of the SEC_DATA flag.  */
3707  if (ms_style && ((section->flags & SEC_DATA) == 0))
3708    return;
3709
3710  if ((datasize = bfd_section_size (abfd, section)) == 0)
3711    return;
3712
3713  data = (bfd_byte *) xmalloc (datasize + 1);
3714  data[0] = '\0';
3715
3716  bfd_get_section_contents (abfd, section, data, 0, datasize);
3717  data[datasize] = '\0';
3718
3719  /* Use a heuristic to determine if data is a dll name.
3720     Possible to defeat this if (a) the library has MANY
3721     (more than 0x302f) imports, (b) it is an ms-style
3722     import library, but (c) it is buggy, in that the SEC_DATA
3723     flag is set on the "wrong" sections.  This heuristic might
3724     also fail to record a valid dll name if the dllname uses
3725     a multibyte or unicode character set (is that valid?).
3726
3727     This heuristic is based on the fact that symbols names in
3728     the chosen section -- as opposed to the dll name -- begin
3729     at offset 2 in the data. The first two bytes are a 16bit
3730     little-endian count, and start at 0x0000. However, the dll
3731     name begins at offset 0 in the data. We assume that the
3732     dll name does not contain unprintable characters.   */
3733  if (data[0] != '\0' && ISPRINT (data[0])
3734      && ((datasize < 2) || ISPRINT (data[1])))
3735    dll_name_list_append (identify_data->list, data);
3736
3737  free (data);
3738}
3739
3740/* Run through the information gathered from the .o files and the
3741   .def file and work out the best stuff.  */
3742
3743static int
3744pfunc (const void *a, const void *b)
3745{
3746  export_type *ap = *(export_type **) a;
3747  export_type *bp = *(export_type **) b;
3748
3749  if (ap->ordinal == bp->ordinal)
3750    return 0;
3751
3752  /* Unset ordinals go to the bottom.  */
3753  if (ap->ordinal == -1)
3754    return 1;
3755  if (bp->ordinal == -1)
3756    return -1;
3757  return (ap->ordinal - bp->ordinal);
3758}
3759
3760static int
3761nfunc (const void *a, const void *b)
3762{
3763  export_type *ap = *(export_type **) a;
3764  export_type *bp = *(export_type **) b;
3765  const char *an = ap->name;
3766  const char *bn = bp->name;
3767  if (ap->its_name)
3768    an = ap->its_name;
3769  if (bp->its_name)
3770    an = bp->its_name;
3771  if (killat)
3772    {
3773      an = (an[0] == '@') ? an + 1 : an;
3774      bn = (bn[0] == '@') ? bn + 1 : bn;
3775    }
3776
3777  return (strcmp (an, bn));
3778}
3779
3780static void
3781remove_null_names (export_type **ptr)
3782{
3783  int src;
3784  int dst;
3785
3786  for (dst = src = 0; src < d_nfuncs; src++)
3787    {
3788      if (ptr[src])
3789	{
3790	  ptr[dst] = ptr[src];
3791	  dst++;
3792	}
3793    }
3794  d_nfuncs = dst;
3795}
3796
3797static void
3798process_duplicates (export_type **d_export_vec)
3799{
3800  int more = 1;
3801  int i;
3802
3803  while (more)
3804    {
3805      more = 0;
3806      /* Remove duplicates.  */
3807      qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3808
3809      for (i = 0; i < d_nfuncs - 1; i++)
3810	{
3811	  if (strcmp (d_export_vec[i]->name,
3812		      d_export_vec[i + 1]->name) == 0)
3813	    {
3814	      export_type *a = d_export_vec[i];
3815	      export_type *b = d_export_vec[i + 1];
3816
3817	      more = 1;
3818
3819	      /* xgettext:c-format */
3820	      inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3821		      a->name, a->ordinal, b->ordinal);
3822
3823	      if (a->ordinal != -1
3824		  && b->ordinal != -1)
3825		/* xgettext:c-format */
3826		fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3827		      a->name);
3828
3829	      /* Merge attributes.  */
3830	      b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
3831	      b->constant |= a->constant;
3832	      b->noname |= a->noname;
3833	      b->data |= a->data;
3834	      d_export_vec[i] = 0;
3835	    }
3836
3837	  remove_null_names (d_export_vec);
3838	}
3839    }
3840
3841  /* Count the names.  */
3842  for (i = 0; i < d_nfuncs; i++)
3843    if (!d_export_vec[i]->noname)
3844      d_named_nfuncs++;
3845}
3846
3847static void
3848fill_ordinals (export_type **d_export_vec)
3849{
3850  int lowest = -1;
3851  int i;
3852  char *ptr;
3853  int size = 65536;
3854
3855  qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3856
3857  /* Fill in the unset ordinals with ones from our range.  */
3858  ptr = (char *) xmalloc (size);
3859
3860  memset (ptr, 0, size);
3861
3862  /* Mark in our large vector all the numbers that are taken.  */
3863  for (i = 0; i < d_nfuncs; i++)
3864    {
3865      if (d_export_vec[i]->ordinal != -1)
3866	{
3867	  ptr[d_export_vec[i]->ordinal] = 1;
3868
3869	  if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
3870	    lowest = d_export_vec[i]->ordinal;
3871	}
3872    }
3873
3874  /* Start at 1 for compatibility with MS toolchain.  */
3875  if (lowest == -1)
3876    lowest = 1;
3877
3878  /* Now fill in ordinals where the user wants us to choose.  */
3879  for (i = 0; i < d_nfuncs; i++)
3880    {
3881      if (d_export_vec[i]->ordinal == -1)
3882	{
3883	  int j;
3884
3885	  /* First try within or after any user supplied range.  */
3886	  for (j = lowest; j < size; j++)
3887	    if (ptr[j] == 0)
3888	      {
3889		ptr[j] = 1;
3890		d_export_vec[i]->ordinal = j;
3891		goto done;
3892	      }
3893
3894	  /* Then try before the range.  */
3895	  for (j = lowest; j >0; j--)
3896	    if (ptr[j] == 0)
3897	      {
3898		ptr[j] = 1;
3899		d_export_vec[i]->ordinal = j;
3900		goto done;
3901	      }
3902	done:;
3903	}
3904    }
3905
3906  free (ptr);
3907
3908  /* And resort.  */
3909  qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
3910
3911  /* Work out the lowest and highest ordinal numbers.  */
3912  if (d_nfuncs)
3913    {
3914      if (d_export_vec[0])
3915	d_low_ord = d_export_vec[0]->ordinal;
3916      if (d_export_vec[d_nfuncs-1])
3917	d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
3918    }
3919}
3920
3921static void
3922mangle_defs (void)
3923{
3924  /* First work out the minimum ordinal chosen.  */
3925  export_type *exp;
3926  export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
3927  int i;
3928
3929  inform (_("Processing definitions"));
3930
3931  for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3932    d_export_vec[i] = exp;
3933
3934  process_duplicates (d_export_vec);
3935  fill_ordinals (d_export_vec);
3936
3937  /* Put back the list in the new order.  */
3938  d_exports = 0;
3939  for (i = d_nfuncs - 1; i >= 0; i--)
3940    {
3941      d_export_vec[i]->next = d_exports;
3942      d_exports = d_export_vec[i];
3943    }
3944
3945  /* Build list in alpha order.  */
3946  d_exports_lexically = (export_type **)
3947    xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
3948
3949  for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3950    d_exports_lexically[i] = exp;
3951
3952  d_exports_lexically[i] = 0;
3953
3954  qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
3955
3956  inform (_("Processed definitions"));
3957}
3958
3959static void
3960usage (FILE *file, int status)
3961{
3962  /* xgetext:c-format */
3963  fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
3964  /* xgetext:c-format */
3965  fprintf (file, _("   -m --machine <machine>    Create as DLL for <machine>.  [default: %s]\n"), mname);
3966  fprintf (file, _("        possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
3967  fprintf (file, _("   -e --output-exp <outname> Generate an export file.\n"));
3968  fprintf (file, _("   -l --output-lib <outname> Generate an interface library.\n"));
3969  fprintf (file, _("   -y --output-delaylib <outname> Create a delay-import library.\n"));
3970  fprintf (file, _("   -a --add-indirect         Add dll indirects to export file.\n"));
3971  fprintf (file, _("   -D --dllname <name>       Name of input dll to put into interface lib.\n"));
3972  fprintf (file, _("   -d --input-def <deffile>  Name of .def file to be read in.\n"));
3973  fprintf (file, _("   -z --output-def <deffile> Name of .def file to be created.\n"));
3974  fprintf (file, _("      --export-all-symbols   Export all symbols to .def\n"));
3975  fprintf (file, _("      --no-export-all-symbols  Only export listed symbols\n"));
3976  fprintf (file, _("      --exclude-symbols <list> Don't export <list>\n"));
3977  fprintf (file, _("      --no-default-excludes  Clear default exclude symbols\n"));
3978  fprintf (file, _("   -b --base-file <basefile> Read linker generated base file.\n"));
3979  fprintf (file, _("   -x --no-idata4            Don't generate idata$4 section.\n"));
3980  fprintf (file, _("   -c --no-idata5            Don't generate idata$5 section.\n"));
3981  fprintf (file, _("      --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
3982  fprintf (file, _("   -U --add-underscore       Add underscores to all symbols in interface library.\n"));
3983  fprintf (file, _("      --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n"));
3984  fprintf (file, _("      --no-leading-underscore All symbols shouldn't be prefixed by an underscore.\n"));
3985  fprintf (file, _("      --leading-underscore   All symbols should be prefixed by an underscore.\n"));
3986  fprintf (file, _("   -k --kill-at              Kill @<n> from exported names.\n"));
3987  fprintf (file, _("   -A --add-stdcall-alias    Add aliases without @<n>.\n"));
3988  fprintf (file, _("   -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3989  fprintf (file, _("   -S --as <name>            Use <name> for assembler.\n"));
3990  fprintf (file, _("   -f --as-flags <flags>     Pass <flags> to the assembler.\n"));
3991  fprintf (file, _("   -C --compat-implib        Create backward compatible import library.\n"));
3992  fprintf (file, _("   -n --no-delete            Keep temp files (repeat for extra preservation).\n"));
3993  fprintf (file, _("   -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3994  fprintf (file, _("   -I --identify <implib>    Report the name of the DLL associated with <implib>.\n"));
3995  fprintf (file, _("      --identify-strict      Causes --identify to report error when multiple DLLs.\n"));
3996  fprintf (file, _("   -v --verbose              Be verbose.\n"));
3997  fprintf (file, _("   -V --version              Display the program version.\n"));
3998  fprintf (file, _("   -h --help                 Display this information.\n"));
3999  fprintf (file, _("   @<file>                   Read options from <file>.\n"));
4000#ifdef DLLTOOL_MCORE_ELF
4001  fprintf (file, _("   -M --mcore-elf <outname>  Process mcore-elf object files into <outname>.\n"));
4002  fprintf (file, _("   -L --linker <name>        Use <name> as the linker.\n"));
4003  fprintf (file, _("   -F --linker-flags <flags> Pass <flags> to the linker.\n"));
4004#endif
4005  if (REPORT_BUGS_TO[0] && status == 0)
4006    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
4007  exit (status);
4008}
4009
4010#define OPTION_EXPORT_ALL_SYMS		150
4011#define OPTION_NO_EXPORT_ALL_SYMS	(OPTION_EXPORT_ALL_SYMS + 1)
4012#define OPTION_EXCLUDE_SYMS		(OPTION_NO_EXPORT_ALL_SYMS + 1)
4013#define OPTION_NO_DEFAULT_EXCLUDES	(OPTION_EXCLUDE_SYMS + 1)
4014#define OPTION_ADD_STDCALL_UNDERSCORE	(OPTION_NO_DEFAULT_EXCLUDES + 1)
4015#define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \
4016  (OPTION_ADD_STDCALL_UNDERSCORE + 1)
4017#define OPTION_IDENTIFY_STRICT		(OPTION_USE_NUL_PREFIXED_IMPORT_TABLES + 1)
4018#define OPTION_NO_LEADING_UNDERSCORE	(OPTION_IDENTIFY_STRICT + 1)
4019#define OPTION_LEADING_UNDERSCORE	(OPTION_NO_LEADING_UNDERSCORE + 1)
4020
4021static const struct option long_options[] =
4022{
4023  {"no-delete", no_argument, NULL, 'n'},
4024  {"dllname", required_argument, NULL, 'D'},
4025  {"no-idata4", no_argument, NULL, 'x'},
4026  {"no-idata5", no_argument, NULL, 'c'},
4027  {"use-nul-prefixed-import-tables", no_argument, NULL,
4028   OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
4029  {"output-exp", required_argument, NULL, 'e'},
4030  {"output-def", required_argument, NULL, 'z'},
4031  {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
4032  {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
4033  {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
4034  {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
4035  {"output-lib", required_argument, NULL, 'l'},
4036  {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
4037  {"input-def", required_argument, NULL, 'd'},
4038  {"add-underscore", no_argument, NULL, 'U'},
4039  {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
4040  {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
4041  {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
4042  {"kill-at", no_argument, NULL, 'k'},
4043  {"add-stdcall-alias", no_argument, NULL, 'A'},
4044  {"ext-prefix-alias", required_argument, NULL, 'p'},
4045  {"identify", required_argument, NULL, 'I'},
4046  {"identify-strict", no_argument, NULL, OPTION_IDENTIFY_STRICT},
4047  {"verbose", no_argument, NULL, 'v'},
4048  {"version", no_argument, NULL, 'V'},
4049  {"help", no_argument, NULL, 'h'},
4050  {"machine", required_argument, NULL, 'm'},
4051  {"add-indirect", no_argument, NULL, 'a'},
4052  {"base-file", required_argument, NULL, 'b'},
4053  {"as", required_argument, NULL, 'S'},
4054  {"as-flags", required_argument, NULL, 'f'},
4055  {"mcore-elf", required_argument, NULL, 'M'},
4056  {"compat-implib", no_argument, NULL, 'C'},
4057  {"temp-prefix", required_argument, NULL, 't'},
4058  {"output-delaylib", required_argument, NULL, 'y'},
4059  {NULL,0,NULL,0}
4060};
4061
4062int main (int, char **);
4063
4064int
4065main (int ac, char **av)
4066{
4067  int c;
4068  int i;
4069  char *firstarg = 0;
4070  program_name = av[0];
4071  oav = av;
4072
4073#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
4074  setlocale (LC_MESSAGES, "");
4075#endif
4076#if defined (HAVE_SETLOCALE)
4077  setlocale (LC_CTYPE, "");
4078#endif
4079  bindtextdomain (PACKAGE, LOCALEDIR);
4080  textdomain (PACKAGE);
4081
4082  bfd_set_error_program_name (program_name);
4083  expandargv (&ac, &av);
4084
4085  while ((c = getopt_long (ac, av,
4086#ifdef DLLTOOL_MCORE_ELF
4087                           "m:e:l:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHhM:L:F:",
4088#else
4089                           "m:e:l:y:aD:d:z:b:xp:cCuUkAS:t:f:nI:vVHh",
4090#endif
4091			   long_options, 0))
4092	 != EOF)
4093    {
4094      switch (c)
4095	{
4096	case OPTION_EXPORT_ALL_SYMS:
4097	  export_all_symbols = TRUE;
4098	  break;
4099	case OPTION_NO_EXPORT_ALL_SYMS:
4100	  export_all_symbols = FALSE;
4101	  break;
4102	case OPTION_EXCLUDE_SYMS:
4103	  add_excludes (optarg);
4104	  break;
4105	case OPTION_NO_DEFAULT_EXCLUDES:
4106	  do_default_excludes = FALSE;
4107	  break;
4108	case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
4109	  use_nul_prefixed_import_tables = TRUE;
4110	  break;
4111	case OPTION_ADD_STDCALL_UNDERSCORE:
4112	  add_stdcall_underscore = 1;
4113	  break;
4114	case OPTION_NO_LEADING_UNDERSCORE:
4115	  leading_underscore = 0;
4116	  break;
4117	case OPTION_LEADING_UNDERSCORE:
4118	  leading_underscore = 1;
4119	  break;
4120	case OPTION_IDENTIFY_STRICT:
4121	  identify_strict = 1;
4122	  break;
4123	case 'x':
4124	  no_idata4 = 1;
4125	  break;
4126	case 'c':
4127	  no_idata5 = 1;
4128	  break;
4129	case 'S':
4130	  as_name = optarg;
4131	  break;
4132	case 't':
4133	  tmp_prefix = optarg;
4134	  break;
4135	case 'f':
4136	  as_flags = optarg;
4137	  break;
4138
4139	  /* Ignored for compatibility.  */
4140	case 'u':
4141	  break;
4142	case 'a':
4143	  add_indirect = 1;
4144	  break;
4145	case 'z':
4146	  output_def = fopen (optarg, FOPEN_WT);
4147	  if (!output_def)
4148	    /* xgettext:c-format */
4149	    fatal (_("Unable to open def-file: %s"), optarg);
4150	  break;
4151	case 'D':
4152	  dll_name = (char*) lbasename (optarg);
4153	  if (dll_name != optarg)
4154	    non_fatal (_("Path components stripped from dllname, '%s'."),
4155	      		 optarg);
4156	  break;
4157	case 'l':
4158	  imp_name = optarg;
4159	  break;
4160	case 'e':
4161	  exp_name = optarg;
4162	  break;
4163	case 'H':
4164	case 'h':
4165	  usage (stdout, 0);
4166	  break;
4167	case 'm':
4168	  mname = optarg;
4169	  break;
4170	case 'I':
4171	  identify_imp_name = optarg;
4172	  break;
4173	case 'v':
4174	  verbose = 1;
4175	  break;
4176	case 'V':
4177	  print_version (program_name);
4178	  break;
4179	case 'U':
4180	  add_underscore = 1;
4181	  break;
4182	case 'k':
4183	  killat = 1;
4184	  break;
4185	case 'A':
4186	  add_stdcall_alias = 1;
4187	  break;
4188	case 'p':
4189	  ext_prefix_alias = optarg;
4190	  break;
4191	case 'd':
4192	  def_file = optarg;
4193	  break;
4194	case 'n':
4195	  dontdeltemps++;
4196	  break;
4197	case 'b':
4198	  base_file = fopen (optarg, FOPEN_RB);
4199
4200	  if (!base_file)
4201	    /* xgettext:c-format */
4202	    fatal (_("Unable to open base-file: %s"), optarg);
4203
4204	  break;
4205#ifdef DLLTOOL_MCORE_ELF
4206	case 'M':
4207	  mcore_elf_out_file = optarg;
4208	  break;
4209	case 'L':
4210	  mcore_elf_linker = optarg;
4211	  break;
4212	case 'F':
4213	  mcore_elf_linker_flags = optarg;
4214	  break;
4215#endif
4216	case 'C':
4217	  create_compat_implib = 1;
4218	  break;
4219	case 'y':
4220	  delayimp_name = optarg;
4221	  break;
4222	default:
4223	  usage (stderr, 1);
4224	  break;
4225	}
4226    }
4227
4228  if (!tmp_prefix)
4229    tmp_prefix = prefix_encode ("d", getpid ());
4230
4231  for (i = 0; mtable[i].type; i++)
4232    if (strcmp (mtable[i].type, mname) == 0)
4233      break;
4234
4235  if (!mtable[i].type)
4236    /* xgettext:c-format */
4237    fatal (_("Machine '%s' not supported"), mname);
4238
4239  machine = i;
4240
4241  /* Check if we generated PE+.  */
4242  create_for_pep = strcmp (mname, "i386:x86-64") == 0;
4243
4244  {
4245    /* Check the default underscore */
4246    int u = leading_underscore; /* Underscoring mode. -1 for use default.  */
4247    if (u == -1)
4248      bfd_get_target_info (mtable[machine].how_bfd_target, NULL,
4249                           NULL, &u, NULL);
4250    if (u != -1)
4251      leading_underscore = (u != 0 ? TRUE : FALSE);
4252  }
4253
4254  if (!dll_name && exp_name)
4255    {
4256      /* If we are inferring dll_name from exp_name,
4257         strip off any path components, without emitting
4258         a warning.  */
4259      const char* exp_basename = lbasename (exp_name);
4260      const int len = strlen (exp_basename) + 5;
4261      dll_name = xmalloc (len);
4262      strcpy (dll_name, exp_basename);
4263      strcat (dll_name, ".dll");
4264      dll_name_set_by_exp_name = 1;
4265    }
4266
4267  if (as_name == NULL)
4268    as_name = deduce_name ("as");
4269
4270  /* Don't use the default exclude list if we're reading only the
4271     symbols in the .drectve section.  The default excludes are meant
4272     to avoid exporting DLL entry point and Cygwin32 impure_ptr.  */
4273  if (! export_all_symbols)
4274    do_default_excludes = FALSE;
4275
4276  if (do_default_excludes)
4277    set_default_excludes ();
4278
4279  if (def_file)
4280    process_def_file (def_file);
4281
4282  while (optind < ac)
4283    {
4284      if (!firstarg)
4285	firstarg = av[optind];
4286      scan_obj_file (av[optind]);
4287      optind++;
4288    }
4289
4290  mangle_defs ();
4291
4292  if (exp_name)
4293    gen_exp_file ();
4294
4295  if (imp_name)
4296    {
4297      /* Make imp_name safe for use as a label.  */
4298      char *p;
4299
4300      imp_name_lab = xstrdup (imp_name);
4301      for (p = imp_name_lab; *p; p++)
4302	{
4303	  if (!ISALNUM (*p))
4304	    *p = '_';
4305	}
4306      head_label = make_label("_head_", imp_name_lab);
4307      gen_lib_file (0);
4308    }
4309
4310  if (delayimp_name)
4311    {
4312      /* Make delayimp_name safe for use as a label.  */
4313      char *p;
4314
4315      if (mtable[machine].how_dljtab == 0)
4316        {
4317          inform (_("Warning, machine type (%d) not supported for "
4318			"delayimport."), machine);
4319        }
4320      else
4321        {
4322          killat = 1;
4323          imp_name = delayimp_name;
4324          imp_name_lab = xstrdup (imp_name);
4325          for (p = imp_name_lab; *p; p++)
4326            {
4327              if (!ISALNUM (*p))
4328                *p = '_';
4329            }
4330          head_label = make_label("__tailMerge_", imp_name_lab);
4331          gen_lib_file (1);
4332        }
4333    }
4334
4335  if (output_def)
4336    gen_def_file ();
4337
4338  if (identify_imp_name)
4339    {
4340      identify_dll_for_implib ();
4341    }
4342
4343#ifdef DLLTOOL_MCORE_ELF
4344  if (mcore_elf_out_file)
4345    mcore_elf_gen_out_file ();
4346#endif
4347
4348  return 0;
4349}
4350
4351/* Look for the program formed by concatenating PROG_NAME and the
4352   string running from PREFIX to END_PREFIX.  If the concatenated
4353   string contains a '/', try appending EXECUTABLE_SUFFIX if it is
4354   appropriate.  */
4355
4356static char *
4357look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
4358{
4359  struct stat s;
4360  char *cmd;
4361
4362  cmd = xmalloc (strlen (prefix)
4363		 + strlen (prog_name)
4364#ifdef HAVE_EXECUTABLE_SUFFIX
4365		 + strlen (EXECUTABLE_SUFFIX)
4366#endif
4367		 + 10);
4368  strcpy (cmd, prefix);
4369
4370  sprintf (cmd + end_prefix, "%s", prog_name);
4371
4372  if (strchr (cmd, '/') != NULL)
4373    {
4374      int found;
4375
4376      found = (stat (cmd, &s) == 0
4377#ifdef HAVE_EXECUTABLE_SUFFIX
4378	       || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
4379#endif
4380	       );
4381
4382      if (! found)
4383	{
4384	  /* xgettext:c-format */
4385	  inform (_("Tried file: %s"), cmd);
4386	  free (cmd);
4387	  return NULL;
4388	}
4389    }
4390
4391  /* xgettext:c-format */
4392  inform (_("Using file: %s"), cmd);
4393
4394  return cmd;
4395}
4396
4397/* Deduce the name of the program we are want to invoke.
4398   PROG_NAME is the basic name of the program we want to run,
4399   eg "as" or "ld".  The catch is that we might want actually
4400   run "i386-pe-as" or "ppc-pe-ld".
4401
4402   If argv[0] contains the full path, then try to find the program
4403   in the same place, with and then without a target-like prefix.
4404
4405   Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
4406   deduce_name("as") uses the following search order:
4407
4408     /usr/local/bin/i586-cygwin32-as
4409     /usr/local/bin/as
4410     as
4411
4412   If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
4413   name, it'll try without and then with EXECUTABLE_SUFFIX.
4414
4415   Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
4416   as the fallback, but rather return i586-cygwin32-as.
4417
4418   Oh, and given, argv[0] = dlltool, it'll return "as".
4419
4420   Returns a dynamically allocated string.  */
4421
4422static char *
4423deduce_name (const char *prog_name)
4424{
4425  char *cmd;
4426  char *dash, *slash, *cp;
4427
4428  dash = NULL;
4429  slash = NULL;
4430  for (cp = program_name; *cp != '\0'; ++cp)
4431    {
4432      if (*cp == '-')
4433	dash = cp;
4434      if (
4435#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
4436	  *cp == ':' || *cp == '\\' ||
4437#endif
4438	  *cp == '/')
4439	{
4440	  slash = cp;
4441	  dash = NULL;
4442	}
4443    }
4444
4445  cmd = NULL;
4446
4447  if (dash != NULL)
4448    {
4449      /* First, try looking for a prefixed PROG_NAME in the
4450         PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME.  */
4451      cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
4452    }
4453
4454  if (slash != NULL && cmd == NULL)
4455    {
4456      /* Next, try looking for a PROG_NAME in the same directory as
4457         that of this program.  */
4458      cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
4459    }
4460
4461  if (cmd == NULL)
4462    {
4463      /* Just return PROG_NAME as is.  */
4464      cmd = xstrdup (prog_name);
4465    }
4466
4467  return cmd;
4468}
4469
4470#ifdef DLLTOOL_MCORE_ELF
4471typedef struct fname_cache
4472{
4473  const char *         filename;
4474  struct fname_cache * next;
4475}
4476fname_cache;
4477
4478static fname_cache fnames;
4479
4480static void
4481mcore_elf_cache_filename (const char * filename)
4482{
4483  fname_cache * ptr;
4484
4485  ptr = & fnames;
4486
4487  while (ptr->next != NULL)
4488    ptr = ptr->next;
4489
4490  ptr->filename = filename;
4491  ptr->next     = (fname_cache *) malloc (sizeof (fname_cache));
4492  if (ptr->next != NULL)
4493    ptr->next->next = NULL;
4494}
4495
4496#define MCORE_ELF_TMP_OBJ "mcoreelf.o"
4497#define MCORE_ELF_TMP_EXP "mcoreelf.exp"
4498#define MCORE_ELF_TMP_LIB "mcoreelf.lib"
4499
4500static void
4501mcore_elf_gen_out_file (void)
4502{
4503  fname_cache * ptr;
4504  dyn_string_t ds;
4505
4506  /* Step one.  Run 'ld -r' on the input object files in order to resolve
4507     any internal references and to generate a single .exports section.  */
4508  ptr = & fnames;
4509
4510  ds = dyn_string_new (100);
4511  dyn_string_append_cstr (ds, "-r ");
4512
4513  if (mcore_elf_linker_flags != NULL)
4514    dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4515
4516  while (ptr->next != NULL)
4517    {
4518      dyn_string_append_cstr (ds, ptr->filename);
4519      dyn_string_append_cstr (ds, " ");
4520
4521      ptr = ptr->next;
4522    }
4523
4524  dyn_string_append_cstr (ds, "-o ");
4525  dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4526
4527  if (mcore_elf_linker == NULL)
4528    mcore_elf_linker = deduce_name ("ld");
4529
4530  run (mcore_elf_linker, ds->s);
4531
4532  dyn_string_delete (ds);
4533
4534  /* Step two. Create a .exp file and a .lib file from the temporary file.
4535     Do this by recursively invoking dlltool...  */
4536  ds = dyn_string_new (100);
4537
4538  dyn_string_append_cstr (ds, "-S ");
4539  dyn_string_append_cstr (ds, as_name);
4540
4541  dyn_string_append_cstr (ds, " -e ");
4542  dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4543  dyn_string_append_cstr (ds, " -l ");
4544  dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB);
4545  dyn_string_append_cstr (ds, " " );
4546  dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4547
4548  if (verbose)
4549    dyn_string_append_cstr (ds, " -v");
4550
4551  if (dontdeltemps)
4552    {
4553      dyn_string_append_cstr (ds, " -n");
4554
4555      if (dontdeltemps > 1)
4556	dyn_string_append_cstr (ds, " -n");
4557    }
4558
4559  /* XXX - FIME: ought to check/copy other command line options as well.  */
4560  run (program_name, ds->s);
4561
4562  dyn_string_delete (ds);
4563
4564  /* Step four. Feed the .exp and object files to ld -shared to create the dll.  */
4565  ds = dyn_string_new (100);
4566
4567  dyn_string_append_cstr (ds, "-shared ");
4568
4569  if (mcore_elf_linker_flags)
4570    dyn_string_append_cstr (ds, mcore_elf_linker_flags);
4571
4572  dyn_string_append_cstr (ds, " ");
4573  dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP);
4574  dyn_string_append_cstr (ds, " ");
4575  dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
4576  dyn_string_append_cstr (ds, " -o ");
4577  dyn_string_append_cstr (ds, mcore_elf_out_file);
4578
4579  run (mcore_elf_linker, ds->s);
4580
4581  dyn_string_delete (ds);
4582
4583  if (dontdeltemps == 0)
4584    unlink (MCORE_ELF_TMP_EXP);
4585
4586  if (dontdeltemps < 2)
4587    unlink (MCORE_ELF_TMP_OBJ);
4588}
4589#endif /* DLLTOOL_MCORE_ELF */
4590