core: Bring back tls handler

This commit is contained in:
GPUCode 2024-02-27 21:07:29 +02:00
parent 29be8273d4
commit 6f96a03c13
8 changed files with 128 additions and 8 deletions

View File

@ -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)

View File

@ -105,7 +105,6 @@ public:
FileShareFlag flag = FileShareFlag::ShareReadOnly);
void Close();
bool Flush() const;
bool Commit() const;

View File

@ -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;

View File

@ -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));

106
src/core/tls.cpp Normal file
View File

@ -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

10
src/core/tls.h Normal file
View File

@ -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

View File

@ -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)) {

View File

@ -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);