kernel: Rewrite pthread emulation (#1440)

* libkernel: Cleanup some function places

* kernel: Refactor thread functions

* kernel: It builds

* kernel: Fix a bunch of bugs, kernel thread heap

* kernel: File cleanup pt1

* File cleanup pt2

* File cleanup pt3

* File cleanup pt4

* kernel: Add missing funcs

* kernel: Add basic exceptions for linux

* gnmdriver: Add workload functions

* kernel: Fix new pthreads code on macOS. (#1441)

* kernel: Downgrade edeadlk to log

* gnmdriver: Add sceGnmSubmitCommandBuffersForWorkload

* exception: Add context register population for macOS. (#1444)

* kernel: Pthread rewrite touchups for Windows

* kernel: Multiplatform thread implementation

* mutex: Remove spamming log

* pthread_spec: Make assert into a log

* pthread_spec: Zero initialize array

* Attempt to fix non-Windows builds

* hotfix: change incorrect NID for scePthreadAttrSetaffinity

* scePthreadAttrSetaffinity implementation

* Attempt to fix Linux

* windows: Address a bunch of address space problems

* address_space: Fix unmap of region surrounded by placeholders

* libs: Reduce logging

* pthread: Implement condvar with waitable atomics and sleepqueue

* sleepq: Separate and make faster

* time: Remove delay execution

* Causes high cpu usage in Tohou Luna Nights

* kernel: Cleanup files again

* pthread: Add missing include

* semaphore: Use binary_semaphore instead of condvar

* Seems more reliable

* libraries/sysmodule: log module on `sceSysmoduleIsLoaded`

* libraries/kernel: implement `scePthreadSetPrio`

---------

Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com>
Co-authored-by: Daniel R. <47796739+polybiusproxy@users.noreply.github.com>
This commit is contained in:
TheTurtle
2024-11-21 22:59:38 +02:00
committed by GitHub
parent 6904764aab
commit c4506da0ae
104 changed files with 5554 additions and 3979 deletions

View File

@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cryptopp/sha.h>
#include "common/alignment.h"
#include "common/arch.h"
#include "common/assert.h"
@@ -9,10 +11,10 @@
#include "common/string_util.h"
#include "core/aerolib/aerolib.h"
#include "core/cpu_patches.h"
#include "core/linker.h"
#include "core/loader/dwarf.h"
#include "core/memory.h"
#include "core/module.h"
#include "core/tls.h"
namespace Core {
@@ -56,6 +58,30 @@ static std::string EncodeId(u64 nVal) {
return enc;
}
static std::string StringToNid(std::string_view symbol) {
static constexpr std::array<u8, 16> Salt = {0x51, 0x8D, 0x64, 0xA6, 0x35, 0xDE, 0xD8, 0xC1,
0xE6, 0xB0, 0x39, 0xB1, 0xC3, 0xE5, 0x52, 0x30};
std::vector<u8> input(symbol.size() + Salt.size());
std::memcpy(input.data(), symbol.data(), symbol.size());
std::memcpy(input.data() + symbol.size(), Salt.data(), Salt.size());
std::array<u8, CryptoPP::SHA1::DIGESTSIZE> hash;
CryptoPP::SHA1().CalculateDigest(hash.data(), input.data(), input.size());
u64 digest;
std::memcpy(&digest, hash.data(), sizeof(digest));
static constexpr std::string_view codes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
std::string dst(11, '\0');
for (int i = 0; i < 10; i++) {
dst[i] = codes[(digest >> (58 - i * 6)) & 0x3f];
}
dst[10] = codes[(digest & 0xf) * 4];
return dst;
}
Module::Module(Core::MemoryManager* memory_, const std::filesystem::path& file_, u32& max_tls_index)
: memory{memory_}, file{file_}, name{file.stem().string()} {
elf.Open(file);
@@ -70,9 +96,8 @@ Module::~Module() = default;
s32 Module::Start(size_t args, const void* argp, void* param) {
LOG_INFO(Core_Linker, "Module started : {}", name);
const auto* linker = Common::Singleton<Core::Linker>::Instance();
const VAddr addr = dynamic_info.init_virtual_addr + GetBaseAddress();
return linker->ExecuteGuest(reinterpret_cast<EntryFunc>(addr), args, argp, param);
return ExecuteGuest(reinterpret_cast<EntryFunc>(addr), args, argp, param);
}
void Module::LoadModuleToMemory(u32& max_tls_index) {
@@ -167,9 +192,7 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
tls.align = elf_pheader[i].p_align;
tls.image_virtual_addr = elf_pheader[i].p_vaddr + base_virtual_addr;
tls.image_size = GetAlignedSize(elf_pheader[i]);
if (tls.image_size != 0) {
tls.modid = ++max_tls_index;
}
tls.modid = ++max_tls_index;
LOG_INFO(Core_Linker, "TLS virtual address = {:#x}", tls.image_virtual_addr);
LOG_INFO(Core_Linker, "TLS image size = {}", tls.image_size);
break;
@@ -492,4 +515,15 @@ const LibraryInfo* Module::FindLibrary(std::string_view id) {
return nullptr;
}
void* Module::FindByName(std::string_view name) {
const auto nid_str = StringToNid(name);
const auto symbols = export_sym.GetSymbols();
const auto it = std::ranges::find_if(
symbols, [&](const Loader::SymbolRecord& record) { return record.name.contains(nid_str); });
if (it != symbols.end()) {
return reinterpret_cast<void*>(it->virtual_address);
}
return nullptr;
}
} // namespace Core