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