Skip to content

target/i386: Clear s->x86_64_hregs when decoding LAHF/SAHF with a REX prefix - #2370

Open
unknown-1-0 wants to merge 1 commit into
unicorn-engine:devfrom
unknown-1-0:i386-fix-lahf-sahf-with-rex
Open

target/i386: Clear s->x86_64_hregs when decoding LAHF/SAHF with a REX prefix#2370
unknown-1-0 wants to merge 1 commit into
unicorn-engine:devfrom
unknown-1-0:i386-fix-lahf-sahf-with-rex

Conversation

@unknown-1-0

Copy link
Copy Markdown

According to both Volume 2 of Intel 64 and IA-32 Architectures Software Developer's Manual and Volume 3 of AMD64 Architecture Programmer's Manual, the LAHF (0x9f) and SAHF (0x9e) instructions always access the AH register. The presence of a REX prefix in 64-bit mode does not alter this behavior, and uniform byte register addressing (SPL) must not be applied.

The bug occurs because the translator blindly sets s->x86_64_hregs to true upon encountering any REX prefix. During translation of LAHF/SAHF, gen_op_deposit_reg_v() is called, which relies on the internal helper byte_reg_is_xH() to check whether to address a high byte register (AH). Since s->x86_64_hregs is true, byte_reg_is_xH(s, 4) returns false. This causes the translator to bypass the high-byte logic (reg - 4 with an 8-bit shift) and instead maps index 4 directly to tcg_ctx->cpu_regs[4], leading to SPL being accessed instead of AH.

Fix this by ensuring s->x86_64_hregs remains false when decoding LAHF/SAHF.

@unknown-1-0

Copy link
Copy Markdown
Author

New tests were added between existing ones to prevent merge conflicts later.

…EX prefix

According to both Volume 2 of Intel 64 and IA-32 Architectures Software
Developer's Manual and Volume 3 of AMD64 Architecture Programmer's Manual,
the LAHF (0x9f) and SAHF (0x9e) instructions always access the AH register.
The presence of a REX prefix in 64-bit mode does not alter this behavior,
and uniform byte register addressing (SPL) must not be applied.

The bug occurs because the translator blindly sets `s->x86_64_hregs` to `true`
upon encountering any REX prefix. During translation of LAHF/SAHF,
`gen_op_deposit_reg_v()` is called, which relies on the internal helper
`byte_reg_is_xH()` to check whether to address a high byte register (AH).
Since `s->x86_64_hregs` is `true`, `byte_reg_is_xH(s, 4)` returns `false`. This
causes the translator to bypass the high-byte logic (`reg - 4` with an
8-bit shift) and instead maps index 4 directly to `tcg_ctx->cpu_regs[4]`,
leading to SPL being accessed instead of AH.

Fix this by ensuring `s->x86_64_hregs` remains `false` when decoding LAHF/SAHF.

Signed-off-by: Andrey Polivoda <apolivodaa433@gmail.com>
@unknown-1-0
unknown-1-0 force-pushed the i386-fix-lahf-sahf-with-rex branch from 1abcfa9 to 6cbb6c1 Compare July 22, 2026 16:20
@unknown-1-0

Copy link
Copy Markdown
Author

Force-pushed to sign the commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant