Commit Graph
771 Commits
Author SHA1 Message Date
Adrià 0fa6ddb137 Merge pull request #6802 from DavidSamir/feat/relinker-macos-fixed-base
feat(relinker): place macOS executables at a fixed base with --macos-fixed-base
2026-10-19 12:54:31 +02:00
Adrià afeaffa6c1 Merge pull request #6717 from simonbronk/codex/strict-empty-arrays
fix(relinker): accept omitted empty array sizes in strict filtering
2026-10-19 11:47:09 +02:00
Adrià 8816fd7720 Merge pull request #6715 from simonbronk/codex/windows-unicode-output-collisions
fix(relinker): reject Unicode output aliases on Windows
2026-10-19 11:06:08 +02:00
Adrià bcdc5f6b3e Merge pull request #6702 from karimibrahim07/fix/relinker-weak-guest-imports
fix(relinker): leave weak imports of bundled modules unbound on Windows
2026-10-19 10:49:10 +02: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
Adrià 4630318457 Merge pull request #6681 from milescoviello/fix/relinker-bss-page-overlap
fix(relinker): keep a segment's zero-filled tail zero when the next PT_LOAD starts on its page
2026-10-19 10:48:54 +02:00
David 3ea53b5412 test(relinker): check the macOS fixed base layout and option parsing
macos_fixed_base relinks the fixed-base fixture with and without
--macos-fixed-base 0x400000 and checks that every segment and section
moves by the same amount, __PAGEZERO ends 64 KiB below the base, the
lowest load page is at the base, the entry offset is unchanged, and the
metadata load bias and the relocated slot hold base-relative addresses.
It also checks the lowest base and the refused options and images.

cli_args covers the parsing, range, repetition and --macos requirement.
2026-10-19 10:32:50 +02:00
David 35fe448155 feat(relinker): place macOS executables at a fixed base with --macos-fixed-base
Ruffle (PPSA68091), VLC (PPSA85300) and XPSemu (PPSA97358) read
app0/imports.txt, whose import slot addresses assume the executable's
lowest ELF load page at 0x400000, and dereference them at once. macOS
output always placed that page at 0x140010000, so all three fault on
their first slot read. Linux and Windows have --linux-fixed-base and
--windows-fixed-base for this; macOS had no equivalent.

--macos-fixed-base <address> builds the load image so that the lowest
ELF load page is at the address, as --windows-fixed-base does. The
Mach-O header takes the 64 KiB below it and __PAGEZERO ends there. The
executable is MH_EXECUTE without MH_PIE, so dyld does not slide it. The
address must be 64 KiB aligned, from 0x20000 through 0x7fffffff0000,
and an image ending past the macOS user address space is refused.
2026-10-19 10:32:30 +02:00
David 96e373f8ad refactor(relinker): take the macOS image base from the load image
WriteMacOsImage wrote the Windows ImageBase constant into the Mach-O
segment and section addresses, __PAGEZERO, the metadata load bias, the
TLS descriptors and the init pointer, while the relocations it rebases
were computed from the WindowsLoadImage base. Read the base from the
load image everywhere instead. Every caller still builds its image at
ImageBase, so the output is unchanged.
2026-10-19 10:32:17 +02:00
Adrià ed8caf6a4f Merge pull request #6619 from Get-fix/ps4/relinker-zero-length-fde
fix(relinker): ignore unwind records that cover no code
2026-10-19 09:59:13 +02:00
Adrià 427194263c Merge pull request #6605 from GalaxyGamingFR/fix/strict-filter-indexed-table-imports
fix(relinker): keep imports reached by indexing a live table base
2026-10-19 09:37:49 +02:00
Adrià 977ee725b2 Merge pull request #6595 from MarcZX10/codex/ps4-relative-jump-tables-3093
fix(relinker): exclude trailing PS4 relative jump tables
2026-10-19 09:01:03 +02:00
Adrià b44d0127d8 Merge pull request #6545 from Get-fix/ps4/relinker-init-array-without-size
fix(relinker): treat DT_INIT_ARRAY without DT_INIT_ARRAYSZ as empty
2026-10-19 08:22:06 +02:00
Kovalev Vladislav 269a59e23a fix(relinker): preserve defined RELATIVE symbols with section markers 2026-10-19 09:46:47 +06:00
Adrià 134a3510c8 Merge pull request #6419 from DavidSamir/fix/relinker-macos-tls-alu-reads
fix(relinker): rewrite ALU reads of guest TLS through %fs in macOS output
2026-10-19 03:02:09 +02:00
Adrià 819c5477b9 Merge pull request #6466 from whamre/fix/windows-sparse-load-image
fix(relinker): keep unmapped gaps out of the Windows load image
2026-10-19 03:00:53 +02:00
Adrià 7b12450b8f Merge pull request #6357 from MarcZX10/codex/relinker-relative-defined-symbol-3093
fix(relinker): accept matching defined relative symbols
2026-10-19 02:56:49 +02:00
Adrià 42d8666f29 Merge pull request #6458 from DavidSamir/fix/relinker-trap-macos-guest-gs
fix(relinker): trap guest GS accesses in macOS output instead of refusing the module
2026-10-19 02:56:44 +02:00
Adrià d265c58e40 Merge pull request #6351 from thuanquang/fix/layout-relative-output
fix(relinker): list converted modules correctly for a relative output path
2026-10-19 02:40:55 +02:00
Dean 60fb8078c7 Merge pull request #6067 from meh7an/perf/libs-mimalloc-windows
feat(libs): let relinked Windows games opt into mimalloc
2026-10-19 13:09:36 +13:00
David 6f89fd706f test(relinker): trap a GS access in a macOS module without a TLS segment
The macOS writer sets up guest TLS only for a module with a non-empty PT_TLS. A GS access in a module without one must still be trapped.
2026-10-19 02:06:44 +02:00
David 8da24830ac test(relinker): cover GS loads, stores and ALU reads trapped in macOS output
macos_gs_traps converts the forms Wine's ntdll in Prospero Win (PPSA99995) uses, a store, an ALU read and a register-address form shorter than a jump, and checks that each becomes ud2 and NOP padding of its own length before the next instruction, with none of the original bytes left.
2026-10-19 02:06:43 +02:00
David 55c6254ee6 fix(relinker): trap guest GS accesses in macOS output instead of refusing the module
On x86-64 macOS, including under Rosetta, the host owns GS (it holds the
pthread TSD base, which the macOS TLS stubs read), so a guest instruction
that reads or writes through GS cannot be translated, and the TLS scan
refused the whole module. Prospero Win's (PPSA99995) Wine ntdll has six.
Overwrite each in place with ud2 and NOP padding of its own length, as the
Windows writer does in #6102, and refuse one that is also an AMD-only
trampoline site.
2026-10-19 02:06:43 +02:00
Adrià ea41ee4031 Merge pull request #6410 from DavidSamir/fix/relinker-macos-tls-overlapping-decode
fix(relinker): skip prefixed decodings inside an earlier instruction in the macOS TLS scan
2026-10-19 01:58:54 +02:00
Adrià a9e7267465 Merge pull request #6418 from jweidenh/codex/optional-rela-table
fix(relinker): accept executables without a RELA table
2026-10-19 01:56:53 +02:00
Adrià 278daa3560 Merge pull request #6381 from SandstromPL/fix/relinker-ps4-needed-module-tag
fix(relinker): read the PS4 needed-module tag in guest modules
2026-10-19 01:47:24 +02: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à cf72c02064 Merge pull request #6325 from amirerfantim/refactor/relinker-remove-dead-code
refactor(relinker): remove functions nothing calls
2026-10-19 01:17:30 +02:00
Adrià eb1a15b5cc Merge pull request #6314 from eliyarson/feat/relinker-game-patches
feat(relinker): add conversion-time game patches
2026-10-19 00:37:51 +02:00
Adrià 8a456334f6 Merge pull request #6240 from ArjenS-LA/fix/guest-registry-weak-imports
fix(relinker): preserve weak imports in guest module registries
2026-10-19 00:06:30 +02:00
Mehran 9824c46fe0 feat(libs): let relinked Windows games opt into mimalloc 2026-10-19 00:08:47 +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
Dean 376c040294 Merge pull request #6112 from ayam04/fix/relinker-guest-preinit
fix(relinker): run guest preinit arrays before the module initializer
2026-10-19 07:33:14 +13:00
Dean 50f2090d53 Merge pull request #5981 from MarcZX10/codex/relinker-df-symbolic-5927
fix(relinker): preserve DF_SYMBOLIC on guest modules
2026-10-19 07:33:07 +13:00
Dean 1fcd86b324 Merge pull request #7098 from jotitadev/fix/relinker-validate-tls-segment
fix(relinker): validate the PT_TLS layout when reading program headers
2026-10-19 07:24:33 +13:00
Eli Yarson 62d881cfaf test(relinker): drop a code comment from the game patch test 2026-10-18 14:57:13 -03:00
Eli Yarson 3b814f00c0 test(relinker): skip quote-named files on Windows and keep backslash coverage 2026-10-18 14:57:13 -03:00
Eli Yarson d39a22e071 test(relinker): make game patch tests path-separator independent 2026-10-18 14:57:13 -03:00
Eli Yarson 346b0a92ca feat(relinker): add conversion-time game patches
A per-game relinker-patches.toml (or --patches) replaces verified bytes in
the input executable and bundled modules before conversion. Entries are
checked against the expected bytes and against every in-place writer,
the ELF header range and relocation targets. An <output-stem>.patches.toml
manifest records the applied entries, and --verify-patches checks an input
or a converted output. With no patch file the output is unchanged.
2026-10-18 14:57:13 -03:00
MarcZX100 e541cc9546 test(relinker): assert Windows symbolic rejection 2026-10-18 17:35:36 +00:00
MarcZX100 2f7eb66c65 test(relinker): keep symbolic fixture on Linux output 2026-10-18 17:34:06 +00:00
MarcZX100 86d3c085e9 fix(relinker): reject Windows DF_SYMBOLIC modules 2026-10-18 17:30:25 +00: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 <noreply@anthropic.com>
2026-10-18 22:51:57 +05:30
Adrià FranchandClaude Sonnet 5.5 e751268ad9 test(relinker): provide libkernel.prx to the native guest preinit load
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 19:09:58 +02:00
Ayamullah Khan 6574ade033 fix(relinker): pop the guest preinit thunk registers in reverse order
The Windows deferred preinit thunk pushed r12, r13 and r14 and then
popped r12, r13 and r14, so the caller got r12 and r14 back swapped.
InitializeDeferredModule keeps the module base, table and count live
across the call to the thunk, so a compiler that keeps any of them in
r12 or r14 sees corrupted loader state after opening a deferred module
that has a preinit array. Pop in reverse push order instead and pin the
new bytes in test_guest_preinit.
2026-10-18 19:09:47 +02:00
Ayamullah Khan 36baa5fcad test(relinker): run the guest preinit test with verify_asan_link_order=0
guest_preinit loads the instrumented guest_module_args_host.prx into Python, so in an ANYPS5_ENABLE_ASAN build it needs the same verify_asan_link_order=0 as the other module tests; without it, it fails with "ASan runtime does not come first in initial library list". add_asan_test_options does nothing outside ASan builds.

Signed-off-by: Ayamullah Khan <ayamullahkhan04@gmail.com>
2026-10-18 19:09:47 +02:00
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à 889cee5f9f Merge pull request #6115 from ArjenS-LA/fix/relinker-needed-output-collisions
fix(relinker): reject needed companion output collisions
2026-10-18 18:44:13 +02:00