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.cpp
|
||||||
src/core/PS4/GPU/tile_manager.h
|
src/core/PS4/GPU/tile_manager.h
|
||||||
src/core/hle/libraries/libkernel/time_management.cpp
|
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)
|
create_target_directory_groups(shadps4)
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ public:
|
||||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
|
||||||
bool Flush() const;
|
bool Flush() const;
|
||||||
bool Commit() const;
|
bool Commit() const;
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ private:
|
||||||
*/
|
*/
|
||||||
class FileBackend {
|
class FileBackend {
|
||||||
public:
|
public:
|
||||||
explicit FileBackend(const std::filesystem::path& filename) : file{filename, FS::FileAccessMode::Write,
|
explicit FileBackend(const std::filesystem::path& filename)
|
||||||
FS::FileType::TextFile} {}
|
: file{filename, FS::FileAccessMode::Write, FS::FileType::TextFile} {}
|
||||||
|
|
||||||
~FileBackend() = default;
|
~FileBackend() = default;
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ template <int stub_index>
|
||||||
static u64 CommonStub() {
|
static u64 CommonStub() {
|
||||||
auto entry = stub_nids[stub_index];
|
auto entry = stub_nids[stub_index];
|
||||||
if (entry) {
|
if (entry) {
|
||||||
LOG_ERROR(Core, "Stub: {} (nid: {}) called, returning zero to {}", entry->name,
|
LOG_ERROR(Core, "Stub: {} (nid: {}) called, returning zero to {}", entry->name, entry->nid,
|
||||||
entry->nid, __builtin_return_address(0));
|
__builtin_return_address(0));
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR(Core, "Stub: Unknown (nid: {}) called, returning zero to {}",
|
LOG_ERROR(Core, "Stub: Unknown (nid: {}) called, returning zero to {}",
|
||||||
stub_nids_unknown[stub_index], __builtin_return_address(0));
|
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) {
|
bool memory_patch(u64 vaddr, u64 value) {
|
||||||
MemoryMode old_mode{};
|
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);
|
auto* ptr = reinterpret_cast<uint64_t*>(vaddr);
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ bool memory_patch(u64 vaddr, u64 value) {
|
||||||
|
|
||||||
*ptr = 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 mode is executable flush it so insure that cpu finds it
|
||||||
if (containsExecuteMode(old_mode)) {
|
if (containsExecuteMode(old_mode)) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/hle/libraries/libs.h"
|
#include "core/hle/libraries/libs.h"
|
||||||
#include "core/linker.h"
|
#include "core/linker.h"
|
||||||
|
#include "core/tls.h"
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
@ -46,6 +47,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
auto linker = Common::Singleton<Core::Linker>::Instance();
|
auto linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
Core::Libraries::InitHLELibs(&linker->getHLESymbols());
|
Core::Libraries::InitHLELibs(&linker->getHLESymbols());
|
||||||
|
Core::InstallTlsHandler();
|
||||||
linker->LoadModule(path);
|
linker->LoadModule(path);
|
||||||
std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); },
|
std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); },
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
Loading…
Reference in New Issue