void ARM_reg_access(const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count) { uint8_t i; uint8_t read_count, write_count; cs_arm *arm = &(insn->detail->arm); read_count = insn->detail->regs_read_count; write_count = insn->detail->regs_write_count; // implicit registers memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0])); memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0])); // explicit registers for (i = 0; i < arm->op_count; i++) { cs_arm_op *op = &(arm->operands[i]); switch((int)op->type) { case ARM_OP_REG: if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) { regs_read[read_count] = (uint16_t)op->reg; read_count++; } if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) { regs_write[write_count] = (uint16_t)op->reg; write_count++; } break; case ARM_OP_MEM: // registers appeared in memory references always being read if ((op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) { regs_read[read_count] = (uint16_t)op->mem.base; read_count++; } if ((op->mem.index != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) { regs_read[read_count] = (uint16_t)op->mem.index; read_count++; } if ((arm->writeback) && (op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) { regs_write[write_count] = (uint16_t)op->mem.base; write_count++; } default: break; } } *regs_read_count = read_count; *regs_write_count = write_count; }
CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id) { struct cs_struct *handle; if (!ud) return false; handle = (struct cs_struct *)(uintptr_t)ud; if (!handle->detail) { handle->errnum = CS_ERR_DETAIL; return false; } if(!insn->id) { handle->errnum = CS_ERR_SKIPDATA; return false; } if(!insn->detail) { handle->errnum = CS_ERR_DETAIL; return false; } return arr_exist(insn->detail->regs_write, insn->detail->regs_write_count, reg_id); }
CAPSTONE_EXPORT bool cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id) { struct cs_struct *handle; if (!ud) return false; handle = (struct cs_struct *)(uintptr_t)ud; if (!handle->detail) { handle->errnum = CS_ERR_DETAIL; return false; } if(!insn->id) { handle->errnum = CS_ERR_SKIPDATA; return false; } if(!insn->detail) { handle->errnum = CS_ERR_DETAIL; return false; } return arr_exist(insn->detail->groups, insn->detail->groups_count, group_id); }
bool cs_reg_write(csh ud, cs_insn *insn, unsigned int reg_id) { if (!ud) return false; struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; if (!handle->detail) { handle->errnum = CS_ERR_DETAIL; return false; } return arr_exist(insn->detail->regs_write, insn->detail->regs_write_count, reg_id); }
bool cs_insn_group(csh ud, cs_insn *insn, unsigned int group_id) { if (!ud) return false; struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud; if (!handle->detail) { handle->errnum = CS_ERR_DETAIL; return false; } return arr_exist(insn->detail->groups, insn->detail->groups_count, group_id); }