* config/tc-mips.c: Remove CYGNUS LOCAL comments.
[deliverable/binutils-gdb.git] / binutils / dlltool.c
CommitLineData
765e60a9
SC
1/* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995 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
fb257042 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
765e60a9
SC
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 A DLL contains an export table which contains the information
27 which the runtime loader needs to tie up references from a
28 referencing program.
29
30 The export table is generated by this program by reading
31 in a .DEF file or scanning the .a and .o files which will be in the
32 DLL. A .o file can contain information in special ".drective" sections
33 with export information.
34
35 A DEF file contains any number of the following commands:
36
37
38 NAME <name> [ , <base> ]
6f2d3212 39 The result is going to be <name>.EXE
765e60a9
SC
40
41 LIBRARY <name> [ , <base> ]
6f2d3212 42 The result is going to be <name>.DLL
765e60a9
SC
43
44 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] ) *
6f2d3212
SC
45 Declares name1 as an exported symbol from the
46 DLL, with optional ordinal number <integer>
765e60a9
SC
47
48 IMPORTS ( [ <name> = ] <name> . <name> ) *
6f2d3212 49 Ignored for compatibility
765e60a9
SC
50
51 DESCRIPTION <string>
6f2d3212 52 Puts <string> into output .exp file in the .rdata section
765e60a9
SC
53
54 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
6f2d3212
SC
55 Generates --stack|--heap <number-reserve>,<number-commit>
56 in the output .drective section. The linker will
57 see this and act upon it.
765e60a9
SC
58
59 [CODE|DATA] <attr>+
60 SECTIONS ( <sectionname> <attr>+ )*
6f2d3212
SC
61 <attr> = READ | WRITE | EXECUTE | SHARED
62 Generates --attr <sectionname> <attr> in the output
63 .drective section. The linker will see this and act
64 upon it.
765e60a9
SC
65
66
67 A -export:<name> in a .drective section in an input .o or .a
68 file to this program is equivalent to a EXPORTS <name>
69 in a .DEF file.
70
71
72
6f2d3212
SC
73 The program generates output files with the prefix supplied
74 on the command line, or in the def file, or taken from the first
75 supplied argument.
765e60a9 76
6f2d3212
SC
77 The .exp.s file contains the information necessary to export
78 the routines in the DLL. The .lib.s file contains the information
79 necessary to use the DLL's routines from a referencing program.
765e60a9
SC
80
81
82
6f2d3212 83 Example:
765e60a9 84
6f2d3212
SC
85 file1.c:
86 asm (".section .drectve");
87 asm (".ascii \"-export:adef\"");
765e60a9 88
6f2d3212
SC
89 adef(char *s)
90 {
91 printf("hello from the dll %s\n",s);
92 }
765e60a9 93
6f2d3212
SC
94 bdef(char *s)
95 {
96 printf("hello from the dll and the other entry point %s\n",s);
97 }
765e60a9 98
6f2d3212
SC
99 file2.c:
100 asm (".section .drectve");
101 asm (".ascii \"-export:cdef\"");
102 asm (".ascii \"-export:ddef\"");
103 cdef(char *s)
104 {
105 printf("hello from the dll %s\n",s);
106 }
765e60a9 107
6f2d3212
SC
108 ddef(char *s)
109 {
110 printf("hello from the dll and the other entry point %s\n",s);
111 }
765e60a9 112
6f2d3212
SC
113 printf()
114 {
115 return 9;
116 }
765e60a9 117
6f2d3212 118 main.c
765e60a9 119
6f2d3212
SC
120 main()
121 {
122 cdef();
123 }
765e60a9 124
6f2d3212 125 thedll.def
765e60a9 126
6f2d3212
SC
127 LIBRARY thedll
128 HEAPSIZE 0x40000, 0x2000
129 EXPORTS bdef @ 20
130 cdef @ 30 NONAME
765e60a9 131
6f2d3212
SC
132 SECTIONS donkey READ WRITE
133 aardvark EXECUTE
765e60a9
SC
134
135
6f2d3212 136 # compile up the parts of the dll
765e60a9 137
6f2d3212
SC
138 gcc -c file1.c
139 gcc -c file2.c
765e60a9 140
6f2d3212
SC
141 # put them in a library (you don't have to, you
142 # could name all the .os on the dlltool line)
765e60a9 143
6f2d3212
SC
144 ar qcv thedll.in file1.o file2.o
145 ranlib thedll.in
765e60a9 146
6f2d3212 147 # run this tool over the library and the def file
2757dc25 148 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
765e60a9 149
6f2d3212 150 # build the dll with the library with file1.o, file2.o and the export table
2757dc25 151 ld -o thedll.dll thedll.o thedll.in
765e60a9 152
6f2d3212
SC
153 # build the mainline
154 gcc -c themain.c
765e60a9 155
6f2d3212 156 # link the executable with the import library
2757dc25 157 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
765e60a9 158
6f2d3212 159 */
765e60a9 160
6f2d3212
SC
161#define PAGE_SIZE 4096
162#define PAGE_MASK (-PAGE_SIZE)
765e60a9
SC
163#include <stdio.h>
164#include <stdlib.h>
165#include <string.h>
166#include "getopt.h"
167#include "bfd.h"
2757dc25
SC
168#include <wait.h>
169
170char *ar_name = "ar";
171char *as_name = "as";
172char *ranlib_name = "ranlib";
fb257042 173
2757dc25
SC
174char *exp_name;
175char *imp_name;
176char *dll_name;
177
f88ebc68 178int dontdeltemps = 0;
fb257042 179
765e60a9
SC
180int yydebug;
181char *def_file;
2757dc25 182
765e60a9
SC
183char *program_name;
184char *strrchr ();
765e60a9
SC
185char *xmalloc ();
186char *strdup ();
187
188static int machine;
6f2d3212 189int suckunderscore;
00289839 190int killat;
6f2d3212
SC
191static int verbose;
192FILE *base_file;
765e60a9 193#ifdef DLLTOOL_ARM
6f2d3212 194static char *mname = "arm";
765e60a9
SC
195#endif
196
197#ifdef DLLTOOL_I386
6f2d3212 198static char *mname = "i386";
765e60a9 199#endif
6f2d3212 200#define PATHMAX 250 /* What's the right name for this ? */
765e60a9 201
6f2d3212 202char outfile[PATHMAX];
765e60a9 203struct mac
6f2d3212
SC
204 {
205 char *type;
206 char *how_byte;
207 char *how_short;
208 char *how_long;
209 char *how_asciz;
210 char *how_comment;
211 char *how_jump;
212 char *how_global;
213 char *how_space;
fb257042 214 char *how_align_short;
6f2d3212
SC
215 }
216mtable[]
217=
765e60a9 218{
6f2d3212 219 {
f88ebc68
SC
220#define MARM 0
221
2757dc25 222 "arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space", ".align\t2",
6f2d3212
SC
223 }
224 ,
225 {
f88ebc68 226#define M386 1
2757dc25
SC
227 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",
228
6f2d3212
SC
229 }
230 ,
231 0
232};
765e60a9 233
2757dc25
SC
234
235char *rvaafter (machine)
236int machine;
237{
f88ebc68
SC
238 switch (machine)
239 {
240 case MARM:
241 return "";
242 case M386:
243 return "";
244 }
2757dc25
SC
245}
246
247char *rvabefore (machine)
248int machine;
249{
f88ebc68
SC
250 switch (machine)
251 {
252 case MARM:
253 return ".rva\t";
254 case M386:
255 return ".rva\t";
256 }
2757dc25 257}
765e60a9
SC
258#define ASM_BYTE mtable[machine].how_byte
259#define ASM_SHORT mtable[machine].how_short
260#define ASM_LONG mtable[machine].how_long
261#define ASM_TEXT mtable[machine].how_asciz
262#define ASM_C mtable[machine].how_comment
263#define ASM_JUMP mtable[machine].how_jump
264#define ASM_GLOBAL mtable[machine].how_global
265#define ASM_SPACE mtable[machine].how_space
fb257042 266#define ASM_ALIGN_SHORT mtable[machine].how_align_short
2757dc25
SC
267#define ASM_RVA_BEFORE rvabefore(machine)
268#define ASM_RVA_AFTER rvaafter(machine)
6f2d3212 269
765e60a9
SC
270static char **oav;
271
272int i;
273
274FILE *yyin; /* communications with flex */
275extern int linenumber;
276void
277process_def_file (name)
278 char *name;
279{
280 FILE *f = fopen (name, "r");
281 if (!f)
282 {
6f2d3212 283 fprintf (stderr, "%s: Can't open def file %s\n", program_name, name);
765e60a9
SC
284 exit (1);
285 }
286
287 yyin = f;
288
289 yyparse ();
290}
291
292/**********************************************************************/
293
294/* Communications with the parser */
295
296
297typedef struct dlist
298{
299 char *text;
300 struct dlist *next;
6f2d3212
SC
301}
302dlist_type;
765e60a9
SC
303
304typedef struct export
6f2d3212
SC
305 {
306 char *name;
307 char *internal_name;
308 int ordinal;
309 int constant;
310 int noname;
311 struct export *next;
312 }
765e60a9
SC
313export_type;
314
315static char *d_name; /* Arg to NAME or LIBRARY */
316static int d_nfuncs; /* Number of functions exported */
317static int d_ord; /* Base ordinal index */
318static export_type *d_exports; /*list of exported functions */
6f2d3212
SC
319static dlist_type *d_list; /* Descriptions */
320static dlist_type *a_list; /* Stuff to go in directives */
765e60a9
SC
321
322static int d_is_dll;
323static int d_is_exe;
324
325yyerror ()
326{
6f2d3212
SC
327 fprintf (stderr, "%s: Syntax error in def file %s:%d\n",
328 program_name, def_file, linenumber);
765e60a9
SC
329}
330
331void
b990c244 332def_exports (name, internal_name, ordinal, noname, constant)
765e60a9 333 char *name;
b990c244 334 char *internal_name;
765e60a9
SC
335 int ordinal;
336 int noname;
337 int constant;
338{
339 struct export *p = (struct export *) xmalloc (sizeof (*p));
340
341 p->name = name;
b990c244 342 p->internal_name = internal_name ? internal_name : name;
765e60a9
SC
343 p->ordinal = ordinal;
344 p->constant = constant;
345 p->noname = noname;
346 p->next = d_exports;
347 d_exports = p;
348 d_nfuncs++;
765e60a9
SC
349}
350
6f2d3212 351
765e60a9
SC
352void
353def_name (name, base)
354 char *name;
355 int base;
356{
6f2d3212
SC
357 if (verbose)
358 fprintf (stderr, "%s NAME %s base %x\n", program_name, name, base);
765e60a9
SC
359 if (d_is_dll)
360 {
361 fprintf (stderr, "Can't have LIBRARY and NAME\n");
362 }
363 d_name = name;
765e60a9
SC
364 d_is_exe = 1;
365}
366
367void
368def_library (name, base)
369 char *name;
370 int base;
371{
6f2d3212
SC
372 if (verbose)
373 printf ("%s: LIBRARY %s base %x\n", program_name, name, base);
765e60a9
SC
374 if (d_is_exe)
375 {
6f2d3212 376 fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name);
765e60a9
SC
377 }
378 d_name = name;
765e60a9
SC
379 d_is_dll = 1;
380}
381
382void
383def_description (desc)
384 char *desc;
385{
6f2d3212 386 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
765e60a9
SC
387 d->text = strdup (desc);
388 d->next = d_list;
389 d_list = d;
390}
391
2757dc25 392void
6f2d3212
SC
393new_directive (dir)
394 char *dir;
765e60a9 395{
6f2d3212 396 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
765e60a9
SC
397 d->text = strdup (dir);
398 d->next = a_list;
399 a_list = d;
400}
401
402void
403def_stacksize (reserve, commit)
404 int reserve;
405 int commit;
406{
407 char b[200];
6f2d3212
SC
408 if (commit > 0)
409 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
410 else
411 sprintf (b, "-stack 0x%x ", reserve);
412 new_directive (strdup (b));
765e60a9
SC
413}
414
415void
416def_heapsize (reserve, commit)
417 int reserve;
418 int commit;
419{
420 char b[200];
6f2d3212
SC
421 if (commit > 0)
422 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
423 else
424 sprintf (b, "-heap 0x%x ", reserve);
425 new_directive (strdup (b));
765e60a9
SC
426}
427
428
429void
430def_import (internal, module, entry)
431 char *internal;
432 char *module;
433 char *entry;
434{
6f2d3212
SC
435 if (verbose)
436 fprintf (stderr, "%s: IMPORTS are ignored", program_name);
765e60a9
SC
437}
438
439void
440def_version (major, minor)
441{
442 printf ("VERSION %d.%d\n", major, minor);
443}
444
445
446void
447def_section (name, attr)
448 char *name;
449 int attr;
450{
451 char buf[200];
6f2d3212 452 char atts[5];
765e60a9
SC
453 char *d = atts;
454 if (attr & 1)
6f2d3212 455 *d++ = 'R';
765e60a9
SC
456
457 if (attr & 2)
458 *d++ = 'W';
459 if (attr & 4)
460 *d++ = 'X';
461 if (attr & 8)
462 *d++ = 'S';
463 *d++ = 0;
464 sprintf (buf, "-attr %s %s", name, atts);
6f2d3212 465 new_directive (strdup (buf));
765e60a9
SC
466}
467void
468def_code (attr)
469 int attr;
470{
471
6f2d3212 472 def_section ("CODE", attr);
765e60a9
SC
473}
474
475void
476def_data (attr)
477 int attr;
478{
6f2d3212 479 def_section ("DATA", attr);
765e60a9
SC
480}
481
482
483/**********************************************************************/
484
2757dc25
SC
485void
486run (what, args)
487 char *what;
488 char *args;
489{
490 char *s;
491 int pid;
492 int i;
493 char **argv;
494 extern char **environ;
495 if (verbose)
496 fprintf (stderr, "%s %s\n", what, args);
497
498 /* Count the args */
499 i = 0;
500 for (s = args; *s ; s++)
501 if (*s == ' ')
502 i++;
503 i++;
504 argv = alloca (sizeof (char *) * (i + 3));
505 i = 0;
506 argv[i++] = what;
507 s = args;
508 while (1) {
509 argv[i++] = s;
510 while (*s != ' ' && *s != 0)
511 s++;
512 if (*s == 0)
513 break;
514 *s++ = 0;
515 }
516 argv[i++] = 0;
517
518
519 pid = vfork ();
520 if (pid == 0)
521 {
522 execvp (what, argv);
523 fprintf (stderr, "%s: can't exec %s\n", program_name, what);
524 exit (1);
525 }
526 else if (pid == -1)
527 {
528 extern int errno;
529 fprintf (stderr, "%s: vfork failed, %d\n", program_name, errno);
530 exit (1);
531 }
532 else
533 {
534 int status;
4828cdba 535 waitpid (pid, &status, 0);
2757dc25
SC
536 if (status)
537 {
538 if (WIFSIGNALED (status))
539 {
540 fprintf (stderr, "%s: %s %s terminated with signal %d\n",
541 program_name, what, args, WTERMSIG (status));
542 exit (1);
543 }
544
545 if (WIFEXITED (status))
546 {
547 fprintf (stderr, "%s: %s %s terminated with exit status %d\n",
548 program_name, what, args, WEXITSTATUS (status));
549 exit (1);
550 }
551 }
552 }
553}
554
6f2d3212 555/* read in and block out the base relocations */
2757dc25 556static void
6f2d3212
SC
557basenames (abfd)
558 bfd *abfd;
559{
560
561
562
563
564}
565
765e60a9
SC
566void
567scan_open_obj_file (abfd)
568 bfd *abfd;
569{
570 /* Look for .drectives */
571 asection *s = bfd_get_section_by_name (abfd, ".drectve");
572 if (s)
573 {
574 int size = bfd_get_section_size_before_reloc (s);
575 char *buf = xmalloc (size);
576 char *p;
577 char *e;
578 bfd_get_section_contents (abfd, s, buf, 0, size);
6f2d3212
SC
579 if (verbose)
580 fprintf (stderr, "%s: Sucking in info from %s\n",
581 program_name,
582 bfd_get_filename (abfd));
765e60a9
SC
583
584 /* Search for -export: strings */
585 p = buf;
586 e = buf + size;
587 while (p < e)
588 {
589 if (p[0] == '-'
590 && strncmp (p, "-export:", 8) == 0)
591 {
592 char *name;
593 char *c;
594 p += 8;
595 name = p;
596 while (*p != ' ' && *p != '-' && p < e)
597 p++;
598 c = xmalloc (p - name + 1);
599 memcpy (c, name, p - name);
600 c[p - name] = 0;
601 def_exports (c, 0, -1, 0);
602 }
603 else
604 p++;
605 }
606 free (buf);
607 }
6f2d3212
SC
608
609 basenames (abfd);
610
611 if (verbose)
612 fprintf (stderr, "%s: Done readin\n",
613 program_name);
614
765e60a9
SC
615}
616
617
618void
619scan_obj_file (filename)
620 char *filename;
621{
622 bfd *f = bfd_openr (filename, 0);
623
624 if (!f)
625 {
2757dc25
SC
626 fprintf (stderr, "%s: Unable to open object file %s\n",
627 program_name,
6f2d3212 628 filename);
765e60a9
SC
629 exit (1);
630 }
631 if (bfd_check_format (f, bfd_archive))
632 {
633 bfd *arfile = bfd_openr_next_archived_file (f, 0);
634 while (arfile)
635 {
636 if (bfd_check_format (arfile, bfd_object))
637 scan_open_obj_file (arfile);
638 bfd_close (arfile);
639 arfile = bfd_openr_next_archived_file (f, arfile);
640 }
641 }
642
643 if (bfd_check_format (f, bfd_object))
644 {
645 scan_open_obj_file (f);
646 }
647
648 bfd_close (f);
649}
650
651/**********************************************************************/
652
653
654/* return the bit of the name before the last . */
655
656static
657char *
658prefix (name)
659 char *name;
660{
661 char *res = strdup (name);
662 char *p = strrchr (res, '.');
663 if (p)
664 *p = 0;
665 return res;
666}
667
668void
669dump_def_info (f)
6f2d3212 670 FILE *f;
765e60a9
SC
671{
672 int i;
673 export_type *exp;
6f2d3212
SC
674 fprintf (f, "%s ", ASM_C);
675 for (i = 0; oav[i]; i++)
676 fprintf (f, "%s ", oav[i]);
677 fprintf (f, "\n");
765e60a9
SC
678 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
679 {
b990c244 680 fprintf (f, "%s %d = %s %s @ %d %s%s\n",
765e60a9
SC
681 ASM_C,
682 i,
6f2d3212
SC
683 exp->name,
684 exp->internal_name,
b990c244 685 exp->ordinal,
765e60a9
SC
686 exp->noname ? "NONAME " : "",
687 exp->constant ? "CONSTANT" : "");
688 }
689}
690/* Generate the .exp file */
691
6f2d3212
SC
692int
693sfunc (a, b)
694 long *a;
695 long *b;
696{
697 return *a - *b;
698}
699
fb257042 700
fb257042 701
2757dc25 702static void
6f2d3212
SC
703flush_page (f, need, page_addr, on_page)
704 FILE *f;
705 long *need;
706 long page_addr;
707 int on_page;
708{
709 int i;
710 /* Flush this page */
4828cdba
DE
711 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
712 ASM_LONG,
ee473c97 713 page_addr,
6f2d3212
SC
714 ASM_C);
715 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
716 ASM_LONG,
717 (on_page * 2) + (on_page & 1) * 2 + 8,
718 ASM_C);
719 for (i = 0; i < on_page; i++)
720 {
721 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, need[i] - page_addr | 0x3000);
722 }
723 /* And padding */
724 if (on_page & 1)
725 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
726
727}
728
765e60a9
SC
729
730void
731gen_exp_file ()
732{
733 FILE *f;
765e60a9
SC
734 int i;
735 export_type *exp;
736 dlist_type *dl;
6f2d3212
SC
737 int had_noname = 0;
738
2757dc25 739 sprintf (outfile, "t%s", exp_name);
6f2d3212
SC
740
741 if (verbose)
742 fprintf (stderr, "%s: Generate exp file %s\n",
2757dc25 743 program_name, exp_name);
765e60a9
SC
744
745 f = fopen (outfile, "w");
746 if (!f)
747 {
6f2d3212 748 fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile);
765e60a9
SC
749 exit (1);
750 }
6f2d3212
SC
751 if (verbose)
752 {
753 fprintf (stderr, "%s: Opened file %s\n",
754 program_name, outfile);
755 }
756
765e60a9 757 dump_def_info (f);
f88ebc68
SC
758 if (d_exports) {
759 fprintf (f, "\t.section .edata\n\n");
760 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
761 fprintf (f, "\t%s %d %s Time and date\n", ASM_LONG, time (0), ASM_C);
762 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
763 fprintf (f, "\t%sname%s%s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
764 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_ord, ASM_C);
765 fprintf (f, "\t%s The next field is documented as being the number of functions\n", ASM_C);
766 fprintf (f, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C);
767 fprintf (f, "\t%s But it shouldn't be a problem, causes there's\n", ASM_C);
768 fprintf (f, "\t%s always the number of names field\n", ASM_C);
769 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_nfuncs, ASM_C);
770 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, d_nfuncs, ASM_C);
771 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
772 fprintf (f, "\t%sanames%s %s Address of names\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
773 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
774
775 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
776
777 fprintf (f, "afuncs:\n");
778 i = d_ord;
779 for (exp = d_exports; exp; exp = exp->next)
780 {
6f2d3212 781#if 0
f88ebc68
SC
782 /* This seems necessary in the doc, but in real
783 life it's not used.. */
784 if (exp->ordinal != i)
785 {
786 fprintf (f, "%s\t%s\t%d\t@ %d..%d missing\n", ASM_C, ASM_SPACE,
787 (exp->ordinal - i) * 4,
788 i, exp->ordinal - 1);
789 i = exp->ordinal;
790 }
6f2d3212 791#endif
f88ebc68
SC
792 fprintf (f, "\t%s%s%s%s %d\n",ASM_RVA_BEFORE,
793 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
794 i++;
795 }
796
797
798 fprintf (f, "anames:\n");
799 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
800 {
801 if (exp->noname)
802 {
803 had_noname = 1;
804 fprintf (f, "\t%s nNoname\n", ASM_LONG, ASM_C);
805 }
806 else
807 {
808 fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, i, ASM_RVA_AFTER);
809 }
810 }
811
812 fprintf (f, "anords:\n");
813 for (exp = d_exports; exp; exp = exp->next)
814 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_ord);
815
816 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
6f2d3212 817 if (exp->noname)
f88ebc68 818 fprintf (f, "@n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
6f2d3212 819 else
f88ebc68
SC
820 fprintf (f, "n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
821
822 if (had_noname)
823 fprintf (f, "nNoname: %s \"__noname__\"\n", ASM_TEXT);
824
825 if (a_list)
826 {
827 fprintf (f, "\t.section .drectve\n");
828 for (dl = a_list; dl; dl = dl->next)
829 {
830 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
831 }
832 }
833 if (d_list)
834 {
835 fprintf (f, "\t.section .rdata\n");
836 for (dl = d_list; dl; dl = dl->next)
837 {
838 char *p;
839 int l;
840 /* We dont output as ascii 'cause there can
841 be quote characters in the string */
842
843 l = 0;
844 for (p = dl->text; *p; p++)
845 {
846 if (l == 0)
847 fprintf (f, "\t%s\t", ASM_BYTE);
848 else
849 fprintf (f, ",");
850 fprintf (f, "%d", *p);
851 if (p[1] == 0)
852 {
853 fprintf (f, ",0\n");
854 break;
855 }
856 if (++l == 10)
857 {
858 fprintf (f, "\n");
859 l = 0;
860 }
861 }
862 }
863 }
6f2d3212 864
f88ebc68 865 }
6f2d3212
SC
866 /* Dump the reloc section if a base file is provided */
867 if (base_file)
868 {
869 int addr;
870 long need[PAGE_SIZE];
871 long page_addr;
872 int numbytes;
873 int num_entries;
874 long *copy;
875 int j;
876 int on_page;
f88ebc68
SC
877 fprintf (f,"\t.section\t.init\n");
878 fprintf (f,"lab:\n");
6f2d3212
SC
879 fprintf (f, "\t.section\t.reloc\n");
880 fseek (base_file, 0, SEEK_END);
881 numbytes = ftell (base_file);
882 fseek (base_file, 0, SEEK_SET);
883 copy = malloc (numbytes);
884 fread (copy, 1, numbytes, base_file);
885 num_entries = numbytes / sizeof (long);
886
887 qsort (copy, num_entries, sizeof (long), sfunc);
888
889 addr = copy[0];
2757dc25 890 page_addr = addr & PAGE_MASK; /* work out the page addr */
6f2d3212
SC
891 on_page = 0;
892 for (j = 0; j < num_entries; j++)
893 {
894 addr = copy[j];
895 if ((addr & PAGE_MASK) != page_addr)
896 {
897 flush_page (f, need, page_addr, on_page);
898 on_page = 0;
899 page_addr = addr & PAGE_MASK;
765e60a9 900 }
6f2d3212 901 need[on_page++] = addr;
765e60a9 902 }
6f2d3212 903 flush_page (f, need, page_addr, on_page);
ee473c97 904
2757dc25 905 fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);
765e60a9 906 }
6f2d3212 907
765e60a9 908 fclose (f);
2757dc25
SC
909
910 /* assemble the file */
911 sprintf (outfile,"-o %s t%s", exp_name, exp_name);
912 run (as_name, outfile);
f88ebc68 913 if (dontdeltemps==0)
2757dc25
SC
914 {
915 sprintf (outfile,"t%s", exp_name);
916 unlink (outfile);
917 }
765e60a9
SC
918}
919
6f2d3212
SC
920static char *
921xlate (char *name)
922{
00289839 923
6f2d3212
SC
924 if (!suckunderscore)
925 return name;
926
927 if (name[0] == '_')
928 name++;
2757dc25
SC
929 if (killat)
930 {
931 char *p;
932 p = strchr (name, '@');
933 if (p)
934 *p = 0;
935 }
6f2d3212
SC
936 return name;
937}
938
2757dc25 939
765e60a9
SC
940/**********************************************************************/
941gen_lib_file ()
942{
765e60a9 943 int i;
2757dc25 944 int sol;
765e60a9
SC
945 FILE *f;
946 export_type *exp;
2757dc25
SC
947 char *output_filename;
948 char prefix[PATHMAX];
765e60a9 949
2757dc25
SC
950 sprintf (outfile, "%s", imp_name);
951 output_filename = strdup (outfile);
765e60a9 952
2757dc25 953 unlink (output_filename);
765e60a9 954
2757dc25
SC
955 strcpy (prefix, "d");
956 sprintf (outfile, "%sh.s", prefix);
765e60a9 957
2757dc25 958 f = fopen (outfile, "w");
765e60a9
SC
959
960 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
961 fprintf (f, "\t.section .idata$2\n");
2757dc25
SC
962
963 fprintf (f, "\t%s\t__%s_head\n", ASM_GLOBAL, imp_name);
964 fprintf (f, "__%s_head:\n", imp_name);
965
f88ebc68 966 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
fb257042 967 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f88ebc68
SC
968 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
969 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
970 fprintf (f, "\t%s\t0\t%s time\n", ASM_LONG, ASM_C);
765e60a9 971 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
f88ebc68 972 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
fb257042 973 ASM_RVA_BEFORE,
2757dc25 974 imp_name,
fb257042
SC
975 ASM_RVA_AFTER,
976 ASM_C);
f88ebc68 977 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
fb257042
SC
978 ASM_RVA_BEFORE,
979 ASM_RVA_AFTER, ASM_C);
765e60a9 980
6f2d3212 981 fprintf (f, "%sStuff for compatibility\n", ASM_C);
6f2d3212
SC
982 fprintf (f, "\t.section\t.idata$5\n");
983 fprintf (f, "\t%s\t0\n", ASM_LONG);
2757dc25 984 fprintf (f, "fthunk:\n");
6f2d3212
SC
985 fprintf (f, "\t.section\t.idata$4\n");
986 fprintf (f, "\t%s\t0\n", ASM_LONG);
2757dc25
SC
987 fprintf (f, "\t.section .idata$4\n");
988 fprintf (f, "hname:\n");
989
990 fclose (f);
991
992 sprintf (outfile, "-o %sh.o %sh.s", prefix, prefix);
993 run (as_name, outfile);
6f2d3212 994
765e60a9
SC
995 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
996 {
2757dc25
SC
997 sprintf (outfile, "%ss%d.s", prefix, i);
998 f = fopen (outfile, "w");
999 fprintf (f, "\n\n\n%s ********************* \n", ASM_C);
1000 fprintf (f, "\t.text\n");
1001 fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name);
f88ebc68 1002 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2757dc25
SC
1003 fprintf (f, "%s:\n\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name);
1004
f88ebc68 1005 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
2757dc25 1006 fprintf (f, "\t%s\t__%s_head\n", ASM_LONG, imp_name);
2757dc25
SC
1007 fprintf (f, "\t.section .idata$5\n");
1008
1009
6f2d3212 1010 fprintf (f, "__imp_%s:\n", exp->name);
f88ebc68 1011 fprintf (f, "\t%sID%d%s\n",
fb257042
SC
1012 ASM_RVA_BEFORE,
1013 i,
1014 ASM_RVA_AFTER);
2757dc25
SC
1015
1016 fprintf (f, "\n%s Hint name array\n", ASM_C);
1017 fprintf (f, "\t.section .idata$4\n");
f88ebc68 1018 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
2757dc25
SC
1019 i,
1020 ASM_RVA_AFTER);
1021
1022 fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C);
1023 fprintf (f, "\t.section .idata$6\n");
1024
1025 fprintf (f, "\t%s\n", ASM_ALIGN_SHORT);
1026 fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal);
1027 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1028 fclose (f);
1029
1030
1031 sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
1032 run (as_name, outfile);
765e60a9 1033 }
2757dc25
SC
1034
1035 sprintf (outfile, "%st.s", prefix);
1036 f = fopen (outfile, "w");
56297cc6 1037 fprintf (f, "\t.section .idata$7\n");
2757dc25 1038 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name);
2757dc25
SC
1039 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
1040 imp_name, ASM_TEXT, dll_name);
1041
765e60a9 1042
765e60a9 1043 fprintf (f, "\t.section .idata$4\n");
2757dc25
SC
1044 fprintf (f, "\t%s\t0\n", ASM_LONG);
1045
1046 fprintf (f, "\t.section .idata$5\n");
1047 fprintf (f, "\t%s\t0\n", ASM_LONG);
1048 fclose (f);
1049
1050 sprintf (outfile, "-o %st.o %st.s", prefix, prefix);
1051 run (as_name, outfile);
1052
1053 /* Now stick them all into the archive */
1054
1055
1056 sprintf (outfile, "crs %s %sh.o %st.o", output_filename, prefix, prefix);
1057 run (ar_name, outfile);
1058
1059 /* Do the rest in groups of however many fit into a command line */
1060 sol = 0;
765e60a9
SC
1061 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1062 {
2757dc25
SC
1063 if (sol == 0)
1064 {
1065 sol = sprintf (outfile, "crs %s", output_filename);
1066 }
1067
1068 sol += sprintf (outfile + sol, " %ss%d.o", prefix, i);
1069
1070 if (sol >100)
1071 {
1072 run (ar_name, outfile);
1073 sol = 0;
1074 }
1075
765e60a9 1076 }
2757dc25
SC
1077 if (sol)
1078 run (ar_name, outfile);
765e60a9 1079
2757dc25 1080 /* Delete all the temp files */
765e60a9 1081
f88ebc68 1082 if (dontdeltemps == 0)
2757dc25
SC
1083 {
1084 sprintf (outfile, "%sh.o", prefix);
1085 unlink (outfile);
1086 sprintf (outfile, "%sh.s", prefix);
1087 unlink (outfile);
1088 sprintf (outfile, "%st.o", prefix);
1089 unlink (outfile);
1090 sprintf (outfile, "%st.s", prefix);
1091 unlink (outfile);
1092 }
f88ebc68
SC
1093
1094if (dontdeltemps < 2)
765e60a9
SC
1095 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1096 {
2757dc25
SC
1097 sprintf (outfile, "%ss%d.o", prefix, i);
1098 unlink (outfile);
1099 sprintf (outfile, "%ss%d.s", prefix, i);
1100 unlink (outfile);
765e60a9 1101 }
2757dc25 1102
765e60a9
SC
1103}
1104/**********************************************************************/
1105
1106/* Run through the information gathered from the .o files and the
1107 .def file and work out the best stuff */
1108int
1109pfunc (a, b)
1110 void *a;
1111 void *b;
1112{
1113 export_type *ap = *(export_type **) a;
1114 export_type *bp = *(export_type **) b;
1115 if (ap->ordinal == bp->ordinal)
1116 return 0;
1117
1118 /* unset ordinals go to the bottom */
1119 if (ap->ordinal == -1)
1120 return 1;
1121 if (bp->ordinal == -1)
1122 return -1;
1123 return (ap->ordinal - bp->ordinal);
1124}
1125
1126
1127int
1128nfunc (a, b)
1129 void *a;
1130 void *b;
1131{
1132 export_type *ap = *(export_type **) a;
1133 export_type *bp = *(export_type **) b;
1134
1135 return (strcmp (ap->name, bp->name));
1136}
1137
1138static
1139void
1140remove_null_names (ptr)
1141 export_type **ptr;
1142{
1143 int src;
1144 int dst;
1145 for (dst = src = 0; src < d_nfuncs; src++)
1146 {
1147 if (ptr[src])
1148 {
1149 ptr[dst] = ptr[src];
1150 dst++;
1151 }
1152 }
1153 d_nfuncs = dst;
1154}
1155
1156static void
1157dtab (ptr)
1158 export_type **ptr;
1159{
1160#ifdef SACDEBUG
1161 int i;
1162 for (i = 0; i < d_nfuncs; i++)
1163 {
1164 if (ptr[i])
1165 {
1166 printf ("%d %s @ %d %s%s\n",
1167 i, ptr[i]->name, ptr[i]->ordinal,
1168 ptr[i]->noname ? "NONAME " : "",
1169 ptr[i]->constant ? "CONSTANT" : "");
1170 }
1171 else
1172 printf ("empty\n");
1173 }
1174#endif
1175}
1176
1177static void
1178process_duplicates (d_export_vec)
1179 export_type **d_export_vec;
1180{
1181 int more = 1;
1182
1183 while (more)
1184 {
1185 more = 0;
1186 /* Remove duplicates */
1187 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
1188
1189 dtab (d_export_vec);
1190 for (i = 0; i < d_nfuncs - 1; i++)
1191 {
1192 if (strcmp (d_export_vec[i]->name,
1193 d_export_vec[i + 1]->name) == 0)
1194 {
1195
1196 export_type *a = d_export_vec[i];
1197 export_type *b = d_export_vec[i + 1];
1198
1199 more = 1;
6f2d3212
SC
1200 if (verbose)
1201 fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1202 a->name,
1203 a->ordinal,
1204 b->ordinal);
765e60a9
SC
1205 if (a->ordinal != -1
1206 && b->ordinal != -1)
1207 {
1208
1209 fprintf (stderr, "Error, duplicate EXPORT with oridinals %s\n",
1210 a->name);
1211 exit (1);
1212 }
1213 /* Merge attributes */
1214 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
1215 b->constant |= a->constant;
1216 b->noname |= a->noname;
1217 d_export_vec[i] = 0;
1218 }
1219
1220 dtab (d_export_vec);
1221 remove_null_names (d_export_vec);
1222 dtab (d_export_vec);
1223 }
1224 }
1225}
1226
1227static void
1228fill_ordinals (d_export_vec)
1229 export_type **d_export_vec;
1230{
1231 int lowest = 0;
6f2d3212
SC
1232 int unset = 0;
1233 char *ptr;
765e60a9
SC
1234 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1235
6f2d3212
SC
1236 /* fill in the unset ordinals with ones from our range */
1237
1238 ptr = (char *) malloc (65536);
1239
1240 memset (ptr, 65536, 0);
1241
1242 /* Mark in our large vector all the numbers that are taken */
765e60a9
SC
1243 for (i = 0; i < d_nfuncs; i++)
1244 {
6f2d3212 1245 if (d_export_vec[i]->ordinal != -1)
765e60a9 1246 {
6f2d3212
SC
1247 ptr[d_export_vec[i]->ordinal] = 1;
1248 if (lowest == 0)
1249 lowest = d_export_vec[i]->ordinal;
765e60a9 1250 }
6f2d3212
SC
1251 }
1252
1253 for (i = 0; i < d_nfuncs; i++)
1254 {
1255 if (d_export_vec[i]->ordinal == -1)
765e60a9 1256 {
6f2d3212
SC
1257 int j;
1258 for (j = lowest; j < 65536; j++)
1259 if (ptr[j] == 0)
1260 {
1261 ptr[j] = 1;
1262 d_export_vec[i]->ordinal = j;
1263 goto done;
1264 }
1265
1266 for (j = 1; j < lowest; j++)
1267 if (ptr[j] == 0)
1268 {
1269 ptr[j] = 1;
1270 d_export_vec[i]->ordinal = j;
1271 goto done;
1272 }
1273 done:;
1274
765e60a9
SC
1275 }
1276 }
1277
6f2d3212
SC
1278 free (ptr);
1279
1280 /* And resort */
1281
1282 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1283
765e60a9
SC
1284 /* Work out the lowest ordinal number */
1285 if (d_export_vec[0])
1286 d_ord = d_export_vec[0]->ordinal;
1287}
1288void
1289mangle_defs ()
1290{
1291 /* First work out the minimum ordinal chosen */
1292
1293 export_type *exp;
1294 int lowest = 0;
1295 int i;
1296 export_type **d_export_vec
1297 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
1298
1299 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1300 {
1301 d_export_vec[i] = exp;
1302 }
1303
1304 process_duplicates (d_export_vec);
1305 fill_ordinals (d_export_vec);
1306
1307 /* Put back the list in the new order */
1308 d_exports = 0;
1309 for (i = d_nfuncs - 1; i >= 0; i--)
1310 {
1311 d_export_vec[i]->next = d_exports;
1312 d_exports = d_export_vec[i];
1313 }
1314}
1315
1316
2757dc25
SC
1317
1318 /* Work out exec prefix from the name of this file */
1319void
1320workout_prefix ()
1321{
1322 char *ps = 0;
1323 char *s = 0;
1324 char *p;
1325 /* See if we're running in a devo tree */
1326 for (p = program_name; *p; p++)
1327 {
1328 if (*p == '/' || *p == '\\')
1329 {
1330 ps = s;
1331 s = p;
1332 }
1333 }
1334
1335 if (ps && strncmp (ps, "/binutils", 9) == 0)
1336 {
1337 /* running in the binutils directory, the other
1338 executables will be surrounding it in the usual places. */
1339 int len = ps - program_name;
1340 ar_name = xmalloc (len + strlen ("/binutils/ar") + 1);
1341 ranlib_name = xmalloc (len + strlen ("/binutils/ranlib") + 1);
1342 as_name = xmalloc (len + strlen ("/gas/as.new") + 1);
1343
f88ebc68
SC
1344 memcpy (ar_name, program_name, len);
1345 strcpy (ar_name + len, "/binutils/ar");
1346 memcpy (ranlib_name, program_name, len);
1347 strcpy (ranlib_name + len, "/binutils/ranlib");
1348 memcpy (as_name, program_name, len);
1349 strcpy (as_name + len, "/gas/as.new");
2757dc25
SC
1350 }
1351 else
1352 {
1353 /* Otherwise chop off any prefix and use it for the rest of the progs,
1354 so i386-win32-dll generates i386-win32-ranlib etc etc */
1355
1356 for (p = program_name; *p; p++)
1357 {
1358 if (strncmp (p, "dlltool", 7) == 0)
1359 {
1360 int len = p - program_name;
1361 ar_name = xmalloc (len + strlen ("ar") +1);
1362 ranlib_name = xmalloc (len + strlen ("ranlib")+1);
1363 as_name = xmalloc (len + strlen ("as")+1);
1364
4828cdba
DE
1365 memcpy (ar_name, program_name, len);
1366 strcpy (ar_name + len, "ar");
1367 memcpy (ranlib_name, program_name, len);
1368 strcpy (ranlib_name + len, "ranlib");
1369 memcpy (as_name, program_name, len);
1370 strcpy (as_name + len, "as");
2757dc25
SC
1371 }
1372 }
1373 }
1374}
1375
1376
765e60a9
SC
1377/**********************************************************************/
1378
1379void
1380usage (file, status)
1381 FILE *file;
1382 int status;
1383{
6f2d3212 1384 fprintf (file, "Usage %s <options> <object-files>\n", program_name);
f88ebc68
SC
1385 fprintf (file, " --machine <machine>\n");
1386 fprintf (file, " --output-exp <outname> Generate export file.\n");
1387 fprintf (file, " --output-lib <outname> Generate input library.\n");
1388 fprintf (file, " --dllname <name> Name of input dll to put into output lib.\n");
1389 fprintf (file, " --def <deffile> Name input .def file\n");
1390 fprintf (file, " --base-file <basefile> Read linker generated base file\n");
1391 fprintf (file, " -v Verbose\n");
1392 fprintf (file, " -u Remove leading underscore from .lib\n");
1393 fprintf (file, " -k Kill @<n> from exported names\n");
1394 fprintf (file, " --nodelete Keep temp files.\n");
765e60a9
SC
1395 exit (status);
1396}
1397
1398static struct option long_options[] =
1399{
2757dc25
SC
1400 {"nodelete", no_argument, NULL,'n'},
1401 {"dllname", required_argument, NULL,'D'},
1402 {"output-exp", required_argument, NULL, 'e'},
1403 {"output-lib", required_argument, NULL, 'l'},
765e60a9 1404 {"def", required_argument, NULL, 'd'},
6f2d3212 1405 {"underscore", no_argument, NULL, 'u'},
00289839 1406 {"killat", no_argument, NULL, 'k'},
765e60a9
SC
1407 {"help", no_argument, NULL, 'h'},
1408 {"machine", required_argument, NULL, 'm'},
2757dc25 1409 {"rva", required_argument, NULL, 'r'},
f88ebc68 1410/* {"image-base", required_argument, NULL, 'i'},*/
6f2d3212 1411 {"base-file", required_argument, NULL, 'b'},
765e60a9
SC
1412 0
1413};
1414
2757dc25
SC
1415
1416
765e60a9
SC
1417int
1418main (ac, av)
1419 int ac;
1420 char **av;
1421{
1422 int c;
1423 char *firstarg = 0;
1424 program_name = av[0];
1425 oav = av;
6f2d3212 1426
2757dc25 1427 while ((c = getopt_long (ac, av, "D:l:e:nr:kvbuh?m:yd:", long_options, 0)) != EOF)
765e60a9
SC
1428 {
1429 switch (c)
1430 {
2757dc25
SC
1431 case 'D':
1432 dll_name = optarg;
1433 break;
1434 case 'l':
1435 imp_name = optarg;
1436 break;
1437 case 'e':
1438 exp_name = optarg;
1439 break;
765e60a9
SC
1440 case 'h':
1441 case '?':
6f2d3212 1442 usage (stderr, 0);
765e60a9
SC
1443 break;
1444 case 'm':
1445 mname = optarg;
1446 break;
6f2d3212
SC
1447 case 'v':
1448 verbose = 1;
1449 break;
2757dc25 1450 case 'y':
765e60a9
SC
1451 yydebug = 1;
1452 break;
6f2d3212
SC
1453 case 'u':
1454 suckunderscore = 1;
1455 break;
00289839
SC
1456 case 'k':
1457 killat = 1;
1458 break;
765e60a9
SC
1459 case 'd':
1460 def_file = optarg;
1461 break;
2757dc25 1462 case 'n':
f88ebc68 1463 dontdeltemps++;
2757dc25 1464 break;
6f2d3212
SC
1465 case 'b':
1466 base_file = fopen (optarg, "r");
1467 if (!base_file)
1468 {
1469 fprintf (stderr, "%s: Unable to open base-file %s\n",
1470 av[0],
1471 optarg);
1472 exit (1);
1473 }
1474 break;
765e60a9
SC
1475 default:
1476 usage (stderr, 1);
1477 }
1478 }
1479
1480
6f2d3212 1481 for (i = 0; mtable[i].type; i++)
765e60a9
SC
1482 {
1483 if (strcmp (mtable[i].type, mname) == 0)
1484 break;
1485 }
1486
6f2d3212 1487 if (!mtable[i].type)
765e60a9 1488 {
6f2d3212
SC
1489 fprintf (stderr, "Machine not supported\n");
1490 exit (1);
765e60a9
SC
1491 }
1492 machine = i;
1493
1494
2757dc25
SC
1495 if (!dll_name && exp_name)
1496 {
1497 char len = strlen (exp_name) + 5;
1498 dll_name = xmalloc (len);
1499 strcpy (dll_name, exp_name);
1500 strcat (dll_name, ".dll");
1501 }
1502 workout_prefix ();
1503
1504
765e60a9
SC
1505 if (def_file)
1506 {
765e60a9
SC
1507 process_def_file (def_file);
1508 }
1509 while (optind < ac)
1510 {
1511 if (!firstarg)
1512 firstarg = av[optind];
1513 scan_obj_file (av[optind]);
1514 optind++;
1515 }
1516
765e60a9
SC
1517
1518 mangle_defs ();
6f2d3212 1519
2757dc25
SC
1520 if (exp_name)
1521 gen_exp_file ();
1522 if (imp_name)
1523 gen_lib_file ();
6f2d3212 1524
765e60a9
SC
1525 return 0;
1526}
2757dc25 1527
This page took 0.094644 seconds and 4 git commands to generate.