1 /* radare - LGPL - Copyright 2010-2020 - pancake */
2 
3 #include <r_anal.h>
4 
r_anal_value_new(void)5 R_API RAnalValue *r_anal_value_new(void) { //macro for this ?
6 	return R_NEW0 (RAnalValue);
7 }
8 
r_anal_value_new_from_string(const char * str)9 R_API RAnalValue *r_anal_value_new_from_string(const char *str) {
10 	/* TODO */
11 	return NULL;
12 }
13 
r_anal_value_copy(RAnalValue * ov)14 R_API RAnalValue *r_anal_value_copy(RAnalValue *ov) {
15 	r_return_val_if_fail (ov, NULL);
16 
17 	RAnalValue *v = R_NEW0 (RAnalValue);
18 	if (!v) {
19 		return NULL;
20 	}
21 
22 	memcpy (v, ov, sizeof (RAnalValue));
23 	// reference to reg and regdelta should be kept
24 	return v;
25 }
26 
27 // TODO: move into .h as #define free
r_anal_value_free(RAnalValue * value)28 R_API void r_anal_value_free(RAnalValue *value) {
29 	free (value);
30 #if 0
31 	ut64 pval = (ut64)(size_t)value;
32 	if (pval && pval != UT64_MAX) {
33 		/* TODO: free RRegItem objects? */
34 		free (value);
35 	}
36 #endif
37 }
38 
39 // mul*value+regbase+regidx+delta
r_anal_value_to_ut64(RAnal * anal,RAnalValue * val)40 R_API ut64 r_anal_value_to_ut64(RAnal *anal, RAnalValue *val) {
41 	ut64 num;
42 	if (!val) {
43 		return 0LL;
44 	}
45 	num = val->base + (val->delta*(val->mul?val->mul:1));
46 	if (val->reg) {
47 		num += r_reg_get_value (anal->reg, val->reg);
48 	}
49 	if (val->regdelta) {
50 		num += r_reg_get_value (anal->reg, val->regdelta);
51 	}
52 	switch (val->memref) {
53 	case 1:
54 	case 2:
55 	case 4:
56 	case 8:
57 		//anal->bio ...
58 		eprintf ("TODO: memref for to_ut64 not supported\n");
59 		break;
60 	}
61 	return num;
62 }
63 
r_anal_value_set_ut64(RAnal * anal,RAnalValue * val,ut64 num)64 R_API int r_anal_value_set_ut64(RAnal *anal, RAnalValue *val, ut64 num) {
65 	if (val->memref) {
66 		if (anal->iob.io) {
67 			ut8 data[8];
68 			ut64 addr = r_anal_value_to_ut64 (anal, val);
69 			r_mem_set_num (data, val->memref, num);
70 			anal->iob.write_at (anal->iob.io, addr, data, val->memref);
71 		} else {
72 			eprintf ("No IO binded to r_anal\n");
73 		}
74 	} else {
75 		if (val->reg) {
76 			r_reg_set_value (anal->reg, val->reg, num);
77 		}
78 	}
79 	return false;							//is this necessary
80 }
81 
r_anal_value_to_string(RAnalValue * value)82 R_API char *r_anal_value_to_string (RAnalValue *value) {
83 	char *out = NULL;
84 	if (value) {
85 		out = r_str_new ("");
86 		if (!value->base && !value->reg) {
87 			if (value->imm != -1LL) {
88 				out = r_str_appendf (out, "0x%"PFMT64x, value->imm);
89 			} else {
90 				out = r_str_append (out, "-1");
91 			}
92 		} else {
93 			if (value->memref) {
94 				switch (value->memref) {
95 				case 1: out = r_str_append (out, "(char)"); break;
96 				case 2: out = r_str_append (out, "(short)"); break;
97 				case 4: out = r_str_append (out, "(word)"); break;
98 				case 8: out = r_str_append (out, "(dword)"); break;
99 				}
100 				out = r_str_append (out, "[");
101 			}
102 			if (value->mul) {
103 				out = r_str_appendf (out, "%d*", value->mul);
104 			}
105 			if (value->reg) {
106 				out = r_str_appendf (out, "%s", value->reg->name);
107 			}
108 			if (value->regdelta) {
109 				out = r_str_appendf (out, "+%s", value->regdelta->name);
110 			}
111 			if (value->base != 0) {
112 				out = r_str_appendf (out, "0x%" PFMT64x, value->base);
113 			}
114 			if (value->delta > 0) {
115 				out = r_str_appendf (out, "+0x%" PFMT64x, value->delta);
116 			} else if (value->delta < 0) {
117 				out = r_str_appendf (out, "-0x%" PFMT64x, -value->delta);
118 			}
119 			if (value->memref) {
120 				out = r_str_append (out, "]");
121 			}
122 		}
123 	}
124 	return out;
125 }
126