emulation on i386-coff, i386-elf patches
Robert Lipe
robertl@dgii.com
Wed Jan 8 10:43:00 GMT 1997
I have a need for an assembler that can switch between generating
i386-elf and i386-coff. Since the gas doco hints that the emulation
stuff is desirable, but not fully implemented, I decided to take one
stab at it. Once finished, this would surely be desirable in, say,
Linux, where it's common to need to flip between the two targets.
The attached patches probably break non-bfd COFF targets and should not
be applied by anyone not willing to slog around in the code a little bit.
If someone that really understands BFD is willing to work with me a little
bit on this, I think it will be useful.
I did most of my testing on progressive-96q4 code. I did apply the
stuff to the 1217 snaps on ftp.cygnus.com:/private/jelly. All I had
to change was to add the frob_file_after_relocs vector into the middle
of the format_ops structure.
I can switch between the two modes with --em=i386coff [ default ]and
--em=i386elf. I see that it does the right thing in switching around
the recognized pseudo ops and it generates .o's recognized correctly by
file. The ELF .o of "hello, world" world even links and runs.
However, the COFF version has a problem that isn't obvious to me. Here
is a disassembly of the same .s file generated with the native COFF
assembler and with this assembler in COFF mode.
$ dis x.o | tail
main
0: eb 0d jmp 0xd <f>
2: 68 00 00 00 00 pushl $0x0
7: e8 fc ff ff ff call 0xfffffffc <8>
c: 59 popl %ecx
d: c9 leave
e: c3 ret
f: 55 pushl %ebp
10: 8b ec movl %esp,%ebp
12: eb ee jmp 0xee <2>
(robertl) pento:/home/robertl/tmp/c/x/gas
$ dis x.gas.o | tail
main
0: eb 0d jmp 0xd <f>
2: 68 00 00 00 00 pushl $0x0
7: e8 04 00 00 00 call 0x4 <10>
c: 59 popl %ecx
d: c9 leave
e: c3 ret
f: 55 pushl %ebp
10: 89 e5 movl %esp,%ebp
12: eb ee jmp 0xee <2>
Clearly, the call to printf is very different, and it's distrubing
that one of them is -4 and the other one is 4.
Can anyone work with me on getting this stuff hammered into a usable
form?
Thanx,
RJL
--- gas/Makefile.in_ Mon Aug 19 17:26:40 1996
+++ gas/Makefile.in Wed Jan 8 10:11:15 1997
@@ -390,11 +390,18 @@
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/obj-elf.c
obj-ecoff.o : $(srcdir)/config/obj-ecoff.c
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/obj-ecoff.c
+obj-coff.o : $(srcdir)/config/obj-coff.c
+ $(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/obj-coff.c
+
e-mipself.o : $(srcdir)/config/e-mipself.c
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/e-mipself.c
e-mipsecoff.o : $(srcdir)/config/e-mipsecoff.c
$(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/e-mipsecoff.c
+e-i386coff.o : $(srcdir)/config/e-i386coff.c
+ $(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/e-i386coff.c
+e-i386elf.o : $(srcdir)/config/e-i386elf.c
+ $(CC) -c $(ALL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(srcdir)/config/e-i386elf.c
# The m68k operand parser.
--- gas/as.c_ Mon Aug 19 12:28:38 1996
+++ gas/as.c Wed Jan 8 00:01:12 1997
@@ -146,6 +146,7 @@
extern struct emulation mipsbelf, mipslelf, mipself;
extern struct emulation mipsbecoff, mipslecoff, mipsecoff;
+extern struct emulation i386coff, i386elf;
static struct emulation *const emulations[] = { EMULATIONS };
static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
--- gas/configure_ Wed Sep 11 19:20:03 1996
+++ gas/configure Wed Jan 8 10:02:57 1997
@@ -1029,6 +1029,7 @@
big) emulation="mipsbelf mipslelf mipself" ;;
*) emulation="mipslelf mipsbelf mipself" ;;
esac ;;
+ i386-*-*-elf) emulation="i386coff i386elf" ;;
esac
emulations="$emulations $emulation"
@@ -1140,6 +1141,10 @@
fmt=elf file=mipself ;;
mipsbecoff | mipslecoff)
fmt=ecoff file=mipsecoff ;;
+ i386coff)
+ fmt=coff file=i386coff ;;
+ i386elf)
+ fmt=elf file=i386elf ;;
esac
formats="$formats $fmt"
emfiles="$emfiles e-$file.o"
--- gas/obj.h_ Tue Jan 7 23:41:06 1997
+++ gas/obj.h Tue Jan 7 23:44:09 1997
@@ -68,6 +68,7 @@
extern const struct format_ops elf_format_ops;
extern const struct format_ops ecoff_format_ops;
+extern const struct format_ops coff_format_ops;
#ifndef this_format
COMMON const struct format_ops *this_format;
--- /dev/null Wed Jan 8 10:35:01 1997
+++ gas/config/e-i386elf.c Wed Jan 8 10:19:46 1997
@@ -0,0 +1,18 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *
+i386elf_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386elf_bfd_name
+#define emul_format &elf_format_ops
+
+#define emul_name "i386elf"
+#define emul_struct_name i386elf
+#define emul_default_endian 0
+#include "emul-target.h"
+
--- /dev/null Wed Jan 8 10:35:01 1997
+++ gas/config/e-i386coff.c Wed Jan 8 10:19:31 1997
@@ -0,0 +1,18 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *
+i386coff_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386coff_bfd_name
+#define emul_format &coff_format_ops
+
+#define emul_name "i386coff"
+#define emul_struct_name i386coff
+#define emul_default_endian 0
+#include "emul-target.h"
+
--- gas/config/obj-coff.c_ Tue Jan 7 22:50:56 1997
+++ gas/config/obj-coff.c Wed Jan 8 02:37:26 1997
@@ -18,7 +18,7 @@
along with GAS; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-
+#define OBJ_HEADER "obj-coff.h"
#include "as.h"
#include "obstack.h"
#include "subsegs.h"
@@ -328,7 +328,7 @@
void
-obj_symbol_new_hook (symbolP)
+coff_obj_symbol_new_hook (symbolP)
symbolS *symbolP;
{
char underscore = 0; /* Symbol has leading _ */
@@ -869,7 +869,7 @@
}
void
-obj_read_begin_hook ()
+coff_obj_read_begin_hook ()
{
/* These had better be the same. Usually 18 bytes. */
#ifndef BFD_HEADERS
@@ -4215,6 +4215,7 @@
#else
{"optim", s_ignore, 0}, /* For sun386i cc (?) */
{"ident", s_ignore, 0}, /* we don't yet handle this. */
+ {"version", s_ignore, 0}, /* we don't yet handle this. */
#endif
{"ABORT", s_abort, 0},
#ifdef TC_M88K
@@ -4223,3 +4224,51 @@
#endif
{NULL} /* end sentinel */
}; /* obj_pseudo_table */
+
+void coff_pop_insert(void)
+{
+ pop_insert(obj_pseudo_table) ;
+}
+
+static int
+coff_sec_sym_ok_for_reloc (sec)
+ asection *sec;
+{
+ return (0);
+}
+
+void no_func(void)
+{
+ abort();
+}
+static int
+null_func(void)
+{
+ return(0);
+}
+
+const struct format_ops coff_format_ops =
+{
+ bfd_target_coff_flavour,
+ 0,
+ 1,
+ coff_frob_symbol,
+ coff_frob_file,
+ no_func,
+ 0, 0,
+ 0, 0,
+ 0,
+#if 0
+ obj_generate_asm_lineno,
+#else
+ no_func,
+#endif
+#if 0
+ obj_stab,
+#else
+ no_func,
+#endif
+ coff_sec_sym_ok_for_reloc,
+ coff_pop_insert,
+#if 0
+ obj_set_ext,
+#else
+ no_func,
+#endif
+ coff_obj_read_begin_hook,
+ coff_obj_symbol_new_hook,
+};
--- gas/config/tc-i386.c_ Wed Jan 8 00:57:03 1997
+++ gas/config/tc-i386.c Wed Jan 8 01:15:08 1997
@@ -3001,6 +3001,19 @@
return rel;
}
+const char *
+i386_target_format()
+{
+ switch (OUTPUT_FLAVOR) {
+ case bfd_target_coff_flavour:
+ return "coff-i386" ;
+ case bfd_target_elf_flavour:
+ return "elf32-i386" ;
+ default:
+ abort() ;
+ }
+}
+
#else /* ! BFD_ASSEMBLER */
#if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
--- gas/config/tc-i386.h_ Wed Jan 8 01:05:12 1997
+++ gas/config/tc-i386.h Wed Jan 8 01:19:18 1997
@@ -82,6 +82,7 @@
#ifdef OBJ_ELF
#define TARGET_FORMAT "elf32-i386"
#endif
+#define TARGET_FORMAT i386_target_format()
#else /* ! BFD_ASSEMBLER */
More information about the Gas2
mailing list