1 This patch provides Eraser-like lock set checking for Bochs.
2 See the Pintos documentation for more information.
4 This patch is provided by Sorav Bansal <sbansal@cs.stanford.edu>.
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
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@ \
46 @@ -274,6 +274,11 @@ gui/libgui.a::
47 $(MAKE) $(MDEFINES) libgui.a
51 + cd taint @COMMAND_SEPARATOR@
52 + $(MAKE) $(MDEFINES) libtaint.a
56 cd disasm @COMMAND_SEPARATOR@
57 $(MAKE) $(MDEFINES) libdisasm.a
58 @@ -503,6 +508,9 @@ all-clean: clean
59 cd fpu @COMMAND_SEPARATOR@
62 + cd taint @COMMAND_SEPARATOR@
65 cd doc/docbook @COMMAND_SEPARATOR@
68 @@ -538,6 +546,9 @@ dist-clean: local-dist-clean
69 cd fpu @COMMAND_SEPARATOR@
72 + cd taint @COMMAND_SEPARATOR@
75 cd doc/docbook @COMMAND_SEPARATOR@
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 {
83 bx_param_enum_c *Osel_config;
84 bx_param_enum_c *Osel_displaylib;
85 + bx_param_enum_c *Otaint_type ;
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
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
114 #define LOG_THIS BX_CPU_THIS_PTR
116 +#include "taint/globals.h"
117 +#include "taint/mydebug.h"
120 #define this (BX_CPU(0))
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;
126 - BxExecutePtr_t execute;
127 + BxExecutePtr_t execute, taint_execute ;
129 + BX_CPU_THIS_PTR curInstruction = i ;
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.
136 execute = i->execute; // fetch as soon as possible for speculation.
138 + taint_execute = i->taint_execute ;
139 + if (!taint_execute) taint_execute = &BX_CPU_C::NOP ;
142 BX_CPU_CALL_METHODR(resolveModRM, (i));
144 @@ -281,6 +290,10 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
147 execute = i->execute; // fetch as soon as possible for speculation.
149 + taint_execute = i->taint_execute ;
150 + if (!taint_execute) taint_execute = &BX_CPU_C::NOP ;
153 BX_CPU_CALL_METHODR(resolveModRM, (i));
155 @@ -303,6 +316,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_coun
156 BX_INSTR_BEFORE_EXECUTION(BX_CPU_ID);
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:
166 BX_CPU_CALL_METHOD(execute, (i));
167 + BX_CPU_CALL_METHOD(taint_execute, (i));
170 if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
171 @@ -335,6 +350,7 @@ repeat_loop:
174 BX_CPU_CALL_METHOD(execute, (i));
175 + BX_CPU_CALL_METHOD(taint_execute, (i));
178 if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
179 @@ -345,6 +361,7 @@ repeat_loop:
182 BX_CPU_CALL_METHOD(execute, (i));
183 + BX_CPU_CALL_METHOD(taint_execute, (i));
186 if ((i->repUsedValue()==3) && (get_ZF()==0)) goto repeat_done;
187 @@ -358,6 +375,7 @@ repeat_loop:
190 BX_CPU_CALL_METHOD(execute, (i));
191 + BX_CPU_CALL_METHOD(taint_execute, (i));
194 if (RCX == 0) goto repeat_done;
195 @@ -368,6 +386,7 @@ repeat_loop:
198 BX_CPU_CALL_METHOD(execute, (i));
199 + BX_CPU_CALL_METHOD(taint_execute, (i));
202 if (ECX == 0) goto repeat_done;
203 @@ -376,6 +395,7 @@ repeat_loop:
204 else { // 16bit addrsize
206 BX_CPU_CALL_METHOD(execute, (i));
207 + BX_CPU_CALL_METHOD(taint_execute, (i));
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);
216 +BX_CPU_C::panic(const char *fmt, ...)
220 + printf("backtrace: %s.\n",backtrace(btstr));
223 + logfunctions::panic(fmt,arg);
227 #if BX_EXTERNAL_DEBUGGER
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:
234 void (*ResolveModrm)(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
235 void (*execute)(bxInstruction_c *);
236 + void (*taint_execute)(bxInstruction_c *);
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 *);
243 // 26..23 ilen (0..15). Leave this one on top so no mask is needed.
244 @@ -821,6 +823,11 @@ public:
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 ; }
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.
262 + Bit32u taint_paddress1;
263 + Bit32u taint_paddress2;
266 + bx_ptr_equiv_t taint_pages;
270 + bxInstruction_c *curInstruction ;
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 {
277 bx_local_apic_c local_apic;
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);
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);
299 + BX_SMF char *backtrace(char *s);
300 + BX_SMF Bit32u callingEIP(void);
302 + BX_SMF void eraser_access_linear(bx_address laddr, unsigned len, unsigned pl, unsigned rw, void *data);
304 + BX_SMF void eraser_init_globals (void) ;
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
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 ();
324 + case 3: /*added by sorav */
325 + RBX = 0x6e696154; // "Tain"
326 + RDX = 0x49646574; // "tedI"
327 + RCX = 0x6c65746e; // "ntel"
331 #if BX_CPU_LEVEL >= 6
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
338 #define LOG_THIS BX_CPU_THIS_PTR
340 +#include "taint/eraser.h"
343 ///////////////////////////
345 @@ -156,6 +158,7 @@ typedef struct BxOpcodeInfo_t {
347 BxExecutePtr_t ExecutePtr;
348 struct BxOpcodeInfo_t *AnotherArray;
349 + BxExecutePtr_t TaintExecutePtr ;
353 @@ -458,6 +461,17 @@ static BxOpcodeInfo_t BxOpcodeInfoG16[8]
354 /* 7 */ { 0, &BX_CPU_C::BxError }
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*/}
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 },
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 },
390 @@ -1564,6 +1580,8 @@ BX_CPU_C::fetchDecode(Bit8u *iptr, bxIns
391 /*os64*/ 0, /*as64*/ 0,
392 /*extend8bit*/ 0, /*repUsed*/ 0);
394 + instruction->setLocked (false) ;
396 sse_prefix = SSE_PREFIX_NONE;
399 @@ -1669,6 +1687,7 @@ another_byte:
401 BX_INSTR_PREFIX_LOCK(BX_CPU_ID);
403 + instruction->setLocked (false) ;
407 @@ -1883,6 +1902,7 @@ modrm_done:
410 instruction->execute = OpcodeInfoPtr->ExecutePtr;
411 + instruction->taint_execute = OpcodeInfoPtr->TaintExecutePtr;
412 instruction->setRepAttr(attr & (BxRepeatable | BxRepeatableZF));
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;
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
428 #define LOG_THIS BX_CPU_THIS_PTR
430 +#include "taint/globals.h"
433 #define this (BX_CPU(0))
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);
439 + BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
443 @@ -1195,6 +1198,7 @@ BX_CPU_C::access_linear(bx_address laddr
447 + BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
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);
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);
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);
470 BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
472 + BX_CPU_THIS_PTR eraser_access_linear(laddr,length,pl,rw,data);
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
485 -CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@ @GUI_CXXFLAGS@
486 +CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@ @GUI_CXXFLAGS@ -fms-extensions
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 {
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
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
510 #include "state_file.h"
512 +#include "taint/taint_type.h"
513 +#include "taint/mydebug.h"
514 +#include "taint/globals.h"
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() ;
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);
530 // update headerbar buttons since drive status can change during init
531 + static char *taint_type_list[] = {
536 + bx_options.Otaint_type = new bx_param_enum_c (BXP_SEL_TAINT_TYPE,
537 + "Taint Type (Eraser,..)",
538 + "Select Taint Type",
543 bx_gui->update_drive_status_buttons ();
545 // The set handler for mouse_enabled does not actually update the gui
546 @@ -2507,7 +2532,7 @@ bx_init_hardware()
548 signal(SIGINT, bx_signal_handler);
551 + assign_taint_functions ("eraser") ;
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]));
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)) ;
563 + if (!bx_options.Otaint_type->set_by_name (params[1])) {
564 + PARSE_ERR(("%s: taint type '%s' not available.", context, params[1]));
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)) ;
571 + strncpy (g_logfn, params[1], 128) ;
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
582 Bit8u *actual_vector;
583 Bit8u *vector; // aligned correctly
585 + Bit32u *actual_taint_vector; //keep a word for every byte
586 + Bit32u *taint_vector; // aligned correctly
589 size_t megabytes; // (len in Megabytes)
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);
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);
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)
611 + taint_vector = NULL;
612 actual_vector = NULL;
613 + actual_taint_vector = NULL;
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;
625 + taint_vector = NULL;
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));
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]));
647 @@ -136,6 +150,7 @@ BX_MEM_C::init_memory(int memsize)
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
665 +top_builddir = $(srcdir)/..
666 +top_srcdir = $(srcdir)/..
673 +CXXFLAGS = -g -O2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES $(X_CFLAGS)
677 +X_LIBS = -L/usr/X11R6/lib
678 +X_PRE_LIBS = -lSM -lICE
683 +BX_INCDIRS = -I.. -I$(srcdir)/.. -I../instrument/stubs -I$(srcdir)/../instrument/stubs
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
696 +BX_INCLUDES = ../bochs.h ../config.h
702 + $(CXX) -c $(BX_INCDIRS) $(CXXFLAGS) $< -o $@
708 + $(RANLIB) libtaint.a
710 +$(OBJS): $(BX_INCLUDES)
712 +$(OBJS64): $(BX_INCLUDES)
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
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
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
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
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
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
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
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
838 +lockset.o: lockset.h lockset.cc hash.h mydebug.h
840 +hash.o: hash.h hash.cc
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
847 +#define NEED_CPU_REG_SHORTCUTS 1
849 +#define LOG_THIS BX_CPU_THIS_PTR
851 +#include "taint/mydebug.h"
852 +#include "taint/globals.h"
856 +#define STACK_DEPTH 256
859 +#define this (BX_CPU(0))
862 +#define MASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT))
864 +/* Page offset (bits 0:13). */
865 +#define PGSHIFT 0 /* Index of first offset bit. */
868 +#define PGBITS 13 /* Number of offset bits. */
873 +#define PGBITS 13 /* Number of offset bits. */
874 +#warning "Dont know whether compiling for Pintos or Linux. Assuming Linux (PGBITS=13)"
878 +#define PGMASK MASK(PGSHIFT, PGBITS) /* Page offset bits (0:12). */
879 +#define PGSIZE (1 << PGBITS) /* Bytes in a page. */
882 + Bit32u arr[STACK_DEPTH];
885 +bool savedRegsStackInitialized = false;
887 +void push(struct stack *s, Bit32u val) {
889 + if (s->top++==STACK_DEPTH) {
890 + DBG(ERR,("Stack Overflow. Exiting.."));
893 + s->arr[s->top-1] = val;
896 +Bit32u pop(struct stack *s) {
900 + DBG(ERR,("Stack Underflow. Exiting.."));
903 + ret = s->arr[s->top-1];
908 +Bit32u stack_init(struct stack *s) {
912 +void BX_CPU_C::TT_TaintSaveRegs(bxInstruction_c *i) {
913 + Bit32u opId = i->Id();
915 + if (!savedRegsStackInitialized) {
916 + stack_init(&savedRegsStack);
917 + savedRegsStackInitialized = true;
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;
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));
939 +BX_CPU_C::thread_current(void) {
940 + unsigned kernelPL = 0;
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
948 + get_SS_ESP_from_TSS(kernelPL,&ss,&esp);
954 +char *BX_CPU_C::backtrace(char *s) {
956 + int stackdepth = 0, readsuccessful = 1;
958 + //printf("EIP = %x.\n",EIP);
959 + snprintf(s,16,"%x ",EIP);
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);
972 +Bit32u BX_CPU_C::callingEIP(void) {
974 + int stackdepth = 0, readsuccessful = 1;
977 + readsuccessful = read_virtual_dword_silent(BX_SEG_REG_SS, ebp+4, &eip);
978 + if (readsuccessful) return eip;
982 +void checkbochs_log (const char *fmt, ...)
989 + va_start (ap, fmt) ;
990 + vfprintf (g_logfp, fmt, ap) ;
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
998 +#define NEED_CPU_REG_SHORTCUTS 1
1000 +#define LOG_THIS BX_CPU_THIS_PTR
1003 +#define this (BX_CPU(0))
1006 +#define PHYS_BASE 0xc0000000
1008 +#include "mydebug.h"
1009 +#include "taint_type.h"
1010 +#include "lockset.h"
1012 +#include "eraser.h"
1013 +#include "globals.h"
1014 +#include "mydebug.h"
1018 +#define WRN_UNINIT(loc) do { \
1019 + /* DBG(WRN,("Thread %x: Read on uninitialized location %x, backtrace: %s\n",myid,loc, backtrace(btstr))); */ \
1022 +#define WRN_ERASER(myid,loc,tval) do { \
1023 + if (!already_warned(loc)) { \
1025 + DBG(WRN,("Thread %x: Warning on location %x, backtrace: %s\n",myid,loc, backtrace(btstr))); \
1030 +struct warn_table_entry {
1035 +static int warn_table_initialized = 0;
1036 +static struct hash warn_table ;
1038 +unsigned warn_hash (const hash_elem *e, void *aux)
1040 + struct warn_table_entry *h = hash_entry (e, struct warn_table_entry, h_elem);
1045 +warn_less (const hash_elem *a_, const hash_elem *b_,
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);
1054 +already_warned(unsigned loc) {
1055 + struct warn_table_entry tmp;
1056 + hash_elem *h_element;
1057 + if (!warn_table_initialized) return 0;
1059 + h_element = hash_find(&warn_table, &tmp.h_elem);
1060 + if (h_element) return 1;
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;
1072 + hash_insert(&warn_table, &tmp->h_elem);
1076 +void BX_CPU_C::TT_Lock(bxInstruction_c *i) {
1077 + Bit32u opId = i->Id();
1078 + if (opId!=ERASER_ID) return;
1080 + Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff;
1081 + DBG(LOCKS,("%x: acquiring lock %x. backtrace: %s\n",myid,ECX,backtrace(btstr)));
1083 + //lockset_t lset = add_lock(cur_held(myid),ECX);
1084 + //update_lockset(myid,lset);
1087 +void BX_CPU_C::TT_Unlock(bxInstruction_c *i) {
1088 + Bit32u opId = i->Id();
1089 + if (opId!=ERASER_ID) return;
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);
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 ;
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);
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);
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)));
1131 + WRN_UNINIT(laddr) ;
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)));
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)));
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)));
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)));
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)));
1163 + /* Update the taintval in shadow memory */
1164 + if (origval!=taintval[i]) {
1165 + try_access = access_linear_taint(laddr+i,1,pl,BX_WRITE,
1167 + ASSERT(try_access);
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]);
1173 + if (!BX_CPU_THIS_PTR get_IF()) eraser_unlock(INTERRUPT_LOCK); //release the lock that I had earlier acquired (to avoid duplicates)
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);
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;
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));
1190 + else if (EAX==LOCKINIT_OP) {
1193 + else if (EAX==IGNOREON_OP) {
1194 + if (global_startup_ignore) {
1197 + set_ignore(myid,true);
1198 + DBG(L1,("setting ignore on for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
1200 + else if (EAX==IGNOREOFF_OP) {
1201 + if (global_startup_ignore) {
1204 + set_ignore(myid,false);
1205 + DBG(L1,("setting ignore off for thread %x. backtrace: %s\n",myid,backtrace(btstr)));
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));
1215 + } else if (EAX==DBG_MARK_OP) {
1216 + Bit32u taintval = 0;
1217 + char str[MAX_STRLEN];
1218 + int pl = 0; //kernel privileges
1221 + ret = access_linear_silent(EDX+i,1,pl,BX_READ,&str[i]) ;
1222 + } while (ret && str[i] && ++i<MAX_STRLEN);
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));
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)) ;
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
1246 +#define IGNORE_OP 0
1247 +#define LOCKINIT_OP 1
1248 +#define IGNOREON_OP 2
1249 +#define IGNOREOFF_OP 3
1251 +#define DBG_MARK_OP 5
1252 +#define GLOBAL_STARTUP_IGNOREOFF_OP 6
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); \
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); \
1266 +#define eraser_init(x) do { \
1267 + Bit32u myid = (BX_CPU_THIS_PTR thread_current())&0x3fffffff; \
1268 + lockset_t mylocks = cur_held(myid); \
1270 + if (belongs(mylocks,x)) { \
1271 + lset = remove_lock(mylocks,x); \
1272 + update_lockset(myid,lset); \
1276 +#define INTERRUPT_LOCK 0x1234
1277 +#define HW_PREFIX_LOCK 0x2345
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
1285 +#define NEED_CPU_REG_SHORTCUTS 1
1287 +#define LOG_THIS BX_CPU_THIS_PTR
1289 +#include "taint/globals.h"
1291 +void (*g_access_linear_fptr)(bx_address laddr, unsigned length, unsigned pl, unsigned rw, void *taint_value) = NULL;
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
1303 +#ifndef __GLOBALS_H
1304 +#define __GLOBALS_H
1306 +#define MAX_STRLEN 128
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
1311 +extern bool global_startup_ignore ;
1312 +extern int disassemble_num ;
1314 +extern FILE *g_logfp ;
1315 +extern char g_logfn[128] ;
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
1323 +#include <stdlib.h>
1325 +#include <assert.h>
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 *);
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.
1339 +hash_init (struct hash *h,
1340 + hash_hash_func *hash, hash_less_func *less, void *aux)
1343 + h->bucket_cnt = 4;
1344 + h->buckets = (list *)(malloc (sizeof *h->buckets * h->bucket_cnt));
1349 + if (h->buckets != NULL)
1358 +/* Removes all the elements from H. */
1360 +hash_clear (struct hash *h)
1364 + for (i = 0; i < h->bucket_cnt; i++)
1365 + list_init (&h->buckets[i]);
1369 +/* Destroys hash table H. */
1371 +hash_destroy (struct hash *h)
1373 + free (h->buckets);
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. */
1381 +hash_insert (struct hash *h, hash_elem *newelem)
1383 + struct list *bucket = find_bucket (h, newelem);
1384 + struct list_elem *old = find_elem (h, bucket, newelem);
1387 + insert_elem (h, bucket, newelem);
1394 +/* Inserts NEW into hash table H, replacing any equal element
1395 + already in the table, which is returned. */
1397 +hash_replace (struct hash *h, hash_elem *newelem)
1399 + struct list *bucket = find_bucket (h, newelem);
1400 + struct list_elem *old = find_elem (h, bucket, newelem);
1403 + remove_elem (h, old);
1404 + insert_elem (h, bucket, newelem);
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. */
1414 +hash_find (struct hash *h, hash_elem *e)
1416 + return find_elem (h, find_bucket (h, e), e);
1419 +/* Finds, removes, and returns an element equal to E in hash
1420 + table H. Returns a null pointer if no equal element existed
1423 +hash_delete (struct hash *h, hash_elem *e)
1425 + struct list_elem *found = find_elem (h, find_bucket (h, e), e);
1426 + if (found != NULL)
1428 + remove_elem (h, found);
1434 +/* Initializes I for iterating hash table H.
1438 + struct hash_iterator i;
1440 + hash_first (&i, h);
1441 + while (hash_next (&i))
1443 + struct foo *f = hash_entry (hash_cur (&i), struct foo, elem);
1444 + ...do something with f...
1447 + NOTE: Modifying a hash table during iteration invalidates all
1451 +hash_first (struct hash_iterator *i, struct hash *h)
1453 + assert (i != NULL);
1454 + assert (h != NULL);
1457 + i->bucket = i->hash->buckets;
1458 + i->elem = list_head (i->bucket);
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.
1465 + NOTE: Modifying a hash table during iteration invalidates all
1468 +hash_next (struct hash_iterator *i)
1470 + assert (i != NULL);
1472 + i->elem = list_next (i->elem);
1473 + while (i->elem == list_end (i->bucket))
1475 + if (++i->bucket >= i->hash->buckets + i->hash->bucket_cnt)
1480 + i->elem = list_begin (i->bucket);
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(). */
1490 +hash_cur (struct hash_iterator *i)
1495 +/* Returns the number of elements in H. */
1497 +hash_size (struct hash *h)
1499 + return h->elem_cnt;
1502 +/* Returns true if H contains no elements, false otherwise. */
1504 +hash_empty (struct hash *h)
1506 + return h->elem_cnt == 0;
1509 +/* Fowler-Noll-Vo hash constants, for 32-bit word sizes. */
1510 +#define FNV_32_PRIME 16777619u
1511 +#define FNV_32_BASIS 2166136261u
1513 +/* Returns a hash of the SIZE bytes in BUF. */
1515 +hash_bytes (const void *buf_, size_t size)
1517 + /* Fowler-Noll-Vo 32-bit hash, for bytes. */
1518 + const unsigned char *buf = (unsigned char *)buf_;
1521 + assert (buf != NULL);
1523 + hash = FNV_32_BASIS;
1524 + while (size-- > 0)
1525 + hash = (hash * FNV_32_PRIME) ^ *buf++;
1530 +/* Returns a hash of string S. */
1532 +hash_string (const char *s_)
1534 + const unsigned char *s = (unsigned char *)s_;
1537 + assert (s != NULL);
1539 + hash = FNV_32_BASIS;
1540 + while (*s != '\0')
1541 + hash = (hash * FNV_32_PRIME) ^ *s++;
1546 +/* Returns a hash of integer I. */
1550 + return hash_bytes (&i, sizeof i);
1553 +/* Returns the bucket in H that E belongs in. */
1554 +static struct list *
1555 +find_bucket (struct hash *h, hash_elem *e)
1557 + size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
1558 + return &h->buckets[bucket_idx];
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)
1566 + struct list_elem *i;
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))
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)
1578 + return x & (x - 1);
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)
1585 + return x != 0 && turn_off_least_1bit (x) == 0;
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. */
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. */
1598 +rehash (struct hash *h)
1600 + size_t old_bucket_cnt, new_bucket_cnt;
1601 + struct list *new_buckets, *old_buckets;
1604 + assert (h != NULL);
1606 + /* Save old bucket info for later use. */
1607 + old_buckets = h->buckets;
1608 + old_bucket_cnt = h->bucket_cnt;
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);
1620 + /* Don't do anything if the bucket count wouldn't change. */
1621 + if (new_bucket_cnt == old_bucket_cnt)
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)
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. */
1633 + for (i = 0; i < new_bucket_cnt; i++)
1634 + list_init (&new_buckets[i]);
1636 + /* Install new bucket info. */
1637 + h->buckets = new_buckets;
1638 + h->bucket_cnt = new_bucket_cnt;
1640 + /* Move each old element into the appropriate new bucket. */
1641 + for (i = 0; i < old_bucket_cnt; i++)
1643 + struct list *old_bucket;
1644 + struct list_elem *elem, *next;
1646 + old_bucket = &old_buckets[i];
1647 + for (elem = list_begin (old_bucket);
1648 + elem != list_end (old_bucket); elem = next)
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);
1657 + free (old_buckets);
1660 +/* Inserts E into BUCKET (in hash table H). */
1662 +insert_elem (struct hash *h, struct list *bucket, hash_elem *e)
1665 + list_push_front (bucket, e);
1668 +/* Removes E from hash table H. */
1670 +remove_elem (struct hash *h, hash_elem *e)
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
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.
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.
1699 + The FAQ for the VM project contains a detailed example of how
1700 + to use the hash table. */
1702 +#include <stdbool.h>
1703 +#include <stddef.h>
1704 +#include <inttypes.h>
1707 +/* Hash element. */
1708 +typedef list_elem hash_elem;
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)))
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);
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,
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'. */
1739 +/* A hash table iterator. */
1740 +struct hash_iterator
1742 + struct hash *hash; /* The hash table. */
1743 + struct list *bucket; /* Current bucket. */
1744 + hash_elem *elem; /* Current hash element in current bucket. */
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 *);
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 *);
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 *);
1764 +size_t hash_size (struct hash *);
1765 +bool hash_empty (struct hash *);
1767 +/* Sample hash functions. */
1768 +unsigned hash_bytes (const void *, size_t);
1769 +unsigned hash_string (const char *);
1770 +unsigned hash_int (int);
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
1778 +#include <stdlib.h>
1779 +#include <assert.h>
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.
1788 + An empty list looks like this:
1791 + <---| head |<--->| tail |--->
1794 + A list with two elements in it looks like this:
1796 + +------+ +-------+ +-------+ +------+
1797 + <---| head |<--->| 1 |<--->| 2 |<--->| tail |<--->
1798 + +------+ +-------+ +-------+ +------+
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.
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.) */
1812 +/* Returns true if ELEM is a head, false otherwise. */
1814 +is_head (list_elem *elem)
1816 + return elem != NULL && elem->prev == NULL && elem->next != NULL;
1819 +/* Returns true if ELEM is an interior element,
1820 + false otherwise. */
1822 +is_interior (list_elem *elem)
1824 + return elem != NULL && elem->prev != NULL && elem->next != NULL;
1827 +/* Returns true if ELEM is a tail, false otherwise. */
1829 +is_tail (list_elem *elem)
1831 + return elem != NULL && elem->prev != NULL && elem->next == NULL;
1834 +/* Initializes LIST as an empty list. */
1836 +list_init (struct list *list)
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;
1845 +/* Returns the beginning of LIST. */
1847 +list_begin (struct list *list)
1849 + assert (list != NULL);
1850 + return list->head.next;
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. */
1857 +list_next (list_elem *elem)
1859 + assert (is_head (elem) || is_interior (elem));
1860 + return elem->next;
1863 +/* Returns LIST's tail.
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
1869 +list_end (struct list *list)
1871 + assert (list != NULL);
1872 + return &list->tail;
1875 +/* Returns the LIST's reverse beginning, for iterating through
1876 + LIST in reverse order, from back to front. */
1878 +list_rbegin (struct list *list)
1880 + assert (list != NULL);
1881 + return list->tail.prev;
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. */
1888 +list_prev (list_elem *elem)
1890 + assert (is_interior (elem) || is_tail (elem));
1891 + return elem->prev;
1894 +/* Returns LIST's head.
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:
1900 + for (e = list_rbegin (&foo_list); e != list_rend (&foo_list);
1901 + e = list_prev (e))
1903 + struct foo *f = list_entry (e, struct foo, elem);
1904 + ...do something with f...
1908 +list_rend (struct list *list)
1910 + assert (list != NULL);
1911 + return &list->head;
1914 +/* Return's LIST's head.
1916 + list_head() can be used for an alternate style of iterating
1917 + through a list, e.g.:
1919 + e = list_head (&list);
1920 + while ((e = list_next (e)) != list_end (&list))
1926 +list_head (struct list *list)
1928 + assert (list != NULL);
1929 + return &list->head;
1932 +/* Return's LIST's tail. */
1934 +list_tail (struct list *list)
1936 + assert (list != NULL);
1937 + return &list->tail;
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(). */
1944 +list_insert (list_elem *before, list_elem *elem)
1946 + assert (is_interior (before) || is_tail (before));
1947 + assert (elem != NULL);
1949 + elem->prev = before->prev;
1950 + elem->next = before;
1951 + before->prev->next = elem;
1952 + before->prev = elem;
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. */
1959 +list_splice (list_elem *before,
1960 + list_elem *first, list_elem *last)
1962 + assert (is_interior (before) || is_tail (before));
1963 + if (first == last)
1965 + last = list_prev (last);
1967 + assert (is_interior (first));
1968 + assert (is_interior (last));
1970 + /* Cleanly remove FIRST...LAST from its current list. */
1971 + first->prev->next = last->next;
1972 + last->next->prev = first->prev;
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;
1981 +/* Inserts ELEM at the beginning of LIST, so that it becomes the
1984 +list_push_front (struct list *list, list_elem *elem)
1986 + list_insert (list_begin (list), elem);
1989 +/* Inserts ELEM at the end of LIST, so that it becomes the
1992 +list_push_back (struct list *list, list_elem *elem)
1994 + list_insert (list_end (list), elem);
1997 +/* Removes ELEM from its list and returns the element that
1998 + followed it. Undefined behavior if ELEM is not in a list. */
2000 +list_remove (list_elem *elem)
2002 + assert (is_interior (elem));
2003 + elem->prev->next = elem->next;
2004 + elem->next->prev = elem->prev;
2005 + return elem->next;
2008 +/* Removes the front element from LIST and returns it.
2009 + Undefined behavior if LIST is empty before removal. */
2011 +list_pop_front (struct list *list)
2013 + list_elem *front = list_front (list);
2014 + list_remove (front);
2018 +/* Removes the back element from LIST and returns it.
2019 + Undefined behavior if LIST is empty before removal. */
2021 +list_pop_back (struct list *list)
2023 + list_elem *back = list_back (list);
2024 + list_remove (back);
2028 +/* Returns the front element in LIST.
2029 + Undefined behavior if LIST is empty. */
2031 +list_front (struct list *list)
2033 + assert (!list_empty (list));
2034 + return list->head.next;
2037 +/* Returns the back element in LIST.
2038 + Undefined behavior if LIST is empty. */
2040 +list_back (struct list *list)
2042 + assert (!list_empty (list));
2043 + return list->tail.prev;
2046 +/* Returns the number of elements in LIST.
2047 + Runs in O(n) in the number of elements. */
2049 +list_size (struct list *list)
2054 + for (e = list_begin (list); e != list_end (list); e = list_next (e))
2059 +/* Returns true if LIST is empty, false otherwise. */
2061 +list_empty (struct list *list)
2063 + return list_begin (list) == list_end (list);
2066 +/* Swaps the `list_elem *'s that A and B point to. */
2068 +swap (list_elem **a, list_elem **b)
2070 + list_elem *t = *a;
2075 +/* Reverses the order of LIST. */
2077 +list_reverse (struct list *list)
2079 + if (!list_empty (list))
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);
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. */
2095 +list_merge (struct list *al, struct list *bl,
2096 + list_less_func *less, void *aux)
2100 + assert (al != NULL);
2101 + assert (bl != NULL);
2102 + assert (less != NULL);
2104 + a = list_begin (al);
2105 + while (a != list_end (al))
2107 + list_elem *b = list_begin (bl);
2108 + if (less (b, a, aux))
2110 + list_splice (a, b, list_next (b));
2111 + if (list_empty (bl))
2115 + a = list_next (a);
2117 + list_splice (list_end (al), list_begin (bl), list_end (bl));
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. */
2124 +middle_of_list (struct list *list)
2126 + list_elem *middle, *last;
2128 + middle = last = list_begin (list);
2129 + while (last != list_end (list) && list_next (last) != list_end (list))
2131 + middle = list_next (middle);
2132 + last = list_next (list_next (last));
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. */
2140 +list_sort (struct list *list,
2141 + list_less_func *less, void *aux)
2143 + /* Find the middle of the list. */
2144 + list_elem *middle = middle_of_list (list);
2145 + if (middle != list_begin (list))
2147 + /* Extract first half of LIST into a temporary list. */
2150 + list_splice (list_begin (&tmp), list_begin (list), middle);
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);
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
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. */
2170 +list_insert_ordered (struct list *list, list_elem *elem,
2171 + list_less_func *less, void *aux)
2175 + assert (list != NULL);
2176 + assert (elem != NULL);
2177 + assert (less != NULL);
2179 + for (e = list_begin (list); e != list_end (list); e = list_next (e))
2180 + if (less (elem, e, aux))
2182 + return list_insert (e, elem);
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. */
2190 +list_unique (struct list *list, struct list *duplicates,
2191 + list_less_func *less, void *aux)
2193 + list_elem *elem, *next;
2195 + assert (list != NULL);
2196 + assert (less != NULL);
2197 + if (list_empty (list))
2200 + elem = list_begin (list);
2201 + while ((next = list_next (elem)) != list_end (list))
2202 + if (!less (elem, next, aux) && !less (next, elem, aux))
2204 + list_remove (next);
2205 + if (duplicates != NULL)
2206 + list_push_back (duplicates, next);
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. */
2217 +list_max (struct list *list, list_less_func *less, void *aux)
2219 + list_elem *max = list_begin (list);
2220 + if (max != list_end (list))
2224 + for (e = list_next (max); e != list_end (list); e = list_next (e))
2225 + if (less (max, e, aux))
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. */
2236 +list_min (struct list *list, list_less_func *less, void *aux)
2238 + list_elem *min = list_begin (list);
2239 + if (min != list_end (list))
2243 + for (e = list_next (min); e != list_end (list); e = list_next (e))
2244 + if (less (e, min, aux))
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
2254 +#ifndef __LIB_KERNEL_LIST_H
2255 +#define __LIB_KERNEL_LIST_H
2257 +/* Doubly linked list.
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.
2266 + For example, suppose there is a needed for a list of `struct
2267 + foo'. `struct foo' should contain a `list_elem' member, like
2274 + ...other members...
2277 + Then a list of `struct foo' can be be declared and initialized
2280 + struct list foo_list;
2282 + list_init (&foo_list);
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:
2290 + for (e = list_begin (&foo_list); e != list_end (&foo_list);
2291 + e = list_next (e))
2293 + struct foo *f = list_entry (e, struct foo, elem);
2294 + ...do something with f...
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.
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.
2307 + Glossary of list terms:
2309 + - "front": The first element in a list. Undefined in an
2310 + empty list. Returned by list_front().
2312 + - "back": The last element in a list. Undefined in an empty
2313 + list. Returned by list_back().
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.
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.
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.
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.
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.
2338 +#include <stdbool.h>
2339 +#include <stddef.h>
2340 +#include <inttypes.h>
2342 +/* List element. */
2343 +typedef struct list_elem
2345 + struct list_elem *prev; /* Previous list element. */
2346 + struct list_elem *next; /* Next list element. */
2353 + list_elem head; /* List head. */
2354 + list_elem tail; /* List tail. */
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)))
2365 +void list_init (struct list *);
2367 +/* List traversal. */
2368 +list_elem *list_begin (struct list *);
2369 +list_elem *list_next (list_elem *);
2370 +list_elem *list_end (struct list *);
2372 +list_elem *list_rbegin (struct list *);
2373 +list_elem *list_prev (list_elem *);
2374 +list_elem *list_rend (struct list *);
2376 +list_elem *list_head (struct list *);
2377 +list_elem *list_tail (struct list *);
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 *);
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 *);
2391 +/* List elements. */
2392 +list_elem *list_front (struct list *);
2393 +list_elem *list_back (struct list *);
2395 +/* List properties. */
2396 +size_t list_size (struct list *);
2397 +bool list_empty (struct list *);
2399 +/* Miscellaneous. */
2400 +void list_reverse (struct list *);
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,
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);
2419 +list_elem *list_max (struct list *, list_less_func *, void *aux);
2420 +list_elem *list_min (struct list *, list_less_func *, void *aux);
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
2431 +#include <stdlib.h>
2432 +#include <assert.h>
2434 +#define NEED_CPU_REG_SHORTCUTS 1
2436 +#define LOG_THIS BX_CPU_THIS_PTR
2437 +#include "lockset.h"
2439 +#include "eraser.h"
2440 +#include "globals.h"
2441 +#include "mydebug.h"
2444 +#define MAX_LOCKSETS ((unsigned int)100000)
2445 +#define HTABLE_SIZE ((unsigned int)4*MAX_LOCKSETS) //overprovision for closed hashing
2447 +typedef unsigned int hval_t;
2449 +struct add_lock_entry {
2450 + locksetidx_t oldindex;
2451 + address_t newlock;
2452 + locksetidx_t newindex;
2453 + hash_elem h_elem; /* Hash element */
2456 +struct remove_lock_entry {
2457 + locksetidx_t oldindex;
2458 + address_t oldlock;
2459 + locksetidx_t newindex;
2460 + hash_elem h_elem; /* Hash element */
2464 +struct intersect_entry {
2465 + locksetidx_t index1, index2, newindex;
2466 + hash_elem h_elem; /* Hash element */
2469 +unsigned add_lock_hash (const hash_elem *e, void *aux)
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) );
2476 +add_lock_less (const hash_elem *a_, const hash_elem *b_,
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));
2484 +unsigned remove_lock_hash (const hash_elem *e, void *aux)
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));
2491 +remove_lock_less (const hash_elem *a_, const hash_elem *b_,
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));
2499 +unsigned intersect_hash (const hash_elem *e, void *aux)
2501 + struct intersect_entry *h = hash_entry (e, struct intersect_entry, h_elem);
2502 + return hash_int ((h->index1 << 16) | (h->index2&0x0000ffff));
2506 +intersect_less (const hash_elem *a_, const hash_elem *b_,
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));
2517 +static int add_lock_cache_initialized = 0;
2518 +static struct hash add_lock_cache;
2520 +static int remove_lock_cache_initialized = 0;
2521 +static struct hash remove_lock_cache;
2523 +static int intersect_cache_initialized = 0;
2524 +static struct hash intersect_cache;
2526 +typedef struct lockvector {
2527 + address_t lockaddress;
2528 + struct lockvector *next;
2532 +static locksetidx_t lockset_index = 1;
2533 +static lockvector_t *index_table[MAX_LOCKSETS];
2534 +static locksetidx_t hash_table[HTABLE_SIZE];
2536 +static unsigned int cum_hash(unsigned int a, address_t b) {
2540 +static unsigned int hashfn(lockvector_t *vec) {
2541 + lockvector_t *cur;
2542 + unsigned int ret=0;
2546 + ret = cum_hash(ret,cur->lockaddress);
2553 +freevector(lockvector_t *lockvec) {
2554 + static lockvector_t *cur, *prev;
2563 +static lockvector_t *
2564 +clonevector(lockvector_t *lockvec) {
2565 + static lockvector_t *cur, *newlockvec,*newprev;
2566 + if (!lockvec) return NULL;
2568 + newlockvec = (lockvector_t*)malloc(sizeof(lockvector_t));
2569 + newlockvec->lockaddress = lockvec->lockaddress;
2570 + newprev = newlockvec;
2571 + cur = lockvec->next;
2573 + newprev->next = (lockvector_t*)malloc(sizeof(lockvector_t));
2574 + newprev->next->lockaddress = cur->lockaddress;
2576 + newprev = newprev->next;
2578 + newprev->next = NULL;
2579 + return newlockvec;
2582 +static lockvector_t *
2583 +remove_from_lockvector(lockvector_t *lockvec, address_t oldlock) {
2584 + lockvector_t *ret, *cur, *newlockvec, *tmp;
2587 + if (oldlock<lockvec->lockaddress) assert(0);
2588 + if (oldlock==lockvec->lockaddress) {
2589 + ret = clonevector(lockvec->next);
2593 + cur = newlockvec = clonevector(lockvec);
2594 + while (cur->next && oldlock>cur->next->lockaddress) {
2597 + assert(oldlock==cur->next->lockaddress);
2600 + cur->next = cur->next->next;
2601 + tmp->lockaddress = 0;
2604 + return newlockvec;
2607 +static lockvector_t *
2608 +intersect_lockvectors(lockvector_t *lockvec1, lockvector_t *lockvec2) {
2609 + lockvector_t *cur1, *cur2, *out, *ret;
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;
2620 + out->next = (lockvector_t *)malloc(sizeof(lockvector_t));
2623 + ret = out = (lockvector_t *)malloc(sizeof(lockvector_t));
2625 + out->lockaddress = cur1->lockaddress;
2627 + cur1 = cur1->next;
2628 + cur2 = cur2->next;
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;
2646 + if (newlock<lockvec->lockaddress) {
2647 + ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2648 + ret->lockaddress = newlock;
2649 + ret->next = clonevector(lockvec);
2652 + if (newlock==lockvec->lockaddress) {
2653 + if (BX_CPU(0)) BX_CPU(0)->backtrace(btstr);
2655 + return clonevector(lockvec);
2657 + assert(newlock>lockvec->lockaddress);
2659 + cur = newlockvec = clonevector(lockvec);
2660 + while (cur->next && newlock>cur->next->lockaddress) {
2665 + ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2666 + ret->lockaddress = newlock;
2669 + return newlockvec;
2672 + if (newlock==cur->next->lockaddress) {
2673 + BX_CPU(0)->backtrace(btstr);
2674 + assert(0); //acquiring the same lock twice
2675 + return newlockvec;
2678 + ret = (lockvector_t *)malloc(sizeof(lockvector_t));
2679 + ret->lockaddress = newlock;
2680 + ret->next = cur->next;
2682 + return newlockvec;
2685 +void add_to_hashtable(lockvector_t *newlockset, locksetidx_t index) {
2686 + hval_t hval = (hashfn(newlockset))%HTABLE_SIZE;
2688 + while (hash_table[hval]) {
2689 + hval = (hval+1)%HTABLE_SIZE; //closed hashing
2690 + //printf("hval=%d.\n",hval);
2693 + if (numtries>20) printf("%s: Warning: numtries too large for closed hashing (=%d).\n",__func__,numtries);
2694 + hash_table[hval] = index;
2697 +//returns true if they are equal
2699 +compare_locksets(lockvector_t *vec1, lockvector_t *vec2) {
2700 + lockvector_t *cur1, *cur2;
2707 + while (cur1 && cur2 && cur1->lockaddress==cur2->lockaddress) {
2708 + cur1 = cur1->next;
2709 + cur2 = cur2->next;
2712 + if (cur1) return 0;
2713 + if (cur2) return 0;
2718 +static locksetidx_t
2719 +find_in_add_cache(locksetidx_t index, address_t newlock) {
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);
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;
2735 +static locksetidx_t
2736 +find_in_remove_cache(locksetidx_t index, address_t oldlock) {
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);
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;
2752 +static locksetidx_t
2753 +find_in_intersect_cache(locksetidx_t index1, locksetidx_t index2) {
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);
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;
2769 +void insert_in_remove_cache(locksetidx_t index, address_t lock, locksetidx_t new_index)
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;
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);
2782 +insert_in_add_cache(locksetidx_t index, address_t lock, locksetidx_t new_index)
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;
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);
2795 +insert_in_intersect_cache(locksetidx_t index1, locksetidx_t index2, locksetidx_t new_index)
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;
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);
2807 +static locksetidx_t
2808 +find_duplicate(lockvector_t *vec) {
2810 + locksetidx_t new_index;
2811 + hash_elem *h_element = NULL;
2813 + hval = (hashfn(vec))%HTABLE_SIZE;
2814 + new_index = hash_table[hval];
2816 + while (new_index) {
2817 + if (compare_locksets(vec,index_table[new_index])) {
2820 + hval = (hval+1)%HTABLE_SIZE;
2821 + new_index = hash_table[hval];
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;
2832 + if (lockset_index >= MAX_LOCKSETS) {
2833 + printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
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;
2842 + newlockset = add_to_lockvector(index_table[index],newlock);
2844 + assert(newlockset);
2845 + ret_index = find_duplicate(newlockset);
2847 + insert_in_add_cache(index,newlock,ret_index);
2848 + freevector(newlockset);
2852 + index_table[lockset_index] = newlockset;
2853 + add_to_hashtable(newlockset,lockset_index);
2854 + ret_index = lockset_index;
2860 +singleton_lockset(lockvector_t *vec) {
2862 + if (vec->next==NULL) return 1;
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);
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);
2879 + assert(index_table[index]->lockaddress==oldlock);
2882 + ret_index = find_in_remove_cache(index,oldlock);
2883 + if (ret_index) return ret_index;
2885 + if (lockset_index >= MAX_LOCKSETS) {
2886 + printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
2890 + assert(index); //you cannot remove from an empty lockset
2891 + newlockset = remove_from_lockvector(index_table[index],oldlock);
2892 + assert(newlockset);
2894 + ret_index = find_duplicate(newlockset);
2896 + insert_in_remove_cache(index,oldlock,ret_index);
2897 + freevector(newlockset);
2901 + index_table[lockset_index] = newlockset;
2902 + add_to_hashtable(newlockset,lockset_index);
2903 + ret_index = lockset_index;
2908 +locksetidx_t intersect_locksets(locksetidx_t index1, locksetidx_t index2) {
2909 + lockvector_t *newlockset;
2910 + locksetidx_t ret_index;
2912 + if (index1==0) return 0;
2913 + if (index2==0) return 0;
2915 + ret_index = find_in_intersect_cache(index1,index2);
2916 + if (ret_index) return ret_index;
2918 + if (lockset_index >= MAX_LOCKSETS) {
2919 + printf("%s: Number of locksets exceed %d. returning 0\n",__func__,MAX_LOCKSETS);
2925 + newlockset = intersect_lockvectors(index_table[index1],index_table[index2]);
2926 + if (!newlockset) return 0; //empty lockset
2927 + ret_index = find_duplicate(newlockset);
2929 + insert_in_intersect_cache(index1,index2,ret_index);
2930 + freevector(newlockset);
2934 + index_table[lockset_index] = newlockset;
2935 + add_to_hashtable(newlockset,lockset_index);
2936 + ret_index = lockset_index;
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 */
2948 +static int locks_held_table_initialized = 0;
2949 +static struct hash locks_held_table ;
2951 +unsigned locks_held_hash (const hash_elem *e, void *aux)
2953 + locks_held_t *h = hash_entry (e, struct locks_held, h_elem);
2954 + return hash_int (h->threadId);
2958 +locks_held_less (const hash_elem *a_, const hash_elem *b_,
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);
2968 +cur_held(unsigned threadId) {
2969 + hash_elem *h_element;
2971 + if (!locks_held_table_initialized) return 0;
2972 + tmp.threadId = threadId;
2973 + h_element = hash_find(&locks_held_table, &tmp.h_elem);
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;
2982 +void update_lockset(unsigned threadId, locksetidx_t lset) {
2984 + hash_elem *h_element;
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;
2991 + tmp.threadId = threadId;
2992 + h_element = hash_find(&locks_held_table, &tmp.h_elem);
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);
2998 + e = hash_entry(h_element, struct locks_held, h_elem);
2999 + assert(e->threadId==threadId);
3000 + e->locks_held = lset;
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;
3012 + while (cur->next && lock>cur->next->lockaddress) {
3015 + if (!cur->next) return false;
3016 + if (cur->next->lockaddress==lock) return true;
3020 +bool belongs(locksetidx_t index, address_t lock) {
3021 + if (!index) return false;
3022 + return (find_in_lockvector(index_table[index],lock));
3025 +void set_ignore(unsigned threadId, bool val) {
3027 + hash_elem *h_element;
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;
3033 + tmp.threadId = threadId;
3034 + h_element = hash_find(&locks_held_table, &tmp.h_elem);
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);
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);
3047 + DBG(L1,("ignore value for thread %x = %d.\n",threadId,e->ignore));
3051 +ignore_on(unsigned threadId) {
3052 + hash_elem *h_element;
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);
3059 + locks_held_t *answer = hash_entry(h_element, struct locks_held, h_elem);
3060 + assert(answer->ignore>=0);
3061 + return answer->ignore > 0;
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
3070 +#ifndef __LOCKSET_H
3071 +#define __LOCKSET_H
3073 +#define LOCKSET_EMPTY 0
3076 +#define EXCLUSIVE 0x40000000
3077 +#define SHARED 0x80000000
3078 +#define SHARED_MOD 0xc0000000
3080 +#define get_state(x) (x&0xc0000000)
3081 +#define set_state(x,s) ((x&0x3fffffff)|s)
3083 +#define get_value(x) (x&0x3fffffff)
3084 +#define set_value(x,v) ((x&0xc0000000)|(v&0x3fffffff))
3086 +typedef unsigned int address_t;
3087 +typedef unsigned long locksetidx_t;
3088 +typedef locksetidx_t lockset_t;
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);
3095 +locksetidx_t cur_held(unsigned threadId);
3096 +void update_lockset(unsigned threadId, locksetidx_t lockset);
3098 +void set_ignore(unsigned threadId, bool val);
3099 +bool ignore_on(unsigned threadId);
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
3107 +#include "lockset.h"
3110 + int i1, i2, i3, i12, i21, i31, i32, i123, i312, i321, i312_2, i321m2, i312m2;
3111 + int i312i123, i312i21, i312i1, i32i1;
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);
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);
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
3145 +#define LOG_THIS BX_MEM_THIS
3148 + void BX_CPP_AttrRegparmN(3)
3149 +BX_MEM_C::readPhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
3154 + a20addr = A20ADDR(addr);
3156 + *(Bit32u *)data = 0x0; //initialize, so that if we are unable to read mem, we return 0
3158 + if ( (a20addr + len) <= BX_MEM_THIS len ) {
3159 + // all of data is within limits of physical memory
3160 + if ( (a20addr & 0xfff80000) != 0x00080000 ) {
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];
3168 + printf("Not yet supported for big endian host platforms.\n");
3175 + *(Bit32u *)data = taint_vector[a20addr];
3176 + *((Bit32u *)data+1) = taint_vector[a20addr+1];
3178 + printf("Not yet supported for big endian host platforms.\n");
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;
3191 + *(Bit32u *)data = taint_vector[a20addr];
3193 + printf("Not yet supported for big endian host platforms.\n");
3198 + // len == 3 case can just fall thru to special cases handling
3202 +#ifdef BX_LITTLE_ENDIAN
3203 + data_ptr = (Bit32u *) data;
3204 +#else // BX_BIG_ENDIAN
3205 + data_ptr = (Bit32u *) data + (len - 1);
3211 + if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3212 + // addr *not* in range 00080000 .. 000FFFFF
3213 + *data_ptr = taint_vector[a20addr];
3215 + if (len == 1) return;
3218 +#ifdef BX_LITTLE_ENDIAN
3220 +#else // BX_BIG_ENDIAN
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];
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
3238 +#else // #if BX_PCI_SUPPORT == 0
3239 + if (a20addr <= 0x0009ffff) {
3240 + *data_ptr = taint_vector[a20addr];
3243 + if (a20addr <= 0x000BFFFF) {
3245 + // VGA memory A0000 .. BFFFF
3246 + //*data_ptr = DEV_vga_mem_read(a20addr);
3247 + //BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr);
3251 + // a20addr in C0000 .. FFFFF
3252 + if (!bx_options.Oi440FXSupport->get ()) {
3253 + *data_ptr = taint_vector[a20addr];
3258 +#endif // #if BX_PCI_SUPPORT == 0
3261 + // some or all of data is outside limits of physical memory
3264 +#ifdef BX_LITTLE_ENDIAN
3265 + data_ptr = (Bit32u *) data;
3266 +#else // BX_BIG_ENDIAN
3267 + data_ptr = (Bit32u *) data + (len - 1);
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)))
3280 +#if BX_SUPPORT_APIC
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];
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];
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));
3302 + case 0x1: // Read from Shadow RAM
3306 + BX_PANIC(("readPhysicalPage: default case"));
3311 + *data_ptr = taint_vector[a20addr];
3312 + BX_INFO(("Reading from Norm %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
3316 + *data_ptr = 0xffffffff;
3317 +#endif // BX_PCI_SUPPORT == 0
3320 +#ifdef BX_LITTLE_ENDIAN
3322 +#else // BX_BIG_ENDIAN
3330 + void BX_CPP_AttrRegparmN(3)
3331 +BX_MEM_C::writePhysicalTaintPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
3338 + a20addr = A20ADDR(addr);
3340 + // Note: accesses should always be contained within a single page now.
3342 + //if (*(Bit8u *)data!=0xff && *(Bit8u *)data!=0) assert(0);
3343 + //if (*(Bit8u *)data==0xff) assert(0);
3345 + if ( a20addr <= BX_MEM_THIS len ) {
3347 + //LOG_MEM_TAINT(cpu,addr,len,&taint_vector[a20addr],data,true);
3349 + // all of data is within limits of physical memory
3350 + if ( (a20addr & 0xfff80000) != 0x00080000 ) {
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);
3358 + printf("Not yet supported for big endian host platforms.\n");
3365 + taint_vector[a20addr] = *(Bit32u*)data;
3366 + taint_vector[a20addr+1] = *((Bit32u*)data+1);
3368 + printf("Not yet supported for big endian host platforms.\n");
3375 + taint_vector[a20addr] = *(Bit32u*)data;
3377 + printf("Not yet supported for big endian host platforms.\n");
3382 + // len == other, just fall thru to special cases handling
3385 +#ifdef BX_LITTLE_ENDIAN
3386 + data_ptr = (Bit32u *) data;
3387 +#else // BX_BIG_ENDIAN
3388 + data_ptr = (Bit32u *) data + (len - 1);
3392 + if ( (a20addr & 0xfff80000) != 0x00080000 ) {
3393 + // addr *not* in range 00080000 .. 000FFFFF
3394 + taint_vector[a20addr] = *data_ptr;
3396 + if (len == 1) return;
3399 +#ifdef BX_LITTLE_ENDIAN
3401 +#else // BX_BIG_ENDIAN
3407 + // addr in range 00080000 .. 000FFFFF
3409 + if (a20addr <= 0x0009ffff) {
3410 + // regular memory 80000 .. 9FFFF
3411 + taint_vector[a20addr] = *data_ptr;
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
3422 + // adapter ROM C0000 .. DFFFF
3423 + // ROM BIOS memory E0000 .. FFFFF
3425 + //BX_INFO(("ROM lock %08x: len=%u",
3426 + // (unsigned) a20addr, (unsigned) len));
3427 +#if BX_PCI_SUPPORT == 0
3429 + // Write it since its in shadow RAM
3430 + taint_vector[a20addr] = *data_ptr;
3432 + // ignore write to ROM
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
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);
3446 + case 0x0: // Writes to ROM, Inhibit
3448 + //BX_DEBUG(("Write to ROM ignored: address %08x, data %02x", (unsigned) a20addr, *data_ptr));
3451 + BX_PANIC(("writePhysicalPage: default case"));
3460 + // some or all of data is outside limits of physical memory
3463 +#ifdef BX_LITTLE_ENDIAN
3464 + data_ptr = (Bit32u *) data;
3465 +#else // BX_BIG_ENDIAN
3466 + data_ptr = (Bit32u *) data + (len - 1);
3471 + // Check VBE LFB support
3473 + if ((a20addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS) &&
3474 + (a20addr < (VBE_DISPI_LFB_PHYSICAL_ADDRESS + VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)))
3483 +#if BX_SUPPORT_APIC
3487 + for (i = 0; i < len; i++) {
3488 + if (a20addr < BX_MEM_THIS len) {
3489 + taint_vector[a20addr] = *data_ptr;
3491 + // otherwise ignore byte, since it overruns memory
3494 +#ifdef BX_LITTLE_ENDIAN
3496 +#else // BX_BIG_ENDIAN
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
3508 +#ifndef __MYDEBUG_H
3509 +#define __MYDEBUG_H
3511 +#define ACCESS_LINEAR 0
3514 +#define CHECKBOCHS 1
3518 +void checkbochs_log (const char *fmt, ...) ;
3520 +#define DBG(l,x) if (l) { \
3521 + checkbochs_log x; \
3522 + /*bx_dbg_disassemble_current(-1,0);*/ \
3525 +#define PANIC(...) do { \
3526 + printf("PANIC at %s:%d in %s(): ",__FILE__,__LINE__,__func__); \
3527 + BX_CPU(0)->panic(__VA_ARGS__); \
3530 +#define ASSERT(CONDITION) \
3531 + if (CONDITION) { } else { \
3532 + PANIC ("assertion `%s' failed.", #CONDITION); \
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
3541 +#define NEED_CPU_REG_SHORTCUTS 1
3543 +#define LOG_THIS BX_CPU_THIS_PTR
3545 +#include "taint/globals.h"
3546 +#include "taint/mydebug.h"
3547 +#include "taint/lockset.h"
3550 +#define this (BX_CPU(0))
3554 +#if BX_SUPPORT_PAGING
3556 +#define InstrTLB_Stats()
3557 +#define InstrTLB_Increment(v)
3559 +// ==============================================================
3562 +// Translate a linear address to a physical address, for
3563 +// a data access (D)
3565 + Bit32s BX_CPP_AttrRegparmN(3)
3566 +BX_CPU_C::taint_dtranslate_linear(bx_address laddr, unsigned pl, unsigned rw)
3569 + Bit32u ppf, poffset, TLB_index, error_code, paddress;
3570 + Bit32u pde, pde_addr;
3572 + Bit32u accessBits, combined_access;
3573 + unsigned priv_index;
3575 + // CR4.PAE==0 (and MSR.LMA==0)
3577 + lpf = laddr & 0xfffff000; // linear page frame
3578 + poffset = laddr & 0x00000fff; // physical offset
3579 + TLB_index = BX_TLB_INDEX_OF(lpf);
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
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)) ) {
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.
3598 + return(-1); //return -1 for failure
3602 +// Translate a linear address to a physical address, for
3603 +// an instruction fetch access (I)
3605 + Bit32u BX_CPP_AttrRegparmN(2)
3606 +BX_CPU_C::taint_itranslate_linear(bx_address laddr, unsigned pl)
3608 + //assign_type(type8,generic_type_executed_code8);
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);
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)
3623 + Bit32u pageOffset;
3624 + unsigned xlate_rw;
3627 + assert(length==1);
3628 + ASSERT(rw==BX_READ || get_value(*(Bit32u*)taint_value)<2 || get_state(*(Bit32u*)taint_value));
3637 + pageOffset = laddr & 0x00000fff;
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;
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);
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);
3658 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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;
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);
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);
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);
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);
3706 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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) {
3718 + // Let access fall through to the following for this iteration.
3719 + BX_CPU_THIS_PTR mem->readPhysicalTaintPage(this, laddr, length, taint_value);
3722 + BX_CPU_THIS_PTR mem->writePhysicalTaintPage(this, laddr, length, taint_value);
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;
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);
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);
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);
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);
3776 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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
3787 +#define NEED_CPU_REG_SHORTCUTS 1
3789 +#define LOG_THIS BX_CPU_THIS_PTR
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)
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))
3802 +#define IsLongMode() (0)
3803 +#define LPFOf(laddr) ((laddr) & 0xfffff000)
3804 +#define IsCanonical(offset) (0)
3808 + int BX_CPP_AttrRegparmN(3)
3809 +BX_CPU_C::read_virtual_checks_silent(bx_segment_reg_t *seg, bx_address offset,
3812 + Bit32u upper_limit;
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);
3822 + if (seg->cache.p == 0) { /* not present */
3823 + BX_INFO(("read_virtual_checks(): segment not present"));
3824 + //exception(int_number(seg), 0, 0);
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);
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;
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);
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;
3859 + case 4: case 5: /* read only, expand down */
3860 + if (seg->cache.u.segment.d_b)
3861 + upper_limit = 0xffffffff;
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);
3873 + case 6: case 7: /* read write, expand down */
3874 + if (seg->cache.u.segment.d_b)
3875 + upper_limit = 0xffffffff;
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);
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);
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);
3907 + //exception(BX_GP_EXCEPTION, 0, 0);
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;
3920 + int BX_CPP_AttrRegparmN(3)
3921 +BX_CPU_C::read_virtual_byte_silent(unsigned s, bx_address offset, Bit8u *data)
3924 + bx_segment_reg_t *seg;
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)) {
3933 + laddr = seg->cache.u.segment.base + offset;
3934 + BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 1, BX_READ);
3937 + ret = access_linear_silent(laddr, 1, pl, BX_READ, (void *) data);
3941 + ret = read_virtual_checks_silent(seg, offset, 1); //if exception would be raised return 0
3942 + if (!ret) return 0;
3946 + int BX_CPP_AttrRegparmN(3)
3947 +BX_CPU_C::read_virtual_word_silent(unsigned s, bx_address offset, Bit16u *data)
3950 + bx_segment_reg_t *seg;
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)) {
3959 + laddr = seg->cache.u.segment.base + offset;
3960 + BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 2, BX_READ);
3963 + ret = access_linear_silent(laddr, 2, pl, BX_READ, (void *) data);
3967 + ret = read_virtual_checks_silent(seg, offset, 2);
3968 + if (!ret) return 0;
3972 + int BX_CPP_AttrRegparmN(3)
3973 +BX_CPU_C::read_virtual_dword_silent(unsigned s, bx_address offset, Bit32u *data)
3976 + bx_segment_reg_t *seg;
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))) {
3985 + laddr = seg->cache.u.segment.base + offset;
3986 + BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 4, BX_READ);
3989 + ret = access_linear_silent(laddr, 4, pl, BX_READ, (void *) data);
3993 + ret = read_virtual_checks_silent(seg, offset, 4);
3994 + if (!ret) return 0;
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
4002 +#define NEED_CPU_REG_SHORTCUTS 1
4004 +#define LOG_THIS BX_CPU_THIS_PTR
4007 +#define this (BX_CPU(0))
4011 +#if BX_SUPPORT_PAGING
4013 +#define InstrTLB_Stats()
4014 +#define InstrTLB_Increment(v)
4016 +// ==============================================================
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)
4023 + Bit32u pageOffset;
4024 + unsigned xlate_rw;
4026 + assert(rw==BX_READ);
4035 + pageOffset = laddr & 0x00000fff;
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;
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 );
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);
4055 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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,
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);
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);
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);
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);
4102 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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) {
4114 + // Let access fall through to the following for this iteration.
4115 + BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
4118 + BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
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;
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);
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);
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);
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);
4172 + //if (rw==BX_WRITE) BX_CPU_THIS_PTR address_xlation.taint_write_paddress1 = BX_CPU_THIS_PTR address_xlation.taint_paddress1;
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
4182 +#define NEED_CPU_REG_SHORTCUTS 1
4184 +#define LOG_THIS BX_CPU_THIS_PTR
4186 +#include "taint/taint_type.h"
4187 +#include "taint/globals.h"
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);
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
4200 +#ifndef __TAINT_TYPE_H
4201 +#define __TAINT_TYPE_H
4203 +#define ERASER_ID 0
4205 +void assign_taint_functions(char *taint_type);
4208 diff -urpN bochs-2.1.1.orig/taint/taint_type.h.bak checkbochs-2.1.1/taint/taint_type.h.bak