Description
Work environment
Questions | Answers |
---|---|
OS/arch/bits | . |
Architecture | AArch64 |
Source of Capstone | . |
Version/git commit | next |
Some operands have incorrect access attributes set. If the same register is used twice in the instruction, once for reading and once for writing, those registers are required by the ISA to be the same, the details for this register will always be access = CS_AC_READ_WRITE. There is no distinction for READ and WRITE.
Instructions affected (maybe more): eor
, casal
Instruction bytes giving faulty results
0 01 68 61 4e fcvtn2 v1.4s, v0.2d
ID: 367 (fcvtn2)
op_count: 2
operands[0].type: REG = q1 (vreg)
operands[0].access: READ | WRITE
Vector Arrangement Specifier: 0x420
operands[1].type: REG = q0 (vreg)
operands[1].access: READ
Vector Arrangement Specifier: 0x240
Write-back: True
Registers read: fpcr q1 q0
Registers modified: q1
Groups: HasNEON
operands[0] should be WRITE only. More variants of this instruction may be effected, I just haven't verified this:
Expected results
0 01 68 61 4e fcvtn2 v1.4s, v0.2d
ID: 367 (fcvtn2)
op_count: 2
operands[0].type: REG = q1 (vreg)
operands[0].access: WRITE
Vector Arrangement Specifier: 0x420
operands[1].type: REG = q0 (vreg)
operands[1].access: READ
Vector Arrangement Specifier: 0x240
Write-back: True
Registers read: fpcr q1 q0
Registers modified: q1
Groups: HasNEON
Steps to get the wrong result
cstool
Additional Logs, screenshots, source code, configuration dump, ...
Transferred from #2472
Mentioned in https://github.com/capstone-engine/capstone/blob/next/docs/cs_v6_release_guide.md#known-bugs-in-the-alpha
Issue
eor and the others
Fixing this, requires to track which MCOperands (LLVM operands) are used for which Capstone operand. This is not yet implemented (sorry, forgot to put it onto the todo list).
As described in the chat, currently we check for tied operands and their access attributes.
If two operands are tied (are physically the same, but logical distinct in the disassembler), we set both access flags.
This is necessary, because write back registers are given the RW property like this:
For a register which is read and written there are effectively two distinct logical operands for it. One "invisible" "written" register (which is never printed into the asm text) and the register which is printed/added to the details (and marked as read).
Because of this, registers which use the same register twice, once for reading and once for writing AND have the name twice in the asm text, now are marked both as READ_WRITE.
Implementing this would also fix the issue that the memory can be written, but none of the operands forming the address is. But up until now, the registers nonetheless appear in the regs_write list.