Update Checkbochs patches. eraser
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 3 Aug 2005 19:13:58 +0000 (19:13 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 3 Aug 2005 19:13:58 +0000 (19:13 +0000)
src/misc/bochs-2.1.1-checkbochs.patch
src/misc/bochs.README
src/misc/checkbochs.README [new file with mode: 0644]
src/misc/checkbochs.patch

index 17a869b5ab48e19418b94e162927d255ff7080e0..0976d6809447ff92361ebe21bb8d696d18bf2cf5 100644 (file)
@@ -1,11 +1,6 @@
-This patch provides Eraser-like lock set checking for Bochs.
-See the Pintos documentation for more information.
-
-This patch is provided by Sorav Bansal <sbansal@cs.stanford.edu>.
-
-diff -urpN bochs-2.1.1.orig/Makefile.in checkbochs-2.1.1/Makefile.in
---- bochs-2.1.1.orig/Makefile.in       2004-02-11 14:28:02.000000000 -0800
-+++ checkbochs-2.1.1/Makefile.in       2005-06-29 10:59:56.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/Makefile.in checkbochs-2.1.1/Makefile.in
+--- bochs-2.1.1/Makefile.in    2004-02-11 14:28:02.000000000 -0800
++++ checkbochs-2.1.1/Makefile.in       2005-07-02 17:25:47.000000000 -0700
 @@ -177,11 +177,11 @@ all: @PRIMARY_TARGET@ @PLUGIN_TARGET@ bx
  @EXTERNAL_DEPENDENCY@
  
 @@ -177,11 +177,11 @@ all: @PRIMARY_TARGET@ @PLUGIN_TARGET@ bx
  @EXTERNAL_DEPENDENCY@
  
@@ -75,9 +70,9 @@ diff -urpN bochs-2.1.1.orig/Makefile.in checkbochs-2.1.1/Makefile.in
        cd doc/docbook @COMMAND_SEPARATOR@
        $(MAKE) dist-clean
        @CD_UP_TWO@
        cd doc/docbook @COMMAND_SEPARATOR@
        $(MAKE) dist-clean
        @CD_UP_TWO@
-diff -urpN bochs-2.1.1.orig/bochs.h checkbochs-2.1.1/bochs.h
---- bochs-2.1.1.orig/bochs.h   2004-02-11 14:28:03.000000000 -0800
-+++ checkbochs-2.1.1/bochs.h   2005-06-29 10:59:53.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/bochs.h checkbochs-2.1.1/bochs.h
+--- bochs-2.1.1/bochs.h        2005-07-02 17:23:03.000000000 -0700
++++ checkbochs-2.1.1/bochs.h   2005-07-02 17:25:47.000000000 -0700
 @@ -671,6 +671,7 @@ typedef struct BOCHSAPI {
    bx_gdbstub_t      gdbstub;
    bx_param_enum_c *Osel_config;
 @@ -671,6 +671,7 @@ typedef struct BOCHSAPI {
    bx_gdbstub_t      gdbstub;
    bx_param_enum_c *Osel_config;
@@ -86,40 +81,69 @@ diff -urpN bochs-2.1.1.orig/bochs.h checkbochs-2.1.1/bochs.h
    } bx_options_t;
  
  BOCHSAPI extern bx_options_t bx_options;
    } bx_options_t;
  
  BOCHSAPI extern bx_options_t bx_options;
-diff -urpN bochs-2.1.1.orig/configure checkbochs-2.1.1/configure
---- bochs-2.1.1.orig/configure 2004-02-11 14:28:40.000000000 -0800
-+++ checkbochs-2.1.1/configure 2005-06-29 10:59:53.000000000 -0700
-@@ -36189,7 +36189,7 @@ echo "${ECHO_T}no" >&6
+diff -X ignore -urpNb bochs-2.1.1/configure.in checkbochs-2.1.1/configure.in
+--- bochs-2.1.1/configure.in   2004-02-11 14:28:40.000000000 -0800
++++ checkbochs-2.1.1/configure.in      2005-07-19 15:51:35.000000000 -0700
+@@ -2244,6 +2244,11 @@ if test "$with_rfb" = yes; then
+   fi
  fi
  
  fi
  
--                                                                                                                                                                          ac_config_files="$ac_config_files Makefile iodev/Makefile bx_debug/Makefile bios/Makefile cpu/Makefile memory/Makefile gui/Makefile disasm/Makefile ${INSTRUMENT_DIR}/Makefile misc/Makefile fpu/Makefile doc/docbook/Makefile build/linux/bochs-dlx bxversion.h build/macosx/Info.plist build/win32/nsis/Makefile build/win32/nsis/bochs.nsi"
-+                                                                                                                                                                          ac_config_files="$ac_config_files Makefile iodev/Makefile bx_debug/Makefile bios/Makefile cpu/Makefile memory/Makefile gui/Makefile disasm/Makefile ${INSTRUMENT_DIR}/Makefile misc/Makefile fpu/Makefile taint/Makefile doc/docbook/Makefile build/linux/bochs-dlx bxversion.h build/macosx/Info.plist build/win32/nsis/Makefile build/win32/nsis/bochs.nsi"
- cat >confcache <<\_ACEOF
- # This file is a shell script that caches the results of configure
- # tests run on this system so they can be shared between configure
-@@ -36724,6 +36724,7 @@ do
-   "${INSTRUMENT_DIR}/Makefile" ) CONFIG_FILES="$CONFIG_FILES ${INSTRUMENT_DIR}/Makefile" ;;
-   "misc/Makefile" ) CONFIG_FILES="$CONFIG_FILES misc/Makefile" ;;
-   "fpu/Makefile" ) CONFIG_FILES="$CONFIG_FILES fpu/Makefile" ;;
-+  "taint/Makefile" ) CONFIG_FILES="$CONFIG_FILES taint/Makefile" ;;
-   "doc/docbook/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/docbook/Makefile" ;;
-   "build/linux/bochs-dlx" ) CONFIG_FILES="$CONFIG_FILES build/linux/bochs-dlx" ;;
-   "bxversion.h" ) CONFIG_FILES="$CONFIG_FILES bxversion.h" ;;
-diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
---- bochs-2.1.1.orig/cpu/cpu.cc        2004-02-11 14:28:51.000000000 -0800
-+++ checkbochs-2.1.1/cpu/cpu.cc        2005-06-29 10:59:54.000000000 -0700
-@@ -30,6 +30,9 @@
++AC_CHECK_LIB(gdbm, gdbm_open, , [dnl
++echo 'Error: checkbochs requires libgdbm'
++exit 1
++])
++
+ # The ACX_PTHREAD function was written by 
+ # Steven G. Johnson <stevenj@alum.mit.edu> and 
+ # Alejandro Forero Cuervo <bachue@bachue.com> 
+@@ -2516,4 +2521,5 @@ AC_OUTPUT(Makefile iodev/Makefile bx_deb
+        fpu/Makefile doc/docbook/Makefile \
+        build/linux/bochs-dlx \
+        bxversion.h build/macosx/Info.plist \
+-       build/win32/nsis/Makefile build/win32/nsis/bochs.nsi)
++       build/win32/nsis/Makefile build/win32/nsis/bochs.nsi \
++       taint/Makefile)
+diff -X ignore -urpNb bochs-2.1.1/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
+--- bochs-2.1.1/cpu/cpu.cc     2004-02-11 14:28:51.000000000 -0800
++++ checkbochs-2.1.1/cpu/cpu.cc        2005-07-19 14:47:38.000000000 -0700
+@@ -30,6 +30,10 @@
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
  
 +#include "taint/globals.h"
 +#include "taint/mydebug.h"
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
  
 +#include "taint/globals.h"
 +#include "taint/mydebug.h"
++#include "taint/lockset.h"
 +
  #if BX_USE_CPU_SMF
  #define this (BX_CPU(0))
  #endif
 +
  #if BX_USE_CPU_SMF
  #define this (BX_CPU(0))
  #endif
-@@ -111,7 +114,9 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
+@@ -104,6 +108,25 @@ extern void REGISTER_IADDR(bx_addr addr)
+ #endif
++static void
++clear_stack_taints(void) 
++{
++    BX_CPU_C *cpu = BX_CPU(0);
++
++    Bit32u old_esp = cpu->prev_esp;
++    Bit32u new_esp = ESP;
++    if (old_esp >= new_esp
++        || (old_esp & 0xfffff000) != (new_esp & 0xfffff000))
++        return;
++
++    Bit32u start = old_esp - PHYS_BASE;
++    Bit32u length = new_esp - old_esp;
++    if (start > cpu->mem->len || start + length > cpu->mem->len)
++        return;
++    memset (cpu->mem->taint_vector + start, 0,
++            sizeof *cpu->mem->taint_vector * length);
++}
++
+   void
+ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
+ {
+@@ -111,7 +134,9 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
    bxInstruction_c iStorage BX_CPP_AlignN(32);
    bxInstruction_c *i = &iStorage;
  
    bxInstruction_c iStorage BX_CPP_AlignN(32);
    bxInstruction_c *i = &iStorage;
  
@@ -130,7 +154,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
  
  #if BX_DEBUGGER
    BX_CPU_THIS_PTR break_point = 0;
  
  #if BX_DEBUGGER
    BX_CPU_THIS_PTR break_point = 0;
-@@ -209,6 +214,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
+@@ -209,6 +234,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
      BxExecutePtr_tR resolveModRM = i->ResolveModrm; // Get as soon as possible for speculation.
  
      execute = i->execute; // fetch as soon as possible for speculation.
      BxExecutePtr_tR resolveModRM = i->ResolveModrm; // Get as soon as possible for speculation.
  
      execute = i->execute; // fetch as soon as possible for speculation.
@@ -141,7 +165,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
      if (resolveModRM) {
        BX_CPU_CALL_METHODR(resolveModRM, (i));
      }
      if (resolveModRM) {
        BX_CPU_CALL_METHODR(resolveModRM, (i));
      }
-@@ -281,6 +290,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
+@@ -281,6 +310,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
      }
  #endif
      execute = i->execute; // fetch as soon as possible for speculation.
      }
  #endif
      execute = i->execute; // fetch as soon as possible for speculation.
@@ -152,15 +176,16 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
      if (resolveModRM) {
        BX_CPU_CALL_METHODR(resolveModRM, (i));
        }
      if (resolveModRM) {
        BX_CPU_CALL_METHODR(resolveModRM, (i));
        }
-@@ -303,6 +316,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
+@@ -303,6 +336,8 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
        BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID);
        RIP += i->ilen();
        BX_CPU_CALL_METHOD(execute, (i));
 +      BX_CPU_CALL_METHOD(taint_execute, (i));
        BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID);
        RIP += i->ilen();
        BX_CPU_CALL_METHOD(execute, (i));
 +      BX_CPU_CALL_METHOD(taint_execute, (i));
++      clear_stack_taints ();
        BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
        BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
        BX_INSTR_AFTER_EXECUTION(BX_CPU_ID);
        BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
        BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
        BX_INSTR_AFTER_EXECUTION(BX_CPU_ID);
-@@ -323,6 +337,7 @@ repeat_loop:
+@@ -323,6 +358,7 @@ repeat_loop:
          if (i->as64L()) {
            if (RCX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          if (i->as64L()) {
            if (RCX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -168,7 +193,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              RCX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
              RCX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
-@@ -335,6 +350,7 @@ repeat_loop:
+@@ -335,6 +371,7 @@ repeat_loop:
          if (i->as32L()) {
            if (ECX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          if (i->as32L()) {
            if (ECX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -176,7 +201,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              ECX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
              ECX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
-@@ -345,6 +361,7 @@ repeat_loop:
+@@ -345,6 +382,7 @@ repeat_loop:
          else {
            if (CX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          else {
            if (CX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -184,7 +209,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              CX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
              CX --;
              }
            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
-@@ -358,6 +375,7 @@ repeat_loop:
+@@ -358,6 +396,7 @@ repeat_loop:
          if (i->as64L()) {
            if (RCX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          if (i->as64L()) {
            if (RCX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -192,7 +217,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              RCX --;
              }
            if (RCX == 0) goto repeat_done;
              RCX --;
              }
            if (RCX == 0) goto repeat_done;
-@@ -368,6 +386,7 @@ repeat_loop:
+@@ -368,6 +407,7 @@ repeat_loop:
          if (i->as32L()) {
            if (ECX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          if (i->as32L()) {
            if (ECX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -200,7 +225,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              ECX --;
              }
            if (ECX == 0) goto repeat_done;
              ECX --;
              }
            if (ECX == 0) goto repeat_done;
-@@ -376,6 +395,7 @@ repeat_loop:
+@@ -376,6 +416,7 @@ repeat_loop:
          else { // 16bit addrsize
            if (CX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
          else { // 16bit addrsize
            if (CX != 0) {
              BX_CPU_CALL_METHOD(execute, (i));
@@ -208,7 +233,23 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
              CX --;
              }
            if (CX == 0) goto repeat_done;
              CX --;
              }
            if (CX == 0) goto repeat_done;
-@@ -865,6 +885,17 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; /
+@@ -405,6 +446,7 @@ repeat_not_done:
+ repeat_done:
+       RIP += i->ilen();
++      clear_stack_taints ();
+       BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
+       BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
+       BX_INSTR_REPEAT_ITERATION(BX_CPU_ID);
+@@ -617,6 +659,7 @@ BX_CPU_C::handleAsyncEvent(void)
+     // the new EIP/ESP values.  But here, we call interrupt() much like
+     // it was a sofware interrupt instruction, and need to effect the
+     // commit here.  This code mirrors similar code above.
++    clear_stack_taints ();
+     BX_CPU_THIS_PTR prev_eip = RIP; // commit new RIP
+     BX_CPU_THIS_PTR prev_esp = RSP; // commit new RSP
+     BX_CPU_THIS_PTR EXT = 0;
+@@ -865,6 +908,17 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; /
                    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
  }
  
                    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
  }
  
@@ -226,9 +267,9 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
  
  #if BX_EXTERNAL_DEBUGGER
  
  
  #if BX_EXTERNAL_DEBUGGER
  
-diff -urpN bochs-2.1.1.orig/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
---- bochs-2.1.1.orig/cpu/cpu.h 2004-02-11 14:28:51.000000000 -0800
-+++ checkbochs-2.1.1/cpu/cpu.h 2005-06-29 10:59:54.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
+--- bochs-2.1.1/cpu/cpu.h      2004-02-11 14:28:51.000000000 -0800
++++ checkbochs-2.1.1/cpu/cpu.h 2005-07-19 12:24:02.000000000 -0700
 @@ -739,9 +739,11 @@ public:
  #if BX_USE_CPU_SMF
    void (*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
 @@ -739,9 +739,11 @@ public:
  #if BX_USE_CPU_SMF
    void (*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@@ -272,7 +313,7 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
  #if BX_SUPPORT_X86_64
    // data upper 32 bits - not used any longer
    //Bit32s daddr_upper;    // upper bits must be canonical  (-virtmax --> + virtmax)
  #if BX_SUPPORT_X86_64
    // data upper 32 bits - not used any longer
    //Bit32s daddr_upper;    // upper bits must be canonical  (-virtmax --> + virtmax)
-@@ -2952,6 +2969,33 @@ union {
+@@ -2952,6 +2969,35 @@ union {
  #if BX_SUPPORT_APIC
    bx_local_apic_c local_apic;
  #endif
  #if BX_SUPPORT_APIC
    bx_local_apic_c local_apic;
  #endif
@@ -282,31 +323,33 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
 +  BX_SMF Bit32u thread_current(void) ;
 +  BX_SMF Bit32s BX_CPP_AttrRegparmN(3) BX_CPU_C::taint_dtranslate_linear(bx_address laddr, unsigned pl, unsigned rw);
 +  BX_SMF Bit32u BX_CPP_AttrRegparmN(2) BX_CPU_C::taint_itranslate_linear(bx_address laddr, unsigned pl);
 +  BX_SMF Bit32u thread_current(void) ;
 +  BX_SMF Bit32s BX_CPP_AttrRegparmN(3) BX_CPU_C::taint_dtranslate_linear(bx_address laddr, unsigned pl, unsigned rw);
 +  BX_SMF Bit32u BX_CPP_AttrRegparmN(2) BX_CPU_C::taint_itranslate_linear(bx_address laddr, unsigned pl);
-+  BX_SMF int BX_CPP_AttrRegparmN(3) BX_CPU_C::access_linear_taint(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value);
++  BX_SMF struct lockset *BX_CPU_C::access_linear_taint(bx_address laddr);
 +//SHADOW STATE FUNCTIONS
 +  BX_SMF void TT_TaintSaveRegs(bxInstruction_c *i);
 +  BX_SMF void TT_TaintRestoreRegs(bxInstruction_c *i);
 +  BX_SMF void TT_Lock(bxInstruction_c *i);
 +  BX_SMF void TT_Unlock(bxInstruction_c *i);
 +  BX_SMF void TT_CommonOps(bxInstruction_c *i);
 +//SHADOW STATE FUNCTIONS
 +  BX_SMF void TT_TaintSaveRegs(bxInstruction_c *i);
 +  BX_SMF void TT_TaintRestoreRegs(bxInstruction_c *i);
 +  BX_SMF void TT_Lock(bxInstruction_c *i);
 +  BX_SMF void TT_Unlock(bxInstruction_c *i);
 +  BX_SMF void TT_CommonOps(bxInstruction_c *i);
-+                                                                                                                                                                                                     
++
 +  BX_SMF int read_virtual_checks_silent(bx_segment_reg_t *seg, bx_address offset, unsigned length) BX_CPP_AttrRegparmN(3);
 +  BX_SMF int read_virtual_byte_silent(unsigned s, bx_address offset, Bit8u *data);
 +  BX_SMF int read_virtual_word_silent(unsigned s, bx_address offset, Bit16u *data);
 +  BX_SMF int read_virtual_dword_silent(unsigned s, bx_address offset, Bit32u *data);
 +  BX_SMF int access_linear_silent(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *data);
 +  BX_SMF int read_virtual_checks_silent(bx_segment_reg_t *seg, bx_address offset, unsigned length) BX_CPP_AttrRegparmN(3);
 +  BX_SMF int read_virtual_byte_silent(unsigned s, bx_address offset, Bit8u *data);
 +  BX_SMF int read_virtual_word_silent(unsigned s, bx_address offset, Bit16u *data);
 +  BX_SMF int read_virtual_dword_silent(unsigned s, bx_address offset, Bit32u *data);
 +  BX_SMF int access_linear_silent(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *data);
-+                                                                                                                                                                                                     
++
 +  BX_SMF char *backtrace(char *s);
 +  BX_SMF char *backtrace(char *s);
++  BX_SMF void backtrace_eips(Bit32u *eips, int n);
 +  BX_SMF Bit32u callingEIP(void);
 +  BX_SMF Bit32u callingEIP(void);
-+                                                                                                                                                                                                     
++
 +  BX_SMF void eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *data);
 +  BX_SMF void eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *data);
-+                                                                                                                                                                                                     
++
 +  BX_SMF void eraser_init_globals (void) ;
 +  BX_SMF void eraser_init_globals (void) ;
++  BX_SMF void eraser_done_globals (void) ;
 +
    };
  
  
 +
    };
  
  
-@@ -3299,6 +3343,7 @@ IMPLEMENT_EFLAG_ACCESSOR   (TF,  8)
+@@ -3299,6 +3345,7 @@ IMPLEMENT_EFLAG_ACCESSOR   (TF,  8)
  #define BxGroup14         BxGroupN
  #define BxGroup15         BxGroupN
  #define BxGroup16         BxGroupN
  #define BxGroup14         BxGroupN
  #define BxGroup15         BxGroupN
  #define BxGroup16         BxGroupN
@@ -314,9 +357,9 @@ diff -urpN bochs-2.1.1.orig/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
  
  #if BX_DEBUGGER
  typedef enum _show_flags {
  
  #if BX_DEBUGGER
  typedef enum _show_flags {
-diff -urpN bochs-2.1.1.orig/cpu/cpuid.cc checkbochs-2.1.1/cpu/cpuid.cc
---- bochs-2.1.1.orig/cpu/cpuid.cc      2003-12-31 09:35:43.000000000 -0800
-+++ checkbochs-2.1.1/cpu/cpuid.cc      2005-06-29 10:59:54.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/cpu/cpuid.cc checkbochs-2.1.1/cpu/cpuid.cc
+--- bochs-2.1.1/cpu/cpuid.cc   2003-12-31 09:35:43.000000000 -0800
++++ checkbochs-2.1.1/cpu/cpuid.cc      2005-07-02 17:25:48.000000000 -0700
 @@ -251,6 +251,12 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
        RDX = get_std_cpuid_features ();
        break;
 @@ -251,6 +251,12 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
        RDX = get_std_cpuid_features ();
        break;
@@ -330,9 +373,18 @@ diff -urpN bochs-2.1.1.orig/cpu/cpuid.cc checkbochs-2.1.1/cpu/cpuid.cc
  #if 0
  #if BX_CPU_LEVEL >= 6
      case 2:
  #if 0
  #if BX_CPU_LEVEL >= 6
      case 2:
-diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.cc
---- bochs-2.1.1.orig/cpu/fetchdecode.cc        2003-12-28 10:19:41.000000000 -0800
-+++ checkbochs-2.1.1/cpu/fetchdecode.cc        2005-06-29 10:59:54.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/cpu/debugstuff.cc checkbochs-2.1.1/cpu/debugstuff.cc
+--- bochs-2.1.1/cpu/debugstuff.cc      2003-12-24 12:32:59.000000000 -0800
++++ checkbochs-2.1.1/cpu/debugstuff.cc 2005-07-18 21:40:23.000000000 -0700
+@@ -1023,4 +1023,5 @@ BX_CPU_C::atexit(void)
+     BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b ? 32 : 16));
+   debug(BX_CPU_THIS_PTR prev_eip);
++  eraser_done_globals();
+ }
+diff -X ignore -urpNb bochs-2.1.1/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.cc
+--- bochs-2.1.1/cpu/fetchdecode.cc     2003-12-28 10:19:41.000000000 -0800
++++ checkbochs-2.1.1/cpu/fetchdecode.cc        2005-07-02 17:25:48.000000000 -0700
 @@ -29,6 +29,8 @@
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
 @@ -29,6 +29,8 @@
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
@@ -387,7 +439,7 @@ diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.
  #if BX_SUPPORT_X86_64
    /* 0F 05 */  { 0, &BX_CPU_C::SYSCALL },
  #else
  #if BX_SUPPORT_X86_64
    /* 0F 05 */  { 0, &BX_CPU_C::SYSCALL },
  #else
-@@ -1564,6 +1580,8 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxIns
+@@ -1564,6 +1579,8 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxIns
                    /*os64*/       0,  /*as64*/     0,
                    /*extend8bit*/ 0,  /*repUsed*/  0);
  
                    /*os64*/       0,  /*as64*/     0,
                    /*extend8bit*/ 0,  /*repUsed*/  0);
  
@@ -396,7 +448,7 @@ diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.
    sse_prefix = SSE_PREFIX_NONE;
    
  fetch_b1:
    sse_prefix = SSE_PREFIX_NONE;
    
  fetch_b1:
-@@ -1669,6 +1687,7 @@ another_byte:
+@@ -1669,6 +1686,7 @@ another_byte:
          case 0xf0: // LOCK:
            BX_INSTR_PREFIX_LOCK(BX_CPU_ID);
            lock = 1;
          case 0xf0: // LOCK:
            BX_INSTR_PREFIX_LOCK(BX_CPU_ID);
            lock = 1;
@@ -404,7 +456,7 @@ diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.
            if (ilen < remain) {
              ilen++;
              goto fetch_b1;
            if (ilen < remain) {
              ilen++;
              goto fetch_b1;
-@@ -1883,6 +1902,7 @@ modrm_done:
+@@ -1883,6 +1901,7 @@ modrm_done:
      }
  
      instruction->execute = OpcodeInfoPtr->ExecutePtr;
      }
  
      instruction->execute = OpcodeInfoPtr->ExecutePtr;
@@ -412,7 +464,7 @@ diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.
      instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
    }
    else {
      instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
    }
    else {
-@@ -1891,6 +1911,7 @@ modrm_done:
+@@ -1891,6 +1910,7 @@ modrm_done:
      // the if() above after fetching the 2nd byte, so this path is
      // taken in all cases if a modrm byte is NOT required.
      instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
      // the if() above after fetching the 2nd byte, so this path is
      // taken in all cases if a modrm byte is NOT required.
      instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
@@ -420,9 +472,9 @@ diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.
      instruction->IxForm.opcodeReg = b1 & 7;
    }
  
      instruction->IxForm.opcodeReg = b1 & 7;
    }
  
-diff -urpN bochs-2.1.1.orig/cpu/paging.cc checkbochs-2.1.1/cpu/paging.cc
---- bochs-2.1.1.orig/cpu/paging.cc     2003-12-30 14:12:45.000000000 -0800
-+++ checkbochs-2.1.1/cpu/paging.cc     2005-06-29 10:59:54.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/cpu/paging.cc checkbochs-2.1.1/cpu/paging.cc
+--- bochs-2.1.1/cpu/paging.cc  2003-12-30 14:12:45.000000000 -0800
++++ checkbochs-2.1.1/cpu/paging.cc     2005-07-02 17:25:48.000000000 -0700
 @@ -38,6 +38,8 @@
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
 @@ -38,6 +38,8 @@
  #include "bochs.h"
  #define LOG_THIS BX_CPU_THIS_PTR
@@ -473,11 +525,9 @@ diff -urpN bochs-2.1.1.orig/cpu/paging.cc checkbochs-2.1.1/cpu/paging.cc
      return;
      }
  
      return;
      }
  
-diff -urpN bochs-2.1.1.orig/gdbstub.cc checkbochs-2.1.1/gdbstub.cc
-diff -urpN bochs-2.1.1.orig/gdbstub.cc.rej checkbochs-2.1.1/gdbstub.cc.rej
-diff -urpN bochs-2.1.1.orig/gui/Makefile.in checkbochs-2.1.1/gui/Makefile.in
---- bochs-2.1.1.orig/gui/Makefile.in   2003-11-28 07:07:28.000000000 -0800
-+++ checkbochs-2.1.1/gui/Makefile.in   2005-06-29 10:13:21.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/gui/Makefile.in checkbochs-2.1.1/gui/Makefile.in
+--- bochs-2.1.1/gui/Makefile.in        2003-11-28 07:07:28.000000000 -0800
++++ checkbochs-2.1.1/gui/Makefile.in   2005-07-02 17:25:48.000000000 -0700
 @@ -44,7 +44,7 @@ SHELL = /bin/sh
  @SET_MAKE@
  
 @@ -44,7 +44,7 @@ SHELL = /bin/sh
  @SET_MAKE@
  
@@ -487,9 +537,9 @@ diff -urpN bochs-2.1.1.orig/gui/Makefile.in checkbochs-2.1.1/gui/Makefile.in
  LOCAL_CXXFLAGS =
  LDFLAGS = @LDFLAGS@
  LIBS = @LIBS@
  LOCAL_CXXFLAGS =
  LDFLAGS = @LDFLAGS@
  LIBS = @LIBS@
-diff -urpN bochs-2.1.1.orig/gui/siminterface.h checkbochs-2.1.1/gui/siminterface.h
---- bochs-2.1.1.orig/gui/siminterface.h        2004-02-11 14:28:52.000000000 -0800
-+++ checkbochs-2.1.1/gui/siminterface.h        2005-06-29 10:59:55.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/gui/siminterface.h checkbochs-2.1.1/gui/siminterface.h
+--- bochs-2.1.1/gui/siminterface.h     2004-02-11 14:28:52.000000000 -0800
++++ checkbochs-2.1.1/gui/siminterface.h        2005-07-02 17:25:48.000000000 -0700
 @@ -464,6 +464,7 @@ typedef enum {
  #endif
    BXP_SEL_CONFIG_INTERFACE,
 @@ -464,6 +464,7 @@ typedef enum {
  #endif
    BXP_SEL_CONFIG_INTERFACE,
@@ -498,13 +548,21 @@ diff -urpN bochs-2.1.1.orig/gui/siminterface.h checkbochs-2.1.1/gui/siminterface
    BXP_THIS_IS_THE_LAST    // used to determine length of list
  } bx_id;
  
    BXP_THIS_IS_THE_LAST    // used to determine length of list
  } bx_id;
  
-diff -urpN bochs-2.1.1.orig/iodev/pit82c54.cc checkbochs-2.1.1/iodev/pit82c54.cc
-diff -urpN bochs-2.1.1.orig/iodev/pit82c54.cc~ checkbochs-2.1.1/iodev/pit82c54.cc~
-diff -urpN bochs-2.1.1.orig/iodev/serial.cc checkbochs-2.1.1/iodev/serial.cc
-diff -urpN bochs-2.1.1.orig/iodev/serial.cc.rej checkbochs-2.1.1/iodev/serial.cc.rej
-diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
---- bochs-2.1.1.orig/main.cc   2004-02-11 14:28:41.000000000 -0800
-+++ checkbochs-2.1.1/main.cc   2005-06-29 11:29:46.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/iodev/vmware3.h checkbochs-2.1.1/iodev/vmware3.h
+--- bochs-2.1.1/iodev/vmware3.h        2004-02-11 14:28:54.000000000 -0800
++++ checkbochs-2.1.1/iodev/vmware3.h   2005-07-19 12:23:26.000000000 -0700
+@@ -75,7 +75,7 @@ class vmware3_image_t : public device_im
+           Bit32u   vmware_version;
+           Bit8u    PAD3[364];
+       } COW_Header
+-#if !defined(_MSC_VER)
++#if 0 && !defined(_MSC_VER)
+         GCC_ATTRIBUTE((packed))
+ #endif
+       ;
+diff -X ignore -urpNb bochs-2.1.1/main.cc checkbochs-2.1.1/main.cc
+--- bochs-2.1.1/main.cc        2005-07-02 17:23:03.000000000 -0700
++++ checkbochs-2.1.1/main.cc   2005-07-03 11:01:28.000000000 -0700
 @@ -28,6 +28,10 @@
  #include <assert.h>
  #include "state_file.h"
 @@ -28,6 +28,10 @@
  #include <assert.h>
  #include "state_file.h"
@@ -516,15 +574,15 @@ diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
  #ifdef HAVE_LOCALE_H
  #include <locale.h>
  #endif
  #ifdef HAVE_LOCALE_H
  #include <locale.h>
  #endif
-@@ -1768,6 +1773,7 @@ int bxmain () {
-   if (setjmp (context) == 0) {
+@@ -1770,6 +1774,7 @@ int bxmain () {
      SIM->set_quit_context (&context);
      if (bx_init_main (bx_startup_flags.argc, bx_startup_flags.argv) < 0) 
      SIM->set_quit_context (&context);
      if (bx_init_main (bx_startup_flags.argc, bx_startup_flags.argv) < 0) 
-+    BX_CPU(0)->eraser_init_globals() ;
        return 0;
        return 0;
++    BX_CPU(0)->eraser_init_globals() ;
      // read a param to decide which config interface to start.
      // If one exists, start it.  If not, just begin.
      // read a param to decide which config interface to start.
      // If one exists, start it.  If not, just begin.
-@@ -2309,6 +2322,18 @@ bx_begin_simulation (int argc, char *arg
+     bx_param_enum_c *ci_param = SIM->get_param_enum (BXP_SEL_CONFIG_INTERFACE);
+@@ -2317,6 +2322,18 @@ bx_begin_simulation (int argc, char *arg
    SIM->set_init_done (1);
  
    // update headerbar buttons since drive status can change during init
    SIM->set_init_done (1);
  
    // update headerbar buttons since drive status can change during init
@@ -543,7 +601,7 @@ diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
    bx_gui->update_drive_status_buttons ();
  
    // The set handler for mouse_enabled does not actually update the gui
    bx_gui->update_drive_status_buttons ();
  
    // The set handler for mouse_enabled does not actually update the gui
-@@ -2507,7 +2532,7 @@ bx_init_hardware()
+@@ -2515,7 +2532,7 @@ bx_init_hardware()
  #if !BX_DEBUGGER
    signal(SIGINT, bx_signal_handler);
  #endif
  #if !BX_DEBUGGER
    signal(SIGINT, bx_signal_handler);
  #endif
@@ -552,7 +610,7 @@ diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
  #if BX_SHOW_IPS
  #ifndef __MINGW32__
    signal(SIGALRM, bx_signal_handler);
  #if BX_SHOW_IPS
  #ifndef __MINGW32__
    signal(SIGALRM, bx_signal_handler);
-@@ -3971,6 +3996,20 @@ parse_line_formatted(char *context, int 
+@@ -3979,6 +3996,20 @@ parse_line_formatted(char *context, int 
      if (!bx_options.Osel_config->set_by_name (params[1]))
        PARSE_ERR(("%s: config_interface '%s' not available", context, params[1]));
      }
      if (!bx_options.Osel_config->set_by_name (params[1]))
        PARSE_ERR(("%s: config_interface '%s' not available", context, params[1]));
      }
@@ -573,10 +631,9 @@ diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
    else if (!strcmp(params[0], "display_library")) {
      if (num_params != 2) {
        PARSE_ERR(("%s: display_library directive: wrong # args.", context));
    else if (!strcmp(params[0], "display_library")) {
      if (num_params != 2) {
        PARSE_ERR(("%s: display_library directive: wrong # args.", context));
-diff -urpN bochs-2.1.1.orig/main.cc~ checkbochs-2.1.1/main.cc~
-diff -urpN bochs-2.1.1.orig/memory/memory.h checkbochs-2.1.1/memory/memory.h
---- bochs-2.1.1.orig/memory/memory.h   2004-02-11 14:28:54.000000000 -0800
-+++ checkbochs-2.1.1/memory/memory.h   2005-06-29 10:59:56.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/memory/memory.h checkbochs-2.1.1/memory/memory.h
+--- bochs-2.1.1/memory/memory.h        2004-02-11 14:28:54.000000000 -0800
++++ checkbochs-2.1.1/memory/memory.h   2005-07-02 17:25:48.000000000 -0700
 @@ -45,6 +45,10 @@ class BOCHSAPI BX_MEM_C : public logfunc
  public:
    Bit8u   *actual_vector;
 @@ -45,6 +45,10 @@ class BOCHSAPI BX_MEM_C : public logfunc
  public:
    Bit8u   *actual_vector;
@@ -601,9 +658,9 @@ diff -urpN bochs-2.1.1.orig/memory/memory.h checkbochs-2.1.1/memory/memory.h
    };
  
  #if BX_PROVIDE_CPU_MEMORY==1
    };
  
  #if BX_PROVIDE_CPU_MEMORY==1
-diff -urpN bochs-2.1.1.orig/memory/misc_mem.cc checkbochs-2.1.1/memory/misc_mem.cc
---- bochs-2.1.1.orig/memory/misc_mem.cc        2004-02-11 14:28:54.000000000 -0800
-+++ checkbochs-2.1.1/memory/misc_mem.cc        2005-06-29 10:59:56.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/memory/misc_mem.cc checkbochs-2.1.1/memory/misc_mem.cc
+--- bochs-2.1.1/memory/misc_mem.cc     2004-02-11 14:28:54.000000000 -0800
++++ checkbochs-2.1.1/memory/misc_mem.cc        2005-07-02 17:25:48.000000000 -0700
 @@ -54,7 +54,9 @@ BX_MEM_C::BX_MEM_C(void)
    settype(MEMLOG);
  
 @@ -54,7 +54,9 @@ BX_MEM_C::BX_MEM_C(void)
    settype(MEMLOG);
  
@@ -644,7 +701,7 @@ diff -urpN bochs-2.1.1.orig/memory/misc_mem.cc checkbochs-2.1.1/memory/misc_mem.
  }
  #endif
  
  }
  #endif
  
-@@ -136,6 +150,7 @@ BX_MEM_C::init_memory(int memsize)
+@@ -136,6 +149,7 @@ BX_MEM_C::init_memory(int memsize)
  
    if (BX_MEM_THIS vector == NULL) {
      // memory not already allocated, do now...
  
    if (BX_MEM_THIS vector == NULL) {
      // memory not already allocated, do now...
@@ -652,9 +709,9 @@ diff -urpN bochs-2.1.1.orig/memory/misc_mem.cc checkbochs-2.1.1/memory/misc_mem.
      alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
      BX_MEM_THIS len    = memsize;
      BX_MEM_THIS megabytes = memsize / (1024*1024);
      alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
      BX_MEM_THIS len    = memsize;
      BX_MEM_THIS megabytes = memsize / (1024*1024);
-diff -urpN bochs-2.1.1.orig/taint/Makefile.in checkbochs-2.1.1/taint/Makefile.in
---- bochs-2.1.1.orig/taint/Makefile.in 1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/Makefile.in 2005-06-29 11:14:31.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/Makefile.in checkbochs-2.1.1/taint/Makefile.in
+--- bochs-2.1.1/taint/Makefile.in      1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/Makefile.in 2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,184 @@
 +.SUFFIXES: .cc
 +
 @@ -0,0 +1,184 @@
 +.SUFFIXES: .cc
 +
@@ -840,10 +897,10 @@ diff -urpN bochs-2.1.1.orig/taint/Makefile.in checkbochs-2.1.1/taint/Makefile.in
 +hash.o: hash.h hash.cc
 +
 +list.o: list.h list.cc
 +hash.o: hash.h hash.cc
 +
 +list.o: list.h list.cc
-diff -urpN bochs-2.1.1.orig/taint/common.cc checkbochs-2.1.1/taint/common.cc
---- bochs-2.1.1.orig/taint/common.cc   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/common.cc   2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,146 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/common.cc checkbochs-2.1.1/taint/common.cc
+--- bochs-2.1.1/taint/common.cc        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/common.cc   2005-07-19 15:33:53.000000000 -0700
+@@ -0,0 +1,185 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
@@ -940,13 +997,9 @@ diff -urpN bochs-2.1.1.orig/taint/common.cc checkbochs-2.1.1/taint/common.cc
 +    unsigned kernelPL = 0;
 +    Bit32u pid;
 +    if (CPL==kernelPL) {
 +    unsigned kernelPL = 0;
 +    Bit32u pid;
 +    if (CPL==kernelPL) {
-+      //pid = (ESP & 0xffffe000);
-+      pid = ((ESP-1) & ~PGMASK);      //subtract 1 so that we do not get incorrect pid, if stack is empty
++      pid = ((ESP-1) - 0xc0000000) >> 12;
 +    } else {
 +    } else {
-+      /*Bit32u esp;
-+      Bit16u ss;
-+      get_SS_ESP_from_TSS(kernelPL,&ss,&esp);
-+      pid = esp;*/
++        pid = 0;
 +    }
 +    return pid;
 +}
 +    }
 +    return pid;
 +}
@@ -969,6 +1022,49 @@ diff -urpN bochs-2.1.1.orig/taint/common.cc checkbochs-2.1.1/taint/common.cc
 +    return s;
 +}
 +
 +    return s;
 +}
 +
++static Bit32u
++read_dword(Bit32u laddr) 
++{
++    Bit32u paddr = laddr - PHYS_BASE;
++    if (paddr <= BX_MEM(0)->len - 4) {
++        Bit32u tmp;
++        ReadHostDWordFromLittleEndian(BX_MEM(0)->vector + paddr, tmp);
++        return tmp;
++    } else {
++        return 0;
++    }
++}
++
++static void
++read_2_dwords(Bit32u laddr, Bit32u *dst0, Bit32u *dst1) 
++{
++    Bit32u paddr = laddr - PHYS_BASE;
++    if (paddr <= BX_MEM(0)->len - 8) {
++        ReadHostDWordFromLittleEndian(BX_MEM(0)->vector + paddr, *dst0);
++        ReadHostDWordFromLittleEndian(BX_MEM(0)->vector + paddr + 4, *dst1);
++    } else {
++        *dst0 = 0;
++        *dst1 = 0;
++    }
++}
++
++void BX_CPU_C::backtrace_eips(Bit32u *eips, int n)  {
++    Bit32u ebp, eip;
++    *eips++ = EIP;
++    ebp = EBP;
++    while (ebp>0xc0000000 && --n > 0) {
++        read_2_dwords(ebp, &ebp, &eip);
++/* 
++        eip = read_dword (ebp+4);
++        ebp = read_dword (ebp);
++*/
++        *eips++ = eip;
++    }
++    while (--n > 0) {
++        *eips++ = 0;
++    }
++}
++
 +Bit32u BX_CPU_C::callingEIP(void) {
 +    Bit32u ebp, eip;
 +    int stackdepth = 0, readsuccessful = 1;
 +Bit32u BX_CPU_C::callingEIP(void) {
 +    Bit32u ebp, eip;
 +    int stackdepth = 0, readsuccessful = 1;
@@ -990,11 +1086,10 @@ diff -urpN bochs-2.1.1.orig/taint/common.cc checkbochs-2.1.1/taint/common.cc
 +      vfprintf (g_logfp, fmt, ap) ;
 +      va_end (ap) ;
 +}
 +      vfprintf (g_logfp, fmt, ap) ;
 +      va_end (ap) ;
 +}
-diff -urpN bochs-2.1.1.orig/taint/common.cc.bak checkbochs-2.1.1/taint/common.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
---- bochs-2.1.1.orig/taint/eraser.cc   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/eraser.cc   2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,240 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
+--- bochs-2.1.1/taint/eraser.cc        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/eraser.cc   2005-07-19 21:10:55.000000000 -0700
+@@ -0,0 +1,375 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
@@ -1003,8 +1098,7 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
 +#define this (BX_CPU(0))
 +#endif
 +
 +#define this (BX_CPU(0))
 +#endif
 +
-+#define PHYS_BASE     0xc0000000
-+
++#include <gdbm.h>
 +#include "mydebug.h"
 +#include "taint_type.h"
 +#include "lockset.h"
 +#include "mydebug.h"
 +#include "taint_type.h"
 +#include "lockset.h"
@@ -1013,6 +1107,104 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
 +#include "globals.h"
 +#include "mydebug.h"
 +
 +#include "globals.h"
 +#include "mydebug.h"
 +
++/* Backtrace database file name. */
++char btdb_fn[] = "/tmp/eraserXXXXXX";
++
++/* Backtrace database. */
++GDBM_FILE btdb;
++
++struct backtrace_key {
++    Bit32u laddr;
++    unsigned seq;
++};
++
++struct backtrace {
++    char type[8];
++    Bit32u thread;              /* Thread ID. */
++    Bit32u eips[16];            /* Backtrace EIPs. */
++    Bit32u locks[16];           /* Locks held. */
++};
++
++static void
++get_key(Bit32u address, unsigned seq, struct backtrace_key *key)
++{
++    key->laddr = address;
++    key->seq = seq;
++}
++
++static datum
++mk_datum(void *block, size_t length) 
++{
++    datum d;
++    d.dptr = (char *) block;
++    d.dsize = length;
++    return d;
++}
++
++static void
++record_backtrace(const char *type, Bit32u laddr) 
++{
++    lockset &tv = *BX_CPU(0)->access_linear_taint(laddr);
++    struct backtrace_key key;
++    struct backtrace bt;
++
++    /* Fill in backtrace struct. */
++    strncpy(bt.type, type, sizeof bt.type);
++    bt.type[sizeof bt.type - 1] = '\0';
++    bt.thread = BX_CPU(0)->thread_current();
++    BX_CPU(0)->backtrace_eips(bt.eips, sizeof bt.eips / sizeof *bt.eips);
++    lockset_dump(cur_held(bt.thread),
++                 bt.locks, sizeof bt.locks / sizeof *bt.locks);
++
++    /* Store backtrace struct. */
++    get_key(laddr, tv.seq, &key);
++    if (gdbm_store(btdb, mk_datum(&key, sizeof key), mk_datum(&bt, sizeof bt),
++                   GDBM_REPLACE) != 0) {
++        DBG(ERR, ("gdbm_store failed"));
++        exit(1);
++    }
++
++    /* Increment sequence number. */
++    tv.seq++;
++}
++
++static void
++dump_backtrace(Bit32u laddr, unsigned seq)
++{
++    struct backtrace_key key;
++    struct backtrace *bt;
++    datum content;
++
++    /* Fetch backtrace. */
++    get_key(laddr, seq, &key);
++    content = gdbm_fetch(btdb, mk_datum(&key, sizeof key));
++    if (content.dptr == NULL) {
++        abort();
++    }
++    bt = (backtrace *) content.dptr;
++
++    /* Dump. */
++    fprintf(g_logfp, "%s: thread %x, backtrace", bt->type, bt->thread);
++    for (unsigned i = 0; i < sizeof bt->eips / sizeof *bt->eips; i++) {
++        if (bt->eips[i] == 0)
++            break;
++        fprintf(g_logfp, " %x", bt->eips[i]); 
++    }
++    fprintf(g_logfp, ", locks");
++    for (unsigned i = 0; i < sizeof bt->locks / sizeof *bt->locks; i++) {
++        if (bt->locks[i] == 0)
++            break;
++        fprintf(g_logfp, " %x", bt->locks[i]);
++    }
++    fprintf(g_logfp, "\n");
++
++    free(bt);
++}
++
++    
++    
++
++
 +void breakme() {}
 +
 +#define WRN_UNINIT(loc) do {  \
 +void breakme() {}
 +
 +#define WRN_UNINIT(loc) do {  \
@@ -1096,86 +1288,95 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
 +    //update_lockset(myid,lset);
 +}
 +
 +    //update_lockset(myid,lset);
 +}
 +
-+void BX_CPU_C::eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *notused) {
-+    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
-+    Bit32u taintval[4], origval;
-+    int i, try_access;
-+    if (ignore_on(myid)) return;
-+    if (laddr + len <= PHYS_BASE) return ;
-+    if (laddr < PHYS_BASE) {
-+      len -= (PHYS_BASE-laddr) ;
-+      laddr = PHYS_BASE ;
-+    }
-+    DBG (ACCESS_LINEAR, ("%s() %d: entry. laddr=%x, len=%x, rw=%x\n",__func__,__LINE__,laddr,len,rw)) ;
-+    if (!BX_CPU_THIS_PTR get_IF()) {
-+      eraser_lock(INTERRUPT_LOCK); //acquire a dummy lock for disabled interrupts
-+      assert(cur_held(myid)!=0);
-+    }
-+    if (BX_CPU_THIS_PTR curInstruction->isLocked()) {
-+        DBG(LOCKS,("acquiring HW_PREFIX_LOCK. laddr=%x, len=%d.\n",laddr,len));
-+      eraser_lock(HW_PREFIX_LOCK); //acquire a dummy lock for h/w prefix "LOCK"
-+      assert(cur_held(myid)!=0);
-+    }
++void BX_CPU_C::eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *notused)
++{
++    Bit32u tid = BX_CPU_THIS_PTR thread_current ();
++    if (ignore_on (tid))
++        return;
++
++    // Acquire a dummy lock for disabled interrupts.
++    if (!BX_CPU_THIS_PTR get_IF())
++      eraser_lock(INTERRUPT_LOCK);
++
++    // Acquire a dummy lock for h/w prefix "LOCK".
++    if (BX_CPU_THIS_PTR curInstruction->isLocked())
++      eraser_lock(HW_PREFIX_LOCK);
 +
 +
-+    for (i=0;i<len;i++) {
-+        //taintval[i] = 0x0;
-+      try_access = access_linear_taint(laddr+i,1,pl,BX_READ,&taintval[i]);
-+      ASSERT(try_access);
-+      origval = taintval[i];
-+      if (get_state(taintval[i])==VIRGIN) {
++    for (; len-- > 0; laddr++) {
++        lockset *tvp = access_linear_taint(laddr);
++        if (tvp == NULL)
++            continue;
++        lockset &tv = *tvp;
++        lockset orig_tv = tv;
++
++        switch (tv.state) {
++        case S_VIRGIN:
 +          if (rw==BX_WRITE || rw==BX_RW) {
 +          if (rw==BX_WRITE || rw==BX_RW) {
-+              taintval[i] = set_state(taintval[i], EXCLUSIVE);
-+              taintval[i] = set_value(taintval[i], myid);
-+              DBG(CHECKBOCHS,("%x: Virgin->Exclusive(%x) location %x.if=%x. backtrace: %s\n",myid,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),backtrace(btstr)));
++                tv.state = S_EXCLUSIVE;
++                tv.seq = 0;
++                tv.value = tid;
++                record_backtrace("V->E", laddr);
 +          } else {
 +          } else {
-+              WRN_UNINIT(laddr) ;
++              //WRN_UNINIT(laddr) ;
 +          }
 +          }
-+      }
-+      else if (get_state(taintval[i])==EXCLUSIVE) {
-+          if (get_value(taintval[i])!=myid) {
-+              taintval[i] =  set_value(taintval[i],cur_held(myid));
++            break;
++
++        case S_EXCLUSIVE:
++          if (tv.value == tid) {
++                // Still exclusive to same thread.
++            } else {
++              tv.value = cur_held (tid);
 +              if (rw==BX_WRITE || rw==BX_RW) {
 +              if (rw==BX_WRITE || rw==BX_RW) {
-+                  taintval[i] = set_state(taintval[i],SHARED_MOD);
-+                  DBG(CHECKBOCHS,("%x: Ex(%x)->SM(%x) location %x from exclusive to shared-mod state. if=%x, cur_held=%d. backtrace: %s\n",myid,origval,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),cur_held(myid),backtrace(btstr)));
++                  tv.state = S_SH_MOD;
++                    record_backtrace("E->SM", laddr);
 +              } else {
 +              } else {
-+                  taintval[i] = set_state(taintval[i],SHARED);
-+                  DBG(CHECKBOCHS,("%x: Ex(%x)->Shared(%x) location %x from exclusive to shared-mod state. if=%x, cur_held=%d. backtrace: %s\n",myid,origval,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),cur_held(myid),backtrace(btstr)));
++                    tv.state = S_SHARED;
++                    record_backtrace("E->S", laddr);
 +              }
 +          }
 +              }
 +          }
-+      }
-+      else if (get_state(taintval[i])==SHARED) {
-+          taintval[i] = set_value(taintval[i],intersect_locksets(get_value(taintval[i]),cur_held(myid)));
++            break;
++
++        case S_SHARED:
++            tv.value = intersect_locksets (tv.value, cur_held (tid));
 +          if (rw==BX_WRITE || rw==BX_RW) {
 +          if (rw==BX_WRITE || rw==BX_RW) {
-+              taintval[i] = set_state(taintval[i],SHARED_MOD);
-+              DBG(CHECKBOCHS,("%x: Shared(%x)->SM(%x) location %x from shared to shared-mod state. if=%x, cur_held=%d. backtrace: %s\n",myid,origval,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),cur_held(myid),backtrace(btstr)));
-+          } else
-+          if (origval!=taintval[i]) {
-+              DBG(CHECKBOCHS,("%x: Shared(%x)->Shared(%x) location %x from shared to shared-mod state. if=%x, cur_held=%d. backtrace: %s\n",myid,origval,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),cur_held(myid),backtrace(btstr)));
++              tv.state = S_SH_MOD;
++                record_backtrace("S->SM", laddr);
++          } else if (tv.value != orig_tv.value) {
++                record_backtrace("S", laddr);
 +          }
 +          }
-+      }
-+      else if (get_state(taintval[i])==SHARED_MOD) {
-+          taintval[i] = set_value(taintval[i],intersect_locksets(get_value(taintval[i]),cur_held(myid)));
-+          if (origval!=taintval[i]) {
-+              DBG(CHECKBOCHS,("%x: SM(%x)->SM(%x) location %x from exclusive to shared-mod state. if=%x, cur_held=%d. backtrace: %s\n",myid,origval,taintval[i],laddr+i,BX_CPU_THIS_PTR get_IF(),cur_held(myid),backtrace(btstr)));
-+          }
-+      }
++            break;
 +
 +
-+      /* Update the taintval in shadow memory */
-+      if (origval!=taintval[i]) {
-+          try_access = access_linear_taint(laddr+i,1,pl,BX_WRITE,
-+                                           &taintval[i]);
-+          ASSERT(try_access);
++        case S_SH_MOD:
++            tv.value = intersect_locksets (tv.value, cur_held (tid));
++            if (tv.value != orig_tv.value) {
++                record_backtrace("SM", laddr);
++          }
 +      }
 +
 +      /* Warn if needed */
 +      }
 +
 +      /* Warn if needed */
-+      if (get_state(taintval[i])==SHARED_MOD && get_value(taintval[i])==LOCKSET_EMPTY) WRN_ERASER(myid,laddr+i,taintval[i]);
++      if (tv.state == S_SH_MOD
++            && tv.value == LOCKSET_EMPTY
++            && !already_warned(laddr)) {
++            warn(laddr);
++            
++            unsigned v_e_seq;
++            
++            fprintf(g_logfp, "Warning on location %x:\n", laddr);
++
++            for (unsigned i = 0; i < tv.seq; i++)
++                dump_backtrace(laddr, i);
++
++            fprintf(g_logfp, "\n");
++        }
 +    }
 +    }
-+    if (!BX_CPU_THIS_PTR get_IF()) eraser_unlock(INTERRUPT_LOCK); //release the lock that I had earlier acquired (to avoid duplicates)
 +
 +
-+    if (BX_CPU_THIS_PTR curInstruction->isLocked()) {
-+        DBG(LOCKS,("releasing HW_PREFIX_LOCK. laddr=%x, len=%d.\n",laddr,len));
++    // Release interrupt lock. 
++    if (!BX_CPU_THIS_PTR get_IF())
++        eraser_unlock(INTERRUPT_LOCK);
++
++    // Release LOCK prefix lock.
++    if (BX_CPU_THIS_PTR curInstruction->isLocked())
 +      eraser_unlock(HW_PREFIX_LOCK);
 +      eraser_unlock(HW_PREFIX_LOCK);
-+    }
 +}
 +
 +void BX_CPU_C::TT_CommonOps(bxInstruction_c *i) {
 +}
 +
 +void BX_CPU_C::TT_CommonOps(bxInstruction_c *i) {
@@ -1205,12 +1406,12 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
 +      DBG(L1,("setting ignore off for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
 +    }
 +    else if (EAX==REUSE_OP) {
 +      DBG(L1,("setting ignore off for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
 +    }
 +    else if (EAX==REUSE_OP) {
-+        Bit32u taintval = 0;
 +      int pl = 0;     //kernel privileges
 +      DBG(L1,("%x: reusing location %x (%d). ESP=%x\n",myid,EDX,ECX,ESP));
 +      for (int i=0;i<ECX;i++) {
 +      int pl = 0;     //kernel privileges
 +      DBG(L1,("%x: reusing location %x (%d). ESP=%x\n",myid,EDX,ECX,ESP));
 +      for (int i=0;i<ECX;i++) {
-+          int ret = access_linear_taint(EDX+i,1,pl,BX_WRITE,&taintval);
-+          if (ret==0) DBG(L1,("reuse on location %x failed.\n",EDX+i));
++            lockset *tv = access_linear_taint(EDX+i);
++            if (tv != NULL)
++                tv->state = S_VIRGIN;
 +      }
 +    } else if (EAX==DBG_MARK_OP) {
 +        Bit32u taintval = 0;
 +      }
 +    } else if (EAX==DBG_MARK_OP) {
 +        Bit32u taintval = 0;
@@ -1234,11 +1435,39 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
 +    if (g_logfp==NULL) {
 +      DBG (ERR, ("%s(): Error opening checkbochs log %s for writing.\n",__func__,g_logfn)) ;
 +    }
 +    if (g_logfp==NULL) {
 +      DBG (ERR, ("%s(): Error opening checkbochs log %s for writing.\n",__func__,g_logfn)) ;
 +    }
++
++    /* Create temporary file and set name into btdb_fn. */
++    int old_umask = umask(0077);
++    int fd = mkstemp(btdb_fn);
++    if (fd < 0) {
++        DBG(ERR, ("mkstemp: Couldn't create temp file: %s.\n", strerror(errno)));
++        exit(1);
++    }
++    umask(old_umask);
++    close(fd);
++    
++    /* Create database. */
++    btdb = gdbm_open(btdb_fn, 0, GDBM_NEWDB | GDBM_NOLOCK, 0600, NULL);
++    if (btdb == NULL) {
++        DBG(ERR, ("gdbm_open: Couldn't create backtrace database: %s.\n",
++                  gdbm_strerror(gdbm_errno)));
++        exit(1);
++    }
++    unlink(btdb_fn);
 +}
 +}
-diff -urpN bochs-2.1.1.orig/taint/eraser.cc.bak checkbochs-2.1.1/taint/eraser.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/eraser.h checkbochs-2.1.1/taint/eraser.h
---- bochs-2.1.1.orig/taint/eraser.h    1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/eraser.h    2005-06-29 11:19:16.000000000 -0700
++
++void BX_CPU_C::eraser_done_globals(void) 
++{
++    if (global_startup_ignore) {
++        fprintf(g_logfp,
++                "WARNING: Eraser never enabled.  Did you really apply "
++                "pintos/src/misc/checkbochs.patch?\n");
++    }
++}
++
+diff -X ignore -urpNb bochs-2.1.1/taint/eraser.h checkbochs-2.1.1/taint/eraser.h
+--- bochs-2.1.1/taint/eraser.h 1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/eraser.h    2005-07-19 13:59:02.000000000 -0700
 @@ -0,0 +1,37 @@
 +#ifndef __ERASER_H
 +#define __ERASER_H
 @@ -0,0 +1,37 @@
 +#ifndef __ERASER_H
 +#define __ERASER_H
@@ -1273,14 +1502,13 @@ diff -urpN bochs-2.1.1.orig/taint/eraser.h checkbochs-2.1.1/taint/eraser.h
 +    } \
 +} while (0);
 +
 +    } \
 +} while (0);
 +
-+#define INTERRUPT_LOCK 0x1234
-+#define HW_PREFIX_LOCK 0x2345
++#define INTERRUPT_LOCK 0xffff0001
++#define HW_PREFIX_LOCK 0xffff0002
 +
 +#endif
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/eraser.h.bak checkbochs-2.1.1/taint/eraser.h.bak
-diff -urpN bochs-2.1.1.orig/taint/globals.cc checkbochs-2.1.1/taint/globals.cc
---- bochs-2.1.1.orig/taint/globals.cc  1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/globals.cc  2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/globals.cc checkbochs-2.1.1/taint/globals.cc
+--- bochs-2.1.1/taint/globals.cc       1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/globals.cc  2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,13 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 @@ -0,0 +1,13 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
@@ -1295,14 +1523,15 @@ diff -urpN bochs-2.1.1.orig/taint/globals.cc checkbochs-2.1.1/taint/globals.cc
 +bool global_startup_ignore = true ;
 +FILE *g_logfp = NULL ;
 +char g_logfn [128] = "checkbochs.log" ;
 +bool global_startup_ignore = true ;
 +FILE *g_logfp = NULL ;
 +char g_logfn [128] = "checkbochs.log" ;
-diff -urpN bochs-2.1.1.orig/taint/globals.cc.bak checkbochs-2.1.1/taint/globals.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/globals.h checkbochs-2.1.1/taint/globals.h
---- bochs-2.1.1.orig/taint/globals.h   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/globals.h   2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,15 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/globals.h checkbochs-2.1.1/taint/globals.h
+--- bochs-2.1.1/taint/globals.h        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/globals.h   2005-07-19 12:09:53.000000000 -0700
+@@ -0,0 +1,17 @@
 +#ifndef __GLOBALS_H
 +#define __GLOBALS_H
 +
 +#ifndef __GLOBALS_H
 +#define __GLOBALS_H
 +
++#define PHYS_BASE     0xc0000000
++
 +#define MAX_STRLEN 128
 +
 +extern void (*g_access_linear_fptr)(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value);
 +#define MAX_STRLEN 128
 +
 +extern void (*g_access_linear_fptr)(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value);
@@ -1315,10 +1544,9 @@ diff -urpN bochs-2.1.1.orig/taint/globals.h checkbochs-2.1.1/taint/globals.h
 +extern char g_logfn[128] ;
 +
 +#endif
 +extern char g_logfn[128] ;
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/globals.h.bak checkbochs-2.1.1/taint/globals.h.bak
-diff -urpN bochs-2.1.1.orig/taint/hash.cc checkbochs-2.1.1/taint/hash.cc
---- bochs-2.1.1.orig/taint/hash.cc     1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/hash.cc     2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/hash.cc checkbochs-2.1.1/taint/hash.cc
+--- bochs-2.1.1/taint/hash.cc  1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/hash.cc     2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,353 @@
 +#include <stdlib.h>
 +#include <stdio.h>
 @@ -0,0 +1,353 @@
 +#include <stdlib.h>
 +#include <stdio.h>
@@ -1673,10 +1901,9 @@ diff -urpN bochs-2.1.1.orig/taint/hash.cc checkbochs-2.1.1/taint/hash.cc
 +  list_remove (e);
 +}
 +
 +  list_remove (e);
 +}
 +
-diff -urpN bochs-2.1.1.orig/taint/hash.cc.bak checkbochs-2.1.1/taint/hash.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/hash.h checkbochs-2.1.1/taint/hash.h
---- bochs-2.1.1.orig/taint/hash.h      1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/hash.h      2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/hash.h checkbochs-2.1.1/taint/hash.h
+--- bochs-2.1.1/taint/hash.h   1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/hash.h      2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,92 @@
 +#ifndef __HASH_H
 +#define __HASH_H
 @@ -0,0 +1,92 @@
 +#ifndef __HASH_H
 +#define __HASH_H
@@ -1770,10 +1997,9 @@ diff -urpN bochs-2.1.1.orig/taint/hash.h checkbochs-2.1.1/taint/hash.h
 +unsigned hash_int (int);
 +
 +#endif /* lib/kernel/hash.h */
 +unsigned hash_int (int);
 +
 +#endif /* lib/kernel/hash.h */
-diff -urpN bochs-2.1.1.orig/taint/hash.h.bak checkbochs-2.1.1/taint/hash.h.bak
-diff -urpN bochs-2.1.1.orig/taint/list.cc checkbochs-2.1.1/taint/list.cc
---- bochs-2.1.1.orig/taint/list.cc     1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/list.cc     2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/list.cc checkbochs-2.1.1/taint/list.cc
+--- bochs-2.1.1/taint/list.cc  1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/list.cc     2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,471 @@
 +#include <stdlib.h>
 +#include <assert.h>
 @@ -0,0 +1,471 @@
 +#include <stdlib.h>
 +#include <assert.h>
@@ -2246,10 +2472,9 @@ diff -urpN bochs-2.1.1.orig/taint/list.cc checkbochs-2.1.1/taint/list.cc
 +    }
 +  return min;
 +}
 +    }
 +  return min;
 +}
-diff -urpN bochs-2.1.1.orig/taint/list.cc.bak checkbochs-2.1.1/taint/list.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/list.h checkbochs-2.1.1/taint/list.h
---- bochs-2.1.1.orig/taint/list.h      1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/list.h      2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/list.h checkbochs-2.1.1/taint/list.h
+--- bochs-2.1.1/taint/list.h   1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/list.h      2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,171 @@
 +#ifndef __LIB_KERNEL_LIST_H
 +#define __LIB_KERNEL_LIST_H
 @@ -0,0 +1,171 @@
 +#ifndef __LIB_KERNEL_LIST_H
 +#define __LIB_KERNEL_LIST_H
@@ -2422,11 +2647,10 @@ diff -urpN bochs-2.1.1.orig/taint/list.h checkbochs-2.1.1/taint/list.h
 +inline bool
 +is_head (list_elem *elem);
 +#endif /* lib/kernel/list.h */
 +inline bool
 +is_head (list_elem *elem);
 +#endif /* lib/kernel/list.h */
-diff -urpN bochs-2.1.1.orig/taint/list.h.bak checkbochs-2.1.1/taint/list.h.bak
-diff -urpN bochs-2.1.1.orig/taint/lockset.cc checkbochs-2.1.1/taint/lockset.cc
---- bochs-2.1.1.orig/taint/lockset.cc  1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/lockset.cc  2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,635 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/lockset.cc checkbochs-2.1.1/taint/lockset.cc
+--- bochs-2.1.1/taint/lockset.cc       1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/lockset.cc  2005-07-19 22:38:45.000000000 -0700
+@@ -0,0 +1,647 @@
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <assert.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <assert.h>
@@ -2938,6 +3162,18 @@ diff -urpN bochs-2.1.1.orig/taint/lockset.cc checkbochs-2.1.1/taint/lockset.cc
 +    return ret_index;
 +}
 +
 +    return ret_index;
 +}
 +
++void lockset_dump(locksetidx_t idx, Bit32u *locks, int cnt) 
++{
++    lockvector_t *vec = index_table[idx];
++    while (vec != NULL && cnt-- > 0) {
++        *locks++ = vec->lockaddress;
++        vec = vec->next;
++    }
++    while (cnt-- > 0) {
++        *locks++ = 0;
++    }
++}
++
 +typedef struct locks_held {
 +    unsigned threadId;
 +    locksetidx_t locks_held;
 +typedef struct locks_held {
 +    unsigned threadId;
 +    locksetidx_t locks_held;
@@ -3062,26 +3298,27 @@ diff -urpN bochs-2.1.1.orig/taint/lockset.cc checkbochs-2.1.1/taint/lockset.cc
 +    }
 +    return false;
 +}
 +    }
 +    return false;
 +}
-diff -urpN bochs-2.1.1.orig/taint/lockset.cc.bak checkbochs-2.1.1/taint/lockset.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/lockset.h checkbochs-2.1.1/taint/lockset.h
---- bochs-2.1.1.orig/taint/lockset.h   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/lockset.h   2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,32 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/lockset.h checkbochs-2.1.1/taint/lockset.h
+--- bochs-2.1.1/taint/lockset.h        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/lockset.h   2005-07-19 13:40:21.000000000 -0700
+@@ -0,0 +1,35 @@
 +#ifndef __LOCKSET_H
 +#define __LOCKSET_H
 +
 +#define LOCKSET_EMPTY 0
 +
 +#ifndef __LOCKSET_H
 +#define __LOCKSET_H
 +
 +#define LOCKSET_EMPTY 0
 +
-+#define VIRGIN 0x0
-+#define EXCLUSIVE     0x40000000
-+#define SHARED                0x80000000
-+#define SHARED_MOD    0xc0000000
++/* States. */
++#define S_VIRGIN        0
++#define S_EXCLUSIVE     1
++#define S_SHARED        2
++#define S_SH_MOD        3
 +
 +
-+#define get_state(x) (x&0xc0000000)
-+#define set_state(x,s) ((x&0x3fffffff)|s)
-+
-+#define get_value(x) (x&0x3fffffff)
-+#define set_value(x,v) ((x&0xc0000000)|(v&0x3fffffff))
++struct lockset 
++  {
++    unsigned int state : 2;
++    unsigned int seq : 10;
++    unsigned int value : 20;
++  };
 +
 +typedef unsigned int address_t;
 +typedef unsigned long locksetidx_t;
 +
 +typedef unsigned int address_t;
 +typedef unsigned long locksetidx_t;
@@ -3091,6 +3328,7 @@ diff -urpN bochs-2.1.1.orig/taint/lockset.h checkbochs-2.1.1/taint/lockset.h
 +locksetidx_t remove_lock(locksetidx_t index, address_t newlock);
 +locksetidx_t intersect_locksets(locksetidx_t index1, locksetidx_t index2);
 +bool belongs(locksetidx_t index, address_t lock);
 +locksetidx_t remove_lock(locksetidx_t index, address_t newlock);
 +locksetidx_t intersect_locksets(locksetidx_t index1, locksetidx_t index2);
 +bool belongs(locksetidx_t index, address_t lock);
++void lockset_dump(locksetidx_t, Bit32u locks[], int cnt);
 +
 +locksetidx_t cur_held(unsigned threadId);
 +void update_lockset(unsigned threadId, locksetidx_t lockset);
 +
 +locksetidx_t cur_held(unsigned threadId);
 +void update_lockset(unsigned threadId, locksetidx_t lockset);
@@ -3099,10 +3337,9 @@ diff -urpN bochs-2.1.1.orig/taint/lockset.h checkbochs-2.1.1/taint/lockset.h
 +bool ignore_on(unsigned threadId);
 +
 +#endif
 +bool ignore_on(unsigned threadId);
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/lockset.h.bak checkbochs-2.1.1/taint/lockset.h.bak
-diff -urpN bochs-2.1.1.orig/taint/main.c checkbochs-2.1.1/taint/main.c
---- bochs-2.1.1.orig/taint/main.c      1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/main.c      2005-06-16 18:14:07.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/main.c checkbochs-2.1.1/taint/main.c
+--- bochs-2.1.1/taint/main.c   1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/main.c      2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,32 @@
 +#include "lockset.h"
 +
 @@ -0,0 +1,32 @@
 +#include "lockset.h"
 +
@@ -3136,9 +3373,9 @@ diff -urpN bochs-2.1.1.orig/taint/main.c checkbochs-2.1.1/taint/main.c
 +    printf("i12 = %d, i21 = %d, i123=%d, i312=%d, i321=%d, i321m2=%d, i312m2=%d.\n",i12,i21,i123,i312,i321,i321m2,i312m2);
 +    printf("i312i123 = %d, i312i21 = %d, i312i1=%d, i32i1=%d.\n",i312i123,i312i21,i312i1,i32i1);
 +}
 +    printf("i12 = %d, i21 = %d, i123=%d, i312=%d, i321=%d, i321m2=%d, i312m2=%d.\n",i12,i21,i123,i312,i321,i321m2,i312m2);
 +    printf("i312i123 = %d, i312i21 = %d, i312i1=%d, i32i1=%d.\n",i312i123,i312i21,i312i1,i32i1);
 +}
-diff -urpN bochs-2.1.1.orig/taint/memory.cc checkbochs-2.1.1/taint/memory.cc
---- bochs-2.1.1.orig/taint/memory.cc   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/memory.cc   2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/memory.cc checkbochs-2.1.1/taint/memory.cc
+--- bochs-2.1.1/taint/memory.cc        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/memory.cc   2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,360 @@
 +
 +#include "bochs.h"
 @@ -0,0 +1,360 @@
 +
 +#include "bochs.h"
@@ -3500,10 +3737,9 @@ diff -urpN bochs-2.1.1.orig/taint/memory.cc checkbochs-2.1.1/taint/memory.cc
 +    return;
 +    }
 +}
 +    return;
 +    }
 +}
-diff -urpN bochs-2.1.1.orig/taint/memory.cc.bak checkbochs-2.1.1/taint/memory.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/mydebug.h checkbochs-2.1.1/taint/mydebug.h
---- bochs-2.1.1.orig/taint/mydebug.h   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/mydebug.h   2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/mydebug.h checkbochs-2.1.1/taint/mydebug.h
+--- bochs-2.1.1/taint/mydebug.h        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/mydebug.h   2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,28 @@
 +#ifndef __MYDEBUG_H
 +#define __MYDEBUG_H
 @@ -0,0 +1,28 @@
 +#ifndef __MYDEBUG_H
 +#define __MYDEBUG_H
@@ -3533,11 +3769,10 @@ diff -urpN bochs-2.1.1.orig/taint/mydebug.h checkbochs-2.1.1/taint/mydebug.h
 +      }
 +
 +#endif
 +      }
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/mydebug.h.bak checkbochs-2.1.1/taint/mydebug.h.bak
-diff -urpN bochs-2.1.1.orig/taint/paging.cc checkbochs-2.1.1/taint/paging.cc
---- bochs-2.1.1.orig/taint/paging.cc   1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/paging.cc   2005-06-29 11:19:16.000000000 -0700
-@@ -0,0 +1,241 @@
+diff -X ignore -urpNb bochs-2.1.1/taint/paging.cc checkbochs-2.1.1/taint/paging.cc
+--- bochs-2.1.1/taint/paging.cc        1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/paging.cc   2005-07-19 14:40:31.000000000 -0700
+@@ -0,0 +1,90 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 +#define LOG_THIS BX_CPU_THIS_PTR
@@ -3616,173 +3851,21 @@ diff -urpN bochs-2.1.1.orig/taint/paging.cc checkbochs-2.1.1/taint/paging.cc
 +}
 +
 +
 +}
 +
 +
-+  int BX_CPP_AttrRegparmN(3)
-+BX_CPU_C::access_linear_taint(bx_address laddr, unsigned length, unsigned pl,
-+    unsigned rw, void *taint_value)
++lockset *
++BX_CPU_C::access_linear_taint(bx_address laddr)
 +{
 +{
-+  Bit32u pageOffset;
-+  unsigned xlate_rw;
-+  int try_access;
-+
-+  assert(length==1);
-+  ASSERT(rw==BX_READ || get_value(*(Bit32u*)taint_value)<2 || get_state(*(Bit32u*)taint_value));
-+  if (rw==BX_RW) {
-+    xlate_rw = BX_RW;
-+    rw = BX_READ;
-+  }
-+  else {
-+    xlate_rw = rw;
-+  }
-+
-+  pageOffset = laddr & 0x00000fff;
-+
-+  if (BX_CPU_THIS_PTR cr0.pg) {
-+    /* check for reference across multiple pages */
-+    if ( (pageOffset + length) <= 4096 ) {
-+      // Access within single page.
-+      try_access = taint_dtranslate_linear(laddr, pl, xlate_rw);
-+      if (try_access==-1) return 0;
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = try_access;
-+      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
++    if (!BX_CPU_THIS_PTR cr0.pg)
++        return NULL;
 +
 +
-+      if (rw == BX_READ) {
-+        BX_INSTR_LIN_READ(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, taint_value);
-+        }
-+      else {
-+        BX_INSTR_LIN_WRITE(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, taint_value);
-+        }
-+      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
-+      }
-+    else {
-+      try_access = taint_dtranslate_linear(laddr, pl, xlate_rw);
-+      if (try_access==-1) return 0;
-+      // access across 2 pages
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = try_access;
-+      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
-+      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
-+          BX_CPU_THIS_PTR address_xlation.taint_len1;
-+      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
-+      try_access = taint_dtranslate_linear(laddr + BX_CPU_THIS_PTR address_xlation.taint_len1, pl, xlate_rw);
-+      if (try_access==-1) return 0;
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress2 = try_access;
-+
-+#ifdef BX_LITTLE_ENDIAN
-+      if (rw == BX_READ) {
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+                             BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+                             BX_CPU_THIS_PTR address_xlation.taint_len2,
-+                             ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
-+        }
-+      else {
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+                              BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+                              BX_CPU_THIS_PTR address_xlation.taint_len2,
-+                              ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
-+        }
-+
-+#else // BX_BIG_ENDIAN
-+      if (rw == BX_READ) {
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+                             BX_CPU_THIS_PTR address_xlation.taint_len1,
-+                             ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+                             BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
-+        }
-+      else {
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+                              BX_CPU_THIS_PTR address_xlation.taint_len1,
-+                              ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+                              BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
-+        }
-+#endif
-+
-+      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
-+      }
-+    }
-+
-+  else {
-+    // Paging off.
-+    if ( (pageOffset + length) <= 4096 ) {
-+      // Access within single page.
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
-+      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
-+      if (rw == BX_READ) {
-+
-+        // Let access fall through to the following for this iteration.
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, laddr, length, taint_value);
-+        }
-+      else { // Write
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, laddr, length, taint_value);
-+        }
-+      }
-+    else {
-+      // Access spans two pages.
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
-+      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
-+      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
-+          BX_CPU_THIS_PTR address_xlation.taint_len1;
-+      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
-+      BX_CPU_THIS_PTR address_xlation.taint_paddress2 = laddr +
-+          BX_CPU_THIS_PTR address_xlation.taint_len1;
-+
-+#ifdef BX_LITTLE_ENDIAN
-+      if (rw == BX_READ) {
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+            BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+            BX_CPU_THIS_PTR address_xlation.taint_len2,
-+            ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
-+        }
-+      else {
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+            BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+            BX_CPU_THIS_PTR address_xlation.taint_len2,
-+            ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
-+        }
-+
-+#else // BX_BIG_ENDIAN
-+      if (rw == BX_READ) {
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+            BX_CPU_THIS_PTR address_xlation.taint_len1,
-+            ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
-+        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+            BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
-+        }
-+      else {
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
-+            BX_CPU_THIS_PTR address_xlation.taint_len1,
-+            ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
-+        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
-+            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
-+            BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
-+        }
-+#endif
-+      }
-+    //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
-+    }
-+    return 1;
++    BX_MEM_C *m = BX_CPU_THIS_PTR mem;
++    Bit32u paddr = laddr - PHYS_BASE;
++    return paddr < m->len ? (lockset *) &m->taint_vector[paddr] : NULL;
 +}
 +
 +#endif
 +}
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/paging.cc.bak checkbochs-2.1.1/taint/paging.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/silent_access.cc checkbochs-2.1.1/taint/silent_access.cc
---- bochs-2.1.1.orig/taint/silent_access.cc    1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/silent_access.cc    2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/silent_access.cc checkbochs-2.1.1/taint/silent_access.cc
+--- bochs-2.1.1/taint/silent_access.cc 1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/silent_access.cc    2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,210 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 @@ -0,0 +1,210 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
@@ -3994,10 +4077,9 @@ diff -urpN bochs-2.1.1.orig/taint/silent_access.cc checkbochs-2.1.1/taint/silent
 +  if (!ret) return 0;
 +  goto accessOK;
 +}
 +  if (!ret) return 0;
 +  goto accessOK;
 +}
-diff -urpN bochs-2.1.1.orig/taint/silent_access.cc.bak checkbochs-2.1.1/taint/silent_access.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/silent_paging.cc checkbochs-2.1.1/taint/silent_paging.cc
---- bochs-2.1.1.orig/taint/silent_paging.cc    1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/silent_paging.cc    2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/silent_paging.cc checkbochs-2.1.1/taint/silent_paging.cc
+--- bochs-2.1.1/taint/silent_paging.cc 1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/silent_paging.cc    2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,175 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 @@ -0,0 +1,175 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
@@ -4174,10 +4256,9 @@ diff -urpN bochs-2.1.1.orig/taint/silent_paging.cc checkbochs-2.1.1/taint/silent
 +}
 +
 +#endif
 +}
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/silent_paging.cc.bak checkbochs-2.1.1/taint/silent_paging.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/taint_type.cc checkbochs-2.1.1/taint/taint_type.cc
---- bochs-2.1.1.orig/taint/taint_type.cc       1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/taint_type.cc       2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/taint_type.cc checkbochs-2.1.1/taint/taint_type.cc
+--- bochs-2.1.1/taint/taint_type.cc    1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/taint_type.cc       2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,13 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
 @@ -0,0 +1,13 @@
 +#define NEED_CPU_REG_SHORTCUTS 1
 +#include "bochs.h"
@@ -4192,10 +4273,9 @@ diff -urpN bochs-2.1.1.orig/taint/taint_type.cc checkbochs-2.1.1/taint/taint_typ
 +      //g_access_linear_fptr = &(BX_CPU_C::eraser_access_linear);
 +    }
 +}
 +      //g_access_linear_fptr = &(BX_CPU_C::eraser_access_linear);
 +    }
 +}
-diff -urpN bochs-2.1.1.orig/taint/taint_type.cc.bak checkbochs-2.1.1/taint/taint_type.cc.bak
-diff -urpN bochs-2.1.1.orig/taint/taint_type.h checkbochs-2.1.1/taint/taint_type.h
---- bochs-2.1.1.orig/taint/taint_type.h        1969-12-31 16:00:00.000000000 -0800
-+++ checkbochs-2.1.1/taint/taint_type.h        2005-06-29 11:19:16.000000000 -0700
+diff -X ignore -urpNb bochs-2.1.1/taint/taint_type.h checkbochs-2.1.1/taint/taint_type.h
+--- bochs-2.1.1/taint/taint_type.h     1969-12-31 16:00:00.000000000 -0800
++++ checkbochs-2.1.1/taint/taint_type.h        2005-07-02 17:25:48.000000000 -0700
 @@ -0,0 +1,8 @@
 +#ifndef __TAINT_TYPE_H
 +#define __TAINT_TYPE_H
 @@ -0,0 +1,8 @@
 +#ifndef __TAINT_TYPE_H
 +#define __TAINT_TYPE_H
@@ -4205,4 +4285,3 @@ diff -urpN bochs-2.1.1.orig/taint/taint_type.h checkbochs-2.1.1/taint/taint_type
 +void assign_taint_functions(char *taint_type);
 +
 +#endif
 +void assign_taint_functions(char *taint_type);
 +
 +#endif
-diff -urpN bochs-2.1.1.orig/taint/taint_type.h.bak checkbochs-2.1.1/taint/taint_type.h.bak
index e93d64858c3d6b15b0070accf84eb330dacf6d23..8dc7482238b92cbaa13dbc73608dcbbc067c53bc 100644 (file)
@@ -16,6 +16,8 @@ are provided:
 
        bochs-2.1.1-checkbochs.patch:
                Implements Eraser-like lock checking support.
 
        bochs-2.1.1-checkbochs.patch:
                Implements Eraser-like lock checking support.
+               (This patch is provided by Sorav Bansal, with
+               modifications by Ben Pfaff.)
 
 On Solaris, we recommend applying all the patches for use with Pintos.
 On other host OSes, do not apply the Solaris patch.
 
 On Solaris, we recommend applying all the patches for use with Pintos.
 On other host OSes, do not apply the Solaris patch.
@@ -46,14 +48,18 @@ Bourne shell, and that PATCHDIR is set to the directory that contains
 the Bochs patches.
 
 # Setup.
 the Bochs patches.
 
 # Setup.
+PATCHDIR=$HOME/cs140/eraser/src/misc
 PREFIX="/usr/class/cs140/`uname -m`"
 BINDIR=$PREFIX/bin
 CFGOPTS="--with-x --with-x11 --with-term --with-nogui --prefix=$PREFIX"
 
 # Fetch sources.
 PREFIX="/usr/class/cs140/`uname -m`"
 BINDIR=$PREFIX/bin
 CFGOPTS="--with-x --with-x11 --with-term --with-nogui --prefix=$PREFIX"
 
 # Fetch sources.
-wget http://easynews.dl.sourceforge.net/sourceforge/bochs/bochs-2.1.1.tar.gz
+if test ! -e bochs-2.1.1.tar.gz; then
+       wget http://easynews.dl.sourceforge.net/sourceforge/bochs/bochs-2.1.1.tar.gz
+fi
 
 # Apply patches.
 
 # Apply patches.
+rm -rf bochs-2.1.1 checkbochs-2.1.1
 tar xzf bochs-2.1.1.tar.gz
 (cd bochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-tty-stdout.patch)
 (cd bochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-jitter.patch)
 tar xzf bochs-2.1.1.tar.gz
 (cd bochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-tty-stdout.patch)
 (cd bochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-jitter.patch)
@@ -65,22 +71,21 @@ cp -pR bochs-2.1.1 checkbochs-2.1.1
 (cd checkbochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-checkbochs.patch)
 
 # Build and install Bochs variants.
 (cd checkbochs-2.1.1 && patch -p1 < $PATCHDIR/bochs-2.1.1-checkbochs.patch)
 
 # Build and install Bochs variants.
-(cd bochs-2.1.1 && rm -rf plain && mkdir plain && cd plain && 
+(cd bochs-2.1.1 && rm -rf _plain && mkdir _plain && cd _plain && 
  ../configure $CFGOPTS && make && make install)
  ../configure $CFGOPTS && make && make install)
-(cd bochs-2.1.1 && rm -rf with-gdb mkdir with-gdb && cd with-gdb && 
- ../configure --enable-gdb-stub $CFGOPTS && 
- make && cp bochs $BINDIR/bochs-gdb)
-(cd bochs-2.1.1 && rm -rf with-dbg && mkdir with-dbg && cd with-dbg && 
- ../configure --enable-debugger $CFGOPTS &&
- make && cp bochs $BINDIR/bochs-dbg)
+(cd bochs-2.1.1 && rm -rf _gdb && mkdir _gdb && cd _gdb && 
+ ../configure --enable-gdb-stub $CFGOPTS && make && cp bochs $BINDIR/bochs-gdb)
+(cd bochs-2.1.1 && rm -rf _dbg && mkdir _dbg && cd _dbg && 
+ ../configure --enable-debugger $CFGOPTS && make && cp bochs $BINDIR/bochs-dbg)
 
 # Build and install Checkbochs variants.
 
 # Build and install Checkbochs variants.
-(cd checkbochs-2.1.1 && rm -rf plain && mkdir plain && cd plain &&
+(cd checkbochs-2.1.1 && autoconf)
+(cd checkbochs-2.1.1 && rm -rf _plain && mkdir _plain && cd _plain &&
  ../configure $CFGOPTS && make && cp bochs $BINDIR/checkbochs)
  ../configure $CFGOPTS && make && cp bochs $BINDIR/checkbochs)
-(cd checkbochs-2.1.1 && rm -rf with-gdb && mkdir with-gdb && cd with-gdb && 
- ../configure --enable-gdb-stub $CFGOPTS && 
+(cd checkbochs-2.1.1 && rm -rf _gdb && mkdir _gdb && cd _gdb && 
+ ../configure --enable-gdb-stub $CFGOPTS &&
  make && cp bochs $BINDIR/checkbochs-gdb)
  make && cp bochs $BINDIR/checkbochs-gdb)
-(cd checkbochs-2.1.1 && rm -rf with-dbg && mkdir with-dbg && cd with-dbg && 
+(cd checkbochs-2.1.1 && rm -rf _dbg && mkdir _dbg && cd _dbg && 
  ../configure --enable-debugger $CFGOPTS &&
  make && cp bochs $BINDIR/checkbochs-dbg)
 
  ../configure --enable-debugger $CFGOPTS &&
  make && cp bochs $BINDIR/checkbochs-dbg)
 
diff --git a/src/misc/checkbochs.README b/src/misc/checkbochs.README
new file mode 100644 (file)
index 0000000..e2eeda3
--- /dev/null
@@ -0,0 +1,7 @@
+The patch in checkbochs.patch must be applied to Pintos before
+Checkbochs will be useful.  To apply it, `cd' to pintos/src and type
+       patch -p2 < misc/checkbochs.patch
+
+Checkbochs and this patch were written by Sorav Bansal
+<sbansal@stanford.edu>.  They have been modified by Ben Pfaff
+<blp@cs.stanford.edu>.
index 21474bad39d1666ad55e34bac47a835794f65da2..f0b7fb6b68ee0ef7e07470f4528a3fb2ff12250f 100644 (file)
@@ -1,10 +1,3 @@
-This patch must be applied to Pintos before Checkbochs may be usefully
-applied to it.  To apply it, `cd' to pintos/src and type
-       patch -p2 < misc/checkbochs.patch
-
-Written by Sorav Bansal <sbansal@stanford.edu>.
-Modified by Ben Pfaff <blp@cs.stanford.edu>.
-
 diff -X ignore -urpN pintos.orig/src/lib/debug.h pintos.eraser/src/lib/debug.h
 --- pintos.orig/src/lib/debug.h        2005-06-18 20:20:49.000000000 -0700
 +++ pintos.eraser/src/lib/debug.h      2005-06-29 22:38:01.000000000 -0700
 diff -X ignore -urpN pintos.orig/src/lib/debug.h pintos.eraser/src/lib/debug.h
 --- pintos.orig/src/lib/debug.h        2005-06-18 20:20:49.000000000 -0700
 +++ pintos.eraser/src/lib/debug.h      2005-06-29 22:38:01.000000000 -0700