1 /* radare - LGPL - Copyright 2010-2016 - pancake */
2 
3 #include <r_anal.h>
4 
r_anal_cond_tostring(int cc)5 R_API const char *r_anal_cond_tostring(int cc) {
6 	switch (cc) {
7 	case R_ANAL_COND_EQ: return "eq";
8 	case R_ANAL_COND_NV: return "nv";
9 	case R_ANAL_COND_NE: return "ne";
10 	case R_ANAL_COND_HS: return "hs";
11 	case R_ANAL_COND_LO: return "lo";
12 	case R_ANAL_COND_MI: return "mi";
13 	case R_ANAL_COND_PL: return "pl";
14 	case R_ANAL_COND_VS: return "vs";
15 	case R_ANAL_COND_VC: return "vc";
16 	case R_ANAL_COND_HI: return "hi";
17 	case R_ANAL_COND_LS: return "ls";
18 	case R_ANAL_COND_GE: return "ge";
19 	case R_ANAL_COND_LT: return "lt";
20 	case R_ANAL_COND_GT: return "gt";
21 	case R_ANAL_COND_LE: return "le";
22 	case R_ANAL_COND_AL: return "al";
23 	}
24 	return "??";
25 }
26 
r_anal_cond_new(void)27 R_API RAnalCond *r_anal_cond_new(void) {
28 	return R_NEW0 (RAnalCond);
29 }
30 
r_anal_cond_fini(RAnalCond * c)31 R_API void r_anal_cond_fini (RAnalCond *c) {
32 	if (!c) {
33 		return;
34 	}
35 	r_anal_value_free (c->arg[0]);
36 	r_anal_value_free (c->arg[1]);
37 	c->arg[0] = c->arg[1] = NULL;
38 }
39 
r_anal_cond_free(RAnalCond * c)40 R_API void r_anal_cond_free (RAnalCond *c) {
41 	if (!c) {
42 		return;
43 	}
44 	r_anal_cond_fini (c);
45 	free (c);
46 }
47 
48 // XXX?
r_anal_cond_clone(RAnalCond * cond)49 R_API RAnalCond *r_anal_cond_clone(RAnalCond *cond) {
50 	RAnalCond *c = R_NEW (RAnalCond);
51 	if (!c) {
52 		return NULL;
53 	}
54 	memcpy (c, cond, sizeof (RAnalCond));
55 	return c;
56 }
57 
condstring(RAnalCond * cond)58 static inline const char *condstring(RAnalCond *cond) {
59 	const char *condstr_single[] = { "!", "", "0<", "0<=", "0>", "0>=" };
60 	const char *condstr[] = { "==", "!=", ">=", ">", "<=", "<" };
61 	if (cond) {
62 		if (cond->arg[1]) {
63 			return condstr[cond->type % 6];
64 		} else {
65 			return condstr_single[cond->type % 6];
66 		}
67 	}
68 	return "";
69 }
70 
r_anal_cond_eval(RAnal * anal,RAnalCond * cond)71 R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) {
72 	// XXX: sign issue here?
73 	st64 arg0 = (st64) r_anal_value_to_ut64 (anal, cond->arg[0]);
74 	if (cond->arg[1]) {
75 		st64 arg1 = (st64) r_anal_value_to_ut64 (anal, cond->arg[1]);
76 		switch (cond->type) {
77 		case R_ANAL_COND_EQ: return arg0 == arg1;
78 		case R_ANAL_COND_NE: return arg0 != arg1;
79 		case R_ANAL_COND_GE: return arg0 >= arg1;
80 		case R_ANAL_COND_GT: return arg0 > arg1;
81 		case R_ANAL_COND_LE: return arg0 <= arg1;
82 		case R_ANAL_COND_LT: return arg0 < arg1;
83 		}
84 	} else {
85 		switch (cond->type) {
86 		case R_ANAL_COND_EQ: return !arg0;
87 		case R_ANAL_COND_NE: return arg0;
88 		case R_ANAL_COND_GT: return arg0>0;
89 		case R_ANAL_COND_GE: return arg0>=0;
90 		case R_ANAL_COND_LT: return arg0<0;
91 		case R_ANAL_COND_LE: return arg0<=0;
92 		}
93 	}
94 	return false;
95 }
96 
97 // XXX conflict naming with tostring()
r_anal_cond_to_string(RAnalCond * cond)98 R_API char *r_anal_cond_to_string(RAnalCond *cond) {
99 	char *val0, *val1, *out = NULL;
100 	const char *cnd;
101 	if (!cond) {
102 		return NULL;
103 	}
104 	cnd = condstring (cond);
105 	val0 = r_anal_value_to_string (cond->arg[0]);
106 	val1 = r_anal_value_to_string (cond->arg[1]);
107 	if (val0) {
108 		if (R_ANAL_COND_SINGLE (cond)) {
109 			int val0len = strlen (val0) + 10;
110 			if ((out = malloc (val0len))) {
111 				snprintf (out, val0len, "%s%s", cnd, val0);
112 			}
113 		} else {
114 			if (val1) {
115 				int val0len = strlen (val0) + strlen (val1) + 10;
116 				if ((out = malloc (val0len))) {
117 					snprintf (out, val0len, "%s %s %s", val0, cnd, val1);
118 				}
119 			}
120 		}
121 	}
122 	free (val0);
123 	free (val1);
124 	return out? out: strdup ("?");
125 }
126 
r_anal_cond_new_from_op(RAnalOp * op)127 R_API RAnalCond *r_anal_cond_new_from_op(RAnalOp *op) {
128 	RAnalCond *cond;
129 	if (!(cond = r_anal_cond_new ())) {
130 		return NULL;
131 	}
132 	//v->reg[0] = op->src[0];
133 	//v->reg[1] = op->src[1];
134 	cond->arg[0] = op->src[0];
135 	op->src[0] = NULL;
136 	cond->arg[1] = op->src[1];
137 	op->src[1] = NULL;
138 	// TODO: moar!
139 	//cond->arg[1] = op->src[1];
140 	return cond;
141 }
142 
r_anal_cond_new_from_string(const char * str)143 R_API RAnalCond *r_anal_cond_new_from_string(const char *str) {
144 	RAnalCond *cond = R_NEW (RAnalCond);
145 	// TODO: find '<','=','>','!'...
146 	return cond;
147 }
148