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