Commit Graph
75 Commits
Author SHA1 Message Date
JJenkx adf0176d3a fix(loader): preserve SDK startup in browser conversions 2026-10-23 11:15:40 -04:00
Adrià 3a2ca40dab Merge pull request #9234 from mossyanwar/fix/relinker-linux-named-imports
fix(relinker): resolve symbol-name imports through NIDs on Linux
2026-10-22 20:54:22 +02:00
Rookie 123ba70839 fix(relinker): load Linux executables at 0x400000 by default 2026-10-21 19:25:33 +01:00
mossyanwar be51ab7bae fix(relinker): resolve symbol-name imports through NIDs on Linux
Homebrew built with the ps5-payload-dev SDK names its system
libraries with .sprx and imports by symbol name, while the libraries
in libs/ are .prx files that export NIDs. On Linux such an executable
converted but stopped at load time on the first .sprx dependency and,
once that was found, on the first symbol name.

The Linux patcher now loads a dependency named with .sprx, .suprx or
.debug_prx as the .prx library of the same stem. In an executable that
names such a dependency, an import without a module that is named by
symbol gets the NID of that name. A name that a bundled module exports
still binds to that module. There is no lookup by the name as written,
because the host loader also searches the host C library. Other
executables keep their unqualified imports as written.
2026-10-21 18:43:42 +01:00
Dean 27bcd6a29e Merge pull request #8162 from savvaniss/fix/windows-runtime-module-start
fix(relinker): start Windows runtime modules the executable needs when the title loads them
2026-10-22 02:10:11 +13:00
Savvanis SpyrosandClaude Opus 5.5 1d0451f659 docs(relinker): note that a deferred module the title never loads gets no module_start
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 14:12:12 +03:00
Dean fbba6e8208 Merge pull request #8845 from rooklz/fix/refs-file-identity
fix(relinker): compare Windows file identities by their 128-bit file ID
2026-10-21 20:57:16 +13:00
Rookie 5748d7ce81 fix(relinker): compare Windows file identities by their 128-bit file ID 2026-10-21 06:09:46 +01:00
Dean 46bfbe4e25 Merge pull request #8063 from AasishDairelSahayaGrinspan/fix/relinker-gs-memory-only-traps
fix(relinker): trap only GS memory accesses in Windows and macOS output
2026-10-21 16:35:25 +13:00
mpratsakiandClaude Opus 5.5 763702c5ce fix(relinker): use the Windows file identity in module and executable checks
Guest module discovery skipped the input executable and the
--executable check rejected an executable converted twice through
std::filesystem::equivalent, which MinGW reports as false for hard links
whose names give different permissions, such as .bin and .exe. Move the
GetFileInformationByHandle comparison to Io::SameFile and use it for
these checks and for SameOutputFile.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 02:19:01 +03:00
Dean Galvin 143ed02750 Merge branch 'main' into #7417
Resolve docs/dev/debt/libc.md: keep main's _Throw_Cpp_error entry and this branch's call tracing entry.
2026-10-21 06:33:59 +13:00
Dean bdc33a556c Merge pull request #7995 from mpratsaki/fix/relinker-windows-file-identity
fix(relinker): compare Windows file identities by handle
2026-10-21 06:25:35 +13:00
Savvanis SpyrosandClaude Opus 5.5 e0095e5b49 fix(relinker): find more constant syscall numbers before a gap syscall
The raw-byte check that runs before a syscall pattern between PS4 unwind
functions is skipped now also accepts mov rax, imm64, merges a following
mov al, imm8 or mov ax, imm16 into the earlier constant, and walks back
over any number of register moves or zeroings that leave rax alone
instead of at most seven. Visited states keep the walk linear in the
bytes it covers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 18:10:59 +03:00
Savvanis SpyrosandClaude Opus 5.5 58a2a4962f fix(relinker): follow fs loads and report pointers taken as data between PS4 unwind functions
A relocation or lea target outside the unwind functions of a PS4 image
is now decoded up to its first jump, return or trap, or to the start of
the next unwind function, which also bounds the transfer check of the
tail rule. A target whose run holds an fs:[disp32] access, the form the
linear TLS sweep roots, is followed as code. The other targets taken as
data are counted in one message and kept as entry points that the
Windows TLS rewrite may not overwrite. The analysis merges nested
unwind ranges like the scans.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 15:48:42 +03:00
Savvanis SpyrosandClaude Opus 5.5 1ea49c741f fix(relinker): tighten the syscall skip between PS4 unwind functions
The skip of syscall patterns outside the unwind functions let some real
syscalls through. The scan now merges nested and overlapping unwind
ranges with the instruction scanner's MergeCodeRanges, so a pattern
inside an outer function is refused. A constant syscall number is also
looked for in the bytes in front of the pattern, whatever alignment the
decoding took: a mov eax, mov rax or xor eax, eax that ends at the
pattern or before register moves and zeroings that leave rax alone. The
decoded lookback requires each instruction to end where the next one
starts. Guest modules without PT_SCE_DYNLIBDATA get no unwind ranges,
so their scan stays strict even when their unwind table is read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 15:48:42 +03:00
Savvanis Spyros 079e6ca316 Merge remote-tracking branch 'origin/main' into fix/windows-runtime-module-start 2026-10-20 15:27:06 +03:00
Savvanis SpyrosandClaude Opus 5.5 f154e132bc fix(relinker): take pointers into data between PS4 unwind functions as data
The code analysis of the Windows and macOS outputs followed every
relocation and lea target inside the code range as code. PS4 images keep
read-only data between unwind functions, and strings and tables there
decoded into garbage, failing the conversion. Outside the unwind functions
such a target is now code only when it is 16-byte aligned, starts less
than 256 bytes after an unwind function and decodes to a jump, return or
trap; lea targets go through the same rule instead of the graph's own.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 15:19:45 +03:00
Adrià 8afd6ea478 Merge pull request #7660 from savvaniss/fix/sce-code-gaps
fix(relinker): resume scans after undecodable bytes between PS4 unwind functions
2026-10-20 13:17:15 +02:00
aasishdairel 570c3297d3 fix(relinker): trap only GS memory accesses in Windows and macOS output 2026-10-20 10:13:34 +05:30
Dean d85b7c759a Merge pull request #2780 from SuarezPM/ai/relinker-hardening
feat(relinker): lower MCOMMIT and RDPRU for Intel with execution tests
2026-10-20 16:22:49 +13:00
Savvanis SpyrosandClaude Opus 5.5 45cc02c49c fix(relinker): start Windows runtime modules the executable needs when the title loads them
A --module-dir module that only the executable needs was initialized by
the Windows entry stub with no start arguments, so a later
sceKernelLoadStartModule with arguments found it started and its
module_start never saw them. Unity's mono-ps4.sprx keeps those
arguments for the plugins it loads. Such a module is now deferred like
any other runtime module: mapped at startup and started, with its
arguments, when the title loads it. Modules another guest module needs
are still started at startup, and Linux and macOS are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 03:57:24 +03:00
Adrià 34b1b77abf Merge pull request #7651 from DavidSamir/fix/relinker-amd-only-branch-targets
fix(relinker): ignore direct branch targets inside an instruction past its prefixes
2026-10-20 02:13:47 +02:00
SuarezPM bf47697ec0 feat(relinker): lower MCOMMIT and RDPRU for Intel with execution tests
MCOMMIT becomes STC plus NOP padding and RDPRU goes through a
runtime-checked stub returning the host TSC for MPERF/APERF while
other selectors yield zero, with converter and execution tests.

docs/dev/debt/relinker.md records the new lowering and its unverified
assumptions.
2026-10-19 19:19:31 -03:00
Ishmam Ahmed 78634fb0a9 feat(relinker): support --trace-imports for Linux output
The Linux entry stub now passes each traced import through libc.prx's
TraceImport_nid_no_patch before it calls the guest entry, and stores the
returned thunk in the import's slot. The same imports are traced as on
Windows: functions bound through a PLT slot or a GOT slot, without an
addend, and not weak. TraceImport_nid_no_patch is bound eagerly through
an added GLOB_DAT relocation, so a libc.prx without it fails at load.
Each slot's page is made writable with mprotect first, so slots inside a
PT_GNU_RELRO range can be replaced.

--trace-imports now requires libc.prx among the libraries on Linux too,
and is refused with --macos.
2026-10-19 22:56:03 +01:00
mpratsakiandClaude Opus 5.5 c9731df4c9 fix(relinker): compare Windows file identities by handle
MinGW's std::filesystem::equivalent returns false for hard links whose
names give different permissions, such as .elf and .exe. The temporary
hard-link probe that worked around it failed on read-only files and on
directories that refuse the link. Compare the volume serial number and
file index from GetFileInformationByHandle instead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 19:54:53 +03:00
Savvanis SpyrosandClaude Opus 5.5 c92f09d1d5 docs(debt): name no title in the SCE code gap entry
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 14:53:58 +03:00
Adrià e0adc075a2 Merge pull request #6697 from karimibrahim07/feat/relinker-named-host-imports
fix(relinker): resolve symbol-name imports through NIDs on Windows
2026-10-19 10:49:05 +02:00
Savvanis Spyros 504c41a9ad Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into fix/sce-code-gaps
# Conflicts:
#	core/relinker/relinker/src/pipeline/RelinkerPipeline.cpp
2026-10-19 10:06:58 +03:00
Adrià Franch da5b7e3334 docs(debt): note that macOS output traps GS-prefixed instructions without a memory operand too 2026-10-19 02:06:49 +02:00
David 414c1f96a6 docs(debt): record that guest GS accesses trap in macOS output 2026-10-19 02:06:44 +02:00
Savvanis Spyros c3d1363df3 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into fix/sce-code-gaps
# Conflicts:
#	docs/dev/debt/relinker.md
2026-10-19 02:35:44 +03:00
Adrià 2c2abc453b Merge pull request #6354 from SandstromPL/fix/relinker-plt-before-code
fix(relinker): find the PLT before the code in PS4 modules
2026-10-19 01:32:36 +02:00
Adrià 64b57d1b02 Merge pull request #6328 from aaro56/fix/relinker-preserve-input-hardlinks
fix(relinker): preserve inputs behind Windows executable hard links
2026-10-19 01:17:35 +02:00
Adrià 9121a9e455 Merge pull request #6327 from HilalElusive/patch-1
docs(debt): correct Windows GUI logging description
2026-10-19 01:08:04 +02:00
Savvanis SpyrosandClaude Opus 5.5 45a2e3dd4a fix(relinker): resume scans after undecodable bytes between PS4 unwind functions
In PS4 executables and modules the bytes between unwind functions are
16-byte slots of function tails and padding, and a tail can begin inside
an instruction, such as a lone REX byte before a 15-byte NOP. The
syscall and call-site scans decode the executable segment linearly, so
such a slot failed the relink with "Cannot decode instruction".

For images with a PT_SCE_DYNLIBDATA segment the scans now receive the
unwind function ranges. Outside every range an undecodable byte is
skipped and decoding resumes at the next byte, and a decoding that would
cross into a range ends at its start, so gap bytes cannot change how a
function is decoded. Inside a range a decode failure still fails the
relink, and images without unwind ranges are scanned as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 23:45:49 +03:00
Dean Galvin c3b9001592 revert(relinker): run guest preinit arrays before the module initializer (#6112)
This reverts commit 376c040294.
2026-10-19 09:38:31 +13:00
David 2f406862a8 docs(debt): note the branch targets the AMD-only converter ignores 2026-10-19 00:10:07 +04:00
SandstromPLandClaude Opus 5.5 81561867fc Merge upstream/main into fix/relinker-plt-before-code
Resolve the docs/dev/debt/relinker.md conflict with #5994: keep its
sce_module syscall-scan entry, which now also stops at the end of the
last unwind function when the PLT comes before the code (it calls the
same FindSceCodeEnd), and its /libexec/ld-elf.so.1 start in the code
analysis entry, with this PR's end for a PLT before the code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 22:51:57 +05:30
Ayamullah Khan 9c43211664 fix(relinker): run guest preinit arrays before the module initializer
Converted guest modules never ran their DT_PREINIT_ARRAY entries: the
reader validated the array and the unused-NID filter kept its targets,
but no writer emitted or ran it. ld.so runs a shared object's preinit
array only for the main executable, so the Linux output runs the
entries from the DT_INIT stub before the module initializer; the macOS
and Windows outputs run them before the initializer in their startup
stubs, and the deferred Windows output exports a thunk that runs them
before the initializer for runtime-loaded modules. A module with a
preinit array and no initializer is still rejected, since the Linux
stub exists only with one.
2026-10-18 19:09:46 +02:00
Adrià f890e21a81 Merge pull request #6111 from Kernel-Hunter/fix/rosetta-rdtscp-processor
fix(relinker): report processor 0 from RDTSCP under --to-rosetta
2026-10-18 19:00:12 +02:00
Adrià aff1f7190d Merge pull request #6102 from DavidSamir/fix/relinker-trap-windows-guest-gs
fix(relinker): trap guest GS accesses in Windows output instead of refusing the module
2026-10-18 18:29:03 +02:00
Karim Masmoudi 57e52c1f03 fix(relinker): report processor 0 from RDTSCP under --to-rosetta
Rosetta sets RDTSCP's ECX to its constant TSC_AUX, 0xAAAAAAAB, which is
not a processor index. --to-rosetta already makes RDPID return processor
0 for the same reason, so code reading the processor through RDTSCP saw
a different value from code reading it through RDPID.

--to-rosetta now moves RDTSCP into an optional stub that runs the
instruction unchanged and then loads 0 into ECX with a MOV, which
leaves the counter in EDX:EAX and the flags as they were. A site with no
movable instruction after it for the jump is kept, as for RDPID. The
Intel target and a plain relink are unchanged.
2026-10-18 18:27:15 +02:00
Adrià e00260b6b3 Merge pull request #5994 from Get-fix/ps4/sce-module-code-extent
fix(relinker): stop module syscall scans at the PLT and skip the PS4 loader path
2026-10-18 16:45:24 +02:00
Karim Ibrahim ea61baec62 fix(relinker): resolve symbol-name imports through NIDs on Windows
Homebrew built with the ps5-payload-dev SDK imports by symbol name and
names its system libraries with .sprx, while the libraries in libs/
are .prx files that export NIDs. Quake from the websrv launcher
stopped with 457 unresolved imports such as strlen and malloc.

An import without a module that no searched library exports under its
name is now looked up again under the NID of that name. A dependency
named with .sprx, .suprx or .debug_prx loads the .prx library of the
same stem, and libkernel_web also loads libkernel.prx, as
libSceLibcInternal already loads libc.prx.
2026-10-17 22:40:09 -04:00
Dean 5b7ec4a9bd Merge pull request #7272 from OskarLGS/fix/relinker-decoder-osize-branches
fix(relinker): decode near branches with an operand-size prefix as AM…
2026-10-18 12:56:40 +13:00
oskarlgsandClaude Opus 5.5 206aaa56cb fix(relinker): decode near branches with an operand-size prefix as AMD does
66 E8, 66 E9 and 66 0F 80-8F without REX.W take a 16-bit displacement on
AMD processors, the console included. Every near relative branch with that
prefix truncates its target to 16 bits, so the decoder reports no branch
target for it and stubs refuse to move it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016TFMtUC4L4wMS4eeEqaNSR
2026-10-17 20:58:29 +00:00
Destroyers212xandClaude Opus 5.5 10c1c24cea docs(relinker): record Rosetta instruction support on an M1 with macOS 26.6.2
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 11:22:28 -04:00
javierUDP b38f146ce6 docs(relinker): record what Rosetta executes on an M5
The Rosetta conversion limits were measured on an M1 running macOS 15.3.1
and an M5 Max. A survey on an M5 running macOS 26.4 executes ANDN, RDRAND,
the rest of BMI1 and BMI2, LZCNT, PREFETCHW, CLFLUSHOPT, AVX, AVX2, FMA,
F16C and MOVBE while CPUID reports none of them, and raises an illegal
instruction for RDSEED, CLWB, RDPID, ADCX and ADOX.
2026-10-17 10:31:23 -03:00
inmert f91e53d595 fix(relinker): list libc.prx with libkernel.prx in macOS executables 2026-10-17 14:06:01 +05:30
SandstromPLandClaude Opus 5.5 051dac94ee fix(relinker): find the PLT before the code in PS4 modules
FindSceCodeEnd looked for the PLT only after the last function of the
unwind table and failed with "PLT not found after the last unwind
function" otherwise. The libSceFios2.prx and libc.prx that Until Dawn
(CUSA02636) bundles have their PLT at 0xc8, at the start of the text
segment, before the code. In both, the last unwind function is
followed by the module's DT_FINI routine, which has no unwind entry,
and then by read-only data.

When no PLT follows the last unwind function, the search now also looks
before it. A PLT found there must not overlap an unwind function, and
the code extent then ends at the last unwind function, so what follows
it stays out of the scans and the code analysis, including code
without an unwind entry such as the DT_FINI routine of both modules
(recorded in the debt file). A missing PLT now fails with "PLT not
found before or after the unwind functions".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 09:43:51 +05:30