diff --git a/CMakeLists.txt b/CMakeLists.txt index b07dcea87d8..914e25e4058 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -571,6 +571,9 @@ set(FIBER_LIB src/core/libraries/fiber/fiber_context.s ) set_source_files_properties(src/core/libraries/fiber/fiber_context.s PROPERTIES COMPILE_OPTIONS -Wno-unused-command-line-argument) +if(APPLE) + set_source_files_properties(src/core/libraries/fiber/fiber.cpp PROPERTIES COMPILE_OPTIONS -fno-lto) +endif() set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp src/core/libraries/videodec/videodec2_impl.h diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 9a3fe0aa106..0f34e2c07c4 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -142,6 +142,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Vdec2) \ SUB(Lib, Videodec) \ SUB(Lib, RazorCpu) \ + SUB(Lib, Ulobjmgr) \ SUB(Lib, Mouse) \ SUB(Lib, WebBrowserDialog) \ SUB(Lib, NpParty) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index 9e176c698a5..7ce844728ce 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -109,6 +109,7 @@ enum class Class : u8 { Lib_Videodec, ///< The LibSceVideodec implementation. Lib_Voice, ///< The LibSceVoice implementation. Lib_RazorCpu, ///< The LibRazorCpu implementation. + Lib_Ulobjmgr, ///< The ulobjmgr implementation. Lib_Mouse, ///< The LibSceMouse implementation Lib_WebBrowserDialog, ///< The LibSceWebBrowserDialog implementation Lib_NpParty, ///< The LibSceNpParty implementation diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 2ebfbd24491..a201ac72240 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -6,18 +6,285 @@ #include "common/elf_info.h" #include "common/logging/log.h" #include "core/libraries/fiber/fiber_error.h" +#include "core/libraries/kernel/memory.h" +#include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" +#include "core/libraries/razor_cpu/razor_cpu.h" +#include "core/libraries/system/sysmodule.h" +#include "core/libraries/ulobjmgr/ulobjmgr.h" #include "core/tls.h" +#include +#include +#include +#if defined(_MSC_VER) +#include +#endif + namespace Libraries::Fiber { static constexpr u32 kFiberSignature0 = 0xdef1649c; static constexpr u32 kFiberSignature1 = 0xb37592a0; static constexpr u32 kFiberOptSignature = 0xbb40e64d; +static constexpr u64 kFiberEntryXor = 0xca953a6953c56aa5; +static constexpr u64 kFiberArgInitXor = 0xa356a3569c95ca5a; +static constexpr u32 kFiberRazorIdXor = 0x5a4c69a5; +static constexpr u64 kFiberSwitchCookieInit = 0xa5a569695c5c5a5a; static constexpr u64 kFiberStackSignature = 0x7149f2ca7149f2ca; static constexpr u64 kFiberStackSizeCheck = 0xdeadbeefdeadbeef; +static constexpr u64 kFiberNameSeedInit = 0x1234567812345678; +static constexpr u64 kFiberNameSeedMul = 0xfedcba89fedcba89; +static constexpr u64 kFiberNameSeedAdd = 0x9182736591827365; + +static constexpr u8 kFiberNameXorTable[ORBIS_FIBER_MAX_NAME_LENGTH + 1] = { + 0x5a, 0x5a, 0x66, 0x66, 0x99, 0x99, 0x66, 0x96, 0x99, 0x66, 0x99, 0x96, 0x33, 0x33, 0xcc, 0xcc, + 0x33, 0xc3, 0xcc, 0x33, 0xcc, 0xc3, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0xa5, 0xaa, 0x55, 0xaa, 0xa5, +}; static std::atomic context_size_check = false; +static std::atomic name_seed = kFiberNameSeedInit; +static std::atomic fiber_globals_init = false; +static std::atomic razor_enabled = false; +static std::atomic asan_enabled = false; +static std::atomic switch_cookie_counter = 0; + +static u64 PthreadSelf() { + auto* thread = ::Libraries::Kernel::posix_pthread_self(); + return reinterpret_cast(thread); +} + +static void GetThreadStack(void** stack_addr, size_t* stack_size) { + if (!stack_addr || !stack_size) { + return; + } + + auto* thread = ::Libraries::Kernel::g_curthread; + if (!thread) { + *stack_addr = nullptr; + *stack_size = 0; + return; + } + + *stack_addr = thread->attr.stackaddr_attr; + *stack_size = thread->attr.stacksize_attr; +} + +static void RazorCpuFiberSwitch(u32 from_id, u32 to_id, u32 reason) { + (void)from_id; + (void)to_id; + (void)reason; + ::Libraries::RazorCpu::sceRazorCpuFiberSwitch(); +} + +static void RazorCpuFiberLogNameChange(OrbisFiber* fiber, const char* name) { + (void)fiber; + (void)name; + ::Libraries::RazorCpu::sceRazorCpuFiberLogNameChange(); +} + +static s32 UlobjmgrRegister(u64 arg0, s32 arg1, u32* arg2) { + return ::Libraries::Ulobjmgr::Func_046DBA8411A2365C(arg0, arg1, arg2); +} + +static s32 UlobjmgrUnregister(u32 arg0) { + return ::Libraries::Ulobjmgr::Func_4A67FE7D435B94F7(arg0); +} + +extern "C" { +void PS4_SYSV_ABI __sanitizer_start_switch_fiber(void** fake_stack_save, const void* stack_addr, + size_t stack_size); +void PS4_SYSV_ABI __sanitizer_finish_switch_fiber(void* fake_stack_save, + const void** old_stack_addr, + size_t* old_stack_size); +void PS4_SYSV_ABI __asan_destroy_fake_stack(); +} // extern "C" + +extern "C" void PS4_SYSV_ABI __sanitizer_start_switch_fiber(void** fake_stack_save, + const void* stack_addr, + size_t stack_size) { + (void)fake_stack_save; + (void)stack_addr; + (void)stack_size; +} + +extern "C" void PS4_SYSV_ABI __sanitizer_finish_switch_fiber(void* fake_stack_save, + const void** old_stack_addr, + size_t* old_stack_size) { + (void)fake_stack_save; + (void)old_stack_addr; + (void)old_stack_size; +} + +extern "C" void PS4_SYSV_ABI __asan_destroy_fake_stack() {} + +#if defined(__APPLE__) +extern "C" void PS4_SYSV_ABI __sanitizer_start_switch_fiber_macho(void** fake_stack_save, + const void* stack_addr, + size_t stack_size) + __attribute__((used, externally_visible, + visibility("default"))) asm("__sanitizer_start_switch_fiber"); +extern "C" void PS4_SYSV_ABI __sanitizer_finish_switch_fiber_macho(void* fake_stack_save, + const void** old_stack_addr, + size_t* old_stack_size) + __attribute__((used, externally_visible, + visibility("default"))) asm("__sanitizer_finish_switch_fiber"); +extern "C" void PS4_SYSV_ABI __asan_destroy_fake_stack_macho(void) + __attribute__((used, externally_visible, + visibility("default"))) asm("__asan_destroy_fake_stack"); + +extern "C" void PS4_SYSV_ABI __sanitizer_start_switch_fiber_macho(void** fake_stack_save, + const void* stack_addr, + size_t stack_size) { + __sanitizer_start_switch_fiber(fake_stack_save, stack_addr, stack_size); +} + +extern "C" void PS4_SYSV_ABI __sanitizer_finish_switch_fiber_macho(void* fake_stack_save, + const void** old_stack_addr, + size_t* old_stack_size) { + __sanitizer_finish_switch_fiber(fake_stack_save, old_stack_addr, old_stack_size); +} + +extern "C" void PS4_SYSV_ABI __asan_destroy_fake_stack_macho(void) { + __asan_destroy_fake_stack(); +} +#endif + +static void EnsureFiberGlobalsInitialized() { + u32 expected = 0; + if (fiber_globals_init.compare_exchange_strong(expected, 1u, std::memory_order_relaxed)) { + const auto razor_loaded = ::Libraries::SysModule::sceSysmoduleIsLoadedInternal( + ::Libraries::SysModule::OrbisSysModuleInternal::ORBIS_SYSMODULE_INTERNAL_RAZOR_CPU); + razor_enabled.store(razor_loaded == 0 ? 1u : 0u, std::memory_order_relaxed); + asan_enabled.store(::Libraries::Kernel::sceKernelIsAddressSanitizerEnabled() != 0 ? 1u : 0u, + std::memory_order_relaxed); + } +} + +static bool RazorEnabled() { + EnsureFiberGlobalsInitialized(); + return razor_enabled.load(std::memory_order_relaxed) != 0; +} + +static bool AsanEnabled() { + EnsureFiberGlobalsInitialized(); + return asan_enabled.load(std::memory_order_relaxed) != 0; +} + +static void UpdateSwitchCookie(OrbisFiber* fiber) { + const u64 value = switch_cookie_counter.fetch_add(1, std::memory_order_relaxed) + 1; + fiber->switch_cookie = value ^ kFiberSwitchCookieInit; +} + +static u64 ComputeContextSizeMargin(const OrbisFiber* fiber) { + if (!fiber || !fiber->context_start || !fiber->context_end) { + return 0; + } + + u64* stack_start = reinterpret_cast(fiber->context_start); + u64* stack_end = reinterpret_cast(fiber->context_end); + if (stack_start >= stack_end) { + return 0; + } + + u64* stack_ptr = stack_start + 1; + while (stack_ptr < stack_end && *stack_ptr == kFiberStackSizeCheck) { + ++stack_ptr; + } + + return reinterpret_cast(stack_ptr) - reinterpret_cast(stack_start + 1); +} + +static u64 NextNameSeed() { + u64 seed = name_seed.load(std::memory_order_relaxed); + u64 next = 0; + do { + next = seed * kFiberNameSeedMul + kFiberNameSeedAdd; + } while (!name_seed.compare_exchange_weak(seed, next, std::memory_order_relaxed)); + return next; +} + +static void FillFiberRandomPad(OrbisFiber* fiber) { + if (!fiber) { + return; + } + + constexpr size_t kRandomPadWords = 0x78 / sizeof(u64); + u64 values[kRandomPadWords]{}; + for (size_t i = 0; i < kRandomPadWords; ++i) { + values[i] = NextNameSeed(); + } + std::memcpy(fiber->random_pad, values, sizeof(values)); +} + +static void EncodeFiberName(OrbisFiber* fiber, const char* name) { + if (!fiber) { + return; + } + + u64 seed_values[4] = {NextNameSeed(), NextNameSeed(), NextNameSeed(), NextNameSeed()}; + std::memcpy(fiber->name_xor, seed_values, sizeof(seed_values)); + + if (!name) { + fiber->name_xor[0] = kFiberNameXorTable[0]; + return; + } + + for (u32 i = 0; i < ORBIS_FIBER_MAX_NAME_LENGTH; ++i) { + const u8 value = static_cast(name[i]); + if (value == 0) { + fiber->name_xor[i] = kFiberNameXorTable[i]; + return; + } + fiber->name_xor[i] = value ^ kFiberNameXorTable[i]; + } + + fiber->name_xor[ORBIS_FIBER_MAX_NAME_LENGTH] = 0xa5; +} + +static void DecodeFiberName(const OrbisFiber* fiber, char* out, size_t out_size) { + if (!fiber || !out || out_size < ORBIS_FIBER_MAX_NAME_LENGTH + 1) { + return; + } + + for (u32 i = 0; i < ORBIS_FIBER_MAX_NAME_LENGTH; ++i) { + const u8 value = fiber->name_xor[i] ^ kFiberNameXorTable[i]; + out[i] = static_cast(value); + if (value == 0) { + std::memset(out + i + 1, 0, ORBIS_FIBER_MAX_NAME_LENGTH - i); + return; + } + } + + out[ORBIS_FIBER_MAX_NAME_LENGTH] = '\0'; +} + +static OrbisFiberEntry DecodeEntry(const OrbisFiber* fiber) { + return reinterpret_cast(fiber->entry_xor ^ kFiberEntryXor); +} + +static void EncodeEntry(OrbisFiber* fiber, OrbisFiberEntry entry) { + fiber->entry_xor = reinterpret_cast(entry) ^ kFiberEntryXor; +} + +static u64 DecodeArgOnInitialize(const OrbisFiber* fiber) { + return fiber->arg_on_initialize_xor ^ kFiberArgInitXor; +} + +static void EncodeArgOnInitialize(OrbisFiber* fiber, u64 arg_on_initialize) { + fiber->arg_on_initialize_xor = arg_on_initialize ^ kFiberArgInitXor; +} + +static bool TryTransitionFiberState(OrbisFiber* fiber, FiberState expected, FiberState desired) { + std::atomic_ref state_ref(fiber->state); + u32 expected_value = static_cast(expected); + return state_ref.compare_exchange_strong(expected_value, static_cast(desired), + std::memory_order_seq_cst); +} + +static void StoreFiberState(OrbisFiber* fiber, FiberState value) { + std::atomic_ref state_ref(fiber->state); + state_ref.store(static_cast(value), std::memory_order_seq_cst); +} OrbisFiberContext* GetFiberContext() { return Core::GetTcbBase()->tcb_fiber; @@ -36,9 +303,26 @@ extern "C" void PS4_SYSV_ABI _sceFiberForceQuit(u64 ret) { } void PS4_SYSV_ABI _sceFiberCheckStackOverflow(OrbisFiberContext* ctx) { - u64* stack_base = reinterpret_cast(ctx->current_fiber->addr_context); - u64 stack_size = ctx->current_fiber->size_context; + OrbisFiber* fiber = ctx->current_fiber; + u64* stack_base = reinterpret_cast(fiber->addr_context); + u64 stack_size = fiber->size_context; if (stack_base && *stack_base != kFiberStackSignature) { + char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1]{}; + DecodeFiberName(fiber, name, sizeof(name)); + + const uintptr_t stack_base_addr = reinterpret_cast(stack_base); + const uintptr_t stack_top_addr = stack_base_addr + static_cast(stack_size); + LOG_CRITICAL( + Lib_Fiber, + "Fiber stack overflow: name='{}' fiber={:#x} ctx={:#x} stack_base={:#x} " + "stack_top={:#x} size=0x{:x} sig={:#x} expected={:#x} context_start={:#x} " + "context_end={:#x} flags=0x{:x} state=0x{:x} switch_cookie={:#x} magic_start=0x{:x} " + "magic_end=0x{:x}", + name, reinterpret_cast(fiber), reinterpret_cast(ctx), + stack_base_addr, stack_top_addr, stack_size, *stack_base, kFiberStackSignature, + reinterpret_cast(fiber->context_start), + reinterpret_cast(fiber->context_end), fiber->flags, fiber->state, + fiber->switch_cookie, fiber->magic_start, fiber->magic_end); UNREACHABLE_MSG("Stack overflow detected in fiber with size = 0x{:x}", stack_size); } } @@ -64,6 +348,11 @@ s32 PS4_SYSV_ABI _sceFiberAttachContext(OrbisFiber* fiber, void* addr_context, u /* Apply signature to start of stack */ *(u64*)addr_context = kFiberStackSignature; + LOG_INFO( + Lib_Fiber, + "Fiber attach context: fiber={:#x} addr_context={:#x} size=0x{:x} sig={:#x} flags=0x{:x}", + reinterpret_cast(fiber), reinterpret_cast(addr_context), size_context, + *(u64*)addr_context, fiber->flags); if (fiber->flags & FiberFlags::ContextSizeCheck) { u64* stack_start = reinterpret_cast(fiber->context_start); @@ -79,7 +368,7 @@ s32 PS4_SYSV_ABI _sceFiberAttachContext(OrbisFiber* fiber, void* addr_context, u } void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to, - OrbisFiberContext* ctx) { + OrbisFiberContext* ctx, u64 asan_cookie) { OrbisFiberContext* fiber_ctx = fiber->context; if (fiber_ctx) { ctx->arg_on_run_to = arg_on_run_to; @@ -96,52 +385,53 @@ void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to, data.state = nullptr; } - data.entry = fiber->entry; - data.arg_on_initialize = fiber->arg_on_initialize; + data.entry = DecodeEntry(fiber); + data.arg_on_initialize = DecodeArgOnInitialize(fiber); data.arg_on_run_to = arg_on_run_to; data.stack_addr = reinterpret_cast(fiber->addr_context) + fiber->size_context; - if (fiber->flags & FiberFlags::SetFpuRegs) { - data.fpucw = 0x037f; - data.mxcsr = 0x9fc0; - _sceFiberSwitchEntry(&data, true); - } else { - _sceFiberSwitchEntry(&data, false); - } + data.asan_fake_stack = reinterpret_cast(asan_cookie); + _sceFiberSwitchEntry(&data, (fiber->flags & FiberFlags::SetFpuRegs) != 0); __builtin_trap(); } void PS4_SYSV_ABI _sceFiberSwitch(OrbisFiber* cur_fiber, OrbisFiber* fiber, u64 arg_on_run_to, - OrbisFiberContext* ctx) { + OrbisFiberContext* ctx, u64 asan_cookie) { + UpdateSwitchCookie(cur_fiber); ctx->prev_fiber = cur_fiber; ctx->current_fiber = fiber; + if (RazorEnabled()) { + RazorCpuFiberSwitch(static_cast(reinterpret_cast(cur_fiber)), + static_cast(reinterpret_cast(fiber)), 1); + } + if (fiber->addr_context == nullptr) { ctx->prev_fiber = nullptr; OrbisFiberData data{}; - data.entry = fiber->entry; - data.arg_on_initialize = fiber->arg_on_initialize; + data.entry = DecodeEntry(fiber); + data.arg_on_initialize = DecodeArgOnInitialize(fiber); data.arg_on_run_to = arg_on_run_to; - data.stack_addr = reinterpret_cast(ctx->rsp & ~15); + data.stack_addr = reinterpret_cast(ctx->jmp.rsp & ~15); data.state = reinterpret_cast(&cur_fiber->state); - - if (fiber->flags & FiberFlags::SetFpuRegs) { - data.fpucw = 0x037f; - data.mxcsr = 0x9fc0; - _sceFiberSwitchEntry(&data, true); + if (asan_cookie != 0) { + data.asan_fake_stack = + reinterpret_cast(reinterpret_cast(fiber->asan_fake_stack) + 1); } else { - _sceFiberSwitchEntry(&data, false); + data.asan_fake_stack = nullptr; } + _sceFiberSwitchEntry(&data, (fiber->flags & FiberFlags::SetFpuRegs) != 0); __builtin_trap(); } - _sceFiberSwitchToFiber(fiber, arg_on_run_to, ctx); + _sceFiberSwitchToFiber(fiber, arg_on_run_to, ctx, asan_cookie); __builtin_trap(); } void PS4_SYSV_ABI _sceFiberTerminate(OrbisFiber* fiber, u64 arg_on_return, OrbisFiberContext* ctx) { + UpdateSwitchCookie(fiber); ctx->arg_on_return = arg_on_return; _sceFiberLongJmp(ctx); __builtin_trap(); @@ -151,6 +441,7 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb u64 arg_on_initialize, void* addr_context, u64 size_context, const OrbisFiberOptParam* opt_param, u32 flags, u32 build_ver) { + EnsureFiberGlobalsInitialized(); if (!fiber || !name || !entry) { return ORBIS_FIBER_ERROR_NULL; } @@ -172,6 +463,9 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb if (addr_context && !size_context) { return ORBIS_FIBER_ERROR_INVALID; } + if (size_context && size_context <= 4096) { + LOG_WARNING(Lib_Fiber, "Fiber initialized with small stack area."); + } if (opt_param && opt_param->magic != kFiberOptSignature) { return ORBIS_FIBER_ERROR_INVALID; } @@ -180,26 +474,25 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb if (build_ver >= Common::ElfInfo::FW_35) { user_flags |= FiberFlags::SetFpuRegs; } - if (context_size_check) { + if (context_size_check.load(std::memory_order_relaxed) != 0) { user_flags |= FiberFlags::ContextSizeCheck; } - strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH); - - fiber->entry = entry; - fiber->arg_on_initialize = arg_on_initialize; + FillFiberRandomPad(fiber); + EncodeFiberName(fiber, name); + EncodeEntry(fiber, entry); + EncodeArgOnInitialize(fiber, arg_on_initialize); fiber->addr_context = addr_context; fiber->size_context = size_context; fiber->context = nullptr; + fiber->owner_thread = 0; fiber->flags = user_flags; - - /* - A low stack area is problematic, as we can easily - cause a stack overflow with our HLE. - */ - if (size_context && size_context <= 4096) { - LOG_WARNING(Lib_Fiber, "Fiber initialized with small stack area."); - } + fiber->razor_id_xor = 0; + fiber->switch_cookie = kFiberSwitchCookieInit; + fiber->asan_fake_stack = nullptr; + fiber->context_start = nullptr; + fiber->context_end = nullptr; + fiber->reserved = 0; fiber->magic_start = kFiberSignature0; fiber->magic_end = kFiberSignature1; @@ -210,8 +503,14 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb /* Apply signature to start of stack */ *(u64*)addr_context = kFiberStackSignature; - - if (flags & FiberFlags::ContextSizeCheck) { + LOG_INFO(Lib_Fiber, + "Fiber init context: fiber={:#x} name='{}' addr_context={:#x} size=0x{:x} " + "sig={:#x} flags=0x{:x}", + reinterpret_cast(fiber), name, + reinterpret_cast(addr_context), size_context, *(u64*)addr_context, + fiber->flags); + + if (fiber->flags & FiberFlags::ContextSizeCheck) { u64* stack_start = reinterpret_cast(fiber->context_start); u64* stack_end = reinterpret_cast(fiber->context_end); @@ -222,7 +521,17 @@ s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, Orb } } - fiber->state = FiberState::Idle; + StoreFiberState(fiber, FiberState::Idle); + if ((fiber->flags & FiberFlags::NoUlobjmgr) == 0) { + LOG_DEBUG(Lib_Fiber, "Ulobjmgr register: fiber={:#x} flags=0x{:x}", + reinterpret_cast(fiber), fiber->flags); + u32 razor_id = 0; + UlobjmgrRegister(reinterpret_cast(fiber), 1, &razor_id); + fiber->razor_id_xor = razor_id ^ kFiberRazorIdXor; + } else { + LOG_DEBUG(Lib_Fiber, "Ulobjmgr register skipped (NoUlobjmgr): fiber={:#x} flags=0x{:x}", + reinterpret_cast(fiber), fiber->flags); + } return ORBIS_OK; } @@ -234,11 +543,13 @@ s32 PS4_SYSV_ABI sceFiberOptParamInitialize(OrbisFiberOptParam* opt_param) { return ORBIS_FIBER_ERROR_ALIGNMENT; } + std::memset(opt_param, 0, sizeof(*opt_param)); opt_param->magic = kFiberOptSignature; return ORBIS_OK; } s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber) { + EnsureFiberGlobalsInitialized(); if (!fiber) { return ORBIS_FIBER_ERROR_NULL; } @@ -249,16 +560,33 @@ s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber) { return ORBIS_FIBER_ERROR_INVALID; } - FiberState expected = FiberState::Idle; - if (!fiber->state.compare_exchange_strong(expected, FiberState::Terminated)) { + if (!TryTransitionFiberState(fiber, FiberState::Idle, FiberState::Terminated)) { return ORBIS_FIBER_ERROR_STATE; } + if (RazorEnabled()) { + char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1]{}; + DecodeFiberName(fiber, name, sizeof(name)); + RazorCpuFiberLogNameChange(fiber, name); + } + if ((fiber->flags & FiberFlags::NoUlobjmgr) == 0) { + LOG_DEBUG(Lib_Fiber, "Ulobjmgr unregister: fiber={:#x} flags=0x{:x}", + reinterpret_cast(fiber), fiber->flags); + UlobjmgrUnregister(fiber->razor_id_xor ^ kFiberRazorIdXor); + } else { + LOG_DEBUG(Lib_Fiber, "Ulobjmgr unregister skipped (NoUlobjmgr): fiber={:#x} flags=0x{:x}", + reinterpret_cast(fiber), fiber->flags); + } + if (AsanEnabled() && fiber->asan_fake_stack != nullptr && fiber->addr_context != nullptr) { + __asan_destroy_fake_stack(); + fiber->asan_fake_stack = nullptr; + } return ORBIS_OK; } s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size_context, u64 arg_on_run_to, u64* arg_on_return) { + EnsureFiberGlobalsInitialized(); if (!fiber) { return ORBIS_FIBER_ERROR_NULL; } @@ -274,51 +602,87 @@ s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size return ORBIS_FIBER_ERROR_PERMISSION; } + const bool attach_context = (addr_context != nullptr || size_context != 0); + if (attach_context) { + if (size_context != 0 && size_context < ORBIS_FIBER_CONTEXT_MINIMUM_SIZE) { + return ORBIS_FIBER_ERROR_RANGE; + } + if (!addr_context || size_context == 0 || (size_context & 15)) { + return ORBIS_FIBER_ERROR_INVALID; + } + if (fiber->addr_context != nullptr) { + return ORBIS_FIBER_ERROR_INVALID; + } + } + + if (!TryTransitionFiberState(fiber, FiberState::Idle, FiberState::Run)) { + return ORBIS_FIBER_ERROR_STATE; + } + /* Caller wants to attach context and run. */ - if (addr_context != nullptr || size_context != 0) { + if (attach_context) { s32 res = _sceFiberAttachContext(fiber, addr_context, size_context); if (res < 0) { return res; } } - FiberState expected = FiberState::Idle; - if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) { - return ORBIS_FIBER_ERROR_STATE; - } + fiber->owner_thread = PthreadSelf(); OrbisFiberContext ctx{}; ctx.current_fiber = fiber; ctx.prev_fiber = nullptr; + ctx.arg_on_run_to = 0; + ctx.arg_on_return = 0; ctx.return_val = 0; + ctx.owner_thread = fiber->owner_thread; + ctx.asan_fake_stack = nullptr; + ctx.reserved0 = 0; + ctx.reserved1 = 0; + ctx.reserved2 = 0xffffffffu; + ctx.reserved3 = 0xffffffffu; tcb->tcb_fiber = &ctx; + if (RazorEnabled()) { + RazorCpuFiberSwitch(0, static_cast(reinterpret_cast(fiber)), 2); + } + + bool asan_switch = false; + if (AsanEnabled() && fiber->addr_context != nullptr) { + __sanitizer_start_switch_fiber(&ctx.asan_fake_stack, fiber->addr_context, + fiber->size_context); + asan_switch = true; + } + s32 jmp = _sceFiberSetJmp(&ctx); if (!jmp) { if (fiber->addr_context) { - _sceFiberSwitchToFiber(fiber, arg_on_run_to, &ctx); + _sceFiberSwitchToFiber(fiber, arg_on_run_to, &ctx, asan_switch ? 1 : 0); __builtin_trap(); } OrbisFiberData data{}; - data.entry = fiber->entry; - data.arg_on_initialize = fiber->arg_on_initialize; + data.entry = DecodeEntry(fiber); + data.arg_on_initialize = DecodeArgOnInitialize(fiber); data.arg_on_run_to = arg_on_run_to; - data.stack_addr = reinterpret_cast(ctx.rsp & ~15); + data.stack_addr = reinterpret_cast(ctx.jmp.rsp & ~15); data.state = nullptr; - if (fiber->flags & FiberFlags::SetFpuRegs) { - data.fpucw = 0x037f; - data.mxcsr = 0x9fc0; - _sceFiberSwitchEntry(&data, true); - } else { - _sceFiberSwitchEntry(&data, false); - } + data.asan_fake_stack = nullptr; + _sceFiberSwitchEntry(&data, (fiber->flags & FiberFlags::SetFpuRegs) != 0); + } + + if (asan_switch) { + __sanitizer_finish_switch_fiber(ctx.asan_fake_stack, nullptr, nullptr); } OrbisFiber* cur_fiber = ctx.current_fiber; ctx.current_fiber = nullptr; - cur_fiber->state = FiberState::Idle; + + if (RazorEnabled()) { + RazorCpuFiberSwitch(static_cast(reinterpret_cast(cur_fiber)), 0, 3); + } + StoreFiberState(cur_fiber, FiberState::Idle); if (ctx.return_val != 0) { /* Fiber entry returned! This should never happen. */ @@ -335,6 +699,7 @@ s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size s32 PS4_SYSV_ABI sceFiberSwitchImpl(OrbisFiber* fiber, void* addr_context, u64 size_context, u64 arg_on_run_to, u64* arg_on_run) { + EnsureFiberGlobalsInitialized(); if (!fiber) { return ORBIS_FIBER_ERROR_NULL; } @@ -350,37 +715,73 @@ s32 PS4_SYSV_ABI sceFiberSwitchImpl(OrbisFiber* fiber, void* addr_context, u64 s return ORBIS_FIBER_ERROR_PERMISSION; } + const bool attach_context = (addr_context != nullptr || size_context != 0); + if (attach_context) { + if (size_context != 0 && size_context < ORBIS_FIBER_CONTEXT_MINIMUM_SIZE) { + return ORBIS_FIBER_ERROR_RANGE; + } + if (!addr_context || size_context == 0 || (size_context & 15)) { + return ORBIS_FIBER_ERROR_INVALID; + } + if (fiber->addr_context != nullptr) { + return ORBIS_FIBER_ERROR_INVALID; + } + } + + if (!TryTransitionFiberState(fiber, FiberState::Idle, FiberState::Run)) { + return ORBIS_FIBER_ERROR_STATE; + } + /* Caller wants to attach context and switch. */ - if (addr_context != nullptr || size_context != 0) { + if (attach_context) { s32 res = _sceFiberAttachContext(fiber, addr_context, size_context); if (res < 0) { return res; } } - FiberState expected = FiberState::Idle; - if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) { - return ORBIS_FIBER_ERROR_STATE; - } + fiber->owner_thread = g_ctx->owner_thread; OrbisFiber* cur_fiber = g_ctx->current_fiber; if (cur_fiber->addr_context == nullptr) { - _sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx); + u64 asan_cookie = 0; + if (AsanEnabled() && fiber->addr_context != nullptr) { + __sanitizer_start_switch_fiber(&cur_fiber->asan_fake_stack, fiber->addr_context, + fiber->size_context); + asan_cookie = 1; + } + _sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx, asan_cookie); __builtin_trap(); } + if (AsanEnabled()) { + void* stack_addr = nullptr; + size_t stack_size = 0; + if (fiber->addr_context == nullptr) { + GetThreadStack(&stack_addr, &stack_size); + } else { + stack_addr = fiber->addr_context; + stack_size = fiber->size_context; + } + __sanitizer_start_switch_fiber(&cur_fiber->asan_fake_stack, stack_addr, stack_size); + } + OrbisFiberContext ctx{}; s32 jmp = _sceFiberSetJmp(&ctx); if (!jmp) { cur_fiber->context = &ctx; _sceFiberCheckStackOverflow(g_ctx); - _sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx); + _sceFiberSwitch(cur_fiber, fiber, arg_on_run_to, g_ctx, AsanEnabled() ? 1 : 0); __builtin_trap(); } + if (AsanEnabled()) { + __sanitizer_finish_switch_fiber(cur_fiber->asan_fake_stack, nullptr, nullptr); + } + g_ctx = GetFiberContext(); if (g_ctx->prev_fiber) { - g_ctx->prev_fiber->state = FiberState::Idle; + StoreFiberState(g_ctx->prev_fiber, FiberState::Idle); g_ctx->prev_fiber = nullptr; } @@ -413,12 +814,22 @@ s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 arg_on_return, u64* arg_on_run) { OrbisFiber* cur_fiber = g_ctx->current_fiber; if (cur_fiber->addr_context) { + if (AsanEnabled()) { + void* stack_addr = nullptr; + size_t stack_size = 0; + GetThreadStack(&stack_addr, &stack_size); + __sanitizer_start_switch_fiber(&cur_fiber->asan_fake_stack, stack_addr, stack_size); + } + OrbisFiberContext ctx{}; s32 jmp = _sceFiberSetJmp(&ctx); if (jmp) { + if (AsanEnabled()) { + __sanitizer_finish_switch_fiber(cur_fiber->asan_fake_stack, nullptr, nullptr); + } g_ctx = GetFiberContext(); if (g_ctx->prev_fiber) { - g_ctx->prev_fiber->state = FiberState::Idle; + StoreFiberState(g_ctx->prev_fiber, FiberState::Idle); g_ctx->prev_fiber = nullptr; } if (arg_on_run) { @@ -449,11 +860,11 @@ s32 PS4_SYSV_ABI sceFiberGetInfo(OrbisFiber* fiber, OrbisFiberInfo* fiber_info) return ORBIS_FIBER_ERROR_INVALID; } - fiber_info->entry = fiber->entry; - fiber_info->arg_on_initialize = fiber->arg_on_initialize; + fiber_info->entry = DecodeEntry(fiber); + fiber_info->arg_on_initialize = DecodeArgOnInitialize(fiber); fiber_info->addr_context = fiber->addr_context; fiber_info->size_context = fiber->size_context; - strncpy(fiber_info->name, fiber->name, ORBIS_FIBER_MAX_NAME_LENGTH); + DecodeFiberName(fiber, fiber_info->name, sizeof(fiber_info->name)); fiber_info->size_context_margin = -1; if (fiber->flags & FiberFlags::ContextSizeCheck && fiber->addr_context != nullptr) { @@ -463,10 +874,8 @@ s32 PS4_SYSV_ABI sceFiberGetInfo(OrbisFiber* fiber, OrbisFiberInfo* fiber_info) if (*stack_start == kFiberStackSignature) { u64* stack_ptr = stack_start + 1; - while (stack_ptr < stack_end) { - if (*stack_ptr == kFiberStackSizeCheck) { - stack_ptr++; - } + while (stack_ptr < stack_end && *stack_ptr == kFiberStackSizeCheck) { + stack_ptr++; } stack_margin = @@ -502,6 +911,7 @@ s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck() { } s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name) { + EnsureFiberGlobalsInitialized(); if (!fiber || !name) { return ORBIS_FIBER_ERROR_NULL; } @@ -512,7 +922,13 @@ s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name) { return ORBIS_FIBER_ERROR_INVALID; } - strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH); + if (RazorEnabled()) { + char old_name[ORBIS_FIBER_MAX_NAME_LENGTH + 1]{}; + DecodeFiberName(fiber, old_name, sizeof(old_name)); + RazorCpuFiberLogNameChange(fiber, old_name); + } + + EncodeFiberName(fiber, name); return ORBIS_OK; } @@ -526,7 +942,7 @@ s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer) { return ORBIS_FIBER_ERROR_PERMISSION; } - *addr_frame_pointer = g_ctx->rbp; + *addr_frame_pointer = g_ctx->jmp.rbp; return ORBIS_OK; } diff --git a/src/core/libraries/fiber/fiber.h b/src/core/libraries/fiber/fiber.h index f52a751b186..46a026b0abe 100644 --- a/src/core/libraries/fiber/fiber.h +++ b/src/core/libraries/fiber/fiber.h @@ -7,6 +7,7 @@ #include "common/types.h" #include +#include namespace Core::Loader { class SymbolsResolver; @@ -33,18 +34,40 @@ enum FiberFlags : u32 { struct OrbisFiber; +struct OrbisFiberJmpBuf { + u64 rsp; // 0x00 + u64 rbp; // 0x08 + u64 ret_addr; // 0x10 + u64 rbx; // 0x18 + u64 r12; // 0x20 + u64 r13; // 0x28 + u64 r14; // 0x30 + u64 r15; // 0x38 + u16 fpucw; // 0x40 + u16 pad0; // 0x42 + u32 mxcsr; // 0x44 +}; +static_assert(sizeof(OrbisFiberJmpBuf) == 0x48); + struct OrbisFiberContext { - struct { - u64 rax, rcx, rdx, rbx, rsp, rbp, r8, r9, r10, r11, r12, r13, r14, r15; - u16 fpucw; - u32 mxcsr; - }; - OrbisFiber* current_fiber; - OrbisFiber* prev_fiber; - u64 arg_on_run_to; - u64 arg_on_return; - u64 return_val; + OrbisFiberJmpBuf jmp; // 0x00 + OrbisFiber* current_fiber; // 0x48 + OrbisFiber* prev_fiber; // 0x50 + u64 arg_on_run_to; // 0x58 + u64 arg_on_return; // 0x60 + u64 return_val; // 0x68 + u64 owner_thread; // 0x70 + void* asan_fake_stack; // 0x78 + u32 reserved0; // 0x80 + u32 reserved1; // 0x84 + u32 reserved2; // 0x88 + u32 reserved3; // 0x8c }; +static_assert(sizeof(OrbisFiberContext) == 0x90); +static_assert(offsetof(OrbisFiberContext, current_fiber) == 0x48); +static_assert(offsetof(OrbisFiberContext, arg_on_run_to) == 0x58); +static_assert(offsetof(OrbisFiberContext, owner_thread) == 0x70); +static_assert(offsetof(OrbisFiberContext, asan_fake_stack) == 0x78); struct OrbisFiberData { OrbisFiberEntry entry; @@ -52,28 +75,36 @@ struct OrbisFiberData { u64 arg_on_run_to; void* stack_addr; u32* state; - u16 fpucw; - s8 pad[2]; - u32 mxcsr; + void* asan_fake_stack; }; - -struct OrbisFiber { - u32 magic_start; - std::atomic state; - OrbisFiberEntry entry; - u64 arg_on_initialize; - void* addr_context; - u64 size_context; - char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1]; - OrbisFiberContext* context; - u32 flags; - void* context_start; - void* context_end; - u32 magic_end; +static_assert(sizeof(OrbisFiberData) == 0x30); + +struct alignas(8) OrbisFiber { + u32 magic_start; // 0x00 + u32 state; // 0x04 + u64 entry_xor; // 0x08 + u64 arg_on_initialize_xor; // 0x10 + void* addr_context; // 0x18 + u64 size_context; // 0x20 + u8 name_xor[ORBIS_FIBER_MAX_NAME_LENGTH + 1]; // 0x28 + OrbisFiberContext* context; // 0x48 + u64 owner_thread; // 0x50 + u32 flags; // 0x58 + u32 razor_id_xor; // 0x5c + u64 switch_cookie; // 0x60 + void* asan_fake_stack; // 0x68 + u8 random_pad[0x78]; // 0x70 + void* context_start; // 0xe8 + void* context_end; // 0xf0 + u32 reserved; // 0xf8 + u32 magic_end; // 0xfc }; -static_assert(sizeof(OrbisFiber) <= 256); +static_assert(sizeof(OrbisFiber) == 0x100); +static_assert(offsetof(OrbisFiber, context_start) == 0xe8); +static_assert(offsetof(OrbisFiber, context_end) == 0xf0); +static_assert(offsetof(OrbisFiber, magic_end) == 0xfc); -struct OrbisFiberInfo { +struct alignas(8) OrbisFiberInfo { u64 size; OrbisFiberEntry entry; u64 arg_on_initialize; @@ -85,10 +116,12 @@ struct OrbisFiberInfo { }; static_assert(sizeof(OrbisFiberInfo) == 128); -struct OrbisFiberOptParam { +struct alignas(8) OrbisFiberOptParam { u32 magic; + u32 option_flags; + u8 reserved[0x80 - 8]; }; -static_assert(sizeof(OrbisFiberOptParam) <= 128); +static_assert(sizeof(OrbisFiberOptParam) == 0x80); s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry, u64 arg_on_initialize, void* addr_context, u64 size_context, @@ -117,4 +150,4 @@ s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name); s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer); void RegisterLib(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Fiber \ No newline at end of file +} // namespace Libraries::Fiber diff --git a/src/core/libraries/fiber/fiber_context.s b/src/core/libraries/fiber/fiber_context.s index 4c8f20f7145..7e3cb33c4f2 100644 --- a/src/core/libraries/fiber/fiber_context.s +++ b/src/core/libraries/fiber/fiber_context.s @@ -3,75 +3,77 @@ .global _sceFiberSetJmp _sceFiberSetJmp: - movq %rax, 0x0(%rdi) + movq %rsp, 0x00(%rdi) + movq %rbp, 0x08(%rdi) - movq (%rsp), %rdx - movq %rdx, 0x10(%rdi) + movq (%rsp), %rax + movq %rax, 0x10(%rdi) - movq %rcx, 0x08(%rdi) movq %rbx, 0x18(%rdi) - movq %rsp, 0x20(%rdi) - movq %rbp, 0x28(%rdi) + movq %r12, 0x20(%rdi) + movq %r13, 0x28(%rdi) + movq %r14, 0x30(%rdi) + movq %r15, 0x38(%rdi) - movq %r8, 0x30(%rdi) - movq %r9, 0x38(%rdi) - movq %r10, 0x40(%rdi) - movq %r11, 0x48(%rdi) - movq %r12, 0x50(%rdi) - movq %r13, 0x58(%rdi) - movq %r14, 0x60(%rdi) - movq %r15, 0x68(%rdi) - - fnstcw 0x70(%rdi) - stmxcsr 0x72(%rdi) + fnstcw 0x40(%rdi) + stmxcsr 0x44(%rdi) xor %eax, %eax ret .global _sceFiberLongJmp _sceFiberLongJmp: - # MXCSR = (MXCSR & 0x3f) ^ (ctx->mxcsr & ~0x3f) - stmxcsr -0x4(%rsp) - movl 0x72(%rdi), %eax - andl $0xffffffc0, %eax - movl -0x4(%rsp), %ecx - andl $0x3f, %ecx - xorl %eax, %ecx - movl %ecx, -0x4(%rsp) - ldmxcsr -0x4(%rsp) - - movq 0x00(%rdi), %rax - movq 0x08(%rdi), %rcx - movq 0x10(%rdi), %rdx - movq 0x18(%rdi), %rbx - movq 0x20(%rdi), %rsp - movq 0x28(%rdi), %rbp - - movq 0x30(%rdi), %r8 - movq 0x38(%rdi), %r9 - movq 0x40(%rdi), %r10 - movq 0x48(%rdi), %r11 - movq 0x50(%rdi), %r12 - movq 0x58(%rdi), %r13 - movq 0x60(%rdi), %r14 - movq 0x68(%rdi), %r15 - - fldcw 0x70(%rdi) - - # Make the jump and return 1 - movq %rdx, 0x00(%rsp) + mov %rdi, %r11 + stmxcsr -4(%rsp) + mov 0x44(%r11), %eax + and $0xffffffc0, %eax + mov -4(%rsp), %ecx + and $0x3f, %ecx + xor %ecx, %eax + mov %eax, -4(%rsp) + ldmxcsr -4(%rsp) + + movq 0x00(%r11), %rsp + movq 0x08(%r11), %rbp + movq 0x10(%r11), %rcx + movq 0x18(%r11), %rbx + movq 0x20(%r11), %r12 + movq 0x28(%r11), %r13 + movq 0x30(%r11), %r14 + movq 0x38(%r11), %r15 + + fldcw 0x40(%r11) + + movq %rcx, 0x00(%rsp) movl $0x1, %eax ret .global _sceFiberSwitchEntry _sceFiberSwitchEntry: mov %rdi, %r11 + mov %esi, %r8d # Set stack address to provided stack movq 0x18(%r11), %rsp xorl %ebp, %ebp + movq 0x28(%r11), %rdi # data->asan_fake_stack + test %rdi, %rdi + jz .skip_asan_finish + dec %rdi + xor %rsi, %rsi + xor %rdx, %rdx + push %r11 + push %r11 + call __sanitizer_finish_switch_fiber + pop %r11 + pop %r11 +.skip_asan_finish: + + movq 0x08(%r11), %rdi # data->arg_on_initialize + movq 0x10(%r11), %rsi # data->arg_on_run_to movq 0x20(%r11), %r10 # data->state + movq 0x00(%r11), %r11 # data->entry # Set previous fiber state to Idle test %r10, %r10 @@ -79,17 +81,13 @@ _sceFiberSwitchEntry: movl $2, (%r10) .clear_regs: - test %esi, %esi + test %r8d, %r8d jz .skip_fpu_regs - ldmxcsr 0x2c(%r11) - fldcw 0x28(%r11) + ldmxcsr kFiberMxcsrDefault(%rip) + fldcw kFiberFpucwDefault(%rip) .skip_fpu_regs: - movq 0x08(%r11), %rdi # data->arg_on_initialize - movq 0x10(%r11), %rsi # data->arg_on_run_to - movq 0x00(%r11), %r11 # data->entry - xorl %eax, %eax xorl %ebx, %ebx xorl %ecx, %ecx @@ -119,3 +117,10 @@ _sceFiberSwitchEntry: movl $1, %edi call _sceFiberForceQuit ret + + .align 4 +kFiberMxcsrDefault: + .long 0x00009fc0 + .align 2 +kFiberFpucwDefault: + .short 0x037f diff --git a/src/core/libraries/kernel/memory.h b/src/core/libraries/kernel/memory.h index 9f78eb84faa..dae6d48e3f9 100644 --- a/src/core/libraries/kernel/memory.h +++ b/src/core/libraries/kernel/memory.h @@ -186,6 +186,8 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolGetBlockStats(OrbisKernelMemoryPoolBlockStat s32 PS4_SYSV_ABI sceKernelMunmap(void* addr, u64 len); +u32 PS4_SYSV_ABI sceKernelIsAddressSanitizerEnabled(); + void RegisterMemory(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index fed3b96fe6b..b25723fdef1 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -352,6 +352,8 @@ using PthreadT = Pthread*; extern thread_local Pthread* g_curthread; +PthreadT PS4_SYSV_ABI posix_pthread_self(); + void RegisterMutex(Core::Loader::SymbolsResolver* sym); void RegisterCond(Core::Loader::SymbolsResolver* sym); void RegisterRwlock(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/razor_cpu/razor_cpu.h b/src/core/libraries/razor_cpu/razor_cpu.h index c8ed3c942fd..a63583efdc9 100644 --- a/src/core/libraries/razor_cpu/razor_cpu.h +++ b/src/core/libraries/razor_cpu/razor_cpu.h @@ -13,5 +13,8 @@ class SymbolsResolver; } namespace Libraries::RazorCpu { +void PS4_SYSV_ABI sceRazorCpuDisableFiberUserMarkers(); +s32 PS4_SYSV_ABI sceRazorCpuFiberLogNameChange(); +s32 PS4_SYSV_ABI sceRazorCpuFiberSwitch(); void RegisterLib(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::RazorCpu \ No newline at end of file +} // namespace Libraries::RazorCpu diff --git a/src/core/libraries/ulobjmgr/ulobjmgr.cpp b/src/core/libraries/ulobjmgr/ulobjmgr.cpp index ff729b3ec8d..9f0d6ba9ce0 100644 --- a/src/core/libraries/ulobjmgr/ulobjmgr.cpp +++ b/src/core/libraries/ulobjmgr/ulobjmgr.cpp @@ -10,6 +10,8 @@ namespace Libraries::Ulobjmgr { s32 PS4_SYSV_ABI Func_046DBA8411A2365C(u64 arg0, s32 arg1, u32* arg2) { + LOG_DEBUG(Lib_Ulobjmgr, "(STUBBED) called arg0={:#x} arg1={} arg2={:#x}", arg0, arg1, + reinterpret_cast(arg2)); if (arg0 == 0 || arg1 == 0 || arg2 == nullptr) { return POSIX_EINVAL; } @@ -18,10 +20,12 @@ s32 PS4_SYSV_ABI Func_046DBA8411A2365C(u64 arg0, s32 arg1, u32* arg2) { } s32 PS4_SYSV_ABI Func_1D9F50D9CFB8054E() { + LOG_DEBUG(Lib_Ulobjmgr, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI Func_4A67FE7D435B94F7(u32 arg0) { + LOG_DEBUG(Lib_Ulobjmgr, "(STUBBED) called arg0={:#x}", arg0); if (arg0 >= 0x4000) { return POSIX_EINVAL; } @@ -29,6 +33,7 @@ s32 PS4_SYSV_ABI Func_4A67FE7D435B94F7(u32 arg0) { } s32 PS4_SYSV_ABI Func_4B07893BBB77A649(u64 arg0) { + LOG_DEBUG(Lib_Ulobjmgr, "(STUBBED) called arg0={:#x}", arg0); if (arg0 == 0) { return POSIX_EINVAL; } diff --git a/src/core/libraries/ulobjmgr/ulobjmgr.h b/src/core/libraries/ulobjmgr/ulobjmgr.h index baf90719cff..070e5fadd0b 100644 --- a/src/core/libraries/ulobjmgr/ulobjmgr.h +++ b/src/core/libraries/ulobjmgr/ulobjmgr.h @@ -10,5 +10,14 @@ class SymbolsResolver; } namespace Libraries::Ulobjmgr { +// NID: BG26hBGiNlw +s32 PS4_SYSV_ABI Func_046DBA8411A2365C(u64 arg0, s32 arg1, u32* arg2); +// NID: HZ9Q2c+4BU4 +s32 PS4_SYSV_ABI Func_1D9F50D9CFB8054E(); +// NID: Smf+fUNblPc +s32 PS4_SYSV_ABI Func_4A67FE7D435B94F7(u32 arg0); +// NID: SweJO7t3pkk +s32 PS4_SYSV_ABI Func_4B07893BBB77A649(u64 arg0); + void RegisterLib(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Ulobjmgr \ No newline at end of file +} // namespace Libraries::Ulobjmgr