Skip to content

Commit c3c0c7c

Browse files
committed
Fix register access for AArch64 atomics
The LSE atomics (CAS, CASP, SWP and the LD<op>/ST<op> families) had empty operand access, so cs_regs_access reported neither the value registers read nor the destination written. Populate the access table, and handle the CASP register pairs in AArch64_reg_access, whose second element gets no access info from the printer.
1 parent 0225758 commit c3c0c7c

4 files changed

Lines changed: 253 additions & 169 deletions

File tree

arch/AArch64/AArch64Mapping.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,11 @@ const uint8_t *AArch64_get_op_access(cs_struct *h, unsigned int id)
827827
return NULL;
828828
}
829829

830+
static bool is_casp(unsigned int id);
831+
static void add_casp_register_pair_access(const cs_arm64 *arm64,
832+
cs_regs regs_read, uint8_t *read_count,
833+
cs_regs regs_write, uint8_t *write_count);
834+
830835
void AArch64_reg_access(const cs_insn *insn,
831836
cs_regs regs_read, uint8_t *regs_read_count,
832837
cs_regs regs_write, uint8_t *regs_write_count)
@@ -875,9 +880,40 @@ void AArch64_reg_access(const cs_insn *insn,
875880
}
876881
}
877882

883+
if (is_casp(insn->id))
884+
add_casp_register_pair_access(arm64, regs_read, &read_count, regs_write, &write_count);
885+
878886
*regs_read_count = read_count;
879887
*regs_write_count = write_count;
880888
}
889+
890+
static bool is_casp(unsigned int id)
891+
{
892+
return id == ARM64_INS_CASP || id == ARM64_INS_CASPA ||
893+
id == ARM64_INS_CASPAL || id == ARM64_INS_CASPL;
894+
}
895+
896+
// The CASP register-pair operands have their second element printed without any
897+
// operand-access info, so populate it here: operands 0..1 are read and written,
898+
// 2..3 are read.
899+
static void add_casp_register_pair_access(const cs_arm64 *arm64,
900+
cs_regs regs_read, uint8_t *read_count,
901+
cs_regs regs_write, uint8_t *write_count)
902+
{
903+
uint8_t i;
904+
905+
for (i = 0; i < 4 && i < arm64->op_count; i++) {
906+
arm64_reg reg = arm64->operands[i].reg;
907+
if (!arr_exist(regs_read, *read_count, reg)) {
908+
regs_read[*read_count] = (uint16_t)reg;
909+
(*read_count)++;
910+
}
911+
if (i < 2 && !arr_exist(regs_write, *write_count, reg)) {
912+
regs_write[*write_count] = (uint16_t)reg;
913+
(*write_count)++;
914+
}
915+
}
916+
}
881917
#endif
882918

883919
#endif

0 commit comments

Comments
 (0)