mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 16:02:26 +00:00
Use a singleton for instruction decoding
This commit is contained in:
parent
4a0bd876ff
commit
6cc61fc27d
@ -350,8 +350,8 @@ set(COMMON src/common/logging/backend.cpp
|
|||||||
src/common/config.cpp
|
src/common/config.cpp
|
||||||
src/common/config.h
|
src/common/config.h
|
||||||
src/common/debug.h
|
src/common/debug.h
|
||||||
src/common/disassembler.cpp
|
src/common/decoder.cpp
|
||||||
src/common/disassembler.h
|
src/common/decoder.h
|
||||||
src/common/endian.h
|
src/common/endian.h
|
||||||
src/common/enum.h
|
src/common/enum.h
|
||||||
src/common/io_file.cpp
|
src/common/io_file.cpp
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/disassembler.h"
|
#include "common/decoder.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
Disassembler::Disassembler() {
|
Decoder::Decoder() {
|
||||||
ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
|
ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
|
||||||
ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Disassembler::~Disassembler() = default;
|
Decoder::~Decoder() = default;
|
||||||
|
|
||||||
void Disassembler::printInstruction(void* code, u64 address) {
|
void Decoder::printInstruction(void* code, u64 address) {
|
||||||
ZydisDecodedInstruction instruction;
|
ZydisDecodedInstruction instruction;
|
||||||
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
|
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
|
||||||
ZyanStatus status =
|
ZyanStatus status =
|
||||||
@ -25,8 +25,7 @@ void Disassembler::printInstruction(void* code, u64 address) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands,
|
void Decoder::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address) {
|
||||||
u64 address) {
|
|
||||||
const int bufLen = 256;
|
const int bufLen = 256;
|
||||||
char szBuffer[bufLen];
|
char szBuffer[bufLen];
|
||||||
ZydisFormatterFormatInstruction(&m_formatter, &inst, operands, inst.operand_count_visible,
|
ZydisFormatterFormatInstruction(&m_formatter, &inst, operands, inst.operand_count_visible,
|
||||||
@ -34,4 +33,9 @@ void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand*
|
|||||||
fmt::print("instruction: {}\n", szBuffer);
|
fmt::print("instruction: {}\n", szBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZyanStatus Decoder::decodeInstruction(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands,
|
||||||
|
void* data, u64 size) {
|
||||||
|
return ZydisDecoderDecodeFull(&m_decoder, data, size, &inst, operands);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
@ -8,13 +8,20 @@
|
|||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
class Disassembler {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Disassembler();
|
Decoder();
|
||||||
~Disassembler();
|
~Decoder();
|
||||||
|
|
||||||
void printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address);
|
void printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address);
|
||||||
void printInstruction(void* code, u64 address);
|
void printInstruction(void* code, u64 address);
|
||||||
|
ZyanStatus decodeInstruction(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands,
|
||||||
|
void* data, u64 size = 15);
|
||||||
|
|
||||||
|
static Decoder& Instance() {
|
||||||
|
static Decoder instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZydisDecoder m_decoder;
|
ZydisDecoder m_decoder;
|
@ -9,6 +9,7 @@
|
|||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/decoder.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/signals.h"
|
#include "core/signals.h"
|
||||||
#include "core/tls.h"
|
#include "core/tls.h"
|
||||||
@ -622,7 +623,6 @@ static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static std::once_flag init_flag;
|
static std::once_flag init_flag;
|
||||||
static ZydisDecoder instr_decoder;
|
|
||||||
|
|
||||||
struct PatchModule {
|
struct PatchModule {
|
||||||
/// Mutex controlling access to module code regions.
|
/// Mutex controlling access to module code regions.
|
||||||
@ -663,8 +663,8 @@ static PatchModule* GetModule(const void* ptr) {
|
|||||||
static std::pair<bool, u64> TryPatch(u8* code, PatchModule* module) {
|
static std::pair<bool, u64> TryPatch(u8* code, PatchModule* module) {
|
||||||
ZydisDecodedInstruction instruction;
|
ZydisDecodedInstruction instruction;
|
||||||
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
||||||
const auto status =
|
const auto status = Common::Decoder::Instance().decodeInstruction(instruction, operands, code,
|
||||||
ZydisDecoderDecodeFull(&instr_decoder, code, module->end - code, &instruction, operands);
|
module->end - code);
|
||||||
if (!ZYAN_SUCCESS(status)) {
|
if (!ZYAN_SUCCESS(status)) {
|
||||||
return std::make_pair(false, 1);
|
return std::make_pair(false, 1);
|
||||||
}
|
}
|
||||||
@ -755,8 +755,6 @@ static bool PatchesIllegalInstructionHandler(void* code_address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void PatchesInit() {
|
static void PatchesInit() {
|
||||||
ZydisDecoderInit(&instr_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
|
|
||||||
|
|
||||||
if (!Patches.empty()) {
|
if (!Patches.empty()) {
|
||||||
auto* signals = Signals::Instance();
|
auto* signals = Signals::Instance();
|
||||||
// Should be called last.
|
// Should be called last.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "common/arch.h"
|
#include "common/arch.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/decoder.h"
|
||||||
#include "core/signals.h"
|
#include "core/signals.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -10,7 +11,6 @@
|
|||||||
#else
|
#else
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#ifdef ARCH_X86_64
|
#ifdef ARCH_X86_64
|
||||||
#include <Zydis/Decoder.h>
|
|
||||||
#include <Zydis/Formatter.h>
|
#include <Zydis/Formatter.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -66,14 +66,10 @@ static std::string DisassembleInstruction(void* code_address) {
|
|||||||
char buffer[256] = "<unable to decode>";
|
char buffer[256] = "<unable to decode>";
|
||||||
|
|
||||||
#ifdef ARCH_X86_64
|
#ifdef ARCH_X86_64
|
||||||
ZydisDecoder decoder;
|
|
||||||
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
|
|
||||||
|
|
||||||
ZydisDecodedInstruction instruction;
|
ZydisDecodedInstruction instruction;
|
||||||
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
||||||
static constexpr u64 max_length = 0x20;
|
|
||||||
const auto status =
|
const auto status =
|
||||||
ZydisDecoderDecodeFull(&decoder, code_address, max_length, &instruction, operands);
|
Common::Decoder::Instance().decodeInstruction(instruction, operands, code_address);
|
||||||
if (ZYAN_SUCCESS(status)) {
|
if (ZYAN_SUCCESS(status)) {
|
||||||
ZydisFormatter formatter;
|
ZydisFormatter formatter;
|
||||||
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||||
|
Loading…
Reference in New Issue
Block a user