Example of Capstone for both libxenia and the UI. Going to shuffle around.

This commit is contained in:
Ben Vanik
2015-06-10 23:31:19 -07:00
parent 8ca2b17e51
commit 6d4d1db310
16 changed files with 751 additions and 8 deletions

View File

@@ -19,9 +19,18 @@
#include "xenia/cpu/processor.h"
#include "xenia/profiling.h"
//#define DISASM_BEAENGINE
#define DISASM_CAPSTONE
#ifdef DISASM_BEAENGINE
namespace BE {
#include <beaengine/BeaEngine.h>
} // namespace BE
#endif // DISASM_BEAENGINE
#ifdef DISASM_CAPSTONE
#include "third_party/capstone/include/capstone.h"
#include "third_party/capstone/include/x86.h"
#endif // DISASM_CAPSTONE
namespace xe {
namespace cpu {
@@ -34,12 +43,26 @@ using namespace xe::cpu;
using xe::cpu::hir::HIRBuilder;
X64Assembler::X64Assembler(X64Backend* backend)
: Assembler(backend), x64_backend_(backend) {}
: Assembler(backend), x64_backend_(backend), capstone_handle_(0) {
#ifdef DISASM_CAPSTONE
if (cs_open(CS_ARCH_X86, CS_MODE_64, &capstone_handle_) != CS_ERR_OK) {
assert_always("Failed to initialize capstone");
}
cs_option(capstone_handle_, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL);
cs_option(capstone_handle_, CS_OPT_DETAIL, CS_OPT_OFF);
#endif // DISASM_CAPSTONE
}
X64Assembler::~X64Assembler() {
// Emitter must be freed before the allocator.
emitter_.reset();
allocator_.reset();
#ifdef DISASM_CAPSTONE
if (capstone_handle_) {
cs_close(&capstone_handle_);
}
#endif // DISASM_CAPSTONE
}
bool X64Assembler::Initialize() {
@@ -106,6 +129,7 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
auto source_map_index = 0;
uint32_t next_code_offset = source_map_entries[0].code_offset;
#if defined(DISASM_BEAENGINE)
BE::DISASM disasm = {0};
disasm.Archi = 64;
disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral;
@@ -133,6 +157,31 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
str->AppendFormat("%.8X %s\n", uint32_t(disasm.EIP), disasm.CompleteInstr);
disasm.EIP += len;
}
#elif defined(DISASM_CAPSTONE)
const uint8_t* code_ptr = reinterpret_cast<uint8_t*>(machine_code);
size_t remaining_code_size = code_size;
uint64_t address = uint64_t(machine_code);
cs_insn insn = {0};
while (remaining_code_size &&
cs_disasm_iter(capstone_handle_, &code_ptr, &remaining_code_size,
&address, &insn)) {
// Look up source offset.
auto code_offset =
uint32_t(code_ptr - reinterpret_cast<uint8_t*>(machine_code));
if (code_offset >= next_code_offset &&
source_map_index < source_map_count) {
auto& source_map_entry = source_map_entries[source_map_index];
str->AppendFormat("%.8X ", source_map_entry.source_offset);
++source_map_index;
next_code_offset = source_map_entries[source_map_index].code_offset;
} else {
str->Append(" ");
}
str->AppendFormat("%.8X %-6s %s\n", uint32_t(insn.address),
insn.mnemonic, insn.op_str);
}
#endif // DISASM_BEAENGINE / DISASM_CAPSTONE
}
} // namespace x64

View File

@@ -46,6 +46,7 @@ class X64Assembler : public Assembler {
X64Backend* x64_backend_;
std::unique_ptr<X64Emitter> emitter_;
std::unique_ptr<XbyakAllocator> allocator_;
uintptr_t capstone_handle_;
StringBuffer string_buffer_;
};