mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-03 16:02:26 +00:00
tls: Add caching for Windows exception handler.
This commit is contained in:
parent
c70014a992
commit
69472d79a4
@ -28,26 +28,46 @@ namespace Core {
|
|||||||
// Windows
|
// Windows
|
||||||
|
|
||||||
static DWORD slot = 0;
|
static DWORD slot = 0;
|
||||||
|
static std::set<void*> known_fs_accesses;
|
||||||
|
static std::mutex known_fs_accesses_lock;
|
||||||
static ZydisDecoder tls_instr_decoder;
|
static ZydisDecoder tls_instr_decoder;
|
||||||
static std::once_flag slot_alloc_flag;
|
static std::once_flag slot_alloc_flag;
|
||||||
|
|
||||||
static bool TlsAccessViolationHandler(void* code_address, void* fault_address, bool is_write) {
|
static bool TlsAccessViolationHandler(void* code_address, void* fault_address, bool is_write) {
|
||||||
ZydisDecodedInstruction instruction;
|
bool known;
|
||||||
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
{
|
||||||
const auto status =
|
std::unique_lock lock{known_fs_accesses_lock};
|
||||||
ZydisDecoderDecodeFull(&tls_instr_decoder, code_address, 0x20, &instruction, operands);
|
known = known_fs_accesses.contains(code_address);
|
||||||
if (!ZYAN_SUCCESS(status)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < instruction.operand_count_visible; i++) {
|
if (!known) {
|
||||||
if (operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
ZydisDecodedInstruction instruction;
|
||||||
operands[i].mem.segment == ZYDIS_REGISTER_FS) {
|
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
|
||||||
// Set the FS register and try again.
|
const auto status =
|
||||||
const auto* tcb_base = GetTcbBase();
|
ZydisDecoderDecodeFull(&tls_instr_decoder, code_address, 0x20, &instruction, operands);
|
||||||
asm volatile("wrfsbase %0" ::"r"(tcb_base) : "memory");
|
if (!ZYAN_SUCCESS(status)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < instruction.operand_count_visible; i++) {
|
||||||
|
if (operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
|
operands[i].mem.segment == ZYDIS_REGISTER_FS) {
|
||||||
|
known = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (known) {
|
||||||
|
std::unique_lock lock{known_fs_accesses_lock};
|
||||||
|
known_fs_accesses.insert(code_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (known) {
|
||||||
|
// Set the FS register and try again.
|
||||||
|
const auto* tcb_base = GetTcbBase();
|
||||||
|
asm volatile("wrfsbase %0" ::"r"(tcb_base) : "memory");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user