1 /* radare - LGPL - Copyright 2014-2020 - pancake, condret */
2 
3 #include <r_anal.h>
4 #include <r_types.h>
5 #include <r_util.h>
6 #include <r_bind.h>
7 
8 // should these be here?
9 #include <math.h>
10 #include <float.h>
11 #include <fenv.h>
12 
13 #define IFDBG if (esil && esil->verbose > 1)
14 #define IFVBS if (esil && esil->verbose > 0)
15 #define FLG(x) R_ANAL_ESIL_FLAG_##x
16 #define cpuflag(x, y)\
17 if (esil) {\
18 	if (y) { \
19 		R_BIT_SET (&esil->flags, FLG (x));\
20 	} else { \
21 		R_BIT_UNSET (&esil->flags, FLG (x));\
22 	} \
23 }
24 
25 /* Returns the number that has bits + 1 least significant bits set. */
genmask(int bits)26 static inline ut64 genmask(int bits) {
27 	ut64 m = UT64_MAX;
28 	if (bits > 0 && bits < 64) {
29 		m = (ut64)(((ut64)(2) << bits) - 1);
30 		if (!m) {
31 			m = UT64_MAX;
32 		}
33 	}
34 	return m;
35 }
36 
37 #define ERR(x) if (esil->verbose) { eprintf ("%s\n", x); }
38 
isnum(RAnalEsil * esil,const char * str,ut64 * num)39 static bool isnum(RAnalEsil *esil, const char *str, ut64 *num) {
40 	if (!esil || !str) {
41 		return false;
42 	}
43 	if (IS_DIGIT (*str)) {
44 		if (num) {
45 			*num = r_num_get (NULL, str);
46 		}
47 		return true;
48 	}
49 	if (num) {
50 		*num = 0;
51 	}
52 	return false;
53 }
54 
ispackedreg(RAnalEsil * esil,const char * str)55 static bool ispackedreg(RAnalEsil *esil, const char *str) {
56 	RRegItem *ri = r_reg_get (esil->anal->reg, str, -1);
57 	return ri? ri->packed_size > 0: false;
58 }
59 
isregornum(RAnalEsil * esil,const char * str,ut64 * num)60 static bool isregornum(RAnalEsil *esil, const char *str, ut64 *num) {
61 	if (!r_anal_esil_reg_read (esil, str, num, NULL)) {
62 		if (!isnum (esil, str, num)) {
63 			return false;
64 		}
65 	}
66 	return true;
67 }
68 
69 /* pop Register or Number */
popRN(RAnalEsil * esil,ut64 * n)70 static bool popRN(RAnalEsil *esil, ut64 *n) {
71 	char *str = r_anal_esil_pop (esil);
72 	if (str) {
73 		bool ret = isregornum (esil, str, n);
74 		free (str);
75 		return ret;
76 	}
77 	return false;
78 }
79 
80 /* R_ANAL_ESIL API */
81 
esil_ops_free(HtPPKv * kv)82 static void esil_ops_free(HtPPKv *kv) {
83 	free (kv->key);
84 	free (kv->value);
85 }
86 
r_anal_esil_new(int stacksize,int iotrap,unsigned int addrsize)87 R_API RAnalEsil *r_anal_esil_new(int stacksize, int iotrap, unsigned int addrsize) {
88 	RAnalEsil *esil = R_NEW0 (RAnalEsil);
89 	if (!esil) {
90 		return NULL;
91 	}
92 	if (stacksize < 3) {
93 		free (esil);
94 		return NULL;
95 	}
96 	if (!(esil->stack = calloc (sizeof (char *), stacksize))) {
97 		free (esil);
98 		return NULL;
99 	}
100 	esil->verbose = false;
101 	esil->stacksize = stacksize;
102 	esil->parse_goto_count = R_ANAL_ESIL_GOTO_LIMIT;
103 	esil->ops = ht_pp_new (NULL, esil_ops_free, NULL);
104 	esil->iotrap = iotrap;
105 	r_anal_esil_handlers_init (esil);
106 	esil->addrmask = genmask (addrsize - 1);
107 	return esil;
108 }
109 
r_anal_esil_set_op(RAnalEsil * esil,const char * op,RAnalEsilOpCb code,ut32 push,ut32 pop,ut32 type)110 R_API bool r_anal_esil_set_op(RAnalEsil *esil, const char *op, RAnalEsilOpCb code, ut32 push, ut32 pop, ut32 type) {
111 	r_return_val_if_fail (code && R_STR_ISNOTEMPTY (op) && esil && esil->ops, false);
112 	RAnalEsilOp *eop = ht_pp_find (esil->ops, op, NULL);
113 	if (!eop) {
114 		eop = R_NEW (RAnalEsilOp);
115 		if (!eop) {
116 			eprintf ("Cannot allocate esil-operation %s\n", op);
117 			return false;
118 		}
119 		if (!ht_pp_insert (esil->ops, op, eop)) {
120 			eprintf ("Cannot set esil-operation %s\n", op);
121 			free (eop);
122 			return false;
123 		}
124 	}
125 	eop->push = push;
126 	eop->pop = pop;
127 	eop->type = type;
128 	eop->code = code;
129 	return true;
130 }
131 
r_anal_esil_fire_trap(RAnalEsil * esil,int trap_type,int trap_code)132 static bool r_anal_esil_fire_trap(RAnalEsil *esil, int trap_type, int trap_code) {
133 	r_return_val_if_fail (esil, false);
134 	if (esil->cmd) {
135 		if (esil->cmd (esil, esil->cmd_trap, trap_type, trap_code)) {
136 			return true;
137 		}
138 	}
139 	if (esil->anal) {
140 		RAnalPlugin *ap = esil->anal->cur;
141 		if (ap && ap->esil_trap) {
142 			if (ap->esil_trap (esil, trap_type, trap_code)) {
143 				return true;
144 			}
145 		}
146 	}
147 #if 0
148 	RAnalEsilTrapCB icb;
149 	icb = (RAnalEsilTrapCB)sdb_ptr_get (esil->traps, i, 0);
150 	return icb (esil, trap_type, trap_code);
151 #endif
152 	return false;
153 }
154 
r_anal_esil_set_pc(RAnalEsil * esil,ut64 addr)155 R_API bool r_anal_esil_set_pc(RAnalEsil *esil, ut64 addr) {
156 	if (esil) {
157 		esil->address = addr;
158 		return true;
159 	}
160 	return false;
161 }
162 
r_anal_esil_free(RAnalEsil * esil)163 R_API void r_anal_esil_free(RAnalEsil *esil) {
164 	if (!esil) {
165 		return;
166 	}
167 	if (esil->anal && esil == esil->anal->esil) {
168 		esil->anal->esil = NULL;
169 	}
170 	ht_pp_free (esil->ops);
171 	esil->ops = NULL;
172 	r_anal_esil_handlers_fini (esil);
173 	sdb_free (esil->stats);
174 	esil->stats = NULL;
175 	r_anal_esil_stack_free (esil);
176 	free (esil->stack);
177 	if (esil->anal && esil->anal->cur && esil->anal->cur->esil_fini) {
178 		esil->anal->cur->esil_fini (esil);
179 	}
180 	r_anal_esil_trace_free (esil->trace);
181 	esil->trace = NULL;
182 	free (esil->cmd_intr);
183 	free (esil->cmd_trap);
184 	free (esil->cmd_mdev);
185 	free (esil->cmd_todo);
186 	free (esil->cmd_step);
187 	free (esil->cmd_step_out);
188 	free (esil->cmd_ioer);
189 	free (esil);
190 }
191 
esil_internal_sizeof_reg(RAnalEsil * esil,const char * r)192 static ut8 esil_internal_sizeof_reg(RAnalEsil *esil, const char *r) {
193 	r_return_val_if_fail (esil && esil->anal && esil->anal->reg && r, 0);
194 	RRegItem *ri = r_reg_get (esil->anal->reg, r, -1);
195 	return ri? ri->size: 0;
196 }
197 
alignCheck(RAnalEsil * esil,ut64 addr)198 static bool alignCheck(RAnalEsil *esil, ut64 addr) {
199 	int dataAlign = r_anal_archinfo (esil->anal, R_ANAL_ARCHINFO_DATA_ALIGN);
200 	return !(dataAlign > 0 && addr % dataAlign);
201 }
202 
internal_esil_mem_read(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)203 static int internal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
204 	r_return_val_if_fail (esil && esil->anal && esil->anal->iob.io, 0);
205 
206 	addr &= esil->addrmask;
207 	if (!alignCheck (esil, addr)) {
208 		esil->trap = R_ANAL_TRAP_READ_ERR;
209 		esil->trap_code = addr;
210 		return false;
211 	}
212 	if (esil->cmd_mdev && esil->mdev_range) {
213 		if (r_str_range_in (esil->mdev_range, addr)) {
214 			if (esil->cmd (esil, esil->cmd_mdev, addr, 0)) {
215 				return true;
216 			}
217 		}
218 	}
219 	//TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
220 	(void)esil->anal->iob.read_at (esil->anal->iob.io, addr, buf, len);
221 	// check if request address is mapped , if don't fire trap and esil ioer callback
222 	// now with siol, read_at return true/false can't be used to check error vs len
223 	if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
224 		if (esil->iotrap) {
225 			esil->trap = R_ANAL_TRAP_READ_ERR;
226 			esil->trap_code = addr;
227 		}
228 		if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
229 			esil->cmd (esil, esil->cmd_ioer, esil->address, 0);
230 		}
231 	}
232 	return len;
233 }
234 
internal_esil_mem_read_no_null(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)235 static int internal_esil_mem_read_no_null(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
236 	r_return_val_if_fail (esil && esil->anal && esil->anal->iob.io, 0);
237 
238 	addr &= esil->addrmask;
239 	if (!alignCheck (esil, addr)) {
240 		esil->trap = R_ANAL_TRAP_READ_ERR;
241 		esil->trap_code = addr;
242 		return false;
243 	}
244 	//TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
245 	(void)esil->anal->iob.read_at (esil->anal->iob.io, addr, buf, len);
246 	// check if request address is mapped , if don't fire trap and esil ioer callback
247 	// now with siol, read_at return true/false can't be used to check error vs len
248 	if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
249 		if (esil->iotrap) {
250 			esil->trap = R_ANAL_TRAP_READ_ERR;
251 			esil->trap_code = addr;
252 		}
253 	}
254 	return len;
255 }
256 
r_anal_esil_mem_read(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)257 R_API int r_anal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
258 	int i, ret = 0;
259 	r_return_val_if_fail (buf && esil, 0);
260 	addr &= esil->addrmask;
261 	if (esil->cb.hook_mem_read) {
262 		ret = esil->cb.hook_mem_read (esil, addr, buf, len);
263 	}
264 	if (!alignCheck (esil, addr)) {
265 		esil->trap = R_ANAL_TRAP_READ_ERR;
266 		esil->trap_code = addr;
267 		return false;
268 	}
269 	if (!ret && esil->cb.mem_read) {
270 		ret = esil->cb.mem_read (esil, addr, buf, len);
271 		if (ret != len) {
272 			if (esil->iotrap) {
273 				esil->trap = R_ANAL_TRAP_READ_ERR;
274 				esil->trap_code = addr;
275 			}
276 		}
277 	}
278 	IFDBG {
279 		eprintf ("0x%08" PFMT64x " R> ", addr);
280 		for (i = 0; i < len; i++) {
281 			eprintf ("%02x", buf[i]);
282 		}
283 		eprintf ("\n");
284 	}
285 	return ret;
286 }
287 
internal_esil_mem_write(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)288 static int internal_esil_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
289 	int ret = 0;
290 	if (!esil || !esil->anal || !esil->anal->iob.io || esil->nowrite) {
291 		return 0;
292 	}
293 	addr &= esil->addrmask;
294 	if (!alignCheck (esil, addr)) {
295 		esil->trap = R_ANAL_TRAP_READ_ERR;
296 		esil->trap_code = addr;
297 		return false;
298 	}
299 	if (esil->cmd_mdev && esil->mdev_range) {
300 		if (r_str_range_in (esil->mdev_range, addr)) {
301 			if (esil->cmd (esil, esil->cmd_mdev, addr, 1)) {
302 				return true;
303 			}
304 		}
305 	}
306 	if (esil->anal->iob.write_at (esil->anal->iob.io, addr, buf, len)) {
307 		ret = len;
308 	}
309 	// check if request address is mapped , if don't fire trap and esil ioer callback
310 	// now with siol, write_at return true/false can't be used to check error vs len
311 	if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
312 		if (esil->iotrap) {
313 			esil->trap = R_ANAL_TRAP_WRITE_ERR;
314 			esil->trap_code = addr;
315 		}
316 		if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
317 			esil->cmd (esil, esil->cmd_ioer, esil->address, 0);
318 		}
319 	}
320 	return ret;
321 }
322 
internal_esil_mem_write_no_null(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)323 static int internal_esil_mem_write_no_null(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
324 	int ret = 0;
325 	if (!esil || !esil->anal || !esil->anal->iob.io || !addr) {
326 		return 0;
327 	}
328 	if (esil->nowrite) {
329 		return 0;
330 	}
331 	addr &= esil->addrmask;
332 	if (esil->anal->iob.write_at (esil->anal->iob.io, addr, buf, len)) {
333 		ret = len;
334 	}
335 	// check if request address is mapped , if don't fire trap and esil ioer callback
336 	// now with siol, write_at return true/false can't be used to check error vs len
337 	if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
338 		if (esil->iotrap) {
339 			esil->trap = R_ANAL_TRAP_WRITE_ERR;
340 			esil->trap_code = addr;
341 		}
342 	}
343 	return ret;
344 }
345 
r_anal_esil_mem_write(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)346 R_API int r_anal_esil_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
347 	int i, ret = 0;
348 	if (!buf || !esil) {
349 		return 0;
350 	}
351 	addr &= esil->addrmask;
352 	IFDBG {
353 		eprintf ("0x%08" PFMT64x " <W ", addr);
354 		for (i = 0; i < len; i++) {
355 			eprintf ("%02x", buf[i]);
356 		}
357 		eprintf ("\n");
358 	}
359 	if (esil->cb.hook_mem_write) {
360 		ret = esil->cb.hook_mem_write (esil, addr, buf, len);
361 	}
362 	if (!ret && esil->cb.mem_write) {
363 		ret = esil->cb.mem_write (esil, addr, buf, len);
364 	}
365 	return ret;
366 }
367 
internal_esil_reg_read(RAnalEsil * esil,const char * regname,ut64 * num,int * size)368 static int internal_esil_reg_read(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
369 	RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
370 	if (reg) {
371 		if (size) {
372 			*size = reg->size;
373 		}
374 		if (num) {
375 			*num = r_reg_get_value (esil->anal->reg, reg);
376 		}
377 		return true;
378 	}
379 	return false;
380 }
381 
internal_esil_reg_write(RAnalEsil * esil,const char * regname,ut64 num)382 static int internal_esil_reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
383 	if (esil && esil->anal) {
384 		RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
385 		if (reg) {
386 			r_reg_set_value (esil->anal->reg, reg, num);
387 			return true;
388 		}
389 	}
390 	return false;
391 }
392 
393 //WTF IS THIS!!!
394 //Are you really trying to prevent the analyzed binary from doing anything that would cause it to segfault irl?
395 //WHY?
396 //	- condret
internal_esil_reg_write_no_null(RAnalEsil * esil,const char * regname,ut64 num)397 static int internal_esil_reg_write_no_null (RAnalEsil *esil, const char *regname, ut64 num) {
398 	r_return_val_if_fail (esil && esil->anal && esil->anal->reg, false);
399 
400 	RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
401 	const char *pc = r_reg_get_name (esil->anal->reg, R_REG_NAME_PC);
402 	const char *sp = r_reg_get_name (esil->anal->reg, R_REG_NAME_SP);
403 	const char *bp = r_reg_get_name (esil->anal->reg, R_REG_NAME_BP);
404 
405 	if (!pc) {
406 		eprintf ("Warning: RReg profile does not contain PC register\n");
407 		return false;
408 	}
409 	if (!sp) {
410 		eprintf ("Warning: RReg profile does not contain SP register\n");
411 		return false;
412 	}
413 	if (!bp) {
414 		eprintf ("Warning: RReg profile does not contain BP register\n");
415 		return false;
416 	}
417 	if (reg && reg->name && ((strcmp (reg->name , pc) && strcmp (reg->name, sp) && strcmp(reg->name, bp)) || num)) { //I trust k-maps
418 		r_reg_set_value (esil->anal->reg, reg, num);
419 		return true;
420 	}
421 	return false;
422 }
423 
r_anal_esil_pushnum(RAnalEsil * esil,ut64 num)424 R_API bool r_anal_esil_pushnum(RAnalEsil *esil, ut64 num) {
425 	char str[64];
426 	snprintf (str, sizeof (str) - 1, "0x%" PFMT64x, num);
427 	return r_anal_esil_push (esil, str);
428 }
429 
r_anal_esil_push(RAnalEsil * esil,const char * str)430 R_API bool r_anal_esil_push(RAnalEsil *esil, const char *str) {
431 	if (!str || !esil || !*str || esil->stackptr > (esil->stacksize - 1)) {
432 		return false;
433 	}
434 	esil->stack[esil->stackptr++] = strdup (str);
435 	return true;
436 }
437 
r_anal_esil_pop(RAnalEsil * esil)438 R_API char *r_anal_esil_pop(RAnalEsil *esil) {
439 	r_return_val_if_fail (esil, NULL);
440 	if (esil->stackptr < 1) {
441 		return NULL;
442 	}
443 	return esil->stack[--esil->stackptr];
444 }
445 
r_anal_esil_get_parm_type(RAnalEsil * esil,const char * str)446 R_API int r_anal_esil_get_parm_type(RAnalEsil *esil, const char *str) {
447 	int len, i;
448 
449 	if (!str || !(len = strlen (str))) {
450 		return R_ANAL_ESIL_PARM_INVALID;
451 	}
452 	if (!strncmp (str, "0x", 2)) {
453 		return R_ANAL_ESIL_PARM_NUM;
454 	}
455 	if (!((IS_DIGIT (str[0])) || str[0] == '-')) {
456 		goto not_a_number;
457 	}
458 	for (i = 1; i < len; i++) {
459 		if (!(IS_DIGIT (str[i]))) {
460 			goto not_a_number;
461 		}
462 	}
463 	return R_ANAL_ESIL_PARM_NUM;
464 not_a_number:
465 	if (r_reg_get (esil->anal->reg, str, -1)) {
466 		return R_ANAL_ESIL_PARM_REG;
467 	}
468 	return R_ANAL_ESIL_PARM_INVALID;
469 }
470 
r_anal_esil_get_parm_size(RAnalEsil * esil,const char * str,ut64 * num,int * size)471 R_API int r_anal_esil_get_parm_size(RAnalEsil *esil, const char *str, ut64 *num, int *size) {
472 	if (!str || !*str) {
473 		return false;
474 	}
475 	int parm_type = r_anal_esil_get_parm_type (esil, str);
476 	if (!num || !esil) {
477 		return false;
478 	}
479 	switch (parm_type) {
480 	case R_ANAL_ESIL_PARM_NUM:
481 		*num = r_num_get (NULL, str);
482 		if (size) {
483 			*size = esil->anal->bits;
484 		}
485 		return true;
486 	case R_ANAL_ESIL_PARM_REG:
487 		if (!r_anal_esil_reg_read (esil, str, num, size)) {
488 			break;
489 		}
490 		return true;
491 	default:
492 		if (esil->verbose) {
493 			eprintf ("Invalid arg (%s)\n", str);
494 		}
495 		esil->parse_stop = 1;
496 		break;
497 	}
498 	return false;
499 }
500 
r_anal_esil_get_parm(RAnalEsil * esil,const char * str,ut64 * num)501 R_API int r_anal_esil_get_parm(RAnalEsil *esil, const char *str, ut64 *num) {
502 	return r_anal_esil_get_parm_size (esil, str, num, NULL);
503 }
504 
r_anal_esil_reg_write(RAnalEsil * esil,const char * dst,ut64 num)505 R_API int r_anal_esil_reg_write(RAnalEsil *esil, const char *dst, ut64 num) {
506 	int ret = 0;
507 	IFDBG { eprintf ("%s=0x%" PFMT64x "\n", dst, num); }
508 	if (esil && esil->cb.hook_reg_write) {
509 		ret = esil->cb.hook_reg_write (esil, dst, &num);
510 	}
511 	if (!ret && esil && esil->cb.reg_write) {
512 		ret = esil->cb.reg_write (esil, dst, num);
513 	}
514 	return ret;
515 }
516 
r_anal_esil_reg_read_nocallback(RAnalEsil * esil,const char * regname,ut64 * num,int * size)517 R_API int r_anal_esil_reg_read_nocallback(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
518 	int ret;
519 	void *old_hook_reg_read = (void *) esil->cb.hook_reg_read;
520 	esil->cb.hook_reg_read = NULL;
521 	ret = r_anal_esil_reg_read (esil, regname, num, size);
522 	esil->cb.hook_reg_read = old_hook_reg_read;
523 	return ret;
524 }
525 
r_anal_esil_reg_read(RAnalEsil * esil,const char * regname,ut64 * num,int * size)526 R_API int r_anal_esil_reg_read(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
527 	bool ret = false;
528 	ut64 localnum; // XXX why is this necessary?
529 	if (!esil || !regname) {
530 		return false;
531 	}
532 	if (!num) {
533 		num = &localnum;
534 	}
535 	*num = 0LL;
536 	if (size) {
537 		*size = esil->anal->bits;
538 	}
539 	if (esil->cb.hook_reg_read) {
540 		ret = esil->cb.hook_reg_read (esil, regname, num, size);
541 	}
542 	if (!ret && esil->cb.reg_read) {
543 		ret = esil->cb.reg_read (esil, regname, num, size);
544 	}
545 	return ret;
546 }
547 
r_anal_esil_signext(RAnalEsil * esil,bool assign)548 R_API int r_anal_esil_signext(RAnalEsil *esil, bool assign) {
549 	bool ret = false;
550 	ut64 src, dst;
551 
552 	char *p_src = r_anal_esil_pop (esil);
553 	if (!p_src) {
554 		return false;
555 	}
556 
557 	if (!r_anal_esil_get_parm (esil, p_src, &src)) {
558 		ERR ("esil_of: empty stack");
559 		free (p_src);
560 		return false;
561 	}
562 
563 	char *p_dst = r_anal_esil_pop (esil);
564 	if (!p_dst) {
565 		free (p_src);
566 		return false;
567 	}
568 
569 	if (!r_anal_esil_get_parm (esil, p_dst, &dst)) {
570 		ERR ("esil_of: empty stack");
571 		free (p_src);
572 		free (p_dst);
573 		return false;
574 	} else {
575 		free (p_dst);
576 	}
577 
578 	//Make sure the other bits are 0
579 	src &= UT64_MAX >> (64 - dst);
580 
581 	ut64 m = 0;
582 	if (dst < 64) {
583 		m = 1ULL << (dst - 1);
584 	}
585 
586 	// dst = (dst & ((1U << src_bit) - 1)); // clear upper bits
587 	if (assign) {
588 		ret = r_anal_esil_reg_write (esil, p_src, ((src ^ m) - m));
589 	} else {
590 		ret = r_anal_esil_pushnum (esil, ((src ^ m) - m));
591 	}
592 
593 	free (p_src);
594 	return ret;
595 }
596 
597 // sign extension operator for use in idiv, imul, movsx*
598 // and other instructions involving signed values, extends n bit value to 64 bit value
599 // example : >"ae 8,0x81,~" ( <src bit width>,<value>,~ )
600 // output  : 0xffffffffffffff81
esil_signext(RAnalEsil * esil)601 static bool esil_signext(RAnalEsil *esil) {
602 	return r_anal_esil_signext(esil, false);
603 }
604 
605 // sign extension assignement
606 // example : > "ae 0x81,a0,="
607 //           > "ae 8,a0,~="   ( <src bit width>,register,~= )
608 // output  : > ar a0
609 //           0xffffff81
esil_signexteq(RAnalEsil * esil)610 static bool esil_signexteq(RAnalEsil *esil) {
611 	return r_anal_esil_signext(esil, true);
612 }
613 
esil_zf(RAnalEsil * esil)614 static bool esil_zf(RAnalEsil *esil) {
615 	return r_anal_esil_pushnum (esil, !(esil->cur & genmask (esil->lastsz - 1)));
616 }
617 
618 // checks if there was a carry from bit x (x,$c)
esil_cf(RAnalEsil * esil)619 static bool esil_cf(RAnalEsil *esil) {
620 	char *src = r_anal_esil_pop (esil);
621 
622 	if (!src) {
623 		return false;
624 	}
625 
626 	if (r_anal_esil_get_parm_type (esil, src) != R_ANAL_ESIL_PARM_NUM) {
627 		//I'd wish we could enforce consts here
628 		//I can't say why, but I feel like "al,$c" would be cancer af
629 		//	- condret
630 		free (src);
631 		return false;
632 	}
633 	ut64 bit;
634 	r_anal_esil_get_parm (esil, src, &bit);
635 	free (src);
636 	//carry from bit <src>
637 	//range of src goes from 0 to 63
638 	//
639 	//implements bit mod 64
640 	const ut64 mask = genmask (bit & 0x3f);
641 	return r_anal_esil_pushnum (esil, (esil->cur & mask) < (esil->old & mask));
642 }
643 
644 // checks if there was a borrow from bit x (x,$b)
esil_bf(RAnalEsil * esil)645 static bool esil_bf(RAnalEsil *esil) {
646 	char *src = r_anal_esil_pop (esil);
647 
648 	if (!src) {
649 		return false;
650 	}
651 
652 	if (r_anal_esil_get_parm_type (esil, src) != R_ANAL_ESIL_PARM_NUM) {
653 		free (src);
654 		return false;
655 	}
656 	ut64 bit;
657 	r_anal_esil_get_parm (esil, src, &bit);
658 	free (src);
659 	//borrow from bit <src>
660 	//range of src goes from 1 to 64
661 	//	you cannot borrow from bit 0, bc bit -1 cannot not exist
662 	//
663 	//implements (bit - 1) mod 64
664 	const ut64 mask = genmask ((bit + 0x3f) & 0x3f);
665 	return r_anal_esil_pushnum (esil, (esil->old & mask) < (esil->cur & mask));
666 }
667 
esil_pf(RAnalEsil * esil)668 static bool esil_pf(RAnalEsil *esil) {
669 	// Set if the number of set bits in the least significant _byte_ is a multiple of 2.
670 	//   - Taken from: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits
671 	const ut64 c1 = 0x0101010101010101ULL;
672 	const ut64 c2 = 0x8040201008040201ULL;
673 	const ut64 c3 = 0x1FF;
674 	// Take only the least significant byte.
675 	ut64 lsb = esil->cur & 0xff;
676 	return r_anal_esil_pushnum (esil, !((((lsb * c1) & c2) % c3) & 1));
677 }
678 
679 // like carry
680 // checks overflow from bit x (x,$o)
681 //	x,$o ===> x,$c,x-1,$c,^
esil_of(RAnalEsil * esil)682 static bool esil_of(RAnalEsil *esil) {
683 	char *p_bit = r_anal_esil_pop (esil);
684 
685 	if (!p_bit) {
686 		return false;
687 	}
688 
689 	if (r_anal_esil_get_parm_type (esil, p_bit) != R_ANAL_ESIL_PARM_NUM) {
690 		free (p_bit);
691 		return false;
692 	}
693 	ut64 bit;
694 
695 	if (!r_anal_esil_get_parm (esil, p_bit, &bit)) {
696 		ERR ("esil_of: empty stack");
697 		free (p_bit);
698 		return false;
699 	}
700 	free (p_bit);
701 
702 	const ut64 m[2] = {genmask (bit & 0x3f), genmask ((bit + 0x3f) & 0x3f)};
703 	const ut64 result = ((esil->cur & m[0]) < (esil->old & m[0])) ^ ((esil->cur & m[1]) < (esil->old & m[1]));
704 	ut64 res = r_anal_esil_pushnum (esil, result);
705 	return res;
706 }
707 
708 //checks sign bit at x (x,$s)
esil_sf(RAnalEsil * esil)709 static bool esil_sf(RAnalEsil *esil) {
710 	r_return_val_if_fail (esil, false);
711 
712 	char *p_size = r_anal_esil_pop (esil);
713 	r_return_val_if_fail (p_size, false);
714 
715 	if (r_anal_esil_get_parm_type (esil, p_size) != R_ANAL_ESIL_PARM_NUM) {
716 		free (p_size);
717 		return false;
718 	}
719 	ut64 size, num;
720 	r_anal_esil_get_parm (esil, p_size, &size);
721 	free (p_size);
722 
723 	if (size > 63) {
724 		num = 0;
725 	} else {
726 		num = (esil->cur >> size) & 1;
727 	}
728 	ut64 res = r_anal_esil_pushnum (esil, num);
729 	return res;
730 }
731 
esil_ds(RAnalEsil * esil)732 static bool esil_ds(RAnalEsil *esil) {
733 	r_return_val_if_fail (esil, false);
734 	return r_anal_esil_pushnum (esil, esil->delay);
735 }
736 
esil_jt(RAnalEsil * esil)737 static bool esil_jt(RAnalEsil *esil) {
738 	r_return_val_if_fail (esil, false);
739 	return r_anal_esil_pushnum (esil, esil->jump_target);
740 }
741 
esil_js(RAnalEsil * esil)742 static bool esil_js(RAnalEsil *esil) {
743 	r_return_val_if_fail (esil, false);
744 	return r_anal_esil_pushnum (esil, esil->jump_target_set);
745 }
746 
747 //regsize
748 //can we please deprecate this, it's neither accurate, nor needed
749 //plugins should know regsize, and since this is a const even users should know this: ?´e anal.bits´/8
750 //	- condret
751 // YES PLS KILL IT
esil_rs(RAnalEsil * esil)752 static bool esil_rs(RAnalEsil *esil) {
753 	r_return_val_if_fail (esil && esil->anal, false);
754 	return r_anal_esil_pushnum (esil, esil->anal->bits >> 3);
755 }
756 
757 //can we please deprecate this, plugins should know their current address
758 //even if they don't know it, $$ should be equal to PC register at the begin of each expression
759 //	- condret
760 // YES PLS KILL IT
esil_address(RAnalEsil * esil)761 static bool esil_address(RAnalEsil *esil) {
762 	r_return_val_if_fail (esil, false);
763 	return r_anal_esil_pushnum (esil, esil->address);
764 }
765 
esil_weak_eq(RAnalEsil * esil)766 static bool esil_weak_eq(RAnalEsil *esil) {
767 	r_return_val_if_fail (esil && esil->anal, false);
768 	char *dst = r_anal_esil_pop (esil);
769 	char *src = r_anal_esil_pop (esil);
770 
771 	if (!(dst && src && (r_anal_esil_get_parm_type(esil, dst) == R_ANAL_ESIL_PARM_REG))) {
772 		free (dst);
773 		free (src);
774 		return false;
775 	}
776 
777 	ut64 src_num;
778 	if (r_anal_esil_get_parm (esil, src, &src_num)) {
779 		(void)r_anal_esil_reg_write (esil, dst, src_num);
780 		free (src);
781 		free (dst);
782 		return true;
783 	}
784 
785 	free (src);
786 	free (dst);
787 	return false;
788 }
789 
esil_eq(RAnalEsil * esil)790 static bool esil_eq(RAnalEsil *esil) {
791 	bool ret = false;
792 	ut64 num, num2;
793 	char *dst = r_anal_esil_pop (esil);
794 	char *src = r_anal_esil_pop (esil);
795 	if (!src || !dst) {
796 		if (esil->verbose) {
797 			eprintf ("Missing elements in the esil stack for '=' at 0x%08"PFMT64x"\n", esil->address);
798 		}
799 		free (src);
800 		free (dst);
801 		return false;
802 	}
803 	if (ispackedreg (esil, dst)) {
804 		char *src2 = r_anal_esil_pop (esil);
805 		char *newreg = r_str_newf ("%sl", dst);
806 		if (r_anal_esil_get_parm (esil, src2, &num2)) {
807 			ret = r_anal_esil_reg_write (esil, newreg, num2);
808 		}
809 		free (newreg);
810 		free (src2);
811 		goto beach;
812 	}
813 
814 	if (src && dst && r_anal_esil_reg_read_nocallback (esil, dst, &num, NULL)) {
815 		if (r_anal_esil_get_parm (esil, src, &num2)) {
816 			ret = r_anal_esil_reg_write (esil, dst, num2);
817 			esil->cur = num2;
818 			esil->old = num;
819 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
820 		} else {
821 			ERR ("esil_eq: invalid src");
822 		}
823 	} else {
824 		ERR ("esil_eq: invalid parameters");
825 	}
826 beach:
827 	free (src);
828 	free (dst);
829 	return ret;
830 }
831 
esil_neg(RAnalEsil * esil)832 static bool esil_neg(RAnalEsil *esil) {
833 	bool ret = false;
834 	char *src = r_anal_esil_pop (esil);
835 	if (src) {
836 		ut64 num;
837 		if (r_anal_esil_get_parm (esil, src, &num)) {
838 			r_anal_esil_pushnum (esil, !num);
839 			ret = true;
840 		} else {
841 			if (isregornum (esil, src, &num)) {
842 				ret = true;
843 				r_anal_esil_pushnum (esil, !num);
844 			} else {
845 				eprintf ("0x%08"PFMT64x" esil_neg: unknown reg %s\n", esil->address, src);
846 			}
847 		}
848 	} else {
849 		ERR ("esil_neg: empty stack");
850 	}
851 	free (src);
852 	return ret;
853 }
854 
esil_negeq(RAnalEsil * esil)855 static bool esil_negeq(RAnalEsil *esil) {
856 	bool ret = false;
857 	ut64 num;
858 	char *src = r_anal_esil_pop (esil);
859 	if (src && r_anal_esil_reg_read (esil, src, &num, NULL)) {
860 		num = !num;
861 		r_anal_esil_reg_write (esil, src, num);
862 		ret = true;
863 	} else {
864 		ERR ("esil_negeq: empty stack");
865 	}
866 	free (src);
867 	//r_anal_esil_pushnum (esil, ret);
868 	return ret;
869 }
870 
esil_nop(RAnalEsil * esil)871 static bool esil_nop(RAnalEsil *esil) {
872 	return true;
873 }
874 
esil_andeq(RAnalEsil * esil)875 static bool esil_andeq(RAnalEsil *esil) {
876 	bool ret = false;
877 	ut64 num, num2;
878 	char *dst = r_anal_esil_pop (esil);
879 	char *src = r_anal_esil_pop (esil);
880 	if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
881 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
882 			esil->old = num;
883 			esil->cur = num & num2;
884 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
885 			r_anal_esil_reg_write (esil, dst, num & num2);
886 			ret = true;
887 		} else {
888 			ERR ("esil_andeq: empty stack");
889 		}
890 	}
891 	free (src);
892 	free (dst);
893 	return ret;
894 }
895 
esil_oreq(RAnalEsil * esil)896 static bool esil_oreq(RAnalEsil *esil) {
897 	bool ret = false;
898 	ut64 num, num2;
899 	char *dst = r_anal_esil_pop (esil);
900 	char *src = r_anal_esil_pop (esil);
901 	if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
902 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
903 			esil->old = num;
904 			esil->cur = num | num2;
905 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
906 			ret = r_anal_esil_reg_write (esil, dst, num | num2);
907 		} else {
908 			ERR ("esil_ordeq: empty stack");
909 		}
910 	}
911 	free (src);
912 	free (dst);
913 	return ret;
914 }
915 
esil_xoreq(RAnalEsil * esil)916 static bool esil_xoreq(RAnalEsil *esil) {
917 	bool ret = false;
918 	ut64 num, num2;
919 	char *dst = r_anal_esil_pop (esil);
920 	char *src = r_anal_esil_pop (esil);
921 	if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
922 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
923 				esil->old = num;
924 				esil->cur = num ^ num2;
925 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
926 			ret = r_anal_esil_reg_write (esil, dst, num ^ num2);
927 		} else {
928 			ERR ("esil_xoreq: empty stack");
929 		}
930 	}
931 	free (src);
932 	free (dst);
933 	return ret;
934 }
935 
936 #if 0
937 static int esil_interrupt_linux_i386(RAnalEsil *esil) { 		//move this into a plugin
938 	ut32 sn, ret = 0;
939 	char *usn = r_anal_esil_pop (esil);
940 	if (usn) {
941 		sn = (ut32) r_num_get (NULL, usn);
942 	} else sn = 0x80;
943 
944 	if (sn == 3) {
945 		// trap
946 		esil->trap = R_ANAL_TRAP_BREAKPOINT;
947 		esil->trap_code = 3;
948 		return -1;
949 	}
950 
951 	if (sn != 0x80) {
952 		eprintf ("Interrupt 0x%x not handled.", sn);
953 		esil->trap = R_ANAL_TRAP_UNHANDLED;
954 		esil->trap_code = sn;
955 		return -1;
956 	}
957 #undef r
958 #define r(x) r_reg_getv (esil->anal->reg, "##x##")
959 #undef rs
960 #define rs(x, y) r_reg_setv (esil->anal->reg, "##x##", y)
961 	switch (r(eax)) {
962 	case 1:
963 		printf ("exit(%d)\n", (int)r(ebx));
964 		rs(eax, -1);
965 		// never return. stop execution somehow, throw an exception
966 		break;
967 	case 3:
968 		ret = r(edx);
969 		printf ("ret:%d = read(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
970 			(int)ret, r(ebx), r(ecx), r(edx));
971 		rs(eax, ret);
972 		break;
973 	case 4:
974 		ret = r(edx);
975 		printf ("ret:%d = write(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
976 			(int)ret, r(ebx), r(ecx), r(edx));
977 		rs(eax, ret);
978 		break;
979 	case 5:
980 		ret = -1;
981 		printf ("fd:%d = open(file:0x%08"PFMT64x", mode:%"PFMT64d", perm:%"PFMT64d")\n",
982 			(int)ret, r(ebx), r(ecx), r(edx));
983 		rs(eax, ret);
984 		break;
985 	}
986 #undef r
987 #undef rs
988 	return 0;
989 }
990 #endif
991 
esil_trap(RAnalEsil * esil)992 static bool esil_trap(RAnalEsil *esil) {
993 	ut64 s, d;
994 	if (popRN (esil, &s) && popRN (esil, &d)) {
995 		esil->trap = s;
996 		esil->trap_code = d;
997 		return r_anal_esil_fire_trap (esil, (int)s, (int)d);
998 	}
999 	ERR ("esil_trap: missing parameters in stack");
1000 	return false;
1001 }
1002 
esil_bits(RAnalEsil * esil)1003 static bool esil_bits(RAnalEsil *esil) {
1004 	ut64 s;
1005 	if (popRN (esil, &s)) {
1006 		if (esil->anal && esil->anal->coreb.setab) {
1007 			esil->anal->coreb.setab (esil->anal->coreb.core, NULL, s);
1008 		}
1009 		return true;
1010 	}
1011 	ERR ("esil_bits: missing parameters in stack");
1012 	return false;
1013 }
1014 
esil_interrupt(RAnalEsil * esil)1015 static bool esil_interrupt(RAnalEsil *esil) {
1016 	ut64 interrupt;
1017 	if (popRN (esil, &interrupt)) {
1018 		return r_anal_esil_fire_interrupt (esil, (ut32)interrupt);
1019 	}
1020 	return false;
1021 }
1022 
esil_syscall(RAnalEsil * esil)1023 static bool esil_syscall(RAnalEsil *esil) {
1024 	ut64 sc;
1025 	if (popRN (esil, &sc)) {
1026 		return r_anal_esil_do_syscall (esil, (ut32)sc);
1027 	}
1028 	return false;
1029 }
1030 
1031 // This function also sets internal vars which is used in flag calculations.
esil_cmp(RAnalEsil * esil)1032 static bool esil_cmp(RAnalEsil *esil) {
1033 	ut64 num, num2;
1034 	bool ret = false;
1035 	char *dst = r_anal_esil_pop (esil);
1036 	char *src = r_anal_esil_pop (esil);
1037 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1038 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1039 			esil->old = num;
1040 			esil->cur = num - num2;
1041 			ret = true;
1042 			if (r_reg_get (esil->anal->reg, dst, -1)) {
1043 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1044 			} else if (r_reg_get (esil->anal->reg, src, -1)) {
1045 				esil->lastsz = esil_internal_sizeof_reg (esil, src);
1046 			} else {
1047 				// default size is set to 64 as internally operands are ut64
1048 				esil->lastsz = 64;
1049 			}
1050 		}
1051 	}
1052 	free (dst);
1053 	free (src);
1054 	return ret;
1055 }
1056 
1057 #if 0
1058 x86 documentation:
1059 CF - carry flag -- Set on high-order bit carry or borrow; cleared otherwise
1060 	num>>63
1061 PF - parity flag
1062 	(num&0xff)
1063     Set if low-order eight bits of result contain an even number of "1" bits; cleared otherwise
1064 ZF - zero flags
1065     Set if result is zero; cleared otherwise
1066 	zf = num?0:1;
1067 SF - sign flag
1068     Set equal to high-order bit of result (0 if positive 1 if negative)
1069 	sf = ((st64)num)<0)?1:0;
1070 OF - overflow flag
1071 	if (a>0&&b>0 && (a+b)<0)
1072     Set if result is too large a positive number or too small a negative number (excluding sign bit) to fit in destination operand; cleared otherwise
1073 
1074 JBE: CF = 1 || ZF = 1
1075 
1076 #endif
1077 
1078 /*
1079  * Expects a string in the stack. Each char of the string represents a CPU flag.
1080  * Those relations are associated by the CPU itself and are used to move values
1081  * from the internal ESIL into the RReg instance.
1082  *
1083  * For example:
1084  *   zco,?=     # update zf, cf and of
1085  *
1086  * If we want to update the esil value of a specific flag we use the =? command
1087  *
1088  *    zf,z,=?    # esil[zf] = r_reg[zf]
1089  *
1090  * Defining new cpu flags
1091  */
1092 #if 0
1093 static int esil_ifset(RAnalEsil *esil) {
1094 	char *s, *src = r_anal_esil_pop (esil);
1095 	for (s=src; *s; s++) {
1096 		switch (*s) {
1097 		case 'z':
1098 			r_anal_esil_reg_write (esil, "zf", R_BIT_CHK(&esil->flags, FLG(ZERO)));
1099 			break;
1100 		case 'c':
1101 			r_anal_esil_reg_write (esil, "cf", R_BIT_CHK(&esil->flags, FLG(CARRY)));
1102 			break;
1103 		case 'o':
1104 			r_anal_esil_reg_write (esil, "of", R_BIT_CHK(&esil->flags, FLG(OVERFLOW)));
1105 			break;
1106 		case 'p':
1107 			r_anal_esil_reg_write (esil, "pf", R_BIT_CHK(&esil->flags, FLG(PARITY)));
1108 			break;
1109 		}
1110 	}
1111 	free (src);
1112 	return 0;
1113 }
1114 #endif
1115 
esil_if(RAnalEsil * esil)1116 static bool esil_if(RAnalEsil *esil) {
1117 	ut64 num = 0LL;
1118 	if (esil->skip) {
1119 		esil->skip++;
1120 		return true;
1121 	}
1122 	bool ret = false;
1123 	char *src = r_anal_esil_pop (esil);
1124 	if (src && r_anal_esil_get_parm (esil, src, &num)) {
1125 		// condition not matching, skipping until
1126 		if (!num) {
1127 			esil->skip++;
1128 		}
1129 		ret = true;
1130 	}
1131 	free (src);
1132 	return ret;
1133 }
1134 
esil_lsl(RAnalEsil * esil)1135 static bool esil_lsl(RAnalEsil *esil) {
1136 	bool ret = false;
1137 	ut64 num, num2;
1138 	char *dst = r_anal_esil_pop (esil);
1139 	char *src = r_anal_esil_pop (esil);
1140 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1141 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1142 			if (num2 > sizeof (ut64) * 8) {
1143 				ERR ("esil_lsl: shift is too big");
1144 			} else {
1145 				if (num2 > 63) {
1146 					r_anal_esil_pushnum (esil, 0);
1147 				} else {
1148 					r_anal_esil_pushnum (esil, num << num2);
1149 				}
1150 				ret = true;
1151 			}
1152 		} else {
1153 			ERR ("esil_lsl: empty stack");
1154 		}
1155 	}
1156 	free (src);
1157 	free (dst);
1158 	return ret;
1159 }
1160 
esil_lsleq(RAnalEsil * esil)1161 static bool esil_lsleq(RAnalEsil *esil) {
1162 	bool ret = false;
1163 	ut64 num, num2;
1164 	char *dst = r_anal_esil_pop (esil);
1165 	char *src = r_anal_esil_pop (esil);
1166 	if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
1167 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1168 			if (num2 > sizeof (ut64) * 8) {
1169 				ERR ("esil_lsleq: shift is too big");
1170 			} else {
1171 				esil->old = num;
1172 				if (num2 > 63) {
1173 					num = 0;
1174 				} else {
1175 					num <<= num2;
1176 				}
1177 				esil->cur = num;
1178 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1179 				r_anal_esil_reg_write (esil, dst, num);
1180 				ret = true;
1181 			}
1182 		} else {
1183 			ERR ("esil_lsleq: empty stack");
1184 		}
1185 	}
1186 	free (src);
1187 	free (dst);
1188 	return ret;
1189 }
1190 
esil_lsr(RAnalEsil * esil)1191 static bool esil_lsr(RAnalEsil *esil) {
1192 	bool ret = false;
1193 	ut64 num, num2;
1194 	char *dst = r_anal_esil_pop (esil);
1195 	char *src = r_anal_esil_pop (esil);
1196 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1197 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1198 			ut64 res = num >> R_MIN (num2, 63);
1199 			r_anal_esil_pushnum (esil, res);
1200 			ret = true;
1201 		} else {
1202 			ERR ("esil_lsr: empty stack");
1203 		}
1204 	}
1205 	free (src);
1206 	free (dst);
1207 	return ret;
1208 }
1209 
esil_lsreq(RAnalEsil * esil)1210 static bool esil_lsreq(RAnalEsil *esil) {
1211 	bool ret = false;
1212 	ut64 num, num2;
1213 	char *dst = r_anal_esil_pop (esil);
1214 	char *src = r_anal_esil_pop (esil);
1215 	if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
1216 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1217 			if (num2 > 63) {
1218 				if (esil->verbose) {
1219 					eprintf ("Invalid shift at 0x%08"PFMT64x"\n", esil->address);
1220 				}
1221 				num2 = 63;
1222 			}
1223 			esil->old = num;
1224 			num >>= num2;
1225 			esil->cur = num;
1226 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1227 			r_anal_esil_reg_write (esil, dst, num);
1228 			ret = true;
1229 		} else {
1230 			ERR ("esil_lsreq: empty stack");
1231 		}
1232 	}
1233 	free (src);
1234 	free (dst);
1235 	return ret;
1236 }
1237 
esil_asreq(RAnalEsil * esil)1238 static bool esil_asreq(RAnalEsil *esil) {
1239 	bool ret = false;
1240 	int regsize = 0;
1241 	ut64 op_num, param_num;
1242 	char *op = r_anal_esil_pop (esil);
1243 	char *param = r_anal_esil_pop (esil);
1244 	if (op && r_anal_esil_get_parm_size (esil, op, &op_num, &regsize)) {
1245 		if (param && r_anal_esil_get_parm (esil, param, &param_num)) {
1246 			ut64 mask = (regsize - 1);
1247 			param_num &= mask;
1248 			bool isNegative;
1249 			if (regsize == 32) {
1250 				isNegative = ((st32)op_num)<0;
1251 				st32 snum = op_num;
1252 				op_num = snum;
1253 			} else {
1254 				isNegative = ((st64)op_num)<0;
1255 			}
1256 			if (isNegative) {
1257 				if (regsize == 32) {
1258 					op_num = -(st64)op_num;
1259 					if (op_num >> param_num) {
1260 						op_num >>= param_num;
1261 						op_num = -(st64)op_num;
1262 					} else {
1263 						op_num = -1;
1264 					}
1265 				} else {
1266 					ut64 mask = (regsize - 1);
1267 					param_num &= mask;
1268 					ut64 left_bits = 0;
1269 					int shift = regsize - 1;
1270 					if (shift < 0 || shift > regsize - 1) {
1271 						if (esil->verbose) {
1272 							eprintf ("Invalid asreq shift of %d at 0x%"PFMT64x"\n", shift, esil->address);
1273 						}
1274 						shift = 0;
1275 					}
1276 					if (param_num > regsize - 1) {
1277 						// capstone bug?
1278 						if (esil->verbose) {
1279 							eprintf ("Invalid asreq shift of %"PFMT64d" at 0x%"PFMT64x"\n", param_num, esil->address);
1280 						}
1281 						param_num = 30;
1282 					}
1283 					if (shift >= 63) {
1284 						// LL can't handle LShift of 63 or more
1285 						if (esil->verbose) {
1286 							eprintf ("Invalid asreq shift of %d at 0x%08"PFMT64x"\n", shift, esil->address);
1287 						}
1288 					} else if (op_num & (1LL << shift)) {
1289 						left_bits = (1 << param_num) - 1;
1290 						left_bits <<= regsize - param_num;
1291 					}
1292 					op_num = left_bits | (op_num >> param_num);
1293 				}
1294 			} else {
1295 				op_num >>= param_num;
1296 			}
1297 			ut64 res = op_num;
1298 			esil->cur = res;
1299 			esil->lastsz = esil_internal_sizeof_reg (esil, op);
1300 			r_anal_esil_reg_write (esil, op, res);
1301 			// r_anal_esil_pushnum (esil, res);
1302 			ret = true;
1303 		} else {
1304 			if (esil->verbose) {
1305 				eprintf ("esil_asr: empty stack");
1306 			}
1307 		}
1308 	}
1309 	free (param);
1310 	free (op);
1311 	return ret;
1312 }
1313 
esil_asr(RAnalEsil * esil)1314 static bool esil_asr(RAnalEsil *esil) {
1315 	bool ret = false;
1316 	int regsize = 0;
1317 	ut64 op_num = 0, param_num = 0;
1318 	char *op = r_anal_esil_pop (esil);
1319 	char *param = r_anal_esil_pop (esil);
1320 	if (op && r_anal_esil_get_parm_size (esil, op, &op_num, &regsize)) {
1321 		if (param && r_anal_esil_get_parm (esil, param, &param_num)) {
1322 			if (param_num > regsize - 1) {
1323 				// capstone bug?
1324 				if (esil->verbose) {
1325 					eprintf ("Invalid asr shift of %"PFMT64d" at 0x%"PFMT64x"\n", param_num, esil->address);
1326 				}
1327 				param_num = 30;
1328 			}
1329 			bool isNegative;
1330 			if (regsize == 32) {
1331 				isNegative = ((st32)op_num)<0;
1332 				st32 snum = op_num;
1333 				op_num = snum;
1334 			} else {
1335 				isNegative = ((st64)op_num)<0;
1336 			}
1337 			if (isNegative) {
1338 				ut64 mask = (regsize - 1);
1339 				param_num &= mask;
1340 				ut64 left_bits = 0;
1341 				if (op_num & (1ULL << (regsize - 1))) {
1342 					left_bits = (1ULL << param_num) - 1;
1343 					left_bits <<= regsize - param_num;
1344 				}
1345 				op_num = left_bits | (op_num >> param_num);
1346 			} else {
1347 				op_num >>= param_num;
1348 			}
1349 			ut64 res = op_num;
1350 			r_anal_esil_pushnum (esil, res);
1351 			ret = true;
1352 		} else {
1353 			ERR ("esil_asr: empty stack");
1354 		}
1355 	}
1356 	free (param);
1357 	free (op);
1358 	return ret;
1359 }
1360 
esil_ror(RAnalEsil * esil)1361 static bool esil_ror(RAnalEsil *esil) {
1362 	bool ret = 0;
1363 	int regsize;
1364 	ut64 num, num2;
1365 	char *dst = r_anal_esil_pop (esil);
1366 	char *src = r_anal_esil_pop (esil);
1367 	if (dst && r_anal_esil_get_parm_size (esil, dst, &num, &regsize)) {
1368 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1369 			ut64 mask = (regsize - 1);
1370 			num2 &= mask;
1371 			ut64 res = (num >> num2) | (num << ((-(st64)num2) & mask));
1372 			r_anal_esil_pushnum (esil, res);
1373 			ret = true;
1374 		} else {
1375 			ERR ("esil_ror: empty stack");
1376 		}
1377 	}
1378 	free (src);
1379 	free (dst);
1380 	return ret;
1381 }
1382 
esil_rol(RAnalEsil * esil)1383 static bool esil_rol(RAnalEsil *esil) {
1384 	bool ret = 0;
1385 	int regsize;
1386 	ut64 num, num2;
1387 	char *dst = r_anal_esil_pop (esil);
1388 	char *src = r_anal_esil_pop (esil);
1389 	if (dst && r_anal_esil_get_parm_size (esil, dst, &num, &regsize)) {
1390 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1391 			ut64 mask = (regsize - 1);
1392 			num2 &= mask;
1393 			ut64 res = (num << num2) | (num >> ((-(st64)num2) & mask));
1394 			r_anal_esil_pushnum (esil, res);
1395 			ret = true;
1396 		} else {
1397 			ERR ("esil_rol: empty stack");
1398 		}
1399 	}
1400 	free (src);
1401 	free (dst);
1402 	return ret;
1403 }
1404 
esil_and(RAnalEsil * esil)1405 static bool esil_and(RAnalEsil *esil) {
1406 	bool ret = false;
1407 	ut64 num, num2;
1408 	char *dst = r_anal_esil_pop (esil);
1409 	char *src = r_anal_esil_pop (esil);
1410 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1411 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1412 			num &= num2;
1413 			r_anal_esil_pushnum (esil, num);
1414 			ret = true;
1415 		} else {
1416 			ERR ("esil_and: empty stack");
1417 		}
1418 	}
1419 	free (src);
1420 	free (dst);
1421 	return ret;
1422 }
1423 
esil_xor(RAnalEsil * esil)1424 static bool esil_xor(RAnalEsil *esil) {
1425 	bool ret = false;
1426 	ut64 num, num2;
1427 	char *dst = r_anal_esil_pop (esil);
1428 	char *src = r_anal_esil_pop (esil);
1429 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1430 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1431 			num ^= num2;
1432 			r_anal_esil_pushnum (esil, num);
1433 			ret = true;
1434 		} else {
1435 			ERR ("esil_xor: empty stack");
1436 		}
1437 	}
1438 	free (src);
1439 	free (dst);
1440 	return ret;
1441 }
1442 
esil_or(RAnalEsil * esil)1443 static bool esil_or(RAnalEsil *esil) {
1444 	bool ret = false;
1445 	ut64 num, num2;
1446 	char *dst = r_anal_esil_pop (esil);
1447 	char *src = r_anal_esil_pop (esil);
1448 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1449 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1450 			num |= num2;
1451 			r_anal_esil_pushnum (esil, num);
1452 			ret = true;
1453 		} else {
1454 			ERR ("esil_xor: empty stack");
1455 		}
1456 	}
1457 	free (src);
1458 	free (dst);
1459 	return ret;
1460 }
1461 
r_anal_esil_trapstr(int type)1462 R_API const char *r_anal_esil_trapstr(int type) {
1463 	switch (type) {
1464 	case R_ANAL_TRAP_READ_ERR:
1465 		return "read-err";
1466 	case R_ANAL_TRAP_WRITE_ERR:
1467 		return "write-err";
1468 	case R_ANAL_TRAP_BREAKPOINT:
1469 		return "breakpoint";
1470 	case R_ANAL_TRAP_UNHANDLED:
1471 		return "unhandled";
1472 	case R_ANAL_TRAP_DIVBYZERO:
1473 		return "divbyzero";
1474 	case R_ANAL_TRAP_INVALID:
1475 		return "invalid";
1476 	case R_ANAL_TRAP_UNALIGNED:
1477 		return "unaligned";
1478 	case R_ANAL_TRAP_TODO:
1479 		return "todo";
1480 	default:
1481 		return "unknown";
1482 	}
1483 }
1484 
r_anal_esil_dumpstack(RAnalEsil * esil)1485 R_API bool r_anal_esil_dumpstack(RAnalEsil *esil) {
1486 	r_return_val_if_fail (esil, false);
1487 	int i;
1488 	if (esil->trap) {
1489 		eprintf ("ESIL TRAP type %d code 0x%08x %s\n",
1490 			esil->trap, esil->trap_code,
1491 			r_anal_esil_trapstr (esil->trap));
1492 	}
1493 	if (esil->stackptr < 1) {
1494 		return false;
1495 	}
1496 	for (i = esil->stackptr - 1; i >= 0; i--) {
1497 		esil->anal->cb_printf ("%s\n", esil->stack[i]);
1498 	}
1499 	return true;
1500 }
1501 
esil_break(RAnalEsil * esil)1502 static bool esil_break(RAnalEsil *esil) {
1503 	esil->parse_stop = 1;
1504 	return 1;
1505 }
1506 
esil_clear(RAnalEsil * esil)1507 static bool esil_clear(RAnalEsil *esil) {
1508 	char *r;
1509 	while ((r = r_anal_esil_pop (esil))) {
1510 		free (r);
1511 	}
1512 	return 1;
1513 }
1514 
esil_todo(RAnalEsil * esil)1515 static bool esil_todo(RAnalEsil *esil) {
1516 	esil->parse_stop = 2;
1517 	return 1;
1518 }
1519 
esil_goto(RAnalEsil * esil)1520 static bool esil_goto(RAnalEsil *esil) {
1521 	ut64 num = 0;
1522 	char *src = r_anal_esil_pop (esil);
1523 	if (src && *src && r_anal_esil_get_parm (esil, src, &num)) {
1524 		esil->parse_goto = num;
1525 	}
1526 	free (src);
1527 	return 1;
1528 }
1529 
esil_repeat(RAnalEsil * esil)1530 static bool esil_repeat(RAnalEsil *esil) {
1531 	char *dst = r_anal_esil_pop (esil); // destaintion of the goto
1532 	char *src = r_anal_esil_pop (esil); // value of the counter
1533 	ut64 n, num = 0;
1534 	if (r_anal_esil_get_parm (esil, src, &n) && r_anal_esil_get_parm (esil, dst, &num)) {
1535 		if (n > 1) {
1536 			esil->parse_goto = num;
1537 			r_anal_esil_pushnum (esil, n - 1);
1538 		}
1539 	}
1540 	free (dst);
1541 	free (src);
1542 	return 1;
1543 }
1544 
esil_pop(RAnalEsil * esil)1545 static bool esil_pop(RAnalEsil *esil) {
1546 	char *dst = r_anal_esil_pop (esil);
1547 	free (dst);
1548 	return 1;
1549 }
1550 
esil_mod(RAnalEsil * esil)1551 static bool esil_mod(RAnalEsil *esil) {
1552 	bool ret = false;
1553 	ut64 s, d;
1554 	char *dst = r_anal_esil_pop (esil);
1555 	char *src = r_anal_esil_pop (esil);
1556 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1557 		if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1558 			if (s == 0) {
1559 				if (esil->verbose > 0) {
1560 					eprintf ("0x%08"PFMT64x" esil_mod: Division by zero!\n", esil->address);
1561 				}
1562 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1563 				esil->trap_code = 0;
1564 			} else {
1565 				r_anal_esil_pushnum (esil, d % s);
1566 			}
1567 			ret = true;
1568 		}
1569 	} else {
1570 		ERR ("esil_mod: invalid parameters");
1571 	}
1572 	free (dst);
1573 	free (src);
1574 	return ret;
1575 }
1576 
esil_signed_mod(RAnalEsil * esil)1577 static bool esil_signed_mod(RAnalEsil *esil) {
1578 	bool ret = false;
1579 	st64 s, d;
1580 	char *dst = r_anal_esil_pop (esil);
1581 	char *src = r_anal_esil_pop (esil);
1582 	if (src && r_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
1583 		if (dst && r_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
1584 			if (ST64_DIV_OVFCHK (d, s)) {
1585 				if (esil->verbose > 0) {
1586 					eprintf ("0x%08"PFMT64x" esil_mod: Division by zero!\n", esil->address);
1587 				}
1588 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1589 				esil->trap_code = 0;
1590 			} else {
1591 				r_anal_esil_pushnum (esil, d % s);
1592 			}
1593 			ret = true;
1594 		}
1595 	} else {
1596 		ERR ("esil_mod: invalid parameters");
1597 	}
1598 	free (dst);
1599 	free (src);
1600 	return ret;
1601 }
1602 
esil_modeq(RAnalEsil * esil)1603 static bool esil_modeq(RAnalEsil *esil) {
1604 	bool ret = false;
1605 	ut64 s, d;
1606 	char *dst = r_anal_esil_pop (esil);
1607 	char *src = r_anal_esil_pop (esil);
1608 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1609 		if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1610 			if (s) {
1611 				esil->old = d;
1612 				esil->cur = d % s;
1613 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1614 				r_anal_esil_reg_write (esil, dst, d % s);
1615 			} else {
1616 				ERR ("esil_modeq: Division by zero!");
1617 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1618 				esil->trap_code = 0;
1619 			}
1620 			ret = true;
1621 		} else {
1622 			ERR ("esil_modeq: empty stack");
1623 		}
1624 	} else {
1625 		ERR ("esil_modeq: invalid parameters");
1626 	}
1627 	free (src);
1628 	free (dst);
1629 	return ret;
1630 }
1631 
esil_div(RAnalEsil * esil)1632 static bool esil_div(RAnalEsil *esil) {
1633 	bool ret = false;
1634 	ut64 s, d;
1635 	char *dst = r_anal_esil_pop (esil);
1636 	char *src = r_anal_esil_pop (esil);
1637 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1638 		if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1639 			if (s == 0) {
1640 				ERR ("esil_div: Division by zero!");
1641 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1642 				esil->trap_code = 0;
1643 			} else {
1644 				r_anal_esil_pushnum (esil, d / s);
1645 			}
1646 			ret = true;
1647 		}
1648 	} else {
1649 		ERR ("esil_div: invalid parameters");
1650 	}
1651 	free (src);
1652 	free (dst);
1653 	return ret;
1654 }
1655 
esil_signed_div(RAnalEsil * esil)1656 static bool esil_signed_div(RAnalEsil *esil) {
1657 	bool ret = false;
1658 	st64 s, d;
1659 	char *dst = r_anal_esil_pop (esil);
1660 	char *src = r_anal_esil_pop (esil);
1661 	if (src && r_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
1662 		if (dst && r_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
1663 			if (ST64_DIV_OVFCHK (d, s)) {
1664 				ERR ("esil_div: Division by zero!");
1665 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1666 				esil->trap_code = 0;
1667 			} else {
1668 				r_anal_esil_pushnum (esil, d / s);
1669 			}
1670 			ret = true;
1671 		}
1672 	} else {
1673 		ERR ("esil_div: invalid parameters");
1674 	}
1675 	free (src);
1676 	free (dst);
1677 	return ret;
1678 }
1679 
esil_diveq(RAnalEsil * esil)1680 static bool esil_diveq(RAnalEsil *esil) {
1681 	bool ret = false;
1682 	ut64 s, d;
1683 	char *dst = r_anal_esil_pop (esil);
1684 	char *src = r_anal_esil_pop (esil);
1685 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1686 		if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1687 			if (s) {
1688 				esil->old = d;
1689 				esil->cur = d / s;
1690 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1691 				r_anal_esil_reg_write (esil, dst, d / s);
1692 			} else {
1693 				// eprintf ("0x%08"PFMT64x" esil_diveq: Division by zero!\n", esil->address);
1694 				esil->trap = R_ANAL_TRAP_DIVBYZERO;
1695 				esil->trap_code = 0;
1696 			}
1697 			ret = true;
1698 		} else {
1699 			ERR ("esil_diveq: empty stack");
1700 		}
1701 	} else {
1702 		ERR ("esil_diveq: invalid parameters");
1703 	}
1704 	free (src);
1705 	free (dst);
1706 	return ret;
1707 }
1708 
1709 // 128 bit multiplication result
mult64to128(ut64 op1,ut64 op2,ut64 * hi,ut64 * lo)1710 static void mult64to128(ut64 op1, ut64 op2, ut64 *hi, ut64 *lo) {
1711     ut64 u1 = (op1 & 0xffffffff);
1712     ut64 v1 = (op2 & 0xffffffff);
1713     ut64 t = (u1 * v1);
1714     ut64 w3 = (t & 0xffffffff);
1715     ut64 k = (t >> 32);
1716 
1717     op1 >>= 32;
1718     t = (op1 * v1) + k;
1719     k = (t & 0xffffffff);
1720     ut64 w1 = (t >> 32);
1721 
1722     op2 >>= 32;
1723     t = (u1 * op2) + k;
1724     k = (t >> 32);
1725 
1726     *hi = (op1 * op2) + w1 + k;
1727     *lo = (t << 32) + w3;
1728 }
1729 
esil_long_mul(RAnalEsil * esil)1730 static bool esil_long_mul(RAnalEsil *esil) {
1731 	bool ret = false;
1732 	ut64 s, d;
1733 	ut64 hi, lo;
1734 	char *dst = r_anal_esil_pop (esil);
1735 	char *src = r_anal_esil_pop (esil);
1736 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1737 		if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1738 			mult64to128(s, d, &hi, &lo);
1739 			r_anal_esil_pushnum (esil, hi);
1740 			r_anal_esil_pushnum (esil, lo);
1741 			ret = true;
1742 		} else {
1743 			ERR ("esil_long_mul: empty stack");
1744 		}
1745 	} else {
1746 		ERR ("esil_long_mul: invalid parameters");
1747 	}
1748 	free (src);
1749 	free (dst);
1750 	return ret;
1751 }
1752 
esil_mul(RAnalEsil * esil)1753 static bool esil_mul(RAnalEsil *esil) {
1754 	bool ret = false;
1755 	ut64 s, d;
1756 	char *dst = r_anal_esil_pop (esil);
1757 	char *src = r_anal_esil_pop (esil);
1758 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1759 		if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1760 			r_anal_esil_pushnum (esil, d * s);
1761 			ret = true;
1762 		} else {
1763 			ERR ("esil_mul: empty stack");
1764 		}
1765 	} else {
1766 		ERR ("esil_mul: invalid parameters");
1767 	}
1768 	free (src);
1769 	free (dst);
1770 	return ret;
1771 }
1772 
esil_muleq(RAnalEsil * esil)1773 static bool esil_muleq(RAnalEsil *esil) {
1774 	bool ret = false;
1775 	ut64 s, d;
1776 	char *dst = r_anal_esil_pop (esil);
1777 	char *src = r_anal_esil_pop (esil);
1778 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1779 		if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1780 			esil->old = d;
1781 			esil->cur = d * s;
1782 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1783 			ret = r_anal_esil_reg_write (esil, dst, s * d);
1784 		} else {
1785 			ERR ("esil_muleq: empty stack");
1786 		}
1787 	} else {
1788 		ERR ("esil_muleq: invalid parameters");
1789 	}
1790 	free (dst);
1791 	free (src);
1792 	return ret;
1793 }
1794 
esil_add(RAnalEsil * esil)1795 static bool esil_add(RAnalEsil *esil) {
1796 	bool ret = false;
1797 	ut64 s, d;
1798 	char *dst = r_anal_esil_pop (esil);
1799 	char *src = r_anal_esil_pop (esil);
1800 	if ((src && r_anal_esil_get_parm (esil, src, &s)) && (dst && r_anal_esil_get_parm (esil, dst, &d))) {
1801 		r_anal_esil_pushnum (esil, s + d);
1802 		ret = true;
1803 	} else {
1804 		ERR ("esil_add: invalid parameters");
1805 	}
1806 	free (src);
1807 	free (dst);
1808 	return ret;
1809 }
1810 
esil_addeq(RAnalEsil * esil)1811 static bool esil_addeq(RAnalEsil *esil) {
1812 	bool ret = false;
1813 	ut64 s, d;
1814 	char *dst = r_anal_esil_pop (esil);
1815 	char *src = r_anal_esil_pop (esil);
1816 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1817 		if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1818 			esil->old = d;
1819 			esil->cur = d + s;
1820 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1821 			ret = r_anal_esil_reg_write (esil, dst, s + d);
1822 		}
1823 	} else {
1824 		ERR ("esil_addeq: invalid parameters");
1825 	}
1826 	free (src);
1827 	free (dst);
1828 	return ret;
1829 }
1830 
esil_inc(RAnalEsil * esil)1831 static bool esil_inc(RAnalEsil *esil) {
1832 	bool ret = false;
1833 	ut64 s;
1834 	char *src = r_anal_esil_pop (esil);
1835 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1836 		s++;
1837 		ret = r_anal_esil_pushnum (esil, s);
1838 	} else {
1839 		ERR ("esil_inc: invalid parameters");
1840 	}
1841 	free (src);
1842 	return ret;
1843 }
1844 
esil_inceq(RAnalEsil * esil)1845 static bool esil_inceq(RAnalEsil *esil) {
1846 	bool ret = false;
1847 	ut64 sd;
1848 	char *src_dst = r_anal_esil_pop (esil);
1849 	if (src_dst && (r_anal_esil_get_parm_type (esil, src_dst) == R_ANAL_ESIL_PARM_REG) && r_anal_esil_get_parm (esil, src_dst, &sd)) {
1850 		// inc rax
1851 		esil->old = sd++;
1852 		esil->cur = sd;
1853 		r_anal_esil_reg_write (esil, src_dst, sd);
1854 		esil->lastsz = esil_internal_sizeof_reg (esil, src_dst);
1855 		ret = true;
1856 	} else {
1857 		ERR ("esil_inceq: invalid parameters");
1858 	}
1859 	free (src_dst);
1860 	return ret;
1861 }
1862 
esil_sub(RAnalEsil * esil)1863 static bool esil_sub(RAnalEsil *esil) {
1864 	bool ret = false;
1865 	ut64 s, d;
1866 	char *dst = r_anal_esil_pop (esil);
1867 	char *src = r_anal_esil_pop (esil);
1868 	if ((src && r_anal_esil_get_parm (esil, src, &s)) && (dst && r_anal_esil_get_parm (esil, dst, &d))) {
1869 		ret = r_anal_esil_pushnum (esil, d - s);
1870 	} else {
1871 		ERR ("esil_sub: invalid parameters");
1872 	}
1873 	free (src);
1874 	free (dst);
1875 	return ret;
1876 }
1877 
esil_subeq(RAnalEsil * esil)1878 static bool esil_subeq(RAnalEsil *esil) {
1879 	bool ret = false;
1880 	ut64 s, d;
1881 	char *dst = r_anal_esil_pop (esil);
1882 	char *src = r_anal_esil_pop (esil);
1883 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1884 		if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1885 			esil->old = d;
1886 			esil->cur = d - s;
1887 			esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1888 			ret = r_anal_esil_reg_write (esil, dst, d - s);
1889 		}
1890 	} else {
1891 		ERR ("esil_subeq: invalid parameters");
1892 	}
1893 	free (src);
1894 	free (dst);
1895 	return ret;
1896 }
1897 
esil_dec(RAnalEsil * esil)1898 static bool esil_dec(RAnalEsil *esil) {
1899 	bool ret = false;
1900 	ut64 s;
1901 	char *src = r_anal_esil_pop (esil);
1902 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
1903 		s--;
1904 		ret = r_anal_esil_pushnum (esil, s);
1905 	} else {
1906 		ERR ("esil_dec: invalid parameters");
1907 	}
1908 	free (src);
1909 	return ret;
1910 }
1911 
esil_deceq(RAnalEsil * esil)1912 static bool esil_deceq(RAnalEsil *esil) {
1913 	bool ret = false;
1914 	ut64 sd;
1915 	char *src_dst = r_anal_esil_pop (esil);
1916 	if (src_dst && (r_anal_esil_get_parm_type (esil, src_dst) == R_ANAL_ESIL_PARM_REG) && r_anal_esil_get_parm (esil, src_dst, &sd)) {
1917 		esil->old = sd;
1918 		sd--;
1919 		esil->cur = sd;
1920 		r_anal_esil_reg_write (esil, src_dst, sd);
1921 		esil->lastsz = esil_internal_sizeof_reg (esil, src_dst);
1922 		ret = true;
1923 	} else {
1924 		ERR ("esil_deceq: invalid parameters");
1925 	}
1926 	free (src_dst);
1927 	return ret;
1928 }
1929 
1930 /* POKE */
esil_poke_n(RAnalEsil * esil,int bits)1931 static bool esil_poke_n(RAnalEsil *esil, int bits) {
1932 	ut64 bitmask = genmask (bits - 1);
1933 	ut64 num, num2, addr;
1934 	ut8 b[8] = {0};
1935 	ut64 n;
1936 	char *dst = r_anal_esil_pop (esil);
1937 	char *src = r_anal_esil_pop (esil);
1938 	int bytes = R_MIN (sizeof (b), bits / 8);
1939 	if (bits % 8) {
1940 		free (src);
1941 		free (dst);
1942 		return false;
1943 	}
1944 	bool ret = false;
1945 	//eprintf ("GONA POKE %d src:%s dst:%s\n", bits, src, dst);
1946 	char *src2 = NULL;
1947 	if (src && r_anal_esil_get_parm (esil, src, &num)) {
1948 		if (dst && r_anal_esil_get_parm (esil, dst, &addr)) {
1949 			if (bits == 128) {
1950 				src2 = r_anal_esil_pop (esil);
1951 				if (src2 && r_anal_esil_get_parm (esil, src2, &num2)) {
1952 					r_write_ble (b, num, esil->anal->big_endian, 64);
1953 					ret = r_anal_esil_mem_write (esil, addr, b, bytes);
1954 					if (ret == 0) {
1955 						r_write_ble (b, num2, esil->anal->big_endian, 64);
1956 						ret = r_anal_esil_mem_write (esil, addr + 8, b, bytes);
1957 					}
1958 					goto out;
1959 				}
1960 				ret = 0;
1961 				goto out;
1962 			}
1963 			// this is a internal peek performed before a poke
1964 			// we disable hooks to avoid run hooks on internal peeks
1965 			void * oldhook = (void*)esil->cb.hook_mem_read;
1966 			esil->cb.hook_mem_read = NULL;
1967 			r_anal_esil_mem_read (esil, addr, b, bytes);
1968 			esil->cb.hook_mem_read = oldhook;
1969 			n = r_read_ble64 (b, esil->anal->big_endian);
1970 			esil->old = n;
1971 			esil->cur = num;
1972 			esil->lastsz = bits;
1973 			num = num & bitmask;
1974 			r_write_ble (b, num, esil->anal->big_endian, bits);
1975 			ret = r_anal_esil_mem_write (esil, addr, b, bytes);
1976 		}
1977 	}
1978 out:
1979 	free (src2);
1980 	free (src);
1981 	free (dst);
1982 	return ret;
1983 }
1984 
esil_poke1(RAnalEsil * esil)1985 static bool esil_poke1(RAnalEsil *esil) {
1986 	return esil_poke_n (esil, 8);
1987 }
1988 
esil_poke2(RAnalEsil * esil)1989 static bool esil_poke2(RAnalEsil *esil) {
1990 	return esil_poke_n (esil, 16);
1991 }
1992 
esil_poke3(RAnalEsil * esil)1993 static bool esil_poke3(RAnalEsil *esil) {
1994 	return esil_poke_n (esil, 24);
1995 }
1996 
esil_poke4(RAnalEsil * esil)1997 static bool esil_poke4(RAnalEsil *esil) {
1998 	return esil_poke_n (esil, 32);
1999 }
2000 
esil_poke8(RAnalEsil * esil)2001 static bool esil_poke8(RAnalEsil *esil) {
2002 	return esil_poke_n (esil, 64);
2003 }
2004 
esil_poke16(RAnalEsil * esil)2005 static bool esil_poke16(RAnalEsil *esil) {
2006 	return esil_poke_n (esil, 128);
2007 }
2008 
esil_poke(RAnalEsil * esil)2009 static bool esil_poke(RAnalEsil *esil) {
2010 	return esil_poke_n (esil, esil->anal->bits);
2011 }
2012 
esil_poke_some(RAnalEsil * esil)2013 static bool esil_poke_some(RAnalEsil *esil) {
2014 	bool ret = false;
2015 	int i, regsize;
2016 	ut64 ptr, regs = 0, tmp;
2017 	char *count, *dst = r_anal_esil_pop (esil);
2018 
2019 	if (dst && r_anal_esil_get_parm_size (esil, dst, &tmp, &regsize)) {
2020 		// reg
2021 		isregornum (esil, dst, &ptr);
2022 		count = r_anal_esil_pop (esil);
2023 		if (count) {
2024 			isregornum (esil, count, &regs);
2025 			if (regs > 0) {
2026 				ut8 b[8] = {0};
2027 				ut64 num64;
2028 				for (i = 0; i < regs; i++) {
2029 					char *foo = r_anal_esil_pop (esil);
2030 					if (!foo) {
2031 						// avoid looping out of stack
2032 						free (dst);
2033 						free (count);
2034 						return true;
2035 					}
2036 					r_anal_esil_get_parm_size (esil, foo, &tmp, &regsize);
2037 					isregornum (esil, foo, &num64);
2038 					r_write_ble (b, num64, esil->anal->big_endian, regsize);
2039 					const int size_bytes = regsize / 8;
2040 					const ut32 written = r_anal_esil_mem_write (esil, ptr, b, size_bytes);
2041 					if (written != size_bytes) {
2042 						//eprintf ("Cannot write at 0x%08" PFMT64x "\n", ptr);
2043 						esil->trap = 1;
2044 					}
2045 					ptr += size_bytes;
2046 					free (foo);
2047 				}
2048 			}
2049 			free (dst);
2050 			free (count);
2051 			return ret;
2052 		}
2053 		free (dst);
2054 	}
2055 	return false;
2056 }
2057 
2058 /* PEEK */
2059 
esil_peek_n(RAnalEsil * esil,int bits)2060 static bool esil_peek_n(RAnalEsil *esil, int bits) {
2061 	if (bits & 7) {
2062 		return false;
2063 	}
2064 	bool ret = false;
2065 	char res[32];
2066 	ut64 addr;
2067 	ut32 bytes = bits / 8;
2068 	char *dst = r_anal_esil_pop (esil);
2069 	if (!dst) {
2070 		eprintf ("ESIL-ERROR at 0x%08"PFMT64x": Cannot peek memory without specifying an address\n", esil->address);
2071 		return false;
2072 	}
2073 	//eprintf ("GONA PEEK %d dst:%s\n", bits, dst);
2074 	if (dst && isregornum (esil, dst, &addr)) {
2075 		if (bits == 128) {
2076 			ut8 a[sizeof(ut64) * 2] = {0};
2077 			ret = r_anal_esil_mem_read (esil, addr, a, bytes);
2078 			ut64 b = r_read_ble64 (&a, 0); //esil->anal->big_endian);
2079 			ut64 c = r_read_ble64 (&a[8], 0); //esil->anal->big_endian);
2080 			snprintf (res, sizeof (res), "0x%" PFMT64x, b);
2081 			r_anal_esil_push (esil, res);
2082 			snprintf (res, sizeof (res), "0x%" PFMT64x, c);
2083 			r_anal_esil_push (esil, res);
2084 			free (dst);
2085 			return ret;
2086 		}
2087 		ut64 bitmask = genmask (bits - 1);
2088 		ut8 a[sizeof(ut64)] = {0};
2089 		ret = !!r_anal_esil_mem_read (esil, addr, a, bytes);
2090 		ut64 b = r_read_ble64 (a, 0); //esil->anal->big_endian);
2091 		if (esil->anal->big_endian) {
2092 			r_mem_swapendian ((ut8*)&b, (const ut8*)&b, bytes);
2093 		}
2094 		snprintf (res, sizeof (res), "0x%" PFMT64x, b & bitmask);
2095 		r_anal_esil_push (esil, res);
2096 		esil->lastsz = bits;
2097 	}
2098 	free (dst);
2099 	return ret;
2100 }
2101 
esil_peek1(RAnalEsil * esil)2102 static bool esil_peek1(RAnalEsil *esil) {
2103 	return esil_peek_n (esil, 8);
2104 }
2105 
esil_peek2(RAnalEsil * esil)2106 static bool esil_peek2(RAnalEsil *esil) {
2107 	return esil_peek_n (esil, 16);
2108 }
2109 
esil_peek3(RAnalEsil * esil)2110 static bool esil_peek3(RAnalEsil *esil) {
2111 	return esil_peek_n (esil, 24);
2112 }
2113 
esil_peek4(RAnalEsil * esil)2114 static bool esil_peek4(RAnalEsil *esil) {
2115 	return esil_peek_n (esil, 32);
2116 }
2117 
esil_peek8(RAnalEsil * esil)2118 static bool esil_peek8(RAnalEsil *esil) {
2119 	return esil_peek_n (esil, 64);
2120 }
2121 
esil_peek16(RAnalEsil * esil)2122 static bool esil_peek16(RAnalEsil *esil) {
2123 	// packed only
2124 	return esil_peek_n (esil, 128);
2125 }
2126 
esil_peek(RAnalEsil * esil)2127 static bool esil_peek(RAnalEsil *esil) {
2128 	return esil_peek_n (esil, esil->anal->bits);
2129 };
2130 
esil_peek_some(RAnalEsil * esil)2131 static bool esil_peek_some(RAnalEsil *esil) {
2132 	int i;
2133 	ut64 ptr, regs;
2134 	// pop ptr
2135 	char *count, *dst = r_anal_esil_pop (esil);
2136 	if (dst) {
2137 		// reg
2138 		isregornum (esil, dst, &ptr);
2139 		count = r_anal_esil_pop (esil);
2140 		if (count) {
2141 			isregornum (esil, count, &regs);
2142 			if (regs > 0) {
2143 				ut32 num32;
2144 				ut8 a[4];
2145 				for (i = 0; i < regs; i++) {
2146 					char *foo = r_anal_esil_pop (esil);
2147 					if (!foo) {
2148 						ERR ("Cannot pop in peek");
2149 						free (dst);
2150 						free (count);
2151 						return 0;
2152 					}
2153 					const ut32 read = r_anal_esil_mem_read (esil, ptr, a, 4);
2154 					if (read == 4) {	//this is highly questionabla
2155 						num32 = r_read_ble32 (a, esil->anal->big_endian);
2156 						r_anal_esil_reg_write (esil, foo, num32);
2157 					} else {
2158 						if (esil->verbose) {
2159 							eprintf ("Cannot peek from 0x%08" PFMT64x "\n", ptr);
2160 						}
2161 					}
2162 					ptr += 4;
2163 					free (foo);
2164 				}
2165 			}
2166 			free (dst);
2167 			free (count);
2168 			return 1;
2169 		}
2170 		free (dst);
2171 	}
2172 	return 0;
2173 }
2174 
2175 /* OREQ */
2176 
esil_mem_oreq_n(RAnalEsil * esil,int bits)2177 static bool esil_mem_oreq_n(RAnalEsil *esil, int bits) {
2178 	bool ret = false;
2179 	ut64 s, d;
2180 	char *dst = r_anal_esil_pop (esil);  //save the dst-addr
2181 	char *src0 = r_anal_esil_pop (esil); //get the src
2182 	char *src1 = NULL;
2183 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) { 	//get the src
2184 		r_anal_esil_push (esil, dst);			//push the dst-addr
2185 		ret = (!!esil_peek_n (esil, bits));		//read
2186 		src1 = r_anal_esil_pop (esil);			//get the old dst-value
2187 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) { //get the old dst-value
2188 			d |= s;					//calculate the new dst-value
2189 			r_anal_esil_pushnum (esil, d);		//push the new dst-value
2190 			r_anal_esil_push (esil, dst);		//push the dst-addr
2191 			ret &= (!!esil_poke_n (esil, bits));	//write
2192 		} else {
2193 			ret = false;
2194 		}
2195 	}
2196 	if (!ret) {
2197 		ERR ("esil_mem_oreq_n: invalid parameters");
2198 	}
2199 	free (dst);
2200 	free (src0);
2201 	free (src1);
2202 	return ret;
2203 }
2204 
esil_mem_oreq1(RAnalEsil * esil)2205 static bool esil_mem_oreq1(RAnalEsil *esil) {
2206 	return esil_mem_oreq_n (esil, 8);
2207 }
esil_mem_oreq2(RAnalEsil * esil)2208 static bool esil_mem_oreq2(RAnalEsil *esil) {
2209 	return esil_mem_oreq_n (esil, 16);
2210 }
esil_mem_oreq4(RAnalEsil * esil)2211 static bool esil_mem_oreq4(RAnalEsil *esil) {
2212 	return esil_mem_oreq_n (esil, 32);
2213 }
esil_mem_oreq8(RAnalEsil * esil)2214 static bool esil_mem_oreq8(RAnalEsil *esil) {
2215 	return esil_mem_oreq_n (esil, 64);
2216 }
esil_mem_oreq(RAnalEsil * esil)2217 static bool esil_mem_oreq(RAnalEsil *esil) {
2218 	return esil_mem_oreq_n (esil, esil->anal->bits);
2219 }
2220 
2221 /* XOREQ */
2222 
esil_mem_xoreq_n(RAnalEsil * esil,int bits)2223 static bool esil_mem_xoreq_n(RAnalEsil *esil, int bits) {
2224 	bool ret = false;
2225 	ut64 s, d;
2226 	char *dst = r_anal_esil_pop (esil);
2227 	char *src0 = r_anal_esil_pop (esil);
2228 	char *src1 = NULL;
2229 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2230 		r_anal_esil_push (esil, dst);
2231 		ret = (!!esil_peek_n (esil, bits));
2232 		src1 = r_anal_esil_pop (esil);
2233 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2234 			d ^= s;
2235 			r_anal_esil_pushnum (esil, d);
2236 			r_anal_esil_push (esil, dst);
2237 			ret &= (!!esil_poke_n (esil, bits));
2238 		} else {
2239 			ret = false;
2240 		}
2241 	}
2242 	if (!ret) {
2243 		ERR ("esil_mem_xoreq_n: invalid parameters");
2244 	}
2245 	free (dst);
2246 	free (src0);
2247 	free (src1);
2248 	return ret;
2249 }
2250 
esil_mem_xoreq1(RAnalEsil * esil)2251 static bool esil_mem_xoreq1(RAnalEsil *esil) {
2252 	return esil_mem_xoreq_n (esil, 8);
2253 }
esil_mem_xoreq2(RAnalEsil * esil)2254 static bool esil_mem_xoreq2(RAnalEsil *esil) {
2255 	return esil_mem_xoreq_n (esil, 16);
2256 }
esil_mem_xoreq4(RAnalEsil * esil)2257 static bool esil_mem_xoreq4(RAnalEsil *esil) {
2258 	return esil_mem_xoreq_n (esil, 32);
2259 }
esil_mem_xoreq8(RAnalEsil * esil)2260 static bool esil_mem_xoreq8(RAnalEsil *esil) {
2261 	return esil_mem_xoreq_n (esil, 64);
2262 }
esil_mem_xoreq(RAnalEsil * esil)2263 static bool esil_mem_xoreq(RAnalEsil *esil) {
2264 	return esil_mem_xoreq_n (esil, esil->anal->bits);
2265 }
2266 
2267 /* ANDEQ */
2268 
esil_mem_andeq_n(RAnalEsil * esil,int bits)2269 static bool esil_mem_andeq_n(RAnalEsil *esil, int bits) {
2270 	bool ret = false;
2271 	ut64 s, d;
2272 	char *dst = r_anal_esil_pop (esil);
2273 	char *src0 = r_anal_esil_pop (esil);
2274 	char *src1 = NULL;
2275 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2276 		r_anal_esil_push (esil, dst);
2277 		ret = (!!esil_peek_n (esil, bits));
2278 		src1 = r_anal_esil_pop (esil);
2279 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2280 			d &= s;
2281 			r_anal_esil_pushnum (esil, d);
2282 			r_anal_esil_push (esil, dst);
2283 			ret &= (!!esil_poke_n (esil, bits));
2284 		} else {
2285 			ret = false;
2286 		}
2287 	}
2288 	if (!ret) {
2289 		ERR ("esil_mem_andeq_n: invalid parameters");
2290 	}
2291 	free (dst);
2292 	free (src0);
2293 	free (src1);
2294 	return ret;
2295 }
2296 
esil_mem_andeq1(RAnalEsil * esil)2297 static bool esil_mem_andeq1(RAnalEsil *esil) {
2298 	return esil_mem_andeq_n (esil, 8);
2299 }
esil_mem_andeq2(RAnalEsil * esil)2300 static bool esil_mem_andeq2(RAnalEsil *esil) {
2301 	return esil_mem_andeq_n (esil, 16);
2302 }
esil_mem_andeq4(RAnalEsil * esil)2303 static bool esil_mem_andeq4(RAnalEsil *esil) {
2304 	return esil_mem_andeq_n (esil, 32);
2305 }
esil_mem_andeq8(RAnalEsil * esil)2306 static bool esil_mem_andeq8(RAnalEsil *esil) {
2307 	return esil_mem_andeq_n (esil, 64);
2308 }
esil_mem_andeq(RAnalEsil * esil)2309 static bool esil_mem_andeq(RAnalEsil *esil) {
2310 	return esil_mem_andeq_n (esil, esil->anal->bits);
2311 }
2312 
2313 /* ADDEQ */
2314 
esil_mem_addeq_n(RAnalEsil * esil,int bits)2315 static bool esil_mem_addeq_n(RAnalEsil *esil, int bits) {
2316 	bool ret = false;
2317 	ut64 s, d;
2318 	char *dst = r_anal_esil_pop (esil);
2319 	char *src0 = r_anal_esil_pop (esil);
2320 	char *src1 = NULL;
2321 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2322 		r_anal_esil_push (esil, dst);
2323 		ret = (!!esil_peek_n (esil, bits));
2324 		src1 = r_anal_esil_pop (esil);
2325 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2326 			d += s;
2327 			r_anal_esil_pushnum (esil, d);
2328 			r_anal_esil_push (esil, dst);
2329 			ret &= (!!esil_poke_n (esil, bits));
2330 		} else {
2331 			ret = false;
2332 		}
2333 	}
2334 	if (!ret) {
2335 		ERR ("esil_mem_addeq_n: invalid parameters");
2336 	}
2337 	free (dst);
2338 	free (src0);
2339 	free (src1);
2340 	return ret;
2341 }
2342 
esil_mem_addeq1(RAnalEsil * esil)2343 static bool esil_mem_addeq1(RAnalEsil *esil) {
2344 	return esil_mem_addeq_n (esil, 8);
2345 }
esil_mem_addeq2(RAnalEsil * esil)2346 static bool esil_mem_addeq2(RAnalEsil *esil) {
2347 	return esil_mem_addeq_n (esil, 16);
2348 }
esil_mem_addeq4(RAnalEsil * esil)2349 static bool esil_mem_addeq4(RAnalEsil *esil) {
2350 	return esil_mem_addeq_n (esil, 32);
2351 }
esil_mem_addeq8(RAnalEsil * esil)2352 static bool esil_mem_addeq8(RAnalEsil *esil) {
2353 	return esil_mem_addeq_n (esil, 64);
2354 }
esil_mem_addeq(RAnalEsil * esil)2355 static bool esil_mem_addeq(RAnalEsil *esil) {
2356 	return esil_mem_addeq_n (esil, esil->anal->bits);
2357 }
2358 
2359 /* SUBEQ */
2360 
esil_mem_subeq_n(RAnalEsil * esil,int bits)2361 static bool esil_mem_subeq_n(RAnalEsil *esil, int bits) {
2362 	bool ret = false;
2363 	ut64 s, d;
2364 	char *dst = r_anal_esil_pop (esil);
2365 	char *src0 = r_anal_esil_pop (esil);
2366 	char *src1 = NULL;
2367 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2368 		r_anal_esil_push (esil, dst);
2369 		ret = (!!esil_peek_n (esil, bits));
2370 		src1 = r_anal_esil_pop (esil);
2371 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2372 			d -= s;
2373 			r_anal_esil_pushnum (esil, d);
2374 			r_anal_esil_push (esil, dst);
2375 			ret &= (!!esil_poke_n (esil, bits));
2376 		} else {
2377 			ret = false;
2378 		}
2379 	}
2380 	if (!ret) {
2381 		ERR ("esil_mem_subeq_n: invalid parameters");
2382 	}
2383 	free (dst);
2384 	free (src0);
2385 	free (src1);
2386 	return ret;
2387 }
2388 
esil_mem_subeq1(RAnalEsil * esil)2389 static bool esil_mem_subeq1(RAnalEsil *esil) {
2390 	return esil_mem_subeq_n (esil, 8);
2391 }
esil_mem_subeq2(RAnalEsil * esil)2392 static bool esil_mem_subeq2(RAnalEsil *esil) {
2393 	return esil_mem_subeq_n (esil, 16);
2394 }
esil_mem_subeq4(RAnalEsil * esil)2395 static bool esil_mem_subeq4(RAnalEsil *esil) {
2396 	return esil_mem_subeq_n (esil, 32);
2397 }
esil_mem_subeq8(RAnalEsil * esil)2398 static bool esil_mem_subeq8(RAnalEsil *esil) {
2399 	return esil_mem_subeq_n (esil, 64);
2400 }
esil_mem_subeq(RAnalEsil * esil)2401 static bool esil_mem_subeq(RAnalEsil *esil) {
2402 	return esil_mem_subeq_n (esil, esil->anal->bits);
2403 }
2404 
2405 /* MODEQ */
2406 
esil_mem_modeq_n(RAnalEsil * esil,int bits)2407 static bool esil_mem_modeq_n(RAnalEsil *esil, int bits) {
2408 	bool ret = false;
2409 	ut64 s, d;
2410 	char *dst = r_anal_esil_pop (esil);
2411 	char *src0 = r_anal_esil_pop (esil);
2412 	char *src1 = NULL;
2413 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2414 		if (s == 0) {
2415 			ERR ("esil_mem_modeq4: Division by zero!");
2416 			esil->trap = R_ANAL_TRAP_DIVBYZERO;
2417 			esil->trap_code = 0;
2418 		} else {
2419 			r_anal_esil_push (esil, dst);
2420 			ret = (!!esil_peek_n (esil, bits));
2421 			src1 = r_anal_esil_pop (esil);
2422 			if (src1 && r_anal_esil_get_parm (esil, src1, &d) && s >= 1) {
2423 				r_anal_esil_pushnum (esil, d % s);
2424 				d = d % s;
2425 				r_anal_esil_pushnum (esil, d);
2426 				r_anal_esil_push (esil, dst);
2427 				ret &= (!!esil_poke_n (esil, bits));
2428 			} else {
2429 				ret = false;
2430 			}
2431 		}
2432 	}
2433 	if (!ret) {
2434 		ERR ("esil_mem_modeq_n: invalid parameters");
2435 	}
2436 	free (dst);
2437 	free (src0);
2438 	free (src1);
2439 	return ret;
2440 }
2441 
esil_mem_modeq1(RAnalEsil * esil)2442 static bool esil_mem_modeq1(RAnalEsil *esil) {
2443 	return esil_mem_modeq_n (esil, 8);
2444 }
esil_mem_modeq2(RAnalEsil * esil)2445 static bool esil_mem_modeq2(RAnalEsil *esil) {
2446 	return esil_mem_modeq_n (esil, 16);
2447 }
esil_mem_modeq4(RAnalEsil * esil)2448 static bool esil_mem_modeq4(RAnalEsil *esil) {
2449 	return esil_mem_modeq_n (esil, 32);
2450 }
esil_mem_modeq8(RAnalEsil * esil)2451 static bool esil_mem_modeq8(RAnalEsil *esil) {
2452 	return esil_mem_modeq_n (esil, 64);
2453 }
esil_mem_modeq(RAnalEsil * esil)2454 static bool esil_mem_modeq(RAnalEsil *esil) {
2455 	return esil_mem_modeq_n (esil, esil->anal->bits);
2456 }
2457 
2458 /* DIVEQ */
2459 
esil_mem_diveq_n(RAnalEsil * esil,int bits)2460 static bool esil_mem_diveq_n(RAnalEsil *esil, int bits) {
2461 	bool ret = false;
2462 	ut64 s, d;
2463 	char *dst = r_anal_esil_pop (esil);
2464 	char *src0 = r_anal_esil_pop (esil);
2465 	char *src1 = NULL;
2466 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2467 		if (s == 0) {
2468 			ERR ("esil_mem_diveq8: Division by zero!");
2469 			esil->trap = R_ANAL_TRAP_DIVBYZERO;
2470 			esil->trap_code = 0;
2471 		} else {
2472 			r_anal_esil_push (esil, dst);
2473 			ret = (!!esil_peek_n (esil, bits));
2474 			src1 = r_anal_esil_pop (esil);
2475 			if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2476 				d = d / s;
2477 				r_anal_esil_pushnum (esil, d);
2478 				r_anal_esil_push (esil, dst);
2479 				ret &= (!!esil_poke_n (esil, bits));
2480 			} else {
2481 				ret = false;
2482 			}
2483 		}
2484 	}
2485 	if (!ret) {
2486 		ERR ("esil_mem_diveq_n: invalid parameters");
2487 	}
2488 	free (dst);
2489 	free (src0);
2490 	free (src1);
2491 	return ret;
2492 }
2493 
esil_mem_diveq1(RAnalEsil * esil)2494 static bool esil_mem_diveq1(RAnalEsil *esil) {
2495 	return esil_mem_diveq_n (esil, 8);
2496 }
esil_mem_diveq2(RAnalEsil * esil)2497 static bool esil_mem_diveq2(RAnalEsil *esil) {
2498 	return esil_mem_diveq_n (esil, 16);
2499 }
esil_mem_diveq4(RAnalEsil * esil)2500 static bool esil_mem_diveq4(RAnalEsil *esil) {
2501 	return esil_mem_diveq_n (esil, 32);
2502 }
esil_mem_diveq8(RAnalEsil * esil)2503 static bool esil_mem_diveq8(RAnalEsil *esil) {
2504 	return esil_mem_diveq_n (esil, 64);
2505 }
esil_mem_diveq(RAnalEsil * esil)2506 static bool esil_mem_diveq(RAnalEsil *esil) {
2507 	return esil_mem_diveq_n (esil, esil->anal->bits);
2508 }
2509 
2510 /* MULEQ */
2511 
esil_mem_muleq_n(RAnalEsil * esil,int bits,ut64 bitmask)2512 static bool esil_mem_muleq_n(RAnalEsil *esil, int bits, ut64 bitmask) {
2513 	bool ret = false;
2514 	ut64 s, d;
2515 	char *dst = r_anal_esil_pop (esil);
2516 	char *src0 = r_anal_esil_pop (esil);
2517 	char *src1 = NULL;
2518 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2519 		r_anal_esil_push (esil, dst);
2520 		ret = (!!esil_peek_n (esil, bits));
2521 		src1 = r_anal_esil_pop (esil);
2522 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2523 			d *= s;
2524 			r_anal_esil_pushnum (esil, d);
2525 			r_anal_esil_push (esil, dst);
2526 			ret &= (!!esil_poke_n (esil, bits));
2527 		} else {
2528 			ret = false;
2529 		}
2530 	}
2531 	if (!ret) {
2532 		ERR ("esil_mem_muleq_n: invalid parameters");
2533 	}
2534 	free (dst);
2535 	free (src0);
2536 	free (src1);
2537 	return ret;
2538 }
2539 
esil_mem_muleq1(RAnalEsil * esil)2540 static bool esil_mem_muleq1(RAnalEsil *esil) {
2541 	return esil_mem_muleq_n (esil, 8, UT8_MAX);
2542 }
esil_mem_muleq2(RAnalEsil * esil)2543 static bool esil_mem_muleq2(RAnalEsil *esil) {
2544 	return esil_mem_muleq_n (esil, 16, UT16_MAX);
2545 }
esil_mem_muleq4(RAnalEsil * esil)2546 static bool esil_mem_muleq4(RAnalEsil *esil) {
2547 	return esil_mem_muleq_n (esil, 32, UT32_MAX);
2548 }
esil_mem_muleq8(RAnalEsil * esil)2549 static bool esil_mem_muleq8(RAnalEsil *esil) {
2550 	return esil_mem_muleq_n (esil, 64, UT64_MAX);
2551 }
2552 
esil_mem_muleq(RAnalEsil * esil)2553 static bool esil_mem_muleq(RAnalEsil *esil) {
2554 	switch (esil->anal->bits) {
2555 	case 64: return esil_mem_muleq8 (esil);
2556 	case 32: return esil_mem_muleq4 (esil);
2557 	case 16: return esil_mem_muleq2 (esil);
2558 	case 8: return esil_mem_muleq1 (esil);
2559 	}
2560 	return 0;
2561 }
2562 
2563 /* INCEQ */
2564 
esil_mem_inceq_n(RAnalEsil * esil,int bits)2565 static bool esil_mem_inceq_n(RAnalEsil *esil, int bits) {
2566 	bool ret = false;
2567 	ut64 s;
2568 	char *off = r_anal_esil_pop (esil);
2569 	char *src = NULL;
2570 	if (off) {
2571 		r_anal_esil_push (esil, off);
2572 		ret = (!!esil_peek_n (esil, bits));
2573 		src = r_anal_esil_pop (esil);
2574 		if (src && r_anal_esil_get_parm (esil, src, &s)) {
2575 			esil->old = s;
2576 			s++;
2577 			esil->cur = s;
2578 			esil->lastsz = bits;
2579 			r_anal_esil_pushnum (esil, s);
2580 			r_anal_esil_push (esil, off);
2581 			ret &= (!!esil_poke_n (esil, bits));
2582 		} else {
2583 			ret = false;
2584 		}
2585 	}
2586 	if (!ret) {
2587 		ERR ("esil_mem_inceq_n: invalid parameters");
2588 	}
2589 	free (src);
2590 	free (off);
2591 	return ret;
2592 }
2593 
esil_mem_inceq1(RAnalEsil * esil)2594 static bool esil_mem_inceq1(RAnalEsil *esil) {
2595 	return esil_mem_inceq_n (esil, 8);
2596 }
esil_mem_inceq2(RAnalEsil * esil)2597 static bool esil_mem_inceq2(RAnalEsil *esil) {
2598 	return esil_mem_inceq_n (esil, 16);
2599 }
esil_mem_inceq4(RAnalEsil * esil)2600 static bool esil_mem_inceq4(RAnalEsil *esil) {
2601 	return esil_mem_inceq_n (esil, 32);
2602 }
esil_mem_inceq8(RAnalEsil * esil)2603 static bool esil_mem_inceq8(RAnalEsil *esil) {
2604 	return esil_mem_inceq_n (esil, 64);
2605 }
esil_mem_inceq(RAnalEsil * esil)2606 static bool esil_mem_inceq(RAnalEsil *esil) {
2607 	return esil_mem_inceq_n (esil, esil->anal->bits);
2608 }
2609 
2610 /* DECEQ */
2611 
esil_mem_deceq_n(RAnalEsil * esil,int bits)2612 static bool esil_mem_deceq_n(RAnalEsil *esil, int bits) {
2613 	bool ret = false;
2614 	ut64 s;
2615 	char *off = r_anal_esil_pop (esil);
2616 	char *src = NULL;
2617 	if (off) {
2618 		r_anal_esil_push (esil, off);
2619 		ret = (!!esil_peek_n (esil, bits));
2620 		src = r_anal_esil_pop (esil);
2621 		if (src && r_anal_esil_get_parm (esil, src, &s)) {
2622 			s--;
2623 			r_anal_esil_pushnum (esil, s);
2624 			r_anal_esil_push (esil, off);
2625 			ret &= (!!esil_poke_n (esil, bits));
2626 		} else {
2627 			ret = false;
2628 		}
2629 	}
2630 	if (!ret) {
2631 		ERR ("esil_mem_deceq_n: invalid parameters");
2632 	}
2633 	free (src);
2634 	free (off);
2635 	return ret;
2636 }
2637 
esil_mem_deceq1(RAnalEsil * esil)2638 static bool esil_mem_deceq1(RAnalEsil *esil) {
2639 	return esil_mem_deceq_n (esil, 8);
2640 }
esil_mem_deceq2(RAnalEsil * esil)2641 static bool esil_mem_deceq2(RAnalEsil *esil) {
2642 	return esil_mem_deceq_n (esil, 16);
2643 }
esil_mem_deceq4(RAnalEsil * esil)2644 static bool esil_mem_deceq4(RAnalEsil *esil) {
2645 	return esil_mem_deceq_n (esil, 32);
2646 }
esil_mem_deceq8(RAnalEsil * esil)2647 static bool esil_mem_deceq8(RAnalEsil *esil) {
2648 	return esil_mem_deceq_n (esil, 64);
2649 }
esil_mem_deceq(RAnalEsil * esil)2650 static bool esil_mem_deceq(RAnalEsil *esil) {
2651 	return esil_mem_deceq_n (esil, esil->anal->bits);
2652 }
2653 
2654 /* LSLEQ */
2655 
esil_mem_lsleq_n(RAnalEsil * esil,int bits)2656 static bool esil_mem_lsleq_n(RAnalEsil *esil, int bits) {
2657 	bool ret = false;
2658 	ut64 s, d;
2659 	char *dst = r_anal_esil_pop (esil);
2660 	char *src0 = r_anal_esil_pop (esil);
2661 	char *src1 = NULL;
2662 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2663 		if (s > sizeof (ut64) * 8) {
2664 			ERR ("esil_mem_lsleq_n: shift is too big");
2665 		} else {
2666 			r_anal_esil_push (esil, dst);
2667 			ret = (!!esil_peek_n (esil, bits));
2668 			src1 = r_anal_esil_pop (esil);
2669 			if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2670 				if (s > 63) {
2671 					d = 0;
2672 				} else {
2673 					d <<= s;
2674 				}
2675 				r_anal_esil_pushnum (esil, d);
2676 				r_anal_esil_push (esil, dst);
2677 				ret &= (!!esil_poke_n (esil, bits));
2678 			} else {
2679 				ret = false;
2680 			}
2681 		}
2682 	}
2683 	if (!ret) {
2684 		ERR ("esil_mem_lsleq_n: invalid parameters");
2685 	}
2686 	free (dst);
2687 	free (src0);
2688 	free (src1);
2689 	return ret;
2690 }
2691 
esil_mem_lsleq1(RAnalEsil * esil)2692 static bool esil_mem_lsleq1(RAnalEsil *esil) {
2693 	return esil_mem_lsleq_n (esil, 8);
2694 }
esil_mem_lsleq2(RAnalEsil * esil)2695 static bool esil_mem_lsleq2(RAnalEsil *esil) {
2696 	return esil_mem_lsleq_n (esil, 16);
2697 }
esil_mem_lsleq4(RAnalEsil * esil)2698 static bool esil_mem_lsleq4(RAnalEsil *esil) {
2699 	return esil_mem_lsleq_n (esil, 32);
2700 }
esil_mem_lsleq8(RAnalEsil * esil)2701 static bool esil_mem_lsleq8(RAnalEsil *esil) {
2702 	return esil_mem_lsleq_n (esil, 64);
2703 }
esil_mem_lsleq(RAnalEsil * esil)2704 static bool esil_mem_lsleq(RAnalEsil *esil) {
2705 	return esil_mem_lsleq_n (esil, esil->anal->bits);
2706 }
2707 
2708 /* LSREQ */
2709 
esil_mem_lsreq_n(RAnalEsil * esil,int bits)2710 static bool esil_mem_lsreq_n(RAnalEsil *esil, int bits) {
2711 	bool ret = false;
2712 	ut64 s, d;
2713 	char *dst = r_anal_esil_pop (esil);
2714 	char *src0 = r_anal_esil_pop (esil);
2715 	char *src1 = NULL;
2716 	if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2717 		r_anal_esil_push (esil, dst);
2718 		ret = (!!esil_peek_n (esil, bits));
2719 		src1 = r_anal_esil_pop (esil);
2720 		if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2721 			d >>= s;
2722 			r_anal_esil_pushnum (esil, d);
2723 			r_anal_esil_push (esil, dst);
2724 			ret &= (!!esil_poke_n (esil, bits));
2725 		} else {
2726 			ret = false;
2727 		}
2728 	}
2729 	if (!ret) {
2730 		ERR ("esil_mem_lsreq_n: invalid parameters");
2731 	}
2732 	free (dst);
2733 	free (src0);
2734 	free (src1);
2735 	return ret;
2736 }
2737 
esil_mem_lsreq1(RAnalEsil * esil)2738 static bool esil_mem_lsreq1(RAnalEsil *esil) {
2739 	return esil_mem_lsreq_n (esil, 8);
2740 }
esil_mem_lsreq2(RAnalEsil * esil)2741 static bool esil_mem_lsreq2(RAnalEsil *esil) {
2742 	return esil_mem_lsreq_n (esil, 16);
2743 }
esil_mem_lsreq4(RAnalEsil * esil)2744 static bool esil_mem_lsreq4(RAnalEsil *esil) {
2745 	return esil_mem_lsreq_n (esil, 32);
2746 }
esil_mem_lsreq8(RAnalEsil * esil)2747 static bool esil_mem_lsreq8(RAnalEsil *esil) {
2748 	return esil_mem_lsreq_n (esil, 64);
2749 }
esil_mem_lsreq(RAnalEsil * esil)2750 static bool esil_mem_lsreq(RAnalEsil *esil) {
2751 	return esil_mem_lsreq_n (esil, esil->anal->bits);
2752 }
2753 
2754 /* get value of register or memory reference and push the value */
esil_num(RAnalEsil * esil)2755 static bool esil_num(RAnalEsil *esil) {
2756 	char *dup_me;
2757 	ut64 dup;
2758 	if (!esil) {
2759 		return false;
2760 	}
2761 	if (!(dup_me = r_anal_esil_pop (esil))) {
2762 		return false;
2763 	}
2764 	if (!r_anal_esil_get_parm (esil, dup_me, &dup)) {
2765 		free (dup_me);
2766 		return false;
2767 	}
2768 	free (dup_me);
2769 	return r_anal_esil_pushnum (esil, dup);
2770 }
2771 
2772 /* duplicate the last element in the stack */
esil_dup(RAnalEsil * esil)2773 static bool esil_dup(RAnalEsil *esil) {
2774 	if (!esil || !esil->stack || esil->stackptr < 1 || esil->stackptr > (esil->stacksize - 1)) {
2775 		return false;
2776 	}
2777 	return r_anal_esil_push (esil, esil->stack[esil->stackptr-1]);
2778 }
2779 
esil_swap(RAnalEsil * esil)2780 static bool esil_swap(RAnalEsil *esil) {
2781 	char *tmp;
2782 	if (!esil || !esil->stack || esil->stackptr < 2) {
2783 		return false;
2784 	}
2785 	if (!esil->stack[esil->stackptr-1] || !esil->stack[esil->stackptr-2]) {
2786 		return false;
2787 	}
2788 	tmp = esil->stack[esil->stackptr-1];
2789 	esil->stack[esil->stackptr-1] = esil->stack[esil->stackptr-2];
2790 	esil->stack[esil->stackptr-2] = tmp;
2791 	return true;
2792 }
2793 
2794 // NOTE on following comparison functions:
2795 // The push to top of the stack is based on a
2796 // signed compare (as this causes least surprise to the users).
2797 // If an unsigned comparison is necessary, one must not use the
2798 // result pushed onto the top of the stack, but rather test the flags which
2799 // are set as a result of the compare.
2800 
signed_compare_gt(ut64 a,ut64 b,ut64 size)2801 static int signed_compare_gt(ut64 a, ut64 b, ut64 size) {
2802 	int result;
2803 	switch (size) {
2804 	case 1:  result = (a & 1) > (b & 1);
2805 		break;
2806 	case 8:  result = (st8) a > (st8) b;
2807 		break;
2808 	case 16: result = (st16) a > (st16) b;
2809 		break;
2810 	case 32: result = (st32) a > (st32) b;
2811 		break;
2812 	case 64:
2813 	default: result = (st64) a > (st64) b;
2814 		break;
2815 	}
2816 	return result;
2817 }
2818 
esil_smaller(RAnalEsil * esil)2819 static bool esil_smaller(RAnalEsil *esil) { // 'dst < src' => 'src,dst,<'
2820 	ut64 num, num2;
2821 	bool ret = false;
2822 	char *dst = r_anal_esil_pop (esil);
2823 	char *src = r_anal_esil_pop (esil);
2824 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2825 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2826 			esil->old = num;
2827 			esil->cur = num - num2;
2828 			ret = true;
2829 			if (r_reg_get (esil->anal->reg, dst, -1)) {
2830 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2831 			} else if (r_reg_get (esil->anal->reg, src, -1)) {
2832 				esil->lastsz = esil_internal_sizeof_reg (esil, src);
2833 			} else {
2834 				// default size is set to 64 as internally operands are ut64
2835 				esil->lastsz = 64;
2836 			}
2837 			r_anal_esil_pushnum (esil, (num != num2) &
2838 			                           !signed_compare_gt (num, num2, esil->lastsz));
2839 		}
2840 	}
2841 	free (dst);
2842 	free (src);
2843 	return ret;
2844 }
2845 
esil_bigger(RAnalEsil * esil)2846 static bool esil_bigger(RAnalEsil *esil) { // 'dst > src' => 'src,dst,>'
2847 	ut64 num, num2;
2848 	bool ret = false;
2849 	char *dst = r_anal_esil_pop (esil);
2850 	char *src = r_anal_esil_pop (esil);
2851 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2852 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2853 			esil->old = num;
2854 			esil->cur = num - num2;
2855 			ret = true;
2856 			if (r_reg_get (esil->anal->reg, dst, -1)) {
2857 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2858 			} else if (r_reg_get (esil->anal->reg, src, -1)) {
2859 				esil->lastsz = esil_internal_sizeof_reg (esil, src);
2860 			} else {
2861 				// default size is set to 64 as internally operands are ut64
2862 				esil->lastsz = 64;
2863 			}
2864 			r_anal_esil_pushnum (esil, signed_compare_gt (num, num2, esil->lastsz));
2865 		}
2866 	}
2867 	free (dst);
2868 	free (src);
2869 	return ret;
2870 }
2871 
esil_smaller_equal(RAnalEsil * esil)2872 static bool esil_smaller_equal(RAnalEsil *esil) { // 'dst <= src' => 'src,dst,<='
2873 	ut64 num, num2;
2874 	bool ret = false;
2875 	char *dst = r_anal_esil_pop (esil);
2876 	char *src = r_anal_esil_pop (esil);
2877 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2878 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2879 			esil->old = num;
2880 			esil->cur = num - num2;
2881 			ret = true;
2882 			if (r_reg_get (esil->anal->reg, dst, -1)) {
2883 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2884 			} else if (r_reg_get (esil->anal->reg, src, -1)) {
2885 				esil->lastsz = esil_internal_sizeof_reg (esil, src);
2886 			} else {
2887 				// default size is set to 64 as internally operands are ut64
2888 				esil->lastsz = 64;
2889 			}
2890 			r_anal_esil_pushnum (esil, !signed_compare_gt (num, num2, esil->lastsz));
2891 		}
2892 	}
2893 	free (dst);
2894 	free (src);
2895 	return ret;
2896 }
2897 
esil_bigger_equal(RAnalEsil * esil)2898 static bool esil_bigger_equal(RAnalEsil *esil) { // 'dst >= src' => 'src,dst,>='
2899 	ut64 num, num2;
2900 	bool ret = false;
2901 	char *dst = r_anal_esil_pop (esil);
2902 	char *src = r_anal_esil_pop (esil);
2903 	if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2904 		if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2905 			esil->old = num;
2906 			esil->cur = num - num2;
2907 			ret = true;
2908 			if (r_reg_get (esil->anal->reg, dst, -1)) {
2909 				esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2910 			} else if (r_reg_get (esil->anal->reg, src, -1)) {
2911 				esil->lastsz = esil_internal_sizeof_reg (esil, src);
2912 			} else {
2913 				// default size is set to 64 as internally operands are ut64
2914 				esil->lastsz = 64;
2915 			}
2916 			r_anal_esil_pushnum (esil, (num == num2) |
2917 			                           signed_compare_gt (num, num2, esil->lastsz));
2918 		}
2919 	}
2920 	free (dst);
2921 	free (src);
2922 	return ret;
2923 }
2924 
esil_set_jump_target(RAnalEsil * esil)2925 static bool esil_set_jump_target(RAnalEsil *esil) {
2926 	bool ret = false;
2927 	ut64 s;
2928 	char *src = r_anal_esil_pop (esil);
2929 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
2930 		esil->jump_target = s;
2931 		esil->jump_target_set = 1;
2932 		ret = true;
2933 	} else {
2934 		R_FREE (src);
2935 		ERR ("esil_set_jump_target: empty stack");
2936 	}
2937 	free (src);
2938 	return ret;
2939 }
2940 
esil_set_jump_target_set(RAnalEsil * esil)2941 static bool esil_set_jump_target_set(RAnalEsil *esil) {
2942 	bool ret = false;
2943 	ut64 s;
2944 	char *src = r_anal_esil_pop (esil);
2945 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
2946 		esil->jump_target_set = s;
2947 		ret = true;
2948 	} else {
2949 		R_FREE (src);
2950 		ERR ("esil_set_jump_target_set: empty stack");
2951 	}
2952 	free (src);
2953 	return ret;
2954 }
2955 
esil_set_delay_slot(RAnalEsil * esil)2956 static bool esil_set_delay_slot(RAnalEsil *esil) {
2957 	bool ret = false;
2958 	ut64 s;
2959 	char *src = r_anal_esil_pop (esil);
2960 	if (src && r_anal_esil_get_parm (esil, src, &s)) {
2961 		esil->delay = s;
2962 		ret = true;
2963 	} else {
2964 		R_FREE (src);
2965 		ERR ("esil_set_delay_slot: empty stack");
2966 	}
2967 	free (src);
2968 	return ret;
2969 }
2970 
esil_get_parm_float(RAnalEsil * esil,const char * str,double * num)2971 static int esil_get_parm_float(RAnalEsil *esil, const char *str, double *num) {
2972 	return r_anal_esil_get_parm(esil, str, (ut64 *)num);
2973 }
2974 
esil_pushnum_float(RAnalEsil * esil,double num)2975 static bool esil_pushnum_float(RAnalEsil *esil, double num) {
2976 	RNumFloat n;
2977 	n.f64 = num;
2978 	return r_anal_esil_pushnum(esil, n.u64);
2979 }
2980 
esil_is_nan(RAnalEsil * esil)2981 static bool esil_is_nan(RAnalEsil *esil) {
2982 	bool ret = false;
2983 	double s;
2984 	char *src = r_anal_esil_pop(esil);
2985 	if (src) {
2986 		if (esil_get_parm_float(esil, src, &s)) {
2987 			ret = r_anal_esil_pushnum(esil, isnan(s));
2988 		} else {
2989 			ERR("esil_is_nan: invalid parameters.");
2990 		}
2991 		free(src);
2992 	} else {
2993 		ERR("esil_is_nan: fail to get argument from stack.");
2994 	}
2995 	return ret;
2996 }
2997 
esil_int_to_double(RAnalEsil * esil,int sign)2998 static bool esil_int_to_double(RAnalEsil *esil, int sign) {
2999 	bool ret = false;
3000 	RNumFloat s;
3001 	char *src = r_anal_esil_pop(esil);
3002 	if (src) {
3003 		if (r_anal_esil_get_parm(esil, src, &s.u64)) {
3004 			if (sign) {
3005 				ret = esil_pushnum_float(esil, (double)(s.s64) * 1.0);
3006 			} else {
3007 				ret = esil_pushnum_float(esil, (double)(s.u64) * 1.0);
3008 			}
3009 		} else {
3010 			ERR("esil_int_to_float: invalid parameters.");
3011 		}
3012 		free(src);
3013 	} else {
3014 		ERR("esil_int_to_float: fail to get argument from stack.");
3015 	}
3016 	return ret;
3017 }
3018 
esil_signed_to_double(RAnalEsil * esil)3019 static bool esil_signed_to_double(RAnalEsil *esil) {
3020 	return esil_int_to_double(esil, 1);
3021 }
3022 
esil_unsigned_to_double(RAnalEsil * esil)3023 static bool esil_unsigned_to_double(RAnalEsil *esil) {
3024 	return esil_int_to_double(esil, 0);
3025 }
3026 
esil_double_to_int(RAnalEsil * esil)3027 static bool esil_double_to_int(RAnalEsil *esil) {
3028 	bool ret = false;
3029 	RNumFloat s;
3030 	char *src = r_anal_esil_pop(esil);
3031 	if (src) {
3032 		if (esil_get_parm_float(esil, src, &s.f64)) {
3033 			if (isnan(s.f64) || isinf(s.f64)) {
3034 				ERR("esil_float_to_int: nan or inf detected.");
3035 			}
3036 			ret = r_anal_esil_pushnum(esil, (st64)(s.f64));
3037 		} else {
3038 			ERR("esil_float_to_int: invalid parameters.");
3039 		}
3040 		free(src);
3041 	} else {
3042 		ERR("esil_float_to_int: fail to get argument from stack.");
3043 	}
3044 	return ret;
3045 }
3046 
esil_double_to_float(RAnalEsil * esil)3047 static bool esil_double_to_float(RAnalEsil *esil) {
3048 	bool ret = false;
3049 	RNumFloat d;
3050 	RNumFloat f;
3051 	ut64 s = 0;
3052 	char *dst = r_anal_esil_pop(esil);
3053 	char *src = r_anal_esil_pop(esil);
3054 
3055 	if (r_anal_esil_get_parm(esil, src, &s) && esil_get_parm_float(esil, dst, &d.f64)) {
3056 		if (isnan(d.f64) || isinf(d.f64)) {
3057 			ret = r_anal_esil_pushnum(esil, d.u64);
3058 		} else if (s == 32) {
3059 			f.f32 = (float)d.f64;
3060 			ret = r_anal_esil_pushnum(esil, f.u32);
3061 		} else if (s == 64) {
3062 			ret = r_anal_esil_pushnum(esil, d.u64);
3063 		/* TODO handle 80 bit and 128 bit floats */
3064 		} else {
3065 			ret = r_anal_esil_pushnum(esil, d.u64);
3066 		}
3067 	} else {
3068 		ERR("esil_float_to_float: invalid parameters.");
3069 	}
3070 
3071 	free(dst);
3072 	free(src);
3073 	return ret;
3074 }
3075 
esil_float_to_double(RAnalEsil * esil)3076 static bool esil_float_to_double(RAnalEsil *esil) {
3077 	bool ret = false;
3078 	RNumFloat d;
3079 	ut64 s = 0;
3080 	char *dst = r_anal_esil_pop(esil);
3081 	char *src = r_anal_esil_pop(esil);
3082 
3083 	if (r_anal_esil_get_parm(esil, src, &s) && esil_get_parm_float(esil, dst, &d.f64)) {
3084 		if (isnan(d.f64) || isinf(d.f64)) {
3085 			ret = esil_pushnum_float(esil, d.f64);
3086 		} else if (s == 32) {
3087 			ret = esil_pushnum_float(esil, (double)d.f32);
3088 		} else if (s == 64) {
3089 			ret = esil_pushnum_float(esil, d.f64);
3090 		/* TODO handle 80 bit and 128 bit floats */
3091 		} else {
3092 			ret = esil_pushnum_float(esil, d.f64);
3093 		}
3094 	} else {
3095 		ERR("esil_float_to_float: invalid parameters.");
3096 	}
3097 	free(dst);
3098 	free(src);
3099 	return ret;
3100 }
3101 
esil_float_cmp(RAnalEsil * esil)3102 static bool esil_float_cmp(RAnalEsil *esil) {
3103 	bool ret = false;
3104 	double s, d;
3105 	char *dst = r_anal_esil_pop(esil);
3106 	char *src = r_anal_esil_pop(esil);
3107 
3108 	if (src && dst && esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3109 		if (isnan(s) || isnan(d)) {
3110 			ret = r_anal_esil_pushnum(esil, 0);
3111 		} else {
3112 			ret = r_anal_esil_pushnum(esil, fabs(s - d) <= DBL_EPSILON);
3113 		}
3114 	} else {
3115 		ERR("esil_float_cmp: invalid parameters.");
3116 	}
3117 	free(dst);
3118 	free(src);
3119 	return ret;
3120 }
3121 
esil_float_negcmp(RAnalEsil * esil)3122 static bool esil_float_negcmp(RAnalEsil *esil) {
3123 	bool ret = false;
3124 	double s, d;
3125 	char *dst = r_anal_esil_pop(esil);
3126 	char *src = r_anal_esil_pop(esil);
3127 
3128 	if (src && dst && esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3129 		if (isnan(s) || isnan(d)) {
3130 			ret = r_anal_esil_pushnum(esil, 0);
3131 		} else {
3132 			ret = r_anal_esil_pushnum(esil, fabs(s - d) >= DBL_EPSILON);
3133 		}
3134 	} else {
3135 		ERR("esil_float_negcmp: invalid parameters.");
3136 	}
3137 	free(dst);
3138 	free(src);
3139 	return ret;
3140 }
3141 
esil_float_less(RAnalEsil * esil)3142 static bool esil_float_less(RAnalEsil *esil) {
3143 	bool ret = false;
3144 	double s, d;
3145 	char *dst = r_anal_esil_pop(esil);
3146 	char *src = r_anal_esil_pop(esil);
3147 
3148 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3149 		if (isnan(s) || isnan(d)) {
3150 			ret = r_anal_esil_pushnum(esil, 0);
3151 		} else {
3152 			ret = r_anal_esil_pushnum(esil, d < s);
3153 		}
3154 	} else {
3155 		ERR("esil_float_less: invalid parameters.");
3156 	}
3157 	free(dst);
3158 	free(src);
3159 	return ret;
3160 }
3161 
esil_float_lesseq(RAnalEsil * esil)3162 static bool esil_float_lesseq(RAnalEsil *esil) {
3163 	bool ret = false;
3164 	double s, d;
3165 	char *dst = r_anal_esil_pop(esil);
3166 	char *src = r_anal_esil_pop(esil);
3167 
3168 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3169 		if (isnan(s) || isnan(d)) {
3170 			ret = r_anal_esil_pushnum(esil, 0);
3171 		} else {
3172 			ret = r_anal_esil_pushnum(esil, d <= s);
3173 		}
3174 	} else {
3175 		ERR("esil_float_lesseq: invalid parameters.");
3176 	}
3177 	free(dst);
3178 	free(src);
3179 	return ret;
3180 }
3181 
esil_float_add(RAnalEsil * esil)3182 static bool esil_float_add(RAnalEsil *esil) {
3183 	bool ret = false;
3184 	double s, d;
3185 	char *dst = r_anal_esil_pop(esil);
3186 	char *src = r_anal_esil_pop(esil);
3187 
3188 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3189 		if (isnan(s)) {
3190 			ret = esil_pushnum_float(esil, s);
3191 		} else if (isnan(d)) {
3192 			ret = esil_pushnum_float(esil, d);
3193 		} else {
3194 			feclearexcept(FE_OVERFLOW);
3195 			double tmp = s + d;
3196 			(void)(tmp); // suppress unused warning
3197 			int raised = fetestexcept(FE_OVERFLOW);
3198 			if (raised & FE_OVERFLOW) {
3199 				ret = esil_pushnum_float(esil, NAN);
3200 			} else {
3201 				ret = esil_pushnum_float(esil, s + d);
3202 			}
3203 		}
3204 	} else {
3205 		ERR("esil_float_add: invalid parameters.");
3206 	}
3207 	free(dst);
3208 	free(src);
3209 	return ret;
3210 }
3211 
esil_float_sub(RAnalEsil * esil)3212 static bool esil_float_sub(RAnalEsil *esil) {
3213 	bool ret = false;
3214 	double s, d;
3215 	char *dst = r_anal_esil_pop(esil);
3216 	char *src = r_anal_esil_pop(esil);
3217 
3218 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3219 		if (isnan(s)) {
3220 			ret = esil_pushnum_float(esil, s);
3221 		} else if (isnan(d)) {
3222 			ret = esil_pushnum_float(esil, d);
3223 		} else {
3224 			feclearexcept(FE_OVERFLOW);
3225 			double tmp = d - s;
3226 			(void)(tmp);
3227 			int raised = fetestexcept(FE_OVERFLOW);
3228 			if (raised & FE_OVERFLOW) {
3229 				ret = esil_pushnum_float(esil, NAN);
3230 			} else {
3231 				ret = esil_pushnum_float(esil, d - s);
3232 			}
3233 		}
3234 	} else {
3235 		ERR("esil_float_sub: invalid parameters.");
3236 	}
3237 	free(dst);
3238 	free(src);
3239 	return ret;
3240 }
3241 
esil_float_mul(RAnalEsil * esil)3242 static bool esil_float_mul(RAnalEsil *esil) {
3243 	bool ret = false;
3244 	double s, d;
3245 	char *dst = r_anal_esil_pop(esil);
3246 	char *src = r_anal_esil_pop(esil);
3247 
3248 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3249 		if (isnan(s)) {
3250 			ret = esil_pushnum_float(esil, s);
3251 		} else if (isnan(d)) {
3252 			ret = esil_pushnum_float(esil, d);
3253 		} else {
3254 			feclearexcept(FE_OVERFLOW);
3255 			double tmp = s * d;
3256 			(void)(tmp);
3257 			int raised = fetestexcept(FE_OVERFLOW);
3258 			if (raised & FE_OVERFLOW) {
3259 				ret = esil_pushnum_float(esil, NAN);
3260 			} else {
3261 				ret = esil_pushnum_float(esil, s * d);
3262 			}
3263 		}
3264 	} else {
3265 		ERR("esil_float_mul: invalid parameters.");
3266 	}
3267 	free(dst);
3268 	free(src);
3269 	return ret;
3270 }
3271 
esil_float_div(RAnalEsil * esil)3272 static bool esil_float_div(RAnalEsil *esil) {
3273 	bool ret = false;
3274 	double s, d;
3275 	char *dst = r_anal_esil_pop(esil);
3276 	char *src = r_anal_esil_pop(esil);
3277 
3278 	if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3279 		if (isnan(s)) {
3280 			ret = esil_pushnum_float(esil, s);
3281 		} else if (isnan(d)) {
3282 			ret = esil_pushnum_float(esil, d);
3283 		} else {
3284 			feclearexcept(FE_OVERFLOW);
3285 			double tmp = d / s;
3286 			(void)(tmp);
3287 			int raised = fetestexcept(FE_OVERFLOW);
3288 			if (raised & FE_OVERFLOW) {
3289 				ret = esil_pushnum_float(esil, NAN);
3290 			} else {
3291 				ret = esil_pushnum_float(esil, d / s);
3292 			}
3293 		}
3294 	} else {
3295 		ERR("esil_float_div: invalid parameters.");
3296 	}
3297 	free(dst);
3298 	free(src);
3299 	return ret;
3300 }
3301 
esil_float_neg(RAnalEsil * esil)3302 static bool esil_float_neg(RAnalEsil *esil) {
3303 	bool ret = false;
3304 	double s;
3305 	char *src = r_anal_esil_pop(esil);
3306 
3307 	if (src)	{
3308 		if (esil_get_parm_float(esil, src, &s)) {
3309 			ret = esil_pushnum_float(esil, -s);
3310 		} else {
3311 			ERR("esil_float_neg: invalid parameters.");
3312 		}
3313 		free(src);
3314 	} else {
3315 		ERR("esil_float_neg: fail to get element from stack.");
3316 	}
3317 	return ret;
3318 }
3319 
esil_float_ceil(RAnalEsil * esil)3320 static bool esil_float_ceil(RAnalEsil *esil) {
3321 	bool ret = false;
3322 	double s;
3323 	char *src = r_anal_esil_pop(esil);
3324 
3325 	if (src) {
3326 		if (esil_get_parm_float(esil, src, &s)) {
3327 			if (isnan(s)) {
3328 				ret = esil_pushnum_float(esil, s);
3329 			} else {
3330 				ret = esil_pushnum_float(esil, ceil(s));
3331 			}
3332 		} else {
3333 			ERR("esil_float_ceil: invalid parameters.");
3334 		}
3335 		free(src);
3336 	} else {
3337 		ERR("esil_float_ceil: fail to get element from stack.");
3338 	}
3339 	return ret;
3340 }
3341 
esil_float_floor(RAnalEsil * esil)3342 static bool esil_float_floor(RAnalEsil *esil) {
3343 	bool ret = false;
3344 	double s;
3345 	char *src = r_anal_esil_pop(esil);
3346 
3347 	if (src) {
3348 		if (esil_get_parm_float(esil, src, &s)) {
3349 			if (isnan(s)) {
3350 				ret = esil_pushnum_float(esil, s);
3351 			} else {
3352 				ret = esil_pushnum_float(esil, floor(s));
3353 			}
3354 		} else {
3355 			ERR("esil_float_floor: invalid parameters.");
3356 		}
3357 		free(src);
3358 	} else {
3359 		ERR("esil_float_floor: fail to get element from stack.");
3360 	}
3361 
3362 	return ret;
3363 }
3364 
esil_float_round(RAnalEsil * esil)3365 static bool esil_float_round(RAnalEsil *esil) {
3366 	bool ret = false;
3367 	double s;
3368 	char *src = r_anal_esil_pop(esil);
3369 
3370 	if (src) {
3371 		if (esil_get_parm_float(esil, src, &s)) {
3372 			if (isnan(s)) {
3373 				ret = esil_pushnum_float(esil, s);
3374 			} else {
3375 				ret = esil_pushnum_float(esil, round(s));
3376 			}
3377 		} else {
3378 			ERR("esil_float_round: invalid parameters.");
3379 		}
3380 		free(src);
3381 	} else {
3382 		ERR("esil_float_round: fail to get element from stack.");
3383 	}
3384 	return ret;
3385 }
3386 
esil_float_sqrt(RAnalEsil * esil)3387 static bool esil_float_sqrt(RAnalEsil *esil) {
3388 	bool ret = false;
3389 	double s;
3390 	char *src = r_anal_esil_pop(esil);
3391 
3392 	if (src) {
3393 		if (esil_get_parm_float(esil, src, &s)) {
3394 			if (isnan(s)) {
3395 				ret = esil_pushnum_float(esil, s);
3396 			} else {
3397 				ret = esil_pushnum_float(esil, sqrt(s));
3398 			}
3399 		} else {
3400 			ERR("esil_float_sqrt: invalid parameters.");
3401 		}
3402 		free(src);
3403 	} else {
3404 		ERR("esil_float_sqrt: fail to get element from stack.");
3405 	}
3406 	return ret;
3407 }
3408 
iscommand(RAnalEsil * esil,const char * word,RAnalEsilOp ** op)3409 static bool iscommand(RAnalEsil *esil, const char *word, RAnalEsilOp **op) {
3410 	RAnalEsilOp *eop = ht_pp_find (esil->ops, word, NULL);
3411 	if (eop) {
3412 		*op = eop;
3413 		return true;
3414 	}
3415 	return false;
3416 }
3417 
runword(RAnalEsil * esil,const char * word)3418 static bool runword(RAnalEsil *esil, const char *word) {
3419 	RAnalEsilOp *op = NULL;
3420 	if (!word) {
3421 		return false;
3422 	}
3423 	esil->parse_goto_count--;
3424 	if (esil->parse_goto_count < 1) {
3425 		ERR ("ESIL infinite loop detected\n");
3426 		esil->trap = 1;       // INTERNAL ERROR
3427 		esil->parse_stop = 1; // INTERNAL ERROR
3428 		return false;
3429 	}
3430 
3431 	// Don't push anything onto stack when processing if statements
3432 	if (!strcmp (word, "?{") && esil->Reil) {
3433 		esil->Reil->skip = esil->Reil->skip? 0: 1;
3434 		if (esil->Reil->skip) {
3435 			esil->Reil->cmd_count = 0;
3436 			memset (esil->Reil->if_buf, 0, sizeof (esil->Reil->if_buf));
3437 		}
3438 	}
3439 
3440 	if (esil->Reil && esil->Reil->skip) {
3441 		char *if_buf = esil->Reil->if_buf;
3442 		size_t n = strlen (if_buf);
3443 		snprintf (if_buf + n, sizeof (esil->Reil->if_buf) - n, "%s,", word);
3444 		if (!strcmp (word, "}")) {
3445 			r_anal_esil_pushnum (esil, esil->Reil->addr + esil->Reil->cmd_count + 1);
3446 			r_anal_esil_parse (esil, esil->Reil->if_buf);
3447 		} else if (iscommand (esil, word, &op)) {
3448 			esil->Reil->cmd_count++;
3449 		}
3450 		return true;
3451 	}
3452 
3453 	//eprintf ("WORD (%d) (%s)\n", esil->skip, word);
3454 	if (!strcmp (word, "}{")) {
3455 		if (esil->skip == 1) {
3456 			esil->skip = 0;
3457 		} else if (esil->skip == 0) {	//this isn't perfect, but should work for valid esil
3458 			esil->skip = 1;
3459 		}
3460 		return true;
3461 	}
3462 	if (!strcmp (word, "}")) {
3463 		if (esil->skip) {
3464 			esil->skip--;
3465 		}
3466 		return true;
3467 	}
3468 	if (esil->skip && strcmp(word, "?{")) {
3469 		return true;
3470 	}
3471 
3472 	if (iscommand (esil, word, &op)) {
3473 		// run action
3474 		if (op) {
3475 			if (esil->cb.hook_command) {
3476 				if (esil->cb.hook_command (esil, word)) {
3477 					return 1; // XXX cannot return != 1
3478 				}
3479 			}
3480 			esil->current_opstr = strdup (word);
3481 			//so this is basically just sharing what's the operation with the operation
3482 			//useful for wrappers
3483 			const bool ret = op->code (esil);
3484 			free (esil->current_opstr);
3485 			esil->current_opstr = NULL;
3486 			if (!ret) {
3487 				if (esil->verbose) {
3488 					eprintf ("%s returned 0\n", word);
3489 				}
3490 			}
3491 			return ret;
3492 		}
3493 	}
3494 	if (!*word || *word == ',') {
3495 		// skip empty words
3496 		return true;
3497 	}
3498 
3499 	// push value
3500 	if (!r_anal_esil_push (esil, word)) {
3501 		ERR ("ESIL stack is full");
3502 		esil->trap = 1;
3503 		esil->trap_code = 1;
3504 	}
3505 	return true;
3506 }
3507 
gotoWord(const char * str,int n)3508 static const char *gotoWord(const char *str, int n) {
3509 	const char *ostr = str;
3510 	int count = 0;
3511 	while (*str) {
3512 		if (count == n) {
3513 			return ostr;
3514 		}
3515 		str++;
3516 		if (*str == ',') {
3517 			ostr = str + 1;
3518 			count++;
3519 		}
3520 	}
3521 	return NULL;
3522 }
3523 
3524 /** evaluate an esil word and return the action to perform
3525  * TODO: Use `enum` here
3526  * 0: continue running the
3527  * 1: stop execution
3528  * 2: continue in loop
3529  * 3: normal continuation
3530  */
evalWord(RAnalEsil * esil,const char * ostr,const char ** str)3531 static int evalWord(RAnalEsil *esil, const char *ostr, const char **str) {
3532 	r_return_val_if_fail (esil && str, 0);
3533 	if (!*str) {
3534 		return 0;
3535 	}
3536 	if ((*str)[0] && (*str)[1] == ',') {
3537 		return 2;
3538 	}
3539 	if (esil->repeat) {
3540 		return 0;
3541 	}
3542 	if (esil->parse_goto != -1) {
3543 		// TODO: detect infinite loop??? how??
3544 		*str = gotoWord (ostr, esil->parse_goto);
3545 		if (*str) {
3546 			esil->parse_goto = -1;
3547 			return 2;
3548 		}
3549 		if (esil->verbose) {
3550 			eprintf ("Cannot find word %d\n", esil->parse_goto);
3551 		}
3552 		return 1;
3553 	}
3554 	if (esil->parse_stop) {
3555 		if (esil->parse_stop == 2) {
3556 			eprintf ("[esil at 0x%08"PFMT64x"] TODO: %s\n", esil->address, *str + 1);
3557 		}
3558 		return 1;
3559 	}
3560 	return 3;
3561 }
3562 
__stepOut(RAnalEsil * esil,const char * cmd)3563 static bool __stepOut(RAnalEsil *esil, const char *cmd) {
3564 	static bool inCmdStep = false;
3565 	if (cmd && esil && esil->cmd && !inCmdStep) {
3566 		inCmdStep = true;
3567 		if (esil->cmd (esil, cmd, esil->address, 0)) {
3568 			inCmdStep = false;
3569 			// if returns 1 we skip the impl
3570 			return true;
3571 		}
3572 		inCmdStep = false;
3573 	}
3574 	return false;
3575 }
3576 
r_anal_esil_parse(RAnalEsil * esil,const char * str)3577 R_API bool r_anal_esil_parse(RAnalEsil *esil, const char *str) {
3578 	int wordi = 0;
3579 	int dorunword;
3580 	char word[64];
3581 	const char *ostr = str;
3582 	r_return_val_if_fail (esil && R_STR_ISNOTEMPTY (str), 0);
3583 
3584 	if (__stepOut (esil, esil->cmd_step)) {
3585 		(void)__stepOut (esil, esil->cmd_step_out);
3586 		return true;
3587 	}
3588 	const char *hashbang = strstr (str, "#!");
3589 	esil->trap = 0;
3590 	if (esil->cmd && esil->cmd_todo) {
3591 		if (!strncmp (str, "TODO", 4)) {
3592 			esil->cmd (esil, esil->cmd_todo, esil->address, 0);
3593 		}
3594 	}
3595 loop:
3596 	esil->repeat = 0;
3597 	esil->skip = 0;
3598 	esil->parse_goto = -1;
3599 	esil->parse_stop = 0;
3600 // memleak or failing aetr test. wat du
3601 //	r_anal_esil_stack_free (esil);
3602 	esil->parse_goto_count = esil->anal? esil->anal->esil_goto_limit: R_ANAL_ESIL_GOTO_LIMIT;
3603 	str = ostr;
3604 repeat:
3605 	wordi = 0;
3606 	while (*str) {
3607 		if (str == hashbang) {
3608 			if (esil->anal && esil->anal->coreb.setab) {
3609 				esil->anal->coreb.cmd (esil->anal->coreb.core, str + 2);
3610 			}
3611 			break;
3612 		}
3613 		if (wordi > 62) {
3614 			ERR ("Invalid esil string");
3615 			__stepOut (esil, esil->cmd_step_out);
3616 			return -1;
3617 		}
3618 		dorunword = 0;
3619 		if (*str == ';') {
3620 			word[wordi] = 0;
3621 			dorunword = 1;
3622 		}
3623 		if (*str == ',') {
3624 			word[wordi] = 0;
3625 			dorunword = 2;
3626 		}
3627 		if (dorunword) {
3628 			if (*word) {
3629 				if (!runword (esil, word)) {
3630 					__stepOut (esil, esil->cmd_step_out);
3631 					return 0;
3632 				}
3633 				word[wordi] = ',';
3634 				wordi = 0;
3635 				switch (evalWord (esil, ostr, &str)) {
3636 				case 0: goto loop;
3637 				case 1:
3638 					__stepOut (esil, esil->cmd_step_out);
3639 					return 0;
3640 				case 2: continue;
3641 				}
3642 				if (dorunword == 1) {
3643 					__stepOut (esil, esil->cmd_step_out);
3644 					return 0;
3645 				}
3646 			}
3647 			str++;
3648 		}
3649 		word[wordi++] = *str;
3650 		//is *str is '\0' in the next iteration the condition will be true
3651 		//reading beyond the boundaries
3652 		if (*str) {
3653 			str++;
3654 		}
3655 	}
3656 	word[wordi] = 0;
3657 	if (*word) {
3658 		if (!runword (esil, word)) {
3659 			__stepOut (esil, esil->cmd_step_out);
3660 			return 0;
3661 		}
3662 		switch (evalWord (esil, ostr, &str)) {
3663 		case 0: goto loop;
3664 		case 1: __stepOut (esil, esil->cmd_step_out);
3665 			return 0;
3666 		case 2: goto repeat;
3667 		}
3668 	}
3669 	__stepOut (esil, esil->cmd_step_out);
3670 	return 1;
3671 }
3672 
r_anal_esil_runword(RAnalEsil * esil,const char * word)3673 R_API bool r_anal_esil_runword(RAnalEsil *esil, const char *word) {
3674 	const char *str = NULL;
3675 	(void)runword (esil, word);
3676 	if (*word) {
3677 		if (!runword (esil, word)) {
3678 			return false;
3679 		}
3680 		int ew = evalWord (esil, word, &str);
3681 		eprintf ("ew %d\n", ew);
3682 		eprintf ("--> %s\n", r_str_getf (str));
3683 	}
3684 	return true;
3685 }
3686 
3687 //frees all elements from the stack, not the stack itself
3688 //rename to stack_empty() ?
r_anal_esil_stack_free(RAnalEsil * esil)3689 R_API void r_anal_esil_stack_free(RAnalEsil *esil) {
3690 	int i;
3691 	if (esil) {
3692 		for (i = 0; i < esil->stackptr; i++) {
3693 			R_FREE (esil->stack[i]);
3694 		}
3695 		esil->stackptr = 0;
3696 	}
3697 }
3698 
r_anal_esil_condition(RAnalEsil * esil,const char * str)3699 R_API int r_anal_esil_condition(RAnalEsil *esil, const char *str) {
3700 	char *popped;
3701 	int ret;
3702 	if (!esil) {
3703 		return false;
3704 	}
3705 	while (*str == ' ') {
3706 		str++; // use proper string chop?
3707 	}
3708 	(void) r_anal_esil_parse (esil, str);
3709 	popped = r_anal_esil_pop (esil);
3710 	if (popped) {
3711 		ut64 num;
3712 		if (isregornum (esil, popped, &num)) {
3713 			ret = !!num;
3714 		} else {
3715 			ret = 0;
3716 		}
3717 		free (popped);
3718 	} else {
3719 		eprintf ("Warning: Cannot pop because The ESIL stack is empty");
3720 		return -1;
3721 	}
3722 	return ret;
3723 }
3724 
r_anal_esil_setup_ops(RAnalEsil * esil)3725 static void r_anal_esil_setup_ops(RAnalEsil *esil) {
3726 #define OP(v, w, x, y, z) r_anal_esil_set_op (esil, v, w, x, y, z)
3727 #define	OT_UNK	R_ANAL_ESIL_OP_TYPE_UNKNOWN
3728 #define	OT_CTR	R_ANAL_ESIL_OP_TYPE_CONTROL_FLOW
3729 #define	OT_MATH	R_ANAL_ESIL_OP_TYPE_MATH
3730 #define	OT_REGW	R_ANAL_ESIL_OP_TYPE_REG_WRITE
3731 #define	OT_MEMW	R_ANAL_ESIL_OP_TYPE_MEM_WRITE
3732 #define	OT_MEMR	R_ANAL_ESIL_OP_TYPE_MEM_READ
3733 
3734 	OP ("$", esil_interrupt, 0, 1, OT_UNK);		//hm, type seems a bit wrong
3735 	OP ("()", esil_syscall, 0, 1, OT_UNK);		//same
3736 	OP ("$z", esil_zf, 1, 0, OT_UNK);
3737 	OP ("$c", esil_cf, 1, 1, OT_UNK);
3738 	OP ("$b", esil_bf, 1, 1, OT_UNK);
3739 	OP ("$p", esil_pf, 1, 0, OT_UNK);
3740 	OP ("$s", esil_sf, 1, 1, OT_UNK);
3741 	OP ("$o", esil_of, 1, 1, OT_UNK);
3742 	OP ("$ds", esil_ds, 1, 0, OT_UNK);
3743 	OP ("$jt", esil_jt, 1, 0, OT_UNK);
3744 	OP ("$js", esil_js, 1, 0, OT_UNK);
3745 	OP ("$r", esil_rs, 1, 0, OT_UNK);
3746 	OP ("$$", esil_address, 1, 0, OT_UNK);
3747 	OP ("~", esil_signext, 1, 2, OT_MATH);
3748 	OP ("~=", esil_signexteq, 0, 2, OT_MATH);
3749 	OP ("==", esil_cmp, 0, 2, OT_MATH);
3750 	OP ("<", esil_smaller, 1, 2, OT_MATH);
3751 	OP (">", esil_bigger, 1, 2, OT_MATH);
3752 	OP ("<=", esil_smaller_equal, 1, 2, OT_MATH);
3753 	OP (">=", esil_bigger_equal, 1, 2, OT_MATH);
3754 	OP ("?{", esil_if, 0, 1, OT_CTR);
3755 	OP ("<<", esil_lsl, 1, 2, OT_MATH);
3756 	OP ("<<=", esil_lsleq, 0, 2, OT_MATH | OT_REGW);
3757 	OP (">>", esil_lsr, 1, 2, OT_MATH);
3758 	OP (">>=", esil_lsreq, 0, 2, OT_MATH | OT_REGW);
3759 	OP (">>>>", esil_asr, 1, 2, OT_MATH);
3760 	OP (">>>>=", esil_asreq, 0, 2, OT_MATH | OT_REGW);
3761 	OP (">>>", esil_ror, 1, 2, OT_MATH);
3762 	OP ("<<<", esil_rol, 1, 2, OT_MATH);
3763 	OP ("&", esil_and, 1, 2, OT_MATH);
3764 	OP ("&=", esil_andeq, 0, 2, OT_MATH | OT_REGW);
3765 	OP ("}", esil_nop, 0, 0, OT_CTR); // just to avoid push
3766 	OP ("}{", esil_nop, 0, 0, OT_CTR);
3767 	OP ("|", esil_or, 1, 2, OT_MATH);
3768 	OP ("|=", esil_oreq, 0, 2, OT_MATH | OT_REGW);
3769 	OP ("!", esil_neg, 1, 1, OT_MATH);
3770 	OP ("!=", esil_negeq, 0, 1, OT_MATH | OT_REGW);
3771 	OP ("=", esil_eq, 0, 2, OT_REGW);
3772 	OP (":=", esil_weak_eq, 0, 2, OT_REGW);
3773 	OP ("L*", esil_long_mul, 2, 2, OT_MATH);
3774 	OP ("*", esil_mul, 1, 2, OT_MATH);
3775 	OP ("*=", esil_muleq, 0, 2, OT_MATH | OT_REGW);
3776 	OP ("^", esil_xor, 1, 2, OT_MATH);
3777 	OP ("^=", esil_xoreq, 0, 2, OT_MATH | OT_REGW);
3778 	OP ("+", esil_add, 1, 2, OT_MATH);
3779 	OP ("+=", esil_addeq, 0, 2, OT_MATH | OT_REGW);
3780 	OP ("++", esil_inc, 1, 1, OT_MATH);
3781 	OP ("++=", esil_inceq, 0, 1, OT_MATH | OT_REGW);
3782 	OP ("-", esil_sub, 1, 2, OT_MATH);
3783 	OP ("-=", esil_subeq, 0, 2, OT_MATH | OT_REGW);
3784 	OP ("--", esil_dec, 1, 1, OT_MATH);
3785 	OP ("--=", esil_deceq, 0, 1, OT_MATH | OT_REGW);
3786 	OP ("/", esil_div, 1, 2, OT_MATH);
3787 	OP ("~/", esil_signed_div, 1, 2, OT_MATH);
3788 	OP ("/=", esil_diveq, 0, 2, OT_MATH | OT_REGW);
3789 	OP ("%", esil_mod, 1, 2, OT_MATH);
3790 	OP ("~%", esil_signed_mod, 1, 2, OT_MATH);
3791 	OP ("%=", esil_modeq, 0, 2, OT_MATH | OT_REGW);
3792 	OP ("=[]", esil_poke, 0, 2, OT_MEMW);
3793 	OP ("=[1]", esil_poke1, 0, 2, OT_MEMW);
3794 	OP ("=[2]", esil_poke2, 0, 2, OT_MEMW);
3795 	OP ("=[3]", esil_poke3, 0, 2, OT_MEMW);
3796 	OP ("=[4]", esil_poke4, 0, 2, OT_MEMW);
3797 	OP ("=[8]", esil_poke8, 0, 2, OT_MEMW);
3798 	OP ("=[16]", esil_poke16, 0, 2, OT_MEMW);
3799 	OP ("|=[]", esil_mem_oreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3800 	OP ("|=[1]", esil_mem_oreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3801 	OP ("|=[2]", esil_mem_oreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3802 	OP ("|=[4]", esil_mem_oreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3803 	OP ("|=[8]", esil_mem_oreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3804 	OP ("^=[]", esil_mem_xoreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3805 	OP ("^=[1]", esil_mem_xoreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3806 	OP ("^=[2]", esil_mem_xoreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3807 	OP ("^=[4]", esil_mem_xoreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3808 	OP ("^=[8]", esil_mem_xoreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3809 	OP ("&=[]", esil_mem_andeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3810 	OP ("&=[1]", esil_mem_andeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3811 	OP ("&=[2]", esil_mem_andeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3812 	OP ("&=[4]", esil_mem_andeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3813 	OP ("&=[8]", esil_mem_andeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3814 	OP ("+=[]", esil_mem_addeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3815 	OP ("+=[1]", esil_mem_addeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3816 	OP ("+=[2]", esil_mem_addeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3817 	OP ("+=[4]", esil_mem_addeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3818 	OP ("+=[8]", esil_mem_addeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3819 	OP ("-=[]", esil_mem_subeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3820 	OP ("-=[1]", esil_mem_subeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3821 	OP ("-=[2]", esil_mem_subeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3822 	OP ("-=[4]", esil_mem_subeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3823 	OP ("-=[8]", esil_mem_subeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3824 	OP ("%=[]", esil_mem_modeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3825 	OP ("%=[1]", esil_mem_modeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3826 	OP ("%=[2]", esil_mem_modeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3827 	OP ("%=[4]", esil_mem_modeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3828 	OP ("%=[8]", esil_mem_modeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3829 	OP ("/=[]", esil_mem_diveq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3830 	OP ("/=[1]", esil_mem_diveq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3831 	OP ("/=[2]", esil_mem_diveq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3832 	OP ("/=[4]", esil_mem_diveq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3833 	OP ("/=[8]", esil_mem_diveq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3834 	OP ("*=[]", esil_mem_muleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3835 	OP ("*=[1]", esil_mem_muleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3836 	OP ("*=[2]", esil_mem_muleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3837 	OP ("*=[4]", esil_mem_muleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3838 	OP ("*=[8]", esil_mem_muleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3839 	OP ("++=[]", esil_mem_inceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3840 	OP ("++=[1]", esil_mem_inceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3841 	OP ("++=[2]", esil_mem_inceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3842 	OP ("++=[4]", esil_mem_inceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3843 	OP ("++=[8]", esil_mem_inceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3844 	OP ("--=[]", esil_mem_deceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3845 	OP ("--=[1]", esil_mem_deceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3846 	OP ("--=[2]", esil_mem_deceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3847 	OP ("--=[4]", esil_mem_deceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3848 	OP ("--=[8]", esil_mem_deceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3849 	OP ("<<=[]", esil_mem_lsleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3850 	OP ("<<=[1]", esil_mem_lsleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3851 	OP ("<<=[2]", esil_mem_lsleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3852 	OP ("<<=[4]", esil_mem_lsleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3853 	OP ("<<=[8]", esil_mem_lsleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3854 	OP (">>=[]", esil_mem_lsreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3855 	OP (">>=[1]", esil_mem_lsreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3856 	OP (">>=[2]", esil_mem_lsreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3857 	OP (">>=[4]", esil_mem_lsreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3858 	OP (">>=[8]", esil_mem_lsreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3859 	OP ("[]", esil_peek, 1, 1, OT_MEMR);
3860 	OP ("[*]", esil_peek_some, 0, 0, OT_MEMR);
3861 	OP ("=[*]", esil_poke_some, 0, 0, OT_MEMW);
3862 	OP ("[1]", esil_peek1, 1, 1, OT_MEMR);
3863 	OP ("[2]", esil_peek2, 1, 1, OT_MEMR);
3864 	OP ("[3]", esil_peek3, 1, 1, OT_MEMR);
3865 	OP ("[4]", esil_peek4, 1, 1, OT_MEMR);
3866 	OP ("[8]", esil_peek8, 1, 1, OT_MEMR);
3867 	OP ("[16]", esil_peek16, 1, 1, OT_MEMR);
3868 	OP ("STACK", r_anal_esil_dumpstack, 0, 0, OT_UNK);
3869 	OP ("REPEAT", esil_repeat, 0, 2, OT_CTR);
3870 	OP ("POP", esil_pop, 0, 1, OT_UNK);
3871 	OP ("TODO", esil_todo, 0, 0, OT_UNK);
3872 	OP ("GOTO", esil_goto, 0, 1, OT_CTR);
3873 	OP ("BREAK", esil_break, 0, 0, OT_CTR);
3874 	OP ("CLEAR", esil_clear, 0, 0, OT_UNK);
3875 	OP ("DUP", esil_dup, 1, 0, OT_UNK);
3876 	OP ("NUM", esil_num, 1, 1, OT_UNK);
3877 	OP ("SWAP", esil_swap, 2, 2, OT_UNK);
3878 	OP ("TRAP", esil_trap, 0, 0, OT_UNK);
3879 	OP ("BITS", esil_bits, 1, 0, OT_UNK);
3880 	OP ("SETJT", esil_set_jump_target, 0, 1, OT_UNK);
3881 	OP ("SETJTS", esil_set_jump_target_set, 0, 1, OT_UNK);
3882 	OP ("SETD", esil_set_delay_slot, 0, 1, OT_UNK);
3883 
3884 	/* we all float down here */
3885 	OP ("NAN", esil_is_nan, 1, 1, OT_MATH);
3886 	OP ("I2D", esil_signed_to_double, 1, 1, OT_MATH);
3887 	OP ("S2D", esil_signed_to_double, 1, 1, OT_MATH);
3888 	OP ("U2D", esil_unsigned_to_double, 1, 1, OT_MATH);
3889 	OP ("D2I", esil_double_to_int, 1, 1, OT_MATH);
3890 	OP ("D2F", esil_double_to_float, 1, 2, OT_MATH);
3891 	OP ("F2D", esil_float_to_double, 1, 2, OT_MATH);
3892 	OP ("F==", esil_float_cmp, 1, 2, OT_MATH);
3893 	OP ("F!=", esil_float_negcmp, 1, 2, OT_MATH);
3894 	OP ("F<", esil_float_less, 1, 2, OT_MATH);
3895 	OP ("F<=", esil_float_lesseq, 1, 2, OT_MATH);
3896 	OP ("F+", esil_float_add, 1, 2, OT_MATH);
3897 	OP ("F-", esil_float_sub, 1, 2, OT_MATH);
3898 	OP ("F*", esil_float_mul, 1, 2, OT_MATH);
3899 	OP ("F/", esil_float_div, 1, 2, OT_MATH);
3900 	OP ("-F", esil_float_neg, 1, 1, OT_MATH);
3901 	OP ("CEIL", esil_float_ceil, 1, 1, OT_MATH);
3902 	OP ("FLOOR", esil_float_floor, 1, 1, OT_MATH);
3903 	OP ("ROUND", esil_float_round, 1, 1, OT_MATH);
3904 	OP ("SQRT", esil_float_sqrt, 1, 1, OT_MATH);
3905 
3906 }
3907 
3908 /* register callbacks using this anal module. */
r_anal_esil_setup(RAnalEsil * esil,RAnal * anal,int romem,int stats,int nonull)3909 R_API bool r_anal_esil_setup(RAnalEsil *esil, RAnal *anal, int romem, int stats, int nonull) {
3910 	r_return_val_if_fail (esil, false);
3911 	//esil->debug = 0;
3912 	esil->anal = anal;
3913 	esil->parse_goto_count = anal->esil_goto_limit;
3914 	esil->trap = 0;
3915 	esil->trap_code = 0;
3916 	//esil->user = NULL;
3917 	esil->cb.reg_read = internal_esil_reg_read;
3918 	esil->cb.mem_read = internal_esil_mem_read;
3919 
3920 	if (nonull) {
3921 		// this is very questionable, most platforms allow accessing NULL
3922 		// never writes zero to PC, BP, SP, why? because writing
3923 		// zeros to these registers is equivalent to accessing NULL
3924 		// pointer somehow
3925 		esil->cb.reg_write = internal_esil_reg_write_no_null;
3926 		esil->cb.mem_read = internal_esil_mem_read_no_null;
3927 		esil->cb.mem_write = internal_esil_mem_write_no_null;
3928 	} else {
3929 		esil->cb.reg_write = internal_esil_reg_write;
3930 		esil->cb.mem_read = internal_esil_mem_read;
3931 		esil->cb.mem_write = internal_esil_mem_write;
3932 	}
3933 	r_anal_esil_mem_ro (esil, romem);
3934 	r_anal_esil_stats (esil, stats);
3935 	r_anal_esil_setup_ops (esil);
3936 
3937 	return (anal->cur && anal->cur->esil_init)
3938 		? anal->cur->esil_init (esil): true;
3939 }
3940