From c6cc2e2c3be15e55e00c5bb13a131f215c1123e2 Mon Sep 17 00:00:00 2001 From: billow Date: Wed, 10 Jul 2024 17:17:54 +0800 Subject: [PATCH] [skip-ci] xtensa: fix Xtensa_add_cs_detail --- Mapping.c | 1 + Mapping.h | 1 + arch/Xtensa/XtensaInstPrinter.c | 4 +- arch/Xtensa/XtensaMapping.c | 117 +++++++++++++------------------- 4 files changed, 50 insertions(+), 73 deletions(-) diff --git a/Mapping.c b/Mapping.c index 2f871273d89..4e9d7c5ef73 100644 --- a/Mapping.c +++ b/Mapping.c @@ -339,6 +339,7 @@ DEFINE_get_detail_op(alpha, Alpha); DEFINE_get_detail_op(hppa, HPPA); DEFINE_get_detail_op(loongarch, LoongArch); DEFINE_get_detail_op(riscv, RISCV); +DEFINE_get_detail_op(xtensa, Xtensa); /// Returns true if for this architecture the /// alias operands should be filled. diff --git a/Mapping.h b/Mapping.h index d1bc13c5fef..fd8d1d57c98 100644 --- a/Mapping.h +++ b/Mapping.h @@ -139,6 +139,7 @@ DECL_get_detail_op(alpha, Alpha); DECL_get_detail_op(hppa, HPPA); DECL_get_detail_op(loongarch, LoongArch); DECL_get_detail_op(riscv, RISCV); +DECL_get_detail_op(xtensa, Xtensa); /// Increments the detail->arch.op_count by one. #define DEFINE_inc_detail_op_count(arch, ARCH) \ diff --git a/arch/Xtensa/XtensaInstPrinter.c b/arch/Xtensa/XtensaInstPrinter.c index dbbcd925742..70fdb3bee83 100644 --- a/arch/Xtensa/XtensaInstPrinter.c +++ b/arch/Xtensa/XtensaInstPrinter.c @@ -46,10 +46,10 @@ static const char *getRegisterName(unsigned RegNo); static void printOperand(MCInst *MI, int OpNum, SStream *O) { + add_cs_detail(MI, XTENSA_OP_GROUP_OPERAND, OpNum); const MCOperand *MC = MCInst_getOperand(MI, (OpNum)); if (MCOperand_isReg(MC)) { SStream_concat0(O, getRegisterName(MCOperand_getReg(MC))); - } else if (MCOperand_isImm(MC)) { printInt64(O, MCOperand_getImm(MC)); } else if (MCOperand_isExpr(MC)) { @@ -64,7 +64,7 @@ static inline void printMemOperand(MCInst *MI, int OpNum, SStream *OS) SStream_concat0(OS, getRegisterName(MCOperand_getReg( MCInst_getOperand(MI, (OpNum))))); SStream_concat0(OS, ", "); - printOperand(MI, OpNum + 1, OS); + printInt64(OS, MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1))); } static inline void printBranchTarget(MCInst *MI, int OpNum, SStream *OS) diff --git a/arch/Xtensa/XtensaMapping.c b/arch/Xtensa/XtensaMapping.c index 3969b4dceab..7ded3803036 100644 --- a/arch/Xtensa/XtensaMapping.c +++ b/arch/Xtensa/XtensaMapping.c @@ -58,54 +58,6 @@ static void set_instr_map_data(MCInst *MI) map_implicit_reads(MI, mapping_insns); map_implicit_writes(MI, mapping_insns); map_groups(MI, mapping_insns); - - unsigned opcode = MCInst_getOpcode(MI); - if (opcode > ARR_SIZE(insn_operands)) { - return; - } - - const map_insn_ops *ops = &insn_operands[opcode]; - cs_xtensa *detail = Xtensa_get_detail(MI); - cs_xtensa_op *operand = detail->operands; - for (int i = 0; i < ARR_SIZE(ops->ops); ++i) { - const mapping_op *op = ops->ops + i; - if (!op->access || !op->type) { - break; - } - operand->access = op->access; - operand->type = op->type; - MCOperand *mc = MCInst_getOperand(MI, i); - -#define check(_k) if ((op->type & (_k)) == (_k)) - check(CS_OP_IMM) - { - operand->imm = (int32_t)mc->ImmVal; - } - check(CS_OP_REG) - { - operand->reg = (uint8_t)mc->RegVal; - } - check(CS_OP_MEM_REG) - { - operand->mem.base = mc->RegVal; - } - check(CS_OP_MEM_IMM) - { - if (i > 0) { - cs_xtensa_op *prev = (operand - 1); - if (prev->type == CS_OP_MEM_REG && - prev->access == op->access) { - prev->type = XTENSA_OP_MEM; - prev->mem.disp = mc->ImmVal; - continue; - } - } - operand->mem.disp = mc->ImmVal; - } - - detail->op_count++; - operand++; - } #endif } @@ -211,37 +163,60 @@ void Xtensa_reg_access(const cs_insn *insn, cs_regs regs_read, void Xtensa_add_cs_detail(MCInst *MI, xtensa_op_group op_group, va_list args) { - CS_ASSERT(0 && "unimplemented"); + int op_num = va_arg(args, int); + cs_xtensa_op *xop = Xtensa_get_detail_op(MI, 0); switch (op_group) { - case XTENSA_OP_GROUP_OPERAND: - break; + case XTENSA_OP_GROUP_OPERAND: { + const MCOperand *MC = MCInst_getOperand(MI, op_num); + if (MCOperand_isReg(MC)) { + xop->type = XTENSA_OP_REG; + xop->reg = MC->RegVal; + } else if (MCOperand_isImm(MC)) { + xop->type = XTENSA_OP_IMM; + xop->imm = MC->ImmVal; + } + } break; case XTENSA_OP_GROUP_IMM8_ASMOPERAND: - break; case XTENSA_OP_GROUP_IMM8_SH8_ASMOPERAND: - break; - case XTENSA_OP_GROUP_BRANCHTARGET: - break; case XTENSA_OP_GROUP_UIMM5_ASMOPERAND: - break; case XTENSA_OP_GROUP_B4CONST_ASMOPERAND: - break; case XTENSA_OP_GROUP_B4CONSTU_ASMOPERAND: - break; - case XTENSA_OP_GROUP_CALLOPERAND: - break; case XTENSA_OP_GROUP_IMM1_16_ASMOPERAND: - break; - case XTENSA_OP_GROUP_JUMPTARGET: - break; - case XTENSA_OP_GROUP_MEMOPERAND: - break; - case XTENSA_OP_GROUP_L32RTARGET: - break; case XTENSA_OP_GROUP_IMM12M_ASMOPERAND: - break; case XTENSA_OP_GROUP_SHIMM1_31_ASMOPERAND: - break; - case XTENSA_OP_GROUP_UIMM4_ASMOPERAND: - break; + case XTENSA_OP_GROUP_UIMM4_ASMOPERAND: { + int64_t val = MCOperand_getImm(MCInst_getOperand(MI, op_num)); + xop->type = XTENSA_OP_IMM; + xop->imm = (int32_t)val; + } break; + case XTENSA_OP_GROUP_BRANCHTARGET: + case XTENSA_OP_GROUP_JUMPTARGET: + case XTENSA_OP_GROUP_CALLOPERAND: { + int64_t val = + MCOperand_getImm(MCInst_getOperand(MI, op_num)) + 4; + xop->type = XTENSA_OP_MEM_IMM; + xop->mem.base = (int32_t)val; + } break; + case XTENSA_OP_GROUP_L32RTARGET: { + int64_t val = MCOperand_getImm(MCInst_getOperand(MI, (op_num))); + int64_t instr_off = val & 0x3; + val -= instr_off; + val += ((instr_off + 0x3) & 0x4) - instr_off; + xop->type = XTENSA_OP_MEM_IMM; + xop->mem.base = (int32_t)val; + } break; + case XTENSA_OP_GROUP_MEMOPERAND: { + unsigned reg = + MCOperand_getReg(MCInst_getOperand(MI, (op_num))); + int64_t val = + MCOperand_getImm(MCInst_getOperand(MI, op_num + 1)); + xop->type = XTENSA_OP_MEM; + xop->mem.base = reg; + xop->mem.disp = val; + } break; } + + const map_insn_ops *ops = insn_operands + MCInst_getOpcode(MI); + xop->access = (ops->ops + op_num)->access; + Xtensa_inc_op_count(MI); } \ No newline at end of file