Skip to content

Some memory operands have incorrectly RW access (e.g. eor, casal) #2589

Open
@Rot127

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.

Metadata

Assignees

No one assigned

    Labels

    AArch64ArchbugSomething is not working as it should

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions