Skip to content

Commit

Permalink
core: Add wrapper for calling into guest code.
Browse files Browse the repository at this point in the history
  • Loading branch information
squidbus committed Sep 23, 2024
1 parent ad9f137 commit 193e55b
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 35 deletions.
27 changes: 14 additions & 13 deletions src/core/libraries/avplayer/avplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,20 @@ struct SceAvPlayerFileReplacement {
SceAvPlayerSizeFile size;
};

typedef void PS4_SYSV_ABI (*SceAvPlayerEventCallback)(void* p, s32 event, s32 src_id, void* data);
enum SceAvPlayerEvents {
SCE_AVPLAYER_STATE_STOP = 0x01,
SCE_AVPLAYER_STATE_READY = 0x02,
SCE_AVPLAYER_STATE_PLAY = 0x03,
SCE_AVPLAYER_STATE_PAUSE = 0x04,
SCE_AVPLAYER_STATE_BUFFERING = 0x05,
SCE_AVPLAYER_TIMED_TEXT_DELIVERY = 0x10,
SCE_AVPLAYER_WARNING_ID = 0x20,
SCE_AVPLAYER_ENCRYPTION = 0x30,
SCE_AVPLAYER_DRM_ERROR = 0x40
};

typedef void PS4_SYSV_ABI (*SceAvPlayerEventCallback)(void* p, SceAvPlayerEvents event, s32 src_id,
void* data);

struct SceAvPlayerEventReplacement {
void* object_ptr;
Expand Down Expand Up @@ -275,18 +288,6 @@ enum SceAvPlayerAvSyncMode {

typedef int PS4_SYSV_ABI (*SceAvPlayerLogCallback)(void* p, const char* format, va_list args);

enum SceAvPlayerEvents {
SCE_AVPLAYER_STATE_STOP = 0x01,
SCE_AVPLAYER_STATE_READY = 0x02,
SCE_AVPLAYER_STATE_PLAY = 0x03,
SCE_AVPLAYER_STATE_PAUSE = 0x04,
SCE_AVPLAYER_STATE_BUFFERING = 0x05,
SCE_AVPLAYER_TIMED_TEXT_DELIVERY = 0x10,
SCE_AVPLAYER_WARNING_ID = 0x20,
SCE_AVPLAYER_ENCRYPTION = 0x30,
SCE_AVPLAYER_DRM_ERROR = 0x40
};

void RegisterlibSceAvPlayer(Core::Loader::SymbolsResolver* sym);

} // namespace Libraries::AvPlayer
13 changes: 8 additions & 5 deletions src/core/libraries/avplayer/avplayer_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
#include "avplayer_source.h"
#include "avplayer_state.h"

#include "common/singleton.h"
#include "common/thread.h"

#include "core/libraries/error_codes.h"
#include "core/libraries/kernel/time_management.h"
#include "core/linker.h"

#include <magic_enum.hpp>

namespace Libraries::AvPlayer {

using namespace Kernel;

void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, s32 event_id, s32 source_id,
void* event_data) {
void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, SceAvPlayerEvents event_id,
s32 source_id, void* event_data) {
auto const self = reinterpret_cast<AvPlayerState*>(opaque);

if (event_id == SCE_AVPLAYER_STATE_READY) {
Expand Down Expand Up @@ -90,7 +91,8 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, s32 event_i
const auto callback = self->m_event_replacement.event_callback;
const auto ptr = self->m_event_replacement.object_ptr;
if (callback != nullptr) {
callback(ptr, event_id, 0, event_data);
auto* linker = Common::Singleton<Core::Linker>::Instance();
linker->ExecuteGuest(callback, ptr, event_id, 0, event_data);
}
}

Expand Down Expand Up @@ -365,7 +367,8 @@ 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;
callback(ptr, event_id, 0, event_data);
auto* linker = Common::Singleton<Core::Linker>::Instance();
linker->ExecuteGuest(callback, ptr, event_id, 0, event_data);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/libraries/avplayer/avplayer_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class AvPlayerState : public AvPlayerStateCallback {

private:
// Event Replacement
static void PS4_SYSV_ABI AutoPlayEventCallback(void* handle, s32 event_id, s32 source_id,
void* event_data);
static void PS4_SYSV_ABI AutoPlayEventCallback(void* handle, SceAvPlayerEvents event_id,
s32 source_id, void* event_data);

void OnWarning(u32 id) override;
void OnError() override;
Expand Down
8 changes: 1 addition & 7 deletions src/core/libraries/kernel/thread_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
#include <thread>

#include "common/alignment.h"
#include "common/arch.h"
#include "common/assert.h"
#include "common/error.h"
#include "common/logging/log.h"
#include "common/singleton.h"
#include "common/thread.h"
#include "core/cpu_patches.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/kernel/libkernel.h"
#include "core/libraries/kernel/thread_management.h"
Expand Down Expand Up @@ -991,16 +989,12 @@ static void cleanup_thread(void* arg) {
static void* run_thread(void* arg) {
auto* thread = static_cast<ScePthread>(arg);
Common::SetCurrentThreadName(thread->name.c_str());
#ifdef ARCH_X86_64
Core::InitializeThreadPatchStack();
#endif
auto* linker = Common::Singleton<Core::Linker>::Instance();
linker->InitTlsForThread(false);
void* ret = nullptr;
g_pthread_self = thread;
pthread_cleanup_push(cleanup_thread, thread);
thread->is_started = true;
ret = thread->entry(thread->arg);
ret = linker->ExecuteGuest(thread->entry, thread->arg);
pthread_cleanup_pop(1);
return ret;
}
Expand Down
10 changes: 8 additions & 2 deletions src/core/libraries/network/net_ctl_obj.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "common/singleton.h"
#include "core/linker.h"
#include "net_ctl_codes.h"
#include "net_ctl_obj.h"

Expand Down Expand Up @@ -57,18 +59,22 @@ s32 Libraries::NetCtl::NetCtlInternal::registerNpToolkitCallback(

void Libraries::NetCtl::NetCtlInternal::checkCallback() {
std::unique_lock lock{m_mutex};
auto* linker = Common::Singleton<Core::Linker>::Instance();
for (auto& callback : callbacks) {
if (callback.func != nullptr) {
callback.func(ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, callback.arg);
linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED,
callback.arg);
}
}
}

void Libraries::NetCtl::NetCtlInternal::checkNpToolkitCallback() {
std::unique_lock lock{m_mutex};
auto* linker = Common::Singleton<Core::Linker>::Instance();
for (auto& callback : nptoolCallbacks) {
if (callback.func != nullptr) {
callback.func(ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, callback.arg);
linker->ExecuteGuest(callback.func, ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED,
callback.arg);
}
}
}
16 changes: 12 additions & 4 deletions src/core/linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,8 @@ void Linker::Execute() {

// Init primary thread.
Common::SetCurrentThreadName("GAME_MainThread");
#ifdef ARCH_X86_64
InitializeThreadPatchStack();
#endif
Libraries::Kernel::pthreadInitSelfMainThread();
InitTlsForThread(true);
EnsureThreadInitialized(true);

// Start shared library modules
for (auto& m : m_modules) {
Expand Down Expand Up @@ -335,6 +332,17 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) {
return addr + offset;
}

thread_local std::once_flag init_tls_flag;

void Linker::EnsureThreadInitialized(bool is_primary) {
std::call_once(init_tls_flag, [this, is_primary] {
#ifdef ARCH_X86_64
InitializeThreadPatchStack();
#endif
InitTlsForThread(is_primary);
});
}

void Linker::InitTlsForThread(bool is_primary) {
static constexpr size_t TcbSize = 0x40;
static constexpr size_t TlsAllocAlign = 0x20;
Expand Down
10 changes: 9 additions & 1 deletion src/core/linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ class Linker {
}

void* TlsGetAddr(u64 module_index, u64 offset);
void InitTlsForThread(bool is_primary = false);

s32 LoadModule(const std::filesystem::path& elf_name, bool is_dynamic = false);
Module* FindByAddress(VAddr address);
Expand All @@ -109,8 +108,17 @@ class Linker {
void Execute();
void DebugDump();

template <class ReturnType, class... FuncArgs, class... CallArgs>
ReturnType ExecuteGuest(PS4_SYSV_ABI ReturnType (*func)(FuncArgs...), CallArgs&&... args) {
// Make sure TLS is initialized for the thread before entering guest.
EnsureThreadInitialized();
return func(std::forward<CallArgs>(args)...);
}

private:
const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l);
void EnsureThreadInitialized(bool is_primary = false);
void InitTlsForThread(bool is_primary);

MemoryManager* memory;
std::mutex mutex;
Expand Down
4 changes: 3 additions & 1 deletion src/core/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#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"
Expand Down Expand Up @@ -69,8 +70,9 @@ 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<Core::Linker>::Instance();
const VAddr addr = dynamic_info.init_virtual_addr + GetBaseAddress();
return reinterpret_cast<EntryFunc>(addr)(args, argp, param);
return linker->ExecuteGuest(reinterpret_cast<EntryFunc>(addr), args, argp, param);
}

void Module::LoadModuleToMemory(u32& max_tls_index) {
Expand Down

0 comments on commit 193e55b

Please sign in to comment.