ARM FP instruction (`vldmia`) does not report written registers as such
Work environment
| Questions | Answers |
|---|---|
| System Capstone runs on OS/arch/bits | macOS AArch64 |
| Capstone module affected | arm |
| Source of Capstone | Homebrew |
| Version/git commit | v5.0.6 |
I'm not sure if you would classify it as an incorrect disassembly per se -- it's actually an issue with classifying registers that are written as such.
Instruction bytes giving faulty results
0x91,0xec,0x08,0x4a
Expected results
It should be:
0 91 ec 08 4a vldmia r1, {s8, s9, s10, s11, s12, s13, s14, s15}
ID: 362 (vldmia)
op_count: 9
operands[0].type: REG = r1
operands[0].access: READ
operands[1].type: REG = s8
operands[1].access: WRITE
operands[2].type: REG = s9
operands[2].access: WRITE
operands[3].type: REG = s10
operands[3].access: WRITE
operands[4].type: REG = s11
operands[4].access: WRITE
operands[5].type: REG = s12
operands[5].access: WRITE
operands[6].type: REG = s13
operands[6].access: WRITE
operands[7].type: REG = s14
operands[7].access: WRITE
operands[8].type: REG = s15
operands[8].access: WRITE
Registers read: r1
Registers modified: s8, s9, s10, s11, s12, s13, s14, s15
Groups: vfp2
But the actual result is:
0 91 ec 08 4a vldmia r1, {s8, s9, s10, s11, s12, s13, s14, s15}
ID: 362 (vldmia)
op_count: 9
operands[0].type: REG = r1
operands[0].access: READ
operands[1].type: REG = s8
operands[2].type: REG = s9
operands[3].type: REG = s10
operands[4].type: REG = s11
operands[5].type: REG = s12
operands[6].type: REG = s13
operands[7].type: REG = s14
operands[8].type: REG = s15
Registers read: r1
Groups: vfp2
For reference, here is the disassembly for an ldm instruction (for integer, rather than FP, registers):
% cstool -d -s cortexm "\x98\xe8\xff\x00" "0x00ffe898"
ffe898 98 e8 ff 00 ldm.w r8, {r0, r1, r2, r3, r4, r5, r6, r7}
ID: 79 (ldm)
op_count: 9
operands[0].type: REG = r8
operands[0].access: READ
operands[1].type: REG = r0
operands[1].access: WRITE
operands[2].type: REG = r1
operands[2].access: WRITE
operands[3].type: REG = r2
operands[3].access: WRITE
operands[4].type: REG = r3
operands[4].access: WRITE
operands[5].type: REG = r4
operands[5].access: WRITE
operands[6].type: REG = r5
operands[6].access: WRITE
operands[7].type: REG = r6
operands[7].access: WRITE
operands[8].type: REG = r7
operands[8].access: WRITE
Registers read: r8
Registers modified: r0 r1 r2 r3 r4 r5 r6 r7
Groups: thumb2
Steps to get the wrong result
With cstool:
cstool -d -s cortexm "\x91\xec\x08\x4a"
If it is not too much trouble for your use case, I'd highly recommend to switch to the v6 Alpha4 version of Capstone. Especially ARM got a huge update. And the instruction in question is decoded correctly there as well.
v6Alpha4 has some breaking changes (see: https://github.com/capstone-engine/capstone/blob/next/docs/cs_v6_release_guide.md). Especially the values of the CC enum changed. But we got only positive feedback for it so far.
OK, I will try that one out. Thanks for the suggestion.
I just migrated my project to use Capstone v6 Alpha4. However, I've found an unrelated regression relative to v5.0.6. Please advise if you'd like me to open a new bug report.
Capstone v5.0.6:
% cstool -d cortexm "\x03\xbc"
0 03 bc pop {r0, r1}
ID: 127 (pop)
op_count: 2
operands[0].type: REG = r0
operands[0].access: WRITE
operands[1].type: REG = r1
operands[1].access: WRITE
Registers read: sp
Registers modified: sp r0 r1
Groups: thumb thumb1only
Capstone v6 Alpha4:
cstool -d arm+m+thumb "\x03\xbc"
0 03 bc pop {r0, r1}
ID: 634 (pop)
op_count: 2
operands[0].type: REG = r0
operands[0].access: READ
operands[1].type: REG = r1
operands[1].access: READ
Registers read: r13 r0 r1
Registers modified: r13
Groups: IsThumb
As you can notice, it considers the access type for target registers of pop as READ rather than WRITE.
@dgazzoni See https://github.com/capstone-engine/capstone/pull/2718
Fixed on next branch:
$ ./cstool -d arm+m+thumb 91ec084a
0 91 ec 08 4a vldmia r1, {s8, s9, s10, s11, s12, s13, s14, s15}
ID: 526 (vldmia)
op_count: 9
operands[0].type: REG = r1
operands[0].access: READ
operands[1].type: REG = s8
operands[1].access: WRITE
operands[2].type: REG = s9
operands[2].access: WRITE
operands[3].type: REG = s10
operands[3].access: WRITE
operands[4].type: REG = s11
operands[4].access: WRITE
operands[5].type: REG = s12
operands[5].access: WRITE
operands[6].type: REG = s13
operands[6].access: WRITE
operands[7].type: REG = s14
operands[7].access: WRITE
operands[8].type: REG = s15
operands[8].access: WRITE
Registers read: r1
Registers modified: s8 s9 s10 s11 s12 s13 s14 s15
Groups: HasFPRegs
Yes, this is mostly open for the v5 branch.