Patch extrq (#943)

* Use a singleton for instruction decoding

* Use singleton class

* Patch `EXTRQ`

* Fixup signal context functions

* Update CMakeLists.txt

---------

Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
Paris Oplopoios 2024-09-23 19:19:52 +03:00 committed by GitHub
parent 5a8e8f5936
commit 5799091044
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 371 additions and 67 deletions

View file

@ -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() {
DecoderImpl::DecoderImpl() {
ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL);
}
Disassembler::~Disassembler() = default;
DecoderImpl::~DecoderImpl() = default;
void Disassembler::printInstruction(void* code, u64 address) {
void DecoderImpl::printInstruction(void* code, u64 address) {
ZydisDecodedInstruction instruction;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
ZyanStatus status =
@ -25,8 +25,8 @@ void Disassembler::printInstruction(void* code, u64 address) {
}
}
void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands,
u64 address) {
void DecoderImpl::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 +34,9 @@ void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand*
fmt::print("instruction: {}\n", szBuffer);
}
ZyanStatus DecoderImpl::decodeInstruction(ZydisDecodedInstruction& inst,
ZydisDecodedOperand* operands, void* data, u64 size) {
return ZydisDecoderDecodeFull(&m_decoder, data, size, &inst, operands);
}
} // namespace Common

View file

@ -4,21 +4,26 @@
#pragma once
#include <Zydis/Zydis.h>
#include "common/singleton.h"
#include "common/types.h"
namespace Common {
class Disassembler {
class DecoderImpl {
public:
Disassembler();
~Disassembler();
DecoderImpl();
~DecoderImpl();
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);
private:
ZydisDecoder m_decoder;
ZydisFormatter m_formatter;
};
using Decoder = Common::Singleton<DecoderImpl>;
} // namespace Common

View file

@ -0,0 +1,92 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/arch.h"
#include "common/assert.h"
#include "common/signal_context.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/ucontext.h>
#endif
namespace Common {
void* GetXmmPointer(void* ctx, u8 index) {
#if defined(_WIN32)
#define CASE(index) \
case index: \
return (void*)(&((EXCEPTION_POINTERS*)ctx)->ContextRecord->Xmm##index.Low)
#elif defined(__APPLE__)
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext->__fs.__fpu_xmm##index);
#else
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext.fpregs->_xmm[index].element[0])
#endif
switch (index) {
CASE(0);
CASE(1);
CASE(2);
CASE(3);
CASE(4);
CASE(5);
CASE(6);
CASE(7);
CASE(8);
CASE(9);
CASE(10);
CASE(11);
CASE(12);
CASE(13);
CASE(14);
CASE(15);
default: {
UNREACHABLE_MSG("Invalid XMM register index: {}", index);
return nullptr;
}
}
#undef CASE
}
void* GetRip(void* ctx) {
#if defined(_WIN32)
return (void*)((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip;
#elif defined(__APPLE__)
return (void*)((ucontext_t*)ctx)->uc_mcontext->__ss.__rip;
#else
return (void*)((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP];
#endif
}
void IncrementRip(void* ctx, u64 length) {
#if defined(_WIN32)
((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip += length;
#elif defined(__APPLE__)
((ucontext_t*)ctx)->uc_mcontext->__ss.__rip += length;
#else
((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP] += length;
#endif
}
bool IsWriteError(void* ctx) {
#if defined(_WIN32)
return ((EXCEPTION_POINTERS*)ctx)->ExceptionRecord->ExceptionInformation[0] == 1;
#elif defined(__APPLE__)
#if defined(ARCH_X86_64)
return ((ucontext_t*)ctx)->uc_mcontext->__es.__err & 0x2;
#elif defined(ARCH_ARM64)
return ((ucontext_t*)ctx)->uc_mcontext->__es.__esr & 0x40;
#endif
#else
#if defined(ARCH_X86_64)
return ((ucontext_t*)ctx)->uc_mcontext.gregs[REG_ERR] & 0x2;
#else
#error "Unsupported architecture"
#endif
#endif
}
} // namespace Common

View file

@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Common {
void* GetXmmPointer(void* ctx, u8 index);
void* GetRip(void* ctx);
void IncrementRip(void* ctx, u64 length);
bool IsWriteError(void* ctx);
} // namespace Common