From 41fb65761fd2d5ae987264e1c6e7b747bc51159f Mon Sep 17 00:00:00 2001 From: Dean Galvin Date: Mon, 28 Sep 2026 19:46:38 +1300 Subject: [PATCH] refactor(fiber): keep the assembly entry points out of NID patching with _nid_no_patch Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ --- core/libs/prx/libSceFiber/Export.cpp | 54 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/core/libs/prx/libSceFiber/Export.cpp b/core/libs/prx/libSceFiber/Export.cpp index adbe258a5..81562fa18 100644 --- a/core/libs/prx/libSceFiber/Export.cpp +++ b/core/libs/prx/libSceFiber/Export.cpp @@ -92,14 +92,14 @@ static void CompletePendingSuspend() { #ifdef _WIN32 -extern "C" void Aps5FiberSwitchStack(void** save, void* load); -extern "C" void Aps5FiberTrampoline(); +extern "C" void Aps5FiberSwitchStack_nid_no_patch(void** save, void* load); +extern "C" void Aps5FiberTrampoline_nid_no_patch(); asm(R"( .text - .globl Aps5FiberSwitchStack - .def Aps5FiberSwitchStack; .scl 2; .type 32; .endef -Aps5FiberSwitchStack: + .globl Aps5FiberSwitchStack_nid_no_patch + .def Aps5FiberSwitchStack_nid_no_patch; .scl 2; .type 32; .endef +Aps5FiberSwitchStack_nid_no_patch: push %rbp push %rbx push %rdi @@ -146,13 +146,13 @@ Aps5FiberSwitchStack: pop %rbp ret - .globl Aps5FiberTrampoline - .def Aps5FiberTrampoline; .scl 2; .type 32; .endef -Aps5FiberTrampoline: + .globl Aps5FiberTrampoline_nid_no_patch + .def Aps5FiberTrampoline_nid_no_patch; .scl 2; .type 32; .endef +Aps5FiberTrampoline_nid_no_patch: mov %r12, %rcx and $-16, %rsp sub $32, %rsp - call Aps5FiberMain + call Aps5FiberMain_nid_no_patch ud2 )"); @@ -164,7 +164,7 @@ struct InitialFrame { std::uint64_t r15, r14, r13, r12, rsi, rdi, rbx, rbp; std::uint64_t returnAddress; }; -static_assert(sizeof(InitialFrame) == 0xa8 + 8 * 8 + 8, "initial fiber frame must match Aps5FiberSwitchStack"); +static_assert(sizeof(InitialFrame) == 0xa8 + 8 * 8 + 8, "initial fiber frame must match Aps5FiberSwitchStack_nid_no_patch"); static StackBounds CurrentBounds() { auto* tib = reinterpret_cast(NtCurrentTeb()); @@ -182,15 +182,14 @@ static void SetBounds(const StackBounds& bounds) { #else -extern "C" __attribute__((visibility("hidden"))) void Aps5FiberSwitchStack(void** save, void* load); -extern "C" __attribute__((visibility("hidden"))) void Aps5FiberTrampoline(); +extern "C" void Aps5FiberSwitchStack_nid_no_patch(void** save, void* load); +extern "C" void Aps5FiberTrampoline_nid_no_patch(); asm(R"( .text - .globl Aps5FiberSwitchStack - .hidden Aps5FiberSwitchStack - .type Aps5FiberSwitchStack, @function -Aps5FiberSwitchStack: + .globl Aps5FiberSwitchStack_nid_no_patch + .type Aps5FiberSwitchStack_nid_no_patch, @function +Aps5FiberSwitchStack_nid_no_patch: push %rbp push %rbx push %r12 @@ -212,17 +211,16 @@ Aps5FiberSwitchStack: pop %rbx pop %rbp ret - .size Aps5FiberSwitchStack, .-Aps5FiberSwitchStack + .size Aps5FiberSwitchStack_nid_no_patch, .-Aps5FiberSwitchStack_nid_no_patch - .globl Aps5FiberTrampoline - .hidden Aps5FiberTrampoline - .type Aps5FiberTrampoline, @function -Aps5FiberTrampoline: + .globl Aps5FiberTrampoline_nid_no_patch + .type Aps5FiberTrampoline_nid_no_patch, @function +Aps5FiberTrampoline_nid_no_patch: mov %r12, %rdi and $-16, %rsp - call Aps5FiberMain + call Aps5FiberMain_nid_no_patch ud2 - .size Aps5FiberTrampoline, .-Aps5FiberTrampoline + .size Aps5FiberTrampoline_nid_no_patch, .-Aps5FiberTrampoline_nid_no_patch )"); struct InitialFrame { @@ -232,7 +230,7 @@ struct InitialFrame { std::uint64_t r15, r14, r13, r12, rbx, rbp; std::uint64_t returnAddress; }; -static_assert(sizeof(InitialFrame) == 8 + 6 * 8 + 8, "initial fiber frame must match Aps5FiberSwitchStack"); +static_assert(sizeof(InitialFrame) == 8 + 6 * 8 + 8, "initial fiber frame must match Aps5FiberSwitchStack_nid_no_patch"); static StackBounds CurrentBounds() { return {}; @@ -251,7 +249,7 @@ static Fiber* AsFiber(FiberObject* object) { return fiber && fiber->magic == FIBER_MAGIC ? fiber : nullptr; } -extern "C" [[noreturn]] __attribute__((visibility("hidden"))) void Aps5FiberMain(Fiber* fiber) { +extern "C" [[noreturn]] void Aps5FiberMain_nid_no_patch(Fiber* fiber) { CompletePendingSuspend(); fiber->entry(fiber->argOnInitialize, ThreadState().transfer); throw std::runtime_error(std::string("sceFiber: entry function of fiber '") + fiber->name + "' returned"); @@ -266,7 +264,7 @@ static void PrepareInitialStack(Fiber* fiber) { asm volatile("fnstcw %0" : "=m"(control)); frame->fpuControl = control; frame->r12 = reinterpret_cast(fiber); - frame->returnAddress = reinterpret_cast(&Aps5FiberTrampoline); + frame->returnAddress = reinterpret_cast(&Aps5FiberTrampoline_nid_no_patch); fiber->savedStack = frame; } @@ -298,7 +296,7 @@ static void Resume(Fiber* target, void** save, std::uint64_t argOnRun) { ThreadState().current = target; ThreadState().transfer = argOnRun; SetBounds(FiberBounds(target)); - Aps5FiberSwitchStack(save, target->savedStack); + Aps5FiberSwitchStack_nid_no_patch(save, target->savedStack); } extern "C" { @@ -380,7 +378,7 @@ int32_t APS5_VABI sceFiberReturnToThread(uint64_t arg_on_return, uint64_t* arg_o ThreadState().current = nullptr; ThreadState().transfer = arg_on_return; SetBounds(ThreadState().threadBounds); - Aps5FiberSwitchStack(&self->savedStack, ThreadState().threadStack); + Aps5FiberSwitchStack_nid_no_patch(&self->savedStack, ThreadState().threadStack); CompletePendingSuspend(); if (arg_on_run) *arg_on_run = ThreadState().transfer; return SCE_OK;