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