From 6235f7fa1ebce56ad1eb815e5966c844dea258c2 Mon Sep 17 00:00:00 2001 From: wargio Date: Wed, 28 Aug 2024 23:42:42 +0800 Subject: [PATCH] Add reg_access --- arch/Mips/MipsMapping.c | 56 +++++++++++++++++++++++++++++++++++++++++ arch/Mips/MipsMapping.h | 4 +++ arch/Mips/MipsModule.c | 2 +- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/arch/Mips/MipsMapping.c b/arch/Mips/MipsMapping.c index f6c4f4eca4..f68710db6e 100644 --- a/arch/Mips/MipsMapping.c +++ b/arch/Mips/MipsMapping.c @@ -92,6 +92,62 @@ const insn_map mips_insns[] = { #include "MipsGenCSMappingInsn.inc" }; +void Mips_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_mips *mips = &(insn->detail->mips); + + 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 < mips->op_count; i++) { + cs_mips_op *op = &(mips->operands[i]); + switch ((int)op->type) { + case MIPS_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 MIPS_OP_MEM: + // registers appeared in memory references always being read + if ((op->mem.base != MIPS_REG_INVALID) && + !arr_exist(regs_read, read_count, op->mem.base)) { + regs_read[read_count] = (uint16_t)op->mem.base; + read_count++; + } + if ((insn->detail->writeback) && + (op->mem.base != MIPS_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; +} + void Mips_set_instr_map_data(MCInst *MI) { map_cs_id(MI, mips_insns, ARR_SIZE(mips_insns)); diff --git a/arch/Mips/MipsMapping.h b/arch/Mips/MipsMapping.h index 8d7de21bba..4a57e72320 100644 --- a/arch/Mips/MipsMapping.h +++ b/arch/Mips/MipsMapping.h @@ -30,6 +30,10 @@ bool Mips_getInstruction(csh handle, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info); +void Mips_reg_access(const cs_insn *insn, cs_regs regs_read, + uint8_t *regs_read_count, cs_regs regs_write, + uint8_t *regs_write_count); + // cs_detail related functions void Mips_init_cs_detail(MCInst *MI); void Mips_set_detail_op_imm(MCInst *MI, unsigned OpNum, diff --git a/arch/Mips/MipsModule.c b/arch/Mips/MipsModule.c index 941abc16ed..6a1a963cb5 100644 --- a/arch/Mips/MipsModule.c +++ b/arch/Mips/MipsModule.c @@ -27,7 +27,7 @@ cs_err Mips_global_init(cs_struct *ud) ud->disasm = Mips_getInstruction; ud->post_printer = NULL; #ifndef CAPSTONE_DIET - //ud->reg_access = Mips_reg_access; + ud->reg_access = Mips_reg_access; #endif return CS_ERR_OK;