From 2c56c68d3696d4aaaba7ce2b573f1caf9148a405 Mon Sep 17 00:00:00 2001 From: billow Date: Wed, 10 Jan 2024 22:36:06 +0800 Subject: [PATCH] Remove static and global variables in TriCore RzAsm and RzAnalysis plugin --- librz/analysis/p/analysis_tricore_cs.c | 359 ++++++++++++++++++------- librz/asm/arch/tricore/tricore.h | 13 +- librz/asm/arch/tricore/tricore.inc | 86 +++--- librz/asm/asm.c | 1 + librz/asm/p/asm_tricore_cs.c | 82 +++--- librz/core/disasm.c | 10 +- test/db/analysis/tricore | 195 ++++++++++++-- 7 files changed, 566 insertions(+), 180 deletions(-) diff --git a/librz/analysis/p/analysis_tricore_cs.c b/librz/analysis/p/analysis_tricore_cs.c index 750a5bbd26b..015695b03a1 100644 --- a/librz/analysis/p/analysis_tricore_cs.c +++ b/librz/analysis/p/analysis_tricore_cs.c @@ -5,15 +5,13 @@ #include #include #include -#include #include -#include #include "../../asm/arch/tricore/tricore.inc" #define TRICORE_REG_SP TRICORE_REG_A10 -static char *get_reg_profile(RzAnalysis *_) { +static char *tricore_reg_profile(RzAnalysis *_) { const char *p = "=PC pc\n" "=SP a10\n" @@ -66,29 +64,192 @@ static char *get_reg_profile(RzAnalysis *_) { "gpr e14 .64 120 0\n" "gpr d14 .32 120 0\n" "gpr d15 .32 124 0\n" - "gpr PSW .32 128 0\n" - "gpr PCXI .32 132 0\n" - "gpr FCX .32 136 0\n" - "gpr LCX .32 140 0\n" - "gpr ISP .32 144 0\n" - "gpr ICR .32 148 0\n" - "gpr PIPN .32 152 0\n" - "gpr BIV .32 156 0\n" - "gpr BTV .32 160 0\n" - "gpr pc .32 164 0\n"; + "drx PCXI .32 128 0\n" + "drx PSW .32 132 0\n" + "drx pc .32 136 0\n" + "drx SYSCON .32 140 0\n" + "drx CPU_ID .32 144 0\n" + "drx CORE_ID .32 148 0\n" + "drx BIV .32 152 0\n" + "drx BTV .32 156 0\n" + "drx ISP .32 160 0\n" + "drx ICR .32 164 0\n" + "drx FCX .32 168 0\n" + "drx LCX .32 172 0\n" + "drx COMPAT .32 176 0\n" + "drx DPR0_L .32 180 0\n" + "drx DPR0_U .32 184 0\n" + "drx DPR1_L .32 188 0\n" + "drx DPR1_U .32 192 0\n" + "drx DPR2_L .32 196 0\n" + "drx DPR2_U .32 200 0\n" + "drx DPR3_L .32 204 0\n" + "drx DPR3_U .32 208 0\n" + "drx DPR4_L .32 212 0\n" + "drx DPR4_U .32 216 0\n" + "drx DPR5_L .32 220 0\n" + "drx DPR5_U .32 224 0\n" + "drx DPR6_L .32 228 0\n" + "drx DPR6_U .32 232 0\n" + "drx DPR7_L .32 236 0\n" + "drx DPR7_U .32 240 0\n" + "drx DPR8_L .32 244 0\n" + "drx DPR8_U .32 248 0\n" + "drx DPR9_L .32 252 0\n" + "drx DPR9_U .32 256 0\n" + "drx DPR10_L .32 260 0\n" + "drx DPR10_U .32 264 0\n" + "drx DPR11_L .32 268 0\n" + "drx DPR11_U .32 272 0\n" + "drx DPR12_L .32 276 0\n" + "drx DPR12_U .32 280 0\n" + "drx DPR13_L .32 284 0\n" + "drx DPR13_U .32 288 0\n" + "drx DPR14_L .32 292 0\n" + "drx DPR14_U .32 296 0\n" + "drx DPR15_L .32 300 0\n" + "drx DPR15_U .32 304 0\n" + "drx CPR0_L .32 308 0\n" + "drx CPR0_U .32 312 0\n" + "drx CPR1_L .32 316 0\n" + "drx CPR1_U .32 320 0\n" + "drx CPR2_L .32 324 0\n" + "drx CPR2_U .32 328 0\n" + "drx CPR3_L .32 332 0\n" + "drx CPR3_U .32 336 0\n" + "drx CPR4_L .32 340 0\n" + "drx CPR4_U .32 344 0\n" + "drx CPR5_L .32 348 0\n" + "drx CPR5_U .32 352 0\n" + "drx CPR6_L .32 356 0\n" + "drx CPR6_U .32 360 0\n" + "drx CPR7_L .32 364 0\n" + "drx CPR7_U .32 368 0\n" + "drx CPR8_L .32 372 0\n" + "drx CPR8_U .32 376 0\n" + "drx CPR9_L .32 380 0\n" + "drx CPR9_U .32 384 0\n" + "drx CPR10_L .32 388 0\n" + "drx CPR10_U .32 392 0\n" + "drx CPR11_L .32 396 0\n" + "drx CPR11_U .32 400 0\n" + "drx CPR12_L .32 404 0\n" + "drx CPR12_U .32 408 0\n" + "drx CPR13_L .32 412 0\n" + "drx CPR13_U .32 416 0\n" + "drx CPR14_L .32 420 0\n" + "drx CPR14_U .32 424 0\n" + "drx CPR15_L .32 428 0\n" + "drx CPR15_U .32 432 0\n" + "drx CPXE_0 .32 436 0\n" + "drx CPXE_1 .32 440 0\n" + "drx CPXE_2 .32 444 0\n" + "drx CPXE_3 .32 448 0\n" + "drx CPXE_4 .32 452 0\n" + "drx CPXE_5 .32 456 0\n" + "drx CPXE_6 .32 460 0\n" + "drx CPXE_7 .32 464 0\n" + "drx DPRE_0 .32 468 0\n" + "drx DPRE_1 .32 472 0\n" + "drx DPRE_2 .32 476 0\n" + "drx DPRE_3 .32 480 0\n" + "drx DPRE_4 .32 484 0\n" + "drx DPRE_5 .32 488 0\n" + "drx DPRE_6 .32 492 0\n" + "drx DPRE_7 .32 496 0\n" + "drx DPWE_0 .32 500 0\n" + "drx DPWE_1 .32 504 0\n" + "drx DPWE_2 .32 508 0\n" + "drx DPWE_3 .32 512 0\n" + "drx DPWE_4 .32 516 0\n" + "drx DPWE_5 .32 520 0\n" + "drx DPWE_6 .32 524 0\n" + "drx DPWE_7 .32 528 0\n" + "drx TPS_CON .32 532 0\n" + "drx TPS_TIMER0 .32 536 0\n" + "drx TPS_TIMER1 .32 540 0\n" + "drx TPS_TIMER2 .32 544 0\n" + "drx TPS_EXTIM_ENTRY_CVAL .32 548 0\n" + "drx TPS_EXTIM_ENTRY_LVAL .32 552 0\n" + "drx TPS_EXTIM_EXIT_CVAL .32 556 0\n" + "drx TPS_EXTIM_EXIT_LVAL .32 560 0\n" + "drx TPS_EXTIM_CLASS_EN .32 564 0\n" + "drx TPS_EXTIM_STAT .32 568 0\n" + "drx TPS_EXTIM_FCX .32 572 0\n" + "drx MMU_CON .32 576 0\n" + "drx MMU_ASI .32 580 0\n" + "drx MMU_TVA .32 584 0\n" + "drx MMU_TPA .32 588 0\n" + "drx MMU_TPX .32 592 0\n" + "drx MMU_TFA .32 596 0\n" + "drx MMU_TFAS .32 600 0\n" + "drx PMA01_ .32 604 0\n" + "drx PMA01 .32 608 0\n" + "drx PMA11 .32 612 0\n" + "drx PMA21 .32 616 0\n" + "drx DCON2 .32 620 0\n" + "drx DCON1 .32 624 0\n" + "drx SMACON .32 628 0\n" + "drx DSTR .32 632 0\n" + "drx DATR .32 636 0\n" + "drx DEADD .32 640 0\n" + "drx DIEAR .32 644 0\n" + "drx DIETR .32 648 0\n" + "drx DCON0 .32 652 0\n" + "drx PSTR .32 656 0\n" + "drx PCON1 .32 660 0\n" + "drx PCON2 .32 664 0\n" + "drx PCON0 .32 668 0\n" + "drx PIEAR .32 672 0\n" + "drx PIETR .32 676 0\n" + "drx DBGSR .32 680 0\n" + "drx EXEVT .32 684 0\n" + "drx CREVT .32 688 0\n" + "drx SWEVT .32 692 0\n" + "drx TR0EVT .32 696 0\n" + "drx TR0ADR .32 700 0\n" + "drx TR1EVT .32 704 0\n" + "drx TR1ADR .32 708 0\n" + "drx TR2EVT .32 712 0\n" + "drx TR2ADR .32 716 0\n" + "drx TR3EVT .32 720 0\n" + "drx TR3ADR .32 724 0\n" + "drx TR4EVT .32 728 0\n" + "drx TR4ADR .32 732 0\n" + "drx TR5EVT .32 736 0\n" + "drx TR5ADR .32 740 0\n" + "drx TR6EVT .32 744 0\n" + "drx TR6ADR .32 748 0\n" + "drx TR7EVT .32 752 0\n" + "drx TR7ADR .32 756 0\n" + "drx TRIG_ACC .32 760 0\n" + "drx DMS .32 764 0\n" + "drx DCX .32 768 0\n" + "drx TASK_ASI .32 772 0\n" + "drx DBGTCR .32 776 0\n" + "drx CCTRL .32 780 0\n" + "drx CCNT .32 784 0\n" + "drx ICNT .32 788 0\n" + "drx M1CNT .32 792 0\n" + "drx M2CNT .32 796 0\n" + "drx M3CNT .32 800 0\n" + "drx FPU_TRAP_CON .32 804 0\n" + "drx FPU_TRAP_PC .32 808 0\n" + "drx FPU_TRAP_OPC .32 812 0\n" + "drx FPU_TRAP_SRC1 .32 816 0\n" + "drx FPU_TRAP_SRC2 .32 820 0\n" + "drx FPU_TRAP_SRC3 .32 824 0\n"; return strdup(p); } -static void tricore_opex(RzStrBuf *ptr, csh handle, cs_insn *p_insn); +static void tricore_opex(RzAsmTriCoreContext *ctx, RzStrBuf *sb); -static void rz_analysis_tricore_fillval(RzAnalysis *, RzAnalysisOp *, csh, cs_insn *); +static void tricore_fillvals(RzAsmTriCoreContext *ctx, RzAnalysis *a, RzAnalysisOp *op); -static RzAnalysisLiftedILOp rz_analysis_tricore_il_op(); - -static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn); +static void tricore_op_set_type(RzAsmTriCoreContext *ctx, RzAnalysisOp *op); static int -rz_analysis_tricore_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) { +tricore_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) { if (!(a && op && data && len > 0)) { return 0; } @@ -96,41 +257,40 @@ rz_analysis_tricore_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *da return -1; } - csh handle = tricore_setup_cs_handle(a->cpu, NULL); - if (handle == 0) { + RzAsmTriCoreContext *ctx = a->plugin_data; + if (!tricore_setup_cs_handle(ctx, a->cpu, NULL)) { return -1; } op->size = 2; - cs_insn *insn = NULL; - ut32 count = cs_disasm(handle, (const ut8 *)data, len, addr, 1, &insn); - if (count <= 0) { + + ctx->insn = NULL; + ctx->count = cs_disasm(ctx->h, (const ut8 *)data, len, addr, 1, &ctx->insn); + if (ctx->count <= 0 || !ctx->insn) { op->type = RZ_ANALYSIS_OP_TYPE_ILL; if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { op->mnemonic = strdup("invalid"); } - return op->size; + goto beach; } + if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { - op->mnemonic = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str); + op->mnemonic = rz_str_newf("%s%s%s", + ctx->insn->mnemonic, ctx->insn->op_str[0] ? " " : "", ctx->insn->op_str); } - - op->size = insn->size; - op->id = (int)insn->id; - op->addr = insn->address; - tricore_op_set_type(op, handle, insn); - + op->size = ctx->insn->size; + op->id = (int)ctx->insn->id; + op->addr = ctx->insn->address; + tricore_op_set_type(ctx, op); if (mask & RZ_ANALYSIS_OP_MASK_OPEX) { - tricore_opex(&op->opex, handle, insn); + tricore_opex(ctx, &op->opex); } if (mask & RZ_ANALYSIS_OP_MASK_VAL) { - rz_analysis_tricore_fillval(a, op, handle, insn); - } - if (mask & RZ_ANALYSIS_OP_MASK_IL) { - op->il_op = rz_analysis_tricore_il_op(); + tricore_fillvals(ctx, a, op); } - cs_free(insn, count); +beach: + cs_free(ctx->insn, ctx->count); return op->size; } @@ -277,14 +437,14 @@ static inline bool is_inst_packed(unsigned int insn) { } } -static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { - if (is_inst_privileged(insn->id)) { +static void tricore_op_set_type(RzAsmTriCoreContext *ctx, RzAnalysisOp *op) { + if (is_inst_privileged(ctx->insn->id)) { op->family = RZ_ANALYSIS_OP_FAMILY_PRIV; - } else if (is_inst_packed(insn->id)) { + } else if (is_inst_packed(ctx->insn->id)) { op->family = RZ_ANALYSIS_OP_FAMILY_MMX; } - switch (insn->id) { + switch (ctx->insn->id) { default: { op->type = RZ_ANALYSIS_OP_TYPE_UNK; break; @@ -292,7 +452,7 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_FCALLI: { op->family = RZ_ANALYSIS_OP_FAMILY_FPU; op->type = RZ_ANALYSIS_OP_TYPE_IRCALL; - op->reg = tricore_get_op_regname(h, insn, 0); + op->reg = tricore_op_as_reg(ctx, 0); op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = -4; break; @@ -301,7 +461,7 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_FCALL: { op->family = RZ_ANALYSIS_OP_FAMILY_FPU; op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = (ut32)tricore_get_op_imm(insn, 0); + op->jump = (ut32)tricore_op_as_imm(ctx, 0); op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = -4; break; @@ -403,11 +563,11 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_ADDS_BU: case TRICORE_INS_ADDS_U: { op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (tricore_op_count(insn) >= 2) { - const cs_tricore_op *op1 = tricore_get_op(insn, 1); + if (tricore_op_count(ctx->insn) >= 2) { + const cs_tricore_op *op1 = tricore_op_get(ctx->insn, 1); if (op1->type == TRICORE_OP_IMM) { op->val = op1->imm; - const cs_tricore_op *op0 = tricore_get_op(insn, 0); + const cs_tricore_op *op0 = tricore_op_get(ctx->insn, 0); if (op0->type == TRICORE_OP_REG && op0->reg == TRICORE_REG_SP) { op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = op1->imm; @@ -476,14 +636,14 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { } case TRICORE_INS_CALLI: { op->type = RZ_ANALYSIS_OP_TYPE_IRCALL; - op->reg = tricore_get_op_regname(h, insn, 0); + op->reg = tricore_op_as_reg(ctx, 0); op->stackop = RZ_ANALYSIS_STACK_GET; break; } case TRICORE_INS_CALLA: case TRICORE_INS_CALL: { op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = (ut32)tricore_get_op_imm(insn, 0); + op->jump = (ut32)tricore_op_as_imm(ctx, 0); op->stackop = RZ_ANALYSIS_STACK_GET; break; } @@ -552,13 +712,13 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_JA: case TRICORE_INS_J: { op->type = RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = (ut32)tricore_get_op_imm(insn, 0); + op->jump = (ut32)tricore_op_as_imm(ctx, 0); break; } case TRICORE_INS_JI: case TRICORE_INS_JLI: { op->type = RZ_ANALYSIS_OP_TYPE_IRJMP; - op->reg = tricore_get_op_regname(h, insn, 0); + op->reg = tricore_op_as_reg(ctx, 0); break; } @@ -589,9 +749,9 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_JZ_A: case TRICORE_INS_JZ: { op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = (ut32)tricore_get_op_imm(insn, tricore_op_count(insn) - 1); - op->fail = insn->address + insn->size; - op->cond = insn2cond(insn->id); + op->jump = (ut32)tricore_op_as_imm(ctx, tricore_op_count(ctx->insn) - 1); + op->fail = ctx->insn->address + ctx->insn->size; + op->cond = insn2cond(ctx->insn->id); break; } case TRICORE_INS_LDLCX: @@ -612,8 +772,8 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_LD_W: { op->refptr = 4; op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - if (insn->detail->tricore.op_count >= 2) { - const cs_tricore_op *op1 = tricore_get_op(insn, 1); + if (ctx->insn->detail->tricore.op_count >= 2) { + const cs_tricore_op *op1 = tricore_op_get(ctx->insn, 1); if (op1->type == TRICORE_OP_REG && op1->reg == TRICORE_REG_SP) { op->stackop = RZ_ANALYSIS_STACK_GET; } @@ -714,12 +874,12 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_CMOVN: case TRICORE_INS_CMOV: { op->type = RZ_ANALYSIS_OP_TYPE_MOV; - cs_tricore_op *dst = tricore_get_op(insn, 0); + cs_tricore_op *dst = tricore_op_get(ctx->insn, 0); if (dst->type == TRICORE_OP_REG) { - op->reg = cs_reg_name(h, dst->reg); + op->reg = cs_reg_name(ctx->h, dst->reg); } - if (insn->detail->tricore.op_count == 2) { - cs_tricore_op *src = tricore_get_op(insn, 1); + if (tricore_op_count(ctx->insn) == 2) { + cs_tricore_op *src = tricore_op_get(ctx->insn, 1); if (src->type == TRICORE_OP_IMM) { op->val = src->imm; } @@ -782,9 +942,9 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_MSUBM_U: case TRICORE_INS_MSUBMS_U: { op->type = RZ_ANALYSIS_OP_TYPE_SUB; - const cs_tricore_op *op0 = tricore_get_op(insn, 0); - if (tricore_op_count(insn) >= 2) { - const cs_tricore_op *op1 = tricore_get_op(insn, 1); + const cs_tricore_op *op0 = tricore_op_get(ctx->insn, 0); + if (tricore_op_count(ctx->insn) >= 2) { + cs_tricore_op *op1 = tricore_op_get(ctx->insn, 1); if (op1->type == TRICORE_OP_IMM) { op->val = op1->imm; if (op0->type == TRICORE_OP_REG && op0->reg == TRICORE_REG_SP) { @@ -902,13 +1062,16 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { op->type = RZ_ANALYSIS_OP_TYPE_SHL; break; } - case TRICORE_INS_STLCX: - case TRICORE_INS_STUCX: - op->ptr = tricore_get_op_imm(insn, 0); + case TRICORE_INS_STLCX: { + const cs_tricore_op *op0 = tricore_op_get(ctx->insn, 0); + op->ptr = op0->type == TRICORE_OP_IMM + ? op0->imm + : (op0->type == TRICORE_OP_MEM ? op0->mem.disp : -1); op->ptrsize = 4 * 16; op->stackop = RZ_ANALYSIS_STACK_GET; op->type = RZ_ANALYSIS_OP_TYPE_STORE; break; + } case TRICORE_INS_ST_A: case TRICORE_INS_ST_B: case TRICORE_INS_ST_DA: @@ -919,7 +1082,7 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { case TRICORE_INS_ST_W: { op->ptrsize = 4; op->type = RZ_ANALYSIS_OP_TYPE_STORE; - const cs_tricore_op *op0 = tricore_get_op(insn, 0); + const cs_tricore_op *op0 = tricore_op_get(ctx->insn, 0); switch (op0->type) { case TRICORE_OP_MEM: case TRICORE_OP_INVALID: @@ -976,11 +1139,7 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) { } } -static RzAnalysisLiftedILOp rz_analysis_tricore_il_op() { - return NULL; -} - -static inline void fill_from_tricore_op(RzReg *rz_reg, csh handle, RzAnalysisValue *av, cs_tricore_op *top) { +static inline void tricore_fillval(RzReg *rz_reg, csh handle, RzAnalysisValue *av, cs_tricore_op *top) { switch (top->type) { case TRICORE_OP_INVALID: default: @@ -1002,13 +1161,13 @@ static inline void fill_from_tricore_op(RzReg *rz_reg, csh handle, RzAnalysisVal } } -static void rz_analysis_tricore_fillval(RzAnalysis *a, RzAnalysisOp *op, csh handle, cs_insn *insn) { +static void tricore_fillvals(RzAsmTriCoreContext *ctx, RzAnalysis *a, RzAnalysisOp *op) { uint8_t srci = 0; - cs_tricore *tc = &insn->detail->tricore; + cs_tricore *tc = &ctx->insn->detail->tricore; for (uint8_t i = 0; i < tc->op_count; ++i) { cs_tricore_op *top = &tc->operands[i]; RzAnalysisValue *av = rz_analysis_value_new(); - fill_from_tricore_op(a->reg, handle, av, top); + tricore_fillval(a->reg, ctx->h, av, top); if (top->access & CS_AC_READ) { av->access |= RZ_ANALYSIS_ACC_R; op->src[srci++] = av; @@ -1026,14 +1185,14 @@ static void rz_analysis_tricore_fillval(RzAnalysis *a, RzAnalysisOp *op, csh han } } -static void tricore_opex(RzStrBuf *ptr, csh handle, cs_insn *p_insn) { +static void tricore_opex(RzAsmTriCoreContext *ctx, RzStrBuf *sb) { PJ *pj = pj_new(); if (!pj) { return; } pj_o(pj); pj_ka(pj, "operands"); - cs_tricore *tc = &p_insn->detail->tricore; + cs_tricore *tc = &ctx->insn->detail->tricore; for (st32 i = 0; i < tc->op_count; i++) { cs_tricore_op *op = tc->operands + i; pj_o(pj); @@ -1044,7 +1203,7 @@ static void tricore_opex(RzStrBuf *ptr, csh handle, cs_insn *p_insn) { } case TRICORE_OP_REG: { pj_ks(pj, "type", "reg"); - pj_ks(pj, "value", cs_reg_name(handle, op->reg)); + pj_ks(pj, "value", cs_reg_name(ctx->h, op->reg)); break; } case TRICORE_OP_IMM: { @@ -1054,7 +1213,7 @@ static void tricore_opex(RzStrBuf *ptr, csh handle, cs_insn *p_insn) { } case TRICORE_OP_MEM: { pj_ks(pj, "type", "mem"); - pj_ks(pj, "base", cs_reg_name(handle, op->mem.base)); + pj_ks(pj, "base", cs_reg_name(ctx->h, op->mem.base)); pj_ki(pj, "disp", op->mem.disp); break; } @@ -1064,17 +1223,12 @@ static void tricore_opex(RzStrBuf *ptr, csh handle, cs_insn *p_insn) { pj_end(pj); pj_end(pj); - rz_strbuf_init(ptr); - rz_strbuf_append(ptr, pj_string(pj)); + rz_strbuf_init(sb); + rz_strbuf_append(sb, pj_string(pj)); pj_free(pj); } -static RzAnalysisILConfig *il_config(RzAnalysis *analysis) { - RzAnalysisILConfig *cfg = rz_analysis_il_config_new(32, false, 32); - return cfg; -} - -static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { +static int tricore_archinfo(RzAnalysis *a, RzAnalysisInfoType query) { switch (query) { case RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE: return 2; @@ -1088,6 +1242,28 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { } } +static bool tricore_init(void **u) { + if (!u) { + return false; + } + RzAsmTriCoreContext *ctx = RZ_NEW0(RzAsmTriCoreContext); + if (!ctx) { + return false; + } + *u = ctx; + return true; +} + +static bool tricore_fini(void *u) { + if (!u) { + return true; + } + RzAsmTriCoreContext *ctx = u; + cs_close(&ctx->h); + free(u); + return true; +} + RzAnalysisPlugin rz_analysis_plugin_tricore_cs = { .name = "tricore", .desc = "Capstone TRICORE analysis plugin", @@ -1095,10 +1271,11 @@ RzAnalysisPlugin rz_analysis_plugin_tricore_cs = { .license = "LGPL3", .arch = "tricore", .bits = 32, - .get_reg_profile = get_reg_profile, - .archinfo = archinfo, - .op = rz_analysis_tricore_op, - .il_config = il_config, + .get_reg_profile = tricore_reg_profile, + .archinfo = tricore_archinfo, + .op = tricore_op, + .init = tricore_init, + .fini = tricore_fini, }; #ifndef RZ_PLUGIN_INCORE diff --git a/librz/asm/arch/tricore/tricore.h b/librz/asm/arch/tricore/tricore.h index f99746f9c97..2abd1f71860 100644 --- a/librz/asm/arch/tricore/tricore.h +++ b/librz/asm/arch/tricore/tricore.h @@ -2,7 +2,18 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include + +#ifndef RZ_TRICORE_H +#define RZ_TRICORE_H typedef struct { + csh h; + cs_mode mode; + cs_insn *insn; + ut32 count; + ut32 word; RzPVector /**/ *token_patterns; -} RzAsmTriCoreState; +} RzAsmTriCoreContext; + +#endif // RZ_TRICORE_H diff --git a/librz/asm/arch/tricore/tricore.inc b/librz/asm/arch/tricore/tricore.inc index aaf22fb45cc..ab2253541b6 100644 --- a/librz/asm/arch/tricore/tricore.inc +++ b/librz/asm/arch/tricore/tricore.inc @@ -2,10 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only #include - -static inline ut8 tricore_op_count(cs_insn *insn) { - return insn->detail->tricore.op_count; -} +#include "tricore.h" static inline cs_mode tricore_cpu_to_cs_mode(const char *cpu_type) { if (RZ_STR_ISNOTEMPTY(cpu_type)) { @@ -28,54 +25,83 @@ static inline cs_mode tricore_cpu_to_cs_mode(const char *cpu_type) { return CS_MODE_TRICORE_162; } -static inline cs_tricore_op *tricore_get_op(cs_insn *insn, int idx) { +static inline bool tricore_setup_cs_handle(RzAsmTriCoreContext *ctx, const char *cpu, const char *features) { + const cs_mode mode = tricore_cpu_to_cs_mode(cpu); + if (mode != ctx->mode) { + cs_close(&ctx->h); + ctx->h = 0; + ctx->mode = mode; + } + + if (ctx->h != 0) { + return true; + } + cs_err err = cs_open(CS_ARCH_TRICORE, mode, &ctx->h); + if (err) { + RZ_LOG_ERROR("Failed on cs_open() with error returned: %u\n", err); + return false; + } + err = cs_option(ctx->h, CS_OPT_DETAIL, + RZ_STR_ISNOTEMPTY(features) || features == NULL ? CS_OPT_ON : CS_OPT_OFF); + if (err) { + RZ_LOG_ERROR("Failed on cs_open() with error returned: %u\n", err); + return false; + } + return true; +} + +static inline ut8 tricore_op_count(cs_insn *insn) { + return insn->detail->tricore.op_count; +} + +static inline cs_tricore_op *tricore_op_get(cs_insn *insn, int idx) { if (idx >= tricore_op_count(insn)) { RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\"\n", idx, tricore_op_count(insn), insn->mnemonic, insn->op_str); + rz_warn_if_reached(); return NULL; } return &insn->detail->tricore.operands[idx]; } -static inline const char *tricore_get_op_regname(csh h, cs_insn *insn, int idx) { - cs_tricore_op *op = tricore_get_op(insn, idx); +static inline const char *tricore_op_as_reg(RzAsmTriCoreContext *ctx, int idx) { + const cs_tricore_op *op = tricore_op_get(ctx->insn, idx); if (op->type != TRICORE_OP_REG) { RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [reg]\n", - idx, tricore_op_count(insn), insn->mnemonic, insn->op_str); + idx, tricore_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str); + rz_warn_if_reached(); return NULL; } - return cs_reg_name(h, op->reg); + return cs_reg_name(ctx->h, op->reg); } -static inline st32 tricore_get_op_imm(cs_insn *insn, int idx) { - cs_tricore_op *op = tricore_get_op(insn, idx); +static inline st32 tricore_op_as_imm(RzAsmTriCoreContext *ctx, int idx) { + const cs_tricore_op *op = tricore_op_get(ctx->insn, idx); if (op->type != TRICORE_OP_IMM) { RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [imm]\n", - idx, tricore_op_count(insn), insn->mnemonic, insn->op_str); + idx, tricore_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str); + rz_warn_if_reached(); return 0; } return op->imm; } -static inline csh tricore_setup_cs_handle(const char *cpu, const char *features) { - static csh handle = 0; - static cs_mode omode = CS_MODE_TRICORE_162; +typedef struct { + const char *reg; + ut32 disp; +} TriCoreMem; - cs_mode mode = tricore_cpu_to_cs_mode(cpu); - if (mode != omode) { - cs_close(&handle); - handle = 0; - omode = mode; +static inline TriCoreMem tricore_op_as_mem(RzAsmTriCoreContext *ctx, int idx) { + const cs_tricore_op *op = tricore_op_get(ctx->insn, idx); + TriCoreMem m = { 0 }; + if (op->type != TRICORE_OP_MEM) { + RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [mem]\n", + idx, tricore_op_count(ctx->insn), ctx->insn->mnemonic, ctx->insn->op_str); + rz_warn_if_reached(); + return m; } - if (handle == 0) { - cs_err err = cs_open(CS_ARCH_TRICORE, mode, &handle); - if (err) { - RZ_LOG_ERROR("Failed on cs_open() with error returned: %u\n", err); - return 0; - } - cs_option(handle, CS_OPT_DETAIL, - RZ_STR_ISNOTEMPTY(features) || features == NULL ? CS_OPT_ON : CS_OPT_OFF); - } - return handle; + m.reg = cs_reg_name(ctx->h, op->mem.base); + m.disp = op->mem.disp; + return m; } diff --git a/librz/asm/asm.c b/librz/asm/asm.c index ea920817d1e..2e4995f29d3 100644 --- a/librz/asm/asm.c +++ b/librz/asm/asm.c @@ -258,6 +258,7 @@ static void plugin_fini(RzAsm *a) { if (a->cur && a->cur->fini && !a->cur->fini(a->plugin_data)) { RZ_LOG_ERROR("asm plugin '%s' failed to terminate.\n", a->cur->name); } + a->plugin_data = NULL; } RZ_API RzAsm *rz_asm_new(void) { diff --git a/librz/asm/p/asm_tricore_cs.c b/librz/asm/p/asm_tricore_cs.c index 6dabebbe63c..dfec1133345 100644 --- a/librz/asm/p/asm_tricore_cs.c +++ b/librz/asm/p/asm_tricore_cs.c @@ -10,46 +10,38 @@ #include #include "../arch/tricore/tricore.inc" -#include #define TRICORE_LONGEST_INSTRUCTION 4 #define TRICORE_SHORTEST_INSTRUCTION 2 -static RzAsmTriCoreState *get_state() { - static RzAsmTriCoreState *state = NULL; - if (state) { - return state; - } - - state = RZ_NEW0(RzAsmTriCoreState); - if (!state) { - RZ_LOG_FATAL("Could not allocate memory for HexState!"); - } - return state; -} - static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { - if (!buf || len < TRICORE_SHORTEST_INSTRUCTION) { + if (!buf || len < TRICORE_SHORTEST_INSTRUCTION || !a->plugin_data) { return -1; } - csh handle = tricore_setup_cs_handle(a->cpu, a->features); - if (handle == 0) { + RzAsmTriCoreContext *ctx = a->plugin_data; + if (!tricore_setup_cs_handle(ctx, a->cpu, a->features)) { return -1; } - cs_insn *insn = NULL; - unsigned count = cs_disasm(handle, buf, len, a->pc, 1, &insn); - if (count <= 0) { - return -1; + ctx->insn = NULL; + ctx->count = cs_disasm(ctx->h, buf, len, a->pc, 1, &ctx->insn); + if (ctx->count <= 0) { + goto beach; } - op->size = insn->size; - char *asmstr = rz_str_newf("%s%s%s", insn->mnemonic, - RZ_STR_ISNOTEMPTY(insn->op_str) ? " " : "", insn->op_str); + op->size = ctx->insn->size; + char *asmstr = rz_str_newf("%s%s%s", + ctx->insn->mnemonic, RZ_STR_ISNOTEMPTY(ctx->insn->op_str) ? " " : "", ctx->insn->op_str); rz_asm_op_set_asm(op, asmstr); free(asmstr); - cs_free(insn, count); + + op->asm_toks = rz_asm_tokenize_asm_regex(&op->buf_asm, ctx->token_patterns); + +beach: + cs_free(ctx->insn, ctx->count); + ctx->insn = NULL; + ctx->count = 0; return op->size; } @@ -74,10 +66,10 @@ static RZ_OWN RzPVector /**/ *get_token_patterns() { TOKEN(NUMBER, "(0x[[:digit:]abcdef]+)"); - TOKEN(MNEMONIC, "([[:alpha:]]+[[:alnum:]\\.]*[[:alnum:]]+)|([[:alpha:]]+)"); - TOKEN(REGISTER, "([adep][[:digit:]]{1,2})|(sp|psw|pcxi|pc|fcx|lcx|isp|icr|pipn|biv|btv)"); + TOKEN(MNEMONIC, "([[:alpha:]]+[[:alnum:]\\.]*[[:alnum:]]+)|([[:alpha:]]+)"); + TOKEN(SEPARATOR, "([[:blank:]]+)|([,;#\\(\\)\\{\\}:])"); TOKEN(NUMBER, "([[:digit:]]+)"); @@ -85,14 +77,35 @@ static RZ_OWN RzPVector /**/ *get_token_patterns() { return pvec; } -static bool init(void **user) { - RzAsmTriCoreState *state = get_state(); - rz_return_val_if_fail(state, false); - - *user = state; // user = RzAsm.plugin_data +static bool init(void **u) { + if (!u) { + return false; + } + // u = RzAsm.plugin_data + RzAsmTriCoreContext *ctx = NULL; + if (*u) { + rz_mem_memzero(*u, sizeof(RzAsmTriCoreContext)); + ctx = *u; + } else { + ctx = RZ_NEW0(RzAsmTriCoreContext); + if (!ctx) { + return false; + } + *u = ctx; + } + ctx->token_patterns = get_token_patterns(); + rz_asm_compile_token_patterns(ctx->token_patterns); + return true; +} - state->token_patterns = get_token_patterns(); - rz_asm_compile_token_patterns(state->token_patterns); +static bool fini(void *u) { + if (!u) { + return true; + } + RzAsmTriCoreContext *ctx = u; + cs_close(&ctx->h); + rz_pvector_free(ctx->token_patterns); + free(u); return true; } @@ -106,6 +119,7 @@ RzAsmPlugin rz_asm_plugin_tricore = { .desc = "Siemens TriCore CPU", .disassemble = &disassemble, .init = &init, + .fini = &fini, }; #ifndef RZ_PLUGIN_INCORE diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 84f8e2e891c..17fa7c509ce 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -11,7 +11,6 @@ #include "core_private.h" #include "rz_analysis.h" #include -#include #define HASRETRY 1 #define HAVE_LOCALS 1 @@ -5019,11 +5018,14 @@ static bool set_jump_realname(RzDisasmState *ds, ut64 addr, const char **kw, con * \brief Remove '#' from the asm string * \param op RzAsmOp instance */ -void rz_asm_op_tricore_fixup(RzAsmOp *op, RzAsmTriCoreState *state) { +void rz_asm_op_tricore_fixup(RzAsmOp *op) { char *asmstr = rz_asm_op_get_asm(op); rz_str_remove_char(asmstr, '#'); rz_asm_op_set_asm(op, asmstr); - op->asm_toks = rz_asm_tokenize_asm_regex(&op->buf_asm, state->token_patterns); + if (op->asm_toks) { + rz_asm_token_string_free(op->asm_toks); + op->asm_toks = NULL; + } } static void ds_asmop_fixup(RzDisasmState *ds) { @@ -5037,7 +5039,7 @@ static void ds_asmop_fixup(RzDisasmState *ds) { return; } if (rz_str_cmp(ds->core->rasm->cur->arch, "tricore", -1) == 0) { - rz_asm_op_tricore_fixup(&ds->asmop, ds->core->rasm->plugin_data); + rz_asm_op_tricore_fixup(&ds->asmop); } } diff --git a/test/db/analysis/tricore b/test/db/analysis/tricore index 9d5fdf8ba2f..49367ec9589 100644 --- a/test/db/analysis/tricore +++ b/test/db/analysis/tricore @@ -101,16 +101,181 @@ gpr d13 .32 116 0 gpr e14 .64 120 0 gpr d14 .32 120 0 gpr d15 .32 124 0 -gpr PSW .32 128 0 -gpr PCXI .32 132 0 -gpr FCX .32 136 0 -gpr LCX .32 140 0 -gpr ISP .32 144 0 -gpr ICR .32 148 0 -gpr PIPN .32 152 0 -gpr BIV .32 156 0 -gpr BTV .32 160 0 -gpr pc .32 164 0 +drx PCXI .32 128 0 +drx PSW .32 132 0 +drx pc .32 136 0 +drx SYSCON .32 140 0 +drx CPU_ID .32 144 0 +drx CORE_ID .32 148 0 +drx BIV .32 152 0 +drx BTV .32 156 0 +drx ISP .32 160 0 +drx ICR .32 164 0 +drx FCX .32 168 0 +drx LCX .32 172 0 +drx COMPAT .32 176 0 +drx DPR0_L .32 180 0 +drx DPR0_U .32 184 0 +drx DPR1_L .32 188 0 +drx DPR1_U .32 192 0 +drx DPR2_L .32 196 0 +drx DPR2_U .32 200 0 +drx DPR3_L .32 204 0 +drx DPR3_U .32 208 0 +drx DPR4_L .32 212 0 +drx DPR4_U .32 216 0 +drx DPR5_L .32 220 0 +drx DPR5_U .32 224 0 +drx DPR6_L .32 228 0 +drx DPR6_U .32 232 0 +drx DPR7_L .32 236 0 +drx DPR7_U .32 240 0 +drx DPR8_L .32 244 0 +drx DPR8_U .32 248 0 +drx DPR9_L .32 252 0 +drx DPR9_U .32 256 0 +drx DPR10_L .32 260 0 +drx DPR10_U .32 264 0 +drx DPR11_L .32 268 0 +drx DPR11_U .32 272 0 +drx DPR12_L .32 276 0 +drx DPR12_U .32 280 0 +drx DPR13_L .32 284 0 +drx DPR13_U .32 288 0 +drx DPR14_L .32 292 0 +drx DPR14_U .32 296 0 +drx DPR15_L .32 300 0 +drx DPR15_U .32 304 0 +drx CPR0_L .32 308 0 +drx CPR0_U .32 312 0 +drx CPR1_L .32 316 0 +drx CPR1_U .32 320 0 +drx CPR2_L .32 324 0 +drx CPR2_U .32 328 0 +drx CPR3_L .32 332 0 +drx CPR3_U .32 336 0 +drx CPR4_L .32 340 0 +drx CPR4_U .32 344 0 +drx CPR5_L .32 348 0 +drx CPR5_U .32 352 0 +drx CPR6_L .32 356 0 +drx CPR6_U .32 360 0 +drx CPR7_L .32 364 0 +drx CPR7_U .32 368 0 +drx CPR8_L .32 372 0 +drx CPR8_U .32 376 0 +drx CPR9_L .32 380 0 +drx CPR9_U .32 384 0 +drx CPR10_L .32 388 0 +drx CPR10_U .32 392 0 +drx CPR11_L .32 396 0 +drx CPR11_U .32 400 0 +drx CPR12_L .32 404 0 +drx CPR12_U .32 408 0 +drx CPR13_L .32 412 0 +drx CPR13_U .32 416 0 +drx CPR14_L .32 420 0 +drx CPR14_U .32 424 0 +drx CPR15_L .32 428 0 +drx CPR15_U .32 432 0 +drx CPXE_0 .32 436 0 +drx CPXE_1 .32 440 0 +drx CPXE_2 .32 444 0 +drx CPXE_3 .32 448 0 +drx CPXE_4 .32 452 0 +drx CPXE_5 .32 456 0 +drx CPXE_6 .32 460 0 +drx CPXE_7 .32 464 0 +drx DPRE_0 .32 468 0 +drx DPRE_1 .32 472 0 +drx DPRE_2 .32 476 0 +drx DPRE_3 .32 480 0 +drx DPRE_4 .32 484 0 +drx DPRE_5 .32 488 0 +drx DPRE_6 .32 492 0 +drx DPRE_7 .32 496 0 +drx DPWE_0 .32 500 0 +drx DPWE_1 .32 504 0 +drx DPWE_2 .32 508 0 +drx DPWE_3 .32 512 0 +drx DPWE_4 .32 516 0 +drx DPWE_5 .32 520 0 +drx DPWE_6 .32 524 0 +drx DPWE_7 .32 528 0 +drx TPS_CON .32 532 0 +drx TPS_TIMER0 .32 536 0 +drx TPS_TIMER1 .32 540 0 +drx TPS_TIMER2 .32 544 0 +drx TPS_EXTIM_ENTRY_CVAL .32 548 0 +drx TPS_EXTIM_ENTRY_LVAL .32 552 0 +drx TPS_EXTIM_EXIT_CVAL .32 556 0 +drx TPS_EXTIM_EXIT_LVAL .32 560 0 +drx TPS_EXTIM_CLASS_EN .32 564 0 +drx TPS_EXTIM_STAT .32 568 0 +drx TPS_EXTIM_FCX .32 572 0 +drx MMU_CON .32 576 0 +drx MMU_ASI .32 580 0 +drx MMU_TVA .32 584 0 +drx MMU_TPA .32 588 0 +drx MMU_TPX .32 592 0 +drx MMU_TFA .32 596 0 +drx MMU_TFAS .32 600 0 +drx PMA01_ .32 604 0 +drx PMA01 .32 608 0 +drx PMA11 .32 612 0 +drx PMA21 .32 616 0 +drx DCON2 .32 620 0 +drx DCON1 .32 624 0 +drx SMACON .32 628 0 +drx DSTR .32 632 0 +drx DATR .32 636 0 +drx DEADD .32 640 0 +drx DIEAR .32 644 0 +drx DIETR .32 648 0 +drx DCON0 .32 652 0 +drx PSTR .32 656 0 +drx PCON1 .32 660 0 +drx PCON2 .32 664 0 +drx PCON0 .32 668 0 +drx PIEAR .32 672 0 +drx PIETR .32 676 0 +drx DBGSR .32 680 0 +drx EXEVT .32 684 0 +drx CREVT .32 688 0 +drx SWEVT .32 692 0 +drx TR0EVT .32 696 0 +drx TR0ADR .32 700 0 +drx TR1EVT .32 704 0 +drx TR1ADR .32 708 0 +drx TR2EVT .32 712 0 +drx TR2ADR .32 716 0 +drx TR3EVT .32 720 0 +drx TR3ADR .32 724 0 +drx TR4EVT .32 728 0 +drx TR4ADR .32 732 0 +drx TR5EVT .32 736 0 +drx TR5ADR .32 740 0 +drx TR6EVT .32 744 0 +drx TR6ADR .32 748 0 +drx TR7EVT .32 752 0 +drx TR7ADR .32 756 0 +drx TRIG_ACC .32 760 0 +drx DMS .32 764 0 +drx DCX .32 768 0 +drx TASK_ASI .32 772 0 +drx DBGTCR .32 776 0 +drx CCTRL .32 780 0 +drx CCNT .32 784 0 +drx ICNT .32 788 0 +drx M1CNT .32 792 0 +drx M2CNT .32 796 0 +drx M3CNT .32 800 0 +drx FPU_TRAP_CON .32 804 0 +drx FPU_TRAP_PC .32 808 0 +drx FPU_TRAP_OPC .32 812 0 +drx FPU_TRAP_SRC1 .32 816 0 +drx FPU_TRAP_SRC2 .32 820 0 +drx FPU_TRAP_SRC3 .32 824 0 EOF RUN @@ -180,16 +345,6 @@ e8 = 0x0000000000000000 e10 = 0x0000000000000000 e12 = 0x0000000000000000 e14 = 0x0000000000000000 -PSW = 0x00000000 -PCXI = 0x00000000 -FCX = 0x00000000 -LCX = 0x00000000 -ISP = 0x00000000 -ICR = 0x00000000 -PIPN = 0x00000000 -BIV = 0x00000000 -BTV = 0x00000000 -pc = 0x00000000 EOF RUN