core: Bring back tls handler
This commit is contained in:
parent
29be8273d4
commit
6f96a03c13
|
@ -224,7 +224,10 @@ add_executable(shadps4
|
|||
src/core/PS4/GPU/tile_manager.cpp
|
||||
src/core/PS4/GPU/tile_manager.h
|
||||
src/core/hle/libraries/libkernel/time_management.cpp
|
||||
src/core/hle/libraries/libkernel/time_management.h)
|
||||
src/core/hle/libraries/libkernel/time_management.h
|
||||
src/core/tls.cpp
|
||||
src/core/tls.h
|
||||
)
|
||||
|
||||
create_target_directory_groups(shadps4)
|
||||
|
||||
|
|
|
@ -105,7 +105,6 @@ public:
|
|||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||
void Close();
|
||||
|
||||
|
||||
bool Flush() const;
|
||||
bool Commit() const;
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ private:
|
|||
*/
|
||||
class FileBackend {
|
||||
public:
|
||||
explicit FileBackend(const std::filesystem::path& filename) : file{filename, FS::FileAccessMode::Write,
|
||||
FS::FileType::TextFile} {}
|
||||
explicit FileBackend(const std::filesystem::path& filename)
|
||||
: file{filename, FS::FileAccessMode::Write, FS::FileType::TextFile} {}
|
||||
|
||||
~FileBackend() = default;
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ template <int stub_index>
|
|||
static u64 CommonStub() {
|
||||
auto entry = stub_nids[stub_index];
|
||||
if (entry) {
|
||||
LOG_ERROR(Core, "Stub: {} (nid: {}) called, returning zero to {}", entry->name,
|
||||
entry->nid, __builtin_return_address(0));
|
||||
LOG_ERROR(Core, "Stub: {} (nid: {}) called, returning zero to {}", entry->name, entry->nid,
|
||||
__builtin_return_address(0));
|
||||
} else {
|
||||
LOG_ERROR(Core, "Stub: Unknown (nid: {}) called, returning zero to {}",
|
||||
stub_nids_unknown[stub_index], __builtin_return_address(0));
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/types.h"
|
||||
#include "core/tls.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
thread_local u8 TLS[1024];
|
||||
|
||||
uintptr_t GetGuestTls(s64 tls_offset) {
|
||||
if (tls_offset == 0) {
|
||||
return reinterpret_cast<uintptr_t>(TLS);
|
||||
}
|
||||
UNREACHABLE_MSG("Unimplemented offset info tls");
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
static LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS pExp) noexcept {
|
||||
auto orig_rip = pExp->ContextRecord->Rip;
|
||||
while (*(u8*)pExp->ContextRecord->Rip == 0x66) {
|
||||
pExp->ContextRecord->Rip++;
|
||||
}
|
||||
|
||||
if (*(u8*)pExp->ContextRecord->Rip == 0xcd) {
|
||||
int reg = *(u8*)(pExp->ContextRecord->Rip + 1) - 0x80;
|
||||
int sizes = *(u8*)(pExp->ContextRecord->Rip + 2);
|
||||
int pattern_size = sizes & 0xF;
|
||||
int imm_size = sizes >> 4;
|
||||
|
||||
int64_t tls_offset;
|
||||
if (imm_size == 4) {
|
||||
tls_offset = *(s32*)(pExp->ContextRecord->Rip + pattern_size);
|
||||
} else {
|
||||
tls_offset = *(s64*)(pExp->ContextRecord->Rip + pattern_size);
|
||||
}
|
||||
|
||||
(&pExp->ContextRecord->Rax)[reg] = GetGuestTls(tls_offset); /* GetGuestTls */
|
||||
pExp->ContextRecord->Rip += pattern_size + imm_size;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
pExp->ContextRecord->Rip = orig_rip;
|
||||
const u32 ec = pExp->ExceptionRecord->ExceptionCode;
|
||||
switch (ec) {
|
||||
case EXCEPTION_ACCESS_VIOLATION: {
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_ACCESS_VIOLATION ({:#x})", ec);
|
||||
const auto info = pExp->ExceptionRecord->ExceptionInformation;
|
||||
switch (info[0]) {
|
||||
case 0:
|
||||
LOG_CRITICAL(Core, "Read violation at address {:#x}", info[1]);
|
||||
break;
|
||||
case 1:
|
||||
LOG_CRITICAL(Core, "Write violation at address {:#x}", info[1]);
|
||||
break;
|
||||
case 8:
|
||||
LOG_CRITICAL(Core, "DEP violation at address {:#x}", info[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_DATATYPE_MISALIGNMENT ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_ILLEGAL_INSTRUCTION ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_IN_PAGE_ERROR ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_INT_DIVIDE_BY_ZERO ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_PRIV_INSTRUCTION ({:#x})", ec);
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
LOG_CRITICAL(Core, "Exception EXCEPTION_STACK_OVERFLOW ({:#x})", ec);
|
||||
break;
|
||||
default:
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
Flush();
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
void InstallTlsHandler() {
|
||||
#ifdef _WIN64
|
||||
if (!AddVectoredExceptionHandler(0, ExceptionHandler)) {
|
||||
LOG_CRITICAL(Core, "Failed to register an exception handler");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Core
|
|
@ -0,0 +1,10 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
|
||||
void InstallTlsHandler();
|
||||
|
||||
} // namespace Core
|
|
@ -125,7 +125,7 @@ bool memory_flush(u64 address, u64 size) {
|
|||
}
|
||||
bool memory_patch(u64 vaddr, u64 value) {
|
||||
MemoryMode old_mode{};
|
||||
//memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode);
|
||||
// memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode);
|
||||
|
||||
auto* ptr = reinterpret_cast<uint64_t*>(vaddr);
|
||||
|
||||
|
@ -133,7 +133,7 @@ bool memory_patch(u64 vaddr, u64 value) {
|
|||
|
||||
*ptr = value;
|
||||
|
||||
//memory_protect(vaddr, 8, old_mode, nullptr);
|
||||
// memory_protect(vaddr, 8, old_mode, nullptr);
|
||||
|
||||
// if mode is executable flush it so insure that cpu finds it
|
||||
if (containsExecuteMode(old_mode)) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "core/file_sys/fs.h"
|
||||
#include "core/hle/libraries/libs.h"
|
||||
#include "core/linker.h"
|
||||
#include "core/tls.h"
|
||||
#include "emulator.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
@ -46,6 +47,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
auto linker = Common::Singleton<Core::Linker>::Instance();
|
||||
Core::Libraries::InitHLELibs(&linker->getHLESymbols());
|
||||
Core::InstallTlsHandler();
|
||||
linker->LoadModule(path);
|
||||
std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); },
|
||||
nullptr);
|
||||
|
|
Loading…
Reference in New Issue