Skip to content

Commit 52abc77

Browse files
DanielBotnikclaude
andcommitted
Fix AArch64 register-offset load/store memory operand access
Fix issue #2802 where register-offset addressing mode load and store instructions were not correctly marking memory operands as READ/WRITE. For example, LDRSW with register offset (ldrsw x10, [x22, x10, lsl #2]) had the memory operand access as invalid instead of READ. The issue was in the auto-generated mapping table where roW/roX variants incorrectly had CS_AC_INVALID instead of CS_AC_READ/CS_AC_WRITE. Since the mapping is auto-generated and cannot be modified directly, add a correction function AArch64_get_mem_access_for_opcode() that provides the correct access type for these instructions. This affects all load/store variants with register offset addressing: - LDR*, LDRB*, LDRH*, LDRSB*, LDRSH*, LDRSW* - STR*, STRB*, STRH*, STRD* - PRFM Add test case for LDRSW with register offset addressing mode. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent a020137 commit 52abc77

2 files changed

Lines changed: 92 additions & 2 deletions

File tree

arch/AArch64/AArch64Mapping.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,69 @@ const insn_map aarch64_insns[] = {
136136
#include "AArch64GenCSMappingInsn.inc"
137137
};
138138

139+
// Helper function to get the correct memory access type for an instruction.
140+
// Corrects auto-generated mapping entries that have CS_AC_INVALID for
141+
// register-offset addressing modes (roW/roX variants).
142+
static cs_ac_type AArch64_get_mem_access(unsigned opcode)
143+
{
144+
// Corrections for register-offset load/store instructions
145+
switch (opcode) {
146+
// Load instructions with register offset
147+
case AArch64_LDRBBroW:
148+
case AArch64_LDRBBroX:
149+
case AArch64_LDRBroW:
150+
case AArch64_LDRBroX:
151+
case AArch64_LDRDroX:
152+
case AArch64_LDRHHroW:
153+
case AArch64_LDRHHroX:
154+
case AArch64_LDRHroW:
155+
case AArch64_LDRHroX:
156+
case AArch64_LDRQroX:
157+
case AArch64_LDRSBWroW:
158+
case AArch64_LDRSBWroX:
159+
case AArch64_LDRSBXroW:
160+
case AArch64_LDRSBXroX:
161+
case AArch64_LDRSHWroW:
162+
case AArch64_LDRSHWroX:
163+
case AArch64_LDRSHXroW:
164+
case AArch64_LDRSHXroX:
165+
case AArch64_LDRSWroW:
166+
case AArch64_LDRSWroX:
167+
case AArch64_LDRSroW:
168+
case AArch64_LDRSroX:
169+
case AArch64_LDRWroW:
170+
case AArch64_LDRWroX:
171+
case AArch64_LDRXroW:
172+
case AArch64_LDRXroX:
173+
return CS_AC_READ;
174+
// Store instructions with register offset
175+
case AArch64_STRBBroW:
176+
case AArch64_STRBBroX:
177+
case AArch64_STRBroW:
178+
case AArch64_STRBroX:
179+
case AArch64_STRDroX:
180+
case AArch64_STRHHroW:
181+
case AArch64_STRHHroX:
182+
case AArch64_STRHroW:
183+
case AArch64_STRHroX:
184+
case AArch64_STRQroX:
185+
case AArch64_STRSroW:
186+
case AArch64_STRSroX:
187+
case AArch64_STRWroW:
188+
case AArch64_STRWroX:
189+
case AArch64_STRXroW:
190+
case AArch64_STRXroX:
191+
return CS_AC_WRITE;
192+
// Prefetch (read-only)
193+
case AArch64_PRFMroW:
194+
case AArch64_PRFMroX:
195+
return CS_AC_READ;
196+
default:
197+
// Use the auto-generated mapping for all other instructions
198+
return aarch64_insns[opcode].suppl_info.aarch64.mem_acc;
199+
}
200+
}
201+
139202
static const name_map insn_alias_mnem_map[] = {
140203
#include "AArch64GenCSAliasMnemMap.inc"
141204
{ AARCH64_INS_ALIAS_CFP, "cfp" },
@@ -903,8 +966,7 @@ static void AArch64_correct_mem_access(MCInst *MI)
903966
#ifndef CAPSTONE_DIET
904967
if (!detail_is_set(MI))
905968
return;
906-
cs_ac_type access =
907-
aarch64_insns[MI->Opcode].suppl_info.aarch64.mem_acc;
969+
cs_ac_type access = AArch64_get_mem_access(MI->Opcode);
908970
if (access == CS_AC_INVALID) {
909971
return;
910972
}

tests/details/aarch64.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,3 +1542,31 @@ test_cases:
15421542
operands: []
15431543
regs_read: []
15441544
regs_write: []
1545+
-
1546+
input:
1547+
bytes: [0xca, 0x7a, 0xaa, 0xb8]
1548+
arch: "CS_ARCH_AARCH64"
1549+
options: [ "CS_OPT_DETAIL" ]
1550+
address: 0x0
1551+
expected:
1552+
insns:
1553+
-
1554+
asm_text: "ldrsw x10, [x22, x10, lsl #2]"
1555+
details:
1556+
aarch64:
1557+
operands:
1558+
-
1559+
type: AARCH64_OP_REG
1560+
reg: x10
1561+
access: CS_AC_WRITE
1562+
-
1563+
type: AARCH64_OP_MEM
1564+
mem:
1565+
base: x22
1566+
index: x10
1567+
access: CS_AC_READ
1568+
shift:
1569+
type: AARCH64_SFT_LSL
1570+
value: 2
1571+
regs_read: [x22, x10]
1572+
regs_write: [x10]

0 commit comments

Comments
 (0)