Condition code matching
In the AArch32 execution state, every instruction begins with a four-bit condition code field. The processor evaluates this field against the current condition flags in the CPSR (Current Program Status Register) and only executes the instruction when the condition holds. When the condition does not hold, the instruction is treated as a NOP.
When fuzzing for hidden or undocumented instructions on real hardware, this default behavior can produce a large number of false positives. Some Armv8-A implementations execute undefined instructions whose condition code does not match the current flags as silent NOPs, rather than raising an undefined-instruction exception. This is documented as implementation-defined behavior in section G1.16.1 of the Arm Architecture Reference Manual (DDI0487).
Mechanism in armshaker
The armshaker fuzzer back-end exposes a dedicated flag to counteract this behavior:
-c, --cond Set cpsr flags to match instruction condition code.
When invoked with -c (or --cond), the fuzzer sets the condition flags in CPSR so that they match the condition code encoded in the instruction currently being tested. This guarantees that the instruction is not skipped due to an unmatched condition, allowing the fuzzer to surface undefined instructions that would otherwise be silently NOPed by the processor.
The option is described in the project documentation as:
On AArch32: Set the condition flags in the CPSR to match the condition code in the instruction encoding. This ensures that undefined instructions with a normally non-matching condition code won't be skipped, as is the case in some ISA implementations.
Practical effect
If the fuzzer reports millions of apparent hidden instructions in A32, the project's documentation notes that this can in some sense be bypassed by enabling condition code matching. Re-running the fuzzer with the -c option typically reduces the number of reported hidden instructions on systems whose processor implements the NOP-on-mismatch behavior.
Use by the fuzzer back-end
The condition code matching option is an execution-related option of the fuzzer binary, which is the back-end used by armshaker for instruction-level fuzzing on AArch32 targets.
Related references
- Arm Architecture Reference Manual DDI0487, section G1.16.1 — describes the implementation-defined behavior of executing instructions with unmatched condition codes.
- Christopher Domas's sandsifter project, which inspired armshaker and introduced analogous techniques for x86 instruction fuzzing.
- The HASP 2020 article Uncovering Hidden Instructions in Armv8-A Implementations, which discusses the use of armshaker for instruction fuzzing on Armv8-A systems.