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)

Reply via email to