test(tests): bundle an ARM64 PE so the interior-gap rule has a real one - #333
Conversation
danielplohmann#312's interior-gap rule is driven end to end only over an image the suite synthesises. That pins the extent decode and the refusal, but not that the rule meets the shapes a compiler emits, and until now there was no ARM64 PE among the bundled samples at all: scanning them for a PE machine field finds eight i386, four AMD64 and one ReadyToRun image, and no 0xAA64. The fixture is built from source rather than taken from a system, so it can be redistributed and rebuilt: aarch64-w64-mingw32-clang++ -O2 -g -gdwarf-4 probe.cpp -o probe.exe with llvm-mingw 20250430. The source exercises catch funclets, cleanup funclets and a [[noreturn]] cold path, the shapes that get their own unwind record. That also makes it a control. clang emits one .pdata record per named function and splits none of them, so the over-seeding an MSVC-built ARM64 PE shows does not occur here; anything refused is refused on the extent evidence rather than on a compiler's chunking habit. Eight addresses move, each interior to a RUNTIME_FUNCTION extent whose own function the analysis recovered, and they are listed rather than counted so a change that refuses a different set fails instead of staying green on a total. XORed like every other bundled sample. 200K, against 1.1M for the largest already carried.
|
Reviewed here and good to go. Verified the fixture end to end end to end: Listing the eight addresses rather than counting them is the part that makes this a regression test instead of a tally, and asserting One non-blocking suggestion. The claim the fixture rests on is "built from source, so it can be redistributed and rebuilt", and the command line is in the docstring but |
Item 2 of #322, the ARM64 PE row — the "bundle fixtures that reach these paths" option rather than the corpus one.
Still true, and this closes it.
testAArch64PdataExtraction.pydrivesUSE_PE_ARM64_PDATA_INTERIOR_GAPSend to end, but over an image the suite synthesises — which pins the extent decode and the refusal, and cannot say the rule meets the shapes a compiler actually emits.The fixture
Built from source rather than taken from a system, so it is redistributable and rebuildable:
The source deliberately exercises catch funclets, cleanup funclets and a
[[noreturn]]cold path — the shapes that get their own unwind record.It is a control as well as a fixture. clang emits one
.pdatarecord per named function and splits none of them, so the MSVC over-seeding described in item 1 does not occur here. Anything this test refuses is refused on the extent evidence, not on a compiler's chunking habit.XORed like every other bundled sample. 200K, against 1.1M for the largest already carried and 247K for the next.
What it pins
Eight addresses move between the flag off and on, each interior to a
RUNTIME_FUNCTIONextent whose own function the analysis recovered:They are listed rather than counted, so a change that refuses a different set of eight fails instead of staying green on an unchanged total.
on - offis asserted empty as well, so the rule is shown to only refuse.Three cases: that the fixture really is an
0xAA64PE (the gap this file exists to close), the refusal itself with both directions asserted, and that none of the eight survives with the rule on. Verified to fail when the rule is disabled at source — two of the three fail, and the machine-field case correctly does not.Gates
python -m pytest tests/→ 2,063 passed, 1 skipped, 2,593 subtestsruff check .andruff format --check .→ cleanmake typecheck→ exit 0, 261 diagnostics, identical to mastersrc/change; no existing fixture baseline moves.What it does not do
It does not make #312's magnitude reproducible in-repo, and does not try to. What the fixtures owe is that the mechanism cannot silently stop working on a real ARM64 PE, which is the durable half of the two options that item lists. The magnitude I measured separately and put on the issue: −10 false positives on ping/robocopy/bcrypt against IDA labels, and −49 with +11 functions gained on six .NET ARM64 images against private-PDB truth.
You marked these as yours in the issue, so this is offered rather than assumed — and bundling a binary is a repo-content call, so close it if you would rather not carry the 200K.