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