fix(lift): SDIV of the most negative number by -1 kills the game on x86 #361
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot#361
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happens
The lifted C for SDIV traps on x86 when the guest divides the most negative number by -1, and the game process dies with
0xC0000095(integer overflow,#DE). AArch64 returns the dividend (INT64_MIN/INT32_MIN) there and goes on.Where
third_party/a64-kit/lift/suyu/arm64_to_c.h, the data-processing 2-source group,case 3: // SDIV(line 4098 oncf605c85):The divide-by-zero case is handled (
_b ? ... : 0), butINT_MIN / -1is undefined in C, and x86'sidivfaults on it.Fix (suggested)
Handle -1 on its own, as the negation AArch64 gives:
That's the same result for every other input, and one compare more per SDIV. It's in
third_party/, so it needs the a64-kit's provenance updated, or an edit outside it on the lifted text.How it was found
A game-free equivalence harness ran every instruction form the lift emits against Unicorn: 15,709 encodings, 477,468 random states. The lifted C's own program crashed on the
SDIV INT_MIN, -1states, so SDIV was left out of that run. No game data is involved: it's the translator's output for the instruction alone.Whether the game ever divides like that is unknown. If it does, it's a crash with no message.