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