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