Skip to content

Commit

Permalink
Fix LDR not assigning immediate as memory offset.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Sep 26, 2024
1 parent cc01c04 commit b7e0d21
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
16 changes: 12 additions & 4 deletions arch/AArch64/AArch64Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,17 @@ 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_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,
Expand All @@ -2581,7 +2592,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;
}
Expand Down Expand Up @@ -2635,7 +2646,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val)
if (!detail_is_set(MI))
return;
AArch64_check_safe_inc();
assert(map_get_op_type(MI, OpNum) & CS_OP_MEM);

AArch64_set_mem_access(MI, true);

Expand All @@ -2644,7 +2654,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val)
default:
assert(0 && "Secondary type not supported yet.");
case CS_OP_REG: {
assert(secondary_type == CS_OP_REG);
bool is_index_reg = AArch64_get_detail_op(MI, 0)->mem.base !=
AARCH64_REG_INVALID;
if (is_index_reg)
Expand All @@ -2666,7 +2675,6 @@ void AArch64_set_detail_op_mem(MCInst *MI, unsigned OpNum, uint64_t Val)
break;
}
case CS_OP_IMM: {
assert(secondary_type == CS_OP_IMM);
AArch64_get_detail_op(MI, 0)->mem.disp = Val;
break;
}
Expand Down
5 changes: 1 addition & 4 deletions tests/details/aarch64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions tests/issues/issues.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]

0 comments on commit b7e0d21

Please sign in to comment.