Commit Graph

232 Commits

Author SHA1 Message Date
Dean 51f69aa218
Merge pull request #1586 from awake-devel/fix/relinker-keep-eh-frame-hdr
fix(relinker): keep PT_GNU_EH_FRAME in the relinked executable
2026-10-09 23:25:35 +13:00
Dean 2bf781eabb
Merge pull request #1856 from sarohy03/test/cli-args-coverage
test(relinker): cover CLI argument parsing
2026-10-09 22:41:25 +13:00
Dean b38abc0a69
Merge pull request #1774 from 011010/test/guest-intel-trampolines-e2e
test(relinker): execute the guest Intel trampolines end to end
2026-10-09 21:04:06 +13:00
Dean 7988ed27c9
Merge pull request #1510 from Kikoarl/fix/unique-test-temp-paths-cpu-topology-icon
test: give cpu topology and icon resource temp paths a random suffix
2026-10-09 21:03:51 +13:00
sarohy f765b27cc0 test(relinker): cover CLI argument parsing
Cli::ParseArgs had no test coverage: its only sibling test
(AutorunExitTests) exercises the autorun launcher, not the parser.

Add cli_args_tests covering every option and its side effects, the
--rpath and --exclude-sce-module value consumption (including that the
following token is taken verbatim rather than re-parsed as a flag), the
unused-filter value and single-specification validation, the
--exclude-sce-module/--skip-sce-module conflict in both orders, the
order-independent --windows-diagnostics/--windows-gui requirement on
--windows, unknown-option and extra-positional rejection, and the usage
message when an input or output path is missing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-09 02:40:19 +05:00
husari.orozco 4d13e99a0d test(relinker): execute the guest Intel trampolines end to end 2026-10-08 12:46:05 -06:00
Adrià 9e2ffe0da4
Merge pull request #1457 from drk1rd/fix/relinker-ud1-trap
fix(relinker): decode UD1 as a trap
2026-10-08 16:17:06 +02:00
Adrià 94d03f29fa
Merge pull request #1454 from mrk1987/fix/windows-internal-guest-libc
fix(relinker): resolve internal libc imports from guest libc
2026-10-08 16:07:33 +02:00
clem-gb d16cac0ab2 fix(relinker): keep PT_GNU_EH_FRAME in the relinked executable
The segment filter dropped every header in the PT_LOOS..PT_HIOS range,
which includes PT_GNU_EH_FRAME. The unwinders find the executable's
unwind tables through that header, so no C++ exception thrown in the
main executable could be caught on Linux.

The header is kept only when the output program header table still fits
in the input's table; otherwise it is dropped as before, with a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8
2026-10-08 15:47:39 +02:00
Adrià 63c57d2222
Merge pull request #1432 from ToyuAU/build/standalone-relinker
build(relinker): add a dependency-free conversion build mode
2026-10-08 15:43:51 +02:00
Adrià 033a46360d
Merge pull request #1424 from muhzain05/fix/relinker-jmprel-bounds
fix(relinker): bound the jump relocation table range
2026-10-08 15:39:32 +02:00
Adrià fd5f63a2d0
Merge pull request #1393 from xsvm/fix/relinker-rewriter-reference-sites
fix(relinker): classify rewrite reference sites with the instruction decoder
2026-10-08 15:03:48 +02:00
Adrià 2a906716f9
Merge pull request #1403 from overlordxrz-source/refactor/relinker-read-needed-once
refactor(relinker): read the executable's DT_NEEDED entries in one place
2026-10-08 15:00:52 +02:00
muhzain05 19f2fcf059 fix(relinker): bound the jump relocation table range
DT_JMPREL and DT_PLTRELSZ were never range-checked against the input
file. With DT_OS_JMPREL the offset is used raw, so an offset outside the
image reached BuildDynamicSection and CompactPlt. When DT_PLTRELSZ is
zero the per-entry loops never run, so nothing rejected the table and
the relink produced an output executable.

Validate the declared range with the subtraction-based check already
used for DT_STRTAB and DT_STRSZ, next to it and before the table is
read.
2026-10-08 05:25:08 -06:00
Gjon Gojcevic 90dcd6256c fix(relinker): tolerate unwind ranges that split an instruction
A static branch into a skipped function tail is accepted when an
instruction decodes there within its executable segment, so a range that
ends inside an instruction no longer stops code analysis.

The Windows TLS rewriter skips a non-FS segment-prefixed instruction that
starts inside an earlier collected instruction: it is an alternative
decoding from a range that begins mid-instruction, not a TLS access.
2026-10-08 13:20:32 +02:00
Dean Galvin 2096c66a91 revert: undo #1156's bundled libc lifecycle suppression
Since #1156 a title's bundled sce_module/libc.prx is loaded for its
exports but its init is suppressed, while titles still call its malloc,
which then returns NULL (#1500). On Linux, titles that bundle libc crash
at launch: one segfaults within 0.2 s, another stops with bad_alloc.

This reverts commit 2d6aff7a1e, reversing
changes made to e82e03f11e.
2026-10-08 23:49:41 +13:00
Kikoarl 319ac9ba78 test: give cpu topology and icon resource temp paths a random suffix 2026-10-08 12:40:39 +02:00
xsvm 22ebf5e608 fix(relinker): classify rewrite reference sites with the instruction decoder
ClassifyInstruction assumed a ModRM byte right after every opcode that
was not a near branch. A length-changing rewrite therefore adjusted
immediates such as MOVABS imm64 that looked like a RIP-relative ModRM,
and missed RIP-relative operands of VEX and 0F 38 / 0F 3A instructions
and the rel8 targets of LOOP and JRCXZ. Take the RIP-relative
displacement and branch target from DecodeInstruction instead.
2026-10-08 18:20:14 +08:00
Suryansh Prajapati 7a3ec9f015 fix(relinker): decode UD1 as a trap
UD1 (0F B9 /r) always raises #UD, like UD2, but DecodeInstruction
reported it as sequential. Reachability analysis then followed the
bytes after it, so an import reachable only through that fallthrough
was kept by the strict unused NID filter. UD1 keeps its ModRM, so a
RIP-relative operand is still reported.
2026-10-08 15:26:54 +05:30
Adrià 73ac9ef7f4
Merge pull request #1218 from hashaam1217/feat/relinker-rip-relative-stubs
feat(relinker): relocate RIP-relative operands into --to-intel stubs
2026-10-08 11:40:17 +02:00
Dean 1bd8f07ccd
Merge pull request #1317 from Dextroid17/fix/name-both-self-container-magics
fix(relinker): name the second SELF container magic as a SELF input
2026-10-08 22:36:28 +13:00
Dean 9e5ade70fb
Merge pull request #1381 from overlordxrz-source/fix/relinker-decoder-0f-no-modrm
fix(relinker): decode 0F A8-AA without a ModRM and MOV CR/DR without a memory operand
2026-10-08 22:35:44 +13:00
Dean a753d0de45
Merge pull request #1303 from overlordxrz-source/fix/relinker-evex-grp3-immediate
fix(relinker): do not add the F6/F7 TEST immediate to EVEX instructions
2026-10-08 22:35:39 +13:00
Adrià 0802d02713
Merge pull request #1242 from hashaam1217/fix/program-header-entry-size
fix(relinker): reject a program header entry size other than 56 bytes
2026-10-08 11:28:29 +02:00
Adrià 296d68a31d
Merge pull request #1238 from hashaam1217/fix/windows-overlapping-load-segments
fix(relinker): reject overlapping PT_LOAD segments before sizing the Windows image
2026-10-08 11:14:58 +02:00
Adrià 71a0eab968
Merge pull request #1233 from hashaam1217/feat/windows-tls-register-loads
feat(relinker): load Windows guest TLS values through register addresses
2026-10-08 11:11:10 +02:00
Hashaam Zafar a571a7f100 feat(relinker): relocate RIP-relative operands into --to-intel stubs
SHA-1 and SHA-256 instructions with a [rip+disp32] operand, and
instructions with one that a short site absorbs, now move into the
stub. The stub records each displacement as a relocation relative to
the site, and the Linux, guest and Windows placements resolve it once
the stub address is known. Indirect branches through [rip+disp32]
still fail the relink.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 11:10:38 +02:00
Adrià 2d6aff7a1e
Merge pull request #1156 from ahir061/fix/linux-bundled-libc-lifecycle
fix(relinker): suppress duplicate system library lifecycle
2026-10-08 11:03:20 +02:00
Adrià 0703d818d0
Merge pull request #1194 from ASVLCII/fix/relinker-input-validation-20261007
fix(relinker): reject incomplete RELA entries
2026-10-08 10:49:19 +02:00
Adrià 2959dc5318
Merge pull request #1168 from oguzhanozfe/fix/decoder-moffs-length
fix(relinker): decode the 64-bit address of MOV moffs instructions
2026-10-08 10:39:59 +02:00
Adrià Franch 402cd1545e test(relinker): give the lifecycle fixture a non-executable stack header
glibc 2.41+ refuses to dlopen a module without PT_GNU_STACK, so the native
part of guest_lifecycle_ownership failed on current distributions.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 10:27:52 +02:00
Adrià 8388121a4f
Merge pull request #1153 from ebarr24/codex/windows-gui-error-status
fix(relinker): preserve GUI startup failure status without stderr
2026-10-08 10:26:56 +02:00
Adrià 17440abe24
Merge pull request #1165 from oguzhanozfe/fix/linux-dynstr-runpath-size
fix(relinker): include the run path in the Linux DT_STRSZ
2026-10-08 10:25:19 +02:00
Adrià 61896dea23
Merge pull request #1163 from oguzhanozfe/fix/decoder-rexw-immediate-size
fix(relinker): let REX.W override 0x66 when sizing decoder immediates
2026-10-08 10:23:35 +02:00
Ahir Barman Maji b12022bb4e test(relinker): fix Windows lifecycle fixture build 2026-10-08 10:22:40 +02:00
Ahir Barman Maji 9517cc33f8 fix(relinker): suppress duplicate system library lifecycle 2026-10-08 10:22:40 +02:00
Adrià f51eeff059
Merge pull request #1117 from TideOPL/fix/relinker-tls-unreached-code
fix(relinker): find Windows guest TLS accesses in code no root reaches
2026-10-08 09:54:40 +02:00
mrk1987 2050d84595 test(relinker): isolate guest libc resolution coverage 2026-10-08 09:43:52 +02:00
mrk1987 b64bb679cc fix(relinker): resolve internal libc imports from guest libc 2026-10-08 09:23:13 +02:00
ToyuAU 2d59fffdb7 build(relinker): add a dependency-free conversion build mode 2026-10-08 18:21:30 +11:00
Adrià 66b8abd8e6
Merge pull request #1101 from eliasbruno124-dev/fix/relinker-windows-guest-filenames
fix(relinker): resolve Windows guest filename casing
2026-10-08 08:43:35 +02:00
Adrià 7a178e2276
Merge pull request #1089 from AaravMehta-07/fix/relinker-registry-json
fix(relinker): escape control characters in call registry JSON
2026-10-08 08:10:07 +02:00
Adrià Franch 4e69584edf test(relinker): pin RELA bounds check with malformed-ELF cases
Co-authored-by: Dextroid17 <noreply@github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 07:52:32 +02:00
Fynn Jannis Schulz 9ff9d4325c fix(relinker): share RELA entry bounds check with extractRelative 2026-10-08 07:52:23 +02:00
Fynn Jannis Schulz cfba9c09d2 fix(relinker): overflow-safe RELA entry bounds check 2026-10-08 07:52:23 +02:00
Dean 4a435af58a
Merge pull request #1103 from ctz23/test/windows-icon-distinct-output-20261007
test(relinker): use distinct executables in Windows icon tests
2026-10-08 18:28:01 +13:00
overlordxrz-source cd51d8b1bf refactor(relinker): read the executable's DT_NEEDED entries in one place 2026-10-07 22:31:35 -04:00
overlordxrz-source e66d78c626 fix(relinker): decode 0F A8-AA without a ModRM and MOV CR/DR without a memory operand
PUSH GS, POP GS and RSM (0F A8, 0F A9, 0F AA) have no ModRM byte, but fell in the 0F A3-AB ModRM range, so the decoder read the next byte as a ModRM and sized its displacement. MOV to and from control and debug registers (0F 20-23) ignore the ModRM mod field and always name a register, but were sized and reported as memory forms, including a RIP-relative disp32 for mod 00 r/m 101.
2026-10-07 21:14:30 -04:00
Dextroid17 9fce570e95 fix(relinker): name the second SELF container magic as a SELF input
ElfReader::ReadHeader names 0x1D3D154F as a SELF container, but dumps also
carry a second container magic, 0xEEF51454 (bytes 54 14 f5 ee), which fell
through to "Invalid ELF magic number: 54 14 f5 ee". That message reads as a
corrupt input rather than an encrypted one, so a user cannot tell that
decryption is what stands between them and a relink.

Both magics now report the SELF message. Measured on two retail dumps:
PPSA03671's eboot.bin and libcohtml.Prospero.prx are 54 14 f5 ee; PPSA28997's
eboot and modules are 4f 15 3d 1d.

Tested: Linux (CachyOS, GCC, Release, BUILD_TESTING=ON), relinker rebuilt. The
new case fails on the revert of the reader change with the exact message above
and passes with it; elf_header, elf_offsets, dynamic_segment,
string_table_bounds, guest_needed_modules, guest_module_directories and
linux_load_alignment still pass.
2026-10-07 19:28:04 -04:00
overlordxrz-source f4ef1cd6ec fix(relinker): do not add the F6/F7 TEST immediate to EVEX instructions
The decoder adds the TEST immediate of opcodes F6 and F7 when ModRM.reg
is 0 or 1. The check excluded VEX and two-byte opcodes but not EVEX, so
an EVEX.0F F6 (VPSADBW) whose ModRM.reg is 0 or 1 was given an extra
imm8 and decoded one byte too long. VPSADBW has no immediate (Intel SDM
Vol. 2B, VPSADBW).
2026-10-07 18:51:05 -04:00