250 Commits
Author SHA1 Message Date
Dean 6df35a4f58 Merge pull request #10997 from SandstromPL/fix/relinker-backup-copies-in-conversion
fix(relinker): skip backup copies of guest modules in the online converter too
2026-10-27 10:58:32 +13:00
Dean 1748d26517 Merge pull request #10871 from Chronyyx/feat/relinker-frame-short-exits
feat(relinker): frame red-zone leaves whose prologue or exit is shorter than a jump
2026-10-27 10:55:26 +13:00
Dean b7cfbf0115 Merge pull request #9346 from Techx3/feat/fullscreen-env
feat(libSceVideoOut): open the display window fullscreen with ANYPS5_FULLSCREEN
2026-10-27 10:29:49 +13:00
Adrià ad6a8e646e Merge pull request #10487 from EagleBearerYS/feat/agc-overlay-detail-page
feat(agc): add a detailed second page to the performance overlay
2026-10-26 22:24:46 +01:00
Adrià c7b4878fa8 Merge pull request #10577 from Contemplating-Rain/docs/usage-sandbox
docs(usage): state that converted titles run without a sandbox
2026-10-26 22:07:38 +01:00
Yunus Shaikh b2d870962b docs: describe the performance overlay's second page
USAGE.md's performance overlay section now gives F10's cycle (off, page
1, page 2, off) and ANYPS5_OVERLAY=2, a table with one row per line of
page 2 that names each source and the system it comes from, and what the
page costs: the trace totals it turns on while it shows, and the checks
and counters that run while the overlay is hidden or on page 1.
ENVIRONMENT.md's ANYPS5_OVERLAY row lists page 2.
2026-10-26 20:42:30 +01:00
Adrià cbf76e7a6e Merge pull request #9408 from rursache/feat/macos-trace-imports
feat(relinker): trace function imports on macOS
2026-10-26 11:27:51 +01:00
Dean 2bdd30ebe6 Merge pull request #10719 from WhiteAssassins/feat/patch-advisor-list-verified
feat(tools): list verified patch catalog entries
2026-10-26 20:00:41 +13:00
Dean dbf4f6aa3f Merge pull request #10607 from roboterspinne/fix/relinker-linux-run-path
fix(relinker): validate every entry of the Linux run path
2026-10-26 14:26:39 +13:00
Adrià 58c9977e3b Merge pull request #9562 from milescoviello/feat/uds-trophy-progress
feat(libSceNpTrophy2,libSceNpUniversalDataSystem): unlock progressive trophies through _UpdateTrophyProgress
2026-10-25 19:45:49 +01:00
Adrià 5d48c6233e Merge pull request #9401 from tibzejoker/perf/grow-pipeline-store
perf(agc): size the pipeline store to the title's working set
2026-10-25 19:07:59 +01:00
Radu Ursache 66ca5c0442 feat(relinker): trace function imports on macOS
Walk each macOS function import before the guest entry and pass it through TraceImport_nid_no_patch, as Linux and Windows already do. An x86-64 libc build records the call and prints it on SIGABRT.
2026-10-25 18:37:23 +01:00
Adrià 7b7d445bfb Merge pull request #9439 from milescoviello/feat/trace-calls-file
feat(libc): write the called imports to APS5_TRACE_CALLS_FILE every 10 seconds
2026-10-25 17:42:50 +01:00
Adrià Franch 6ce060e3ee docs(libSceNpTrophy2): describe max and int32 statistics and property filters in USAGE 2026-10-25 17:24:50 +01:00
milescovielloandClaude Opus 5.5 ca34fdb351 feat(libSceNpTrophy2,libSceNpUniversalDataSystem): unlock progressive trophies through _UpdateTrophyProgress
Titles report a progressive trophy's progress with _UpdateTrophyProgress
events. Their udsNN.ucp rules feed $._trophy_progress into an int32
statistic with the max aggregation, filtered on $._trophy_id, and the
trophy's unlockCondition names that statistic. Those statistics and
rules were skipped and the events were dropped, so such trophies never
reported progress or unlocked (21 of Borderlands 4's 64).

- Read max statistics (largest value posted, from initialValue) and
  int32 statistics (0 to 2147483647).
- Read a rule condition with one == property equal to an unsigned
  integer, and apply the rule only to events whose property matches.
- Post _UpdateTrophyProgress through the statistic rules.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 17:24:43 +01:00
boykopovar 2e773bff38 Merge pull request #10990 from boykopovar/feat/nid-patcher-exec
feat(nid): executables nid patching functional
2026-10-25 18:56:44 +03:00
Adrià de74cf1deb Merge pull request #9488 from dantdmdarealguy/docs/relinker-converted-module-output
docs: describe the converted module output the relinker prints
2026-10-25 16:16:34 +01:00
SandstromPLandClaude Opus 5.5 479fcec4ee fix(relinker): skip backup copies of guest modules in the online converter too
The command-line relinker skips an ELF module whose file name extends
another module's in the same directory when both have the same SONAME, a
dumper's backup such as libX.prx.esbak (#7380). That check lives in the
CLI's ReadModules, so the online converter, which hands every ELF in
sce_module/ straight to Conversion, still stops on such a layout with
"Ambiguous guest dependency name: libX.prx".

The check moves into the relinker core as RemoveBackupCopies, which
Conversion::Convert now runs before patching or converting modules and
reports through the progress messages, so the browser prints the same
"Skipping backup copy" lines. ReadModules uses the same function, so the
command line and --verify-patches behave as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 18:42:27 +05:30
boykopovar e3db6dacf7 docs(nid): remove executable patching debt entry 2026-10-25 15:05:11 +03:00
boykopovar 1cf017b189 feat(nid): add executable import patching with optional sce filter 2026-10-25 15:03:02 +03:00
Dean 5aa203ba74 Merge pull request #9663 from AdnanKhan-ak47/feat/relinker-report-unconverted-needed
feat(relinker): report needed modules shipped outside the module directories
2026-10-25 21:50:08 +13:00
ChronyyxandClaude Opus 5.5 c697fb0ba9 feat(relinker): frame red-zone leaves whose prologue or exit is shorter than a jump
--frame-red-zone replaces a leaf's prologue and each exit with a 5-byte jump
to a stub, so it skipped leaves whose pushes or pop-and-ret exit were shorter
than that, and leaves with neither pushes nor an allocation. A short prologue
now takes in the straight-line instructions after it and a short exit those
before it, re-encoded in the stub with the moved displacement. Widening stops
at branches, rets, RIP-relative instructions, pushes and pops, and the leaf is
skipped when a branch targets the instructions taken in or the first
instruction of a widened prologue, or when a leaf without pushes pushes or
pops.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 02:47:12 -04:00
milescovielloandClaude Opus 5.5 a938dd8f20 feat(libc): write the called imports to APS5_TRACE_CALLS_FILE every 10 seconds
A traced run that ends without a crash or an abort never reports which
imports it called. With APS5_TRACE_CALLS_FILE set, the first traced import
starts a thread that rewrites that file every 10 seconds with every import
called so far, most called first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 00:15:39 +00:00
thibautandClaude Opus 5.5 ad047899bb perf(agc): grow the pipeline store from 1024 up to 4096 entries
The graphics pipeline store kept a fixed 1024 entries and the pipeline journal replayed at most
1024 records, and a replayed pipeline that found the store full was dropped. A title whose
working set is larger rebuilt the rest at the draw on every run, and evicted pipelines it kept
using were rebuilt again and again.

The bound now starts at 1024 and doubles up to 4096: a journal replay that does not fit grows it
instead of dropping the pipeline, and so does eviction churn (a ghost list of evicted keys, checked
every bound/32 evictions: more than half of them came back). It never shrinks during a run;
APS5_PIPELINE_STORE_ENTRIES still fixes it. The journal loads its last 4096 records by default
(APS5_PIPELINE_JOURNAL_ENTRIES). Resident pipelines are bounded by count, not bytes.

agc_driver_recorder_tests --benchmark-pipeline-store-memory [count] (opt-in, not registered)
builds count graphics pipelines with one fragment module each through CachedPipeline and prints
process private bytes and VK_EXT_memory_budget heap usage before and after: with the triangle
shaders about 59 KiB host and no device memory per pipeline on an RTX 4090, 100 KiB host and
8 KiB device-local on a UHD 770.

Tests: agc_pipeline_store_growth (fails on main), agc_pipeline_store_fixed_bound,
agc_pipeline_store_replay_growth (replays on one thread: the mock Vulkan is not thread-safe).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017SNUYRd7sRKZrMYpquAsnU
2026-10-25 02:02:41 +02:00
Dean c4446bbb09 Merge pull request #9332 from rooklz/fix/windows-console-base
fix(relinker): prefer 0x400000 for Windows executables
2026-10-25 12:57:28 +13:00
WhiteAssassins dbe74bf422 fix(tools): guide users through verified patch choices 2026-10-24 15:24:38 -04:00
WhiteAssassins 20f1039d89 feat(tools): list verified patch catalog entries 2026-10-24 14:52:36 -04:00
Adrià d01070d6c3 Merge pull request #5640 from EagleBearerYS/feat/relinker-frame-frameless-leaves
feat(relinker): frame red-zone leaves without a frame pointer by moving their rsp operands
2026-10-24 18:14:53 +02:00
Rookie 39df8e081c fix(relinker): prefer 0x400000 for Windows executables 2026-10-24 15:58:35 +01:00
Dean a8c8b8117b Merge pull request #8900 from WhiteAssassins/feat/patch-advisor
feat(tools): recommend verified local game patches
2026-10-25 03:51:47 +13:00
roboterspinne 5362dcaaf0 fix(relinker): validate every entry of the Linux run path
LinuxElfPatcher wrote --rpath into DT_RUNPATH unchanged, so an empty
entry (an empty value, a leading or trailing colon, or a double colon)
reached the output, where glibc searches the working directory for it,
while the macOS and Windows outputs reject empty run paths. The guest
module rule that each entry is absolute or begins with $ORIGIN only
looked at the start of the whole value, so "$ORIGIN/libs:" or
"$ORIGIN:relative/libs" passed. The Linux patcher now rejects an empty
entry with the message the macOS patcher uses, the guest rule checks
every colon-separated entry, and USAGE.md says so.
2026-10-24 12:16:08 +00:00
Adrià b84322da6a Merge pull request #7918 from Kernel-Hunter/fix/rosetta-xsaveopt
fix(relinker): rewrite XSAVEOPT to XSAVE under --to-rosetta
2026-10-24 14:14:59 +02:00
Claude 3d0b24843d docs(usage): state that converted titles run without a sandbox
A converted title runs with the user's permissions, and its executable is not randomized on any host: Linux loads it at a fixed address unless the deprecated --lazy-binding is used, Windows without DYNAMIC_BASE, and macOS without MH_PIE. Say so next to the host requirements.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01E7j2SYGtKCiPHcU9SwUSjh
2026-10-24 10:42:05 +00:00
Adrià 0210d3b878 Merge pull request #8909 from dantdmdarealguy/docs/usage-mimalloc-dlls
docs(usage): name the mimalloc DLLs a self-built Windows libs/ needs
2026-10-24 11:29:00 +02:00
Karim Masmoudi ce6c2a0c66 fix(relinker): rewrite XSAVEOPT to XSAVE under --to-rosetta
XSAVEOPT raises an illegal instruction under Rosetta on an M5 running
macOS 27.0.1, as XSAVEC does, while XSAVE and XRSTOR save and restore
x87, SSE and AVX state in the standard format. The PS5's Zen 2 has
XSAVEOPT, so code built for it can use the instruction without a CPUID
check.

XSAVEOPT differs from XSAVE only in the init and modified optimizations:
it may skip writing state that is in its initial configuration or
unchanged since the last XRSTOR from the same area. XRSTOR restores the
same state from the area XSAVE writes, so --to-rosetta rewrites
XSAVEOPT (NP 0F AE /6, memory operand) to XSAVE (/4) in place, keeping
the prefixes and the operand, as RDSEED becomes RDRAND. CLWB (66 0F AE
/6), MFENCE, UMONITOR, UMWAIT and the Intel target are left alone.
XSAVEC is not converted: it writes the compacted format.

The converter tests check the rewrite for the plain, REX.W,
RSP-relative, extended-base, RIP-relative and FS-relative forms, check
that the neighbouring 0F AE encodings are not taken, and execute the
rewritten XSAVEOPT64 followed by XRSTOR on YMM3 in the x86-64 build.
The --to-rosetta integration test now covers XSAVEOPT as well.
2026-10-24 11:01:44 +02:00
Dean ec3ea2f558 Merge pull request #6586 from JJenkx/fix/linux-runtime-module-start
fix(loader): defer Linux runtime module starts until requested
2026-10-24 19:54:29 +13:00
Dean 5540852c54 Merge pull request #9241 from veosett/codex/audit-sdk-symbol-names
fix(tools): flag qualified imports exported only under a NID
2026-10-24 14:21:32 +13:00
dantdmdarealguy 0c5e45e9f3 docs: describe the converted module output the relinker prints
The relinker stopped printing a 'Guest module:' line for each converted
module in 56c2a5318; it reports 'Converted modules: N' and lists the
.guest.prx files under app0/ in its runtime layout tree. GAME_TESTING.md
and USAGE.md still told readers to use the files printed as 'Guest module:'.
2026-10-23 19:14:55 -05:00
JJenkx adf0176d3a fix(loader): preserve SDK startup in browser conversions 2026-10-23 11:15:40 -04:00
Santhosh Kumar 3bcd89e10e fix(agc): reclaim idle images safely during cache creation
Forward new-image recovery permission through AllocateImageMemory while preserving host-memory fallback and allocated-type reporting. Reuse held cache locks only at safe construction points, retain caller-held sampled textures and pending storage results, and try resource-cache removal without waiting.

Count released Vulkan allocations and saturate the reclaim reserve. Cover sampled/storage allocation failures, host fallback after image recovery, bounded attempts and overflow. Remove stale conflict markers and unrelated debt, and refresh the recorded validation.
2026-10-23 16:37:26 +02:00
Dean 5e9f4b8966 Merge pull request #9832 from johandavidcm/fix/libkernel-dlopen-unrelinked
fix(libkernel): fail dlopen of an unrelinked module without the Windows Bad Image dialog
2026-10-23 23:18:00 +13:00
Kovalev Vladislav 46ff145113 fix(tools): flag qualified imports exported only under a NID 2026-10-23 12:18:57 +06:00
Yunus Shaikh a376e37b88 fix(relinker): decode each red-zone leaf over its whole FDE range 2026-10-23 05:22:26 +00:00
Yunus Shaikh 542cb30f70 docs(relinker): describe the operand stubs and refused patches of --frame-red-zone
The debt entry no longer says that a leaf with an rsp operand that
cannot move in place is skipped. A new entry says that such an operand
moves to a stub, when the leaf is still skipped, and that a game patch
over a framed site or a moved displacement is refused. The USAGE row
says the same in short.
2026-10-23 04:50:13 +00:00
Yunus Shaikh a665ef2dfb docs(relinker): describe the per-leaf shift and sub allocations of --frame-red-zone 2026-10-23 03:45:27 +00:00
Yunus Shaikh ff16118b63 Merge branch 'main' into feat/relinker-frame-frameless-leaves-next 2026-10-23 03:13:53 +00:00
raghav314andClaude Opus 5.5 c0dbd1871c perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE)
The second half of a pipelined draw (stage materialization, cache insert,
enqueue) runs on a finisher thread, overlapping the next draw's packet
work; draws whose stages could write memory are held back. Commits skip
work whose inputs did not change since the last commit, color metadata
passes are ordered through the pipeline, resource and storage-image proofs
are reused within one collect epoch until a write breaks them, and a shape
entry is refreshed in place at the second sight of the same read user words.
APS5_VERIFY_DRAW_PIPELINE checks reused proofs against a full check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 03:46:57 +05:30
Dean d2b1c3edd5 Merge pull request #9079 from JJenkx/feat/pad-input-chords
feat(tools): press several buttons together from pad_input.py
2026-10-23 11:09:00 +13:00
Dean 44ce348a74 Merge pull request #9291 from veosett/codex/self-alignment-padding
fix(tools): bound total SELF alignment padding
2026-10-23 09:40:16 +13:00
Johan David dc84bec7b9 fix(libkernel): fail dlopen of an unrelinked module without the Windows Bad Image dialog
On Windows, dlopen passed a module that was never relinked to LoadLibraryExW, which raised the
modal Bad Image hard-error dialog and blocked the calling thread until someone answered it. The
load now runs with SEM_FAILCRITICALERRORS set for that thread only, so it fails at once with the
same result as before. Every failed load is reported once per file on stderr with a [module]
prefix; a file that exists with no relinked .guest.prx names the relinker's --module-dir option.
2026-10-22 13:05:34 -05:00