capstone icon indicating copy to clipboard operation
capstone copied to clipboard

ARM FP instruction (`vldmia`) does not report written registers as such

Open dgazzoni opened this issue 7 months ago • 6 comments

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"  

dgazzoni avatar May 22 '25 12:05 dgazzoni

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.

Rot127 avatar May 22 '25 12:05 Rot127

OK, I will try that one out. Thanks for the suggestion.

dgazzoni avatar May 22 '25 13:05 dgazzoni

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 avatar May 22 '25 20:05 dgazzoni

@dgazzoni See https://github.com/capstone-engine/capstone/pull/2718

Rot127 avatar May 24 '25 10:05 Rot127

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

jiegec avatar Jul 09 '25 10:07 jiegec

Yes, this is mostly open for the v5 branch.

Rot127 avatar Jul 09 '25 12:07 Rot127