1 /* dlltool.c -- tool to generate stuff for PE style DLLs
2 Copyright (C) 1995 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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.
26 A DLL contains an export table which contains the information
27 which the runtime loader needs to tie up references from a
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.
35 A DEF file contains any number of the following commands:
38 NAME <name> [ , <base> ]
39 The result is going to be <name>.EXE
41 LIBRARY <name> [ , <base> ]
42 The result is going to be <name>.DLL
44 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] ) *
45 Declares name1 as an exported symbol from the
46 DLL, with optional ordinal number <integer>
48 IMPORTS ( [ <name> = ] <name> . <name> ) *
49 Ignored for compatibility
52 Puts <string> into output .exp file in the .rdata section
54 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
55 Generates --stack|--heap <number-reserve>,<number-commit>
56 in the output .drective section. The linker will
57 see this and act upon it.
60 SECTIONS ( <sectionname> <attr>+ )*
61 <attr> = READ | WRITE | EXECUTE | SHARED
62 Generates --attr <sectionname> <attr> in the output
63 .drective section. The linker will see this and act
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>
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
77 The output files are <prefix>-exp.s and <prefix>-lib.s
79 The .exp.s file contains the information necessary to export
80 the routines in the DLL. The .lib.s file contains the information
81 necessary to use the DLL's routines from a referencing program.
88 asm (".section .drectve");
89 asm (".ascii \"-export:adef\"");
93 printf("hello from the dll %s\n",s);
98 printf("hello from the dll and the other entry point %s\n",s);
102 asm (".section .drectve");
103 asm (".ascii \"-export:cdef\"");
104 asm (".ascii \"-export:ddef\"");
107 printf("hello from the dll %s\n",s);
112 printf("hello from the dll and the other entry point %s\n",s);
130 HEAPSIZE 0x40000, 0x2000
134 SECTIONS donkey READ WRITE
138 # compile up the parts of the dll
143 # put them in a library (you don't have to, you
144 # could name all the .os on the dlltool line)
146 ar qcv thedll.in file1.o file2.o
149 # run this tool over the library and the def file
150 ./dlltool -o thedll -d thedll.def thedll.in
152 # build the export table for the dll
153 as -o thedll.exp thedll-exp.s
154 # build the dll with the library with file1.o, file2.o and the export table
155 ld -o thedll.dll thedll.exp thedll.in
157 # build the import table for the executable
158 as -o thedll.lib thedll-lib.s
163 # link the executable with the import library
164 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.lib
168 #define PAGE_SIZE 4096
169 #define PAGE_MASK (-PAGE_SIZE)
179 char *outfile_prefix
;
188 static char *mname
= "arm";
192 static char *mname
= "i386";
194 #define PATHMAX 250 /* What's the right name for this ? */
196 char outfile
[PATHMAX
];
213 "arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space"
217 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space"
223 #define ASM_BYTE mtable[machine].how_byte
224 #define ASM_SHORT mtable[machine].how_short
225 #define ASM_LONG mtable[machine].how_long
226 #define ASM_TEXT mtable[machine].how_asciz
227 #define ASM_C mtable[machine].how_comment
228 #define ASM_JUMP mtable[machine].how_jump
229 #define ASM_GLOBAL mtable[machine].how_global
230 #define ASM_SPACE mtable[machine].how_space
237 FILE *yyin
; /* communications with flex */
238 extern int linenumber
;
240 process_def_file (name
)
243 FILE *f
= fopen (name
, "r");
246 fprintf (stderr
, "%s: Can't open def file %s\n", program_name
, name
);
255 /**********************************************************************/
257 /* Communications with the parser */
267 typedef struct export
278 static char *d_name
; /* Arg to NAME or LIBRARY */
279 static int d_nfuncs
; /* Number of functions exported */
280 static int d_ord
; /* Base ordinal index */
281 static export_type
*d_exports
; /*list of exported functions */
282 static char *d_suffix
= "dll";
283 static dlist_type
*d_list
; /* Descriptions */
284 static dlist_type
*a_list
; /* Stuff to go in directives */
291 fprintf (stderr
, "%s: Syntax error in def file %s:%d\n",
292 program_name
, def_file
, linenumber
);
296 def_exports (name
, internal_name
, ordinal
, noname
, constant
)
303 struct export
*p
= (struct export
*) xmalloc (sizeof (*p
));
306 p
->internal_name
= internal_name
? internal_name
: name
;
307 p
->ordinal
= ordinal
;
308 p
->constant
= constant
;
317 def_name (name
, base
)
322 fprintf (stderr
, "%s NAME %s base %x\n", program_name
, name
, base
);
325 fprintf (stderr
, "Can't have LIBRARY and NAME\n");
328 if (strchr (d_name
, '.'))
329 d_suffix
= strdup (strchr (d_name
, '.') + 1);
334 def_library (name
, base
)
339 printf ("%s: LIBRARY %s base %x\n", program_name
, name
, base
);
342 fprintf (stderr
, "%s: Can't have LIBRARY and NAME\n", program_name
);
345 if (strchr (d_name
, '.'))
346 d_suffix
= strdup (strchr (d_name
, '.') + 1);
351 def_description (desc
)
354 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
355 d
->text
= strdup (desc
);
364 dlist_type
*d
= (dlist_type
*) xmalloc (sizeof (dlist_type
));
365 d
->text
= strdup (dir
);
371 def_stacksize (reserve
, commit
)
377 sprintf (b
, "-stack 0x%x,0x%x ", reserve
, commit
);
379 sprintf (b
, "-stack 0x%x ", reserve
);
380 new_directive (strdup (b
));
384 def_heapsize (reserve
, commit
)
390 sprintf (b
, "-heap 0x%x,0x%x ", reserve
, commit
);
392 sprintf (b
, "-heap 0x%x ", reserve
);
393 new_directive (strdup (b
));
398 def_import (internal
, module
, entry
)
404 fprintf (stderr
, "%s: IMPORTS are ignored", program_name
);
408 def_version (major
, minor
)
410 printf ("VERSION %d.%d\n", major
, minor
);
415 def_section (name
, attr
)
432 sprintf (buf
, "-attr %s %s", name
, atts
);
433 new_directive (strdup (buf
));
440 def_section ("CODE", attr
);
447 def_section ("DATA", attr
);
451 /**********************************************************************/
453 /* read in and block out the base relocations */
465 scan_open_obj_file (abfd
)
468 /* Look for .drectives */
469 asection
*s
= bfd_get_section_by_name (abfd
, ".drectve");
472 int size
= bfd_get_section_size_before_reloc (s
);
473 char *buf
= xmalloc (size
);
476 bfd_get_section_contents (abfd
, s
, buf
, 0, size
);
478 fprintf (stderr
, "%s: Sucking in info from %s\n",
480 bfd_get_filename (abfd
));
482 /* Search for -export: strings */
488 && strncmp (p
, "-export:", 8) == 0)
494 while (*p
!= ' ' && *p
!= '-' && p
< e
)
496 c
= xmalloc (p
- name
+ 1);
497 memcpy (c
, name
, p
- name
);
499 def_exports (c
, 0, -1, 0);
510 fprintf (stderr
, "%s: Done readin\n",
517 scan_obj_file (filename
)
520 bfd
*f
= bfd_openr (filename
, 0);
524 fprintf (stderr
, "%s: Unable to open object file %s\n",
529 if (bfd_check_format (f
, bfd_archive
))
531 bfd
*arfile
= bfd_openr_next_archived_file (f
, 0);
534 if (bfd_check_format (arfile
, bfd_object
))
535 scan_open_obj_file (arfile
);
537 arfile
= bfd_openr_next_archived_file (f
, arfile
);
541 if (bfd_check_format (f
, bfd_object
))
543 scan_open_obj_file (f
);
549 /**********************************************************************/
552 /* return the bit of the name before the last . */
559 char *res
= strdup (name
);
560 char *p
= strrchr (res
, '.');
572 fprintf (f
, "%s ", ASM_C
);
573 for (i
= 0; oav
[i
]; i
++)
574 fprintf (f
, "%s ", oav
[i
]);
576 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
578 fprintf (f
, "%s %d = %s %s @ %d %s%s\n",
584 exp
->noname
? "NONAME " : "",
585 exp
->constant
? "CONSTANT" : "");
588 /* Generate the .exp file */
599 flush_page (f
, need
, page_addr
, on_page
)
606 /* Flush this page */
607 fprintf (f
, "\t%s\t0x%x\t%s Starting RVA for chunk\n",
611 fprintf (f
, "\t%s\t0x%x\t%s Size of block\n",
613 (on_page
* 2) + (on_page
& 1) * 2 + 8,
615 for (i
= 0; i
< on_page
; i
++)
617 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, need
[i
] - page_addr
| 0x3000);
621 fprintf (f
, "\t%s\t0x%x\n", ASM_SHORT
, 0 | 0x0000);
635 sprintf (outfile
, "%s-exp.s", outfile_prefix
);
638 fprintf (stderr
, "%s: Generate exp file %s\n",
639 program_name
, outfile_prefix
);
641 f
= fopen (outfile
, "w");
644 fprintf (stderr
, "%s: Unable to open output file %s\n", program_name
, outfile
);
649 fprintf (stderr
, "%s: Opened file %s\n",
650 program_name
, outfile
);
654 fprintf (f
, "\t.section .edata\n\n");
655 fprintf (f
, "\t%s 0 %s Allways 0\n", ASM_LONG
, ASM_C
);
656 fprintf (f
, "\t%s %d %s Time and date\n", ASM_LONG
, time (0), ASM_C
);
657 fprintf (f
, "\t%s 0 %s Major and Minor version\n", ASM_LONG
, ASM_C
);
658 fprintf (f
, "\t%s name %s Ptr to name of dll\n", ASM_LONG
, ASM_C
);
659 fprintf (f
, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG
, d_ord
, ASM_C
);
660 fprintf (f
, "\t%s The next field is documented as being the number of functions\n", ASM_C
);
661 fprintf (f
, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C
);
662 fprintf (f
, "\t%s But it shouldn't be a problem, causes there's\n", ASM_C
);
663 fprintf (f
, "\t%s always the number of names field\n", ASM_C
);
664 fprintf (f
, "\t%s %d %s Number of functions\n", ASM_LONG
, d_nfuncs
, ASM_C
);
665 fprintf (f
, "\t%s %d %s Number of names\n", ASM_LONG
, d_nfuncs
, ASM_C
);
666 fprintf (f
, "\t%s afuncs %s Address of functions\n", ASM_LONG
, ASM_C
);
667 fprintf (f
, "\t%s anames %s Address of names\n", ASM_LONG
, ASM_C
);
668 fprintf (f
, "\t%s anords %s Address of ordinals\n", ASM_LONG
, ASM_C
);
670 fprintf (f
, "name: %s \"%s.%s\"\n", ASM_TEXT
, outfile_prefix
, d_suffix
);
672 fprintf (f
, "afuncs:\n");
674 for (exp
= d_exports
; exp
; exp
= exp
->next
)
677 /* This seems necessary in the doc, but in real
678 life it's not used.. */
679 if (exp
->ordinal
!= i
)
681 fprintf (f
, "%s\t%s\t%d\t@ %d..%d missing\n", ASM_C
, ASM_SPACE
,
682 (exp
->ordinal
- i
) * 4,
683 i
, exp
->ordinal
- 1);
687 fprintf (f
, "\t%s %s\t%s %d\n", ASM_LONG
, exp
->internal_name
, ASM_C
, exp
->ordinal
);
692 fprintf (f
, "anames:\n");
693 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
698 fprintf (f
, "\t%s nNoname\n", ASM_LONG
, ASM_C
);
702 fprintf (f
, "\t%s n%d\n", ASM_LONG
, i
);
706 fprintf (f
, "anords:\n");
707 for (exp
= d_exports
; exp
; exp
= exp
->next
)
708 fprintf (f
, "\t%s %d\n", ASM_SHORT
, exp
->ordinal
- d_ord
);
710 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
712 fprintf (f
, "@n%d: %s \"%s\"\n", i
, ASM_TEXT
, exp
->name
);
714 fprintf (f
, "n%d: %s \"%s\"\n", i
, ASM_TEXT
, exp
->name
);
717 fprintf (f
, "nNoname: %s \"__noname__\"\n", ASM_TEXT
);
721 fprintf (f
, "\t.section .drectve\n");
722 for (dl
= a_list
; dl
; dl
= dl
->next
)
724 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, dl
->text
);
729 fprintf (f
, "\t.section .rdata\n");
730 for (dl
= d_list
; dl
; dl
= dl
->next
)
734 /* We dont output as ascii 'cause there can
735 be quote characters in the string */
738 for (p
= dl
->text
; *p
; p
++)
741 fprintf (f
, "\t%s\t", ASM_BYTE
);
744 fprintf (f
, "%d", *p
);
759 /* Dump the reloc section if a base file is provided */
763 long need
[PAGE_SIZE
];
770 fprintf (f
, "\t.section\t.reloc\n");
771 fseek (base_file
, 0, SEEK_END
);
772 numbytes
= ftell (base_file
);
773 fseek (base_file
, 0, SEEK_SET
);
774 copy
= malloc (numbytes
);
775 fread (copy
, 1, numbytes
, base_file
);
776 num_entries
= numbytes
/ sizeof (long);
778 qsort (copy
, num_entries
, sizeof (long), sfunc
);
781 page_addr
= addr
& PAGE_MASK
; /* work out the page addr */
783 for (j
= 0; j
< num_entries
; j
++)
786 if ((addr
& PAGE_MASK
) != page_addr
)
788 flush_page (f
, need
, page_addr
, on_page
);
790 page_addr
= addr
& PAGE_MASK
;
792 need
[on_page
++] = addr
;
794 flush_page (f
, need
, page_addr
, on_page
);
809 p
= strchr (name
, '@');
815 /**********************************************************************/
822 sprintf (outfile
, "%s-lib.s", outfile_prefix
);
824 f
= fopen (outfile
, "w");
827 fprintf (stderr
, "Unable to open output file %s\n", outfile
);
833 fprintf (f
, "\t.text\n");
834 fprintf (f
, "%s Thunk table\n", ASM_C
);
835 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
837 fprintf (f
, "\t%s\t%s\n", ASM_GLOBAL
, exp
->name
);
838 fprintf (f
, "\t%s\t__imp_%s\n", ASM_GLOBAL
, exp
->name
);
841 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
843 fprintf (f
, "%s:\t%s\t__imp_%s\n", exp
->name
, ASM_JUMP
, exp
->name
);
847 fprintf (f
, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C
);
848 fprintf (f
, "\t.section .idata$2\n");
849 fprintf (f
, "\t%s\thname\t%s Ptr to image import by name list\n", ASM_LONG
, ASM_C
);
850 fprintf (f
, "\t%s\t%d\t%s time\n", ASM_LONG
, time (0), ASM_C
);
851 fprintf (f
, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG
, ASM_C
);
852 fprintf (f
, "\t%s\tiname\t%s imported dll's name\n", ASM_LONG
, ASM_C
);
853 fprintf (f
, "\t%s\tfthunk\t%s pointer to firstthunk\n", ASM_LONG
, ASM_C
);
855 fprintf (f
, "%sStuff for compatibility\n", ASM_C
);
856 fprintf (f
, "\t.section\t.idata$3\n");
857 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
858 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
859 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
860 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
861 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
862 fprintf (f
, "\t.section\t.idata$5\n");
863 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
865 fprintf (f
, "\t.section\t.idata$4\n");
866 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
868 fprintf (f
, "\n%s Loader modifies this\n", ASM_C
);
869 fprintf (f
, "\t.section .idata$5\n");
870 fprintf (f
, "fthunk:\n");
871 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
873 fprintf (f
, "__imp_%s:\n", exp
->name
);
874 fprintf (f
, "\t%s\tID%d\n", ASM_LONG
, i
);
876 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
878 fprintf (f
, "\n%s Hint name array\n", ASM_C
);
879 fprintf (f
, "\t.section .idata$4\n");
880 fprintf (f
, "hname:\n");
881 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
883 fprintf (f
, "\t%s\tID%d\n", ASM_LONG
, i
);
886 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
887 fprintf (f
, "%s Hint/name array storage and import dll name\n", ASM_C
);
888 fprintf (f
, "\t.section .idata$6\n");
890 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
892 fprintf (f
, "ID%d:\t%s\t%d\n", i
, ASM_SHORT
, exp
->ordinal
);
893 fprintf (f
, "\t%s\t\"%s\"\n", ASM_TEXT
, xlate (exp
->name
));
895 fprintf (f
, "\t%s\t0\n", ASM_LONG
);
896 fprintf (f
, "iname:\t%s\t\"%s.%s\"\n", ASM_TEXT
, outfile_prefix
, d_suffix
);
899 /**********************************************************************/
901 /* Run through the information gathered from the .o files and the
902 .def file and work out the best stuff */
908 export_type
*ap
= *(export_type
**) a
;
909 export_type
*bp
= *(export_type
**) b
;
910 if (ap
->ordinal
== bp
->ordinal
)
913 /* unset ordinals go to the bottom */
914 if (ap
->ordinal
== -1)
916 if (bp
->ordinal
== -1)
918 return (ap
->ordinal
- bp
->ordinal
);
927 export_type
*ap
= *(export_type
**) a
;
928 export_type
*bp
= *(export_type
**) b
;
930 return (strcmp (ap
->name
, bp
->name
));
935 remove_null_names (ptr
)
940 for (dst
= src
= 0; src
< d_nfuncs
; src
++)
957 for (i
= 0; i
< d_nfuncs
; i
++)
961 printf ("%d %s @ %d %s%s\n",
962 i
, ptr
[i
]->name
, ptr
[i
]->ordinal
,
963 ptr
[i
]->noname
? "NONAME " : "",
964 ptr
[i
]->constant
? "CONSTANT" : "");
973 process_duplicates (d_export_vec
)
974 export_type
**d_export_vec
;
981 /* Remove duplicates */
982 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), nfunc
);
985 for (i
= 0; i
< d_nfuncs
- 1; i
++)
987 if (strcmp (d_export_vec
[i
]->name
,
988 d_export_vec
[i
+ 1]->name
) == 0)
991 export_type
*a
= d_export_vec
[i
];
992 export_type
*b
= d_export_vec
[i
+ 1];
996 fprintf (stderr
, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1000 if (a
->ordinal
!= -1
1001 && b
->ordinal
!= -1)
1004 fprintf (stderr
, "Error, duplicate EXPORT with oridinals %s\n",
1008 /* Merge attributes */
1009 b
->ordinal
= a
->ordinal
> 0 ? a
->ordinal
: b
->ordinal
;
1010 b
->constant
|= a
->constant
;
1011 b
->noname
|= a
->noname
;
1012 d_export_vec
[i
] = 0;
1015 dtab (d_export_vec
);
1016 remove_null_names (d_export_vec
);
1017 dtab (d_export_vec
);
1023 fill_ordinals (d_export_vec
)
1024 export_type
**d_export_vec
;
1029 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
1031 /* fill in the unset ordinals with ones from our range */
1033 ptr
= (char *) malloc (65536);
1035 memset (ptr
, 65536, 0);
1037 /* Mark in our large vector all the numbers that are taken */
1038 for (i
= 0; i
< d_nfuncs
; i
++)
1040 if (d_export_vec
[i
]->ordinal
!= -1)
1042 ptr
[d_export_vec
[i
]->ordinal
] = 1;
1044 lowest
= d_export_vec
[i
]->ordinal
;
1048 for (i
= 0; i
< d_nfuncs
; i
++)
1050 if (d_export_vec
[i
]->ordinal
== -1)
1053 for (j
= lowest
; j
< 65536; j
++)
1057 d_export_vec
[i
]->ordinal
= j
;
1061 for (j
= 1; j
< lowest
; j
++)
1065 d_export_vec
[i
]->ordinal
= j
;
1077 qsort (d_export_vec
, d_nfuncs
, sizeof (export_type
*), pfunc
);
1079 /* Work out the lowest ordinal number */
1080 if (d_export_vec
[0])
1081 d_ord
= d_export_vec
[0]->ordinal
;
1086 /* First work out the minimum ordinal chosen */
1091 export_type
**d_export_vec
1092 = (export_type
**) xmalloc (sizeof (export_type
*) * d_nfuncs
);
1094 for (i
= 0, exp
= d_exports
; exp
; i
++, exp
= exp
->next
)
1096 d_export_vec
[i
] = exp
;
1099 process_duplicates (d_export_vec
);
1100 fill_ordinals (d_export_vec
);
1102 /* Put back the list in the new order */
1104 for (i
= d_nfuncs
- 1; i
>= 0; i
--)
1106 d_export_vec
[i
]->next
= d_exports
;
1107 d_exports
= d_export_vec
[i
];
1112 /**********************************************************************/
1115 usage (file
, status
)
1119 fprintf (file
, "Usage %s <options> <object-files>\n", program_name
);
1120 fprintf (file
, "\t -m <machine> Generate code for <machine>\n");
1121 fprintf (file
, "\t --machine <machine>\n");
1122 fprintf (file
, "\t -o <outprefix> Set output prefix\n");
1123 fprintf (file
, "\t -d <deffile> Name input .def file\n");
1124 fprintf (file
, "\t --def <deffile> \n");
1125 fprintf (file
, "\t --base-file <basefile> Read linker generated base file\n");
1126 fprintf (file
, "\t -b <basefile> \n");
1127 fprintf (file
, "\t -v Verbose\n");
1132 static struct option long_options
[] =
1134 {"def", required_argument
, NULL
, 'd'},
1135 {"underscore", no_argument
, NULL
, 'u'},
1136 {"help", no_argument
, NULL
, 'h'},
1137 {"machine", required_argument
, NULL
, 'm'},
1138 {"base-file", required_argument
, NULL
, 'b'},
1149 program_name
= av
[0];
1152 while ((c
= getopt_long (ac
, av
, "vbuh?m:o:Dd:", long_options
, 0)) != EOF
)
1164 outfile_prefix
= optarg
;
1179 base_file
= fopen (optarg
, "r");
1182 fprintf (stderr
, "%s: Unable to open base-file %s\n",
1194 for (i
= 0; mtable
[i
].type
; i
++)
1196 if (strcmp (mtable
[i
].type
, mname
) == 0)
1200 if (!mtable
[i
].type
)
1202 fprintf (stderr
, "Machine not supported\n");
1210 process_def_file (def_file
);
1215 firstarg
= av
[optind
];
1216 scan_obj_file (av
[optind
]);
1220 if (!outfile_prefix
)
1223 outfile_prefix
= d_name
;
1225 outfile_prefix
= def_file
;
1227 outfile_prefix
= firstarg
;
1230 fprintf (stderr
, "No way to create an output filename\n");
1234 outfile_prefix
= prefix (outfile_prefix
);
1237 fprintf (stderr
, "%s: Outfile prefix is %s\n",
1238 program_name
, outfile_prefix
);
This page took 0.058413 seconds and 5 git commands to generate.