From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robert Lipe To: gas2@cygnus.com Subject: emulation on i386-coff, i386-elf patches Date: Wed, 08 Jan 1997 10:43:00 -0000 Message-id: X-SW-Source: 1997/msg00001.html 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 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 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 */