Skip to content

feat(libSceShare.native): add the four exports the plain library has - #1024

Closed
Dextroid17 wants to merge 1 commit into
boykopovar:mainfrom
Dextroid17:fix/share-native-missing-exports
Closed

Dextroid17 wants to merge 1 commit into
boykopovar:mainfrom
Dextroid17:fix/share-native-missing-exports

Conversation

@Dextroid17

@Dextroid17 Dextroid17 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Which title needs this

PPSA12544. Its Share plugin imports sceShareCaptureVideoClipExtended from this library, which is the provenance the closed #989 records for the declaration. A plugin that links libSceShare.native and imports a symbol the wrapper does not export cannot load at all — it stops with undefined symbol before any call is made — so the evidence needed here is that a title imports it, which is what PPSA12544 does, rather than that a title calls it.

The same shape as #992, merged: declaring exports a named title imports and no library provides.

What this does

libSceShare.native exported 13 of the 17 symbols libSceShare exports, so a title importing one of the four stopped at load with an undefined symbol even though the plain library answers it. The wrapper now exports all 17.

Function Behaviour (as libSceShare implements it)
sceShareCaptureScreenshotExtended zeroes the request id, answers ERROR_NOT_SUPPORTED
sceShareCaptureVideoClipExtended NotImplemented_nid_no_patch
sceShareGetRunningStatus NotImplemented_nid_no_patch
sceShareSetContentParamForApplicationTitle NotImplemented_nid_no_patch

Why this shape and not a dependency edge

Context is #906. The plan there was to give each .native wrapper a DT_NEEDED edge to its plain twin, which fails: the wrappers are in the executable's DT_NEEDED, the pairs share NIDs, so the twins enter the global scope and modules rebind to the wrong implementation (that was #1009, closed).

Measuring the pairs first (nm -D --defined-only over a Release build of libs) shows most of that work is unnecessary:

pair plain wrapper shared missing from the wrapper
libSceFont.native 356 356 356 –
libSceAvPlayer.native 30 30 30 –
libSceAudiodec.native 15 15 15 –
libSceShare.native 17 13 → 17 13 → 17 4 NIDs → none
libSceMsgDialog.native 10 11 10 –
libSceSaveDataDialog.native 8 10 8 –
libSceSaveData.native 12 40 11 _ZNKSt5ctypeIcE8do_widenEc
libSceAjm.native 1 37 0 DummyFunction_nid_no_patch
libSceNgs2.native 1 35 0 DummyFunction_nid_no_patch

Eight of the nine wrappers already cover their plain library; the three remaining differences are not NIDs at all (a std::ctype instantiation and the DummyFunction_nid_no_patch placeholder of two libraries with one real export each). libSceShare.native was the only genuine gap, and closing it needs no edge, no second copy of anything in the global scope, and nothing for the pairs to rebind against.

Verification

  • guest_share_extended_tests passes.
  • Full suite: 371/371 (370 on main plus the new test).
  • Symbol measurement from the same build, before and after: the wrapper goes 13 → 17 defined symbols, shared with the plain library 13 → 17, and symbols the plain library has that the wrapper lacks 4 → none.
  • The new test cannot link before the change: the four symbols did not exist.
  • static-free change: nothing existing is modified in behaviour, only four exports are added.

Notes for review

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)
  • No investigation .md files or images added to the repository
  • New test registered with ctest and passing

AI-assisted: yes.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Progress report (ee391a5 → a84acf0)

📉 System libraries: 86.53% (-0.09%, +1 implemented, +3 declared functions)

✅ 1 implemented
Library Name
libSceShare.native sceShareCaptureScreenshotExtended
🆕 3 declared as stubs
Library Name
libSceShare.native sceShareCaptureVideoClipExtended
libSceShare.native sceShareGetRunningStatus
libSceShare.native sceShareSetContentParamForApplicationTitle

libSceShare.native exported thirteen of the seventeen symbols libSceShare exports, so a
title importing one of the four stopped at load with an undefined symbol while the plain
library answers it:

- sceShareCaptureScreenshotExtended - zeroes the request id and answers ERROR_NOT_SUPPORTED
- sceShareCaptureVideoClipExtended, sceShareGetRunningStatus and
  sceShareSetContentParamForApplicationTitle - unimplemented paths, declared under their
  names as libSceShare declares them

Measured from a Release build of libs (nm -D --defined-only): the wrapper goes from four
symbols missing to none. The same measurement over the other eight .native wrappers shows
they already cover their plain libraries completely - five of them exactly, and the three
remaining differences are a std::ctype instantiation and the DummyFunction_nid_no_patch
placeholder of two libraries that have one real export each. No dependency edge or lookup
scope change is needed for any of them.

The declarations are appended rather than placed alphabetically: an open pull request edits
this file a few lines above where sceShareGetRunningStatus would go.

Add the guest_share_extended test: the answer the extended screenshot call gives, the
request id it leaves behind for both null and non-null parameters, and the throwing paths.
@Dextroid17
Dextroid17 force-pushed the fix/share-native-missing-exports branch from d94f281 to a84acf0 Compare October 7, 2026 01:26
@Dextroid17

Copy link
Copy Markdown
Contributor Author

The first Windows run failed in cmake --build build:

ld.exe: GuestShareExtended.cpp.obj:GuestShareExtended.cpp:(.data+0x8):
  undefined reference to `__gxx_personality_v0'

The test's try/catch needs the C++ runtime, and the test linked only libSceShare.native, which is a plain C-style export library, so nothing pulled libstdc++ in. Every other test in this tree that catches an exception links libc as well for exactly that reason (guest_ajm_tests, guest_aio_tests, guest_buffer_reuse_tests, guest_jpeg_enc_tests, ngs2_geom_tests), so this now does too, and the link pulls libstdc++.so.6.

No change to the library or the exports. Linux was already green; the suite is 371/371 locally.

@Dextroid17

Copy link
Copy Markdown
Contributor Author

Worth stating up front, because #989 (now closed) implemented one of these four in the plain library and this PR touches the same function.

That closure was right for its own case: nothing on main stops at sceShareCaptureVideoClipExtended, so implementing its behaviour had no evidence behind it. This PR does not change that function's behaviour. All three unimplemented ones are declared as NotImplemented_nid_no_patch, exactly as libSceShare already declares them, and sceShareCaptureScreenshotExtended is copied value for value from the plain library, which #989's review already called consistent.

What is fixed here is reachability, which fails differently. A title's Share plugin that links libSceShare.native and imports sceShareCaptureVideoClipExtended cannot load at all while the wrapper does not export it — it stops with undefined symbol before any call happens. So the evidence this needs is that a title imports it, not that a title calls it, and that is exactly the provenance #989 records: PPSA12544's Share plugin imports sceShareCaptureVideoClipExtended.

That is the same shape as #992, merged today — declaring exports a named title imports that no library provides.

For completeness on the other three, libSceShare declares them all, and the wrapper is the library a title actually links:

function in libSceShare now in libSceShare.native
sceShareCaptureScreenshotExtended implemented (ERROR_NOT_SUPPORTED) same
sceShareCaptureVideoClipExtended NotImplemented_nid_no_patch same
sceShareGetRunningStatus NotImplemented_nid_no_patch same
sceShareSetContentParamForApplicationTitle NotImplemented_nid_no_patch same

If the direction you prefer is to leave the wrapper short until a title log shows the load failing, say so and I will close this — but the failure mode here is a load that cannot start, so a log line would be the absence of one.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks for laying that out; the distinction between calling and importing is fair, and #992 was the same shape.

The difference is that on #992 no library provided those exports, while here libSceShare already does. On #228 the owner's point was that a title importing libSceAjm also loads libSceAjm.native, so a copy in the twin isn't needed. If that's true for Share too, PPSA12544's plugin resolves these four from the plain library and loads fine on main.

A load that can't start does leave a log line: the loader prints undefined symbol: <name> (or the NotImplemented-style stop) with the module that asked for it. If you can run PPSA12544 on main and it stops there, please post that line and I'll reopen this straight away; it would also tell us whether the fix belongs in the twin or in how the plain library is found. Until then I'm closing it, since the evidence so far is the import list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux: .native wrapper libraries have no dependency edge to their plain twin, so guest modules cannot bind

2 participants