Skip to content

fix(libc): hand out the unwind cursor table through a _nid_no_patch export - #5014

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/fix-windows-patched-libraries
Oct 13, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/fix-windows-patched-libraries

Conversation

@oneandonlydean

Copy link
Copy Markdown
Collaborator

What

The Windows job fails on patched_libraries since #4945 was merged (first seen on builds based on 6d7b873, and on the push build of fc1f063):

libSceAgc.prx: LoadLibraryEx failed with error 127
libSceAgcDriver.prx: LoadLibraryEx failed with error 127
libSceVideoOut.prx: LoadLibraryEx failed with error 127
123 patched libraries loaded, 3 failed

#4945 gave _Unwind_Context a default member initializer that points at LibcUnwind::CursorSlots, a C++ data symbol defined in libc. On Windows LibcUnwind::Frame contains an _Unwind_Context, and libSceAgcDriver builds frames in StackWalk.hpp for the worker sampler, so it now imports _ZN10LibcUnwind11CursorSlotsE from libc.prx. The NID patcher renames that export in the patched libc and does not touch the import (it only rewrites sce* and _nid_postfix names), so the patched libSceAgcDriver has an import nothing exports. libSceAgc and libSceVideoOut link to it and fail the same way. Linux is not affected because Frame has no context member there.

The table is now local to Unwind.cpp and the context reads it through UnwindCursorSlots_nid_no_patch(), the same naming the other libc helpers used across libraries have, so the name is the same in the patched libc and in the importer. Behaviour of #4945 is unchanged.

Tested

Linux, GCC, Release: built libc, all patched libraries and the tests below; patched_libraries, exception_runtime (includes the cursor table check from #4945), exception_personality, exception_c_cleanup, guest_exception_handler, guest_raise_exception, guest_unwind_module_info, guest_dynamic_cast, agc_stack_walk, unwind_record_bounds and the standalone register_context tests pass. The patched libc.prx exports UnwindCursorSlots_nid_no_patch under that name.

Not built on Windows locally. The cause is read from the sources and the CI logs; the Windows job of this PR is what shows the three libraries load again.

The Linux failure of guest_fminf on main (fminf check failed at line 33, from #4592) is a different problem and is not touched here.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none (Windows CI on main)
  • AI-assisted: yes

…xport

_Unwind_Context took its cursor table from LibcUnwind::CursorSlots, a C++
data symbol of libc. On Windows LibcUnwind::Frame holds an _Unwind_Context,
so libSceAgcDriver, which builds frames for its worker sampler, imported
_ZN10LibcUnwind11CursorSlotsE from libc.prx. The NID patcher renames that
export in the patched libc and leaves the import alone, so the patched
libSceAgcDriver, libSceAgc and libSceVideoOut failed to load with error 127
and patched_libraries failed. The table is now file-local and the context
reads it through UnwindCursorSlots_nid_no_patch, which keeps its name on
both sides.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant