summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-09-24 10:35:10 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2021-09-24 10:35:10 +0200
commita595e1f3e9ec47bdc0c9a8a0d7c764516e29e00b (patch)
tree8657126e42dea7f41d2a0cd293627a0ae6bd693d
parente3cb0f8facec3723a8e0f6f245c7688cf3da8804 (diff)
downloadcompilertests-a595e1f3e9ec47bdc0c9a8a0d7c764516e29e00b.tar.gz
compilertests-a595e1f3e9ec47bdc0c9a8a0d7c764516e29e00b.tar.bz2
emul
- added command line options for verbose output, tracing, ...
-rw-r--r--ecomp-c/emul.c125
1 files changed, 92 insertions, 33 deletions
diff --git a/ecomp-c/emul.c b/ecomp-c/emul.c
index e4234f9..f97e787 100644
--- a/ecomp-c/emul.c
+++ b/ecomp-c/emul.c
@@ -9,6 +9,7 @@
#include <errno.h>
#include <stdbool.h>
#include <assert.h>
+#include <unistd.h>
#define PAGE_SIZE 4 * 1024 * 1024
#define CODE_START 0x1000000
@@ -119,6 +120,40 @@ int main( int argc, char *argv[] )
cs_insn *instrs;
uint64_t data_start = 0;
size_t data_size = 0;
+ int opt;
+ bool verbose = false;
+ bool dump = false;
+ bool trace = false;
+
+ while( ( opt = getopt( argc, argv, "vdth" ) ) != -1 ) {
+ switch( opt ) {
+ case 'v':
+ verbose = true;
+ break;
+ case 'd':
+ dump = true;
+ break;
+ case 't':
+ trace = true;
+ break;
+ case 'h':
+ printf( "Usage: %s [-v] [file.bin]\n\n", argv[0] );
+ printf( "Options:\n" );
+ printf( " -h show help\n" );
+ printf( " -v verbose output\n" );
+ printf( " -d dump code and data read\n" );
+ printf( " -t trace and print single stepts during emulation\n" );
+ exit( EXIT_SUCCESS );
+ default:
+ fprintf( stderr, "Usage: %s [-v] [file.bin]\n", argv[0] );
+ exit( EXIT_FAILURE );
+ }
+ }
+
+ if( optind >= argc ) {
+ fprintf( stderr, "Expected a binary file to interpret\n" );
+ exit( EXIT_FAILURE );
+ }
uerr = uc_open( UC_ARCH_X86, UC_MODE_32, &uc );
if( uerr != UC_ERR_OK ) {
@@ -146,8 +181,8 @@ int main( int argc, char *argv[] )
uc_close( uc );
exit( EXIT_FAILURE );
}
-
- f = fopen( argv[1], "r" );
+
+ f = fopen( argv[optind], "r" );
if( f == NULL ) {
fprintf( stderr, "ERROR: unable to read file '%s': %s\n", argv[1], strerror( errno ) );
uc_close( uc );
@@ -189,7 +224,9 @@ int main( int argc, char *argv[] )
uc_close( uc );
exit( EXIT_FAILURE );
}
- printf( "Read %zu bytes of code and static data..\n", code_size );
+ if( verbose ) {
+ printf( "Read %zu bytes of code and static data..\n", code_size );
+ }
fclose( f );
@@ -202,20 +239,26 @@ int main( int argc, char *argv[] )
exit( EXIT_FAILURE );
}
+ if( verbose ) {
+ printf( "Executing code..\n" );
+ }
+
// print all the disassembled code
for( int i = 0; i < nof_instrs; i++ ) {
- printf( "%04X: ", (uint32_t)instrs[i].address );
- for( int j = 0; j < instrs[i].size; j++ ) {
- printf( "%02X", instrs[i].bytes[j] );
- }
- for( int j = ( 16 - instrs[i].size ) * 2; j > 0; j-- ) {
- printf( " " );
- }
-
- if( data_start == 0 ) {
- printf( "%s %s\n", instrs[i].mnemonic, instrs[i].op_str );
- } else {
- printf( "data\n" );
+ if( dump ) {
+ printf( "%04X: ", (uint32_t)instrs[i].address );
+ for( int j = 0; j < instrs[i].size; j++ ) {
+ printf( "%02X", instrs[i].bytes[j] );
+ }
+ for( int j = ( 16 - instrs[i].size ) * 2; j > 0; j-- ) {
+ printf( " " );
+ }
+
+ if( data_start == 0 ) {
+ printf( "%s %s\n", instrs[i].mnemonic, instrs[i].op_str );
+ } else {
+ printf( "data\n" );
+ }
}
/* code and data segment are separated by a 'hlt' instruction,
@@ -295,22 +338,29 @@ int main( int argc, char *argv[] )
uc_reg_write( uc, UC_X86_REG_EBP, &esp );
data_size = file_size - ( data_start - CODE_START );
- dump_memory( uc, data_start, data_start + data_size );
- printf( "core start %x\n", (unsigned int)CODE_START );
- printf( "data start %x\n", (unsigned int)data_start );
- printf( "data size %x\n", (unsigned int)data_size );
- printf( "stack start %x\n", (unsigned int)esp );
+ if( dump ) {
+ dump_memory( uc, data_start, data_start + data_size );
+ printf( "core start %x\n", (unsigned int)CODE_START );
+ printf( "data start %x\n", (unsigned int)data_start );
+ printf( "data size %x\n", (unsigned int)data_size );
+ printf( "stack start %x\n", (unsigned int)esp );
+ }
uint64_t address = CODE_START;
bool terminate = false;
bool notfound = false;
int iteration = 1;
- printf( "Single step execution:\n" );
+ if( trace ) {
+ printf( "Single step execution:\n" );
+ }
+
while( !terminate ) {
- printf( "-- iteration %d\n", iteration );
+ if( trace ) {
+ printf( "-- iteration %d\n", iteration );
+ }
iteration++;
int n = mul_hash( address, p ) * 2;
@@ -330,17 +380,20 @@ int main( int argc, char *argv[] )
}
n = instrs_map[n];
- printf( "%04X: ", (unsigned int)address );
+ if( trace ) {
+ printf( "%04X: ", (unsigned int)address );
- for( int i = 0; i < instrs[n].size; i++ ) {
- printf( "%02X", instrs[n].bytes[i] );
- }
- for( int i = ( 16 - instrs[n].size ) * 2; i > 0; i-- ) {
- printf( " " );
+ for( int i = 0; i < instrs[n].size; i++ ) {
+ printf( "%02X", instrs[n].bytes[i] );
+ }
+
+ for( int i = ( 16 - instrs[n].size ) * 2; i > 0; i-- ) {
+ printf( " " );
+ }
+
+ printf( "%s %s\n", instrs[n].mnemonic, instrs[n].op_str );
}
- printf( "%s %s\n", instrs[n].mnemonic, instrs[n].op_str );
-
uerr = uc_emu_start( uc, addr, CODE_START + code_size, 0, 1 );
if( uerr != UC_ERR_OK ) {
fprintf( stderr, "ERROR: failed to call uc_emu_start( ): %s\n", uc_strerror( uerr ) );
@@ -354,15 +407,21 @@ int main( int argc, char *argv[] )
addr = eip;
address = eip;
- dump_regs( uc );
- dump_stack( uc );
- dump_memory( uc, data_start, data_start + data_size );
+ if( trace ) {
+ dump_regs( uc );
+ dump_stack( uc );
+ dump_memory( uc, data_start, data_start + data_size );
+ }
if( strcmp( instrs[n].mnemonic, "hlt" ) == 0 ) {
terminate = true;
}
}
+ if( verbose ) {
+ printf( "Done, executed %d instructions.\n", iteration );
+ }
+
free( instrs_map );
cs_free( instrs, nof_instrs );
cs_close( &cs );