From: Ben Pfaff Date: Sun, 3 Jul 2005 22:41:47 +0000 (+0000) Subject: Basic Eraser support. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=commitdiff_plain;h=14c61e5782a8e8725de21e3448d902ad2d14d55b Basic Eraser support. --- diff --git a/src/misc/bochs-2.1.1-bigendian.patch b/src/misc/bochs-2.1.1-bigendian.patch new file mode 100644 index 0000000..ef75b3f --- /dev/null +++ b/src/misc/bochs-2.1.1-bigendian.patch @@ -0,0 +1,83 @@ +The third patch makes the gdb stubs work on Solaris/Sparc, by doing +proper byteswapping. It should be harmless elsewhere. + +diff -urp orig/bochs-2.1.1/gdbstub.cc bochs-2.1.1/gdbstub.cc +--- orig/bochs-2.1.1/gdbstub.cc 2004-02-11 14:28:41.000000000 -0800 ++++ bochs-2.1.1/gdbstub.cc 2004-09-13 16:41:59.652988000 -0700 +@@ -474,11 +475,13 @@ static void debug_loop(void) + case 'P': + { + int reg; +- int value; ++ Bit8u vbits[4]; ++ Bit32u value; + char* ebuf; + + reg = strtoul(&buffer[1], &ebuf, 16); +- value = ntohl(strtoul(ebuf + 1, &ebuf, 16)); ++ hex2mem(ebuf + 1, vbits, sizeof value); ++ ReadHostDWordFromLittleEndian(vbits, value); + + BX_INFO (("reg %d set to %x", reg, value)); + +@@ -527,35 +530,36 @@ static void debug_loop(void) + } + + case 'g': +- registers[0] = EAX; +- registers[1] = ECX; +- registers[2] = EDX; +- registers[3] = EBX; +- registers[4] = ESP; +- registers[5] = EBP; +- registers[6] = ESI; +- registers[7] = EDI; ++ WriteHostDWordToLittleEndian(registers + 0, EAX); ++ WriteHostDWordToLittleEndian(registers + 1, ECX); ++ WriteHostDWordToLittleEndian(registers + 2, EDX); ++ WriteHostDWordToLittleEndian(registers + 3, EBX); ++ WriteHostDWordToLittleEndian(registers + 4, ESP); ++ WriteHostDWordToLittleEndian(registers + 5, EBP); ++ WriteHostDWordToLittleEndian(registers + 6, ESI); ++ WriteHostDWordToLittleEndian(registers + 7, EDI); + if (last_stop_reason == GDBSTUB_EXECUTION_BREAKPOINT) + { +- registers[8] = EIP + 1; ++ WriteHostDWordToLittleEndian(registers + 8, EIP + 1); + } + else + { +- registers[8] = EIP; ++ WriteHostDWordToLittleEndian(registers + 8, EIP); + } +- registers[9] = BX_CPU_THIS_PTR read_eflags(); +- registers[10] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; +- registers[11] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value; +- registers[12] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value; +- registers[13] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value; +- registers[14] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value; +- registers[15] = +- BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value; ++ WriteHostDWordToLittleEndian(registers + 9, ++ BX_CPU_THIS_PTR read_eflags()); ++ WriteHostDWordToLittleEndian(registers + 10, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); ++ WriteHostDWordToLittleEndian(registers + 11, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value); ++ WriteHostDWordToLittleEndian(registers + 12, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); ++ WriteHostDWordToLittleEndian(registers + 13, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); ++ WriteHostDWordToLittleEndian(registers + 14, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); ++ WriteHostDWordToLittleEndian(registers + 15, ++ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); + mem2hex((char *)registers, obuf, NUMREGSBYTES); + put_reply(obuf); + break; + diff --git a/src/misc/bochs-2.1.1-checkbochs.patch b/src/misc/bochs-2.1.1-checkbochs.patch new file mode 100644 index 0000000..17a869b --- /dev/null +++ b/src/misc/bochs-2.1.1-checkbochs.patch @@ -0,0 +1,4208 @@ +This patch provides Eraser-like lock set checking for Bochs. +See the Pintos documentation for more information. + +This patch is provided by Sorav Bansal . + +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 +@@ -177,11 +177,11 @@ all: @PRIMARY_TARGET@ @PLUGIN_TARGET@ bx + @EXTERNAL_DEPENDENCY@ + + bochs@EXE@: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \ +- cpu/libcpu.a memory/libmemory.a gui/libgui.a \ ++ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \ + @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \ + $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@ + @LINK@ -export-dynamic $(BX_OBJS) $(SIMX86_OBJS) \ +- iodev/libiodev.a cpu/libcpu.a memory/libmemory.a gui/libgui.a \ ++ iodev/libiodev.a cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \ + @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ \ + @NONPLUGIN_GUI_LINK_OPTS@ \ +@@ -195,19 +195,19 @@ bochs@EXE@: @IODEV_LIB_VAR@ @DEBUGGER_VA + # libtool. This creates a .DEF file, and exports file, an import library, + # and then links bochs.exe with the exports file. + .win32_dll_plugin_target: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \ +- cpu/libcpu.a memory/libmemory.a gui/libgui.a \ ++ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \ + @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \ + $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@ + $(DLLTOOL) --export-all-symbols --output-def bochs.def \ + $(BX_OBJS) $(SIMX86_OBJS) \ +- @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a \ ++ @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \ + @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ + $(DLLTOOL) --dllname bochs.exe --def bochs.def --output-lib dllexports.a + $(DLLTOOL) --dllname bochs.exe --output-exp bochs.exp --def bochs.def + $(CXX) -o bochs.exe $(CXXFLAGS) $(LDFLAGS) -export-dynamic \ + $(BX_OBJS) bochs.exp $(SIMX86_OBJS) \ +- @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a \ ++ @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \ + @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \ + @GDBSTUB_VAR@ @FPU_VAR@ \ + $(GUI_LINK_OPTS) \ +@@ -274,6 +274,11 @@ gui/libgui.a:: + $(MAKE) $(MDEFINES) libgui.a + @CD_UP_ONE@ + ++taint/libtaint.a:: ++ cd taint @COMMAND_SEPARATOR@ ++ $(MAKE) $(MDEFINES) libtaint.a ++ @CD_UP_ONE@ ++ + disasm/libdisasm.a:: + cd disasm @COMMAND_SEPARATOR@ + $(MAKE) $(MDEFINES) libdisasm.a +@@ -503,6 +508,9 @@ all-clean: clean + cd fpu @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_ONE@ ++ cd taint @COMMAND_SEPARATOR@ ++ $(MAKE) clean ++ @CD_UP_ONE@ + cd doc/docbook @COMMAND_SEPARATOR@ + $(MAKE) clean + @CD_UP_TWO@ +@@ -538,6 +546,9 @@ dist-clean: local-dist-clean + cd fpu @COMMAND_SEPARATOR@ + $(MAKE) dist-clean + @CD_UP_ONE@ ++ cd taint @COMMAND_SEPARATOR@ ++ $(MAKE) dist-clean ++ @CD_UP_ONE@ + 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 +@@ -671,6 +671,7 @@ typedef struct BOCHSAPI { + bx_gdbstub_t gdbstub; + bx_param_enum_c *Osel_config; + bx_param_enum_c *Osel_displaylib; ++ bx_param_enum_c *Otaint_type ; + } 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 + 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 @@ + #include "bochs.h" + #define LOG_THIS BX_CPU_THIS_PTR + ++#include "taint/globals.h" ++#include "taint/mydebug.h" ++ + #if BX_USE_CPU_SMF + #define this (BX_CPU(0)) + #endif +@@ -111,7 +114,9 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun + bxInstruction_c iStorage BX_CPP_AlignN(32); + bxInstruction_c *i = &iStorage; + +- BxExecutePtr_t execute; ++ BxExecutePtr_t execute, taint_execute ; ++ ++ BX_CPU_THIS_PTR curInstruction = i ; + + #if BX_DEBUGGER + BX_CPU_THIS_PTR break_point = 0; +@@ -209,6 +214,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. ++ ++ taint_execute = i->taint_execute ; ++ if (!taint_execute) taint_execute = &BX_CPU_C::NOP ; ++ + if (resolveModRM) { + BX_CPU_CALL_METHODR(resolveModRM, (i)); + } +@@ -281,6 +290,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun + } + #endif + execute = i->execute; // fetch as soon as possible for speculation. ++ ++ taint_execute = i->taint_execute ; ++ if (!taint_execute) taint_execute = &BX_CPU_C::NOP ; ++ + if (resolveModRM) { + BX_CPU_CALL_METHODR(resolveModRM, (i)); + } +@@ -303,6 +316,7 @@ 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_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: + if (i->as64L()) { + if (RCX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + RCX --; + } + if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done; +@@ -335,6 +350,7 @@ repeat_loop: + if (i->as32L()) { + if (ECX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + ECX --; + } + if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done; +@@ -345,6 +361,7 @@ repeat_loop: + else { + if (CX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + CX --; + } + if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done; +@@ -358,6 +375,7 @@ repeat_loop: + if (i->as64L()) { + if (RCX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + RCX --; + } + if (RCX == 0) goto repeat_done; +@@ -368,6 +386,7 @@ repeat_loop: + if (i->as32L()) { + if (ECX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + ECX --; + } + if (ECX == 0) goto repeat_done; +@@ -376,6 +395,7 @@ repeat_loop: + else { // 16bit addrsize + if (CX != 0) { + BX_CPU_CALL_METHOD(execute, (i)); ++ BX_CPU_CALL_METHOD(taint_execute, (i)); + CX --; + } + if (CX == 0) goto repeat_done; +@@ -865,6 +885,17 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; / + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b); + } + ++void ++BX_CPU_C::panic(const char *fmt, ...) ++{ ++ va_list arg; ++ ++ printf("backtrace: %s.\n",backtrace(btstr)); ++ ++ va_start(arg,fmt); ++ logfunctions::panic(fmt,arg); ++ va_end(arg); ++} + + #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 +@@ -739,9 +739,11 @@ public: + #if BX_USE_CPU_SMF + void (*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + void (*execute)(bxInstruction_c *); ++ void (*taint_execute)(bxInstruction_c *); + #else + void (BX_CPU_C::*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + void (BX_CPU_C::*execute)(bxInstruction_c *); ++ void (BX_CPU_C::*taint_execute)(bxInstruction_c *); + #endif + + // 26..23 ilen (0..15). Leave this one on top so no mask is needed. +@@ -821,6 +823,11 @@ public: + #endif + }; + ++ /* sorav: to check if the instruction has a lock prefix */ ++ bool locked; //whether lock prefix is held ++ BX_CPP_INLINE void setLocked(bool val) { locked = val; } ++ BX_CPP_INLINE bool isLocked(void) { return locked ; } ++ + BX_CPP_INLINE unsigned opcodeReg() { + // The opcodeReg form (low 3 bits of the opcode byte (extended + // by REX.B on x86-64) can be accessed by IxForm or IqForm. They +@@ -1428,8 +1435,18 @@ union { + // is greated than 2 (the maximum possible for + // normal cases) it is a native pointer and is used + // for a direct write access. ++ ++ /* taint fields */ ++ Bit32u taint_paddress1; ++ Bit32u taint_paddress2; ++ Bit32u taint_len1; ++ Bit32u taint_len2; ++ bx_ptr_equiv_t taint_pages; ++ + } address_xlation; + ++ bxInstruction_c *curInstruction ; ++ + #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 { + #if BX_SUPPORT_APIC + bx_local_apic_c local_apic; + #endif ++ ++ /* taint functions */ ++ void panic(const char *fmt, ...); ++ 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); ++//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 char *backtrace(char *s); ++ 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_init_globals (void) ; ++ + }; + + +@@ -3299,6 +3343,7 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8) + #define BxGroup14 BxGroupN + #define BxGroup15 BxGroupN + #define BxGroup16 BxGroupN ++#define BxGroupTaint BxGroupN + + #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 +@@ -251,6 +251,12 @@ void BX_CPU_C::CPUID(bxInstruction_c *i) + RDX = get_std_cpuid_features (); + break; + ++ case 3: /*added by sorav */ ++ RBX = 0x6e696154; // "Tain" ++ RDX = 0x49646574; // "tedI" ++ RCX = 0x6c65746e; // "ntel" ++ break; ++ + #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 +@@ -29,6 +29,8 @@ + #include "bochs.h" + #define LOG_THIS BX_CPU_THIS_PTR + ++#include "taint/eraser.h" ++ + + /////////////////////////// + // prefix bytes +@@ -156,6 +158,7 @@ typedef struct BxOpcodeInfo_t { + Bit16u Attr; + BxExecutePtr_t ExecutePtr; + struct BxOpcodeInfo_t *AnotherArray; ++ BxExecutePtr_t TaintExecutePtr ; + } BxOpcodeInfo_t; + + +@@ -458,6 +461,17 @@ static BxOpcodeInfo_t BxOpcodeInfoG16[8] + /* 7 */ { 0, &BX_CPU_C::BxError } + }; + ++BxOpcodeInfo_t BxOpcodeInfoGTaint[8] = { ++ /* 0 */ { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_TaintSaveRegs}, ++ /* 1 */ { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_TaintRestoreRegs}, ++ /* 2 */ { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_Lock /*&BX_CPU_C::TT_RegionTaint*/}, ++ /* 3 */ { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_Unlock /*&BX_CPU_C::TT_RegionCheck*/}, ++ /* 4 */ { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_CommonOps }, ++ /* 5 */ { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Taint*/ }, ++ /* 6 */ { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Untaint*/ }, ++ /* 7 */ { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Check*/} ++ }; ++ + + /* ************************** */ + /* 512 entries for 16bit mode */ +@@ -728,7 +742,8 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2 + /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 }, + /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw }, + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, +- /* 0F 04 */ { 0, &BX_CPU_C::BxError }, ++ ///* 0F 04 */ { 0, &BX_CPU_C::BxError }, ++ /* 0F 04 : sorav */ { BxAnother | BxGroupTaint, NULL, BxOpcodeInfoGTaint }, // 2-byte escape + #if BX_SUPPORT_X86_64 + /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, + #else +@@ -1263,7 +1278,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2 + /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 }, + /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw }, + /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw }, +- /* 0F 04 */ { 0, &BX_CPU_C::BxError }, ++ /* 0F 04 : sorav */ { BxAnother | BxGroupTaint, NULL, BxOpcodeInfoGTaint }, // 2-byte escape + #if BX_SUPPORT_X86_64 + /* 0F 05 */ { 0, &BX_CPU_C::SYSCALL }, + #else +@@ -1564,6 +1580,8 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxIns + /*os64*/ 0, /*as64*/ 0, + /*extend8bit*/ 0, /*repUsed*/ 0); + ++ instruction->setLocked (false) ; ++ + sse_prefix = SSE_PREFIX_NONE; + + fetch_b1: +@@ -1669,6 +1687,7 @@ another_byte: + case 0xf0: // LOCK: + BX_INSTR_PREFIX_LOCK(BX_CPU_ID); + lock = 1; ++ instruction->setLocked (false) ; + if (ilen < remain) { + ilen++; + goto fetch_b1; +@@ -1883,6 +1902,7 @@ modrm_done: + } + + instruction->execute = OpcodeInfoPtr->ExecutePtr; ++ instruction->taint_execute = OpcodeInfoPtr->TaintExecutePtr; + instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF)); + } + else { +@@ -1891,6 +1911,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; ++ instruction->taint_execute = BxOpcodeInfo[b1+offset].TaintExecutePtr; + 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 +@@ -38,6 +38,8 @@ + #include "bochs.h" + #define LOG_THIS BX_CPU_THIS_PTR + ++#include "taint/globals.h" ++ + #if BX_USE_CPU_SMF + #define this (BX_CPU(0)) + #endif +@@ -1124,6 +1126,7 @@ BX_CPU_C::access_linear(bx_address laddr + BX_CPU_THIS_PTR mem->writePhysicalPage(this, + BX_CPU_THIS_PTR address_xlation.paddress1, length, data); + } ++ BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data); + return; + } + else { +@@ -1195,6 +1198,7 @@ BX_CPU_C::access_linear(bx_address laddr + } + #endif + ++ BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data); + return; + } + } +@@ -1216,6 +1220,7 @@ BX_CPU_C::access_linear(bx_address laddr + lpf = laddr & 0xfffff000; + if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) { + BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data); ++ BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data); + return; + } + // We haven't seen this page, or it's been bumped before. +@@ -1258,6 +1263,7 @@ BX_CPU_C::access_linear(bx_address laddr + lpf = laddr & 0xfffff000; + if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) { + BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data); ++ BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data); + return; + } + // We haven't seen this page, or it's been bumped before. +@@ -1401,6 +1407,8 @@ BX_CPU_C::access_linear(Bit32u laddr, un + BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data); + else + BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data); ++ ++ BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data); + 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 +@@ -44,7 +44,7 @@ SHELL = /bin/sh + @SET_MAKE@ + + CXX = @CXX@ +-CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@ @GUI_CXXFLAGS@ ++CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@ @GUI_CXXFLAGS@ -fms-extensions + 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 +@@ -464,6 +464,7 @@ typedef enum { + #endif + BXP_SEL_CONFIG_INTERFACE, + BXP_SEL_DISPLAY_LIBRARY, ++ BXP_SEL_TAINT_TYPE, + 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 +@@ -28,6 +28,10 @@ + #include + #include "state_file.h" + ++#include "taint/taint_type.h" ++#include "taint/mydebug.h" ++#include "taint/globals.h" ++ + #ifdef HAVE_LOCALE_H + #include + #endif +@@ -1768,6 +1773,7 @@ int bxmain () { + if (setjmp (context) == 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; + // 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 + SIM->set_init_done (1); + + // update headerbar buttons since drive status can change during init ++ static char *taint_type_list[] = { ++ "eraser", ++ "none", ++ NULL ++ }; ++ bx_options.Otaint_type = new bx_param_enum_c (BXP_SEL_TAINT_TYPE, ++ "Taint Type (Eraser,..)", ++ "Select Taint Type", ++ taint_type_list, ++ 0, ++ 0); ++ + 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() + #if !BX_DEBUGGER + signal(SIGINT, bx_signal_handler); + #endif +- ++ assign_taint_functions ("eraser") ; + #if BX_SHOW_IPS + #ifndef __MINGW32__ + signal(SIGALRM, bx_signal_handler); +@@ -3971,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])); + } ++ else if (!strcmp (params[0], "taint")) { ++ if (num_params!=2) { ++ PARSE_ERR(("%s: taint directive: wrong # of args. Usage: taint