capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.61k stars 1.56k forks source link

Incorrect operands in arm64 "prfm" disassembly #2417

Open david942j opened 3 months ago

david942j commented 3 months ago

I found this issue when implementing Crabstone Ruby binding on Capstone 5. The existing unit tests failed with Capstone 5.

Work environment

Questions Answers
OS/arch/bits Ubuntu x86 64
Architecture arm64
Source of Capstone git clone
Version/git commit (v5.0.1, 1bd2a32f2afc6e08225d7491b82619cf4c8e87d9), (next, 4f964a264ec25eb9d468a5495fbd6142778c3a47)

Instruction bytes giving faulty results

0x40,0x4b,0xa6,0xf8

Expected results

It should be:

Have two operands, one is PREFETCH and one is MEM.

Steps to get the wrong result

With cstool:

On the v5 branch, only one operand is reported:

cstool/cstool -v
cstool for Capstone Disassembler, v5.0.1
Capstone build: x86=1 arm=1 arm64=1 mips=1 ppc=1 sparc=1 sysz=1 xcore=1 m68k=1 tms320c64x=1 m680x=1 evm=1 wasm=1 mos65xx=1 bpf=1 riscv=1 sh=1 tricore=1

cstool/cstool -d arm64 '404ba6f8'
 0  40 4b a6 f8  prfm   pldl1keep, [x26, w6, uxtw]
        ID: 713 (prfm)
        op_count: 1
                operands[0].type: MEM
                        operands[0].mem.base: REG = x26
                        operands[0].mem.index: REG = w6
                operands[0].access: READ | WRITE
                        Ext: 3
        Registers read: x26 w6

On the next branch, it reports two operands but the first one doesn't look right, at least it seems reporting mnemonic instead of the operand.

cstool/cstool -d aarch64 '404ba6f8'
 0  40 4b a6 f8  prfm   pldl1keep, [x26, w6, uxtw]
        ID: 782 (prfm)
        op_count: 2
                operands[0].type: SYS ALIAS:
                operands[0].subtype PRFM = 0x0
                operands[1].type: MEM
                        operands[1].mem.base: REG = x26
                        operands[1].mem.index: REG = w6
                operands[1].access: READ
                        Ext: 3
        Registers read: x26 w6

On both Capstone v3 and v4 the output match what I expect:

On v3:

cstool/cstool -d arm64 '404ba6f8'
0  40 4b a6 f8  prfm    pldl1keep, [x26, w6, uxtw]
        op_count: 2
                operands[0].type: PREFETCH = 0x1
                operands[1].type: MEM
                        operands[1].mem.base: REG = x26
                        operands[1].mem.index: REG = w6
                        Ext: 3

On v4:

cstool/cstool -d arm64 '404ba6f8'
 0  40 4b a6 f8  prfm   pldl1keep, [x26, w6, uxtw]
        ID: 204 (prfm)
        op_count: 2
                operands[0].type: PREFETCH = 0x1
                operands[1].type: MEM
                        operands[1].mem.base: REG = x26
                        operands[1].mem.index: REG = w6
                operands[1].access: READ | WRITE
                        Ext: 3
        Registers read: x26 w6
david942j commented 3 months ago

I am fine with the behavior on the next branch if the output there is expected. In this case this bug only happens on the v5 branch.

Rot127 commented 3 months ago

On the next branch it shows the enumeration value.

In this case it is AARCH64_PRFM_PLDL1KEEP = 0x0. See aarch64_prfm what the others are.

v5 is broken, yes.

Rot127 commented 3 months ago

I found this issue when implementing Crabstone Ruby binding on Capstone 5. The existing unit tests failed with Capstone 5.

I am currently rebuild testing. If you want to add support for newer versions, add support only for future v6 (the current next branch, release set to September). It is way way more up to data and modernized. If you continue, consider rebasing on https://github.com/capstone-engine/capstone/pull/2384. You can consume the yaml files with test cases there. Way way more easier.