Commit Graph
887 Commits
Author SHA1 Message Date
Dean 59d53d0d31 Merge pull request #8757 from Nejilu/codex/relinker-tls-file-bounds
fix(relinker): reject TLS initialization images outside the input file
2026-10-21 15:27:20 +13:00
Dean b2d804d5f7 Merge pull request #8738 from Queuse/codex/fix-registry-utf8
fix(relinker): reject invalid registry UTF-8
2026-10-21 15:27:16 +13:00
Dean 6056689ad6 Merge pull request #8614 from DavidSamir/fix/relinker-call-zero-padding
fix(relinker): stop the control-flow walk at zero padding after a call
2026-10-21 15:27:12 +13:00
Nejilu 9fb55e186d fix(relinker): reject TLS initialization images outside the input file 2026-10-21 01:45:30 +02: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
Queuze 41cd0435ec fix(relinker): reject invalid registry UTF-8 2026-10-20 20:07:16 -03:00
Dean c6145997ef Merge pull request #8270 from thuanquang/fix/relinker-module-name-input-path
fix(relinker): name the guest module in its output filename errors
2026-10-21 09:39:58 +13:00
Dean 29e4c46b4d Merge pull request #7417 from IshmamDC217/feat/relinker-trace-imports-linux
feat(relinker): support --trace-imports for Linux output
2026-10-21 09:03:29 +13:00
David 24c5c8ed5f test(relinker): convert a call before zero padding and a misread FS byte for Windows and macOS 2026-10-20 22:17:45 +04:00
David c978e4d4c4 test(relinker): keep falling through calls that end at a boundary or before non-zero bytes 2026-10-20 22:17:44 +04:00
David c139a3faf2 test(relinker): stop at zero padding after direct and indirect calls 2026-10-20 22:17:43 +04:00
David 95db1ab6e6 fix(relinker): stop the control-flow walk at zero padding after a call 2026-10-20 22:17:42 +04:00
javierUDP 2775e72bf0 fix(relinker): trim only an interpreter path at the start of the segment
Trimming the end of any PT_INTERP inside an executable segment dropped
the code in front of one that follows it, so an image without an SCE
block whose interpreter sits after its code lost its entry points. The
trim now applies to an interpreter that starts the segment, and the SCE
path keeps taking any interpreter inside the scanned range, as before.
2026-10-20 14:56:41 -03:00
javierUDP cc69253830 fix(relinker): keep the interpreter path out of the scanned code
The code analysis trims an interpreter path from the start of an
executable segment only for images that have a PT_SCE_DYNLIBDATA block.
An executable without one keeps that path in the scanned range, so
/libexec/ld-elf.so.1 is walked as code: a RELATIVE relocation with
addend 0 roots the control flow graph at the first byte of the segment,
and the 0x64 of "ld-elf" decodes as an FS-prefixed instruction that the
Windows and macOS TLS rewriters refuse. The trim now runs for both
layouts, ending at the segment for an image without the block.
2026-10-20 14:56:20 -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 892a4f1328 Merge pull request #7993 from MarrasFederico/fix/relinker-windows-trampoline-builder-guards
fix(relinker): validate Windows trampoline section placement and sites
2026-10-21 06:30:55 +13:00
Dean b9731811ba Merge pull request #8001 from mopga/fix/relinker-amd-only-claimed-followers
fix(relinker): do not take instructions another AMD-only stub moved as a short instruction's followers
2026-10-21 06:30:39 +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
Dean 989b6ea794 Merge pull request #7999 from mopga/fix/relinker-amd-only-sequence-in-place
fix(relinker): move in-place AMD-only replacements into a short instruction's stub
2026-10-21 06:19:51 +13:00
Dean 2fee39f1b3 Merge pull request #6684 from SandstromPL/fix/relinker-guest-zero-init
fix(relinker): run a guest DT_INIT of 0 as the module initializer
2026-10-21 06:07:25 +13:00
Dean 1b08a33b12 Merge pull request #8548 from tkcm01/fix/windows-icon-utf8-path
fix(relinker): format invalid Windows icon paths as UTF-8
2026-10-21 05:47:06 +13:00
thuanquangandClaude Opus 5.5 d896645ec7 fix(relinker): name the guest module in its output filename errors
The checks on a guest module's output name threw without an input
path, so the conversion's catch reported the main executable. They now
carry the module's path, as the guest image reader's errors do. The
loop's duplicate-export check gets the same change for consistency; it
cannot fire, because the reader rejects a duplicate first.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 23:45:00 +07:00
Dean 6bef96df7c Merge pull request #8168 from savvaniss/fix/relinker-trailing-table-before-code
fix(relinker): accept a relative jump table padded to 16 bytes before more code
2026-10-21 05:17:27 +13:00
Dean ab07854a58 Merge pull request #8166 from savvaniss/fix/sce-gap-syscall-data
fix(relinker): treat data between PS4 unwind functions as data in the syscall scan and the code roots
2026-10-21 05:17:04 +13:00
tkcm01 4d07bc0231 fix(relinker): format invalid Windows icon paths as UTF-8 2026-10-20 12:10:00 -04: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
Adrià 7d9372b77c Merge pull request #7740 from whamre/fix/windows-lazy-zero-fill-v2
fix(relinker): keep zero-filled PT_LOAD memory out of the Windows loa…
2026-10-20 15:41:27 +02: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 SpyrosandClaude Opus 5.5 fb050223dd fix(relinker): keep padding to the range end and check what the function still covers
Check padding up to the end of the inspected range first, as before, and
use the 16-byte boundary rule only when that fails, so a long NOP that
crosses the boundary no longer rejects the table. Check the bytes the
function's own unwind range still covers after the table, so a table cut
short inside its function is rejected again.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 15:26:15 +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
Savvanis SpyrosandClaude Opus 5.5 e0230e6a75 fix(relinker): skip syscall bytes without a syscall number between PS4 unwind functions
Between the unwind functions of a PS4 image the bytes are not known to be
code, and read-only tables there can hold 0f 05. Outside the unwind
functions a syscall, sysenter, int 0x80 or sysret pattern now fails the
relink only when a constant syscall number is loaded right before it; the
others are skipped and counted in one message. Inside the unwind functions
and in other images every such instruction still fails.

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
Adrià 77c18cefae Merge pull request #6903 from Zinebyte/fix/guest-unused-import-dependencies
fix(relinker): infer guest dependencies from referenced imports
2026-10-20 11:08:47 +02:00
Adrià 3d54c5b2b2 Merge pull request #6448 from DavidSamir/fix/relinker-macos-empty-tls
fix(relinker): convert stack-guard and thread-pointer reads with an empty PT_TLS for macOS
2026-10-20 10:40:07 +02:00
Adrià 5e7c618699 Merge pull request #6607 from jweidenh/codex/overlapping-rela-tables
fix(relinker): handle overlapping relocation tables
2026-10-20 10:38:40 +02:00
Dean b9ff25b787 Merge pull request #8197 from JJenkx/windows/relinker-tests-exited-module-cleanup
test(relinker): retry removing fixtures an exited Windows program still holds
2026-10-20 18:31:23 +13:00
Dean a9f1341b62 Merge pull request #8179 from JJenkx/windows/relinker-diagnostics-fixture-retry
test(relinker): wait for the exited diagnostic runner to release its fixtures
2026-10-20 18:31:19 +13:00
Dean 13d5f0e884 Merge pull request #8024 from MarrasFederico/test/relinker-trap-runs-without-core-dumps
test(relinker): run the outputs that stop at int3 without a core dump
2026-10-20 17:55:31 +13:00
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
JJenkxandClaude Opus 5.5 a3ac9fd9e4 test(relinker): retry removing fixtures an exited Windows program still holds
windows_named_imports, windows_trace_imports, windows_guest_weak_imports and
guest_module_identity run converted programs that stop on a missing import,
then remove their temporary directory. Windows keeps the modules of such an
exited process open for a short time after the process handle is signaled, so
under parallel ctest the removal fails with PermissionError on a .prx that
program loaded: with Defender real-time protection off, 3 or 4 of these tests
failed in each of three runs of ctest --repeat until-fail:10 -j 16 over the 69
tests that run converted programs.

Add fixture_directory to guest_import_fixtures, a temporary directory whose
removal retries on PermissionError for at most 10 s, and use it in the four
tests. Their checks are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 22:14:40 -04:00
JJenkxandClaude Opus 5.5 92ea0b9ce3 test(relinker): wait for the exited diagnostic runner to release its fixtures
windows_dependency_diagnostics rewrites the fixture images right after the
diagnostic runner exits. The runner ends with an unhandled RaiseException of
STATUS_DLL_NOT_FOUND, and Windows fault handling keeps the exited process's
image files open for a short time after its handle is signaled: on Windows 11
22621 the Restart Manager names the exited runner as the holder and the file
opens 37 to 153 ms later. The rewrite then fails with ERROR_SHARING_VIOLATION,
and the final removal of the fixtures with access denied. Retry opening a
fixture while it fails with a sharing violation and the removal while it fails
with access denied, for at most 10 s each; every other failure still fails the
test at once.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 21:45:35 -04:00
Adrià 7e12b3da80 Merge pull request #7736 from jotitadev/fix/relinker-desktop-entry-test-unique-dir
test(relinker): give the desktop entry test its own temporary directory
2026-10-20 03:13:23 +02:00
Savvanis SpyrosandClaude Opus 5.5 4aadd19659 fix(relinker): accept a relative jump table padded to 16 bytes before more code
FindTrailingRelativeJumpTable accepted a jump table after a function's
code only when padding followed it up to the end of the inspected range.
A PS4 function's table can end past its FDE, be padded to the next
16-byte boundary and be followed by more code before the next FDE. The
table is now accepted when padding reaches that boundary; it then ends
there, so the code after it is still analysed as code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 04:07:56 +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
Adrià cb89266437 Merge pull request #7519 from Destroyers212x/test/macos-load-under-rosetta
test(relinker): run the macOS guest module argument check under Rosetta
2026-10-20 00:35:22 +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
Adrià 7c43dc6bfc Merge pull request #7453 from Agnibha007/fix/unused-filter-fallthrough-padding-abort
fix(relinker): stop the unused-filter CFG walk before trailing zero padding
2026-10-19 23:51:02 +02:00
Adrià dd4c2a413b Merge pull request #7418 from tkcm01/fix/relinker-backup-copy-export-aliases
fix(relinker): allow Windows export aliases when probing backup copies
2026-10-19 21:51:59 +02:00