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