Add differential decode test harness - #636
Draft
flobernd wants to merge 3 commits into
Draft
Conversation
clock_gettime/CLOCK_MONOTONIC are POSIX and unavailable under MSVC and ClangCL, which failed the Windows CI jobs. Standard C clock() is portable and, for this single-threaded decode microbenchmark, tracks wall time closely enough.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a self-contained differential decode harness for catching behavioral
regressions in the decoder.
ZydisDiffDumpdecodes an input file at everybyte offset across a fixed set of decoder configurations and emits per-block
FNV-1a hashes of the full decode result (status, instruction struct, operands,
and the pointed-to CPU/FPU flag records). Two builds of the tool over the same
input are guaranteed to produce byte-identical output, so any semantic drift
between a baseline and a candidate build shows up as a hash mismatch.
Intention
Decoder refactors (e.g. the performance work) need a cheap, high-coverage way
to prove that a change is behavior-preserving. Exhaustive per-offset decoding
over a large corpus exercises far more of the decoder than the unit tests, and
reducing each decode to a hash makes a full corpus comparison a single
diff.Changes
tools/ZydisDiffDump.c- new tool with three subcommands:gen <file> <MiB>- write a deterministic xorshift64 corpus so both buildshash the exact same bytes.
dump <file> [start end]- emit per-block hashes; the optional range printsper-offset detail lines to bisect a mismatch down to the offending offset.
bench <file>- simple decode throughput benchmark (instr-only and full).CMakeLists.txt- buildsZydisDiffDumpwhenZYDIS_BUILD_TOOLSandZYDIS_FEATURE_DECODERare enabled.tests/differential/diffcheck.sh- gate script that diffs the currentbuild's dump against reference dumps captured from a baseline build (kept
untracked in
.diffref/) and reports the first differing lines on mismatch.Testing
cmake -B build -DZYDIS_BUILD_TOOLS=ON -DCMAKE_BUILD_TYPE=Release+cmake --build build --target ZydisDiffDump- builds clean.ZydisDiffDump gen corpus.bin 1thenZydisDiffDump dump corpus.bin- runsacross all five configs; two successive dumps of the same corpus are
byte-identical (determinism confirmed via
diff).Notes
cpu_flags/fpu_flagsreference static tables whoseaddresses differ between binaries, so their contents are hashed and the
pointers nulled before hashing the instruction struct - otherwise identical
decodes would hash differently across builds.
.diffref/; the harness compares builds,it does not ship a golden baseline.