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