/* radare - LGPL - Copyright 2010-2016 - pancake */ #include R_API const char *r_anal_cond_tostring(int cc) { 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"; } return "??"; } R_API RAnalCond *r_anal_cond_new() { return R_NEW0 (RAnalCond); } R_API void r_anal_cond_fini (RAnalCond *c) { if (!c) return; 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_anal_cond_fini (c); free (c); } // XXX? R_API RAnalCond *r_anal_cond_clone(RAnalCond *cond) { RAnalCond *c = R_NEW (RAnalCond); if (!c) return NULL; 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 ""; } R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) { // XXX: sign issue here? st64 arg0 = (st64) r_anal_value_to_ut64 (anal, cond->arg[0]); 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; } } 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; } } return false; } // XXX conflict naming with tostring() R_API char *r_anal_cond_to_string(RAnalCond *cond) { char *val0, *val1, *out = NULL; const char *cnd; if (!cond) return NULL; cnd = condstring (cond); val0 = r_anal_value_to_string (cond->arg[0]); val1 = r_anal_value_to_string (cond->arg[1]); if (val0) { if (R_ANAL_COND_SINGLE (cond)) { int val0len = strlen (val0) + 10; if ((out = malloc (val0len))) snprintf (out, val0len, "%s%s", cnd, val0); } else { if (val1) { int val0len = strlen (val0) + strlen (val1) + 10; if ((out = malloc (val0len))) snprintf (out, val0len, "%s %s %s", val0, cnd, val1); } } } free (val0); free (val1); return out? out: strdup ("?"); } R_API RAnalCond *r_anal_cond_new_from_op(RAnalOp *op) { RAnalCond *cond; if (!(cond = r_anal_cond_new ())) return NULL; //v->reg[0] = op->src[0]; //v->reg[1] = op->src[1]; cond->arg[0] = op->src[0]; op->src[0] = NULL; cond->arg[1] = op->src[1]; op->src[1] = NULL; // TODO: moar! //cond->arg[1] = op->src[1]; return cond; } R_API RAnalCond *r_anal_cond_new_from_string(const char *str) { RAnalCond *cond = R_NEW (RAnalCond); // TODO: find '<','=','>','!'... return cond; }