From 075f043392c72939b9708daebf7148083de774fc Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Wed, 2 Oct 2024 22:38:24 -0700 Subject: [PATCH] core: Fix some missing uses of ExecuteGuest. (#1214) --- .../libraries/avplayer/avplayer_state.cpp | 4 ++-- .../libraries/kernel/thread_management.cpp | 2 +- src/core/libraries/network/net_ctl_obj.cpp | 4 ++-- src/core/linker.cpp | 22 +++++++++++-------- src/core/linker.h | 15 +++++++++---- src/core/module.cpp | 2 +- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/core/libraries/avplayer/avplayer_state.cpp b/src/core/libraries/avplayer/avplayer_state.cpp index c4d666fc..b0e49847 100644 --- a/src/core/libraries/avplayer/avplayer_state.cpp +++ b/src/core/libraries/avplayer/avplayer_state.cpp @@ -91,7 +91,7 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, SceAvPlayer const auto callback = self->m_event_replacement.event_callback; const auto ptr = self->m_event_replacement.object_ptr; if (callback != nullptr) { - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); linker->ExecuteGuest(callback, ptr, event_id, 0, event_data); } } @@ -367,7 +367,7 @@ void AvPlayerState::EmitEvent(SceAvPlayerEvents event_id, void* event_data) { const auto callback = m_init_data.event_replacement.event_callback; if (callback) { const auto ptr = m_init_data.event_replacement.object_ptr; - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); linker->ExecuteGuest(callback, ptr, event_id, 0, event_data); } } diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 90e03293..e6b9a5c1 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -993,7 +993,7 @@ static void cleanup_thread(void* arg) { static void* run_thread(void* arg) { auto* thread = static_cast(arg); Common::SetCurrentThreadName(thread->name.c_str()); - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); void* ret = nullptr; g_pthread_self = thread; pthread_cleanup_push(cleanup_thread, thread); diff --git a/src/core/libraries/network/net_ctl_obj.cpp b/src/core/libraries/network/net_ctl_obj.cpp index 8193c684..07381d67 100644 --- a/src/core/libraries/network/net_ctl_obj.cpp +++ b/src/core/libraries/network/net_ctl_obj.cpp @@ -59,7 +59,7 @@ s32 Libraries::NetCtl::NetCtlInternal::registerNpToolkitCallback( void Libraries::NetCtl::NetCtlInternal::checkCallback() { std::unique_lock lock{m_mutex}; - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); for (auto& callback : callbacks) { if (callback.func != nullptr) { linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, @@ -70,7 +70,7 @@ void Libraries::NetCtl::NetCtlInternal::checkCallback() { void Libraries::NetCtl::NetCtlInternal::checkNpToolkitCallback() { std::unique_lock lock{m_mutex}; - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); for (auto& callback : nptoolCallbacks) { if (callback.func != nullptr) { linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 4e4fa28d..9f4ae062 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -27,8 +27,8 @@ static PS4_SYSV_ABI void ProgramExitFunc() { fmt::print("exit function called\n"); } -static void RunMainEntry(VAddr addr, EntryParams* params, ExitFunc exit_func) { #ifdef ARCH_X86_64 +static PS4_SYSV_ABI void RunMainEntry(VAddr addr, EntryParams* params, ExitFunc exit_func) { // reinterpret_cast(addr)(params, exit_func); // can't be used, stack has to have // a specific layout asm volatile("andq $-16, %%rsp\n" // Align to 16 bytes @@ -48,10 +48,8 @@ static void RunMainEntry(VAddr addr, EntryParams* params, ExitFunc exit_func) { : : "r"(addr), "r"(params), "r"(exit_func) : "rax", "rsi", "rdi"); -#else - UNIMPLEMENTED_MSG("Missing RunMainEntry() implementation for target CPU architecture."); -#endif } +#endif Linker::Linker() : memory{Memory::Instance()} {} @@ -107,7 +105,12 @@ void Linker::Execute() { for (auto& m : m_modules) { if (!m->IsSharedLib()) { - RunMainEntry(m->GetEntryAddress(), &p, ProgramExitFunc); +#ifdef ARCH_X86_64 + ExecuteGuest(RunMainEntry, m->GetEntryAddress(), &p, ProgramExitFunc); +#else + UNIMPLEMENTED_MSG( + "Missing guest entrypoint implementation for target CPU architecture."); +#endif } } @@ -322,7 +325,8 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { Module* module = m_modules[module_index - 1].get(); const u32 init_image_size = module->tls.init_image_size; // TODO: Determine if Windows will crash from this - u8* dest = reinterpret_cast(heap_api->heap_malloc(module->tls.image_size)); + u8* dest = + reinterpret_cast(ExecuteGuest(heap_api->heap_malloc, module->tls.image_size)); const u8* src = reinterpret_cast(module->tls.image_virtual_addr); std::memcpy(dest, src, init_image_size); std::memset(dest + init_image_size, 0, module->tls.image_size - init_image_size); @@ -334,7 +338,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { thread_local std::once_flag init_tls_flag; -void Linker::EnsureThreadInitialized(bool is_primary) { +void Linker::EnsureThreadInitialized(bool is_primary) const { std::call_once(init_tls_flag, [this, is_primary] { #ifdef ARCH_X86_64 InitializeThreadPatchStack(); @@ -343,7 +347,7 @@ void Linker::EnsureThreadInitialized(bool is_primary) { }); } -void Linker::InitTlsForThread(bool is_primary) { +void Linker::InitTlsForThread(bool is_primary) const { static constexpr size_t TcbSize = 0x40; static constexpr size_t TlsAllocAlign = 0x20; const size_t total_tls_size = Common::AlignUp(static_tls_size, TlsAllocAlign) + TcbSize; @@ -365,7 +369,7 @@ void Linker::InitTlsForThread(bool is_primary) { } else { if (heap_api) { #ifndef WIN32 - addr_out = heap_api->heap_malloc(total_tls_size); + addr_out = ExecuteGuestWithoutTls(heap_api->heap_malloc, total_tls_size); } else { addr_out = std::malloc(total_tls_size); #else diff --git a/src/core/linker.h b/src/core/linker.h index 18454f60..fe1278d0 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -109,16 +109,23 @@ public: void DebugDump(); template - ReturnType ExecuteGuest(PS4_SYSV_ABI ReturnType (*func)(FuncArgs...), CallArgs&&... args) { + ReturnType ExecuteGuest(PS4_SYSV_ABI ReturnType (*func)(FuncArgs...), + CallArgs&&... args) const { // Make sure TLS is initialized for the thread before entering guest. EnsureThreadInitialized(); - return func(std::forward(args)...); + return ExecuteGuestWithoutTls(func, args...); } private: const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l); - void EnsureThreadInitialized(bool is_primary = false); - void InitTlsForThread(bool is_primary); + void EnsureThreadInitialized(bool is_primary = false) const; + void InitTlsForThread(bool is_primary) const; + + template + ReturnType ExecuteGuestWithoutTls(PS4_SYSV_ABI ReturnType (*func)(FuncArgs...), + CallArgs&&... args) const { + return func(std::forward(args)...); + } MemoryManager* memory; std::mutex mutex; diff --git a/src/core/module.cpp b/src/core/module.cpp index e62c5778..5d3b4057 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -70,7 +70,7 @@ Module::~Module() = default; s32 Module::Start(size_t args, const void* argp, void* param) { LOG_INFO(Core_Linker, "Module started : {}", name); - auto* linker = Common::Singleton::Instance(); + const auto* linker = Common::Singleton::Instance(); const VAddr addr = dynamic_info.init_virtual_addr + GetBaseAddress(); return linker->ExecuteGuest(reinterpret_cast(addr), args, argp, param); }