fuzz_arm: Correctly print thumb instruction listing
This commit is contained in:
parent
62003a2d89
commit
68bd9547c5
4 changed files with 28 additions and 13 deletions
|
@ -54,20 +54,38 @@ std::string DisassembleX64(const void* begin, const void* end) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DisassembleAArch32([[maybe_unused]] u32 instruction, [[maybe_unused]] u64 pc) {
|
std::string DisassembleAArch32([[maybe_unused]] bool is_thumb, [[maybe_unused]] u32 pc, [[maybe_unused]] const u8* instructions, [[maybe_unused]] size_t length) {
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
#ifdef DYNARMIC_USE_LLVM
|
#ifdef DYNARMIC_USE_LLVM
|
||||||
LLVMInitializeARMTargetInfo();
|
LLVMInitializeARMTargetInfo();
|
||||||
LLVMInitializeARMTargetMC();
|
LLVMInitializeARMTargetMC();
|
||||||
LLVMInitializeARMDisassembler();
|
LLVMInitializeARMDisassembler();
|
||||||
LLVMDisasmContextRef llvm_ctx = LLVMCreateDisasm("armv8-arm", nullptr, 0, nullptr, nullptr);
|
LLVMDisasmContextRef llvm_ctx = LLVMCreateDisasm(is_thumb ? "thumbv8-arm" : "armv8-arm", nullptr, 0, nullptr, nullptr);
|
||||||
LLVMSetDisasmOptions(llvm_ctx, LLVMDisassembler_Option_AsmPrinterVariant);
|
LLVMSetDisasmOptions(llvm_ctx, LLVMDisassembler_Option_AsmPrinterVariant);
|
||||||
|
|
||||||
char buffer[80];
|
char buffer[1024];
|
||||||
size_t inst_size = LLVMDisasmInstruction(llvm_ctx, (u8*)&instruction, sizeof(instruction), pc, buffer, sizeof(buffer));
|
while (length) {
|
||||||
result = inst_size > 0 ? buffer : "<invalid instruction>";
|
size_t inst_size = LLVMDisasmInstruction(llvm_ctx, const_cast<u8*>(instructions), length, pc, buffer, sizeof(buffer));
|
||||||
result += '\n';
|
|
||||||
|
result += fmt::format("{:08x} ", pc);
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
if (i < inst_size) {
|
||||||
|
result += fmt::format("{:02x}", instructions[inst_size - i - 1]);
|
||||||
|
} else {
|
||||||
|
result += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result += inst_size > 0 ? buffer : "<invalid instruction>";
|
||||||
|
result += '\n';
|
||||||
|
|
||||||
|
if (inst_size == 0) inst_size = is_thumb ? 2 : 4;
|
||||||
|
if (length <= inst_size) break;
|
||||||
|
|
||||||
|
pc += inst_size;
|
||||||
|
instructions += inst_size;
|
||||||
|
length -= inst_size;
|
||||||
|
}
|
||||||
|
|
||||||
LLVMDisasmDispose(llvm_ctx);
|
LLVMDisasmDispose(llvm_ctx);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace Dynarmic::Common {
|
namespace Dynarmic::Common {
|
||||||
|
|
||||||
std::string DisassembleX64(const void* pos, const void* end);
|
std::string DisassembleX64(const void* pos, const void* end);
|
||||||
std::string DisassembleAArch32(u32 instruction, u64 pc = 0);
|
std::string DisassembleAArch32(bool is_thumb, u32 pc, const u8* instructions, size_t length);
|
||||||
std::string DisassembleAArch64(u32 instruction, u64 pc = 0);
|
std::string DisassembleAArch64(u32 instruction, u64 pc = 0);
|
||||||
|
|
||||||
} // namespace Dynarmic::Common
|
} // namespace Dynarmic::Common
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/fp/fpcr.h"
|
#include "common/fp/fpcr.h"
|
||||||
#include "common/fp/fpsr.h"
|
#include "common/fp/fpsr.h"
|
||||||
|
#include "common/llvm_disassemble.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "frontend/A32/disassembler/disassembler.h"
|
|
||||||
#include "frontend/A32/location_descriptor.h"
|
#include "frontend/A32/location_descriptor.h"
|
||||||
#include "frontend/A32/translate/translate.h"
|
#include "frontend/A32/translate/translate.h"
|
||||||
#include "frontend/A32/types.h"
|
#include "frontend/A32/types.h"
|
||||||
|
@ -247,10 +247,7 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit,
|
||||||
|
|
||||||
SCOPE_FAIL {
|
SCOPE_FAIL {
|
||||||
fmt::print("Instruction Listing:\n");
|
fmt::print("Instruction Listing:\n");
|
||||||
for (u32 instruction : instructions) {
|
fmt::print("{}\n", Common::DisassembleAArch32(std::is_same_v<TestEnv, ThumbTestEnv>, initial_pc, (const u8*)instructions.data(), instructions.size() * sizeof(instructions[0])));
|
||||||
fmt::print("{:08x} {}\n", instruction, A32::DisassembleArm(instruction));
|
|
||||||
}
|
|
||||||
fmt::print("\n");
|
|
||||||
|
|
||||||
fmt::print("Initial register listing:\n");
|
fmt::print("Initial register listing:\n");
|
||||||
for (size_t i = 0; i < regs.size(); ++i) {
|
for (size_t i = 0; i < regs.size(); ++i) {
|
||||||
|
|
|
@ -54,7 +54,7 @@ const char* GetNameOfA64Instruction(u32 instruction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintA32Instruction(u32 instruction) {
|
void PrintA32Instruction(u32 instruction) {
|
||||||
fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(instruction));
|
fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(false, 0, (u8*)&instruction, sizeof(instruction)));
|
||||||
fmt::print("Name: {}\n", GetNameOfA32Instruction(instruction));
|
fmt::print("Name: {}\n", GetNameOfA32Instruction(instruction));
|
||||||
|
|
||||||
const A32::LocationDescriptor location{0, {}, {}};
|
const A32::LocationDescriptor location{0, {}, {}};
|
||||||
|
|
Loading…
Reference in a new issue