Skip to content

Commit

Permalink
Patch extrq (#943)
Browse files Browse the repository at this point in the history
* Use a singleton for instruction decoding

* Use singleton class

* Patch `EXTRQ`

* Fixup signal context functions

* Update CMakeLists.txt

---------

Co-authored-by: georgemoralis <[email protected]>
  • Loading branch information
OFFTKP and georgemoralis authored Sep 23, 2024
1 parent 5a8e8f5 commit 5799091
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 67 deletions.
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ set(COMMON src/common/logging/backend.cpp
src/common/config.h
src/common/cstring.h
src/common/debug.h
src/common/disassembler.cpp
src/common/disassembler.h
src/common/decoder.cpp
src/common/decoder.h
src/common/elf_info.h
src/common/endian.h
src/common/enum.h
Expand All @@ -378,6 +378,8 @@ set(COMMON src/common/logging/backend.cpp
src/common/polyfill_thread.h
src/common/rdtsc.cpp
src/common/rdtsc.h
src/common/signal_context.h
src/common/signal_context.cpp
src/common/singleton.h
src/common/slot_vector.h
src/common/string_util.cpp
Expand Down
17 changes: 11 additions & 6 deletions src/common/disassembler.cpp → src/common/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -25,13 +25,18 @@ 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,
szBuffer, sizeof(szBuffer), address, ZYAN_NULL);
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
11 changes: 8 additions & 3 deletions src/common/disassembler.h → src/common/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
92 changes: 92 additions & 0 deletions src/common/signal_context.cpp
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions src/common/signal_context.h
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 5799091

Please sign in to comment.