Scanner breaks ARM Thumb IT blocks incorrectly
The following sequence of ARM Thumb instructions model setting r7 to 1 or 0 depending on the value of the Z processor flag.
"14BF" + // ite ne
"0127" + // movne r7,#1
"0027"); // mov r7,#0
If given those six bytes, the Reko ThumbRewriter class handles this correctly and generates the following RTL clusters:
l0000:
nop
l0002:
if (Test(EQ,Z)) branch l0004
r7 = 1<32>
l0004:
if (TEST(NE,Z)) branch l0006
r7 = 0<32>
This relies on the ThumbDisassembler maintaining the state of the current IT block to perform the appropriate conditional jumps. However, the Reko Scanner create a new disassembler instance after every basic block it completes, and the new disassembler instance doesn't have the IT state set correctly. Therefore we get the following RTL:
l0000:
nop
l0002:
if (Test(EQ,Z)) branch l0004
r7 = 1<32>
l0004: <-- new basic block, so blank IT state
r7 = 0<32>
which generates the wrong result.
What Reko should do here is try to hang on to the ThumbRewriter (with its ThumbDisassembler inside) across the fall-through of a basic block. That way the IT` state will preserved and correct output will be obtained.
An example of this code in the wild is the subject binary subjects/Elf/ARM/angr-685/RTOSDemo at address 0000925C, corresponding to the procedure GPIOPadConfigGet