Rizin
unix-like reverse engineering framework and cli tools
esil.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2021 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2014-2021 condret <condr3t@protonmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_analysis.h>
6 #include <rz_types.h>
7 #include <rz_util.h>
8 #include <rz_bind.h>
9 
10 #define FLG(x) RZ_ANALYSIS_ESIL_FLAG_##x
11 #define cpuflag(x, y) \
12  if (esil) { \
13  if (y) { \
14  RZ_BIT_SET(&esil->flags, FLG(x)); \
15  } else { \
16  RZ_BIT_UNSET(&esil->flags, FLG(x)); \
17  } \
18  }
19 
20 /* Returns the number that has bits + 1 least significant bits set. */
21 static inline ut64 genmask(int bits) {
22  ut64 m = UT64_MAX;
23  if (bits > 0 && bits < 64) {
24  m = (ut64)(((ut64)(2) << bits) - 1);
25  if (!m) {
26  m = UT64_MAX;
27  }
28  }
29  return m;
30 }
31 
32 #define ESIL_LOG(fmtstr, ...) \
33  if (esil->verbose) { \
34  RZ_LOG_WARN(fmtstr, ##__VA_ARGS__); \
35  }
36 
37 static bool isnum(RzAnalysisEsil *esil, const char *str, ut64 *num) {
38  if (!esil || !str) {
39  return false;
40  }
41  if (IS_DIGIT(*str)) {
42  if (num) {
43  *num = rz_num_get(NULL, str);
44  }
45  return true;
46  }
47  if (num) {
48  *num = 0;
49  }
50  return false;
51 }
52 
53 static bool ispackedreg(RzAnalysisEsil *esil, const char *str) {
54  RzRegItem *ri = rz_reg_get(esil->analysis->reg, str, -1);
55  return ri ? ri->packed_size > 0 : false;
56 }
57 
58 static bool isregornum(RzAnalysisEsil *esil, const char *str, ut64 *num) {
59  if (!rz_analysis_esil_reg_read(esil, str, num, NULL)) {
60  if (!isnum(esil, str, num)) {
61  return false;
62  }
63  }
64  return true;
65 }
66 
67 /* pop Register or Number */
68 static bool popRN(RzAnalysisEsil *esil, ut64 *n) {
69  char *str = rz_analysis_esil_pop(esil);
70  if (str) {
71  bool ret = isregornum(esil, str, n);
72  free(str);
73  return ret;
74  }
75  return false;
76 }
77 
78 /* RZ_ANALYSIS_ESIL API */
79 
80 static void esil_ops_free(HtPPKv *kv) {
81  free(kv->key);
82  free(kv->value);
83 }
84 
85 RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize) {
87  if (!esil) {
88  return NULL;
89  }
90  if (stacksize < 3) {
91  free(esil);
92  return NULL;
93  }
94  if (!(esil->stack = calloc(sizeof(char *), stacksize))) {
95  free(esil);
96  return NULL;
97  }
98  esil->verbose = false;
99  esil->stacksize = stacksize;
101  esil->ops = ht_pp_new(NULL, esil_ops_free, NULL);
102  esil->iotrap = iotrap;
105  esil->addrmask = genmask(addrsize - 1);
107  return esil;
108 }
109 
111  rz_return_val_if_fail(code && RZ_STR_ISNOTEMPTY(op) && esil && esil->ops, false);
112  RzAnalysisEsilOp *eop = ht_pp_find(esil->ops, op, NULL);
113  if (!eop) {
114  eop = RZ_NEW(RzAnalysisEsilOp);
115  if (!eop) {
116  RZ_LOG_ERROR("Cannot allocate esil-operation %s\n", op);
117  return false;
118  }
119  if (!ht_pp_insert(esil->ops, op, eop)) {
120  RZ_LOG_ERROR("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 
132 static bool rz_analysis_esil_fire_trap(RzAnalysisEsil *esil, int trap_type, int trap_code) {
133  rz_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->analysis) {
140  RzAnalysisPlugin *ap = esil->analysis->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
149  icb = (RzAnalysisEsilTrapCB)sdb_ptr_get (esil->traps, i, 0);
150  return icb (esil, trap_type, trap_code);
151 #endif
152  return false;
153 }
154 
156  if (esil) {
157  esil->address = addr;
158  return true;
159  }
160  return false;
161 }
162 
164  if (!esil) {
165  return;
166  }
167  if (esil->analysis && esil == esil->analysis->esil) {
168  esil->analysis->esil = NULL;
169  }
170  ht_pp_free(esil->ops);
171  esil->ops = NULL;
174  sdb_free(esil->stats);
175  esil->stats = NULL;
177  free(esil->stack);
178  if (esil->analysis && esil->analysis->cur && esil->analysis->cur->esil_fini) {
179  esil->analysis->cur->esil_fini(esil);
180  }
183  esil->trace = NULL;
184  free(esil->cmd_intr);
185  free(esil->cmd_trap);
186  free(esil->cmd_mdev);
187  free(esil->cmd_todo);
188  free(esil->cmd_step);
189  free(esil->cmd_step_out);
190  free(esil->cmd_ioer);
191  free(esil);
192 }
193 
194 static ut8 esil_internal_sizeof_reg(RzAnalysisEsil *esil, const char *r) {
195  rz_return_val_if_fail(esil && esil->analysis && esil->analysis->reg && r, 0);
196  RzRegItem *ri = rz_reg_get(esil->analysis->reg, r, -1);
197  return ri ? ri->size : 0;
198 }
199 
200 static bool alignCheck(RzAnalysisEsil *esil, ut64 addr) {
202  return !(dataAlign > 0 && addr % dataAlign);
203 }
204 
206  rz_return_val_if_fail(esil && esil->analysis && esil->analysis->iob.io, 0);
207 
208  addr &= esil->addrmask;
209  if (!alignCheck(esil, addr)) {
211  esil->trap_code = addr;
212  return false;
213  }
214  if (esil->cmd_mdev && esil->mdev_range) {
215  if (rz_str_range_in(esil->mdev_range, addr)) {
216  if (esil->cmd(esil, esil->cmd_mdev, addr, 0)) {
217  return true;
218  }
219  }
220  }
221  // TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
222  (void)esil->analysis->iob.read_at(esil->analysis->iob.io, addr, buf, len);
223  // check if request address is mapped , if don't fire trap and esil ioer callback
224  // now with siol, read_at return true/false can't be used to check error vs len
225  if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
226  if (esil->iotrap) {
228  esil->trap_code = addr;
229  }
230  if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
231  esil->cmd(esil, esil->cmd_ioer, esil->address, 0);
232  }
233  }
234  return len;
235 }
236 
238  rz_return_val_if_fail(esil && esil->analysis && esil->analysis->iob.io, 0);
239 
240  addr &= esil->addrmask;
241  if (!alignCheck(esil, addr)) {
243  esil->trap_code = addr;
244  return false;
245  }
246  // TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
247  (void)esil->analysis->iob.read_at(esil->analysis->iob.io, addr, buf, len);
248  // check if request address is mapped , if don't fire trap and esil ioer callback
249  // now with siol, read_at return true/false can't be used to check error vs len
250  if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
251  if (esil->iotrap) {
253  esil->trap_code = addr;
254  }
255  }
256  return len;
257 }
258 
260  int ret = 0;
261  rz_return_val_if_fail(buf && esil, 0);
262  addr &= esil->addrmask;
263  if (esil->cb.hook_mem_read) {
264  ret = esil->cb.hook_mem_read(esil, addr, buf, len);
265  }
266  if (!alignCheck(esil, addr)) {
268  esil->trap_code = addr;
269  return false;
270  }
271  if (!ret && esil->cb.mem_read) {
272  ret = esil->cb.mem_read(esil, addr, buf, len);
273  if (ret != len) {
274  if (esil->iotrap) {
276  esil->trap_code = addr;
277  }
278  }
279  }
280  return ret;
281 }
282 
283 static int internal_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
284  int ret = 0;
285  if (!esil || !esil->analysis || !esil->analysis->iob.io || esil->nowrite) {
286  return 0;
287  }
288  addr &= esil->addrmask;
289  if (!alignCheck(esil, addr)) {
291  esil->trap_code = addr;
292  return false;
293  }
294  if (esil->cmd_mdev && esil->mdev_range) {
295  if (rz_str_range_in(esil->mdev_range, addr)) {
296  if (esil->cmd(esil, esil->cmd_mdev, addr, 1)) {
297  return true;
298  }
299  }
300  }
301  if (esil->analysis->iob.write_at(esil->analysis->iob.io, addr, buf, len)) {
302  ret = len;
303  }
304  // check if request address is mapped , if don't fire trap and esil ioer callback
305  // now with siol, write_at return true/false can't be used to check error vs len
306  if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
307  if (esil->iotrap) {
309  esil->trap_code = addr;
310  }
311  if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
312  esil->cmd(esil, esil->cmd_ioer, esil->address, 0);
313  }
314  }
315  return ret;
316 }
317 
319  int ret = 0;
320  if (!esil || !esil->analysis || !esil->analysis->iob.io || !addr) {
321  return 0;
322  }
323  if (esil->nowrite) {
324  return 0;
325  }
326  addr &= esil->addrmask;
327  if (esil->analysis->iob.write_at(esil->analysis->iob.io, addr, buf, len)) {
328  ret = len;
329  }
330  // check if request address is mapped , if don't fire trap and esil ioer callback
331  // now with siol, write_at return true/false can't be used to check error vs len
332  if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
333  if (esil->iotrap) {
335  esil->trap_code = addr;
336  }
337  }
338  return ret;
339 }
340 
342  int ret = 0;
343  if (!buf || !esil) {
344  return 0;
345  }
346  addr &= esil->addrmask;
347  if (esil->cb.hook_mem_write) {
348  ret = esil->cb.hook_mem_write(esil, addr, buf, len);
349  }
350  if (!ret && esil->cb.mem_write) {
351  ret = esil->cb.mem_write(esil, addr, buf, len);
352  }
353  return ret;
354 }
355 
356 static int internal_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size) {
357  RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
358  if (reg) {
359  if (size) {
360  *size = reg->size;
361  }
362  if (num) {
363  *num = rz_reg_get_value(esil->analysis->reg, reg);
364  }
365  return true;
366  }
367  return false;
368 }
369 
370 static int internal_esil_reg_write(RzAnalysisEsil *esil, const char *regname, ut64 num) {
371  if (esil && esil->analysis) {
372  RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
373  if (reg) {
374  rz_reg_set_value(esil->analysis->reg, reg, num);
375  return true;
376  }
377  }
378  return false;
379 }
380 
382  rz_return_val_if_fail(esil && esil->analysis && esil->analysis->reg, false);
383 
384  RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
385  const char *pc = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_PC);
386  const char *sp = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_SP);
387  const char *bp = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_BP);
388 
389  if (!pc) {
390  RZ_LOG_WARN("RzReg profile does not contain PC register\n");
391  return false;
392  }
393  if (!sp) {
394  RZ_LOG_WARN("RzReg profile does not contain SP register\n");
395  return false;
396  }
397  if (!bp) {
398  RZ_LOG_WARN("RzReg profile does not contain BP register\n");
399  return false;
400  }
401  if (reg && reg->name && ((strcmp(reg->name, pc) && strcmp(reg->name, sp) && strcmp(reg->name, bp)) || num)) { // I trust k-maps
402  rz_reg_set_value(esil->analysis->reg, reg, num);
403  return true;
404  }
405  return false;
406 }
407 
409  char str[64];
410  snprintf(str, sizeof(str) - 1, "0x%" PFMT64x, num);
411  return rz_analysis_esil_push(esil, str);
412 }
413 
414 RZ_API bool rz_analysis_esil_push(RzAnalysisEsil *esil, const char *str) {
415  if (!str || !esil || !*str || esil->stackptr > (esil->stacksize - 1)) {
416  return false;
417  }
418  esil->stack[esil->stackptr++] = strdup(str);
419  return true;
420 }
421 
424  if (esil->stackptr < 1) {
425  return NULL;
426  }
427  return esil->stack[--esil->stackptr];
428 }
429 
431  int len, i;
432 
433  if (!str || !(len = strlen(str))) {
435  }
436  if (!strncmp(str, "0x", 2)) {
438  }
439  if (!((IS_DIGIT(str[0])) || str[0] == '-')) {
440  goto not_a_number;
441  }
442  for (i = 1; i < len; i++) {
443  if (!(IS_DIGIT(str[i]))) {
444  goto not_a_number;
445  }
446  }
448 not_a_number:
449  if (rz_reg_get(esil->analysis->reg, str, -1)) {
451  }
453 }
454 
456  if (!str || !*str) {
457  return false;
458  }
459  int parm_type = rz_analysis_esil_get_parm_type(esil, str);
460  if (!num || !esil) {
461  return false;
462  }
463  switch (parm_type) {
465  *num = rz_num_get(NULL, str);
466  if (size) {
467  *size = esil->analysis->bits;
468  }
469  return true;
471  if (!rz_analysis_esil_reg_read(esil, str, num, size)) {
472  break;
473  }
474  return true;
475  default:
476  ESIL_LOG("Invalid arg (%s)\n", str);
477  esil->parse_stop = 1;
478  break;
479  }
480  return false;
481 }
482 
484  return rz_analysis_esil_get_parm_size(esil, str, num, NULL);
485 }
486 
488  int ret = 0;
489  if (esil && esil->cb.hook_reg_write) {
490  ret = esil->cb.hook_reg_write(esil, dst, &num);
491  }
492  if (!ret && esil && esil->cb.reg_write) {
493  ret = esil->cb.reg_write(esil, dst, num);
494  }
495  return ret;
496 }
497 
499  int ret;
500  void *old_hook_reg_read = (void *)esil->cb.hook_reg_read;
501  esil->cb.hook_reg_read = NULL;
502  ret = rz_analysis_esil_reg_read(esil, regname, num, size);
503  esil->cb.hook_reg_read = old_hook_reg_read;
504  return ret;
505 }
506 
508  bool ret = false;
509  ut64 localnum; // XXX why is this necessary?
510  if (!esil || !regname) {
511  return false;
512  }
513  if (!num) {
514  num = &localnum;
515  }
516  *num = 0LL;
517  if (size) {
518  *size = esil->analysis->bits;
519  }
520  if (esil->cb.hook_reg_read) {
521  ret = esil->cb.hook_reg_read(esil, regname, num, size);
522  }
523  if (!ret && esil->cb.reg_read) {
524  ret = esil->cb.reg_read(esil, regname, num, size);
525  }
526  return ret;
527 }
528 
530  bool ret = false;
531  ut64 src, dst;
532 
533  char *p_src = rz_analysis_esil_pop(esil);
534  if (!p_src) {
535  return false;
536  }
537 
538  if (!rz_analysis_esil_get_parm(esil, p_src, &src)) {
539  ESIL_LOG("esil_of: empty stack\n");
540  free(p_src);
541  return false;
542  }
543 
544  char *p_dst = rz_analysis_esil_pop(esil);
545  if (!p_dst) {
546  free(p_src);
547  return false;
548  }
549 
550  if (!rz_analysis_esil_get_parm(esil, p_dst, &dst)) {
551  ESIL_LOG("esil_of: empty stack\n");
552  free(p_dst);
553  free(p_src);
554  return false;
555  } else {
556  free(p_dst);
557  }
558 
559  // Make sure the other bits are 0
560  src &= UT64_MAX >> (64 - dst);
561 
562  ut64 m = 0;
563  if (dst < 64) {
564  m = 1ULL << (dst - 1);
565  }
566 
567  // dst = (dst & ((1U << src_bit) - 1)); // clear upper bits
568  if (assign) {
569  ret = rz_analysis_esil_reg_write(esil, p_src, ((src ^ m) - m));
570  } else {
571  ret = rz_analysis_esil_pushnum(esil, ((src ^ m) - m));
572  }
573 
574  free(p_src);
575  return ret;
576 }
577 
578 // sign extension operator for use in idiv, imul, movsx*
579 // and other instructions involving signed values, extends n bit value to 64 bit value
580 // example : >"ae 8,0x81,~" ( <src bit width>,<value>,~ )
581 // output : 0xffffffffffffff81
582 static bool esil_signext(RzAnalysisEsil *esil) {
583  return rz_analysis_esil_signext(esil, false);
584 }
585 
586 // sign extension assignement
587 // example : > "ae 0x81,a0,="
588 // > "ae 8,a0,~=" ( <src bit width>,register,~= )
589 // output : > ar a0
590 // 0xffffff81
591 static bool esil_signexteq(RzAnalysisEsil *esil) {
592  return rz_analysis_esil_signext(esil, true);
593 }
594 
595 static bool esil_zf(RzAnalysisEsil *esil) {
596  return rz_analysis_esil_pushnum(esil, !(esil->cur & genmask(esil->lastsz - 1)));
597 }
598 
599 // checks if there was a carry from bit x (x,$c)
600 static bool esil_cf(RzAnalysisEsil *esil) {
601  char *src = rz_analysis_esil_pop(esil);
602 
603  if (!src) {
604  return false;
605  }
606 
608  free(src);
609  return false;
610  }
611  ut64 bit;
613  free(src);
614  // carry from bit <src>
615  // range of src goes from 0 to 63
616  //
617  // implements bit mod 64
618  const ut64 mask = genmask(bit & 0x3f);
619  return rz_analysis_esil_pushnum(esil, (esil->cur & mask) < (esil->old & mask));
620 }
621 
622 // checks if there was a borrow from bit x (x,$b)
623 static bool esil_bf(RzAnalysisEsil *esil) {
624  char *src = rz_analysis_esil_pop(esil);
625 
626  if (!src) {
627  return false;
628  }
629 
631  free(src);
632  return false;
633  }
634  ut64 bit;
636  free(src);
637  // borrow from bit <src>
638  // range of src goes from 1 to 64
639  // you cannot borrow from bit 0, bc bit -1 cannot not exist
640  //
641  // implements (bit - 1) mod 64
642  const ut64 mask = genmask((bit + 0x3f) & 0x3f);
643  return rz_analysis_esil_pushnum(esil, (esil->old & mask) < (esil->cur & mask));
644 }
645 
646 static bool esil_pf(RzAnalysisEsil *esil) {
647  // Set if the number of set bits in the least significant _byte_ is a multiple of 2.
648  // - Taken from: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits
649  const ut64 c1 = 0x0101010101010101ULL;
650  const ut64 c2 = 0x8040201008040201ULL;
651  const ut64 c3 = 0x1FF;
652  // Take only the least significant byte.
653  ut64 lsb = esil->cur & 0xff;
654  return rz_analysis_esil_pushnum(esil, !((((lsb * c1) & c2) % c3) & 1));
655 }
656 
657 // like carry
658 // checks overflow from bit x (x,$o)
659 // x,$o ===> x,$c,x-1,$c,^
660 static bool esil_of(RzAnalysisEsil *esil) {
661  char *p_bit = rz_analysis_esil_pop(esil);
662 
663  if (!p_bit) {
664  return false;
665  }
666 
668  free(p_bit);
669  return false;
670  }
671  ut64 bit;
672 
673  if (!rz_analysis_esil_get_parm(esil, p_bit, &bit)) {
674  ESIL_LOG("esil_of: empty stack\n");
675  free(p_bit);
676  return false;
677  }
678  free(p_bit);
679 
680  const ut64 m[2] = { genmask(bit & 0x3f), genmask((bit + 0x3f) & 0x3f) };
681  const ut64 result = ((esil->cur & m[0]) < (esil->old & m[0])) ^ ((esil->cur & m[1]) < (esil->old & m[1]));
682  ut64 res = rz_analysis_esil_pushnum(esil, result);
683  return res;
684 }
685 
686 // checks sign bit at x (x,$s)
687 static bool esil_sf(RzAnalysisEsil *esil) {
688  rz_return_val_if_fail(esil, false);
689 
690  char *p_size = rz_analysis_esil_pop(esil);
691  rz_return_val_if_fail(p_size, false);
692 
694  free(p_size);
695  return false;
696  }
697  ut64 size, num;
698  rz_analysis_esil_get_parm(esil, p_size, &size);
699  free(p_size);
700 
701  if (size > 63) {
702  num = 0;
703  } else {
704  num = (esil->cur >> size) & 1;
705  }
706  ut64 res = rz_analysis_esil_pushnum(esil, num);
707  return res;
708 }
709 
710 static bool esil_ds(RzAnalysisEsil *esil) {
711  rz_return_val_if_fail(esil, false);
712  return rz_analysis_esil_pushnum(esil, esil->delay);
713 }
714 
715 static bool esil_jt(RzAnalysisEsil *esil) {
716  rz_return_val_if_fail(esil, false);
717  return rz_analysis_esil_pushnum(esil, esil->jump_target);
718 }
719 
720 static bool esil_js(RzAnalysisEsil *esil) {
721  rz_return_val_if_fail(esil, false);
722  return rz_analysis_esil_pushnum(esil, esil->jump_target_set);
723 }
724 
725 // TODO: this should be deprecated because it is not accurate
726 static bool esil_rs(RzAnalysisEsil *esil) {
727  rz_return_val_if_fail(esil && esil->analysis, false);
728  return rz_analysis_esil_pushnum(esil, esil->analysis->bits >> 3);
729 }
730 
731 // TODO: this should be deprecated because plugins should know their current address
732 static bool esil_address(RzAnalysisEsil *esil) {
733  rz_return_val_if_fail(esil, false);
734  return rz_analysis_esil_pushnum(esil, esil->address);
735 }
736 
737 static bool esil_weak_eq(RzAnalysisEsil *esil) {
738  rz_return_val_if_fail(esil && esil->analysis, false);
739  char *dst = rz_analysis_esil_pop(esil);
740  char *src = rz_analysis_esil_pop(esil);
741 
743  free(dst);
744  free(src);
745  return false;
746  }
747 
748  ut64 src_num;
749  if (rz_analysis_esil_get_parm(esil, src, &src_num)) {
750  (void)rz_analysis_esil_reg_write(esil, dst, src_num);
751  free(src);
752  free(dst);
753  return true;
754  }
755 
756  free(src);
757  free(dst);
758  return false;
759 }
760 
761 static bool esil_eq(RzAnalysisEsil *esil) {
762  bool ret = false;
763  ut64 num, num2;
764  char *dst = rz_analysis_esil_pop(esil);
765  char *src = rz_analysis_esil_pop(esil);
766  if (!src || !dst) {
767  ESIL_LOG("Missing elements in the esil stack for '=' at 0x%08" PFMT64x "\n", esil->address);
768  free(src);
769  free(dst);
770  return false;
771  }
772  if (ispackedreg(esil, dst)) {
773  char *src2 = rz_analysis_esil_pop(esil);
774  char *newreg = rz_str_newf("%sl", dst);
775  if (rz_analysis_esil_get_parm(esil, src2, &num2)) {
776  ret = rz_analysis_esil_reg_write(esil, newreg, num2);
777  }
778  free(newreg);
779  free(src2);
780  goto beach;
781  }
782 
783  if (src && dst && rz_analysis_esil_reg_read_nocallback(esil, dst, &num, NULL)) {
784  if (rz_analysis_esil_get_parm(esil, src, &num2)) {
785  ret = rz_analysis_esil_reg_write(esil, dst, num2);
786  esil->cur = num2;
787  esil->old = num;
788  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
789  } else {
790  ESIL_LOG("esil_eq: invalid src\n");
791  }
792  } else {
793  ESIL_LOG("esil_eq: invalid parameters\n");
794  }
795 
796 beach:
797  free(src);
798  free(dst);
799  return ret;
800 }
801 
802 static bool esil_neg(RzAnalysisEsil *esil) {
803  bool ret = false;
804  char *src = rz_analysis_esil_pop(esil);
805  if (src) {
806  ut64 num;
807  if (rz_analysis_esil_get_parm(esil, src, &num)) {
809  ret = true;
810  } else {
811  if (isregornum(esil, src, &num)) {
812  ret = true;
814  } else {
815  RZ_LOG_ERROR("0x%08" PFMT64x " esil_neg: unknown reg %s\n", esil->address, src);
816  }
817  }
818  } else {
819  ESIL_LOG("esil_neg: empty stack\n");
820  }
821  free(src);
822  return ret;
823 }
824 
825 static bool esil_negeq(RzAnalysisEsil *esil) {
826  bool ret = false;
827  ut64 num;
828  char *src = rz_analysis_esil_pop(esil);
829  if (src && rz_analysis_esil_reg_read(esil, src, &num, NULL)) {
830  num = !num;
832  ret = true;
833  } else {
834  ESIL_LOG("esil_negeq: empty stack\n");
835  }
836  free(src);
837  // rz_analysis_esil_pushnum (esil, ret);
838  return ret;
839 }
840 
841 static bool esil_nop(RzAnalysisEsil *esil) {
842  return true;
843 }
844 
845 static bool esil_andeq(RzAnalysisEsil *esil) {
846  bool ret = false;
847  ut64 num, num2;
848  char *dst = rz_analysis_esil_pop(esil);
849  char *src = rz_analysis_esil_pop(esil);
850  if (dst && rz_analysis_esil_reg_read(esil, dst, &num, NULL)) {
851  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
852  esil->old = num;
853  esil->cur = num & num2;
854  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
855  rz_analysis_esil_reg_write(esil, dst, num & num2);
856  ret = true;
857  } else {
858  ESIL_LOG("esil_andeq: empty stack\n");
859  }
860  }
861  free(src);
862  free(dst);
863  return ret;
864 }
865 
866 static bool esil_oreq(RzAnalysisEsil *esil) {
867  bool ret = false;
868  ut64 num, num2;
869  char *dst = rz_analysis_esil_pop(esil);
870  char *src = rz_analysis_esil_pop(esil);
871  if (dst && rz_analysis_esil_reg_read(esil, dst, &num, NULL)) {
872  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
873  esil->old = num;
874  esil->cur = num | num2;
875  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
876  ret = rz_analysis_esil_reg_write(esil, dst, num | num2);
877  } else {
878  ESIL_LOG("esil_ordeq: empty stack\n");
879  }
880  }
881  free(src);
882  free(dst);
883  return ret;
884 }
885 
886 static bool esil_xoreq(RzAnalysisEsil *esil) {
887  bool ret = false;
888  ut64 num, num2;
889  char *dst = rz_analysis_esil_pop(esil);
890  char *src = rz_analysis_esil_pop(esil);
891  if (dst && rz_analysis_esil_reg_read(esil, dst, &num, NULL)) {
892  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
893  esil->old = num;
894  esil->cur = num ^ num2;
895  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
896  ret = rz_analysis_esil_reg_write(esil, dst, num ^ num2);
897  } else {
898  ESIL_LOG("esil_xoreq: empty stack\n");
899  }
900  }
901  free(src);
902  free(dst);
903  return ret;
904 }
905 
906 #if 0
907 static int esil_interrupt_linux_i386(RzAnalysisEsil *esil) { //move this into a plugin
908  ut32 sn, ret = 0;
909  char *usn = rz_analysis_esil_pop (esil);
910  if (usn) {
911  sn = (ut32) rz_num_get (NULL, usn);
912  } else sn = 0x80;
913 
914  if (sn == 3) {
915  // trap
917  esil->trap_code = 3;
918  return -1;
919  }
920 
921  if (sn != 0x80) {
922  RZ_LOG_ERROR("Interrupt 0x%x not handled.", sn);
924  esil->trap_code = sn;
925  return -1;
926  }
927 #undef r
928 #define r(x) rz_reg_getv(esil->analysis->reg, "##x##")
929 #undef rs
930 #define rs(x, y) rz_reg_setv(esil->analysis->reg, "##x##", y)
931  switch (r(eax)) {
932  case 1:
933  printf ("exit(%d)\n", (int)r(ebx));
934  rs(eax, -1);
935  // never return. stop execution somehow, throw an exception
936  break;
937  case 3:
938  ret = r(edx);
939  printf ("ret:%d = read(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
940  (int)ret, r(ebx), r(ecx), r(edx));
941  rs(eax, ret);
942  break;
943  case 4:
944  ret = r(edx);
945  printf ("ret:%d = write(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
946  (int)ret, r(ebx), r(ecx), r(edx));
947  rs(eax, ret);
948  break;
949  case 5:
950  ret = -1;
951  printf ("fd:%d = open(file:0x%08"PFMT64x", mode:%"PFMT64d", perm:%"PFMT64d")\n",
952  (int)ret, r(ebx), r(ecx), r(edx));
953  rs(eax, ret);
954  break;
955  }
956 #undef r
957 #undef rs
958  return 0;
959 }
960 #endif
961 
962 static bool esil_trap(RzAnalysisEsil *esil) {
963  ut64 s, d;
964  if (popRN(esil, &s) && popRN(esil, &d)) {
965  esil->trap = s;
966  esil->trap_code = d;
967  return rz_analysis_esil_fire_trap(esil, (int)s, (int)d);
968  }
969  ESIL_LOG("esil_trap: missing parameters in stack\n");
970  return false;
971 }
972 
973 static bool esil_bits(RzAnalysisEsil *esil) {
974  ut64 s;
975  if (popRN(esil, &s)) {
976  if (esil->analysis && esil->analysis->coreb.setab) {
977  esil->analysis->coreb.setab(esil->analysis->coreb.core, NULL, s);
978  }
979  return true;
980  }
981  ESIL_LOG("esil_bits: missing parameters in stack\n");
982  return false;
983 }
984 
985 static bool esil_interrupt(RzAnalysisEsil *esil) {
986  ut64 interrupt;
987  if (popRN(esil, &interrupt)) {
988  return rz_analysis_esil_fire_interrupt(esil, (ut32)interrupt);
989  }
990  return false;
991 }
992 
993 // This function also sets internal vars which is used in flag calculations.
994 static bool esil_cmp(RzAnalysisEsil *esil) {
995  ut64 num, num2;
996  bool ret = false;
997  char *dst = rz_analysis_esil_pop(esil);
998  char *src = rz_analysis_esil_pop(esil);
999  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1000  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1001  esil->old = num;
1002  esil->cur = num - num2;
1003  ret = true;
1004  if (rz_reg_get(esil->analysis->reg, dst, -1)) {
1005  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1006  } else if (rz_reg_get(esil->analysis->reg, src, -1)) {
1007  esil->lastsz = esil_internal_sizeof_reg(esil, src);
1008  } else {
1009  // default size is set to 64 as internally operands are ut64
1010  esil->lastsz = 64;
1011  }
1012  }
1013  }
1014  free(dst);
1015  free(src);
1016  return ret;
1017 }
1018 
1019 #if 0
1020 x86 documentation:
1021 CF - carry flag -- Set on high-order bit carry or borrow; cleared otherwise
1022  num>>63
1023 PF - parity flag
1024  (num&0xff)
1025  Set if low-order eight bits of result contain an even number of "1" bits; cleared otherwise
1026 ZF - zero flags
1027  Set if result is zero; cleared otherwise
1028  zf = num?0:1;
1029 SF - sign flag
1030  Set equal to high-order bit of result (0 if positive 1 if negative)
1031  sf = ((st64)num)<0)?1:0;
1032 OF - overflow flag
1033  if (a>0&&b>0 && (a+b)<0)
1034  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
1035 
1036 JBE: CF = 1 || ZF = 1
1037 
1038 #endif
1039 
1040 /*
1041  * Expects a string in the stack. Each char of the string represents a CPU flag.
1042  * Those relations are associated by the CPU itself and are used to move values
1043  * from the internal ESIL into the RzReg instance.
1044  *
1045  * For example:
1046  * zco,?= # update zf, cf and of
1047  *
1048  * If we want to update the esil value of a specific flag we use the =? command
1049  *
1050  * zf,z,=? # esil[zf] = rz_reg[zf]
1051  *
1052  * Defining new cpu flags
1053  */
1054 #if 0
1055 static int esil_ifset(RzAnalysisEsil *esil) {
1056  char *s, *src = rz_analysis_esil_pop (esil);
1057  for (s=src; *s; s++) {
1058  switch (*s) {
1059  case 'z':
1060  rz_analysis_esil_reg_write (esil, "zf", RZ_BIT_CHK(&esil->flags, FLG(ZERO)));
1061  break;
1062  case 'c':
1063  rz_analysis_esil_reg_write (esil, "cf", RZ_BIT_CHK(&esil->flags, FLG(CARRY)));
1064  break;
1065  case 'o':
1066  rz_analysis_esil_reg_write (esil, "of", RZ_BIT_CHK(&esil->flags, FLG(OVERFLOW)));
1067  break;
1068  case 'p':
1069  rz_analysis_esil_reg_write (esil, "pf", RZ_BIT_CHK(&esil->flags, FLG(PARITY)));
1070  break;
1071  }
1072  }
1073  free (src);
1074  return 0;
1075 }
1076 #endif
1077 
1078 static bool esil_if(RzAnalysisEsil *esil) {
1079  bool ret = false;
1080  ut64 num = 0LL;
1081  if (esil->skip) {
1082  esil->skip++;
1083  return true;
1084  }
1085  char *src = rz_analysis_esil_pop(esil);
1086  if (src && rz_analysis_esil_get_parm(esil, src, &num)) {
1087  // condition not matching, skipping until
1088  if (!num) {
1089  esil->skip++;
1090  }
1091  ret = true;
1092  }
1093  free(src);
1094  return ret;
1095 }
1096 
1097 static bool esil_lsl(RzAnalysisEsil *esil) {
1098  bool ret = false;
1099  ut64 num, num2;
1100  char *dst = rz_analysis_esil_pop(esil);
1101  char *src = rz_analysis_esil_pop(esil);
1102  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1103  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1104  if (num2 > sizeof(ut64) * 8) {
1105  ESIL_LOG("esil_lsl: shift is too big\n");
1106  } else {
1107  if (num2 > 63) {
1108  rz_analysis_esil_pushnum(esil, 0);
1109  } else {
1110  rz_analysis_esil_pushnum(esil, num << num2);
1111  }
1112  ret = true;
1113  }
1114  } else {
1115  ESIL_LOG("esil_lsl: empty stack\n");
1116  }
1117  }
1118  free(src);
1119  free(dst);
1120  return ret;
1121 }
1122 
1123 static bool esil_lsleq(RzAnalysisEsil *esil) {
1124  bool ret = false;
1125  ut64 num, num2;
1126  char *dst = rz_analysis_esil_pop(esil);
1127  char *src = rz_analysis_esil_pop(esil);
1128  if (dst && rz_analysis_esil_reg_read(esil, dst, &num, NULL)) {
1129  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1130  if (num2 > sizeof(ut64) * 8) {
1131  ESIL_LOG("esil_lsleq: shift is too big\n");
1132  } else {
1133  esil->old = num;
1134  if (num2 > 63) {
1135  num = 0;
1136  } else {
1137  num <<= num2;
1138  }
1139  esil->cur = num;
1140  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1142  ret = true;
1143  }
1144  } else {
1145  ESIL_LOG("esil_lsleq: empty stack\n");
1146  }
1147  }
1148  free(src);
1149  free(dst);
1150  return ret;
1151 }
1152 
1153 static bool esil_lsr(RzAnalysisEsil *esil) {
1154  bool ret = false;
1155  ut64 num, num2;
1156  char *dst = rz_analysis_esil_pop(esil);
1157  char *src = rz_analysis_esil_pop(esil);
1158  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1159  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1160  ut64 res = num >> RZ_MIN(num2, 63);
1161  rz_analysis_esil_pushnum(esil, res);
1162  ret = true;
1163  } else {
1164  ESIL_LOG("esil_lsr: empty stack\n");
1165  }
1166  }
1167  free(src);
1168  free(dst);
1169  return ret;
1170 }
1171 
1172 static bool esil_lsreq(RzAnalysisEsil *esil) {
1173  bool ret = false;
1174  ut64 num, num2;
1175  char *dst = rz_analysis_esil_pop(esil);
1176  char *src = rz_analysis_esil_pop(esil);
1177  if (dst && rz_analysis_esil_reg_read(esil, dst, &num, NULL)) {
1178  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1179  if (num2 > 63) {
1180  ESIL_LOG("Invalid shift at 0x%08" PFMT64x "\n", esil->address);
1181  num2 = 63;
1182  }
1183  esil->old = num;
1184  num >>= num2;
1185  esil->cur = num;
1186  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1188  ret = true;
1189  } else {
1190  ESIL_LOG("esil_lsreq: empty stack\n");
1191  }
1192  }
1193  free(src);
1194  free(dst);
1195  return ret;
1196 }
1197 
1198 static bool esil_asreq(RzAnalysisEsil *esil) {
1199  bool ret = false;
1200  int regsize = 0;
1201  ut64 op_num, param_num;
1202  char *op = rz_analysis_esil_pop(esil);
1203  char *param = rz_analysis_esil_pop(esil);
1204  if (op && rz_analysis_esil_get_parm_size(esil, op, &op_num, &regsize)) {
1205  if (param && rz_analysis_esil_get_parm(esil, param, &param_num)) {
1206  ut64 mask = (regsize - 1);
1207  param_num &= mask;
1208  bool isNegative;
1209  if (regsize == 32) {
1210  isNegative = ((st32)op_num) < 0;
1211  st32 snum = op_num;
1212  op_num = snum;
1213  } else {
1214  isNegative = ((st64)op_num) < 0;
1215  }
1216  if (isNegative) {
1217  if (regsize == 32) {
1218  op_num = -(st64)op_num;
1219  if (op_num >> param_num) {
1220  op_num >>= param_num;
1221  op_num = -(st64)op_num;
1222  } else {
1223  op_num = -1;
1224  }
1225  } else {
1226  ut64 mask = (regsize - 1);
1227  param_num &= mask;
1228  ut64 left_bits = 0;
1229  int shift = regsize - 1;
1230  if (shift < 0 || shift > regsize - 1) {
1231  ESIL_LOG("Invalid asreq shift of %d at 0x%" PFMT64x "\n", shift, esil->address);
1232  shift = 0;
1233  }
1234  if (param_num > regsize - 1) {
1235  // capstone bug?
1236  ESIL_LOG("Invalid asreq shift of %" PFMT64d " at 0x%" PFMT64x "\n", param_num, esil->address);
1237  param_num = 30;
1238  }
1239  if (shift >= 63) {
1240  // LL can't handle LShift of 63 or more
1241  ESIL_LOG("Invalid asreq shift of %d at 0x%08" PFMT64x "\n", shift, esil->address);
1242  } else if (op_num & (1LL << shift)) {
1243  left_bits = (1 << param_num) - 1;
1244  left_bits <<= regsize - param_num;
1245  }
1246  op_num = left_bits | (op_num >> param_num);
1247  }
1248  } else {
1249  op_num >>= param_num;
1250  }
1251  ut64 res = op_num;
1252  esil->cur = res;
1253  esil->lastsz = esil_internal_sizeof_reg(esil, op);
1254  rz_analysis_esil_reg_write(esil, op, res);
1255  // rz_analysis_esil_pushnum (esil, res);
1256  ret = true;
1257  } else {
1258  ESIL_LOG("esil_asr: empty stack\n");
1259  }
1260  }
1261  free(param);
1262  free(op);
1263  return ret;
1264 }
1265 
1266 static bool esil_asr(RzAnalysisEsil *esil) {
1267  bool ret = false;
1268  int regsize = 0;
1269  ut64 op_num = 0, param_num = 0;
1270  char *op = rz_analysis_esil_pop(esil);
1271  char *param = rz_analysis_esil_pop(esil);
1272  if (op && rz_analysis_esil_get_parm_size(esil, op, &op_num, &regsize)) {
1273  if (param && rz_analysis_esil_get_parm(esil, param, &param_num)) {
1274  if (param_num > regsize - 1) {
1275  // capstone bug?
1276  ESIL_LOG("Invalid asr shift of %" PFMT64d " at 0x%" PFMT64x "\n", param_num, esil->address);
1277  param_num = 30;
1278  }
1279  bool isNegative;
1280  if (regsize == 32) {
1281  isNegative = ((st32)op_num) < 0;
1282  st32 snum = op_num;
1283  op_num = snum;
1284  } else {
1285  isNegative = ((st64)op_num) < 0;
1286  }
1287  if (isNegative) {
1288  ut64 mask = (regsize - 1);
1289  param_num &= mask;
1290  ut64 left_bits = 0;
1291  if (op_num & (1ULL << (regsize - 1))) {
1292  left_bits = (1ULL << param_num) - 1;
1293  left_bits <<= regsize - param_num;
1294  }
1295  op_num = left_bits | (op_num >> param_num);
1296  } else {
1297  op_num >>= param_num;
1298  }
1299  ut64 res = op_num;
1300  rz_analysis_esil_pushnum(esil, res);
1301  ret = true;
1302  } else {
1303  ESIL_LOG("esil_asr: empty stack\n");
1304  }
1305  }
1306  free(param);
1307  free(op);
1308  return ret;
1309 }
1310 
1311 static bool esil_ror(RzAnalysisEsil *esil) {
1312  bool ret = 0;
1313  int regsize;
1314  ut64 num, num2;
1315  char *dst = rz_analysis_esil_pop(esil);
1316  char *src = rz_analysis_esil_pop(esil);
1317  if (dst && rz_analysis_esil_get_parm_size(esil, dst, &num, &regsize)) {
1318  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1319  ut64 mask = (regsize - 1);
1320  num2 &= mask;
1321  ut64 res = (num >> num2) | (num << ((-(st64)num2) & mask));
1322  rz_analysis_esil_pushnum(esil, res);
1323  ret = true;
1324  } else {
1325  ESIL_LOG("esil_ror: empty stack\n");
1326  }
1327  }
1328  free(src);
1329  free(dst);
1330  return ret;
1331 }
1332 
1333 static bool esil_rol(RzAnalysisEsil *esil) {
1334  bool ret = 0;
1335  int regsize;
1336  ut64 num, num2;
1337  char *dst = rz_analysis_esil_pop(esil);
1338  char *src = rz_analysis_esil_pop(esil);
1339  if (dst && rz_analysis_esil_get_parm_size(esil, dst, &num, &regsize)) {
1340  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1341  ut64 mask = (regsize - 1);
1342  num2 &= mask;
1343  ut64 res = (num << num2) | (num >> ((-(st64)num2) & mask));
1344  rz_analysis_esil_pushnum(esil, res);
1345  ret = true;
1346  } else {
1347  ESIL_LOG("esil_rol: empty stack\n");
1348  }
1349  }
1350  free(src);
1351  free(dst);
1352  return ret;
1353 }
1354 
1355 static bool esil_and(RzAnalysisEsil *esil) {
1356  bool ret = false;
1357  ut64 num, num2;
1358  char *dst = rz_analysis_esil_pop(esil);
1359  char *src = rz_analysis_esil_pop(esil);
1360  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1361  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1362  num &= num2;
1364  ret = true;
1365  } else {
1366  ESIL_LOG("esil_and: empty stack\n");
1367  }
1368  }
1369  free(src);
1370  free(dst);
1371  return ret;
1372 }
1373 
1374 static bool esil_xor(RzAnalysisEsil *esil) {
1375  bool ret = false;
1376  ut64 num, num2;
1377  char *dst = rz_analysis_esil_pop(esil);
1378  char *src = rz_analysis_esil_pop(esil);
1379  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1380  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1381  num ^= num2;
1383  ret = true;
1384  } else {
1385  ESIL_LOG("esil_xor: empty stack\n");
1386  }
1387  }
1388  free(src);
1389  free(dst);
1390  return ret;
1391 }
1392 
1393 static bool esil_or(RzAnalysisEsil *esil) {
1394  bool ret = false;
1395  ut64 num, num2;
1396  char *dst = rz_analysis_esil_pop(esil);
1397  char *src = rz_analysis_esil_pop(esil);
1398  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
1399  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
1400  num |= num2;
1402  ret = true;
1403  } else {
1404  ESIL_LOG("esil_xor: empty stack\n");
1405  }
1406  }
1407  free(src);
1408  free(dst);
1409  return ret;
1410 }
1411 
1413  switch (type) {
1415  return "read-err";
1417  return "write-err";
1419  return "breakpoint";
1421  return "unhandled";
1423  return "divbyzero";
1425  return "invalid";
1427  return "unaligned";
1428  case RZ_ANALYSIS_TRAP_TODO:
1429  return "todo";
1430  default:
1431  return "unknown";
1432  }
1433 }
1434 
1435 static bool esil_break(RzAnalysisEsil *esil) {
1436  esil->parse_stop = 1;
1437  return 1;
1438 }
1439 
1440 static bool esil_clear(RzAnalysisEsil *esil) {
1441  char *r;
1442  while ((r = rz_analysis_esil_pop(esil))) {
1443  free(r);
1444  }
1445  return 1;
1446 }
1447 
1448 static bool esil_todo(RzAnalysisEsil *esil) {
1449  esil->parse_stop = 2;
1450  return 1;
1451 }
1452 
1453 static bool esil_goto(RzAnalysisEsil *esil) {
1454  ut64 num = 0;
1455  char *src = rz_analysis_esil_pop(esil);
1456  if (src && *src && rz_analysis_esil_get_parm(esil, src, &num)) {
1457  esil->parse_goto = num;
1458  }
1459  free(src);
1460  return 1;
1461 }
1462 
1463 static bool esil_repeat(RzAnalysisEsil *esil) {
1464  char *dst = rz_analysis_esil_pop(esil); // destaintion of the goto
1465  char *src = rz_analysis_esil_pop(esil); // value of the counter
1466  ut64 n, num = 0;
1467  if (rz_analysis_esil_get_parm(esil, src, &n) && rz_analysis_esil_get_parm(esil, dst, &num)) {
1468  if (n > 1) {
1469  esil->parse_goto = num;
1470  rz_analysis_esil_pushnum(esil, n - 1);
1471  }
1472  }
1473  free(dst);
1474  free(src);
1475  return 1;
1476 }
1477 
1478 static bool esil_pop(RzAnalysisEsil *esil) {
1479  char *dst = rz_analysis_esil_pop(esil);
1480  free(dst);
1481  return 1;
1482 }
1483 
1484 static bool esil_mod(RzAnalysisEsil *esil) {
1485  bool ret = false;
1486  ut64 s, d;
1487  char *dst = rz_analysis_esil_pop(esil);
1488  char *src = rz_analysis_esil_pop(esil);
1489  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1490  if (dst && rz_analysis_esil_get_parm(esil, dst, &d)) {
1491  if (s == 0) {
1492  ESIL_LOG("0x%08" PFMT64x " esil_mod: Division by zero!\n", esil->address);
1494  esil->trap_code = 0;
1495  } else {
1496  rz_analysis_esil_pushnum(esil, d % s);
1497  }
1498  ret = true;
1499  }
1500  } else {
1501  ESIL_LOG("esil_mod: invalid parameters\n");
1502  }
1503  free(dst);
1504  free(src);
1505  return ret;
1506 }
1507 
1508 static bool esil_signed_mod(RzAnalysisEsil *esil) {
1509  bool ret = false;
1510  st64 s, d;
1511  char *dst = rz_analysis_esil_pop(esil);
1512  char *src = rz_analysis_esil_pop(esil);
1513  if (src && rz_analysis_esil_get_parm(esil, src, (ut64 *)&s)) {
1514  if (dst && rz_analysis_esil_get_parm(esil, dst, (ut64 *)&d)) {
1515  if (ST64_DIV_OVFCHK(d, s)) {
1516  ESIL_LOG("0x%08" PFMT64x " esil_mod: Division by zero!\n", esil->address);
1518  esil->trap_code = 0;
1519  } else {
1520  rz_analysis_esil_pushnum(esil, d % s);
1521  }
1522  ret = true;
1523  }
1524  } else {
1525  ESIL_LOG("esil_mod: invalid parameters\n");
1526  }
1527  free(dst);
1528  free(src);
1529  return ret;
1530 }
1531 
1532 static bool esil_modeq(RzAnalysisEsil *esil) {
1533  bool ret = false;
1534  ut64 s, d;
1535  char *dst = rz_analysis_esil_pop(esil);
1536  char *src = rz_analysis_esil_pop(esil);
1537  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1538  if (dst && rz_analysis_esil_reg_read(esil, dst, &d, NULL)) {
1539  if (s) {
1540  esil->old = d;
1541  esil->cur = d % s;
1542  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1543  rz_analysis_esil_reg_write(esil, dst, d % s);
1544  } else {
1545  ESIL_LOG("esil_modeq: Division by zero!\n");
1547  esil->trap_code = 0;
1548  }
1549  ret = true;
1550  } else {
1551  ESIL_LOG("esil_modeq: empty stack\n");
1552  }
1553  } else {
1554  ESIL_LOG("esil_modeq: invalid parameters\n");
1555  }
1556  free(src);
1557  free(dst);
1558  return ret;
1559 }
1560 
1561 static bool esil_div(RzAnalysisEsil *esil) {
1562  bool ret = false;
1563  ut64 s, d;
1564  char *dst = rz_analysis_esil_pop(esil);
1565  char *src = rz_analysis_esil_pop(esil);
1566  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1567  if (dst && rz_analysis_esil_get_parm(esil, dst, &d)) {
1568  if (s == 0) {
1569  ESIL_LOG("esil_div: Division by zero!\n");
1571  esil->trap_code = 0;
1572  } else {
1573  rz_analysis_esil_pushnum(esil, d / s);
1574  }
1575  ret = true;
1576  }
1577  } else {
1578  ESIL_LOG("esil_div: invalid parameters\n");
1579  }
1580  free(src);
1581  free(dst);
1582  return ret;
1583 }
1584 
1585 static bool esil_signed_div(RzAnalysisEsil *esil) {
1586  bool ret = false;
1587  st64 s, d;
1588  char *dst = rz_analysis_esil_pop(esil);
1589  char *src = rz_analysis_esil_pop(esil);
1590  if (src && rz_analysis_esil_get_parm(esil, src, (ut64 *)&s)) {
1591  if (dst && rz_analysis_esil_get_parm(esil, dst, (ut64 *)&d)) {
1592  if (ST64_DIV_OVFCHK(d, s)) {
1593  ESIL_LOG("esil_div: Division by zero!\n");
1595  esil->trap_code = 0;
1596  } else {
1597  rz_analysis_esil_pushnum(esil, d / s);
1598  }
1599  ret = true;
1600  }
1601  } else {
1602  ESIL_LOG("esil_div: invalid parameters\n");
1603  }
1604  free(src);
1605  free(dst);
1606  return ret;
1607 }
1608 
1609 static bool esil_diveq(RzAnalysisEsil *esil) {
1610  bool ret = false;
1611  ut64 s, d;
1612  char *dst = rz_analysis_esil_pop(esil);
1613  char *src = rz_analysis_esil_pop(esil);
1614  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1615  if (dst && rz_analysis_esil_reg_read(esil, dst, &d, NULL)) {
1616  if (s) {
1617  esil->old = d;
1618  esil->cur = d / s;
1619  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1620  rz_analysis_esil_reg_write(esil, dst, d / s);
1621  } else {
1622  // RZ_LOG_ERROR("0x%08"PFMT64x" esil_diveq: Division by zero!\n", esil->address);
1624  esil->trap_code = 0;
1625  }
1626  ret = true;
1627  } else {
1628  ESIL_LOG("esil_diveq: empty stack\n");
1629  }
1630  } else {
1631  ESIL_LOG("esil_diveq: invalid parameters\n");
1632  }
1633  free(src);
1634  free(dst);
1635  return ret;
1636 }
1637 
1638 static bool esil_mul(RzAnalysisEsil *esil) {
1639  bool ret = false;
1640  ut64 s, d;
1641  char *dst = rz_analysis_esil_pop(esil);
1642  char *src = rz_analysis_esil_pop(esil);
1643  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1644  if (dst && rz_analysis_esil_get_parm(esil, dst, &d)) {
1645  rz_analysis_esil_pushnum(esil, d * s);
1646  ret = true;
1647  } else {
1648  ESIL_LOG("esil_mul: empty stack\n");
1649  }
1650  } else {
1651  ESIL_LOG("esil_mul: invalid parameters\n");
1652  }
1653  free(src);
1654  free(dst);
1655  return ret;
1656 }
1657 
1658 static bool esil_muleq(RzAnalysisEsil *esil) {
1659  bool ret = false;
1660  ut64 s, d;
1661  char *dst = rz_analysis_esil_pop(esil);
1662  char *src = rz_analysis_esil_pop(esil);
1663  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1664  if (dst && rz_analysis_esil_reg_read(esil, dst, &d, NULL)) {
1665  esil->old = d;
1666  esil->cur = d * s;
1667  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1668  ret = rz_analysis_esil_reg_write(esil, dst, s * d);
1669  } else {
1670  ESIL_LOG("esil_muleq: empty stack\n");
1671  }
1672  } else {
1673  ESIL_LOG("esil_muleq: invalid parameters\n");
1674  }
1675  free(dst);
1676  free(src);
1677  return ret;
1678 }
1679 
1680 static bool esil_add(RzAnalysisEsil *esil) {
1681  bool ret = false;
1682  ut64 s, d;
1683  char *dst = rz_analysis_esil_pop(esil);
1684  char *src = rz_analysis_esil_pop(esil);
1685  if ((src && rz_analysis_esil_get_parm(esil, src, &s)) && (dst && rz_analysis_esil_get_parm(esil, dst, &d))) {
1686  rz_analysis_esil_pushnum(esil, s + d);
1687  ret = true;
1688  } else {
1689  ESIL_LOG("esil_add: invalid parameters\n");
1690  }
1691  free(src);
1692  free(dst);
1693  return ret;
1694 }
1695 
1696 static bool esil_addeq(RzAnalysisEsil *esil) {
1697  bool ret = false;
1698  ut64 s, d;
1699  char *dst = rz_analysis_esil_pop(esil);
1700  char *src = rz_analysis_esil_pop(esil);
1701  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1702  if (dst && rz_analysis_esil_reg_read(esil, dst, &d, NULL)) {
1703  esil->old = d;
1704  esil->cur = d + s;
1705  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1706  ret = rz_analysis_esil_reg_write(esil, dst, s + d);
1707  }
1708  } else {
1709  ESIL_LOG("esil_addeq: invalid parameters\n");
1710  }
1711  free(src);
1712  free(dst);
1713  return ret;
1714 }
1715 
1716 static bool esil_inc(RzAnalysisEsil *esil) {
1717  bool ret = false;
1718  ut64 s;
1719  char *src = rz_analysis_esil_pop(esil);
1720  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1721  s++;
1722  ret = rz_analysis_esil_pushnum(esil, s);
1723  } else {
1724  ESIL_LOG("esil_inc: invalid parameters\n");
1725  }
1726  free(src);
1727  return ret;
1728 }
1729 
1730 static bool esil_inceq(RzAnalysisEsil *esil) {
1731  bool ret = false;
1732  ut64 sd;
1733  char *src_dst = rz_analysis_esil_pop(esil);
1734  if (src_dst && (rz_analysis_esil_get_parm_type(esil, src_dst) == RZ_ANALYSIS_ESIL_PARM_REG) && rz_analysis_esil_get_parm(esil, src_dst, &sd)) {
1735  // inc rax
1736  esil->old = sd++;
1737  esil->cur = sd;
1738  rz_analysis_esil_reg_write(esil, src_dst, sd);
1739  esil->lastsz = esil_internal_sizeof_reg(esil, src_dst);
1740  ret = true;
1741  } else {
1742  ESIL_LOG("esil_inceq: invalid parameters\n");
1743  }
1744  free(src_dst);
1745  return ret;
1746 }
1747 
1748 static bool esil_sub(RzAnalysisEsil *esil) {
1749  bool ret = false;
1750  ut64 s, d;
1751  char *dst = rz_analysis_esil_pop(esil);
1752  char *src = rz_analysis_esil_pop(esil);
1753  if ((src && rz_analysis_esil_get_parm(esil, src, &s)) && (dst && rz_analysis_esil_get_parm(esil, dst, &d))) {
1754  ret = rz_analysis_esil_pushnum(esil, d - s);
1755  } else {
1756  ESIL_LOG("esil_sub: invalid parameters\n");
1757  }
1758  free(src);
1759  free(dst);
1760  return ret;
1761 }
1762 
1763 static bool esil_subeq(RzAnalysisEsil *esil) {
1764  bool ret = false;
1765  ut64 s, d;
1766  char *dst = rz_analysis_esil_pop(esil);
1767  char *src = rz_analysis_esil_pop(esil);
1768  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1769  if (dst && rz_analysis_esil_reg_read(esil, dst, &d, NULL)) {
1770  esil->old = d;
1771  esil->cur = d - s;
1772  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
1773  ret = rz_analysis_esil_reg_write(esil, dst, d - s);
1774  }
1775  } else {
1776  ESIL_LOG("esil_subeq: invalid parameters\n");
1777  }
1778  free(src);
1779  free(dst);
1780  return ret;
1781 }
1782 
1783 static bool esil_dec(RzAnalysisEsil *esil) {
1784  bool ret = false;
1785  ut64 s;
1786  char *src = rz_analysis_esil_pop(esil);
1787  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
1788  s--;
1789  ret = rz_analysis_esil_pushnum(esil, s);
1790  } else {
1791  ESIL_LOG("esil_dec: invalid parameters\n");
1792  }
1793  free(src);
1794  return ret;
1795 }
1796 
1797 static bool esil_deceq(RzAnalysisEsil *esil) {
1798  bool ret = false;
1799  ut64 sd;
1800  char *src_dst = rz_analysis_esil_pop(esil);
1801  if (src_dst && (rz_analysis_esil_get_parm_type(esil, src_dst) == RZ_ANALYSIS_ESIL_PARM_REG) && rz_analysis_esil_get_parm(esil, src_dst, &sd)) {
1802  esil->old = sd;
1803  sd--;
1804  esil->cur = sd;
1805  rz_analysis_esil_reg_write(esil, src_dst, sd);
1806  esil->lastsz = esil_internal_sizeof_reg(esil, src_dst);
1807  ret = true;
1808  } else {
1809  ESIL_LOG("esil_deceq: invalid parameters\n");
1810  }
1811  free(src_dst);
1812  return ret;
1813 }
1814 
1815 /* POKE */
1816 static bool esil_poke_n(RzAnalysisEsil *esil, int bits) {
1817  ut64 bitmask = genmask(bits - 1);
1818  ut64 num, num2, addr;
1819  ut8 b[8] = { 0 };
1820  ut64 n;
1821  char *dst = rz_analysis_esil_pop(esil);
1822  char *src = rz_analysis_esil_pop(esil);
1823  int bytes = RZ_MIN(sizeof(b), bits / 8);
1824  if (bits % 8) {
1825  free(src);
1826  free(dst);
1827  return false;
1828  }
1829  bool ret = false;
1830  char *src2 = NULL;
1831  if (src && rz_analysis_esil_get_parm(esil, src, &num)) {
1832  if (dst && rz_analysis_esil_get_parm(esil, dst, &addr)) {
1833  if (bits == 128) {
1834  src2 = rz_analysis_esil_pop(esil);
1835  if (src2 && rz_analysis_esil_get_parm(esil, src2, &num2)) {
1836  rz_write_ble(b, num, esil->analysis->big_endian, 64);
1837  ret = rz_analysis_esil_mem_write(esil, addr, b, bytes);
1838  if (ret == 0) {
1839  rz_write_ble(b, num2, esil->analysis->big_endian, 64);
1840  ret = rz_analysis_esil_mem_write(esil, addr + 8, b, bytes);
1841  }
1842  goto out;
1843  }
1844  ret = -1;
1845  goto out;
1846  }
1847  // this is a internal peek performed before a poke
1848  // we disable hooks to avoid run hooks on internal peeks
1849  void *oldhook = (void *)esil->cb.hook_mem_read;
1850  esil->cb.hook_mem_read = NULL;
1852  esil->cb.hook_mem_read = oldhook;
1853  n = rz_read_ble64(b, esil->analysis->big_endian);
1854  esil->old = n;
1855  esil->cur = num;
1856  esil->lastsz = bits;
1857  num = num & bitmask;
1859  ret = rz_analysis_esil_mem_write(esil, addr, b, bytes);
1860  }
1861  }
1862 out:
1863  free(src2);
1864  free(src);
1865  free(dst);
1866  return ret;
1867 }
1868 
1869 static bool esil_poke1(RzAnalysisEsil *esil) {
1870  return esil_poke_n(esil, 8);
1871 }
1872 
1873 static bool esil_poke2(RzAnalysisEsil *esil) {
1874  return esil_poke_n(esil, 16);
1875 }
1876 
1877 static bool esil_poke3(RzAnalysisEsil *esil) {
1878  return esil_poke_n(esil, 24);
1879 }
1880 
1881 static bool esil_poke4(RzAnalysisEsil *esil) {
1882  return esil_poke_n(esil, 32);
1883 }
1884 
1885 static bool esil_poke8(RzAnalysisEsil *esil) {
1886  return esil_poke_n(esil, 64);
1887 }
1888 
1889 static bool esil_poke16(RzAnalysisEsil *esil) {
1890  return esil_poke_n(esil, 128);
1891 }
1892 
1893 static bool esil_poke(RzAnalysisEsil *esil) {
1894  return esil_poke_n(esil, esil->analysis->bits);
1895 }
1896 
1897 static bool esil_poke_some(RzAnalysisEsil *esil) {
1898  bool ret = false;
1899  int i, regsize;
1900  ut64 ptr, regs = 0, tmp;
1901  char *count, *dst = rz_analysis_esil_pop(esil);
1902 
1903  if (dst && rz_analysis_esil_get_parm_size(esil, dst, &tmp, &regsize)) {
1904  // reg
1905  isregornum(esil, dst, &ptr);
1906  count = rz_analysis_esil_pop(esil);
1907  if (count) {
1908  isregornum(esil, count, &regs);
1909  if (regs > 0) {
1910  ut8 b[8] = { 0 };
1911  ut64 num64;
1912  for (i = 0; i < regs; i++) {
1913  char *foo = rz_analysis_esil_pop(esil);
1914  if (!foo) {
1915  // avoid looping out of stack
1916  free(dst);
1917  free(count);
1918  return true;
1919  }
1920  rz_analysis_esil_get_parm_size(esil, foo, &tmp, &regsize);
1921  isregornum(esil, foo, &num64);
1922  rz_write_ble(b, num64, esil->analysis->big_endian, regsize);
1923  const int size_bytes = regsize / 8;
1924  const ut32 written = rz_analysis_esil_mem_write(esil, ptr, b, size_bytes);
1925  if (written != size_bytes) {
1926  esil->trap = 1;
1927  }
1928  ptr += size_bytes;
1929  free(foo);
1930  }
1931  }
1932  free(dst);
1933  free(count);
1934  return ret;
1935  }
1936  free(dst);
1937  }
1938  return false;
1939 }
1940 
1941 /* PEEK */
1942 
1943 static bool esil_peek_n(RzAnalysisEsil *esil, int bits) {
1944  if (bits & 7) {
1945  return false;
1946  }
1947  bool ret = false;
1948  char res[32];
1949  ut64 addr;
1950  ut32 bytes = bits / 8;
1951  char *dst = rz_analysis_esil_pop(esil);
1952  if (!dst) {
1953  RZ_LOG_ERROR("Cannot peek memory without specifying an address (esil address: 0x%08" PFMT64x ")\n", esil->address);
1954  return false;
1955  }
1956  if (dst && isregornum(esil, dst, &addr)) {
1957  if (bits == 128) {
1958  ut8 a[sizeof(ut64) * 2] = { 0 };
1959  ret = rz_analysis_esil_mem_read(esil, addr, a, bytes);
1960  ut64 b = rz_read_ble64(&a, 0); // esil->analysis->big_endian);
1961  ut64 c = rz_read_ble64(&a[8], 0); // esil->analysis->big_endian);
1962  snprintf(res, sizeof(res), "0x%" PFMT64x, b);
1963  rz_analysis_esil_push(esil, res);
1964  snprintf(res, sizeof(res), "0x%" PFMT64x, c);
1965  rz_analysis_esil_push(esil, res);
1966  free(dst);
1967  return ret;
1968  }
1969  ut64 bitmask = genmask(bits - 1);
1970  ut8 a[sizeof(ut64)] = { 0 };
1971  ret = !!rz_analysis_esil_mem_read(esil, addr, a, bytes);
1972  ut64 b = rz_read_ble64(a, 0); // esil->analysis->big_endian);
1973  if (esil->analysis->big_endian) {
1974  rz_mem_swapendian((ut8 *)&b, (const ut8 *)&b, bytes);
1975  }
1976  snprintf(res, sizeof(res), "0x%" PFMT64x, b & bitmask);
1977  rz_analysis_esil_push(esil, res);
1978  esil->lastsz = bits;
1979  }
1980  free(dst);
1981  return ret;
1982 }
1983 
1984 static bool esil_peek1(RzAnalysisEsil *esil) {
1985  return esil_peek_n(esil, 8);
1986 }
1987 
1988 static bool esil_peek2(RzAnalysisEsil *esil) {
1989  return esil_peek_n(esil, 16);
1990 }
1991 
1992 static bool esil_peek3(RzAnalysisEsil *esil) {
1993  return esil_peek_n(esil, 24);
1994 }
1995 
1996 static bool esil_peek4(RzAnalysisEsil *esil) {
1997  return esil_peek_n(esil, 32);
1998 }
1999 
2000 static bool esil_peek8(RzAnalysisEsil *esil) {
2001  return esil_peek_n(esil, 64);
2002 }
2003 
2004 static bool esil_peek16(RzAnalysisEsil *esil) {
2005  // packed only
2006  return esil_peek_n(esil, 128);
2007 }
2008 
2009 static bool esil_stack(RzAnalysisEsil *esil) {
2010  return esil->stackptr >= 1;
2011 }
2012 
2013 static bool esil_peek(RzAnalysisEsil *esil) {
2014  return esil_peek_n(esil, esil->analysis->bits);
2015 };
2016 
2017 static bool esil_peek_some(RzAnalysisEsil *esil) {
2018  int i;
2019  ut64 ptr, regs;
2020  // pop ptr
2021  char *count, *dst = rz_analysis_esil_pop(esil);
2022  if (dst) {
2023  // reg
2024  isregornum(esil, dst, &ptr);
2025  count = rz_analysis_esil_pop(esil);
2026  if (count) {
2027  isregornum(esil, count, &regs);
2028  if (regs > 0) {
2029  ut32 num32;
2030  ut8 a[4];
2031  for (i = 0; i < regs; i++) {
2032  char *foo = rz_analysis_esil_pop(esil);
2033  if (!foo) {
2034  ESIL_LOG("Cannot pop in peek\n");
2035  free(dst);
2036  free(count);
2037  return 0;
2038  }
2039  const ut32 read = rz_analysis_esil_mem_read(esil, ptr, a, 4);
2040  if (read == 4) { // this is highly questionabla
2041  num32 = rz_read_ble32(a, esil->analysis->big_endian);
2042  rz_analysis_esil_reg_write(esil, foo, num32);
2043  } else {
2044  ESIL_LOG("Cannot peek from 0x%08" PFMT64x "\n", ptr);
2045  }
2046  ptr += 4;
2047  free(foo);
2048  }
2049  }
2050  free(dst);
2051  free(count);
2052  return 1;
2053  }
2054  free(dst);
2055  }
2056  return 0;
2057 }
2058 
2059 /* OREQ */
2060 
2061 static bool esil_mem_oreq_n(RzAnalysisEsil *esil, int bits) {
2062  bool ret = false;
2063  ut64 s, d;
2064  char *dst = rz_analysis_esil_pop(esil); // save the dst-addr
2065  char *src0 = rz_analysis_esil_pop(esil); // get the src
2066  char *src1 = NULL;
2067  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) { // get the src
2068  rz_analysis_esil_push(esil, dst); // push the dst-addr
2069  ret = (!!esil_peek_n(esil, bits)); // read
2070  src1 = rz_analysis_esil_pop(esil); // get the old dst-value
2071  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) { // get the old dst-value
2072  d |= s; // calculate the new dst-value
2073  rz_analysis_esil_pushnum(esil, d); // push the new dst-value
2074  rz_analysis_esil_push(esil, dst); // push the dst-addr
2075  ret &= (!!esil_poke_n(esil, bits)); // write
2076  } else {
2077  ret = false;
2078  }
2079  }
2080  if (!ret) {
2081  ESIL_LOG("esil_mem_oreq_n: invalid parameters\n");
2082  }
2083  free(dst);
2084  free(src0);
2085  free(src1);
2086  return ret;
2087 }
2088 
2089 static bool esil_mem_oreq1(RzAnalysisEsil *esil) {
2090  return esil_mem_oreq_n(esil, 8);
2091 }
2092 static bool esil_mem_oreq2(RzAnalysisEsil *esil) {
2093  return esil_mem_oreq_n(esil, 16);
2094 }
2095 static bool esil_mem_oreq4(RzAnalysisEsil *esil) {
2096  return esil_mem_oreq_n(esil, 32);
2097 }
2098 static bool esil_mem_oreq8(RzAnalysisEsil *esil) {
2099  return esil_mem_oreq_n(esil, 64);
2100 }
2101 static bool esil_mem_oreq(RzAnalysisEsil *esil) {
2102  return esil_mem_oreq_n(esil, esil->analysis->bits);
2103 }
2104 
2105 /* XOREQ */
2106 
2107 static bool esil_mem_xoreq_n(RzAnalysisEsil *esil, int bits) {
2108  bool ret = false;
2109  ut64 s, d;
2110  char *dst = rz_analysis_esil_pop(esil);
2111  char *src0 = rz_analysis_esil_pop(esil);
2112  char *src1 = NULL;
2113  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2114  rz_analysis_esil_push(esil, dst);
2115  ret = (!!esil_peek_n(esil, bits));
2116  src1 = rz_analysis_esil_pop(esil);
2117  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2118  d ^= s;
2119  rz_analysis_esil_pushnum(esil, d);
2120  rz_analysis_esil_push(esil, dst);
2121  ret &= (!!esil_poke_n(esil, bits));
2122  } else {
2123  ret = false;
2124  }
2125  }
2126  if (!ret) {
2127  ESIL_LOG("esil_mem_xoreq_n: invalid parameters\n");
2128  }
2129  free(dst);
2130  free(src0);
2131  free(src1);
2132  return ret;
2133 }
2134 
2135 static bool esil_mem_xoreq1(RzAnalysisEsil *esil) {
2136  return esil_mem_xoreq_n(esil, 8);
2137 }
2138 static bool esil_mem_xoreq2(RzAnalysisEsil *esil) {
2139  return esil_mem_xoreq_n(esil, 16);
2140 }
2141 static bool esil_mem_xoreq4(RzAnalysisEsil *esil) {
2142  return esil_mem_xoreq_n(esil, 32);
2143 }
2144 static bool esil_mem_xoreq8(RzAnalysisEsil *esil) {
2145  return esil_mem_xoreq_n(esil, 64);
2146 }
2147 static bool esil_mem_xoreq(RzAnalysisEsil *esil) {
2148  return esil_mem_xoreq_n(esil, esil->analysis->bits);
2149 }
2150 
2151 /* ANDEQ */
2152 
2153 static bool esil_mem_andeq_n(RzAnalysisEsil *esil, int bits) {
2154  bool ret = false;
2155  ut64 s, d;
2156  char *dst = rz_analysis_esil_pop(esil);
2157  char *src0 = rz_analysis_esil_pop(esil);
2158  char *src1 = NULL;
2159  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2160  rz_analysis_esil_push(esil, dst);
2161  ret = (!!esil_peek_n(esil, bits));
2162  src1 = rz_analysis_esil_pop(esil);
2163  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2164  d &= s;
2165  rz_analysis_esil_pushnum(esil, d);
2166  rz_analysis_esil_push(esil, dst);
2167  ret &= (!!esil_poke_n(esil, bits));
2168  } else {
2169  ret = false;
2170  }
2171  }
2172  if (!ret) {
2173  ESIL_LOG("esil_mem_andeq_n: invalid parameters\n");
2174  }
2175  free(dst);
2176  free(src0);
2177  free(src1);
2178  return ret;
2179 }
2180 
2181 static bool esil_mem_andeq1(RzAnalysisEsil *esil) {
2182  return esil_mem_andeq_n(esil, 8);
2183 }
2184 static bool esil_mem_andeq2(RzAnalysisEsil *esil) {
2185  return esil_mem_andeq_n(esil, 16);
2186 }
2187 static bool esil_mem_andeq4(RzAnalysisEsil *esil) {
2188  return esil_mem_andeq_n(esil, 32);
2189 }
2190 static bool esil_mem_andeq8(RzAnalysisEsil *esil) {
2191  return esil_mem_andeq_n(esil, 64);
2192 }
2193 static bool esil_mem_andeq(RzAnalysisEsil *esil) {
2194  return esil_mem_andeq_n(esil, esil->analysis->bits);
2195 }
2196 
2197 /* ADDEQ */
2198 
2199 static bool esil_mem_addeq_n(RzAnalysisEsil *esil, int bits) {
2200  bool ret = false;
2201  ut64 s, d;
2202  char *dst = rz_analysis_esil_pop(esil);
2203  char *src0 = rz_analysis_esil_pop(esil);
2204  char *src1 = NULL;
2205  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2206  rz_analysis_esil_push(esil, dst);
2207  ret = (!!esil_peek_n(esil, bits));
2208  src1 = rz_analysis_esil_pop(esil);
2209  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2210  d += s;
2211  rz_analysis_esil_pushnum(esil, d);
2212  rz_analysis_esil_push(esil, dst);
2213  ret &= (!!esil_poke_n(esil, bits));
2214  } else {
2215  ret = false;
2216  }
2217  }
2218  if (!ret) {
2219  ESIL_LOG("esil_mem_addeq_n: invalid parameters\n");
2220  }
2221  free(dst);
2222  free(src0);
2223  free(src1);
2224  return ret;
2225 }
2226 
2227 static bool esil_mem_addeq1(RzAnalysisEsil *esil) {
2228  return esil_mem_addeq_n(esil, 8);
2229 }
2230 static bool esil_mem_addeq2(RzAnalysisEsil *esil) {
2231  return esil_mem_addeq_n(esil, 16);
2232 }
2233 static bool esil_mem_addeq4(RzAnalysisEsil *esil) {
2234  return esil_mem_addeq_n(esil, 32);
2235 }
2236 static bool esil_mem_addeq8(RzAnalysisEsil *esil) {
2237  return esil_mem_addeq_n(esil, 64);
2238 }
2239 static bool esil_mem_addeq(RzAnalysisEsil *esil) {
2240  return esil_mem_addeq_n(esil, esil->analysis->bits);
2241 }
2242 
2243 /* SUBEQ */
2244 
2245 static bool esil_mem_subeq_n(RzAnalysisEsil *esil, int bits) {
2246  bool ret = false;
2247  ut64 s, d;
2248  char *dst = rz_analysis_esil_pop(esil);
2249  char *src0 = rz_analysis_esil_pop(esil);
2250  char *src1 = NULL;
2251  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2252  rz_analysis_esil_push(esil, dst);
2253  ret = (!!esil_peek_n(esil, bits));
2254  src1 = rz_analysis_esil_pop(esil);
2255  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2256  d -= s;
2257  rz_analysis_esil_pushnum(esil, d);
2258  rz_analysis_esil_push(esil, dst);
2259  ret &= (!!esil_poke_n(esil, bits));
2260  } else {
2261  ret = false;
2262  }
2263  }
2264  if (!ret) {
2265  ESIL_LOG("esil_mem_subeq_n: invalid parameters\n");
2266  }
2267  free(dst);
2268  free(src0);
2269  free(src1);
2270  return ret;
2271 }
2272 
2273 static bool esil_mem_subeq1(RzAnalysisEsil *esil) {
2274  return esil_mem_subeq_n(esil, 8);
2275 }
2276 static bool esil_mem_subeq2(RzAnalysisEsil *esil) {
2277  return esil_mem_subeq_n(esil, 16);
2278 }
2279 static bool esil_mem_subeq4(RzAnalysisEsil *esil) {
2280  return esil_mem_subeq_n(esil, 32);
2281 }
2282 static bool esil_mem_subeq8(RzAnalysisEsil *esil) {
2283  return esil_mem_subeq_n(esil, 64);
2284 }
2285 static bool esil_mem_subeq(RzAnalysisEsil *esil) {
2286  return esil_mem_subeq_n(esil, esil->analysis->bits);
2287 }
2288 
2289 /* MODEQ */
2290 
2291 static bool esil_mem_modeq_n(RzAnalysisEsil *esil, int bits) {
2292  bool ret = false;
2293  ut64 s, d;
2294  char *dst = rz_analysis_esil_pop(esil);
2295  char *src0 = rz_analysis_esil_pop(esil);
2296  char *src1 = NULL;
2297  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2298  if (s == 0) {
2299  ESIL_LOG("esil_mem_modeq4: Division by zero!\n");
2301  esil->trap_code = 0;
2302  } else {
2303  rz_analysis_esil_push(esil, dst);
2304  ret = (!!esil_peek_n(esil, bits));
2305  src1 = rz_analysis_esil_pop(esil);
2306  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d) && s >= 1) {
2307  rz_analysis_esil_pushnum(esil, d % s);
2308  d = d % s;
2309  rz_analysis_esil_pushnum(esil, d);
2310  rz_analysis_esil_push(esil, dst);
2311  ret &= (!!esil_poke_n(esil, bits));
2312  } else {
2313  ret = false;
2314  }
2315  }
2316  }
2317  if (!ret) {
2318  ESIL_LOG("esil_mem_modeq_n: invalid parameters\n");
2319  }
2320  free(dst);
2321  free(src0);
2322  free(src1);
2323  return ret;
2324 }
2325 
2326 static bool esil_mem_modeq1(RzAnalysisEsil *esil) {
2327  return esil_mem_modeq_n(esil, 8);
2328 }
2329 static bool esil_mem_modeq2(RzAnalysisEsil *esil) {
2330  return esil_mem_modeq_n(esil, 16);
2331 }
2332 static bool esil_mem_modeq4(RzAnalysisEsil *esil) {
2333  return esil_mem_modeq_n(esil, 32);
2334 }
2335 static bool esil_mem_modeq8(RzAnalysisEsil *esil) {
2336  return esil_mem_modeq_n(esil, 64);
2337 }
2338 static bool esil_mem_modeq(RzAnalysisEsil *esil) {
2339  return esil_mem_modeq_n(esil, esil->analysis->bits);
2340 }
2341 
2342 /* DIVEQ */
2343 
2344 static bool esil_mem_diveq_n(RzAnalysisEsil *esil, int bits) {
2345  bool ret = false;
2346  ut64 s, d;
2347  char *dst = rz_analysis_esil_pop(esil);
2348  char *src0 = rz_analysis_esil_pop(esil);
2349  char *src1 = NULL;
2350  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2351  if (s == 0) {
2352  ESIL_LOG("esil_mem_diveq8: Division by zero!\n");
2354  esil->trap_code = 0;
2355  } else {
2356  rz_analysis_esil_push(esil, dst);
2357  ret = (!!esil_peek_n(esil, bits));
2358  src1 = rz_analysis_esil_pop(esil);
2359  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2360  d = d / s;
2361  rz_analysis_esil_pushnum(esil, d);
2362  rz_analysis_esil_push(esil, dst);
2363  ret &= (!!esil_poke_n(esil, bits));
2364  } else {
2365  ret = false;
2366  }
2367  }
2368  }
2369  if (!ret) {
2370  ESIL_LOG("esil_mem_diveq_n: invalid parameters\n");
2371  }
2372  free(dst);
2373  free(src0);
2374  free(src1);
2375  return ret;
2376 }
2377 
2378 static bool esil_mem_diveq1(RzAnalysisEsil *esil) {
2379  return esil_mem_diveq_n(esil, 8);
2380 }
2381 static bool esil_mem_diveq2(RzAnalysisEsil *esil) {
2382  return esil_mem_diveq_n(esil, 16);
2383 }
2384 static bool esil_mem_diveq4(RzAnalysisEsil *esil) {
2385  return esil_mem_diveq_n(esil, 32);
2386 }
2387 static bool esil_mem_diveq8(RzAnalysisEsil *esil) {
2388  return esil_mem_diveq_n(esil, 64);
2389 }
2390 static bool esil_mem_diveq(RzAnalysisEsil *esil) {
2391  return esil_mem_diveq_n(esil, esil->analysis->bits);
2392 }
2393 
2394 /* MULEQ */
2395 
2396 static bool esil_mem_muleq_n(RzAnalysisEsil *esil, int bits, ut64 bitmask) {
2397  bool ret = false;
2398  ut64 s, d;
2399  char *dst = rz_analysis_esil_pop(esil);
2400  char *src0 = rz_analysis_esil_pop(esil);
2401  char *src1 = NULL;
2402  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2403  rz_analysis_esil_push(esil, dst);
2404  ret = (!!esil_peek_n(esil, bits));
2405  src1 = rz_analysis_esil_pop(esil);
2406  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2407  d *= s;
2408  rz_analysis_esil_pushnum(esil, d);
2409  rz_analysis_esil_push(esil, dst);
2410  ret &= (!!esil_poke_n(esil, bits));
2411  } else {
2412  ret = false;
2413  }
2414  }
2415  if (!ret) {
2416  ESIL_LOG("esil_mem_muleq_n: invalid parameters\n");
2417  }
2418  free(dst);
2419  free(src0);
2420  free(src1);
2421  return ret;
2422 }
2423 
2424 static bool esil_mem_muleq1(RzAnalysisEsil *esil) {
2425  return esil_mem_muleq_n(esil, 8, UT8_MAX);
2426 }
2427 static bool esil_mem_muleq2(RzAnalysisEsil *esil) {
2428  return esil_mem_muleq_n(esil, 16, UT16_MAX);
2429 }
2430 static bool esil_mem_muleq4(RzAnalysisEsil *esil) {
2431  return esil_mem_muleq_n(esil, 32, UT32_MAX);
2432 }
2433 static bool esil_mem_muleq8(RzAnalysisEsil *esil) {
2434  return esil_mem_muleq_n(esil, 64, UT64_MAX);
2435 }
2436 
2437 static bool esil_mem_muleq(RzAnalysisEsil *esil) {
2438  switch (esil->analysis->bits) {
2439  case 64: return esil_mem_muleq8(esil);
2440  case 32: return esil_mem_muleq4(esil);
2441  case 16: return esil_mem_muleq2(esil);
2442  case 8: return esil_mem_muleq1(esil);
2443  }
2444  return 0;
2445 }
2446 
2447 /* INCEQ */
2448 
2449 static bool esil_mem_inceq_n(RzAnalysisEsil *esil, int bits) {
2450  bool ret = false;
2451  ut64 s;
2452  char *off = rz_analysis_esil_pop(esil);
2453  char *src = NULL;
2454  if (off) {
2455  rz_analysis_esil_push(esil, off);
2456  ret = (!!esil_peek_n(esil, bits));
2457  src = rz_analysis_esil_pop(esil);
2458  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
2459  esil->old = s;
2460  s++;
2461  esil->cur = s;
2462  esil->lastsz = bits;
2463  rz_analysis_esil_pushnum(esil, s);
2464  rz_analysis_esil_push(esil, off);
2465  ret &= (!!esil_poke_n(esil, bits));
2466  } else {
2467  ret = false;
2468  }
2469  }
2470  if (!ret) {
2471  ESIL_LOG("esil_mem_inceq_n: invalid parameters\n");
2472  }
2473  free(src);
2474  free(off);
2475  return ret;
2476 }
2477 
2478 static bool esil_mem_inceq1(RzAnalysisEsil *esil) {
2479  return esil_mem_inceq_n(esil, 8);
2480 }
2481 static bool esil_mem_inceq2(RzAnalysisEsil *esil) {
2482  return esil_mem_inceq_n(esil, 16);
2483 }
2484 static bool esil_mem_inceq4(RzAnalysisEsil *esil) {
2485  return esil_mem_inceq_n(esil, 32);
2486 }
2487 static bool esil_mem_inceq8(RzAnalysisEsil *esil) {
2488  return esil_mem_inceq_n(esil, 64);
2489 }
2490 static bool esil_mem_inceq(RzAnalysisEsil *esil) {
2491  return esil_mem_inceq_n(esil, esil->analysis->bits);
2492 }
2493 
2494 /* DECEQ */
2495 
2496 static bool esil_mem_deceq_n(RzAnalysisEsil *esil, int bits) {
2497  bool ret = false;
2498  ut64 s;
2499  char *off = rz_analysis_esil_pop(esil);
2500  char *src = NULL;
2501  if (off) {
2502  rz_analysis_esil_push(esil, off);
2503  ret = (!!esil_peek_n(esil, bits));
2504  src = rz_analysis_esil_pop(esil);
2505  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
2506  s--;
2507  rz_analysis_esil_pushnum(esil, s);
2508  rz_analysis_esil_push(esil, off);
2509  ret &= (!!esil_poke_n(esil, bits));
2510  } else {
2511  ret = false;
2512  }
2513  }
2514  if (!ret) {
2515  ESIL_LOG("esil_mem_deceq_n: invalid parameters\n");
2516  }
2517  free(src);
2518  free(off);
2519  return ret;
2520 }
2521 
2522 static bool esil_mem_deceq1(RzAnalysisEsil *esil) {
2523  return esil_mem_deceq_n(esil, 8);
2524 }
2525 static bool esil_mem_deceq2(RzAnalysisEsil *esil) {
2526  return esil_mem_deceq_n(esil, 16);
2527 }
2528 static bool esil_mem_deceq4(RzAnalysisEsil *esil) {
2529  return esil_mem_deceq_n(esil, 32);
2530 }
2531 static bool esil_mem_deceq8(RzAnalysisEsil *esil) {
2532  return esil_mem_deceq_n(esil, 64);
2533 }
2534 static bool esil_mem_deceq(RzAnalysisEsil *esil) {
2535  return esil_mem_deceq_n(esil, esil->analysis->bits);
2536 }
2537 
2538 /* LSLEQ */
2539 
2540 static bool esil_mem_lsleq_n(RzAnalysisEsil *esil, int bits) {
2541  bool ret = false;
2542  ut64 s, d;
2543  char *dst = rz_analysis_esil_pop(esil);
2544  char *src0 = rz_analysis_esil_pop(esil);
2545  char *src1 = NULL;
2546  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2547  if (s > sizeof(ut64) * 8) {
2548  ESIL_LOG("esil_mem_lsleq_n: shift is too big\n");
2549  } else {
2550  rz_analysis_esil_push(esil, dst);
2551  ret = (!!esil_peek_n(esil, bits));
2552  src1 = rz_analysis_esil_pop(esil);
2553  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2554  if (s > 63) {
2555  d = 0;
2556  } else {
2557  d <<= s;
2558  }
2559  rz_analysis_esil_pushnum(esil, d);
2560  rz_analysis_esil_push(esil, dst);
2561  ret &= (!!esil_poke_n(esil, bits));
2562  } else {
2563  ret = false;
2564  }
2565  }
2566  }
2567  if (!ret) {
2568  ESIL_LOG("esil_mem_lsleq_n: invalid parameters\n");
2569  }
2570  free(dst);
2571  free(src0);
2572  free(src1);
2573  return ret;
2574 }
2575 
2576 static bool esil_mem_lsleq1(RzAnalysisEsil *esil) {
2577  return esil_mem_lsleq_n(esil, 8);
2578 }
2579 static bool esil_mem_lsleq2(RzAnalysisEsil *esil) {
2580  return esil_mem_lsleq_n(esil, 16);
2581 }
2582 static bool esil_mem_lsleq4(RzAnalysisEsil *esil) {
2583  return esil_mem_lsleq_n(esil, 32);
2584 }
2585 static bool esil_mem_lsleq8(RzAnalysisEsil *esil) {
2586  return esil_mem_lsleq_n(esil, 64);
2587 }
2588 static bool esil_mem_lsleq(RzAnalysisEsil *esil) {
2589  return esil_mem_lsleq_n(esil, esil->analysis->bits);
2590 }
2591 
2592 /* LSREQ */
2593 
2594 static bool esil_mem_lsreq_n(RzAnalysisEsil *esil, int bits) {
2595  bool ret = false;
2596  ut64 s, d;
2597  char *dst = rz_analysis_esil_pop(esil);
2598  char *src0 = rz_analysis_esil_pop(esil);
2599  char *src1 = NULL;
2600  if (src0 && rz_analysis_esil_get_parm(esil, src0, &s)) {
2601  rz_analysis_esil_push(esil, dst);
2602  ret = (!!esil_peek_n(esil, bits));
2603  src1 = rz_analysis_esil_pop(esil);
2604  if (src1 && rz_analysis_esil_get_parm(esil, src1, &d)) {
2605  d >>= s;
2606  rz_analysis_esil_pushnum(esil, d);
2607  rz_analysis_esil_push(esil, dst);
2608  ret &= (!!esil_poke_n(esil, bits));
2609  } else {
2610  ret = false;
2611  }
2612  }
2613  if (!ret) {
2614  ESIL_LOG("esil_mem_lsreq_n: invalid parameters\n");
2615  }
2616  free(dst);
2617  free(src0);
2618  free(src1);
2619  return ret;
2620 }
2621 
2622 static bool esil_mem_lsreq1(RzAnalysisEsil *esil) {
2623  return esil_mem_lsreq_n(esil, 8);
2624 }
2625 static bool esil_mem_lsreq2(RzAnalysisEsil *esil) {
2626  return esil_mem_lsreq_n(esil, 16);
2627 }
2628 static bool esil_mem_lsreq4(RzAnalysisEsil *esil) {
2629  return esil_mem_lsreq_n(esil, 32);
2630 }
2631 static bool esil_mem_lsreq8(RzAnalysisEsil *esil) {
2632  return esil_mem_lsreq_n(esil, 64);
2633 }
2634 static bool esil_mem_lsreq(RzAnalysisEsil *esil) {
2635  return esil_mem_lsreq_n(esil, esil->analysis->bits);
2636 }
2637 
2638 /* get value of register or memory reference and push the value */
2639 static bool esil_num(RzAnalysisEsil *esil) {
2640  char *dup_me;
2641  ut64 dup;
2642  if (!esil) {
2643  return false;
2644  }
2645  if (!(dup_me = rz_analysis_esil_pop(esil))) {
2646  return false;
2647  }
2648  if (!rz_analysis_esil_get_parm(esil, dup_me, &dup)) {
2649  free(dup_me);
2650  return false;
2651  }
2652  free(dup_me);
2653  return rz_analysis_esil_pushnum(esil, dup);
2654 }
2655 
2656 /* duplicate the last element in the stack */
2657 static bool esil_dup(RzAnalysisEsil *esil) {
2658  if (!esil || !esil->stack || esil->stackptr < 1 || esil->stackptr > (esil->stacksize - 1)) {
2659  return false;
2660  }
2661  return rz_analysis_esil_push(esil, esil->stack[esil->stackptr - 1]);
2662 }
2663 
2664 static bool esil_swap(RzAnalysisEsil *esil) {
2665  char *tmp;
2666  if (!esil || !esil->stack || esil->stackptr < 2) {
2667  return false;
2668  }
2669  if (!esil->stack[esil->stackptr - 1] || !esil->stack[esil->stackptr - 2]) {
2670  return false;
2671  }
2672  tmp = esil->stack[esil->stackptr - 1];
2673  esil->stack[esil->stackptr - 1] = esil->stack[esil->stackptr - 2];
2674  esil->stack[esil->stackptr - 2] = tmp;
2675  return true;
2676 }
2677 
2678 // NOTE on following comparison functions:
2679 // The push to top of the stack is based on a
2680 // signed compare (as this causes least surprise to the users).
2681 // If an unsigned comparison is necessary, one must not use the
2682 // result pushed onto the top of the stack, but rather test the flags which
2683 // are set as a result of the compare.
2684 
2686  int result;
2687  switch (size) {
2688  case 1:
2689  result = (a & 1) > (b & 1);
2690  break;
2691  case 8:
2692  result = (st8)a > (st8)b;
2693  break;
2694  case 16:
2695  result = (st16)a > (st16)b;
2696  break;
2697  case 32:
2698  result = (st32)a > (st32)b;
2699  break;
2700  case 64:
2701  default:
2702  result = (st64)a > (st64)b;
2703  break;
2704  }
2705  return result;
2706 }
2707 
2708 static bool esil_smaller(RzAnalysisEsil *esil) { // 'dst < src' => 'src,dst,<'
2709  ut64 num, num2;
2710  bool ret = false;
2711  char *dst = rz_analysis_esil_pop(esil);
2712  char *src = rz_analysis_esil_pop(esil);
2713  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
2714  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
2715  esil->old = num;
2716  esil->cur = num - num2;
2717  ret = true;
2718  if (rz_reg_get(esil->analysis->reg, dst, -1)) {
2719  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
2720  } else if (rz_reg_get(esil->analysis->reg, src, -1)) {
2721  esil->lastsz = esil_internal_sizeof_reg(esil, src);
2722  } else {
2723  // default size is set to 64 as internally operands are ut64
2724  esil->lastsz = 64;
2725  }
2726  rz_analysis_esil_pushnum(esil, (num != num2) & !signed_compare_gt(num, num2, esil->lastsz));
2727  }
2728  }
2729  free(dst);
2730  free(src);
2731  return ret;
2732 }
2733 
2734 static bool esil_bigger(RzAnalysisEsil *esil) { // 'dst > src' => 'src,dst,>'
2735  ut64 num, num2;
2736  bool ret = false;
2737  char *dst = rz_analysis_esil_pop(esil);
2738  char *src = rz_analysis_esil_pop(esil);
2739  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
2740  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
2741  esil->old = num;
2742  esil->cur = num - num2;
2743  ret = true;
2744  if (rz_reg_get(esil->analysis->reg, dst, -1)) {
2745  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
2746  } else if (rz_reg_get(esil->analysis->reg, src, -1)) {
2747  esil->lastsz = esil_internal_sizeof_reg(esil, src);
2748  } else {
2749  // default size is set to 64 as internally operands are ut64
2750  esil->lastsz = 64;
2751  }
2753  }
2754  }
2755  free(dst);
2756  free(src);
2757  return ret;
2758 }
2759 
2760 static bool esil_smaller_equal(RzAnalysisEsil *esil) { // 'dst <= src' => 'src,dst,<='
2761  ut64 num, num2;
2762  bool ret = false;
2763  char *dst = rz_analysis_esil_pop(esil);
2764  char *src = rz_analysis_esil_pop(esil);
2765  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
2766  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
2767  esil->old = num;
2768  esil->cur = num - num2;
2769  ret = true;
2770  if (rz_reg_get(esil->analysis->reg, dst, -1)) {
2771  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
2772  } else if (rz_reg_get(esil->analysis->reg, src, -1)) {
2773  esil->lastsz = esil_internal_sizeof_reg(esil, src);
2774  } else {
2775  // default size is set to 64 as internally operands are ut64
2776  esil->lastsz = 64;
2777  }
2778  rz_analysis_esil_pushnum(esil, !signed_compare_gt(num, num2, esil->lastsz));
2779  }
2780  }
2781  free(dst);
2782  free(src);
2783  return ret;
2784 }
2785 
2786 static bool esil_bigger_equal(RzAnalysisEsil *esil) { // 'dst >= src' => 'src,dst,>='
2787  ut64 num, num2;
2788  bool ret = false;
2789  char *dst = rz_analysis_esil_pop(esil);
2790  char *src = rz_analysis_esil_pop(esil);
2791  if (dst && rz_analysis_esil_get_parm(esil, dst, &num)) {
2792  if (src && rz_analysis_esil_get_parm(esil, src, &num2)) {
2793  esil->old = num;
2794  esil->cur = num - num2;
2795  ret = true;
2796  if (rz_reg_get(esil->analysis->reg, dst, -1)) {
2797  esil->lastsz = esil_internal_sizeof_reg(esil, dst);
2798  } else if (rz_reg_get(esil->analysis->reg, src, -1)) {
2799  esil->lastsz = esil_internal_sizeof_reg(esil, src);
2800  } else {
2801  // default size is set to 64 as internally operands are ut64
2802  esil->lastsz = 64;
2803  }
2804  rz_analysis_esil_pushnum(esil, (num == num2) | signed_compare_gt(num, num2, esil->lastsz));
2805  }
2806  }
2807  free(dst);
2808  free(src);
2809  return ret;
2810 }
2811 
2813  bool ret = false;
2814  ut64 s;
2815  char *src = rz_analysis_esil_pop(esil);
2816  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
2817  esil->jump_target = s;
2818  esil->jump_target_set = 1;
2819  ret = true;
2820  } else {
2821  RZ_FREE(src);
2822  ESIL_LOG("esil_set_jump_target: empty stack\n");
2823  }
2824  free(src);
2825  return ret;
2826 }
2827 
2829  bool ret = false;
2830  ut64 s;
2831  char *src = rz_analysis_esil_pop(esil);
2832  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
2833  esil->jump_target_set = s;
2834  ret = true;
2835  } else {
2836  RZ_FREE(src);
2837  ESIL_LOG("esil_set_jump_target_set: empty stack\n");
2838  }
2839  free(src);
2840  return ret;
2841 }
2842 
2844  bool ret = false;
2845  ut64 s;
2846  char *src = rz_analysis_esil_pop(esil);
2847  if (src && rz_analysis_esil_get_parm(esil, src, &s)) {
2848  esil->delay = s;
2849  ret = true;
2850  } else {
2851  RZ_FREE(src);
2852  ESIL_LOG("esil_set_delay_slot: empty stack\n");
2853  }
2854  free(src);
2855  return ret;
2856 }
2857 
2858 static bool iscommand(RzAnalysisEsil *esil, const char *word, RzAnalysisEsilOp **op) {
2859  RzAnalysisEsilOp *eop = ht_pp_find(esil->ops, word, NULL);
2860  if (eop) {
2861  *op = eop;
2862  return true;
2863  }
2864  return false;
2865 }
2866 
2867 static bool runword(RzAnalysisEsil *esil, const char *word) {
2869  if (!word) {
2870  return false;
2871  }
2872  esil->parse_goto_count--;
2873  if (esil->parse_goto_count < 1) {
2874  ESIL_LOG("ESIL infinite loop detected\n");
2875  esil->trap = 1; // INTERNAL ERROR
2876  esil->parse_stop = 1; // INTERNAL ERROR
2877  return false;
2878  }
2879 
2880  if (!strcmp(word, "}{")) {
2881  if (esil->skip == 1) {
2882  esil->skip = 0;
2883  } else if (esil->skip == 0) { // this isn't perfect, but should work for valid esil
2884  esil->skip = 1;
2885  }
2886  return true;
2887  }
2888  if (!strcmp(word, "}")) {
2889  if (esil->skip) {
2890  esil->skip--;
2891  }
2892  return true;
2893  }
2894  if (esil->skip && strcmp(word, "?{")) {
2895  return true;
2896  }
2897 
2898  if (iscommand(esil, word, &op)) {
2899  // run action
2900  if (op) {
2901  if (esil->cb.hook_command) {
2902  if (esil->cb.hook_command(esil, word)) {
2903  return 1; // XXX cannot return != 1
2904  }
2905  }
2906  rz_strbuf_set(&esil->current_opstr, word);
2907  // so this is basically just sharing what's the operation with the operation
2908  // useful for wrappers
2909  const bool ret = op->code(esil);
2910  rz_strbuf_fini(&esil->current_opstr);
2911  if (!ret) {
2912  ESIL_LOG("%s returned 0\n", word);
2913  }
2914  return ret;
2915  }
2916  }
2917  if (!*word || *word == ',') {
2918  // skip empty words
2919  return true;
2920  }
2921 
2922  // push value
2923  if (!rz_analysis_esil_push(esil, word)) {
2924  ESIL_LOG("ESIL stack is full\n");
2925  esil->trap = 1;
2926  esil->trap_code = 1;
2927  }
2928  return true;
2929 }
2930 
2931 static const char *gotoWord(const char *str, int n) {
2932  const char *ostr = str;
2933  int count = 0;
2934  while (*str) {
2935  if (count == n) {
2936  return ostr;
2937  }
2938  str++;
2939  if (*str == ',') {
2940  ostr = str + 1;
2941  count++;
2942  }
2943  }
2944  return NULL;
2945 }
2946 
2954 static int evalWord(RzAnalysisEsil *esil, const char *ostr, const char **str) {
2955  rz_return_val_if_fail(esil && str, 0);
2956  if (!*str) {
2957  return 0;
2958  }
2959  if ((*str)[0] && (*str)[1] == ',') {
2960  return 2;
2961  }
2962  if (esil->repeat) {
2963  return 0;
2964  }
2965  if (esil->parse_goto != -1) {
2966  // TODO: detect infinite loop??? how??
2967  *str = gotoWord(ostr, esil->parse_goto);
2968  if (*str) {
2969  esil->parse_goto = -1;
2970  return 2;
2971  }
2972  ESIL_LOG("Cannot find word %d\n", esil->parse_goto);
2973  return 1;
2974  }
2975  if (esil->parse_stop) {
2976  if (esil->parse_stop == 2) {
2977  RZ_LOG_DEBUG("[esil at 0x%08" PFMT64x "] TODO: %s\n", esil->address, *str + 1);
2978  }
2979  return 1;
2980  }
2981  return 3;
2982 }
2983 
2984 static bool __stepOut(RzAnalysisEsil *esil, const char *cmd) {
2985  static bool inCmdStep = false;
2986  if (cmd && esil && esil->cmd && !inCmdStep) {
2987  inCmdStep = true;
2988  if (esil->cmd(esil, cmd, esil->address, 0)) {
2989  inCmdStep = false;
2990  // if returns 1 we skip the impl
2991  return true;
2992  }
2993  inCmdStep = false;
2994  }
2995  return false;
2996 }
2997 
2999  int wordi = 0;
3000  int dorunword;
3001  char word[64];
3002  const char *ostr = str;
3004 
3005  if (__stepOut(esil, esil->cmd_step)) {
3006  (void)__stepOut(esil, esil->cmd_step_out);
3007  return true;
3008  }
3009  const char *hashbang = strstr(str, "#!");
3010  esil->trap = 0;
3011  if (esil->cmd && esil->cmd_todo) {
3012  if (!strncmp(str, "TODO", 4)) {
3013  esil->cmd(esil, esil->cmd_todo, esil->address, 0);
3014  }
3015  }
3016 loop:
3017  esil->repeat = 0;
3018  esil->skip = 0;
3019  esil->parse_goto = -1;
3020  esil->parse_stop = 0;
3021  // memleak or failing aetr test. wat du
3022  // rz_analysis_esil_stack_free (esil);
3024  str = ostr;
3025 repeat:
3026  wordi = 0;
3027  while (*str) {
3028  if (str == hashbang) {
3029  if (esil->analysis && esil->analysis->coreb.setab) {
3030  esil->analysis->coreb.cmd(esil->analysis->coreb.core, str + 2);
3031  }
3032  break;
3033  }
3034  if (wordi > 62) {
3035  ESIL_LOG("Invalid esil string\n");
3036  __stepOut(esil, esil->cmd_step_out);
3037  return -1;
3038  }
3039  dorunword = 0;
3040  if (*str == ';') {
3041  word[wordi] = 0;
3042  dorunword = 1;
3043  }
3044  if (*str == ',') {
3045  word[wordi] = 0;
3046  dorunword = 2;
3047  }
3048  if (dorunword) {
3049  if (*word) {
3050  if (!runword(esil, word)) {
3051  __stepOut(esil, esil->cmd_step_out);
3052  return 0;
3053  }
3054  word[wordi] = ',';
3055  wordi = 0;
3056  switch (evalWord(esil, ostr, &str)) {
3057  case 0: goto loop;
3058  case 1:
3059  __stepOut(esil, esil->cmd_step_out);
3060  return 0;
3061  case 2: continue;
3062  }
3063  if (dorunword == 1) {
3064  __stepOut(esil, esil->cmd_step_out);
3065  return 0;
3066  }
3067  }
3068  str++;
3069  }
3070  word[wordi++] = *str;
3071  // is *str is '\0' in the next iteration the condition will be true
3072  // reading beyond the boundaries
3073  if (*str) {
3074  str++;
3075  }
3076  }
3077  word[wordi] = 0;
3078  if (*word) {
3079  if (!runword(esil, word)) {
3080  __stepOut(esil, esil->cmd_step_out);
3081  return 0;
3082  }
3083  switch (evalWord(esil, ostr, &str)) {
3084  case 0: goto loop;
3085  case 1:
3086  __stepOut(esil, esil->cmd_step_out);
3087  return 0;
3088  case 2: goto repeat;
3089  }
3090  }
3091  __stepOut(esil, esil->cmd_step_out);
3092  return 1;
3093 }
3094 
3095 RZ_API bool rz_analysis_esil_runword(RzAnalysisEsil *esil, const char *word) {
3096  (void)runword(esil, word);
3097  // for some reasons this is called twice in the original code from condret.
3098  return runword(esil, word);
3099 }
3100 
3101 // frees all elements from the stack, not the stack itself
3102 // rename to stack_empty() ?
3104  int i;
3105  if (esil) {
3106  for (i = 0; i < esil->stackptr; i++) {
3107  RZ_FREE(esil->stack[i]);
3108  }
3109  esil->stackptr = 0;
3110  }
3111 }
3112 
3114  char *popped;
3115  int ret;
3116  if (!esil) {
3117  return false;
3118  }
3119  while (*str == ' ') {
3120  str++; // use proper string chop?
3121  }
3122  (void)rz_analysis_esil_parse(esil, str);
3123  popped = rz_analysis_esil_pop(esil);
3124  if (popped) {
3125  ut64 num;
3126  if (isregornum(esil, popped, &num)) {
3127  ret = !!num;
3128  } else {
3129  ret = 0;
3130  }
3131  free(popped);
3132  } else {
3133  RZ_LOG_ERROR("Cannot pop because The ESIL stack is empty");
3134  return -1;
3135  }
3136  return ret;
3137 }
3138 
3140 #define OP(v, w, x, y, z) rz_analysis_esil_set_op(esil, v, w, x, y, z)
3141 #define OT_UNK RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN
3142 #define OT_CTR RZ_ANALYSIS_ESIL_OP_TYPE_CONTROL_FLOW
3143 #define OT_MATH RZ_ANALYSIS_ESIL_OP_TYPE_MATH
3144 #define OT_REGW RZ_ANALYSIS_ESIL_OP_TYPE_REG_WRITE
3145 #define OT_MEMW RZ_ANALYSIS_ESIL_OP_TYPE_MEM_WRITE
3146 #define OT_MEMR RZ_ANALYSIS_ESIL_OP_TYPE_MEM_READ
3147 
3148  OP("$", esil_interrupt, 0, 1, OT_UNK); // hm, type seems a bit wrong
3149  OP("$z", esil_zf, 1, 0, OT_UNK);
3150  OP("$c", esil_cf, 1, 1, OT_UNK);
3151  OP("$b", esil_bf, 1, 1, OT_UNK);
3152  OP("$p", esil_pf, 1, 0, OT_UNK);
3153  OP("$s", esil_sf, 1, 1, OT_UNK);
3154  OP("$o", esil_of, 1, 1, OT_UNK);
3155  OP("$ds", esil_ds, 1, 0, OT_UNK);
3156  OP("$jt", esil_jt, 1, 0, OT_UNK);
3157  OP("$js", esil_js, 1, 0, OT_UNK);
3158  OP("$r", esil_rs, 1, 0, OT_UNK);
3159  OP("$$", esil_address, 1, 0, OT_UNK);
3160  OP("~", esil_signext, 1, 2, OT_MATH);
3161  OP("~=", esil_signexteq, 0, 2, OT_MATH);
3162  OP("==", esil_cmp, 0, 2, OT_MATH);
3163  OP("<", esil_smaller, 1, 2, OT_MATH);
3164  OP(">", esil_bigger, 1, 2, OT_MATH);
3165  OP("<=", esil_smaller_equal, 1, 2, OT_MATH);
3166  OP(">=", esil_bigger_equal, 1, 2, OT_MATH);
3167  OP("?{", esil_if, 0, 1, OT_CTR);
3168  OP("<<", esil_lsl, 1, 2, OT_MATH);
3169  OP("<<=", esil_lsleq, 0, 2, OT_MATH | OT_REGW);
3170  OP(">>", esil_lsr, 1, 2, OT_MATH);
3171  OP(">>=", esil_lsreq, 0, 2, OT_MATH | OT_REGW);
3172  OP(">>>>", esil_asr, 1, 2, OT_MATH);
3173  OP(">>>>=", esil_asreq, 0, 2, OT_MATH | OT_REGW);
3174  OP(">>>", esil_ror, 1, 2, OT_MATH);
3175  OP("<<<", esil_rol, 1, 2, OT_MATH);
3176  OP("&", esil_and, 1, 2, OT_MATH);
3177  OP("&=", esil_andeq, 0, 2, OT_MATH | OT_REGW);
3178  OP("}", esil_nop, 0, 0, OT_CTR); // just to avoid push
3179  OP("}{", esil_nop, 0, 0, OT_CTR);
3180  OP("|", esil_or, 1, 2, OT_MATH);
3181  OP("|=", esil_oreq, 0, 2, OT_MATH | OT_REGW);
3182  OP("!", esil_neg, 1, 1, OT_MATH);
3183  OP("!=", esil_negeq, 0, 1, OT_MATH | OT_REGW);
3184  OP("=", esil_eq, 0, 2, OT_REGW);
3185  OP(":=", esil_weak_eq, 0, 2, OT_REGW);
3186  OP("*", esil_mul, 1, 2, OT_MATH);
3187  OP("*=", esil_muleq, 0, 2, OT_MATH | OT_REGW);
3188  OP("^", esil_xor, 1, 2, OT_MATH);
3189  OP("^=", esil_xoreq, 0, 2, OT_MATH | OT_REGW);
3190  OP("+", esil_add, 1, 2, OT_MATH);
3191  OP("+=", esil_addeq, 0, 2, OT_MATH | OT_REGW);
3192  OP("++", esil_inc, 1, 1, OT_MATH);
3193  OP("++=", esil_inceq, 0, 1, OT_MATH | OT_REGW);
3194  OP("-", esil_sub, 1, 2, OT_MATH);
3195  OP("-=", esil_subeq, 0, 2, OT_MATH | OT_REGW);
3196  OP("--", esil_dec, 1, 1, OT_MATH);
3197  OP("--=", esil_deceq, 0, 1, OT_MATH | OT_REGW);
3198  OP("/", esil_div, 1, 2, OT_MATH);
3199  OP("~/", esil_signed_div, 1, 2, OT_MATH);
3200  OP("/=", esil_diveq, 0, 2, OT_MATH | OT_REGW);
3201  OP("%", esil_mod, 1, 2, OT_MATH);
3202  OP("~%", esil_signed_mod, 1, 2, OT_MATH);
3203  OP("%=", esil_modeq, 0, 2, OT_MATH | OT_REGW);
3204  OP("=[]", esil_poke, 0, 2, OT_MEMW);
3205  OP("=[1]", esil_poke1, 0, 2, OT_MEMW);
3206  OP("=[2]", esil_poke2, 0, 2, OT_MEMW);
3207  OP("=[3]", esil_poke3, 0, 2, OT_MEMW);
3208  OP("=[4]", esil_poke4, 0, 2, OT_MEMW);
3209  OP("=[8]", esil_poke8, 0, 2, OT_MEMW);
3210  OP("=[16]", esil_poke16, 0, 2, OT_MEMW);
3211  OP("|=[]", esil_mem_oreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3212  OP("|=[1]", esil_mem_oreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3213  OP("|=[2]", esil_mem_oreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3214  OP("|=[4]", esil_mem_oreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3215  OP("|=[8]", esil_mem_oreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3216  OP("^=[]", esil_mem_xoreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3217  OP("^=[1]", esil_mem_xoreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3218  OP("^=[2]", esil_mem_xoreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3219  OP("^=[4]", esil_mem_xoreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3220  OP("^=[8]", esil_mem_xoreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3221  OP("&=[]", esil_mem_andeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3222  OP("&=[1]", esil_mem_andeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3223  OP("&=[2]", esil_mem_andeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3224  OP("&=[4]", esil_mem_andeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3225  OP("&=[8]", esil_mem_andeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3226  OP("+=[]", esil_mem_addeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3227  OP("+=[1]", esil_mem_addeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3228  OP("+=[2]", esil_mem_addeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3229  OP("+=[4]", esil_mem_addeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3230  OP("+=[8]", esil_mem_addeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3231  OP("-=[]", esil_mem_subeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3232  OP("-=[1]", esil_mem_subeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3233  OP("-=[2]", esil_mem_subeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3234  OP("-=[4]", esil_mem_subeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3235  OP("-=[8]", esil_mem_subeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3236  OP("%=[]", esil_mem_modeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3237  OP("%=[1]", esil_mem_modeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3238  OP("%=[2]", esil_mem_modeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3239  OP("%=[4]", esil_mem_modeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3240  OP("%=[8]", esil_mem_modeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3241  OP("/=[]", esil_mem_diveq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3242  OP("/=[1]", esil_mem_diveq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3243  OP("/=[2]", esil_mem_diveq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3244  OP("/=[4]", esil_mem_diveq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3245  OP("/=[8]", esil_mem_diveq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3246  OP("*=[]", esil_mem_muleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3247  OP("*=[1]", esil_mem_muleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3248  OP("*=[2]", esil_mem_muleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3249  OP("*=[4]", esil_mem_muleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3250  OP("*=[8]", esil_mem_muleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3251  OP("++=[]", esil_mem_inceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3252  OP("++=[1]", esil_mem_inceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3253  OP("++=[2]", esil_mem_inceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3254  OP("++=[4]", esil_mem_inceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3255  OP("++=[8]", esil_mem_inceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3256  OP("--=[]", esil_mem_deceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3257  OP("--=[1]", esil_mem_deceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3258  OP("--=[2]", esil_mem_deceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3259  OP("--=[4]", esil_mem_deceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3260  OP("--=[8]", esil_mem_deceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3261  OP("<<=[]", esil_mem_lsleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3262  OP("<<=[1]", esil_mem_lsleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3263  OP("<<=[2]", esil_mem_lsleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3264  OP("<<=[4]", esil_mem_lsleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3265  OP("<<=[8]", esil_mem_lsleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3266  OP(">>=[]", esil_mem_lsreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3267  OP(">>=[1]", esil_mem_lsreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3268  OP(">>=[2]", esil_mem_lsreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3269  OP(">>=[4]", esil_mem_lsreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3270  OP(">>=[8]", esil_mem_lsreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3271  OP("[]", esil_peek, 1, 1, OT_MEMR);
3272  OP("[*]", esil_peek_some, 0, 0, OT_MEMR);
3273  OP("=[*]", esil_poke_some, 0, 0, OT_MEMW);
3274  OP("[1]", esil_peek1, 1, 1, OT_MEMR);
3275  OP("[2]", esil_peek2, 1, 1, OT_MEMR);
3276  OP("[3]", esil_peek3, 1, 1, OT_MEMR);
3277  OP("[4]", esil_peek4, 1, 1, OT_MEMR);
3278  OP("[8]", esil_peek8, 1, 1, OT_MEMR);
3279  OP("[16]", esil_peek16, 1, 1, OT_MEMR);
3280  OP("STACK", esil_stack, 0, 0, OT_UNK);
3281  OP("REPEAT", esil_repeat, 0, 2, OT_CTR);
3282  OP("POP", esil_pop, 0, 1, OT_UNK);
3283  OP("TODO", esil_todo, 0, 0, OT_UNK);
3284  OP("GOTO", esil_goto, 0, 1, OT_CTR);
3285  OP("BREAK", esil_break, 0, 0, OT_CTR);
3286  OP("CLEAR", esil_clear, 0, 0, OT_UNK);
3287  OP("DUP", esil_dup, 1, 0, OT_UNK);
3288  OP("NUM", esil_num, 1, 1, OT_UNK);
3289  OP("SWAP", esil_swap, 2, 2, OT_UNK);
3290  OP("TRAP", esil_trap, 0, 0, OT_UNK);
3291  OP("BITS", esil_bits, 1, 0, OT_UNK);
3292  OP("SETJT", esil_set_jump_target, 0, 1, OT_UNK);
3293  OP("SETJTS", esil_set_jump_target_set, 0, 1, OT_UNK);
3294  OP("SETD", esil_set_delay_slot, 0, 1, OT_UNK);
3295 }
3296 
3297 /* register callbacks using this analysis module. */
3298 RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull) {
3299  rz_return_val_if_fail(esil, false);
3300  // esil->debug = 0;
3301  esil->analysis = analysis;
3302  esil->parse_goto_count = analysis->esil_goto_limit;
3303  esil->trap = 0;
3304  esil->trap_code = 0;
3305  // esil->user = NULL;
3308 
3309  if (nonull) {
3310  // this is very questionable, most platforms allow accessing NULL
3311  // never writes zero to PC, BP, SP, why? because writing
3312  // zeros to these registers is equivalent to accessing NULL
3313  // pointer somehow
3317  } else {
3321  }
3322  rz_analysis_esil_mem_ro(esil, romem);
3323  rz_analysis_esil_stats(esil, stats);
3325 
3326  return (analysis->cur && analysis->cur->esil_init)
3327  ? analysis->cur->esil_init(esil)
3328  : true;
3329 }
size_t len
Definition: 6502dis.c:15
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
#define rs()
#define mask()
static char * regs[]
Definition: analysis_sh.c:203
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
operand
Definition: arc-opc.c:39
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
static ut8 bytes[32]
Definition: asm_arc.c:23
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c1
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c3
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c2
int bits(struct state *s, int need)
Definition: blast.c:72
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RzCryptoSelector bit
Definition: crypto.c:16
#define r
Definition: crypto_rc6.c:12
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint32_t ut32
int large
Definition: enough.c:227
static int internal_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size)
Definition: esil.c:356
static bool esil_mem_lsreq1(RzAnalysisEsil *esil)
Definition: esil.c:2622
static bool esil_repeat(RzAnalysisEsil *esil)
Definition: esil.c:1463
RZ_API int rz_analysis_esil_reg_read_nocallback(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size)
Definition: esil.c:498
static bool esil_poke16(RzAnalysisEsil *esil)
Definition: esil.c:1889
static bool esil_trap(RzAnalysisEsil *esil)
Definition: esil.c:962
#define FLG(x)
Definition: esil.c:10
static bool esil_mem_addeq(RzAnalysisEsil *esil)
Definition: esil.c:2239
static bool esil_inceq(RzAnalysisEsil *esil)
Definition: esil.c:1730
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil)
Definition: esil.c:3103
RZ_API int rz_analysis_esil_get_parm_size(RzAnalysisEsil *esil, const char *str, ut64 *num, int *size)
Definition: esil.c:455
static int signed_compare_gt(ut64 a, ut64 b, ut64 size)
Definition: esil.c:2685
static bool esil_mem_diveq8(RzAnalysisEsil *esil)
Definition: esil.c:2387
static bool esil_poke3(RzAnalysisEsil *esil)
Definition: esil.c:1877
static bool esil_signext(RzAnalysisEsil *esil)
Definition: esil.c:582
static bool esil_poke(RzAnalysisEsil *esil)
Definition: esil.c:1893
static bool esil_addeq(RzAnalysisEsil *esil)
Definition: esil.c:1696
RZ_API RzAnalysisEsil * rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize)
Definition: esil.c:85
static bool esil_pop(RzAnalysisEsil *esil)
Definition: esil.c:1478
static bool esil_peek3(RzAnalysisEsil *esil)
Definition: esil.c:1992
static bool esil_interrupt(RzAnalysisEsil *esil)
Definition: esil.c:985
static bool esil_mul(RzAnalysisEsil *esil)
Definition: esil.c:1638
static bool esil_signexteq(RzAnalysisEsil *esil)
Definition: esil.c:591
static ut8 esil_internal_sizeof_reg(RzAnalysisEsil *esil, const char *r)
Definition: esil.c:194
static bool esil_peek4(RzAnalysisEsil *esil)
Definition: esil.c:1996
static bool esil_peek8(RzAnalysisEsil *esil)
Definition: esil.c:2000
static bool isregornum(RzAnalysisEsil *esil, const char *str, ut64 *num)
Definition: esil.c:58
#define OT_MEMR
RZ_API int rz_analysis_esil_get_parm(RzAnalysisEsil *esil, const char *str, ut64 *num)
Definition: esil.c:483
static bool esil_peek_some(RzAnalysisEsil *esil)
Definition: esil.c:2017
RZ_API bool rz_analysis_esil_pushnum(RzAnalysisEsil *esil, ut64 num)
Definition: esil.c:408
static bool esil_bits(RzAnalysisEsil *esil)
Definition: esil.c:973
static bool esil_set_jump_target_set(RzAnalysisEsil *esil)
Definition: esil.c:2828
static bool esil_mem_deceq2(RzAnalysisEsil *esil)
Definition: esil.c:2525
static bool esil_mem_diveq2(RzAnalysisEsil *esil)
Definition: esil.c:2381
static bool esil_nop(RzAnalysisEsil *esil)
Definition: esil.c:841
static bool esil_mem_lsreq4(RzAnalysisEsil *esil)
Definition: esil.c:2628
static bool esil_mem_lsreq8(RzAnalysisEsil *esil)
Definition: esil.c:2631
static bool esil_signed_div(RzAnalysisEsil *esil)
Definition: esil.c:1585
#define OP(v, w, x, y, z)
static bool esil_mem_andeq1(RzAnalysisEsil *esil)
Definition: esil.c:2181
static bool esil_and(RzAnalysisEsil *esil)
Definition: esil.c:1355
RZ_API int rz_analysis_esil_condition(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:3113
static bool esil_asr(RzAnalysisEsil *esil)
Definition: esil.c:1266
static bool esil_mem_xoreq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2107
static bool esil_ror(RzAnalysisEsil *esil)
Definition: esil.c:1311
static bool esil_break(RzAnalysisEsil *esil)
Definition: esil.c:1435
static bool esil_mem_lsleq2(RzAnalysisEsil *esil)
Definition: esil.c:2579
static bool esil_mem_andeq2(RzAnalysisEsil *esil)
Definition: esil.c:2184
static bool esil_clear(RzAnalysisEsil *esil)
Definition: esil.c:1440
static bool esil_mem_deceq4(RzAnalysisEsil *esil)
Definition: esil.c:2528
static bool esil_lsl(RzAnalysisEsil *esil)
Definition: esil.c:1097
static void esil_ops_free(HtPPKv *kv)
Definition: esil.c:80
static bool esil_mem_subeq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2245
static bool esil_add(RzAnalysisEsil *esil)
Definition: esil.c:1680
static bool esil_mem_deceq1(RzAnalysisEsil *esil)
Definition: esil.c:2522
static bool esil_mem_xoreq(RzAnalysisEsil *esil)
Definition: esil.c:2147
static bool isnum(RzAnalysisEsil *esil, const char *str, ut64 *num)
Definition: esil.c:37
static bool esil_oreq(RzAnalysisEsil *esil)
Definition: esil.c:866
#define OT_MEMW
static bool esil_mem_muleq2(RzAnalysisEsil *esil)
Definition: esil.c:2427
static int internal_esil_mem_read_no_null(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
Definition: esil.c:237
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:155
static bool esil_subeq(RzAnalysisEsil *esil)
Definition: esil.c:1763
static int internal_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
Definition: esil.c:205
static bool esil_mem_muleq_n(RzAnalysisEsil *esil, int bits, ut64 bitmask)
Definition: esil.c:2396
static bool esil_mem_subeq2(RzAnalysisEsil *esil)
Definition: esil.c:2276
static bool esil_todo(RzAnalysisEsil *esil)
Definition: esil.c:1448
RZ_API const char * rz_analysis_esil_trapstr(int type)
Definition: esil.c:1412
static bool popRN(RzAnalysisEsil *esil, ut64 *n)
Definition: esil.c:68
static bool esil_pf(RzAnalysisEsil *esil)
Definition: esil.c:646
static bool esil_mem_deceq(RzAnalysisEsil *esil)
Definition: esil.c:2534
static bool esil_mem_inceq8(RzAnalysisEsil *esil)
Definition: esil.c:2487
RZ_API int rz_analysis_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: esil.c:341
static bool esil_mem_inceq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2449
static bool esil_sub(RzAnalysisEsil *esil)
Definition: esil.c:1748
static bool esil_mem_inceq(RzAnalysisEsil *esil)
Definition: esil.c:2490
static bool esil_poke_some(RzAnalysisEsil *esil)
Definition: esil.c:1897
static bool esil_set_jump_target(RzAnalysisEsil *esil)
Definition: esil.c:2812
static bool esil_smaller_equal(RzAnalysisEsil *esil)
Definition: esil.c:2760
static bool esil_or(RzAnalysisEsil *esil)
Definition: esil.c:1393
static bool esil_mem_muleq(RzAnalysisEsil *esil)
Definition: esil.c:2437
static bool esil_mem_muleq4(RzAnalysisEsil *esil)
Definition: esil.c:2430
static bool esil_mem_modeq8(RzAnalysisEsil *esil)
Definition: esil.c:2335
static bool esil_mem_oreq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2061
#define ESIL_LOG(fmtstr,...)
Definition: esil.c:32
static bool esil_js(RzAnalysisEsil *esil)
Definition: esil.c:720
static bool esil_mem_xoreq8(RzAnalysisEsil *esil)
Definition: esil.c:2144
static bool esil_peek2(RzAnalysisEsil *esil)
Definition: esil.c:1988
static bool esil_mem_diveq4(RzAnalysisEsil *esil)
Definition: esil.c:2384
RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size)
Definition: esil.c:507
static bool esil_mem_inceq2(RzAnalysisEsil *esil)
Definition: esil.c:2481
static bool esil_mem_addeq2(RzAnalysisEsil *esil)
Definition: esil.c:2230
static int internal_esil_reg_write(RzAnalysisEsil *esil, const char *regname, ut64 num)
Definition: esil.c:370
static bool esil_mem_xoreq4(RzAnalysisEsil *esil)
Definition: esil.c:2141
#define OT_CTR
static bool esil_cmp(RzAnalysisEsil *esil)
Definition: esil.c:994
static bool esil_mem_andeq8(RzAnalysisEsil *esil)
Definition: esil.c:2190
static bool esil_mem_diveq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2344
static bool esil_bigger_equal(RzAnalysisEsil *esil)
Definition: esil.c:2786
static bool esil_zf(RzAnalysisEsil *esil)
Definition: esil.c:595
RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type)
Definition: esil.c:110
static bool esil_mem_oreq1(RzAnalysisEsil *esil)
Definition: esil.c:2089
static bool esil_div(RzAnalysisEsil *esil)
Definition: esil.c:1561
static bool esil_asreq(RzAnalysisEsil *esil)
Definition: esil.c:1198
static bool esil_mod(RzAnalysisEsil *esil)
Definition: esil.c:1484
static int internal_esil_reg_write_no_null(RzAnalysisEsil *esil, const char *regname, ut64 num)
Definition: esil.c:381
#define OT_REGW
static bool esil_mem_subeq8(RzAnalysisEsil *esil)
Definition: esil.c:2282
static bool esil_if(RzAnalysisEsil *esil)
Definition: esil.c:1078
static bool esil_peek(RzAnalysisEsil *esil)
Definition: esil.c:2013
static bool alignCheck(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:200
static bool esil_mem_xoreq2(RzAnalysisEsil *esil)
Definition: esil.c:2138
static bool esil_mem_lsleq8(RzAnalysisEsil *esil)
Definition: esil.c:2585
static bool esil_of(RzAnalysisEsil *esil)
Definition: esil.c:660
static bool esil_mem_andeq4(RzAnalysisEsil *esil)
Definition: esil.c:2187
static int internal_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: esil.c:283
static bool iscommand(RzAnalysisEsil *esil, const char *word, RzAnalysisEsilOp **op)
Definition: esil.c:2858
static bool esil_mem_subeq(RzAnalysisEsil *esil)
Definition: esil.c:2285
RZ_API int rz_analysis_esil_reg_write(RzAnalysisEsil *esil, const char *dst, ut64 num)
Definition: esil.c:487
static bool esil_negeq(RzAnalysisEsil *esil)
Definition: esil.c:825
static bool esil_mem_lsreq2(RzAnalysisEsil *esil)
Definition: esil.c:2625
static bool esil_mem_deceq8(RzAnalysisEsil *esil)
Definition: esil.c:2531
static bool esil_mem_subeq1(RzAnalysisEsil *esil)
Definition: esil.c:2273
static bool esil_lsreq(RzAnalysisEsil *esil)
Definition: esil.c:1172
static bool esil_deceq(RzAnalysisEsil *esil)
Definition: esil.c:1797
static bool esil_weak_eq(RzAnalysisEsil *esil)
Definition: esil.c:737
static bool esil_poke4(RzAnalysisEsil *esil)
Definition: esil.c:1881
static bool esil_mem_lsleq1(RzAnalysisEsil *esil)
Definition: esil.c:2576
static bool esil_lsleq(RzAnalysisEsil *esil)
Definition: esil.c:1123
static bool esil_set_delay_slot(RzAnalysisEsil *esil)
Definition: esil.c:2843
static bool esil_ds(RzAnalysisEsil *esil)
Definition: esil.c:710
static bool esil_mem_modeq(RzAnalysisEsil *esil)
Definition: esil.c:2338
static bool esil_poke2(RzAnalysisEsil *esil)
Definition: esil.c:1873
static bool esil_stack(RzAnalysisEsil *esil)
Definition: esil.c:2009
RZ_API char * rz_analysis_esil_pop(RzAnalysisEsil *esil)
Definition: esil.c:422
static void rz_analysis_esil_setup_ops(RzAnalysisEsil *esil)
Definition: esil.c:3139
static bool esil_mem_oreq(RzAnalysisEsil *esil)
Definition: esil.c:2101
static const char * gotoWord(const char *str, int n)
Definition: esil.c:2931
static int evalWord(RzAnalysisEsil *esil, const char *ostr, const char **str)
Definition: esil.c:2954
static bool esil_mem_oreq8(RzAnalysisEsil *esil)
Definition: esil.c:2098
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull)
Definition: esil.c:3298
static bool esil_mem_andeq(RzAnalysisEsil *esil)
Definition: esil.c:2193
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:2998
static bool esil_peek1(RzAnalysisEsil *esil)
Definition: esil.c:1984
static bool esil_mem_addeq1(RzAnalysisEsil *esil)
Definition: esil.c:2227
static bool esil_mem_lsleq4(RzAnalysisEsil *esil)
Definition: esil.c:2582
RZ_API bool rz_analysis_esil_push(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:414
static bool esil_lsr(RzAnalysisEsil *esil)
Definition: esil.c:1153
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil)
Definition: esil.c:163
static bool esil_goto(RzAnalysisEsil *esil)
Definition: esil.c:1453
static bool ispackedreg(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:53
RZ_API int rz_analysis_esil_get_parm_type(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:430
static bool esil_dup(RzAnalysisEsil *esil)
Definition: esil.c:2657
static bool esil_mem_modeq1(RzAnalysisEsil *esil)
Definition: esil.c:2326
static bool esil_mem_muleq8(RzAnalysisEsil *esil)
Definition: esil.c:2433
static bool esil_mem_modeq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2291
#define OT_MATH
RZ_API int rz_analysis_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
Definition: esil.c:259
static bool esil_mem_diveq1(RzAnalysisEsil *esil)
Definition: esil.c:2378
static bool esil_neg(RzAnalysisEsil *esil)
Definition: esil.c:802
static bool esil_sf(RzAnalysisEsil *esil)
Definition: esil.c:687
static bool esil_signed_mod(RzAnalysisEsil *esil)
Definition: esil.c:1508
static bool __stepOut(RzAnalysisEsil *esil, const char *cmd)
Definition: esil.c:2984
static bool esil_mem_subeq4(RzAnalysisEsil *esil)
Definition: esil.c:2279
static bool esil_muleq(RzAnalysisEsil *esil)
Definition: esil.c:1658
static bool esil_address(RzAnalysisEsil *esil)
Definition: esil.c:732
static bool esil_mem_deceq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2496
static bool esil_eq(RzAnalysisEsil *esil)
Definition: esil.c:761
static bool esil_bigger(RzAnalysisEsil *esil)
Definition: esil.c:2734
static bool esil_andeq(RzAnalysisEsil *esil)
Definition: esil.c:845
static bool esil_mem_inceq1(RzAnalysisEsil *esil)
Definition: esil.c:2478
RZ_API int rz_analysis_esil_signext(RzAnalysisEsil *esil, bool assign)
Definition: esil.c:529
static bool esil_mem_lsleq(RzAnalysisEsil *esil)
Definition: esil.c:2588
static bool esil_inc(RzAnalysisEsil *esil)
Definition: esil.c:1716
static bool esil_poke_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:1816
static bool esil_diveq(RzAnalysisEsil *esil)
Definition: esil.c:1609
static bool esil_mem_addeq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2199
static bool esil_xor(RzAnalysisEsil *esil)
Definition: esil.c:1374
static bool esil_bf(RzAnalysisEsil *esil)
Definition: esil.c:623
static int internal_esil_mem_write_no_null(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: esil.c:318
static bool esil_swap(RzAnalysisEsil *esil)
Definition: esil.c:2664
static bool esil_mem_oreq4(RzAnalysisEsil *esil)
Definition: esil.c:2095
static bool esil_num(RzAnalysisEsil *esil)
Definition: esil.c:2639
static bool esil_peek16(RzAnalysisEsil *esil)
Definition: esil.c:2004
static bool esil_xoreq(RzAnalysisEsil *esil)
Definition: esil.c:886
static bool esil_mem_xoreq1(RzAnalysisEsil *esil)
Definition: esil.c:2135
static bool esil_poke1(RzAnalysisEsil *esil)
Definition: esil.c:1869
static bool esil_mem_diveq(RzAnalysisEsil *esil)
Definition: esil.c:2390
static bool esil_jt(RzAnalysisEsil *esil)
Definition: esil.c:715
static bool esil_smaller(RzAnalysisEsil *esil)
Definition: esil.c:2708
static bool esil_mem_inceq4(RzAnalysisEsil *esil)
Definition: esil.c:2484
static bool esil_mem_addeq8(RzAnalysisEsil *esil)
Definition: esil.c:2236
static bool esil_peek_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:1943
static bool esil_poke8(RzAnalysisEsil *esil)
Definition: esil.c:1885
RZ_API bool rz_analysis_esil_runword(RzAnalysisEsil *esil, const char *word)
Definition: esil.c:3095
#define OT_UNK
static bool esil_mem_oreq2(RzAnalysisEsil *esil)
Definition: esil.c:2092
static bool esil_cf(RzAnalysisEsil *esil)
Definition: esil.c:600
static bool esil_rol(RzAnalysisEsil *esil)
Definition: esil.c:1333
static bool esil_mem_lsreq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2594
static bool esil_mem_addeq4(RzAnalysisEsil *esil)
Definition: esil.c:2233
static bool esil_mem_muleq1(RzAnalysisEsil *esil)
Definition: esil.c:2424
static bool esil_mem_modeq4(RzAnalysisEsil *esil)
Definition: esil.c:2332
static bool esil_modeq(RzAnalysisEsil *esil)
Definition: esil.c:1532
static bool rz_analysis_esil_fire_trap(RzAnalysisEsil *esil, int trap_type, int trap_code)
Definition: esil.c:132
static bool esil_mem_modeq2(RzAnalysisEsil *esil)
Definition: esil.c:2329
static bool esil_rs(RzAnalysisEsil *esil)
Definition: esil.c:726
static bool esil_dec(RzAnalysisEsil *esil)
Definition: esil.c:1783
static bool esil_mem_lsreq(RzAnalysisEsil *esil)
Definition: esil.c:2634
static bool runword(RzAnalysisEsil *esil, const char *word)
Definition: esil.c:2867
static ut64 genmask(int bits)
Definition: esil.c:21
static bool esil_mem_andeq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2153
static bool esil_mem_lsleq_n(RzAnalysisEsil *esil, int bits)
Definition: esil.c:2540
RZ_API void rz_analysis_esil_interrupts_init(RzAnalysisEsil *esil)
RZ_API int rz_analysis_esil_fire_interrupt(RzAnalysisEsil *esil, ut32 intr_num)
RZ_API void rz_analysis_esil_interrupts_fini(RzAnalysisEsil *esil)
RZ_API void rz_analysis_esil_sources_init(RzAnalysisEsil *esil)
Definition: esil_sources.c:8
RZ_API void rz_analysis_esil_sources_fini(RzAnalysisEsil *esil)
Definition: esil_sources.c:85
RZ_API void rz_analysis_esil_mem_ro(RzAnalysisEsil *esil, int mem_readonly)
Definition: esil_stats.c:42
RZ_API void rz_analysis_esil_stats(RzAnalysisEsil *esil, int enable)
Definition: esil_stats.c:50
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace)
Definition: esil_trace.c:79
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
static RzMain foo[]
Definition: main.c:11
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode dup
Definition: sflib.h:68
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
char * dst
Definition: lz4.h:724
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
RZ_API void * sdb_ptr_get(Sdb *db, const char *key, ut32 *cas)
Definition: num.c:87
int off
Definition: pal.c:13
const char * code
Definition: pal.c:98
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
static RzSocket * s
Definition: rtr.c:28
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
#define RZ_ANALYSIS_ARCHINFO_DATA_ALIGN
Definition: rz_analysis.h:101
@ RZ_ANALYSIS_ESIL_PARM_NUM
Definition: rz_analysis.h:966
@ RZ_ANALYSIS_ESIL_PARM_INVALID
Definition: rz_analysis.h:964
@ RZ_ANALYSIS_ESIL_PARM_REG
Definition: rz_analysis.h:965
bool(* RzAnalysisEsilOpCb)(RzAnalysisEsil *esil)
Definition: rz_analysis.h:1187
#define RZ_ANALYSIS_ESIL_GOTO_LIMIT
Definition: rz_analysis.h:504
@ RZ_ANALYSIS_TRAP_UNHANDLED
Definition: rz_analysis.h:951
@ RZ_ANALYSIS_TRAP_DIVBYZERO
Definition: rz_analysis.h:953
@ RZ_ANALYSIS_TRAP_INVALID
Definition: rz_analysis.h:957
@ RZ_ANALYSIS_TRAP_TODO
Definition: rz_analysis.h:959
@ RZ_ANALYSIS_TRAP_WRITE_ERR
Definition: rz_analysis.h:954
@ RZ_ANALYSIS_TRAP_READ_ERR
Definition: rz_analysis.h:955
@ RZ_ANALYSIS_TRAP_UNALIGNED
Definition: rz_analysis.h:958
@ RZ_ANALYSIS_TRAP_BREAKPOINT
Definition: rz_analysis.h:952
int(* RzAnalysisEsilTrapCB)(RzAnalysisEsil *esil, int trap_type, int trap_code)
Definition: rz_analysis.h:1229
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
static void rz_write_ble(void *dst, ut64 val, bool big_endian, int size)
Definition: rz_endian.h:548
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API void rz_mem_swapendian(ut8 *dest, const ut8 *orig, int size)
Definition: mem.c:202
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API bool rz_str_range_in(const char *r, ut64 addr)
Definition: str.c:2807
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_BIT_CHK(x, y)
Definition: rz_types.h:316
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define st8
Definition: rz_types_base.h:16
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT64_MAX
Definition: rz_types_base.h:86
#define UT8_MAX
#define st16
Definition: rz_types_base.h:14
#define st32
Definition: rz_types_base.h:12
#define UT16_MAX
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
Definition: inftree9.h:24
int(* mem_write)(ANALYSIS_ESIL *esil, ut64 addr, const ut8 *buf, int len)
Definition: rz_analysis.h:1035
int(* hook_mem_read)(ANALYSIS_ESIL *esil, ut64 addr, ut8 *buf, int len)
Definition: rz_analysis.h:1032
int(* mem_read)(ANALYSIS_ESIL *esil, ut64 addr, ut8 *buf, int len)
Definition: rz_analysis.h:1033
int(* hook_command)(ANALYSIS_ESIL *esil, const char *op)
Definition: rz_analysis.h:1031
int(* reg_read)(ANALYSIS_ESIL *esil, const char *name, ut64 *res, int *size)
Definition: rz_analysis.h:1037
int(* hook_reg_read)(ANALYSIS_ESIL *esil, const char *name, ut64 *res, int *size)
Definition: rz_analysis.h:1036
int(* hook_mem_write)(ANALYSIS_ESIL *esil, ut64 addr, const ut8 *buf, int len)
Definition: rz_analysis.h:1034
int(* reg_write)(ANALYSIS_ESIL *esil, const char *name, ut64 val)
Definition: rz_analysis.h:1039
RzAnalysisEsilHookRegWriteCB hook_reg_write
Definition: rz_analysis.h:1038
RzAnalysisEsilOpCb code
Definition: rz_analysis.h:1190
RzAnalysis * analysis
Definition: rz_analysis.h:1043
RzAnalysisEsilCallbacks cb
Definition: rz_analysis.h:1078
RzAnalysisEsilTrace * trace
Definition: rz_analysis.h:1077
bool(* cmd)(ANALYSIS_ESIL *esil, const char *name, ut64 a0, ut64 a1)
Definition: rz_analysis.h:1089
RzStrBuf current_opstr
Definition: rz_analysis.h:1072
RzAnalysisEsilCB esil_fini
Definition: rz_analysis.h:1269
RzAnalysisEsilTrapCB esil_trap
Definition: rz_analysis.h:1268
RzAnalysisEsilCB esil_init
Definition: rz_analysis.h:1266
struct rz_analysis_plugin_t * cur
Definition: rz_analysis.h:586
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584
RzIOBind iob
Definition: rz_analysis.h:574
RzCoreBind coreb
Definition: rz_analysis.h:580
RzCoreSetArchBits setab
Definition: rz_bind.h:39
RzCoreCmd cmd
Definition: rz_bind.h:32
void * core
Definition: rz_bind.h:31
RzIOReadAt read_at
Definition: rz_io.h:240
RzIOIsValidOff is_valid_offset
Definition: rz_io.h:257
RzIOWriteAt write_at
Definition: rz_io.h:241
RzIO * io
Definition: rz_io.h:232
int size
in bits> 8,16,32,64 ... 128/256
Definition: rz_reg.h:120
int packed_size
0 means no packed register, 1byte pack, 2b pack...
Definition: rz_reg.h:122
uv_loop_t * loop
Definition: main.c:7
Definition: dis.c:32
struct op_code code
Definition: dis.c:33
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
eax
Definition: x86-32-avx.s.cs:79
ecx
Definition: x86-32-avx.s.cs:85
ebx
Definition: x86-32-avx.s.cs:85
static char * regname(int reg)
Definition: dis.c:71
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58
#define OF(args)
Definition: zconf.h:292
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115