Rizin
unix-like reverse engineering framework and cli tools
parse_x86_pseudo.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2020 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 
9 #include <rz_lib.h>
10 #include <rz_util.h>
11 #include <rz_analysis.h>
12 #include <rz_parse.h>
13 // 16 bit examples
14 // 0x0001f3a4 9a67620eca call word 0xca0e:0x6267
15 // 0x0001f41c eabe76de12 jmp word 0x12de:0x76be [2]
16 // 0x0001f56a ea7ed73cd3 jmp word 0xd33c:0xd77e [6]
17 static int replace(int argc, char *argv[], char *newstr) {
18 #define MAXPSEUDOOPS 10
19  int i, j, k, d;
20  char ch;
21  struct {
22  char *op;
23  char *str;
24  int args[MAXPSEUDOOPS]; // XXX can't use flex arrays, all unused will be 0
25  } ops[] = {
26  { "adc", "# += #", { 1, 2 } },
27  { "add", "# += #", { 1, 2 } },
28  { "and", "# &= #", { 1, 2 } },
29  { "call", "# ()", { 1 } },
30  { "cmove", "if (!var) # = #", { 1, 2 } },
31  { "cmovl", "if (var < 0) # = #", { 1, 2 } },
32  { "cmp", "var = # - #", { 1, 2 } },
33  { "cmpsq", "var = # - #", { 1, 2 } },
34  { "cmpsb", "while (CX != 0) { var = *(DS*16 + SI) - *(ES*16 + DI); SI++; DI++; CX--; if (!var) break; }", { 0 } },
35  { "cmpsw", "while (CX != 0) { var = *(DS*16 + SI) - *(ES*16 + DI); SI+=4; DI+=4; CX--; if (!var) break; }", { 0 } },
36  { "dec", "#--", { 1 } },
37  { "div", "# /= #", { 1, 2 } },
38  { "fabs", "abs(#)", { 1 } },
39  { "fadd", "# = # + #", { 1, 1, 2 } },
40  { "fcomp", "var = # - #", { 1, 2 } },
41  { "fcos", "# = cos(#)", { 1, 1 } },
42  { "fdiv", "# = # / #", { 1, 1, 2 } },
43  { "fiadd", "# = # / #", { 1, 1, 2 } },
44  { "ficom", "var = # - #", { 1, 2 } },
45  { "fidiv", "# = # / #", { 1, 1, 2 } },
46  { "fidiv", "# = # * #", { 1, 1, 2 } },
47  { "fisub", "# = # - #", { 1, 1, 2 } },
48  { "fnul", "# = # * #", { 1, 1, 2 } },
49  { "fnop", " ", { 0 } },
50  { "frndint", "# = (int) #", { 1, 1 } },
51  { "fsin", "# = sin(#)", { 1, 1 } },
52  { "fsqrt", "# = sqrt(#)", { 1, 1 } },
53  { "fsub", "# = # - #", { 1, 1, 2 } },
54  { "fxch", "#,# = #,#", { 1, 2, 2, 1 } },
55  { "idiv", "# /= #", { 1, 2 } },
56  { "imul", "# = # * #", { 1, 2, 3 } },
57  { "in", "# = io[#]", { 1, 2 } },
58  { "inc", "#++", { 1 } },
59  { "ja", "if (((unsigned) var) > 0) goto #", { 1 } },
60  { "jb", "if (((unsigned) var) < 0) goto #", { 1 } },
61  { "jbe", "if (((unsigned) var) <= 0) goto #", { 1 } },
62  { "je", "if (!var) goto #", { 1 } },
63  { "jg", "if (var > 0) goto #", { 1 } },
64  { "jge", "if (var >= 0) goto #", { 1 } },
65  { "jle", "if (var <= 0) goto #", { 1 } },
66  { "jmp", "goto #", { 1 } },
67  { "jne", "if (var) goto #", { 1 } },
68  { "lea", "# = #", { 1, 2 } },
69  { "mov", "# = #", { 1, 2 } },
70  { "movabs", "# = #", { 1, 2 } },
71  { "movq", "# = #", { 1, 2 } },
72  { "movaps", "# = #", { 1, 2 } },
73  { "movups", "# = #", { 1, 2 } },
74  { "movsd", "# = #", { 1, 2 } },
75  { "movsx", "# = #", { 1, 2 } },
76  { "movsxd", "# = #", { 1, 2 } },
77  { "movzx", "# = #", { 1, 2 } },
78  { "movntdq", "# = #", { 1, 2 } },
79  { "movnti", "# = #", { 1, 2 } },
80  { "movntpd", "# = #", { 1, 2 } },
81  { "pcmpeqb", "# == #", { 1, 2 } },
82 
83  { "movdqu", "# = #", { 1, 2 } },
84  { "movdqa", "# = #", { 1, 2 } },
85  { "pextrb", "# = (byte) # [#]", { 1, 2, 3 } },
86  { "palignr", "# = # align #", { 1, 2, 3 } },
87  { "pxor", "# ^= #", { 1, 2 } },
88  { "xorps", "# ^= #", { 1, 2 } },
89  { "mul", "# = # * #", { 1, 2, 3 } },
90  { "mulss", "# = # * #", { 1, 2, 3 } },
91  { "neg", "# ~= #", { 1, 1 } },
92  { "nop", "", { 0 } },
93  { "not", "# = !#", { 1, 1 } },
94  { "or", "# |= #", { 1, 2 } },
95  { "out", "io[#] = #", { 1, 2 } },
96  { "pop", "pop #", { 1 } },
97  { "push", "push #", { 1 } },
98  { "ret", "return", { 0 } },
99  { "sal", "# <<= #", { 1, 2 } },
100  { "sar", "# >>= #", { 1, 2 } },
101  { "sete", "# = e", { 1 } },
102  { "setne", "# = ne", { 1 } },
103  { "shl", "# <<<= #", { 1, 2 } },
104  { "shld", "# <<<= #", { 1, 2 } },
105  { "sbb", "# = # - #", { 1, 1, 2 } },
106  { "shr", "# >>>= #", { 1, 2 } },
107  { "shlr", "# >>>= #", { 1, 2 } },
108  //{ "strd", "# = # - #", {1, 2, 3}},
109  { "sub", "# -= #", { 1, 2 } },
110  { "swap", "var = #; # = #; # = var", { 1, 1, 2, 2 } },
111  { "test", "var = # & #", { 1, 2 } },
112  { "xchg", "#,# = #,#", { 1, 2, 2, 1 } },
113  { "xadd", "#,# = #,#+#", { 1, 2, 2, 1, 2 } },
114  { "xor", "# ^= #", { 1, 2 } },
115  { NULL }
116  };
117 
118  if (argc > 2 && !strcmp(argv[0], "xor")) {
119  if (!strcmp(argv[1], argv[2])) {
120  argv[0] = "mov";
121  argv[2] = "0";
122  }
123  }
124  for (i = 0; ops[i].op != NULL; i++) {
125  if (!strcmp(ops[i].op, argv[0])) {
126  if (newstr != NULL) {
127  d = 0;
128  j = 0;
129  ch = ops[i].str[j];
130  for (j = 0, k = 0; ch != '\0'; j++, k++) {
131  ch = ops[i].str[j];
132  if (ch == '#') {
133  if (d >= MAXPSEUDOOPS) {
134  // XXX Shouldn't ever happen...
135  continue;
136  }
137  int idx = ops[i].args[d];
138  d++;
139  if (idx <= 0) {
140  // XXX Shouldn't ever happen...
141  continue;
142  }
143  const char *w = argv[idx];
144  if (w != NULL) {
145  strcpy(newstr + k, w);
146  k += strlen(w) - 1;
147  }
148  } else {
149  newstr[k] = ch;
150  }
151  }
152  newstr[k] = '\0';
153  }
154  return true;
155  }
156  }
157 
158  /* TODO: this is slow */
159  if (newstr) {
160  newstr[0] = '\0';
161  for (i = 0; i < argc; i++) {
162  strcat(newstr, argv[i]);
163  strcat(newstr, (i == 0 || i == argc - 1) ? " " : ",");
164  }
165  }
166  return false;
167 }
168 
169 static bool parse(RzParse *p, const char *data, RzStrBuf *sb) {
170  char w0[256], w1[256], w2[256], w3[256];
171  char str[1024] = { 0 };
172  int i;
173  size_t len = strlen(data);
174  int sz = 32;
175  char *buf, *ptr, *optr, *end;
176  if (len >= sizeof(w0) || sz >= sizeof(w0)) {
177  return false;
178  }
179  // strdup can be slow here :?
180  if (!(buf = strdup(data))) {
181  return false;
182  }
183  *w0 = *w1 = *w2 = *w3 = '\0';
184  if (*buf) {
185  end = buf + strlen(buf);
186  ptr = strchr(buf, ' ');
187  if (!ptr) {
188  ptr = strchr(buf, '\t');
189  }
190  if (!ptr) {
191  ptr = end;
192  }
193  *ptr = '\0';
194  if (ptr != end) {
195  for (++ptr; *ptr == ' '; ptr++) {
196  ;
197  }
198  }
199  rz_str_ncpy(w0, buf, sizeof(w0));
200  rz_str_ncpy(w1, ptr, sizeof(w1));
201  optr = ptr;
202  ptr = strchr(ptr, ',');
203  if (ptr) {
204  *ptr = '\0';
205  for (++ptr; *ptr == ' '; ptr++) {
206  ;
207  }
208  rz_str_ncpy(w1, optr, sizeof(w1));
209  rz_str_ncpy(w2, ptr, sizeof(w2));
210  optr = ptr;
211  ptr = strchr(ptr, ',');
212  if (ptr) {
213  *ptr = '\0';
214  for (++ptr; *ptr == ' '; ptr++) {
215  ;
216  }
217  rz_str_ncpy(w2, optr, sizeof(w2));
218  rz_str_ncpy(w3, ptr, sizeof(w3));
219  }
220  }
221  }
222  char *wa[] = { w0, w1, w2, w3 };
223  int nw = 0;
224  for (i = 0; i < 4; i++) {
225  if (wa[i][0] != '\0') {
226  nw++;
227  }
228  }
229  /* TODO: interpretation of memory location fails*/
230  // ensure imul & mul interpretations works
231  if (strstr(w0, "mul")) {
232  if (nw == 2) {
233  rz_str_ncpy(wa[3], wa[1], sizeof(w3));
234 
235  switch (wa[3][0]) {
236  case 'q':
237  case 'r': // qword, r..
238  rz_str_ncpy(wa[1], "rax", sizeof(w1));
239  rz_str_ncpy(wa[2], "rax", sizeof(w2));
240  break;
241  case 'd':
242  case 'e': // dword, e..
243  if (strlen(wa[3]) > 2) {
244  rz_str_ncpy(wa[1], "eax", sizeof(w1));
245  rz_str_ncpy(wa[2], "eax", sizeof(w2));
246  }
247  break;
248  default: // .x, .p, .i or word
249  if (wa[3][1] == 'x' || wa[3][1] == 'p' ||
250  wa[3][1] == 'i' || wa[3][0] == 'w') {
251  rz_str_ncpy(wa[1], "ax", sizeof(w1));
252  rz_str_ncpy(wa[2], "ax", sizeof(w2));
253  } else { // byte and lowest 8 bit registers
254  rz_str_ncpy(wa[1], "al", sizeof(w1));
255  rz_str_ncpy(wa[2], "al", sizeof(w2));
256  }
257  break;
258  }
259  } else if (nw == 3) {
260  rz_str_ncpy(wa[3], wa[2], sizeof(w3));
261  rz_str_ncpy(wa[2], wa[1], sizeof(w2));
262  }
263 
264  replace(nw, wa, str);
265 
266  } else if (strstr(w0, "lea")) {
267  rz_str_replace_char(w2, '[', 0);
268  rz_str_replace_char(w2, ']', 0);
269  replace(nw, wa, str);
270  } else if ((strstr(w1, "ax") || strstr(w1, "ah") || strstr(w1, "al")) && !p->retleave_asm) {
271  if (!(p->retleave_asm = (char *)malloc(sz))) {
272  return false;
273  }
274  rz_snprintf(p->retleave_asm, sz, "return %s", w2);
275  replace(nw, wa, str);
276  } else if ((strstr(w0, "leave") && p->retleave_asm) || (strstr(w0, "pop") && strstr(w1, "bp"))) {
277  rz_str_ncpy(wa[0], " ", 2);
278  rz_str_ncpy(wa[1], " ", 2);
279  replace(nw, wa, str);
280  } else if (strstr(w0, "ret") && p->retleave_asm) {
281  rz_str_ncpy(str, p->retleave_asm, sz);
282  RZ_FREE(p->retleave_asm);
283  } else if (p->retleave_asm) {
284  RZ_FREE(p->retleave_asm);
285  replace(nw, wa, str);
286  } else {
287  replace(nw, wa, str);
288  }
289  free(buf);
290  rz_strbuf_set(sb, str);
291  return true;
292 }
293 
294 static void parse_localvar(RzParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, const char *ireg, bool att) {
295  RzStrBuf *sb = rz_strbuf_new("");
296  if (att) {
297  if (p->localvar_only) {
298  if (ireg) {
299  rz_strbuf_setf(sb, "(%%%s)", ireg);
300  }
301  snprintf(newstr, newstr_len - 1, "%s%s", var, rz_strbuf_get(sb));
302  } else {
303  if (ireg) {
304  rz_strbuf_setf(sb, ", %%%s", ireg);
305  }
306  snprintf(newstr, newstr_len - 1, "%s(%%%s%s)", var, reg, rz_strbuf_get(sb));
307  }
308  } else {
309  if (ireg) {
310  rz_strbuf_setf(sb, " + %s", ireg);
311  }
312  if (p->localvar_only) {
313  snprintf(newstr, newstr_len - 1, "%s%s", var, rz_strbuf_get(sb));
314  } else {
315  snprintf(newstr, newstr_len - 1, "%s%s %c %s", reg, rz_strbuf_get(sb), sign, var);
316  }
317  }
319 }
320 
321 static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, const char *ireg, char *dest, int len) {
322  RzStrBuf *sb = rz_strbuf_new("");
323  if (att) {
324  if (ireg) {
325  rz_strbuf_setf(sb, ", %%%s", ireg);
326  }
327  if (delta == 0) {
328  snprintf(dest, len - 1, "(%%%s%s)", regname, rz_strbuf_get(sb));
329  } else if (delta < 10) {
330  snprintf(dest, len - 1, "%s%d(%%%s%s)", sign ? "" : "-", delta, regname, rz_strbuf_get(sb));
331  } else {
332  snprintf(dest, len - 1, "%s0x%x(%%%s%s)", sign ? "" : "-", delta, regname, rz_strbuf_get(sb));
333  }
334  } else {
335  if (ireg) {
336  rz_strbuf_setf(sb, " + %s", ireg);
337  }
338  if (delta == 0) {
339  snprintf(dest, len - 1, "%s%s", regname, rz_strbuf_get(sb));
340  } else if (delta < 10) {
341  snprintf(dest, len - 1, "%s%s %c %d", regname, rz_strbuf_get(sb), sign ? '+' : '-', delta);
342  } else {
343  snprintf(dest, len - 1, "%s%s %c 0x%x", regname, rz_strbuf_get(sb), sign ? '+' : '-', delta);
344  }
345  }
347 }
348 
349 static bool subvar(RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len) {
350  const ut64 addr = op->addr;
351  const int oplen = op->size;
352  RzList *bpargs, *spargs;
353  RzAnalysis *analysis = p->analb.analysis;
354  RzListIter *bpargiter, *spiter;
355  char oldstr[64], newstr[64];
356  char *tstr = strdup(data);
357  if (!tstr) {
358  return false;
359  }
360 
361  bool att = strchr(data, '%');
362 
363  if (p->subrel) {
364  if (att) {
365  char *rip = (char *)rz_str_casestr(tstr, "(%rip)");
366  if (rip) {
367  *rip = 0;
368  char *pre = tstr;
369  char *pos = rip + 6;
370  char *word = rip;
371  while (word > tstr && *word != ' ') {
372  word--;
373  }
374 
375  if (word > tstr) {
376  *word++ = 0;
377  *rip = 0;
378  st64 n = rz_num_math(NULL, word);
379  ut64 repl_num = oplen + addr + n;
380  char *tstr_new = rz_str_newf("%s 0x%08" PFMT64x "%s", pre, repl_num, pos);
381  *rip = '(';
382  free(tstr);
383  tstr = tstr_new;
384  }
385  }
386  } else {
387  char *rip = (char *)rz_str_casestr(tstr, "[rip");
388  if (rip) {
389  char *ripend = strchr(rip + 3, ']');
390  const char *plus = strchr(rip, '+');
391  const char *neg = strchr(rip, '-');
392  char *tstr_new;
393  ut64 repl_num = oplen + addr;
394 
395  if (!ripend) {
396  ripend = "]";
397  }
398  if (plus) {
399  repl_num += rz_num_get(NULL, plus + 1);
400  }
401  if (neg) {
402  repl_num -= rz_num_get(NULL, neg + 1);
403  }
404 
405  rip[1] = '\0';
406  tstr_new = rz_str_newf("%s0x%08" PFMT64x "%s", tstr, repl_num, ripend);
407  free(tstr);
408  tstr = tstr_new;
409  }
410  }
411  }
412 
413  if (!p->varlist) {
414  free(tstr);
415  return false;
416  }
417  bpargs = p->varlist(f, 'b');
418  spargs = p->varlist(f, 's');
419  /* Iterate over stack pointer arguments/variables */
420  bool ucase = *tstr >= 'A' && *tstr <= 'Z';
421  if (ucase && tstr[1]) {
422  ucase = tstr[1] >= 'A' && tstr[1] <= 'Z';
423  }
424  const char *ireg = op->ireg;
425  RzAnalysisVarField *bparg, *sparg;
426  rz_list_foreach (spargs, spiter, sparg) {
427  char sign = '+';
428  st64 delta = p->get_ptr_at
429  ? p->get_ptr_at(f, sparg->delta, addr)
430  : ST64_MAX;
431  if (delta == ST64_MAX && sparg->field) {
432  delta = sparg->delta;
433  } else if (delta == ST64_MAX) {
434  continue;
435  }
436  if (delta < 0) {
437  sign = '-';
438  delta = -delta;
439  }
440  const char *reg = NULL;
441  if (p->get_reg_at) {
442  reg = p->get_reg_at(f, sparg->delta, addr);
443  }
444  if (!reg) {
445  reg = analysis->reg->name[RZ_REG_NAME_SP];
446  }
447  mk_reg_str(reg, delta, sign == '+', att, ireg, oldstr, sizeof(oldstr));
448 
449  if (ucase) {
450  rz_str_case(oldstr, true);
451  }
452  parse_localvar(p, newstr, sizeof(newstr), sparg->name, reg, sign, ireg, att);
453  char *ptr = strstr(tstr, oldstr);
454  if (ptr && (!att || *(ptr - 1) == ' ')) {
455  if (delta == 0) {
456  char *end = ptr + strlen(oldstr);
457  if (*end != ']' && *end != '\0') {
458  continue;
459  }
460  }
461  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
462  break;
463  } else {
464  rz_str_case(oldstr, false);
465  ptr = strstr(tstr, oldstr);
466  if (ptr && (!att || *(ptr - 1) == ' ')) {
467  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
468  break;
469  }
470  }
471  }
472  /* iterate over base pointer args/vars */
473  rz_list_foreach (bpargs, bpargiter, bparg) {
474  char sign = '+';
475  st64 delta = p->get_ptr_at
476  ? p->get_ptr_at(f, bparg->delta, addr)
477  : ST64_MAX;
478  if (delta == ST64_MAX && bparg->field) {
479  delta = bparg->delta + f->bp_off;
480  } else if (delta == ST64_MAX) {
481  continue;
482  }
483  if (delta < 0) {
484  sign = '-';
485  delta = -delta;
486  }
487  const char *reg = NULL;
488  if (p->get_reg_at) {
489  reg = p->get_reg_at(f, bparg->delta, addr);
490  }
491  if (!reg) {
492  reg = analysis->reg->name[RZ_REG_NAME_BP];
493  }
494  mk_reg_str(reg, delta, sign == '+', att, ireg, oldstr, sizeof(oldstr));
495  if (ucase) {
496  rz_str_case(oldstr, true);
497  }
498  parse_localvar(p, newstr, sizeof(newstr), bparg->name, reg, sign, ireg, att);
499  char *ptr = strstr(tstr, oldstr);
500  if (ptr && (!att || *(ptr - 1) == ' ')) {
501  if (delta == 0) {
502  char *end = ptr + strlen(oldstr);
503  if (*end != ']' && *end != '\0') {
504  continue;
505  }
506  }
507  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
508  break;
509  } else {
510  rz_str_case(oldstr, false);
511  ptr = strstr(tstr, oldstr);
512  if (ptr && (!att || *(ptr - 1) == ' ')) {
513  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
514  break;
515  }
516  }
517  // Figure out the first hex digit of the delta to know if we need a leading zero
518  st64 delta_first_digit = delta;
519  while (delta_first_digit >= 16) {
520  delta_first_digit /= 16;
521  }
522  // Try with trailing-h notation (if using MASM syntax)
523  snprintf(oldstr, sizeof(oldstr) - 1, "%s %c %s%xh", reg, sign, delta_first_digit > 9 ? "0" : "", (int)delta);
524  if (rz_str_casestr(tstr, oldstr)) {
525  tstr = rz_str_replace_icase(tstr, oldstr, newstr, 1, 0);
526  break;
527  }
528  // Try with no spaces
529  snprintf(oldstr, sizeof(oldstr) - 1, "[%s%c0x%x]", reg, sign, (int)delta);
530  if (strstr(tstr, oldstr) != NULL) {
531  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
532  break;
533  }
534  }
535 
536  char bp[32];
537  if (analysis->reg->name[RZ_REG_NAME_BP]) {
538  strncpy(bp, analysis->reg->name[RZ_REG_NAME_BP], sizeof(bp) - 1);
539  if (isupper((ut8)*str)) {
540  rz_str_case(bp, true);
541  }
542  bp[sizeof(bp) - 1] = 0;
543  } else {
544  bp[0] = 0;
545  }
546 
547  bool ret = true;
548  if (len > strlen(tstr)) {
549  strcpy(str, tstr);
550  } else {
551  // TOO BIG STRING CANNOT REPLACE HERE
552  ret = false;
553  }
554  free(tstr);
555  rz_list_free(spargs);
556  rz_list_free(bpargs);
557  return ret;
558 }
559 
561  .name = "x86.pseudo",
562  .desc = "X86 pseudo syntax",
563  .parse = &parse,
564  .subvar = &subvar,
565 };
566 
567 #ifndef RZ_PLUGIN_INCORE
571  .version = RZ_VERSION
572 };
573 #endif
size_t len
Definition: 6502dis.c:15
static struct @29 ops[]
ut8 op
Definition: 6502dis.c:13
lzma_index ** i
Definition: index.h:629
static ut32 neg(ArmOp *op)
Definition: armass64.c:981
static RASN1String * newstr(const char *string)
Definition: astr.c:23
static SblHeader sb
Definition: bin_mbn.c:26
void rip(char *fname, off_t offset, unsigned int length)
Definition: cabrip.c:18
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define w
Definition: crypto_rc6.c:13
const char * k
Definition: dsignal.c:11
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
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 * dest
Definition: lz4.h:697
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
int idx
Definition: setup.py:197
static bool parse(RzParse *p, const char *data, RzStrBuf *sb)
static int replace(int argc, char *argv[], char *newstr)
static bool subvar(RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len)
RZ_API RzLibStruct rizin_plugin
#define MAXPSEUDOOPS
static void mk_reg_str(const char *regname, int delta, bool sign, bool att, const char *ireg, char *dest, int len)
RzParsePlugin rz_parse_plugin_x86_pseudo
static void parse_localvar(RzParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, const char *ireg, bool att)
RZ_DEPRECATE struct rz_analysis_var_field_t RzAnalysisVarField
@ RZ_LIB_TYPE_PARSE
Definition: rz_lib.h:74
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
RZ_API char * rz_str_replace_icase(char *str, const char *key, const char *val, int g, int keep_case)
Definition: str.c:1160
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API void rz_str_case(char *str, bool up)
Definition: str.c:341
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
Definition: str.c:923
RZ_API int rz_snprintf(char *string, int len, const char *fmt,...) RZ_PRINTF_CHECK(3
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
RZ_API const char * rz_str_casestr(const char *a, const char *b)
Definition: str.c:2757
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define ST64_MAX
Definition: rz_types_base.h:84
#define RZ_VERSION
Definition: rz_version.h:8
#define isupper(c)
Definition: safe-ctype.h:143
#define d(i)
Definition: sha256.c:44
#define f(i)
Definition: sha256.c:46
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
int pos
Definition: main.c:11
Definition: dis.c:32
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static char * regname(int reg)
Definition: dis.c:71
static int addr
Definition: z80asm.c:58