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