This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.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   /* Ignore bfds with an import descriptor table.  We assume that any
1255      such BFD contains symbols which are exported from another DLL,
1256      and we don't want to reexport them from here.  */
1257   if (bfd_get_section_by_name (abfd, ".idata$4"))
1258     return;
1259
1260   if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
1261     {
1262       /* xgettext:c-format */
1263       warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1264       return;
1265     }
1266
1267   symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
1268   if (symcount < 0)
1269     bfd_fatal (bfd_get_filename (abfd));
1270
1271   if (symcount == 0)
1272     {
1273       /* xgettext:c-format */
1274       warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
1275       return;
1276     }
1277
1278   /* Discard the symbols we don't want to export.  It's OK to do this
1279      in place; we'll free the storage anyway.  */
1280
1281   symcount = filter_symbols (abfd, minisyms, symcount, size);
1282   scan_filtered_symbols (abfd, minisyms, symcount, size);
1283
1284   free (minisyms);
1285 }
1286
1287 /* Look at the object file to decide which symbols to export.  */
1288
1289 static void
1290 scan_open_obj_file (abfd)
1291      bfd *abfd;
1292 {
1293   if (export_all_symbols)
1294     scan_all_symbols (abfd);
1295   else
1296     scan_drectve_symbols (abfd);
1297  
1298   /* FIXME: we ought to read in and block out the base relocations */
1299
1300   /* xgettext:c-format */
1301   inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
1302 }
1303
1304 static void
1305 scan_obj_file (filename)
1306      const char *filename;
1307 {
1308   bfd * f = bfd_openr (filename, 0);
1309
1310   if (!f)
1311     /* xgettext:c-format */
1312     fatal (_("Unable to open object file: %s"), filename);
1313
1314   /* xgettext:c-format */
1315   inform (_("Scanning object file %s"), filename);
1316   
1317   if (bfd_check_format (f, bfd_archive))
1318     {
1319       bfd *arfile = bfd_openr_next_archived_file (f, 0);
1320       while (arfile)
1321         {
1322           if (bfd_check_format (arfile, bfd_object))
1323             scan_open_obj_file (arfile);
1324           bfd_close (arfile);
1325           arfile = bfd_openr_next_archived_file (f, arfile);
1326         }
1327     }
1328   else if (bfd_check_format (f, bfd_object))
1329     {
1330       scan_open_obj_file (f);
1331     }
1332
1333   bfd_close (f);
1334 }
1335
1336 /**********************************************************************/
1337
1338 static void
1339 dump_def_info (f)
1340      FILE *f;
1341 {
1342   int i;
1343   export_type *exp;
1344   fprintf (f, "%s ", ASM_C);
1345   for (i = 0; oav[i]; i++)
1346     fprintf (f, "%s ", oav[i]);
1347   fprintf (f, "\n");
1348   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1349     {
1350       fprintf (f, "%s  %d = %s %s @ %d %s%s%s\n",
1351                ASM_C,
1352                i,
1353                exp->name,
1354                exp->internal_name,
1355                exp->ordinal,
1356                exp->noname ? "NONAME " : "",
1357                exp->constant ? "CONSTANT" : "",
1358                exp->data ? "DATA" : "");
1359     }
1360 }
1361
1362 /* Generate the .exp file */
1363
1364 static int
1365 sfunc (a, b)
1366      const void *a;
1367      const void *b;
1368 {
1369   return *(const long *) a - *(const long *) b;
1370 }
1371
1372 static void
1373 flush_page (f, need, page_addr, on_page)
1374      FILE *f;
1375      long *need;
1376      int page_addr;
1377      int on_page;
1378 {
1379   int i;
1380
1381   /* Flush this page */
1382   fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
1383            ASM_LONG,
1384            page_addr,
1385            ASM_C);
1386   fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
1387            ASM_LONG,
1388            (on_page * 2) + (on_page & 1) * 2 + 8,
1389            ASM_C);
1390   for (i = 0; i < on_page; i++)
1391     {
1392       fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
1393     }
1394   /* And padding */
1395   if (on_page & 1)
1396     fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
1397 }
1398
1399 static void
1400 gen_def_file ()
1401 {
1402   int i;
1403   export_type *exp;
1404
1405   inform (_("Adding exports to output file"));
1406   
1407   fprintf (output_def, ";");
1408   for (i = 0; oav[i]; i++)
1409     fprintf (output_def, " %s", oav[i]);
1410
1411   fprintf (output_def, "\nEXPORTS\n");
1412
1413   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1414     {
1415       char *quote = strchr (exp->name, '.') ? "\"" : "";
1416       char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
1417
1418       fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
1419                quote,
1420                exp->name,
1421                quote,
1422                exp->ordinal,
1423                exp->noname ? " NONAME" : "",
1424                exp->data ? " DATA" : "",
1425                res ? res : "");
1426       if (res)
1427         free (res);
1428     }
1429   
1430   inform (_("Added exports to output file"));
1431 }
1432
1433 /* generate_idata_ofile generates the portable assembly source code
1434    for the idata sections.  It appends the source code to the end of
1435    the file.  */
1436
1437 static void
1438 generate_idata_ofile (filvar)
1439      FILE *filvar;
1440 {
1441   iheadtype *headptr;
1442   ifunctype *funcptr;
1443   int        headindex;
1444   int        funcindex;
1445   int        nheads;
1446
1447   if (import_list == NULL)
1448     return;
1449
1450   fprintf (filvar, "%s Import data sections\n", ASM_C);
1451   fprintf (filvar, "\n\t.section\t.idata$2\n");
1452   fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
1453   fprintf (filvar, "doi_idata:\n");
1454
1455   nheads = 0;
1456   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1457     {
1458       fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
1459                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
1460                ASM_C, headptr->dllname);
1461       fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1462       fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1463       fprintf (filvar, "\t%sdllname%d%s\n",
1464                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1465       fprintf (filvar, "\t%slisttwo%d%s\n\n",
1466                ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
1467       nheads++;
1468     }
1469
1470   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
1471   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
1472   fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section        */
1473   fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1474   fprintf (filvar, "\t%s\t0\n", ASM_LONG);
1475
1476   fprintf (filvar, "\n\t.section\t.idata$4\n");
1477   headindex = 0;
1478   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1479     {
1480       fprintf (filvar, "listone%d:\n", headindex);
1481       for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1482         fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1483                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1484       fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1485       headindex++;
1486     }
1487
1488   fprintf (filvar, "\n\t.section\t.idata$5\n");
1489   headindex = 0;
1490   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1491     {
1492       fprintf (filvar, "listtwo%d:\n", headindex);
1493       for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
1494         fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
1495                  ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
1496       fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
1497       headindex++;
1498     }
1499
1500   fprintf (filvar, "\n\t.section\t.idata$6\n");
1501   headindex = 0;
1502   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1503     {
1504       funcindex = 0;
1505       for (funcptr = headptr->funchead; funcptr != NULL;
1506            funcptr = funcptr->next)
1507         {
1508           fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
1509           fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
1510                    ((funcptr->ord) & 0xFFFF));
1511           fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
1512           fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1513           funcindex++;
1514         }
1515       headindex++;
1516     }
1517
1518   fprintf (filvar, "\n\t.section\t.idata$7\n");
1519   headindex = 0;
1520   for (headptr = import_list; headptr != NULL; headptr = headptr->next)
1521     {
1522       fprintf (filvar,"dllname%d:\n", headindex);
1523       fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
1524       fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
1525       headindex++;
1526     }
1527 }
1528
1529 static void
1530 gen_exp_file ()
1531 {
1532   FILE *f;
1533   int i;
1534   export_type *exp;
1535   dlist_type *dl;
1536
1537   /* xgettext:c-format */
1538   inform (_("Generating export file: %s\n"), exp_name);
1539   
1540   f = fopen (TMP_ASM, FOPEN_WT);
1541   if (!f)
1542     /* xgettext:c-format */
1543     fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
1544   
1545   /* xgettext:c-format */
1546   inform (_("Opened temporary file: %s"), TMP_ASM);
1547
1548   dump_def_info (f);
1549   
1550   if (d_exports)
1551     {
1552       fprintf (f, "\t.section   .edata\n\n");
1553       fprintf (f, "\t%s 0       %s Allways 0\n", ASM_LONG, ASM_C);
1554       fprintf (f, "\t%s 0x%lx   %s Time and date\n", ASM_LONG, (long) time(0),
1555                ASM_C);
1556       fprintf (f, "\t%s 0       %s Major and Minor version\n", ASM_LONG, ASM_C);
1557       fprintf (f, "\t%sname%s   %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1558       fprintf (f, "\t%s %d      %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
1559
1560
1561       fprintf (f, "\t%s %d      %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
1562       fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
1563               ASM_C,
1564               d_named_nfuncs, d_low_ord, d_high_ord);
1565       fprintf (f, "\t%s %d      %s Number of names\n", ASM_LONG,
1566                show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
1567       fprintf (f, "\t%safuncs%s  %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1568
1569       fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
1570                ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1571
1572       fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1573
1574       fprintf (f, "name:        %s      \"%s\"\n", ASM_TEXT, dll_name);
1575
1576
1577       fprintf(f,"%s Export address Table\n", ASM_C);
1578       fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1579       fprintf (f, "afuncs:\n");
1580       i = d_low_ord;
1581
1582       for (exp = d_exports; exp; exp = exp->next)
1583         {
1584           if (exp->ordinal != i)
1585             {
1586 #if 0
1587               fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1588                        ASM_SPACE,
1589                        (exp->ordinal - i) * 4,
1590                        ASM_C,
1591                        i, exp->ordinal - 1);
1592               i = exp->ordinal;
1593 #endif
1594               while (i < exp->ordinal)
1595                 {
1596                   fprintf(f,"\t%s\t0\n", ASM_LONG);
1597                   i++;
1598                 }
1599             }
1600           fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1601                    ASM_PREFIX,
1602                    exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1603           i++;
1604         }
1605
1606       fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1607       fprintf (f, "anames:\n");
1608
1609       for (i = 0; (exp = d_exports_lexically[i]); i++)
1610         {
1611           if (!exp->noname || show_allnames)
1612             fprintf (f, "\t%sn%d%s\n",
1613                      ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1614         }
1615
1616       fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1617       fprintf (f, "anords:\n");
1618       for (i = 0; (exp = d_exports_lexically[i]); i++)
1619         {
1620           if (!exp->noname || show_allnames)
1621             fprintf (f, "\t%s   %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1622         }
1623
1624       fprintf(f,"%s Export Name Table\n", ASM_C);
1625       for (i = 0; (exp = d_exports_lexically[i]); i++)
1626         if (!exp->noname || show_allnames)
1627           fprintf (f, "n%d:     %s      \"%s\"\n",
1628                    exp->ordinal, ASM_TEXT, exp->name);
1629
1630       if (a_list)
1631         {
1632           fprintf (f, "\t.section .drectve\n");
1633           for (dl = a_list; dl; dl = dl->next)
1634             {
1635               fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1636             }
1637         }
1638       if (d_list)
1639         {
1640           fprintf (f, "\t.section .rdata\n");
1641           for (dl = d_list; dl; dl = dl->next)
1642             {
1643               char *p;
1644               int l;
1645               /* We dont output as ascii 'cause there can
1646                  be quote characters in the string */
1647
1648               l = 0;
1649               for (p = dl->text; *p; p++)
1650                 {
1651                   if (l == 0)
1652                     fprintf (f, "\t%s\t", ASM_BYTE);
1653                   else
1654                     fprintf (f, ",");
1655                   fprintf (f, "%d", *p);
1656                   if (p[1] == 0)
1657                     {
1658                       fprintf (f, ",0\n");
1659                       break;
1660                     }
1661                   if (++l == 10)
1662                     {
1663                       fprintf (f, "\n");
1664                       l = 0;
1665                     }
1666                 }
1667             }
1668         }
1669     }
1670
1671
1672   /* Add to the output file a way of getting to the exported names
1673      without using the import library. */
1674   if (add_indirect)
1675     {
1676       fprintf (f, "\t.section\t.rdata\n");
1677       for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1678         if (!exp->noname || show_allnames)
1679           {
1680             /* We use a single underscore for MS compatibility, and a
1681                double underscore for backward compatibility with old
1682                cygwin releases.  */
1683             fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1684             fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1685             fprintf (f, "__imp_%s:\n", exp->name);
1686             fprintf (f, "_imp__%s:\n", exp->name);
1687             fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1688           }
1689     }
1690
1691   /* Dump the reloc section if a base file is provided */
1692   if (base_file)
1693     {
1694       int addr;
1695       long need[PAGE_SIZE];
1696       long page_addr;
1697       int numbytes;
1698       int num_entries;
1699       long *copy;
1700       int j;
1701       int on_page;
1702       fprintf (f, "\t.section\t.init\n");
1703       fprintf (f, "lab:\n");
1704
1705       fseek (base_file, 0, SEEK_END);
1706       numbytes = ftell (base_file);
1707       fseek (base_file, 0, SEEK_SET);
1708       copy = xmalloc (numbytes);
1709       fread (copy, 1, numbytes, base_file);
1710       num_entries = numbytes / sizeof (long);
1711
1712
1713       fprintf (f, "\t.section\t.reloc\n");
1714       if (num_entries)
1715         {
1716           int src;
1717           int dst = 0;
1718           int last = -1;
1719           qsort (copy, num_entries, sizeof (long), sfunc);
1720           /* Delete duplcates */
1721           for (src = 0; src < num_entries; src++)
1722             {
1723               if (last != copy[src])
1724                 last = copy[dst++] = copy[src];
1725             }
1726           num_entries = dst;
1727           addr = copy[0];
1728           page_addr = addr & PAGE_MASK;         /* work out the page addr */
1729           on_page = 0;
1730           for (j = 0; j < num_entries; j++)
1731             {
1732               addr = copy[j];
1733               if ((addr & PAGE_MASK) != page_addr)
1734                 {
1735                   flush_page (f, need, page_addr, on_page);
1736                   on_page = 0;
1737                   page_addr = addr & PAGE_MASK;
1738                 }
1739               need[on_page++] = addr;
1740             }
1741           flush_page (f, need, page_addr, on_page);
1742
1743 /*        fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1744         }
1745     }
1746
1747   generate_idata_ofile (f);
1748
1749   fclose (f);
1750
1751   /* assemble the file */
1752   sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
1753
1754 #ifdef DLLTOOL_ARM
1755   if (interwork)
1756     strcat (outfile, " -mthumb-interwork");
1757 #endif
1758   
1759   run (as_name, outfile);
1760   
1761   if (dontdeltemps == 0)
1762     unlink (TMP_ASM);
1763   
1764   inform (_("Generated exports file"));
1765 }
1766
1767 static const char *
1768 xlate (name)
1769      const char *name;
1770 {
1771   if (add_underscore)
1772     {
1773       char *copy = xmalloc (strlen (name) + 2);
1774       copy[0] = '_';
1775       strcpy (copy + 1, name);
1776       name = copy;
1777     }
1778
1779   if (killat)
1780     {
1781       char *p;
1782       p = strchr (name, '@');
1783       if (p)
1784         *p = 0;
1785     }
1786   return name;
1787 }
1788
1789 /**********************************************************************/
1790
1791 #if 0
1792
1793 static void
1794 dump_iat (f, exp)
1795      FILE *f;
1796      export_type *exp;
1797 {
1798   if (exp->noname && !show_allnames )
1799     {
1800       fprintf (f, "\t%s\t0x%08x\n",
1801                ASM_LONG,
1802                exp->ordinal | 0x80000000); /* hint or orindal ?? */
1803     }
1804   else
1805     {
1806       fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1807                exp->ordinal,
1808                ASM_RVA_AFTER);
1809     }
1810 }
1811
1812 #endif
1813
1814 typedef struct
1815 {
1816   int id;
1817   const char *name;
1818   int flags;
1819   int align;
1820   asection *sec;
1821   asymbol *sym;
1822   asymbol **sympp;
1823   int size;
1824   unsigned   char *data;
1825 } sinfo;
1826
1827 #ifndef DLLTOOL_PPC
1828
1829 #define TEXT 0
1830 #define DATA 1
1831 #define BSS 2
1832 #define IDATA7 3
1833 #define IDATA5 4
1834 #define IDATA4 5
1835 #define IDATA6 6
1836
1837 #define NSECS 7
1838
1839 static sinfo secdata[NSECS] =
1840 {
1841   { TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 2},
1842   { DATA,   ".data",    SEC_DATA,                    2},
1843   { BSS,    ".bss",     0,                           2},
1844   { IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2},
1845   { IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2},
1846   { IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2},
1847   { IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1}
1848 };
1849
1850 #else
1851
1852 /* Sections numbered to make the order the same as other PowerPC NT    */
1853 /* compilers. This also keeps funny alignment thingies from happening. */
1854 #define TEXT   0
1855 #define PDATA  1
1856 #define RDATA  2
1857 #define IDATA5 3
1858 #define IDATA4 4
1859 #define IDATA6 5
1860 #define IDATA7 6
1861 #define DATA   7
1862 #define BSS    8
1863
1864 #define NSECS 9
1865
1866 static sinfo secdata[NSECS] =
1867 {
1868   { TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 3},
1869   { PDATA,  ".pdata",   SEC_HAS_CONTENTS,            2},
1870   { RDATA,  ".reldata", SEC_HAS_CONTENTS,            2},
1871   { IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2},
1872   { IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2},
1873   { IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1},
1874   { IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2},
1875   { DATA,   ".data",    SEC_DATA,                    2},
1876   { BSS,    ".bss",     0,                           2}
1877 };
1878
1879 #endif
1880
1881 /*
1882 This is what we're trying to make.  We generate the imp symbols with
1883 both single and double underscores, for compatibility.
1884
1885         .text
1886         .global _GetFileVersionInfoSizeW@8
1887         .global __imp_GetFileVersionInfoSizeW@8
1888 _GetFileVersionInfoSizeW@8:
1889         jmp *   __imp_GetFileVersionInfoSizeW@8
1890         .section        .idata$7        # To force loading of head
1891         .long   __version_a_head
1892 # Import Address Table
1893         .section        .idata$5
1894 __imp_GetFileVersionInfoSizeW@8:
1895         .rva    ID2
1896
1897 # Import Lookup Table
1898         .section        .idata$4
1899         .rva    ID2
1900 # Hint/Name table
1901         .section        .idata$6
1902 ID2:    .short  2
1903         .asciz  "GetFileVersionInfoSizeW"
1904
1905
1906 For the PowerPC, here's the variation on the above scheme:
1907
1908 # Rather than a simple "jmp *", the code to get to the dll function
1909 # looks like:
1910          .text
1911          lwz    r11,[tocv]__imp_function_name(r2)
1912 #                  RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1913          lwz    r12,0(r11)
1914          stw    r2,4(r1)
1915          mtctr  r12
1916          lwz    r2,4(r11)
1917          bctr
1918 */
1919
1920 static char *
1921 make_label (prefix, name)
1922      const char *prefix;
1923      const char *name;
1924 {
1925   int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1926   char *copy = xmalloc (len +1 );
1927   strcpy (copy, ASM_PREFIX);
1928   strcat (copy, prefix);
1929   strcat (copy, name);
1930   return copy;
1931 }
1932
1933 static bfd *
1934 make_one_lib_file (exp, i)
1935      export_type *exp;
1936      int i;
1937 {
1938 #if 0
1939     {
1940       FILE *f;
1941       char *prefix="d";
1942       sprintf (outfile, "%ss%d.s", prefix, i);
1943       f = fopen (outfile, FOPEN_WT);
1944       fprintf (f, "\t.text\n");
1945       fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
1946       fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1947       fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1948       fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1949                exp->name, ASM_JUMP, exp->name);
1950
1951       fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
1952       fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
1953
1954
1955       fprintf (f,"%s Import Address Table\n", ASM_C);
1956
1957       fprintf (f, "\t.section   .idata$5\n");
1958       fprintf (f, "__imp_%s:\n", exp->name);
1959       fprintf (f, "_imp__%s:\n", exp->name);
1960
1961       dump_iat (f, exp);
1962
1963       fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
1964       fprintf (f, "\t.section   .idata$4\n");
1965
1966       dump_iat (f, exp);
1967
1968       if(!exp->noname || show_allnames)
1969         {
1970           fprintf (f, "%s Hint/Name table\n", ASM_C);
1971           fprintf (f, "\t.section       .idata$6\n");
1972           fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
1973           fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1974         }
1975
1976       fclose (f);
1977
1978       sprintf (outfile, "%s -o %ss%d.o %ss%d.s",
1979                as_flags, prefix, i, prefix, i);
1980
1981 #ifdef DLLTOOL_ARM
1982       if (interwork)
1983         strcat (outfile, " -mthumb-interwork");
1984 #endif
1985   
1986       run (as_name, outfile);
1987     }
1988 #else /* if 0 */
1989     {
1990       bfd *      abfd;
1991       asymbol *  exp_label;
1992       asymbol *  iname;
1993       asymbol *  iname2;
1994       asymbol *  iname_lab;
1995       asymbol ** iname_lab_pp;
1996       asymbol ** iname_pp;
1997 #ifdef DLLTOOL_PPC
1998       asymbol ** fn_pp;
1999       asymbol ** toc_pp;
2000 #define EXTRA    2
2001 #endif
2002 #ifndef EXTRA
2003 #define EXTRA    0
2004 #endif
2005       asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
2006
2007       char *     outname = xmalloc (10);
2008       int        oidx = 0;
2009
2010       
2011       sprintf (outname, "%s%d.o", TMP_STUB, i);
2012       
2013       abfd = bfd_openw (outname, HOW_BFD_TARGET);
2014       
2015       if (!abfd)
2016         /* xgettext:c-format */
2017         fatal (_("bfd_open failed open stub file: %s"), outname);
2018
2019       /* xgettext:c-format */
2020       inform (_("Creating stub file: %s"), outname);
2021       
2022       bfd_set_format (abfd, bfd_object);
2023       bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
2024
2025 #ifdef DLLTOOL_ARM
2026       if (interwork)
2027         bfd_set_private_flags (abfd, F_INTERWORK);
2028 #endif
2029       
2030       /* First make symbols for the sections */
2031       for (i = 0; i < NSECS; i++)
2032         {
2033           sinfo *si = secdata + i;
2034           if (si->id != i)
2035             abort();
2036           si->sec = bfd_make_section_old_way (abfd, si->name);
2037           bfd_set_section_flags (abfd,
2038                                  si->sec,
2039                                  si->flags);
2040
2041           bfd_set_section_alignment(abfd, si->sec, si->align);
2042           si->sec->output_section = si->sec;
2043           si->sym = bfd_make_empty_symbol(abfd);
2044           si->sym->name = si->sec->name;
2045           si->sym->section = si->sec;
2046           si->sym->flags = BSF_LOCAL;
2047           si->sym->value = 0;
2048           ptrs[oidx] = si->sym;
2049           si->sympp = ptrs + oidx;
2050           si->size = 0;
2051           si->data = NULL;
2052
2053           oidx++;
2054         }
2055
2056       if (! exp->data)
2057         {
2058           exp_label = bfd_make_empty_symbol (abfd);
2059           exp_label->name = make_label ("", exp->name);
2060
2061           /* On PowerPC, the function name points to a descriptor in
2062              the rdata section, the first element of which is a
2063              pointer to the code (..function_name), and the second
2064              points to the .toc */
2065 #ifdef DLLTOOL_PPC
2066           if (machine == MPPC)
2067             exp_label->section = secdata[RDATA].sec;
2068           else
2069 #endif
2070             exp_label->section = secdata[TEXT].sec;
2071
2072           exp_label->flags = BSF_GLOBAL;
2073           exp_label->value = 0;
2074
2075 #ifdef DLLTOOL_ARM
2076           if (machine == MTHUMB)
2077             bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXT);
2078 #endif
2079           ptrs[oidx++] = exp_label;
2080         }
2081
2082       /* Generate imp symbols with one underscore for Microsoft
2083          compatibility, and with two underscores for backward
2084          compatibility with old versions of cygwin.  */
2085       iname = bfd_make_empty_symbol(abfd);
2086       iname->name = make_label ("__imp_", exp->name);
2087       iname->section = secdata[IDATA5].sec;
2088       iname->flags = BSF_GLOBAL;
2089       iname->value = 0;
2090
2091       iname2 = bfd_make_empty_symbol(abfd);
2092       iname2->name = make_label ("_imp__", exp->name);
2093       iname2->section = secdata[IDATA5].sec;
2094       iname2->flags = BSF_GLOBAL;
2095       iname2->value = 0;
2096
2097       iname_lab = bfd_make_empty_symbol(abfd);
2098
2099       iname_lab->name = head_label;
2100       iname_lab->section = (asection *)&bfd_und_section;
2101       iname_lab->flags = 0;
2102       iname_lab->value = 0;
2103
2104
2105       iname_pp = ptrs + oidx;
2106       ptrs[oidx++] = iname;
2107       ptrs[oidx++] = iname2;
2108
2109       iname_lab_pp = ptrs + oidx;
2110       ptrs[oidx++] = iname_lab;
2111
2112 #ifdef DLLTOOL_PPC
2113       /* The symbol refering to the code (.text) */
2114       {
2115         asymbol *function_name;
2116
2117         function_name = bfd_make_empty_symbol(abfd);
2118         function_name->name = make_label ("..", exp->name);
2119         function_name->section = secdata[TEXT].sec;
2120         function_name->flags = BSF_GLOBAL;
2121         function_name->value = 0;
2122
2123         fn_pp = ptrs + oidx;
2124         ptrs[oidx++] = function_name;
2125       }
2126
2127       /* The .toc symbol */
2128       {
2129         asymbol *toc_symbol;    /* The .toc symbol */
2130
2131         toc_symbol = bfd_make_empty_symbol (abfd);
2132         toc_symbol->name = make_label (".", "toc");
2133         toc_symbol->section = (asection *)&bfd_und_section;
2134         toc_symbol->flags = BSF_GLOBAL;
2135         toc_symbol->value = 0;
2136
2137         toc_pp = ptrs + oidx;
2138         ptrs[oidx++] = toc_symbol;
2139       }
2140 #endif
2141       
2142       ptrs[oidx] = 0;
2143
2144       for (i = 0; i < NSECS; i++)
2145         {
2146           sinfo *si = secdata + i;
2147           asection *sec = si->sec;
2148           arelent *rel;
2149           arelent **rpp;
2150
2151           switch (i)
2152             {
2153             case TEXT:
2154               if (! exp->data)
2155                 {
2156                   si->size = HOW_JTAB_SIZE;
2157                   si->data = xmalloc (HOW_JTAB_SIZE);
2158                   memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
2159
2160                   /* add the reloc into idata$5 */
2161                   rel = xmalloc (sizeof (arelent));
2162                   
2163                   rpp = xmalloc (sizeof (arelent *) * 2);
2164                   rpp[0] = rel;
2165                   rpp[1] = 0;
2166                   
2167                   rel->address = HOW_JTAB_ROFF;
2168                   rel->addend = 0;
2169
2170                   if (machine == MPPC)
2171                     {
2172                       rel->howto = bfd_reloc_type_lookup (abfd,
2173                                                           BFD_RELOC_16_GOTOFF);
2174                       rel->sym_ptr_ptr = iname_pp;
2175                     }
2176                   else
2177                     {
2178                       rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2179                       rel->sym_ptr_ptr = secdata[IDATA5].sympp;
2180                     }
2181                   sec->orelocation = rpp;
2182                   sec->reloc_count = 1;
2183                 }
2184               break;
2185             case IDATA4:
2186             case IDATA5:
2187               /* An idata$4 or idata$5 is one word long, and has an
2188                  rva to idata$6 */
2189
2190               si->data = xmalloc (4);
2191               si->size = 4;
2192
2193               if (exp->noname)
2194                 {
2195                   si->data[0] = exp->ordinal ;
2196                   si->data[1] = exp->ordinal >> 8;
2197                   si->data[2] = exp->ordinal >> 16;
2198                   si->data[3] = 0x80;
2199                 }
2200               else
2201                 {
2202                   sec->reloc_count = 1;
2203                   memset (si->data, 0, si->size);
2204                   rel = xmalloc (sizeof (arelent));
2205                   rpp = xmalloc (sizeof (arelent *) * 2);
2206                   rpp[0] = rel;
2207                   rpp[1] = 0;
2208                   rel->address = 0;
2209                   rel->addend = 0;
2210                   rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2211                   rel->sym_ptr_ptr = secdata[IDATA6].sympp;
2212                   sec->orelocation = rpp;
2213                 }
2214
2215               break;
2216
2217             case IDATA6:
2218               if (!exp->noname)
2219                 {
2220                   /* This used to add 1 to exp->hint.  I don't know
2221                      why it did that, and it does not match what I see
2222                      in programs compiled with the MS tools.  */
2223                   int idx = exp->hint;
2224                   si->size = strlen (xlate (exp->name)) + 3;
2225                   si->data = xmalloc (si->size);
2226                   si->data[0] = idx & 0xff;
2227                   si->data[1] = idx >> 8;
2228                   strcpy (si->data + 2, xlate (exp->name));
2229                 }
2230               break;
2231             case IDATA7:
2232               si->size = 4;
2233               si->data =xmalloc(4);
2234               memset (si->data, 0, si->size);
2235               rel = xmalloc (sizeof (arelent));
2236               rpp = xmalloc (sizeof (arelent *) * 2);
2237               rpp[0] = rel;
2238               rel->address = 0;
2239               rel->addend = 0;
2240               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
2241               rel->sym_ptr_ptr = iname_lab_pp;
2242               sec->orelocation = rpp;
2243               sec->reloc_count = 1;
2244               break;
2245
2246 #ifdef DLLTOOL_PPC
2247             case PDATA:
2248               {
2249                 /* The .pdata section is 5 words long. */
2250                 /* Think of it as:                     */
2251                 /* struct                              */
2252                 /* {                                   */
2253                 /*   bfd_vma BeginAddress,     [0x00]  */
2254                 /*           EndAddress,       [0x04]  */
2255                 /*           ExceptionHandler, [0x08]  */
2256                 /*           HandlerData,      [0x0c]  */
2257                 /*           PrologEndAddress; [0x10]  */
2258                 /* };                                  */
2259
2260                 /* So this pdata section setups up this as a glue linkage to
2261                    a dll routine. There are a number of house keeping things
2262                    we need to do:
2263
2264                    1. In the name of glue trickery, the ADDR32 relocs for 0,
2265                       4, and 0x10 are set to point to the same place:
2266                       "..function_name".
2267                    2. There is one more reloc needed in the pdata section.
2268                       The actual glue instruction to restore the toc on
2269                       return is saved as the offset in an IMGLUE reloc.
2270                       So we need a total of four relocs for this section.
2271
2272                    3. Lastly, the HandlerData field is set to 0x03, to indicate
2273                       that this is a glue routine.
2274                 */
2275                 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
2276
2277                 /* alignment must be set to 2**2 or you get extra stuff */
2278                 bfd_set_section_alignment(abfd, sec, 2);
2279
2280                 si->size = 4 * 5;
2281                 si->data =xmalloc(4 * 5);
2282                 memset (si->data, 0, si->size);
2283                 rpp = xmalloc (sizeof (arelent *) * 5);
2284                 rpp[0] = imglue  = xmalloc (sizeof (arelent));
2285                 rpp[1] = ba_rel  = xmalloc (sizeof (arelent));
2286                 rpp[2] = ea_rel  = xmalloc (sizeof (arelent));
2287                 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
2288                 rpp[4] = 0;
2289
2290                 /* stick the toc reload instruction in the glue reloc */
2291                 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
2292
2293                 imglue->addend = 0;
2294                 imglue->howto = bfd_reloc_type_lookup (abfd,
2295                                                        BFD_RELOC_32_GOTOFF);
2296                 imglue->sym_ptr_ptr = fn_pp;
2297
2298                 ba_rel->address = 0;
2299                 ba_rel->addend = 0;
2300                 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2301                 ba_rel->sym_ptr_ptr = fn_pp;
2302
2303                 bfd_put_32(abfd, 0x18, si->data + 0x04);
2304                 ea_rel->address = 4;
2305                 ea_rel->addend = 0;
2306                 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2307                 ea_rel->sym_ptr_ptr = fn_pp;
2308
2309                 /* mark it as glue */
2310                 bfd_put_32(abfd, 0x03, si->data + 0x0c);
2311
2312                 /* mark the prolog end address */
2313                 bfd_put_32(abfd, 0x0D, si->data + 0x10);
2314                 pea_rel->address = 0x10;
2315                 pea_rel->addend = 0;
2316                 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2317                 pea_rel->sym_ptr_ptr = fn_pp;
2318
2319                 sec->orelocation = rpp;
2320                 sec->reloc_count = 4;
2321                 break;
2322               }
2323             case RDATA:
2324               /* Each external function in a PowerPC PE file has a two word
2325                  descriptor consisting of:
2326                  1. The address of the code.
2327                  2. The address of the appropriate .toc
2328                  We use relocs to build this.
2329               */
2330
2331               si->size = 8;
2332               si->data = xmalloc (8);
2333               memset (si->data, 0, si->size);
2334
2335               rpp = xmalloc (sizeof (arelent *) * 3);
2336               rpp[0] = rel = xmalloc (sizeof (arelent));
2337               rpp[1] = xmalloc (sizeof (arelent));
2338               rpp[2] = 0;
2339
2340               rel->address = 0;
2341               rel->addend = 0;
2342               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2343               rel->sym_ptr_ptr = fn_pp;
2344
2345               rel = rpp[1];
2346
2347               rel->address = 4;
2348               rel->addend = 0;
2349               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
2350               rel->sym_ptr_ptr = toc_pp;
2351
2352               sec->orelocation = rpp;
2353               sec->reloc_count = 2;
2354               break;
2355 #endif /* DLLTOOL_PPC */
2356             }
2357         }
2358
2359       {
2360         bfd_vma vma = 0;
2361         /* Size up all the sections */
2362         for (i = 0; i < NSECS; i++)
2363           {
2364             sinfo *si = secdata + i;
2365
2366             bfd_set_section_size (abfd, si->sec, si->size);
2367             bfd_set_section_vma (abfd, si->sec, vma);
2368
2369 /*          vma += si->size;*/
2370           }
2371       }
2372       /* Write them out */
2373       for (i = 0; i < NSECS; i++)
2374         {
2375           sinfo *si = secdata + i;
2376
2377           if (i == IDATA5 && no_idata5)
2378             continue;
2379
2380           if (i == IDATA4 && no_idata4)
2381             continue;
2382
2383           bfd_set_section_contents (abfd, si->sec,
2384                                     si->data, 0,
2385                                     si->size);
2386         }
2387
2388       bfd_set_symtab (abfd, ptrs, oidx);
2389       bfd_close (abfd);
2390       abfd = bfd_openr (outname, HOW_BFD_TARGET);
2391       return abfd;
2392     }
2393 #endif
2394 }
2395
2396 static bfd *
2397 make_head ()
2398 {
2399   FILE *  f = fopen (TMP_HEAD_S, FOPEN_WT);
2400
2401   fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
2402   fprintf (f, "\t.section       .idata$2\n");
2403
2404   fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
2405
2406   fprintf (f, "%s:\n", head_label);
2407
2408   fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
2409            ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
2410
2411   fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
2412   fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
2413   fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
2414   fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
2415   fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
2416            ASM_RVA_BEFORE,
2417            imp_name_lab,
2418            ASM_RVA_AFTER,
2419            ASM_C);
2420   fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
2421            ASM_RVA_BEFORE,
2422            ASM_RVA_AFTER, ASM_C);
2423
2424   fprintf (f, "%sStuff for compatibility\n", ASM_C);
2425
2426   if (!no_idata5)
2427     {
2428       fprintf (f, "\t.section\t.idata$5\n");
2429       fprintf (f, "\t%s\t0\n", ASM_LONG);
2430       fprintf (f, "fthunk:\n");
2431     }
2432   if (!no_idata4)
2433     {
2434       fprintf (f, "\t.section\t.idata$4\n");
2435
2436       fprintf (f, "\t%s\t0\n", ASM_LONG);
2437       fprintf (f, "\t.section   .idata$4\n");
2438       fprintf (f, "hname:\n");
2439     }
2440   fclose (f);
2441
2442   sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
2443   
2444 #ifdef DLLTOOL_ARM
2445   if (interwork)
2446     strcat (outfile, " -mthumb-interwork");
2447 #endif
2448   
2449   run (as_name, outfile);
2450
2451   return  bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
2452 }
2453
2454 static bfd *
2455 make_tail ()
2456 {
2457   FILE *  f = fopen (TMP_TAIL_S, FOPEN_WT);
2458
2459   if (!no_idata4)
2460     {
2461       fprintf (f, "\t.section   .idata$4\n");
2462       fprintf (f, "\t%s\t0\n", ASM_LONG);
2463     }
2464   if (!no_idata5)
2465     {
2466       fprintf (f, "\t.section   .idata$5\n");
2467       fprintf (f, "\t%s\t0\n", ASM_LONG);
2468     }
2469
2470 #ifdef DLLTOOL_PPC
2471   /* Normally, we need to see a null descriptor built in idata$3 to
2472      act as the terminator for the list. The ideal way, I suppose,
2473      would be to mark this section as a comdat type 2 section, so
2474      only one would appear in the final .exe (if our linker supported
2475      comdat, that is) or cause it to be inserted by something else (say
2476      crt0)
2477   */
2478
2479   fprintf (f, "\t.section       .idata$3\n");
2480   fprintf (f, "\t%s\t0\n", ASM_LONG);
2481   fprintf (f, "\t%s\t0\n", ASM_LONG);
2482   fprintf (f, "\t%s\t0\n", ASM_LONG);
2483   fprintf (f, "\t%s\t0\n", ASM_LONG);
2484   fprintf (f, "\t%s\t0\n", ASM_LONG);
2485 #endif
2486
2487 #ifdef DLLTOOL_PPC
2488   /* Other PowerPC NT compilers use idata$6 for the dllname, so I
2489      do too. Original, huh? */
2490   fprintf (f, "\t.section       .idata$6\n");
2491 #else
2492   fprintf (f, "\t.section       .idata$7\n");
2493 #endif
2494
2495   fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2496   fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
2497            imp_name_lab, ASM_TEXT, dll_name);
2498
2499   fclose (f);
2500
2501   sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
2502   
2503 #ifdef DLLTOOL_ARM
2504   if (interwork)
2505     strcat (outfile, " -mthumb-interwork");
2506 #endif
2507   
2508   run (as_name, outfile);
2509   
2510   return  bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
2511 }
2512
2513 static void
2514 gen_lib_file ()
2515 {
2516   int i;
2517   export_type *exp;
2518   bfd *ar_head;
2519   bfd *ar_tail;
2520   bfd *outarch;
2521   bfd * head  = 0;
2522
2523   unlink (imp_name);
2524
2525   outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2526
2527   if (!outarch)
2528     /* xgettext:c-format */
2529     fatal (_("Can't open .lib file: %s"), imp_name);
2530
2531   /* xgettext:c-format */
2532   inform (_("Creating library file: %s\n"), imp_name);
2533   
2534   bfd_set_format (outarch, bfd_archive);
2535   outarch->has_armap = 1;
2536
2537   /* Work out a reasonable size of things to put onto one line. */
2538
2539   ar_head = make_head ();
2540   ar_tail = make_tail();
2541
2542   if (ar_head == NULL || ar_tail == NULL)
2543     return;
2544   
2545   for (i = 0; (exp = d_exports_lexically[i]); i++)
2546     {
2547       bfd *n = make_one_lib_file (exp, i);
2548       n->next = head;
2549       head = n;
2550     }
2551
2552   /* Now stick them all into the archive */
2553
2554   ar_head->next = head;
2555   ar_tail->next = ar_head;
2556   head = ar_tail;
2557
2558   if (! bfd_set_archive_head (outarch, head))
2559     bfd_fatal ("bfd_set_archive_head");
2560   
2561   if (! bfd_close (outarch))
2562     bfd_fatal (imp_name);
2563
2564   while (head != NULL)
2565     {
2566       bfd *n = head->next;
2567       bfd_close (head);
2568       head = n;
2569     }
2570
2571   /* Delete all the temp files */
2572
2573   if (dontdeltemps == 0)
2574     {
2575       unlink (TMP_HEAD_O);
2576       unlink (TMP_HEAD_S);
2577       unlink (TMP_TAIL_O);
2578       unlink (TMP_TAIL_S);
2579     }
2580
2581   if (dontdeltemps < 2)
2582     {
2583       for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2584         {
2585           sprintf (outfile, "%s%d.o", TMP_STUB, i);
2586           if (unlink (outfile) < 0)
2587             /* xgettext:c-format */
2588             warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
2589         }
2590     }
2591   
2592   inform (_("Created lib file"));
2593 }
2594
2595 /**********************************************************************/
2596
2597 /* Run through the information gathered from the .o files and the
2598    .def file and work out the best stuff */
2599 static int
2600 pfunc (a, b)
2601      const void *a;
2602      const void *b;
2603 {
2604   export_type *ap = *(export_type **) a;
2605   export_type *bp = *(export_type **) b;
2606   if (ap->ordinal == bp->ordinal)
2607     return 0;
2608
2609   /* unset ordinals go to the bottom */
2610   if (ap->ordinal == -1)
2611     return 1;
2612   if (bp->ordinal == -1)
2613     return -1;
2614   return (ap->ordinal - bp->ordinal);
2615 }
2616
2617 static int
2618 nfunc (a, b)
2619      const void *a;
2620      const void *b;
2621 {
2622   export_type *ap = *(export_type **) a;
2623   export_type *bp = *(export_type **) b;
2624
2625   return (strcmp (ap->name, bp->name));
2626 }
2627
2628 static void
2629 remove_null_names (ptr)
2630      export_type **ptr;
2631 {
2632   int src;
2633   int dst;
2634   for (dst = src = 0; src < d_nfuncs; src++)
2635     {
2636       if (ptr[src])
2637         {
2638           ptr[dst] = ptr[src];
2639           dst++;
2640         }
2641     }
2642   d_nfuncs = dst;
2643 }
2644
2645 static void
2646 dtab (ptr)
2647      export_type **ptr;
2648 {
2649 #ifdef SACDEBUG
2650   int i;
2651   for (i = 0; i < d_nfuncs; i++)
2652     {
2653       if (ptr[i])
2654         {
2655           printf ("%d %s @ %d %s%s%s\n",
2656                   i, ptr[i]->name, ptr[i]->ordinal,
2657                   ptr[i]->noname ? "NONAME " : "",
2658                   ptr[i]->constant ? "CONSTANT" : "",
2659                   ptr[i]->data ? "DATA" : "");
2660         }
2661       else
2662         printf ("empty\n");
2663     }
2664 #endif
2665 }
2666
2667 static void
2668 process_duplicates (d_export_vec)
2669      export_type **d_export_vec;
2670 {
2671   int more = 1;
2672   int i;
2673   while (more)
2674     {
2675
2676       more = 0;
2677       /* Remove duplicates */
2678       qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2679
2680       dtab (d_export_vec);
2681       for (i = 0; i < d_nfuncs - 1; i++)
2682         {
2683           if (strcmp (d_export_vec[i]->name,
2684                       d_export_vec[i + 1]->name) == 0)
2685             {
2686
2687               export_type *a = d_export_vec[i];
2688               export_type *b = d_export_vec[i + 1];
2689
2690               more = 1;
2691               
2692               /* xgettext:c-format */
2693               inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2694                       a->name, a->ordinal, b->ordinal);
2695               
2696               if (a->ordinal != -1
2697                   && b->ordinal != -1)
2698                 /* xgettext:c-format */
2699                 fatal (_("Error, duplicate EXPORT with oridinals: %s"),
2700                       a->name);
2701
2702               /* Merge attributes */
2703               b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2704               b->constant |= a->constant;
2705               b->noname |= a->noname;
2706               b->data |= a->data;
2707               d_export_vec[i] = 0;
2708             }
2709
2710           dtab (d_export_vec);
2711           remove_null_names (d_export_vec);
2712           dtab (d_export_vec);
2713         }
2714     }
2715
2716
2717   /* Count the names */
2718   for (i = 0; i < d_nfuncs; i++)
2719     {
2720       if (!d_export_vec[i]->noname)
2721         d_named_nfuncs++;
2722     }
2723 }
2724
2725 static void
2726 fill_ordinals (d_export_vec)
2727      export_type **d_export_vec;
2728 {
2729   int lowest = -1;
2730   int i;
2731   char *ptr;
2732   int size = 65536;
2733
2734   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2735
2736   /* fill in the unset ordinals with ones from our range */
2737
2738   ptr = (char *) xmalloc (size);
2739
2740   memset (ptr, 0, size);
2741
2742   /* Mark in our large vector all the numbers that are taken */
2743   for (i = 0; i < d_nfuncs; i++)
2744     {
2745       if (d_export_vec[i]->ordinal != -1)
2746         {
2747           ptr[d_export_vec[i]->ordinal] = 1;
2748           if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2749             {
2750               lowest = d_export_vec[i]->ordinal;
2751             }
2752         }
2753     }
2754
2755   /* Start at 1 for compatibility with MS toolchain.  */
2756   if (lowest == -1)
2757     lowest = 1;
2758
2759   /* Now fill in ordinals where the user wants us to choose. */
2760   for (i = 0; i < d_nfuncs; i++)
2761     {
2762       if (d_export_vec[i]->ordinal == -1)
2763         {
2764           register int j;
2765
2766           /* First try within or after any user supplied range. */
2767           for (j = lowest; j < size; j++)
2768             if (ptr[j] == 0)
2769               {
2770                 ptr[j] = 1;
2771                 d_export_vec[i]->ordinal = j;
2772                 goto done;
2773               }
2774
2775           /* Then try before the range. */
2776           for (j = lowest; j >0; j--)
2777             if (ptr[j] == 0)
2778               {
2779                 ptr[j] = 1;
2780                 d_export_vec[i]->ordinal = j;
2781                 goto done;
2782               }
2783         done:;
2784         }
2785     }
2786
2787   free (ptr);
2788
2789   /* And resort */
2790
2791   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2792
2793   /* Work out the lowest and highest ordinal numbers.  */
2794   if (d_nfuncs)
2795     {
2796       if (d_export_vec[0])
2797         d_low_ord = d_export_vec[0]->ordinal;
2798       if (d_export_vec[d_nfuncs-1])
2799         d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2800     }
2801 }
2802
2803 static int
2804 alphafunc (av,bv)
2805      const void *av;
2806      const void *bv;
2807 {
2808   const export_type **a = (const export_type **) av;
2809   const export_type **b = (const export_type **) bv;
2810
2811   return strcmp ((*a)->name, (*b)->name);
2812 }
2813
2814 static void
2815 mangle_defs ()
2816 {
2817   /* First work out the minimum ordinal chosen */
2818
2819   export_type *exp;
2820
2821   int i;
2822   int hint = 0;
2823   export_type **d_export_vec
2824   = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2825
2826   inform (_("Processing definitions"));
2827   
2828   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2829     {
2830       d_export_vec[i] = exp;
2831     }
2832
2833   process_duplicates (d_export_vec);
2834   fill_ordinals (d_export_vec);
2835
2836   /* Put back the list in the new order */
2837   d_exports = 0;
2838   for (i = d_nfuncs - 1; i >= 0; i--)
2839     {
2840       d_export_vec[i]->next = d_exports;
2841       d_exports = d_export_vec[i];
2842     }
2843
2844   /* Build list in alpha order */
2845   d_exports_lexically = (export_type **)
2846     xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
2847
2848   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2849     {
2850       d_exports_lexically[i] = exp;
2851     }
2852   d_exports_lexically[i] = 0;
2853
2854   qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2855
2856   /* Fill exp entries with their hint values */
2857
2858   for (i = 0; i < d_nfuncs; i++)
2859     {
2860       if (!d_exports_lexically[i]->noname || show_allnames)
2861         d_exports_lexically[i]->hint = hint++;
2862     }
2863   
2864   inform (_("Processed definitions"));
2865 }
2866
2867 /**********************************************************************/
2868
2869 static void
2870 usage (file, status)
2871      FILE *file;
2872      int status;
2873 {
2874   /* xgetext:c-format */
2875   fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
2876   /* xgetext:c-format */
2877   fprintf (file, _("   -m --machine <machine>    Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname);
2878   fprintf (file, _("   -e --output-exp <outname> Generate an export file.\n"));
2879   fprintf (file, _("   -l --output-lib <outname> Generate an interface library.\n"));
2880   fprintf (file, _("   -a --add-indirect         Add dll indirects to export file.\n"));
2881   fprintf (file, _("   -D --dllname <name>       Name of input dll to put into interface lib.\n"));
2882   fprintf (file, _("   -d --input-def <deffile>  Name of .def file to be read in.\n"));
2883   fprintf (file, _("   -z --output-def <deffile> Name of .def file to be created.\n"));
2884   fprintf (file, _("   --export-all-symbols      Export all symbols to .def\n"));
2885   fprintf (file, _("   --no-export-all-symbols   Only export listed symbols\n"));
2886   fprintf (file, _("   --exclude-symbols <list>  Don't export <list>\n"));
2887   fprintf (file, _("   --no-default-excludes     Clear default exclude symbols\n"));
2888   fprintf (file, _("   -b --base-file <basefile> Read linker generated base file.\n"));
2889   fprintf (file, _("   -x --no-idata4            Don't generate idata$4 section.\n"));
2890   fprintf (file, _("   -c --no-idata5            Don't generate idata$5 section.\n"));
2891   fprintf (file, _("   -U --add-underscore       Add underscores to symbols in interface library.\n"));
2892   fprintf (file, _("   -k --kill-at              Kill @<n> from exported names.\n"));
2893   fprintf (file, _("   -S --as <name>            Use <name> for assembler.\n"));
2894   fprintf (file, _("   -f --as-flags <flags>     Pass <flags> to the assembler.\n"));
2895 #ifdef DLLTOOL_ARM
2896   fprintf (file, _("   -i --interwork            Support ARM/Thumb interworking.\n"));
2897 #endif
2898   fprintf (file, _("   -n --no-delete            Keep temp files (repeat for extra preservation).\n"));
2899   fprintf (file, _("   -v --verbose              Be verbose.\n"));
2900   fprintf (file, _("   -V --version              Display the program version.\n"));
2901   fprintf (file, _("   -h --help                 Display this information.\n"));
2902   
2903   exit (status);
2904 }
2905
2906 #define OPTION_EXPORT_ALL_SYMS          150
2907 #define OPTION_NO_EXPORT_ALL_SYMS       (OPTION_EXPORT_ALL_SYMS + 1)
2908 #define OPTION_EXCLUDE_SYMS             (OPTION_NO_EXPORT_ALL_SYMS + 1)
2909 #define OPTION_NO_DEFAULT_EXCLUDES      (OPTION_EXCLUDE_SYMS + 1)
2910 #define OPTION_NO_IDATA4                'x'
2911 #define OPTION_NO_IDATA5                'c'
2912
2913 static const struct option long_options[] =
2914 {
2915   {"no-delete", no_argument, NULL, 'n'},
2916   {"dllname", required_argument, NULL, 'D'},
2917   {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2918   {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2919   {"output-exp", required_argument, NULL, 'e'},
2920   {"output-def", required_argument, NULL, 'z'},
2921   {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
2922   {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
2923   {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
2924   {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
2925   {"output-lib", required_argument, NULL, 'l'},
2926   {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
2927   {"input-def", required_argument, NULL, 'd'},
2928   {"add-underscore", no_argument, NULL, 'U'},
2929   {"kill-at", no_argument, NULL, 'k'},
2930   {"verbose", no_argument, NULL, 'v'},
2931   {"version", no_argument, NULL, 'V'},
2932   {"help", no_argument, NULL, 'h'},
2933   {"machine", required_argument, NULL, 'm'},
2934   {"add-indirect", no_argument, NULL, 'a'},
2935   {"base-file", required_argument, NULL, 'b'},
2936   {"as", required_argument, NULL, 'S'},
2937   {"as-flags", required_argument, NULL, 'f'},
2938 #ifdef DLLTOOL_ARM
2939   {"interwork", no_argument, NULL, 'i'},
2940 #endif
2941   {0}
2942 };
2943
2944 int
2945 main (ac, av)
2946      int ac;
2947      char **av;
2948 {
2949   int c;
2950   int i;
2951   char *firstarg = 0;
2952   program_name = av[0];
2953   oav = av;
2954
2955 #ifdef HAVE_SETLOCALE
2956   setlocale (LC_MESSAGES, "");
2957 #endif
2958   bindtextdomain (PACKAGE, LOCALEDIR);
2959   textdomain (PACKAGE);
2960
2961   while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkvVb:Uh?m:d:f:i",
2962                            long_options, 0))
2963          != EOF)
2964     {
2965       switch (c)
2966         {
2967         case OPTION_NO_IDATA4:
2968           no_idata4 = 1;
2969           break;
2970         case OPTION_NO_IDATA5:
2971           no_idata5 = 1;
2972           break;
2973         case OPTION_EXPORT_ALL_SYMS:
2974           export_all_symbols = true;
2975           break;
2976         case OPTION_NO_EXPORT_ALL_SYMS:
2977           export_all_symbols = false;
2978           break;
2979         case OPTION_EXCLUDE_SYMS:
2980           add_excludes (optarg);
2981           break;
2982         case OPTION_NO_DEFAULT_EXCLUDES:
2983           do_default_excludes = false;
2984           break;
2985         case 'S':
2986           as_name = optarg;
2987           break;
2988         case 'f':
2989           as_flags = optarg;
2990           break;
2991
2992           /* ignored for compatibility */
2993         case 'u':
2994           break;
2995         case 'a':
2996           add_indirect = 1;
2997           break;
2998         case 'z':
2999           output_def = fopen (optarg, FOPEN_WT);
3000           break;
3001         case 'D':
3002           dll_name = optarg;
3003           break;
3004         case 'l':
3005           imp_name = optarg;
3006           break;
3007         case 'e':
3008           exp_name = optarg;
3009           break;
3010         case 'h':
3011           usage (stdout, 0);
3012           break;
3013         case 'm':
3014           mname = optarg;
3015           break;
3016         case 'v':
3017           verbose = 1;
3018           break;
3019         case 'V':
3020           print_version (program_name);
3021           break;
3022 #ifdef DLLTOOL_ARM
3023         case 'i':
3024           interwork = 1;
3025           break;
3026 #endif
3027         case 'y':
3028 #if 0
3029           /* We don't currently define YYDEBUG when building
3030              defparse.y.  */
3031           yydebug = 1;
3032 #endif
3033           break;
3034         case 'U':
3035           add_underscore = 1;
3036           break;
3037         case 'k':
3038           killat = 1;
3039           break;
3040         case 'd':
3041           def_file = optarg;
3042           break;
3043         case 'n':
3044           dontdeltemps++;
3045           break;
3046         case 'b':
3047           base_file = fopen (optarg, FOPEN_RB);
3048           
3049           if (!base_file)
3050             /* xgettext:c-format */
3051             fatal (_("Unable to open base-file: %s"), optarg);
3052
3053           break;
3054         default:
3055           usage (stderr, 1);
3056           break;
3057         }
3058     }
3059
3060   for (i = 0; mtable[i].type; i++)
3061     {
3062       if (strcmp (mtable[i].type, mname) == 0)
3063         break;
3064     }
3065
3066   if (!mtable[i].type)
3067     /* xgettext:c-format */
3068     fatal (_("Machine '%s' not supported"), mname);
3069
3070   machine = i;
3071
3072 #ifdef DLLTOOL_ARM
3073   /* Always enable interworking for Thumb targets.  */
3074   if (machine == MTHUMB && (! interwork))
3075     interwork = 1;
3076 #endif
3077   
3078   if (!dll_name && exp_name)
3079     {
3080       int len = strlen (exp_name) + 5;
3081       dll_name = xmalloc (len);
3082       strcpy (dll_name, exp_name);
3083       strcat (dll_name, ".dll");
3084     }
3085
3086   /* Don't use the default exclude list if we're reading only the
3087      symbols in the .drectve section.  The default excludes are meant
3088      to avoid exporting DLL entry point and Cygwin32 impure_ptr.  */
3089   if (! export_all_symbols)
3090     do_default_excludes = false;
3091   
3092   if (do_default_excludes)
3093     set_default_excludes ();
3094
3095   if (def_file)
3096     process_def_file (def_file);
3097
3098   while (optind < ac)
3099     {
3100       if (!firstarg)
3101         firstarg = av[optind];
3102       scan_obj_file (av[optind]);
3103       optind++;
3104     }
3105
3106   mangle_defs ();
3107
3108   if (exp_name)
3109     gen_exp_file ();
3110   
3111   if (imp_name)
3112     {
3113       /* Make imp_name safe for use as a label. */
3114       char *p;
3115
3116       imp_name_lab = xstrdup (imp_name);
3117       for (p = imp_name_lab; *p; p++)
3118         {
3119           if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
3120             *p = '_';
3121         }
3122       head_label = make_label("_head_", imp_name_lab);
3123       gen_lib_file ();
3124     }
3125   
3126   if (output_def)
3127     gen_def_file ();
3128
3129   return 0;
3130 }