From d0075f4ea6e45c924b379776ac9ef8bc03051284 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 17 May 2020 22:30:46 +0100 Subject: [PATCH] print_info: Use LLVM to disassemble A32 --- CMakeLists.txt | 2 +- src/common/llvm_disassemble.cpp | 23 +++++++++++++++++++++++ src/common/llvm_disassemble.h | 1 + tests/print_info.cpp | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a791af6..bb1e696a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,7 +127,7 @@ if (DYNARMIC_USE_LLVM) find_package(LLVM REQUIRED CONFIG) include_directories(${LLVM_INCLUDE_DIRS}) add_definitions(-DDYNARMIC_USE_LLVM ${LLVM_DEFINITIONS}) - llvm_map_components_to_libnames(llvm_libs aarch64desc aarch64disassembler x86desc x86disassembler) + llvm_map_components_to_libnames(llvm_libs armdesc armdisassembler aarch64desc aarch64disassembler x86desc x86disassembler) endif() if (DYNARMIC_TESTS_USE_UNICORN) diff --git a/src/common/llvm_disassemble.cpp b/src/common/llvm_disassemble.cpp index dff7154c..88e79937 100644 --- a/src/common/llvm_disassemble.cpp +++ b/src/common/llvm_disassemble.cpp @@ -54,6 +54,29 @@ std::string DisassembleX64(const void* begin, const void* end) { return result; } +std::string DisassembleAArch32([[maybe_unused]] u32 instruction, [[maybe_unused]] u64 pc) { + std::string result; + +#ifdef DYNARMIC_USE_LLVM + LLVMInitializeARMTargetInfo(); + LLVMInitializeARMTargetMC(); + LLVMInitializeARMDisassembler(); + LLVMDisasmContextRef llvm_ctx = LLVMCreateDisasm("armv8-arm", nullptr, 0, nullptr, nullptr); + LLVMSetDisasmOptions(llvm_ctx, LLVMDisassembler_Option_AsmPrinterVariant); + + char buffer[80]; + size_t inst_size = LLVMDisasmInstruction(llvm_ctx, (u8*)&instruction, sizeof(instruction), pc, buffer, sizeof(buffer)); + result = inst_size > 0 ? buffer : ""; + result += '\n'; + + LLVMDisasmDispose(llvm_ctx); +#else + result += fmt::format("(disassembly disabled)\n"); +#endif + + return result; +} + std::string DisassembleAArch64([[maybe_unused]] u32 instruction, [[maybe_unused]] u64 pc) { std::string result; diff --git a/src/common/llvm_disassemble.h b/src/common/llvm_disassemble.h index c40f4dbf..a49ca2fd 100644 --- a/src/common/llvm_disassemble.h +++ b/src/common/llvm_disassemble.h @@ -12,6 +12,7 @@ namespace Dynarmic::Common { std::string DisassembleX64(const void* pos, const void* end); +std::string DisassembleAArch32(u32 instruction, u64 pc = 0); std::string DisassembleAArch64(u32 instruction, u64 pc = 0); } // namespace Dynarmic::Common diff --git a/tests/print_info.cpp b/tests/print_info.cpp index 6a84bf7a..3e87d3db 100644 --- a/tests/print_info.cpp +++ b/tests/print_info.cpp @@ -48,7 +48,7 @@ const char* GetNameOfA64Instruction(u32 instruction) { } void PrintA32Instruction(u32 instruction) { - fmt::print("{:08x} {}\n", instruction, A32::DisassembleArm(instruction)); + fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(instruction)); fmt::print("Name: {}\n", GetNameOfA32Instruction(instruction)); const A32::LocationDescriptor location{0, {}, {}};