Repository navigation
Conversation
…d imports The import thunks of the call tracer can now hand every call of the imports an observer selects to it: the six integer argument registers on the way in, rax on the way out. The thunk replaces the return address with a stub that finishes the call, keeps a shadow stack per thread, and finishes calls a longjmp unwound at the next observed call.
…he import thunks An observer in libSceNetCtl picks the imports of the network libraries out of the call tracer's thunks and writes the observation line, so an export needs no line of its own. CMake scans the sources for the export names and return kinds when it configures, ObservedArguments.inc names the arguments worth logging, and a NetBridgeCall or NetBridgeRecord in an export claims its call so the line is written once.
1,763 NetBridgeCall objects and their Ret wrappers leave the exports of the network libraries. The 14 that describe what an export writes back stay.
…e and shorten the debt entries
Merged
12 tasks done
…ect the argument checks
Member
Author
|
Full build (run 40599806387, linux hosted + windows, all tests): Windows is green. Linux passes everything except |
12 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Observation of the network libraries no longer needs a line in every export, so an upstream sync stops conflicting on them.
Mechanism. A game converted with
--trace-importsalready sends each import through a thunk of libc.prx (CallTrace.cpp, installed by the relinker's startup code on Linux, Windows and macOS). The thunk gains an optional call observer:SetCallObserver_nid_no_patchregistersselect,enterandleave.entergets rdi, rsi, rdx, rcx, r8 and r9; the thunk puts a small stub (CallTraceReturn_nid_no_patch) in place of the return address soleavegets rax. A per-thread shadow stack pairs them, and calls alongjmpunwound are finished without a result at the next observed call.libSceNetCtl registers the observer when it loads (
NetBridgeObserveHook.cpp).selectmaps an import's NID to a library and export name and writes the same line as before (lib,fn,in,out,ret); it does nothing unlessANYPS5_NET_OBSERVEis set. The names come from CMake:ObservedExports.cmakescans the observed libraries forAPS5_VABIdefinitions when it configures, so a new upstream export is observed with no line of its own, and an import of an observed library that the scan does not know is written under its NID instead of being lost. Arguments that were logged by name (netIn.Int("s", s)) are rows ofObservedArguments.inc(register, type, name).NetBridgeCallandNetBridgeRecordstay where an export writes something back or answers; they claim their call, so the hook writes no second line.Size. 1,763 of 1,777
NetBridgeCallobjects and theirnetCall.Ret(...)wrappers are gone from the 17 observed libraries (about 4,000 lines deleted); 14 stay (sockaddr and option decoding inlibSceNet,Out()andBoolusers). 485 of them became rows ofObservedArguments.inc. The edit was made by a script that can be run again on a merged tree, so this PR need not land first: if #29 or #33 land before it, rebase and rerun the script instead of resolving hunks.Cost, and why it is opt-in. Expected, not measured. An import nothing selects gets no thunk and costs nothing; at start each import costs one
getenvand a string compare (plus a hash lookup while observing), a few hundred nanoseconds in all. An observed call costs the thunk (about 20 register saves and two calls into libc.prx), a thread-local stack push, and building the line (a JSON string, a mutex and a queue push), on the order of one to three microseconds. The network libraries' calls are not per-frame, so that is acceptable while recording, but not something to pay in normal play. The launcher therefore passes--trace-importsonly while the player records network calls: anyplaynet/launcher#242 (relinks when the setting changes, leaves normal play untouched). Without the flag nothing is observed except what an export describes itself.Behaviour changes
NotImplemented_nid_no_patch) can no longer reach a handler in guest code. This only applies to executables converted with--trace-importsand only to libraries inNET_OBSERVED_EXPORT_LIBS; it needs parl0v's decision.NotImplementedwrites thenot_implementedline but none of its own.retis written for every export whose declared return type is an integer of 32 bits or less (read from the source); before, where the code calledRet.--trace-imports.Also listed in the debt files of libc and libSceNetCtl.
Tested
Not tested on a game.
guest_call_trace_observe(libc): arguments, results (integer, struct return, floating point, variadic), nesting, claim,longjmp(not on Windows), four threads, and that an import only the observer selected is not counted by the tracer.net_observe_hook(libSceNetCtl): exports per library against floors (the number of exports that carried a line before, so a silent loss fails), an export that answers nothing (libSceNpCppWebApi) observed through the hook alone, argument types, a claimed call written once, an unknown NID of an observed library written under the NID. CI builds on Linux, Windows and macOS are the first full build; the Mach-O build compiles the stub but does not run the tests.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)