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