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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)
182 char *outfile_prefix;
192 static char *mname = "arm";
196 static char *mname = "i386";
198 #define PATHMAX 250 /* What's the right name for this ? */
200 char outfile[PATHMAX];
212 char *how_align_short;
213 char *how_rva_before;
220 "arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space",".align\t2","(",")-0x400000"
224 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space",".align\t2",
231 #define ASM_BYTE mtable[machine].how_byte
232 #define ASM_SHORT mtable[machine].how_short
233 #define ASM_LONG mtable[machine].how_long
234 #define ASM_TEXT mtable[machine].how_asciz
235 #define ASM_C mtable[machine].how_comment
236 #define ASM_JUMP mtable[machine].how_jump
237 #define ASM_GLOBAL mtable[machine].how_global
238 #define ASM_SPACE mtable[machine].how_space
239 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
240 #define ASM_RVA_BEFORE mtable[machine].how_rva_before
241 #define ASM_RVA_AFTER mtable[machine].how_rva_after
247 FILE *yyin; /* communications with flex */
248 extern int linenumber;
250 process_def_file (name)
253 FILE *f = fopen (name, "r");
256 fprintf (stderr, "%s: Can't open def file %s\n", program_name, name);
265 /**********************************************************************/
267 /* Communications with the parser */
277 typedef struct export
288 static char *d_name; /* Arg to NAME or LIBRARY */
289 static int d_nfuncs; /* Number of functions exported */
290 static int d_ord; /* Base ordinal index */
291 static export_type *d_exports; /*list of exported functions */
292 static char *d_suffix = "dll";
293 static dlist_type *d_list; /* Descriptions */
294 static dlist_type *a_list; /* Stuff to go in directives */
301 fprintf (stderr, "%s: Syntax error in def file %s:%d\n",
302 program_name, def_file, linenumber);
306 def_exports (name, internal_name, ordinal, noname, constant)
313 struct export *p = (struct export *) xmalloc (sizeof (*p));
316 p->internal_name = internal_name ? internal_name : name;
317 p->ordinal = ordinal;
318 p->constant = constant;
327 def_name (name, base)
332 fprintf (stderr, "%s NAME %s base %x\n", program_name, name, base);
335 fprintf (stderr, "Can't have LIBRARY and NAME\n");
338 if (strchr (d_name, '.'))
339 d_suffix = strdup (strchr (d_name, '.') + 1);
344 def_library (name, base)
349 printf ("%s: LIBRARY %s base %x\n", program_name, name, base);
352 fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name);
355 if (strchr (d_name, '.'))
356 d_suffix = strdup (strchr (d_name, '.') + 1);
361 def_description (desc)
364 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
365 d->text = strdup (desc);
374 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
375 d->text = strdup (dir);
381 def_stacksize (reserve, commit)
387 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
389 sprintf (b, "-stack 0x%x ", reserve);
390 new_directive (strdup (b));
394 def_heapsize (reserve, commit)
400 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
402 sprintf (b, "-heap 0x%x ", reserve);
403 new_directive (strdup (b));
408 def_import (internal, module, entry)
414 fprintf (stderr, "%s: IMPORTS are ignored", program_name);
418 def_version (major, minor)
420 printf ("VERSION %d.%d\n", major, minor);
425 def_section (name, attr)
442 sprintf (buf, "-attr %s %s", name, atts);
443 new_directive (strdup (buf));
450 def_section ("CODE", attr);
457 def_section ("DATA", attr);
461 /**********************************************************************/
463 /* read in and block out the base relocations */
475 scan_open_obj_file (abfd)
478 /* Look for .drectives */
479 asection *s = bfd_get_section_by_name (abfd, ".drectve");
482 int size = bfd_get_section_size_before_reloc (s);
483 char *buf = xmalloc (size);
486 bfd_get_section_contents (abfd, s, buf, 0, size);
488 fprintf (stderr, "%s: Sucking in info from %s\n",
490 bfd_get_filename (abfd));
492 /* Search for -export: strings */
498 && strncmp (p, "-export:", 8) == 0)
504 while (*p != ' ' && *p != '-' && p < e)
506 c = xmalloc (p - name + 1);
507 memcpy (c, name, p - name);
509 def_exports (c, 0, -1, 0);
520 fprintf (stderr, "%s: Done readin\n",
527 scan_obj_file (filename)
530 bfd *f = bfd_openr (filename, 0);
534 fprintf (stderr, "%s: Unable to open object file %s\n",
539 if (bfd_check_format (f, bfd_archive))
541 bfd *arfile = bfd_openr_next_archived_file (f, 0);
544 if (bfd_check_format (arfile, bfd_object))
545 scan_open_obj_file (arfile);
547 arfile = bfd_openr_next_archived_file (f, arfile);
551 if (bfd_check_format (f, bfd_object))
553 scan_open_obj_file (f);
559 /**********************************************************************/
562 /* return the bit of the name before the last . */
569 char *res = strdup (name);
570 char *p = strrchr (res, '.');
582 fprintf (f, "%s ", ASM_C);
583 for (i = 0; oav[i]; i++)
584 fprintf (f, "%s ", oav[i]);
586 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
588 fprintf (f, "%s %d = %s %s @ %d %s%s\n",
594 exp->noname ? "NONAME " : "",
595 exp->constant ? "CONSTANT" : "");
598 /* Generate the .exp file */
609 static char *rva_n (long addr)
612 sprintf (b, "0x%08x - __rva");
616 static char *rva_s (char *s)
619 sprintf (b, "0x%08x - __rva");
624 flush_page (f, need, page_addr, on_page)
631 /* Flush this page */
632 fprintf (f, "\t%s\t%s\t%s Starting RVA for chunk\n",
636 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
638 (on_page * 2) + (on_page & 1) * 2 + 8,
640 for (i = 0; i < on_page; i++)
642 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, need[i] - page_addr | 0x3000);
646 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
660 sprintf (outfile, "%s-exp.s", outfile_prefix);
663 fprintf (stderr, "%s: Generate exp file %s\n",
664 program_name, outfile_prefix);
666 f = fopen (outfile, "w");
669 fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile);
674 fprintf (stderr, "%s: Opened file %s\n",
675 program_name, outfile);
679 fprintf (f, "\t.section .edata\n\n");
680 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
681 fprintf (f, "\t%s %d %s Time and date\n", ASM_LONG, time (0), ASM_C);
682 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
683 fprintf (f, "\t%s name %s Ptr to name of dll\n", ASM_LONG, ASM_C);
684 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_ord, ASM_C);
685 fprintf (f, "\t%s The next field is documented as being the number of functions\n", ASM_C);
686 fprintf (f, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C);
687 fprintf (f, "\t%s But it shouldn't be a problem, causes there's\n", ASM_C);
688 fprintf (f, "\t%s always the number of names field\n", ASM_C);
689 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_nfuncs, ASM_C);
690 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, d_nfuncs, ASM_C);
691 fprintf (f, "\t%s afuncs %s Address of functions\n", ASM_LONG, ASM_C);
692 fprintf (f, "\t%s anames %s Address of names\n", ASM_LONG, ASM_C);
693 fprintf (f, "\t%s anords %s Address of ordinals\n", ASM_LONG, ASM_C);
695 fprintf (f, "name: %s \"%s.%s\"\n", ASM_TEXT, outfile_prefix, d_suffix);
697 fprintf (f, "afuncs:\n");
699 for (exp = d_exports; exp; exp = exp->next)
702 /* This seems necessary in the doc, but in real
703 life it's not used.. */
704 if (exp->ordinal != i)
706 fprintf (f, "%s\t%s\t%d\t@ %d..%d missing\n", ASM_C, ASM_SPACE,
707 (exp->ordinal - i) * 4,
708 i, exp->ordinal - 1);
712 fprintf (f, "\t%s %s\t%s %d\n", ASM_LONG, exp->internal_name, ASM_C, exp->ordinal);
717 fprintf (f, "anames:\n");
718 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
723 fprintf (f, "\t%s nNoname\n", ASM_LONG, ASM_C);
727 fprintf (f, "\t%s n%d\n", ASM_LONG, i);
731 fprintf (f, "anords:\n");
732 for (exp = d_exports; exp; exp = exp->next)
733 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_ord);
735 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
737 fprintf (f, "@n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
739 fprintf (f, "n%d: %s \"%s\"\n", i, ASM_TEXT, exp->name);
742 fprintf (f, "nNoname: %s \"__noname__\"\n", ASM_TEXT);
746 fprintf (f, "\t.section .drectve\n");
747 for (dl = a_list; dl; dl = dl->next)
749 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
754 fprintf (f, "\t.section .rdata\n");
755 for (dl = d_list; dl; dl = dl->next)
759 /* We dont output as ascii 'cause there can
760 be quote characters in the string */
763 for (p = dl->text; *p; p++)
766 fprintf (f, "\t%s\t", ASM_BYTE);
769 fprintf (f, "%d", *p);
784 /* Dump the reloc section if a base file is provided */
788 long need[PAGE_SIZE];
795 fprintf (f, "\t.section\t.reloc\n");
796 fseek (base_file, 0, SEEK_END);
797 numbytes = ftell (base_file);
798 fseek (base_file, 0, SEEK_SET);
799 copy = malloc (numbytes);
800 fread (copy, 1, numbytes, base_file);
801 num_entries = numbytes / sizeof (long);
803 qsort (copy, num_entries, sizeof (long), sfunc);
806 page_addr = addr & PAGE_MASK; /* work out the page addr */
808 for (j = 0; j < num_entries; j++)
811 if ((addr & PAGE_MASK) != page_addr)
813 flush_page (f, need, page_addr, on_page);
815 page_addr = addr & PAGE_MASK;
817 need[on_page++] = addr;
819 flush_page (f, need, page_addr, on_page);
836 p = strchr (name, '@');
843 /**********************************************************************/
850 sprintf (outfile, "%s-lib.s", outfile_prefix);
852 f = fopen (outfile, "w");
855 fprintf (stderr, "Unable to open output file %s\n", outfile);
861 fprintf (f, "\t.text\n");
862 fprintf (f, "%s Thunk table\n", ASM_C);
863 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
865 fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name);
866 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
869 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
871 fprintf (f, "%s:\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name);
875 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
876 fprintf (f, "\t.section .idata$2\n");
877 fprintf (f, "\t%s\t%shname%s\t%sPtr to image import by name list\n", ASM_LONG,
878 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
879 fprintf (f, "\t%s\t%d\t%s time\n", ASM_LONG, time (0), ASM_C);
880 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
881 fprintf (f, "\t%s\t%siname%s\t%s imported dll's name\n", ASM_LONG,
885 fprintf (f, "\t%s\t%sfthunk%s\t%s pointer to firstthunk\n", ASM_LONG,
887 ASM_RVA_AFTER, ASM_C);
889 fprintf (f, "%sStuff for compatibility\n", ASM_C);
891 fprintf (f, "\t.section\t.idata$3\n");
892 fprintf (f, "\t%s\t0\n", ASM_LONG);
893 fprintf (f, "\t%s\t0\n", ASM_LONG);
894 fprintf (f, "\t%s\t0\n", ASM_LONG);
895 fprintf (f, "\t%s\t0\n", ASM_LONG);
896 fprintf (f, "\t%s\t0\n", ASM_LONG);
899 fprintf (f, "\t.section\t.idata$5\n");
900 fprintf (f, "\t%s\t0\n", ASM_LONG);
902 fprintf (f, "\t.section\t.idata$4\n");
903 fprintf (f, "\t%s\t0\n", ASM_LONG);
905 fprintf (f, "\n%s Loader modifies this\n", ASM_C);
906 fprintf (f, "\t.section .idata$5\n");
907 fprintf (f, "fthunk:\n");
908 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
910 fprintf (f, "__imp_%s:\n", exp->name);
911 fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG,
916 fprintf (f, "\t%s\t0\n", ASM_LONG);
918 fprintf (f, "\n%s Hint name array\n", ASM_C);
919 fprintf (f, "\t.section .idata$4\n");
920 fprintf (f, "hname:\n");
921 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
923 fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG, ASM_RVA_BEFORE,
928 fprintf (f, "\t%s\t0\n", ASM_LONG);
929 fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C);
930 fprintf (f, "\t.section .idata$6\n");
932 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
934 fprintf (f,"\t%s\n", ASM_ALIGN_SHORT);
935 fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal);
936 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
938 fprintf (f, "\t%s\t0\n", ASM_LONG);
939 fprintf (f, "iname:\t%s\t\"%s.%s\"\n", ASM_TEXT, outfile_prefix, d_suffix);
942 /**********************************************************************/
944 /* Run through the information gathered from the .o files and the
945 .def file and work out the best stuff */
951 export_type *ap = *(export_type **) a;
952 export_type *bp = *(export_type **) b;
953 if (ap->ordinal == bp->ordinal)
956 /* unset ordinals go to the bottom */
957 if (ap->ordinal == -1)
959 if (bp->ordinal == -1)
961 return (ap->ordinal - bp->ordinal);
970 export_type *ap = *(export_type **) a;
971 export_type *bp = *(export_type **) b;
973 return (strcmp (ap->name, bp->name));
978 remove_null_names (ptr)
983 for (dst = src = 0; src < d_nfuncs; src++)
1000 for (i = 0; i < d_nfuncs; i++)
1004 printf ("%d %s @ %d %s%s\n",
1005 i, ptr[i]->name, ptr[i]->ordinal,
1006 ptr[i]->noname ? "NONAME " : "",
1007 ptr[i]->constant ? "CONSTANT" : "");
1016 process_duplicates (d_export_vec)
1017 export_type **d_export_vec;
1024 /* Remove duplicates */
1025 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
1027 dtab (d_export_vec);
1028 for (i = 0; i < d_nfuncs - 1; i++)
1030 if (strcmp (d_export_vec[i]->name,
1031 d_export_vec[i + 1]->name) == 0)
1034 export_type *a = d_export_vec[i];
1035 export_type *b = d_export_vec[i + 1];
1039 fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1043 if (a->ordinal != -1
1044 && b->ordinal != -1)
1047 fprintf (stderr, "Error, duplicate EXPORT with oridinals %s\n",
1051 /* Merge attributes */
1052 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
1053 b->constant |= a->constant;
1054 b->noname |= a->noname;
1055 d_export_vec[i] = 0;
1058 dtab (d_export_vec);
1059 remove_null_names (d_export_vec);
1060 dtab (d_export_vec);
1066 fill_ordinals (d_export_vec)
1067 export_type **d_export_vec;
1072 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1074 /* fill in the unset ordinals with ones from our range */
1076 ptr = (char *) malloc (65536);
1078 memset (ptr, 65536, 0);
1080 /* Mark in our large vector all the numbers that are taken */
1081 for (i = 0; i < d_nfuncs; i++)
1083 if (d_export_vec[i]->ordinal != -1)
1085 ptr[d_export_vec[i]->ordinal] = 1;
1087 lowest = d_export_vec[i]->ordinal;
1091 for (i = 0; i < d_nfuncs; i++)
1093 if (d_export_vec[i]->ordinal == -1)
1096 for (j = lowest; j < 65536; j++)
1100 d_export_vec[i]->ordinal = j;
1104 for (j = 1; j < lowest; j++)
1108 d_export_vec[i]->ordinal = j;
1120 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1122 /* Work out the lowest ordinal number */
1123 if (d_export_vec[0])
1124 d_ord = d_export_vec[0]->ordinal;
1129 /* First work out the minimum ordinal chosen */
1134 export_type **d_export_vec
1135 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
1137 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1139 d_export_vec[i] = exp;
1142 process_duplicates (d_export_vec);
1143 fill_ordinals (d_export_vec);
1145 /* Put back the list in the new order */
1147 for (i = d_nfuncs - 1; i >= 0; i--)
1149 d_export_vec[i]->next = d_exports;
1150 d_exports = d_export_vec[i];
1155 /**********************************************************************/
1158 usage (file, status)
1162 fprintf (file, "Usage %s <options> <object-files>\n", program_name);
1163 fprintf (file, "\t -m <machine> Generate code for <machine>\n");
1164 fprintf (file, "\t --machine <machine>\n");
1165 fprintf (file, "\t -o <outprefix> Set output prefix\n");
1166 fprintf (file, "\t -d <deffile> Name input .def file\n");
1167 fprintf (file, "\t --def <deffile> \n");
1168 fprintf (file, "\t --base-file <basefile> Read linker generated base file\n");
1169 fprintf (file, "\t -b <basefile> \n");
1170 fprintf (file, "\t -v Verbose\n");
1171 fprintf (file, "\t -u Remove leading underscore from .lib\n");
1172 fprintf (file, "\t -k Kill @<n> from exported names\n");
1176 static struct option long_options[] =
1178 {"def", required_argument, NULL, 'd'},
1179 {"underscore", no_argument, NULL, 'u'},
1180 {"killat", no_argument, NULL, 'k'},
1181 {"help", no_argument, NULL, 'h'},
1182 {"machine", required_argument, NULL, 'm'},
1183 {"base-file", required_argument, NULL, 'b'},
1194 program_name = av[0];
1197 while ((c = getopt_long (ac, av, "kvbuh?m:o:Dd:", long_options, 0)) != EOF)
1209 outfile_prefix = optarg;
1227 base_file = fopen (optarg, "r");
1230 fprintf (stderr, "%s: Unable to open base-file %s\n",
1242 for (i = 0; mtable[i].type; i++)
1244 if (strcmp (mtable[i].type, mname) == 0)
1248 if (!mtable[i].type)
1250 fprintf (stderr, "Machine not supported\n");
1258 process_def_file (def_file);
1263 firstarg = av[optind];
1264 scan_obj_file (av[optind]);
1268 if (!outfile_prefix)
1271 outfile_prefix = d_name;
1273 outfile_prefix = def_file;
1275 outfile_prefix = firstarg;
1278 fprintf (stderr, "No way to create an output filename\n");
1282 outfile_prefix = prefix (outfile_prefix);
1285 fprintf (stderr, "%s: Outfile prefix is %s\n",
1286 program_name, outfile_prefix);