diff --git a/arch/AArch64/AArch64Mapping.c b/arch/AArch64/AArch64Mapping.c index 6bfc55f181..71ac20347c 100644 --- a/arch/AArch64/AArch64Mapping.c +++ b/arch/AArch64/AArch64Mapping.c @@ -2559,6 +2559,18 @@ void AArch64_set_detail_op_reg(MCInst *MI, unsigned OpNum, aarch64_reg Reg) AArch64_inc_op_count(MI); } +/// Check if the previous operand is a memory operand +/// with only the base register set AND if this base register +/// is write-back. +/// This indicates the following immediate is a post-indexed +/// memory offset. +static bool prev_is_membase_wb(MCInst *MI) { + return AArch64_get_detail(MI)->op_count > 0 && + AArch64_get_detail_op(MI, -1)->type == AARCH64_OP_MEM && + AArch64_get_detail_op(MI, -1)->mem.disp == 0 && + get_detail(MI)->writeback; +} + /// Adds an immediate AArch64 operand at position OpNum and increases the op_count /// by one. void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum, @@ -2581,7 +2593,7 @@ void AArch64_set_detail_op_imm(MCInst *MI, unsigned OpNum, } return; } - if (map_get_op_type(MI, OpNum) & CS_OP_MEM) { + if (map_get_op_type(MI, OpNum) & CS_OP_MEM || prev_is_membase_wb(MI)) { AArch64_set_detail_op_mem(MI, OpNum, Imm); return; } @@ -2635,7 +2647,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val) if (!detail_is_set(MI)) return; AArch64_check_safe_inc(MI); - CS_ASSERT_RET(map_get_op_type(MI, OpNum) & CS_OP_MEM); AArch64_set_mem_access(MI, true); @@ -2644,7 +2655,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val) default: CS_ASSERT_RET(0 && "Secondary type not supported yet."); case CS_OP_REG: { - CS_ASSERT_RET(secondary_type == CS_OP_REG); bool is_index_reg = AArch64_get_detail_op(MI, 0)->mem.base != AARCH64_REG_INVALID; if (is_index_reg) @@ -2666,7 +2676,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val) break; } case CS_OP_IMM: { - CS_ASSERT_RET(secondary_type == CS_OP_IMM); AArch64_get_detail_op(MI, 0)->mem.disp = Val; break; } diff --git a/tests/details/aarch64.yaml b/tests/details/aarch64.yaml index a8190b1d61..c01859ace7 100644 --- a/tests/details/aarch64.yaml +++ b/tests/details/aarch64.yaml @@ -361,10 +361,7 @@ test_cases: - type: AARCH64_OP_MEM mem_base: sp - access: CS_AC_READ - - - type: AARCH64_OP_IMM - imm: 0x3c + mem_disp: 0x3c access: CS_AC_READ post_indexed: 1 cc: AArch64CC_Invalid diff --git a/tests/issues/issues.yaml b/tests/issues/issues.yaml index 81abf5818b..8d39204f55 100644 --- a/tests/issues/issues.yaml +++ b/tests/issues/issues.yaml @@ -5411,3 +5411,30 @@ test_cases: mem_base: x0 access: CS_AC_READ_WRITE regs_read: [ w1, w2, x0 ] + - + input: + name: "issue ldr offset as imm: https://github.com/capstone-engine/capstone/issues/2015#issuecomment-2373660217" + bytes: [ 0x01, 0xa4, 0x40, 0xf8 ] + arch: "CS_ARCH_AARCH64" + options: [ CS_OPT_DETAIL ] + address: 0x0 + expected: + insns: + - + asm_text: "ldr x1, [x0], #0xa" + details: + aarch64: + operands: + - + type: AARCH64_OP_REG + reg: x1 + access: CS_AC_WRITE + - + type: AARCH64_OP_MEM + mem_base: x0 + mem_disp: 0xa + access: CS_AC_READ + post_indexed: 1 + writeback: 1 + regs_read: [ x0 ] + regs_write: [ x0, x1 ]