17a869b5ab48e19418b94e162927d255ff7080e0
[pintos-anon] / src / misc / bochs-2.1.1-checkbochs.patch
1 This patch provides Eraser-like lock set checking for Bochs.
2 See the Pintos documentation for more information.
3
4 This patch is provided by Sorav Bansal <sbansal@cs.stanford.edu>.
5
6 diff -urpN bochs-2.1.1.orig/Makefile.in checkbochs-2.1.1/Makefile.in
7 --- bochs-2.1.1.orig/Makefile.in        2004-02-11 14:28:02.000000000 -0800
8 +++ checkbochs-2.1.1/Makefile.in        2005-06-29 10:59:56.000000000 -0700
9 @@ -177,11 +177,11 @@ all: @PRIMARY_TARGET@ @PLUGIN_TARGET@ bx
10  @EXTERNAL_DEPENDENCY@
11  
12  bochs@EXE@: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \
13 -           cpu/libcpu.a memory/libmemory.a gui/libgui.a \
14 +           cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \
15             @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \
16             $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@
17         @LINK@ -export-dynamic $(BX_OBJS) $(SIMX86_OBJS) \
18 -               iodev/libiodev.a cpu/libcpu.a memory/libmemory.a gui/libgui.a \
19 +               iodev/libiodev.a cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \
20                 @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \
21                 @GDBSTUB_VAR@ @FPU_VAR@ \
22                 @NONPLUGIN_GUI_LINK_OPTS@ \
23 @@ -195,19 +195,19 @@ bochs@EXE@: @IODEV_LIB_VAR@ @DEBUGGER_VA
24  # libtool.  This creates a .DEF file, and exports file, an import library,
25  # and then links bochs.exe with the exports file.
26  .win32_dll_plugin_target: @IODEV_LIB_VAR@ @DEBUGGER_VAR@ \
27 -           cpu/libcpu.a memory/libmemory.a gui/libgui.a \
28 +           cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \
29             @DISASM_VAR@ @INSTRUMENT_VAR@ $(BX_OBJS) \
30             $(SIMX86_OBJS) @FPU_VAR@ @GDBSTUB_VAR@ @PLUGIN_VAR@
31         $(DLLTOOL) --export-all-symbols --output-def bochs.def \
32                 $(BX_OBJS) $(SIMX86_OBJS) \
33 -               @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a \
34 +               @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \
35                 @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \
36                 @GDBSTUB_VAR@ @FPU_VAR@
37         $(DLLTOOL) --dllname bochs.exe --def bochs.def --output-lib dllexports.a
38         $(DLLTOOL) --dllname bochs.exe --output-exp bochs.exp --def bochs.def
39         $(CXX) -o bochs.exe $(CXXFLAGS) $(LDFLAGS) -export-dynamic \
40             $(BX_OBJS) bochs.exp $(SIMX86_OBJS) \
41 -               @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a \
42 +               @IODEV_LIB_VAR@ cpu/libcpu.a memory/libmemory.a gui/libgui.a taint/libtaint.a \
43                 @DEBUGGER_VAR@ @DISASM_VAR@ @INSTRUMENT_VAR@ @PLUGIN_VAR@ \
44                 @GDBSTUB_VAR@ @FPU_VAR@ \
45                 $(GUI_LINK_OPTS) \
46 @@ -274,6 +274,11 @@ gui/libgui.a::
47         $(MAKE) $(MDEFINES) libgui.a
48         @CD_UP_ONE@
49  
50 +taint/libtaint.a::
51 +       cd taint @COMMAND_SEPARATOR@
52 +       $(MAKE) $(MDEFINES) libtaint.a
53 +       @CD_UP_ONE@
54 +
55  disasm/libdisasm.a::
56         cd disasm @COMMAND_SEPARATOR@
57         $(MAKE) $(MDEFINES) libdisasm.a
58 @@ -503,6 +508,9 @@ all-clean: clean
59         cd fpu @COMMAND_SEPARATOR@
60         $(MAKE) clean
61         @CD_UP_ONE@
62 +       cd taint @COMMAND_SEPARATOR@
63 +       $(MAKE) clean
64 +       @CD_UP_ONE@
65         cd doc/docbook @COMMAND_SEPARATOR@
66         $(MAKE) clean
67         @CD_UP_TWO@
68 @@ -538,6 +546,9 @@ dist-clean: local-dist-clean
69         cd fpu @COMMAND_SEPARATOR@
70         $(MAKE) dist-clean
71         @CD_UP_ONE@
72 +       cd taint @COMMAND_SEPARATOR@
73 +       $(MAKE) dist-clean
74 +       @CD_UP_ONE@
75         cd doc/docbook @COMMAND_SEPARATOR@
76         $(MAKE) dist-clean
77         @CD_UP_TWO@
78 diff -urpN bochs-2.1.1.orig/bochs.h checkbochs-2.1.1/bochs.h
79 --- bochs-2.1.1.orig/bochs.h    2004-02-11 14:28:03.000000000 -0800
80 +++ checkbochs-2.1.1/bochs.h    2005-06-29 10:59:53.000000000 -0700
81 @@ -671,6 +671,7 @@ typedef struct BOCHSAPI {
82    bx_gdbstub_t      gdbstub;
83    bx_param_enum_c *Osel_config;
84    bx_param_enum_c *Osel_displaylib;
85 +  bx_param_enum_c *Otaint_type ;
86    } bx_options_t;
87  
88  BOCHSAPI extern bx_options_t bx_options;
89 diff -urpN bochs-2.1.1.orig/configure checkbochs-2.1.1/configure
90 --- bochs-2.1.1.orig/configure  2004-02-11 14:28:40.000000000 -0800
91 +++ checkbochs-2.1.1/configure  2005-06-29 10:59:53.000000000 -0700
92 @@ -36189,7 +36189,7 @@ echo "${ECHO_T}no" >&6
93  fi
94  
95  
96 -                                                                                                                                                                          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"
97 +                                                                                                                                                                          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"
98  cat >confcache <<\_ACEOF
99  # This file is a shell script that caches the results of configure
100  # tests run on this system so they can be shared between configure
101 @@ -36724,6 +36724,7 @@ do
102    "${INSTRUMENT_DIR}/Makefile" ) CONFIG_FILES="$CONFIG_FILES ${INSTRUMENT_DIR}/Makefile" ;;
103    "misc/Makefile" ) CONFIG_FILES="$CONFIG_FILES misc/Makefile" ;;
104    "fpu/Makefile" ) CONFIG_FILES="$CONFIG_FILES fpu/Makefile" ;;
105 +  "taint/Makefile" ) CONFIG_FILES="$CONFIG_FILES taint/Makefile" ;;
106    "doc/docbook/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/docbook/Makefile" ;;
107    "build/linux/bochs-dlx" ) CONFIG_FILES="$CONFIG_FILES build/linux/bochs-dlx" ;;
108    "bxversion.h" ) CONFIG_FILES="$CONFIG_FILES bxversion.h" ;;
109 diff -urpN bochs-2.1.1.orig/cpu/cpu.cc checkbochs-2.1.1/cpu/cpu.cc
110 --- bochs-2.1.1.orig/cpu/cpu.cc 2004-02-11 14:28:51.000000000 -0800
111 +++ checkbochs-2.1.1/cpu/cpu.cc 2005-06-29 10:59:54.000000000 -0700
112 @@ -30,6 +30,9 @@
113  #include "bochs.h"
114  #define LOG_THIS BX_CPU_THIS_PTR
115  
116 +#include "taint/globals.h"
117 +#include "taint/mydebug.h"
118 +
119  #if BX_USE_CPU_SMF
120  #define this (BX_CPU(0))
121  #endif
122 @@ -111,7 +114,9 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
123    bxInstruction_c iStorage BX_CPP_AlignN(32);
124    bxInstruction_c *i = &iStorage;
125  
126 -  BxExecutePtr_t execute;
127 +  BxExecutePtr_t execute, taint_execute ;
128 +
129 +  BX_CPU_THIS_PTR curInstruction = i ;
130  
131  #if BX_DEBUGGER
132    BX_CPU_THIS_PTR break_point = 0;
133 @@ -209,6 +214,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
134      BxExecutePtr_tR resolveModRM = i->ResolveModrm; // Get as soon as possible for speculation.
135  
136      execute = i->execute; // fetch as soon as possible for speculation.
137 +
138 +    taint_execute = i->taint_execute ;
139 +    if (!taint_execute) taint_execute = &BX_CPU_C::NOP ;
140 +
141      if (resolveModRM) {
142        BX_CPU_CALL_METHODR(resolveModRM, (i));
143      }
144 @@ -281,6 +290,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
145      }
146  #endif
147      execute = i->execute; // fetch as soon as possible for speculation.
148 +
149 +    taint_execute = i->taint_execute ;
150 +    if (!taint_execute) taint_execute = &BX_CPU_C::NOP ;
151 +
152      if (resolveModRM) {
153        BX_CPU_CALL_METHODR(resolveModRM, (i));
154        }
155 @@ -303,6 +316,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
156        BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID);
157        RIP += i->ilen();
158        BX_CPU_CALL_METHOD(execute, (i));
159 +      BX_CPU_CALL_METHOD(taint_execute, (i));
160        BX_CPU_THIS_PTR prev_eip = RIP; // commit new EIP
161        BX_CPU_THIS_PTR prev_esp = RSP; // commit new ESP
162        BX_INSTR_AFTER_EXECUTION(BX_CPU_ID);
163 @@ -323,6 +337,7 @@ repeat_loop:
164          if (i->as64L()) {
165            if (RCX != 0) {
166              BX_CPU_CALL_METHOD(execute, (i));
167 +            BX_CPU_CALL_METHOD(taint_execute, (i));
168              RCX --;
169              }
170            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
171 @@ -335,6 +350,7 @@ repeat_loop:
172          if (i->as32L()) {
173            if (ECX != 0) {
174              BX_CPU_CALL_METHOD(execute, (i));
175 +            BX_CPU_CALL_METHOD(taint_execute, (i));
176              ECX --;
177              }
178            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
179 @@ -345,6 +361,7 @@ repeat_loop:
180          else {
181            if (CX != 0) {
182              BX_CPU_CALL_METHOD(execute, (i));
183 +            BX_CPU_CALL_METHOD(taint_execute, (i));
184              CX --;
185              }
186            if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
187 @@ -358,6 +375,7 @@ repeat_loop:
188          if (i->as64L()) {
189            if (RCX != 0) {
190              BX_CPU_CALL_METHOD(execute, (i));
191 +            BX_CPU_CALL_METHOD(taint_execute, (i));
192              RCX --;
193              }
194            if (RCX == 0) goto repeat_done;
195 @@ -368,6 +386,7 @@ repeat_loop:
196          if (i->as32L()) {
197            if (ECX != 0) {
198              BX_CPU_CALL_METHOD(execute, (i));
199 +            BX_CPU_CALL_METHOD(taint_execute, (i));
200              ECX --;
201              }
202            if (ECX == 0) goto repeat_done;
203 @@ -376,6 +395,7 @@ repeat_loop:
204          else { // 16bit addrsize
205            if (CX != 0) {
206              BX_CPU_CALL_METHOD(execute, (i));
207 +            BX_CPU_CALL_METHOD(taint_execute, (i));
208              CX --;
209              }
210            if (CX == 0) goto repeat_done;
211 @@ -865,6 +885,17 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; /
212                    BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b);
213  }
214  
215 +void
216 +BX_CPU_C::panic(const char *fmt, ...)
217 +{
218 +    va_list arg;
219 +
220 +    printf("backtrace: %s.\n",backtrace(btstr));
221 +
222 +    va_start(arg,fmt);
223 +    logfunctions::panic(fmt,arg);
224 +    va_end(arg);
225 +}
226  
227  #if BX_EXTERNAL_DEBUGGER
228  
229 diff -urpN bochs-2.1.1.orig/cpu/cpu.h checkbochs-2.1.1/cpu/cpu.h
230 --- bochs-2.1.1.orig/cpu/cpu.h  2004-02-11 14:28:51.000000000 -0800
231 +++ checkbochs-2.1.1/cpu/cpu.h  2005-06-29 10:59:54.000000000 -0700
232 @@ -739,9 +739,11 @@ public:
233  #if BX_USE_CPU_SMF
234    void (*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
235    void (*execute)(bxInstruction_c *);
236 +  void (*taint_execute)(bxInstruction_c *);
237  #else
238    void (BX_CPU_C::*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
239    void (BX_CPU_C::*execute)(bxInstruction_c *);
240 +  void (BX_CPU_C::*taint_execute)(bxInstruction_c *);
241  #endif
242  
243    // 26..23  ilen (0..15).  Leave this one on top so no mask is needed.
244 @@ -821,6 +823,11 @@ public:
245  #endif
246      };
247  
248 +  /* sorav: to check if the instruction has a lock prefix */
249 +  bool locked;                  //whether lock prefix is held
250 +  BX_CPP_INLINE void setLocked(bool val) { locked = val; }
251 +  BX_CPP_INLINE bool isLocked(void) { return locked ; }
252 +
253    BX_CPP_INLINE unsigned opcodeReg() {
254      // The opcodeReg form (low 3 bits of the opcode byte (extended
255      // by REX.B on x86-64) can be accessed by IxForm or IqForm.  They
256 @@ -1428,8 +1435,18 @@ union {
257                          //   is greated than 2 (the maximum possible for
258                          //   normal cases) it is a native pointer and is used
259                          //   for a direct write access.
260 +
261 +    /* taint fields */
262 +    Bit32u taint_paddress1;
263 +    Bit32u taint_paddress2;
264 +    Bit32u taint_len1;
265 +    Bit32u taint_len2;
266 +    bx_ptr_equiv_t taint_pages;
267 +
268      } address_xlation;
269  
270 +    bxInstruction_c *curInstruction ;
271 +
272  #if BX_SUPPORT_X86_64
273    // data upper 32 bits - not used any longer
274    //Bit32s daddr_upper;    // upper bits must be canonical  (-virtmax --> + virtmax)
275 @@ -2952,6 +2969,33 @@ union {
276  #if BX_SUPPORT_APIC
277    bx_local_apic_c local_apic;
278  #endif
279 +
280 +  /* taint functions */
281 +  void panic(const char *fmt, ...);
282 +  BX_SMF Bit32u thread_current(void) ;
283 +  BX_SMF Bit32s BX_CPP_AttrRegparmN(3) BX_CPU_C::taint_dtranslate_linear(bx_address laddr, unsigned pl, unsigned rw);
284 +  BX_SMF Bit32u BX_CPP_AttrRegparmN(2) BX_CPU_C::taint_itranslate_linear(bx_address laddr, unsigned pl);
285 +  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);
286 +//SHADOW STATE FUNCTIONS
287 +  BX_SMF void TT_TaintSaveRegs(bxInstruction_c *i);
288 +  BX_SMF void TT_TaintRestoreRegs(bxInstruction_c *i);
289 +  BX_SMF void TT_Lock(bxInstruction_c *i);
290 +  BX_SMF void TT_Unlock(bxInstruction_c *i);
291 +  BX_SMF void TT_CommonOps(bxInstruction_c *i);
292 +                                                                                                                                                                                                     
293 +  BX_SMF int read_virtual_checks_silent(bx_segment_reg_t *seg, bx_address offset, unsigned length) BX_CPP_AttrRegparmN(3);
294 +  BX_SMF int read_virtual_byte_silent(unsigned s, bx_address offset, Bit8u *data);
295 +  BX_SMF int read_virtual_word_silent(unsigned s, bx_address offset, Bit16u *data);
296 +  BX_SMF int read_virtual_dword_silent(unsigned s, bx_address offset, Bit32u *data);
297 +  BX_SMF int access_linear_silent(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *data);
298 +                                                                                                                                                                                                     
299 +  BX_SMF char *backtrace(char *s);
300 +  BX_SMF Bit32u callingEIP(void);
301 +                                                                                                                                                                                                     
302 +  BX_SMF void eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *data);
303 +                                                                                                                                                                                                     
304 +  BX_SMF void eraser_init_globals (void) ;
305 +
306    };
307  
308  
309 @@ -3299,6 +3343,7 @@ IMPLEMENT_EFLAG_ACCESSOR   (TF,  8)
310  #define BxGroup14         BxGroupN
311  #define BxGroup15         BxGroupN
312  #define BxGroup16         BxGroupN
313 +#define BxGroupTaint     BxGroupN
314  
315  #if BX_DEBUGGER
316  typedef enum _show_flags {
317 diff -urpN bochs-2.1.1.orig/cpu/cpuid.cc checkbochs-2.1.1/cpu/cpuid.cc
318 --- bochs-2.1.1.orig/cpu/cpuid.cc       2003-12-31 09:35:43.000000000 -0800
319 +++ checkbochs-2.1.1/cpu/cpuid.cc       2005-06-29 10:59:54.000000000 -0700
320 @@ -251,6 +251,12 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
321        RDX = get_std_cpuid_features ();
322        break;
323  
324 +    case 3:             /*added by sorav */
325 +      RBX = 0x6e696154; // "Tain"
326 +      RDX = 0x49646574; // "tedI"
327 +      RCX = 0x6c65746e; // "ntel"
328 +      break;
329 +
330  #if 0
331  #if BX_CPU_LEVEL >= 6
332      case 2:
333 diff -urpN bochs-2.1.1.orig/cpu/fetchdecode.cc checkbochs-2.1.1/cpu/fetchdecode.cc
334 --- bochs-2.1.1.orig/cpu/fetchdecode.cc 2003-12-28 10:19:41.000000000 -0800
335 +++ checkbochs-2.1.1/cpu/fetchdecode.cc 2005-06-29 10:59:54.000000000 -0700
336 @@ -29,6 +29,8 @@
337  #include "bochs.h"
338  #define LOG_THIS BX_CPU_THIS_PTR
339  
340 +#include "taint/eraser.h"
341 +
342  
343  ///////////////////////////
344  // prefix bytes
345 @@ -156,6 +158,7 @@ typedef struct BxOpcodeInfo_t {
346    Bit16u         Attr;
347    BxExecutePtr_t ExecutePtr;
348    struct BxOpcodeInfo_t *AnotherArray;
349 +  BxExecutePtr_t TaintExecutePtr ;
350  } BxOpcodeInfo_t;
351  
352  
353 @@ -458,6 +461,17 @@ static BxOpcodeInfo_t BxOpcodeInfoG16[8]
354    /* 7 */  { 0, &BX_CPU_C::BxError }
355    };
356  
357 +BxOpcodeInfo_t BxOpcodeInfoGTaint[8] = {
358 +  /* 0 */  { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_TaintSaveRegs},
359 +  /* 1 */  { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_TaintRestoreRegs},
360 +  /* 2 */  { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_Lock /*&BX_CPU_C::TT_RegionTaint*/},
361 +  /* 3 */  { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_Unlock /*&BX_CPU_C::TT_RegionCheck*/},
362 +  /* 4 */  { BxImmediate_Iv, &BX_CPU_C::NOP, NULL, &BX_CPU_C::TT_CommonOps },
363 +  /* 5 */  { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Taint*/ },
364 +  /* 6 */  { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Untaint*/ },
365 +  /* 7 */  { 0, &BX_CPU_C::NOP, NULL, NULL /*&BX_CPU_C::TT_Check*/}
366 +  };
367 +
368  
369  /* ************************** */
370  /* 512 entries for 16bit mode */
371 @@ -728,7 +742,8 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2
372    /* 0F 01 */  { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
373    /* 0F 02 */  { BxAnother, &BX_CPU_C::LAR_GvEw },
374    /* 0F 03 */  { BxAnother, &BX_CPU_C::LSL_GvEw },
375 -  /* 0F 04 */  { 0, &BX_CPU_C::BxError },
376 +  ///* 0F 04 */  { 0, &BX_CPU_C::BxError },
377 +  /* 0F 04 : sorav */  { BxAnother | BxGroupTaint, NULL, BxOpcodeInfoGTaint }, // 2-byte escape
378  #if BX_SUPPORT_X86_64
379    /* 0F 05 */  { 0, &BX_CPU_C::SYSCALL },
380  #else
381 @@ -1263,7 +1278,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2
382    /* 0F 01 */  { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
383    /* 0F 02 */  { BxAnother, &BX_CPU_C::LAR_GvEw },
384    /* 0F 03 */  { BxAnother, &BX_CPU_C::LSL_GvEw },
385 -  /* 0F 04 */  { 0, &BX_CPU_C::BxError },
386 +  /* 0F 04 : sorav */  { BxAnother | BxGroupTaint, NULL, BxOpcodeInfoGTaint }, // 2-byte escape
387  #if BX_SUPPORT_X86_64
388    /* 0F 05 */  { 0, &BX_CPU_C::SYSCALL },
389  #else
390 @@ -1564,6 +1580,8 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxIns
391                    /*os64*/       0,  /*as64*/     0,
392                    /*extend8bit*/ 0,  /*repUsed*/  0);
393  
394 +  instruction->setLocked (false) ;
395 +
396    sse_prefix = SSE_PREFIX_NONE;
397    
398  fetch_b1:
399 @@ -1669,6 +1687,7 @@ another_byte:
400          case 0xf0: // LOCK:
401            BX_INSTR_PREFIX_LOCK(BX_CPU_ID);
402            lock = 1;
403 +         instruction->setLocked (false) ;
404            if (ilen < remain) {
405              ilen++;
406              goto fetch_b1;
407 @@ -1883,6 +1902,7 @@ modrm_done:
408      }
409  
410      instruction->execute = OpcodeInfoPtr->ExecutePtr;
411 +    instruction->taint_execute = OpcodeInfoPtr->TaintExecutePtr;
412      instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
413    }
414    else {
415 @@ -1891,6 +1911,7 @@ modrm_done:
416      // the if() above after fetching the 2nd byte, so this path is
417      // taken in all cases if a modrm byte is NOT required.
418      instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
419 +    instruction->taint_execute = BxOpcodeInfo[b1+offset].TaintExecutePtr;
420      instruction->IxForm.opcodeReg = b1 & 7;
421    }
422  
423 diff -urpN bochs-2.1.1.orig/cpu/paging.cc checkbochs-2.1.1/cpu/paging.cc
424 --- bochs-2.1.1.orig/cpu/paging.cc      2003-12-30 14:12:45.000000000 -0800
425 +++ checkbochs-2.1.1/cpu/paging.cc      2005-06-29 10:59:54.000000000 -0700
426 @@ -38,6 +38,8 @@
427  #include "bochs.h"
428  #define LOG_THIS BX_CPU_THIS_PTR
429  
430 +#include "taint/globals.h"
431 +
432  #if BX_USE_CPU_SMF
433  #define this (BX_CPU(0))
434  #endif
435 @@ -1124,6 +1126,7 @@ BX_CPU_C::access_linear(bx_address laddr
436          BX_CPU_THIS_PTR mem->writePhysicalPage(this,
437              BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
438          }
439 +      BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
440        return;
441        }
442      else {
443 @@ -1195,6 +1198,7 @@ BX_CPU_C::access_linear(bx_address laddr
444          }
445  #endif
446  
447 +      BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
448        return;
449        }
450      }
451 @@ -1216,6 +1220,7 @@ BX_CPU_C::access_linear(bx_address laddr
452          lpf = laddr & 0xfffff000;
453          if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
454            BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
455 +          BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
456            return;
457            }
458          // We haven't seen this page, or it's been bumped before.
459 @@ -1258,6 +1263,7 @@ BX_CPU_C::access_linear(bx_address laddr
460          lpf = laddr & 0xfffff000;
461          if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
462            BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
463 +          BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
464            return;
465            }
466          // We haven't seen this page, or it's been bumped before.
467 @@ -1401,6 +1407,8 @@ BX_CPU_C::access_linear(Bit32u laddr, un
468        BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
469      else
470        BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
471 +
472 +    BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
473      return;
474      }
475  
476 diff -urpN bochs-2.1.1.orig/gdbstub.cc checkbochs-2.1.1/gdbstub.cc
477 diff -urpN bochs-2.1.1.orig/gdbstub.cc.rej checkbochs-2.1.1/gdbstub.cc.rej
478 diff -urpN bochs-2.1.1.orig/gui/Makefile.in checkbochs-2.1.1/gui/Makefile.in
479 --- bochs-2.1.1.orig/gui/Makefile.in    2003-11-28 07:07:28.000000000 -0800
480 +++ checkbochs-2.1.1/gui/Makefile.in    2005-06-29 10:13:21.000000000 -0700
481 @@ -44,7 +44,7 @@ SHELL = /bin/sh
482  @SET_MAKE@
483  
484  CXX = @CXX@
485 -CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@  @GUI_CXXFLAGS@
486 +CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@  @GUI_CXXFLAGS@ -fms-extensions
487  LOCAL_CXXFLAGS =
488  LDFLAGS = @LDFLAGS@
489  LIBS = @LIBS@
490 diff -urpN bochs-2.1.1.orig/gui/siminterface.h checkbochs-2.1.1/gui/siminterface.h
491 --- bochs-2.1.1.orig/gui/siminterface.h 2004-02-11 14:28:52.000000000 -0800
492 +++ checkbochs-2.1.1/gui/siminterface.h 2005-06-29 10:59:55.000000000 -0700
493 @@ -464,6 +464,7 @@ typedef enum {
494  #endif
495    BXP_SEL_CONFIG_INTERFACE,
496    BXP_SEL_DISPLAY_LIBRARY,
497 +  BXP_SEL_TAINT_TYPE,
498    BXP_THIS_IS_THE_LAST    // used to determine length of list
499  } bx_id;
500  
501 diff -urpN bochs-2.1.1.orig/iodev/pit82c54.cc checkbochs-2.1.1/iodev/pit82c54.cc
502 diff -urpN bochs-2.1.1.orig/iodev/pit82c54.cc~ checkbochs-2.1.1/iodev/pit82c54.cc~
503 diff -urpN bochs-2.1.1.orig/iodev/serial.cc checkbochs-2.1.1/iodev/serial.cc
504 diff -urpN bochs-2.1.1.orig/iodev/serial.cc.rej checkbochs-2.1.1/iodev/serial.cc.rej
505 diff -urpN bochs-2.1.1.orig/main.cc checkbochs-2.1.1/main.cc
506 --- bochs-2.1.1.orig/main.cc    2004-02-11 14:28:41.000000000 -0800
507 +++ checkbochs-2.1.1/main.cc    2005-06-29 11:29:46.000000000 -0700
508 @@ -28,6 +28,10 @@
509  #include <assert.h>
510  #include "state_file.h"
511  
512 +#include "taint/taint_type.h"
513 +#include "taint/mydebug.h"
514 +#include "taint/globals.h"
515 +
516  #ifdef HAVE_LOCALE_H
517  #include <locale.h>
518  #endif
519 @@ -1768,6 +1773,7 @@ int bxmain () {
520    if (setjmp (context) == 0) {
521      SIM->set_quit_context (&context);
522      if (bx_init_main (bx_startup_flags.argc, bx_startup_flags.argv) < 0) 
523 +    BX_CPU(0)->eraser_init_globals() ;
524        return 0;
525      // read a param to decide which config interface to start.
526      // If one exists, start it.  If not, just begin.
527 @@ -2309,6 +2322,18 @@ bx_begin_simulation (int argc, char *arg
528    SIM->set_init_done (1);
529  
530    // update headerbar buttons since drive status can change during init
531 +  static char *taint_type_list[] = {
532 +      "eraser",
533 +      "none",
534 +      NULL
535 +  };
536 +  bx_options.Otaint_type = new bx_param_enum_c (BXP_SEL_TAINT_TYPE,
537 +    "Taint Type (Eraser,..)",
538 +    "Select Taint Type",
539 +    taint_type_list,
540 +    0,
541 +    0);
542 +                                                                                                                                                                                                     
543    bx_gui->update_drive_status_buttons ();
544  
545    // The set handler for mouse_enabled does not actually update the gui
546 @@ -2507,7 +2532,7 @@ bx_init_hardware()
547  #if !BX_DEBUGGER
548    signal(SIGINT, bx_signal_handler);
549  #endif
550 -
551 +  assign_taint_functions ("eraser") ;
552  #if BX_SHOW_IPS
553  #ifndef __MINGW32__
554    signal(SIGALRM, bx_signal_handler);
555 @@ -3971,6 +3996,20 @@ parse_line_formatted(char *context, int 
556      if (!bx_options.Osel_config->set_by_name (params[1]))
557        PARSE_ERR(("%s: config_interface '%s' not available", context, params[1]));
558      }
559 +  else if (!strcmp (params[0], "taint")) {
560 +    if (num_params!=2) {
561 +       PARSE_ERR(("%s: taint directive: wrong # of args. Usage: taint <option>",context)) ;
562 +    }
563 +    if (!bx_options.Otaint_type->set_by_name (params[1])) {
564 +       PARSE_ERR(("%s: taint type '%s' not available.", context, params[1]));
565 +    }
566 +  }
567 +  else if (!strcmp (params[0], "logfile")) {
568 +    if (num_params!=2) {
569 +       PARSE_ERR(("%s: logfile directive: wrong # of args. Usage- logfile: <filename>",context)) ;
570 +    }
571 +    strncpy (g_logfn, params[1], 128) ;
572 +  }
573    else if (!strcmp(params[0], "display_library")) {
574      if (num_params != 2) {
575        PARSE_ERR(("%s: display_library directive: wrong # args.", context));
576 diff -urpN bochs-2.1.1.orig/main.cc~ checkbochs-2.1.1/main.cc~
577 diff -urpN bochs-2.1.1.orig/memory/memory.h checkbochs-2.1.1/memory/memory.h
578 --- bochs-2.1.1.orig/memory/memory.h    2004-02-11 14:28:54.000000000 -0800
579 +++ checkbochs-2.1.1/memory/memory.h    2005-06-29 10:59:56.000000000 -0700
580 @@ -45,6 +45,10 @@ class BOCHSAPI BX_MEM_C : public logfunc
581  public:
582    Bit8u   *actual_vector;
583    Bit8u   *vector;  // aligned correctly
584 +
585 +  Bit32u   *actual_taint_vector;        //keep a word for every byte
586 +  Bit32u   *taint_vector;       // aligned correctly
587 +
588    size_t  len;
589    size_t  megabytes;  // (len in Megabytes)
590  #if BX_PCI_SUPPORT
591 @@ -77,6 +81,12 @@ public:
592      unsigned long (*f)(unsigned char *buf, int len),
593      Bit32u addr1, Bit32u addr2, Bit32u *crc);
594    BX_MEM_SMF Bit8u * getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op) BX_CPP_AttrRegparmN(3);
595 +
596 +//Taint functions
597 +  BX_MEM_SMF void    readPhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr,
598 +                                      unsigned len, void *data) BX_CPP_AttrRegparmN(3);
599 +  BX_MEM_SMF void    writePhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr,
600 +                                       unsigned len, void *data) BX_CPP_AttrRegparmN(3);
601    };
602  
603  #if BX_PROVIDE_CPU_MEMORY==1
604 diff -urpN bochs-2.1.1.orig/memory/misc_mem.cc checkbochs-2.1.1/memory/misc_mem.cc
605 --- bochs-2.1.1.orig/memory/misc_mem.cc 2004-02-11 14:28:54.000000000 -0800
606 +++ checkbochs-2.1.1/memory/misc_mem.cc 2005-06-29 10:59:56.000000000 -0700
607 @@ -54,7 +54,9 @@ BX_MEM_C::BX_MEM_C(void)
608    settype(MEMLOG);
609  
610    vector = NULL;
611 +  taint_vector = NULL;
612    actual_vector = NULL;
613 +  actual_taint_vector = NULL;
614    len    = 0;
615    megabytes = 0;
616  }
617 @@ -69,11 +71,15 @@ BX_MEM_C::alloc_vector_aligned (size_t b
618    if (actual_vector != NULL) {
619      BX_INFO (("freeing existing memory vector"));
620      delete [] actual_vector;
621 +    delete [] actual_taint_vector;
622      actual_vector = NULL;
623 +    actual_taint_vector = NULL;
624      vector = NULL;
625 +    taint_vector = NULL;
626    }
627    Bit64u test_mask = alignment - 1;
628    actual_vector = new Bit8u [bytes+test_mask];
629 +  actual_taint_vector = new Bit32u [bytes+test_mask];
630    // round address forward to nearest multiple of alignment.  Alignment 
631    // MUST BE a power of two for this to work.
632    Bit64u masked = ((Bit64u)(actual_vector + test_mask)) & ~test_mask;
633 @@ -84,6 +90,13 @@ BX_MEM_C::alloc_vector_aligned (size_t b
634    BX_ASSERT (vector+bytes <= actual_vector+bytes+test_mask);
635    BX_INFO (("allocated memory at %p. after alignment, vector=%p", 
636         actual_vector, vector));
637 +
638 +  //sorav
639 +  unsigned int wasted_memory = masked - (Bit64u)vector ;
640 +  BX_ASSERT(wasted_memory<=test_mask);
641 +  taint_vector = &(actual_taint_vector[wasted_memory]);
642 +  //sanity check: after realignment, everything fits in allocated space
643 +  BX_ASSERT(&(taint_vector[bytes]) <= &(actual_taint_vector[bytes+test_mask]));
644  }
645  #endif
646  
647 @@ -136,6 +150,7 @@ BX_MEM_C::init_memory(int memsize)
648  
649    if (BX_MEM_THIS vector == NULL) {
650      // memory not already allocated, do now...
651 +    assert (taint_vector==NULL) ;
652      alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
653      BX_MEM_THIS len    = memsize;
654      BX_MEM_THIS megabytes = memsize / (1024*1024);
655 diff -urpN bochs-2.1.1.orig/taint/Makefile.in checkbochs-2.1.1/taint/Makefile.in
656 --- bochs-2.1.1.orig/taint/Makefile.in  1969-12-31 16:00:00.000000000 -0800
657 +++ checkbochs-2.1.1/taint/Makefile.in  2005-06-29 11:14:31.000000000 -0700
658 @@ -0,0 +1,184 @@
659 +.SUFFIXES: .cc
660 +
661 +VPATH = @srcdir@
662 +
663 +srcdir = @srcdir@
664 +
665 +top_builddir    = $(srcdir)/..
666 +top_srcdir      = $(srcdir)/..
667 +
668 +SHELL = /bin/sh
669 +
670 +
671 +
672 +CXX = g++
673 +CXXFLAGS = -g -O2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES  $(X_CFLAGS)
674 +
675 +LDFLAGS = 
676 +LIBS =  -lm
677 +X_LIBS =  -L/usr/X11R6/lib
678 +X_PRE_LIBS =  -lSM -lICE
679 +RANLIB = ranlib
680 +
681 +
682 +
683 +BX_INCDIRS = -I.. -I$(srcdir)/.. -I../instrument/stubs -I$(srcdir)/../instrument/stubs
684 +
685 +APIC_OBJS = 
686 +EXT_DEBUG_OBJS = 
687 +
688 +# Objects which are synced between the cpu and cpu64 code and
689 +# are used for either compile.
690 +OBJS = common.o globals.o taint_type.o eraser.o paging.o memory.o \
691 +       lockset.o list.o hash.o silent_access.o silent_paging.o
692 +       
693 +OBJS64 =
694 +       
695 +
696 +BX_INCLUDES = ../bochs.h ../config.h
697 +
698 +
699 +all: libtaint.a
700 +
701 +.cc.o:
702 +       $(CXX) -c $(BX_INCDIRS) $(CXXFLAGS) $< -o $@
703 +
704 +
705 +libtaint.a: $(OBJS) 
706 +       rm -f  libtaint.a
707 +       ar rv $@ $(OBJS) 
708 +       $(RANLIB) libtaint.a
709 +
710 +$(OBJS): $(BX_INCLUDES)
711 +
712 +$(OBJS64): $(BX_INCLUDES)
713 +
714 +clean:
715 +       rm -f  *.o
716 +       rm -f  *.a
717 +
718 +dist-clean: clean
719 +       rm -f  Makefile
720 +
721 +common.o: common.cc ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
722 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
723 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
724 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
725 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
726 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
727 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
728 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
729 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
730 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
731 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
732 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
733 +  ../instrument/stubs/instrument.h mydebug.h
734 +
735 +taint_type.o: taint_type.cc taint_type.h \
736 +  ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
737 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
738 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
739 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
740 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
741 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
742 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
743 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
744 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
745 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
746 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
747 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
748 +  ../instrument/stubs/instrument.h mydebug.h
749 +
750 +memory.o: memory.cc ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
751 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
752 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
753 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
754 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
755 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
756 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
757 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
758 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
759 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
760 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
761 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
762 +  ../instrument/stubs/instrument.h mydebug.h
763 +
764 +paging.o: paging.cc ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
765 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
766 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
767 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
768 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
769 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
770 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
771 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
772 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
773 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
774 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
775 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
776 +  ../instrument/stubs/instrument.h mydebug.h
777 +
778 +eraser.o: eraser.cc lockset.h eraser.h \
779 +  ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
780 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
781 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
782 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
783 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
784 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
785 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
786 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
787 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
788 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
789 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
790 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
791 +  ../instrument/stubs/instrument.h mydebug.h
792 +
793 +silent_paging.o: silent_paging.cc \
794 +  ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
795 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
796 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
797 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
798 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
799 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
800 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
801 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
802 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
803 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
804 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
805 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
806 +  ../instrument/stubs/instrument.h mydebug.h
807 +
808 +silent_access.o: silent_access.cc \
809 +  ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
810 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
811 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
812 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
813 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
814 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
815 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
816 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
817 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
818 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
819 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
820 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
821 +  ../instrument/stubs/instrument.h mydebug.h
822 +
823 +globals.o: globals.cc \
824 +  ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
825 +  ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
826 +  ../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
827 +  ../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
828 +  ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
829 +  ../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
830 +  ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
831 +  ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
832 +  ../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
833 +  ../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
834 +  ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
835 +  ../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
836 +  ../instrument/stubs/instrument.h mydebug.h
837 +
838 +lockset.o: lockset.h lockset.cc hash.h mydebug.h
839 +
840 +hash.o: hash.h hash.cc
841 +
842 +list.o: list.h list.cc
843 diff -urpN bochs-2.1.1.orig/taint/common.cc checkbochs-2.1.1/taint/common.cc
844 --- bochs-2.1.1.orig/taint/common.cc    1969-12-31 16:00:00.000000000 -0800
845 +++ checkbochs-2.1.1/taint/common.cc    2005-06-29 11:19:16.000000000 -0700
846 @@ -0,0 +1,146 @@
847 +#define NEED_CPU_REG_SHORTCUTS 1
848 +#include "bochs.h"
849 +#define LOG_THIS BX_CPU_THIS_PTR
850 +
851 +#include "taint/mydebug.h"
852 +#include "taint/globals.h"
853 +
854 +#define PINTOS
855 +
856 +#define STACK_DEPTH 256
857 +
858 +#if BX_USE_CPU_SMF
859 +#define this (BX_CPU(0))
860 +#endif
861 +
862 +#define MASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT))
863 +
864 +/* Page offset (bits 0:13). */
865 +#define PGSHIFT 0                       /* Index of first offset bit. */
866 +
867 +#ifdef LINUX
868 +#define PGBITS  13                      /* Number of offset bits. */
869 +#else
870 +#ifdef PINTOS
871 +#define PGBITS 12
872 +#else
873 +#define PGBITS  13                      /* Number of offset bits. */
874 +#warning "Dont know whether compiling for Pintos or Linux. Assuming Linux (PGBITS=13)"
875 +#endif
876 +#endif
877 +
878 +#define PGMASK  MASK(PGSHIFT, PGBITS)   /* Page offset bits (0:12). */
879 +#define PGSIZE  (1 << PGBITS)           /* Bytes in a page. */
880 +
881 +struct stack {
882 +    Bit32u arr[STACK_DEPTH];
883 +    unsigned int top;
884 +} savedRegsStack;
885 +bool savedRegsStackInitialized = false;
886 +
887 +void push(struct stack *s, Bit32u val) {
888 +    assert(s->top>=0);
889 +    if (s->top++==STACK_DEPTH) {
890 +       DBG(ERR,("Stack Overflow. Exiting.."));
891 +       exit(1);
892 +    }
893 +    s->arr[s->top-1] = val;
894 +}
895 +
896 +Bit32u pop(struct stack *s) {
897 +    Bit32u ret;
898 +    assert(s->top>=0);
899 +    if (s->top==0) {
900 +       DBG(ERR,("Stack Underflow. Exiting.."));
901 +       exit(1);
902 +    }
903 +    ret = s->arr[s->top-1];
904 +    s->top--;
905 +    return ret;
906 +}
907 +
908 +Bit32u stack_init(struct stack *s) {
909 +    s->top = 0;
910 +}
911 +
912 +void BX_CPU_C::TT_TaintSaveRegs(bxInstruction_c *i) {
913 +       Bit32u opId = i->Id();
914 +
915 +       if (!savedRegsStackInitialized) {
916 +           stack_init(&savedRegsStack);
917 +           savedRegsStackInitialized = true;
918 +       }
919 +       //if (opId==999) mylog(D1,("%s %d: called with opId 999.\n",__func__,__LINE__));
920 +       push(&savedRegsStack, EAX);
921 +       push(&savedRegsStack, EBX);
922 +       push(&savedRegsStack, ECX);
923 +       push(&savedRegsStack, EDX);
924 +       //DBG(L1,("pushing EAX=%x, EBX=%x, ECX=%x, EDX=%x.\n",EAX,EBX,ECX,EDX));
925 +       //g_instruction_display_count = 10;
926 +}
927 +
928 +void BX_CPU_C::TT_TaintRestoreRegs(bxInstruction_c *i) {
929 +       assert(savedRegsStackInitialized);
930 +       //mylog(D1,("%s %d: ECX=%x, EDX=%x\n",__func__,__LINE__,ECX,EDX));
931 +       EDX = pop(&savedRegsStack);
932 +       ECX = pop(&savedRegsStack);
933 +       EBX = pop(&savedRegsStack);
934 +       EAX = pop(&savedRegsStack);
935 +       //DBG(L1,("popping EAX=%x, EBX=%x, ECX=%x, EDX=%x.\n",EAX,EBX,ECX,EDX));
936 +}
937 +
938 +Bit32u
939 +BX_CPU_C::thread_current(void) {
940 +    unsigned kernelPL = 0;
941 +    Bit32u pid;
942 +    if (CPL==kernelPL) {
943 +       //pid = (ESP & 0xffffe000);
944 +       pid = ((ESP-1) & ~PGMASK);      //subtract 1 so that we do not get incorrect pid, if stack is empty
945 +    } else {
946 +       /*Bit32u esp;
947 +       Bit16u ss;
948 +       get_SS_ESP_from_TSS(kernelPL,&ss,&esp);
949 +       pid = esp;*/
950 +    }
951 +    return pid;
952 +}
953 +
954 +char *BX_CPU_C::backtrace(char *s) {
955 +    Bit32u ebp, eip;
956 +    int stackdepth = 0, readsuccessful = 1;
957 +    char tmp[17];
958 +    //printf("EIP = %x.\n",EIP);
959 +    snprintf(s,16,"%x ",EIP);
960 +    ebp = EBP;
961 +    //while (ebp>0xc0000000 && stackdepth<10 && readsuccessful) {
962 +    while (ebp>0xc0000000 && stackdepth<10) {
963 +       readsuccessful &= read_virtual_dword_silent(BX_SEG_REG_SS, ebp+4, &eip);
964 +       readsuccessful &= read_virtual_dword_silent(BX_SEG_REG_SS, ebp, &ebp);
965 +        snprintf(tmp,16,"%x ",eip);
966 +       s = strncat(s,tmp,16);
967 +       stackdepth++;
968 +    }
969 +    return s;
970 +}
971 +
972 +Bit32u BX_CPU_C::callingEIP(void) {
973 +    Bit32u ebp, eip;
974 +    int stackdepth = 0, readsuccessful = 1;
975 +    char tmp[17];
976 +    ebp = EBP;
977 +    readsuccessful = read_virtual_dword_silent(BX_SEG_REG_SS, ebp+4, &eip);
978 +    if (readsuccessful) return eip;
979 +    else return 0;
980 +}
981 +
982 +void checkbochs_log (const char *fmt, ...)
983 +{
984 +       va_list ap;
985 +
986 +       if (!g_logfp) {
987 +           return ;
988 +       }
989 +       va_start (ap, fmt) ;
990 +       vfprintf (g_logfp, fmt, ap) ;
991 +       va_end (ap) ;
992 +}
993 diff -urpN bochs-2.1.1.orig/taint/common.cc.bak checkbochs-2.1.1/taint/common.cc.bak
994 diff -urpN bochs-2.1.1.orig/taint/eraser.cc checkbochs-2.1.1/taint/eraser.cc
995 --- bochs-2.1.1.orig/taint/eraser.cc    1969-12-31 16:00:00.000000000 -0800
996 +++ checkbochs-2.1.1/taint/eraser.cc    2005-06-29 11:19:16.000000000 -0700
997 @@ -0,0 +1,240 @@
998 +#define NEED_CPU_REG_SHORTCUTS 1
999 +#include "bochs.h"
1000 +#define LOG_THIS BX_CPU_THIS_PTR
1001 +
1002 +#if BX_USE_CPU_SMF
1003 +#define this (BX_CPU(0))
1004 +#endif
1005 +
1006 +#define PHYS_BASE      0xc0000000
1007 +
1008 +#include "mydebug.h"
1009 +#include "taint_type.h"
1010 +#include "lockset.h"
1011 +#include "hash.h"
1012 +#include "eraser.h"
1013 +#include "globals.h"
1014 +#include "mydebug.h"
1015 +
1016 +void breakme() {}
1017 +
1018 +#define WRN_UNINIT(loc) do {  \
1019 +    /* DBG(WRN,("Thread %x: Read on uninitialized location %x, backtrace: %s\n",myid,loc, backtrace(btstr))); */ \
1020 +} while (0)
1021 +
1022 +#define WRN_ERASER(myid,loc,tval) do {  \
1023 +    if (!already_warned(loc)) { \
1024 +        warn(loc); \
1025 +       DBG(WRN,("Thread %x: Warning on location %x, backtrace: %s\n",myid,loc, backtrace(btstr))); \
1026 +       breakme(); \
1027 +    } \
1028 +} while (0)
1029 +
1030 +struct warn_table_entry {
1031 +    unsigned loc;
1032 +    hash_elem h_elem;
1033 +};
1034 +
1035 +static int warn_table_initialized = 0;
1036 +static struct hash warn_table ;
1037 +
1038 +unsigned warn_hash (const hash_elem *e, void *aux)
1039 +{
1040 +    struct warn_table_entry *h = hash_entry (e, struct warn_table_entry, h_elem);
1041 +    return h->loc;
1042 +}
1043 +
1044 +bool
1045 +warn_less (const hash_elem *a_, const hash_elem *b_,
1046 +                       void *aux)
1047 +{
1048 +    struct warn_table_entry *a = hash_entry (a_, struct warn_table_entry, h_elem);
1049 +    struct warn_table_entry *b = hash_entry (b_, struct warn_table_entry, h_elem);
1050 +    return (a->loc < b->loc);
1051 +}
1052 +
1053 +static int
1054 +already_warned(unsigned loc) {
1055 +    struct warn_table_entry tmp;
1056 +    hash_elem *h_element;
1057 +    if (!warn_table_initialized) return 0;
1058 +    tmp.loc = loc;
1059 +    h_element = hash_find(&warn_table, &tmp.h_elem);
1060 +    if (h_element) return 1;
1061 +    else return 0;
1062 +}
1063 +
1064 +static int
1065 +warn(unsigned loc) {
1066 +    struct warn_table_entry *tmp = (struct warn_table_entry*)malloc(sizeof(struct warn_table_entry));
1067 +    if (!warn_table_initialized) {
1068 +       hash_init(&warn_table, warn_hash, warn_less, NULL);
1069 +       warn_table_initialized = 1;
1070 +    }
1071 +    tmp->loc = loc;
1072 +    hash_insert(&warn_table, &tmp->h_elem);
1073 +}
1074 +
1075 +
1076 +void BX_CPU_C::TT_Lock(bxInstruction_c *i) {
1077 +    Bit32u opId = i->Id();
1078 +    if (opId!=ERASER_ID) return;
1079 +
1080 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1081 +    DBG(LOCKS,("%x: acquiring lock %x. backtrace: %s\n",myid,ECX,backtrace(btstr)));
1082 +    eraser_lock(ECX);
1083 +    //lockset_t lset = add_lock(cur_held(myid),ECX);
1084 +    //update_lockset(myid,lset);
1085 +}
1086 +
1087 +void BX_CPU_C::TT_Unlock(bxInstruction_c *i) {
1088 +    Bit32u opId = i->Id();
1089 +    if (opId!=ERASER_ID) return;
1090 +
1091 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1092 +    DBG(LOCKS,("%x: releasing lock %x. backtrace: %s\n",myid,ECX,backtrace(btstr)));
1093 +    eraser_unlock(ECX);
1094 +    //Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1095 +    //lockset_t lset = remove_lock(cur_held(myid),ECX);
1096 +    //update_lockset(myid,lset);
1097 +}
1098 +
1099 +void BX_CPU_C::eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *notused) {
1100 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1101 +    Bit32u taintval[4], origval;
1102 +    int i, try_access;
1103 +    if (ignore_on(myid)) return;
1104 +    if (laddr + len <= PHYS_BASE) return ;
1105 +    if (laddr < PHYS_BASE) {
1106 +       len -= (PHYS_BASE-laddr) ;
1107 +       laddr = PHYS_BASE ;
1108 +    }
1109 +    DBG (ACCESS_LINEAR, ("%s() %d: entry. laddr=%x, len=%x, rw=%x\n",__func__,__LINE__,laddr,len,rw)) ;
1110 +    if (!BX_CPU_THIS_PTR get_IF()) {
1111 +       eraser_lock(INTERRUPT_LOCK); //acquire a dummy lock for disabled interrupts
1112 +       assert(cur_held(myid)!=0);
1113 +    }
1114 +    if (BX_CPU_THIS_PTR curInstruction->isLocked()) {
1115 +        DBG(LOCKS,("acquiring HW_PREFIX_LOCK. laddr=%x, len=%d.\n",laddr,len));
1116 +       eraser_lock(HW_PREFIX_LOCK); //acquire a dummy lock for h/w prefix "LOCK"
1117 +       assert(cur_held(myid)!=0);
1118 +    }
1119 +
1120 +    for (i=0;i<len;i++) {
1121 +        //taintval[i] = 0x0;
1122 +       try_access = access_linear_taint(laddr+i,1,pl,BX_READ,&taintval[i]);
1123 +       ASSERT(try_access);
1124 +       origval = taintval[i];
1125 +       if (get_state(taintval[i])==VIRGIN) {
1126 +           if (rw==BX_WRITE || rw==BX_RW) {
1127 +               taintval[i] = set_state(taintval[i], EXCLUSIVE);
1128 +               taintval[i] = set_value(taintval[i], myid);
1129 +               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)));
1130 +           } else {
1131 +               WRN_UNINIT(laddr) ;
1132 +           }
1133 +       }
1134 +       else if (get_state(taintval[i])==EXCLUSIVE) {
1135 +           if (get_value(taintval[i])!=myid) {
1136 +               taintval[i] =  set_value(taintval[i],cur_held(myid));
1137 +               if (rw==BX_WRITE || rw==BX_RW) {
1138 +                   taintval[i] = set_state(taintval[i],SHARED_MOD);
1139 +                   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)));
1140 +               } else {
1141 +                   taintval[i] = set_state(taintval[i],SHARED);
1142 +                   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)));
1143 +               }
1144 +           }
1145 +       }
1146 +       else if (get_state(taintval[i])==SHARED) {
1147 +           taintval[i] = set_value(taintval[i],intersect_locksets(get_value(taintval[i]),cur_held(myid)));
1148 +           if (rw==BX_WRITE || rw==BX_RW) {
1149 +               taintval[i] = set_state(taintval[i],SHARED_MOD);
1150 +               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)));
1151 +           } else
1152 +           if (origval!=taintval[i]) {
1153 +               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)));
1154 +           }
1155 +       }
1156 +       else if (get_state(taintval[i])==SHARED_MOD) {
1157 +           taintval[i] = set_value(taintval[i],intersect_locksets(get_value(taintval[i]),cur_held(myid)));
1158 +           if (origval!=taintval[i]) {
1159 +               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)));
1160 +           }
1161 +       }
1162 +
1163 +       /* Update the taintval in shadow memory */
1164 +       if (origval!=taintval[i]) {
1165 +           try_access = access_linear_taint(laddr+i,1,pl,BX_WRITE,
1166 +                                            &taintval[i]);
1167 +           ASSERT(try_access);
1168 +       }
1169 +
1170 +       /* Warn if needed */
1171 +       if (get_state(taintval[i])==SHARED_MOD && get_value(taintval[i])==LOCKSET_EMPTY) WRN_ERASER(myid,laddr+i,taintval[i]);
1172 +    }
1173 +    if (!BX_CPU_THIS_PTR get_IF()) eraser_unlock(INTERRUPT_LOCK); //release the lock that I had earlier acquired (to avoid duplicates)
1174 +
1175 +    if (BX_CPU_THIS_PTR curInstruction->isLocked()) {
1176 +        DBG(LOCKS,("releasing HW_PREFIX_LOCK. laddr=%x, len=%d.\n",laddr,len));
1177 +       eraser_unlock(HW_PREFIX_LOCK);
1178 +    }
1179 +}
1180 +
1181 +void BX_CPU_C::TT_CommonOps(bxInstruction_c *i) {
1182 +    Bit32u opId = i->Id();
1183 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1184 +    if (opId!=ERASER_ID) return;
1185 +
1186 +    if (EAX==IGNORE_OP) {
1187 +       for (int i=0;i<ECX;i++) warn(EDX+i);
1188 +       DBG(L1,("ignoring location %x (%d).\n",EDX,ECX));
1189 +    }
1190 +    else if (EAX==LOCKINIT_OP) {
1191 +       eraser_init(ECX);
1192 +    }
1193 +    else if (EAX==IGNOREON_OP) {
1194 +       if (global_startup_ignore) {
1195 +           return ;
1196 +       }
1197 +       set_ignore(myid,true);
1198 +       DBG(L1,("setting ignore on for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
1199 +    }
1200 +    else if (EAX==IGNOREOFF_OP) {
1201 +       if (global_startup_ignore) {
1202 +           return ;
1203 +       }
1204 +       set_ignore(myid,false);
1205 +       DBG(L1,("setting ignore off for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
1206 +    }
1207 +    else if (EAX==REUSE_OP) {
1208 +        Bit32u taintval = 0;
1209 +       int pl = 0;     //kernel privileges
1210 +       DBG(L1,("%x: reusing location %x (%d). ESP=%x\n",myid,EDX,ECX,ESP));
1211 +       for (int i=0;i<ECX;i++) {
1212 +           int ret = access_linear_taint(EDX+i,1,pl,BX_WRITE,&taintval);
1213 +           if (ret==0) DBG(L1,("reuse on location %x failed.\n",EDX+i));
1214 +       }
1215 +    } else if (EAX==DBG_MARK_OP) {
1216 +        Bit32u taintval = 0;
1217 +       char str[MAX_STRLEN];
1218 +       int pl = 0;     //kernel privileges
1219 +       int ret, i=0;
1220 +       do {
1221 +           ret = access_linear_silent(EDX+i,1,pl,BX_READ,&str[i]) ;
1222 +       } while (ret && str[i] && ++i<MAX_STRLEN);
1223 +       str[i] = '\0';
1224 +       DBG(L1,("%x: dbg mark at %s:%d. EIP=%x\n",myid,str,ECX,EIP));
1225 +    } else if (EAX==GLOBAL_STARTUP_IGNOREOFF_OP) {
1226 +       assert (global_startup_ignore) ;
1227 +       global_startup_ignore = false ;
1228 +       DBG(L1,("%x: setting global_startup_ignore to off\n",myid));
1229 +    }
1230 +}
1231 +
1232 +void BX_CPU_C::eraser_init_globals(void) {
1233 +    g_logfp = fopen (g_logfn, "w") ;
1234 +    if (g_logfp==NULL) {
1235 +       DBG (ERR, ("%s(): Error opening checkbochs log %s for writing.\n",__func__,g_logfn)) ;
1236 +    }
1237 +}
1238 diff -urpN bochs-2.1.1.orig/taint/eraser.cc.bak checkbochs-2.1.1/taint/eraser.cc.bak
1239 diff -urpN bochs-2.1.1.orig/taint/eraser.h checkbochs-2.1.1/taint/eraser.h
1240 --- bochs-2.1.1.orig/taint/eraser.h     1969-12-31 16:00:00.000000000 -0800
1241 +++ checkbochs-2.1.1/taint/eraser.h     2005-06-29 11:19:16.000000000 -0700
1242 @@ -0,0 +1,37 @@
1243 +#ifndef __ERASER_H
1244 +#define __ERASER_H
1245 +
1246 +#define IGNORE_OP 0
1247 +#define LOCKINIT_OP 1
1248 +#define IGNOREON_OP 2
1249 +#define IGNOREOFF_OP 3
1250 +#define REUSE_OP 4
1251 +#define DBG_MARK_OP 5
1252 +#define GLOBAL_STARTUP_IGNOREOFF_OP 6
1253 +
1254 +#define eraser_lock(x) do {    \
1255 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;       \
1256 +    lockset_t lset = add_lock(cur_held(myid),x);       \
1257 +    update_lockset(myid,lset); \
1258 +}  while (0);
1259 +
1260 +#define eraser_unlock(x) do {  \
1261 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff; \
1262 +    lockset_t lset = remove_lock(cur_held(myid),x); \
1263 +    update_lockset(myid,lset); \
1264 +} while (0);
1265 +
1266 +#define eraser_init(x) do {    \
1267 +    Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff; \
1268 +    lockset_t mylocks = cur_held(myid); \
1269 +    lockset_t lset; \
1270 +    if (belongs(mylocks,x)) { \
1271 +       lset = remove_lock(mylocks,x); \
1272 +       update_lockset(myid,lset); \
1273 +    } \
1274 +} while (0);
1275 +
1276 +#define INTERRUPT_LOCK 0x1234
1277 +#define HW_PREFIX_LOCK 0x2345
1278 +
1279 +#endif
1280 diff -urpN bochs-2.1.1.orig/taint/eraser.h.bak checkbochs-2.1.1/taint/eraser.h.bak
1281 diff -urpN bochs-2.1.1.orig/taint/globals.cc checkbochs-2.1.1/taint/globals.cc
1282 --- bochs-2.1.1.orig/taint/globals.cc   1969-12-31 16:00:00.000000000 -0800
1283 +++ checkbochs-2.1.1/taint/globals.cc   2005-06-29 11:19:16.000000000 -0700
1284 @@ -0,0 +1,13 @@
1285 +#define NEED_CPU_REG_SHORTCUTS 1
1286 +#include "bochs.h"
1287 +#define LOG_THIS BX_CPU_THIS_PTR
1288 +
1289 +#include "taint/globals.h"
1290 +
1291 +void (*g_access_linear_fptr)(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value) = NULL;
1292 +
1293 +char btstr[512];       //a global string to print the backtrace
1294 +int disassemble_num = 0;
1295 +bool global_startup_ignore = true ;
1296 +FILE *g_logfp = NULL ;
1297 +char g_logfn [128] = "checkbochs.log" ;
1298 diff -urpN bochs-2.1.1.orig/taint/globals.cc.bak checkbochs-2.1.1/taint/globals.cc.bak
1299 diff -urpN bochs-2.1.1.orig/taint/globals.h checkbochs-2.1.1/taint/globals.h
1300 --- bochs-2.1.1.orig/taint/globals.h    1969-12-31 16:00:00.000000000 -0800
1301 +++ checkbochs-2.1.1/taint/globals.h    2005-06-29 11:19:16.000000000 -0700
1302 @@ -0,0 +1,15 @@
1303 +#ifndef __GLOBALS_H
1304 +#define __GLOBALS_H
1305 +
1306 +#define MAX_STRLEN 128
1307 +
1308 +extern void (*g_access_linear_fptr)(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value);
1309 +extern char btstr[512];        //a global string to print the backtrace
1310 +
1311 +extern bool global_startup_ignore ;
1312 +extern int disassemble_num ;
1313 +
1314 +extern FILE *g_logfp ;
1315 +extern char g_logfn[128] ;
1316 +
1317 +#endif
1318 diff -urpN bochs-2.1.1.orig/taint/globals.h.bak checkbochs-2.1.1/taint/globals.h.bak
1319 diff -urpN bochs-2.1.1.orig/taint/hash.cc checkbochs-2.1.1/taint/hash.cc
1320 --- bochs-2.1.1.orig/taint/hash.cc      1969-12-31 16:00:00.000000000 -0800
1321 +++ checkbochs-2.1.1/taint/hash.cc      2005-06-29 11:19:16.000000000 -0700
1322 @@ -0,0 +1,353 @@
1323 +#include <stdlib.h>
1324 +#include <stdio.h>
1325 +#include <assert.h>
1326 +#include "hash.h"
1327 +
1328 +static struct list *find_bucket (struct hash *, hash_elem *);
1329 +static struct list_elem *find_elem (struct hash *, struct list *, hash_elem *);
1330 +static void insert_elem (struct hash *, struct list *, hash_elem *);
1331 +static void remove_elem (struct hash *, hash_elem *);
1332 +static void rehash (struct hash *);
1333 +
1334 +/* Initializes hash table H to compute hash values using HASH and
1335 +   compare hash elements using LESS, given auxiliary data AUX.
1336 +   this function can sleep on malloc. hence, CANNOT be called from thread_init.
1337 + */
1338 +bool
1339 +hash_init (struct hash *h,
1340 +           hash_hash_func *hash, hash_less_func *less, void *aux) 
1341 +{
1342 +  h->elem_cnt = 0;
1343 +  h->bucket_cnt = 4;
1344 +  h->buckets = (list *)(malloc (sizeof *h->buckets * h->bucket_cnt));
1345 +  h->hash = hash;
1346 +  h->less = less;
1347 +  h->aux = aux;
1348 +
1349 +  if (h->buckets != NULL) 
1350 +    {
1351 +      hash_clear (h);
1352 +      return true;
1353 +    }
1354 +  else
1355 +    return false;
1356 +}
1357 +
1358 +/* Removes all the elements from H. */
1359 +void
1360 +hash_clear (struct hash *h) 
1361 +{
1362 +  size_t i;
1363 +      
1364 +  for (i = 0; i < h->bucket_cnt; i++) 
1365 +    list_init (&h->buckets[i]);
1366 +  h->elem_cnt = 0;
1367 +}
1368 +
1369 +/* Destroys hash table H. */
1370 +void
1371 +hash_destroy (struct hash *h) 
1372 +{
1373 +  free (h->buckets);
1374 +}
1375 +
1376 +/* Inserts NEW into hash table H and returns a null pointer, if
1377 +   no equal element is already in the table.
1378 +   If an equal element is already in the table, returns it
1379 +   without inserting NEW. */   
1380 +hash_elem *
1381 +hash_insert (struct hash *h, hash_elem *newelem)
1382 +{
1383 +  struct list *bucket = find_bucket (h, newelem);
1384 +  struct list_elem *old = find_elem (h, bucket, newelem);
1385 +
1386 +  if (old == NULL) 
1387 +    insert_elem (h, bucket, newelem);
1388 +
1389 +  rehash (h);
1390 +
1391 +  return old; 
1392 +}
1393 +
1394 +/* Inserts NEW into hash table H, replacing any equal element
1395 +   already in the table, which is returned. */
1396 +hash_elem *
1397 +hash_replace (struct hash *h, hash_elem *newelem) 
1398 +{
1399 +  struct list *bucket = find_bucket (h, newelem);
1400 +  struct list_elem *old = find_elem (h, bucket, newelem);
1401 +
1402 +  if (old != NULL)
1403 +    remove_elem (h, old);
1404 +  insert_elem (h, bucket, newelem);
1405 +
1406 +  rehash (h);
1407 +
1408 +  return old;
1409 +}
1410 +
1411 +/* Finds and returns an element equal to E in hash table H, or a
1412 +   null pointer if no equal element exists in the table. */
1413 +hash_elem *
1414 +hash_find (struct hash *h, hash_elem *e) 
1415 +{
1416 +  return find_elem (h, find_bucket (h, e), e);
1417 +}
1418 +
1419 +/* Finds, removes, and returns an element equal to E in hash
1420 +   table H.  Returns a null pointer if no equal element existed
1421 +   in the table. */
1422 +hash_elem *
1423 +hash_delete (struct hash *h, hash_elem *e)
1424 +{
1425 +  struct list_elem *found = find_elem (h, find_bucket (h, e), e);
1426 +  if (found != NULL) 
1427 +    {
1428 +      remove_elem (h, found);
1429 +      rehash (h); 
1430 +    }
1431 +  return found;
1432 +}
1433 +
1434 +/* Initializes I for iterating hash table H.
1435 +
1436 +   Iteration idiom:
1437 +
1438 +      struct hash_iterator i;
1439 +
1440 +      hash_first (&i, h);
1441 +      while (hash_next (&i))
1442 +        {
1443 +          struct foo *f = hash_entry (hash_cur (&i), struct foo, elem);
1444 +          ...do something with f...
1445 +        }
1446 +
1447 +   NOTE: Modifying a hash table during iteration invalidates all
1448 +   iterators.
1449 +*/
1450 +void
1451 +hash_first (struct hash_iterator *i, struct hash *h) 
1452 +{
1453 +  assert (i != NULL);
1454 +  assert (h != NULL);
1455 +
1456 +  i->hash = h;
1457 +  i->bucket = i->hash->buckets;
1458 +  i->elem = list_head (i->bucket);
1459 +}
1460 +
1461 +/* Advances I to the next element in the hash table and returns
1462 +   it.  Returns a null pointer if no elements are left.  Elements
1463 +   are returned in arbitrary order.
1464 +
1465 +   NOTE: Modifying a hash table during iteration invalidates all
1466 +   iterators. */
1467 +hash_elem *
1468 +hash_next (struct hash_iterator *i)
1469 +{
1470 +  assert (i != NULL);
1471 +
1472 +  i->elem = list_next (i->elem);
1473 +  while (i->elem == list_end (i->bucket)) 
1474 +    {
1475 +      if (++i->bucket >= i->hash->buckets + i->hash->bucket_cnt)
1476 +        {
1477 +          i->elem = NULL;
1478 +          break;
1479 +        }
1480 +      i->elem = list_begin (i->bucket);
1481 +    }
1482 +  
1483 +  return i->elem;
1484 +}
1485 +
1486 +/* Returns the current element in the hash table iteration, or a
1487 +   null pointer at the end of the table.  Undefined behavior
1488 +   after calling hash_first() but before hash_next(). */
1489 +hash_elem *
1490 +hash_cur (struct hash_iterator *i) 
1491 +{
1492 +  return i->elem;
1493 +}
1494 +
1495 +/* Returns the number of elements in H. */
1496 +size_t
1497 +hash_size (struct hash *h) 
1498 +{
1499 +  return h->elem_cnt;
1500 +}
1501 +
1502 +/* Returns true if H contains no elements, false otherwise. */
1503 +bool
1504 +hash_empty (struct hash *h) 
1505 +{
1506 +  return h->elem_cnt == 0;
1507 +}
1508 +
1509 +/* Fowler-Noll-Vo hash constants, for 32-bit word sizes. */
1510 +#define FNV_32_PRIME 16777619u
1511 +#define FNV_32_BASIS 2166136261u
1512 +
1513 +/* Returns a hash of the SIZE bytes in BUF. */
1514 +unsigned
1515 +hash_bytes (const void *buf_, size_t size)
1516 +{
1517 +  /* Fowler-Noll-Vo 32-bit hash, for bytes. */
1518 +  const unsigned char *buf = (unsigned char *)buf_;
1519 +  unsigned hash;
1520 +
1521 +  assert (buf != NULL);
1522 +
1523 +  hash = FNV_32_BASIS;
1524 +  while (size-- > 0)
1525 +    hash = (hash * FNV_32_PRIME) ^ *buf++;
1526 +
1527 +  return hash;
1528 +} 
1529 +
1530 +/* Returns a hash of string S. */
1531 +unsigned
1532 +hash_string (const char *s_) 
1533 +{
1534 +  const unsigned char *s = (unsigned char *)s_;
1535 +  unsigned hash;
1536 +
1537 +  assert (s != NULL);
1538 +
1539 +  hash = FNV_32_BASIS;
1540 +  while (*s != '\0')
1541 +    hash = (hash * FNV_32_PRIME) ^ *s++;
1542 +
1543 +  return hash;
1544 +}
1545 +
1546 +/* Returns a hash of integer I. */
1547 +unsigned
1548 +hash_int (int i) 
1549 +{
1550 +  return hash_bytes (&i, sizeof i);
1551 +}
1552 +\f
1553 +/* Returns the bucket in H that E belongs in. */
1554 +static struct list *
1555 +find_bucket (struct hash *h, hash_elem *e) 
1556 +{
1557 +  size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
1558 +  return &h->buckets[bucket_idx];
1559 +}
1560 +
1561 +/* Searches BUCKET in H for a hash element equal to E.  Returns
1562 +   it if found or a null pointer otherwise. */
1563 +static struct list_elem *
1564 +find_elem (struct hash *h, struct list *bucket, hash_elem *e) 
1565 +{
1566 +  struct list_elem *i;
1567 +
1568 +  for (i = list_begin (bucket); i != list_end (bucket); i = list_next (i)) 
1569 +    if (!h->less (i, e, h->aux) && !h->less (e, i, h->aux))
1570 +      return i; 
1571 +  return NULL;
1572 +}
1573 +
1574 +/* Returns X with its lowest-order bit set to 1 turned off. */
1575 +static inline size_t
1576 +turn_off_least_1bit (size_t x) 
1577 +{
1578 +  return x & (x - 1);
1579 +}
1580 +
1581 +/* Returns true if X is a power of 2, otherwise false. */
1582 +static inline size_t
1583 +is_power_of_2 (size_t x) 
1584 +{
1585 +  return x != 0 && turn_off_least_1bit (x) == 0;
1586 +}
1587 +
1588 +/* Element per bucket ratios. */
1589 +#define MIN_ELEMS_PER_BUCKET  1 /* Elems/bucket < 1: reduce # of buckets. */
1590 +#define BEST_ELEMS_PER_BUCKET 2 /* Ideal elems/bucket. */
1591 +#define MAX_ELEMS_PER_BUCKET  4 /* Elems/bucket > 4: increase # of buckets. */
1592 +
1593 +/* Changes the number of buckets in hash table H to match the
1594 +   ideal.  This function can fail because of an out-of-memory
1595 +   condition, but that'll just make hash accesses less efficient;
1596 +   we can still continue. */
1597 +static void
1598 +rehash (struct hash *h) 
1599 +{
1600 +  size_t old_bucket_cnt, new_bucket_cnt;
1601 +  struct list *new_buckets, *old_buckets;
1602 +  size_t i;
1603 +
1604 +  assert (h != NULL);
1605 +
1606 +  /* Save old bucket info for later use. */
1607 +  old_buckets = h->buckets;
1608 +  old_bucket_cnt = h->bucket_cnt;
1609 +
1610 +  /* Calculate the number of buckets to use now.
1611 +     We want one bucket for about every BEST_ELEMS_PER_BUCKET.
1612 +     We must have at least four buckets, and the number of
1613 +     buckets must be a power of 2. */
1614 +  new_bucket_cnt = h->elem_cnt / BEST_ELEMS_PER_BUCKET;
1615 +  if (new_bucket_cnt < 4)
1616 +    new_bucket_cnt = 4;
1617 +  while (!is_power_of_2 (new_bucket_cnt))
1618 +    new_bucket_cnt = turn_off_least_1bit (new_bucket_cnt);
1619 +
1620 +  /* Don't do anything if the bucket count wouldn't change. */
1621 +  if (new_bucket_cnt == old_bucket_cnt)
1622 +    return;
1623 +
1624 +  /* Allocate new buckets and initialize them as empty. */
1625 +  new_buckets = (struct list *)malloc (sizeof *new_buckets * new_bucket_cnt);
1626 +  if (new_buckets == NULL) 
1627 +    {
1628 +      /* Allocation failed.  This means that use of the hash table will
1629 +         be less efficient.  However, it is still usable, so
1630 +         there's no reason for it to be an error. */
1631 +      return;
1632 +    }
1633 +  for (i = 0; i < new_bucket_cnt; i++) 
1634 +    list_init (&new_buckets[i]);
1635 +
1636 +  /* Install new bucket info. */
1637 +  h->buckets = new_buckets;
1638 +  h->bucket_cnt = new_bucket_cnt;
1639 +
1640 +  /* Move each old element into the appropriate new bucket. */
1641 +  for (i = 0; i < old_bucket_cnt; i++) 
1642 +    {
1643 +      struct list *old_bucket;
1644 +      struct list_elem *elem, *next;
1645 +
1646 +      old_bucket = &old_buckets[i];
1647 +      for (elem = list_begin (old_bucket);
1648 +           elem != list_end (old_bucket); elem = next) 
1649 +        {
1650 +          struct list *new_bucket = find_bucket (h, elem);
1651 +          next = list_next (elem);
1652 +          list_remove (elem);
1653 +          list_push_front (new_bucket, elem);
1654 +        }
1655 +    }
1656 +
1657 +  free (old_buckets);
1658 +}
1659 +
1660 +/* Inserts E into BUCKET (in hash table H). */
1661 +static void
1662 +insert_elem (struct hash *h, struct list *bucket, hash_elem *e) 
1663 +{
1664 +  h->elem_cnt++;
1665 +  list_push_front (bucket, e);
1666 +}
1667 +
1668 +/* Removes E from hash table H. */
1669 +static void
1670 +remove_elem (struct hash *h, hash_elem *e) 
1671 +{
1672 +  h->elem_cnt--;
1673 +  list_remove (e);
1674 +}
1675 +
1676 diff -urpN bochs-2.1.1.orig/taint/hash.cc.bak checkbochs-2.1.1/taint/hash.cc.bak
1677 diff -urpN bochs-2.1.1.orig/taint/hash.h checkbochs-2.1.1/taint/hash.h
1678 --- bochs-2.1.1.orig/taint/hash.h       1969-12-31 16:00:00.000000000 -0800
1679 +++ checkbochs-2.1.1/taint/hash.h       2005-06-29 11:19:16.000000000 -0700
1680 @@ -0,0 +1,92 @@
1681 +#ifndef __HASH_H
1682 +#define __HASH_H
1683 +
1684 +/* Hash table.
1685 +
1686 +   This is a standard hash table with chaining.  To locate an
1687 +   element in the table, we compute a hash function over the
1688 +   element's data and use that as an index into an array of
1689 +   doubly linked lists, then linearly search the list.
1690 +
1691 +   The chain lists do not use dynamic allocation.  Instead, each
1692 +   structure that can potentially be in a hash must embed a
1693 +   hash_elem member.  All of the hash functions operate on these
1694 +   `hash_elem's.  The hash_entry macro allows conversion from a
1695 +   hash_elem back to a structure object that contains it.  This
1696 +   is the same technique used in the linked list implementation.
1697 +   Refer to lib/kernel/list.h for a detailed explanation.
1698 +
1699 +   The FAQ for the VM project contains a detailed example of how
1700 +   to use the hash table. */
1701 +
1702 +#include <stdbool.h>
1703 +#include <stddef.h>
1704 +#include <inttypes.h>
1705 +#include "list.h"
1706 +
1707 +/* Hash element. */
1708 +typedef list_elem hash_elem;
1709 +
1710 +/* Converts pointer to hash element HASH_ELEM into a pointer to
1711 +   the structure that HASH_ELEM is embedded inside.  Supply the
1712 +   name of the outer structure STRUCT and the member name MEMBER
1713 +   of the hash element.  See the big comment at the top of the
1714 +   file for an example. */
1715 +#define hash_entry(HASH_ELEM, STRUCT, MEMBER)                              \
1716 +        ((STRUCT *) ((uint8_t *) (HASH_ELEM) - offsetof (STRUCT, MEMBER)))
1717 +
1718 +/* Computes and returns the hash value for hash element E, given
1719 +   auxiliary data AUX. */
1720 +typedef unsigned hash_hash_func (const hash_elem *e, void *aux);
1721 +
1722 +/* Compares the value of two hash elements A and B, given
1723 +   auxiliary data AUX.  Returns true if A is less than B, or
1724 +   false if A is greater than or equal to B. */
1725 +typedef bool hash_less_func (const hash_elem *a, const hash_elem *b,
1726 +                             void *aux);
1727 +
1728 +/* Hash table. */
1729 +struct hash 
1730 +  {
1731 +    size_t elem_cnt;            /* Number of elements in table. */
1732 +    size_t bucket_cnt;          /* Number of buckets, a power of 2. */
1733 +    struct list *buckets;       /* Array of `bucket_cnt' lists. */
1734 +    hash_hash_func *hash;       /* Hash function. */
1735 +    hash_less_func *less;       /* Comparison function. */
1736 +    void *aux;                  /* Auxiliary data for `hash' and `less'. */
1737 +  };
1738 +
1739 +/* A hash table iterator. */
1740 +struct hash_iterator 
1741 +  {
1742 +    struct hash *hash;          /* The hash table. */
1743 +    struct list *bucket;        /* Current bucket. */
1744 +    hash_elem *elem;            /* Current hash element in current bucket. */
1745 +  };
1746 +
1747 +/* Basic life cycle. */
1748 +bool hash_init (struct hash *, hash_hash_func *, hash_less_func *, void *aux);
1749 +void hash_clear (struct hash *);
1750 +void hash_destroy (struct hash *);
1751 +
1752 +/* Search, insertion, deletion. */
1753 +hash_elem *hash_insert (struct hash *, hash_elem *);
1754 +hash_elem *hash_replace (struct hash *, hash_elem *);
1755 +hash_elem *hash_find (struct hash *, hash_elem *);
1756 +hash_elem *hash_delete (struct hash *, hash_elem *);
1757 +
1758 +/* Iteration. */
1759 +void hash_first (struct hash_iterator *, struct hash *);
1760 +hash_elem *hash_next (struct hash_iterator *);
1761 +hash_elem *hash_cur (struct hash_iterator *);
1762 +
1763 +/* Information. */
1764 +size_t hash_size (struct hash *);
1765 +bool hash_empty (struct hash *);
1766 +
1767 +/* Sample hash functions. */
1768 +unsigned hash_bytes (const void *, size_t);
1769 +unsigned hash_string (const char *);
1770 +unsigned hash_int (int);
1771 +
1772 +#endif /* lib/kernel/hash.h */
1773 diff -urpN bochs-2.1.1.orig/taint/hash.h.bak checkbochs-2.1.1/taint/hash.h.bak
1774 diff -urpN bochs-2.1.1.orig/taint/list.cc checkbochs-2.1.1/taint/list.cc
1775 --- bochs-2.1.1.orig/taint/list.cc      1969-12-31 16:00:00.000000000 -0800
1776 +++ checkbochs-2.1.1/taint/list.cc      2005-06-29 11:19:16.000000000 -0700
1777 @@ -0,0 +1,471 @@
1778 +#include <stdlib.h>
1779 +#include <assert.h>
1780 +#include "list.h"
1781 +
1782 +/* Our doubly linked lists have two header elements: the "head"
1783 +   just before the first element and the "tail" just after the
1784 +   last element.  The `prev' link of the front header is null, as
1785 +   is the `next' link of the back header.  Their other two links
1786 +   point toward each other via the interior elements of the list.
1787 +
1788 +   An empty list looks like this:
1789 +
1790 +                      +------+     +------+
1791 +                  <---| head |<--->| tail |--->
1792 +                      +------+     +------+
1793 +
1794 +   A list with two elements in it looks like this:
1795 +
1796 +        +------+     +-------+     +-------+     +------+
1797 +    <---| head |<--->|   1   |<--->|   2   |<--->| tail |<--->
1798 +        +------+     +-------+     +-------+     +------+
1799 +
1800 +   The symmetry of this arrangement eliminates lots of special
1801 +   cases in list processing.  For example, take a look at
1802 +   list_remove(): it takes only two pointer assignments and no
1803 +   conditionals.  That's a lot simpler than the code would be
1804 +   without header elements.
1805 +
1806 +   (Because only one of the pointers in each header element is used,
1807 +   we could in fact combine them into a single header element
1808 +   without sacrificing this simplicity.  But using two separate
1809 +   elements allows us to do a little bit of checking on some
1810 +   operations, which can be valuable.) */
1811 +
1812 +/* Returns true if ELEM is a head, false otherwise. */
1813 +inline bool
1814 +is_head (list_elem *elem)
1815 +{
1816 +  return elem != NULL && elem->prev == NULL && elem->next != NULL;
1817 +}
1818 +
1819 +/* Returns true if ELEM is an interior element,
1820 +   false otherwise. */
1821 +static inline bool
1822 +is_interior (list_elem *elem)
1823 +{
1824 +  return elem != NULL && elem->prev != NULL && elem->next != NULL;
1825 +}
1826 +
1827 +/* Returns true if ELEM is a tail, false otherwise. */
1828 +static inline bool
1829 +is_tail (list_elem *elem)
1830 +{
1831 +  return elem != NULL && elem->prev != NULL && elem->next == NULL;
1832 +}
1833 +
1834 +/* Initializes LIST as an empty list. */
1835 +void
1836 +list_init (struct list *list)
1837 +{
1838 +  assert (list != NULL);
1839 +  list->head.prev = NULL;
1840 +  list->head.next = &list->tail;
1841 +  list->tail.prev = &list->head;
1842 +  list->tail.next = NULL;
1843 +}
1844 +
1845 +/* Returns the beginning of LIST.  */
1846 +list_elem *
1847 +list_begin (struct list *list)
1848 +{
1849 +  assert (list != NULL);
1850 +  return list->head.next;
1851 +}
1852 +
1853 +/* Returns the element after ELEM in its list.  If ELEM is the
1854 +   last element in its list, returns the list tail.  Results are
1855 +   undefined if ELEM is itself a list tail. */
1856 +list_elem *
1857 +list_next (list_elem *elem)
1858 +{
1859 +  assert (is_head (elem) || is_interior (elem));
1860 +  return elem->next;
1861 +}
1862 +
1863 +/* Returns LIST's tail.
1864 +
1865 +   list_end() is often used in iterating through a list from
1866 +   front to back.  See the big comment at the top of list.h for
1867 +   an example. */
1868 +list_elem *
1869 +list_end (struct list *list)
1870 +{
1871 +  assert (list != NULL);
1872 +  return &list->tail;
1873 +}
1874 +
1875 +/* Returns the LIST's reverse beginning, for iterating through
1876 +   LIST in reverse order, from back to front. */
1877 +list_elem *
1878 +list_rbegin (struct list *list) 
1879 +{
1880 +  assert (list != NULL);
1881 +  return list->tail.prev;
1882 +}
1883 +
1884 +/* Returns the element before ELEM in its list.  If ELEM is the
1885 +   first element in its list, returns the list head.  Results are
1886 +   undefined if ELEM is itself a list head. */
1887 +list_elem *
1888 +list_prev (list_elem *elem)
1889 +{
1890 +  assert (is_interior (elem) || is_tail (elem));
1891 +  return elem->prev;
1892 +}
1893 +
1894 +/* Returns LIST's head.
1895 +
1896 +   list_rend() is often used in iterating through a list in
1897 +   reverse order, from back to front.  Here's typical usage,
1898 +   following the example from the top of list.h:
1899 +
1900 +      for (e = list_rbegin (&foo_list); e != list_rend (&foo_list);
1901 +           e = list_prev (e))
1902 +        {
1903 +          struct foo *f = list_entry (e, struct foo, elem);
1904 +          ...do something with f...
1905 +        }
1906 +*/
1907 +list_elem *
1908 +list_rend (struct list *list) 
1909 +{
1910 +  assert (list != NULL);
1911 +  return &list->head;
1912 +}
1913 +
1914 +/* Return's LIST's head.
1915 +
1916 +   list_head() can be used for an alternate style of iterating
1917 +   through a list, e.g.:
1918 +
1919 +      e = list_head (&list);
1920 +      while ((e = list_next (e)) != list_end (&list)) 
1921 +        {
1922 +          ...
1923 +        }
1924 +*/
1925 +list_elem *
1926 +list_head (struct list *list) 
1927 +{
1928 +  assert (list != NULL);
1929 +  return &list->head;
1930 +}
1931 +
1932 +/* Return's LIST's tail. */
1933 +list_elem *
1934 +list_tail (struct list *list) 
1935 +{
1936 +  assert (list != NULL);
1937 +  return &list->tail;
1938 +}
1939 +
1940 +/* Inserts ELEM just before BEFORE, which may be either an
1941 +   interior element or a tail.  The latter case is equivalent to
1942 +   list_push_back(). */
1943 +void
1944 +list_insert (list_elem *before, list_elem *elem)
1945 +{
1946 +  assert (is_interior (before) || is_tail (before));
1947 +  assert (elem != NULL);
1948 +
1949 +  elem->prev = before->prev;
1950 +  elem->next = before;
1951 +  before->prev->next = elem;
1952 +  before->prev = elem;
1953 +}
1954 +
1955 +/* Removes elements FIRST though LAST (exclusive) from their
1956 +   current list, then inserts them just before BEFORE, which may
1957 +   be either an interior element or a tail. */
1958 +void
1959 +list_splice (list_elem *before,
1960 +             list_elem *first, list_elem *last)
1961 +{
1962 +  assert (is_interior (before) || is_tail (before));
1963 +  if (first == last)
1964 +    return;
1965 +  last = list_prev (last);
1966 +
1967 +  assert (is_interior (first));
1968 +  assert (is_interior (last));
1969 +
1970 +  /* Cleanly remove FIRST...LAST from its current list. */
1971 +  first->prev->next = last->next;
1972 +  last->next->prev = first->prev;
1973 +
1974 +  /* Splice FIRST...LAST into new list. */
1975 +  first->prev = before->prev;
1976 +  last->next = before;
1977 +  before->prev->next = first;
1978 +  before->prev = last;
1979 +}
1980 +
1981 +/* Inserts ELEM at the beginning of LIST, so that it becomes the
1982 +   front in LIST. */
1983 +void
1984 +list_push_front (struct list *list, list_elem *elem)
1985 +{
1986 +  list_insert (list_begin (list), elem);
1987 +}
1988 +
1989 +/* Inserts ELEM at the end of LIST, so that it becomes the
1990 +   back in LIST. */
1991 +void
1992 +list_push_back (struct list *list, list_elem *elem)
1993 +{
1994 +  list_insert (list_end (list), elem);
1995 +}
1996 +
1997 +/* Removes ELEM from its list and returns the element that
1998 +   followed it.  Undefined behavior if ELEM is not in a list.  */
1999 +list_elem *
2000 +list_remove (list_elem *elem)
2001 +{
2002 +  assert (is_interior (elem));
2003 +  elem->prev->next = elem->next;
2004 +  elem->next->prev = elem->prev;
2005 +  return elem->next;
2006 +}
2007 +
2008 +/* Removes the front element from LIST and returns it.
2009 +   Undefined behavior if LIST is empty before removal. */
2010 +list_elem *
2011 +list_pop_front (struct list *list)
2012 +{
2013 +  list_elem *front = list_front (list);
2014 +  list_remove (front);
2015 +  return front;
2016 +}
2017 +
2018 +/* Removes the back element from LIST and returns it.
2019 +   Undefined behavior if LIST is empty before removal. */
2020 +list_elem *
2021 +list_pop_back (struct list *list)
2022 +{
2023 +  list_elem *back = list_back (list);
2024 +  list_remove (back);
2025 +  return back;
2026 +}
2027 +
2028 +/* Returns the front element in LIST.
2029 +   Undefined behavior if LIST is empty. */
2030 +list_elem *
2031 +list_front (struct list *list)
2032 +{
2033 +  assert (!list_empty (list));
2034 +  return list->head.next;
2035 +}
2036 +
2037 +/* Returns the back element in LIST.
2038 +   Undefined behavior if LIST is empty. */
2039 +list_elem *
2040 +list_back (struct list *list)
2041 +{
2042 +  assert (!list_empty (list));
2043 +  return list->tail.prev;
2044 +}
2045 +
2046 +/* Returns the number of elements in LIST.
2047 +   Runs in O(n) in the number of elements. */
2048 +size_t
2049 +list_size (struct list *list)
2050 +{
2051 +  list_elem *e;
2052 +  size_t cnt = 0;
2053 +
2054 +  for (e = list_begin (list); e != list_end (list); e = list_next (e))
2055 +    cnt++;
2056 +  return cnt;
2057 +}
2058 +
2059 +/* Returns true if LIST is empty, false otherwise. */
2060 +bool
2061 +list_empty (struct list *list)
2062 +{
2063 +  return list_begin (list) == list_end (list);
2064 +}
2065 +
2066 +/* Swaps the `list_elem *'s that A and B point to. */
2067 +static void
2068 +swap (list_elem **a, list_elem **b) 
2069 +{
2070 +  list_elem *t = *a;
2071 +  *a = *b;
2072 +  *b = t;
2073 +}
2074 +
2075 +/* Reverses the order of LIST. */
2076 +void
2077 +list_reverse (struct list *list)
2078 +{
2079 +  if (!list_empty (list)) 
2080 +    {
2081 +      list_elem *e;
2082 +
2083 +      for (e = list_begin (list); e != list_end (list); e = e->prev)
2084 +        swap (&e->prev, &e->next);
2085 +      swap (&list->head.next, &list->tail.prev);
2086 +      swap (&list->head.next->prev, &list->tail.prev->next);
2087 +    }
2088 +}
2089 +
2090 +/* Merges lists AL and BL, which must each be sorted according to
2091 +   LESS given auxiliary data AUX, by inserting each element of BL
2092 +   at the proper place in AL to preserve the ordering.
2093 +   Runs in O(n) in the combined length of AL and BL. */
2094 +void
2095 +list_merge (struct list *al, struct list *bl,
2096 +            list_less_func *less, void *aux)
2097 +{
2098 +  list_elem *a;
2099 +
2100 +  assert (al != NULL);
2101 +  assert (bl != NULL);
2102 +  assert (less != NULL);
2103 +
2104 +  a = list_begin (al);
2105 +  while (a != list_end (al))
2106 +    {
2107 +      list_elem *b = list_begin (bl);
2108 +      if (less (b, a, aux))
2109 +        {
2110 +          list_splice (a, b, list_next (b));
2111 +          if (list_empty (bl))
2112 +            break;
2113 +        }
2114 +      else
2115 +        a = list_next (a);
2116 +    }
2117 +  list_splice (list_end (al), list_begin (bl), list_end (bl));
2118 +}
2119 +
2120 +/* Returns the middle element in LIST, that is, the N/2'th
2121 +   element (rounding down) in a N-element list.
2122 +   Given an empty list, returns the list tail. */
2123 +static list_elem *
2124 +middle_of_list (struct list *list) 
2125 +{
2126 +  list_elem *middle, *last;
2127 +
2128 +  middle = last = list_begin (list);
2129 +  while (last != list_end (list) && list_next (last) != list_end (list))
2130 +    {
2131 +      middle = list_next (middle);
2132 +      last = list_next (list_next (last));
2133 +    }
2134 +  return middle;
2135 +}
2136 +
2137 +/* Sorts LIST according to LESS given auxiliary data AUX.
2138 +   Runs in O(n lg n) time in the number of elements in LIST. */
2139 +void
2140 +list_sort (struct list *list,
2141 +           list_less_func *less, void *aux)
2142 +{
2143 +  /* Find the middle of the list. */
2144 +  list_elem *middle = middle_of_list (list);
2145 +  if (middle != list_begin (list))
2146 +    {
2147 +      /* Extract first half of LIST into a temporary list. */
2148 +      struct list tmp;
2149 +      list_init (&tmp);
2150 +      list_splice (list_begin (&tmp), list_begin (list), middle);
2151 +
2152 +      /* Sort each half-list and merge the result. */
2153 +      list_sort (&tmp, less, aux);
2154 +      list_sort (list, less, aux);
2155 +      list_merge (list, &tmp, less, aux);
2156 +    }
2157 +  else 
2158 +    {
2159 +      /* The middle is at the beginning of the list.
2160 +         This only happens in empty lists and 1-element lists.
2161 +         Because such lists are already sorted, we have nothing
2162 +         to do. */
2163 +    }
2164 +}
2165 +
2166 +/* Inserts ELEM in the proper position in LIST, which must be
2167 +   sorted according to LESS given auxiliary data AUX.
2168 +   Runs in O(n) average case in the number of elements in LIST. */
2169 +void
2170 +list_insert_ordered (struct list *list, list_elem *elem,
2171 +                     list_less_func *less, void *aux)
2172 +{
2173 +  list_elem *e;
2174 +
2175 +  assert (list != NULL);
2176 +  assert (elem != NULL);
2177 +  assert (less != NULL);
2178 +
2179 +  for (e = list_begin (list); e != list_end (list); e = list_next (e))
2180 +    if (less (elem, e, aux))
2181 +      break;
2182 +  return list_insert (e, elem);
2183 +}
2184 +
2185 +/* Iterates through LIST and removes all but the first in each
2186 +   set of adjacent elements that are equal according to LESS
2187 +   given auxiliary data AUX.  If DUPLICATES is non-null, then the
2188 +   elements from LIST are appended to DUPLICATES. */
2189 +void
2190 +list_unique (struct list *list, struct list *duplicates,
2191 +             list_less_func *less, void *aux)
2192 +{
2193 +  list_elem *elem, *next;
2194 +
2195 +  assert (list != NULL);
2196 +  assert (less != NULL);
2197 +  if (list_empty (list))
2198 +    return;
2199 +
2200 +  elem = list_begin (list);
2201 +  while ((next = list_next (elem)) != list_end (list))
2202 +    if (!less (elem, next, aux) && !less (next, elem, aux)) 
2203 +      {
2204 +        list_remove (next);
2205 +        if (duplicates != NULL)
2206 +          list_push_back (duplicates, next);
2207 +      }
2208 +    else
2209 +      elem = next;
2210 +}
2211 +
2212 +/* Returns the element in LIST with the largest value according
2213 +   to LESS given auxiliary data AUX.  If there is more than one
2214 +   maximum, returns the one that appears earlier in the list.  If
2215 +   the list is empty, returns its tail. */
2216 +list_elem *
2217 +list_max (struct list *list, list_less_func *less, void *aux)
2218 +{
2219 +  list_elem *max = list_begin (list);
2220 +  if (max != list_end (list)) 
2221 +    {
2222 +      list_elem *e;
2223 +      
2224 +      for (e = list_next (max); e != list_end (list); e = list_next (e))
2225 +        if (less (max, e, aux))
2226 +          max = e; 
2227 +    }
2228 +  return max;
2229 +}
2230 +
2231 +/* Returns the element in LIST with the smallest value according
2232 +   to LESS given auxiliary data AUX.  If there is more than one
2233 +   minimum, returns the one that appears earlier in the list.  If
2234 +   the list is empty, returns its tail. */
2235 +list_elem *
2236 +list_min (struct list *list, list_less_func *less, void *aux)
2237 +{
2238 +  list_elem *min = list_begin (list);
2239 +  if (min != list_end (list)) 
2240 +    {
2241 +      list_elem *e;
2242 +      
2243 +      for (e = list_next (min); e != list_end (list); e = list_next (e))
2244 +        if (less (e, min, aux))
2245 +          min = e; 
2246 +    }
2247 +  return min;
2248 +}
2249 diff -urpN bochs-2.1.1.orig/taint/list.cc.bak checkbochs-2.1.1/taint/list.cc.bak
2250 diff -urpN bochs-2.1.1.orig/taint/list.h checkbochs-2.1.1/taint/list.h
2251 --- bochs-2.1.1.orig/taint/list.h       1969-12-31 16:00:00.000000000 -0800
2252 +++ checkbochs-2.1.1/taint/list.h       2005-06-29 11:19:16.000000000 -0700
2253 @@ -0,0 +1,171 @@
2254 +#ifndef __LIB_KERNEL_LIST_H
2255 +#define __LIB_KERNEL_LIST_H
2256 +
2257 +/* Doubly linked list.
2258 +
2259 +   This implementation of a doubly linked list does not require
2260 +   use of dynamically allocated memory.  Instead, each structure
2261 +   that is a potential list element must embed a list_elem
2262 +   member.  All of the list functions operate on these
2263 +   `list_elem's.  The list_entry macro allows conversion from a
2264 +   list_elem back to a structure object that contains it.
2265 +
2266 +   For example, suppose there is a needed for a list of `struct
2267 +   foo'.  `struct foo' should contain a `list_elem' member, like
2268 +   so:
2269 +
2270 +      struct foo
2271 +        {
2272 +          list_elem elem;
2273 +          int bar;
2274 +          ...other members...
2275 +        };
2276 +
2277 +   Then a list of `struct foo' can be be declared and initialized
2278 +   like so:
2279 +
2280 +      struct list foo_list;
2281 +
2282 +      list_init (&foo_list);
2283 +
2284 +   Iteration is a typical situation where it is necessary to
2285 +   convert from a list_elem back to its enclosing structure.
2286 +   Here's an example using foo_list:
2287 +
2288 +      list_elem *e;
2289 +
2290 +      for (e = list_begin (&foo_list); e != list_end (&foo_list);
2291 +           e = list_next (e))
2292 +        {
2293 +          struct foo *f = list_entry (e, struct foo, elem);
2294 +          ...do something with f...
2295 +        }
2296 +
2297 +   You can find real examples of list usage throughout the
2298 +   source; for example, malloc.c, palloc.c, and thread.c in the
2299 +   threads directory all use lists.
2300 +
2301 +   The interface for this list is inspired by the list<> template
2302 +   in the C++ STL.  If you're familiar with list<>, you should
2303 +   find this easy to use.  However, it should be emphasized that
2304 +   these lists do *no* type checking and can't do much other
2305 +   correctness checking.  If you screw up, it will bite you.
2306 +
2307 +   Glossary of list terms:
2308 +
2309 +     - "front": The first element in a list.  Undefined in an
2310 +       empty list.  Returned by list_front().
2311 +
2312 +     - "back": The last element in a list.  Undefined in an empty
2313 +       list.  Returned by list_back().
2314 +
2315 +     - "tail": The element figuratively just after the last
2316 +       element of a list.  Well defined even in an empty list.
2317 +       Returned by list_end().  Used as the end sentinel for an
2318 +       iteration from front to back.
2319 +
2320 +     - "beginning": In a non-empty list, the front.  In an empty
2321 +       list, the tail.  Returned by list_begin().  Used as the
2322 +       starting point for an iteration from front to back.
2323 +
2324 +     - "head": The element figuratively just before the first
2325 +       element of a list.  Well defined even in an empty list.
2326 +       Returned by list_rend().  Used as the end sentinel for an
2327 +       iteration from back to front.
2328 +
2329 +     - "reverse beginning": In a non-empty list, the back.  In an
2330 +       empty list, the head.  Returned by list_rbegin().  Used as
2331 +       the starting point for an iteration from back to front.
2332 +
2333 +     - "interior element": An element that is not the head or
2334 +       tail, that is, a real list element.  An empty list does
2335 +       not have any interior elements.
2336 +*/
2337 +
2338 +#include <stdbool.h>
2339 +#include <stddef.h>
2340 +#include <inttypes.h>
2341 +
2342 +/* List element. */
2343 +typedef struct list_elem 
2344 +  {
2345 +    struct list_elem *prev;     /* Previous list element. */
2346 +    struct list_elem *next;     /* Next list element. */
2347 +  }
2348 +list_elem;
2349 +
2350 +/* List. */
2351 +struct list 
2352 +  {
2353 +    list_elem head;             /* List head. */
2354 +    list_elem tail;             /* List tail. */
2355 +  };
2356 +
2357 +/* Converts pointer to list element LIST_ELEM into a pointer to
2358 +   the structure that LIST_ELEM is embedded inside.  Supply the
2359 +   name of the outer structure STRUCT and the member name MEMBER
2360 +   of the list element.  See the big comment at the top of the
2361 +   file for an example. */
2362 +#define list_entry(LIST_ELEM, STRUCT, MEMBER)                              \
2363 +        ((STRUCT *) ((uint8_t *) (LIST_ELEM) - offsetof (STRUCT, MEMBER)))
2364 +
2365 +void list_init (struct list *);
2366 +
2367 +/* List traversal. */
2368 +list_elem *list_begin (struct list *);
2369 +list_elem *list_next (list_elem *);
2370 +list_elem *list_end (struct list *);
2371 +
2372 +list_elem *list_rbegin (struct list *);
2373 +list_elem *list_prev (list_elem *);
2374 +list_elem *list_rend (struct list *);
2375 +
2376 +list_elem *list_head (struct list *);
2377 +list_elem *list_tail (struct list *);
2378 +
2379 +/* List insertion. */
2380 +void list_insert (list_elem *, list_elem *);
2381 +void list_splice (list_elem *before,
2382 +                  list_elem *first, list_elem *last);
2383 +void list_push_front (struct list *, list_elem *);
2384 +void list_push_back (struct list *, list_elem *);
2385 +
2386 +/* List removal. */
2387 +list_elem *list_remove (list_elem *);
2388 +list_elem *list_pop_front (struct list *);
2389 +list_elem *list_pop_back (struct list *);
2390 +
2391 +/* List elements. */
2392 +list_elem *list_front (struct list *);
2393 +list_elem *list_back (struct list *);
2394 +
2395 +/* List properties. */
2396 +size_t list_size (struct list *);
2397 +bool list_empty (struct list *);
2398 +
2399 +/* Miscellaneous. */
2400 +void list_reverse (struct list *);
2401 +\f
2402 +/* Compares the value of two list elements A and B, given
2403 +   auxiliary data AUX.  Returns true if A is less than B, or
2404 +   false if A is greater than or equal to B. */
2405 +typedef bool list_less_func (const list_elem *a, const list_elem *b,
2406 +                             void *aux);
2407 +
2408 +/* Operations on lists with ordered elements. */
2409 +void list_merge (struct list *, struct list *,
2410 +                 list_less_func *, void *aux);
2411 +void list_sort (struct list *,
2412 +                list_less_func *, void *aux);
2413 +void list_insert_ordered (struct list *, list_elem *,
2414 +                          list_less_func *, void *aux);
2415 +void list_unique (struct list *, struct list *duplicates,
2416 +                  list_less_func *, void *aux);
2417 +
2418 +/* Max and min. */
2419 +list_elem *list_max (struct list *, list_less_func *, void *aux);
2420 +list_elem *list_min (struct list *, list_less_func *, void *aux);
2421 +
2422 +inline bool
2423 +is_head (list_elem *elem);
2424 +#endif /* lib/kernel/list.h */
2425 diff -urpN bochs-2.1.1.orig/taint/list.h.bak checkbochs-2.1.1/taint/list.h.bak
2426 diff -urpN bochs-2.1.1.orig/taint/lockset.cc checkbochs-2.1.1/taint/lockset.cc
2427 --- bochs-2.1.1.orig/taint/lockset.cc   1969-12-31 16:00:00.000000000 -0800
2428 +++ checkbochs-2.1.1/taint/lockset.cc   2005-06-29 11:19:16.000000000 -0700
2429 @@ -0,0 +1,635 @@
2430 +#include <stdio.h>
2431 +#include <stdlib.h>
2432 +#include <assert.h>
2433 +
2434 +#define NEED_CPU_REG_SHORTCUTS 1
2435 +#include "bochs.h"
2436 +#define LOG_THIS BX_CPU_THIS_PTR
2437 +#include "lockset.h"
2438 +#include "hash.h"
2439 +#include "eraser.h"
2440 +#include "globals.h"
2441 +#include "mydebug.h"
2442 +
2443 +
2444 +#define MAX_LOCKSETS ((unsigned int)100000)
2445 +#define HTABLE_SIZE ((unsigned int)4*MAX_LOCKSETS)   //overprovision for closed hashing
2446 +
2447 +typedef unsigned int hval_t;
2448 +
2449 +struct add_lock_entry {
2450 +    locksetidx_t oldindex;
2451 +    address_t newlock;
2452 +    locksetidx_t newindex;
2453 +    hash_elem h_elem;  /* Hash element */
2454 +};
2455 +
2456 +struct remove_lock_entry {
2457 +    locksetidx_t oldindex;
2458 +    address_t oldlock;
2459 +    locksetidx_t newindex;
2460 +    hash_elem h_elem;  /* Hash element */
2461 +};
2462 +
2463 +
2464 +struct intersect_entry {
2465 +    locksetidx_t index1, index2, newindex;
2466 +    hash_elem h_elem;  /* Hash element */
2467 +};
2468 +
2469 +unsigned add_lock_hash (const hash_elem *e, void *aux)
2470 +{
2471 +    struct add_lock_entry *h = hash_entry (e, struct add_lock_entry, h_elem);
2472 +    return hash_int ((h->oldindex << 16) | (h->newlock&0x0000ffff) );
2473 +}
2474 +
2475 +bool
2476 +add_lock_less (const hash_elem *a_, const hash_elem *b_,
2477 +                       void *aux)
2478 +{
2479 +    struct add_lock_entry *a = hash_entry (a_, struct add_lock_entry, h_elem);
2480 +    struct add_lock_entry *b = hash_entry (b_, struct add_lock_entry, h_elem);
2481 +    return (a->oldindex < b->oldindex || (a->oldindex==b->oldindex && a->newlock < b->newlock));
2482 +}
2483 +
2484 +unsigned remove_lock_hash (const hash_elem *e, void *aux)
2485 +{
2486 +    struct remove_lock_entry *h = hash_entry (e, struct remove_lock_entry, h_elem);
2487 +    return hash_int ((h->oldindex << 16) | (h->oldlock&0x0000ffff));
2488 +}
2489 +
2490 +bool
2491 +remove_lock_less (const hash_elem *a_, const hash_elem *b_,
2492 +                       void *aux)
2493 +{
2494 +    struct remove_lock_entry *a = hash_entry (a_, struct remove_lock_entry, h_elem);
2495 +    struct remove_lock_entry *b = hash_entry (b_, struct remove_lock_entry, h_elem);
2496 +    return (a->oldindex < b->oldindex || (a->oldindex==b->oldindex && a->oldlock < b->oldlock));
2497 +}
2498 +
2499 +unsigned intersect_hash (const hash_elem *e, void *aux)
2500 +{
2501 +    struct intersect_entry *h = hash_entry (e, struct intersect_entry, h_elem);
2502 +    return hash_int ((h->index1 << 16) | (h->index2&0x0000ffff));
2503 +}
2504 +
2505 +bool
2506 +intersect_less (const hash_elem *a_, const hash_elem *b_,
2507 +                       void *aux)
2508 +{
2509 +    struct intersect_entry *a = hash_entry (a_, struct intersect_entry, h_elem);
2510 +    struct intersect_entry *b = hash_entry (b_, struct intersect_entry, h_elem);
2511 +    return (a->index1 < b->index1 || (a->index1==b->index1 && a->index2 < b->index2));
2512 +}
2513 +
2514 +
2515 +
2516 +
2517 +static int add_lock_cache_initialized = 0;
2518 +static struct hash add_lock_cache;
2519 +
2520 +static int remove_lock_cache_initialized = 0;
2521 +static struct hash remove_lock_cache;
2522 +
2523 +static int intersect_cache_initialized = 0;
2524 +static struct hash intersect_cache;
2525 +
2526 +typedef struct lockvector {
2527 +  address_t lockaddress;
2528 +  struct lockvector *next;
2529 +} lockvector_t;
2530 +
2531 +
2532 +static locksetidx_t lockset_index = 1;
2533 +static lockvector_t *index_table[MAX_LOCKSETS];
2534 +static locksetidx_t hash_table[HTABLE_SIZE];
2535 +
2536 +static unsigned int cum_hash(unsigned int a, address_t b) {
2537 +    return (3*a+b);
2538 +}
2539 +
2540 +static unsigned int hashfn(lockvector_t *vec) {
2541 +    lockvector_t *cur;
2542 +    unsigned int ret=0;
2543 +    assert(vec);
2544 +    cur = vec;
2545 +    while (cur) {
2546 +        ret = cum_hash(ret,cur->lockaddress);
2547 +       cur = cur->next;
2548 +    }
2549 +    return ret;
2550 +}
2551 +
2552 +static void
2553 +freevector(lockvector_t *lockvec) {
2554 +    static lockvector_t *cur, *prev;
2555 +    cur = lockvec;
2556 +    while (cur) {
2557 +        prev = cur;
2558 +       cur = cur->next;
2559 +       free(prev);
2560 +    }
2561 +}
2562 +
2563 +static lockvector_t *
2564 +clonevector(lockvector_t *lockvec) {
2565 +    static lockvector_t *cur, *newlockvec,*newprev;
2566 +    if (!lockvec) return NULL;
2567 +    assert(lockvec);
2568 +    newlockvec = (lockvector_t*)malloc(sizeof(lockvector_t));
2569 +    newlockvec->lockaddress = lockvec->lockaddress;
2570 +    newprev = newlockvec;
2571 +    cur = lockvec->next;
2572 +    while (cur) {
2573 +        newprev->next = (lockvector_t*)malloc(sizeof(lockvector_t));
2574 +       newprev->next->lockaddress = cur->lockaddress;
2575 +       cur = cur->next;
2576 +       newprev = newprev->next;
2577 +    }
2578 +    newprev->next = NULL;
2579 +    return newlockvec;
2580 +}
2581 +
2582 +static lockvector_t *
2583 +remove_from_lockvector(lockvector_t *lockvec, address_t oldlock) {
2584 +    lockvector_t *ret, *cur, *newlockvec, *tmp;
2585 +    assert(lockvec);
2586 +
2587 +    if (oldlock<lockvec->lockaddress) assert(0);
2588 +    if (oldlock==lockvec->lockaddress) {
2589 +       ret = clonevector(lockvec->next);
2590 +       return ret;
2591 +    }
2592 +
2593 +    cur = newlockvec = clonevector(lockvec);
2594 +    while (cur->next && oldlock>cur->next->lockaddress) {
2595 +        cur = cur->next;
2596 +    }
2597 +    assert(oldlock==cur->next->lockaddress);
2598 +
2599 +    tmp = cur->next;
2600 +    cur->next = cur->next->next;
2601 +    tmp->lockaddress = 0;
2602 +    tmp->next = NULL;
2603 +    free(tmp);
2604 +    return newlockvec;
2605 +}
2606 +
2607 +static lockvector_t *
2608 +intersect_lockvectors(lockvector_t *lockvec1, lockvector_t *lockvec2) {
2609 +    lockvector_t *cur1, *cur2, *out, *ret;
2610 +    cur1 = lockvec1;
2611 +    cur2 = lockvec2;
2612 +    ret = out = NULL;
2613 +    while (cur1 && cur2) {
2614 +       if (cur1->lockaddress < cur2->lockaddress) {
2615 +           cur1 = cur1->next;
2616 +       } else if (cur1->lockaddress > cur2->lockaddress) {
2617 +           cur2 = cur2->next;
2618 +       } else {
2619 +           if (out) {
2620 +               out->next = (lockvector_t *)malloc(sizeof(lockvector_t));
2621 +               out = out->next;
2622 +           } else {
2623 +               ret = out = (lockvector_t *)malloc(sizeof(lockvector_t));
2624 +           }
2625 +           out->lockaddress = cur1->lockaddress;
2626 +           out->next = NULL;
2627 +           cur1 = cur1->next;
2628 +           cur2 = cur2->next;
2629 +       }
2630 +    }
2631 +    return ret;
2632 +}
2633 +
2634 +
2635 +
2636 +
2637 +static lockvector_t *
2638 +add_to_lockvector(lockvector_t *lockvec, address_t newlock) {
2639 +    lockvector_t *ret, *cur, *newlockvec;
2640 +    if (lockvec==NULL) {
2641 +       ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2642 +       ret->lockaddress = newlock;
2643 +       ret->next = NULL;
2644 +       return ret;
2645 +    }
2646 +    if (newlock<lockvec->lockaddress) {
2647 +       ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2648 +       ret->lockaddress = newlock;
2649 +       ret->next = clonevector(lockvec);
2650 +       return ret;
2651 +    }
2652 +    if (newlock==lockvec->lockaddress) {
2653 +       if (BX_CPU(0)) BX_CPU(0)->backtrace(btstr);
2654 +        assert(0);
2655 +       return clonevector(lockvec);
2656 +    }
2657 +    assert(newlock>lockvec->lockaddress);
2658 +
2659 +    cur = newlockvec = clonevector(lockvec);
2660 +    while (cur->next && newlock>cur->next->lockaddress) {
2661 +        cur = cur->next;
2662 +    }
2663 +
2664 +    if (!cur->next) {
2665 +       ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2666 +       ret->lockaddress = newlock;
2667 +       cur->next = ret;
2668 +       ret->next = NULL;
2669 +       return newlockvec;
2670 +    }
2671 +
2672 +    if (newlock==cur->next->lockaddress) {
2673 +       BX_CPU(0)->backtrace(btstr);
2674 +       assert(0); //acquiring the same lock twice
2675 +        return newlockvec;
2676 +    }
2677 +
2678 +    ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2679 +    ret->lockaddress = newlock;
2680 +    ret->next = cur->next;
2681 +    cur->next = ret;
2682 +    return newlockvec;
2683 +}
2684 +
2685 +void add_to_hashtable(lockvector_t *newlockset, locksetidx_t index) {
2686 +    hval_t hval = (hashfn(newlockset))%HTABLE_SIZE;
2687 +    int numtries = 0;
2688 +    while (hash_table[hval]) {
2689 +        hval = (hval+1)%HTABLE_SIZE; //closed hashing
2690 +       //printf("hval=%d.\n",hval);
2691 +       numtries++;
2692 +    }
2693 +    if (numtries>20) printf("%s: Warning: numtries too large for closed hashing (=%d).\n",__func__,numtries);
2694 +    hash_table[hval] = index;
2695 +}
2696 +
2697 +//returns true if they are equal
2698 +static int
2699 +compare_locksets(lockvector_t *vec1, lockvector_t *vec2) {
2700 +    lockvector_t *cur1, *cur2;
2701 +
2702 +    assert(vec1);
2703 +    assert(vec2);
2704 +    
2705 +    cur1 = vec1;
2706 +    cur2 = vec2;
2707 +    while (cur1 && cur2 && cur1->lockaddress==cur2->lockaddress) {
2708 +       cur1 = cur1->next;
2709 +       cur2 = cur2->next;
2710 +    }
2711 +
2712 +    if (cur1) return 0;
2713 +    if (cur2) return 0;
2714 +    return 1;
2715 +}
2716 +
2717 +
2718 +static locksetidx_t
2719 +find_in_add_cache(locksetidx_t index, address_t newlock) {
2720 +    hval_t hval;
2721 +    locksetidx_t new_index;
2722 +    hash_elem *h_element = NULL;
2723 +    struct add_lock_entry tmp;
2724 +    tmp.oldindex = index; tmp.newlock = newlock;
2725 +    if (add_lock_cache_initialized) h_element = hash_find(&add_lock_cache, &tmp.h_elem);
2726 +    if (h_element) {
2727 +        struct add_lock_entry *answer = hash_entry(h_element, struct add_lock_entry, h_elem);
2728 +       //printf("%s: returning (%d, %x)->%d from cache.\n",__func__,index,newlock,answer->newindex);
2729 +       return answer->newindex;
2730 +    }
2731 +    return 0;
2732 +}
2733 +
2734 +
2735 +static locksetidx_t
2736 +find_in_remove_cache(locksetidx_t index, address_t oldlock) {
2737 +    hval_t hval;
2738 +    locksetidx_t new_index;
2739 +    hash_elem *h_element = NULL;
2740 +    struct remove_lock_entry tmp;
2741 +    tmp.oldindex = index; tmp.oldlock = oldlock;
2742 +    if (remove_lock_cache_initialized) h_element = hash_find(&remove_lock_cache, &tmp.h_elem);
2743 +    if (h_element) {
2744 +        struct remove_lock_entry *answer = hash_entry(h_element, struct remove_lock_entry, h_elem);
2745 +       //printf("%s: returning (%d, %d)->%d from cache.\n",__func__,index,oldlock,answer->newindex);
2746 +       return answer->newindex;
2747 +    }
2748 +
2749 +    return 0;
2750 +}
2751 +
2752 +static locksetidx_t
2753 +find_in_intersect_cache(locksetidx_t index1, locksetidx_t index2) {
2754 +    hval_t hval;
2755 +    locksetidx_t new_index;
2756 +    hash_elem *h_element = NULL;
2757 +    struct intersect_entry tmp;
2758 +    tmp.index1 = index1; tmp.index2 = index2;
2759 +    if (intersect_cache_initialized) h_element = hash_find(&intersect_cache, &tmp.h_elem);
2760 +    if (h_element) {
2761 +        struct intersect_entry *answer = hash_entry(h_element, struct intersect_entry, h_elem);
2762 +       //printf("%s: returning (%d, %x)->%d from cache.\n",__func__,index1,index2,answer->newindex);
2763 +       return answer->newindex;
2764 +    }
2765 +    return 0;
2766 +}
2767 +
2768 +
2769 +void insert_in_remove_cache(locksetidx_t index, address_t lock, locksetidx_t new_index)
2770 +{
2771 +    struct remove_lock_entry *e;
2772 +    if (!remove_lock_cache_initialized) {
2773 +       hash_init(&remove_lock_cache, remove_lock_hash, remove_lock_less, NULL);
2774 +       remove_lock_cache_initialized = 1;
2775 +    }
2776 +    e = (struct remove_lock_entry *)malloc(sizeof(struct remove_lock_entry));
2777 +    e->oldindex = index; e->oldlock = lock; e->newindex = new_index;
2778 +    hash_insert(&remove_lock_cache, &e->h_elem);
2779 +}
2780 +
2781 +void
2782 +insert_in_add_cache(locksetidx_t index, address_t lock, locksetidx_t new_index)
2783 +{
2784 +    struct add_lock_entry *e;
2785 +    if (!add_lock_cache_initialized) {
2786 +       hash_init(&add_lock_cache, add_lock_hash, add_lock_less, NULL);
2787 +       add_lock_cache_initialized = 1;
2788 +    }
2789 +    e = (struct add_lock_entry *)malloc(sizeof(struct add_lock_entry));
2790 +    e->oldindex = index; e->newlock = lock; e->newindex = new_index;
2791 +    hash_insert(&add_lock_cache, &e->h_elem);
2792 +}
2793 +
2794 +void
2795 +insert_in_intersect_cache(locksetidx_t index1, locksetidx_t index2, locksetidx_t new_index)
2796 +{
2797 +    struct intersect_entry *e;
2798 +    if (!intersect_cache_initialized) {
2799 +       hash_init(&intersect_cache, intersect_hash, intersect_less, NULL);
2800 +       intersect_cache_initialized = 1;
2801 +    }
2802 +    e = (struct intersect_entry *)malloc(sizeof(struct intersect_entry));
2803 +    e->index1 = index1; e->index2 = index2; e->newindex = new_index;
2804 +    hash_insert(&intersect_cache, &e->h_elem);
2805 +}
2806 +
2807 +static locksetidx_t
2808 +find_duplicate(lockvector_t *vec) {
2809 +    hval_t hval;
2810 +    locksetidx_t new_index;
2811 +    hash_elem *h_element = NULL;
2812 +
2813 +    hval = (hashfn(vec))%HTABLE_SIZE;
2814 +    new_index = hash_table[hval];
2815 +
2816 +    while (new_index) {
2817 +        if (compare_locksets(vec,index_table[new_index])) {
2818 +         return new_index;
2819 +       }
2820 +       hval = (hval+1)%HTABLE_SIZE;
2821 +       new_index = hash_table[hval];
2822 +    }
2823 +    return 0;
2824 +}
2825 +
2826 +locksetidx_t add_lock(locksetidx_t index, address_t newlock) {
2827 +    lockvector_t *newlockset;
2828 +    locksetidx_t ret_index;
2829 +    ret_index = find_in_add_cache(index,newlock);
2830 +    if (ret_index) return ret_index;
2831 +
2832 +    if (lockset_index >= MAX_LOCKSETS) {
2833 +       printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
2834 +        return 0;
2835 +    }
2836 +
2837 +    if (!index) {      //adding a lock to an empty lockset
2838 +        newlockset = (lockvector_t *)malloc(sizeof(lockvector_t));
2839 +       newlockset->lockaddress = newlock;
2840 +       newlockset->next = NULL;
2841 +    } else {
2842 +       newlockset = add_to_lockvector(index_table[index],newlock);
2843 +    }
2844 +    assert(newlockset);
2845 +    ret_index = find_duplicate(newlockset);
2846 +    if (ret_index) {
2847 +        insert_in_add_cache(index,newlock,ret_index);
2848 +        freevector(newlockset);
2849 +       return ret_index;
2850 +    }
2851 +
2852 +    index_table[lockset_index] = newlockset;
2853 +    add_to_hashtable(newlockset,lockset_index);
2854 +    ret_index = lockset_index;
2855 +    lockset_index++;
2856 +    return ret_index;
2857 +}
2858 +
2859 +static int
2860 +singleton_lockset(lockvector_t *vec) {
2861 +    assert(vec);
2862 +    if (vec->next==NULL) return 1;
2863 +    return 0;
2864 +}
2865 +
2866 +locksetidx_t remove_lock(locksetidx_t index, address_t oldlock) {
2867 +    lockvector_t *newlockset;
2868 +    locksetidx_t ret_index;
2869 +    if (!index_table[index]) {
2870 +       assert(oldlock==INTERRUPT_LOCK);
2871 +       assert(index==0);
2872 +       return 0;
2873 +    }
2874 +    if (singleton_lockset(index_table[index])) {
2875 +        if (index_table[index]->lockaddress!=oldlock) {
2876 +           BX_CPU(0)->backtrace(btstr);
2877 +           printf("ERROR: index=%d, index_table[index]->lockaddress=%x, oldlock=%x.\n",index,index_table[index]->lockaddress,oldlock);
2878 +       }
2879 +        assert(index_table[index]->lockaddress==oldlock);
2880 +       return 0;
2881 +    }
2882 +    ret_index = find_in_remove_cache(index,oldlock);
2883 +    if (ret_index) return ret_index;
2884 +
2885 +    if (lockset_index >= MAX_LOCKSETS) {
2886 +       printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
2887 +        return 0;
2888 +    }
2889 +
2890 +    assert(index);     //you cannot remove from an empty lockset
2891 +    newlockset = remove_from_lockvector(index_table[index],oldlock);
2892 +    assert(newlockset);
2893 +
2894 +    ret_index = find_duplicate(newlockset);
2895 +    if (ret_index) {
2896 +        insert_in_remove_cache(index,oldlock,ret_index);
2897 +        freevector(newlockset);
2898 +       return ret_index;
2899 +    }
2900 +
2901 +    index_table[lockset_index] = newlockset;
2902 +    add_to_hashtable(newlockset,lockset_index);
2903 +    ret_index = lockset_index;
2904 +    lockset_index++;
2905 +    return ret_index;
2906 +}
2907 +
2908 +locksetidx_t intersect_locksets(locksetidx_t index1, locksetidx_t index2) {
2909 +    lockvector_t *newlockset;
2910 +    locksetidx_t ret_index;
2911 +
2912 +    if (index1==0) return 0;
2913 +    if (index2==0) return 0;
2914 +    
2915 +    ret_index = find_in_intersect_cache(index1,index2);
2916 +    if (ret_index) return ret_index;
2917 +
2918 +    if (lockset_index >= MAX_LOCKSETS) {
2919 +       printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
2920 +        return 0;
2921 +    }
2922 +    assert(index1);
2923 +    assert(index2);
2924 +
2925 +    newlockset = intersect_lockvectors(index_table[index1],index_table[index2]);
2926 +    if (!newlockset) return 0;         //empty lockset
2927 +    ret_index = find_duplicate(newlockset);
2928 +    if (ret_index) {
2929 +        insert_in_intersect_cache(index1,index2,ret_index);
2930 +        freevector(newlockset);
2931 +       return ret_index;
2932 +    }
2933 +
2934 +    index_table[lockset_index] = newlockset;
2935 +    add_to_hashtable(newlockset,lockset_index);
2936 +    ret_index = lockset_index;
2937 +    lockset_index++;
2938 +    return ret_index;
2939 +}
2940 +
2941 +typedef struct locks_held {
2942 +    unsigned threadId;
2943 +    locksetidx_t locks_held;
2944 +    int ignore;        //whether this thread should be ignored. =0 if not. otherwise stores ignore depth
2945 +    hash_elem h_elem;  /* Hash element */
2946 +} locks_held_t ;
2947 +
2948 +static int locks_held_table_initialized = 0;
2949 +static struct hash locks_held_table ;
2950 +
2951 +unsigned locks_held_hash (const hash_elem *e, void *aux)
2952 +{
2953 +    locks_held_t *h = hash_entry (e, struct locks_held, h_elem);
2954 +    return hash_int (h->threadId);
2955 +}
2956 +
2957 +bool
2958 +locks_held_less (const hash_elem *a_, const hash_elem *b_,
2959 +                       void *aux)
2960 +{
2961 +    locks_held_t *a = hash_entry (a_, struct locks_held, h_elem);
2962 +    locks_held_t *b = hash_entry (b_, struct locks_held, h_elem);
2963 +    return (a->threadId < b->threadId);
2964 +}
2965 +
2966 +
2967 +locksetidx_t
2968 +cur_held(unsigned threadId) {
2969 +    hash_elem *h_element;
2970 +    locks_held_t tmp;
2971 +    if (!locks_held_table_initialized) return 0;
2972 +    tmp.threadId = threadId;
2973 +    h_element = hash_find(&locks_held_table, &tmp.h_elem);
2974 +    if (h_element) {
2975 +        locks_held_t *answer = hash_entry(h_element, struct locks_held, h_elem);
2976 +       assert(answer->locks_held<lockset_index);
2977 +       return answer->locks_held;
2978 +    }
2979 +    return 0;
2980 +}
2981 +
2982 +void update_lockset(unsigned threadId, locksetidx_t lset) {
2983 +    locks_held_t *e;
2984 +    hash_elem *h_element;
2985 +    locks_held_t tmp;
2986 +    assert(lset<lockset_index);
2987 +    if (!locks_held_table_initialized) {
2988 +       hash_init(&locks_held_table, locks_held_hash, locks_held_less, NULL);
2989 +       locks_held_table_initialized = 1;
2990 +    }
2991 +    tmp.threadId = threadId;
2992 +    h_element = hash_find(&locks_held_table, &tmp.h_elem);
2993 +    if (!h_element) {
2994 +       e = (struct locks_held *)malloc(sizeof(struct locks_held));
2995 +       e->threadId = threadId; e->locks_held = lset; e->ignore = 0;
2996 +       hash_insert(&locks_held_table, &e->h_elem);
2997 +    } else {
2998 +       e = hash_entry(h_element, struct locks_held, h_elem);
2999 +       assert(e->threadId==threadId);
3000 +       e->locks_held = lset;
3001 +    }
3002 +}
3003 +
3004 +
3005 +static bool
3006 +find_in_lockvector(lockvector_t *lockvec, address_t lock) {
3007 +    lockvector_t *cur;
3008 +    assert(lockvec!=NULL);
3009 +    if (lock<lockvec->lockaddress) return false;
3010 +    if (lock==lockvec->lockaddress) return true;
3011 +    cur = lockvec;
3012 +    while (cur->next && lock>cur->next->lockaddress) {
3013 +        cur = cur->next;
3014 +    }
3015 +    if (!cur->next) return false;
3016 +    if (cur->next->lockaddress==lock) return true;
3017 +    return false;
3018 +}
3019 +
3020 +bool belongs(locksetidx_t index, address_t lock) {
3021 +    if (!index) return false;
3022 +    return (find_in_lockvector(index_table[index],lock));
3023 +}
3024 +
3025 +void set_ignore(unsigned threadId, bool val) {
3026 +    locks_held_t *e;
3027 +    hash_elem *h_element;
3028 +    locks_held_t tmp;
3029 +    if (!locks_held_table_initialized) {
3030 +       hash_init(&locks_held_table, locks_held_hash, locks_held_less, NULL);
3031 +       locks_held_table_initialized = 1;
3032 +    }
3033 +    tmp.threadId = threadId;
3034 +    h_element = hash_find(&locks_held_table, &tmp.h_elem);
3035 +    if (!h_element) {
3036 +       e = (struct locks_held *)malloc(sizeof(struct locks_held));
3037 +       e->threadId = threadId; e->locks_held = LOCKSET_EMPTY; e->ignore=0;
3038 +       if (val) e->ignore++; else if (e->ignore) e->ignore--;
3039 +       assert(e->ignore>=0);
3040 +       hash_insert(&locks_held_table, &e->h_elem);
3041 +    } else {
3042 +       e = hash_entry(h_element, struct locks_held, h_elem);
3043 +       assert(e->threadId==threadId);
3044 +       if (val) e->ignore++; else if (e->ignore) e->ignore--;
3045 +       assert(e->ignore>=0);
3046 +    }
3047 +    DBG(L1,("ignore value for thread %x = %d.\n",threadId,e->ignore));
3048 +}
3049 +
3050 +bool
3051 +ignore_on(unsigned threadId) {
3052 +    hash_elem *h_element;
3053 +    locks_held_t tmp;
3054 +    if (global_startup_ignore) return true;
3055 +    if (!locks_held_table_initialized) return 0;
3056 +    tmp.threadId = threadId;
3057 +    h_element = hash_find(&locks_held_table, &tmp.h_elem);
3058 +    if (h_element) {
3059 +        locks_held_t *answer = hash_entry(h_element, struct locks_held, h_elem);
3060 +       assert(answer->ignore>=0);
3061 +       return answer->ignore > 0;
3062 +    }
3063 +    return false;
3064 +}
3065 diff -urpN bochs-2.1.1.orig/taint/lockset.cc.bak checkbochs-2.1.1/taint/lockset.cc.bak
3066 diff -urpN bochs-2.1.1.orig/taint/lockset.h checkbochs-2.1.1/taint/lockset.h
3067 --- bochs-2.1.1.orig/taint/lockset.h    1969-12-31 16:00:00.000000000 -0800
3068 +++ checkbochs-2.1.1/taint/lockset.h    2005-06-29 11:19:16.000000000 -0700
3069 @@ -0,0 +1,32 @@
3070 +#ifndef __LOCKSET_H
3071 +#define __LOCKSET_H
3072 +
3073 +#define LOCKSET_EMPTY 0
3074 +
3075 +#define VIRGIN 0x0
3076 +#define EXCLUSIVE      0x40000000
3077 +#define SHARED         0x80000000
3078 +#define SHARED_MOD     0xc0000000
3079 +
3080 +#define get_state(x) (x&0xc0000000)
3081 +#define set_state(x,s) ((x&0x3fffffff)|s)
3082 +
3083 +#define get_value(x) (x&0x3fffffff)
3084 +#define set_value(x,v) ((x&0xc0000000)|(v&0x3fffffff))
3085 +
3086 +typedef unsigned int address_t;
3087 +typedef unsigned long locksetidx_t;
3088 +typedef locksetidx_t lockset_t;
3089 +
3090 +locksetidx_t add_lock(locksetidx_t index, address_t newlock);
3091 +locksetidx_t remove_lock(locksetidx_t index, address_t newlock);
3092 +locksetidx_t intersect_locksets(locksetidx_t index1, locksetidx_t index2);
3093 +bool belongs(locksetidx_t index, address_t lock);
3094 +
3095 +locksetidx_t cur_held(unsigned threadId);
3096 +void update_lockset(unsigned threadId, locksetidx_t lockset);
3097 +
3098 +void set_ignore(unsigned threadId, bool val);
3099 +bool ignore_on(unsigned threadId);
3100 +
3101 +#endif
3102 diff -urpN bochs-2.1.1.orig/taint/lockset.h.bak checkbochs-2.1.1/taint/lockset.h.bak
3103 diff -urpN bochs-2.1.1.orig/taint/main.c checkbochs-2.1.1/taint/main.c
3104 --- bochs-2.1.1.orig/taint/main.c       1969-12-31 16:00:00.000000000 -0800
3105 +++ checkbochs-2.1.1/taint/main.c       2005-06-16 18:14:07.000000000 -0700
3106 @@ -0,0 +1,32 @@
3107 +#include "lockset.h"
3108 +
3109 +int main() {
3110 +    int i1, i2, i3, i12, i21, i31, i32, i123, i312, i321, i312_2, i321m2, i312m2;
3111 +    int i312i123, i312i21, i312i1, i32i1;
3112 +
3113 +    i1 = add_lock(0,1);
3114 +    i2 = add_lock(0,2);
3115 +    i3 = add_lock(0,3);
3116 +    i12 = add_lock(i1,2);
3117 +    i21 = add_lock(i2,1);
3118 +    i21 = add_lock(i2,1);
3119 +    i31 = add_lock(i3,1);
3120 +    i32 = add_lock(i3,2);
3121 +    i123 = add_lock(i12,3);
3122 +    i312 = add_lock(i31,2);
3123 +    i321 = add_lock(i32,1);
3124 +    i321m2 = remove_lock(i321,2);
3125 +    i312m2 = remove_lock(i312,2);
3126 +    i312i123 = intersect_locksets(i312,i321);
3127 +    i312i123 = intersect_locksets(i312,i321);
3128 +    i312i123 = intersect_locksets(i312,i321);
3129 +    i312i21 = intersect_locksets(i312,i21);
3130 +    i312i1 = intersect_locksets(i312,i1);
3131 +    i312i1 = intersect_locksets(i312,i1);
3132 +    i312i1 = intersect_locksets(i312,i1);
3133 +    i32i1 = intersect_locksets(i32,i1);
3134 +    i32i1 = intersect_locksets(i32,i1);
3135 +
3136 +    printf("i12 = %d, i21 = %d, i123=%d, i312=%d, i321=%d, i321m2=%d, i312m2=%d.\n",i12,i21,i123,i312,i321,i321m2,i312m2);
3137 +    printf("i312i123 = %d, i312i21 = %d, i312i1=%d, i32i1=%d.\n",i312i123,i312i21,i312i1,i32i1);
3138 +}
3139 diff -urpN bochs-2.1.1.orig/taint/memory.cc checkbochs-2.1.1/taint/memory.cc
3140 --- bochs-2.1.1.orig/taint/memory.cc    1969-12-31 16:00:00.000000000 -0800
3141 +++ checkbochs-2.1.1/taint/memory.cc    2005-06-29 11:19:16.000000000 -0700
3142 @@ -0,0 +1,360 @@
3143 +
3144 +#include "bochs.h"
3145 +#define LOG_THIS BX_MEM_THIS
3146 +
3147 +
3148 +  void BX_CPP_AttrRegparmN(3)
3149 +BX_MEM_C::readPhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
3150 +{
3151 +  Bit32u *data_ptr;
3152 +  Bit32u a20addr;
3153 +
3154 +  a20addr = A20ADDR(addr);
3155 +  assert(len==1);
3156 +  *(Bit32u *)data = 0x0;       //initialize, so that if we are unable to read mem, we return 0
3157 +
3158 +  if ( (a20addr + len) <= BX_MEM_THIS len ) {
3159 +    // all of data is within limits of physical memory
3160 +    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3161 +      if (len == 4) {
3162 +#ifdef __i386__
3163 +        *(Bit32u *)data = taint_vector[a20addr];
3164 +        *((Bit32u *)data+1) = taint_vector[a20addr+1];
3165 +        *((Bit32u *)data+2) = taint_vector[a20addr+2];
3166 +        *((Bit32u *)data+3) = taint_vector[a20addr+3];
3167 +#else
3168 +       printf("Not yet supported for big endian host platforms.\n");
3169 +       assert(0);
3170 +#endif
3171 +        return;
3172 +        }
3173 +      if (len == 2) {
3174 +#ifdef __i386__
3175 +        *(Bit32u *)data = taint_vector[a20addr];
3176 +        *((Bit32u *)data+1) = taint_vector[a20addr+1];
3177 +#else
3178 +       printf("Not yet supported for big endian host platforms.\n");
3179 +       assert(0);
3180 +#endif
3181 +       /*
3182 +       if (*(Bit16u *)data && g_instruction_display_count>0) {
3183 +               printf("%s %d: tainted dword read from addr %x. data=%x.\n",__func__,__LINE__,addr,*(Bit16u*)data);
3184 +               g_instruction_display_count = 512;
3185 +       }
3186 +       */
3187 +        return;
3188 +        }
3189 +      if (len == 1) {
3190 +#ifdef __i386__
3191 +        *(Bit32u *)data = taint_vector[a20addr];
3192 +#else
3193 +       printf("Not yet supported for big endian host platforms.\n");
3194 +       assert(0);
3195 +#endif
3196 +        return;
3197 +        }
3198 +      // len == 3 case can just fall thru to special cases handling
3199 +      }
3200 +
3201 +
3202 +#ifdef BX_LITTLE_ENDIAN
3203 +    data_ptr = (Bit32u *) data;
3204 +#else // BX_BIG_ENDIAN
3205 +    data_ptr = (Bit32u *) data + (len - 1);
3206 +#endif
3207 +
3208 +
3209 +
3210 +read_one:
3211 +    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3212 +      // addr *not* in range 00080000 .. 000FFFFF
3213 +      *data_ptr = taint_vector[a20addr];
3214 +inc_one:
3215 +      if (len == 1) return;
3216 +      len--;
3217 +      a20addr++;
3218 +#ifdef BX_LITTLE_ENDIAN
3219 +      data_ptr++;
3220 +#else // BX_BIG_ENDIAN
3221 +      data_ptr--;
3222 +#endif
3223 +      goto read_one;
3224 +      }
3225 +
3226 +    // addr in range 00080000 .. 000FFFFF
3227 +#if BX_PCI_SUPPORT == 0
3228 +    if ((a20addr <= 0x0009ffff) || (a20addr >= 0x000c0000) ) {
3229 +      // regular memory 80000 .. 9FFFF, C0000 .. F0000
3230 +      *data_ptr = taint_vector[a20addr];
3231 +      goto inc_one;
3232 +      }
3233 +    return; //assert(0);
3234 +    // VGA memory A0000 .. BFFFF
3235 +    //*data_ptr = DEV_vga_mem_read(a20addr);
3236 +    //BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr); // obsolete
3237 +    //goto inc_one;
3238 +#else   // #if BX_PCI_SUPPORT == 0
3239 +    if (a20addr <= 0x0009ffff) {
3240 +      *data_ptr = taint_vector[a20addr];
3241 +      goto inc_one;
3242 +      }
3243 +    if (a20addr <= 0x000BFFFF) {
3244 +      assert(0);
3245 +      // VGA memory A0000 .. BFFFF
3246 +      //*data_ptr = DEV_vga_mem_read(a20addr);
3247 +      //BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr);
3248 +      //goto inc_one;
3249 +      }
3250 +
3251 +    // a20addr in C0000 .. FFFFF
3252 +    if (!bx_options.Oi440FXSupport->get ()) {
3253 +      *data_ptr = taint_vector[a20addr];
3254 +      goto inc_one;
3255 +    }
3256 +    else assert(0);
3257 +    goto inc_one;
3258 +#endif  // #if BX_PCI_SUPPORT == 0
3259 +    }
3260 +  else {
3261 +    // some or all of data is outside limits of physical memory
3262 +    unsigned i;
3263 +
3264 +#ifdef BX_LITTLE_ENDIAN
3265 +    data_ptr = (Bit32u *) data;
3266 +#else // BX_BIG_ENDIAN
3267 +    data_ptr = (Bit32u *) data + (len - 1);
3268 +#endif
3269 +
3270 +#if BX_SUPPORT_VBE
3271 +    // Check VBE LFB support
3272 +    if ((a20addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS) &&
3273 +        (a20addr <  (VBE_DISPI_LFB_PHYSICAL_ADDRESS +  VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)))
3274 +    {
3275 +      assert(0);
3276 +      return;
3277 +    }
3278 +#endif
3279 +
3280 +#if BX_SUPPORT_APIC
3281 +    //assert(0);
3282 +    return;
3283 +#endif
3284 +    for (i = 0; i < len; i++) {
3285 +#if BX_PCI_SUPPORT == 0
3286 +      if (a20addr < BX_MEM_THIS len)
3287 +        *data_ptr = taint_vector[a20addr];
3288 +      else
3289 +        *data_ptr = 0xffffffff;
3290 +#else   // BX_PCI_SUPPORT == 0
3291 +      if (a20addr < BX_MEM_THIS len) {
3292 +        if ((a20addr >= 0x000C0000) && (a20addr <= 0x000FFFFF)) {
3293 +          if (!bx_options.Oi440FXSupport->get ())
3294 +            *data_ptr = taint_vector[a20addr];
3295 +          else {
3296 +            switch (DEV_pci_rd_memtype(a20addr & 0xFC000)) {
3297 +              case 0x0:   // Read from ROM
3298 +                *data_ptr = taint_vector[a20addr];
3299 +                //BX_INFO(("Reading from ROM %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
3300 +                break;
3301 +
3302 +              case 0x1:   // Read from Shadow RAM
3303 +               assert(0);
3304 +                break;
3305 +              default:
3306 +                BX_PANIC(("readPhysicalPage: default case"));
3307 +              } // Switch
3308 +            }
3309 +          }
3310 +        else {
3311 +          *data_ptr = taint_vector[a20addr];
3312 +          BX_INFO(("Reading from Norm %08x, Data %02x  ", (unsigned) a20addr, *data_ptr));
3313 +          }
3314 +        }
3315 +      else 
3316 +        *data_ptr = 0xffffffff;
3317 +#endif  // BX_PCI_SUPPORT == 0
3318 +      addr++;
3319 +      a20addr = (addr);
3320 +#ifdef BX_LITTLE_ENDIAN
3321 +      data_ptr++;
3322 +#else // BX_BIG_ENDIAN
3323 +      data_ptr--;
3324 +#endif
3325 +      }
3326 +    return;
3327 +    }
3328 +}
3329 +
3330 +  void BX_CPP_AttrRegparmN(3)
3331 +BX_MEM_C::writePhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
3332 +{
3333 +  Bit32u *data_ptr;
3334 +  Bit32u a20addr;
3335 +
3336 +  assert(len==1);
3337 +
3338 +  a20addr = A20ADDR(addr);
3339 +
3340 +  // Note: accesses should always be contained within a single page now.
3341 +
3342 +  //if (*(Bit8u *)data!=0xff && *(Bit8u *)data!=0) assert(0);
3343 +  //if (*(Bit8u *)data==0xff) assert(0);
3344 +
3345 +  if ( a20addr <= BX_MEM_THIS len ) {
3346 +
3347 +    //LOG_MEM_TAINT(cpu,addr,len,&taint_vector[a20addr],data,true);
3348 +
3349 +    // all of data is within limits of physical memory
3350 +    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3351 +      if (len == 4) {
3352 +#ifdef __i386__
3353 +        taint_vector[a20addr]  = *(Bit32u*)data;
3354 +        taint_vector[a20addr+1]  = *((Bit32u*)data+1);
3355 +        taint_vector[a20addr+2]  = *((Bit32u*)data+2);
3356 +        taint_vector[a20addr+3]  = *((Bit32u*)data+3);
3357 +#else
3358 +       printf("Not yet supported for big endian host platforms.\n");
3359 +       assert(0);
3360 +#endif
3361 +        return;
3362 +        }
3363 +      if (len == 2) {
3364 +#ifdef __i386__
3365 +        taint_vector[a20addr]  = *(Bit32u*)data;
3366 +        taint_vector[a20addr+1]  = *((Bit32u*)data+1);
3367 +#else
3368 +       printf("Not yet supported for big endian host platforms.\n");
3369 +       assert(0);
3370 +#endif
3371 +        return;
3372 +        }
3373 +      if (len == 1) {
3374 +#ifdef __i386__
3375 +        taint_vector[a20addr]  = *(Bit32u*)data;
3376 +#else
3377 +       printf("Not yet supported for big endian host platforms.\n");
3378 +       assert(0);
3379 +#endif
3380 +        return;
3381 +        }
3382 +      // len == other, just fall thru to special cases handling
3383 +      }
3384 +
3385 +#ifdef BX_LITTLE_ENDIAN
3386 +  data_ptr = (Bit32u *) data;
3387 +#else // BX_BIG_ENDIAN
3388 +  data_ptr = (Bit32u *) data + (len - 1);
3389 +#endif
3390 +
3391 +write_one:
3392 +    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3393 +      // addr *not* in range 00080000 .. 000FFFFF
3394 +      taint_vector[a20addr] = *data_ptr;
3395 +inc_one:
3396 +      if (len == 1) return;
3397 +      len--;
3398 +      a20addr++;
3399 +#ifdef BX_LITTLE_ENDIAN
3400 +      data_ptr++;
3401 +#else // BX_BIG_ENDIAN
3402 +      data_ptr--;
3403 +#endif
3404 +      goto write_one;
3405 +      }
3406 +
3407 +    // addr in range 00080000 .. 000FFFFF
3408 +
3409 +    if (a20addr <= 0x0009ffff) {
3410 +      // regular memory 80000 .. 9FFFF
3411 +      taint_vector[a20addr] = *data_ptr;
3412 +      goto inc_one;
3413 +      }
3414 +    if (a20addr <= 0x000bffff) {
3415 +      // VGA memory A0000 .. BFFFF
3416 +      return; //assert(0);
3417 +      //DEV_vga_mem_write(a20addr, *data_ptr);
3418 +      //BX_DBG_DIRTY_PAGE(a20addr >> 12);
3419 +      //BX_DBG_UCMEM_REPORT(a20addr, 1, BX_WRITE, *data_ptr); // obsolete
3420 +      goto inc_one;
3421 +      }
3422 +    // adapter ROM     C0000 .. DFFFF
3423 +    // ROM BIOS memory E0000 .. FFFFF
3424 +    // (ignore write)
3425 +    //BX_INFO(("ROM lock %08x: len=%u",
3426 +    //  (unsigned) a20addr, (unsigned) len));
3427 +#if BX_PCI_SUPPORT == 0
3428 +#if BX_SHADOW_RAM
3429 +    // Write it since its in shadow RAM
3430 +    taint_vector[a20addr] = *data_ptr;
3431 +#else
3432 +    // ignore write to ROM
3433 +#endif
3434 +#else
3435 +    // Write Based on 440fx Programming
3436 +    if (bx_options.Oi440FXSupport->get () &&
3437 +        ((a20addr >= 0xC0000) && (a20addr <= 0xFFFFF))) {
3438 +      switch (DEV_pci_wr_memtype(a20addr & 0xFC000)) {
3439 +        case 0x1:   // Writes to ShadowRAM
3440 +         assert(0);
3441 +//        BX_INFO(("Writing to ShadowRAM %08x, len %u ! ", (unsigned) a20addr, (unsigned) len));
3442 +          shadow[a20addr - 0xc0000] = *data_ptr;
3443 +          BX_DBG_DIRTY_PAGE(a20addr >> 12);
3444 +          goto inc_one;
3445 +
3446 +        case 0x0:   // Writes to ROM, Inhibit
3447 +         assert(0);
3448 +          //BX_DEBUG(("Write to ROM ignored: address %08x, data %02x", (unsigned) a20addr, *data_ptr));
3449 +          goto inc_one;
3450 +        default:
3451 +          BX_PANIC(("writePhysicalPage: default case"));
3452 +          goto inc_one;
3453 +        }
3454 +      }
3455 +#endif
3456 +    goto inc_one;
3457 +    }
3458 +
3459 +  else {
3460 +    // some or all of data is outside limits of physical memory
3461 +    unsigned i;
3462 +
3463 +#ifdef BX_LITTLE_ENDIAN
3464 +  data_ptr = (Bit32u *) data;
3465 +#else // BX_BIG_ENDIAN
3466 +  data_ptr = (Bit32u *) data + (len - 1);
3467 +#endif
3468 +
3469 +
3470 +#if BX_SUPPORT_VBE
3471 +    // Check VBE LFB support
3472 +    
3473 +    if ((a20addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS) &&
3474 +        (a20addr <  (VBE_DISPI_LFB_PHYSICAL_ADDRESS +  VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)))
3475 +    {
3476 +      assert(0);
3477 +      return;
3478 +    }
3479 +    
3480 +#endif    
3481
3482 +
3483 +#if BX_SUPPORT_APIC
3484 +    //assert(0);
3485 +    return;
3486 +#endif
3487 +    for (i = 0; i < len; i++) {
3488 +      if (a20addr < BX_MEM_THIS len) {
3489 +        taint_vector[a20addr] = *data_ptr;
3490 +        }
3491 +      // otherwise ignore byte, since it overruns memory
3492 +      addr++;
3493 +      a20addr = (addr);
3494 +#ifdef BX_LITTLE_ENDIAN
3495 +      data_ptr++;
3496 +#else // BX_BIG_ENDIAN
3497 +      data_ptr--;
3498 +#endif
3499 +      }
3500 +    return;
3501 +    }
3502 +}
3503 diff -urpN bochs-2.1.1.orig/taint/memory.cc.bak checkbochs-2.1.1/taint/memory.cc.bak
3504 diff -urpN bochs-2.1.1.orig/taint/mydebug.h checkbochs-2.1.1/taint/mydebug.h
3505 --- bochs-2.1.1.orig/taint/mydebug.h    1969-12-31 16:00:00.000000000 -0800
3506 +++ checkbochs-2.1.1/taint/mydebug.h    2005-06-29 11:19:16.000000000 -0700
3507 @@ -0,0 +1,28 @@
3508 +#ifndef __MYDEBUG_H
3509 +#define __MYDEBUG_H
3510 +
3511 +#define ACCESS_LINEAR 0
3512 +#define L1 0
3513 +#define LOCKS 0
3514 +#define CHECKBOCHS 1
3515 +#define WRN 1
3516 +#define ERR 1
3517 +
3518 +void checkbochs_log (const char *fmt, ...) ;
3519 +
3520 +#define DBG(l,x) if (l) {                                              \
3521 +       checkbochs_log x;                                                       \
3522 +       /*bx_dbg_disassemble_current(-1,0);*/                           \
3523 +}
3524 +
3525 +#define PANIC(...) do {                                \
3526 +       printf("PANIC at %s:%d in %s(): ",__FILE__,__LINE__,__func__);   \
3527 +       BX_CPU(0)->panic(__VA_ARGS__);          \
3528 +} while(0)
3529 +
3530 +#define ASSERT(CONDITION)                                      \
3531 +       if (CONDITION) { } else {                               \
3532 +               PANIC ("assertion `%s' failed.", #CONDITION);   \
3533 +       }
3534 +
3535 +#endif
3536 diff -urpN bochs-2.1.1.orig/taint/mydebug.h.bak checkbochs-2.1.1/taint/mydebug.h.bak
3537 diff -urpN bochs-2.1.1.orig/taint/paging.cc checkbochs-2.1.1/taint/paging.cc
3538 --- bochs-2.1.1.orig/taint/paging.cc    1969-12-31 16:00:00.000000000 -0800
3539 +++ checkbochs-2.1.1/taint/paging.cc    2005-06-29 11:19:16.000000000 -0700
3540 @@ -0,0 +1,241 @@
3541 +#define NEED_CPU_REG_SHORTCUTS 1
3542 +#include "bochs.h"
3543 +#define LOG_THIS BX_CPU_THIS_PTR
3544 +
3545 +#include "taint/globals.h"
3546 +#include "taint/mydebug.h"
3547 +#include "taint/lockset.h"
3548 +
3549 +#if BX_USE_CPU_SMF
3550 +#define this (BX_CPU(0))
3551 +#endif
3552 +
3553 +
3554 +#if BX_SUPPORT_PAGING
3555 +
3556 +#define InstrTLB_Stats()
3557 +#define InstrTLB_Increment(v)
3558 +
3559 +// ==============================================================
3560 +
3561 +
3562 +// Translate a linear address to a physical address, for
3563 +// a data access (D)
3564 +
3565 +  Bit32s BX_CPP_AttrRegparmN(3)
3566 +BX_CPU_C::taint_dtranslate_linear(bx_address laddr, unsigned pl, unsigned rw)
3567 +{
3568 +  bx_address   lpf;
3569 +  Bit32u   ppf, poffset, TLB_index, error_code, paddress;
3570 +  Bit32u   pde, pde_addr;
3571 +  bx_bool  isWrite;
3572 +  Bit32u   accessBits, combined_access;
3573 +  unsigned priv_index;
3574 +
3575 +  // CR4.PAE==0 (and MSR.LMA==0)
3576 +
3577 +  lpf       = laddr & 0xfffff000; // linear page frame
3578 +  poffset   = laddr & 0x00000fff; // physical offset
3579 +  TLB_index = BX_TLB_INDEX_OF(lpf);
3580 +
3581 +
3582 +  //isWrite = (rw>=BX_WRITE); // write or r-m-w
3583 +  isWrite = 0; // sorav: allow write accesses even if you have only read permissions on the address
3584 +
3585 +  if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == BX_TLB_LPF_VALUE(lpf)) {
3586 +    paddress   = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
3587 +    accessBits = BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits;
3588 +    if (accessBits & (1 << ((isWrite<<1) | pl)) ) {
3589 +      return(paddress);
3590 +      }
3591 +
3592 +    // The current access does not have permission according to the info
3593 +    // in our TLB cache entry.  Re-walk the page tables, in case there is
3594 +    // updated information in the memory image, and let the long path code
3595 +    // generate an exception if one is warranted.
3596 +    }
3597 +
3598 +  return(-1); //return -1 for failure
3599 +}
3600 +
3601 +
3602 +// Translate a linear address to a physical address, for
3603 +// an instruction fetch access (I)
3604 +
3605 +  Bit32u BX_CPP_AttrRegparmN(2)
3606 +BX_CPU_C::taint_itranslate_linear(bx_address laddr, unsigned pl)
3607 +{
3608 +  //assign_type(type8,generic_type_executed_code8);
3609 +
3610 +  ////Bit32u pAddr = dtranslate_linear_type(laddr, pl, BX_READ);
3611 +  //printf("Assigning a codebyte.\n");
3612 +  //access_linear_type(laddr,1,pl,BX_WRITE,type8);
3613 +  //typestats_t stats;
3614 +  //stats.print(BX_CPU_THIS_PTR mem->type_vector,BX_CPU_THIS_PTR mem->len);
3615 +  exit(0);
3616 +}
3617 +
3618 +
3619 +  int BX_CPP_AttrRegparmN(3)
3620 +BX_CPU_C::access_linear_taint(bx_address laddr, unsigned length, unsigned pl,
3621 +    unsigned rw, void *taint_value)
3622 +{
3623 +  Bit32u pageOffset;
3624 +  unsigned xlate_rw;
3625 +  int try_access;
3626 +
3627 +  assert(length==1);
3628 +  ASSERT(rw==BX_READ || get_value(*(Bit32u*)taint_value)<2 || get_state(*(Bit32u*)taint_value));
3629 +  if (rw==BX_RW) {
3630 +    xlate_rw = BX_RW;
3631 +    rw = BX_READ;
3632 +  }
3633 +  else {
3634 +    xlate_rw = rw;
3635 +  }
3636 +
3637 +  pageOffset = laddr & 0x00000fff;
3638 +
3639 +  if (BX_CPU_THIS_PTR cr0.pg) {
3640 +    /* check for reference across multiple pages */
3641 +    if ( (pageOffset + length) <= 4096 ) {
3642 +      // Access within single page.
3643 +      try_access = taint_dtranslate_linear(laddr, pl, xlate_rw);
3644 +      if (try_access==-1) return 0;
3645 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = try_access;
3646 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
3647 +
3648 +      if (rw == BX_READ) {
3649 +        BX_INSTR_LIN_READ(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
3650 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
3651 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, taint_value);
3652 +        }
3653 +      else {
3654 +        BX_INSTR_LIN_WRITE(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
3655 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
3656 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, taint_value);
3657 +        }
3658 +      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
3659 +      }
3660 +    else {
3661 +      try_access = taint_dtranslate_linear(laddr, pl, xlate_rw);
3662 +      if (try_access==-1) return 0;
3663 +      // access across 2 pages
3664 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = try_access;
3665 +      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
3666 +      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
3667 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
3668 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
3669 +      try_access = taint_dtranslate_linear(laddr + BX_CPU_THIS_PTR address_xlation.taint_len1, pl, xlate_rw);
3670 +      if (try_access==-1) return 0;
3671 +      BX_CPU_THIS_PTR address_xlation.taint_paddress2 = try_access;
3672 +
3673 +#ifdef BX_LITTLE_ENDIAN
3674 +      if (rw == BX_READ) {
3675 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3676 +                             BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
3677 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3678 +                             BX_CPU_THIS_PTR address_xlation.taint_len2,
3679 +                             ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
3680 +        }
3681 +      else {
3682 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3683 +                              BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
3684 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3685 +                              BX_CPU_THIS_PTR address_xlation.taint_len2,
3686 +                              ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
3687 +        }
3688 +
3689 +#else // BX_BIG_ENDIAN
3690 +      if (rw == BX_READ) {
3691 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3692 +                             BX_CPU_THIS_PTR address_xlation.taint_len1,
3693 +                             ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
3694 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3695 +                             BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
3696 +        }
3697 +      else {
3698 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3699 +                              BX_CPU_THIS_PTR address_xlation.taint_len1,
3700 +                              ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
3701 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3702 +                              BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
3703 +        }
3704 +#endif
3705 +
3706 +      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
3707 +      }
3708 +    }
3709 +
3710 +  else {
3711 +    // Paging off.
3712 +    if ( (pageOffset + length) <= 4096 ) {
3713 +      // Access within single page.
3714 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
3715 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
3716 +      if (rw == BX_READ) {
3717 +
3718 +        // Let access fall through to the following for this iteration.
3719 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, laddr, length, taint_value);
3720 +        }
3721 +      else { // Write
3722 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, laddr, length, taint_value);
3723 +        }
3724 +      }
3725 +    else {
3726 +      // Access spans two pages.
3727 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
3728 +      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
3729 +      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
3730 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
3731 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
3732 +      BX_CPU_THIS_PTR address_xlation.taint_paddress2 = laddr +
3733 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
3734 +
3735 +#ifdef BX_LITTLE_ENDIAN
3736 +      if (rw == BX_READ) {
3737 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
3738 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3739 +            BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
3740 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
3741 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3742 +            BX_CPU_THIS_PTR address_xlation.taint_len2,
3743 +            ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
3744 +        }
3745 +      else {
3746 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
3747 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3748 +            BX_CPU_THIS_PTR address_xlation.taint_len1, taint_value);
3749 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
3750 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3751 +            BX_CPU_THIS_PTR address_xlation.taint_len2,
3752 +            ((Bit32u*)taint_value) + BX_CPU_THIS_PTR address_xlation.taint_len1);
3753 +        }
3754 +
3755 +#else // BX_BIG_ENDIAN
3756 +      if (rw == BX_READ) {
3757 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
3758 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3759 +            BX_CPU_THIS_PTR address_xlation.taint_len1,
3760 +            ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
3761 +        BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this,
3762 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3763 +            BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
3764 +        }
3765 +      else {
3766 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
3767 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
3768 +            BX_CPU_THIS_PTR address_xlation.taint_len1,
3769 +            ((Bit32u*)taint_value) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
3770 +        BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this,
3771 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
3772 +            BX_CPU_THIS_PTR address_xlation.taint_len2, taint_value);
3773 +        }
3774 +#endif
3775 +      }
3776 +    //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
3777 +    }
3778 +    return 1;
3779 +}
3780 +
3781 +#endif
3782 diff -urpN bochs-2.1.1.orig/taint/paging.cc.bak checkbochs-2.1.1/taint/paging.cc.bak
3783 diff -urpN bochs-2.1.1.orig/taint/silent_access.cc checkbochs-2.1.1/taint/silent_access.cc
3784 --- bochs-2.1.1.orig/taint/silent_access.cc     1969-12-31 16:00:00.000000000 -0800
3785 +++ checkbochs-2.1.1/taint/silent_access.cc     2005-06-29 11:19:16.000000000 -0700
3786 @@ -0,0 +1,210 @@
3787 +#define NEED_CPU_REG_SHORTCUTS 1
3788 +#include "bochs.h"
3789 +#define LOG_THIS BX_CPU_THIS_PTR
3790 +
3791 +#if BX_SUPPORT_X86_64
3792 +#define IsLongMode() (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
3793 +#define LPFOf(laddr) ((laddr) & BX_CONST64(0xfffffffffffff000))
3794 +#define BX_CANONICAL_BITS     48
3795 +#define IsCanonical(offset)   ((Bit64u)((((Bit64s)(offset)) >> (BX_CANONICAL_BITS-1)) + 1) < 2)
3796 +
3797 +//#define BX_CANONICAL_LO       BX_CONST64(0xffff800000000000)
3798 +//#define BX_CANONICAL_HI       BX_CONST64(0x0000800000000000)
3799 +//#define IsCanonical(offset)   ((Bit64u)(offset-BX_CANONICAL_LO) < (Bit64u)(BX_CANONICAL_HI-BX_CANONICAL_LO))
3800 +
3801 +#else
3802 +#define IsLongMode() (0)
3803 +#define LPFOf(laddr) ((laddr) & 0xfffff000)
3804 +#define IsCanonical(offset) (0)
3805 +#endif
3806 +
3807 +
3808 +  int BX_CPP_AttrRegparmN(3)
3809 +BX_CPU_C::read_virtual_checks_silent(bx_segment_reg_t *seg, bx_address offset,
3810 +                              unsigned length)
3811 +{
3812 +  Bit32u upper_limit;
3813 +
3814 +  if (protected_mode()) {
3815 +    if (seg->cache.valid==0) {
3816 +      BX_ERROR(("seg = %s", BX_CPU_THIS_PTR strseg(seg)));
3817 +      BX_ERROR(("seg->selector.value = %04x", (unsigned) seg->selector.value));
3818 +      //exception(BX_GP_EXCEPTION, 0, 0);
3819 +      return 0;
3820 +      }
3821 +
3822 +    if (seg->cache.p == 0) { /* not present */
3823 +          BX_INFO(("read_virtual_checks(): segment not present"));
3824 +      //exception(int_number(seg), 0, 0);
3825 +      return 0;
3826 +      }
3827 +
3828 +    switch (seg->cache.type) {
3829 +      case 0: case 1: /* read only */
3830 +      case 10: case 11: /* execute/read */
3831 +      case 14: case 15: /* execute/read-only, conforming */
3832 +        if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
3833 +            || (length-1 > seg->cache.u.segment.limit_scaled)) {
3834 +                  BX_INFO(("read_virtual_checks(): write beyond limit"));
3835 +          //exception(int_number(seg), 0, 0);
3836 +          return 0;
3837 +          }
3838 +        if (seg->cache.u.segment.limit_scaled >= 7) {
3839 +          // Mark cache as being OK type for succeeding writes.  See notes for
3840 +          // write checks; similar code.
3841 +          seg->cache.valid |= SegAccessROK;
3842 +          }
3843 +        break;
3844 +
3845 +      case 2: case 3: /* read/write */
3846 +        if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
3847 +            || (length-1 > seg->cache.u.segment.limit_scaled)) {
3848 +                  BX_INFO(("read_virtual_checks(): write beyond limit"));
3849 +          //exception(int_number(seg), 0, 0);
3850 +          return 0;
3851 +          }
3852 +        if (seg->cache.u.segment.limit_scaled >= 7) {
3853 +          // Mark cache as being OK type for succeeding writes.  See notes for
3854 +          // write checks; similar code.
3855 +          seg->cache.valid |= SegAccessROK;
3856 +          }
3857 +        break;
3858 +
3859 +      case 4: case 5: /* read only, expand down */
3860 +        if (seg->cache.u.segment.d_b)
3861 +          upper_limit = 0xffffffff;
3862 +        else
3863 +          upper_limit = 0x0000ffff;
3864 +        if ((offset <= seg->cache.u.segment.limit_scaled) ||
3865 +             (offset > upper_limit) ||
3866 +             ((upper_limit - offset) < (length - 1))) {
3867 +                  BX_INFO(("read_virtual_checks(): write beyond limit"));
3868 +          //exception(int_number(seg), 0, 0);
3869 +          return 0;
3870 +          }
3871 +        break;
3872 +
3873 +      case 6: case 7: /* read write, expand down */
3874 +        if (seg->cache.u.segment.d_b)
3875 +          upper_limit = 0xffffffff;
3876 +        else
3877 +          upper_limit = 0x0000ffff;
3878 +        if ((offset <= seg->cache.u.segment.limit_scaled) ||
3879 +             (offset > upper_limit) ||
3880 +             ((upper_limit - offset) < (length - 1))) {
3881 +                  BX_INFO(("read_virtual_checks(): write beyond limit"));
3882 +          //exception(int_number(seg), 0, 0);
3883 +          return 0;
3884 +          }
3885 +        break;
3886 +
3887 +      case 8: case 9: /* execute only */
3888 +      case 12: case 13: /* execute only, conforming */
3889 +        /* can't read or write an execute-only segment */
3890 +                BX_INFO(("read_virtual_checks(): execute only"));
3891 +        //exception(int_number(seg), 0, 0);
3892 +        return 0;
3893 +        break;
3894 +      }
3895 +    return 1;
3896 +    }
3897 +
3898 +  else { /* real mode */
3899 +    if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
3900 +        || (length-1 > seg->cache.u.segment.limit_scaled)) {
3901 +      //BX_ERROR(("read_virtual_checks() SEG EXCEPTION:  %x:%x + %x",
3902 +      //  (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
3903 +      if (seg == & BX_CPU_THIS_PTR sregs[2]) {
3904 +       //exception(BX_SS_EXCEPTION, 0, 0);
3905 +       return 0;
3906 +      } else {
3907 +        //exception(BX_GP_EXCEPTION, 0, 0);
3908 +       return 0;
3909 +      }
3910 +      }
3911 +    if (seg->cache.u.segment.limit_scaled >= 7) {
3912 +      // Mark cache as being OK type for succeeding writes.  See notes for
3913 +      // write checks; similar code.
3914 +      seg->cache.valid |= SegAccessROK;
3915 +      }
3916 +    return 1;
3917 +    }
3918 +}
3919 +
3920 +  int BX_CPP_AttrRegparmN(3)
3921 +BX_CPU_C::read_virtual_byte_silent(unsigned s, bx_address offset, Bit8u *data)
3922 +{
3923 +  bx_address laddr;
3924 +  bx_segment_reg_t *seg;
3925 +  int ret = 1;
3926 +
3927 +  seg = &BX_CPU_THIS_PTR sregs[s];
3928 +  if (seg->cache.valid & SegAccessROK) {
3929 +    if ((IsLongMode() && IsCanonical(offset))
3930 +     || (offset <= seg->cache.u.segment.limit_scaled)) {
3931 +      unsigned pl;
3932 +accessOK:
3933 +      laddr = seg->cache.u.segment.base + offset;
3934 +      BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 1, BX_READ);
3935 +      pl = (CPL==3);
3936 +
3937 +      ret = access_linear_silent(laddr, 1, pl, BX_READ, (void *) data);
3938 +      return ret;
3939 +      }
3940 +    }
3941 +  ret = read_virtual_checks_silent(seg, offset, 1); //if exception would be raised return 0
3942 +  if (!ret) return 0;
3943 +  goto accessOK;
3944 +}
3945 +
3946 +  int BX_CPP_AttrRegparmN(3)
3947 +BX_CPU_C::read_virtual_word_silent(unsigned s, bx_address offset, Bit16u *data)
3948 +{
3949 +  bx_address laddr;
3950 +  bx_segment_reg_t *seg;
3951 +  int ret;
3952 +
3953 +  seg = &BX_CPU_THIS_PTR sregs[s];
3954 +  if (seg->cache.valid & SegAccessROK) {
3955 +    if ((IsLongMode() && IsCanonical(offset))
3956 +     || (offset < seg->cache.u.segment.limit_scaled)) {
3957 +      unsigned pl;
3958 +accessOK:
3959 +      laddr = seg->cache.u.segment.base + offset;
3960 +      BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 2, BX_READ);
3961 +      pl = (CPL==3);
3962 +
3963 +      ret = access_linear_silent(laddr, 2, pl, BX_READ, (void *) data);
3964 +      return ret;
3965 +      }
3966 +    }
3967 +  ret = read_virtual_checks_silent(seg, offset, 2);
3968 +  if (!ret) return 0;
3969 +  goto accessOK;
3970 +}
3971 +
3972 +  int BX_CPP_AttrRegparmN(3)
3973 +BX_CPU_C::read_virtual_dword_silent(unsigned s, bx_address offset, Bit32u *data)
3974 +{
3975 +  bx_address laddr;
3976 +  bx_segment_reg_t *seg;
3977 +  int ret;
3978 +
3979 +  seg = &BX_CPU_THIS_PTR sregs[s];
3980 +  if (seg->cache.valid & SegAccessROK) {
3981 +    if ((IsLongMode() && IsCanonical(offset))
3982 +     || (offset < (seg->cache.u.segment.limit_scaled-2))) {
3983 +      unsigned pl;
3984 +accessOK:
3985 +      laddr = seg->cache.u.segment.base + offset;
3986 +      BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 4, BX_READ);
3987 +      pl = (CPL==3);
3988 +
3989 +      ret = access_linear_silent(laddr, 4, pl, BX_READ, (void *) data);
3990 +      return ret;
3991 +      }
3992 +    }
3993 +  ret = read_virtual_checks_silent(seg, offset, 4);
3994 +  if (!ret) return 0;
3995 +  goto accessOK;
3996 +}
3997 diff -urpN bochs-2.1.1.orig/taint/silent_access.cc.bak checkbochs-2.1.1/taint/silent_access.cc.bak
3998 diff -urpN bochs-2.1.1.orig/taint/silent_paging.cc checkbochs-2.1.1/taint/silent_paging.cc
3999 --- bochs-2.1.1.orig/taint/silent_paging.cc     1969-12-31 16:00:00.000000000 -0800
4000 +++ checkbochs-2.1.1/taint/silent_paging.cc     2005-06-29 11:19:16.000000000 -0700
4001 @@ -0,0 +1,175 @@
4002 +#define NEED_CPU_REG_SHORTCUTS 1
4003 +#include "bochs.h"
4004 +#define LOG_THIS BX_CPU_THIS_PTR
4005 +
4006 +#if BX_USE_CPU_SMF
4007 +#define this (BX_CPU(0))
4008 +#endif
4009 +
4010 +
4011 +#if BX_SUPPORT_PAGING
4012 +
4013 +#define InstrTLB_Stats()
4014 +#define InstrTLB_Increment(v)
4015 +
4016 +// ==============================================================
4017 +
4018 +
4019 +  int BX_CPP_AttrRegparmN(3)
4020 +BX_CPU_C::access_linear_silent(bx_address laddr, unsigned length, unsigned pl,
4021 +    unsigned rw, void *data)
4022 +{
4023 +  Bit32u pageOffset;
4024 +  unsigned xlate_rw;
4025 +
4026 +  assert(rw==BX_READ);
4027 +  if (rw==BX_RW) {
4028 +    xlate_rw = BX_RW;
4029 +    rw = BX_READ;
4030 +  }
4031 +  else {
4032 +    xlate_rw = rw;
4033 +  }
4034 +
4035 +  pageOffset = laddr & 0x00000fff;
4036 +
4037 +  if (BX_CPU_THIS_PTR cr0.pg) {
4038 +    /* check for reference across multiple pages */
4039 +    if ( (pageOffset + length) <= 4096 ) {
4040 +      // Access within single page.
4041 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 =
4042 +          taint_dtranslate_linear(laddr, pl, xlate_rw);
4043 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
4044 +
4045 +      if (rw == BX_READ) {
4046 +        BX_INSTR_LIN_READ(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
4047 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this,
4048 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, data );
4049 +        }
4050 +      else {
4051 +        BX_INSTR_LIN_WRITE(BX_CPU_ID, laddr, BX_CPU_THIS_PTR address_xlation.taint_paddress1, length);
4052 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this,
4053 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1, length, data);
4054 +        }
4055 +      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
4056 +      }
4057 +    else {
4058 +      // access across 2 pages
4059 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 =
4060 +          taint_dtranslate_linear(laddr, pl, xlate_rw);
4061 +      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
4062 +      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
4063 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
4064 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
4065 +      BX_CPU_THIS_PTR address_xlation.taint_paddress2 =
4066 +          taint_dtranslate_linear(laddr + BX_CPU_THIS_PTR address_xlation.taint_len1,
4067 +                            pl, xlate_rw);
4068 +
4069 +#ifdef BX_LITTLE_ENDIAN
4070 +      if (rw == BX_READ) {
4071 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4072 +                             BX_CPU_THIS_PTR address_xlation.taint_len1, data);
4073 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4074 +                             BX_CPU_THIS_PTR address_xlation.taint_len2,
4075 +                             ((Bit32u*)data) + BX_CPU_THIS_PTR address_xlation.taint_len1);
4076 +        }
4077 +      else {
4078 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4079 +                              BX_CPU_THIS_PTR address_xlation.taint_len1, data);
4080 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4081 +                              BX_CPU_THIS_PTR address_xlation.taint_len2,
4082 +                              ((Bit32u*)data) + BX_CPU_THIS_PTR address_xlation.taint_len1);
4083 +        }
4084 +
4085 +#else // BX_BIG_ENDIAN
4086 +      if (rw == BX_READ) {
4087 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4088 +                             BX_CPU_THIS_PTR address_xlation.taint_len1,
4089 +                             ((Bit32u*)data) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
4090 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4091 +                             BX_CPU_THIS_PTR address_xlation.taint_len2, data);
4092 +        }
4093 +      else {
4094 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4095 +                              BX_CPU_THIS_PTR address_xlation.taint_len1,
4096 +                              ((Bit32u*)data) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
4097 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4098 +                              BX_CPU_THIS_PTR address_xlation.taint_len2, data);
4099 +        }
4100 +#endif
4101 +
4102 +      //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
4103 +      }
4104 +    }
4105 +
4106 +  else {
4107 +    // Paging off.
4108 +    if ( (pageOffset + length) <= 4096 ) {
4109 +      // Access within single page.
4110 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
4111 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 1;
4112 +      if (rw == BX_READ) {
4113 +
4114 +        // Let access fall through to the following for this iteration.
4115 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
4116 +        }
4117 +      else { // Write
4118 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
4119 +        }
4120 +      }
4121 +    else {
4122 +      // Access spans two pages.
4123 +      BX_CPU_THIS_PTR address_xlation.taint_paddress1 = laddr;
4124 +      BX_CPU_THIS_PTR address_xlation.taint_len1 = 4096 - pageOffset;
4125 +      BX_CPU_THIS_PTR address_xlation.taint_len2 = length -
4126 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
4127 +      BX_CPU_THIS_PTR address_xlation.taint_pages     = 2;
4128 +      BX_CPU_THIS_PTR address_xlation.taint_paddress2 = laddr +
4129 +          BX_CPU_THIS_PTR address_xlation.taint_len1;
4130 +
4131 +#ifdef BX_LITTLE_ENDIAN
4132 +      if (rw == BX_READ) {
4133 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this,
4134 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4135 +            BX_CPU_THIS_PTR address_xlation.taint_len1, data);
4136 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this,
4137 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4138 +            BX_CPU_THIS_PTR address_xlation.taint_len2,
4139 +            ((Bit32u*)data) + BX_CPU_THIS_PTR address_xlation.taint_len1);
4140 +        }
4141 +      else {
4142 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this,
4143 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4144 +            BX_CPU_THIS_PTR address_xlation.taint_len1, data);
4145 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this,
4146 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4147 +            BX_CPU_THIS_PTR address_xlation.taint_len2,
4148 +            ((Bit32u*)data) + BX_CPU_THIS_PTR address_xlation.taint_len1);
4149 +        }
4150 +
4151 +#else // BX_BIG_ENDIAN
4152 +      if (rw == BX_READ) {
4153 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this,
4154 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4155 +            BX_CPU_THIS_PTR address_xlation.taint_len1,
4156 +            ((Bit32u*)data) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
4157 +        BX_CPU_THIS_PTR mem->readPhysicalPage(this,
4158 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4159 +            BX_CPU_THIS_PTR address_xlation.taint_len2, data);
4160 +        }
4161 +      else {
4162 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this,
4163 +            BX_CPU_THIS_PTR address_xlation.taint_paddress1,
4164 +            BX_CPU_THIS_PTR address_xlation.taint_len1,
4165 +            ((Bit32u*)data) + (length - BX_CPU_THIS_PTR address_xlation.taint_len1));
4166 +        BX_CPU_THIS_PTR mem->writePhysicalPage(this,
4167 +            BX_CPU_THIS_PTR address_xlation.taint_paddress2,
4168 +            BX_CPU_THIS_PTR address_xlation.taint_len2, data);
4169 +        }
4170 +#endif
4171 +      }
4172 +    //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
4173 +    }
4174 +}
4175 +
4176 +#endif
4177 diff -urpN bochs-2.1.1.orig/taint/silent_paging.cc.bak checkbochs-2.1.1/taint/silent_paging.cc.bak
4178 diff -urpN bochs-2.1.1.orig/taint/taint_type.cc checkbochs-2.1.1/taint/taint_type.cc
4179 --- bochs-2.1.1.orig/taint/taint_type.cc        1969-12-31 16:00:00.000000000 -0800
4180 +++ checkbochs-2.1.1/taint/taint_type.cc        2005-06-29 11:19:16.000000000 -0700
4181 @@ -0,0 +1,13 @@
4182 +#define NEED_CPU_REG_SHORTCUTS 1
4183 +#include "bochs.h"
4184 +#define LOG_THIS BX_CPU_THIS_PTR
4185 +
4186 +#include "taint/taint_type.h"
4187 +#include "taint/globals.h"
4188 +
4189 +void assign_taint_functions(char *type) {
4190 +    if (!strcmp(type,"none")) return;
4191 +    if (!strcmp(type,"eraser")) {
4192 +       //g_access_linear_fptr = &(BX_CPU_C::eraser_access_linear);
4193 +    }
4194 +}
4195 diff -urpN bochs-2.1.1.orig/taint/taint_type.cc.bak checkbochs-2.1.1/taint/taint_type.cc.bak
4196 diff -urpN bochs-2.1.1.orig/taint/taint_type.h checkbochs-2.1.1/taint/taint_type.h
4197 --- bochs-2.1.1.orig/taint/taint_type.h 1969-12-31 16:00:00.000000000 -0800
4198 +++ checkbochs-2.1.1/taint/taint_type.h 2005-06-29 11:19:16.000000000 -0700
4199 @@ -0,0 +1,8 @@
4200 +#ifndef __TAINT_TYPE_H
4201 +#define __TAINT_TYPE_H
4202 +
4203 +#define ERASER_ID 0
4204 +
4205 +void assign_taint_functions(char *taint_type);
4206 +
4207 +#endif
4208 diff -urpN bochs-2.1.1.orig/taint/taint_type.h.bak checkbochs-2.1.1/taint/taint_type.h.bak