Commit Graph
25 Commits
Author SHA1 Message Date
aasishdairel a0e591c932 fix(relinker): trap CLZERO GS overrides
CLZERO (0F 01 FC) clears the cache line at the logical address in rAX and applies a GS override, so mark its register-form encoding as a memory operand. RDPRU (0F 01 FD) has no memory operand and stays unchanged.
2026-10-20 10:53:42 +05:30
aasishdairel a58d560c9b fix(relinker): trap UMONITOR GS overrides
UMONITOR (F3 0F AE /6) takes its effective address from the register operand and uses DS with segment overrides, so mark its register-form encoding as a memory operand. UMWAIT and TPAUSE use the same opcode with F2/66 and have no memory operand.
2026-10-20 10:19:04 +05:30
aasishdairel cde44070e0 fix(relinker): trap GS overrides on implicit memory operands
MASKMOVQ, MASKMOVDQU, VMASKMOVDQU, MONITOR and MONITORX use a register-form ModRM byte but still access memory at DS:rDI or DS:rAX. Mark them as memory operands and cover the encodings in the Windows and macOS GS trap tests.
2026-10-20 10:13:34 +05:30
aasishdairel 570c3297d3 fix(relinker): trap only GS memory accesses in Windows and macOS output 2026-10-20 10:13:34 +05:30
oskarlgsandClaude Opus 5.5 206aaa56cb fix(relinker): decode near branches with an operand-size prefix as AMD does
66 E8, 66 E9 and 66 0F 80-8F without REX.W take a 16-bit displacement on
AMD processors, the console included. Every near relative branch with that
prefix truncates its target to 16 bits, so the decoder reports no branch
target for it and stubs refuse to move it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TFMtUC4L4wMS4eeEqaNSR
2026-10-17 20:58:29 +00:00
Alexej Szpevák 8e812f4b73 fix(relinker): report RIP-relative operands of far indirect CALL and JMP
DecodeInstruction returned before reading the ModRM of FF /3 and FF /5,
so a far CALL or JMP through a RIP-relative pointer had no RIP-relative
displacement. A stub that moved such a JMP copied the displacement
without relocating it.

The decoder was compared with iced-x86 (AMD decoding) over 3.99 million
encodings: every opcode of the legacy, 0F, 0F38 and 0F3A maps under 34
prefix combinations and the VEX 0F, 0F38 and 0F3A maps, each with 48
ModRM forms. Apart from this, it agrees on length, RIP-relative offset,
control flow kind and branch target for every valid Zen 2 instruction
except near branches with a 66 prefix, recorded as technical debt, and
kernel-only returns, which it treats as sequential.

Add the comparison's metadata as cases: one RIP-relative encoding per
opcode, map and immediate size, every FF /r form, and the branch forms
with their flow kind and target. The existing cases check lengths only;
a loop or jrcxz decoded as an unconditional jump passed the whole suite.
2026-10-14 11:33:59 +02:00
Dean 758aca7373 Merge pull request #4116 from hawwwwwk/investigate/relinker-eip-relative
fix(relinker): resolve EIP-relative imports in strict filter
2026-10-13 13:41:08 +13:00
ethan 63a27648a8 fix(relinker): resolve EIP-relative imports in strict filter 2026-10-11 16:24:12 -07:00
Claude 36c78ba143 fix(relinker): report the ModRM of 3DNow! instructions in decoded instruction info
DecodeInstruction did not treat 0F 0F as having a ModRM byte, so a
RIP-relative 3DNow! operand was not reported to the analyses and the
--to-intel stub relocation that read HasRipRelativeDisp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
2026-10-11 22:34:39 +00:00
Claude feb19a844d fix(relinker): decode 3DNow! instructions with their ModRM and opcode suffix
0F 0F was decoded as a two-byte instruction. 3DNow! instructions are
0F 0F ModRM [SIB] [displacement] imm8, the trailing byte selecting the
operation (AMD64 Architecture Programmer's Manual Volume 3, Appendix A,
3DNow! opcodes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
2026-10-11 22:21:32 +00:00
ethan f2ef0f9557 fix(relinker): reject x86 instructions exceeding 15 bytes
(cherry picked from commit 7243caa56ed79fab09edd23d92851e2508671775)
2026-10-11 03:02:05 -07:00
Achraf ReyaniandClaude Opus 5.5 ce8dbc977f fix(relinker): decode XOP instructions
The x86 decoder had no XOP (AMD 8F escape) support and read 8F E8.. as
POP r/m, losing instruction boundaries. Since #2238 roots code addresses
taken by RIP-relative LEA, code analysis reaches CPU-dispatched XOP
paths, such as the vpperm routines in Stremio Plus (PPSA74126), OpenNOW
(PPSA99082) and PPSA99420, and their Windows conversion failed with
"Code analysis: overlapping instruction boundaries". Decode 8F followed
by a map of 8 or more as a three-byte XOP prefix (8F can only be POP r/m
with ModRM.reg 0) with a ModRM operand, an 8-bit immediate in map 8 and
a 32-bit immediate in map 0Ah, in both the length and operand decoders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:27:24 +13: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
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à 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
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
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
Oguzhan OzdemirandClaude Opus 5.5 e8f73a5531 fix(relinker): decode the 64-bit address of MOV moffs instructions
A0-A3 (MOV AL/eAX/rAX to and from moffs) have no ModRM byte and carry an
8-byte absolute address in 64-bit mode, or 4 bytes with a 0x67 prefix.
The decoder added nothing for the address, so the linear scanner decoded
the address bytes as code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 19:00:37 +03:00
Oguzhan OzdemirandClaude Opus 5.5 d64c0605ea fix(relinker): let REX.W override 0x66 when sizing decoder immediates
In 64-bit mode REX.W takes precedence over the 0x66 operand-size prefix,
so the immediate of 81, C7, 69, 68, A9, the 05..3D accumulator forms and
the F7 TEST form stays imm32. The decoder only applied this to B8+r and
returned a length two bytes short for the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:51:56 +03:00
Adrià FranchandClaude 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
ljkxandClaude Opus 5.5 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
SamG-Coder ee57519cb0 fix(relinker): decode EMMS without a ModRM byte 2026-09-29 07:39:01 +10:00
devilismyfriendandClaude Fable 5.1 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 4b643c6655 refactor(core): seprated folders for relinker and libs 2026-09-11 14:53:01 +03:00