From b252636dc38ced4288cbabbea4ff675f69e393db Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 6 Feb 2021 22:15:02 +0000 Subject: [PATCH] a32_unicorn: Halt when PC leaves code_mem --- tests/A32/fuzz_arm.cpp | 17 +++-------------- tests/A32/testenv.h | 11 +++++++---- tests/unicorn_emu/a32_unicorn.cpp | 3 +++ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/tests/A32/fuzz_arm.cpp b/tests/A32/fuzz_arm.cpp index 2cd9b47e..41b37733 100644 --- a/tests/A32/fuzz_arm.cpp +++ b/tests/A32/fuzz_arm.cpp @@ -215,6 +215,8 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit, jit_env.code_mem.resize(code_mem_size); uni_env.code_mem.resize(code_mem_size); + std::fill(jit_env.code_mem.begin(), jit_env.code_mem.end(), TestEnv::infinite_loop); + std::fill(uni_env.code_mem.begin(), uni_env.code_mem.end(), TestEnv::infinite_loop); std::copy(instructions.begin(), instructions.end(), jit_env.code_mem.begin() + num_words); std::copy(instructions.begin(), instructions.end(), uni_env.code_mem.begin() + num_words); @@ -240,20 +242,7 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit, jit_env.ticks_left = ticks_left; jit.Run(); - uni_env.ticks_left = [&]{ - if constexpr (std::is_same_v) { - // Unicorn counts thumb instructions weirdly: - // A 32-bit thumb instruction counts as two. - // Except for branch instructions which count as one??? - if (instructions.size() <= 1) - return ticks_left; - if ((instructions[instructions.size() - 2] & 0xF800) <= 0xE800) - return instructions.size(); - return instructions.size() - 1; - } else { - return ticks_left; - } - }(); + uni_env.ticks_left = instructions.size(); // Unicorn counts thumb instructions weirdly. uni.Run(); SCOPE_FAIL { diff --git a/tests/A32/testenv.h b/tests/A32/testenv.h index 75e15841..95780222 100644 --- a/tests/A32/testenv.h +++ b/tests/A32/testenv.h @@ -37,18 +37,21 @@ public: } while (code_mem.size() % 2 != 0); } + bool IsInCodeMem(u32 vaddr) const { + return vaddr < sizeof(InstructionType) * code_mem.size(); + } + std::uint32_t MemoryReadCode(u32 vaddr) override { - const size_t index = vaddr / sizeof(InstructionType); - if (index < code_mem.size()) { + if (IsInCodeMem(vaddr)) { u32 value; - std::memcpy(&value, &code_mem[index], sizeof(u32)); + std::memcpy(&value, &code_mem[vaddr / sizeof(InstructionType)], sizeof(u32)); return value; } return infinite_loop_u32; // B . } std::uint8_t MemoryRead8(u32 vaddr) override { - if (vaddr < sizeof(InstructionType) * code_mem.size()) { + if (IsInCodeMem(vaddr)) { return reinterpret_cast(code_mem.data())[vaddr]; } if (auto iter = modified_memory.find(vaddr); iter != modified_memory.end()) { diff --git a/tests/unicorn_emu/a32_unicorn.cpp b/tests/unicorn_emu/a32_unicorn.cpp index f7501913..16052e4c 100644 --- a/tests/unicorn_emu/a32_unicorn.cpp +++ b/tests/unicorn_emu/a32_unicorn.cpp @@ -44,6 +44,9 @@ void A32Unicorn::Run() { constexpr u64 pc_mask = std::is_same_v ? 0 : 1; while (testenv.ticks_left > 0) { const u32 pc = GetPC() | pc_mask; + if (!testenv.IsInCodeMem(pc)) { + return; + } if (auto cerr_ = uc_emu_start(uc, pc, END_ADDRESS, 0, 1)) { ASSERT_MSG(false, "uc_emu_start failed @ {:08x} (code = {:08x}) with error {} ({})", pc, testenv.MemoryReadCode(pc), cerr_, uc_strerror(cerr_)); }