Sun Aug 20 09:59:00 1995 steve chamberlain <sac@slash.cygnus.com>

Modified to generate archives and objects rather than .s files.
	* dlltool.c (run) New function.
 	(gen_exp_file, gen_lib_file): Use run.
	(workout_prefix): New.
	(usage): Document new options.
	(main): Parse new options.
This commit is contained in:
Steve Chamberlain 1995-08-20 17:01:27 +00:00
parent 715682510e
commit 2757dc2534
2 changed files with 376 additions and 127 deletions

View File

@ -1,3 +1,12 @@
Sun Aug 20 09:59:00 1995 steve chamberlain <sac@slash.cygnus.com>
Modified to generate archives and objects rather than .s files.
* dlltool.c (run) New function.
(gen_exp_file, gen_lib_file): Use run.
(workout_prefix): New.
(usage): Document new options.
(main): Parse new options.
Wed Aug 16 16:26:52 1995 steve chamberlain <sac@slash.cygnus.com> Wed Aug 16 16:26:52 1995 steve chamberlain <sac@slash.cygnus.com>
* dlltool.c (gen_exp_file): Fix RVA handling. * dlltool.c (gen_exp_file): Fix RVA handling.

View File

@ -74,8 +74,6 @@
on the command line, or in the def file, or taken from the first on the command line, or in the def file, or taken from the first
supplied argument. supplied argument.
The output files are <prefix>-exp.s and <prefix>-lib.s
The .exp.s file contains the information necessary to export The .exp.s file contains the information necessary to export
the routines in the DLL. The .lib.s file contains the information the routines in the DLL. The .lib.s file contains the information
necessary to use the DLL's routines from a referencing program. necessary to use the DLL's routines from a referencing program.
@ -147,21 +145,16 @@
ranlib thedll.in ranlib thedll.in
# run this tool over the library and the def file # run this tool over the library and the def file
./dlltool -o thedll -d thedll.def thedll.in ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
# build the export table for the dll
as -o thedll.exp thedll-exp.s
# build the dll with the library with file1.o, file2.o and the export table # build the dll with the library with file1.o, file2.o and the export table
ld -o thedll.dll thedll.exp thedll.in ld -o thedll.dll thedll.o thedll.in
# build the import table for the executable
as -o thedll.lib thedll-lib.s
# build the mainline # build the mainline
gcc -c themain.c gcc -c themain.c
# link the executable with the import library # link the executable with the import library
ld -e main -Tthemain.ld -o themain.exe themain.o thedll.lib ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
*/ */
@ -172,14 +165,25 @@
#include <string.h> #include <string.h>
#include "getopt.h" #include "getopt.h"
#include "bfd.h" #include "bfd.h"
#include <wait.h>
char *ar_name = "ar";
char *as_name = "as";
char *ranlib_name = "ranlib";
long rva = 0x400000;
char *exp_name;
char *imp_name;
char *dll_name;
int deltemps = 1;
int yydebug; int yydebug;
char *def_file; char *def_file;
char *program_name; char *program_name;
char *strrchr (); char *strrchr ();
char *outfile_prefix;
char *xmalloc (); char *xmalloc ();
char *strdup (); char *strdup ();
@ -210,24 +214,36 @@ struct mac
char *how_global; char *how_global;
char *how_space; char *how_space;
char *how_align_short; char *how_align_short;
char *how_rva_before;
char *how_rva_after;
} }
mtable[] mtable[]
= =
{ {
{ {
"arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space",".align\t2","(",")-0x400000" "arm", ".byte", ".short", ".long", ".asciz", "@", "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", ".global", ".space", ".align\t2",
} }
, ,
{ {
"i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space",".align\t2", "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",
"(",")-0x400000"
} }
, ,
0 0
}; };
char *rvaafter (machine)
int machine;
{
char b[20];
sprintf(b,")-0x%x", rva);
return strdup (b);
}
char *rvabefore (machine)
int machine;
{
return "(";
}
#define ASM_BYTE mtable[machine].how_byte #define ASM_BYTE mtable[machine].how_byte
#define ASM_SHORT mtable[machine].how_short #define ASM_SHORT mtable[machine].how_short
#define ASM_LONG mtable[machine].how_long #define ASM_LONG mtable[machine].how_long
@ -237,8 +253,8 @@ mtable[]
#define ASM_GLOBAL mtable[machine].how_global #define ASM_GLOBAL mtable[machine].how_global
#define ASM_SPACE mtable[machine].how_space #define ASM_SPACE mtable[machine].how_space
#define ASM_ALIGN_SHORT mtable[machine].how_align_short #define ASM_ALIGN_SHORT mtable[machine].how_align_short
#define ASM_RVA_BEFORE mtable[machine].how_rva_before #define ASM_RVA_BEFORE rvabefore(machine)
#define ASM_RVA_AFTER mtable[machine].how_rva_after #define ASM_RVA_AFTER rvaafter(machine)
static char **oav; static char **oav;
@ -289,7 +305,6 @@ static char *d_name; /* Arg to NAME or LIBRARY */
static int d_nfuncs; /* Number of functions exported */ static int d_nfuncs; /* Number of functions exported */
static int d_ord; /* Base ordinal index */ static int d_ord; /* Base ordinal index */
static export_type *d_exports; /*list of exported functions */ static export_type *d_exports; /*list of exported functions */
static char *d_suffix = "dll";
static dlist_type *d_list; /* Descriptions */ static dlist_type *d_list; /* Descriptions */
static dlist_type *a_list; /* Stuff to go in directives */ static dlist_type *a_list; /* Stuff to go in directives */
@ -335,8 +350,6 @@ def_name (name, base)
fprintf (stderr, "Can't have LIBRARY and NAME\n"); fprintf (stderr, "Can't have LIBRARY and NAME\n");
} }
d_name = name; d_name = name;
if (strchr (d_name, '.'))
d_suffix = strdup (strchr (d_name, '.') + 1);
d_is_exe = 1; d_is_exe = 1;
} }
@ -352,8 +365,6 @@ def_library (name, base)
fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name); fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name);
} }
d_name = name; d_name = name;
if (strchr (d_name, '.'))
d_suffix = strdup (strchr (d_name, '.') + 1);
d_is_dll = 1; d_is_dll = 1;
} }
@ -460,6 +471,76 @@ def_data (attr)
/**********************************************************************/ /**********************************************************************/
void
run (what, args)
char *what;
char *args;
{
char *s;
int pid;
int i;
char **argv;
extern char **environ;
if (verbose)
fprintf (stderr, "%s %s\n", what, args);
/* Count the args */
i = 0;
for (s = args; *s ; s++)
if (*s == ' ')
i++;
i++;
argv = alloca (sizeof (char *) * (i + 3));
i = 0;
argv[i++] = what;
s = args;
while (1) {
argv[i++] = s;
while (*s != ' ' && *s != 0)
s++;
if (*s == 0)
break;
*s++ = 0;
}
argv[i++] = 0;
pid = vfork ();
if (pid == 0)
{
execvp (what, argv);
fprintf (stderr, "%s: can't exec %s\n", program_name, what);
exit (1);
}
else if (pid == -1)
{
extern int errno;
fprintf (stderr, "%s: vfork failed, %d\n", program_name, errno);
exit (1);
}
else
{
int status;
waitpid (pid, &status);
if (status)
{
if (WIFSIGNALED (status))
{
fprintf (stderr, "%s: %s %s terminated with signal %d\n",
program_name, what, args, WTERMSIG (status));
exit (1);
}
if (WIFEXITED (status))
{
fprintf (stderr, "%s: %s %s terminated with exit status %d\n",
program_name, what, args, WEXITSTATUS (status));
exit (1);
}
}
}
}
/* read in and block out the base relocations */ /* read in and block out the base relocations */
static void static void
basenames (abfd) basenames (abfd)
@ -646,11 +727,11 @@ gen_exp_file ()
dlist_type *dl; dlist_type *dl;
int had_noname = 0; int had_noname = 0;
sprintf (outfile, "%s-exp.s", outfile_prefix); sprintf (outfile, "t%s", exp_name);
if (verbose) if (verbose)
fprintf (stderr, "%s: Generate exp file %s\n", fprintf (stderr, "%s: Generate exp file %s\n",
program_name, outfile_prefix); program_name, exp_name);
f = fopen (outfile, "w"); f = fopen (outfile, "w");
if (!f) if (!f)
@ -670,7 +751,7 @@ gen_exp_file ()
fprintf (f, "\t%s %d %s Time and date\n", ASM_LONG, time (0), ASM_C); fprintf (f, "\t%s %d %s Time and date\n", ASM_LONG, time (0), ASM_C);
fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C); fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
fprintf (f, "\t%s %sname%s%s Ptr to name of dll\n", ASM_LONG, ASM_RVA_BEFORE, fprintf (f, "\t%s %sname%s%s Ptr to name of dll\n", ASM_LONG, ASM_RVA_BEFORE,
ASM_RVA_AFTER,ASM_C); ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_ord, ASM_C); fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_ord, ASM_C);
fprintf (f, "\t%s The next field is documented as being the number of functions\n", ASM_C); fprintf (f, "\t%s The next field is documented as being the number of functions\n", ASM_C);
fprintf (f, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C); fprintf (f, "\t%s yet it doesn't look like that in real PE dlls\n", ASM_C);
@ -679,13 +760,13 @@ gen_exp_file ()
fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_nfuncs, ASM_C); fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_nfuncs, ASM_C);
fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, d_nfuncs, ASM_C); fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, d_nfuncs, ASM_C);
fprintf (f, "\t%s %safuncs%s %s Address of functions\n", ASM_LONG, fprintf (f, "\t%s %safuncs%s %s Address of functions\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_AFTER,ASM_C); ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s %sanames%s %s Address of names\n", ASM_LONG, fprintf (f, "\t%s %sanames%s %s Address of names\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_AFTER,ASM_C); ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s %sanords%s %s Address of ordinals\n", ASM_LONG, fprintf (f, "\t%s %sanords%s %s Address of ordinals\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_AFTER,ASM_C); ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
fprintf (f, "name: %s \"%s.%s\"\n", ASM_TEXT, outfile_prefix, d_suffix); fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
fprintf (f, "afuncs:\n"); fprintf (f, "afuncs:\n");
i = d_ord; i = d_ord;
@ -703,7 +784,7 @@ gen_exp_file ()
} }
#endif #endif
fprintf (f, "\t%s\t%s%s%s%s %d\n", ASM_LONG, ASM_RVA_BEFORE, fprintf (f, "\t%s\t%s%s%s%s %d\n", ASM_LONG, ASM_RVA_BEFORE,
exp->internal_name,ASM_RVA_AFTER, ASM_C, exp->ordinal); exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
i++; i++;
} }
@ -718,7 +799,7 @@ gen_exp_file ()
} }
else else
{ {
fprintf (f, "\t%s %sn%d%s\n", ASM_LONG, ASM_RVA_BEFORE,i,ASM_RVA_AFTER); fprintf (f, "\t%s %sn%d%s\n", ASM_LONG, ASM_RVA_BEFORE, i, ASM_RVA_AFTER);
} }
} }
@ -797,7 +878,7 @@ gen_exp_file ()
qsort (copy, num_entries, sizeof (long), sfunc); qsort (copy, num_entries, sizeof (long), sfunc);
addr = copy[0]; addr = copy[0];
page_addr = addr & PAGE_MASK; /* work out the page addr */ page_addr = addr & PAGE_MASK; /* work out the page addr */
on_page = 0; on_page = 0;
for (j = 0; j < num_entries; j++) for (j = 0; j < num_entries; j++)
{ {
@ -812,10 +893,19 @@ gen_exp_file ()
} }
flush_page (f, need, page_addr, on_page); flush_page (f, need, page_addr, on_page);
fprintf (f, "\t%s\t0,0\t%s End\n",ASM_LONG, ASM_C); fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);
} }
fclose (f); fclose (f);
/* assemble the file */
sprintf (outfile,"-o %s t%s", exp_name, exp_name);
run (as_name, outfile);
if (deltemps)
{
sprintf (outfile,"t%s", exp_name);
unlink (outfile);
}
} }
static char * static char *
@ -827,55 +917,50 @@ xlate (char *name)
if (name[0] == '_') if (name[0] == '_')
name++; name++;
if (killat) { if (killat)
char *p; {
p = strchr (name, '@'); char *p;
if (p) p = strchr (name, '@');
*p = 0; if (p)
} *p = 0;
}
return name; return name;
} }
/**********************************************************************/ /**********************************************************************/
gen_lib_file () gen_lib_file ()
{ {
int i; int i;
int sol;
FILE *f; FILE *f;
export_type *exp; export_type *exp;
char *output_filename;
char prefix[PATHMAX];
sprintf (outfile, "%s-lib.s", outfile_prefix); sprintf (outfile, "%s", imp_name);
output_filename = strdup (outfile);
unlink (output_filename);
strcpy (prefix, "d");
sprintf (outfile, "%sh.s", prefix);
f = fopen (outfile, "w"); f = fopen (outfile, "w");
if (!f)
{
fprintf (stderr, "Unable to open output file %s\n", outfile);
exit (1);
}
dump_def_info (f);
fprintf (f, "\t.text\n");
fprintf (f, "%s Thunk table\n", ASM_C);
for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{
fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name);
fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
}
for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{
fprintf (f, "%s:\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name);
}
fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C); fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
fprintf (f, "\t.section .idata$2\n"); fprintf (f, "\t.section .idata$2\n");
fprintf (f, "\t%s\t__%s_head\n", ASM_GLOBAL, imp_name);
fprintf (f, "__%s_head:\n", imp_name);
fprintf (f, "\t%s\t%shname%s\t%sPtr to image import by name list\n", ASM_LONG, fprintf (f, "\t%s\t%shname%s\t%sPtr to image import by name list\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s\t%d\t%s time\n", ASM_LONG, time (0), ASM_C); fprintf (f, "\t%s\t%d\t%s time\n", ASM_LONG, time (0), ASM_C);
fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C); fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
fprintf (f, "\t%s\t%siname%s\t%s imported dll's name\n", ASM_LONG, fprintf (f, "\t%s\t%s__%s_iname%s\t%s imported dll's name\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_BEFORE,
imp_name,
ASM_RVA_AFTER, ASM_RVA_AFTER,
ASM_C); ASM_C);
fprintf (f, "\t%s\t%sfthunk%s\t%s pointer to firstthunk\n", ASM_LONG, fprintf (f, "\t%s\t%sfthunk%s\t%s pointer to firstthunk\n", ASM_LONG,
@ -883,57 +968,131 @@ gen_lib_file ()
ASM_RVA_AFTER, ASM_C); ASM_RVA_AFTER, ASM_C);
fprintf (f, "%sStuff for compatibility\n", ASM_C); fprintf (f, "%sStuff for compatibility\n", ASM_C);
#if 0
fprintf (f, "\t.section\t.idata$3\n");
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
#endif
fprintf (f, "\t.section\t.idata$5\n"); fprintf (f, "\t.section\t.idata$5\n");
fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "fthunk:\n");
fprintf (f, "\t.section\t.idata$4\n"); fprintf (f, "\t.section\t.idata$4\n");
fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t.section .idata$4\n");
fprintf (f, "hname:\n");
fclose (f);
sprintf (outfile, "-o %sh.o %sh.s", prefix, prefix);
run (as_name, outfile);
fprintf (f, "\n%s Loader modifies this\n", ASM_C);
fprintf (f, "\t.section .idata$5\n");
fprintf (f, "fthunk:\n");
for (i = 0, exp = d_exports; exp; i++, exp = exp->next) for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{ {
sprintf (outfile, "%ss%d.s", prefix, i);
f = fopen (outfile, "w");
fprintf (f, "\n\n\n%s ********************* \n", ASM_C);
fprintf (f, "\t.text\n");
fprintf (f, "\t%s\t%s\n", ASM_GLOBAL, exp->name);
fprintf (f, "%s:\n\t%s\t__imp_%s\n", exp->name, ASM_JUMP, exp->name);
fprintf (f, "\t.section\t.idata$7\t%s To force loading of head and tail\n", ASM_C);
fprintf (f, "\t%s\t__%s_head\n", ASM_LONG, imp_name);
fprintf (f, "\t%s\t__%s_tail\n", ASM_LONG, imp_name);
fprintf (f, "\t.section .idata$5\n");
fprintf (f, "__imp_%s:\n", exp->name); fprintf (f, "__imp_%s:\n", exp->name);
fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG, fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG,
ASM_RVA_BEFORE, ASM_RVA_BEFORE,
i, i,
ASM_RVA_AFTER); ASM_RVA_AFTER);
}
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\n%s Hint name array\n", ASM_C); fprintf (f, "\n%s Hint name array\n", ASM_C);
fprintf (f, "\t.section .idata$4\n"); fprintf (f, "\t.section .idata$4\n");
fprintf (f, "hname:\n");
for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{
fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG, ASM_RVA_BEFORE, fprintf (f, "\t%s\t%sID%d%s\n", ASM_LONG, ASM_RVA_BEFORE,
i, i,
ASM_RVA_AFTER); ASM_RVA_AFTER);
}
fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C);
fprintf (f, "%s Hint/name array storage and import dll name\n", ASM_C); fprintf (f, "\t.section .idata$6\n");
fprintf (f, "\t.section .idata$6\n");
for (i = 0, exp = d_exports; exp; i++, exp = exp->next) fprintf (f, "\t%s\n", ASM_ALIGN_SHORT);
{
fprintf (f,"\t%s\n", ASM_ALIGN_SHORT);
fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal); fprintf (f, "ID%d:\t%s\t%d\n", i, ASM_SHORT, exp->ordinal);
fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name)); fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
fclose (f);
sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
run (as_name, outfile);
} }
sprintf (outfile, "%st.s", prefix);
f = fopen (outfile, "w");
fprintf (f, "\t%s\t__%s_tail\n", ASM_GLOBAL, imp_name);
fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name);
fprintf (f, "__%s_tail:\n", imp_name);
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
imp_name, ASM_TEXT, dll_name);
fprintf (f, "\t.section .idata$4\n");
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t.section .idata$5\n");
fprintf (f, "\t%s\t0\n", ASM_LONG); fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "iname:\t%s\t\"%s.%s\"\n", ASM_TEXT, outfile_prefix, d_suffix);
fclose (f); fclose (f);
sprintf (outfile, "-o %st.o %st.s", prefix, prefix);
run (as_name, outfile);
/* Now stick them all into the archive */
sprintf (outfile, "crs %s %sh.o %st.o", output_filename, prefix, prefix);
run (ar_name, outfile);
/* Do the rest in groups of however many fit into a command line */
sol = 0;
for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{
if (sol == 0)
{
sol = sprintf (outfile, "crs %s", output_filename);
}
sol += sprintf (outfile + sol, " %ss%d.o", prefix, i);
if (sol >100)
{
run (ar_name, outfile);
sol = 0;
}
}
if (sol)
run (ar_name, outfile);
/* Delete all the temp files */
if (deltemps)
{
sprintf (outfile, "%sh.o", prefix);
unlink (outfile);
sprintf (outfile, "%sh.s", prefix);
unlink (outfile);
sprintf (outfile, "%st.o", prefix);
unlink (outfile);
sprintf (outfile, "%st.s", prefix);
unlink (outfile);
}
/* Always delete these */
for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
{
sprintf (outfile, "%ss%d.o", prefix, i);
unlink (outfile);
sprintf (outfile, "%ss%d.s", prefix, i);
unlink (outfile);
}
} }
/**********************************************************************/ /**********************************************************************/
@ -1148,6 +1307,66 @@ mangle_defs ()
} }
/* Work out exec prefix from the name of this file */
void
workout_prefix ()
{
char *ps = 0;
char *s = 0;
char *p;
/* See if we're running in a devo tree */
for (p = program_name; *p; p++)
{
if (*p == '/' || *p == '\\')
{
ps = s;
s = p;
}
}
if (ps && strncmp (ps, "/binutils", 9) == 0)
{
/* running in the binutils directory, the other
executables will be surrounding it in the usual places. */
int len = ps - program_name;
ar_name = xmalloc (len + strlen ("/binutils/ar") + 1);
ranlib_name = xmalloc (len + strlen ("/binutils/ranlib") + 1);
as_name = xmalloc (len + strlen ("/gas/as.new") + 1);
strncpy (ar_name, program_name, len);
strcat (ar_name, "/binutils/ar");
strncpy (ranlib_name, program_name, len);
strcat (ranlib_name, "/binutils/ranlib");
strncpy (as_name, program_name, len);
strcat (as_name, "/gas/as.new");
}
else
{
/* Otherwise chop off any prefix and use it for the rest of the progs,
so i386-win32-dll generates i386-win32-ranlib etc etc */
for (p = program_name; *p; p++)
{
if (strncmp (p, "dlltool", 7) == 0)
{
int len = p - program_name;
ar_name = xmalloc (len + strlen ("ar") +1);
ranlib_name = xmalloc (len + strlen ("ranlib")+1);
as_name = xmalloc (len + strlen ("as")+1);
strncpy (ar_name, program_name, len);
strcat (ar_name, "ar");
strncpy (ranlib_name, program_name, len);
strcat (ranlib_name, "ranlib");
strncpy (as_name, program_name, len);
strcat (as_name, "as");
}
}
}
}
/**********************************************************************/ /**********************************************************************/
void void
@ -1158,7 +1377,11 @@ usage (file, status)
fprintf (file, "Usage %s <options> <object-files>\n", program_name); fprintf (file, "Usage %s <options> <object-files>\n", program_name);
fprintf (file, "\t -m <machine> Generate code for <machine>\n"); fprintf (file, "\t -m <machine> Generate code for <machine>\n");
fprintf (file, "\t --machine <machine>\n"); fprintf (file, "\t --machine <machine>\n");
fprintf (file, "\t -o <outprefix> Set output prefix\n"); fprintf (file, "\t --output-exp <outname> Generate export file.\n");
fprintf (file, "\t -e <outname>\n");
fprintf (file, "\t --output-lib <outname> Generate input library.\n");
fprintf (file, "\t -l <outname>");
fprintf (file, "\t --dllname <name> Name of input dll to put into output lib.\n");
fprintf (file, "\t -d <deffile> Name input .def file\n"); fprintf (file, "\t -d <deffile> Name input .def file\n");
fprintf (file, "\t --def <deffile> \n"); fprintf (file, "\t --def <deffile> \n");
fprintf (file, "\t --base-file <basefile> Read linker generated base file\n"); fprintf (file, "\t --base-file <basefile> Read linker generated base file\n");
@ -1166,20 +1389,31 @@ usage (file, status)
fprintf (file, "\t -v Verbose\n"); fprintf (file, "\t -v Verbose\n");
fprintf (file, "\t -u Remove leading underscore from .lib\n"); fprintf (file, "\t -u Remove leading underscore from .lib\n");
fprintf (file, "\t -k Kill @<n> from exported names\n"); fprintf (file, "\t -k Kill @<n> from exported names\n");
fprintf (file, "\t --rva <value> Set the RVA from the default of 0x400000\n");
fprintf (file, "\t -r <value>\n");
fprintf (file, "\t --nodelete Keep temp files.\n");
fprintf (file, "\t -n \n");
exit (status); exit (status);
} }
static struct option long_options[] = static struct option long_options[] =
{ {
{"nodelete", no_argument, NULL,'n'},
{"dllname", required_argument, NULL,'D'},
{"output-exp", required_argument, NULL, 'e'},
{"output-lib", required_argument, NULL, 'l'},
{"def", required_argument, NULL, 'd'}, {"def", required_argument, NULL, 'd'},
{"underscore", no_argument, NULL, 'u'}, {"underscore", no_argument, NULL, 'u'},
{"killat", no_argument, NULL, 'k'}, {"killat", no_argument, NULL, 'k'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"machine", required_argument, NULL, 'm'}, {"machine", required_argument, NULL, 'm'},
{"rva", required_argument, NULL, 'r'},
{"base-file", required_argument, NULL, 'b'}, {"base-file", required_argument, NULL, 'b'},
0 0
}; };
int int
main (ac, av) main (ac, av)
int ac; int ac;
@ -1190,10 +1424,19 @@ main (ac, av)
program_name = av[0]; program_name = av[0];
oav = av; oav = av;
while ((c = getopt_long (ac, av, "kvbuh?m:o:Dd:", long_options, 0)) != EOF) while ((c = getopt_long (ac, av, "D:l:e:nr:kvbuh?m:yd:", long_options, 0)) != EOF)
{ {
switch (c) switch (c)
{ {
case 'D':
dll_name = optarg;
break;
case 'l':
imp_name = optarg;
break;
case 'e':
exp_name = optarg;
break;
case 'h': case 'h':
case '?': case '?':
usage (stderr, 0); usage (stderr, 0);
@ -1201,13 +1444,13 @@ main (ac, av)
case 'm': case 'm':
mname = optarg; mname = optarg;
break; break;
case 'o': case 'r':
outfile_prefix = optarg; rva = strtoul (optarg, 0,0);
break; break;
case 'v': case 'v':
verbose = 1; verbose = 1;
break; break;
case 'D': case 'y':
yydebug = 1; yydebug = 1;
break; break;
case 'u': case 'u':
@ -1219,6 +1462,9 @@ main (ac, av)
case 'd': case 'd':
def_file = optarg; def_file = optarg;
break; break;
case 'n':
deltemps = 0;
break;
case 'b': case 'b':
base_file = fopen (optarg, "r"); base_file = fopen (optarg, "r");
if (!base_file) if (!base_file)
@ -1249,6 +1495,16 @@ main (ac, av)
machine = i; machine = i;
if (!dll_name && exp_name)
{
char len = strlen (exp_name) + 5;
dll_name = xmalloc (len);
strcpy (dll_name, exp_name);
strcat (dll_name, ".dll");
}
workout_prefix ();
if (def_file) if (def_file)
{ {
process_def_file (def_file); process_def_file (def_file);
@ -1261,31 +1517,15 @@ main (ac, av)
optind++; optind++;
} }
if (!outfile_prefix)
{
if (d_name)
outfile_prefix = d_name;
else if (def_file)
outfile_prefix = def_file;
else if (firstarg)
outfile_prefix = firstarg;
else
{
fprintf (stderr, "No way to create an output filename\n");
exit (1);
}
}
outfile_prefix = prefix (outfile_prefix);
if (verbose)
fprintf (stderr, "%s: Outfile prefix is %s\n",
program_name, outfile_prefix);
mangle_defs (); mangle_defs ();
gen_exp_file (); if (exp_name)
gen_exp_file ();
if (imp_name)
gen_lib_file (); gen_lib_file ();
return 0; return 0;
} }