]> Git Repo - binutils.git/blame - binutils/dlltool.c
* Makefile.in (run): Link in math library too.
[binutils.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;
535 waitpid (pid, &status);
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 */
f88ebc68 711 fprintf (f, "\t%s0x%08x%s\t%s Starting RVA for chunk\n",
ee473c97
SC
712 ASM_RVA_BEFORE,
713 page_addr,
714 ASM_RVA_AFTER,
6f2d3212
SC
715 ASM_C);
716 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
717 ASM_LONG,
718 (on_page * 2) + (on_page & 1) * 2 + 8,
719 ASM_C);
720 for (i = 0; i < on_page; i++)
721 {
722 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, need[i] - page_addr | 0x3000);
723 }
724 /* And padding */
725 if (on_page & 1)
726 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
727
728}
729
765e60a9
SC
730
731void
732gen_exp_file ()
733{
734 FILE *f;
765e60a9
SC
735 int i;
736 export_type *exp;
737 dlist_type *dl;
6f2d3212
SC
738 int had_noname = 0;
739
2757dc25 740 sprintf (outfile, "t%s", exp_name);
6f2d3212
SC
741
742 if (verbose)
743 fprintf (stderr, "%s: Generate exp file %s\n",
2757dc25 744 program_name, exp_name);
765e60a9
SC
745
746 f = fopen (outfile, "w");
747 if (!f)
748 {
6f2d3212 749 fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile);
765e60a9
SC
750 exit (1);
751 }
6f2d3212
SC
752 if (verbose)
753 {
754 fprintf (stderr, "%s: Opened file %s\n",
755 program_name, outfile);
756 }
757
765e60a9 758 dump_def_info (f);
f88ebc68
SC
759 if (d_exports) {
760 fprintf (f, "\t.section .edata\n\n");
761 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
762 fprintf (f, "\t%s %d %s Time and date\n", ASM_LONG, time (0), ASM_C);
763 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
764 fprintf (f, "\t%sname%s%s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
765 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_ord, ASM_C);
766 fprintf (f, "\t%s The next field is documented as being the number of functions\n", ASM_C);
767 fprintf (f, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C);
768 fprintf (f, "\t%s But it shouldn't be a problem, causes there's\n", ASM_C);
769 fprintf (f, "\t%s always the number of names field\n", ASM_C);
770 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_nfuncs, ASM_C);
771 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, d_nfuncs, ASM_C);
772 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
773 fprintf (f, "\t%sanames%s %s Address of names\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
774 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
775
776 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
777
778 fprintf (f, "afuncs:\n");
779 i = d_ord;
780 for (exp = d_exports; exp; exp = exp->next)
781 {
6f2d3212 782#if 0
f88ebc68
SC
783 /* This seems necessary in the doc, but in real
784 life it's not used.. */
785 if (exp->ordinal != i)
786 {
787 fprintf (f, "%s\t%s\t%d\t@ %d..%d missing\n", ASM_C, ASM_SPACE,
788 (exp->ordinal - i) * 4,
789 i, exp->ordinal - 1);
790 i = exp->ordinal;
791 }
6f2d3212 792#endif
f88ebc68
SC
793 fprintf (f, "\t%s%s%s%s %d\n",ASM_RVA_BEFORE,
794 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
795 i++;
796 }
797
798
799 fprintf (f, "anames:\n");
800 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
801 {
802 if (exp->noname)
803 {
804 had_noname = 1;
805 fprintf (f, "\t%s nNoname\n", ASM_LONG, ASM_C);
806 }
807 else
808 {
809 fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, i, ASM_RVA_AFTER);
810 }
811 }
812
813 fprintf (f, "anords:\n");
814 for (exp = d_exports; exp; exp = exp->next)
815 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_ord);
816
817 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
6f2d3212 818 if (exp->noname)
f88ebc68 819 fprintf (f, "@n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
6f2d3212 820 else
f88ebc68
SC
821 fprintf (f, "n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
822
823 if (had_noname)
824 fprintf (f, "nNoname: %s \"__noname__\"\n", ASM_TEXT);
825
826 if (a_list)
827 {
828 fprintf (f, "\t.section .drectve\n");
829 for (dl = a_list; dl; dl = dl->next)
830 {
831 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
832 }
833 }
834 if (d_list)
835 {
836 fprintf (f, "\t.section .rdata\n");
837 for (dl = d_list; dl; dl = dl->next)
838 {
839 char *p;
840 int l;
841 /* We dont output as ascii 'cause there can
842 be quote characters in the string */
843
844 l = 0;
845 for (p = dl->text; *p; p++)
846 {
847 if (l == 0)
848 fprintf (f, "\t%s\t", ASM_BYTE);
849 else
850 fprintf (f, ",");
851 fprintf (f, "%d", *p);
852 if (p[1] == 0)
853 {
854 fprintf (f, ",0\n");
855 break;
856 }
857 if (++l == 10)
858 {
859 fprintf (f, "\n");
860 l = 0;
861 }
862 }
863 }
864 }
6f2d3212 865
f88ebc68 866 }
6f2d3212
SC
867 /* Dump the reloc section if a base file is provided */
868 if (base_file)
869 {
870 int addr;
871 long need[PAGE_SIZE];
872 long page_addr;
873 int numbytes;
874 int num_entries;
875 long *copy;
876 int j;
877 int on_page;
f88ebc68
SC
878 fprintf (f,"\t.section\t.init\n");
879 fprintf (f,"lab:\n");
6f2d3212
SC
880 fprintf (f, "\t.section\t.reloc\n");
881 fseek (base_file, 0, SEEK_END);
882 numbytes = ftell (base_file);
883 fseek (base_file, 0, SEEK_SET);
884 copy = malloc (numbytes);
885 fread (copy, 1, numbytes, base_file);
886 num_entries = numbytes / sizeof (long);
887
888 qsort (copy, num_entries, sizeof (long), sfunc);
889
890 addr = copy[0];
2757dc25 891 page_addr = addr & PAGE_MASK; /* work out the page addr */
6f2d3212
SC
892 on_page = 0;
893 for (j = 0; j < num_entries; j++)
894 {
895 addr = copy[j];
896 if ((addr & PAGE_MASK) != page_addr)
897 {
898 flush_page (f, need, page_addr, on_page);
899 on_page = 0;
900 page_addr = addr & PAGE_MASK;
765e60a9 901 }
6f2d3212 902 need[on_page++] = addr;
765e60a9 903 }
6f2d3212 904 flush_page (f, need, page_addr, on_page);
ee473c97 905
2757dc25 906 fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);
765e60a9 907 }
6f2d3212 908
765e60a9 909 fclose (f);
2757dc25
SC
910
911 /* assemble the file */
912 sprintf (outfile,"-o %s t%s", exp_name, exp_name);
913 run (as_name, outfile);
f88ebc68 914 if (dontdeltemps==0)
2757dc25
SC
915 {
916 sprintf (outfile,"t%s", exp_name);
917 unlink (outfile);
918 }
765e60a9
SC
919}
920
6f2d3212
SC
921static char *
922xlate (char *name)
923{
00289839 924
6f2d3212
SC
925 if (!suckunderscore)
926 return name;
927
928 if (name[0] == '_')
929 name++;
2757dc25
SC
930 if (killat)
931 {
932 char *p;
933 p = strchr (name, '@');
934 if (p)
935 *p = 0;
936 }
6f2d3212
SC
937 return name;
938}
939
2757dc25 940
765e60a9
SC
941/**********************************************************************/
942gen_lib_file ()
943{
765e60a9 944 int i;
2757dc25 945 int sol;
765e60a9
SC
946 FILE *f;
947 export_type *exp;
2757dc25
SC
948 char *output_filename;
949 char prefix[PATHMAX];
765e60a9 950
2757dc25
SC
951 sprintf (outfile, "%s", imp_name);
952 output_filename = strdup (outfile);
765e60a9 953
2757dc25 954 unlink (output_filename);
765e60a9 955
2757dc25
SC
956 strcpy (prefix, "d");
957 sprintf (outfile, "%sh.s", prefix);
765e60a9 958
2757dc25 959 f = fopen (outfile, "w");
765e60a9
SC
960
961 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
962 fprintf (f, "\t.section .idata$2\n");
2757dc25
SC
963
964 fprintf (f, "\t%s\t__%s_head\n", ASM_GLOBAL, imp_name);
965 fprintf (f, "__%s_head:\n", imp_name);
966
f88ebc68 967 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
fb257042 968 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f88ebc68
SC
969 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
970 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
971 fprintf (f, "\t%s\t0\t%s time\n", ASM_LONG, ASM_C);
765e60a9 972 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
f88ebc68 973 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
fb257042 974 ASM_RVA_BEFORE,
2757dc25 975 imp_name,
fb257042
SC
976 ASM_RVA_AFTER,
977 ASM_C);
f88ebc68 978 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
fb257042
SC
979 ASM_RVA_BEFORE,
980 ASM_RVA_AFTER, ASM_C);
765e60a9 981
6f2d3212 982 fprintf (f, "%sStuff for compatibility\n", ASM_C);
6f2d3212
SC
983 fprintf (f, "\t.section\t.idata$5\n");
984 fprintf (f, "\t%s\t0\n", ASM_LONG);
2757dc25 985 fprintf (f, "fthunk:\n");
6f2d3212
SC
986 fprintf (f, "\t.section\t.idata$4\n");
987 fprintf (f, "\t%s\t0\n", ASM_LONG);
2757dc25
SC
988 fprintf (f, "\t.section .idata$4\n");
989 fprintf (f, "hname:\n");
990
991 fclose (f);
992
993 sprintf (outfile, "-o %sh.o %sh.s", prefix, prefix);
994 run (as_name, outfile);
6f2d3212 995
765e60a9
SC
996 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
997 {
2757dc25
SC
998 sprintf (outfile, "%ss%d.s", prefix, i);
999 f = fopen (outfile, "w");
1000 fprintf (f, "\n\n\n%s ********************* \n", ASM_C);
1001 fprintf (f, "\t.text\n");
1002 fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name);
f88ebc68 1003 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
2757dc25
SC
1004 fprintf (f, "%s:\n\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name);
1005
f88ebc68 1006 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
2757dc25 1007 fprintf (f, "\t%s\t__%s_head\n", ASM_LONG, imp_name);
2757dc25
SC
1008 fprintf (f, "\t.section .idata$5\n");
1009
1010
6f2d3212 1011 fprintf (f, "__imp_%s:\n", exp->name);
f88ebc68 1012 fprintf (f, "\t%sID%d%s\n",
fb257042
SC
1013 ASM_RVA_BEFORE,
1014 i,
1015 ASM_RVA_AFTER);
2757dc25
SC
1016
1017 fprintf (f, "\n%s Hint name array\n", ASM_C);
1018 fprintf (f, "\t.section .idata$4\n");
f88ebc68 1019 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
2757dc25
SC
1020 i,
1021 ASM_RVA_AFTER);
1022
1023 fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C);
1024 fprintf (f, "\t.section .idata$6\n");
1025
1026 fprintf (f, "\t%s\n", ASM_ALIGN_SHORT);
1027 fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal);
1028 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1029 fclose (f);
1030
1031
1032 sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
1033 run (as_name, outfile);
765e60a9 1034 }
2757dc25
SC
1035
1036 sprintf (outfile, "%st.s", prefix);
1037 f = fopen (outfile, "w");
56297cc6 1038 fprintf (f, "\t.section .idata$7\n");
2757dc25 1039 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name);
2757dc25
SC
1040 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
1041 imp_name, ASM_TEXT, dll_name);
1042
765e60a9 1043
765e60a9 1044 fprintf (f, "\t.section .idata$4\n");
2757dc25
SC
1045 fprintf (f, "\t%s\t0\n", ASM_LONG);
1046
1047 fprintf (f, "\t.section .idata$5\n");
1048 fprintf (f, "\t%s\t0\n", ASM_LONG);
1049 fclose (f);
1050
1051 sprintf (outfile, "-o %st.o %st.s", prefix, prefix);
1052 run (as_name, outfile);
1053
1054 /* Now stick them all into the archive */
1055
1056
1057 sprintf (outfile, "crs %s %sh.o %st.o", output_filename, prefix, prefix);
1058 run (ar_name, outfile);
1059
1060 /* Do the rest in groups of however many fit into a command line */
1061 sol = 0;
765e60a9
SC
1062 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1063 {
2757dc25
SC
1064 if (sol == 0)
1065 {
1066 sol = sprintf (outfile, "crs %s", output_filename);
1067 }
1068
1069 sol += sprintf (outfile + sol, " %ss%d.o", prefix, i);
1070
1071 if (sol >100)
1072 {
1073 run (ar_name, outfile);
1074 sol = 0;
1075 }
1076
765e60a9 1077 }
2757dc25
SC
1078 if (sol)
1079 run (ar_name, outfile);
765e60a9 1080
2757dc25 1081 /* Delete all the temp files */
765e60a9 1082
f88ebc68 1083 if (dontdeltemps == 0)
2757dc25
SC
1084 {
1085 sprintf (outfile, "%sh.o", prefix);
1086 unlink (outfile);
1087 sprintf (outfile, "%sh.s", prefix);
1088 unlink (outfile);
1089 sprintf (outfile, "%st.o", prefix);
1090 unlink (outfile);
1091 sprintf (outfile, "%st.s", prefix);
1092 unlink (outfile);
1093 }
f88ebc68
SC
1094
1095if (dontdeltemps < 2)
765e60a9
SC
1096 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1097 {
2757dc25
SC
1098 sprintf (outfile, "%ss%d.o", prefix, i);
1099 unlink (outfile);
1100 sprintf (outfile, "%ss%d.s", prefix, i);
1101 unlink (outfile);
765e60a9 1102 }
2757dc25 1103
765e60a9
SC
1104}
1105/**********************************************************************/
1106
1107/* Run through the information gathered from the .o files and the
1108 .def file and work out the best stuff */
1109int
1110pfunc (a, b)
1111 void *a;
1112 void *b;
1113{
1114 export_type *ap = *(export_type **) a;
1115 export_type *bp = *(export_type **) b;
1116 if (ap->ordinal == bp->ordinal)
1117 return 0;
1118
1119 /* unset ordinals go to the bottom */
1120 if (ap->ordinal == -1)
1121 return 1;
1122 if (bp->ordinal == -1)
1123 return -1;
1124 return (ap->ordinal - bp->ordinal);
1125}
1126
1127
1128int
1129nfunc (a, b)
1130 void *a;
1131 void *b;
1132{
1133 export_type *ap = *(export_type **) a;
1134 export_type *bp = *(export_type **) b;
1135
1136 return (strcmp (ap->name, bp->name));
1137}
1138
1139static
1140void
1141remove_null_names (ptr)
1142 export_type **ptr;
1143{
1144 int src;
1145 int dst;
1146 for (dst = src = 0; src < d_nfuncs; src++)
1147 {
1148 if (ptr[src])
1149 {
1150 ptr[dst] = ptr[src];
1151 dst++;
1152 }
1153 }
1154 d_nfuncs = dst;
1155}
1156
1157static void
1158dtab (ptr)
1159 export_type **ptr;
1160{
1161#ifdef SACDEBUG
1162 int i;
1163 for (i = 0; i < d_nfuncs; i++)
1164 {
1165 if (ptr[i])
1166 {
1167 printf ("%d %s @ %d %s%s\n",
1168 i, ptr[i]->name, ptr[i]->ordinal,
1169 ptr[i]->noname ? "NONAME " : "",
1170 ptr[i]->constant ? "CONSTANT" : "");
1171 }
1172 else
1173 printf ("empty\n");
1174 }
1175#endif
1176}
1177
1178static void
1179process_duplicates (d_export_vec)
1180 export_type **d_export_vec;
1181{
1182 int more = 1;
1183
1184 while (more)
1185 {
1186 more = 0;
1187 /* Remove duplicates */
1188 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
1189
1190 dtab (d_export_vec);
1191 for (i = 0; i < d_nfuncs - 1; i++)
1192 {
1193 if (strcmp (d_export_vec[i]->name,
1194 d_export_vec[i + 1]->name) == 0)
1195 {
1196
1197 export_type *a = d_export_vec[i];
1198 export_type *b = d_export_vec[i + 1];
1199
1200 more = 1;
6f2d3212
SC
1201 if (verbose)
1202 fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1203 a->name,
1204 a->ordinal,
1205 b->ordinal);
765e60a9
SC
1206 if (a->ordinal != -1
1207 && b->ordinal != -1)
1208 {
1209
1210 fprintf (stderr, "Error, duplicate EXPORT with oridinals %s\n",
1211 a->name);
1212 exit (1);
1213 }
1214 /* Merge attributes */
1215 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
1216 b->constant |= a->constant;
1217 b->noname |= a->noname;
1218 d_export_vec[i] = 0;
1219 }
1220
1221 dtab (d_export_vec);
1222 remove_null_names (d_export_vec);
1223 dtab (d_export_vec);
1224 }
1225 }
1226}
1227
1228static void
1229fill_ordinals (d_export_vec)
1230 export_type **d_export_vec;
1231{
1232 int lowest = 0;
6f2d3212
SC
1233 int unset = 0;
1234 char *ptr;
765e60a9
SC
1235 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1236
6f2d3212
SC
1237 /* fill in the unset ordinals with ones from our range */
1238
1239 ptr = (char *) malloc (65536);
1240
1241 memset (ptr, 65536, 0);
1242
1243 /* Mark in our large vector all the numbers that are taken */
765e60a9
SC
1244 for (i = 0; i < d_nfuncs; i++)
1245 {
6f2d3212 1246 if (d_export_vec[i]->ordinal != -1)
765e60a9 1247 {
6f2d3212
SC
1248 ptr[d_export_vec[i]->ordinal] = 1;
1249 if (lowest == 0)
1250 lowest = d_export_vec[i]->ordinal;
765e60a9 1251 }
6f2d3212
SC
1252 }
1253
1254 for (i = 0; i < d_nfuncs; i++)
1255 {
1256 if (d_export_vec[i]->ordinal == -1)
765e60a9 1257 {
6f2d3212
SC
1258 int j;
1259 for (j = lowest; j < 65536; j++)
1260 if (ptr[j] == 0)
1261 {
1262 ptr[j] = 1;
1263 d_export_vec[i]->ordinal = j;
1264 goto done;
1265 }
1266
1267 for (j = 1; j < lowest; j++)
1268 if (ptr[j] == 0)
1269 {
1270 ptr[j] = 1;
1271 d_export_vec[i]->ordinal = j;
1272 goto done;
1273 }
1274 done:;
1275
765e60a9
SC
1276 }
1277 }
1278
6f2d3212
SC
1279 free (ptr);
1280
1281 /* And resort */
1282
1283 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1284
765e60a9
SC
1285 /* Work out the lowest ordinal number */
1286 if (d_export_vec[0])
1287 d_ord = d_export_vec[0]->ordinal;
1288}
1289void
1290mangle_defs ()
1291{
1292 /* First work out the minimum ordinal chosen */
1293
1294 export_type *exp;
1295 int lowest = 0;
1296 int i;
1297 export_type **d_export_vec
1298 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
1299
1300 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1301 {
1302 d_export_vec[i] = exp;
1303 }
1304
1305 process_duplicates (d_export_vec);
1306 fill_ordinals (d_export_vec);
1307
1308 /* Put back the list in the new order */
1309 d_exports = 0;
1310 for (i = d_nfuncs - 1; i >= 0; i--)
1311 {
1312 d_export_vec[i]->next = d_exports;
1313 d_exports = d_export_vec[i];
1314 }
1315}
1316
1317
2757dc25
SC
1318
1319 /* Work out exec prefix from the name of this file */
1320void
1321workout_prefix ()
1322{
1323 char *ps = 0;
1324 char *s = 0;
1325 char *p;
1326 /* See if we're running in a devo tree */
1327 for (p = program_name; *p; p++)
1328 {
1329 if (*p == '/' || *p == '\\')
1330 {
1331 ps = s;
1332 s = p;
1333 }
1334 }
1335
1336 if (ps && strncmp (ps, "/binutils", 9) == 0)
1337 {
1338 /* running in the binutils directory, the other
1339 executables will be surrounding it in the usual places. */
1340 int len = ps - program_name;
1341 ar_name = xmalloc (len + strlen ("/binutils/ar") + 1);
1342 ranlib_name = xmalloc (len + strlen ("/binutils/ranlib") + 1);
1343 as_name = xmalloc (len + strlen ("/gas/as.new") + 1);
1344
f88ebc68
SC
1345 memcpy (ar_name, program_name, len);
1346 strcpy (ar_name + len, "/binutils/ar");
1347 memcpy (ranlib_name, program_name, len);
1348 strcpy (ranlib_name + len, "/binutils/ranlib");
1349 memcpy (as_name, program_name, len);
1350 strcpy (as_name + len, "/gas/as.new");
2757dc25
SC
1351 }
1352 else
1353 {
1354 /* Otherwise chop off any prefix and use it for the rest of the progs,
1355 so i386-win32-dll generates i386-win32-ranlib etc etc */
1356
1357 for (p = program_name; *p; p++)
1358 {
1359 if (strncmp (p, "dlltool", 7) == 0)
1360 {
1361 int len = p - program_name;
1362 ar_name = xmalloc (len + strlen ("ar") +1);
1363 ranlib_name = xmalloc (len + strlen ("ranlib")+1);
1364 as_name = xmalloc (len + strlen ("as")+1);
1365
1366 strncpy (ar_name, program_name, len);
1367 strcat (ar_name, "ar");
1368 strncpy (ranlib_name, program_name, len);
1369 strcat (ranlib_name, "ranlib");
1370 strncpy (as_name, program_name, len);
1371 strcat (as_name, "as");
1372 }
1373 }
1374 }
1375}
1376
1377
765e60a9
SC
1378/**********************************************************************/
1379
1380void
1381usage (file, status)
1382 FILE *file;
1383 int status;
1384{
6f2d3212 1385 fprintf (file, "Usage %s <options> <object-files>\n", program_name);
f88ebc68
SC
1386 fprintf (file, " --machine <machine>\n");
1387 fprintf (file, " --output-exp <outname> Generate export file.\n");
1388 fprintf (file, " --output-lib <outname> Generate input library.\n");
1389 fprintf (file, " --dllname <name> Name of input dll to put into output lib.\n");
1390 fprintf (file, " --def <deffile> Name input .def file\n");
1391 fprintf (file, " --base-file <basefile> Read linker generated base file\n");
1392 fprintf (file, " -v Verbose\n");
1393 fprintf (file, " -u Remove leading underscore from .lib\n");
1394 fprintf (file, " -k Kill @<n> from exported names\n");
1395 fprintf (file, " --nodelete Keep temp files.\n");
765e60a9
SC
1396 exit (status);
1397}
1398
1399static struct option long_options[] =
1400{
2757dc25
SC
1401 {"nodelete", no_argument, NULL,'n'},
1402 {"dllname", required_argument, NULL,'D'},
1403 {"output-exp", required_argument, NULL, 'e'},
1404 {"output-lib", required_argument, NULL, 'l'},
765e60a9 1405 {"def", required_argument, NULL, 'd'},
6f2d3212 1406 {"underscore", no_argument, NULL, 'u'},
00289839 1407 {"killat", no_argument, NULL, 'k'},
765e60a9
SC
1408 {"help", no_argument, NULL, 'h'},
1409 {"machine", required_argument, NULL, 'm'},
2757dc25 1410 {"rva", required_argument, NULL, 'r'},
f88ebc68 1411/* {"image-base", required_argument, NULL, 'i'},*/
6f2d3212 1412 {"base-file", required_argument, NULL, 'b'},
765e60a9
SC
1413 0
1414};
1415
2757dc25
SC
1416
1417
765e60a9
SC
1418int
1419main (ac, av)
1420 int ac;
1421 char **av;
1422{
1423 int c;
1424 char *firstarg = 0;
1425 program_name = av[0];
1426 oav = av;
6f2d3212 1427
2757dc25 1428 while ((c = getopt_long (ac, av, "D:l:e:nr:kvbuh?m:yd:", long_options, 0)) != EOF)
765e60a9
SC
1429 {
1430 switch (c)
1431 {
2757dc25
SC
1432 case 'D':
1433 dll_name = optarg;
1434 break;
1435 case 'l':
1436 imp_name = optarg;
1437 break;
1438 case 'e':
1439 exp_name = optarg;
1440 break;
765e60a9
SC
1441 case 'h':
1442 case '?':
6f2d3212 1443 usage (stderr, 0);
765e60a9
SC
1444 break;
1445 case 'm':
1446 mname = optarg;
1447 break;
6f2d3212
SC
1448 case 'v':
1449 verbose = 1;
1450 break;
2757dc25 1451 case 'y':
765e60a9
SC
1452 yydebug = 1;
1453 break;
6f2d3212
SC
1454 case 'u':
1455 suckunderscore = 1;
1456 break;
00289839
SC
1457 case 'k':
1458 killat = 1;
1459 break;
765e60a9
SC
1460 case 'd':
1461 def_file = optarg;
1462 break;
2757dc25 1463 case 'n':
f88ebc68 1464 dontdeltemps++;
2757dc25 1465 break;
6f2d3212
SC
1466 case 'b':
1467 base_file = fopen (optarg, "r");
1468 if (!base_file)
1469 {
1470 fprintf (stderr, "%s: Unable to open base-file %s\n",
1471 av[0],
1472 optarg);
1473 exit (1);
1474 }
1475 break;
765e60a9
SC
1476 default:
1477 usage (stderr, 1);
1478 }
1479 }
1480
1481
6f2d3212 1482 for (i = 0; mtable[i].type; i++)
765e60a9
SC
1483 {
1484 if (strcmp (mtable[i].type, mname) == 0)
1485 break;
1486 }
1487
6f2d3212 1488 if (!mtable[i].type)
765e60a9 1489 {
6f2d3212
SC
1490 fprintf (stderr, "Machine not supported\n");
1491 exit (1);
765e60a9
SC
1492 }
1493 machine = i;
1494
1495
2757dc25
SC
1496 if (!dll_name && exp_name)
1497 {
1498 char len = strlen (exp_name) + 5;
1499 dll_name = xmalloc (len);
1500 strcpy (dll_name, exp_name);
1501 strcat (dll_name, ".dll");
1502 }
1503 workout_prefix ();
1504
1505
765e60a9
SC
1506 if (def_file)
1507 {
765e60a9
SC
1508 process_def_file (def_file);
1509 }
1510 while (optind < ac)
1511 {
1512 if (!firstarg)
1513 firstarg = av[optind];
1514 scan_obj_file (av[optind]);
1515 optind++;
1516 }
1517
765e60a9
SC
1518
1519 mangle_defs ();
6f2d3212 1520
2757dc25
SC
1521 if (exp_name)
1522 gen_exp_file ();
1523 if (imp_name)
1524 gen_lib_file ();
6f2d3212 1525
765e60a9
SC
1526 return 0;
1527}
2757dc25
SC
1528
1529
This page took 0.224813 seconds and 4 git commands to generate.