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