* Makefile.am (INCLUDES): Search intl dirs for headers; define
[platform/upstream/binutils.git] / binutils / dlltool.c
1 /* dlltool.c -- tool to generate stuff for PE style DLLs 
2    Copyright (C) 1995, 96, 97, 1998 Free Software Foundation, Inc.
3
4    This file is part of GNU Binutils.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21
22 /*
23    This program allows you to build the files necessary to create
24    DLLs to run on a system which understands PE format image files.
25    (eg, Windows NT)
26
27    See "Peering Inside the PE: A Tour of the Win32 Portable Executable
28    File Format", MSJ 1994, Volume 9 for more information.
29    Also see "Microsoft Portable Executable and Common Object File Format,
30    Specification 4.1" for more information.
31
32    A DLL contains an export table which contains the information
33    which the runtime loader needs to tie up references from a
34    referencing program. 
35
36    The export table is generated by this program by reading
37    in a .DEF file or scanning the .a and .o files which will be in the
38    DLL.  A .o file can contain information in special  ".drectve" sections
39    with export information.  
40
41    A DEF file contains any number of the following commands:
42
43
44    NAME <name> [ , <base> ] 
45    The result is going to be <name>.EXE
46
47    LIBRARY <name> [ , <base> ]    
48    The result is going to be <name>.DLL
49
50    EXPORTS  ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
51    Declares name1 as an exported symbol from the
52    DLL, with optional ordinal number <integer>
53
54    IMPORTS  ( [ <name> = ] <name> . <name> ) *
55    Ignored for compatibility
56
57    DESCRIPTION <string>
58    Puts <string> into output .exp file in the .rdata section
59
60    [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
61    Generates --stack|--heap <number-reserve>,<number-commit>
62    in the output .drectve section.  The linker will
63    see this and act upon it.
64
65    [CODE|DATA] <attr>+
66    SECTIONS ( <sectionname> <attr>+ )*
67    <attr> = READ | WRITE | EXECUTE | SHARED
68    Generates --attr <sectionname> <attr> in the output
69    .drectve section.  The linker will see this and act
70    upon it.
71
72
73    A -export:<name> in a .drectve section in an input .o or .a
74    file to this program is equivalent to a EXPORTS <name>
75    in a .DEF file.
76
77
78
79    The program generates output files with the prefix supplied
80    on the command line, or in the def file, or taken from the first 
81    supplied argument.
82
83    The .exp.s file contains the information necessary to export
84    the routines in the DLL.  The .lib.s file contains the information
85    necessary to use the DLL's routines from a referencing program.
86
87
88
89    Example:
90
91    file1.c: 
92    asm (".section .drectve");  
93    asm (".ascii \"-export:adef\"");
94
95    adef(char *s)
96    {
97    printf("hello from the dll %s\n",s);
98    }
99
100    bdef(char *s)
101    {
102    printf("hello from the dll and the other entry point %s\n",s);
103    }
104
105    file2.c:
106    asm (".section .drectve");
107    asm (".ascii \"-export:cdef\"");
108    asm (".ascii \"-export:ddef\"");
109    cdef(char *s)
110    {
111    printf("hello from the dll %s\n",s);
112    }
113
114    ddef(char *s)
115    {
116    printf("hello from the dll and the other entry point %s\n",s);
117    }
118
119    printf()
120    {
121    return 9;
122    }
123
124    main.c
125
126    main()
127    {
128    cdef();
129    }
130
131    thedll.def
132
133    LIBRARY thedll
134    HEAPSIZE 0x40000, 0x2000
135    EXPORTS bdef @ 20
136    cdef @ 30 NONAME 
137
138    SECTIONS donkey READ WRITE
139    aardvark EXECUTE
140
141
142    # compile up the parts of the dll
143
144    gcc -c file1.c       
145    gcc -c file2.c
146
147    # put them in a library (you don't have to, you
148    # could name all the .os on the dlltool line)
149
150    ar  qcv thedll.in file1.o file2.o
151    ranlib thedll.in
152
153    # run this tool over the library and the def file
154    ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
155
156    # build the dll with the library with file1.o, file2.o and the export table
157    ld -o thedll.dll thedll.o thedll.in
158
159    # build the mainline
160    gcc -c themain.c 
161
162    # link the executable with the import library
163    ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
164
165  */
166
167 /* .idata section description
168
169    The .idata section is the import table.  It is a collection of several
170    subsections used to keep the pieces for each dll together: .idata$[234567].
171    IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
172
173    .idata$2 = Import Directory Table
174    = array of IMAGE_IMPORT_DESCRIPTOR's.
175
176         DWORD   Characteristics;      - pointer to .idata$4
177         DWORD   TimeDateStamp;        - currently always 0
178         DWORD   ForwarderChain;       - currently always 0
179         DWORD   Name;                 - pointer to dll's name
180         PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
181
182    .idata$3 = null terminating entry for .idata$2.
183
184    .idata$4 = Import Lookup Table
185    = array of array of pointers to hint name table.
186    There is one for each dll being imported from, and each dll's set is
187    terminated by a trailing NULL.
188
189    .idata$5 = Import Address Table
190    = array of array of pointers to hint name table.
191    There is one for each dll being imported from, and each dll's set is
192    terminated by a trailing NULL.
193    Initially, this table is identical to the Import Lookup Table.  However,
194    at load time, the loader overwrites the entries with the address of the
195    function.
196
197    .idata$6 = Hint Name Table
198    = Array of { short, asciz } entries, one for each imported function.
199    The `short' is the function's ordinal number.
200
201    .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
202 */
203
204 /* AIX requires this to be the first thing in the file.  */
205 #ifndef __GNUC__
206 # ifdef _AIX
207  #pragma alloca
208 #endif
209 #endif
210
211 #define show_allnames 0
212
213 #define PAGE_SIZE 4096
214 #define PAGE_MASK (-PAGE_SIZE)
215 #include "bfd.h"
216 #include "libiberty.h"
217 #include "bucomm.h"
218 #include "getopt.h"
219 #include "demangle.h"
220 #include "dlltool.h"
221
222 #include <ctype.h>
223 #include <time.h>
224
225 #ifdef HAVE_SYS_WAIT_H
226 #include <sys/wait.h>
227 #else /* ! HAVE_SYS_WAIT_H */
228 #if ! defined (_WIN32) || defined (__CYGWIN32__)
229 #ifndef WIFEXITED
230 #define WIFEXITED(w)    (((w)&0377) == 0)
231 #endif
232 #ifndef WIFSIGNALED
233 #define WIFSIGNALED(w)  (((w)&0377) != 0177 && ((w)&~0377) == 0)
234 #endif
235 #ifndef WTERMSIG
236 #define WTERMSIG(w)     ((w) & 0177)
237 #endif
238 #ifndef WEXITSTATUS
239 #define WEXITSTATUS(w)  (((w) >> 8) & 0377)
240 #endif
241 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
242 #ifndef WIFEXITED
243 #define WIFEXITED(w)    (((w) & 0xff) == 0)
244 #endif
245 #ifndef WIFSIGNALED
246 #define WIFSIGNALED(w)  (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
247 #endif
248 #ifndef WTERMSIG
249 #define WTERMSIG(w)     ((w) & 0x7f)
250 #endif
251 #ifndef WEXITSTATUS
252 #define WEXITSTATUS(w)  (((w) & 0xff00) >> 8)
253 #endif
254 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
255 #endif /* ! HAVE_SYS_WAIT_H */
256
257 static char *as_name = "as";
258
259 static int no_idata4;
260 static int no_idata5;
261 static char *exp_name;
262 static char *imp_name;
263 static char *head_label;
264 static char *imp_name_lab;
265 static char *dll_name;
266
267 static int add_indirect = 0;
268 static int add_underscore = 0;
269 static int dontdeltemps = 0;
270
271 static char *def_file;
272
273 static char *program_name;
274
275 static int machine;
276 static int killat;
277 static int verbose;
278 static FILE *output_def;
279 static FILE *base_file;
280
281 #ifdef DLLTOOL_ARM
282 static const char *mname = "arm";
283 #endif
284
285 #ifdef DLLTOOL_I386
286 static const char *mname = "i386";
287 #endif
288
289 #ifdef DLLTOOL_PPC
290 static const char *mname = "ppc";
291 #endif
292
293 #define PATHMAX 250             /* What's the right name for this ? */
294
295 /* This bit of assemly does jmp * ....
296 s set how_jtab_roff to mark where the 32bit abs branch should go */
297 static const unsigned char i386_jtab[] =
298 {
299   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
300 };
301
302 static const unsigned char arm_jtab[] =
303 {
304   0x00, 0xc0, 0x9f, 0xe5,
305   0x00, 0xf0, 0x9c, 0xe5,
306   0,    0,    0,    0
307 };
308
309 /* This is the glue sequence for PowerPC PE. There is a  */
310 /* tocrel16-tocdefn reloc against the first instruction. */
311 /* We also need a IMGLUE reloc against the glue function */
312 /* to restore the toc saved by the third instruction in  */
313 /* the glue. */
314 static const unsigned char ppc_jtab[] = 
315
316   0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2)               */
317                           /*   Reloc TOCREL16 __imp_xxx  */
318   0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11)              */
319   0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1)                */
320   0xA6, 0x03, 0x89, 0x7D, /* mtctr r12                   */
321   0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11)               */
322   0x20, 0x04, 0x80, 0x4E  /* bctr                        */
323 };
324
325 #ifdef DLLTOOL_PPC
326 /* the glue instruction, picks up the toc from the stw in */
327 /* the above code: "lwz r2,4(r1)"                         */
328 static bfd_vma ppc_glue_insn = 0x80410004;
329 #endif
330
331 static char outfile[PATHMAX];
332
333 struct mac
334   {
335     const char *type;
336     const char *how_byte;
337     const char *how_short;
338     const char *how_long;
339     const char *how_asciz;
340     const char *how_comment;
341     const char *how_jump;
342     const char *how_global;
343     const char *how_space;
344     const char *how_align_short;
345     const char *how_align_long;
346     const char *how_bfd_target;
347     enum bfd_architecture how_bfd_arch;
348     const unsigned char *how_jtab;
349     int how_jtab_size; /* size of the jtab entry */
350     int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
351   };
352
353 static const struct mac mtable[] =
354 {
355   {
356 #define MARM 0
357     "arm", ".byte", ".short", ".long", ".asciz", "@", 
358     "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
359     ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
360     arm_jtab, sizeof(arm_jtab),8
361   }
362   ,
363   {
364 #define M386 1
365     "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
366    i386_jtab,sizeof(i386_jtab),2,
367   }
368   ,
369   {
370 #define MPPC 2
371     "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
372    ppc_jtab,sizeof(ppc_jtab),0,
373   }
374   ,
375 {    0}
376 };
377
378 typedef struct dlist
379 {
380   char *text;
381   struct dlist *next;
382 }
383 dlist_type;
384
385 typedef struct export
386   {
387     const char *name;
388     const char *internal_name;
389     int ordinal;
390     int constant;
391     int noname;
392     int data;
393     int hint;
394     struct export *next;
395   }
396 export_type;
397
398 static const char *rvaafter PARAMS ((int));
399 static const char *rvabefore PARAMS ((int));
400 static const char *asm_prefix PARAMS ((int));
401 static void run PARAMS ((const char *, char *));
402 static void basenames PARAMS ((bfd *));
403 static void scan_open_obj_file PARAMS ((bfd *));
404 static void scan_obj_file PARAMS ((const char *));
405 static void dump_def_info PARAMS ((FILE *));
406 static int sfunc PARAMS ((const void *, const void *));
407 static void flush_page PARAMS ((FILE *, long *, int, int));
408 static void gen_def_file PARAMS ((void));
409 static void gen_exp_file PARAMS ((void));
410 static const char *xlate PARAMS ((const char *));
411 static void dump_iat PARAMS ((FILE *, export_type *));
412 static char *make_label PARAMS ((const char *, const char *));
413 static bfd *make_one_lib_file PARAMS ((export_type *, int));
414 static bfd *make_head PARAMS ((void));
415 static bfd *make_tail PARAMS ((void));
416 static void gen_lib_file PARAMS ((void));
417 static int pfunc PARAMS ((const void *, const void *));
418 static int nfunc PARAMS ((const void *, const void *));
419 static void remove_null_names PARAMS ((export_type **));
420 static void dtab PARAMS ((export_type **));
421 static void process_duplicates PARAMS ((export_type **));
422 static void fill_ordinals PARAMS ((export_type **));
423 static int alphafunc PARAMS ((const void *, const void *));
424 static void mangle_defs PARAMS ((void));
425 static void usage PARAMS ((FILE *, int));
426
427 static const char *
428 rvaafter (machine)
429      int machine;
430 {
431   switch (machine)
432     {
433     case MARM:
434       return "";
435     case M386:
436       return "";
437     case MPPC:
438       return "";
439     }
440   return "";
441 }
442
443 static const char *
444 rvabefore (machine)
445      int machine;
446 {
447   switch (machine)
448     {
449     case MARM:
450       return ".rva\t";
451     case M386:
452       return ".rva\t";
453     case MPPC:
454       return ".rva\t";
455     }
456   return "";
457 }
458
459 static const char *
460 asm_prefix (machine)
461      int machine;
462 {
463   switch (machine)
464     {
465     case MARM:
466       return "";
467     case M386:
468       return "_";
469     case MPPC:
470       return "";
471     }
472   return "";
473 }
474
475 #define ASM_BYTE        mtable[machine].how_byte
476 #define ASM_SHORT       mtable[machine].how_short
477 #define ASM_LONG        mtable[machine].how_long
478 #define ASM_TEXT        mtable[machine].how_asciz
479 #define ASM_C           mtable[machine].how_comment
480 #define ASM_JUMP        mtable[machine].how_jump
481 #define ASM_GLOBAL      mtable[machine].how_global
482 #define ASM_SPACE       mtable[machine].how_space
483 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
484 #define ASM_RVA_BEFORE  rvabefore(machine)
485 #define ASM_RVA_AFTER   rvaafter(machine)
486 #define ASM_PREFIX      asm_prefix(machine)
487 #define ASM_ALIGN_LONG mtable[machine].how_align_long
488 #define HOW_BFD_TARGET  0  /* always default*/
489 #define HOW_BFD_ARCH   mtable[machine].how_bfd_arch
490 #define HOW_JTAB       mtable[machine].how_jtab
491 #define HOW_JTAB_SIZE      mtable[machine].how_jtab_size
492 #define HOW_JTAB_ROFF      mtable[machine].how_jtab_roff
493 static char **oav;
494
495 void
496 process_def_file (name)
497      const char *name;
498 {
499   FILE *f = fopen (name, FOPEN_RT);
500   if (!f)
501     {
502       fprintf (stderr, _("%s: Can't open def file %s\n"), program_name, name);
503       exit (1);
504     }
505
506   yyin = f;
507
508   yyparse ();
509 }
510
511 /**********************************************************************/
512
513 /* Communications with the parser */
514
515 static const char *d_name;      /* Arg to NAME or LIBRARY */
516 static int d_nfuncs;            /* Number of functions exported */
517 static int d_named_nfuncs;      /* Number of named functions exported */
518 static int d_low_ord;           /* Lowest ordinal index */
519 static int d_high_ord;          /* Highest ordinal index */
520 static export_type *d_exports;  /*list of exported functions */
521 static export_type **d_exports_lexically;       /* vector of exported functions in alpha order */
522 static dlist_type *d_list;      /* Descriptions */
523 static dlist_type *a_list;      /* Stuff to go in directives */
524
525 static int d_is_dll;
526 static int d_is_exe;
527
528 int 
529 yyerror (err)
530      const char *err;
531 {
532   fprintf (stderr, _("%s: Syntax error in def file %s:%d\n"),
533            program_name, def_file, linenumber);
534   return 0;
535 }
536
537 void
538 def_exports (name, internal_name, ordinal, noname, constant, data)
539      const char *name;
540      const char *internal_name;
541      int ordinal;
542      int noname;
543      int constant;
544      int data;
545 {
546   struct export *p = (struct export *) xmalloc (sizeof (*p));
547
548   p->name = name;
549   p->internal_name = internal_name ? internal_name : name;
550   p->ordinal = ordinal;
551   p->constant = constant;
552   p->noname = noname;
553   p->data = data;
554   p->next = d_exports;
555   d_exports = p;
556   d_nfuncs++;
557 }
558
559 void
560 def_name (name, base)
561      const char *name;
562      int base;
563 {
564   if (verbose)
565     fprintf (stderr, _("%s NAME %s base %x\n"), program_name, name, base);
566   if (d_is_dll)
567     {
568       fprintf (stderr, _("Can't have LIBRARY and NAME\n"));
569     }
570   d_name = name;
571   d_is_exe = 1;
572 }
573
574 void
575 def_library (name, base)
576      const char *name;
577      int base;
578 {
579   if (verbose)
580     printf (_("%s: LIBRARY %s base %x\n"), program_name, name, base);
581   if (d_is_exe)
582     {
583       fprintf (stderr, _("%s: Can't have LIBRARY and NAME\n"), program_name);
584     }
585   d_name = name;
586   d_is_dll = 1;
587 }
588
589 void
590 def_description (desc)
591      const char *desc;
592 {
593   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
594   d->text = xstrdup (desc);
595   d->next = d_list;
596   d_list = d;
597 }
598
599 void
600 new_directive (dir)
601      char *dir;
602 {
603   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
604   d->text = xstrdup (dir);
605   d->next = a_list;
606   a_list = d;
607 }
608
609 void
610 def_stacksize (reserve, commit)
611      int reserve;
612      int commit;
613 {
614   char b[200];
615   if (commit > 0)
616     sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
617   else
618     sprintf (b, "-stack 0x%x ", reserve);
619   new_directive (xstrdup (b));
620 }
621
622 void
623 def_heapsize (reserve, commit)
624      int reserve;
625      int commit;
626 {
627   char b[200];
628   if (commit > 0)
629     sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
630   else
631     sprintf (b, "-heap 0x%x ", reserve);
632   new_directive (xstrdup (b));
633 }
634
635 void
636 def_import (internal, module, entry)
637      const char *internal;
638      const char *module;
639      const char *entry;
640 {
641   if (verbose)
642     fprintf (stderr, _("%s: IMPORTS are ignored"), program_name);
643 }
644
645 void
646 def_version (major, minor)
647      int major;
648      int minor;
649 {
650   printf ("VERSION %d.%d\n", major, minor);
651 }
652
653 void
654 def_section (name, attr)
655      const char *name;
656      int attr;
657 {
658   char buf[200];
659   char atts[5];
660   char *d = atts;
661   if (attr & 1)
662     *d++ = 'R';
663
664   if (attr & 2)
665     *d++ = 'W';
666   if (attr & 4)
667     *d++ = 'X';
668   if (attr & 8)
669     *d++ = 'S';
670   *d++ = 0;
671   sprintf (buf, "-attr %s %s", name, atts);
672   new_directive (xstrdup (buf));
673 }
674
675 void
676 def_code (attr)
677      int attr;
678 {
679
680   def_section ("CODE", attr);
681 }
682
683 void
684 def_data (attr)
685      int attr;
686 {
687   def_section ("DATA", attr);
688 }
689
690 /**********************************************************************/
691
692 static void
693 run (what, args)
694      const char *what;
695      char *args;
696 {
697   char *s;
698   int pid, wait_status;
699   int i;
700   const char **argv;
701   char *errmsg_fmt, *errmsg_arg;
702   char *temp_base = choose_temp_base ();
703
704   if (verbose)
705     fprintf (stderr, "%s %s\n", what, args);
706
707   /* Count the args */
708   i = 0;
709   for (s = args; *s; s++)
710     if (*s == ' ')
711       i++;
712   i++;
713   argv = alloca (sizeof (char *) * (i + 3));
714   i = 0;
715   argv[i++] = what;
716   s = args;
717   while (1)
718     {
719       argv[i++] = s;
720       while (*s != ' ' && *s != 0)
721         s++;
722       if (*s == 0)
723         break;
724       *s++ = 0;
725     }
726   argv[i++] = NULL;
727
728   pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
729                   &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
730
731   if (pid == -1)
732     {
733       int errno_val = errno;
734
735       fprintf (stderr, "%s: ", program_name);
736       fprintf (stderr, errmsg_fmt, errmsg_arg);
737       fprintf (stderr, ": %s\n", strerror (errno_val));
738       exit (1);
739     }
740
741   pid = pwait (pid, &wait_status, 0);
742   if (pid == -1)
743     {
744       fprintf (stderr, _("%s: wait: %s\n"), program_name, strerror (errno));
745       exit (1);
746     }
747   else if (WIFSIGNALED (wait_status))
748     {
749       fprintf (stderr, _("%s: subprocess got fatal signal %d\n"),
750                program_name, WTERMSIG (wait_status));
751       exit (1);
752     }
753   else if (WIFEXITED (wait_status))
754     {
755       if (WEXITSTATUS (wait_status) != 0)
756         fprintf (stderr, _("%s: %s exited with status %d\n"),
757                  program_name, what, WEXITSTATUS (wait_status));
758     }
759   else
760     abort ();
761 }
762
763 /* read in and block out the base relocations */
764 static void
765 basenames (abfd)
766      bfd *abfd;
767 {
768 }
769
770 static void
771 scan_open_obj_file (abfd)
772      bfd *abfd;
773 {
774   /* Look for .drectve's */
775   asection *s = bfd_get_section_by_name (abfd, ".drectve");
776   if (s)
777     {
778       int size = bfd_get_section_size_before_reloc (s);
779       char *buf = xmalloc (size);
780       char *p;
781       char *e;
782       bfd_get_section_contents (abfd, s, buf, 0, size);
783       if (verbose)
784         fprintf (stderr, _("%s: Sucking in info from %s\n"),
785                  program_name,
786                  bfd_get_filename (abfd));
787
788       /* Search for -export: strings */
789       p = buf;
790       e = buf + size;
791       while (p < e)
792         {
793           if (p[0] == '-'
794               && strncmp (p, "-export:", 8) == 0)
795             {
796               char *name;
797               char *c;
798               p += 8;
799               name = p;
800               while (p < e && *p != ' ' && *p != '-')
801                 p++;
802               c = xmalloc (p - name + 1);
803               memcpy (c, name, p - name);
804               c[p - name] = 0;
805               /* FIXME: The 5th arg is for the `constant' field.
806                  What should it be?  Not that it matters since it's not
807                  currently useful.  */
808               def_exports (c, 0, -1, 0, 0, 0);
809             }
810           else
811             p++;
812         }
813       free (buf);
814     }
815
816   basenames (abfd);
817
818   if (verbose)
819     fprintf (stderr, _("%s: Done readin\n"),
820              program_name);
821 }
822
823 static void
824 scan_obj_file (filename)
825      const char *filename;
826 {
827   bfd *f = bfd_openr (filename, 0);
828
829   if (!f)
830     {
831       fprintf (stderr, _("%s: Unable to open object file %s\n"),
832                program_name,
833                filename);
834       exit (1);
835     }
836   if (bfd_check_format (f, bfd_archive))
837     {
838       bfd *arfile = bfd_openr_next_archived_file (f, 0);
839       while (arfile)
840         {
841           if (bfd_check_format (arfile, bfd_object))
842             scan_open_obj_file (arfile);
843           bfd_close (arfile);
844           arfile = bfd_openr_next_archived_file (f, arfile);
845         }
846     }
847   else if (bfd_check_format (f, bfd_object))
848     {
849       scan_open_obj_file (f);
850     }
851
852   bfd_close (f);
853 }
854
855 /**********************************************************************/
856
857 static void
858 dump_def_info (f)
859      FILE *f;
860 {
861   int i;
862   export_type *exp;
863   fprintf (f, "%s ", ASM_C);
864   for (i = 0; oav[i]; i++)
865     fprintf (f, "%s ", oav[i]);
866   fprintf (f, "\n");
867   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
868     {
869       fprintf (f, "%s  %d = %s %s @ %d %s%s%s\n",
870                ASM_C,
871                i,
872                exp->name,
873                exp->internal_name,
874                exp->ordinal,
875                exp->noname ? "NONAME " : "",
876                exp->constant ? "CONSTANT" : "",
877                exp->data ? "DATA" : "");
878     }
879 }
880
881 /* Generate the .exp file */
882
883 static int
884 sfunc (a, b)
885      const void *a;
886      const void *b;
887 {
888   return *(const long *) a - *(const long *) b;
889 }
890
891 static void
892 flush_page (f, need, page_addr, on_page)
893      FILE *f;
894      long *need;
895      int page_addr;
896      int on_page;
897 {
898   int i;
899
900   /* Flush this page */
901   fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
902            ASM_LONG,
903            page_addr,
904            ASM_C);
905   fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
906            ASM_LONG,
907            (on_page * 2) + (on_page & 1) * 2 + 8,
908            ASM_C);
909   for (i = 0; i < on_page; i++)
910     {
911       fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
912     }
913   /* And padding */
914   if (on_page & 1)
915     fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
916 }
917
918 static void
919 gen_def_file ()
920 {
921   int i;
922   export_type *exp;
923
924   fprintf (output_def, ";");
925   for (i = 0; oav[i]; i++)
926     fprintf (output_def, " %s", oav[i]);
927
928   fprintf (output_def, "\nEXPORTS\n");
929
930   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
931     {
932       char *quote = strchr (exp->name, '.') ? "\"" : "";
933       fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
934                quote,
935                exp->name,
936                quote,
937                exp->ordinal,
938                exp->noname ? " NONAME" : "",
939                exp->data ? " DATA" : "",
940                cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS));
941     }
942 }
943
944 static void
945 gen_exp_file ()
946 {
947   FILE *f;
948   int i;
949   export_type *exp;
950   dlist_type *dl;
951
952
953   sprintf (outfile, "t%s", exp_name);
954
955   if (verbose)
956     fprintf (stderr, _("%s: Generate exp file %s\n"),
957              program_name, exp_name);
958
959   f = fopen (outfile, FOPEN_WT);
960   if (!f)
961     {
962       fprintf (stderr, _("%s: Unable to open output file %s\n"), program_name, outfile);
963       exit (1);
964     }
965   if (verbose)
966     {
967       fprintf (stderr, _("%s: Opened file %s\n"),
968                program_name, outfile);
969     }
970
971   dump_def_info (f);
972   if (d_exports)
973     {
974       fprintf (f, "\t.section   .edata\n\n");
975       fprintf (f, "\t%s 0       %s Allways 0\n", ASM_LONG, ASM_C);
976       fprintf (f, "\t%s 0x%lx   %s Time and date\n", ASM_LONG, (long) time(0),
977                ASM_C);
978       fprintf (f, "\t%s 0       %s Major and Minor version\n", ASM_LONG, ASM_C);
979       fprintf (f, "\t%sname%s   %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
980       fprintf (f, "\t%s %d      %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
981
982
983       fprintf (f, "\t%s %d      %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
984       fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
985               ASM_C,
986               d_named_nfuncs, d_low_ord, d_high_ord);
987       fprintf (f, "\t%s %d      %s Number of names\n", ASM_LONG,
988                show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
989       fprintf (f, "\t%safuncs%s  %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
990
991       fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n", 
992                ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
993
994       fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
995
996       fprintf (f, "name:        %s      \"%s\"\n", ASM_TEXT, dll_name);
997
998
999       fprintf(f,"%s Export address Table\n", ASM_C);
1000       fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
1001       fprintf (f, "afuncs:\n");
1002       i = d_low_ord;
1003
1004       for (exp = d_exports; exp; exp = exp->next)
1005         {
1006           if (exp->ordinal != i)
1007             {
1008 #if 0         
1009               fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
1010                        ASM_SPACE,
1011                        (exp->ordinal - i) * 4,
1012                        ASM_C,
1013                        i, exp->ordinal - 1);
1014               i = exp->ordinal;
1015 #endif
1016               while (i < exp->ordinal)
1017                 {
1018                   fprintf(f,"\t%s\t0\n", ASM_LONG);
1019                   i++;
1020                 }
1021             }
1022           fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
1023                    ASM_PREFIX,
1024                    exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
1025           i++;
1026         }
1027
1028       fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
1029       fprintf (f, "anames:\n");
1030
1031       for (i = 0; (exp = d_exports_lexically[i]); i++)
1032         {
1033           if (!exp->noname || show_allnames)
1034             fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
1035         }
1036
1037       fprintf (f,"%s Export Oridinal Table\n", ASM_C);
1038       fprintf (f, "anords:\n");
1039       for (i = 0; (exp = d_exports_lexically[i]); i++)
1040         {
1041           if (!exp->noname || show_allnames)
1042             fprintf (f, "\t%s   %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
1043         }
1044
1045       fprintf(f,"%s Export Name Table\n", ASM_C);
1046       for (i = 0; (exp = d_exports_lexically[i]); i++)
1047         if (!exp->noname || show_allnames)
1048           fprintf (f, "n%d:     %s      \"%s\"\n", exp->ordinal, ASM_TEXT, exp->name);
1049
1050       if (a_list)
1051         {
1052           fprintf (f, "\t.section .drectve\n");
1053           for (dl = a_list; dl; dl = dl->next)
1054             {
1055               fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1056             }
1057         }
1058       if (d_list)
1059         {
1060           fprintf (f, "\t.section .rdata\n");
1061           for (dl = d_list; dl; dl = dl->next)
1062             {
1063               char *p;
1064               int l;
1065               /* We dont output as ascii 'cause there can
1066                  be quote characters in the string */
1067
1068               l = 0;
1069               for (p = dl->text; *p; p++)
1070                 {
1071                   if (l == 0)
1072                     fprintf (f, "\t%s\t", ASM_BYTE);
1073                   else
1074                     fprintf (f, ",");
1075                   fprintf (f, "%d", *p);
1076                   if (p[1] == 0)
1077                     {
1078                       fprintf (f, ",0\n");
1079                       break;
1080                     }
1081                   if (++l == 10)
1082                     {
1083                       fprintf (f, "\n");
1084                       l = 0;
1085                     }
1086                 }
1087             }
1088         }
1089     }
1090
1091
1092   /* Add to the output file a way of getting to the exported names
1093      without using the import library. */
1094   if (add_indirect)
1095     {
1096       fprintf (f, "\t.section\t.rdata\n");
1097       for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1098         if (!exp->noname || show_allnames)
1099           {
1100             /* We use a single underscore for MS compatibility, and a
1101                double underscore for backward compatibility with old
1102                cygwin releases.  */
1103             fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1104             fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1105             fprintf (f, "__imp_%s:\n", exp->name);
1106             fprintf (f, "_imp__%s:\n", exp->name);
1107             fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1108           }
1109     }
1110
1111   /* Dump the reloc section if a base file is provided */
1112   if (base_file)
1113     {
1114       int addr;
1115       long need[PAGE_SIZE];
1116       long page_addr;
1117       int numbytes;
1118       int num_entries;
1119       long *copy;
1120       int j;
1121       int on_page;
1122       fprintf (f, "\t.section\t.init\n");
1123       fprintf (f, "lab:\n");
1124
1125       fseek (base_file, 0, SEEK_END);
1126       numbytes = ftell (base_file);
1127       fseek (base_file, 0, SEEK_SET);
1128       copy = xmalloc (numbytes);
1129       fread (copy, 1, numbytes, base_file);
1130       num_entries = numbytes / sizeof (long);
1131
1132
1133       fprintf (f, "\t.section\t.reloc\n");
1134       if (num_entries)
1135         {
1136           int src;
1137           int dst = 0;
1138           int last = -1;
1139           qsort (copy, num_entries, sizeof (long), sfunc);
1140           /* Delete duplcates */
1141           for (src = 0; src < num_entries; src++)
1142             {
1143               if (last != copy[src]) 
1144                 last = copy[dst++] = copy[src];
1145             }
1146           num_entries = dst;
1147           addr = copy[0];
1148           page_addr = addr & PAGE_MASK;         /* work out the page addr */
1149           on_page = 0;
1150           for (j = 0; j < num_entries; j++)
1151             {
1152               addr = copy[j];
1153               if ((addr & PAGE_MASK) != page_addr)
1154                 {
1155                   flush_page (f, need, page_addr, on_page);
1156                   on_page = 0;
1157                   page_addr = addr & PAGE_MASK;
1158                 }
1159               need[on_page++] = addr;
1160             }
1161           flush_page (f, need, page_addr, on_page);
1162
1163 /*        fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1164         }
1165     }
1166
1167   fclose (f);
1168
1169   /* assemble the file */
1170   sprintf (outfile, "-o %s t%s", exp_name, exp_name);
1171   run (as_name, outfile);
1172   if (dontdeltemps == 0)
1173     {
1174       sprintf (outfile, "t%s", exp_name);
1175       unlink (outfile);
1176     }
1177 }
1178
1179 static const char *
1180 xlate (name)
1181      const char *name;
1182 {
1183   if (add_underscore)
1184     {
1185       char *copy = xmalloc (strlen (name) + 2);
1186       copy[0] = '_';
1187       strcpy (copy + 1, name);
1188       name = copy;
1189     }
1190
1191   if (killat)
1192     {
1193       char *p;
1194       p = strchr (name, '@');
1195       if (p)
1196         *p = 0;
1197     }
1198   return name;
1199 }
1200
1201 /**********************************************************************/
1202
1203 static void
1204 dump_iat (f, exp)
1205      FILE *f;
1206      export_type *exp;
1207 {
1208   if (exp->noname && !show_allnames ) 
1209     {
1210       fprintf (f, "\t%s\t0x%08x\n",
1211                ASM_LONG,
1212                exp->ordinal | 0x80000000); /* hint or orindal ?? */
1213     }
1214   else
1215     {
1216       fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1217                exp->ordinal,
1218                ASM_RVA_AFTER);
1219     }
1220 }
1221
1222 typedef struct 
1223 {
1224   int id;
1225   const char *name;
1226   int flags;
1227   int align;
1228   asection *sec;
1229   asymbol *sym;
1230   asymbol **sympp;
1231   int size;
1232   unsigned   char *data;
1233 } sinfo;
1234
1235 #ifndef DLLTOOL_PPC
1236
1237 #define TEXT 0
1238 #define DATA 1
1239 #define BSS 2
1240 #define IDATA7 3
1241 #define IDATA5 4
1242 #define IDATA4 5
1243 #define IDATA6 6
1244
1245 #define NSECS 7
1246
1247 static sinfo secdata[NSECS] = 
1248 {
1249   { TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 2},
1250   { DATA,   ".data",    SEC_DATA,                    2},
1251   { BSS,    ".bss",     0,                           2},
1252   { IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2},
1253   { IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2},
1254   { IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2},
1255   { IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1}
1256 };
1257
1258 #else 
1259
1260 /* Sections numbered to make the order the same as other PowerPC NT    */
1261 /* compilers. This also keeps funny alignment thingies from happening. */
1262 #define TEXT   0
1263 #define PDATA  1
1264 #define RDATA  2
1265 #define IDATA5 3
1266 #define IDATA4 4
1267 #define IDATA6 5
1268 #define IDATA7 6
1269 #define DATA   7
1270 #define BSS    8
1271
1272 #define NSECS 9
1273
1274 static sinfo secdata[NSECS] = 
1275 {
1276   { TEXT,   ".text",    SEC_CODE | SEC_HAS_CONTENTS, 3},
1277   { PDATA,  ".pdata",   SEC_HAS_CONTENTS,            2},
1278   { RDATA,  ".reldata", SEC_HAS_CONTENTS,            2},
1279   { IDATA5, ".idata$5", SEC_HAS_CONTENTS,            2},
1280   { IDATA4, ".idata$4", SEC_HAS_CONTENTS,            2},
1281   { IDATA6, ".idata$6", SEC_HAS_CONTENTS,            1},
1282   { IDATA7, ".idata$7", SEC_HAS_CONTENTS,            2},
1283   { DATA,   ".data",    SEC_DATA,                    2},
1284   { BSS,    ".bss",     0,                           2}
1285 };
1286
1287 #endif
1288
1289 /*
1290 This is what we're trying to make.  We generate the imp symbols with
1291 both single and double underscores, for compatibility.
1292
1293         .text
1294         .global _GetFileVersionInfoSizeW@8
1295         .global __imp_GetFileVersionInfoSizeW@8
1296 _GetFileVersionInfoSizeW@8:
1297         jmp *   __imp_GetFileVersionInfoSizeW@8
1298         .section        .idata$7        # To force loading of head
1299         .long   __version_a_head
1300 # Import Address Table
1301         .section        .idata$5
1302 __imp_GetFileVersionInfoSizeW@8:
1303         .rva    ID2
1304
1305 # Import Lookup Table
1306         .section        .idata$4
1307         .rva    ID2
1308 # Hint/Name table
1309         .section        .idata$6
1310 ID2:    .short  2
1311         .asciz  "GetFileVersionInfoSizeW"
1312
1313
1314 For the PowerPC, here's the variation on the above scheme:
1315
1316 # Rather than a simple "jmp *", the code to get to the dll function 
1317 # looks like:
1318          .text
1319          lwz    r11,[tocv]__imp_function_name(r2)
1320 #                  RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1321          lwz    r12,0(r11)
1322          stw    r2,4(r1)
1323          mtctr  r12
1324          lwz    r2,4(r11)
1325          bctr
1326 */
1327
1328 static char *
1329 make_label (prefix, name)
1330      const char *prefix;
1331      const char *name;
1332 {
1333   int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1334   char *copy = xmalloc (len +1 );
1335   strcpy (copy, ASM_PREFIX);
1336   strcat (copy, prefix);
1337   strcat (copy, name);
1338   return copy;
1339 }
1340
1341 static bfd *
1342 make_one_lib_file (exp, i)
1343      export_type *exp;
1344      int i;
1345 {
1346   if (0)
1347     {
1348       FILE *f;
1349       char *prefix="d";
1350       sprintf (outfile, "%ss%d.s", prefix, i);
1351       f = fopen (outfile, FOPEN_WT);
1352       fprintf (f, "\t.text\n");
1353       fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
1354       fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1355       fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
1356       fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1357                exp->name, ASM_JUMP, exp->name);
1358
1359       fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
1360       fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
1361
1362
1363       fprintf (f,"%s Import Address Table\n", ASM_C);
1364
1365       fprintf (f, "\t.section   .idata$5\n");
1366       fprintf (f, "__imp_%s:\n", exp->name);
1367       fprintf (f, "_imp__%s:\n", exp->name);
1368
1369       dump_iat (f, exp);
1370
1371       fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
1372       fprintf (f, "\t.section   .idata$4\n");
1373
1374       dump_iat (f, exp);
1375
1376       if(!exp->noname || show_allnames) 
1377         {
1378           fprintf (f, "%s Hint/Name table\n", ASM_C);
1379           fprintf (f, "\t.section       .idata$6\n");
1380           fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);      
1381           fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1382         }
1383
1384       fclose (f);
1385
1386
1387       sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
1388
1389       run (as_name, outfile);
1390
1391     }
1392   else
1393     {
1394
1395       bfd *abfd;
1396
1397       asymbol *exp_label;
1398       asymbol *iname, *iname2;
1399       asymbol *iname_lab;
1400       asymbol **iname_lab_pp;
1401       asymbol **iname_pp;
1402
1403       /* Extra Symbols for PPC */
1404 #ifdef DLLTOOL_PPC
1405 #define EXTRA 2     
1406 #else
1407 #define EXTRA 0
1408 #endif
1409
1410 #ifdef DLLTOOL_PPC
1411       asymbol **fn_pp;
1412       asymbol **toc_pp;
1413 #endif
1414
1415       asymbol *ptrs[NSECS + 4 + EXTRA + 1];
1416
1417       char *outname = xmalloc (10);
1418       int oidx = 0;
1419       sprintf (outname, "ds%d.o",  i);
1420       abfd = bfd_openw (outname, HOW_BFD_TARGET);
1421       if (!abfd)
1422         {
1423           fprintf (stderr, _("%s: bfd_open failed open output file %s\n"), 
1424                    program_name, outname);
1425           exit (1);
1426         }
1427
1428       bfd_set_format (abfd, bfd_object);
1429       bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
1430
1431
1432       /* First make symbols for the sections */
1433       for (i = 0; i < NSECS; i++)
1434         {
1435           sinfo *si = secdata + i;
1436           if (si->id != i)
1437             abort();
1438           si->sec = bfd_make_section_old_way (abfd, si->name);
1439           bfd_set_section_flags (abfd, 
1440                                  si->sec,
1441                                  si->flags);
1442           
1443           bfd_set_section_alignment(abfd, si->sec, si->align);
1444           si->sec->output_section = si->sec;
1445           si->sym = bfd_make_empty_symbol(abfd);
1446           si->sym->name = si->sec->name;
1447           si->sym->section = si->sec;
1448           si->sym->flags = BSF_LOCAL;
1449           si->sym->value = 0;
1450           ptrs[oidx] = si->sym;
1451           si->sympp = ptrs + oidx;
1452           si->size = 0;
1453           si->data = NULL;
1454
1455           oidx++;
1456         }
1457
1458       if (! exp->data)
1459         {
1460           exp_label = bfd_make_empty_symbol (abfd);
1461           exp_label->name = make_label ("", exp->name);
1462
1463           /* On PowerPC, the function name points to a descriptor in
1464              the rdata section, the first element of which is a
1465              pointer to the code (..function_name), and the second
1466              points to the .toc */
1467 #ifdef DLLTOOL_PPC
1468           if (machine == MPPC)
1469             exp_label->section = secdata[RDATA].sec;
1470           else
1471 #endif
1472             exp_label->section = secdata[TEXT].sec;
1473
1474           exp_label->flags = BSF_GLOBAL;
1475           exp_label->value = 0;
1476
1477           ptrs[oidx++] = exp_label;
1478         }
1479
1480       /* Generate imp symbols with one underscore for Microsoft
1481          compatibility, and with two underscores for backward
1482          compatibility with old versions of cygwin.  */
1483       iname = bfd_make_empty_symbol(abfd);
1484       iname->name = make_label ("__imp_", exp->name);
1485       iname->section = secdata[IDATA5].sec;
1486       iname->flags = BSF_GLOBAL;
1487       iname->value = 0;
1488
1489       iname2 = bfd_make_empty_symbol(abfd);
1490       iname2->name = make_label ("_imp__", exp->name);
1491       iname2->section = secdata[IDATA5].sec;
1492       iname2->flags = BSF_GLOBAL;
1493       iname2->value = 0;
1494
1495       iname_lab = bfd_make_empty_symbol(abfd);
1496
1497       iname_lab->name = head_label;
1498       iname_lab->section = (asection *)&bfd_und_section;
1499       iname_lab->flags = 0;
1500       iname_lab->value = 0;
1501
1502
1503       iname_pp = ptrs + oidx;
1504       ptrs[oidx++] = iname;
1505       ptrs[oidx++] = iname2;
1506
1507       iname_lab_pp = ptrs + oidx;
1508       ptrs[oidx++] = iname_lab;
1509
1510 #ifdef DLLTOOL_PPC
1511       /* The symbol refering to the code (.text) */
1512       {
1513         asymbol *function_name;
1514
1515         function_name = bfd_make_empty_symbol(abfd);
1516         function_name->name = make_label ("..", exp->name);
1517         function_name->section = secdata[TEXT].sec;
1518         function_name->flags = BSF_GLOBAL;
1519         function_name->value = 0;
1520
1521         fn_pp = ptrs + oidx;
1522         ptrs[oidx++] = function_name;
1523       }
1524
1525       /* The .toc symbol */
1526       {
1527         asymbol *toc_symbol;    /* The .toc symbol */
1528
1529         toc_symbol = bfd_make_empty_symbol(abfd);
1530         toc_symbol->name = make_label (".", "toc");
1531         toc_symbol->section = (asection *)&bfd_und_section;
1532         toc_symbol->flags = BSF_GLOBAL;
1533         toc_symbol->value = 0;
1534
1535         toc_pp = ptrs + oidx;
1536         ptrs[oidx++] = toc_symbol;
1537       }
1538 #endif
1539
1540       ptrs[oidx] = 0;
1541
1542       for (i = 0; i < NSECS; i++)
1543         {
1544           sinfo *si = secdata + i;
1545           asection *sec = si->sec;
1546           arelent *rel;
1547           arelent **rpp;
1548
1549           switch (i) 
1550             {
1551             case TEXT:
1552               if (! exp->data)
1553                 {
1554                   si->size = HOW_JTAB_SIZE;
1555                   si->data = xmalloc (HOW_JTAB_SIZE);
1556                   memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
1557               
1558                   /* add the reloqc into idata$5 */
1559                   rel = xmalloc (sizeof (arelent));
1560                   rpp = xmalloc (sizeof (arelent *) * 2);
1561                   rpp[0] = rel;
1562                   rpp[1] = 0;
1563                   rel->address = HOW_JTAB_ROFF;
1564                   rel->addend = 0;
1565
1566                   if (machine == MPPC)
1567                     {
1568                       rel->howto = bfd_reloc_type_lookup (abfd, 
1569                                                           BFD_RELOC_16_GOTOFF);
1570                       rel->sym_ptr_ptr = iname_pp;
1571                     }
1572                   else
1573                     {
1574                       rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1575                       rel->sym_ptr_ptr = secdata[IDATA5].sympp;
1576                     }
1577                   sec->orelocation = rpp;
1578                   sec->reloc_count = 1;
1579                 }
1580               break;
1581             case IDATA4:
1582             case IDATA5:
1583               /* An idata$4 or idata$5 is one word long, and has an
1584                  rva to idata$6 */
1585           
1586               si->data = xmalloc (4);
1587               si->size = 4;
1588
1589               if (exp->noname)
1590                 {
1591                   si->data[0] = exp->ordinal ;
1592                   si->data[1] = exp->ordinal >> 8;
1593                   si->data[2] = exp->ordinal >> 16;
1594                   si->data[3] = 0x80;
1595                 }
1596               else 
1597                 {
1598                   sec->reloc_count = 1;
1599                   memset (si->data, 0, si->size);
1600                   rel = xmalloc (sizeof (arelent));
1601                   rpp = xmalloc (sizeof (arelent *) * 2);
1602                   rpp[0] = rel;
1603                   rpp[1] = 0;
1604                   rel->address = 0;
1605                   rel->addend = 0;
1606                   rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1607                   rel->sym_ptr_ptr = secdata[IDATA6].sympp;
1608                   sec->orelocation = rpp;
1609                 }
1610
1611               break;
1612
1613             case IDATA6:
1614               if (!exp->noname) 
1615                 {
1616                   /* This used to add 1 to exp->hint.  I don't know
1617                      why it did that, and it does not match what I see
1618                      in programs compiled with the MS tools.  */
1619                   int idx = exp->hint;
1620                   si->size = strlen (xlate (exp->name)) + 3;
1621                   si->data = xmalloc (si->size);
1622                   si->data[0] = idx & 0xff;
1623                   si->data[1] = idx >> 8;
1624                   strcpy (si->data + 2, xlate (exp->name));
1625                 }
1626               break;
1627             case IDATA7:
1628               si->size = 4;
1629               si->data =xmalloc(4);
1630               memset (si->data, 0, si->size);
1631               rel = xmalloc (sizeof (arelent));
1632               rpp = xmalloc (sizeof (arelent *) * 2);
1633               rpp[0] = rel;
1634               rel->address = 0;
1635               rel->addend = 0;
1636               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1637               rel->sym_ptr_ptr = iname_lab_pp;
1638               sec->orelocation = rpp;
1639               sec->reloc_count = 1;
1640               break;
1641
1642 #ifdef DLLTOOL_PPC
1643             case PDATA:
1644               {
1645                 /* The .pdata section is 5 words long. */
1646                 /* Think of it as:                     */
1647                 /* struct                              */
1648                 /* {                                   */
1649                 /*   bfd_vma BeginAddress,     [0x00]  */
1650                 /*           EndAddress,       [0x04]  */
1651                 /*           ExceptionHandler, [0x08]  */
1652                 /*           HandlerData,      [0x0c]  */
1653                 /*           PrologEndAddress; [0x10]  */
1654                 /* };                                  */
1655
1656                 /* So this pdata section setups up this as a glue linkage to
1657                    a dll routine. There are a number of house keeping things
1658                    we need to do:
1659
1660                    1. In the name of glue trickery, the ADDR32 relocs for 0, 
1661                       4, and 0x10 are set to point to the same place: 
1662                       "..function_name". 
1663                    2. There is one more reloc needed in the pdata section. 
1664                       The actual glue instruction to restore the toc on 
1665                       return is saved as the offset in an IMGLUE reloc.
1666                       So we need a total of four relocs for this section.
1667
1668                    3. Lastly, the HandlerData field is set to 0x03, to indicate
1669                       that this is a glue routine.
1670                 */
1671                 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
1672
1673                 /* alignment must be set to 2**2 or you get extra stuff */
1674                 bfd_set_section_alignment(abfd, sec, 2);
1675
1676                 si->size = 4 * 5;
1677                 si->data =xmalloc(4 * 5);
1678                 memset (si->data, 0, si->size);
1679                 rpp = xmalloc (sizeof (arelent *) * 5);
1680                 rpp[0] = imglue  = xmalloc (sizeof (arelent));
1681                 rpp[1] = ba_rel  = xmalloc (sizeof (arelent));
1682                 rpp[2] = ea_rel  = xmalloc (sizeof (arelent));
1683                 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
1684                 rpp[4] = 0;
1685
1686                 /* stick the toc reload instruction in the glue reloc */
1687                 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
1688
1689                 imglue->addend = 0;
1690                 imglue->howto = bfd_reloc_type_lookup (abfd, 
1691                                                        BFD_RELOC_32_GOTOFF);
1692                 imglue->sym_ptr_ptr = fn_pp;
1693
1694                 ba_rel->address = 0;
1695                 ba_rel->addend = 0;
1696                 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1697                 ba_rel->sym_ptr_ptr = fn_pp;
1698
1699                 bfd_put_32(abfd, 0x18, si->data + 0x04);
1700                 ea_rel->address = 4;
1701                 ea_rel->addend = 0;
1702                 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1703                 ea_rel->sym_ptr_ptr = fn_pp;
1704
1705                 /* mark it as glue */
1706                 bfd_put_32(abfd, 0x03, si->data + 0x0c);
1707
1708                 /* mark the prolog end address */
1709                 bfd_put_32(abfd, 0x0D, si->data + 0x10);
1710                 pea_rel->address = 0x10;
1711                 pea_rel->addend = 0;
1712                 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1713                 pea_rel->sym_ptr_ptr = fn_pp;
1714
1715                 sec->orelocation = rpp;
1716                 sec->reloc_count = 4;
1717                 break;
1718               }
1719             case RDATA:
1720               /* Each external function in a PowerPC PE file has a two word
1721                  descriptor consisting of:
1722                  1. The address of the code.
1723                  2. The address of the appropriate .toc
1724                  We use relocs to build this.
1725               */
1726
1727               si->size = 8;
1728               si->data = xmalloc (8);
1729               memset (si->data, 0, si->size);
1730
1731               rpp = xmalloc (sizeof (arelent *) * 3);
1732               rpp[0] = rel = xmalloc (sizeof (arelent));
1733               rpp[1] = xmalloc (sizeof (arelent));
1734               rpp[2] = 0;
1735
1736               rel->address = 0;
1737               rel->addend = 0;
1738               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1739               rel->sym_ptr_ptr = fn_pp;
1740
1741               rel = rpp[1];
1742
1743               rel->address = 4;
1744               rel->addend = 0;
1745               rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1746               rel->sym_ptr_ptr = toc_pp;
1747
1748               sec->orelocation = rpp;
1749               sec->reloc_count = 2;
1750               break;
1751 #endif /* DLLTOOL_PPC */
1752             }
1753         }
1754
1755       {
1756         bfd_vma vma = 0;
1757         /* Size up all the sections */
1758         for (i = 0; i < NSECS; i++)
1759           {
1760             sinfo *si = secdata + i;
1761
1762             bfd_set_section_size (abfd, si->sec, si->size);
1763             bfd_set_section_vma (abfd, si->sec, vma);
1764
1765 /*          vma += si->size;*/
1766           }
1767       }
1768       /* Write them out */
1769       for (i = 0; i < NSECS; i++)
1770         {
1771           sinfo *si = secdata + i;
1772
1773           if (i == IDATA5 && no_idata5)
1774             continue;
1775
1776           if (i == IDATA4 && no_idata4)
1777             continue;
1778
1779           bfd_set_section_contents (abfd, si->sec, 
1780                                     si->data, 0,
1781                                     si->size);
1782         }
1783
1784       bfd_set_symtab (abfd, ptrs, oidx);
1785       bfd_close (abfd);
1786       abfd = bfd_openr (outname, HOW_BFD_TARGET);
1787       return abfd;
1788     }
1789
1790 }
1791
1792 static bfd *
1793 make_head ()
1794 {
1795   FILE *  f = fopen ("dh.s", FOPEN_WT);
1796
1797   fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
1798   fprintf (f, "\t.section       .idata$2\n");
1799
1800   fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
1801
1802   fprintf (f, "%s:\n", head_label);
1803
1804   fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
1805            ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1806
1807   fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
1808   fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
1809   fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
1810   fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
1811   fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
1812            ASM_RVA_BEFORE,
1813            imp_name_lab,
1814            ASM_RVA_AFTER,
1815            ASM_C);
1816   fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
1817            ASM_RVA_BEFORE,
1818            ASM_RVA_AFTER, ASM_C);
1819
1820   fprintf (f, "%sStuff for compatibility\n", ASM_C);
1821
1822   if (!no_idata5) 
1823     {
1824       fprintf (f, "\t.section\t.idata$5\n");
1825       fprintf (f, "\t%s\t0\n", ASM_LONG);
1826       fprintf (f, "fthunk:\n");
1827     }
1828   if (!no_idata4) 
1829     {
1830       fprintf (f, "\t.section\t.idata$4\n");
1831
1832       fprintf (f, "\t%s\t0\n", ASM_LONG);
1833       fprintf (f, "\t.section   .idata$4\n");
1834       fprintf (f, "hname:\n");
1835     }
1836   fclose (f);
1837
1838   sprintf (outfile, "-o dh.o dh.s");
1839   run (as_name, outfile);
1840
1841   return  bfd_openr ("dh.o", HOW_BFD_TARGET);  
1842 }
1843
1844 static bfd * 
1845 make_tail ()
1846 {
1847   FILE *  f = fopen ("dt.s", FOPEN_WT);
1848
1849   if (!no_idata4) 
1850     {
1851       fprintf (f, "\t.section   .idata$4\n");
1852       fprintf (f, "\t%s\t0\n", ASM_LONG);
1853     }
1854   if (!no_idata5) 
1855     {
1856       fprintf (f, "\t.section   .idata$5\n");
1857       fprintf (f, "\t%s\t0\n", ASM_LONG);
1858     }
1859
1860 #ifdef DLLTOOL_PPC
1861   /* Normally, we need to see a null descriptor built in idata$3 to
1862      act as the terminator for the list. The ideal way, I suppose,
1863      would be to mark this section as a comdat type 2 section, so
1864      only one would appear in the final .exe (if our linker supported
1865      comdat, that is) or cause it to be inserted by something else (say
1866      crt0)
1867   */
1868
1869   fprintf (f, "\t.section       .idata$3\n");
1870   fprintf (f, "\t%s\t0\n", ASM_LONG);
1871   fprintf (f, "\t%s\t0\n", ASM_LONG);
1872   fprintf (f, "\t%s\t0\n", ASM_LONG);
1873   fprintf (f, "\t%s\t0\n", ASM_LONG);
1874   fprintf (f, "\t%s\t0\n", ASM_LONG);
1875 #endif
1876
1877 #ifdef DLLTOOL_PPC
1878   /* Other PowerPC NT compilers use idata$6 for the dllname, so I
1879      do too. Original, huh? */
1880   fprintf (f, "\t.section       .idata$6\n");
1881 #else
1882   fprintf (f, "\t.section       .idata$7\n");
1883 #endif
1884
1885   fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
1886   fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
1887            imp_name_lab, ASM_TEXT, dll_name);
1888
1889   fclose (f);
1890
1891   sprintf (outfile, "-o dt.o dt.s");
1892   run (as_name, outfile);
1893   return  bfd_openr ("dt.o", HOW_BFD_TARGET);  
1894 }
1895
1896 static void
1897 gen_lib_file ()
1898 {
1899   int i;
1900   export_type *exp;
1901   bfd *ar_head;
1902   bfd *ar_tail;
1903   bfd *outarch;
1904   bfd * head  = 0;
1905
1906   unlink (imp_name);
1907
1908   outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
1909
1910   if (!outarch)
1911     {
1912       fprintf (stderr, _("%s: Can't open .lib file %s\n"),
1913                program_name, imp_name);
1914       exit (1);
1915     }
1916   bfd_set_format (outarch, bfd_archive);
1917   outarch->has_armap = 1;
1918
1919   /* Work out a reasonable size of things to put onto one line. */
1920
1921
1922
1923   ar_head = make_head ();
1924   ar_tail = make_tail();
1925
1926   for (i = 0; (exp = d_exports_lexically[i]); i++)
1927     {
1928       bfd *n = make_one_lib_file (exp, i);
1929       n->next = head;
1930       head = n;
1931     }
1932
1933
1934   /* Now stick them all into the archive */
1935
1936   ar_head->next = head;
1937   ar_tail->next = ar_head;
1938   head = ar_tail;
1939
1940   if (! bfd_set_archive_head (outarch, head))
1941     bfd_fatal ("bfd_set_archive_head");
1942   if (! bfd_close (outarch))
1943     bfd_fatal (imp_name);
1944
1945   while (head != NULL)
1946     {
1947       bfd *n = head->next;
1948       bfd_close (head);
1949       head = n;
1950     }
1951
1952   /* Delete all the temp files */
1953
1954   if (dontdeltemps == 0)
1955     {
1956       sprintf (outfile, "dh.o");
1957       unlink (outfile);
1958       sprintf (outfile, "dh.s");
1959       unlink (outfile);
1960       sprintf (outfile, "dt.o");
1961       unlink (outfile);
1962       sprintf (outfile, "dt.s");
1963       unlink (outfile);
1964     }
1965
1966   if (dontdeltemps < 2)
1967     {
1968       for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1969         {
1970           sprintf (outfile, "ds%d.o",i);
1971           if (unlink (outfile) < 0)
1972             fprintf (stderr, _("%s: cannot delete %s: %s\n"), program_name,
1973                      outfile, strerror (errno));
1974         }
1975     }
1976 }
1977
1978 /**********************************************************************/
1979
1980 /* Run through the information gathered from the .o files and the
1981    .def file and work out the best stuff */
1982 static int
1983 pfunc (a, b)
1984      const void *a;
1985      const void *b;
1986 {
1987   export_type *ap = *(export_type **) a;
1988   export_type *bp = *(export_type **) b;
1989   if (ap->ordinal == bp->ordinal)
1990     return 0;
1991
1992   /* unset ordinals go to the bottom */
1993   if (ap->ordinal == -1)
1994     return 1;
1995   if (bp->ordinal == -1)
1996     return -1;
1997   return (ap->ordinal - bp->ordinal);
1998 }
1999
2000 static int
2001 nfunc (a, b)
2002      const void *a;
2003      const void *b;
2004 {
2005   export_type *ap = *(export_type **) a;
2006   export_type *bp = *(export_type **) b;
2007
2008   return (strcmp (ap->name, bp->name));
2009 }
2010
2011 static void
2012 remove_null_names (ptr)
2013      export_type **ptr;
2014 {
2015   int src;
2016   int dst;
2017   for (dst = src = 0; src < d_nfuncs; src++)
2018     {
2019       if (ptr[src])
2020         {
2021           ptr[dst] = ptr[src];
2022           dst++;
2023         }
2024     }
2025   d_nfuncs = dst;
2026 }
2027
2028 static void
2029 dtab (ptr)
2030      export_type **ptr;
2031 {
2032 #ifdef SACDEBUG
2033   int i;
2034   for (i = 0; i < d_nfuncs; i++)
2035     {
2036       if (ptr[i])
2037         {
2038           printf ("%d %s @ %d %s%s%s\n",
2039                   i, ptr[i]->name, ptr[i]->ordinal,
2040                   ptr[i]->noname ? "NONAME " : "",
2041                   ptr[i]->constant ? "CONSTANT" : "",
2042                   ptr[i]->data ? "DATA" : "");
2043         }
2044       else
2045         printf ("empty\n");
2046     }
2047 #endif
2048 }
2049
2050 static void
2051 process_duplicates (d_export_vec)
2052      export_type **d_export_vec;
2053 {
2054   int more = 1;
2055   int i;  
2056   while (more)
2057     {
2058
2059       more = 0;
2060       /* Remove duplicates */
2061       qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
2062
2063       dtab (d_export_vec);
2064       for (i = 0; i < d_nfuncs - 1; i++)
2065         {
2066           if (strcmp (d_export_vec[i]->name,
2067                       d_export_vec[i + 1]->name) == 0)
2068             {
2069
2070               export_type *a = d_export_vec[i];
2071               export_type *b = d_export_vec[i + 1];
2072
2073               more = 1;
2074               if (verbose)
2075                 fprintf (stderr, _("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
2076                          a->name,
2077                          a->ordinal,
2078                          b->ordinal);
2079               if (a->ordinal != -1
2080                   && b->ordinal != -1)
2081                 {
2082
2083                   fprintf (stderr, _("Error, duplicate EXPORT with oridinals %s\n"),
2084                            a->name);
2085                   exit (1);
2086                 }
2087               /* Merge attributes */
2088               b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
2089               b->constant |= a->constant;
2090               b->noname |= a->noname;
2091               b->data |= a->data;
2092               d_export_vec[i] = 0;
2093             }
2094
2095           dtab (d_export_vec);
2096           remove_null_names (d_export_vec);
2097           dtab (d_export_vec);
2098         }
2099     }
2100
2101
2102   /* Count the names */
2103   for (i = 0; i < d_nfuncs; i++)
2104     {
2105       if (!d_export_vec[i]->noname)
2106         d_named_nfuncs++;
2107     }
2108 }
2109
2110 static void
2111 fill_ordinals (d_export_vec)
2112      export_type **d_export_vec;
2113 {
2114   int lowest = -1;
2115   int i;
2116   char *ptr;
2117   int size = 65536;
2118
2119   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2120
2121   /* fill in the unset ordinals with ones from our range */
2122
2123   ptr = (char *) xmalloc (size);
2124
2125   memset (ptr, 0, size);
2126
2127   /* Mark in our large vector all the numbers that are taken */
2128   for (i = 0; i < d_nfuncs; i++)
2129     {
2130       if (d_export_vec[i]->ordinal != -1)
2131         {
2132           ptr[d_export_vec[i]->ordinal] = 1;
2133           if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
2134             {
2135               lowest = d_export_vec[i]->ordinal;
2136             }
2137         }
2138     }
2139
2140   /* Start at 1 for compatibility with MS toolchain.  */
2141   if (lowest == -1)
2142     lowest = 1;
2143
2144   /* Now fill in ordinals where the user wants us to choose. */
2145   for (i = 0; i < d_nfuncs; i++)
2146     {
2147       if (d_export_vec[i]->ordinal == -1)
2148         {
2149           register int j;
2150
2151           /* First try within or after any user supplied range. */
2152           for (j = lowest; j < size; j++)
2153             if (ptr[j] == 0)
2154               {
2155                 ptr[j] = 1;
2156                 d_export_vec[i]->ordinal = j;
2157                 goto done;
2158               }
2159
2160           /* Then try before the range. */
2161           for (j = lowest; j >0; j--)
2162             if (ptr[j] == 0)
2163               {
2164                 ptr[j] = 1;
2165                 d_export_vec[i]->ordinal = j;
2166                 goto done;
2167               }
2168         done:;
2169         }
2170     }
2171
2172   free (ptr);
2173
2174   /* And resort */
2175
2176   qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2177
2178   /* Work out the lowest and highest ordinal numbers.  */
2179   if (d_nfuncs) 
2180     {
2181       if (d_export_vec[0])
2182         d_low_ord = d_export_vec[0]->ordinal;
2183       if (d_export_vec[d_nfuncs-1])
2184         d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2185     }
2186 }
2187
2188 static int
2189 alphafunc (av,bv)
2190      const void *av;
2191      const void *bv;
2192 {
2193   const export_type **a = (const export_type **) av;
2194   const export_type **b = (const export_type **) bv;
2195
2196   return strcmp ((*a)->name, (*b)->name);
2197 }
2198
2199 static void
2200 mangle_defs ()
2201 {
2202   /* First work out the minimum ordinal chosen */
2203
2204   export_type *exp;
2205
2206   int i;
2207   int hint = 0;
2208   export_type **d_export_vec
2209   = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2210
2211   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2212     {
2213       d_export_vec[i] = exp;
2214     }
2215
2216   process_duplicates (d_export_vec);
2217   fill_ordinals (d_export_vec);
2218
2219   /* Put back the list in the new order */
2220   d_exports = 0;
2221   for (i = d_nfuncs - 1; i >= 0; i--)
2222     {
2223       d_export_vec[i]->next = d_exports;
2224       d_exports = d_export_vec[i];
2225     }
2226
2227   /* Build list in alpha order */
2228   d_exports_lexically = (export_type **)xmalloc (sizeof(export_type *)*(d_nfuncs+1));
2229
2230   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2231     {
2232       d_exports_lexically[i] = exp;
2233     }
2234   d_exports_lexically[i] = 0;
2235
2236   qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2237
2238   /* Fill exp entries with their hint values */
2239   
2240   for (i = 0; i < d_nfuncs; i++)
2241     {
2242       if (!d_exports_lexically[i]->noname || show_allnames)
2243         d_exports_lexically[i]->hint = hint++;
2244     }
2245
2246 }
2247
2248 /**********************************************************************/
2249
2250 static void
2251 usage (file, status)
2252      FILE *file;
2253      int status;
2254 {
2255   fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
2256   fprintf (file, _("   --machine <machine>\n"));
2257   fprintf (file, _("   --output-exp <outname> Generate export file.\n"));
2258   fprintf (file, _("   --output-lib <outname> Generate input library.\n"));
2259   fprintf (file, _("   --add-indirect         Add dll indirects to export file.\n"));
2260   fprintf (file, _("   --dllname <name>       Name of input dll to put into output lib.\n"));
2261   fprintf (file, _("   --def <deffile>        Name input .def file\n"));
2262   fprintf (file, _("   --output-def <deffile> Name output .def file\n"));
2263   fprintf (file, _("   --base-file <basefile> Read linker generated base file\n"));
2264   fprintf (file, _("   --no-idata4           Don't generate idata$4 section\n"));
2265   fprintf (file, _("   --no-idata5           Don't generate idata$5 section\n"));
2266   fprintf (file, _("   -v                     Verbose\n"));
2267   fprintf (file, _("   -U                     Add underscores to .lib\n"));
2268   fprintf (file, _("   -k                     Kill @<n> from exported names\n"));
2269   fprintf (file, _("   --as <name>            Use <name> for assembler\n"));
2270   fprintf (file, _("   --nodelete             Keep temp files.\n"));
2271   exit (status);
2272 }
2273
2274 #define OPTION_NO_IDATA4 'x'
2275 #define OPTION_NO_IDATA5 'c'
2276 static const struct option long_options[] =
2277 {
2278   {"nodelete", no_argument, NULL, 'n'},
2279   {"dllname", required_argument, NULL, 'D'},
2280   {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2281   {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2282   {"output-exp", required_argument, NULL, 'e'},
2283   {"output-def", required_argument, NULL, 'z'},
2284   {"output-lib", required_argument, NULL, 'l'},
2285   {"def", required_argument, NULL, 'd'},
2286   {"add-underscore", no_argument, NULL, 'U'},
2287   {"killat", no_argument, NULL, 'k'},
2288   {"help", no_argument, NULL, 'h'},
2289   {"machine", required_argument, NULL, 'm'},
2290   {"add-indirect", no_argument, NULL, 'a'},
2291   {"base-file", required_argument, NULL, 'b'},
2292   {"as", required_argument, NULL, 'S'},
2293   {0}
2294 };
2295
2296 int
2297 main (ac, av)
2298      int ac;
2299      char **av;
2300 {
2301   int c;
2302   int i;
2303   char *firstarg = 0;
2304   program_name = av[0];
2305   oav = av;
2306
2307   setlocale (LC_MESSAGES, "");
2308   bindtextdomain (PACKAGE, LOCALEDIR);
2309   textdomain (PACKAGE);
2310
2311   while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0)) 
2312          != EOF)
2313     {
2314       switch (c)
2315         {
2316         case OPTION_NO_IDATA4:
2317           no_idata4 = 1;
2318           break;
2319         case OPTION_NO_IDATA5:
2320           no_idata5 = 1;
2321           break;
2322         case 'S':
2323           as_name = optarg;
2324           break;
2325
2326           /* ignored for compatibility */
2327         case 'u':
2328           break;
2329         case 'a':
2330           add_indirect = 1;
2331           break;
2332         case 'z':
2333           output_def = fopen (optarg, FOPEN_WT);
2334           break;
2335         case 'D':
2336           dll_name = optarg;
2337           break;
2338         case 'l':
2339           imp_name = optarg;
2340           break;
2341         case 'e':
2342           exp_name = optarg;
2343           break;
2344         case 'h':
2345         case '?':
2346           usage (stderr, 0);
2347           break;
2348         case 'm':
2349           mname = optarg;
2350           break;
2351         case 'v':
2352           verbose = 1;
2353           break;
2354         case 'y':
2355 #if 0
2356           /* We don't currently define YYDEBUG when building
2357              defparse.y.  */
2358           yydebug = 1;
2359 #endif
2360           break;
2361         case 'U':
2362           add_underscore = 1;
2363           break;
2364         case 'k':
2365           killat = 1;
2366           break;
2367         case 'd':
2368           def_file = optarg;
2369           break;
2370         case 'n':
2371           dontdeltemps++;
2372           break;
2373         case 'b':
2374           base_file = fopen (optarg, FOPEN_RB);
2375           if (!base_file)
2376             {
2377               fprintf (stderr, _("%s: Unable to open base-file %s\n"),
2378                        av[0],
2379                        optarg);
2380               exit (1);
2381             }
2382           break;
2383         default:
2384           usage (stderr, 1);
2385         }
2386     }
2387
2388
2389   for (i = 0; mtable[i].type; i++)
2390     {
2391       if (strcmp (mtable[i].type, mname) == 0)
2392         break;
2393     }
2394
2395   if (!mtable[i].type)
2396     {
2397       fprintf (stderr, _("Machine not supported\n"));
2398       exit (1);
2399     }
2400   machine = i;
2401
2402
2403   if (!dll_name && exp_name)
2404     {
2405       char len = strlen (exp_name) + 5;
2406       dll_name = xmalloc (len);
2407       strcpy (dll_name, exp_name);
2408       strcat (dll_name, ".dll");
2409     }
2410
2411   if (def_file)
2412     {
2413       process_def_file (def_file);
2414     }
2415   while (optind < ac)
2416     {
2417       if (!firstarg)
2418         firstarg = av[optind];
2419       scan_obj_file (av[optind]);
2420       optind++;
2421     }
2422
2423   mangle_defs ();
2424
2425   if (exp_name)
2426     gen_exp_file ();
2427   if (imp_name)
2428     {
2429       /* Make imp_name safe for use as a label. */
2430       char *p;
2431
2432       imp_name_lab = xstrdup (imp_name);
2433       for (p = imp_name_lab; *p; p++)
2434         {
2435           if (!isalpha (*p) && !isdigit (*p))
2436             *p = '_';
2437         }
2438       head_label = make_label("_head_", imp_name_lab);
2439       gen_lib_file ();
2440     }
2441   if (output_def)
2442     gen_def_file ();
2443
2444   return 0;
2445 }