Commit Graph
226 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à 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 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à 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à 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
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 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
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
MarcZX100 86d3c085e9 fix(relinker): reject Windows DF_SYMBOLIC modules 2026-10-18 17:30:25 +00: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 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à 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
Werner c0dec34d82 Merge remote-tracking branch 'origin/main' into fix/windows-sparse-load-image 2026-10-18 13:39:35 +00:00
Dean 04b55dda2e Merge pull request #6406 from MarcZX100/codex/preserve-linux-gnu-segments-6394
fix(relinker): preserve GNU stack and RELRO headers on Linux
2026-10-18 22:04:27 +13: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
oskarlgsandClaude Opus 5.5 aed1ffbae8 fix(relinker): keep the Windows TLS rewrite from moving truncated branches
A short TLS access followed by a near branch with an operand-size prefix
decided the branch was relative from its flow kind and opcode alone, then
re-encoded it to the fall-through address or wrote its rel32 over the prefix
and opcode. Such a branch now counts as one that cannot move.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TFMtUC4L4wMS4eeEqaNSR
2026-10-17 21:55:21 +00:00
MarcZX100 c56cafae2e fix(relinker): omit uncovered GNU RELRO ranges 2026-10-17 21:43:42 +00:00
milescovielloandClaude Opus 5.5 24ec391c06 fix(relinker): keep a segment's zero-filled tail zero when the next PT_LOAD starts on its page
On Linux the kernel maps each PT_LOAD from the start of its first page.
When a segment begins inside the page that holds the end of the previous
segment's zero-filled memory, that page is mapped again from the file, and
the bss tail reads whatever bytes precede the segment in the file. Nuvio
Max'd 0.5.27 (PPSA99288) keeps a mutex there and crashes at launch.

A segment whose page would read wrong bytes is now appended to the output
with that page prefix rebuilt from the segments below it. Outputs whose
pages already read right are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 18:41:25 +00:00
MarcZX100 55497ed3a4 fix(relinker): omit RELRO when lazy binding 2026-10-17 13:27:03 +00:00
MarcZX100 09bc5a1799 fix(relinker): preserve GNU stack and RELRO headers on Linux 2026-10-17 13:25:43 +00:00
Adrià 864729dc0d Merge pull request #6105 from Zinebyte/fix/macos-guest-weak-imports
fix(relinker): preserve weak imports in macOS guest modules
2026-10-17 12:44:41 +02:00
inmert f91e53d595 fix(relinker): list libc.prx with libkernel.prx in macOS executables 2026-10-17 14:06:01 +05:30
Dean 750eb13d87 Merge pull request #6401 from MarcZX100/codex/windows-tls-eof-read-6391
fix(relinker): guard TLS instruction byte access at EOF
2026-10-17 18:15:00 +13:00
Adrià a3250608a5 Merge pull request #6080 from Zinebyte/fix/linux-guest-weak-imports
fix(relinker): preserve weak imports in Linux guest modules
2026-10-17 06:53:43 +02:00
Dean e1ac3300d3 Merge pull request #6224 from Agnibha007/fix/linux-fixed-base-relocated-phdrs
fix(relinker): rebase the relocated program header table at a fixed Linux base
2026-10-17 14:41:25 +13:00
Adrià 8c90c879e0 Merge pull request #5990 from Get-fix/ps4/windows-libc-for-libkernel
fix(relinker): search libc.prx for libkernel-only Windows executables
2026-10-17 01:16:00 +02:00
Adrià c1d72d9335 Merge pull request #5890 from Piglit09/phase1/tls-protected-entry
fix(relinker): protect Windows TLS code entry roots
2026-10-17 00:15:50 +02:00
Adrià 383cb26339 Merge pull request #5614 from JJenkx/fix/linux-guest-finalizer-arguments
fix(relinker): clear Linux guest finalizer arguments
2026-10-16 21:23:12 +02:00
Karim Ibrahim 18ecee64d2 fix(relinker): leave weak imports of bundled modules unbound on Windows
Domain::GuestImport had no weak flag, so WindowsPePatcher handed every
import of a bundled module to the entry stub as a strong one, and a
weak import that no library exports stopped the title with
"unresolved ELF import". The executable's own weak imports already
bind to null there. libOSMesa.so.8 of the Quake homebrew has ten weak
imports that nothing provides, such as ZSTD_trace_compress_begin and
the SDK's __dlopen.

The guest relocation writer now records the ELF weak binding, and the
stub binds such an import to null when no library exports it.
2026-10-16 01:17:32 -04:00
Get-fix 8c34587598 fix(relinker): search libc.prx for libkernel-only Windows executables
AnyPS5 exports some libkernel functions, such as __error, from
libc.prx, which libkernel.prx links. On Linux they resolve through that
dependency. On Windows, the import stubs search only the listed
modules, and libc.prx was listed only when libSceLibcInternal.prx was
needed. A PS4 homebrew that needs libkernel.prx but no C library (the
OpenOrbis graphics sample) failed with "unresolved ELF import
9BcDykPmo1I". libc.prx is now also listed when libkernel.prx is needed.
PS5 executables need libSceLibcInternal.prx and convert unchanged.
2026-10-15 21:02:31 +03:00
Zinebyte 5c378ece37 fix(relinker): preserve weak imports in macOS guest modules 2026-10-15 13:25:46 -04:00
Werner 5aa9af5665 fix(relinker): keep unmapped gaps out of the Windows load image
WindowsLoadImage held one buffer spanning every PT_LOAD and BuildSections
copied gap pages into a section, so an image whose segments sit far apart
allocated the whole gap twice: a 32 KiB input with a 2 GiB gap needed 4 GiB
of memory and 30-40 s for --windows and --macos. Segment pages are now kept
in per-range blocks and an unmapped gap becomes a section with only a
virtual size. Output is byte-identical for the existing test inputs.
2026-10-15 16:36:28 +00:00
MarcZX100 2a65acd86c fix(relinker): guard TLS instruction byte access at EOF 2026-10-15 14:05:06 +00:00
Adrià f50d4335ab Merge pull request #5587 from nikowolf123/fix/relinker-dependency-diagnostics
fix(relinker): name missing and non-PE modules in Windows dependency diagnostics
2026-10-15 13:39:17 +02:00
David a56e9cc8db fix(relinker): rewrite ALU reads of guest TLS through %fs in macOS output 2026-10-15 15:32:47 +04:00
Adrià 341613ab62 Merge pull request #5543 from mariuszkreft/fix/gpu-extra-load-drops-guest-tail
fix(relinker): place the Linux extra PT_LOAD past the last guest page
2026-10-15 13:31:07 +02:00
David b689f49625 fix(relinker): skip prefixed decodings inside an earlier instruction in the macOS TLS scan
A function range that begins inside an instruction makes the code analysis
collect a second decoding from the middle of it. The Windows TLS rewriter
skips a non-FS segment-prefixed decoding there (90dcd6256); the macOS scan
did not, and refused the module. OpenSSL's assembly keeps its
"CRYPTOGAMS by <appro@openssl.org>" string in the code segment, where the
"en" of "openssl" decodes as a GS-prefixed instruction, so 24 catalog
titles could not be converted for macOS: "Unsupported macOS guest TLS
instruction (bytes: 65 6e)". The scan now skips such decodings as the
Windows rewriter does.
2026-10-15 13:21:07 +04:00
David f1735f59f7 refactor(relinker): grow a moved branch's displacement with resize
With the GS traps in WindowsTlsBuilder::Build, GCC 15.2 inlines this
vector insert differently and reports eight -Wstringop-overflow false
positives at it. resize appends the same four zero bytes and builds without
them.
2026-10-15 09:52:37 +04:00
Agnibha Mukherjee 8e5073ebe8 fix(relinker): rebase the relocated program header table at a fixed Linux base 2026-10-15 10:32:57 +05:30
Zinebyte 875a159f64 fix(relinker): preserve weak imports in Linux guest modules 2026-10-14 17:26:22 -04:00
David 4ceb020b55 fix(relinker): trap guest GS accesses in Windows output instead of refusing the module
On Windows the host owns GS (the thread environment block), so a guest
instruction that reads or writes through GS cannot be translated the way FS
thread-pointer accesses are. Such an instruction refused the whole module.
Overwrite it in place with ud2 and NOP padding instead, so the module converts
and the instruction reports itself through the crash reporter if it runs.
2026-10-15 01:01:58 +04:00
Adrià 358e218a4c Merge pull request #5083 from Dripl1x/codex/secondary-loadexec
fix(libSceSystemService): pass LoadExec arguments as the whole guest argv
2026-10-14 21:37:44 +02:00