Repository navigation
fix(relinker): preserve EIP-relative jump-table destinations - #15639
PolkadotDom wants to merge 1 commit into
Conversation
BunnyFl
left a comment
There was a problem hiding this comment.
@PolkadotDom thanks, the fix looks right to me. With a 67 prefix in 64-bit mode, the RIP-relative form becomes EIP-relative: next-instruction address plus disp32, truncated to 32 bits (Intel SDM Vol. 2A, §2.2.1.6). Casting the sum to std::uint32_t (Amd64OnlyConverter.cpp:327) does that and leaves the plain RIP case unchanged. lea computes only the offset and ignores the segment (SDM Vol. 2A, LEA), and the FS and GS rows in the new test (Amd64OnlyConverterTests.cpp:117) expect the same placement as the unprefixed ones. The 0x3000 rows check that RIP-relative tables still resolve, and the 0x80001010 row without 67 checks that wrapping isn't applied to them.
What I ran: head 8a0ce96cba merged onto main 1c8c0efc8c, Windows 11, WinLibs GCC, relinker-only Release build:
amd64_only_converter,amd64_only_windows,relinker_conversion,mulx_conversionandto_rosettapass (5 of 5);- negative control,
Amd64OnlyConverter.cpptaken frommainwith the new test kept:amd64_only_converterfails with "A jump table's address size did not protect the instruction after a 256-bit store"; tools/check_conventions.py --base upstream/mainon the head: all checks passed;tools/pr_overlap.py --branch: no shared lines or exports. The tool reported #11192 and #13486 as conflicting withmainand left them uncompared. #13486's diff changes no lines ofsrc/Amd64OnlyConverter.cpp, and #11192 touches only the test file, as you found.
Approving.
|
Correction to my review above: the FS and GS rows are at |
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validation IDs already present on main (8 IDs in 446 tests)Skipped (8)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
|
Tested on an Intel Mac (i5-2415M, AVX1 only, macOS 13.7.8, x86-64 native, no Rosetta), LLVM clang 19.1.7, relinker-only build; PR head 8a0ce96 merged into main ab21370. |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
What
The AMD-only converter misses relative jump tables addressed by
67 LEAwhen the effective address wraps to 32 bits. It then treats a table destination as an instruction it can move into a conversion stub. In the regression, Rosetta conversion of a four-byte vector store consumes the following instruction even though the jump table enters it.For example, an eight-byte LEA at
0x1000with displacement bits0x80000008forms0x80001010. Main looks for the table at0xffffffff80001010instead. The table's second entry targets0x1019, which main moves into the store's stub. With this fix the converter takes the preceding instruction into the stub and leaves the destination at0x1019intact.Truncate the computed table address to 32 bits when the decoder reports the address-size override. Normal RIP-relative table addresses retain their existing behavior. The architecture rule is Intel SDM Volume 2A, §2.2.1.6, reproduced in the Intel documentation changes PDF: the address-size prefix truncates and zero-extends the effective address.
Tested
Base
1c8c0efc8c; candidate8a0ce96cba.relinker,amd64_only_converter_tests,amd64_only_windows_tests,relinker_conversion_testsandrelinker_game_patch_tests.amd64_only_converter,amd64_only_windows,relinker_conversion,relinker_game_patch,relinker_executables,mulx_conversion, andto_rosetta.amd64_only_converter_testsbuilt and its CTest passed.A jump table's address size did not protect the instruction after a 256-bit store.Synthetic code/conversion validation. No PS5 title, Apple/Rosetta execution, GPU testing or full product build was performed.
Native x86-64 jump-table probe
Compile with
g++ -std=c++20 -O2 probe.cpp -o probe, then run./probeon Linux x86-64. The mappings useMAP_FIXED_NOREPLACEand are private to the probe. It verifies the input instruction/addressing semantics; it does not execute the converter's Rosetta output.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)