bfd/
[binutils-gdb.git] / binutils / dlltool.c
1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 3 of the License, or
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
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22
23 /* This program allows you to build the files necessary to create
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
50 EXPORTS ( ( ( <name1> [ = <name2> ] )
51 | ( <name1> = <module-name> . <external-name>))
52 [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
53 Declares name1 as an exported symbol from the
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>.
57
58 IMPORTS ( ( <internal-name> = <module-name> . <integer> )
59 | ( [ <internal-name> = ] <module-name> . <external-name> )) *
60 Declares that <external-name> or the exported function whose ordinal number
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
63 function will be refereed to in the body of the DLL.
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\"");
117
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
128 int printf (void)
129 {
130 return 9;
131 }
132
133 themain.c:
134 int main (void)
135 {
136 cdef ();
137 return 0;
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
150 # Compile up the parts of the dll and the program
151
152 gcc -c file1.c file2.c themain.c
153
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)
157
158 ar qcv thedll.in file1.o file2.o
159 ranlib thedll.in
160
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).
164
165 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
166
167 # Build the dll with the library and the export table
168
169 ld -o thedll.dll thedll.o thedll.in
170
171 # Link the executable with the import library
172
173 gcc -o themain.exe themain.o thedll.a
174
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.
182
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
187
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.
192
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
196
197 ld -o thedll.dll thedll.exp file1.o file2.o */
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
233 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
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
244 #define PAGE_SIZE ((bfd_vma) 4096)
245 #define PAGE_MASK ((bfd_vma) (-4096))
246 #include "sysdep.h"
247 #include "bfd.h"
248 #include "libiberty.h"
249 #include "getopt.h"
250 #include "demangle.h"
251 #include "dyn-string.h"
252 #include "bucomm.h"
253 #include "dlltool.h"
254 #include "safe-ctype.h"
255
256 #include <time.h>
257 #include <sys/stat.h>
258 #include <stdarg.h>
259 #include <assert.h>
260
261 #ifdef DLLTOOL_ARM
262 #include "coff/arm.h"
263 #include "coff/internal.h"
264 #endif
265 #ifdef DLLTOOL_MX86_64
266 #include "coff/x86_64.h"
267 #endif
268
269 /* Forward references. */
270 static char *look_for_prog (const char *, const char *, int);
271 static char *deduce_name (const char *);
272
273 #ifdef DLLTOOL_MCORE_ELF
274 static void mcore_elf_cache_filename (const char *);
275 static void mcore_elf_gen_out_file (void);
276 #endif
277
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
283 #define WIFEXITED(w) (((w) & 0377) == 0)
284 #endif
285 #ifndef WIFSIGNALED
286 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0)
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
325 typedef struct ifunct
326 {
327 char * name; /* Name of function being imported. */
328 int ord; /* Two-byte ordinal value associated with function. */
329 struct ifunct *next;
330 } ifunctype;
331
332 typedef struct iheadt
333 {
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. */
339 } iheadtype;
340
341 /* Structure containing all import information as defined in .def file
342 (qv "ihead structure"). */
343
344 static iheadtype *import_list = NULL;
345
346 static char *as_name = NULL;
347 static char * as_flags = "";
348
349 static char *tmp_prefix;
350
351 static int no_idata4;
352 static int no_idata5;
353 static char *exp_name;
354 static char *imp_name;
355 static char *identify_imp_name;
356 static char *identify_dll_name;
357 static char *head_label;
358 static char *imp_name_lab;
359 static char *dll_name;
360
361 static int add_indirect = 0;
362 static int add_underscore = 0;
363 static int add_stdcall_underscore = 0;
364 static int dontdeltemps = 0;
365
366 /* TRUE if we should export all symbols. Otherwise, we only export
367 symbols listed in .drectve sections or in the def file. */
368 static bfd_boolean export_all_symbols;
369
370 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when
371 exporting all symbols. */
372 static bfd_boolean do_default_excludes = TRUE;
373
374 static bfd_boolean use_nul_prefixed_import_tables = FALSE;
375
376 /* Default symbols to exclude when exporting all the symbols. */
377 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
378
379 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward
380 compatibility to old Cygwin releases. */
381 static bfd_boolean create_compat_implib;
382
383 static char *def_file;
384
385 extern char * program_name;
386
387 static int machine;
388 static int killat;
389 static int add_stdcall_alias;
390 static const char *ext_prefix_alias;
391 static int verbose;
392 static FILE *output_def;
393 static FILE *base_file;
394
395 #ifdef DLLTOOL_DEFAULT_ARM
396 static const char *mname = "arm";
397 #endif
398
399 #ifdef DLLTOOL_DEFAULT_ARM_EPOC
400 static const char *mname = "arm-epoc";
401 #endif
402
403 #ifdef DLLTOOL_DEFAULT_ARM_WINCE
404 static const char *mname = "arm-wince";
405 #endif
406
407 #ifdef DLLTOOL_DEFAULT_I386
408 static const char *mname = "i386";
409 #endif
410
411 #ifdef DLLTOOL_DEFAULT_MX86_64
412 static const char *mname = "i386:x86-64";
413 #endif
414
415 #ifdef DLLTOOL_DEFAULT_PPC
416 static const char *mname = "ppc";
417 #endif
418
419 #ifdef DLLTOOL_DEFAULT_SH
420 static const char *mname = "sh";
421 #endif
422
423 #ifdef DLLTOOL_DEFAULT_MIPS
424 static const char *mname = "mips";
425 #endif
426
427 #ifdef DLLTOOL_DEFAULT_MCORE
428 static const char * mname = "mcore-le";
429 #endif
430
431 #ifdef DLLTOOL_DEFAULT_MCORE_ELF
432 static const char * mname = "mcore-elf";
433 static char * mcore_elf_out_file = NULL;
434 static char * mcore_elf_linker = NULL;
435 static char * mcore_elf_linker_flags = NULL;
436
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
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
449
450 char *tmp_asm_buf;
451 char *tmp_head_s_buf;
452 char *tmp_head_o_buf;
453 char *tmp_tail_s_buf;
454 char *tmp_tail_o_buf;
455 char *tmp_stub_buf;
456
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")
463
464 /* This bit of assembly does jmp * .... */
465 static const unsigned char i386_jtab[] =
466 {
467 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
468 };
469
470 static const unsigned char arm_jtab[] =
471 {
472 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
473 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
474 0, 0, 0, 0
475 };
476
477 static 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 */
482 0, 0, 0, 0
483 };
484
485 static const unsigned char thumb_jtab[] =
486 {
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 */
493 0, 0, 0, 0
494 };
495
496 static const unsigned char mcore_be_jtab[] =
497 {
498 0x71, 0x02, /* lrw r1,2 */
499 0x81, 0x01, /* ld.w r1,(r1,0) */
500 0x00, 0xC1, /* jmp r1 */
501 0x12, 0x00, /* nop */
502 0x00, 0x00, 0x00, 0x00 /* <address> */
503 };
504
505 static const unsigned char mcore_le_jtab[] =
506 {
507 0x02, 0x71, /* lrw r1,2 */
508 0x01, 0x81, /* ld.w r1,(r1,0) */
509 0xC1, 0x00, /* jmp r1 */
510 0x00, 0x12, /* nop */
511 0x00, 0x00, 0x00, 0x00 /* <address> */
512 };
513
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. */
519 static 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
531 /* The glue instruction, picks up the toc from the stw in
532 the above code: "lwz r2,4(r1)". */
533 static bfd_vma ppc_glue_insn = 0x80410004;
534 #endif
535
536 struct 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;
549 const char *how_default_as_switches;
550 const char *how_bfd_target;
551 enum bfd_architecture how_bfd_arch;
552 const unsigned char *how_jtab;
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. */
555 };
556
557 static const struct mac
558 mtable[] =
559 {
560 {
561 #define MARM 0
562 "arm", ".byte", ".short", ".long", ".asciz", "@",
563 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
564 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
565 "pe-arm-little", bfd_arch_arm,
566 arm_jtab, sizeof (arm_jtab), 8
567 }
568 ,
569 {
570 #define M386 1
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
575 }
576 ,
577 {
578 #define MPPC 2
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
583 }
584 ,
585 {
586 #define MTHUMB 3
587 "thumb", ".byte", ".short", ".long", ".asciz", "@",
588 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
589 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
590 "pe-arm-little", bfd_arch_arm,
591 thumb_jtab, sizeof (thumb_jtab), 12
592 }
593 ,
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",
598 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
599 "pe-arm-little", bfd_arch_arm,
600 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
601 }
602 ,
603 {
604 #define MMCORE_BE 5
605 "mcore-be", ".byte", ".short", ".long", ".asciz", "//",
606 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
607 ".global", ".space", ".align\t2",".align\t4", "",
608 "pe-mcore-big", bfd_arch_mcore,
609 mcore_be_jtab, sizeof (mcore_be_jtab), 8
610 }
611 ,
612 {
613 #define MMCORE_LE 6
614 "mcore-le", ".byte", ".short", ".long", ".asciz", "//",
615 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
616 ".global", ".space", ".align\t2",".align\t4", "-EL",
617 "pe-mcore-little", bfd_arch_mcore,
618 mcore_le_jtab, sizeof (mcore_le_jtab), 8
619 }
620 ,
621 {
622 #define MMCORE_ELF 7
623 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//",
624 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
625 ".global", ".space", ".align\t2",".align\t4", "",
626 "elf32-mcore-big", bfd_arch_mcore,
627 mcore_be_jtab, sizeof (mcore_be_jtab), 8
628 }
629 ,
630 {
631 #define MMCORE_ELF_LE 8
632 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//",
633 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
634 ".global", ".space", ".align\t2",".align\t4", "-EL",
635 "elf32-mcore-little", bfd_arch_mcore,
636 mcore_le_jtab, sizeof (mcore_le_jtab), 8
637 }
638 ,
639 {
640 #define MARM_EPOC 9
641 "arm-epoc", ".byte", ".short", ".long", ".asciz", "@",
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 ,
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 ,
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 ,
665 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
666 };
667
668 typedef struct dlist
669 {
670 char *text;
671 struct dlist *next;
672 }
673 dlist_type;
674
675 typedef struct export
676 {
677 const char *name;
678 const char *internal_name;
679 const char *import_name;
680 int ordinal;
681 int constant;
682 int noname; /* Don't put name in image file. */
683 int private; /* Don't put reference in import lib. */
684 int data;
685 int hint;
686 int forward; /* Number of forward label, 0 means no forward. */
687 struct export *next;
688 }
689 export_type;
690
691 /* A list of symbols which we should not export. */
692
693 struct string_list
694 {
695 struct string_list *next;
696 char *string;
697 };
698
699 static struct string_list *excludes;
700
701 static const char *rvaafter (int);
702 static const char *rvabefore (int);
703 static const char *asm_prefix (int, const char *);
704 static void process_def_file (const char *);
705 static void new_directive (char *);
706 static void append_import (const char *, const char *, int);
707 static void run (const char *, char *);
708 static void scan_drectve_symbols (bfd *);
709 static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
710 static void add_excludes (const char *);
711 static bfd_boolean match_exclude (const char *);
712 static void set_default_excludes (void);
713 static long filter_symbols (bfd *, void *, long, unsigned int);
714 static void scan_all_symbols (bfd *);
715 static void scan_open_obj_file (bfd *);
716 static void scan_obj_file (const char *);
717 static void dump_def_info (FILE *);
718 static int sfunc (const void *, const void *);
719 static void flush_page (FILE *, bfd_vma *, bfd_vma, int);
720 static void gen_def_file (void);
721 static void generate_idata_ofile (FILE *);
722 static void assemble_file (const char *, const char *);
723 static void gen_exp_file (void);
724 static const char *xlate (const char *);
725 static char *make_label (const char *, const char *);
726 static char *make_imp_label (const char *, const char *);
727 static bfd *make_one_lib_file (export_type *, int);
728 static bfd *make_head (void);
729 static bfd *make_tail (void);
730 static void gen_lib_file (void);
731 static void identify_dll_for_implib (void);
732 static void identify_search_archive (bfd*);
733 static void identify_search_member (bfd*, bfd*);
734 static bfd_boolean identify_process_section_p (asection *);
735 static void identify_search_section (bfd *, asection *, void *);
736 static int pfunc (const void *, const void *);
737 static int nfunc (const void *, const void *);
738 static void remove_null_names (export_type **);
739 static void process_duplicates (export_type **);
740 static void fill_ordinals (export_type **);
741 static void mangle_defs (void);
742 static void usage (FILE *, int);
743 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
744 static void set_dll_name_from_def (const char *);
745
746 static char *
747 prefix_encode (char *start, unsigned code)
748 {
749 static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
750 static char buf[32];
751 char *p;
752 strcpy (buf, start);
753 p = strchr (buf, '\0');
754 do
755 *p++ = alpha[code % sizeof (alpha)];
756 while ((code /= sizeof (alpha)) != 0);
757 *p = '\0';
758 return buf;
759 }
760
761 static char *
762 dlltmp (char **buf, const char *fmt)
763 {
764 if (!*buf)
765 {
766 *buf = malloc (strlen (tmp_prefix) + 64);
767 sprintf (*buf, fmt, tmp_prefix);
768 }
769 return *buf;
770 }
771
772 static void
773 inform VPARAMS ((const char * message, ...))
774 {
775 VA_OPEN (args, message);
776 VA_FIXEDARG (args, const char *, message);
777
778 if (!verbose)
779 return;
780
781 report (message, args);
782
783 VA_CLOSE (args);
784 }
785
786 static const char *
787 rvaafter (int machine)
788 {
789 switch (machine)
790 {
791 case MARM:
792 case M386:
793 case MX86:
794 case MPPC:
795 case MTHUMB:
796 case MARM_INTERWORK:
797 case MMCORE_BE:
798 case MMCORE_LE:
799 case MMCORE_ELF:
800 case MMCORE_ELF_LE:
801 case MARM_EPOC:
802 case MARM_WINCE:
803 break;
804 default:
805 /* xgettext:c-format */
806 fatal (_("Internal error: Unknown machine type: %d"), machine);
807 break;
808 }
809 return "";
810 }
811
812 static const char *
813 rvabefore (int machine)
814 {
815 switch (machine)
816 {
817 case MARM:
818 case M386:
819 case MX86:
820 case MPPC:
821 case MTHUMB:
822 case MARM_INTERWORK:
823 case MMCORE_BE:
824 case MMCORE_LE:
825 case MMCORE_ELF:
826 case MMCORE_ELF_LE:
827 case MARM_EPOC:
828 case MARM_WINCE:
829 return ".rva\t";
830 default:
831 /* xgettext:c-format */
832 fatal (_("Internal error: Unknown machine type: %d"), machine);
833 break;
834 }
835 return "";
836 }
837
838 static const char *
839 asm_prefix (int machine, const char *name)
840 {
841 switch (machine)
842 {
843 case MARM:
844 case MPPC:
845 case MTHUMB:
846 case MARM_INTERWORK:
847 case MMCORE_BE:
848 case MMCORE_LE:
849 case MMCORE_ELF:
850 case MMCORE_ELF_LE:
851 case MARM_EPOC:
852 case MARM_WINCE:
853 break;
854 case M386:
855 case MX86:
856 /* Symbol names starting with ? do not have a leading underscore. */
857 if (name && *name == '?')
858 break;
859 else
860 return "_";
861 default:
862 /* xgettext:c-format */
863 fatal (_("Internal error: Unknown machine type: %d"), machine);
864 break;
865 }
866 return "";
867 }
868
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
889
890 static char **oav;
891
892 static void
893 process_def_file (const char *name)
894 {
895 FILE *f = fopen (name, FOPEN_RT);
896
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);
905
906 yyparse ();
907
908 inform (_("Processed def file"));
909 }
910
911 /**********************************************************************/
912
913 /* Communications with the parser. */
914
915 static int d_nfuncs; /* Number of functions exported. */
916 static int d_named_nfuncs; /* Number of named functions exported. */
917 static int d_low_ord; /* Lowest ordinal index. */
918 static int d_high_ord; /* Highest ordinal index. */
919 static export_type *d_exports; /* List of exported functions. */
920 static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */
921 static dlist_type *d_list; /* Descriptions. */
922 static dlist_type *a_list; /* Stuff to go in directives. */
923 static int d_nforwards = 0; /* Number of forwarded exports. */
924
925 static int d_is_dll;
926 static int d_is_exe;
927
928 int
929 yyerror (const char * err ATTRIBUTE_UNUSED)
930 {
931 /* xgettext:c-format */
932 non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
933
934 return 0;
935 }
936
937 void
938 def_exports (const char *name, const char *internal_name, int ordinal,
939 int noname, int constant, int data, int private)
940 {
941 struct export *p = (struct export *) xmalloc (sizeof (*p));
942
943 p->name = name;
944 p->internal_name = internal_name ? internal_name : name;
945 p->import_name = name;
946 p->ordinal = ordinal;
947 p->constant = constant;
948 p->noname = noname;
949 p->private = private;
950 p->data = data;
951 p->next = d_exports;
952 d_exports = p;
953 d_nfuncs++;
954
955 if ((internal_name != NULL)
956 && (strchr (internal_name, '.') != NULL))
957 p->forward = ++d_nforwards;
958 else
959 p->forward = 0; /* no forward */
960 }
961
962 static void
963 set_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
972 void
973 def_name (const char *name, int base)
974 {
975 /* xgettext:c-format */
976 inform (_("NAME: %s base: %x"), name, base);
977
978 if (d_is_dll)
979 non_fatal (_("Can't have LIBRARY and NAME"));
980
981 /* If --dllname not provided, use the one in the DEF file.
982 FIXME: Is this appropriate for executables? */
983 if (! dll_name)
984 set_dll_name_from_def (name);
985 d_is_exe = 1;
986 }
987
988 void
989 def_library (const char *name, int base)
990 {
991 /* xgettext:c-format */
992 inform (_("LIBRARY: %s base: %x"), name, base);
993
994 if (d_is_exe)
995 non_fatal (_("Can't have LIBRARY and NAME"));
996
997 /* If --dllname not provided, use the one in the DEF file. */
998 if (! dll_name)
999 set_dll_name_from_def (name);
1000 d_is_dll = 1;
1001 }
1002
1003 void
1004 def_description (const char *desc)
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
1012 static void
1013 new_directive (char *dir)
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
1021 void
1022 def_heapsize (int reserve, int commit)
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
1032 void
1033 def_stacksize (int reserve, int commit)
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
1046 static void
1047 append_import (const char *symbol_name, const char *dll_name, int func_ordinal)
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
1110 void
1111 def_import (const char *app_name, const char *module, const char *dllext,
1112 const char *entry, int ord_val)
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 }
1126
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
1137 void
1138 def_version (int major, int minor)
1139 {
1140 printf ("VERSION %d.%d\n", major, minor);
1141 }
1142
1143 void
1144 def_section (const char *name, int attr)
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
1163 void
1164 def_code (int attr)
1165 {
1166
1167 def_section ("CODE", attr);
1168 }
1169
1170 void
1171 def_data (int attr)
1172 {
1173 def_section ("DATA", attr);
1174 }
1175
1176 /**********************************************************************/
1177
1178 static void
1179 run (const char *what, char *args)
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
1188 inform ("run: %s %s", what, args);
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 {
1218 inform ("%s", strerror (errno));
1219
1220 fatal (errmsg_fmt, errmsg_arg);
1221 }
1222
1223 pid = pwait (pid, & wait_status, 0);
1224
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 */
1239 non_fatal (_("%s exited with status %d"),
1240 what, WEXITSTATUS (wait_status));
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
1249 static void
1250 scan_drectve_symbols (bfd *abfd)
1251 {
1252 asection * s;
1253 int size;
1254 char * buf;
1255 char * p;
1256 char * e;
1257
1258 /* Look for .drectve's */
1259 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME);
1260
1261 if (s == NULL)
1262 return;
1263
1264 size = bfd_get_section_size (s);
1265 buf = xmalloc (size);
1266
1267 bfd_get_section_contents (abfd, s, buf, 0, size);
1268
1269 /* xgettext:c-format */
1270 inform (_("Sucking in info from %s section in %s"),
1271 DRECTVE_SECTION_NAME, bfd_get_filename (abfd));
1272
1273 /* Search for -export: strings. The exported symbols can optionally
1274 have type tags (eg., -export:foo,data), so handle those as well.
1275 Currently only data tag is supported. */
1276 p = buf;
1277 e = buf + size;
1278 while (p < e)
1279 {
1280 if (p[0] == '-'
1281 && CONST_STRNEQ (p, "-export:"))
1282 {
1283 char * name;
1284 char * c;
1285 flagword flags = BSF_FUNCTION;
1286
1287 p += 8;
1288 name = p;
1289 while (p < e && *p != ',' && *p != ' ' && *p != '-')
1290 p++;
1291 c = xmalloc (p - name + 1);
1292 memcpy (c, name, p - name);
1293 c[p - name] = 0;
1294 if (p < e && *p == ',') /* found type tag. */
1295 {
1296 char *tag_start = ++p;
1297 while (p < e && *p != ' ' && *p != '-')
1298 p++;
1299 if (CONST_STRNEQ (tag_start, "data"))
1300 flags &= ~BSF_FUNCTION;
1301 }
1302
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. */
1306 def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0);
1307
1308 if (add_stdcall_alias && strchr (c, '@'))
1309 {
1310 int lead_at = (*c == '@') ;
1311 char *exported_name = xstrdup (c + lead_at);
1312 char *atsym = strchr (exported_name, '@');
1313 *atsym = '\0';
1314 /* Note: stdcall alias symbols can never be data. */
1315 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0);
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
1327 static void
1328 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
1329 unsigned int size)
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
1345 sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store);
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
1353 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
1354 ! (sym->flags & BSF_FUNCTION), 0);
1355
1356 if (add_stdcall_alias && strchr (symbol_name, '@'))
1357 {
1358 int lead_at = (*symbol_name == '@');
1359 char *exported_name = xstrdup (symbol_name + lead_at);
1360 char *atsym = strchr (exported_name, '@');
1361 *atsym = '\0';
1362 /* Note: stdcall alias symbols can never be data. */
1363 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0);
1364 }
1365 }
1366 }
1367
1368 /* Add a list of symbols to exclude. */
1369
1370 static void
1371 add_excludes (const char *new_excludes)
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;
1382
1383 new_exclude = ((struct string_list *)
1384 xmalloc (sizeof (struct string_list)));
1385 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
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);
1391 new_exclude->next = excludes;
1392 excludes = new_exclude;
1393
1394 /* xgettext:c-format */
1395 inform (_("Excluding symbol: %s"), exclude_string);
1396 }
1397
1398 free (local_copy);
1399 }
1400
1401 /* See if STRING is on the list of symbols to exclude. */
1402
1403 static bfd_boolean
1404 match_exclude (const char *string)
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)
1410 return TRUE;
1411 return FALSE;
1412 }
1413
1414 /* Add the default list of symbols to exclude. */
1415
1416 static void
1417 set_default_excludes (void)
1418 {
1419 add_excludes (default_excludes);
1420 }
1421
1422 /* Choose which symbols to export. */
1423
1424 static long
1425 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
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
1443 sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
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));
1452
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
1468 static void
1469 scan_all_symbols (bfd *abfd)
1470 {
1471 long symcount;
1472 void *minisyms;
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 */
1484 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1485 return;
1486 }
1487
1488 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size);
1489 if (symcount < 0)
1490 bfd_fatal (bfd_get_filename (abfd));
1491
1492 if (symcount == 0)
1493 {
1494 /* xgettext:c-format */
1495 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
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
1510 static void
1511 scan_open_obj_file (bfd *abfd)
1512 {
1513 if (export_all_symbols)
1514 scan_all_symbols (abfd);
1515 else
1516 scan_drectve_symbols (abfd);
1517
1518 /* FIXME: we ought to read in and block out the base relocations. */
1519
1520 /* xgettext:c-format */
1521 inform (_("Done reading %s"), bfd_get_filename (abfd));
1522 }
1523
1524 static void
1525 scan_obj_file (const char *filename)
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);
1535
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 }
1546
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
1551 }
1552 else if (bfd_check_format (f, bfd_object))
1553 {
1554 scan_open_obj_file (f);
1555
1556 #ifdef DLLTOOL_MCORE_ELF
1557 if (mcore_elf_out_file)
1558 mcore_elf_cache_filename (filename);
1559 #endif
1560 }
1561
1562 bfd_close (f);
1563 }
1564
1565 /**********************************************************************/
1566
1567 static void
1568 dump_def_info (FILE *f)
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 {
1578 fprintf (f, "%s %d = %s %s @ %d %s%s%s%s\n",
1579 ASM_C,
1580 i,
1581 exp->name,
1582 exp->internal_name,
1583 exp->ordinal,
1584 exp->noname ? "NONAME " : "",
1585 exp->private ? "PRIVATE " : "",
1586 exp->constant ? "CONSTANT" : "",
1587 exp->data ? "DATA" : "");
1588 }
1589 }
1590
1591 /* Generate the .exp file. */
1592
1593 static int
1594 sfunc (const void *a, const void *b)
1595 {
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);
1600 }
1601
1602 static void
1603 flush_page (FILE *f, bfd_vma *need, bfd_vma page_addr, int on_page)
1604 {
1605 int i;
1606
1607 /* Flush this page. */
1608 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1609 ASM_LONG,
1610 (int) page_addr,
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);
1616
1617 for (i = 0; i < on_page; i++)
1618 {
1619 bfd_vma needed = need[i];
1620
1621 if (needed)
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 }
1631
1632 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (long) needed);
1633 }
1634
1635 /* And padding */
1636 if (on_page & 1)
1637 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1638 }
1639
1640 static void
1641 gen_def_file (void)
1642 {
1643 int i;
1644 export_type *exp;
1645
1646 inform (_("Adding exports to output file"));
1647
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
1659 if (res)
1660 {
1661 fprintf (output_def,";\t%s\n", res);
1662 free (res);
1663 }
1664
1665 if (strcmp (exp->name, exp->internal_name) == 0)
1666 {
1667 fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n",
1668 quote,
1669 exp->name,
1670 quote,
1671 exp->ordinal,
1672 exp->noname ? " NONAME" : "",
1673 exp->private ? "PRIVATE " : "",
1674 exp->data ? " DATA" : "");
1675 }
1676 else
1677 {
1678 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
1679 /* char *alias = */
1680 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
1681 quote,
1682 exp->name,
1683 quote,
1684 quote1,
1685 exp->internal_name,
1686 quote1,
1687 exp->ordinal,
1688 exp->noname ? " NONAME" : "",
1689 exp->private ? "PRIVATE " : "",
1690 exp->data ? " DATA" : "");
1691 }
1692 }
1693
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
1701 static void
1702 generate_idata_ofile (FILE *filvar)
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);
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
1749 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1750 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
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
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);
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
1770 fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1771 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
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
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
1810 /* Assemble the specified file. */
1811 static void
1812 assemble_file (const char * source, const char * dest)
1813 {
1814 char * cmd;
1815
1816 cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags)
1817 + strlen (source) + strlen (dest) + 50);
1818
1819 sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source);
1820
1821 run (as_name, cmd);
1822 }
1823
1824 static void
1825 gen_exp_file (void)
1826 {
1827 FILE *f;
1828 int i;
1829 export_type *exp;
1830 dlist_type *dl;
1831
1832 /* xgettext:c-format */
1833 inform (_("Generating export file: %s"), exp_name);
1834
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);
1839
1840 /* xgettext:c-format */
1841 inform (_("Opened temporary file: %s"), TMP_ASM);
1842
1843 dump_def_info (f);
1844
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);
1849 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG,
1850 (unsigned long) time(0), ASM_C);
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 {
1881 while (i < exp->ordinal)
1882 {
1883 fprintf(f,"\t%s\t0\n", ASM_LONG);
1884 i++;
1885 }
1886 }
1887
1888 if (exp->forward == 0)
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,
1895 ASM_PREFIX (exp->internal_name),
1896 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1897 }
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);
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
1914 fprintf (f,"%s Export Ordinal Table\n", ASM_C);
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++)
1924 {
1925 if (!exp->noname || show_allnames)
1926 fprintf (f, "n%d: %s \"%s\"\n",
1927 exp->ordinal, ASM_TEXT, xlate (exp->name));
1928 if (exp->forward != 0)
1929 fprintf (f, "f%d: %s \"%s\"\n",
1930 exp->forward, ASM_TEXT, exp->internal_name);
1931 }
1932
1933 if (a_list)
1934 {
1935 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME);
1936 for (dl = a_list; dl; dl = dl->next)
1937 {
1938 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1939 }
1940 }
1941
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;
1949
1950 /* We don't output as ascii because there can
1951 be quote characters in the string. */
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
1977 without using the import library. */
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. */
1987 if (create_compat_implib)
1988 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1989 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1990 if (create_compat_implib)
1991 fprintf (f, "__imp_%s:\n", exp->name);
1992 fprintf (f, "_imp__%s:\n", exp->name);
1993 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1994 }
1995 }
1996
1997 /* Dump the reloc section if a base file is provided. */
1998 if (base_file)
1999 {
2000 bfd_vma addr;
2001 bfd_vma need[PAGE_SIZE];
2002 bfd_vma page_addr;
2003 bfd_size_type numbytes;
2004 int num_entries;
2005 bfd_vma *copy;
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);
2015 if (fread (copy, 1, numbytes, base_file) < numbytes)
2016 fatal (_("failed to read the number of entries from base file"));
2017 num_entries = numbytes / sizeof (bfd_vma);
2018
2019
2020 fprintf (f, "\t.section\t.reloc\n");
2021 if (num_entries)
2022 {
2023 int src;
2024 int dst = 0;
2025 bfd_vma last = (bfd_vma) -1;
2026 qsort (copy, num_entries, sizeof (bfd_vma), sfunc);
2027 /* Delete duplicates */
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 {
2039 addr = copy[j];
2040 if ((addr & PAGE_MASK) != page_addr)
2041 {
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 }
2048 flush_page (f, need, page_addr, on_page);
2049
2050 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
2051 }
2052 }
2053
2054 generate_idata_ofile (f);
2055
2056 fclose (f);
2057
2058 /* Assemble the file. */
2059 assemble_file (TMP_ASM, exp_name);
2060
2061 if (dontdeltemps == 0)
2062 unlink (TMP_ASM);
2063
2064 inform (_("Generated exports file"));
2065 }
2066
2067 static const char *
2068 xlate (const char *name)
2069 {
2070 int lead_at = (*name == '@');
2071
2072 if (!lead_at && (add_underscore
2073 || (add_stdcall_underscore
2074 && strchr (name, '@'))))
2075 {
2076 char *copy = xmalloc (strlen (name) + 2);
2077
2078 copy[0] = '_';
2079 strcpy (copy + 1, name);
2080 name = copy;
2081 }
2082
2083 if (killat)
2084 {
2085 char *p;
2086
2087 name += lead_at;
2088 p = strchr (name, '@');
2089 if (p)
2090 *p = 0;
2091 }
2092 return name;
2093 }
2094
2095 typedef 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;
2105 unsigned char *data;
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
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 }
2127 static sinfo secdata[NSECS] =
2128 {
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)
2136 };
2137
2138 #else
2139
2140 /* Sections numbered to make the order the same as other PowerPC NT
2141 compilers. This also keeps funny alignment thingies from happening. */
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
2154 static 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
2169 /* This is what we're trying to make. We generate the imp symbols with
2170 both single and double underscores, for compatibility.
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
2189 ID2: .short 2
2190 .asciz "GetFileVersionInfoSizeW"
2191
2192
2193 For the PowerPC, here's the variation on the above scheme:
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)
2204 bctr */
2205
2206 static char *
2207 make_label (const char *prefix, const char *name)
2208 {
2209 int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2210 char *copy = xmalloc (len + 1);
2211
2212 strcpy (copy, ASM_PREFIX (name));
2213 strcat (copy, prefix);
2214 strcat (copy, name);
2215 return copy;
2216 }
2217
2218 static char *
2219 make_imp_label (const char *prefix, const char *name)
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 {
2233 len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
2234 copy = xmalloc (len + 1);
2235 strcpy (copy, prefix);
2236 strcat (copy, ASM_PREFIX (name));
2237 strcat (copy, name);
2238 }
2239 return copy;
2240 }
2241
2242 static bfd *
2243 make_one_lib_file (export_type *exp, int i)
2244 {
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;
2252 #ifdef DLLTOOL_PPC
2253 asymbol ** fn_pp;
2254 asymbol ** toc_pp;
2255 #define EXTRA 2
2256 #endif
2257 #ifndef EXTRA
2258 #define EXTRA 0
2259 #endif
2260 asymbol * ptrs[NSECS + 4 + EXTRA + 1];
2261 flagword applicable;
2262 char * outname = xmalloc (strlen (TMP_STUB) + 10);
2263 int oidx = 0;
2264
2265
2266 sprintf (outname, "%s%05d.o", TMP_STUB, i);
2267
2268 abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET);
2269
2270 if (!abfd)
2271 /* xgettext:c-format */
2272 fatal (_("bfd_open failed open stub file: %s"), outname);
2273
2274 /* xgettext:c-format */
2275 inform (_("Creating stub file: %s"), outname);
2276
2277 bfd_set_format (abfd, bfd_object);
2278 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2279
2280 #ifdef DLLTOOL_ARM
2281 if (machine == MARM_INTERWORK || machine == MTHUMB)
2282 bfd_set_private_flags (abfd, F_INTERWORK);
2283 #endif
2284
2285 applicable = bfd_applicable_section_flags (abfd);
2286
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 }
2313
2314 if (! exp->data)
2315 {
2316 exp_label = bfd_make_empty_symbol (abfd);
2317 exp_label->name = make_imp_label ("", exp->name);
2318
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. */
2323 #ifdef DLLTOOL_PPC
2324 if (machine == MPPC)
2325 exp_label->section = secdata[RDATA].sec;
2326 else
2327 #endif
2328 exp_label->section = secdata[TEXT].sec;
2329
2330 exp_label->flags = BSF_GLOBAL;
2331 exp_label->value = 0;
2332
2333 #ifdef DLLTOOL_ARM
2334 if (machine == MTHUMB)
2335 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
2336 #endif
2337 ptrs[oidx++] = exp_label;
2338 }
2339
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 }
2351
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;
2357
2358 iname_lab = bfd_make_empty_symbol (abfd);
2359
2360 iname_lab->name = head_label;
2361 iname_lab->section = (asection *) &bfd_und_section;
2362 iname_lab->flags = 0;
2363 iname_lab->value = 0;
2364
2365 iname_pp = ptrs + oidx;
2366 if (create_compat_implib)
2367 ptrs[oidx++] = iname;
2368 ptrs[oidx++] = iname2;
2369
2370 iname_lab_pp = ptrs + oidx;
2371 ptrs[oidx++] = iname_lab;
2372
2373 #ifdef DLLTOOL_PPC
2374 /* The symbol referring to the code (.text). */
2375 {
2376 asymbol *function_name;
2377
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;
2383
2384 fn_pp = ptrs + oidx;
2385 ptrs[oidx++] = function_name;
2386 }
2387
2388 /* The .toc symbol. */
2389 {
2390 asymbol *toc_symbol;
2391
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;
2397
2398 toc_pp = ptrs + oidx;
2399 ptrs[oidx++] = toc_symbol;
2400 }
2401 #endif
2402
2403 ptrs[oidx] = 0;
2404
2405 for (i = 0; i < NSECS; i++)
2406 {
2407 sinfo *si = secdata + i;
2408 asection *sec = si->sec;
2409 arelent *rel;
2410 arelent **rpp;
2411
2412 switch (i)
2413 {
2414 case TEXT:
2415 if (! exp->data)
2416 {
2417 si->size = HOW_JTAB_SIZE;
2418 si->data = xmalloc (HOW_JTAB_SIZE);
2419 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2420
2421 /* Add the reloc into idata$5. */
2422 rel = xmalloc (sizeof (arelent));
2423
2424 rpp = xmalloc (sizeof (arelent *) * 2);
2425 rpp[0] = rel;
2426 rpp[1] = 0;
2427
2428 rel->address = HOW_JTAB_ROFF;
2429 rel->addend = 0;
2430
2431 if (machine == MPPC)
2432 {
2433 rel->howto = bfd_reloc_type_lookup (abfd,
2434 BFD_RELOC_16_GOTOFF);
2435 rel->sym_ptr_ptr = iname_pp;
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;
2442 }
2443 else
2444 {
2445 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2446 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2447 }
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. */
2456
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
2487 si->data = xmalloc (4);
2488 si->size = 4;
2489
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;
2500 memset (si->data, 0, si->size);
2501 rel = xmalloc (sizeof (arelent));
2502 rpp = xmalloc (sizeof (arelent *) * 2);
2503 rpp[0] = rel;
2504 rpp[1] = 0;
2505 rel->address = 0;
2506 rel->addend = 0;
2507 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2508 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2509 sec->orelocation = rpp;
2510 }
2511 #endif
2512 break;
2513
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;
2525 strcpy ((char *) si->data + 2, xlate (exp->import_name));
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;
2542
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;
2649 #endif /* DLLTOOL_PPC */
2650 }
2651 }
2652
2653 {
2654 bfd_vma vma = 0;
2655 /* Size up all the sections. */
2656 for (i = 0; i < NSECS; i++)
2657 {
2658 sinfo *si = secdata + i;
2659
2660 bfd_set_section_size (abfd, si->sec, si->size);
2661 bfd_set_section_vma (abfd, si->sec, vma);
2662 }
2663 }
2664 /* Write them out. */
2665 for (i = 0; i < NSECS; i++)
2666 {
2667 sinfo *si = secdata + i;
2668
2669 if (i == IDATA5 && no_idata5)
2670 continue;
2671
2672 if (i == IDATA4 && no_idata4)
2673 continue;
2674
2675 bfd_set_section_contents (abfd, si->sec,
2676 si->data, 0,
2677 si->size);
2678 }
2679
2680 bfd_set_symtab (abfd, ptrs, oidx);
2681 bfd_close (abfd);
2682 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET);
2683 return abfd;
2684 }
2685
2686 static bfd *
2687 make_head (void)
2688 {
2689 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
2690
2691 if (f == NULL)
2692 {
2693 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
2694 return NULL;
2695 }
2696
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");
2725 if (use_nul_prefixed_import_tables)
2726 {
2727 #ifdef DLLTOOL_MX86_64
2728 fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
2729 #else
2730 fprintf (f,"\t%s\t0\n", ASM_LONG);
2731 #endif
2732 }
2733 fprintf (f, "fthunk:\n");
2734 }
2735
2736 if (!no_idata4)
2737 {
2738 fprintf (f, "\t.section\t.idata$4\n");
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 }
2747 fprintf (f, "hname:\n");
2748 }
2749
2750 fclose (f);
2751
2752 assemble_file (TMP_HEAD_S, TMP_HEAD_O);
2753
2754 return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
2755 }
2756
2757 static bfd *
2758 make_tail (void)
2759 {
2760 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
2761
2762 if (f == NULL)
2763 {
2764 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S);
2765 return NULL;
2766 }
2767
2768 if (!no_idata4)
2769 {
2770 fprintf (f, "\t.section .idata$4\n");
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
2776 }
2777
2778 if (!no_idata5)
2779 {
2780 fprintf (f, "\t.section .idata$5\n");
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
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
2794 crt0). */
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
2806 do too. Original, huh? */
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
2818 assemble_file (TMP_TAIL_S, TMP_TAIL_O);
2819
2820 return bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET);
2821 }
2822
2823 static void
2824 gen_lib_file (void)
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
2835 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET);
2836
2837 if (!outarch)
2838 /* xgettext:c-format */
2839 fatal (_("Can't open .lib file: %s"), imp_name);
2840
2841 /* xgettext:c-format */
2842 inform (_("Creating library file: %s"), imp_name);
2843
2844 bfd_set_format (outarch, bfd_archive);
2845 outarch->has_armap = 1;
2846 outarch->is_thin_archive = 0;
2847
2848 /* Work out a reasonable size of things to put onto one line. */
2849 ar_head = make_head ();
2850 ar_tail = make_tail();
2851
2852 if (ar_head == NULL || ar_tail == NULL)
2853 return;
2854
2855 for (i = 0; (exp = d_exports_lexically[i]); i++)
2856 {
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);
2862 n->archive_next = head;
2863 head = n;
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);
2881 n->archive_next = head;
2882 head = n;
2883 }
2884 }
2885
2886 /* Now stick them all into the archive. */
2887 ar_head->archive_next = head;
2888 ar_tail->archive_next = ar_head;
2889 head = ar_tail;
2890
2891 if (! bfd_set_archive_head (outarch, head))
2892 bfd_fatal ("bfd_set_archive_head");
2893
2894 if (! bfd_close (outarch))
2895 bfd_fatal (imp_name);
2896
2897 while (head != NULL)
2898 {
2899 bfd *n = head->archive_next;
2900 bfd_close (head);
2901 head = n;
2902 }
2903
2904 /* Delete all the temp files. */
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 {
2915 char *name;
2916
2917 name = (char *) alloca (strlen (TMP_STUB) + 10);
2918 for (i = 0; (exp = d_exports_lexically[i]); i++)
2919 {
2920 /* Don't delete non-existent stubs for PRIVATE entries. */
2921 if (exp->private)
2922 continue;
2923 sprintf (name, "%s%05d.o", TMP_STUB, i);
2924 if (unlink (name) < 0)
2925 /* xgettext:c-format */
2926 non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
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 }
2934 }
2935 }
2936
2937 inform (_("Created lib file"));
2938 }
2939
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 */
2954 static void
2955 identify_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 */
2997 static void
2998 identify_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 */
3042 static void
3043 identify_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 */
3053 static bfd_boolean
3054 identify_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 */
3082 static void
3083 identify_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 }
3121 identify_dll_name = xstrdup ((char*) data);
3122 }
3123
3124 free (data);
3125 }
3126
3127 /* Run through the information gathered from the .o files and the
3128 .def file and work out the best stuff. */
3129
3130 static int
3131 pfunc (const void *a, const void *b)
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
3138 /* Unset ordinals go to the bottom. */
3139 if (ap->ordinal == -1)
3140 return 1;
3141 if (bp->ordinal == -1)
3142 return -1;
3143 return (ap->ordinal - bp->ordinal);
3144 }
3145
3146 static int
3147 nfunc (const void *a, const void *b)
3148 {
3149 export_type *ap = *(export_type **) a;
3150 export_type *bp = *(export_type **) b;
3151 const char *an = ap->name;
3152 const char *bn = bp->name;
3153
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));
3161 }
3162
3163 static void
3164 remove_null_names (export_type **ptr)
3165 {
3166 int src;
3167 int dst;
3168
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
3180 static void
3181 process_duplicates (export_type **d_export_vec)
3182 {
3183 int more = 1;
3184 int i;
3185
3186 while (more)
3187 {
3188 more = 0;
3189 /* Remove duplicates. */
3190 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
3191
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 {
3197 export_type *a = d_export_vec[i];
3198 export_type *b = d_export_vec[i + 1];
3199
3200 more = 1;
3201
3202 /* xgettext:c-format */
3203 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"),
3204 a->name, a->ordinal, b->ordinal);
3205
3206 if (a->ordinal != -1
3207 && b->ordinal != -1)
3208 /* xgettext:c-format */
3209 fatal (_("Error, duplicate EXPORT with ordinals: %s"),
3210 a->name);
3211
3212 /* Merge attributes. */
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
3220 remove_null_names (d_export_vec);
3221 }
3222 }
3223
3224 /* Count the names. */
3225 for (i = 0; i < d_nfuncs; i++)
3226 if (!d_export_vec[i]->noname)
3227 d_named_nfuncs++;
3228 }
3229
3230 static void
3231 fill_ordinals (export_type **d_export_vec)
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
3240 /* Fill in the unset ordinals with ones from our range. */
3241 ptr = (char *) xmalloc (size);
3242
3243 memset (ptr, 0, size);
3244
3245 /* Mark in our large vector all the numbers that are taken. */
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;
3251
3252 if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
3253 lowest = d_export_vec[i]->ordinal;
3254 }
3255 }
3256
3257 /* Start at 1 for compatibility with MS toolchain. */
3258 if (lowest == -1)
3259 lowest = 1;
3260
3261 /* Now fill in ordinals where the user wants us to choose. */
3262 for (i = 0; i < d_nfuncs; i++)
3263 {
3264 if (d_export_vec[i]->ordinal == -1)
3265 {
3266 int j;
3267
3268 /* First try within or after any user supplied range. */
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
3277 /* Then try before the range. */
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
3291 /* And resort. */
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
3304 static void
3305 mangle_defs (void)
3306 {
3307 /* First work out the minimum ordinal chosen. */
3308 export_type *exp;
3309
3310 int i;
3311 int hint = 0;
3312 export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
3313
3314 inform (_("Processing definitions"));
3315
3316 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
3317 d_export_vec[i] = exp;
3318
3319 process_duplicates (d_export_vec);
3320 fill_ordinals (d_export_vec);
3321
3322 /* Put back the list in the new order. */
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
3330 /* Build list in alpha order. */
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)
3335 d_exports_lexically[i] = exp;
3336
3337 d_exports_lexically[i] = 0;
3338
3339 qsort (d_exports_lexically, i, sizeof (export_type *), nfunc);
3340
3341 /* Fill exp entries with their hint values. */
3342 for (i = 0; i < d_nfuncs; i++)
3343 if (!d_exports_lexically[i]->noname || show_allnames)
3344 d_exports_lexically[i]->hint = hint++;
3345
3346 inform (_("Processed definitions"));
3347 }
3348
3349 static void
3350 usage (FILE *file, int status)
3351 {
3352 /* xgetext:c-format */
3353 fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
3354 /* xgetext:c-format */
3355 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname);
3356 fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
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"));
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"));
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"));
3370 fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n"));
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"));
3373 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
3374 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
3375 fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
3376 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
3377 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
3378 fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n"));
3379 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
3380 fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
3381 fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
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"));
3385 fprintf (file, _(" @<file> Read options from <file>.\n"));
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
3391 if (REPORT_BUGS_TO[0] && status == 0)
3392 fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
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)
3400 #define OPTION_ADD_STDCALL_UNDERSCORE (OPTION_NO_DEFAULT_EXCLUDES + 1)
3401 #define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \
3402 (OPTION_ADD_STDCALL_UNDERSCORE + 1)
3403
3404 static const struct option long_options[] =
3405 {
3406 {"no-delete", no_argument, NULL, 'n'},
3407 {"dllname", required_argument, NULL, 'D'},
3408 {"no-idata4", no_argument, NULL, 'x'},
3409 {"no-idata5", no_argument, NULL, 'c'},
3410 {"use-nul-prefixed-import-tables", no_argument, NULL,
3411 OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
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'},
3419 {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
3420 {"input-def", required_argument, NULL, 'd'},
3421 {"add-underscore", no_argument, NULL, 'U'},
3422 {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE},
3423 {"kill-at", no_argument, NULL, 'k'},
3424 {"add-stdcall-alias", no_argument, NULL, 'A'},
3425 {"ext-prefix-alias", required_argument, NULL, 'p'},
3426 {"identify", required_argument, NULL, 'I'},
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'},
3435 {"mcore-elf", required_argument, NULL, 'M'},
3436 {"compat-implib", no_argument, NULL, 'C'},
3437 {"temp-prefix", required_argument, NULL, 't'},
3438 {NULL,0,NULL,0}
3439 };
3440
3441 int main (int, char **);
3442
3443 int
3444 main (int ac, char **av)
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, "");
3454 #endif
3455 #if defined (HAVE_SETLOCALE)
3456 setlocale (LC_CTYPE, "");
3457 #endif
3458 bindtextdomain (PACKAGE, LOCALEDIR);
3459 textdomain (PACKAGE);
3460
3461 expandargv (&ac, &av);
3462
3463 while ((c = getopt_long (ac, av,
3464 #ifdef DLLTOOL_MCORE_ELF
3465 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
3466 #else
3467 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
3468 #endif
3469 long_options, 0))
3470 != EOF)
3471 {
3472 switch (c)
3473 {
3474 case OPTION_EXPORT_ALL_SYMS:
3475 export_all_symbols = TRUE;
3476 break;
3477 case OPTION_NO_EXPORT_ALL_SYMS:
3478 export_all_symbols = FALSE;
3479 break;
3480 case OPTION_EXCLUDE_SYMS:
3481 add_excludes (optarg);
3482 break;
3483 case OPTION_NO_DEFAULT_EXCLUDES:
3484 do_default_excludes = FALSE;
3485 break;
3486 case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES:
3487 use_nul_prefixed_import_tables = TRUE;
3488 break;
3489 case OPTION_ADD_STDCALL_UNDERSCORE:
3490 add_stdcall_underscore = 1;
3491 break;
3492 case 'x':
3493 no_idata4 = 1;
3494 break;
3495 case 'c':
3496 no_idata5 = 1;
3497 break;
3498 case 'S':
3499 as_name = optarg;
3500 break;
3501 case 't':
3502 tmp_prefix = optarg;
3503 break;
3504 case 'f':
3505 as_flags = optarg;
3506 break;
3507
3508 /* Ignored for compatibility. */
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':
3518 dll_name = (char*) lbasename (optarg);
3519 if (dll_name != optarg)
3520 non_fatal (_("Path components stripped from dllname, '%s'."),
3521 optarg);
3522 break;
3523 case 'l':
3524 imp_name = optarg;
3525 break;
3526 case 'e':
3527 exp_name = optarg;
3528 break;
3529 case 'H':
3530 case 'h':
3531 usage (stdout, 0);
3532 break;
3533 case 'm':
3534 mname = optarg;
3535 break;
3536 case 'I':
3537 identify_imp_name = optarg;
3538 break;
3539 case 'v':
3540 verbose = 1;
3541 break;
3542 case 'V':
3543 print_version (program_name);
3544 break;
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;
3554 case 'p':
3555 ext_prefix_alias = optarg;
3556 break;
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);
3565
3566 if (!base_file)
3567 /* xgettext:c-format */
3568 fatal (_("Unable to open base-file: %s"), optarg);
3569
3570 break;
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
3582 case 'C':
3583 create_compat_implib = 1;
3584 break;
3585 default:
3586 usage (stderr, 1);
3587 break;
3588 }
3589 }
3590
3591 if (!tmp_prefix)
3592 tmp_prefix = prefix_encode ("d", getpid ());
3593
3594 for (i = 0; mtable[i].type; i++)
3595 if (strcmp (mtable[i].type, mname) == 0)
3596 break;
3597
3598 if (!mtable[i].type)
3599 /* xgettext:c-format */
3600 fatal (_("Machine '%s' not supported"), mname);
3601
3602 machine = i;
3603
3604 if (!dll_name && exp_name)
3605 {
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;
3611 dll_name = xmalloc (len);
3612 strcpy (dll_name, exp_basename);
3613 strcat (dll_name, ".dll");
3614 }
3615
3616 if (as_name == NULL)
3617 as_name = deduce_name ("as");
3618
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)
3623 do_default_excludes = FALSE;
3624
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 ();
3643
3644 if (imp_name)
3645 {
3646 /* Make imp_name safe for use as a label. */
3647 char *p;
3648
3649 imp_name_lab = xstrdup (imp_name);
3650 for (p = imp_name_lab; *p; p++)
3651 {
3652 if (!ISALNUM (*p))
3653 *p = '_';
3654 }
3655 head_label = make_label("_head_", imp_name_lab);
3656 gen_lib_file ();
3657 }
3658
3659 if (output_def)
3660 gen_def_file ();
3661
3662 if (identify_imp_name)
3663 {
3664 identify_dll_for_implib ();
3665 }
3666
3667 #ifdef DLLTOOL_MCORE_ELF
3668 if (mcore_elf_out_file)
3669 mcore_elf_gen_out_file ();
3670 #endif
3671
3672 return 0;
3673 }
3674
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
3678 appropriate. */
3679
3680 static char *
3681 look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
3682 {
3683 struct stat s;
3684 char *cmd;
3685
3686 cmd = xmalloc (strlen (prefix)
3687 + strlen (prog_name)
3688 #ifdef HAVE_EXECUTABLE_SUFFIX
3689 + strlen (EXECUTABLE_SUFFIX)
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
3701 #ifdef HAVE_EXECUTABLE_SUFFIX
3702 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
3703 #endif
3704 );
3705
3706 if (! found)
3707 {
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
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
3724 run "i386-pe-as" or "ppc-pe-ld".
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,
3730 deduce_name("as") uses the following search order:
3731
3732 /usr/local/bin/i586-cygwin32-as
3733 /usr/local/bin/as
3734 as
3735
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.
3741
3742 Oh, and given, argv[0] = dlltool, it'll return "as".
3743
3744 Returns a dynamically allocated string. */
3745
3746 static char *
3747 deduce_name (const char *prog_name)
3748 {
3749 char *cmd;
3750 char *dash, *slash, *cp;
3751
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 }
3768
3769 cmd = NULL;
3770
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 }
3777
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;
3792 }
3793
3794 #ifdef DLLTOOL_MCORE_ELF
3795 typedef struct fname_cache
3796 {
3797 const char * filename;
3798 struct fname_cache * next;
3799 }
3800 fname_cache;
3801
3802 static fname_cache fnames;
3803
3804 static void
3805 mcore_elf_cache_filename (const char * filename)
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
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
3824 static void
3825 mcore_elf_gen_out_file (void)
3826 {
3827 fname_cache * ptr;
3828 dyn_string_t ds;
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
3834 ds = dyn_string_new (100);
3835 dyn_string_append_cstr (ds, "-r ");
3836
3837 if (mcore_elf_linker_flags != NULL)
3838 dyn_string_append_cstr (ds, mcore_elf_linker_flags);
3839
3840 while (ptr->next != NULL)
3841 {
3842 dyn_string_append_cstr (ds, ptr->filename);
3843 dyn_string_append_cstr (ds, " ");
3844
3845 ptr = ptr->next;
3846 }
3847
3848 dyn_string_append_cstr (ds, "-o ");
3849 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ);
3850
3851 if (mcore_elf_linker == NULL)
3852 mcore_elf_linker = deduce_name ("ld");
3853
3854 run (mcore_elf_linker, ds->s);
3855
3856 dyn_string_delete (ds);
3857
3858 /* Step two. Create a .exp file and a .lib file from the temporary file.
3859 Do this by recursively invoking dlltool... */
3860 ds = dyn_string_new (100);
3861
3862 dyn_string_append_cstr (ds, "-S ");
3863 dyn_string_append_cstr (ds, as_name);
3864
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);
3871
3872 if (verbose)
3873 dyn_string_append_cstr (ds, " -v");
3874
3875 if (dontdeltemps)
3876 {
3877 dyn_string_append_cstr (ds, " -n");
3878
3879 if (dontdeltemps > 1)
3880 dyn_string_append_cstr (ds, " -n");
3881 }
3882
3883 /* XXX - FIME: ought to check/copy other command line options as well. */
3884 run (program_name, ds->s);
3885
3886 dyn_string_delete (ds);
3887
3888 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */
3889 ds = dyn_string_new (100);
3890
3891 dyn_string_append_cstr (ds, "-shared ");
3892
3893 if (mcore_elf_linker_flags)
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);
3902
3903 run (mcore_elf_linker, ds->s);
3904
3905 dyn_string_delete (ds);
3906
3907 if (dontdeltemps == 0)
3908 unlink (MCORE_ELF_TMP_EXP);
3909
3910 if (dontdeltemps < 2)
3911 unlink (MCORE_ELF_TMP_OBJ);
3912 }
3913 #endif /* DLLTOOL_MCORE_ELF */