///////////////////////////////////////////////////////////////////////// // // test-access-check.cc // $Id$ // by Bryce Denney // // This whole program is intended to test just a few lines in // cpu/access.cc, where it checks if a memory access goes over the // segment limits. // // NOTE: The variable called limit is actually "limit_scaled" in the // bochs code. Limit_scaled is equal to the limit when granularity is 0, // and equal to (limit << 12) | 0xfff when granularity is 1. // // Compile with: // cc -I. -Iinstrument/stubs -o test-access-check misc/test-access-check.cc // Then run "test-access-check" and see how it goes. If mismatches=0, // the rule is good. // /////////////////////////////////////////////////////////////////////////////// #include // rule1 is the original rule used in Bochs from 2000-03-25. It has bad // overflow problems. int rule1 (Bit32u limit, Bit32u length, Bit32u offset); // rule2 is Bryce's first try, which turned out to have bad underflow problems // instead. int rule2 (Bit32u limit, Bit32u length, Bit32u offset); // rule3 is Bryce's second try, which as far as he knows works for all // cases. int rule3 (Bit32u limit, Bit32u length, Bit32u offset); // edit this to test other rules. #define TEST_RULE rule3 typedef struct { Bit32u limit, length, offset, the_answer; } TestStruct; TestStruct tests[] = { // limit length offset exception {0x0a, 4, 0, 0}, {0x0a, 4, 1, 0}, {0x0a, 4, 2, 0}, {0x0a, 4, 3, 0}, {0x0a, 4, 4, 0}, {0x0a, 4, 5, 0}, {0x0a, 4, 6, 0}, {0x0a, 4, 7, 0}, {0x0a, 4, 8, 1}, {0x0a, 4, 9, 1}, {0x0a, 4, 0x0a, 1}, {0x0a, 4, 0x0b, 1}, {0x0a, 4, 0x0c, 1}, {0x0a, 4, 0xfffffffd, 1}, {0x0a, 4, 0xfffffffe, 1}, {0x0a, 4, 0xffffffff, 1}, {0x0a, 2, 0, 0}, {0x0a, 2, 1, 0}, {0x0a, 2, 2, 0}, {0x0a, 2, 3, 0}, {0x0a, 2, 4, 0}, {0x0a, 2, 5, 0}, {0x0a, 2, 6, 0}, {0x0a, 2, 7, 0}, {0x0a, 2, 8, 0}, {0x0a, 2, 9, 0}, {0x0a, 2, 0x0a, 1}, {0x0a, 2, 0x0b, 1}, {0x0a, 2, 0x0c, 1}, {0x0a, 2, 0xfffffffd, 1}, {0x0a, 2, 0xfffffffe, 1}, {0x0a, 2, 0xffffffff, 1}, {0x0a, 1, 0, 0}, {0x0a, 1, 1, 0}, {0x0a, 1, 2, 0}, {0x0a, 1, 3, 0}, {0x0a, 1, 4, 0}, {0x0a, 1, 5, 0}, {0x0a, 1, 6, 0}, {0x0a, 1, 7, 0}, {0x0a, 1, 8, 0}, {0x0a, 1, 9, 0}, {0x0a, 1, 0x0a, 0}, {0x0a, 1, 0x0b, 1}, {0x0a, 1, 0x0c, 1}, // // try a few near the common 0xffff boundary // {0xffff, 1, 0, 0}, {0xffff, 1, 0x100, 0}, {0xffff, 1, 0x1000, 0}, {0xffff, 1, 0x8000, 0}, {0xffff, 1, 0xf000, 0}, {0xffff, 1, 0xfff0, 0}, {0xffff, 1, 0xfff1, 0}, {0xffff, 1, 0xfff2, 0}, {0xffff, 1, 0xfff3, 0}, {0xffff, 1, 0xfff4, 0}, {0xffff, 1, 0xfff5, 0}, {0xffff, 1, 0xfff6, 0}, {0xffff, 1, 0xfff7, 0}, {0xffff, 1, 0xfff8, 0}, {0xffff, 1, 0xfff9, 0}, {0xffff, 1, 0xfffa, 0}, {0xffff, 1, 0xfffb, 0}, {0xffff, 1, 0xfffc, 0}, {0xffff, 1, 0xfffd, 0}, {0xffff, 1, 0xfffe, 0}, {0xffff, 1, 0xffff, 0}, {0xffff, 1, 0x10000, 1}, {0xffff, 1, 0x10001, 1}, {0xffff, 1, 0x10002, 1}, {0xffff, 1, 0x10021, 1}, {0xffff, 1, 0x40001, 1}, {0xffff, 1, 0xffffffff, 1}, // // near 0xffff, length 2 // {0xffff, 2, 0, 0}, {0xffff, 2, 0x100, 0}, {0xffff, 2, 0x1000, 0}, {0xffff, 2, 0x8000, 0}, {0xffff, 2, 0xf000, 0}, {0xffff, 2, 0xfff0, 0}, {0xffff, 2, 0xfff1, 0}, {0xffff, 2, 0xfff2, 0}, {0xffff, 2, 0xfff3, 0}, {0xffff, 2, 0xfff4, 0}, {0xffff, 2, 0xfff5, 0}, {0xffff, 2, 0xfff6, 0}, {0xffff, 2, 0xfff7, 0}, {0xffff, 2, 0xfff8, 0}, {0xffff, 2, 0xfff9, 0}, {0xffff, 2, 0xfffa, 0}, {0xffff, 2, 0xfffb, 0}, {0xffff, 2, 0xfffc, 0}, {0xffff, 2, 0xfffd, 0}, {0xffff, 2, 0xfffe, 0}, {0xffff, 2, 0xffff, 1}, {0xffff, 2, 0x10000, 1}, {0xffff, 2, 0x10001, 1}, {0xffff, 2, 0x10002, 1}, {0xffff, 2, 0x10021, 1}, {0xffff, 2, 0x40001, 1}, {0xffff, 2, 0xffffffff, 1}, // // near 0xffff, length 4 // {0xffff, 4, 0, 0}, {0xffff, 4, 0x100, 0}, {0xffff, 4, 0x1000, 0}, {0xffff, 4, 0x8000, 0}, {0xffff, 4, 0xf000, 0}, {0xffff, 4, 0xfff0, 0}, {0xffff, 4, 0xfff1, 0}, {0xffff, 4, 0xfff2, 0}, {0xffff, 4, 0xfff3, 0}, {0xffff, 4, 0xfff4, 0}, {0xffff, 4, 0xfff5, 0}, {0xffff, 4, 0xfff6, 0}, {0xffff, 4, 0xfff7, 0}, {0xffff, 4, 0xfff8, 0}, {0xffff, 4, 0xfff9, 0}, {0xffff, 4, 0xfffa, 0}, {0xffff, 4, 0xfffb, 0}, {0xffff, 4, 0xfffc, 0}, {0xffff, 4, 0xfffd, 1}, {0xffff, 4, 0xfffe, 1}, {0xffff, 4, 0xffff, 1}, {0xffff, 4, 0x10000, 1}, {0xffff, 4, 0x10001, 1}, {0xffff, 4, 0x10002, 1}, {0xffff, 4, 0x10021, 1}, {0xffff, 4, 0x40001, 1}, {0xffff, 4, 0xffffffff, 1}, // // now a few near the max limit 0xffffffff // {0xffffffff, 1, 0, 0}, {0xffffffff, 1, 0x100, 0}, {0xffffffff, 1, 0x1000, 0}, {0xffffffff, 1, 0x8000, 0}, {0xffffffff, 1, 0xf000, 0}, {0xffffffff, 1, 0xfff0, 0}, {0xffffffff, 1, 0xfff1, 0}, {0xffffffff, 1, 0xfff2, 0}, {0xffffffff, 1, 0xfff3, 0}, {0xffffffff, 1, 0xfff4, 0}, {0xffffffff, 1, 0xfff5, 0}, {0xffffffff, 1, 0xfff6, 0}, {0xffffffff, 1, 0xfff7, 0}, {0xffffffff, 1, 0xfff8, 0}, {0xffffffff, 1, 0xfff9, 0}, {0xffffffff, 1, 0xfffa, 0}, {0xffffffff, 1, 0xfffb, 0}, {0xffffffff, 1, 0xfffc, 0}, {0xffffffff, 1, 0xfffd, 0}, {0xffffffff, 1, 0xfffe, 0}, {0xffffffff, 1, 0xffff, 0}, {0xffffffff, 1, 0x10000, 0}, {0xffffffff, 1, 0x10001, 0}, {0xffffffff, 1, 0x10002, 0}, {0xffffffff, 1, 0x10021, 0}, {0xffffffff, 1, 0x40001, 0}, {0xffffffff, 1, 0xfffffff0, 0}, {0xffffffff, 1, 0xfffffff9, 0}, {0xffffffff, 1, 0xfffffffa, 0}, {0xffffffff, 1, 0xfffffffb, 0}, {0xffffffff, 1, 0xfffffffc, 0}, {0xffffffff, 1, 0xfffffffd, 0}, {0xffffffff, 1, 0xfffffffe, 0}, {0xffffffff, 1, 0xffffffff, 0}, {0xffffffff, 1, 0x00000000, 0}, {0xffffffff, 1, 0x00000001, 0}, {0xffffffff, 1, 0x00000002, 0}, {0xffffffff, 1, 0x00000003, 0}, {0xffffffff, 1, 0x00000004, 0}, {0xffffffff, 1, 0x00000005, 0}, // // repeat with length 2 // {0xffffffff, 2, 0, 0}, {0xffffffff, 2, 0x100, 0}, {0xffffffff, 2, 0x1000, 0}, {0xffffffff, 2, 0x8000, 0}, {0xffffffff, 2, 0xf000, 0}, {0xffffffff, 2, 0xfff0, 0}, {0xffffffff, 2, 0xfff1, 0}, {0xffffffff, 2, 0xfff2, 0}, {0xffffffff, 2, 0xfff3, 0}, {0xffffffff, 2, 0xfff4, 0}, {0xffffffff, 2, 0xfff5, 0}, {0xffffffff, 2, 0xfff6, 0}, {0xffffffff, 2, 0xfff7, 0}, {0xffffffff, 2, 0xfff8, 0}, {0xffffffff, 2, 0xfff9, 0}, {0xffffffff, 2, 0xfffa, 0}, {0xffffffff, 2, 0xfffb, 0}, {0xffffffff, 2, 0xfffc, 0}, {0xffffffff, 2, 0xfffd, 0}, {0xffffffff, 2, 0xfffe, 0}, {0xffffffff, 2, 0xffff, 0}, {0xffffffff, 2, 0x10000, 0}, {0xffffffff, 2, 0x10001, 0}, {0xffffffff, 2, 0x10002, 0}, {0xffffffff, 2, 0x10021, 0}, {0xffffffff, 2, 0x40001, 0}, {0xffffffff, 2, 0xfffffff0, 0}, {0xffffffff, 2, 0xfffffff9, 0}, {0xffffffff, 2, 0xfffffffa, 0}, {0xffffffff, 2, 0xfffffffb, 0}, {0xffffffff, 2, 0xfffffffc, 0}, {0xffffffff, 2, 0xfffffffd, 0}, {0xffffffff, 2, 0xfffffffe, 0}, {0xffffffff, 2, 0xffffffff, 1}, {0xffffffff, 2, 0x00000000, 0}, {0xffffffff, 2, 0x00000001, 0}, {0xffffffff, 2, 0x00000002, 0}, {0xffffffff, 2, 0x00000003, 0}, {0xffffffff, 2, 0x00000004, 0}, {0xffffffff, 2, 0x00000005, 0}, // // repeat with length 4 // {0xffffffff, 4, 0, 0}, {0xffffffff, 4, 0x100, 0}, {0xffffffff, 4, 0x1000, 0}, {0xffffffff, 4, 0x8000, 0}, {0xffffffff, 4, 0xf000, 0}, {0xffffffff, 4, 0xfff0, 0}, {0xffffffff, 4, 0xfff1, 0}, {0xffffffff, 4, 0xfff2, 0}, {0xffffffff, 4, 0xfff3, 0}, {0xffffffff, 4, 0xfff4, 0}, {0xffffffff, 4, 0xfff5, 0}, {0xffffffff, 4, 0xfff6, 0}, {0xffffffff, 4, 0xfff7, 0}, {0xffffffff, 4, 0xfff8, 0}, {0xffffffff, 4, 0xfff9, 0}, {0xffffffff, 4, 0xfffa, 0}, {0xffffffff, 4, 0xfffb, 0}, {0xffffffff, 4, 0xfffc, 0}, {0xffffffff, 4, 0xfffd, 0}, {0xffffffff, 4, 0xfffe, 0}, {0xffffffff, 4, 0xffff, 0}, {0xffffffff, 4, 0x10000, 0}, {0xffffffff, 4, 0x10001, 0}, {0xffffffff, 4, 0x10002, 0}, {0xffffffff, 4, 0x10021, 0}, {0xffffffff, 4, 0x40001, 0}, {0xffffffff, 4, 0xfffffff0, 0}, {0xffffffff, 4, 0xfffffff9, 0}, {0xffffffff, 4, 0xfffffffa, 0}, {0xffffffff, 4, 0xfffffffb, 0}, {0xffffffff, 4, 0xfffffffc, 0}, {0xffffffff, 4, 0xfffffffd, 1}, {0xffffffff, 4, 0xfffffffe, 1}, {0xffffffff, 4, 0xffffffff, 1}, {0xffffffff, 4, 0x00000000, 0}, {0xffffffff, 4, 0x00000001, 0}, {0xffffffff, 4, 0x00000002, 0}, {0xffffffff, 4, 0x00000003, 0}, {0xffffffff, 4, 0x00000004, 0}, {0xffffffff, 4, 0x00000005, 0}, // // now make some underflow cases to disprove my new rule // {1, 1, 0, 0}, {1, 1, 1, 0}, {1, 1, 2, 1}, {1, 1, 3, 1}, {1, 1, 4, 1}, {1, 1, 0xfffffffc, 1}, {1, 1, 0xfffffffd, 1}, {1, 1, 0xfffffffe, 1}, {1, 1, 0xffffffff, 1}, {1, 2, 0, 0}, {1, 2, 1, 1}, {1, 2, 2, 1}, {1, 2, 3, 1}, {1, 2, 4, 1}, {1, 2, 0xfffffffc, 1}, {1, 2, 0xfffffffd, 1}, {1, 2, 0xfffffffe, 1}, {1, 2, 0xffffffff, 1}, {1, 4, 0, 1}, {1, 4, 1, 1}, {1, 4, 2, 1}, {1, 4, 3, 1}, {1, 4, 4, 1}, {1, 4, 0xfffffffc, 1}, {1, 4, 0xfffffffd, 1}, {1, 4, 0xfffffffe, 1}, {1, 4, 0xffffffff, 1} }; int main () { int total=0, mismatches=0; int t; for (t=0; tlimit, ts->length, ts->offset); printf ("limit=%x len=%x offset=%x exception=%x %s\n", ts->limit, ts->length, ts->offset, my_answer, (ts->the_answer==my_answer) ? "" : "MISMATCH"); if (ts->the_answer!=my_answer) mismatches++; total++; } printf ("mismatches=%d\n", mismatches); printf ("total=%d\n", total); } int rule1 (Bit32u limit, Bit32u length, Bit32u offset) { if ((offset + length - 1) > limit) return 1; return 0; } int rule2 (Bit32u limit, Bit32u length, Bit32u offset) { if (offset > (limit - length + 1)) return 1; return 0; } int rule3 (Bit32u limit, Bit32u length, Bit32u offset) { if (offset > (limit - length + 1) || (length-1 > limit)) { return 1; } return 0; }