fix(build): a game image past 2 GB fails the link instead of running broken #356
No reviewers
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!356
Loading…
Reference in a new issue
No description provided.
Delete branch "madebyjordan/Longshot:fix/image-guard"
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?
Why
If the game's linked image ever reaches 2 GB, the game reads the wrong memory and the linker doesn't say so. The build should stop with a plain message instead of handing the player a broken game. Today's image is 588 MB, so nothing changes now; it matters as soon as someone builds more code, or code at a lower optimisation level.
What changed
image_span()andimage_too_big()innx2/build.pyread the linked image's span: a PE'sSizeOfImage, or an ELF'sPT_LOADrange from the lowest address to the highest end. At 2 GB or more, the build printslink FAILED: the game's image is N MB, past the 2048 MB its code can address ..., deletes the image so nothing can start it, and exits 1.main()checks after each of the three links of the lifted code: Linuxlongshot, Windowslongshot.exe, and--dll'slongshot_game.dll.tests/test_image_size_guard.pycovers:main()followed by the check;Why the linker misses it: the game's code reaches its data RIP-relative, through a signed 32-bit offset. lld doesn't range-check those fixups on x86-64 COFF. I found this compiling the lifted code at
-O0for a test: lld linked a 2,262 MBlongshot.exewithout an error..datastarted past 2^31, and the first read ofa64_dirty(movq -0x7d457b8e(%rip)) landed 4 GB below.refptr.a64_dirty. On Linux, lld does range-check these fixups and fails the link itself, so there the guard is a second check; the gap it closes is Windows'.Flags and settings
None.
Measurements
A change to the build scripts that the game doesn't run, so it's measured by its game-free checks.
main:
cf605c85(2026-11-14)this PR: fix/image-guard @
53cbc23cHardware: Ryzen 5 5600, 16 GB, Windows 11, llvm-mingw clang 23 (nightly-34's builder tools)
Method:
tests/test_image_size_guard.py, pluspython -I -B tests/run_all.py --jobs 4on main and on this PR merged with the other four build PRs of this batch.cf605c8553cbc23ctests/test_image_size_guard.pyimage_span)--dllcheck taken outtests/run_all.py --jobs 4bin\longshot.exe,image_spanTesting
Tested:
image_spanon nightly-34'sbin\longshot.exe(588 MB).-O0image from the experiment above, which is the case that fails.Not tested:
make_game.py. The check runs only after a link and changes nothing under 2 GB, so a normal build is unchanged.Needs other testers: None.
Screenshots
Nothing on screen.
Risk and rollback
A wrong reading of a valid image would stop a build that would have worked. The span is read straight from the image's headers, and the test checks it against real links from clang and lld. Reverting the commit removes the check.
Reviewer notes
image_too_bigdeletes the image it refuses, so a broken game can't be started from the build folder by hand.Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
Assisted-by:/Co-Authored-By:trailers.mainand passing here.tests/that reads changed source updated in this PR, not weakened.WIP: fix(build): a game image past 2 GB fails the link instead of running brokento fix(build): a game image past 2 GB fails the link instead of running brokenView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.