Bochs/bochs/misc/test-access-check.cc

379 lines
16 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
//
// 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 <bochs.h>
// 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; t<sizeof(tests)/sizeof(tests[0]); t++) {
TestStruct *ts = &tests[t];
int my_answer = TEST_RULE (ts->limit, 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;
}