summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-07-29 18:26:31 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2020-07-29 18:26:31 +0200
commitb65869a4dbaec4d237b17581b260eb0d48e4fcca (patch)
tree29a98ed623add5f7c49b1de5131bd8a9c6e06177
parent15ed53b1d14876a0db7885a0d34b3d20f94adaf5 (diff)
downloadcompilertests-b65869a4dbaec4d237b17581b260eb0d48e4fcca.tar.gz
compilertests-b65869a4dbaec4d237b17581b260eb0d48e4fcca.tar.bz2
ec: can generate binaries for the simple emulator as well as ELF binaries
the Linux 386 host
-rw-r--r--ecomp-c/ec.c91
1 files changed, 88 insertions, 3 deletions
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index dd95fe7..bc0944e 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -19,6 +19,13 @@ enum {
static int DEBUG_GETCHAR = 0;
static int DEBUG_SCANNER = 0;
+typedef enum {
+ BINARY_FORMAT_EMUL = 0,
+ BINARY_FORMAT_ELF = 1
+} BinaryFormat;
+
+static BinaryFormat binary_format = BINARY_FORMAT_EMUL;
+
/* scanner */
typedef enum {
@@ -2044,7 +2051,7 @@ static void init( void )
sym = getSym( );
}
-static void prologue( void )
+static void prologue_emul( void )
{
/* fasm or asm-i386 syntax */
Emit( "format binary\n" );
@@ -2052,6 +2059,58 @@ static void prologue( void )
Emit( "org $1000000\n" );
}
+static void prologue_elf( void )
+{
+ /* fasm, i386, ELF, Linux */
+ Emit( "format binary\n" );
+ Emit( "use32\n" );
+ Emit( "org $08048000\n" );
+ Emit( "ehdr:\n" );
+ Emit( "db $7F, \"ELF\"\n" );
+ Emit( "db 1\n" );
+ Emit( "db 1\n" );
+ Emit( "db 1\n" );
+ Emit( "db 0\n" );
+ Emit( "dd 0, 0\n" );
+ Emit( "dw 2\n" );
+ Emit( "dw 3\n" );
+ Emit( "dd 1\n" );
+ Emit( "dd _start\n" );
+ Emit( "dd phdr - $$\n" );
+ Emit( "dd 0\n" );
+ Emit( "dd 0\n" );
+ Emit( "dw ehdrsize\n" );
+ Emit( "dw phdrsize\n" );
+ Emit( "dw 1\n" );
+ Emit( "dw 0\n" );
+ Emit( "dw 0\n" );
+ Emit( "dw 0\n" );
+ Emit( "ehdrsize = $ - ehdr\n" );
+ Emit( "phdr:\n" );
+ Emit( "dd 1\n" );
+ Emit( "dd 0\n" );
+ Emit( "dd $$\n" );
+ Emit( "dd $$\n" );
+ Emit( "dd filesize\n" );
+ Emit( "dd filesize\n" );
+ Emit( "dd 7\n" );
+ Emit( "dd $1000\n" );
+ Emit( "phdrsize = $ - phdr\n" );
+ Emit( "_start:");
+}
+
+static void prologue( void )
+{
+ switch( binary_format ) {
+ case BINARY_FORMAT_EMUL:
+ prologue_emul( );
+ break;
+ case BINARY_FORMAT_ELF:
+ prologue_elf( );
+ break;
+ }
+}
+
static void reserve_initialize( Symbol *symbol )
{
int i;
@@ -2119,11 +2178,10 @@ static void reserve_initialize( Symbol *symbol )
}
}
-static void epilogue( void )
+static void Emit_symbols( void )
{
Symbol *symbol;
- Emit( "hlt\n" );
symbol = global_scope->symbol;
while( symbol != NULL ) {
if( symbol->class == SYMBOL_CLASS_VARIABLE ) {
@@ -2134,6 +2192,33 @@ static void epilogue( void )
}
}
+static void epilogue_emul( void )
+{
+ Emit( "hlt\n" );
+ Emit_symbols( );
+}
+
+static void epilogue_elf( void )
+{
+ Emit( "mov ebx, 0\n" );
+ Emit( "mov eax, 1\n" );
+ Emit( "int $80\n" );
+ Emit_symbols( );
+ Emit( "filesize = $ - $$\n" );
+}
+
+static void epilogue( void )
+{
+ switch( binary_format ) {
+ case BINARY_FORMAT_EMUL:
+ epilogue_emul( );
+ break;
+ case BINARY_FORMAT_ELF:
+ epilogue_elf( );
+ break;
+ }
+}
+
static void deinit( void )
{
free_scope( global_scope );