Remove static and global variables in TriCore RzAsm and RzAnalysis plugin (#4092)

This commit is contained in:
billow 2024-01-10 23:44:12 +08:00 committed by GitHub
parent d9c70f6c56
commit a592ea1e8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 566 additions and 180 deletions

View file

@ -5,15 +5,13 @@
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_asm.h>
#include <rz_analysis.h>
#include <capstone/capstone.h>
#include <capstone/tricore.h>
#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

View file

@ -2,7 +2,18 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_types.h>
#include <capstone.h>
#ifndef RZ_TRICORE_H
#define RZ_TRICORE_H
typedef struct {
csh h;
cs_mode mode;
cs_insn *insn;
ut32 count;
ut32 word;
RzPVector /*<RzAsmTokenPattern *>*/ *token_patterns;
} RzAsmTriCoreState;
} RzAsmTriCoreContext;
#endif // RZ_TRICORE_H

View file

@ -2,10 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
#include <capstone/tricore.h>
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;
}

View file

@ -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) {

View file

@ -10,46 +10,38 @@
#include <capstone/capstone.h>
#include "../arch/tricore/tricore.inc"
#include <librz/asm/arch/tricore/tricore.h>
#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 /*<RzAsmTokenPattern *>*/ *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 /*<RzAsmTokenPattern *>*/ *get_token_patterns() {
return pvec;
}
static bool init(void **user) {
RzAsmTriCoreState *state = get_state();
rz_return_val_if_fail(state, false);
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;
}
*user = state; // user = RzAsm.plugin_data
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

View file

@ -11,7 +11,6 @@
#include "core_private.h"
#include "rz_analysis.h"
#include <rz_util/rz_strbuf.h>
#include <librz/asm/arch/tricore/tricore.h>
#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);
}
}

View file

@ -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