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