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