Commit Graph

443 Commits

Author SHA1 Message Date
Tomás Ortellado 9f9e4e28b8 fix(relinker): reject invalid and overflowing alignment 2026-10-05 08:44:55 -03:00
Dean Galvin 7103f390cf fix(relinker): keep the host libc.prx needed on Linux when a title bundles its own
A title that ships sce_module/libc.prx makes addHost drop the host
libc.prx from the executable's dependencies. Every host prx needs it, but
their DT_RUNPATH is empty, so loading fails with "libc.prx: cannot open
shared object file".

Mirror the Windows rule from WindowsImportBuilder: when libSceLibcInternal.prx
is a host dependency and no host libc.prx remains, append libc.prx as the
last host dependency. The title's own imports still bind to the guest
modules first.

Refs #476
2026-10-05 20:36:29 +13:00
Nicolas Abosch 93efde8056 fix(relinker): merge function symbol alias extents 2026-10-05 01:50:14 -03:00
NumberGuan 75f407b926 fix(relinker): discover bundled modules in prx directories
Preserve each bundled module directory under app0 and resolve Linux dependencies across directories. Add integration coverage for both output formats and Windows startup. Refs #556; duplicate-export rejection remains unchanged.
2026-10-04 23:22:50 -03:00
Dean bc0726c486
Merge pull request #583 from DiulioAires/fix/bytewriter-bounds
fix(relinker): check byte writer bounds
2026-10-05 14:30:37 +13:00
DotDebian e11b4b5554 feat(relinker): lower SHA-1 instructions with a memory operand
SHA1RNDS4/NEXTE/MSG1/MSG2 with a memory source made `--to-intel` fail
the whole relink. The stub now spills a scratch xmm, loads the operand
into it with the unaligned load already used for SHA-256 and runs the
register-form lowering. The SHA1RNDS4 immediate is read after the SIB
byte and displacement. RIP-relative operands still fail: the stub runs
at a different address.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 02:02:13 +02:00
Dean d220149542
Merge pull request #299 from Pouare514/fix/relinker-tls-tail
fix(relinker): tolerate trailing data in TLS scan
2026-10-05 12:44:41 +13:00
DiulioAires b6c97084ed fix(relinker): check byte writer bounds 2026-10-04 20:17:21 -03:00
Pouare514 0b5fe3c23c fix(relinker): detect FS-prefixed previous instruction via SegmentPrefix decode 2026-10-05 00:56:11 +02:00
Pouare514 49feb79476 fix(relinker): scan overlapping span from address and cover FS-prefixed previous instruction 2026-10-04 15:41:17 +02:00
Pouare514 52587f8cf1 fix(relinker): tolerate trailing data in TLS scan 2026-10-04 15:27:57 +02:00
QDarkRex 47f0bf93ef fix(relinker): identify unsupported Windows TLS instructions
The unsupported-instruction error now lists the instruction bytes, and the relink failure names the input file, the main executable or the guest module, on an extra Input: line.
2026-10-04 19:09:10 +07:00
Dean 9f9a8f5a53
Merge pull request #340 from QDarkRex/fix/relinker-tls-fs-disp32
fix(relinker): load Windows guest TLS values at signed displacements
2026-10-04 20:39:50 +13:00
Dean 8a64778581
Merge pull request #486 from RomainROCH/codex/fix-executable-segments
fix(relinker): validate all executable segments and preserve live imports
2026-10-04 20:09:49 +13:00
Dean 3237b6b548
Merge pull request #484 from RomainROCH/codex/fix-elf-string-bounds
fix(relinker): bound dynamic strings by the declared table size
2026-10-04 20:09:33 +13:00
QDarkRex ab5c339039 fix(relinker): reject guest TLS loads from unmodelled control block fields
Loads at fs:1 through fs:0x27 read tcb_dtv and tcb_thread on the FreeBSD layout, which the Windows thread control block does not model, so they returned zero. Accept only the TLS block, fs:0 and the stack guard at fs:0x28, and fail the relink for the rest.
2026-10-04 14:09:19 +07:00
Adrià Franch 5fc16a9548 feat(relinker): lower SHA-256 instructions with a memory operand
SHA256RNDS2/MSG1/MSG2 with a memory source made `--to-intel` fail the
whole relink. The stub now spills a scratch xmm, loads the operand into
it with MOVDQU (AMD does not fault on a misaligned SHA operand, so the
unaligned load keeps that behaviour) and runs the register-form
lowering. RSP-based operands get the spill depth added to their
displacement. RIP-relative operands still fail: the stub runs at a
different address.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 08:21:40 +02:00
RomainROCH a35e0cfc84 test(relinker): register segment coverage beside load alignment checks 2026-10-04 05:59:16 +02:00
RomainROCH 85d036ca19 perf(relinker): reuse each segment scan across import records 2026-10-04 05:37:13 +02:00
QDarkRex d8684cb184 test(relinker): add C++ unit test for WindowsIconResourceBuilder 2026-10-04 10:29:20 +07:00
QDarkRex 9642d1b3b0 fix(relinker): add icons to generated Windows executables 2026-10-04 10:29:20 +07:00
RomainROCH 328def4bab fix(relinker): validate all executable segments and preserve live imports 2026-10-04 05:26:01 +02:00
RomainROCH e63524ae34 fix(relinker): bound dynamic strings by the declared table size 2026-10-04 05:23:18 +02:00
Dean Galvin 097566d547 fix(relinker): lower VRSQRTPS and VRCPPS to correctly rounded results for --to-intel
RSQRTPS and RCPPS are approximations whose low bits differ between Intel
and AMD. Intel returns 0x3F7FF000 for 1/sqrt(1.0), and two Newton-Raphson
steps on it settle on 0.99999994 instead of 1.0. PPSA21564 renormalises
its spring quaternions that way: an identity quaternion keeps w at
0.99999994 with a zero axis, its axis-angle conversion then normalises the
zero axis into NaNs, and the NaN bone poses reach keyframed physics bodies.
A NaN body later moves to an invalid broadphase cell and the game crashes
a few seconds into its hub level.

--to-intel now replaces the VEX.128 register forms with an out-of-line stub
that computes 1/sqrt(x) with SQRTPS and DIVPS (1/x with DIVPS), keeping
the upper half of the destination cleared and the scratch register intact.
A site with no room for the jump, including one followed by a branch
target or a RIP-relative instruction, keeps the native instruction and is
reported as kept instead of failing the relink.
2026-10-04 14:40:16 +13:00
Dean 40a9e455ea
Merge pull request #430 from adriadam10/feat/relinker-sha1-lowering
feat(relinker): lower SHA-1 instructions for --to-intel
2026-10-04 14:14:08 +13:00
Dean d43b12c34e
Merge pull request #433 from adriadam10/fix/relinker-sse4a-upper-qword
fix(relinker): zero dst[127:64] in EXTRQ and INSERTQ lowerings
2026-10-04 14:05:41 +13:00
Dean 40b1c7a6f9
Merge pull request #432 from adriadam10/fix/relinker-vex-rip-relative
fix(relinker): report RIP-relative operands of VEX, EVEX and 0F38/0F3A instructions
2026-10-04 14:05:25 +13:00
Adrià Franch b066079628 fix(relinker): zero dst[127:64] in EXTRQ and INSERTQ lowerings
The APM leaves bits 127:64 of the destination undefined after EXTRQ and
INSERTQ, but hardware zeroes them, and the register-form INSERTQ stub
already does the same (#185). The other paths kept the old high qword, so
a following register-form INSERTQ that reads its length and index from
that qword computed the wrong low qword too.

Every stub path that left the high qword now ends with movq dst, dst.
The in-place PSRLQ, PMOVZX and PBLENDW forms leave it non-zero and have
no room for the movq, so those sites now take a stub. The two in-place
forms that emitted nothing now emit movq dst, dst.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-03 08:21:33 +02:00
Adrià Franch ee3b215f33 fix(relinker): report RIP-relative operands of VEX, EVEX and 0F38/0F3A instructions
DecodeInstruction returned before the ModRM byte for VEX and EVEX and
read the third opcode byte of 0F 38/0F 3A as ModRM, so their
RIP-relative operands were never reported. --to-intel then moved such an
instruction after a short EXTRQ/INSERTQ into the stub with its
displacement unchanged, and the strict unused-import filter missed its
references.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-03 08:10:29 +02:00
Adrià Franch 71ca3ff4b8 feat(relinker): lower SHA-1 instructions for --to-intel
SHA1RNDS4, SHA1NEXTE, SHA1MSG1 and SHA1MSG2 passed through --to-intel
unchanged, so a relinked title that executes them faults on Intel CPUs
without SHA-NI. Their register forms are now lowered out of line with
SSE2 only through the shared stub builder; short sites share stubs via
MatchSequence. Memory forms fail the relink with the file offset, as for
SHA-256.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-03 07:40:41 +02:00
Dean Galvin d8b8aafc65 fix(relinker): hand the guest the real argv on Linux
The Linux entry stub built a copy of the entry parameter block holding
argc and a pointer to the host argv array, so the guest read that pointer
as argv[0] and uninitialised stack as argv[1..]. The process stack at
entry already has the guest's layout (argc as a qword, then the argv
pointers and a null), so pass rsp itself.

Test: linux_entry_argv relinks a fixture whose entry checks argc and
argv and runs the output on Linux x86-64.
2026-10-03 13:40:06 +13:00
QDarkRex 508a9710ae fix(relinker): report TLS bounds failures at file offsets 2026-10-02 16:14:54 +07:00
QDarkRex 102e042a49 fix(relinker): bound guest TLS loads to the thread block 2026-10-02 15:45:50 +07:00
QDarkRex 721984a28f fix(relinker): load Windows guest TLS at signed displacements 2026-10-02 15:19:25 +07:00
boykopovar c00bc19c0d
Merge pull request #222 from YossiYad/feat/windows-tls-load-registers
feat(relinker): load the fs:[0] thread pointer into any register in Windows guest code
2026-10-02 10:06:12 +03:00
Yossi Yadgar 53d4ef41d2 feat(relinker): load the fs:[0] thread pointer into any register in Windows guest code 2026-10-01 18:42:14 +03:00
ljkx d54dfb1595 fix(relinker): ignore a REX prefix that is followed by another prefix
In 64-bit mode a REX prefix only takes effect when it immediately
precedes the opcode; a REX followed by a legacy prefix or another REX is
ignored. The instruction decoder, the rewriter's reference classifier,
DecodedInstruction and the SSE4a, SHA-256 and CLZERO operand decoders
read legacy prefixes and then at most one REX. `48 F3 0F 2B 00`
(MOVNTSS) was therefore scanned as `[48 F3][0F 2B 00]` and kept, and
`48 67 0F 01 FC` lost its address-size prefix.

All of them now accept REX bytes among the prefixes and keep only one
that directly precedes the opcode. The converter's guard against
prefix-only fragments is removed, since the decoder no longer produces
them, and the TechnicalDebt entry describing the split is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:09:11 +02:00
ljkx 09cb86b076 feat(relinker): lower CLZERO for --to-intel
Lower CLZERO out of line instead of failing the relink: the 64-byte line
containing rAX (EAX with 67h) is cleared with four MOVNTDQ stores of
zero, the same non-temporal, weakly ordered store. The line address is
masked in xmm0 so RFLAGS stays untouched; xmm0 and rcx are spilled below
the red zone. Short sites share stubs through MatchSequence. CLZERO with
LOCK, an FS/GS override, a 66/F2/F3 prefix or longer than 15 bytes fails
the relink.

The decoder splits a REX followed by another prefix into a separate
instruction, which would hide a prefix that changes what CLZERO or the
next instruction does. The converter now fails the relink when such a
prefix-only fragment directly precedes an AMD-only instruction or would
be moved into a stub as a trailing instruction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:30:35 +02:00
boykopovar c7fb2575a3
Merge pull request #208 from boykopovar/refactor/split-libs-tests-cmake
Refactor/split libs tests cmake
- Moved test inclusions from `core/libs/CMakeLists.txt` to local library CMakeLists.txt files.
- Created CMakeLists.txt files for `libSceSystemService, libSceContentExport, libSceNet, libSceNetCtl, libSceRandom, libSceRtc, libSceJson2, and libSceFiber`.
- The shared libSceNet/libSceNetCtl test is included in libSceNet.
- Added the shared function add_test_executable for hosting test executables.
- Added add_png_decoder(target runtimeTarget) and add_jpeg_decoder(target runtimeTarget). The runtimeTarget parameter is required; libc is currently passed. A non-existent target causes a CMake error. - The decoder is used by the PRX libraries, meaning exceptions from there should be thrown through our libc.prx.

Changed file locations relative to the build folder (previously they were stored in core/libs):
- tests/ - all test executables
- `core/libs/libs/implib/` - PRX import libraries (*.dll.a)

The number of tests found has not changed (88)
2026-10-01 12:55:05 +03:00
boykopovar f694c1387c
Merge pull request #201 from ljkx/feat/monitorx-mwaitx-to-intel
feat(relinker): lower MONITORX and MWAITX for --to-intel
2026-10-01 12:50:04 +03:00
boykopovar 61ba4d661a refactor(cmake): place all test executables in build tests directory 2026-10-01 12:28:06 +03:00
SamG-Coder ad6b37ed42 fix(relinker): resolve guest dependencies and lifecycle arrays 2026-10-01 11:57:13 +03:00
SamG-Coder 3c5fe188b7 fix(relinker): forward Windows arguments to guest startup 2026-10-01 11:57:13 +03:00
Yossi Yadgar 058ba1e08d fix(relinker): name the SELF container and the bytes read when the input is not an ELF 2026-10-01 11:47:55 +03:00
ljkx f994b4f89f feat(relinker): lower MONITORX and MWAITX for --to-intel
Replace MONITORX with a NOP and MWAITX with PAUSE in place, padded with
NOPs to the original length, instead of failing the relink. MWAITX may
return before its timer or a store to the monitored line, and without an
armed monitor it does not wait, so callers already re-check their
condition; the replacement takes that path every time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:35:23 +02:00
boykopovar 261272909c
Merge pull request #200 from ljkx/feat/sha256-to-intel
feat(relinker): lower SHA-256 instructions for --to-intel
2026-10-01 11:31:02 +03:00
boykopovar a7fdb497fe
Merge pull request #195 from MichonGoddijn231849/fix/guest-module-tls
fix(relinker): give Windows guest modules with TLS an import directory
2026-10-01 11:15:39 +03:00
ljkx e66b0b34d7 feat(relinker): lower SHA-256 instructions for --to-intel
Lower SHA256RNDS2, SHA256MSG1 and SHA256MSG2 (register forms) out of line
with legacy SSE2 instructions only, so relinked code no longer needs
SHA-NI. Consecutive short SHA-256 and SSE4a sites share one stub. The
SSE4a stub builder moves to StubBodyBuilder for reuse; IsShaNi now also
recognises SHA256RNDS2 (0F 38 CB). Memory operand forms fail the relink.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:20:43 +02:00
Michon d29a1296cd fix(relinker): give Windows guest modules with TLS an import directory
The Windows loader sets up TLS for a dynamically loaded DLL only when it snaps
the DLL's imports. Guest modules had no import directory, so their TLS
directory was never processed: every guest module kept TLS index 0 and read
and wrote the executable's TLS block. A guest libc's thread-locals (gmtime's
buffer at +0x39c in Marvel's Wolverine) then ran past the executable's
0x150-byte block into the process heap, and corrupted a loader node that
crashed the next thread start in ntdll. Guest modules with TLS now import from
KERNEL32, as the executable does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 22:47:50 +02:00
Alberto Ruiz 46e63f2ec1 fix(relinker): keep ELF bounds checks from overflowing
ElfReader checked ranges as offset + size > buffer size. An offset near
UINT64_MAX wrapped the sum, passed the check and read outside the buffer,
which AddressSanitizer reports as a heap-buffer-overflow. The relinker
then failed later with unrelated messages built from the stray bytes.
The checks now compare without adding to the offset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
2026-09-30 21:06:43 +02:00
boykopovar f59c867a5b
Merge pull request #183 from arreina/fix/elf-header-size
fix(relinker): require a full ELF64 header before reading it
2026-09-30 22:03:27 +03:00
boykopovar a54cffadc3
Merge pull request #190 from RomainROCH/fix/buffer-offset-overflow
fix(relinker): reject overflowing buffer offsets
2026-09-30 22:00:51 +03:00
Alberto Ruiz a4b131435a fix(relinker): require a full ELF64 header before reading it
ReadHeader reads fields up to offset 0x40 but only rejected files
shorter than 20 bytes, so a truncated ELF failed with
"FileByteOffset out of bounds" instead of "File too small for ELF header".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
2026-09-30 18:47:32 +02:00
RomainROCH 442ffbb936 chore: sync upstream main for CI 2026-09-30 18:37:59 +02:00
boykopovar 60bd808132
Merge pull request #185 from ljkx/feat/insertq-register-form
feat(relinker): lower register-form INSERTQ
2026-09-30 19:37:18 +03:00
boykopovar a6c7eca552
Merge pull request #151 from MartinCajiao/feat/guest-intel-trampolines
feat(relinker): support Intel trampolines in guest modules
2026-09-30 19:24:46 +03:00
RomainROCH b6ff4a2116 fix(relinker): reject overflowing buffer offsets 2026-09-30 18:07:26 +02:00
boykopovar fc7f1e7fd1
Merge pull request #140 from SamG-Coder/codex/windows-startup-unwind
fix(relinker): align Windows startup unwind metadata
2026-09-30 18:59:23 +03:00
boykopovar 40774fb87b
Merge pull request #85 from OverkillLabs/fix/pe-got-dir64-reloc
fix(relinker): write lazy-stub GOT slots as DIR64 preferred-VA
2026-09-30 17:48:25 +03:00
ljkx 9d110245fe feat(relinker): lower register-form INSERTQ
Lower INSERTQ xmm1, xmm2 (F2 0F 79) out of line with SSE2 only instead of
failing the --to-intel relink. Length and index are read from bits 69:64
and 77:72 of the source; dst[127:64] is zeroed as on hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:18:02 +02:00
MartinCajiao 671b8c6291 feat(relinker): support Intel trampolines in guest modules 2026-09-29 18:24:00 -05:00
STL1te 6b36c050fe style: drop the branch's code comments per CONVENTIONS.md
Only the lines this branch added lose their comments; the commits before
keep them, with the reasoning behind each change, for whoever digs into
that code later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:25:29 +03:00
STL1te f4f8d5bbce feat(relinker): exclude single sce_module files, tolerate a zero code tail
- --exclude-sce-module <file> (repeatable) drops one title module from
  guest conversion, e.g. a title libc.prx, while the rest of sce_module
  is still relinked as guest modules
- the instruction scanner stops at zero padding that ends a code segment
  with an odd byte instead of failing on a truncated `add [rax], al`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:22:11 +03:00
OverkillLabs 7dedb2e607 style(relinker): drop inline rationale comment per CONVENTIONS.md
The project's coding conventions restrict inline comments to
technical-debt markers, #endif, and namespace-close trailers. Remove
the explanatory comment on writeGotStub's DIR64 write; the same
rationale (why the slot must hold the preferred-VA form, and why the
base-relocation pass was moved after lazy-stub writes) is already
captured in the fix(relinker) commit message and PR description.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:16:05 +03:00
SamG-Coder e211a2fe6f fix(relinker): align Windows startup unwind metadata
(cherry picked from commit a720b85866bdf77f836bcb344f5be806a12d5106)
2026-09-29 10:46:10 +10:00
boykopovar 6742ecf70f fix(relinker): use app0 guest module layout and clarify output diagnostics 2026-09-29 02:05:02 +03:00
SamG-Coder ee57519cb0 fix(relinker): decode EMMS without a ModRM byte 2026-09-29 07:39:01 +10:00
OverkillLabs 2c2fd2cd5d fix(relinker): write GOT stub slots as DIR64 preferred-VA
The Windows PE lazy-import GOT slot was written as a bare 4-byte RVA,
but the .reloc entries generated for the .gtls/data sections use
IMAGE_REL_BASED_DIR64, which only adds the load delta to whatever is
already stored at the slot. A bare RVA therefore resolved at runtime
to (loadBase - ImageBase + rva) instead of the intended stub address,
pointing into unmapped memory whenever the module was not loaded at
its preferred base.

Write the full 8-byte preferred-VA form (ImageBase + stubRva) instead,
matching DIR64 semantics, and generate a base relocation entry for
each lazy-stub GOT slot. The .reloc section is now built after the
lazy stubs are written into their target sections rather than before,
since it previously captured only the relocations known at that
point and missed the newly patched slots entirely.
2026-09-28 12:44:36 +03:00
Claude 210987745c
Merge upstream main into fix/audit-2026-09
Resolve conflicts with boykopovar/AnyPS5#10 (sce module loading) and
later upstream changes.

- Pthread Cond/Mutex: take upstream. It already releases mutex
  ownership across condition waits, returns ETIMEDOUT 0x8002003C, and
  rejects unlocks from non-owners for every mutex type.
- Pthread Thread: keep upstream's lifecycle, Windows adoption and job
  affinity; re-apply the POSIX fixes on top: reference-counted
  release on join/detach/exit, self-join rejection on both platforms,
  and scePthreadSelf adoption for threads not created by
  scePthreadCreate.
- Semaphore: keep upstream's TimedWait::Condition and wait tracing;
  re-apply sceKernelDeleteSema waking waiters with EACCES.
- Relinker: keep --windows-gui alongside upstream's --skip-sce-module,
  trampoline-aware Patch signature and new Python tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
2026-09-28 07:34:25 +00:00
boykopovar a6bb98d4d5
Merge pull request #54 from oneandonlydean/feat/extrq-register-form
feat(relinker): lower register-form EXTRQ and relocate following instructions for short sites
- **Lowering:** register-form EXTRQ is emitted out of line with SSE2 only. Two scratch XMM registers (distinct from both operands) are spilled; one gets the index (`src >> 8 & 63`), the other `(64 - length) & 63` (`length` masked to 6 bits, so 0 means 64). The destination is shifted right by the index, then left and right by the complement, which keeps the low `length` bits. INSERTQ register form is still reported as unsupported.
- **Short sites:** when a site is shorter than a `jmp rel32`, the converter extends it over the instructions that follow it until it's 5 bytes long:
  - following EXTRQ/INSERTQ instructions (before any other instruction) are lowered into the same stub, via a new `MatchSequence`;
  - other instructions are copied after the lowered body (`LowerOutOfLine`'s new `trailing` bytes), but only if they're sequential, have no RIP-relative operand and no branch target;
  - anything else (a return, a branch, RIP-relative code, the segment ending) still fails the relink, as does a branch target inside the extended site.
- `docs/TechnicalDebt.md` now lists only the INSERTQ register form, MONITORX/MWAITX/CLZERO/RDPRU/MCOMMIT and SHA-NI.
2026-09-28 09:35:28 +03:00
boykopovar f354dbd17e
Merge pull request #47 from oneandonlydean/fix/linux-load-alignment
fix(relinker): align the linux header load segment to the largest segment alignment
2026-09-28 08:44:02 +03:00
boykopovar 20e5c359d9
Merge pull request #45 from oneandonlydean/fix/linux-guest-dynlibdata
fix(relinker): skip the flagless dynlib data segment in linux guest modules
2026-09-28 08:31:05 +03:00
Dean Galvin ff1fa9eb69 feat(relinker): lower register-form EXTRQ and relocate following instructions for short sites
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 16:37:15 +13:00
Dean Galvin 06b3413961 fix(relinker): align the linux header load segment to the largest segment alignment
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 14:22:48 +13:00
Dean Galvin 346b7280e2 fix(relinker): skip the flagless dynlib data segment in linux guest modules
GuestModuleWriter::WriteLinux adds read permission to every PT_LOAD, including
the SCE dynlib data segment, which has no flags and is never mapped on the PS5.
When that segment starts inside the last page of the preceding RW segment, the
read-only mapping covers the tail of its bss and the module's initializer faults
on its first write there. The symbol and relocation tables it holds are already
copied into the appended segment, so it no longer needs to be mapped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 13:32:36 +13:00
Darko Gjorgjijoski 42594eecd4 fix(relinker): report buffered output write failures 2026-09-28 00:25:42 +02:00
devilismyfriend a503d0b617 Merge remote-tracking branch 'origin/main' into feat/demons-souls-boot
Brings in main up to 9958d26 (homebrew runtime, POSIX wrappers in
libkernel, sce_module guest modules and --skip-sce-module, the --to-intel
general pipeline, libSceRandom, libSceRtc, libScePosixForWebKit,
libRenoirCore, test wiring).

Resolutions where both sides implemented the same thing:
- libkernel pthread: main's structure (lazy static initialisation,
  destroyed markers, MutexOperations/CondOperations, mutex protocol and
  condattr clock) with this branch's TimedWait deadlines and condition
  (precise timed lock/wait on Windows), wait tracing, the adaptive mutex
  type 4, POSIX default ERRORCHECK mutexes, EDEADLK/EPERM results instead
  of throws, and condition clocks honoured for absolute timeouts.
- libc locale: the guest Dinkumware ABI (_Locimp, facet vtables, short
  ctype/case tables, locale ids, stream storage) is kept because guest code
  inlines those layouts; main's C character functions are kept on top.
- libc stdio/strings/math: main's stream functions (guest FILE status
  sync), strerror/perror, remove, formatting, string and math exports win
  over this branch's duplicates.
- libc paths: main's working directory with this branch's path aliases
  resolved on the normalised guest path.
- libkernel file: this branch's sceKernel* results as SCE errors, main's
  POSIX wrappers and both fstat helpers.
- relinker: this branch's stub lowering keeps its trampolines through the
  main executable path; guest modules refuse lowerings that need stubs.
- AGC driver: main's rendering wait is executed by this branch's workers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-27 10:52:21 -07:00
boykopovar 179841caff feat(relinker): report full module path when windows loading fails 2026-09-27 13:10:06 +03:00
boykopovar 43d2e8b4dc fix(codegen): decode xadd byte and popcnt instruction lengths fix 2026-09-27 12:49:46 +03:00
boykopovar e3dc9a6acc fix(relinker): accept zero alignment for empty tls segments 2026-09-27 12:41:52 +03:00
boykopovar 52b683d208 fix(relinker): skip generated guest prx files during sce module scan 2026-09-27 11:43:42 +03:00
boykopovar bfa1ac0751 fix(relinker): scan complete function ranges for windows tls accesses 2026-09-27 11:43:41 +03:00
boykopovar 2e654e4f89 feat(relinker): scan sce modules for syscalls 2026-09-27 11:43:33 +03:00
boykopovar 630cb018c0 feat(relinker): add --skip-sce-module flag 2026-09-27 11:43:32 +03:00
boykopovar 337e763597 fix(relinker): support operand-size prefixes on fs:[0] access 2026-09-27 11:43:30 +03:00
boykopovar 2cc34985c0 fix(codegen): decode int imm8 instruction length correctly 2026-09-27 11:43:30 +03:00
boykopovar fa10c6d7eb fix(relinker): scan reachable code for windows guest tls accesses 2026-09-27 11:43:30 +03:00
boykopovar 6b2db1d8a8 fix(relinker): support windows guest tls relocations and accesses 2026-09-27 11:43:29 +03:00
boykopovar 0c6765e6a6 fix(relinker): ignore non-loadable SCE segments outside file bounds 2026-09-27 11:43:29 +03:00
boykopovar 1379ec001b feat(relinker): add native guest module loading with export priority 2026-09-27 11:43:28 +03:00
QDarkRex 908befe81d feat(relinker): add --windows-gui to emit a GUI subsystem executable
Generated executables always used the console subsystem and opened a
console window on launch. The opt-in flag writes IMAGE_SUBSYSTEM_WINDOWS_GUI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 12:24:15 +07:00
QDarkRex f8485ce6a6 fix(relinker): return unpacked exit status and wait for a single Enter in autorun
std::system returns a wait status on POSIX, so returning it from main
truncated a guest exit code of 1 (status 256) to 0. The prompt also
required pressing Enter twice because cin.get followed cin.ignore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 12:24:14 +07:00
devilismyfriend 01c4e3edf7 feat(relinker): --to-intel lowers SSE4a sites to same-length jumps into an appended stub section
EXTRQ, INSERTQ, MOVNTSS and MOVNTSD are rewritten at relink time: same-length in-place forms
where they exist, otherwise a jmp rel32 into an appended executable section holding a
scratch-free SSE body and a jump back, so no code shifts and no RIP-relative or jump-table
operand needs adjusting. Decoder fixes for POPCNT and 0F BB (BTC), codegen and elfpatcher
tests, README and technical-debt notes. The runtime illegal-instruction trap stays as a
fallback.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-26 19:00:39 -07:00
boykopovar 2f30b62a69 fix(relinker): use general pipeline after converting for --to-intel flag 2026-09-26 12:47:31 +03:00
SamG-Coder cf3c8081fd fix(build): make Python relinker tests optional 2026-09-26 14:55:02 +10:00
SamG-Coder f146a3d069 fix(windows): expose shared libc for internal runtime imports 2026-09-25 06:00:07 +10:00
SamG-Coder eca52b4725 fix(relinker): accept unused empty ELF TLS segments 2026-09-25 05:53:32 +10:00
SamG-Coder 221086beb6 fix(relinker): support ELF images without PLT relocations 2026-09-25 05:32:49 +10:00
SamG-Coder 0968c32b72 fix(build): register relinker tests with CTest 2026-09-25 05:27:19 +10:00
boykopovar 2778c1e86e perf(agc): keep render targets on gpu across draws 2026-09-24 21:30:00 +03:00
boykopovar 594656581e feat(libs): add new std symbols + unused filter off by default 2026-09-24 10:28:33 +03:00
boykopovar fa27b50832 chore(relinker): unused filter level = 1 by default 2026-09-24 08:14:05 +03:00
boykopovar ad68f86df1 chore(docs): update readme status for unused filter1 bug 2026-09-24 08:13:03 +03:00
boykopovar f5bc2d7649 feat(libs): add new sceAgc functions def 2026-09-24 07:54:15 +03:00
boykopovar 9f2b41b9a1 fix(libc): route guest allocations through application heap 2026-09-24 06:53:12 +03:00
boykopovar 8fd65f2a25 add EVENT_WRITE support for CS/GS/PS_PARTIAL_FLUSH + relinker return exit code from autorun 2026-09-22 20:27:49 +03:00
boykopovar 3da76b9b33 refactor(graphics): add new graphics pipeline log + remove redunant ones 2026-09-18 21:03:11 +03:00
boykopovar 7e5f41aba3 feat(cli): add --windows-diagnostics arg - off by default 2026-09-13 17:21:13 +03:00
boykopovar 04e1bc0a2d refactor(codegen): separated x86 assembler 2026-09-13 17:04:02 +03:00
boykopovar 9d7c255316 feat(windows): add import error chain diagnostic 2026-09-12 15:55:46 +03:00
boykopovar 4b643c6655 refactor(core): seprated folders for relinker and libs 2026-09-11 14:53:01 +03:00
boykopovar 2a14912b65 feat(cli): relinker --lazy-binding flag 2026-09-10 14:57:27 +03:00
boykopovar 5bf78ab8b4 feat(relinker): strict unused nids filtering mode 2026-09-09 19:29:25 +03:00
boykopovar 77cfe65b9c feat(relinker): unused nid filter fix + cli update 2026-09-09 18:17:10 +03:00
boykopovar febac8978e chore(relinker): protect .rela.plt + static jump_slot 2026-09-09 11:36:47 +03:00
boykopovar 3b5ae707cd fix(relinker): exact opcode instead of any rip-relative disp in unused nid filter 2026-09-09 10:14:45 +03:00
boykopovar a81a1bf1b5 feat(relinker): upgrade unused import finder via graph 2026-09-09 09:56:52 +03:00
boykopovar 6af387172a fix(relinker): update elf to windows pe relinking 2026-09-08 18:24:03 +03:00
boykopovar 789699928a fix(relinker): gen r_x86_64_relative relocs for internal ptrs 2026-09-08 00:15:54 +03:00
boykopovar e82abc96c4 fix(nid): remove jump_slot records filtering 2026-08-22 19:35:34 +03:00
boykopovar efd845fcfd fix(patcher): skip broken needed-library recomputation causing empty dt_needed 2026-08-22 15:21:26 +03:00
boykopovar 8672a5cc3d fix(libs): libc export flag name fix 2026-08-22 11:18:42 +03:00
boykopovar f786ea6576 fix(elfpatcher): use original dt pltgot vaddr 2026-08-20 09:41:34 +03:00
boykopovar 948017d734 fix(relinker): add dt pltgot to .dynamic + append elf sym write 24 bytes 2026-08-12 13:46:47 +03:00
boykopovar 8c44cf4a52 feat(cli): cli flag for amd to intel convertion 2026-08-05 13:30:03 +03:00
boykopovar 88fca26a28 refactor(scanner): move scanner from relinker to separated module 2026-08-04 15:28:10 +03:00
boykopovar 007ba188bb feat(relinker): simplify got address resolution + validate entry sizes 2026-08-04 13:54:16 +03:00
boykopovar be508d9647 fix(relinker): validate dt_os/dt dynamic tags 2026-08-04 13:35:52 +03:00
boykopovar 39ae562b51 feat(core): relocation tables from pt dynamic instead of hardcoded offset 2026-08-04 13:32:22 +03:00
boykopovar 0fe6ad11f4 refactor(core): remove extra targets and cmake lists 2026-08-04 01:24:23 +03:00
boykopovar 850eae37eb refactor(core): separate io from domain logic + di 2026-08-04 00:28:58 +03:00
boykopovar e451fde738 fix(patcher): skip pt note and null-page pt load headers 2026-08-03 23:28:43 +03:00
boykopovar b05f877e15 feat(patcher): gen pt interp + executable entry stub 2026-08-03 23:04:11 +03:00
boykopovar 5718f6931a fix(patcher): create pt load segment for dynamic block 2026-08-03 22:53:39 +03:00
boykopovar 6b6004d974 refactor(relinker): clean arch + remove pipelines from main.cpp 2026-08-03 22:36:29 +03:00
boykopovar a4e7d3028e feat(relink): save output linux elf after checking (wip) 2026-08-03 22:13:15 +03:00
boykopovar 6b3deed7e4 fix(scanner): fix false positive fail from naive byte scan for syscall(wip) 2026-08-03 21:38:06 +03:00
boykopovar fe600cb641 fix(header): support pt dynamic import resolution 2026-08-03 21:32:01 +03:00
boykopovar 340a321cbe fix(header): fix read section headers 2026-08-03 21:22:07 +03:00
boykopovar 4d8fc76ff7 refactor(core): add some nodiscard and const 2026-08-03 21:05:36 +03:00
boykopovar 2654c8eb4b fix(types): update type names to fix bug with gcc 2026-08-03 20:40:27 +03:00
boykopovar 8a7c7c4e0d feat(log): add call reg writer 2026-08-03 20:27:55 +03:00
boykopovar 657ada06b3 initial commit 2026-08-03 20:02:52 +03:00