summaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>1999-05-16 14:12:20 +0000
committerNick Clifton <nickc@redhat.com>1999-05-16 14:12:20 +0000
commit09cca3f6f1d2bf2db85a10b875b76cb7942ae88f (patch)
treeb59e70a759f8f62a7be803796a1f2457f2d81f3a /binutils
parent02a36c28bf3262af4ede6115aa1724fe37ec50e1 (diff)
downloadbinutils-redhat-09cca3f6f1d2bf2db85a10b875b76cb7942ae88f.tar.gz
Add support for generating an mcore-elf dll.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog16
-rw-r--r--binutils/dlltool.c213
2 files changed, 206 insertions, 23 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index c24770f4a7..8b39b60a59 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,19 @@
+1999-05-16 Nick Clifton <nickc@cygnus.com>
+
+ * dlltool.c (deduce_name): New function: Deduce name of program to
+ run.
+ (mcore_elf_out_file): New variable: Name of mcore-elf output file.
+ (mcore_elf_linker): New variable: Name of linker to use.
+ (mcore_elf_linker_flags): New variable: Linker flags to pass.
+ (scan_obj_file): Cache filenames if necessary.
+ (usage): Document new command line options.
+ (main): Support new command line options: -M (generate an
+ mcore-elf output file) -L (name of linker to use) -F (flags to
+ pass to linker).
+ (mcore_elf_cache_filename): Store a filename in a cache.
+ (mcore_elf_gen_out_file): New function: Generate an output file
+ per the mcore-elf spec.
+
1999-05-15 Nick Clifton <nickc@cygnus.com>
* configure.in (BUILD_MISC): Build dlltool for mcore
diff --git a/binutils/dlltool.c b/binutils/dlltool.c
index c76fe396c0..91291262f8 100644
--- a/binutils/dlltool.c
+++ b/binutils/dlltool.c
@@ -236,6 +236,15 @@
#include "coff/internal.h"
#endif
+
+/* Forward references. */
+static char * deduce_name (char *);
+
+#ifdef DLLTOOL_MCORE_ELF
+static void mcore_elf_cache_filename (char *);
+static void mcore_elf_gen_out_file (void);
+#endif
+
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#else /* ! HAVE_SYS_WAIT_H */
@@ -304,7 +313,7 @@ typedef struct iheadt
static iheadtype *import_list = NULL;
-static char *as_name = "as";
+static char *as_name = NULL;
static char * as_flags = "";
static int no_idata4;
@@ -363,6 +372,10 @@ static const char * mname = "mcore";
#ifdef DLLTOOL_MCORE_ELF
static const char * mname = "mcore-elf";
+static char * mcore_elf_out_file = NULL;
+static char * mcore_elf_linker = NULL;
+static char * mcore_elf_linker_flags = NULL;
+
#define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")
#endif
@@ -1412,7 +1425,7 @@ scan_open_obj_file (abfd)
/* FIXME: we ought to read in and block out the base relocations */
/* xgettext:c-format */
- inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
+ inform (_("Done reading %s\n"), bfd_get_filename (abfd));
}
static void
@@ -1438,10 +1451,20 @@ scan_obj_file (filename)
bfd_close (arfile);
arfile = bfd_openr_next_archived_file (f, arfile);
}
+
+#ifdef DLLTOOL_MCORE_ELF
+ if (mcore_elf_out_file)
+ inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename);
+#endif
}
else if (bfd_check_format (f, bfd_object))
{
scan_open_obj_file (f);
+
+#ifdef DLLTOOL_MCORE_ELF
+ if (mcore_elf_out_file)
+ mcore_elf_cache_filename ((char *) filename);
+#endif
}
bfd_close (f);
@@ -3063,7 +3086,11 @@ usage (file, status)
fprintf (file, _(" -v --verbose Be verbose.\n"));
fprintf (file, _(" -V --version Display the program version.\n"));
fprintf (file, _(" -h --help Display this information.\n"));
-
+#ifdef DLLTOOL_MCORE_ELF
+ fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n"));
+ fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n"));
+ fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n"));
+#endif
exit (status);
}
@@ -3071,15 +3098,13 @@ usage (file, status)
#define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
#define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
-#define OPTION_NO_IDATA4 'x'
-#define OPTION_NO_IDATA5 'c'
static const struct option long_options[] =
{
{"no-delete", no_argument, NULL, 'n'},
{"dllname", required_argument, NULL, 'D'},
- {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
- {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
+ {"no-idata4", no_argument, NULL, 'x'},
+ {"no-idata5", no_argument, NULL, 'c'},
{"output-exp", required_argument, NULL, 'e'},
{"output-def", required_argument, NULL, 'z'},
{"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
@@ -3100,6 +3125,7 @@ static const struct option long_options[] =
{"base-file", required_argument, NULL, 'b'},
{"as", required_argument, NULL, 'S'},
{"as-flags", required_argument, NULL, 'f'},
+ {"mcore-elf", required_argument, NULL, 'M'},
{0}
};
@@ -3120,18 +3146,17 @@ main (ac, av)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
- while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkAvVb:Uh?m:d:f:i",
+ while ((c = getopt_long (ac, av,
+#ifdef DLLTOOL_MCORE_ELF
+ "m:e:l:aD:d:z:b:xcuUkAS:f:nvVhM:L:F:",
+#else
+ "m:e:l:aD:d:z:b:xcuUkAS:f:nvVh",
+#endif
long_options, 0))
!= EOF)
{
switch (c)
{
- case OPTION_NO_IDATA4:
- no_idata4 = 1;
- break;
- case OPTION_NO_IDATA5:
- no_idata5 = 1;
- break;
case OPTION_EXPORT_ALL_SYMS:
export_all_symbols = true;
break;
@@ -3144,6 +3169,12 @@ main (ac, av)
case OPTION_NO_DEFAULT_EXCLUDES:
do_default_excludes = false;
break;
+ case 'x':
+ no_idata4 = 1;
+ break;
+ case 'c':
+ no_idata5 = 1;
+ break;
case 'S':
as_name = optarg;
break;
@@ -3181,13 +3212,6 @@ main (ac, av)
case 'V':
print_version (program_name);
break;
- case 'y':
-#if 0
- /* We don't currently define YYDEBUG when building
- defparse.y. */
- yydebug = 1;
-#endif
- break;
case 'U':
add_underscore = 1;
break;
@@ -3211,6 +3235,17 @@ main (ac, av)
fatal (_("Unable to open base-file: %s"), optarg);
break;
+#ifdef DLLTOOL_MCORE_ELF
+ case 'M':
+ mcore_elf_out_file = optarg;
+ break;
+ case 'L':
+ mcore_elf_linker = optarg;
+ break;
+ case 'F':
+ mcore_elf_linker_flags = optarg;
+ break;
+#endif
default:
usage (stderr, 1);
break;
@@ -3218,10 +3253,8 @@ main (ac, av)
}
for (i = 0; mtable[i].type; i++)
- {
if (strcmp (mtable[i].type, mname) == 0)
break;
- }
if (!mtable[i].type)
/* xgettext:c-format */
@@ -3237,6 +3270,9 @@ main (ac, av)
strcat (dll_name, ".dll");
}
+ if (as_name == NULL)
+ as_name = deduce_name ("as");
+
/* Don't use the default exclude list if we're reading only the
symbols in the .drectve section. The default excludes are meant
to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
@@ -3280,5 +3316,136 @@ main (ac, av)
if (output_def)
gen_def_file ();
+#ifdef DLLTOOL_MCORE_ELF
+ if (mcore_elf_out_file)
+ mcore_elf_gen_out_file ();
+#endif
+
return 0;
}
+
+/* Deduce the name of the program we are want to invoke.
+ PROG_NAME is the basic name of the program we want to run,
+ eg "as" or "ld". The catch is that we might want actually
+ run "i386-pe-as" or "ppc-pe-ld". We detect this case by
+ examining the name used to invoke dlltool itself. If
+ dlltool is actually called <foo>-<bar>-dlltool then we
+ prepend <foo>-<bar> to the default name. */
+static char *
+deduce_name (char * prog_name)
+{
+ /* Use our own static array to hold the constructed name
+ rather than the outfile[] array, as that array may
+ already be in use. */
+ static char new_name[32];
+ char * p;
+
+ p = strrchr (program_name, '-');
+
+ if (p == NULL)
+ return prog_name;
+
+ /* assert (strlen (program_name) < 32); */
+
+ strcpy (new_name, program_name);
+
+ new_name [(p - program_name) + 1] = 0;
+
+ strcat (new_name, prog_name);
+
+ return new_name;
+}
+
+#ifdef DLLTOOL_MCORE_ELF
+typedef struct fname_cache
+{
+ char * filename;
+ struct fname_cache * next;
+}
+fname_cache;
+
+static fname_cache fnames;
+
+static void
+mcore_elf_cache_filename (char * filename)
+{
+ fname_cache * ptr;
+
+ ptr = & fnames;
+
+ while (ptr->next != NULL)
+ ptr = ptr->next;
+
+ ptr->filename = filename;
+ ptr->next = (fname_cache *) malloc (sizeof (fname_cache));
+ if (ptr->next != NULL)
+ ptr->next->next = NULL;
+}
+
+static void
+mcore_elf_gen_out_file (void)
+{
+ fname_cache * ptr;
+
+ /* Step one. Run 'ld -r' on the input object files in order to resolve
+ any internal references and to generate a single .exports section. */
+ ptr = & fnames;
+
+ strcpy (outfile, "-r ");
+
+ if (mcore_elf_linker_flags != NULL)
+ strcat (outfile, mcore_elf_linker_flags);
+
+ while (ptr->next != NULL)
+ {
+ /* Check for overrun: what the hell, it's only cpu cycles... */
+ if (strlen (outfile) + strlen (ptr->filename) + 2 >= sizeof (outfile))
+ {
+ fatal (_("buffer overflow\n"));
+ return;
+ }
+
+ strcat (outfile, ptr->filename);
+ strcat (outfile, " ");
+
+ ptr = ptr->next;
+ }
+
+ strcat (outfile, "-o mcoreelf.tmp");
+
+ if (mcore_elf_linker == NULL)
+ mcore_elf_linker = deduce_name ("ld");
+
+ run (mcore_elf_linker, outfile);
+
+ /* Step two. Create a .exp file and a .lib file from the temporary file.
+ Do this by recursively invoking dlltool....*/
+ sprintf (outfile, "-S %s", as_name);
+
+ strcat (outfile, " -e mcoreelf.exp -l mcoreelf.lib mcoreelf.tmp");
+
+ if (verbose)
+ strcat (outfile, " -v");
+
+ if (dontdeltemps)
+ strcat (outfile, " -n");
+
+ if (dontdeltemps > 1)
+ strcat (outfile, " -n");
+
+ /* XXX - FIME: ought to check/copy other command line options as well. */
+
+ run (program_name, outfile);
+
+ /* Step four. Feed the two new files to ld -shared. */
+ strcpy (outfile, "-shared ");
+
+ if (mcore_elf_linker_flags)
+ strcat (outfile, mcore_elf_linker_flags);
+
+ strcat (outfile, " mcoreelf.exp mcoreelf.lib -o ");
+ strcat (outfile, mcore_elf_out_file);
+
+ run (mcore_elf_linker, outfile);
+}
+#endif /* DLLTOOL_MCORE_ELF */