Skip to content

Commit

Permalink
Refactor and improve RCondType APIs ##analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
astralia committed Nov 25, 2024
1 parent 657b105 commit e7f8893
Show file tree
Hide file tree
Showing 24 changed files with 2,999 additions and 2,976 deletions.
138 changes: 79 additions & 59 deletions libr/anal/cond.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,75 @@

#include <r_anal.h>

// R2_600 rename
/* Both contdypestr and condtypestr_expr should be in the same order,
depending on the values defined at RAnalCondType */
static const char *condtypestr[] = {
"al", "eq", "ne", "ge", "gt", "le", "lt", "nv",
"hs", "lo", "mi", "pl", "vs", "vc", "hi", "ls"
};

static const char *condtypestr_expr[] = {
".any", "==", "!=", ">=", ">", "<=", "<", ".never",
".carry", ".carryclr", "-", "+", ".ovf", ".novf", ".uhi", ".ulo"
};

R_API const char *r_anal_cond_type_tostring(int cc) {
R_RETURN_VAL_IF_FAIL (cc >= 0, NULL);
switch (cc) {
case R_ANAL_COND_EQ: return "eq";
case R_ANAL_COND_NV: return "nv";
case R_ANAL_COND_NE: return "ne";
case R_ANAL_COND_HS: return "hs";
case R_ANAL_COND_LO: return "lo";
case R_ANAL_COND_MI: return "mi";
case R_ANAL_COND_PL: return "pl";
case R_ANAL_COND_VS: return "vs";
case R_ANAL_COND_VC: return "vc";
case R_ANAL_COND_HI: return "hi";
case R_ANAL_COND_LS: return "ls";
case R_ANAL_COND_GE: return "ge";
case R_ANAL_COND_LT: return "lt";
case R_ANAL_COND_GT: return "gt";
case R_ANAL_COND_LE: return "le";
case R_ANAL_COND_AL: return "al";
if (cc < R_ANAL_CONDTYPE_LAST) {
return condtypestr[cc];
}
return "??";
}

R_API const char *r_anal_cond_typeexpr_tostring(int cc) {
R_RETURN_VAL_IF_FAIL (cc >= 0, NULL);
if (cc < R_ANAL_CONDTYPE_LAST) {
return condtypestr_expr[cc];
}
return "??";
}

R_API RAnalCondType r_anal_cond_type_fromstring(const char *type) {
int i;
for (i = 0; i < R_ANAL_CONDTYPE_LAST; i++) {
if (!strcmp (type, condtypestr[i])) {
return i;
}
if (!strcmp (type, condtypestr_expr[i])) {
return i;
}
}
return R_ANAL_CONDTYPE_ERR;
}

R_API RAnalCond *r_anal_cond_new(void) {
return R_NEW0 (RAnalCond);
}

R_API void r_anal_cond_fini(RAnalCond *c) {
if (!c) {
return;
}
R_RETURN_IF_FAIL (c);
r_anal_value_free (c->arg[0]);
r_anal_value_free (c->arg[1]);
c->arg[0] = c->arg[1] = NULL;
}

R_API void r_anal_cond_free(RAnalCond *c) {
if (!c) {
return;
R_API void r_anal_cond_free(R_NULLABLE RAnalCond *c) {
if (c) {
r_anal_cond_fini (c);
free (c);
}
r_anal_cond_fini (c);
free (c);
}

// XXX?
R_API RAnalCond *r_anal_cond_clone(RAnalCond *cond) {
R_RETURN_VAL_IF_FAIL (cond, NULL);
RAnalCond *c = R_NEW (RAnalCond);
if (!c) {
return NULL;
if (R_LIKELY (c)) {
c->type = cond->type;
c->arg[0] = r_anal_value_clone (cond->arg[0]);
c->arg[1] = r_anal_value_clone (cond->arg[1]);
return c;
}
memcpy (c, cond, sizeof (RAnalCond));
return c;
}

static inline const char *condstring(RAnalCond *cond) {
const char *condstr_single[] = { "!", "", "0<", "0<=", "0>", "0>=" };
const char *condstr[] = { "==", "!=", ">=", ">", "<=", "<" };
if (cond) {
if (cond->arg[1]) {
return condstr[cond->type % 6];
} else {
return condstr_single[cond->type % 6];
}
}
return "";
return NULL;
}

R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) {
Expand All @@ -78,33 +80,33 @@ R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) {
if (cond->arg[1]) {
st64 arg1 = (st64) r_anal_value_to_ut64 (anal, cond->arg[1]);
switch (cond->type) {
case R_ANAL_COND_EQ: return arg0 == arg1;
case R_ANAL_COND_NE: return arg0 != arg1;
case R_ANAL_COND_GE: return arg0 >= arg1;
case R_ANAL_COND_GT: return arg0 > arg1;
case R_ANAL_COND_LE: return arg0 <= arg1;
case R_ANAL_COND_LT: return arg0 < arg1;
case R_ANAL_CONDTYPE_EQ: return arg0 == arg1;
case R_ANAL_CONDTYPE_NE: return arg0 != arg1;
case R_ANAL_CONDTYPE_GE: return arg0 >= arg1;
case R_ANAL_CONDTYPE_GT: return arg0 > arg1;
case R_ANAL_CONDTYPE_LE: return arg0 <= arg1;
case R_ANAL_CONDTYPE_LT: return arg0 < arg1;
}
} else {
switch (cond->type) {
case R_ANAL_COND_EQ: return !arg0;
case R_ANAL_COND_NE: return arg0;
case R_ANAL_COND_GT: return arg0 > 0;
case R_ANAL_COND_GE: return arg0 >= 0;
case R_ANAL_COND_LT: return arg0 < 0;
case R_ANAL_COND_LE: return arg0 <= 0;
case R_ANAL_CONDTYPE_EQ: return !arg0;
case R_ANAL_CONDTYPE_NE: return arg0;
case R_ANAL_CONDTYPE_GT: return arg0 > 0;
case R_ANAL_CONDTYPE_GE: return arg0 >= 0;
case R_ANAL_CONDTYPE_LT: return arg0 < 0;
case R_ANAL_CONDTYPE_LE: return arg0 <= 0;
}
}
return false;
}

R_API char *r_anal_cond_tostring(RAnalCond *cond) {
R_RETURN_VAL_IF_FAIL (cond, NULL);
const char *cnd = condstring (cond);
const char *cnd = r_anal_cond_typeexpr_tostring (cond->type);
char *val0 = r_anal_value_tostring (cond->arg[0]);
char *out = NULL;
if (val0) {
if (R_ANAL_COND_SINGLE (cond)) {
if (R_ANAL_CONDTYPE_SINGLE (cond)) {
out = r_str_newf ("%s%s", cnd, val0);
} else {
char *val1 = r_anal_value_tostring (cond->arg[1]);
Expand Down Expand Up @@ -139,6 +141,24 @@ R_API RAnalCond *r_anal_cond_new_from_op(RAnalOp *op) {
R_API RAnalCond *r_anal_cond_new_from_string(const char *str) {
R_RETURN_VAL_IF_FAIL (str, NULL);
RAnalCond *cond = R_NEW0 (RAnalCond);
// TODO: find '<','=','>','!'...
int i, type = -1;
char *substr = NULL;
for (i = 0; i < R_ANAL_CONDTYPE_LAST; i++) {
substr = strstr(str, condtypestr_expr[i]);
if (substr) {
type = i;
break;
}
}
if (type < 0) {
return NULL;
}
cond->type = r_anal_cond_type_fromstring (condtypestr_expr[i]);
char *left = strndup (substr, substr - str);
char *right = strdup (substr + strlen (condtypestr_expr[i]));
cond->arg[0] = r_anal_value_new_from_string (left);
cond->arg[1] = r_anal_value_new_from_string (right);
free (left);
free (right);
return cond;
}
2 changes: 1 addition & 1 deletion libr/anal/fcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ static ut64 try_get_cmpval_from_parents(RAnal *anal, RAnalFunction *fcn, RAnalBl
if (tmp_bb->jump == my_bb->addr || tmp_bb->fail == my_bb->addr) {
if (tmp_bb->cmpreg == cmp_reg) {
if (tmp_bb->cond) {
if (tmp_bb->cond->type == R_ANAL_COND_HI || tmp_bb->cond->type == R_ANAL_COND_GT) {
if (tmp_bb->cond->type == R_ANAL_CONDTYPE_HI || tmp_bb->cond->type == R_ANAL_CONDTYPE_GT) {
return tmp_bb->cmpval + 1;
}
}
Expand Down
8 changes: 4 additions & 4 deletions libr/anal/var.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,25 +757,25 @@ R_API char *r_anal_var_get_constraints_readable(RAnalVar *var) {
for (i = 0; i < n; i += 1) {
RAnalVarConstraint *constr = r_vector_at (&var->constraints, i);
switch (constr->cond) {
case R_ANAL_COND_LE:
case R_ANAL_CONDTYPE_LE:
if (high) {
r_strbuf_append (&sb, " && ");
}
r_strbuf_appendf (&sb, "<= 0x%"PFMT64x, constr->val);
low = true;
break;
case R_ANAL_COND_LT:
case R_ANAL_CONDTYPE_LT:
if (high) {
r_strbuf_append (&sb, " && ");
}
r_strbuf_appendf (&sb, "< 0x%"PFMT64x, constr->val);
low = true;
break;
case R_ANAL_COND_GE:
case R_ANAL_CONDTYPE_GE:
r_strbuf_appendf (&sb, ">= 0x%"PFMT64x, constr->val);
high = true;
break;
case R_ANAL_COND_GT:
case R_ANAL_CONDTYPE_GT:
r_strbuf_appendf (&sb, "> 0x%"PFMT64x, constr->val);
high = true;
break;
Expand Down
2 changes: 1 addition & 1 deletion libr/arch/p/6502/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ static bool _6502_op(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
}
op->fail = addr + op->size;
// FIXME: add a type of conditional
// op->cond = R_ANAL_COND_LE;
// op->cond = R_ANAL_CONDTYPE_LE;
_6502_anal_esil_ccall (op, data[0]);
break;
// JSR
Expand Down
10 changes: 5 additions & 5 deletions libr/arch/p/8051/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,20 +928,20 @@ static bool decode(RArchSession *as, RAnalOp *op, RAnalOpMask mask) {
case OP_JB:
case OP_JBC:
case OP_JNZ:
op->cond = R_ANAL_COND_NE;
op->cond = R_ANAL_CONDTYPE_NE;
break;
case OP_JNB:
case OP_JZ:
op->cond = R_ANAL_COND_EQ;
op->cond = R_ANAL_CONDTYPE_EQ;
break;
case OP_JC:
op->cond = R_ANAL_COND_HS;
op->cond = R_ANAL_CONDTYPE_HS;
break;
case OP_JNC:
op->cond = R_ANAL_COND_LO;
op->cond = R_ANAL_CONDTYPE_LO;
break;
default:
op->cond = R_ANAL_COND_AL;
op->cond = R_ANAL_CONDTYPE_AL;
break;
}

Expand Down
44 changes: 22 additions & 22 deletions libr/arch/p/arc/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,28 @@ static int sex(int bits, int imm) {

static int map_cond2radare(ut8 cond) {
switch (cond) {
case 0: return R_ANAL_COND_AL;
case 1: return R_ANAL_COND_EQ;
case 2: return R_ANAL_COND_NE;
case 3: return R_ANAL_COND_PL;
case 4: return R_ANAL_COND_MI;
case 7: return R_ANAL_COND_VS;
case 8: return R_ANAL_COND_VC;
case 9: return R_ANAL_COND_GT;
case 0xa: return R_ANAL_COND_GE;
case 0xb: return R_ANAL_COND_LT;
case 0xc: return R_ANAL_COND_LE;
case 0xd: return R_ANAL_COND_HI;
case 0xe: return R_ANAL_COND_LS;
case 0: return R_ANAL_CONDTYPE_AL;
case 1: return R_ANAL_CONDTYPE_EQ;
case 2: return R_ANAL_CONDTYPE_NE;
case 3: return R_ANAL_CONDTYPE_PL;
case 4: return R_ANAL_CONDTYPE_MI;
case 7: return R_ANAL_CONDTYPE_VS;
case 8: return R_ANAL_CONDTYPE_VC;
case 9: return R_ANAL_CONDTYPE_GT;
case 0xa: return R_ANAL_CONDTYPE_GE;
case 0xb: return R_ANAL_CONDTYPE_LT;
case 0xc: return R_ANAL_CONDTYPE_LE;
case 0xd: return R_ANAL_CONDTYPE_HI;
case 0xe: return R_ANAL_CONDTYPE_LS;
#if 0
/* TODO: */
/* - radare defines R_ANAL_COND_LO as carry clear and _HS as carry set */
/* - radare defines R_ANAL_CONDTYPE_LO as carry clear and _HS as carry set */
/* which appears different to the ARC definitions. */
/* Need to do some math and double check the details */
case 5: return R_ANAL_COND_?? - CS,C,LO - Carry set & LO
case 6: return R_ANAL_COND_?? - CC,NC,HS - Carry clear & HS
case 5: return R_ANAL_CONDTYPE_?? - CS,C,LO - Carry set & LO
case 6: return R_ANAL_CONDTYPE_?? - CC,NC,HS - Carry clear & HS
/* - Positive non-zero doesnt map to any Radare cond code. Perhaps just add it? */
case 0xf: return R_ANAL_COND_?? - PNZ - Positive non-zero
case 0xf: return R_ANAL_CONDTYPE_?? - PNZ - Positive non-zero
#endif
}
return -1;
Expand Down Expand Up @@ -809,7 +809,7 @@ static int arcompact_op(RArchSession *as, RAnalOp *op, ut64 addr, const ut8 *dat
op->type = R_ANAL_OP_TYPE_ILL;
break;
case 6: /* SUB_S.NE [b] */
op->cond = R_ANAL_COND_NE;
op->cond = R_ANAL_CONDTYPE_NE;
op->type = R_ANAL_OP_TYPE_SUB;
break;
case 7: /* Zero Operand Instructions, 0x0F, [0x00, 0x07, 0x00 - 0x07] */
Expand All @@ -824,11 +824,11 @@ static int arcompact_op(RArchSession *as, RAnalOp *op, ut64 addr, const ut8 *dat
op->type = R_ANAL_OP_TYPE_ILL;
break;
case 4: /* JEQ_S [blink] */
op->cond = R_ANAL_COND_EQ;
op->cond = R_ANAL_CONDTYPE_EQ;
op->type = R_ANAL_OP_TYPE_CRET;
break;
case 5: /* JNE_S [blink] */
op->cond = R_ANAL_COND_NE;
op->cond = R_ANAL_CONDTYPE_NE;
op->type = R_ANAL_OP_TYPE_CRET;
break;
case 7: /* J_S.D [blink] */
Expand Down Expand Up @@ -1061,11 +1061,11 @@ static int arcompact_op(RArchSession *as, RAnalOp *op, ut64 addr, const ut8 *dat
op->type = R_ANAL_OP_TYPE_JMP;
break;
case 1: /* BEQ_S */
op->cond = R_ANAL_COND_EQ;
op->cond = R_ANAL_CONDTYPE_EQ;
op->type = R_ANAL_OP_TYPE_CJMP;
break;
case 2: /* BNE_S */
op->cond = R_ANAL_COND_NE;
op->cond = R_ANAL_CONDTYPE_NE;
op->type = R_ANAL_OP_TYPE_CJMP;
break;
case 3: /* Bcc_S */
Expand Down
Loading

0 comments on commit e7f8893

Please sign in to comment.