fuzz_thumb: Off by one error
This commit is contained in:
parent
ecebe14a01
commit
c34639f33d
1 changed files with 126 additions and 83 deletions
|
@ -80,6 +80,8 @@ static u16 MemoryRead16(u32 vaddr) {
|
||||||
static u32 MemoryRead32(u32 vaddr) {
|
static u32 MemoryRead32(u32 vaddr) {
|
||||||
if (vaddr < code_mem.size() * sizeof(u16)) {
|
if (vaddr < code_mem.size() * sizeof(u16)) {
|
||||||
size_t index = vaddr / sizeof(u16);
|
size_t index = vaddr / sizeof(u16);
|
||||||
|
if (index + 1 >= code_mem.size())
|
||||||
|
return code_mem[index];
|
||||||
return code_mem[index] | (code_mem[index+1] << 16);
|
return code_mem[index] | (code_mem[index+1] << 16);
|
||||||
}
|
}
|
||||||
return vaddr;
|
return vaddr;
|
||||||
|
@ -90,6 +92,8 @@ static u64 MemoryRead64(u32 vaddr) {
|
||||||
static u32 MemoryReadCode(u32 vaddr) {
|
static u32 MemoryReadCode(u32 vaddr) {
|
||||||
if (vaddr < code_mem.size() * sizeof(u16)) {
|
if (vaddr < code_mem.size() * sizeof(u16)) {
|
||||||
size_t index = vaddr / sizeof(u16);
|
size_t index = vaddr / sizeof(u16);
|
||||||
|
if (index + 1 >= code_mem.size())
|
||||||
|
return code_mem[index];
|
||||||
return code_mem[index] | (code_mem[index + 1] << 16);
|
return code_mem[index] | (code_mem[index + 1] << 16);
|
||||||
}
|
}
|
||||||
return 0xE7FEE7FE; // b +#0, b +#0
|
return 0xE7FEE7FE; // b +#0, b +#0
|
||||||
|
@ -198,33 +202,18 @@ static bool DoesBehaviorMatch(const ARMul_State& interp, const Dynarmic::A32::Ji
|
||||||
&& interp_write_records == jit_write_records;
|
&& interp_write_records == jit_write_records;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_execute_count, const size_t run_count, const std::function<u16()> instruction_generator) {
|
static void RunInstance(size_t run_number, ARMul_State& interp, Dynarmic::A32::Jit& jit, const std::array<u32, 16>& initial_regs, size_t instruction_count, size_t instructions_to_execute_count) {
|
||||||
// Prepare memory
|
|
||||||
code_mem.fill(0xE7FE); // b +#0
|
|
||||||
|
|
||||||
// Prepare test subjects
|
|
||||||
ARMul_State interp{USER32MODE};
|
|
||||||
interp.user_callbacks = GetUserCallbacks();
|
|
||||||
Dynarmic::A32::Jit jit{GetUserCallbacks()};
|
|
||||||
|
|
||||||
for (size_t run_number = 0; run_number < run_count; run_number++) {
|
|
||||||
interp.instruction_cache.clear();
|
interp.instruction_cache.clear();
|
||||||
InterpreterClearCache();
|
InterpreterClearCache();
|
||||||
jit.ClearCache();
|
jit.ClearCache();
|
||||||
|
|
||||||
// Setup initial state
|
// Setup initial state
|
||||||
|
|
||||||
std::array<u32, 16> initial_regs;
|
|
||||||
std::generate_n(initial_regs.begin(), 15, []{ return RandInt<u32>(0, 0xFFFFFFFF); });
|
|
||||||
initial_regs[15] = 0;
|
|
||||||
|
|
||||||
interp.Cpsr = 0x000001F0;
|
interp.Cpsr = 0x000001F0;
|
||||||
interp.Reg = initial_regs;
|
interp.Reg = initial_regs;
|
||||||
jit.SetCpsr(0x000001F0);
|
jit.SetCpsr(0x000001F0);
|
||||||
jit.Regs() = initial_regs;
|
jit.Regs() = initial_regs;
|
||||||
|
|
||||||
std::generate_n(code_mem.begin(), instruction_count, instruction_generator);
|
|
||||||
|
|
||||||
// Run interpreter
|
// Run interpreter
|
||||||
write_records.clear();
|
write_records.clear();
|
||||||
interp.NumInstrsToExecute = static_cast<unsigned>(instructions_to_execute_count);
|
interp.NumInstrsToExecute = static_cast<unsigned>(instructions_to_execute_count);
|
||||||
|
@ -247,7 +236,7 @@ void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_e
|
||||||
|
|
||||||
printf("\nInstruction Listing: \n");
|
printf("\nInstruction Listing: \n");
|
||||||
for (size_t i = 0; i < instruction_count; i++) {
|
for (size_t i = 0; i < instruction_count; i++) {
|
||||||
printf("%s\n", Dynarmic::A32::DisassembleThumb16(code_mem[i]).c_str());
|
printf("%04x %s\n", code_mem[i], Dynarmic::A32::DisassembleThumb16(code_mem[i]).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nInitial Register Listing: \n");
|
printf("\nInitial Register Listing: \n");
|
||||||
|
@ -295,8 +284,25 @@ void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_e
|
||||||
#endif
|
#endif
|
||||||
FAIL();
|
FAIL();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (run_number % 10 == 0) printf("%zu\r", run_number);
|
void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_execute_count, const size_t run_count, const std::function<u16()> instruction_generator) {
|
||||||
|
// Prepare memory
|
||||||
|
code_mem.fill(0xE7FE); // b +#0
|
||||||
|
|
||||||
|
// Prepare test subjects
|
||||||
|
ARMul_State interp{USER32MODE};
|
||||||
|
interp.user_callbacks = GetUserCallbacks();
|
||||||
|
Dynarmic::A32::Jit jit{GetUserCallbacks()};
|
||||||
|
|
||||||
|
for (size_t run_number = 0; run_number < run_count; run_number++) {
|
||||||
|
std::array<u32, 16> initial_regs;
|
||||||
|
std::generate_n(initial_regs.begin(), 15, []{ return RandInt<u32>(0, 0xFFFFFFFF); });
|
||||||
|
initial_regs[15] = 0;
|
||||||
|
|
||||||
|
std::generate_n(code_mem.begin(), instruction_count, instruction_generator);
|
||||||
|
|
||||||
|
RunInstance(run_number, interp, jit, initial_regs, instruction_count, instructions_to_execute_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,3 +386,40 @@ TEST_CASE("Fuzz Thumb instructions set 2 (affects PC)", "[JitX64][Thumb]") {
|
||||||
|
|
||||||
FuzzJitThumb(1, 1, 10000, instruction_select);
|
FuzzJitThumb(1, 1, 10000, instruction_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Verify fix for off by one error in MemoryRead32 worked", "[Thumb]") {
|
||||||
|
// Prepare memory
|
||||||
|
code_mem.fill(0xE7FE); // b +#0
|
||||||
|
|
||||||
|
// Prepare test subjects
|
||||||
|
ARMul_State interp{USER32MODE};
|
||||||
|
interp.user_callbacks = GetUserCallbacks();
|
||||||
|
Dynarmic::A32::Jit jit{GetUserCallbacks()};
|
||||||
|
|
||||||
|
std::array<u32, 16> initial_regs {
|
||||||
|
0xe90ecd70,
|
||||||
|
0x3e3b73c3,
|
||||||
|
0x571616f9,
|
||||||
|
0x0b1ef45a,
|
||||||
|
0xb3a829f2,
|
||||||
|
0x915a7a6a,
|
||||||
|
0x579c38f4,
|
||||||
|
0xd9ffe391,
|
||||||
|
0x55b6682b,
|
||||||
|
0x458d8f37,
|
||||||
|
0x8f3eb3dc,
|
||||||
|
0xe18c0e7d,
|
||||||
|
0x6752657a,
|
||||||
|
0x00001766,
|
||||||
|
0xdbbf23e3,
|
||||||
|
0x00000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
code_mem[0] = 0x40B8; // lsls r0, r7, #0
|
||||||
|
code_mem[1] = 0x01CA; // lsls r2, r1, #7
|
||||||
|
code_mem[2] = 0x83A1; // strh r1, [r4, #28]
|
||||||
|
code_mem[3] = 0x708A; // strb r2, [r1, #2]
|
||||||
|
code_mem[4] = 0xBCC4; // pop {r2, r6, r7}
|
||||||
|
|
||||||
|
RunInstance(1, interp, jit, initial_regs, 5, 5);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue