Here comes the next patch, this time built with cvs diff.
Features:
* rep with ins and outs (but has to be revised in user.c, I don't know whether somebody
has changed the value-parameter from plugin_emulate, remembered so but didn't find
it... *confused*)
* Some bugfixes in invd, wbinvd, outsb/outsw/outsd, insb/insw/insd
* Addes twice-included-protection (or what name for #ifndef... #endif?) in decode.h
* Made ELF load multiboot compliant; but without multiboot modules - do we need these?
* Shortened main(): sourced out command line and config file parsing, kernel image
loading
>You are misunderstanding
You opened my eyes, I see...
>Those modules are called "plugins"... or am I missing something ?
>I don't see the difference.
You're right.
>Yes, that's completely possible with plugins. Why would you need
>to reorg the code for this ?
Oh no, I don't want to jumble the whole code, just put somewhat in functions and don't
access
guest memory directly but use copy_in/out functions and so on. And write all new
"plugin friendly" ;)
Perhaps define some interfaces the plugins can rely on.
jens
-----------------------------------------------
? patch8.cvsdiff
? guest/virtcode/keyboard.c
? guest/virtcode/minishell.c
? guest/virtcode/helper.c
? user/multiboot.h
? user/oskit_types.h
Index: kernel/emulation.c
===================================================================
RCS file: /cvsroot-freemware/freemware/kernel/emulation.c,v
retrieving revision 1.9
diff -u -r1.9 emulation.c
--- kernel/emulation.c 2000/01/18 21:11:07 1.9
+++ kernel/emulation.c 2000/01/20 13:39:05
@@ -29,8 +29,8 @@
int emulate_hlt(guest_context_t *context);
int emulate_cli(guest_context_t *context);
int emulate_sti(guest_context_t *context);
-int emulate_ins(guest_context_t *context, int op_size);
-int emulate_outs(guest_context_t *context, int op_size);
+int emulate_ins(guest_context_t *context, int op_size, int address_size, int rep);
+int emulate_outs(guest_context_t *context, int op_size, int address_size, int rep);
int emulate_clts(void);
int emulate_rdmsr(void);
int emulate_wrmsr(void);
@@ -397,6 +397,7 @@
int use32 = 1; /* FIXME: is CS 16-bit or 32-bit */
int address_size;
int operand_size;
+ int rep;
int seg_override = 0;
u8 c;
u32 addr, val;
@@ -405,6 +406,7 @@
address_size = use32? 32 : 16;
operand_size = use32? 32 : 16;
+ rep = 0;
/*
* Decode Intel instruction
@@ -438,6 +440,9 @@
case 0x67: /* Address size prefix */
address_size = use32? 16 : 32;
goto prefix;
+ case 0xf3: /* rep prefix */
+ rep = 1;
+ goto prefix;
case 0x07: /* pop ES */
val = guest_stack_pop(&esp, operand_size);
@@ -453,19 +458,19 @@
break;
case 0x6c: /* insb == ins dx, m8 */
- action = emulate_ins(context,8);
+ action = emulate_ins(context,8,address_size,rep);
break;
case 0x6d: /* insw || insd */
- action = emulate_ins(context, operand_size);
+ action = emulate_ins(context, operand_size,address_size,rep);
break;
case 0x6e: /* outsb == outs dx, m8 */
- action = emulate_outs(context,8);
+ action = emulate_outs(context,8,address_size,rep);
break;
case 0x6f: /* outsw || outsd */
- action = emulate_outs(context, operand_size);
+ action = emulate_outs(context, operand_size,address_size,rep);
break;
case 0x8e: /* mov Sw, Ew */
@@ -529,6 +534,7 @@
case 0xf4: /* hlt */
action = emulate_hlt(context);
+ context->eip=eip;
break;
case 0xfa: /* cli */
@@ -584,10 +590,12 @@
case 0x08: /* invd */
action = emulate_invd();
+ context->eip=eip;
break;
case 0x09: /* wbinvd */
action = emulate_wbinvd();
+ context->eip=eip;
break;
case 0xa1: /* pop FS */
@@ -622,7 +630,6 @@
context->eip = eip;
context->esp = esp;
return 2;
-
case 4: /* Try to emulate in user space */
context->eip = eip;
context->esp = esp;
@@ -637,8 +644,8 @@
* Emulate cli instruction
*/
{
- context->event_info = EMU_INSTR_CLI | (RET_BECAUSE_USEREMU << 8);
- return 4;
+ context->event_info=EMU_INSTR_CLI | (RET_BECAUSE_USEREMU << 8);
+ return 4;
}
int
@@ -647,8 +654,8 @@
* Emulate sti instruction
*/
{
- context->event_info = EMU_INSTR_STI | (RET_BECAUSE_USEREMU << 8);
- return 4;
+ context->event_info=EMU_INSTR_STI | (RET_BECAUSE_USEREMU << 8);
+ return 4;
}
int
@@ -1055,56 +1062,80 @@
}
int
-emulate_outs(guest_context_t *context, int operand_size)
+emulate_outs(guest_context_t *context, int operand_size, int address_size, int rep)
/*
* Emulate outs instruction
*/
{
- switch (operand_size)
+ if(rep)
{
- case 8: context->event_info = EMU_INSTR_OUTS_8; break;
- case 16: context->event_info = EMU_INSTR_OUTS_16; break;
- case 32: context->event_info = EMU_INSTR_OUTS_32; break;
+ switch(operand_size)
+ {
+ case 8: context->event_info=EMU_INSTR_REP_OUTS_8;break;
+ case 16: context->event_info=EMU_INSTR_REP_OUTS_16;break;
+ case 32: context->event_info=EMU_INSTR_REP_OUTS_32;break;
+ }
}
- context->event_info |= (RET_BECAUSE_USEREMU << 8);
- return 4;
+ else
+ {
+ switch(operand_size)
+ {
+ case 8: context->event_info=EMU_INSTR_OUTS_8;break;
+ case 16: context->event_info=EMU_INSTR_OUTS_16;break;
+ case 32: context->event_info=EMU_INSTR_OUTS_32;break;
+ }
+ }
+ context->event_info |= (RET_BECAUSE_USEREMU << 8) | (address_size << 16);
+ return 4;
}
int
-emulate_ins(guest_context_t *context, int operand_size)
+emulate_ins(guest_context_t *context, int operand_size, int address_size, int rep)
/*
* Emulate ins instruction
*/
{
- switch (operand_size)
+ if(rep)
{
- case 8: context->event_info = EMU_INSTR_INS_8; break;
- case 16: context->event_info = EMU_INSTR_INS_16; break;
- case 32: context->event_info = EMU_INSTR_INS_32; break;
+ switch(operand_size)
+ {
+ case 8: context->event_info=EMU_INSTR_REP_INS_8;break;
+ case 16: context->event_info=EMU_INSTR_REP_INS_16;break;
+ case 32: context->event_info=EMU_INSTR_REP_INS_32;break;
+ }
}
- context->event_info |= (RET_BECAUSE_USEREMU << 8);
- return 4;
+ else
+ {
+ switch(operand_size)
+ {
+ case 8: context->event_info=EMU_INSTR_INS_8;break;
+ case 16: context->event_info=EMU_INSTR_INS_16;break;
+ case 32: context->event_info=EMU_INSTR_INS_32;break;
+ }
+
+ }
+ context->event_info |= (RET_BECAUSE_USEREMU << 8) | (address_size << 16);
+ return 4;
}
int
-emulate_invd()
-{
- /* nothing to do ;) */
- return 2;
+emulate_invd() {
+
+ /* nothing to do ;) */
+ return 1;
}
int
-emulate_wbinvd()
-{
- /* nothing to do ;) */
- return 2;
+emulate_wbinvd() {
+
+ /* nothing to do ;) */
+ return 1;
}
int
-emulate_hlt(guest_context_t *context)
-{
- context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
- return 4;
-}
+emulate_hlt(guest_context_t *context) {
+ context->event_info=EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
+ return 4;
+}
Index: kernel/include/freemware.h
===================================================================
RCS file: /cvsroot-freemware/freemware/kernel/include/freemware.h,v
retrieving revision 1.5
diff -u -r1.5 freemware.h
--- kernel/include/freemware.h 2000/01/18 21:11:07 1.5
+++ kernel/include/freemware.h 2000/01/20 13:39:05
@@ -110,9 +110,16 @@
#define EMU_INSTR_INS_16 11
#define EMU_INSTR_INS_32 12
-#define EMU_INSTR_HLT 13
+#define EMU_INSTR_REP_OUTS_8 13
+#define EMU_INSTR_REP_OUTS_16 14
+#define EMU_INSTR_REP_OUTS_32 15
+#define EMU_INSTR_REP_INS_8 16
+#define EMU_INSTR_REP_INS_16 17
+#define EMU_INSTR_REP_INS_32 18
-#define EMU_INSTR_CLI 14
-#define EMU_INSTR_STI 15
+#define EMU_INSTR_HLT 19
+
+#define EMU_INSTR_CLI 20
+#define EMU_INSTR_STI 21
#endif // #ifndef __FREEMWARE_H__
Index: kernel/include/monitor.h
===================================================================
RCS file: /cvsroot-freemware/freemware/kernel/include/monitor.h,v
retrieving revision 1.16
diff -u -r1.16 monitor.h
--- kernel/include/monitor.h 2000/01/17 02:22:15 1.16
+++ kernel/include/monitor.h 2000/01/20 13:39:05
@@ -54,7 +54,6 @@
#define EMU_LOAD_SEGREG_MSG 8
-
// Method1: push event info (CPU pushes error code before)
typedef struct {
unsigned char pushl; /* Always 0x68 == pushl */
Index: user/decode.h
===================================================================
RCS file: /cvsroot-freemware/freemware/user/decode.h,v
retrieving revision 1.3
diff -u -r1.3 decode.h
--- user/decode.h 2000/01/09 22:03:03 1.3
+++ user/decode.h 2000/01/20 13:39:05
@@ -17,6 +17,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifndef __DECODE_H
+#define __DECODE_H
/* Assembly Syntax */
@@ -323,3 +325,6 @@
int i386_decode_text_intel( struct i386_context *ctx, struct i386_decode *dc, char
*string );
int i386_decode_text_att( struct i386_context *ctx, struct i386_decode *dc, char
*string );
int i386_decode_text( struct i386_context *ctx, struct i386_decode *dc, char *string,
enum i386_asm_syntax syntax );
+
+
+#endif
Index: user/plugin.c
===================================================================
RCS file: /cvsroot-freemware/freemware/user/plugin.c,v
retrieving revision 1.2
diff -u -r1.2 plugin.c
--- user/plugin.c 2000/01/18 00:13:45 1.2
+++ user/plugin.c 2000/01/20 13:39:05
@@ -103,7 +103,7 @@
void
-plugin_init_all (void)
+plugin_init_all (config_info_t *conf)
{
plugin_t *plugin;
@@ -134,7 +134,7 @@
if (plugin->init (plugin, plugin->argc, plugin->argv))
{
fprintf (stderr, "Plugin initialization failed for %s\n", plugin->name);
- plugin_abort();
+ plugin_abort(conf);
}
plugin->initialized = 1;
@@ -368,9 +368,9 @@
/************************************************************************/
void
-plugin_abort (void)
+plugin_abort (config_info_t *conf)
{
- vm_abort ();
+ vm_abort (conf);
return;
}
Index: user/plugin.h
===================================================================
RCS file: /cvsroot-freemware/freemware/user/plugin.h,v
retrieving revision 1.2
diff -u -r1.2 plugin.h
--- user/plugin.h 2000/01/18 00:13:45 1.2
+++ user/plugin.h 2000/01/20 13:39:05
@@ -26,6 +26,7 @@
#include <dlfcn.h>
+#include "user.h"
#define PLUGIN_INIT "plugin_init"
#define PLUGIN_FINI "plugin_fini"
@@ -71,14 +72,14 @@
void plugin_load (char *name, char *args);
plugin_t *plugin_unload (plugin_t *plugin);
-void plugin_init_all (void);
+void plugin_init_all (config_info_t *);
void plugin_fini_all (void);
callback_t *plugin_alloc (plugin_t *plugin, event_t event, handler_t handler, int
base, int range);
void plugin_free (callback_t *callback);
void plugin_emulate (event_t event, int data, int op_size, int count, void *loc);
-void plugin_abort (void);
+void plugin_abort (config_info_t *);
void plugin_break (void);
#ifdef __cplusplus
Index: user/user.c
===================================================================
RCS file: /cvsroot-freemware/freemware/user/user.c,v
retrieving revision 1.23
diff -u -r1.23 user.c
--- user/user.c 2000/01/18 21:11:07 1.23
+++ user/user.c 2000/01/20 13:39:05
@@ -37,15 +37,16 @@
#include "user.h"
#include "plugin.h"
#include "decode.h"
+#include "multiboot.h"
-
/************************************************************************/
/* Declarations */
/************************************************************************/
-static int debug_exception (void);
+static int debug_exception (config_info_t *conf);
static void abort_handler (int i);
+void init_configuration(int argc, char **argv, config_info_t *conf);
@@ -55,13 +56,12 @@
/* Global data */
+config_info_t configuration;
+
guest_context_t context; /* This is the guest context structure */
char *ptr = NULL; /* Pointer to the guest virtual phys mem */
-int max_memory = 0; /* Size of the virtual physical memory */
-
-
/* Global callbacks */
int (*debug_hook) (void); /* Hook for a debugger (ICE) plugin */
@@ -71,11 +71,6 @@
static int filehdl; /* File handle for /dev/freemware */
-static enum i386_asm_syntax syntax; /* Assembly syntax to use */
-
-static char dump_file_name[256]; /* Filename for vm-core dump */
-
-
/* Flags */
static int dump_vm = 0; /* Dump the VM state (vm-core) on exit */
@@ -96,370 +91,14 @@
int
main (int argc, char *argv[])
{
- int virtno;
unsigned i;
- struct stat statbuf;
struct sigaction sg_act;
-
- int config_fd;
- int text_address, data_address, stack_address, bss_address;
- int verbose, is_elf;
- char c, config_file_name[256], guest_file_name[256];
- char line[256], sxname[10];
- int line_index;
- void *elf_buf;
- Elf32_Ehdr eh;
- Elf32_Shdr sh, snst;
- unsigned int symstraddr;
-
-
-
- /* some inits */
-
- strcpy (config_file_name, "fmw.conf");
- guest_file_name[0] = '\0';
- dump_file_name[0] = '\0';
- text_address = -1;
- data_address = -1;
- stack_address = -1;
- bss_address = -1;
- verbose = 0;
- syntax = SX_NONE;
- debug_hook = NULL;
-
-
-
- /* parsing command line for arguments */
-
- for (i = 0; i < argc; i++)
- {
- if (argv[i][0] != '-')
- continue;
-
- switch (argv[i][1])
- {
- case 'h':
- printf ("FreeMWare user-level monitor version " VERSION "\n");
- printf ("Usage: user -dfghmsv\n");
- printf ("Options:\n");
- printf ("-d ... Dump guest state (vm-core) after running\n");
- printf ("-f ... Config File (fully qualified path)\n");
- printf ("-g ... Guest code (fully qualified path)\n");
- printf ("-h ... Print this helpful help\n");
- printf ("-m ... Megs of memory for VM\n");
- printf ("-s ... Select disassembly syntax (\"intel\" or \"att\")\n");
- printf ("-v ... Print debug messages (verbose)\n");
- exit (0);
- break;
-
- case 'm':
- max_memory = atoi (&argv[i][3]);
- break;
-
- case 'f':
- strncpy (config_file_name, &argv[i][3], 255);
- break;
-
- case 'g':
- strncpy (guest_file_name, &argv[i][3], 255);
- break;
-
- case 's':
- strncpy (sxname, &argv[i][3], 10);
- if (!strcmp (sxname, "intel"))
- syntax = SX_INTEL;
- else if (!strcmp (sxname, "att"))
- syntax = SX_ATT;
- break;
-
- case 'v':
- verbose = 1;
- break;
-
- case 'd':
- dump_vm = 1;
- break;
-
- default:
- fprintf (stderr, "Unknown option: %s\n", argv[i]);
- break;
- }
- }
-
-
-
- /* read config file */
-
- config_fd = open (config_file_name, O_RDONLY);
- if (config_fd == -1)
- {
- char error_msg[100];
-
- sprintf (error_msg, "error while opening %s", config_file_name);
- perror (error_msg);
- exit (1);
- }
+ config_info_t *conf = &configuration;
- line_index = 0; /* states: 0 = reading, 1 = ignoring */
+ init_configuration(argc, argv, conf);
- while (read (config_fd, &c, 1))
- {
- line[line_index++] = c;
- if (c == '\n')
- {
- line[line_index - 1] = '\0';
- line_index = 0;
- if ((line[0] == '#') || (line[0] == '\n'))
- continue; // is a comment or a blank line;
-
- while ((line[line_index] != ' ') && (line[line_index] != '='))
- line_index++;
- if (!strncmp (line, "memory", line_index))
- {
- if (max_memory != 0)
- {
- line_index = 0;
- continue;
- } // command line overwrites config file settings;
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- max_memory = atoi (&line[line_index]);
- }
- else if (!strncmp (line, "text_address", line_index))
- {
- if (text_address != -1)
- {
- line_index = 0;
- continue;
- } // command line overwrites config file settings;
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- text_address = atoi (&line[line_index]);
- }
- else if (!strncmp (line, "data_address", line_index))
- {
- if (data_address != -1)
- {
- line_index = 0;
- continue;
- } // command line overwrites config file settings;
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- data_address = atoi (&line[line_index]);
- }
- else if (!strncmp (line, "stack_address", line_index))
- {
- if (stack_address != -1)
- {
- line_index = 0;
- continue;
- } // command line overwrites config file settings;
+ load_guest(conf);
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- stack_address = atoi (&line[line_index]);
- }
- else if (!strncmp (line, "bss_address", line_index))
- {
- if (bss_address != -1)
- {
- line_index = 0;
- continue;
- } // command line overwrites config file settings;
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- bss_address = atoi (&line[line_index]);
- }
- else if (!strncmp (line, "guest", line_index))
- {
- if (guest_file_name[0] != '\0')
- {
- line_index = 0;
- continue;
- }
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- strcpy (guest_file_name, &line[line_index]);
- }
- else if (!strncmp (line, "db_syntax", line_index))
- {
- if (syntax != SX_NONE)
- {
- line_index = 0;
- continue;
- }
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
- strcpy (sxname, &line[line_index]);
-
- if (!strcmp (sxname, "intel"))
- syntax = SX_INTEL;
- else if (!strcmp (sxname, "at&t"))
- syntax = SX_ATT;
- }
- else if (!strncmp (line, "plugin", line_index))
- {
- int parm_index;
- char *plugin_name, *plugin_args;
-
- while ((line[line_index] == ' ') || (line[line_index] == '='))
- line_index++;
-
- parm_index = line_index;
- while ((line[parm_index] != ' ') && (line[parm_index] != '\0'))
- parm_index++;
- if (line[parm_index] != '\0')
- line[parm_index++] = '\0';
-
- plugin_name = strcpy (malloc (strlen (&line[line_index]) + 1),
&line[line_index]);
- plugin_args = strcpy (malloc (strlen (&line[parm_index]) + 1),
&line[parm_index]);
-
- plugin_load (plugin_name, plugin_args);
- }
- line_index = 0;
- }
- }
-
- close (config_fd);
-
-
-
- /* set default settings, if not specified */
-
- if (max_memory == 0)
- max_memory = FMW_MAX_PHY_MEGS;
- if (guest_file_name[0] == '\0')
- strcpy (guest_file_name, "../guest/virtcode/virtcode");
- if (dump_file_name[0] == '\0')
- strcpy (dump_file_name, "vm-core");
- if (syntax == SX_NONE)
- syntax = SX_ATT;
- if (text_address == -1)
- text_address = 0;
-
- if (verbose)
- {
- fprintf (stderr, "Memory:\t\t%d\n", max_memory);
- fprintf (stderr, "Text address:\t%d\n", text_address);
- fprintf (stderr, "Data address:\t%d\n", data_address);
- fprintf (stderr, "Stack address:\t%d\n", stack_address);
- fprintf (stderr, "BSS address:\t%d\n", bss_address);
- }
-
-
-
- /* load guest code */
-
- fprintf (stderr, "Loading guest code: %s ", guest_file_name);
-
- virtno = open (guest_file_name, O_RDONLY);
- if (virtno < 0)
- {
- perror ("open");
- exit (1);
- }
-
- if (fstat (virtno, &statbuf) != 0)
- {
- perror ("fstat");
- exit (1);
- }
-
- fprintf (stderr, "(0x%lx bytes) ", statbuf.st_size);
-
- if ((elf_buf = (void *) malloc (statbuf.st_size)) == NULL)
- {
- perror ("malloc");
- exit (1);
- }
-
- if (read (virtno, elf_buf, statbuf.st_size) != statbuf.st_size)
- {
- perror ("read");
- exit (1);
- }
-
- close (virtno);
-
-
-
- /* check whether binary is an ELF executable */
-
- if ((((char *) elf_buf)[0] != 0x7f) ||
- (((char *) elf_buf)[1] != 'E') ||
- (((char *) elf_buf)[2] != 'L') ||
- (((char *) elf_buf)[3] != 'F'))
- {
- fprintf (stderr, "(BIN)\n");
- is_elf = 0;
- }
- else
- {
- fprintf (stderr, "(ELF)\n");
- is_elf = 1;
-
- eh = ((Elf32_Ehdr *) elf_buf)[0];
-
- if (eh.e_type != ET_EXEC)
- {
- fprintf (stderr, "Please, try it with an executable!\n");
- exit (1);
- }
-
- if (eh.e_machine != EM_386)
- {
- fprintf (stderr, "FreeMWare isn't able to run non-x86 binaries\n");
- fprintf (stderr, "Please use an emulator for your binary!\n");
- exit (1);
- }
-
- snst = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[eh.e_shstrndx]);
- symstraddr = snst.sh_offset;
-
- for (i = 0; i < eh.e_shnum; i++)
- {
- sh = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[i]);
- if (sh.sh_name && !strcmp ((char *) elf_buf + symstraddr + sh.sh_name,
".text"))
- text_address = sh.sh_addr;
- }
- }
-
-
-
- /* open a new VM */
-
- vm_init ();
-
-
-
- /* load the guest code into the virtual physical memory */
-
- fprintf (stderr, "Loading guest code into virtualized physical memory\n");
- if (!is_elf)
- memcpy (ptr + text_address, elf_buf, statbuf.st_size);
- else
- {
- eh = ((Elf32_Ehdr *) elf_buf)[0];
-
- for (i = 0; i < eh.e_shnum; i++)
- {
- sh = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[i]);
- if ((sh.sh_flags & SHF_ALLOC) && (sh.sh_type != SHT_NOBITS))
- {
- /* load if it occupies spaces and has bits */
- memcpy (ptr + sh.sh_addr, elf_buf + sh.sh_offset, sh.sh_size);
- }
- }
- }
- free (elf_buf);
-
-
-
/* setup to catch SIGINT, SIGABRT and SIGQUIT signals so we can clean up */
memset (&sg_act, 0, sizeof (sg_act));
@@ -470,47 +109,39 @@
sigaction (SIGQUIT, &sg_act, NULL);
-
/* initialize the guest context */
- memset (&context, 0, sizeof (context));
- context.eip = text_address;
- context.esp = stack_address;
+ context.eip = conf->text_address;
+ context.esp = conf->stack_address;
-
/* initialize all plugins */
fprintf (stderr, "Initializing plugins\n");
- plugin_init_all ();
-
+ plugin_init_all (conf);
/* run the VM */
fprintf (stderr, "Running VM\n");
- main_event_loop ();
-
+ main_event_loop (conf);
/* the VM has been aborted; if requested, perform a memory dump */
if (dump_vm)
- memory_dump (dump_file_name);
+ memory_dump (conf);
-
/* deinitialize all plugins */
fprintf (stderr, "Shutting down plugins\n");
plugin_fini_all ();
-
/* shut down the virtual machine */
-
- vm_fini ();
+ vm_fini (conf);
/* we're done!! */
@@ -525,7 +156,7 @@
/************************************************************************/
void
-vm_init (void)
+vm_init (config_info_t *conf)
{
int request, data, ret;
@@ -543,9 +174,9 @@
/* allocate memory from the host OS for the virtual physical memory */
- fprintf (stderr, "Allocating %dMB of physical memory in VM\n", max_memory);
+ fprintf (stderr, "Allocating %dMB of physical memory in VM\n", conf->max_memory);
request = FMWALLOCVPHYS;
- data = max_memory;
+ data = conf->max_memory;
ret = ioctl (filehdl, request, data);
if (ret < 0)
{
@@ -558,7 +189,7 @@
/* map guest virtual physical memory into user address space and zero it */
fprintf (stderr, "Mapping virtualized physical memory into monitor\n");
- ptr = mmap (NULL, max_memory * 1024 * 1024, PROT_READ | PROT_WRITE,
+ ptr = mmap (NULL, conf->max_memory * 1024 * 1024, PROT_READ | PROT_WRITE,
MAP_SHARED, filehdl, 0);
if (ptr == (void *) -1)
{
@@ -568,7 +199,7 @@
}
fprintf (stderr, "Zeroing virtualized physical memory\n");
- memset (ptr, 0, max_memory * 1024 * 1024);
+ memset (ptr, 0, conf->max_memory * 1024 * 1024);
return;
@@ -576,7 +207,7 @@
void
-vm_fini (void)
+vm_fini (config_info_t *conf)
{
int request, data, ret;
@@ -584,7 +215,7 @@
/* unmap the guest's virtual physical memory */
fprintf (stderr, "Unmapping guest physical memory\n");
- if (munmap (ptr, max_memory * 1024 * 1024) != 0)
+ if (munmap (ptr, conf->max_memory * 1024 * 1024) != 0)
{
perror ("munmap");
exit (1);
@@ -619,7 +250,7 @@
void
-vm_abort (void)
+vm_abort (config_info_t *conf)
{
if (in_run_loop)
{
@@ -630,12 +261,12 @@
else
{
if (dump_vm)
- memory_dump (dump_file_name);
+ memory_dump (conf);
fprintf (stderr, "Shutting down plugins\n");
plugin_fini_all ();
- vm_fini ();
+ vm_fini (conf);
exit (0);
}
@@ -656,8 +287,9 @@
/************************************************************************/
void
-main_event_loop (void)
+main_event_loop (config_info_t *conf)
{
+ int i;
int request, data, ret;
request = FMWRUNGUEST;
@@ -729,45 +361,159 @@
break;
case EMU_INSTR_INS_8:
- plugin_emulate (EVT_INPORT, context.edx & 0xffff, 1, 1, &value);
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- *(u8 *)(ptr + context.edi) = (u8)value;
- break;
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,1,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u8 *)(ptr+context.edi)=(u8)value;
+ else
+ *(u8 *)(ptr+(context.edi & 0xffff))=(u8)value;
+ if(context.eflags & 0x400) context.edi+=1;
+ else context.edi-=1;
+ break;
case EMU_INSTR_INS_16:
- plugin_emulate (EVT_INPORT, context.edx & 0xffff, 2, 1, &value);
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- *(u16 *)(ptr + context.edi) = (u16)value;
- break;
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,2,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u16 *)(ptr+context.edi)=(u16)value;
+ else
+ *(u16 *)(ptr+(context.edi & 0xffff))=(u16)value;
+ if(context.eflags & 0x400) context.edi+=2;
+ else context.edi-=2;
+ break;
case EMU_INSTR_INS_32:
- plugin_emulate (EVT_INPORT, context.edx & 0xffff, 4, 1, &value);
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- *(u32 *)(ptr + context.edi) = value;
- break;
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,4,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u32 *)(ptr+context.edi)=value;
+ else
+ *(u32 *)(ptr+(context.edi & 0xffff))=value;
+ if(context.eflags & 0x400) context.edi+=4;
+ else context.edi-=4;
+ break;
case EMU_INSTR_OUTS_8:
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- value = *(u8 *)(ptr + context.edi);
- plugin_emulate (EVT_OUTPORT, context.edx & 0xffff, 1, 1, &value);
- break;
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u8 *)(ptr+context.edi);
+ else
+ value=*(u8 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,1,1,&value);
+ if(context.eflags & 0x400) context.edi+=1;
+ else context.edi-=1;
+ break;
case EMU_INSTR_OUTS_16:
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- value = *(u16 *)(ptr + context.edi);
- plugin_emulate (EVT_OUTPORT, context.edx & 0xffff, 2, 1, &value);
- break;
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u16 *)(ptr+context.edi);
+ else
+ value=*(u16 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,2,1,&value);
+ if(context.eflags & 0x400) context.edi+=2;
+ else context.edi-=2;
+ break;
case EMU_INSTR_OUTS_32:
- /* FIXME: works only with flat memory models without paging and ES ==
DS */
- value = *(u32 *)(ptr + context.edi);
- plugin_emulate (EVT_OUTPORT, context.edx & 0xffff, 4, 1, &value);
- break;
+ /* FIXME: works only with flat memory models without paging and ES == DS
+*/
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u32 *)(ptr+context.edi);
+ else
+ value=*(u32 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,4,1,&value);
+ if(context.eflags & 0x400) context.edi+=4;
+ else context.edi-=4;
+ break;
+
+ case EMU_INSTR_REP_INS_8:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,1,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u8 *)(ptr+context.edi)=(u8)value;
+ else
+ *(u8 *)(ptr+(context.edi & 0xffff))=(u8)value;
+ if(context.eflags & 0x400) context.edi+=1;
+ else context.edi-=1;
+ }
+ break;
+
+ case EMU_INSTR_REP_INS_16:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,2,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u16 *)(ptr+context.edi)=(u16)value;
+ else
+ *(u16 *)(ptr+(context.edi & 0xffff))=(u16)value;
+ if(context.eflags & 0x400) context.edi+=2;
+ else context.edi-=2;
+ }
+ break;
+
+ case EMU_INSTR_REP_INS_32:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ plugin_emulate(EVT_INPORT,context.edx & 0xffff,4,1,&value);
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ *(u32 *)(ptr+context.edi)=value;
+ else
+ *(u32 *)(ptr+(context.edi & 0xffff))=value;
+ if(context.eflags & 0x400) context.edi+=4;
+ else context.edi-=4;
+ }
+ break;
+
+ case EMU_INSTR_REP_OUTS_8:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u8 *)(ptr+context.edi);
+ else
+ value=*(u8 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,1,1,&value);
+ if(context.eflags & 0x400) context.edi+=1;
+ else context.edi-=1;
+ }
+ break;
+
+ case EMU_INSTR_REP_OUTS_16:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u16 *)(ptr+context.edi);
+ else
+ value=*(u16 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,2,1,&value);
+ if(context.eflags & 0x400) context.edi+=2;
+ else context.edi-=2;
+ }
+ break;
+ case EMU_INSTR_REP_OUTS_32:
+ for(i = (context.ecx & 0xffff);i--;)
+ {
+ /* FIXME: works only with flat memory models without paging and ES
+== DS */
+ if(((context.event_info >> 16) & 0xff) == 32)
+ value=*(u32 *)(ptr+context.edi);
+ else
+ value=*(u32 *)(ptr+(context.edi & 0xffff));
+ plugin_emulate(EVT_OUTPORT,context.edx & 0xffff,4,1,&value);
+ if(context.eflags & 0x400) context.edi+=4;
+ else context.edi-=4;
+ }
+ break;
+
case EMU_INSTR_HLT:
- fprintf (stderr, "HLT -- shutting down virtual machine\n");
- abort_vm = 1;
- break;
+ fprintf(stderr,"HLT -- shutting down virtual machine\n");
+ abort_vm=1;
+ break;
case EMU_INSTR_CLI:
case EMU_INSTR_STI:
@@ -777,7 +523,7 @@
}
}
}
- while (!abort_vm && (ret >= 0 || !debug_exception ()));
+ while (!abort_vm && (ret >= 0 || !debug_exception (conf)));
}
@@ -787,7 +533,7 @@
/************************************************************************/
static int
-debug_exception ()
+debug_exception (config_info_t *conf)
{
struct i386_context ctx;
struct i386_decode instr;
@@ -813,7 +559,7 @@
ctx.segment = context.cs;
ctx.offset = context.eip;
- if (!i386_decode (&ctx, &instr) || !i386_decode_text (&ctx, &instr, text, syntax))
+ if (!i386_decode (&ctx, &instr) || !i386_decode_text (&ctx, &instr, text,
+conf->syntax))
strcpy (text, "???");
else
len = instr.length;
@@ -865,18 +611,18 @@
/************************************************************************/
void
-memory_dump (char *dump_file_name)
+memory_dump (config_info_t *conf)
{
int dumpno, counter, tmp, i, j;
char outbuf[330];
counter = 0;
- fprintf (stderr, "Dumping memory to %s\n", dump_file_name);
+ fprintf (stderr, "Dumping memory to %s\n", conf->dump_file_name);
- dumpno = open (dump_file_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ dumpno = open (conf->dump_file_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
- for (i = 0; i < max_memory * 1024 * 1024; i++)
+ for (i = 0; i < conf->max_memory * 1024 * 1024; i++)
{
static char hex[] = "0123456789abcdef";
@@ -933,7 +679,450 @@
break;
}
- vm_abort ();
+ vm_abort (&configuration);
return;
+}
+
+
+void
+init_configuration(int argc, char **argv, config_info_t *conf)
+{
+ char line[256], sxname[10], config_file_name[256];
+ int config_fd, line_index, i;
+ plugin_t *plugin;
+ char c;
+
+ /* some inits */
+
+ strcpy (config_file_name, "fmw.conf");
+ conf->guest_file_name[0] = '\0';
+ conf->dump_file_name[0] = '\0';
+ conf->max_memory = 0;
+ conf->text_address = -1;
+ conf->data_address = -1;
+ conf->stack_address = -1;
+ conf->bss_address = -1;
+ conf->debug_on = 0;
+ conf->dump = 0;
+ conf->syntax = SX_NONE;
+ debug_hook = NULL;
+
+
+ /* parsing command line for arguments */
+
+ for (i = 0; i < argc; i++)
+ {
+ if (argv[i][0] != '-')
+ continue;
+ switch (argv[i][1])
+ {
+ case 'h':
+ printf ("FreeMWare Version, hm... don't know. Following options are for
+you:\n");
+ printf ("-h ... Print this helpful help\n");
+ printf ("-m ... Megs of memory for VM\n");
+ printf ("-f ... Config File (fully qualified path)\n");
+ printf ("-g ... Guest code (fully qualified path)\n");
+ printf ("-d ... Print debug messages\n");
+ printf ("-D ... Dump guest after running (human readable hex code)\n");
+ printf ("-s ... Select disassembly syntax (\"intel\" or \"att\")\n");
+ exit (0);
+ break;
+ case 'm':
+ conf->max_memory = atoi (&argv[i][3]);
+ break;
+ case 'f':
+ strncpy (config_file_name, &argv[i][3], 255);
+ break;
+ case 'g':
+ strncpy (conf->guest_file_name, &argv[i][3], 255);
+ break;
+ case 's':
+ strncpy(sxname,&argv[i][3],10);
+ if(!strcmp(sxname,"intel")) conf->syntax=SX_INTEL; else
+ if(!strcmp(sxname,"att")) conf->syntax=SX_ATT;
+ break;
+ case 'd':
+ conf->debug_on = 1;
+ break;
+ case 'D':
+ conf->dump = 1;
+ break;
+ default:
+ fprintf (stderr, "Unknown option: %s\n", argv[i]);
+ break;
+ }
+ }
+
+
+
+ /* read config file */
+
+ config_fd = open (config_file_name, O_RDONLY);
+ if (config_fd == -1)
+ {
+ char error_msg[100],c;
+
+ sprintf (error_msg, "error while opening %s", config_file_name);
+ perror (error_msg);
+ exit (1);
+ }
+
+ line_index = 0; /* states: 0 = reading, 1 = ignoring */
+
+ while (read (config_fd, &c, 1))
+ {
+ line[line_index++] = c;
+ if (c == '\n')
+ {
+ line[line_index - 1] = '\0';
+ line_index = 0;
+ if ((line[0] == '#') || (line[0] == '\n'))
+ continue; // is a comment or a blank line;
+
+ while ((line[line_index] != ' ') && (line[line_index] != '='))
+ line_index++;
+ if (!strncmp (line, "memory", line_index))
+ {
+ if (conf->max_memory != 0)
+ {
+ line_index = 0;
+ continue;
+ } // command line overwrites config file settings;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ conf->max_memory = atoi (&line[line_index]);
+ }
+ else if (!strncmp (line, "text_address", line_index))
+ {
+ if (conf->text_address != -1)
+ {
+ line_index = 0;
+ continue;
+ } // command line overwrites config file settings;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ conf->text_address = atoi (&line[line_index]);
+ }
+ else if (!strncmp (line, "data_address", line_index))
+ {
+ if (conf->data_address != -1)
+ {
+ line_index = 0;
+ continue;
+ } // command line overwrites config file settings;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ conf->data_address = atoi (&line[line_index]);
+ }
+ else if (!strncmp (line, "stack_address", line_index))
+ {
+ if (conf->stack_address != -1)
+ {
+ line_index = 0;
+ continue;
+ } // command line overwrites config file settings;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ conf->stack_address = atoi (&line[line_index]);
+ }
+ else if (!strncmp (line, "bss_address", line_index))
+ {
+ if (conf->bss_address != -1)
+ {
+ line_index = 0;
+ continue;
+ } // command line overwrites config file settings;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ conf->bss_address = atoi (&line[line_index]);
+ }
+ else if (!strncmp (line, "guest", line_index))
+ {
+ if (conf->guest_file_name[0] != '\0')
+ {
+ line_index = 0;
+ continue;
+ }
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ strcpy (conf->guest_file_name, &line[line_index]);
+ }
+ else if(!strncmp(line,"db_syntax",line_index))
+ {
+ if (conf->syntax != SX_NONE)
+ {
+ line_index = 0;
+ continue;
+ }
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+ strcpy(sxname,&line[line_index]);
+
+ if(!strcmp(sxname,"intel")) conf->syntax=SX_INTEL; else
+ if(!strcmp(sxname,"at&t")) conf->syntax=SX_ATT;
+ }
+ else if (!strncmp (line, "plugin", line_index))
+ {
+ int parm_index;
+ char *plugin_name, *plugin_args;
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+
+ parm_index = line_index;
+ while ((line[parm_index] != ' ') && (line[parm_index] != '\0'))
+ parm_index++;
+ if (line[parm_index] != '\0')
+ line[parm_index++] = '\0';
+
+ plugin_name = strcpy (malloc (strlen (&line[line_index]) + 1),
+&line[line_index]);
+ plugin_args = strcpy (malloc (strlen (&line[parm_index]) + 1),
+&line[parm_index]);
+
+ plugin_load (plugin_name, plugin_args);
+
+ /*
+ int parm_index;
+ char *plug_err;
+
+ plugin = malloc(sizeof(plugin_t));
+ if(!plugin)
+ {
+ perror ("malloc");
+ exit (1);
+ }
+
+ while ((line[line_index] == ' ') || (line[line_index] == '='))
+ line_index++;
+
+ parm_index = line_index;
+ while ((line[parm_index] != ' ') && (line[parm_index] != '\0'))
+ parm_index++;
+ if(line[parm_index] != '\0')
+ line[parm_index++] = '\0';
+
+ plugin->name = strcpy (malloc(strlen(&line[line_index])+1),
+&line[line_index]);
+
+ plugin->handle = dlopen (&line[line_index], RTLD_LAZY);
+ if(!plugin->handle)
+ {
+ fputs (dlerror(), stderr);
+ exit (1);
+ }
+
+ plugin->init = dlsym (plugin->handle, PLUGIN_INIT);
+ if ((plug_err = dlerror()) != NULL)
+ {
+ fputs (plug_err, stderr);
+ exit (1);
+ }
+
+ plugin->fini = dlsym (plugin->handle, PLUGIN_FINI);
+ if ((plug_err = dlerror()) != NULL)
+ {
+ fputs (plug_err, stderr);
+ exit (1);
+ }
+
+ plugin->args = strcpy (malloc(strlen(&line[parm_index])+1),
+&line[parm_index]);
+
+ plugin->next = conf->plugins;
+ conf->plugins = plugin;
+ */
+
+ }
+ line_index = 0;
+ }
+ }
+
+ close (config_fd);
+
+
+ /* set default settings, if not specified */
+
+ if (conf->max_memory == 0)
+ conf->max_memory = FMW_MAX_PHY_MEGS;
+ if (conf->guest_file_name[0] == '\0')
+ strcpy (conf->guest_file_name, "../guest/virtcode/virtcode");
+ if (conf->dump_file_name[0] == '\0')
+ strcpy (conf->dump_file_name, "dumpfile");
+ if (conf->syntax == SX_NONE)
+ conf->syntax = SX_ATT;
+
+ if (conf->debug_on)
+ {
+ fprintf (stderr, "Memory: %d\n", conf->max_memory);
+ fprintf (stderr, "Text address: %d\n", conf->text_address);
+ fprintf (stderr, "Data address: %d\n", conf->data_address);
+ fprintf (stderr, "Stack address: %d\n", conf->stack_address);
+ fprintf (stderr, "BSS address: %d\n", conf->bss_address);
+ }
+
+}
+
+void
+load_guest(config_info_t *conf)
+
+{
+ int i,virtno,is_elf;
+ unsigned multi_boot, multiboot_header_flags;
+ struct stat statbuf;
+ void *elf_buf;
+ Elf32_Ehdr eh;
+ Elf32_Shdr sh, snst;
+ unsigned int symstraddr;
+
+ /* load guest code */
+
+ fprintf (stderr, "Loading guest code: %s ", conf->guest_file_name);
+
+ virtno = open (conf->guest_file_name, O_RDONLY);
+ if (virtno < 0)
+ {
+ perror ("open");
+ exit (1);
+ }
+
+ if (fstat (virtno, &statbuf) != 0)
+ {
+ perror ("fstat");
+ exit (1);
+ }
+
+ fprintf (stderr, "(0x%lx bytes) ", statbuf.st_size);
+
+ if ((elf_buf = (void *) malloc (statbuf.st_size)) == NULL)
+ {
+ perror ("malloc");
+ exit (1);
+ }
+
+ if (read (virtno, elf_buf, statbuf.st_size) != statbuf.st_size)
+ {
+ perror ("read");
+ exit (1);
+ }
+
+ close (virtno);
+
+
+
+ /* check whether binary is an ELF executable */
+
+ if ((((char *) elf_buf)[0] != 0x7f) ||
+ (((char *) elf_buf)[1] != 'E') ||
+ (((char *) elf_buf)[2] != 'L') ||
+ (((char *) elf_buf)[3] != 'F'))
+ {
+ fprintf (stderr, "(BIN)\n");
+ is_elf = 0;
+ }
+ else
+ {
+ fprintf (stderr, "(ELF)\n");
+ is_elf = 1;
+
+ eh = ((Elf32_Ehdr *) elf_buf)[0];
+
+ if (eh.e_type != ET_EXEC)
+ {
+ fprintf (stderr, "Please, try it with an executable!\n");
+ exit (1);
+ }
+
+ if (eh.e_machine != EM_386)
+ {
+ fprintf (stderr, "FreeMWare isn't able to run non-x86 binaries\n");
+ fprintf (stderr, "Please use an emulator for your binary!\n");
+ exit (1);
+ }
+
+ snst = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[eh.e_shstrndx]);
+ symstraddr = snst.sh_offset;
+
+ for (i = 0; i < eh.e_shnum; i++)
+ {
+ sh = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[i]);
+ if (sh.sh_name && !strcmp ((char *) elf_buf + symstraddr + sh.sh_name,
+".text"))
+ conf->text_address = sh.sh_addr;
+ }
+ }
+
+
+
+ /* open a new VM */
+
+ vm_init (conf);
+
+
+
+ /* load the guest code into the virtual physical memory */
+
+ fprintf (stderr, "Loading guest code into virtualized physical memory\n");
+ if (!is_elf)
+ memcpy (ptr + conf->text_address, elf_buf, statbuf.st_size);
+ else
+ {
+ eh = ((Elf32_Ehdr *) elf_buf)[0];
+
+ for (i = 0; i < eh.e_shnum; i++)
+ {
+ sh = (((Elf32_Shdr *) (elf_buf + eh.e_shoff))[i]);
+ if ((sh.sh_flags & SHF_ALLOC) && (sh.sh_type != SHT_NOBITS))
+ {
+ /* load if it occupies spaces and has bits */
+ memcpy (ptr + sh.sh_addr, elf_buf + sh.sh_offset, sh.sh_size);
+ }
+ }
+ }
+ free (elf_buf);
+
+
+ /* is it multiboot compliant? */
+
+ multi_boot = 0;
+ memset (&context, 0, sizeof (context));
+ for(i = 0; i<MULTIBOOT_SEARCH;i++)
+ {
+ if( *(u32 *)(ptr + conf->text_address + i) == MULTIBOOT_MAGIC)
+ {
+ fprintf(stderr,"This is a multiboot compliant kernel.\n");
+ multi_boot = 1;
+ multiboot_header_flags = ((struct multiboot_header *)(ptr +
+conf->text_address + i))->flags;
+ break;
+ }
+ }
+ if(multi_boot)
+ {
+ struct multiboot_info mbi;
+
+ memset(&mbi,0,sizeof(mbi));
+ if(multiboot_header_flags & MULTIBOOT_PAGE_ALIGN)
+ {
+ fprintf(stderr,"Should align all boot modules to page boundaries.\n");
+ }
+ if(multiboot_header_flags & MULTIBOOT_MEMORY_INFO)
+ {
+ fprintf(stderr,"Must provide memory information in multiboot info
+structure.\n");
+ mbi.flags |= MULTIBOOT_MEMORY;
+ mbi.mem_lower = 0;
+ mbi.mem_upper = conf->max_memory;
+ }
+ if(multiboot_header_flags & MULTIBOOT_AOUT_KLUDGE)
+ {
+ fprintf(stderr,"PANIC: found a.out kludge in ELF binary!\n");
+ vm_fini(conf);
+ exit(1);
+ }
+ /* FIXME: find a nice, warm and dry place for multiboot info structure */
+ memcpy(ptr + conf->max_memory - sizeof(mbi),&mbi,sizeof(mbi));
+ context.eax = conf->max_memory - sizeof(mbi);
+ }
+
}
Index: user/user.h
===================================================================
RCS file: /cvsroot-freemware/freemware/user/user.h,v
retrieving revision 1.4
diff -u -r1.4 user.h
--- user/user.h 2000/01/18 00:13:45 1.4
+++ user/user.h 2000/01/20 13:39:05
@@ -25,21 +25,38 @@
#endif
#include "freemware.h"
+#include "decode.h"
-#define VERSION "0.0.1-unstable"
+#define VERSION "0.1.1-unstable"
+
+typedef struct {
+
+ int max_memory;
+ char guest_file_name[256];
+ char dump_file_name[256];
+ u32 text_address;
+ u32 data_address;
+ u32 stack_address;
+ u32 bss_address;
+ int debug_on;
+ int dump;
+ enum i386_asm_syntax syntax; /* Assembly syntax to use */
+
+} config_info_t;
+
extern guest_context_t context;
extern char *ptr;
-extern int max_memory;
extern int (*debug_hook)(void);
-void vm_init (void);
-void vm_fini (void);
-void vm_abort (void);
+void vm_init (config_info_t *);
+void vm_fini (config_info_t *);
+void vm_abort (config_info_t *);
void vm_break (void);
-void main_event_loop (void);
-void memory_dump (char *dump_file_name);
+void main_event_loop (config_info_t *);
+void memory_dump (config_info_t *conf);
+void load_guest(config_info_t *conf);
#ifdef __cplusplus
};
Index: user/plugins/bochs/io.cc
===================================================================
RCS file: /cvsroot-freemware/freemware/user/plugins/bochs/io.cc,v
retrieving revision 1.6
diff -u -r1.6 io.cc
--- user/plugins/bochs/io.cc 2000/01/18 00:13:45 1.6
+++ user/plugins/bochs/io.cc 2000/01/20 13:39:05
@@ -33,6 +33,7 @@
#include "bochs.h"
#include "elf.h"
#include "decode.h"
+#include "user.h"
bx_options_t bx_options;
bx_debug_t bx_dbg;
@@ -43,6 +44,8 @@
static void timer_handler(int i);
static void replay_vga_io_log(void);
+extern config_info_t configuration;
+
#define UPDATE_INTERVAL 10000
extern "C" {
@@ -152,7 +155,7 @@
vfprintf(stderr, fmt, ap);
va_end(ap);
- plugin_abort ();
+ plugin_abort (&configuration);
}
void
Index: user/plugins/bochs/state_file.cc
===================================================================
RCS file: /cvsroot-freemware/freemware/user/plugins/bochs/state_file.cc,v
retrieving revision 1.4
diff -u -r1.4 state_file.cc
--- user/plugins/bochs/state_file.cc 2000/01/18 00:13:45 1.4
+++ user/plugins/bochs/state_file.cc 2000/01/20 13:39:05
@@ -25,6 +25,7 @@
#include "bochs.h"
#include "user.h"
+extern config_info_t configuration;
FILE *state_file::get_handle()
@@ -36,73 +37,73 @@
void state_file::write(Bit8u)
{
fprintf(stderr, "bochs: # state_file::write(Bit8u)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::write(Bit16u)
{
fprintf(stderr, "bochs: # state_file::write(Bit16u)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::write(Bit32u)
{
fprintf(stderr, "bochs: # state_file::write(Bit32u)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::write(Bit64u)
{
fprintf(stderr, "bochs: # state_file::write(Bit64u)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::write(const void *, size_t)
{
fprintf(stderr, "bochs: # state_file::write(const void *, size_t)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read(Bit8u &)
{
fprintf(stderr, "bochs: # state_file::read(uint8 &)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read(Bit16u &)
{
fprintf(stderr, "bochs: # state_file::read(uint16 &)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read(Bit32u &)
{
fprintf(stderr, "bochs: # state_file::read(uint32 &)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read(Bit64u &)
{
fprintf(stderr, "bochs: # state_file::read(uint64 &)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read(void *, size_t)
{
fprintf(stderr, "bochs: # state_file::read(void *, size_t)\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::write_check(const char *)
{
fprintf(stderr, "bochs: # state_file::write_check()\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
void state_file::read_check (const char *)
{
fprintf(stderr, "bochs: # state_file::read_check()\n");
- plugin_abort ();
+ plugin_abort(&configuration);
}
state_file::state_file (const char *name, const char *options)