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