Fix Tricore disassembly performance (#3729)
* Try fix Tricore slow disassembly * Fix tricore_op_set_type
This commit is contained in:
parent
0a623e1589
commit
28ad8e943d
4 changed files with 56 additions and 59 deletions
|
|
@ -96,24 +96,13 @@ rz_analysis_tricore_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *da
|
|||
return -1;
|
||||
}
|
||||
|
||||
static csh handle = 0;
|
||||
static cs_mode omode = CS_MODE_TRICORE_162;
|
||||
cs_insn *insn;
|
||||
cs_mode mode = tricore_cpu_to_cs_mode(a->cpu);
|
||||
if (mode != omode) {
|
||||
cs_close(&handle);
|
||||
handle = 0;
|
||||
omode = mode;
|
||||
}
|
||||
|
||||
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);
|
||||
csh handle = tricore_setup_cs_handle(a->cpu, NULL);
|
||||
if (handle == 0) {
|
||||
return -1;
|
||||
}
|
||||
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
|
||||
|
||||
op->size = 2;
|
||||
cs_insn *insn = NULL;
|
||||
ut32 count = cs_disasm(handle, (const ut8 *)data, len, addr, 1, &insn);
|
||||
if (count <= 0) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
|
||||
|
|
@ -414,10 +403,16 @@ 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 (insn->detail->tricore.op_count == 2) {
|
||||
if (tricore_op_count(insn) >= 2) {
|
||||
cs_tricore_op *op1 = tricore_get_op(insn, 1);
|
||||
if (op1->type == TRICORE_OP_IMM) {
|
||||
op->val = op1->imm;
|
||||
|
||||
cs_tricore_op *op0 = tricore_get_op(insn, 0);
|
||||
if (op0->type == TRICORE_OP_REG && op0->reg == TRICORE_REG_SP) {
|
||||
op->stackop = RZ_ANALYSIS_STACK_INC;
|
||||
op->stackptr = op1->imm;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -788,14 +783,16 @@ static void tricore_op_set_type(RzAnalysisOp *op, csh h, cs_insn *insn) {
|
|||
case TRICORE_INS_MSUBMS_U: {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
|
||||
cs_tricore_op *op0 = tricore_get_op(insn, 0);
|
||||
if (op0->type == TRICORE_OP_REG && op0->reg == TRICORE_REG_SP) {
|
||||
op->stackop = RZ_ANALYSIS_STACK_INC;
|
||||
op->stackptr = -tricore_get_op_imm(insn, 1);
|
||||
}
|
||||
if (insn->detail->tricore.op_count == 2) {
|
||||
if (tricore_op_count(insn) >= 2) {
|
||||
cs_tricore_op *op1 = tricore_get_op(insn, 1);
|
||||
if (op1->type == TRICORE_OP_IMM) {
|
||||
op->val = op1->imm;
|
||||
|
||||
cs_tricore_op *op1 = tricore_get_op(insn, 1);
|
||||
if (op0->type == TRICORE_OP_REG && op0->reg == TRICORE_REG_SP) {
|
||||
op->stackop = RZ_ANALYSIS_STACK_INC;
|
||||
op->stackptr = -op1->imm;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include <capstone/tricore.h>
|
||||
|
||||
static inline ut8 tricore_op_count(cs_insn *insn) {
|
||||
return insn->detail->tricore.op_count;
|
||||
}
|
||||
|
||||
static inline cs_mode tricore_cpu_to_cs_mode(const char *cpu_type) {
|
||||
if (RZ_STR_ISNOTEMPTY(cpu_type)) {
|
||||
if (!strcmp(cpu_type, "generic")) {
|
||||
|
|
@ -25,8 +29,9 @@ static inline cs_mode tricore_cpu_to_cs_mode(const char *cpu_type) {
|
|||
}
|
||||
|
||||
static inline cs_tricore_op *tricore_get_op(cs_insn *insn, int idx) {
|
||||
if (idx >= insn->detail->tricore.op_count) {
|
||||
rz_warn_if_reached();
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
return &insn->detail->tricore.operands[idx];
|
||||
|
|
@ -35,7 +40,8 @@ static inline cs_tricore_op *tricore_get_op(cs_insn *insn, int 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);
|
||||
if (op->type != TRICORE_OP_REG) {
|
||||
rz_warn_if_reached();
|
||||
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [reg]\n",
|
||||
idx, tricore_op_count(insn), insn->mnemonic, insn->op_str);
|
||||
return NULL;
|
||||
}
|
||||
return cs_reg_name(h, op->reg);
|
||||
|
|
@ -44,12 +50,32 @@ static inline const char *tricore_get_op_regname(csh h, cs_insn *insn, int idx)
|
|||
static inline st32 tricore_get_op_imm(cs_insn *insn, int idx) {
|
||||
cs_tricore_op *op = tricore_get_op(insn, idx);
|
||||
if (op->type != TRICORE_OP_IMM) {
|
||||
rz_warn_if_reached();
|
||||
RZ_LOG_WARN("Failed to get operand%d [%d]: \"%s %s\" [imm]\n",
|
||||
idx, tricore_op_count(insn), insn->mnemonic, insn->op_str);
|
||||
return 0;
|
||||
}
|
||||
return op->imm;
|
||||
}
|
||||
|
||||
static inline ut8 tricore_op_count(cs_insn *insn) {
|
||||
return insn->detail->tricore.op_count;
|
||||
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;
|
||||
|
||||
cs_mode mode = tricore_cpu_to_cs_mode(cpu);
|
||||
if (mode != omode) {
|
||||
cs_close(&handle);
|
||||
handle = 0;
|
||||
omode = mode;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,32 +33,22 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
csh handle;
|
||||
cs_insn *insn;
|
||||
cs_mode mode = tricore_cpu_to_cs_mode(a->cpu);
|
||||
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);
|
||||
csh handle = tricore_setup_cs_handle(a->cpu, a->features);
|
||||
if (handle == 0) {
|
||||
return -1;
|
||||
}
|
||||
cs_option(handle, CS_OPT_DETAIL, RZ_STR_ISNOTEMPTY(a->features) ? CS_OPT_ON : CS_OPT_OFF);
|
||||
|
||||
cs_insn *insn = NULL;
|
||||
unsigned count = cs_disasm(handle, buf, len, a->pc, 1, &insn);
|
||||
if (count <= 0) {
|
||||
cs_close(&handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
op->size = insn->size;
|
||||
char *asmstr = rz_str_newf("%s%s%s", insn->mnemonic,
|
||||
RZ_STR_ISNOTEMPTY(insn->op_str) ? " " : "", insn->op_str);
|
||||
rz_asm_op_set_asm(op, asmstr);
|
||||
op->size = insn->size;
|
||||
|
||||
RzAsmTriCoreState *state = get_state();
|
||||
op->asm_toks = rz_asm_tokenize_asm_regex(&op->buf_asm, state->token_patterns);
|
||||
|
||||
free(asmstr);
|
||||
cs_close(&handle);
|
||||
cs_free(insn, count);
|
||||
return op->size;
|
||||
}
|
||||
|
|
@ -84,12 +74,12 @@ 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(SEPARATOR, "([[:blank:]]+)|([,;#\\(\\)\\{\\}:])");
|
||||
|
||||
TOKEN(MNEMONIC, "([[:alpha:]]+[[:alnum:]\\.]*[[:alnum:]]+)|([[:alpha:]]+)");
|
||||
|
||||
TOKEN(NUMBER, "([[:digit:]]+)");
|
||||
|
||||
return pvec;
|
||||
|
|
|
|||
|
|
@ -4913,24 +4913,8 @@ static bool set_jump_realname(RzDisasmState *ds, ut64 addr, const char **kw, con
|
|||
* \param op RzAsmOp instance
|
||||
*/
|
||||
void rz_asm_op_tricore_fixup(RzAsmOp *op, RzAsmTriCoreState *state) {
|
||||
if (!op->asm_toks) {
|
||||
return;
|
||||
}
|
||||
char *asmstr = rz_asm_op_get_asm(op);
|
||||
|
||||
RzAsmToken *token = NULL;
|
||||
rz_vector_foreach(op->asm_toks->tokens, token) {
|
||||
char *p = asmstr + token->start;
|
||||
if (token->type != RZ_ASM_TOKEN_SEPARATOR ||
|
||||
rz_str_cmp("#", p, token->len) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < token->len; i++) {
|
||||
*p = -1;
|
||||
}
|
||||
}
|
||||
rz_str_remove_char(asmstr, -1);
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue