Add API function to retrieve dissassembly as vector of strings (#644)

Co-authored-by: ben <Avuxo@users.noreply.github.com>
This commit is contained in:
Ben 2021-09-16 16:45:20 -04:00 committed by GitHub
parent f88aa570a3
commit 6ce8bfaf32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 6 deletions

View file

@ -318,8 +318,12 @@ void Jit::LoadContext(const Context& ctx) {
} }
void Jit::DumpDisassembly() const { void Jit::DumpDisassembly() const {
const size_t size = (const char*)impl->block_of_code.getCurr() - (const char*)impl->block_of_code.GetCodeBegin(); const size_t size = reinterpret_cast<const char*>(impl->block_of_code.getCurr()) - reinterpret_cast<const char*>(impl->block_of_code.GetCodeBegin());
Common::DumpDisassembledX64(impl->block_of_code.GetCodeBegin(), size); Common::DumpDisassembledX64(impl->block_of_code.GetCodeBegin(), size);
} }
std::vector<std::string> Jit::Disassemble() const {
const size_t size = reinterpret_cast<const char*>(impl->block_of_code.getCurr()) - reinterpret_cast<const char*>(impl->block_of_code.GetCodeBegin());
return Common::DisassembleX64(impl->block_of_code.GetCodeBegin(), size);
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

View file

@ -200,10 +200,15 @@ public:
} }
void DumpDisassembly() const { void DumpDisassembly() const {
const size_t size = (const char*)block_of_code.getCurr() - (const char*)block_of_code.GetCodeBegin(); const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size); Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size);
} }
std::vector<std::string> Disassemble() const {
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
return Common::DisassembleX64(block_of_code.GetCodeBegin(), size);
}
private: private:
static CodePtr GetCurrentBlockThunk(void* thisptr) { static CodePtr GetCurrentBlockThunk(void* thisptr) {
Jit::Impl* this_ = static_cast<Jit::Impl*>(thisptr); Jit::Impl* this_ = static_cast<Jit::Impl*>(thisptr);
@ -402,4 +407,8 @@ void Jit::DumpDisassembly() const {
return impl->DumpDisassembly(); return impl->DumpDisassembly();
} }
std::vector<std::string> Jit::Disassemble() const {
return impl->Disassemble();
}
} // namespace Dynarmic::A64 } // namespace Dynarmic::A64

View file

@ -46,7 +46,7 @@ constexpr FPUnpacked ToNormalized(bool sign, int exponent, u64 value) {
const int highest_bit = Common::HighestSetBit(value); const int highest_bit = Common::HighestSetBit(value);
const int offset = static_cast<int>(normalized_point_position) - highest_bit; const int offset = static_cast<int>(normalized_point_position) - highest_bit;
value <<= offset; value <<= offset;
exponent -= offset - normalized_point_position; exponent -= offset - static_cast<int>(normalized_point_position);
return {sign, exponent, value}; return {sign, exponent, value};
} }

View file

@ -21,15 +21,36 @@ void DumpDisassembledX64(const void* ptr, size_t size) {
size_t offset = 0; size_t offset = 0;
ZydisDecodedInstruction instruction; ZydisDecodedInstruction instruction;
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, (const char*)ptr + offset, size - offset, &instruction))) { while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, static_cast<const char*>(ptr) + offset, size - offset, &instruction))) {
fmt::print("{:016x} ", (u64)ptr + offset); fmt::print("{:016x} ", (u64)ptr + offset);
char buffer[256]; char buffer[256];
ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer), (u64)ptr + offset); ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer), reinterpret_cast<u64>(ptr) + offset);
puts(buffer); puts(buffer);
offset += instruction.length; offset += instruction.length;
} }
} }
std::vector<std::string> DisassembleX64(const void* ptr, size_t size) {
std::vector<std::string> result;
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
size_t offset = 0;
ZydisDecodedInstruction instruction;
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, static_cast<const char*>(ptr) + offset, size - offset, &instruction))) {
char buffer[256];
ZydisFormatterFormatInstruction(&formatter, &instruction, buffer, sizeof(buffer), reinterpret_cast<u64>(ptr) + offset);
result.push_back(fmt::format("{:016x} {}", (u64)ptr + offset, buffer));
offset += instruction.length;
}
return result;
}
} // namespace Dynarmic::Common } // namespace Dynarmic::Common

View file

@ -5,10 +5,17 @@
#pragma once #pragma once
#include <string>
#include <vector>
#include "dynarmic/common/common_types.h" #include "dynarmic/common/common_types.h"
namespace Dynarmic::Common { namespace Dynarmic::Common {
void DumpDisassembledX64(const void* ptr, size_t size); void DumpDisassembledX64(const void* ptr, size_t size);
/**
* Disassemble `size' bytes from `ptr' and return the disassembled lines as a vector
* of strings.
*/
std::vector<std::string> DisassembleX64(const void* ptr, size_t size);
} // namespace Dynarmic::Common } // namespace Dynarmic::Common

View file

@ -9,6 +9,7 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include "dynarmic/interface/A32/config.h" #include "dynarmic/interface/A32/config.h"
@ -91,6 +92,12 @@ public:
/// Debugging: Dump a disassembly all compiled code to the console. /// Debugging: Dump a disassembly all compiled code to the console.
void DumpDisassembly() const; void DumpDisassembly() const;
/**
* Disassemble the instructions following the current pc and return
* the resulting instructions as a vector of their string representations.
*/
std::vector<std::string> Disassemble() const;
private: private:
bool is_executing = false; bool is_executing = false;

View file

@ -10,6 +10,7 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include "dynarmic/interface/A64/config.h" #include "dynarmic/interface/A64/config.h"
@ -117,6 +118,12 @@ public:
/// Debugging: Dump a disassembly all of compiled code to the console. /// Debugging: Dump a disassembly all of compiled code to the console.
void DumpDisassembly() const; void DumpDisassembly() const;
/*
* Disassemble the instructions following the current pc and return
* the resulting instructions as a vector of their string representations.
*/
std::vector<std::string> Disassemble() const;
private: private:
struct Impl; struct Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;