Rizin
unix-like reverse engineering framework and cli tools
disasm.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2021 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
3 // SPDX-FileCopyrightText: 2009-2021 dso <dso@rice.edu>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 #include <rz_core.h>
7 #include <rz_socket.h>
8 #include <rz_util/rz_assert.h>
9 #include <rz_util/rz_print.h>
10 #include "core_private.h"
11 #include "rz_analysis.h"
12 #include <rz_util/rz_strbuf.h>
13 
14 #define HASRETRY 1
15 #define HAVE_LOCALS 1
16 #define DEFAULT_NARGS 4
17 #define FLAG_PREFIX ";-- "
18 
19 #define COLOR(ds, field) ((ds)->show_color ? (ds)->field : "")
20 #define COLOR_ARG(ds, field) ((ds)->show_color && (ds)->show_color_args ? (ds)->field : "")
21 #define COLOR_CONST(ds, color) ((ds)->show_color ? Color_##color : "")
22 #define COLOR_RESET(ds) COLOR_CONST(ds, RESET)
23 
24 #define DS_ANALYSIS_OP_MASK (RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_ESIL | \
25  RZ_ANALYSIS_OP_MASK_VAL | (ds->show_cmt_il ? RZ_ANALYSIS_OP_MASK_IL : 0))
26 
27 // ugly globals but meh
28 static ut64 emustack_min = 0LL;
29 static ut64 emustack_max = 0LL;
30 
31 static const char *rz_vline_a[] = {
32  "|", // LINE_VERT
33  "|-", // LINE_CROSS
34  "-", // LINE_HORIZ
35  ":", // LINE_UP
36  ",", // LUP_CORNER
37  "\\", // RDWN_CORNER
38  "/", // RUP_CORNER
39  "`", // LDWN_CORNER
40  "->", // ARROW_RIGHT
41  "=<", // ARROW_LEFT
42  "@", // SELF_LOOP
43 };
44 
45 static const char *rz_vline_u[] = {
46  "│", // LINE_VERT
47  "├", // LINE_CROSS
48  "─", // LINE_HORIZ
49  "╎", // LINE_UP
50  // "↑", // LINE_UP
51  //"┌", // LUP_CORNER
52  "┘", // LUP_CORNER
53  "└", // RDWN_CORNER
54  "┌", // RUP_CORNER
55  "┐", // LDWN_CORNER
56  ">", // ARROW_RIGHT
57  "<", // ARROW_LEFT
58  "@", // SELF_LOOP
59 };
60 
61 static const char *rz_vline_uc[] = {
62  "│", // LINE_VERT
63  "├", // LINE_CROSS
64  "─", // LINE_HORIZ
65  // "↑", // LINE_UP
66  "╎", // LINE_UP
67  // "≀", // LINE_UP
68  //"┌", // LUP_CORNER
69  "╯", // LUP_CORNER
70  "╰", // RDWN_CORNER
71  "╭", // RUP_CORNER
72  "╮", // LDWN_CORNER
73  ">", // ARROW_RIGHT
74  "<", // ARROW_LEFT
75  "@", // SELF_LOOP
76 };
77 
78 #define DS_PRE_NONE 0
79 #define DS_PRE_EMPTY 1
80 #define DS_PRE_FCN_HEAD 2
81 #define DS_PRE_FCN_MIDDLE 3
82 #define DS_PRE_FCN_TAIL 4
83 
84 // TODO: what about using bit shifting and enum for keys? see librz/util/bitmap.c
85 // the problem of this is that the fields will be more opaque to bindings, but we will earn some bits
86 typedef struct {
88  char str[1024], strsub[1024];
89  bool immtrim;
90  bool immstr;
91  bool use_esil;
92  bool show_color;
95  int colorop;
96  int acase;
97  bool capitalize;
99  bool hasMidflag;
100  bool hasMidbb;
101  int atabs;
103  int atabsoff;
104  int decode;
105  bool pseudo;
106  int subnames;
108  bool subjmp;
109  bool subvar;
120  bool show_size;
124  int linesout;
126  bool asm_meta;
129  bool asm_instr;
131  bool show_offdec; // dupe for rz_print->flags
133  bool show_emu;
134  bool pre_emu;
152  bool bblined;
159  bool asm_hints;
168  bool show_slow;
170  int cmtcol;
178  int stackFd;
181  const char *show_cmtoff;
186  int cursor;
190  int lbytes;
192  int pre;
193  char *ocomment;
195  int lastfail;
196  int ocols;
197  int lcols;
198  int nb, nbytes;
200  int lines;
201  int oplen;
203  bool show_vars;
208  int midflags;
209  bool midbb;
210  bool midcursor;
213  const char *pal_comment;
214  const char *color_comment;
215  const char *color_usrcmt;
216  const char *color_fname;
217  const char *color_floc;
218  const char *color_fline;
219  const char *color_flow;
220  const char *color_flow2;
221  const char *color_flag;
222  const char *color_label;
223  const char *color_offset;
224  const char *color_other;
225  const char *color_nop;
226  const char *color_bin;
227  const char *color_math;
228  const char *color_btext;
229  const char *color_jmp;
230  const char *color_cjmp;
231  const char *color_call;
232  const char *color_cmp;
233  const char *color_swi;
234  const char *color_trap;
235  const char *color_ret;
236  const char *color_push;
237  const char *color_pop;
238  const char *color_reg;
239  const char *color_num;
240  const char *color_mov;
241  const char *color_invalid;
242  const char *color_gui_cflow;
243  const char *color_gui_dataoffset;
244  const char *color_gui_background;
246  const char *color_gui_border;
247  const char *color_linehl;
248  const char *color_func_var;
249  const char *color_func_var_type;
250  const char *color_func_var_addr;
251 
255 
260 
261  int l;
262  int middle;
265  char *line;
266  char *line_col, *prev_line_col;
267  char *refline, *refline2;
268  char *comment;
269  char *opstr;
270  char *osl, *sl;
271  int stackptr, ostackptr;
272  int index;
273  ut64 at, vat, addr, dest;
274  int tries, cbytes, idx;
275  char chref;
276  bool retry;
281  const ut8 *buf;
282  int len;
283  int maxrefs;
285  char *prev_ins;
290  // caches
291  char *_tabsbuf;
292  int _tabsoff;
293  bool dwarfFile;
297  int cmtcount;
302 
303  PJ *pj; // not null if printing json
305  const char *strip;
306  int maxflags;
308 
310 } RzDisasmState;
311 
312 static void ds_setup_print_pre(RzDisasmState *ds, bool tail, bool middle);
313 static void ds_setup_pre(RzDisasmState *ds, bool tail, bool middle);
314 static void ds_print_pre(RzDisasmState *ds, bool fcnline);
315 static void ds_pre_line(RzDisasmState *ds);
316 static void ds_begin_line(RzDisasmState *ds);
317 static void ds_newline(RzDisasmState *ds);
318 static void ds_begin_cont(RzDisasmState *ds);
319 static void ds_print_esil_analysis(RzDisasmState *ds);
320 static void ds_reflines_init(RzDisasmState *ds);
321 static void ds_align_comment(RzDisasmState *ds);
322 static RzDisasmState *ds_init(RzCore *core);
323 static void ds_build_op_str(RzDisasmState *ds, bool print_color);
324 static void ds_print_show_bytes(RzDisasmState *ds);
325 static void ds_pre_xrefs(RzDisasmState *ds, bool no_fcnlines);
326 static void ds_show_xrefs(RzDisasmState *ds);
327 static void ds_atabs_option(RzDisasmState *ds);
328 static void ds_show_functions(RzDisasmState *ds);
329 static void ds_control_flow_comments(RzDisasmState *ds);
330 static void ds_adistrick_comments(RzDisasmState *ds);
331 static void ds_print_comments_right(RzDisasmState *ds);
332 static void ds_show_comments_right(RzDisasmState *ds);
333 static void ds_show_flags(RzDisasmState *ds, bool overlapped);
334 static void ds_update_ref_lines(RzDisasmState *ds);
335 static int ds_disassemble(RzDisasmState *ds, ut8 *buf, int len);
336 static void ds_print_lines_right(RzDisasmState *ds);
337 static void ds_print_lines_left(RzDisasmState *ds);
338 static void ds_print_cycles(RzDisasmState *ds);
339 static void ds_print_family(RzDisasmState *ds);
341 static void ds_print_offset(RzDisasmState *ds);
342 static void ds_print_op_size(RzDisasmState *ds);
343 static void ds_print_trace(RzDisasmState *ds);
344 static void ds_print_opstr(RzDisasmState *ds);
345 static void ds_print_color_reset(RzDisasmState *ds);
346 static int ds_print_middle(RzDisasmState *ds, int ret);
348 static void ds_print_sysregs(RzDisasmState *ds);
349 static void ds_print_fcn_name(RzDisasmState *ds);
350 static void ds_print_as_string(RzDisasmState *ds);
351 static bool ds_print_core_vmode(RzDisasmState *ds, int pos);
352 static void ds_print_dwarf(RzDisasmState *ds);
353 static void ds_print_asmop_payload(RzDisasmState *ds, const ut8 *buf);
354 static char *ds_esc_str(RzDisasmState *ds, const char *str, int len, const char **prefix_out, bool is_comment);
355 static void ds_print_ptr(RzDisasmState *ds, int len, int idx);
356 static void ds_print_demangled(RzDisasmState *ds);
357 static void ds_print_str(RzDisasmState *ds, const char *str, int len, ut64 refaddr);
358 static char *ds_sub_jumps(RzDisasmState *ds, char *str);
359 static void ds_start_line_highlight(RzDisasmState *ds);
360 static void ds_end_line_highlight(RzDisasmState *ds);
361 static bool line_highlighted(RzDisasmState *ds);
362 static int ds_print_shortcut(RzDisasmState *ds, ut64 addr, int pos);
363 
365  if (core->print->pava) {
367  if (map) {
368  return addr - map->delta + map->itv.addr;
369  }
370  }
371  return addr;
372 }
373 
375  if (ds->fcn && rz_analysis_function_contains(ds->fcn, at)) {
376  return ds->fcn;
377  }
378  return rz_analysis_get_fcn_in(ds->core->analysis, at, type);
379 }
380 
381 static const char *get_utf8_char(const char line, RzDisasmState *ds) {
382  switch (line) {
383  case '<': return ds->core->cons->vline[ARROW_LEFT];
384  case '>': return ds->core->cons->vline[ARROW_RIGHT];
385  case ':': return ds->core->cons->vline[LINE_UP];
386  case '|': return ds->core->cons->vline[LINE_VERT];
387  case '=':
388  case '-': return ds->core->cons->vline[LINE_HORIZ];
389  case ',': return ds->core->cons->vline[CORNER_TL];
390  case '.': return ds->core->cons->vline[CORNER_TR];
391  case '`': return ds->core->cons->vline[CORNER_BL];
392  case '@': return ds->core->cons->vline[SELF_LOOP];
393  default: return " ";
394  }
395 }
396 
397 static void ds_print_ref_lines(char *line, char *line_col, RzDisasmState *ds) {
398  int i;
399  int len = strlen(line);
401  if (ds->show_color) {
402  for (i = 0; i < len; i++) {
403  if (line[i] == ' ') {
404  rz_cons_printf(" ");
405  continue;
406  }
407  if (line_col[i] == 'd') {
408  rz_cons_printf("%s%s%s", COLOR(ds, color_flow), get_utf8_char(line[i], ds), COLOR_RESET(ds));
409  } else {
410  rz_cons_printf("%s%s%s", COLOR(ds, color_flow2), get_utf8_char(line[i], ds), COLOR_RESET(ds));
411  }
412  }
413  } else {
414  len = strlen(line);
415  for (i = 0; i < len; i++) {
416  rz_cons_printf("%s", get_utf8_char(line[i], ds));
417  }
418  }
419  } else {
420  if (ds->show_color) {
421  for (i = 0; i < len; i++) {
422  if (line[i] == ' ') {
423  rz_cons_printf(" ");
424  continue;
425  }
426  if (line_col[i] == 'd') {
427  rz_cons_printf("%s%c%s", COLOR(ds, color_flow), line[i], COLOR_RESET(ds));
428  } else {
429  rz_cons_printf("%s%c%s", COLOR(ds, color_flow2), line[i], COLOR_RESET(ds));
430  }
431  }
432  } else {
433  rz_cons_printf("%s", line);
434  }
435  }
436 }
437 
438 static void get_bits_comment(RzCore *core, RzAnalysisFunction *f, char *cmt, int cmt_size) {
439  if (core && f && cmt && cmt_size > 0 && f->bits && f->bits != core->rasm->bits) {
440  const char *asm_arch = rz_config_get(core->config, "asm.arch");
441  if (asm_arch && *asm_arch && strstr(asm_arch, "arm")) {
442  switch (f->bits) {
443  case 16: strcpy(cmt, " (thumb)"); break;
444  case 32: strcpy(cmt, " (arm)"); break;
445  case 64: strcpy(cmt, " (aarch64)"); break;
446  }
447  } else {
448  snprintf(cmt, cmt_size, " (%d bits)", f->bits);
449  }
450  } else {
451  if (cmt) {
452  cmt[0] = 0;
453  }
454  }
455 }
456 
458  static char section[128] = "";
459  static ut64 oaddr = UT64_MAX;
460  if (oaddr == addr) {
461  return section;
462  }
463  RzBinObject *bo = rz_bin_cur_object(core->bin);
464  RzBinSection *s = bo ? rz_bin_get_section_at(bo, addr, core->io->va) : NULL;
465  if (s && s->name && *s->name) {
466  snprintf(section, sizeof(section) - 1, "%10s ", s->name);
467  } else {
468  RzListIter *iter;
469  RzDebugMap *map;
470  *section = 0;
471  rz_list_foreach (core->dbg->maps, iter, map) {
472  if (addr >= map->addr && addr < map->addr_end) {
473  const char *mn = rz_str_lchr(map->name, '/');
474  rz_str_ncpy(section, mn ? mn + 1 : map->name, sizeof(section));
475  break;
476  }
477  }
478  }
479  oaddr = addr;
480  return section;
481 }
482 
483 // up means if this lines go up, it controls whether to insert `_
484 // nl if we have to insert new line, it controls whether to insert \n
485 static void _ds_comment_align_(RzDisasmState *ds, bool up, bool nl) {
486  if (ds->show_comment_right) {
487  if (ds->show_color) {
488  rz_cons_print(ds->pal_comment);
489  }
490  return;
491  }
492  const char *sn = ds->show_section ? rz_core_get_section_name(ds->core, ds->at) : "";
493  ds_align_comment(ds);
494  ds_align_comment(ds);
495  rz_cons_print(COLOR_RESET(ds));
496  ds_print_pre(ds, true);
497  rz_cons_printf("%s%s", nl ? "\n" : "", sn);
498  ds_print_ref_lines(ds->refline, ds->line_col, ds);
499  rz_cons_printf(" %s %s", up ? "" : ".-", COLOR(ds, color_comment));
500 }
501 #define CMT_ALIGN _ds_comment_align_(ds, true, false)
502 
504  CMT_ALIGN;
505 }
506 
507 static void ds_comment_(RzDisasmState *ds, bool align, bool nl, const char *format, va_list ap) {
508  if (ds->show_comments) {
509  if (ds->show_comment_right && align) {
510  ds_align_comment(ds);
511  } else {
512  rz_cons_printf("%s", COLOR(ds, color_comment));
513  }
514  }
515 
516  rz_cons_printf_list(format, ap);
517  if (!ds->show_comment_right && nl) {
518  ds_newline(ds);
519  }
520 }
521 
522 static void ds_comment(RzDisasmState *ds, bool align, const char *format, ...) {
523  va_list ap;
524  va_start(ap, format);
525  ds->cmtcount++;
526  ds_comment_(ds, align, align, format, ap);
527  va_end(ap);
528 }
529 
530 #define DS_COMMENT_FUNC(name, align, nl) \
531  static void ds_comment_##name(RzDisasmState *ds, const char *format, ...) { \
532  va_list ap; \
533  va_start(ap, format); \
534  ds_comment_(ds, align, nl, format, ap); \
535  va_end(ap); \
536  }
537 
538 DS_COMMENT_FUNC(start, true, false)
539 DS_COMMENT_FUNC(middle, false, false)
541 
542 static void ds_comment_esil(RzDisasmState *ds, bool up, bool end, const char *format, ...) {
543  va_list ap;
544  va_start(ap, format);
545 
546  if (ds->show_comments && up) {
547  ds->show_comment_right ? ds_align_comment(ds) : ds_comment_lineup(ds);
548  }
549  rz_cons_printf_list(format, ap);
550  va_end(ap);
551 
552  if (ds->show_comments && !ds->show_comment_right) {
553  if (end) {
554  ds_newline(ds);
555  }
556  }
557 }
558 
560  RzCore *core = ds->core;
561  if (ds->show_emu && ds->esil_regstate) {
562  RzCore *core = ds->core;
564  const char *pc = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
566  if (!regset) {
567  eprintf("ESIL: fail to get regset\n");
568  RZ_FREE(ds->esil_regstate);
569  return;
570  }
571  if (ds->esil_regstate_size == regset->arena->size) {
573  }
574  rz_reg_setv(core->analysis->reg, pc, ds->esil_old_pc);
575  RZ_FREE(ds->esil_regstate);
576  }
577  if (core && core->analysis && core->analysis->esil) {
578  // make sure to remove reference to ds to avoid UAF
579  core->analysis->esil->user = NULL;
580  }
581 }
582 
583 static RzDisasmState *ds_init(RzCore *core) {
585  if (!ds) {
586  return NULL;
587  }
588  ds->core = core;
589  ds->strip = rz_config_get(core->config, "asm.strip");
590  ds->pal_comment = core->cons->context->pal.comment;
591 #define P(x) (core->cons && core->cons->context->pal.x) ? core->cons->context->pal.x
592  ds->color_comment = P(comment)
593  : Color_CYAN;
594  ds->color_usrcmt = P(usercomment)
595  : Color_CYAN;
596  ds->color_fname = P(fname)
597  : Color_RED;
598  ds->color_floc = P(floc)
599  : Color_MAGENTA;
600  ds->color_fline = P(fline)
601  : Color_CYAN;
602  ds->color_flow = P(flow)
603  : Color_CYAN;
604  ds->color_flow2 = P(flow2)
605  : Color_BLUE;
606  ds->color_flag = P(flag)
607  : Color_CYAN;
608  ds->color_label = P(label)
609  : Color_CYAN;
610  ds->color_offset = P(offset)
611  : Color_GREEN;
612  ds->color_other = P(other)
613  : Color_WHITE;
614  ds->color_nop = P(nop)
615  : Color_BLUE;
616  ds->color_bin = P(bin)
617  : Color_YELLOW;
618  ds->color_math = P(math)
619  : Color_YELLOW;
620  ds->color_btext = P(btext)
621  : Color_YELLOW;
622  ds->color_jmp = P(jmp)
623  : Color_GREEN;
624  ds->color_cjmp = P(cjmp)
625  : Color_GREEN;
626  ds->color_call = P(call)
627  : Color_BGREEN;
628  ds->color_cmp = P(cmp)
629  : Color_MAGENTA;
630  ds->color_swi = P(swi)
631  : Color_MAGENTA;
632  ds->color_trap = P(trap)
633  : Color_BRED;
634  ds->color_ret = P(ret)
635  : Color_RED;
636  ds->color_push = P(push)
637  : Color_YELLOW;
638  ds->color_pop = P(pop)
639  : Color_BYELLOW;
640  ds->color_reg = P(reg)
641  : Color_YELLOW;
642  ds->color_num = P(num)
643  : Color_CYAN;
644  ds->color_mov = P(mov)
645  : Color_WHITE;
646  ds->color_invalid = P(invalid)
647  : Color_BRED;
648  ds->color_gui_cflow = P(gui_cflow)
649  : Color_YELLOW;
650  ds->color_gui_dataoffset = P(gui_dataoffset)
651  : Color_YELLOW;
652  ds->color_gui_background = P(gui_background)
653  : Color_BLACK;
654  ds->color_gui_alt_background = P(gui_alt_background)
655  : Color_GRAY;
656  ds->color_gui_border = P(gui_border)
657  : Color_BGGRAY;
658  ds->color_linehl = P(linehl)
659  : Color_BGBLUE;
660  ds->color_func_var = P(func_var)
661  : Color_WHITE;
662  ds->color_func_var_type = P(func_var_type)
663  : Color_BLUE;
664  ds->color_func_var_addr = P(func_var_addr)
665  : Color_CYAN;
666 
667  ds->immstr = rz_config_get_b(core->config, "asm.imm.str");
668  ds->immtrim = rz_config_get_b(core->config, "asm.imm.trim");
669  ds->use_esil = rz_config_get_b(core->config, "asm.esil");
670  ds->pre_emu = rz_config_get_b(core->config, "emu.pre");
671  ds->show_flgoff = rz_config_get_b(core->config, "asm.flags.offset");
672  ds->show_nodup = rz_config_get_b(core->config, "asm.nodup");
673  {
674  const char *ah = rz_config_get(core->config, "asm.highlight");
675  ds->asm_highlight = (ah && *ah) ? rz_num_math(core->num, ah) : UT64_MAX;
676  }
677  ds->asm_analysis = rz_config_get_b(core->config, "asm.analysis");
678  ds->show_color = rz_config_get_i(core->config, "scr.color");
679  ds->show_color_bytes = rz_config_get_b(core->config, "scr.color.bytes"); // maybe rename to asm.color.bytes
680  ds->show_color_args = rz_config_get_b(core->config, "scr.color.args");
681  ds->colorop = rz_config_get_b(core->config, "scr.color.ops"); // XXX confusing name // asm.color.inst (mnemonic + operands) ?
682  ds->show_utf8 = rz_config_get_b(core->config, "scr.utf8");
683  ds->acase = rz_config_get_b(core->config, "asm.ucase");
684  ds->capitalize = rz_config_get_b(core->config, "asm.capitalize");
685  ds->atabs = rz_config_get_i(core->config, "asm.tabs");
686  ds->atabsonce = rz_config_get_b(core->config, "asm.tabs.once");
687  ds->atabsoff = rz_config_get_i(core->config, "asm.tabs.off");
688  ds->midflags = rz_config_get_i(core->config, "asm.flags.middle");
689  ds->midbb = rz_config_get_b(core->config, "asm.bb.middle");
690  ds->midcursor = rz_config_get_b(core->config, "asm.midcursor");
691  ds->decode = rz_config_get_b(core->config, "asm.decode");
692  core->parser->pseudo = ds->pseudo = rz_config_get_b(core->config, "asm.pseudo");
693  if (ds->pseudo) {
694  ds->atabs = 0;
695  }
696  ds->subnames = rz_config_get_b(core->config, "asm.sub.names");
698  ds->subjmp = rz_config_get_b(core->config, "asm.sub.jmp");
699  ds->subvar = rz_config_get_b(core->config, "asm.sub.var");
700  core->parser->subrel = rz_config_get_b(core->config, "asm.sub.rel");
701  core->parser->subreg = rz_config_get_b(core->config, "asm.sub.reg");
702  core->parser->localvar_only = rz_config_get_b(core->config, "asm.sub.varonly");
703  core->parser->retleave_asm = NULL;
704  ds->show_fcnsig = rz_config_get_b(core->config, "asm.fcn.signature");
705  ds->show_fcnsize = rz_config_get_b(core->config, "asm.fcn.size");
706  ds->show_vars = rz_config_get_b(core->config, "asm.var");
707  ds->show_varsum = rz_config_get_i(core->config, "asm.var.summary");
708  ds->show_varaccess = rz_config_get_b(core->config, "asm.var.access");
709  ds->maxrefs = rz_config_get_i(core->config, "asm.xrefs.max");
710  ds->maxflags = rz_config_get_i(core->config, "asm.flags.limit");
711  ds->flags_inline = rz_config_get_i(core->config, "asm.flags.inline");
712  ds->asm_types = rz_config_get_i(core->config, "asm.types");
713  ds->foldxrefs = rz_config_get_i(core->config, "asm.xrefs.fold");
714  ds->show_lines = rz_config_get_b(core->config, "asm.lines");
715  ds->show_lines_bb = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.bb") : false;
716  ds->linesright = rz_config_get_b(core->config, "asm.lines.right");
717  ds->show_indent = rz_config_get_b(core->config, "asm.indent");
718  ds->indent_space = rz_config_get_i(core->config, "asm.indentspace");
719  ds->tracespace = rz_config_get_i(core->config, "asm.tracespace");
720  ds->cyclespace = rz_config_get_i(core->config, "asm.cyclespace");
721  ds->show_dwarf = rz_config_get_b(core->config, "asm.dwarf");
722  ds->dwarfFile = rz_config_get_b(ds->core->config, "asm.dwarf.file");
723  ds->dwarfAbspath = rz_config_get_b(ds->core->config, "asm.dwarf.abspath");
724  ds->show_lines_call = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.call") : false;
725  ds->show_lines_ret = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.ret") : false;
726  ds->show_size = rz_config_get_b(core->config, "asm.size");
727  ds->show_trace = rz_config_get_b(core->config, "asm.trace");
728  ds->linesout = rz_config_get_i(core->config, "asm.lines.out");
729  ds->adistrick = rz_config_get_i(core->config, "asm.middle"); // TODO: find better name
730  ds->asm_demangle = rz_config_get_b(core->config, "asm.demangle");
731  ds->asm_describe = rz_config_get_b(core->config, "asm.describe");
732  ds->show_offset = rz_config_get_b(core->config, "asm.offset");
733  ds->show_offdec = rz_config_get_b(core->config, "asm.decoff");
734  ds->show_bbline = rz_config_get_b(core->config, "asm.bb.line");
735  ds->show_section = rz_config_get_b(core->config, "asm.section");
736  ds->show_section_col = rz_config_get_i(core->config, "asm.section.col");
737  ds->show_section_perm = rz_config_get_b(core->config, "asm.section.perm");
738  ds->show_section_name = rz_config_get_b(core->config, "asm.section.name");
739  ds->show_symbols = rz_config_get_b(core->config, "asm.symbol");
740  ds->show_symbols_col = rz_config_get_i(core->config, "asm.symbol.col");
741  ds->asm_instr = rz_config_get_b(core->config, "asm.instr");
742  ds->show_emu = rz_config_get_b(core->config, "asm.emu");
743  ds->show_emu_str = rz_config_get_b(core->config, "emu.str");
744  ds->show_emu_stroff = rz_config_get_b(core->config, "emu.str.off");
745  ds->show_emu_strinv = rz_config_get_b(core->config, "emu.str.inv");
746  ds->show_emu_strflag = rz_config_get_b(core->config, "emu.str.flag");
747  ds->show_emu_strlea = rz_config_get_b(core->config, "emu.str.lea");
748  ds->show_emu_write = rz_config_get_b(core->config, "emu.write");
749  ds->show_emu_ssa = rz_config_get_b(core->config, "emu.ssa");
750  ds->show_emu_stack = rz_config_get_b(core->config, "emu.stack");
751  ds->stackFd = -1;
752  if (ds->show_emu_stack) {
753  // TODO: initialize fake stack in here
754  const char *uri = "malloc://32K";
755  ut64 size = rz_num_get(core->num, "32K");
756  ut64 addr = rz_reg_getv(core->analysis->reg, "SP") - (size / 2);
757  emustack_min = addr;
758  emustack_max = addr + size;
759  ds->stackFd = rz_io_fd_open(core->io, uri, RZ_PERM_RW, 0);
760  RzIOMap *map = rz_io_map_add(core->io, ds->stackFd, RZ_PERM_RW, 0LL, addr, size);
761  if (!map) {
762  rz_io_fd_close(core->io, ds->stackFd);
763  eprintf("Cannot create map for tha stack, fd %d got closed again\n", ds->stackFd);
764  ds->stackFd = -1;
765  } else {
766  rz_io_map_set_name(map, "fake.stack");
767  }
768  }
769  ds->stackptr = core->analysis->stackptr;
770  ds->show_flags = rz_config_get_b(core->config, "asm.flags");
771  ds->show_bytes = rz_config_get_b(core->config, "asm.bytes");
772  ds->show_bytes_right = rz_config_get_b(core->config, "asm.bytes.right");
773  ds->show_optype = rz_config_get_b(core->config, "asm.optype");
774  ds->asm_meta = rz_config_get_i(core->config, "asm.meta");
775  ds->asm_xrefs_code = rz_config_get_i(core->config, "asm.xrefs.code");
776  ds->show_reloff = rz_config_get_b(core->config, "asm.reloff");
777  ds->show_reloff_flags = rz_config_get_b(core->config, "asm.reloff.flags");
778  ds->show_lines_fcn = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.fcn") : false;
779  ds->show_comments = rz_config_get_b(core->config, "asm.comments");
780  ds->show_usercomments = rz_config_get_b(core->config, "asm.usercomments");
781  ds->asm_hint_jmp = rz_config_get_b(core->config, "asm.hint.jmp");
782  ds->asm_hint_call = rz_config_get_b(core->config, "asm.hint.call");
783  ds->asm_hint_call_indirect = rz_config_get_b(core->config, "asm.hint.call.indirect");
784  ds->asm_hint_lea = rz_config_get_b(core->config, "asm.hint.lea");
785  ds->asm_hint_emu = rz_config_get_b(core->config, "asm.hint.emu");
786  ds->asm_hint_cdiv = rz_config_get_b(core->config, "asm.hint.cdiv");
787  ds->asm_hint_pos = rz_config_get_i(core->config, "asm.hint.pos");
788  ds->asm_hints = rz_config_get_b(core->config, "asm.hints");
789  ds->show_slow = rz_config_get_b(core->config, "asm.slow");
790  ds->show_refptr = rz_config_get_b(core->config, "asm.refptr");
791  ds->show_calls = rz_config_get_b(core->config, "asm.calls");
792  ds->show_family = rz_config_get_b(core->config, "asm.family");
793  ds->cmtcol = rz_config_get_i(core->config, "asm.cmt.col");
794  ds->show_cmt_esil = rz_config_get_b(core->config, "asm.cmt.esil");
795  ds->show_cmt_il = rz_config_get_b(core->config, "asm.cmt.il");
796  ds->show_cmtflgrefs = rz_config_get_b(core->config, "asm.cmt.flgrefs");
797  ds->show_cycles = rz_config_get_b(core->config, "asm.cycles");
798  ds->show_stackptr = rz_config_get_b(core->config, "asm.stackptr");
799  ds->show_xrefs = rz_config_get_b(core->config, "asm.xrefs");
800  ds->show_cmtrefs = rz_config_get_b(core->config, "asm.cmt.refs");
801  ds->show_cmtoff = rz_config_get(core->config, "asm.cmt.off");
802  if (!ds->show_cmtoff) {
803  ds->show_cmtoff = "nodup";
804  }
805  ds->show_functions = rz_config_get_b(core->config, "asm.functions");
806  ds->nbytes = rz_config_get_i(core->config, "asm.nbytes");
807  ds->show_asciidot = !strcmp(core->print->strconv_mode, "asciidot");
808  ds->strenc = rz_str_enc_string_as_type(rz_config_get(core->config, "bin.str.enc"));
809  core->print->bytespace = rz_config_get_i(core->config, "asm.bytes.space");
810  ds->cursor = 0;
811  ds->nb = 0;
812  ds->flagspace_ports = rz_flag_space_get(core->flags, "ports");
813  ds->lbytes = rz_config_get_i(core->config, "asm.lbytes");
814  ds->show_comment_right_default = rz_config_get_b(core->config, "asm.cmt.right");
816  ds->show_flag_in_bytes = rz_config_get_b(core->config, "asm.flags.inbytes");
817  ds->show_marks = rz_config_get_b(core->config, "asm.marks");
818  ds->show_noisy_comments = rz_config_get_b(core->config, "asm.noisy");
819  ds->pre = DS_PRE_NONE;
820  ds->ocomment = NULL;
821  ds->linesopts = 0;
822  ds->lastfail = 0;
823  ds->ocols = 0;
824  ds->lcols = 0;
827 
828  ds->esil_old_pc = UT64_MAX;
829  ds->esil_regstate = NULL;
830  ds->esil_likely = false;
831 
832  ds->showpayloads = rz_config_get_b(ds->core->config, "asm.payloads");
833  ds->showrelocs = rz_config_get_b(core->config, "bin.relocs");
834  ds->min_ref_addr = rz_config_get_i(core->config, "asm.sub.varmin");
835 
836  if (ds->show_flag_in_bytes) {
837  ds->show_flags = false;
838  }
839  if (rz_config_get_i(core->config, "asm.lines.wide")) {
841  }
842  if (core->cons->vline) {
843  if (ds->show_utf8) {
845  }
846  }
847  if (ds->show_lines_bb) {
848  ds->ocols += 10; // XXX
849  }
850  if (ds->show_offset) {
851  ds->ocols += 14;
852  }
853  ds->lcols = ds->ocols + 2;
854  if (ds->show_bytes) {
855  ds->ocols += 20;
856  }
857  if (ds->show_trace) {
858  ds->ocols += 8;
859  }
860  if (ds->show_stackptr) {
861  ds->ocols += 4;
862  }
863  /* disasm */ ds->ocols += 20;
864  ds->nb = ds->nbytes ? (1 + ds->nbytes * 2) : 0;
865  ds->tries = 3;
866  if (core->print->cur_enabled) {
867  if (core->print->cur < 0) {
868  core->print->cur = 0;
869  }
870  ds->cursor = core->print->cur;
871  } else {
872  ds->cursor = -1;
873  }
874  if (rz_config_get_b(core->config, "asm.lines.wide")) {
876  }
877  if (core->cons->vline) {
878  if (ds->show_utf8) {
880  }
881  }
882  return ds;
883 }
884 
886 
887 static void ds_reflines_fini(RzDisasmState *ds) {
888  RzAnalysis *analysis = ds->core->analysis;
889  rz_list_free(analysis->reflines);
890  analysis->reflines = NULL;
891  RZ_FREE(ds->refline);
892  RZ_FREE(ds->refline2);
893  RZ_FREE(ds->prev_line_col);
894 }
895 
896 static void ds_reflines_init(RzDisasmState *ds) {
897  RzAnalysis *analysis = ds->core->analysis;
898 
899  lastaddr = UT64_MAX;
900 
901  if (ds->show_lines_bb || ds->pj) {
902  ds_reflines_fini(ds);
903  analysis->reflines = rz_analysis_reflines_get(analysis,
904  ds->addr, ds->buf, ds->len, ds->l,
905  ds->linesout, ds->show_lines_call);
906  } else {
907  rz_list_free(analysis->reflines);
908  analysis->reflines = NULL;
909  }
910 }
911 
912 static void ds_free(RzDisasmState *ds) {
913  if (!ds) {
914  return;
915  }
916  if (ds->show_emu_stack) {
917  // TODO: destroy fake stack in here
918  eprintf("Free fake stack\n");
919  if (ds->stackFd != -1) {
920  rz_io_fd_close(ds->core->io, ds->stackFd);
921  }
922  }
923  rz_asm_op_fini(&ds->asmop);
927  ds_reflines_fini(ds);
929  sdb_free(ds->ssa);
930  free(ds->comment);
931  free(ds->line);
932  free(ds->line_col);
933  free(ds->refline);
934  free(ds->refline2);
935  free(ds->prev_line_col);
936  free(ds->opstr);
937  free(ds->osl);
938  free(ds->sl);
939  free(ds->_tabsbuf);
940  RZ_FREE(ds);
941 }
942 
943 static bool ds_must_strip(RzDisasmState *ds) {
944  if (ds && ds->strip && *ds->strip) {
946  if (optype && *optype) {
947  return strstr(ds->strip, optype);
948  }
949  }
950  return false;
951 }
952 
953 static void ds_highlight_word(RzDisasmState *ds, char *word, char *color) {
954  char *source = ds->opstr ? ds->opstr : rz_asm_op_get_asm(&ds->asmop);
955  const char *color_reset = line_highlighted(ds) ? ds->color_linehl : Color_RESET_BG;
956  char *asm_str = rz_str_highlight(source, word, color, color_reset);
957  ds->opstr = asm_str ? asm_str : source;
958 }
959 
960 static void __replaceImports(RzDisasmState *ds) {
961  if (ds->core->analysis->imports) {
962  char *imp;
963  RzListIter *iter;
964  rz_list_foreach (ds->core->analysis->imports, iter, imp) {
965  ds->opstr = rz_str_replace(ds->opstr, imp, ".", 1);
966  }
967  }
968  if (ds->fcn && ds->fcn->imports) {
969  char *imp;
970  RzListIter *iter;
971  rz_list_foreach (ds->fcn->imports, iter, imp) {
972  ds->opstr = rz_str_replace(ds->opstr, imp, ".", 1);
973  }
974  }
975 }
976 
979 }
980 
981 static const char *get_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr) {
983 }
984 
985 static void ds_build_op_str(RzDisasmState *ds, bool print_color) {
986  RzCore *core = ds->core;
987  bool colorize_asm = print_color && ds->show_color && ds->colorop;
988 
989  if (ds->use_esil) {
990  free(ds->opstr);
991  if (*RZ_STRBUF_SAFEGET(&ds->analysis_op.esil)) {
993  } else {
994  ds->opstr = strdup(",");
995  }
996  return;
997  }
998  if (ds->decode) {
999  free(ds->opstr);
1001  return;
1002  }
1003  if (!ds->opstr) {
1004  const char *assembly = rz_asm_op_get_asm(&ds->asmop);
1005  if (ds->pseudo) {
1006  char *tmp = rz_parse_pseudocode(core->parser, assembly);
1007  if (tmp) {
1008  snprintf(ds->str, sizeof(ds->str), "%s", tmp);
1009  ds->opstr = tmp;
1010  } else {
1011  ds->opstr = strdup("");
1012  ds->str[0] = 0;
1013  }
1014  } else {
1015  ds->opstr = strdup(assembly);
1016  }
1017  }
1018  if (ds->opstr && core->bin && core->bin->cur) {
1019  RzBinPlugin *plugin = rz_bin_file_cur_plugin(core->bin->cur);
1020  char *tmp = plugin && plugin->enrich_asm ? plugin->enrich_asm(core->bin->cur, ds->opstr, strlen(ds->opstr)) : NULL;
1021  if (tmp) {
1022  free(ds->opstr);
1023  ds->opstr = tmp;
1024  }
1025  }
1026 
1027  if (ds->analysis_op.mmio_address != UT64_MAX) {
1028  char number[32];
1029  rz_strf(number, "0x%" PFMT64x, ds->analysis_op.mmio_address);
1030 
1031  RzPlatformTarget *arch_target = core->analysis->arch_target;
1032 
1033  const char *resolved = rz_platform_profile_resolve_mmio(arch_target->profile, ds->analysis_op.mmio_address);
1034  if (resolved) {
1035  ds->opstr = rz_str_replace(ds->opstr, number, resolved, 0);
1036  }
1037  }
1038 
1039  if (ds->analysis_op.ptr != UT64_MAX) {
1040  char number[32];
1041  rz_strf(number, "0x%" PFMT64x, ds->analysis_op.ptr);
1042 
1043  RzPlatformTarget *arch_target = core->analysis->arch_target;
1044 
1045  const char *resolved = rz_platform_profile_resolve_extended_register(arch_target->profile, ds->analysis_op.ptr);
1046  if (resolved) {
1047  ds->opstr = rz_str_replace(ds->opstr, number, resolved, 0);
1048  }
1049  }
1050 
1051  /* initialize */
1052  core->parser->subrel = rz_config_get_b(core->config, "asm.sub.rel");
1053  core->parser->subreg = rz_config_get_b(core->config, "asm.sub.reg");
1054  core->parser->subrel_addr = 0;
1056  core->parser->subrel_addr = ds->analysis_op.ptr;
1057  }
1058  if (ds->subvar && ds->opstr) {
1059  ut64 at = ds->vat;
1061  core->parser->get_ptr_at = get_ptr_at;
1062  core->parser->get_reg_at = get_reg_at;
1063  rz_parse_subvar(core->parser, f, &ds->analysis_op, ds->opstr, ds->strsub, sizeof(ds->strsub));
1064  if (*ds->strsub) {
1065  free(ds->opstr);
1066  ds->opstr = strdup(ds->strsub);
1067  }
1068  if (core->parser->subrel) {
1070  RzListIter *iter;
1071  RzAnalysisXRef *xref;
1072  rz_list_foreach (list, iter, xref) {
1074  core->parser->subrel_addr = xref->to;
1075  break;
1076  }
1077  }
1078  rz_list_free(list);
1079  }
1080  }
1081 
1082  ds->opstr = ds_sub_jumps(ds, ds->opstr);
1083  if (ds->immtrim) {
1084  char *res = rz_parse_immtrim(ds->opstr);
1085  if (res) {
1086  ds->opstr = res;
1087  }
1088  return;
1089  }
1090  if (ds->hint && ds->hint->opcode) {
1091  free(ds->opstr);
1092  ds->opstr = strdup(ds->hint->opcode);
1093  }
1094  if (ds->subnames) {
1095  RzSpace *ofs = core->parser->flagspace;
1096  RzSpace *fs = ds->flagspace_ports;
1098  core->parser->notin_flagspace = NULL;
1099  core->parser->flagspace = fs;
1100  } else {
1101  if (fs) {
1102  core->parser->notin_flagspace = fs;
1103  core->parser->flagspace = fs;
1104  } else {
1105  core->parser->notin_flagspace = NULL;
1106  core->parser->flagspace = NULL;
1107  }
1108  }
1109  if (core->parser->subrel && ds->analysis_op.refptr) {
1110  if (core->parser->subrel_addr == 0) {
1111  ut64 killme = UT64_MAX;
1112  const int be = core->rasm->big_endian;
1113  rz_io_read_i(core->io, ds->analysis_op.ptr, &killme, ds->analysis_op.refptr, be);
1114  core->parser->subrel_addr = killme;
1115  }
1116  }
1117  char *source = ds->opstr ? ds->opstr : rz_asm_op_get_asm(&ds->asmop);
1118  if (colorize_asm) {
1120  RzStrBuf *bw_asm = rz_strbuf_new(source);
1122  RzStrBuf *colored_asm = rz_asm_colorize_asm_str(bw_asm, core->print, param, ds->asmop.asm_toks);
1123  free(param);
1124  rz_strbuf_free(bw_asm);
1125  rz_return_if_fail(colored_asm);
1126  source = rz_strbuf_drain(colored_asm);
1127  } else {
1128  source = strdup(source);
1129  }
1130 
1131  rz_parse_filter(core->parser, ds->vat, core->flags, ds->hint, source,
1132  ds->str, sizeof(ds->str), core->print->big_endian);
1133  // subvar depends on filter
1134  if (ds->subvar) {
1135  // HACK to do subvar outside rparse becacuse the whole rparse api must be rewritten
1136  char *ox = strstr(ds->str, "0x");
1137  if (ox) {
1138  char *e = strchr(ox, ']');
1139  if (e) {
1140  e = strdup(e);
1141  ut64 addr = rz_num_get(NULL, ox);
1142  if (addr > ds->min_ref_addr) {
1143  RzFlagItem *fi = rz_flag_get_i(ds->core->flags, addr);
1144  if (fi) {
1145  rz_str_cpy(ox, fi->name);
1146  rz_str_cat(ox, e);
1147  }
1148  }
1149  free(e);
1150  }
1151  }
1152  }
1153  core->parser->flagspace = ofs;
1154  free(ds->opstr);
1155  ds->opstr = strdup(ds->str);
1156  } else {
1157  char *source;
1158  if (colorize_asm) {
1160  RzStrBuf *bw_asm = rz_strbuf_new(ds->opstr ? ds->opstr : rz_asm_op_get_asm(&ds->asmop));
1162  RzStrBuf *colored_asm = rz_asm_colorize_asm_str(bw_asm, core->print, param, ds->asmop.asm_toks);
1163  free(param);
1164  rz_strbuf_free(bw_asm);
1165  rz_return_if_fail(colored_asm);
1166  source = rz_strbuf_drain(colored_asm);
1167  } else {
1168  source = ds->opstr ? strdup(ds->opstr) : strdup(rz_asm_op_get_asm(&ds->asmop));
1169  }
1170 
1171  free(ds->opstr);
1172  ds->opstr = source;
1173  }
1174  rz_str_trim_char(ds->opstr, '\n');
1175  // updates ds->opstr
1176  __replaceImports(ds);
1177  if (ds->show_color) {
1178  int i = 0;
1179  char *word = NULL;
1180  char *bgcolor = NULL;
1181  const char *wcdata = rz_meta_get_string(ds->core->analysis, RZ_META_TYPE_HIGHLIGHT, ds->at);
1182  int argc = 0;
1183  char **wc_array = rz_str_argv(wcdata, &argc);
1184  for (i = 0; i < argc; i++) {
1185  bgcolor = strchr(wc_array[i], '\x1b');
1186  word = rz_str_newlen(wc_array[i], bgcolor - wc_array[i]);
1187  ds_highlight_word(ds, word, bgcolor);
1188  }
1189  }
1190 }
1191 
1193  static char *hint_syntax = NULL;
1194  rz_analysis_hint_free(hint);
1195  hint = rz_analysis_hint_get(core->analysis, at);
1196  if (hint_syntax) {
1197  rz_config_set(core->config, "asm.syntax", hint_syntax);
1198  hint_syntax = NULL;
1199  }
1200  if (hint) {
1201  /* syntax */
1202  if (hint->syntax) {
1203  if (!hint_syntax) {
1204  hint_syntax = strdup(rz_config_get(core->config, "asm.syntax"));
1205  }
1206  rz_config_set(core->config, "asm.syntax", hint->syntax);
1207  }
1208  if (hint->high) {
1209  /* TODO: do something here */
1210  }
1211  }
1212  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, at, 0);
1213  if (fcn) {
1214  if (fcn->bits == 16 || fcn->bits == 32) {
1215  if (!hint) {
1216  hint = RZ_NEW0(RzAnalysisHint);
1217  }
1218  hint->bits = fcn->bits;
1219  hint->new_bits = fcn->bits;
1220  }
1221  }
1222  return hint;
1223 }
1224 
1225 static void ds_pre_line(RzDisasmState *ds) {
1226  ds_setup_pre(ds, false, false);
1227  ds_print_pre(ds, true);
1228  char *tmp = ds->line;
1229  char *tmp_col = ds->line_col;
1230  ds->line = ds->refline2;
1231  ds->line_col = ds->prev_line_col;
1232  ds_print_lines_left(ds);
1233  ds->line = tmp;
1234  ds->line_col = tmp_col;
1235 }
1236 
1238  if (!t) {
1239  return NULL;
1240  }
1241  t->offset = ds->vat;
1242  t->arrow = UT64_MAX;
1243  t->text = text;
1244  if (ds->core->analysis->reflines) {
1245  RzAnalysisRefline *ref;
1246  RzListIter *iter;
1247  rz_list_foreach (ds->core->analysis->reflines, iter, ref) {
1248  if (ref->from == ds->vat) {
1249  t->arrow = ref->to;
1250  break;
1251  }
1252  }
1253  }
1254  return t;
1255 }
1256 
1257 static void ds_begin_line(RzDisasmState *ds) {
1258  if (ds->vec) {
1259  return;
1260  }
1261 
1262  if (ds->pj) {
1263  pj_o(ds->pj);
1264  pj_kn(ds->pj, "offset", ds->vat);
1265  if (ds->core->analysis->reflines) {
1266  RzAnalysisRefline *ref;
1267  RzListIter *iter;
1268  // XXX Probably expensive
1269  rz_list_foreach (ds->core->analysis->reflines, iter, ref) {
1270  if (ref->from == ds->vat) {
1271  pj_kn(ds->pj, "arrow", ref->to);
1272  break;
1273  }
1274  }
1275  }
1276  pj_k(ds->pj, "text");
1277  }
1279  if (!ds->pj && ds->asm_hint_pos == -1) {
1280  if (!ds_print_core_vmode(ds, ds->asm_hint_pos)) {
1281  rz_cons_printf(" ");
1282  }
1283  }
1284 }
1285 
1286 static void ds_newline(RzDisasmState *ds) {
1287  if (ds->vec) {
1289  if (!t) {
1290  return;
1291  }
1293  rz_cons_reset();
1294  rz_pvector_push(ds->vec, t);
1295  return;
1296  }
1297 
1298  if (ds->pj) {
1299  const bool is_html = rz_config_get_b(ds->core->config, "scr.html");
1300  if (is_html) {
1302  pj_s(ds->pj, s);
1303  free(s);
1304  } else {
1305  pj_s(ds->pj, rz_cons_get_buffer());
1306  }
1307  rz_cons_reset();
1308  pj_end(ds->pj);
1309  } else {
1310  rz_cons_newline();
1311  }
1312 }
1313 
1314 static void ds_begin_cont(RzDisasmState *ds) {
1315  ds_begin_line(ds);
1316  ds_setup_print_pre(ds, false, false);
1317  if (!ds->linesright && ds->show_lines_bb && ds->line) {
1318  RzAnalysisRefStr *refstr = rz_analysis_reflines_str(ds->core, ds->at,
1320  ds_print_ref_lines(refstr->str, refstr->cols, ds);
1322  }
1323 }
1324 
1326  if (ds->show_comment_right) {
1327  CMT_ALIGN;
1328  } else {
1329  ds_begin_line(ds);
1330  ds_pre_xrefs(ds, false);
1331  }
1332 }
1333 
1334 static void ds_show_refs(RzDisasmState *ds) {
1335  RzAnalysisXRef *xref;
1336  RzListIter *iter;
1337 
1338  if (!ds->show_cmtrefs) {
1339  return;
1340  }
1342 
1343  rz_list_foreach (list, iter, xref) {
1344  const char *cmt = rz_meta_get_string(ds->core->analysis, RZ_META_TYPE_COMMENT, xref->to);
1345  const RzList *fls = rz_flag_get_list(ds->core->flags, xref->to);
1346  RzListIter *iter2;
1347  RzFlagItem *fis;
1348  rz_list_foreach (fls, iter2, fis) {
1349  ds_begin_comment(ds);
1350  ds_comment(ds, true, "; (%s)", fis->name);
1351  }
1352 
1353  // ds_align_comment (ds);
1354  if (ds->show_color) {
1356  }
1357  if (cmt) {
1358  ds_begin_comment(ds);
1359  ds_comment(ds, true, "; (%s)", cmt);
1360  }
1361  if (xref->type & RZ_ANALYSIS_XREF_TYPE_CALL) {
1362  RzAnalysisOp aop;
1363  ut8 buf[12];
1364  rz_io_read_at(ds->core->io, xref->from, buf, sizeof(buf));
1365  rz_analysis_op(ds->core->analysis, &aop, xref->from, buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC);
1368  ds_begin_comment(ds);
1369  if (fcn) {
1370  ds_comment(ds, true, "; %s", fcn->name);
1371  } else {
1372  ds_comment(ds, true, "; 0x%" PFMT64x "", xref->to);
1373  }
1374  }
1375  }
1377  }
1378  rz_list_free(list);
1379 }
1380 
1381 static void ds_show_xrefs(RzDisasmState *ds) {
1382  RzAnalysisXRef *xrefi;
1383  RzListIter *iter, *it;
1384  RzCore *core = ds->core;
1385  char *name, *realname;
1386  int count = 0;
1387  if (!ds->show_xrefs || !ds->show_comments) {
1388  return;
1389  }
1390  /* show xrefs */
1391  RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, ds->at);
1392  if (!xrefs) {
1393  return;
1394  }
1395  // only show fcnline in xrefs when addr is not the beginning of a function
1396  bool fcnlines = (ds->fcn && ds->fcn->addr == ds->at);
1397  if (rz_list_length(xrefs) > ds->maxrefs) {
1398  ds_begin_line(ds);
1399  ds_pre_xrefs(ds, fcnlines);
1400  ds_comment(ds, false, "%s; XREFS(%d)",
1401  ds->show_color ? ds->pal_comment : "",
1402  rz_list_length(xrefs));
1403  if (ds->show_color) {
1405  }
1406  ds_newline(ds);
1407  rz_list_free(xrefs);
1408  return;
1409  }
1410  if (rz_list_length(xrefs) > ds->foldxrefs) {
1411  int cols = rz_cons_get_size(NULL);
1412  cols -= 15;
1413  cols /= 23;
1414  cols = cols > 5 ? 5 : cols;
1415  ds_begin_line(ds);
1416  ds_pre_xrefs(ds, fcnlines);
1417  ds_comment(ds, false, "%s; XREFS: ", ds->show_color ? ds->pal_comment : "");
1418  rz_list_foreach (xrefs, iter, xrefi) {
1419  ds_comment(ds, false, "%s 0x%08" PFMT64x " ",
1420  rz_analysis_xrefs_type_tostring(xrefi->type), xrefi->from);
1421  if (count == cols) {
1422  if (iter->n) {
1424  ds_newline(ds);
1425  ds_begin_line(ds);
1426  ds_pre_xrefs(ds, fcnlines);
1427  ds_comment(ds, false, "%s; XREFS: ", ds->show_color ? ds->pal_comment : "");
1428  }
1429  count = 0;
1430  } else {
1431  count++;
1432  }
1433  }
1435  ds_newline(ds);
1436  rz_list_free(xrefs);
1437  return;
1438  }
1439 
1440  RzList *addrs = rz_list_newf(free);
1441  RzAnalysisFunction *fun, *next_fun;
1442  RzFlagItem *f, *next_f;
1443  rz_list_foreach (xrefs, iter, xrefi) {
1444  if (!ds->asm_xrefs_code && xrefi->type == RZ_ANALYSIS_XREF_TYPE_CODE) {
1445  continue;
1446  }
1447  if (xrefi->to == ds->at) {
1448  realname = NULL;
1449  fun = fcnIn(ds, xrefi->from, -1);
1450  if (fun) {
1451  if (iter != xrefs->tail) {
1452  ut64 next_addr = ((RzAnalysisXRef *)(iter->n->data))->from;
1453  next_fun = rz_analysis_get_fcn_in(core->analysis, next_addr, -1);
1454  if (next_fun && next_fun->addr == fun->addr) {
1455  rz_list_append(addrs, rz_num_dup(xrefi->from));
1456  continue;
1457  }
1458  }
1459  if (ds->asm_demangle) {
1461  if (f && f->demangled && f->realname) {
1462  realname = strdup(f->realname);
1463  }
1464  }
1465  name = strdup(fun->name);
1466  rz_list_append(addrs, rz_num_dup(xrefi->from));
1467  } else {
1468  f = rz_flag_get_at(core->flags, xrefi->from, true);
1469  if (f) {
1470  if (iter != xrefs->tail) {
1471  ut64 next_addr = ((RzAnalysisXRef *)(iter->n->data))->from;
1472  next_f = rz_flag_get_at(core->flags, next_addr, true);
1473  if (next_f && f->offset == next_f->offset) {
1474  rz_list_append(addrs, rz_num_dup(xrefi->from - f->offset));
1475  continue;
1476  }
1477  }
1478  if (ds->asm_demangle) {
1479  RzFlagItem *f_sym = f;
1480  if (!rz_str_startswith(f_sym->name, "sym.")) {
1481  f_sym = rz_flag_get_by_spaces(core->flags, f->offset,
1483  }
1484  if (f_sym && f_sym->demangled && f_sym->realname) {
1485  f = f_sym;
1486  realname = strdup(f->realname);
1487  }
1488  }
1489  name = strdup(f->name);
1490  rz_list_append(addrs, rz_num_dup(xrefi->from - f->offset));
1491  } else {
1492  name = strdup("unk");
1493  }
1494  }
1495  ds_begin_line(ds);
1496  ds_pre_xrefs(ds, fcnlines);
1497  const char *plural = rz_list_length(addrs) > 1 ? "S" : "";
1498  const char *plus = fun ? "" : "+";
1499  ds_comment(ds, false, "%s; %s XREF%s from %s @ ",
1500  COLOR(ds, pal_comment), rz_analysis_xrefs_type_tostring(xrefi->type), plural,
1501  realname ? realname : name);
1502  ut64 *addrptr;
1503  rz_list_foreach (addrs, it, addrptr) {
1504  if (addrptr && *addrptr) {
1505  ds_comment(ds, false, "%s%s0x%" PFMT64x, it == addrs->head ? "" : ", ", plus, *addrptr);
1506  }
1507  }
1508  if (realname && (!fun || rz_analysis_get_function_at(core->analysis, ds->at))) {
1509  const char *pad = ds->show_comment_right ? "" : " ";
1510  if (!ds->show_comment_right) {
1511  ds_newline(ds);
1512  ds_begin_line(ds);
1513  ds_pre_xrefs(ds, fcnlines);
1514  }
1515  ds_comment(ds, false, " %s; %s", pad, name);
1516  }
1517  ds_comment(ds, false, "%s", COLOR_RESET(ds));
1518  ds_newline(ds);
1519  rz_list_purge(addrs);
1520  RZ_FREE(name);
1521  free(realname);
1522  } else {
1523  eprintf("Corrupted database?\n");
1524  }
1525  }
1526  rz_list_free(addrs);
1527  rz_list_free(xrefs);
1528 }
1529 
1530 static bool calc_tab_buf_size(size_t len, size_t tabs, size_t *c) {
1531  if (SZT_ADD_OVFCHK(tabs, 1)) {
1532  return true;
1533  }
1534  tabs++;
1535  if (SZT_MUL_OVFCHK(len, tabs)) {
1536  return true;
1537  }
1538  len *= tabs;
1539  if (SZT_MUL_OVFCHK(len, 4)) {
1540  return true;
1541  }
1542  len *= 4;
1543  if (SZT_ADD_OVFCHK(len, 4)) {
1544  return true;
1545  }
1546  len += 4;
1547  *c = len;
1548  return false;
1549 }
1550 
1551 static void ds_atabs_option(RzDisasmState *ds) {
1552  int n, i = 0, comma = 0, word = 0;
1553  int brackets = 0;
1554  char *t, *b;
1555  if (!ds || !ds->atabs) {
1556  return;
1557  }
1558  size_t size;
1559  const char *opstr;
1560  if (ds->opstr) {
1561  if (calc_tab_buf_size(strlen(ds->opstr), ds->atabs, &size)) {
1562  return;
1563  }
1564  opstr = ds->opstr;
1565  } else {
1567  return;
1568  }
1569  opstr = rz_strbuf_get(&ds->asmop.buf_asm);
1570  }
1571  b = malloc(size);
1572  if (!b) {
1573  return;
1574  }
1575  rz_str_ncpy(b, opstr, size);
1576  free(ds->opstr);
1577  ds->opstr = b;
1578  for (; *b; b++, i++) {
1579  if (*b == '(' || *b == '[') {
1580  brackets++;
1581  }
1582  if (*b == ')' || *b == ']') {
1583  brackets--;
1584  }
1585  if (*b == ',') {
1586  comma = 1;
1587  }
1588  if (*b != ' ') {
1589  continue;
1590  }
1591  if (word > 0 && !comma) {
1592  continue; //&& b[1]=='[') continue;
1593  }
1594  if (brackets > 0) {
1595  continue;
1596  }
1597  comma = 0;
1598  brackets = 0;
1599  n = (ds->atabs - i);
1600  t = strdup(b + 1); // XXX slow!
1601  if (n < 1) {
1602  n = 1;
1603  }
1604  memset(b, ' ', n);
1605  b += n;
1606  strcpy(b, t);
1607  free(t);
1608  i = 0;
1609  word++;
1610  if (ds->atabsonce) {
1611  break;
1612  }
1613  }
1614 }
1615 
1616 static int handleMidFlags(RzCore *core, RzDisasmState *ds, bool print) {
1617  ds->midflags = rz_config_get_i(core->config, "asm.flags.middle");
1618  ds->hasMidflag = false;
1619  if (ds->midcursor && core->print->cur != -1) {
1620  ut64 cur = core->offset + core->print->cur;
1621  ut64 from = ds->at;
1622  ut64 to = ds->at + ds->oplen;
1623  if (cur > from && cur < to) {
1624  return cur - from;
1625  }
1626  }
1627  if (!ds->midflags) {
1628  return 0;
1629  }
1630  for (int i = 1; i < ds->oplen; i++) {
1631  RzFlagItem *fi = rz_flag_get_i(core->flags, ds->at + i);
1632  if (fi && fi->name) {
1634  ds->midflags = ds->midflags ? RZ_MIDFLAGS_SHOW : RZ_MIDFLAGS_HIDE;
1635  }
1636  if (ds->midflags == RZ_MIDFLAGS_REALIGN &&
1637  ((fi->name[0] == '$') || (fi->realname && fi->realname[0] == '$'))) {
1638  i = 0;
1639  } else if (!strncmp(fi->name, "hit.", 4)) { // use search.prefix ?
1640  i = 0;
1641  } else if (!strncmp(fi->name, "str.", 4)) {
1642  ds->midflags = RZ_MIDFLAGS_REALIGN;
1643  } else if (fi->space && !strcmp(fi->space->name, RZ_FLAGS_FS_RELOCS)) {
1644  continue;
1645  } else if (ds->midflags == RZ_MIDFLAGS_SYMALIGN) {
1646  if (strncmp(fi->name, "sym.", 4)) {
1647  continue;
1648  }
1649  }
1650  ds->hasMidflag = true;
1651  return i;
1652  }
1653  }
1654  return 0;
1655 }
1656 
1657 static int handleMidBB(RzCore *core, RzDisasmState *ds) {
1658  int i;
1659  ds->hasMidbb = false;
1660  rz_return_val_if_fail(core->analysis, 0);
1661  // Unfortunately, can't just check the addr of the last insn byte since
1662  // a bb (and fcn) can be as small as 1 byte, and advancing i based on
1663  // bb->size is unsound if basic blocks can nest or overlap
1664  for (i = 1; i < ds->oplen; i++) {
1665  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, ds->at + i, 0);
1666  if (fcn) {
1667  RzAnalysisBlock *bb = rz_analysis_fcn_bbget_in(core->analysis, fcn, ds->at + i);
1668  if (bb && bb->addr > ds->at) {
1669  ds->hasMidbb = true;
1670  return bb->addr - ds->at;
1671  }
1672  }
1673  }
1674  return 0;
1675 }
1676 
1685  RZ_INOUT RZ_NONNULL int *oplen, RZ_NONNULL int *ret) {
1686  rz_return_if_fail(core && oplen && ret);
1687  bool midbb = rz_config_get_b(core->config, "asm.bb.middle");
1688  RzDisasmState ds = {
1689  .at = at,
1690  .oplen = *oplen,
1691  };
1692  int skip_bytes_flag = handleMidFlags(core, &ds, false);
1693  int skip_bytes_bb = midbb ? handleMidBB(core, &ds) : 0;
1694  if (skip_bytes_flag && ds.midflags > RZ_MIDFLAGS_SHOW) {
1695  *oplen = *ret = skip_bytes_flag;
1696  }
1697  if (skip_bytes_bb && skip_bytes_bb < *ret) {
1698  *oplen = skip_bytes_bb;
1699  }
1700 }
1701 
1702 RZ_API int rz_core_flag_in_middle(RzCore *core, ut64 at, int oplen, int *midflags) {
1703  rz_return_val_if_fail(midflags, 0);
1704  RzDisasmState ds = {
1705  .at = at,
1706  .oplen = oplen,
1707  .midflags = *midflags
1708  };
1709  int ret = handleMidFlags(core, &ds, true);
1710  *midflags = ds.midflags;
1711  return ret;
1712 }
1713 
1714 RZ_API int rz_core_bb_starts_in_middle(RzCore *core, ut64 at, int oplen) {
1715  RzDisasmState ds = {
1716  .at = at,
1717  .oplen = oplen
1718  };
1719  return handleMidBB(core, &ds);
1720 }
1721 
1723  RzCore *core = ds->core;
1724  char res[] = " ";
1725  if (!ds->show_marks) {
1726  return;
1727  }
1728  int q = core->print->cur_enabled &&
1729  ds->cursor >= ds->index &&
1730  ds->cursor < (ds->index + ds->asmop.size);
1731  RzBreakpointItem *p = rz_bp_get_at(core->dbg->bp, ds->at);
1732  (void)handleMidFlags(core, ds, false);
1733  if (ds->midbb) {
1734  (void)handleMidBB(core, ds);
1735  }
1736  if (p) {
1737  res[0] = 'b';
1738  }
1739  if (ds->hasMidflag || ds->hasMidbb) {
1740  res[1] = '~';
1741  }
1742  if (q) {
1743  if (ds->cursor == ds->index) {
1744  res[2] = '*';
1745  } else {
1746  int i = 2, diff = ds->cursor - ds->index;
1747  if (diff > 9) {
1748  res[i++] = '0' + (diff / 10);
1749  }
1750  res[i] = '0' + (diff % 10);
1751  }
1752  }
1753  rz_cons_strcat(res);
1754 }
1755 
1756 static void ds_pre_xrefs(RzDisasmState *ds, bool no_fcnlines) {
1757  ds_setup_pre(ds, false, false);
1758  if (ds->pre != DS_PRE_NONE && ds->pre != DS_PRE_EMPTY) {
1759  ds->pre = no_fcnlines ? DS_PRE_EMPTY : DS_PRE_FCN_MIDDLE;
1760  }
1761  ds_print_pre(ds, !no_fcnlines);
1762  char *tmp = ds->line;
1763  char *tmp_col = ds->line_col;
1764  ds->line = ds->refline2;
1765  ds->line_col = ds->prev_line_col;
1766  ds_print_lines_left(ds);
1767  if (!ds->show_offset && ds->show_marks) {
1769  }
1770  ds->line = tmp;
1771  ds->line_col = tmp_col;
1772 }
1773 
1774 static void ds_show_functions_argvar(RzDisasmState *ds, RzAnalysisFunction *fcn, RzAnalysisVar *var, const char *base, bool is_var, char sign) {
1775  int delta = var->kind == 'b' ? RZ_ABS(var->delta + fcn->bp_off) : RZ_ABS(var->delta);
1776  const char *pfx = is_var ? "var" : "arg";
1777  char *constr = rz_analysis_var_get_constraints_readable(var);
1778  char *vartype = rz_type_as_string(ds->core->analysis->typedb, var->type);
1779  rz_cons_printf("%s%s %s%s%s%s %s%s%s%s@ %s%c0x%x", COLOR_ARG(ds, color_func_var), pfx,
1780  COLOR_ARG(ds, color_func_var_type), vartype,
1781  rz_str_endswith(vartype, "*") ? "" : " ",
1782  var->name, COLOR_ARG(ds, color_func_var_addr),
1783  constr ? " { " : "",
1784  constr ? constr : "",
1785  constr ? "} " : "",
1786  base, sign, delta);
1787  if (ds->show_varsum == -1) {
1788  char *val = rz_core_analysis_var_display(ds->core, var, false);
1789  if (val) {
1790  rz_str_replace_char(val, '\n', '\0');
1791  rz_cons_printf(" = %s", val);
1792  free(val);
1793  }
1794  }
1795  free(vartype);
1796  free(constr);
1797 }
1798 
1800  const char *numColor = ds->core->cons->context->pal.num;
1801  RzAnalysisVar *var;
1802  RzListIter *iter;
1803  int bp_vars = 0;
1804  int sp_vars = 0;
1805  int rg_vars = 0;
1806  int bp_args = 0;
1807  int sp_args = 0;
1808  int rg_args = 0;
1809  const char *bp_vars_color = COLOR_RESET(ds);
1810  const char *sp_vars_color = COLOR_RESET(ds);
1811  const char *rg_vars_color = COLOR_RESET(ds);
1812  const char *bp_args_color = COLOR_RESET(ds);
1813  const char *sp_args_color = COLOR_RESET(ds);
1814  const char *rg_args_color = COLOR_RESET(ds);
1815  rz_list_foreach (list, iter, var) {
1816  if (var->isarg) {
1817  switch (var->kind) {
1818  case 'b':
1819  bp_args++;
1820  break;
1821  case 's':
1822  sp_args++;
1823  break;
1824  case 'r':
1825  rg_args++;
1826  break;
1827  }
1828  } else {
1829  switch (var->kind) {
1830  case 'b':
1831  bp_vars++;
1832  break;
1833  case 's':
1834  sp_vars++;
1835  break;
1836  case 'r':
1837  rg_vars++;
1838  break;
1839  }
1840  }
1841  }
1842  if (bp_vars) {
1843  bp_vars_color = numColor;
1844  }
1845  if (sp_vars) {
1846  sp_vars_color = numColor;
1847  }
1848  if (rg_vars) {
1849  rg_vars_color = numColor;
1850  }
1851  if (bp_args) {
1852  bp_args_color = numColor;
1853  }
1854  if (sp_args) {
1855  sp_args_color = numColor;
1856  }
1857  if (rg_args) {
1858  rg_args_color = numColor;
1859  }
1860  if (ds->show_varsum == 2) {
1861  ds_begin_line(ds);
1862  ds_print_pre(ds, true);
1863  rz_cons_printf("vars: %s%d%s %s%d%s %s%d%s",
1864  bp_vars_color, bp_vars, COLOR_RESET(ds),
1865  sp_vars_color, sp_vars, COLOR_RESET(ds),
1866  rg_vars_color, rg_vars, COLOR_RESET(ds));
1867  ds_newline(ds);
1868  ds_begin_line(ds);
1869  ds_print_pre(ds, true);
1870  rz_cons_printf("args: %s%d%s %s%d%s %s%d%s",
1871  bp_args_color, bp_args, COLOR_RESET(ds),
1872  sp_args_color, sp_args, COLOR_RESET(ds),
1873  rg_args_color, rg_args, COLOR_RESET(ds));
1874  ds_newline(ds);
1875  return;
1876  }
1877  ds_begin_line(ds);
1878  ds_print_pre(ds, true);
1879  rz_cons_printf("bp: %s%d%s (vars %s%d%s, args %s%d%s)",
1880  bp_args || bp_vars ? numColor : COLOR_RESET(ds), bp_args + bp_vars, COLOR_RESET(ds),
1881  bp_vars_color, bp_vars, COLOR_RESET(ds),
1882  bp_args_color, bp_args, COLOR_RESET(ds));
1883  ds_newline(ds);
1884  ds_begin_line(ds);
1885  ds_print_pre(ds, true);
1886  rz_cons_printf("sp: %s%d%s (vars %s%d%s, args %s%d%s)",
1887  sp_args || sp_vars ? numColor : COLOR_RESET(ds), sp_args + sp_vars, COLOR_RESET(ds),
1888  sp_vars_color, sp_vars, COLOR_RESET(ds),
1889  sp_args_color, sp_args, COLOR_RESET(ds));
1890  ds_newline(ds);
1891  ds_begin_line(ds);
1892  ds_print_pre(ds, true);
1893  rz_cons_printf("rg: %s%d%s (vars %s%d%s, args %s%d%s)",
1894  rg_args || rg_vars ? numColor : COLOR_RESET(ds), rg_args + rg_vars, COLOR_RESET(ds),
1895  rg_vars_color, rg_vars, COLOR_RESET(ds),
1896  rg_args_color, rg_args, COLOR_RESET(ds));
1897  ds_newline(ds);
1898 }
1899 
1900 static bool empty_signature(const char *s) {
1901  return (s && !strncmp(s, "void ", 5) && strstr(s, "()"));
1902 }
1903 
1906  RzCore *core = ds->core;
1907  char *fcn_name;
1908  bool fcn_name_alloc = false; // whether fcn_name needs to be freed by this function
1909 
1910  if (!ds->show_functions) {
1911  return;
1912  }
1913  bool demangle = rz_config_get_b(core->config, "bin.demangle");
1914  bool keep_lib = rz_config_get_b(core->config, "bin.demangle.libs");
1915  bool fcnsig = ds->show_fcnsig;
1916  const char *lang = demangle ? rz_config_get(core->config, "bin.lang") : NULL;
1917  const char *fcntype;
1918  f = rz_analysis_get_function_at(core->analysis, ds->at);
1919  if (!f) {
1920  return;
1921  }
1922  if (demangle) {
1923  fcn_name = rz_bin_demangle(core->bin->cur, lang, f->name, f->addr, keep_lib);
1924  if (fcn_name) {
1925  fcn_name_alloc = true;
1926  } else {
1927  fcn_name = f->name;
1928  }
1929  } else {
1930  fcn_name = f->name;
1931  }
1932 
1933  ds_begin_line(ds);
1934  char *sign = rz_analysis_function_get_signature(f);
1935  if (empty_signature(sign)) {
1936  RZ_FREE(sign);
1937  }
1938 
1939  ds->stackptr = core->analysis->stackptr;
1940  RzAnalysisFcnVarsCache vars_cache;
1941  rz_analysis_fcn_vars_cache_init(core->analysis, &vars_cache, f);
1942 
1943  int o_varsum = ds->show_varsum;
1944  if (ds->interactive && !o_varsum) {
1945  int padding = 10;
1946  int numvars = vars_cache.bvars->length + vars_cache.rvars->length + vars_cache.svars->length + padding;
1947  if (numvars > ds->l) {
1948  ds->show_varsum = 1;
1949  } else {
1950  ds->show_varsum = 0;
1951  }
1952  }
1953  // show function's realname in the signature if realnames are enabled
1954  if (core->flags->realnames) {
1955  RzFlagItem *flag = rz_flag_get(core->flags, fcn_name);
1956  if (flag && flag->realname) {
1957  fcn_name = flag->realname;
1958  }
1959  }
1960 
1961  if (f->type == RZ_ANALYSIS_FCN_TYPE_LOC) {
1962  rz_cons_printf("%s%s ", COLOR(ds, color_fline),
1963  core->cons->vline[LINE_CROSS]); // |-
1964  fcntype = "loc";
1965  } else {
1966  char cmt[32];
1967  get_bits_comment(core, f, cmt, sizeof(cmt));
1968 
1969  switch (f->type) {
1972  fcntype = "fcn";
1973  break;
1975  fcntype = "imp";
1976  break;
1977  default:
1978  fcntype = "loc";
1979  break;
1980  }
1981  // ds_set_pre (ds, core->cons->vline[CORNER_TL]);
1982  if (ds->show_lines_fcn) {
1983  ds->pre = DS_PRE_FCN_HEAD;
1984  }
1985  ds_print_pre(ds, true);
1986  if (ds->show_flgoff) {
1987  ds_print_lines_left(ds);
1988  ds_print_offset(ds);
1989  }
1990  }
1991  if (!strcmp(fcntype, "fcn")) {
1992  rz_cons_printf("%s", COLOR(ds, color_fname));
1993  } else {
1994  rz_cons_printf("%s(%s) ", COLOR(ds, color_fname), fcntype);
1995  }
1996 
1997  if (ds->show_fcnsize) {
1999  }
2000  // show function's realname in the signature if realnames are enabled
2001  if (core->flags->realnames) {
2002  RzFlagItem *flag = rz_flag_get(core->flags, fcn_name);
2003  if (flag && flag->realname) {
2004  fcn_name = flag->realname;
2005  }
2006  }
2007 
2008  char *sig = rz_analysis_fcn_format_sig(core->analysis, f, fcn_name, &vars_cache, COLOR(ds, color_fname), COLOR_RESET(ds));
2009  if (sig && fcnsig) {
2010  rz_cons_print(sig);
2011  RZ_FREE(sig);
2012  } else {
2013  rz_cons_printf("%s", fcn_name);
2014  }
2015  ds_newline(ds);
2016  RZ_FREE(sign);
2017 
2018  if (ds->show_lines_fcn) {
2019  ds->pre = DS_PRE_FCN_MIDDLE;
2020  }
2021 
2022  if (ds->show_vars) {
2023  if (ds->show_varsum && ds->show_varsum != -1) {
2024  RzList *all_vars = vars_cache.bvars;
2025  rz_list_join(all_vars, vars_cache.svars);
2026  rz_list_join(all_vars, vars_cache.rvars);
2027  printVarSummary(ds, all_vars);
2028  } else {
2029  char spaces[32];
2030  RzAnalysisVar *var;
2031  RzListIter *iter;
2032  RzList *all_vars = vars_cache.bvars;
2033  rz_list_join(all_vars, vars_cache.svars);
2034  rz_list_join(all_vars, vars_cache.rvars);
2035  rz_list_foreach (all_vars, iter, var) {
2036  ds_begin_line(ds);
2037  int idx;
2038  RzAnalysis *analysis = ds->core->analysis;
2039  memset(spaces, ' ', sizeof(spaces));
2040  idx = 12 - strlen(var->name);
2041  if (idx < 0) {
2042  idx = 0;
2043  }
2044  spaces[idx] = 0;
2045  ds_pre_xrefs(ds, false);
2046 
2047  if (ds->show_flgoff) {
2048  ds_print_offset(ds);
2049  }
2050  rz_cons_printf("%s; ", COLOR_ARG(ds, color_func_var));
2051  switch (var->kind) {
2052  case RZ_ANALYSIS_VAR_KIND_BPV: {
2053  char sign = var->isarg || (-var->delta <= f->bp_off) ? '+' : '-';
2054  bool is_var = !var->isarg;
2055  ds_show_functions_argvar(ds, f, var,
2056  analysis->reg->name[RZ_REG_NAME_BP], is_var, sign);
2057  } break;
2058  case RZ_ANALYSIS_VAR_KIND_REG: {
2059  RzRegItem *i = rz_reg_index_get(analysis->reg, var->delta);
2060  if (!i) {
2061  eprintf("Register not found");
2062  break;
2063  }
2064  char *vartype = rz_type_as_string(analysis->typedb, var->type);
2065  rz_cons_printf("%sarg %s%s%s%s %s@ %s", COLOR_ARG(ds, color_func_var),
2066  COLOR_ARG(ds, color_func_var_type),
2067  vartype, rz_str_endswith(vartype, "*") ? "" : " ",
2068  var->name, COLOR_ARG(ds, color_func_var_addr), i->name);
2069  if (ds->show_varsum == -1) {
2070  char *val = rz_core_analysis_var_display(ds->core, var, false);
2071  if (val) {
2072  rz_str_replace_char(val, '\n', '\0');
2073  rz_cons_printf(" %s", val);
2074  free(val);
2075  }
2076  }
2077  free(vartype);
2078  } break;
2079  case RZ_ANALYSIS_VAR_KIND_SPV: {
2080  bool is_var = !var->isarg;
2081  int saved_delta = var->delta;
2082  var->delta = f->maxstack + var->delta;
2083  char sign = var->isarg || (-var->delta <= f->maxstack) ? '+' : '-';
2084  ds_show_functions_argvar(ds, f, var,
2085  analysis->reg->name[RZ_REG_NAME_SP],
2086  is_var, sign);
2087  var->delta = saved_delta;
2088  } break;
2089  }
2090  if (var->comment) {
2091  rz_cons_printf(" %s; %s", COLOR(ds, color_comment), var->comment);
2092  }
2093  rz_cons_print(COLOR_RESET(ds));
2094  ds_newline(ds);
2095  }
2096  }
2097  }
2098  ds->show_varsum = o_varsum;
2099  rz_analysis_fcn_vars_cache_fini(&vars_cache);
2100  if (fcn_name_alloc) {
2101  free(fcn_name);
2102  }
2103  {
2104  RzListIter *iter;
2105  char *imp;
2106  if (ds->fcn && ds->fcn->imports) {
2107  rz_list_foreach (ds->fcn->imports, iter, imp) {
2108  ds_print_pre(ds, true);
2109  ds_print_lines_left(ds);
2110  rz_cons_printf(".import %s", imp);
2111  ds_newline(ds);
2112  }
2113  }
2114  rz_list_foreach (ds->core->analysis->imports, iter, imp) {
2115  ds_print_pre(ds, true);
2116  ds_print_lines_left(ds);
2117  rz_cons_printf(".globalimport %s", imp);
2118  ds_newline(ds);
2119  }
2120  }
2121 }
2122 
2123 static void ds_setup_print_pre(RzDisasmState *ds, bool tail, bool middle) {
2124  ds_setup_pre(ds, tail, middle);
2125  ds_print_pre(ds, true);
2126 }
2127 
2128 static void ds_setup_pre(RzDisasmState *ds, bool tail, bool middle) {
2129  ds->cmtcount = 0;
2130  if (!ds->show_functions || !ds->show_lines_fcn) {
2131  ds->pre = DS_PRE_NONE;
2132  return;
2133  }
2134  ds->pre = DS_PRE_EMPTY;
2136  if (f) {
2137  if (f->addr == ds->at) {
2138  if (ds->analysis_op.size == rz_analysis_function_linear_size(f) && !middle) {
2139  ds->pre = DS_PRE_FCN_TAIL;
2140  } else {
2141  ds->pre = DS_PRE_FCN_MIDDLE;
2142  }
2143  } else if (rz_analysis_function_max_addr(f) - ds->analysis_op.size == ds->at && f->addr == rz_analysis_function_min_addr(f)) {
2144  ds->pre = DS_PRE_FCN_TAIL;
2145  } else if (rz_analysis_function_contains(f, ds->at)) {
2146  ds->pre = DS_PRE_FCN_MIDDLE;
2147  }
2148  if (tail) {
2149  if (ds->pre == DS_PRE_FCN_TAIL) {
2150  ds->pre = DS_PRE_EMPTY;
2151  }
2152  if (ds->pre == DS_PRE_FCN_MIDDLE) {
2153  ds->pre = DS_PRE_FCN_TAIL;
2154  }
2155  }
2156  }
2157 }
2158 
2159 static void ds_print_pre(RzDisasmState *ds, bool fcnline) {
2160  RzCore *core = ds->core;
2161  int pre = ds->pre;
2162  const char *c = NULL;
2163  if (!fcnline) {
2164  pre = DS_PRE_EMPTY;
2165  }
2166  switch (pre) {
2167  case DS_PRE_FCN_HEAD:
2168  c = core->cons->vline[CORNER_TL];
2169  break;
2170  case DS_PRE_FCN_MIDDLE:
2171  c = core->cons->vline[LINE_VERT];
2172  break;
2173  case DS_PRE_FCN_TAIL:
2174  c = core->cons->vline[CORNER_BL];
2175  break;
2176  case DS_PRE_EMPTY:
2177  rz_cons_print(" ");
2178  return;
2179  case DS_PRE_NONE:
2180  default:
2181  return;
2182  }
2183 
2184  rz_cons_printf("%s%s%s ",
2185  COLOR(ds, color_fline), c,
2186  COLOR_RESET(ds));
2187 }
2188 
2190  /* respect asm.describe */
2191  char *desc = NULL;
2192  if (ds->asm_describe && !ds->has_description) {
2193  char *op, *locase = strdup(rz_asm_op_get_asm(&ds->asmop));
2194  if (!locase) {
2195  return;
2196  }
2197  op = strchr(locase, ' ');
2198  if (op) {
2199  *op = 0;
2200  }
2201  rz_str_case(locase, 0);
2202  desc = rz_asm_describe(ds->core->rasm, locase);
2203  free(locase);
2204  }
2205  if (desc && *desc) {
2206  ds_begin_comment(ds);
2207  ds_align_comment(ds);
2208  if (ds->show_color) {
2210  }
2211  rz_cons_strcat("; ");
2214  ds_newline(ds);
2215  free(desc);
2216  }
2217 }
2218 
2219 // XXX review this with asm.cmt.right
2221  int linelen;
2222  RzCore *core = ds->core;
2223  /* show comment at right? */
2224  int scr = ds->show_comment_right;
2225  if (!ds->show_comments && !ds->show_usercomments) {
2226  return;
2227  }
2228  RzFlagItem *item = rz_flag_get_i(core->flags, ds->at);
2229  const char *comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, ds->at);
2230  const char *vartype = rz_meta_get_string(core->analysis, RZ_META_TYPE_VARTYPE, ds->at);
2231  if (!comment) {
2232  if (vartype) {
2233  ds->comment = rz_str_newf("%s; %s", COLOR_ARG(ds, color_func_var_type), vartype);
2234  } else if (item && item->comment && *item->comment) {
2235  ds->ocomment = item->comment;
2236  ds->comment = strdup(item->comment);
2237  }
2238  } else if (vartype) {
2239  ds->comment = rz_str_newf("%s; %s %s%s; %s", COLOR_ARG(ds, color_func_var_type), vartype, Color_RESET, COLOR(ds, color_usrcmt), comment);
2240  } else {
2241  ds->comment = rz_str_newf("%s; %s", COLOR_ARG(ds, color_usrcmt), comment);
2242  }
2243  if (!ds->comment || !*ds->comment) {
2244  return;
2245  }
2246  linelen = strlen(ds->comment) + 5;
2247  if (ds->show_comment_right_default) {
2248  if (ds->ocols + linelen < core->cons->columns) {
2249  if (!strchr(ds->comment, '\n')) { // more than one line?
2250  ds->show_comment_right = true;
2251  }
2252  }
2253  }
2254  if (!ds->show_comment_right) {
2255  ds_begin_line(ds);
2256  int mycols = ds->lcols;
2257  if ((mycols + linelen + 10) > core->cons->columns) {
2258  mycols = 0;
2259  }
2260  mycols /= 2;
2261  if (ds->show_color) {
2263  }
2264  ds_pre_xrefs(ds, false);
2265  if (ds->show_color) {
2267  }
2268  ds_comment(ds, false, "%s", ds->comment);
2269 
2270  if (ds->show_color) {
2272  }
2273  RZ_FREE(ds->comment);
2274  ds_newline(ds);
2275  /* flag one */
2276  if (item && item->comment && ds->ocomment != item->comment) {
2277  ds_begin_line(ds);
2278  if (ds->show_color) {
2280  }
2281  ds_newline(ds);
2282  ds_begin_line(ds);
2283  rz_cons_strcat(" ; ");
2284  rz_cons_strcat_justify(item->comment, mycols, ';');
2285  ds_newline(ds);
2286  if (ds->show_color) {
2288  }
2289  }
2290  }
2291  ds->show_comment_right = scr;
2292 }
2293 
2294 static int flagCmp(const void *a, const void *b) {
2295  const RzFlagItem *fa = a;
2296  const RzFlagItem *fb = b;
2297  if (fa->realname && fb->realname) {
2298  return strcmp(fa->realname, fb->realname);
2299  }
2300  return strcmp(fa->name, fb->name);
2301 }
2302 
2303 static void __preline_flag(RzDisasmState *ds, RzFlagItem *flag) {
2304  ds_newline(ds);
2305  ds_begin_line(ds);
2306  ds_pre_line(ds);
2307  if (ds->show_color) {
2308  bool hasColor = false;
2309  if (flag->color) {
2310  char *color = rz_cons_pal_parse(flag->color, NULL);
2311  if (color) {
2313  free(color);
2314  ds->lastflag = flag;
2315  hasColor = true;
2316  }
2317  }
2318  if (!hasColor) {
2320  }
2321  }
2322  if (!ds->show_offset) {
2323  rz_cons_printf(" ");
2324  }
2325 }
2326 
2327 #define printPre (outline || !*comma)
2328 static void ds_show_flags(RzDisasmState *ds, bool overlapped) {
2329  // const char *beginch;
2330  RzFlagItem *flag;
2331  RzListIter *iter;
2333  if (!ds->show_flags) {
2334  return;
2335  }
2336  RzCore *core = ds->core;
2337  char addr[64];
2338  ut64 switch_addr = UT64_MAX;
2339  int case_start = -1, case_prev = 0, case_current = 0;
2341  const RzList *flaglist = rz_flag_get_list(core->flags, ds->at);
2342  RzList *uniqlist = flaglist ? rz_list_uniq(flaglist, flagCmp) : NULL;
2343  int count = 0;
2344  bool outline = !ds->flags_inline;
2345  const char *comma = "";
2346  bool keep_lib = rz_config_get_b(core->config, "bin.demangle.libs");
2347  bool docolon = true;
2348  int nth = 0;
2349  RzAnalysisBlock *switch_block = NULL;
2350  const char *switch_enum_name = NULL;
2351  rz_list_foreach (uniqlist, iter, flag) {
2352  if (!overlapped && f && f->addr == flag->offset && !strcmp(flag->name, f->name)) {
2353  // do not show non-overlapped flags that have the same name as the function
2354  continue;
2355  }
2356  bool no_fcn_lines = (!overlapped && f && f->addr == flag->offset);
2357  if (ds->maxflags && count >= ds->maxflags) {
2358  if (printPre) {
2359  ds_pre_xrefs(ds, no_fcn_lines);
2360  }
2361  rz_cons_printf("...");
2362  break;
2363  }
2364  count++;
2365  if (!strncmp(flag->name, "case.", 5)) {
2366  sscanf(flag->name + 5, "%63[^.].%d", addr, &case_current);
2367  ut64 saddr = rz_num_math(core->num, addr);
2368  if (case_start == -1) {
2369  switch_addr = saddr;
2370  case_prev = case_current;
2371  case_start = case_current;
2372  if (iter != uniqlist->tail) {
2373  continue;
2374  }
2375  }
2376  if (case_current == case_prev + 1 && switch_addr == saddr) {
2377  case_prev = case_current;
2378  if (iter != uniqlist->tail) {
2379  continue;
2380  }
2381  }
2382  }
2383  if (printPre) {
2384  ds_begin_line(ds);
2385  }
2386 
2387  bool fake_flag_marks = (!ds->show_offset && ds->show_marks);
2388  if (printPre) {
2389  if (ds->show_flgoff) {
2390  ds_pre_line(ds);
2391  ds_print_offset(ds);
2392  if (!fake_flag_marks) {
2393  rz_cons_printf(" ");
2394  }
2395  } else {
2396  ds_pre_xrefs(ds, no_fcn_lines);
2397  }
2398  }
2399 
2400  bool hasColor = false;
2401  char *color = NULL;
2402  if (ds->show_color) {
2403  if (flag->color) {
2404  color = rz_cons_pal_parse(flag->color, NULL);
2405  if (color) {
2407  ds->lastflag = flag;
2408  hasColor = true;
2409  }
2410  }
2411  if (!hasColor) {
2413  }
2414  }
2415 
2416  if (ds->asm_demangle && flag->realname) {
2417  if (!strncmp(flag->name, "switch.", 7)) {
2418  rz_cons_printf(FLAG_PREFIX "switch");
2419  } else if (!strncmp(flag->name, "case.", 5)) {
2420  if (nth > 0) {
2421  __preline_flag(ds, flag);
2422  }
2423  if (!switch_block || switch_block->switch_op->addr != switch_addr) {
2424  switch_enum_name = NULL;
2425  switch_block = NULL;
2426  RzList *blocks = rz_analysis_get_blocks_in(core->analysis, switch_addr);
2427  RzListIter *it;
2428  RzAnalysisBlock *block;
2429  rz_list_foreach (blocks, it, block) {
2430  if (block->switch_op && block->switch_op->addr == switch_addr) {
2431  switch_block = block;
2432  if (block->switch_op->enum_type) {
2433  switch_enum_name = rz_type_identifier(block->switch_op->enum_type);
2434  }
2435  break;
2436  }
2437  }
2439  }
2440  if (!strncmp(flag->name + 5, "default", 7)) {
2441  rz_cons_printf(FLAG_PREFIX "default:"); // %s:", flag->name);
2442  rz_str_ncpy(addr, flag->name + 5 + strlen("default."), sizeof(addr));
2443  nth = 0;
2444  } else {
2445  const char *case_prev_name = NULL;
2446  if (switch_enum_name) {
2447  case_prev_name = rz_type_db_enum_member_by_val(core->analysis->typedb, switch_enum_name, case_prev);
2448  }
2449  rz_cons_printf(FLAG_PREFIX "case ");
2450  if (case_prev != case_start) {
2451  const char *case_start_name = NULL;
2452  if (switch_enum_name) {
2453  case_start_name = rz_type_db_enum_member_by_val(core->analysis->typedb, switch_enum_name, case_start);
2454  }
2455  if (case_start_name) {
2456  rz_cons_printf("%s...", case_start_name);
2457  } else {
2458  rz_cons_printf("%d...", case_start);
2459  }
2460  if (case_prev_name) {
2461  rz_cons_printf("%s:", case_prev_name);
2462  } else {
2463  rz_cons_printf("%d:", case_prev);
2464  }
2465  if (iter != uniqlist->head && iter != uniqlist->tail) {
2466  iter = iter->p;
2467  }
2468  case_start = case_current;
2469  } else {
2470  if (!case_prev_name) {
2471  rz_cons_printf("%d:", case_prev);
2472  } else {
2473  rz_cons_printf("%s:", case_prev_name);
2474  }
2475  case_start = -1;
2476  }
2477  }
2478  case_prev = case_current;
2479  ds_align_comment(ds);
2480  rz_cons_printf("%s; from %s", ds->show_color ? ds->pal_comment : "", addr);
2481  outline = false;
2482  docolon = false;
2483  } else {
2484  const char *lang = rz_config_get(core->config, "bin.lang");
2485  char *name = rz_bin_demangle(core->bin->cur, lang, flag->realname, flag->offset, keep_lib);
2486  if (!name) {
2487  const char *n = flag->realname ? flag->realname : flag->name;
2488  if (n) {
2489  name = strdup(n);
2490  }
2491  }
2492  if (name) {
2494  if (!ds->flags_inline || nth == 0) {
2496  if (overlapped) {
2497  rz_cons_printf("%s(0x%08" PFMT64x ")%s ",
2498  ds->show_color ? ds->color_offset : "", ds->at,
2499  ds->show_color ? (hasColor ? color : ds->color_flag) : "");
2500  }
2501  }
2502  if (outline) {
2503  rz_cons_printf("%s:", name);
2504  } else {
2505  rz_cons_printf("%s%s", comma, flag->name);
2506  }
2507  RZ_FREE(name);
2508  }
2509  }
2510  } else {
2511  if (outline) {
2512  rz_cons_printf("%s", flag->name);
2513  } else {
2514  rz_cons_printf("%s%s", comma, flag->name);
2515  }
2516  }
2517  if (ds->show_color) {
2519  }
2520  if (outline) {
2521  ds_newline(ds);
2522  } else {
2523  comma = ", ";
2524  }
2525  free(color);
2526  nth++;
2527  }
2528  if (!outline && *comma) {
2529  if (nth > 0 && docolon) {
2530  rz_cons_printf(":");
2531  }
2532  ds_newline(ds);
2533  }
2534  rz_list_free(uniqlist);
2535 }
2536 
2538  if (ds->show_lines_bb) {
2539  free(ds->line);
2540  free(ds->line_col);
2542  ds->line = line->str;
2543  ds->line_col = line->cols;
2544  free(ds->refline);
2545  ds->refline = ds->line ? strdup(ds->line) : NULL;
2546  free(ds->refline2);
2547  free(ds->prev_line_col);
2548  free(line);
2549  line = rz_analysis_reflines_str(ds->core, ds->at,
2551  ds->refline2 = line->str;
2552  ds->prev_line_col = line->cols;
2553  if (ds->line) {
2554  if (strchr(ds->line, '<')) {
2555  ds->indent_level++;
2556  }
2557  if (strchr(ds->line, '>')) {
2558  ds->indent_level--;
2559  }
2560  } else {
2561  ds->indent_level = 0;
2562  }
2563  free(line);
2564  } else {
2565  RZ_FREE(ds->line);
2566  RZ_FREE(ds->line_col);
2567  RZ_FREE(ds->prev_line_col);
2568  free(ds->refline);
2569  free(ds->refline2);
2570  free(ds->prev_line_col);
2571  ds->refline = strdup("");
2572  ds->refline2 = strdup("");
2573  ds->line = NULL;
2574  ds->line_col = NULL;
2575  ds->prev_line_col = NULL;
2576  }
2577 }
2578 
2579 static int ds_disassemble(RzDisasmState *ds, ut8 *buf, int len) {
2580  RzCore *core = ds->core;
2581  int ret;
2582 
2583  // find the meta item at this offset if any
2584  RzPVector *metas = rz_meta_get_all_at(ds->core->analysis, ds->at); // TODO: do in range
2585  RzAnalysisMetaItem *meta = NULL;
2586  ut64 meta_size = UT64_MAX;
2587  if (metas) {
2588  void **it;
2589  rz_pvector_foreach (metas, it) {
2590  RzIntervalNode *node = *it;
2591  RzAnalysisMetaItem *mi = node->data;
2592  switch (mi->type) {
2593  case RZ_META_TYPE_DATA:
2594  case RZ_META_TYPE_STRING:
2595  case RZ_META_TYPE_FORMAT:
2596  case RZ_META_TYPE_MAGIC:
2597  case RZ_META_TYPE_HIDE:
2598  meta = mi;
2599  meta_size = rz_meta_item_size(node->start, node->end);
2600  break;
2601  default:
2602  break;
2603  }
2604  }
2606  }
2607  if (ds->hint && ds->hint->bits) {
2608  if (!ds->core->analysis->opt.ignbithints) {
2609  rz_config_set_i(core->config, "asm.bits", ds->hint->bits);
2610  }
2611  }
2612  if (ds->hint && ds->hint->size) {
2613  ds->oplen = ds->hint->size;
2614  }
2615  if (ds->hint && ds->hint->opcode) {
2616  free(ds->opstr);
2617  ds->opstr = strdup(ds->hint->opcode);
2618  }
2619  rz_asm_op_fini(&ds->asmop);
2620  ret = rz_asm_disassemble(core->rasm, &ds->asmop, buf, len);
2621  if (ds->asmop.size < 1) {
2622  ds->asmop.size = 1;
2623  }
2624  // handle meta here //
2625  if (!ds->asm_meta) {
2626  int i = 0;
2627  if (meta && meta_size > 0 && meta->type != RZ_META_TYPE_HIDE) {
2628  // XXX this is just noise. should be rewritten
2629  switch (meta->type) {
2630  case RZ_META_TYPE_DATA:
2631  if (meta->str) {
2632  rz_cons_printf(".data: %s\n", meta->str);
2633  }
2634  i += meta_size;
2635  break;
2636  case RZ_META_TYPE_STRING:
2637  i += meta_size;
2638  break;
2639  case RZ_META_TYPE_FORMAT:
2640  rz_cons_printf(".format : %s\n", meta->str);
2641  i += meta_size;
2642  break;
2643  case RZ_META_TYPE_MAGIC:
2644  rz_cons_printf(".magic : %s\n", meta->str);
2645  i += meta_size;
2646  break;
2647  default:
2648  break;
2649  }
2650  int sz = RZ_MIN(16, meta_size);
2651  ds->asmop.size = sz;
2652  rz_asm_op_set_hexbuf(&ds->asmop, buf, sz);
2653  const char *tail = (meta_size > 16) ? "..." : "";
2654  switch (meta->type) {
2655  case RZ_META_TYPE_STRING:
2656  rz_asm_op_set_asm(&ds->asmop, sdb_fmt(".string \"%s%s\"", meta->str, tail));
2657  break;
2658  default: {
2659  char *op_hex = rz_asm_op_get_hex(&ds->asmop);
2660  rz_asm_op_set_asm(&ds->asmop, sdb_fmt(".hex %s%s", op_hex, tail));
2661  free(op_hex);
2662  break;
2663  }
2664  }
2665  ds->oplen = meta_size;
2666  return i;
2667  }
2668  }
2669 
2670  if (ds->show_nodup) {
2671  const char *opname = (ret < 1) ? "invalid" : rz_asm_op_get_asm(&ds->asmop);
2672  if (ds->prev_ins && !strcmp(ds->prev_ins, opname)) {
2673  if (!ds->prev_ins_eq) {
2674  ds->prev_ins_eq = true;
2675  rz_cons_printf("...");
2676  }
2677  ds->prev_ins_count++;
2678  return -31337;
2679  }
2680  if (ds->prev_ins_eq) {
2681  rz_cons_printf("dup (%d)\n", ds->prev_ins_count);
2682  }
2683  ds->prev_ins_count = 0;
2684  ds->prev_ins_eq = false;
2685  if (ds->prev_ins) {
2686  RZ_FREE(ds->prev_ins);
2687  }
2688  ds->prev_ins = strdup(rz_asm_op_get_asm(&ds->asmop));
2689  }
2690  ds->oplen = ds->asmop.size;
2691 
2692  if (ret < 1) {
2693  ret = -1;
2694 #if HASRETRY
2695  if (!ds->cbytes && ds->tries > 0) {
2696  ds->addr = core->rasm->pc;
2697  ds->tries--;
2698  ds->idx = 0;
2699  ds->retry = true;
2700  return ret;
2701  }
2702 #endif
2703  ds->lastfail = 1;
2704  ds->asmop.size = (ds->hint && ds->hint->size) ? ds->hint->size : 1;
2705  ds->oplen = ds->asmop.size;
2706  } else {
2707  ds->lastfail = 0;
2708  ds->asmop.size = (ds->hint && ds->hint->size)
2709  ? ds->hint->size
2710  : rz_asm_op_get_size(&ds->asmop);
2711  ds->oplen = ds->asmop.size;
2712  }
2713  if (ds->pseudo) {
2714  const char *opstr = rz_asm_op_get_asm(&ds->asmop);
2715  char *tmp = rz_parse_pseudocode(core->parser, opstr);
2716  free(ds->opstr);
2717  if (tmp) {
2718  snprintf(ds->str, sizeof(ds->str), "%s", tmp);
2719  ds->opstr = tmp;
2720  } else {
2721  ds->opstr = strdup("");
2722  ds->str[0] = 0;
2723  }
2724  }
2725  if (ds->acase) {
2727  } else if (ds->capitalize) {
2728  char *ba = rz_asm_op_get_asm(&ds->asmop);
2729  *ba = toupper((ut8)*ba);
2730  }
2731  if (meta && meta_size != UT64_MAX) {
2732  ds->oplen = meta_size;
2733  }
2734  return ret;
2735 }
2736 
2738  if (ds->show_comments && ds->show_cmtflgrefs) {
2739  RzFlagItem *item;
2740  if (ds->asm_analysis) {
2741  switch (ds->analysis_op.type) {
2744  break;
2745  }
2746  }
2747  switch (ds->analysis_op.type) {
2751  item = rz_flag_get_i(ds->core->flags, ds->analysis_op.jump);
2752  if (item && item->comment) {
2753  if (ds->show_color) {
2755  }
2756  ds_align_comment(ds);
2757  rz_cons_printf(" ; ref to %s: %s\n", item->name, item->comment);
2759  }
2760  break;
2761  }
2762  }
2763 }
2764 
2766  if (ds->linesright && ds->show_lines_bb && ds->line) {
2767  ds_print_ref_lines(ds->line, ds->line_col, ds);
2768  }
2769 }
2770 
2771 static void printCol(RzDisasmState *ds, char *sect, int cols, const char *color) {
2772  int pre;
2773  if (cols < 8) {
2774  cols = 8;
2775  }
2776  int outsz = cols + 32;
2777  char *out = malloc(outsz);
2778  if (!out) {
2779  return;
2780  }
2781  memset(out, ' ', outsz);
2782  out[outsz - 1] = 0;
2783  int sect_len = strlen(sect);
2784 
2785  if (sect_len > cols) {
2786  sect[cols - 2] = '.';
2787  sect[cols - 1] = '.';
2788  sect[cols] = 0;
2789  }
2790  if (ds->show_color) {
2791  pre = strlen(color) + 1;
2792  snprintf(out, outsz - pre, "%s %s", color, sect);
2793  strcat(out, Color_RESET);
2794  out[outsz - 1] = 0;
2795  } else {
2796  rz_str_ncpy(out + 1, sect, outsz - 2);
2797  }
2798  strcat(out, " ");
2800  free(out);
2801 }
2802 
2804  if (ds->linesright) {
2805  return;
2806  }
2807  RzCore *core = ds->core;
2808  if (ds->show_section) {
2809  char *str = NULL;
2810  if (ds->show_section_perm && core->bin && core->bin->cur) {
2811  int va = rz_config_get_i(core->config, "io.va");
2812  RzBinSection *sec = rz_bin_get_section_at(core->bin->cur->o, ds->at, va);
2813  str = strdup(sec ? rz_str_rwx_i(sec->perm) : "---");
2814  }
2815  if (ds->show_section_name && core->bin && core->bin->cur) {
2816  int va = rz_config_get_i(core->config, "io.va");
2817  RzBinSection *sec = rz_bin_get_section_at(core->bin->cur->o, ds->at, va);
2818  if (sec) {
2819  if (str) {
2820  str = rz_str_append(str, " ");
2821  }
2822  str = rz_str_appendf(str, "%10.10s", sec->name);
2823  }
2824  }
2825  char *sect = str ? str : strdup("");
2826  printCol(ds, sect, ds->show_section_col, ds->color_reg);
2827  free(sect);
2828  }
2829  if (ds->show_symbols) {
2830  static RzFlagItem sfi = RZ_EMPTY;
2831  const char *name = "";
2832  int delta = 0;
2833  if (ds->fcn) {
2834  sfi.offset = ds->fcn->addr;
2835  sfi.name = ds->fcn->name;
2836  ds->lastflag = &sfi;
2837  } else {
2838  RzFlagItem *fi = rz_flag_get_at(core->flags, ds->at, !ds->lastflag);
2839  if (fi) { // && (!ds->lastflag || fi->offset != ds->at))
2840  sfi.offset = fi->offset;
2841  sfi.name = fi->name;
2842  ds->lastflag = &sfi;
2843  }
2844  }
2845  if (ds->lastflag && ds->lastflag->name) {
2846  name = ds->lastflag->name;
2847  delta = ds->at - ds->lastflag->offset;
2848  }
2849  {
2850  char *str = rz_str_newf("%s + %-4d", name, delta);
2851  printCol(ds, str, ds->show_symbols_col, ds->color_num);
2852  free(str);
2853  }
2854  }
2855  if (ds->line) {
2856  ds_print_ref_lines(ds->line, ds->line_col, ds);
2857  }
2858 }
2859 
2860 static void ds_print_family(RzDisasmState *ds) {
2861  if (ds->show_family) {
2862  const char *familystr = rz_analysis_op_family_to_string(ds->analysis_op.family);
2863  rz_cons_printf("%5s ", familystr ? familystr : "");
2864  }
2865 }
2866 
2867 static void ds_print_cycles(RzDisasmState *ds) {
2868  if (ds->show_cycles) {
2869  if (!ds->analysis_op.failcycles) {
2870  rz_cons_printf("%3d ", ds->analysis_op.cycles);
2871  } else {
2872  rz_cons_printf("%3d %3d ", ds->analysis_op.cycles, ds->analysis_op.failcycles);
2873  }
2874  }
2875  if (ds->cyclespace) {
2876  char spaces[32];
2877  int times = RZ_MIN(ds->analysis_op.cycles / 4, 30); // limit to 30
2878  memset(spaces, ' ', sizeof(spaces));
2879  spaces[times] = 0;
2881  }
2882 }
2883 
2884 #include "disasm_stackptr.inc"
2885 
2886 static void ds_print_offset(RzDisasmState *ds) {
2887  RzCore *core = ds->core;
2888  ut64 at = ds->vat;
2889 
2890  bool hasCustomColor = false;
2891  // probably tooslow
2892  RzFlagItem *f = rz_flag_get_at(core->flags, at, 1);
2893  if (ds->show_color && f) { // ds->lastflag) {
2894  const char *color = f->color;
2895  if (ds->at >= f->offset && ds->at < f->offset + f->size) {
2896  // if (rz_itv_inrange (f->itv, ds->at))
2897  if (color && *color) {
2898  char *k = rz_cons_pal_parse(f->color, NULL);
2899  if (k) {
2900  rz_cons_printf("%s", k);
2901  hasCustomColor = true;
2902  free(k);
2903  }
2904  }
2905  }
2906  }
2907  rz_print_set_screenbounds(core->print, at);
2908  if (ds->show_offset) {
2909  static RzFlagItem sfi = RZ_EMPTY;
2910  const char *label = NULL;
2911  RzFlagItem *fi;
2912  int delta = -1;
2913  bool show_trace = false;
2914  unsigned int seggrn = rz_config_get_i(core->config, "asm.seggrn");
2915 
2916  if (ds->show_reloff) {
2918  if (!f) {
2919  f = fcnIn(ds, at, RZ_ANALYSIS_FCN_TYPE_NULL); // rz_analysis_get_fcn_in (core->analysis, at, RZ_ANALYSIS_FCN_TYPE_NULL);
2920  }
2921  if (f) {
2922  delta = at - f->addr;
2923  sfi.name = f->name;
2924  sfi.offset = f->addr;
2925  ds->lastflag = &sfi;
2926  label = f->name;
2927  } else {
2928  if (ds->show_reloff_flags) {
2929  /* XXX: this is wrong if starting to disasm after a flag */
2930  fi = rz_flag_get_i(core->flags, at);
2931  if (fi) {
2932  ds->lastflag = fi;
2933  }
2934  if (ds->lastflag) {
2935  if (ds->lastflag->offset == at) {
2936  delta = 0;
2937  } else {
2938  delta = at - ds->lastflag->offset;
2939  }
2940  } else {
2941  delta = at - core->offset;
2942  }
2943  if (ds->lastflag) {
2944  label = ds->lastflag->name;
2945  }
2946  }
2947  }
2948  if (!ds->lastflag) {
2949  delta = 0;
2950  }
2951  }
2952  if (ds->show_trace) {
2953  RzDebugTracepoint *tp = rz_debug_trace_get(ds->core->dbg, ds->at);
2954  show_trace = (tp ? !!tp->count : false);
2955  }
2956  if (ds->hint && ds->hint->high) {
2957  show_trace = true;
2958  }
2959  if (hasCustomColor) {
2960  int of = core->print->flags;
2961  core->print->flags = 0;
2962  rz_print_offset_sg(core->print, at, (at == ds->dest) || show_trace,
2963  rz_config_get_b(core->config, "asm.segoff"), seggrn, ds->show_offdec, delta, label);
2964  core->print->flags = of;
2966  } else {
2967  rz_print_offset_sg(core->print, at, (at == ds->dest) || show_trace,
2968  rz_config_get_b(core->config, "asm.segoff"), seggrn, ds->show_offdec, delta, label);
2969  }
2970  }
2971  if (ds->atabsoff > 0 && ds->show_offset) {
2972  if (ds->_tabsoff != ds->atabsoff) {
2973  // TODO optimize to avoid down resizing
2974  char *b = malloc(ds->atabsoff + 1);
2975  if (b) {
2976  memset(b, ' ', ds->atabsoff);
2977  b[ds->atabsoff] = 0;
2978  free(ds->_tabsbuf);
2979  ds->_tabsbuf = b;
2980  ds->_tabsoff = ds->atabsoff;
2981  }
2982  }
2983  rz_cons_strcat(ds->_tabsbuf);
2984  }
2985 }
2986 
2989  if (!metas) {
2990  return false;
2991  }
2992 
2993  void **it;
2994  bool res = true;
2995  rz_pvector_foreach (metas, it) {
2996  RzIntervalNode *node = *it;
2997  RzAnalysisMetaItem *mi = node->data;
2998  switch (mi->type) {
2999  case RZ_META_TYPE_DATA:
3000  case RZ_META_TYPE_STRING:
3001  case RZ_META_TYPE_FORMAT:
3002  case RZ_META_TYPE_MAGIC:
3003  case RZ_META_TYPE_HIDE:
3004  res = false;
3005  break;
3006  default:
3007  break;
3008  }
3009  }
3010 
3012  return res;
3013 }
3014 
3016  if (ds->show_size && requires_op_size(ds)) {
3017  int size = ds->oplen;
3018  rz_cons_printf("%d ", size); // ds->analysis_op.size);
3019  }
3020 }
3021 
3022 static void ds_print_trace(RzDisasmState *ds) {
3023  RzDebugTracepoint *tp = NULL;
3024  if (ds->show_trace) {
3025  tp = rz_debug_trace_get(ds->core->dbg, ds->at);
3026  rz_cons_printf("%02x:%04x ", tp ? tp->times : 0, tp ? tp->count : 0);
3027  }
3028  if (ds->tracespace) {
3029  char spaces[32];
3030  int times;
3031  if (!tp) {
3032  tp = rz_debug_trace_get(ds->core->dbg, ds->at);
3033  }
3034  if (tp) {
3035  times = RZ_MIN(tp->times, 30); // limit to 30
3036  memset(spaces, ' ', sizeof(spaces));
3037  spaces[times] = 0;
3039  }
3040  }
3041 }
3042 
3044  if (ds->adistrick) {
3046  ds->core->analysis->reflines, ds->at, ds->analysis_op.size);
3047  }
3048 }
3049 
3050 // TODO move into RzAnalysis.meta
3051 static bool ds_print_data_type(RzDisasmState *ds, const ut8 *buf, int ib, int size) {
3052  RzCore *core = ds->core;
3053  const char *type = NULL;
3054  char msg[64];
3055  const int isSigned = (ib == 1 || ib == 8 || ib == 10) ? 1 : 0;
3056  switch (size) {
3057  case 1: type = isSigned ? ".char" : ".byte"; break;
3058  case 2: type = isSigned ? ".int16" : ".word"; break;
3059  case 3: type = "htons"; break;
3060  case 4: type = isSigned ? ".int32" : ".dword"; break;
3061  case 8: type = isSigned ? ".int64" : ".qword"; break;
3062  default: return false;
3063  }
3064  // adjust alignment
3065  ut64 n = rz_read_ble(buf, core->print->big_endian, size * 8);
3066  if (rz_config_get_b(core->config, "asm.marks")) {
3067  rz_cons_printf(" ");
3068  int q = core->print->cur_enabled &&
3069  ds->cursor >= ds->index &&
3070  ds->cursor < (ds->index + size);
3071  if (q) {
3072  if (ds->cursor > ds->index) {
3073  int diff = ds->cursor - ds->index;
3074  rz_cons_printf("%d ", diff);
3075  } else if (ds->cursor == ds->index) {
3076  rz_cons_printf("* ");
3077  } else {
3078  rz_cons_printf(" ");
3079  }
3080  } else {
3081  rz_cons_printf(" ");
3082  }
3083  }
3084 
3086  switch (ib) {
3087  case 1:
3088  rz_str_bits(msg, buf, size * 8, NULL);
3089  rz_cons_printf("%s %sb", type, msg);
3090  break;
3091  case 3:
3092  rz_cons_printf("%s %d", type, ntohs(n & 0xFFFF));
3093  break;
3094  case 8:
3095  rz_cons_printf("%s %" PFMT64o "o", type, n);
3096  break;
3097  case 10:
3098  rz_cons_printf("%s %" PFMT64d, type, n);
3099  break;
3100  default:
3101  switch (size) {
3102  case 1:
3103  rz_cons_printf("%s 0x%02" PFMT64x, type, n);
3104  break;
3105  case 2:
3106  rz_cons_printf("%s 0x%04" PFMT64x, type, n);
3107  break;
3108  case 4:
3109  rz_cons_printf("%s 0x%08" PFMT64x, type, n);
3110  break;
3111  case 8:
3112  rz_cons_printf("%s 0x%016" PFMT64x, type, n);
3113  break;
3114  default:
3115  return false;
3116  }
3117  }
3118 
3119  if (size == 4 || size == 8) {
3120  if (rz_str_startswith(rz_config_get(core->config, "asm.arch"), "arm")) {
3121  ut64 bits = rz_config_get_i(core->config, "asm.bits");
3122  // adjust address for arm/thumb address
3123  if (bits < 64) {
3124  if (n & 1) {
3125  n--;
3126  }
3127  }
3128  }
3129  if (n >= ds->min_ref_addr) {
3130  const RzList *flags = rz_flag_get_list(core->flags, n);
3131  RzListIter *iter;
3132  RzFlagItem *fi;
3133  rz_list_foreach (flags, iter, fi) {
3134  rz_cons_printf(" ; %s", fi->name);
3135  }
3136  }
3137  }
3138  return true;
3139 }
3140 
3141 static bool ds_print_meta_infos(RzDisasmState *ds, ut8 *buf, int len, int idx, int *mi_type) {
3142  bool ret = false;
3143  RzAnalysisMetaItem *fmi;
3144  RzCore *core = ds->core;
3145  if (!ds->asm_meta) {
3146  return false;
3147  }
3149  if (!metas) {
3150  return false;
3151  }
3152  bool once = true;
3153  fmi = NULL;
3154  void **it;
3155  rz_pvector_foreach (metas, it) {
3156  RzIntervalNode *node = *it;
3157  RzAnalysisMetaItem *mi = node->data;
3158  switch (mi->type) {
3159  case RZ_META_TYPE_DATA:
3160  if (once) {
3161  if (ds->asm_hint_pos == 0) {
3162  if (ds->asm_hint_lea) {
3163  ds_print_shortcut(ds, node->start, 0);
3164  } else {
3165  rz_cons_strcat(" ");
3166  }
3167  }
3168  once = false;
3169  }
3170  break;
3171  case RZ_META_TYPE_STRING:
3172  fmi = mi;
3173  break;
3174  default:
3175  break;
3176  }
3177  }
3178  rz_pvector_foreach (metas, it) {
3179  RzIntervalNode *node = *it;
3180  RzAnalysisMetaItem *mi = node->data;
3181  ut64 mi_size = rz_meta_node_size(node);
3182  char *out = NULL;
3183  int hexlen;
3184  int delta;
3185  if (fmi && mi != fmi) {
3186  continue;
3187  }
3188  if (mi_type) {
3189  *mi_type = mi->type;
3190  }
3191  switch (mi->type) {
3192  case RZ_META_TYPE_STRING:
3193  if (mi->str) {
3194  RzStrEscOptions opt = { 0 };
3195  opt.esc_bslash = core->print->esc_bslash;
3196  opt.esc_double_quotes = true;
3197  opt.show_asciidot = false;
3198 
3199  switch (mi->subtype) {
3200  case RZ_STRING_ENC_UTF8:
3201  out = rz_str_escape_utf8(mi->str, &opt);
3202  break;
3203  case 0: /* temporary legacy workaround */
3204  opt.esc_bslash = false;
3205  /* fallthrough */
3206  default:
3207  out = rz_str_escape_8bit(mi->str, false, &opt);
3208  break;
3209  }
3210  if (!out) {
3211  break;
3212  }
3213  rz_cons_printf(" .string %s\"%s\"%s ; len=%" PFMT64d,
3214  COLOR(ds, color_btext), out, COLOR_RESET(ds),
3215  mi_size);
3216  free(out);
3217  delta = ds->at - node->start;
3218  ds->oplen = mi_size - delta;
3219  ds->asmop.size = (int)mi_size;
3220  // i += mi->size-1;
3221  RZ_FREE(ds->line);
3222  RZ_FREE(ds->line_col);
3223  RZ_FREE(ds->refline);
3224  RZ_FREE(ds->refline2);
3225  RZ_FREE(ds->prev_line_col);
3226  ret = true;
3227  }
3228  break;
3229  case RZ_META_TYPE_HIDE:
3230  rz_cons_printf("(%" PFMT64d " bytes hidden)", mi_size);
3231  ds->asmop.size = mi_size;
3232  ds->oplen = mi_size;
3233  ret = true;
3234  break;
3235  case RZ_META_TYPE_DATA:
3236  hexlen = len - idx;
3237  delta = ds->at - node->start;
3238  if (mi_size < hexlen) {
3239  hexlen = mi_size;
3240  }
3241  ds->oplen = mi_size - delta;
3242  core->print->flags &= ~RZ_PRINT_FLAGS_HEADER;
3243  int size = RZ_MIN(mi_size, len - idx);
3244  if (!ds_print_data_type(ds, buf + idx, ds->hint ? ds->hint->immbase : 0, size)) {
3245  if (size > delta && hexlen > delta) {
3246  rz_cons_printf("hex length=%d delta=%d\n", size, delta);
3247  rz_core_print_hexdump(core, ds->at, buf + idx, hexlen - delta, 16, 1, 1);
3248  } else {
3249  rz_cons_printf("hex size=%d hexlen=%d delta=%d", size, hexlen, delta);
3250  }
3251  }
3252  core->print->flags |= RZ_PRINT_FLAGS_HEADER;
3253  ds->asmop.size = (int)size - (node->start - ds->at);
3254  RZ_FREE(ds->line);
3255  RZ_FREE(ds->line_col);
3256  RZ_FREE(ds->refline);
3257  RZ_FREE(ds->refline2);
3258  RZ_FREE(ds->prev_line_col);
3259  ret = true;
3260  break;
3261  case RZ_META_TYPE_FORMAT: {
3262  rz_cons_printf("pf %s # size=%" PFMT64d "\n", mi->str, mi_size);
3263  int len_before = rz_cons_get_buffer_len();
3264  char *format = rz_type_format_data(core->analysis->typedb, core->print, ds->at, buf + idx,
3265  len - idx, mi->str, RZ_PRINT_MUSTSEE, NULL, NULL);
3266  if (format) {
3267  rz_cons_print(format);
3268  free(format);
3269  }
3270  int len_after = rz_cons_get_buffer_len();
3271  const char *cons_buf = rz_cons_get_buffer();
3272  if (len_after > len_before && buf && cons_buf[len_after - 1] == '\n') {
3273  rz_cons_drop(1);
3274  }
3275  ds->oplen = ds->asmop.size = (int)mi_size;
3276  RZ_FREE(ds->line);
3277  RZ_FREE(ds->refline);
3278  RZ_FREE(ds->refline2);
3279  RZ_FREE(ds->prev_line_col);
3280  ret = true;
3281  } break;
3282  default:
3283  break;
3284  }
3285  }
3287  return ret;
3288 }
3289 
3290 static st64 revert_cdiv_magic(st64 magic) {
3291  ut64 amagic = llabs(magic);
3292  const st64 N = ST64_MAX;
3293  st64 E, candidate;
3294  short s;
3295 
3296  if (amagic < 0xFFFFFF || amagic > UT32_MAX) {
3297  return 0;
3298  }
3299  if (magic < 0) {
3300  magic += 1LL << 32;
3301  }
3302  for (s = 0; s < 16; s++) {
3303  E = 1LL << (32 + s);
3304  candidate = (E + magic - 1) / magic;
3305  if (candidate > 0) {
3306  if (((N * magic) >> (32 + s)) == (N / candidate)) {
3307  return candidate;
3308  }
3309  }
3310  }
3311  return 0;
3312 }
3313 
3315  char *esil;
3316  char *end, *comma;
3317  st64 imm;
3318  st64 divisor;
3319  if (!ds->asm_hints || !ds->asm_hint_cdiv) {
3320  return;
3321  }
3322  switch (ds->analysis_op.type) {
3325  esil = RZ_STRBUF_SAFEGET(&ds->analysis_op.esil);
3326  while (esil) {
3327  comma = strchr(esil, ',');
3328  if (!comma) {
3329  break;
3330  }
3331  imm = strtol(esil, &end, 10);
3332  if (comma && comma == end) {
3333  divisor = revert_cdiv_magic(imm);
3334  if (divisor) {
3335  rz_cons_printf(" ; CDIV: %lld * 2^n", divisor);
3336  break;
3337  }
3338  }
3339  esil = comma + 1;
3340  }
3341  }
3342  // /TODO: check following SHR instructions
3343 }
3344 
3346  RzCore *core = ds->core;
3347  char *nstr, *str = NULL, pad[64];
3348  char *flagstr = NULL;
3349  int oldFlags = core->print->flags;
3350  char extra[128];
3351  int j, k;
3352 
3353  if (!ds->show_bytes || ds->nb < 1) {
3354  return;
3355  }
3356  if (!ds->show_color_bytes) {
3357  core->print->flags &= ~RZ_PRINT_FLAGS_COLOR;
3358  }
3359  strcpy(extra, " ");
3360  if (ds->show_flag_in_bytes) {
3361  flagstr = rz_flag_get_liststr(core->flags, ds->at);
3362  }
3363  if (flagstr) {
3364  str = rz_str_newf("%s:", flagstr);
3365  if (ds->nb > 0) {
3366  k = ds->nb - strlen(str) - 1;
3367  if (k < 0) {
3368  str[ds->nb - 1] = '\0';
3369  }
3370  if (k > sizeof(pad)) {
3371  k = 0;
3372  }
3373  for (j = 0; j < k; j++) {
3374  pad[j] = ' ';
3375  }
3376  pad[j] = '\0';
3377  } else {
3378  pad[0] = 0;
3379  }
3380  RZ_FREE(flagstr);
3381  } else {
3382  if (ds->show_flag_in_bytes) {
3383  k = ds->nb - 1;
3384  if (k < 0 || k > sizeof(pad)) {
3385  k = 0;
3386  }
3387  for (j = 0; j < k; j++) {
3388  pad[j] = ' ';
3389  }
3390  pad[j] = '\0';
3391  str = strdup("");
3392  } else {
3393  str = rz_asm_op_get_hex(&ds->asmop);
3394  if (rz_str_ansi_len(str) > ds->nb) {
3395  char *p = (char *)rz_str_ansi_chrn(str, ds->nb);
3396  if (p) {
3397  p[0] = '.';
3398  p[1] = '\0';
3399  }
3400  }
3401  ds->print->cur_enabled = (ds->cursor != -1);
3402  nstr = rz_print_hexpair(ds->print, str, ds->index);
3403  if (ds->print->bytespace) {
3404  k = (ds->nb + (ds->nb / 2)) - rz_str_ansi_len(nstr) + 2;
3405  } else {
3406  k = ds->nb - rz_str_ansi_len(nstr) + 1;
3407  }
3408  if (k > 0) {
3409  // setting to sizeof screw up the disasm
3410  if (k > sizeof(pad)) {
3411  k = 18;
3412  }
3413  for (j = 0; j < k; j++) {
3414  pad[j] = ' ';
3415  }
3416  pad[j] = 0;
3417  if (ds->lbytes) {
3418  // hack to align bytes left
3419  strcpy(extra, pad);
3420  *pad = 0;
3421  }
3422  } else {
3423  pad[0] = 0;
3424  }
3425  free(str);
3426  str = nstr;
3427  }
3428  }
3429  rz_cons_printf("%s%s %s", pad, str, extra);
3430  free(str);
3431  core->print->flags = oldFlags;
3432 }
3433 
3434 static void ds_print_indent(RzDisasmState *ds) {
3435  if (ds->show_indent) {
3436  char indent[128];
3437  int num = ds->indent_level * ds->indent_space;
3438  if (num < 0) {
3439  num = 0;
3440  }
3441  if (num >= sizeof(indent)) {
3442  num = sizeof(indent) - 1;
3443  }
3444  memset(indent, ' ', num);
3445  indent[num] = 0;
3446  rz_cons_strcat(indent);
3447  }
3448 }
3449 
3450 static void ds_print_optype(RzDisasmState *ds) {
3451  if (ds->show_optype) {
3454  const char *pad = rz_str_pad(' ', 8 - strlen(optype));
3455  rz_cons_printf("[%s]%s", optype, pad);
3456  }
3457 }
3458 
3459 static void ds_print_opstr(RzDisasmState *ds) {
3460  ds_print_indent(ds);
3461  if (ds->asm_instr) {
3462  rz_cons_strcat(ds->opstr);
3464  }
3465 }
3466 
3468  if (ds->show_color) {
3470  }
3471 }
3472 
3473 static int ds_print_middle(RzDisasmState *ds, int ret) {
3474  if (ds->middle != 0) {
3475  ret -= ds->middle;
3476  ds_align_comment(ds);
3477  if (ds->show_color) {
3479  }
3480  rz_cons_printf(" ; *middle* %d", ret);
3481  if (ds->show_color) {
3483  }
3484  }
3485  return ret;
3486 }
3487 
3489  const char *label;
3490  if (!f) {
3491  // f = rz_analysis_get_fcn_in (core->analysis, ds->at, 0);
3492  f = fcnIn(ds, ds->at, 0);
3493  }
3494  if (!f) {
3495  return false;
3496  }
3498  if (!label) {
3499  return false;
3500  }
3501  ds_pre_line(ds);
3502  if (ds->show_color) {
3504  rz_cons_printf(" .%s:\n", label);
3506  } else {
3507  rz_cons_printf(" .%s:\n", label);
3508  }
3509  return true;
3510 }
3511 
3513  RzCore *core = ds->core;
3514  if (!ds->show_comments) {
3515  return;
3516  }
3517  switch (ds->analysis_op.type) {
3518  case RZ_ANALYSIS_OP_TYPE_IO: {
3519  const int imm = (int)ds->analysis_op.val;
3520  const char *ioname = rz_sysreg_get(core->analysis->syscall, "mmio", imm);
3521  if (ioname) {
3522  CMT_ALIGN;
3523  ds_comment(ds, true, "; IO %s", ioname);
3524  ds->has_description = true;
3525  }
3526  } break;
3527  // Then sysregs
3532  const int imm = (int)ds->analysis_op.ptr;
3533  const char *sr = rz_sysreg_get(core->analysis->syscall, "reg", imm);
3534  if (sr) {
3535  CMT_ALIGN;
3536  ds_comment(ds, true, "; REG %s - %s", sr, "");
3537  // TODO: add register description description
3538  ds->has_description = true;
3539  }
3540  } break;
3541  }
3542 }
3543 
3545  if (!ds->show_comments) {
3546  return;
3547  }
3549  return;
3550  }
3552  if (!f && ds->core->flags && (!ds->core->vmode || (!ds->subjmp && !ds->subnames))) {
3553  const char *arch;
3556  if (flag && flag->name && ds->opstr && !strstr(ds->opstr, flag->name) && (rz_str_startswith(flag->name, "sym.") || rz_str_startswith(flag->name, "method.")) && (arch = rz_config_get(ds->core->config, "asm.arch")) && strcmp(arch, "dalvik")) {
3557  RzFlagItem *flag_sym = flag;
3558  if (ds->core->vmode && ds->asm_demangle && (rz_str_startswith(flag->name, "sym.") || (flag_sym = rz_flag_get_by_spaces(ds->core->flags, ds->analysis_op.jump, RZ_FLAGS_FS_SYMBOLS, NULL))) && flag_sym->demangled) {
3559  return;
3560  }
3561  ds_begin_comment(ds);
3562  ds_comment(ds, true, "; %s", flag->name);
3563  return;
3564  }
3565  }
3566  if (!f || !f->name) {
3567  return;
3568  }
3569  st64 delta = ds->analysis_op.jump - f->addr;
3571  if (label) {
3572  ds_begin_comment(ds);
3573  ds_comment(ds, true, "; %s.%s", f->name, label);
3574  } else {
3575  RzAnalysisFunction *f2 = fcnIn(ds, ds->at, 0);
3576  if (f == f2) {
3577  return;
3578  }
3579  if (delta > 0) {
3580  ds_begin_comment(ds);
3581  ds_comment(ds, true, "; %s+0x%x", f->name, delta);
3582  } else if (delta < 0) {
3583  ds_begin_comment(ds);
3584  ds_comment(ds, true, "; %s-0x%x", f->name, -delta);
3585  } else if ((!ds->core->vmode || (!ds->subjmp && !ds->subnames)) && (!ds->opstr || !strstr(ds->opstr, f->name))) {
3586  RzFlagItem *flag_sym;
3587  if (ds->core->vmode && ds->asm_demangle && (flag_sym = rz_flag_get_by_spaces(ds->core->flags, ds->analysis_op.jump, RZ_FLAGS_FS_SYMBOLS, NULL)) && flag_sym->demangled) {
3588  return;
3589  }
3590  ds_begin_comment(ds);
3591  ds_comment(ds, true, "; %s", f->name);
3592  }
3593  }
3594 }
3595 
3597  char *shortcut = rz_core_add_asmqjmp(ds->core, addr);
3598  int slen = shortcut ? strlen(shortcut) : 0;
3599  if (ds->asm_hint_pos > 0) {
3600  if (pos) {
3601  ds_align_comment(ds);
3602  }
3603  }
3604  const char *ch = (pos) ? ";" : "";
3605  if (ds->asm_hint_pos == -1) {
3606  ch = " ";
3607  }
3608  if (ds->show_color) {
3610  }
3611  if (*ch) {
3612  slen++;
3613  }
3614  if (shortcut) {
3615  if (ds->core->is_asmqjmps_letter) {
3616  rz_cons_printf("%s[o%s]", ch, shortcut);
3617  slen++;
3618  } else {
3619  rz_cons_printf("%s[%s]", ch, shortcut);
3620  }
3621  free(shortcut);
3622  } else {
3623  rz_cons_printf("%s[?]", ch);
3624  }
3625  if (ds->show_color) {
3626  if (ds->core->print->resetbg) {
3628  } else {
3630  }
3631  }
3632  slen++;
3633  return slen;
3634 }
3635 
3637  RzCore *core = ds->core;
3638  RzAnalysis *a = core->analysis;
3639  RzAnalysisHint *hint = rz_analysis_hint_get(a, ds->at);
3640  bool res = false;
3641  if (hint) {
3642  if (hint->jump != UT64_MAX) {
3643  ds_print_shortcut(ds, hint->jump, pos);
3644  res = true;
3645  }
3646  rz_analysis_hint_free(hint);
3647  }
3648  return res;
3649 }
3650 
3652  ut8 buf[sizeof(ut64)] = { 0 };
3653  rz_io_read_at(ds->core->io, addr, buf, sizeof(buf));
3654  ut64 n64_32;
3655  if (ds->core->rasm->bits == 64) {
3656  n64_32 = rz_read_ble64(buf, 0);
3657  } else {
3658  n64_32 = rz_read_ble32(buf, 0);
3659  }
3660  return n64_32;
3661 }
3662 
3664  ut8 buf[sizeof(ut64)] = { 0 };
3665  int endian = ds->core->rasm->big_endian;
3666  ut64 n64_32;
3667  rz_io_read_at(ds->core->io, addr, buf, sizeof(buf));
3668  if (ds->core->rasm->bits == 64) {
3669  n64_32 = rz_read_ble64(buf, endian);
3670  } else {
3671  n64_32 = rz_read_ble32(buf, endian);
3672  }
3673  return n64_32;
3674 }
3675 
3676 static bool ds_print_core_vmode(RzDisasmState *ds, int pos) {
3677  RzCore *core = ds->core;
3678  bool gotShortcut = false;
3679  int i, slen = 0;
3680 
3681  if (!core->vmode) {
3682  return false;
3683  }
3684  if (!ds->asm_hints) {
3685  return false;
3686  }
3687  if (ds->asm_hint_emu) {
3688  if (ds->emuptr) {
3689  if (rz_io_is_valid_offset(core->io, ds->emuptr, 0)) {
3690  ds_print_shortcut(ds, ds->emuptr, pos);
3691  // getPtr (ds, ds->emuptr, pos);
3692  ds->emuptr = 0;
3693  ds->hinted_line = true;
3694  gotShortcut = true;
3695  goto beach;
3696  }
3697  }
3698  }
3699  if (ds->asm_hint_lea) {
3700  ut64 size;
3702  if (mi) {
3703  int obits = ds->core->rasm->bits;
3704  ds->core->rasm->bits = size * 8;
3705  slen = ds_print_shortcut(ds, get_ptr(ds, ds->at), pos);
3706  ds->core->rasm->bits = obits;
3707  gotShortcut = true;
3708  }
3709  }
3710  switch (ds->analysis_op.type) {
3715  if (ds->asm_hint_lea) {
3716  if (ds->analysis_op.ptr != UT64_MAX && ds->analysis_op.ptr != UT32_MAX) {
3717  slen = ds_print_shortcut(ds, get_ptr(ds, ds->analysis_op.ptr), pos);
3718  gotShortcut = true;
3719  }
3720  }
3721  break;
3725  if (ds->asm_hint_lea) {
3726  if (ds->analysis_op.ptr != UT64_MAX && ds->analysis_op.ptr != UT32_MAX && ds->analysis_op.ptr > 256) {
3727  slen = ds_print_shortcut(ds, ds->analysis_op.ptr, pos);
3728  gotShortcut = true;
3729  }
3730  }
3731  break;
3735  if (ds->asm_hint_call) {
3736  if (ds->analysis_op.jump != UT64_MAX) {
3737  slen = ds_print_shortcut(ds, ds->analysis_op.jump, pos);
3738  } else {
3739  ut64 addr;
3740  if (ds->asm_hint_call_indirect) {
3741  addr = get_ptr_ble(ds, ds->analysis_op.ptr);
3742  } else {
3743  addr = ds->analysis_op.ptr;
3744  }
3745  slen = ds_print_shortcut(ds, addr, pos);
3746  }
3747  gotShortcut = true;
3748  }
3749  break;
3752  if (ds->analysis_op.jump != UT64_MAX && ds->analysis_op.jump != UT32_MAX) {
3753  ds->analysis_op.jump = get_ptr_ble(ds, ds->analysis_op.jump);
3754  slen = ds_print_shortcut(ds, ds->analysis_op.jump, pos);
3755  gotShortcut = true;
3756  }
3757  break;
3760  if (ds->asm_hint_jmp) {
3761  slen = ds_print_shortcut(ds, ds->analysis_op.jump, pos);
3762  gotShortcut = true;
3763  }
3764  break;
3767  if (ds->asm_hint_call) {
3768  slen = ds_print_shortcut(ds, ds->analysis_op.jump, pos);
3769  gotShortcut = true;
3770  }
3771  break;
3772  default:
3773  if (ds_print_core_vmode_jump_hit(ds, pos)) {
3774  gotShortcut = true;
3775  }
3776  break;
3777  }
3778 beach:
3779  if (ds->asm_hint_pos > 0) {
3780  const int begin = gotShortcut ? 2 : 3;
3781  for (i = begin - slen; i > 0; i--) {
3782  rz_cons_strcat(" ");
3783  }
3784  } else if (ds->asm_hint_pos == 0 && !gotShortcut) {
3785  rz_cons_strcat(" ");
3786  }
3787  ds->hinted_line = gotShortcut;
3788  return gotShortcut;
3789 }
3790 
3792  if (ds->cmtcount > 0 && ds->show_comment_right) {
3793  ds_newline(ds);
3794  ds_begin_cont(ds);
3795  } else if (ds->cmtcount > 0 || !ds->show_comment_right) {
3796  ds_begin_line(ds);
3797  ds_pre_xrefs(ds, false);
3798  }
3799  if (ds->show_color && (ds->cmtcount > 0 || ds->show_comment_right)) {
3800  rz_cons_print(ds->pal_comment);
3801  }
3802 }
3803 
3804 // align for comment
3806  if (!ds->show_comment_right_default) {
3807  return;
3808  }
3809  const int cmtcol = ds->cmtcol - 1;
3810  const char *ll = rz_cons_get_buffer();
3811  if (!ll) {
3812  return;
3813  }
3814  ll += ds->buf_line_begin;
3815  int cells = rz_str_len_utf8_ansi(ll);
3816  int cols = ds->interactive ? ds->core->cons->columns : 1024;
3817  if (cells < cmtcol) {
3818  int len = cmtcol - cells;
3819  if (len < cols && len > 0) {
3820  rz_cons_memset(' ', len);
3821  }
3822  }
3823  rz_cons_print(" ");
3824 }
3825 
3826 static void ds_print_dwarf(RzDisasmState *ds) {
3827  if (ds->show_dwarf) {
3828  // TODO: cache value in ds
3829  int dwarfFile = (int)ds->dwarfFile + (int)ds->dwarfAbspath;
3830  free(ds->sl);
3831  ds->sl = rz_bin_addr2text(ds->core->bin, ds->at, dwarfFile);
3832  if (ds->sl) {
3833  if ((!ds->osl || (ds->osl && strcmp(ds->sl, ds->osl)))) {
3834  char *line = strdup(ds->sl);
3835  if (!line) {
3836  return;
3837  }
3838  rz_str_replace_char(line, '\t', ' ');
3839  rz_str_replace_char(line, '\x1b', ' ');
3840  rz_str_replace_char(line, '\r', ' ');
3841  rz_str_replace_char(line, '\n', '\x00');
3842  rz_str_trim(line);
3843  if (!*line) {
3844  free(line);
3845  return;
3846  }
3847  // handle_set_pre (ds, " ");
3848  ds_align_comment(ds);
3849  if (ds->show_color) {
3850  rz_cons_printf("%s; %s" Color_RESET, ds->pal_comment, line);
3851  } else {
3852  rz_cons_printf("; %s", line);
3853  }
3854  free(ds->osl);
3855  ds->osl = ds->sl;
3856  ds->sl = NULL;
3857  free(line);
3858  }
3859  }
3860  }
3861 }
3862 
3863 static void ds_print_asmop_payload(RzDisasmState *ds, const ut8 *buf) {
3864  if (ds->show_varaccess) {
3865  // XXX assume analysis_op is filled
3866  // rz_analysis_op (core->analysis, &ds->analysis_op, ds->at, core->block+i, core->blocksize-i);
3867  int v = ds->analysis_op.ptr;
3868  switch (ds->analysis_op.stackop) {
3869  case RZ_ANALYSIS_STACK_GET:
3870  if (v < 0) {
3871  rz_cons_printf(" ; local.get %d", -v);
3872  } else {
3873  rz_cons_printf(" ; arg.get %d", v);
3874  }
3875  break;
3876  case RZ_ANALYSIS_STACK_SET:
3877  if (v < 0) {
3878  rz_cons_printf(" ; local.set %d", -v);
3879  } else {
3880  rz_cons_printf(" ; arg.set %d", v);
3881  }
3882  break;
3883  default:
3884  break;
3885  }
3886  }
3887  if (ds->asmop.payload != 0) {
3888  rz_cons_printf("\n; .. payload of %d byte(s)", ds->asmop.payload);
3889  if (ds->showpayloads) {
3890  int mod = ds->asmop.payload % ds->core->rasm->dataalign;
3891  int x;
3892  for (x = 0; x < ds->asmop.payload; x++) {
3893  rz_cons_printf("\n 0x%02x", buf[ds->oplen + x]);
3894  }
3895  for (x = 0; x < mod; x++) {
3896  rz_cons_printf("\n 0x%02x ; alignment", buf[ds->oplen + ds->asmop.payload + x]);
3897  }
3898  }
3899  }
3900 }
3901 
3902 /* Do not use this function for escaping JSON! */
3903 static char *ds_esc_str(RzDisasmState *ds, const char *str, int len, const char **prefix_out, bool is_comment) {
3904  int str_len;
3905  char *escstr = NULL;
3906  const char *prefix = "";
3907  RzStrEnc strenc = ds->strenc;
3908  if (strenc == RZ_STRING_ENC_GUESS) {
3909  strenc = rz_utf_bom_encoding((ut8 *)str, len);
3910  }
3911  RzStrEscOptions opt = { 0 };
3912  opt.show_asciidot = ds->show_asciidot;
3913  opt.esc_double_quotes = true;
3914  opt.esc_bslash = ds->core->print->esc_bslash;
3915  switch (strenc) {
3916  case RZ_STRING_ENC_8BIT:
3917  escstr = rz_str_escape_8bit(str, is_comment, &opt);
3918  break;
3919  case RZ_STRING_ENC_UTF8:
3920  escstr = rz_str_escape_utf8(str, &opt);
3921  break;
3922  case RZ_STRING_ENC_UTF16LE:
3923  escstr = rz_str_escape_utf16le(str, len, &opt);
3924  prefix = "u";
3925  break;
3926  case RZ_STRING_ENC_UTF32LE:
3927  escstr = rz_str_escape_utf32le(str, len, &opt);
3928  prefix = "U";
3929  break;
3930  case RZ_STRING_ENC_UTF16BE:
3931  escstr = rz_str_escape_utf16be(str, len, &opt);
3932  prefix = "ub";
3933  break;
3934  case RZ_STRING_ENC_UTF32BE:
3935  escstr = rz_str_escape_utf32be(str, len, &opt);
3936  prefix = "Ub";
3937  break;
3938  default:
3939  str_len = strlen(str);
3940  if ((str_len == 1 && len > 3 && str[2] && !str[3]) || (str_len == 3 && len > 5 && !memcmp(str, "\xff\xfe", 2) && str[4] && !str[5])) {
3941  escstr = rz_str_escape_utf16le(str, len, &opt);
3942  prefix = "u";
3943  } else if (str_len == 1 && len > 7 && !str[2] && !str[3] && str[4] && !str[5]) {
3945  RzRune ch;
3946  const char *ptr, *end;
3947  end = (const char *)rz_mem_mem_aligned((ut8 *)str, len, (ut8 *)"\0\0\0\0", 4, 4);
3948  if (!end) {
3949  end = str + len - 1;
3950  }
3951  for (ptr = str; ptr < end; ptr += 4) {
3952  if (rz_utf32le_decode((ut8 *)ptr, end - ptr, &ch) > 0 && ch > 0x10ffff) {
3953  enc = RZ_STRING_ENC_8BIT;
3954  break;
3955  }
3956  }
3957  if (enc == RZ_STRING_ENC_UTF32LE) {
3958  escstr = rz_str_escape_utf32le(str, len, &opt);
3959  prefix = "U";
3960  } else {
3961  escstr = rz_str_escape_8bit(str, is_comment, &opt);
3962  }
3963  } else {
3965  const char *ptr = str, *end = str + str_len;
3966  for (; ptr < end; ptr++) {
3967  if (rz_utf8_decode((ut8 *)ptr, end - ptr, NULL) > 1) {
3968  enc = RZ_STRING_ENC_UTF8;
3969  break;
3970  }
3971  }
3972  escstr = (enc == RZ_STRING_ENC_UTF8 ? rz_str_escape_utf8(str, &opt) : rz_str_escape_8bit(str, is_comment, &opt));
3973  }
3974  }
3975  if (prefix_out) {
3976  *prefix_out = prefix;
3977  }
3978  return escstr;
3979 }
3980 
3981 static void ds_print_str(RzDisasmState *ds, const char *str, int len, ut64 refaddr) {
3982  if (ds->core->flags->realnames || !rz_bin_string_filter(ds->core->bin, str, -1, refaddr)) {
3983  return;
3984  }
3985  // do not resolve strings on arm64 pointed with ADRP
3987  if (ds->core->rasm->bits == 64 && rz_str_startswith(rz_config_get(ds->core->config, "asm.arch"), "arm")) {
3988  return;
3989  }
3990  }
3991  const char *prefix;
3992  char *escstr = ds_esc_str(ds, str, len, &prefix, false);
3993  if (escstr) {
3994  bool inv = ds->show_color && !ds->show_emu_strinv;
3995  ds_begin_comment(ds);
3996  ds_comment(ds, true, "; %s%s\"%.128s\"%s", inv ? Color_INVERT : "", prefix, escstr,
3997  inv ? Color_INVERT_RESET : "");
3998  ds->printed_str_addr = refaddr;
3999  free(escstr);
4000  }
4001 }
4002 
4003 static inline bool is_filtered_flag(RzDisasmState *ds, const char *name) {
4004  if (ds->show_noisy_comments || strncmp(name, "str.", 4)) {
4005  return false;
4006  }
4007  ut64 refaddr = ds->analysis_op.ptr;
4008  const char *analysis_flag = rz_meta_get_string(ds->core->analysis, RZ_META_TYPE_STRING, refaddr);
4009  if (analysis_flag) {
4010  char *dupped = strdup(analysis_flag);
4011  if (dupped) {
4012  rz_name_filter(dupped, -1, true);
4013  if (!strcmp(&name[4], dupped)) {
4014  return true;
4015  }
4016  }
4017  }
4018  return false;
4019 }
4020 
4021 /* convert numeric value in opcode to ascii char or number */
4022 static void ds_print_ptr(RzDisasmState *ds, int len, int idx) {
4023  RzCore *core = ds->core;
4024  ut64 p = ds->analysis_op.ptr;
4025  ut64 v = ds->analysis_op.val;
4026  ut64 refaddr = p;
4027  bool aligned = false;
4028  int refptr = ds->analysis_op.refptr;
4029  RzFlagItem *f = NULL, *f2 = NULL;
4030  bool f2_in_opstr = false; /* Also if true, f exists */
4031  if (!ds->show_comments || !ds->show_slow) {
4032  return;
4033  }
4034  const int opType = ds->analysis_op.type & RZ_ANALYSIS_OP_TYPE_MASK;
4035  bool canHaveChar = opType == RZ_ANALYSIS_OP_TYPE_MOV;
4036  if (!canHaveChar) {
4037  canHaveChar = opType == RZ_ANALYSIS_OP_TYPE_PUSH;
4038  }
4039 
4040  ds->chref = 0;
4041  if ((char)v > 0 && v >= '!') {
4042  ds->chref = (char)v;
4043  if (ds->immstr) {
4044  char *str = rz_str_from_ut64(rz_read_ble64(&v, core->print->big_endian));
4045  if (str && *str) {
4046  const char *ptr = str;
4047  bool printable = true;
4048  for (; *ptr; ptr++) {
4049  if (!IS_PRINTABLE(*ptr)) {
4050  printable = false;
4051  break;
4052  }
4053  }
4054  if (rz_flag_get_i(core->flags, v)) {
4055  printable = false;
4056  }
4057  if (canHaveChar && printable) {
4058  ds_begin_comment(ds);
4059  ds_comment(ds, true, "; '%s'", str);
4060  }
4061  }
4062  free(str);
4063  } else {
4064  if (canHaveChar && (char)v > 0 && v >= '!' && v <= '~') {
4065  ds_begin_comment(ds);
4066  aligned = true;
4067  ds_comment(ds, true, "; '%c'", (char)v);
4068  }
4069  }
4070  }
4071  RzListIter *iter;
4072  RzAnalysisXRef *xref;
4074  rz_list_foreach (list, iter, xref) {
4076  if ((f = rz_flag_get_i(core->flags, xref->to))) {
4077  refaddr = xref->to;
4078  break;
4079  }
4080  }
4081  }
4082  rz_list_free(list);
4084  const char *arch = rz_config_get(core->config, "asm.arch");
4085  if (arch && !strcmp(arch, "x86")) {
4086  p = refaddr = ds->analysis_op.val;
4087  refptr = 0;
4088  }
4089  }
4090  bool flag_printed = false;
4091  bool refaddr_printed = false;
4092  bool string_printed = false;
4093  if (refaddr == UT64_MAX) {
4094  /* do nothing */
4095  } else if (((st64)p) > 0 || ((st64)refaddr) > 0) {
4096  const char *kind;
4097  char *msg = calloc(sizeof(char), len);
4098  if (((st64)p) > 0) {
4099  f = rz_flag_get_i(core->flags, p);
4100  if (f) {
4101  ut64 subrel_addr = core->parser->subrel_addr;
4102  if (subrel_addr && subrel_addr != p) {
4103  f2 = rz_core_flag_get_by_spaces(core->flags, subrel_addr);
4104  f2_in_opstr = f2 && ds->opstr && (strstr(ds->opstr, f2->name) || strstr(ds->opstr, f2->realname));
4105  }
4106  refaddr = p;
4107  if (!flag_printed && !is_filtered_flag(ds, f->name) && (!ds->opstr || (!strstr(ds->opstr, f->name) && !strstr(ds->opstr, f->realname))) && !f2_in_opstr) {
4108  ds_begin_comment(ds);
4109  ds_comment(ds, true, "; %s", f->name);
4110  ds->printed_flag_addr = p;
4111  flag_printed = true;
4112  }
4113  }
4114  }
4115  rz_io_read_at(core->io, refaddr, (ut8 *)msg, len - 1);
4116  if (refptr && ds->show_refptr) {
4117  ut64 num = rz_read_ble(msg, core->print->big_endian, refptr * 8);
4118  st64 n = (st64)num;
4119  st32 n32 = (st32)(n & UT32_MAX);
4121  char str[128] = { 0 };
4122  f = rz_flag_get_i(core->flags, refaddr);
4123  if (!f && ds->show_slow) {
4124  rz_io_read_at(ds->core->io, ds->analysis_op.ptr,
4125  (ut8 *)str, sizeof(str) - 1);
4126  str[sizeof(str) - 1] = 0;
4127  if (!string_printed && str[0] && rz_str_is_printable_incl_newlines(str)) {
4128  ds_print_str(ds, str, sizeof(str), ds->analysis_op.ptr);
4129  string_printed = true;
4130  }
4131  }
4132  } else {
4133  if (n == UT32_MAX || n == UT64_MAX) {
4134  ds_begin_nl_comment(ds);
4135  ds_comment(ds, true, "; [0x%" PFMT64x ":%d]=-1",
4136  refaddr, refptr);
4137  } else if (n == n32 && (n32 > -512 && n32 < 512)) {
4138  ds_begin_nl_comment(ds);
4139  ds_comment(ds, true, "; [0x%" PFMT64x ":%d]=%" PFMT64d, refaddr, refptr, n);
4140  } else {
4141  const char *kind, *flag = "";
4142  char *msg2 = NULL;
4143  RzFlagItem *f2_ = rz_flag_get_i(core->flags, n);
4144  if (f2_) {
4145  flag = f2_->name;
4146  } else {
4147  msg2 = calloc(sizeof(char), len);
4148  rz_io_read_at(core->io, n, (ut8 *)msg2, len - 1);
4149  msg2[len - 1] = 0;
4150  kind = rz_analysis_data_kind(core->analysis, refaddr, (const ut8 *)msg2, len - 1);
4151  if (kind && !strcmp(kind, "text")) {
4152  rz_str_filter(msg2);
4153  if (*msg2) {
4154  char *lala = rz_str_newf("\"%s\"", msg2);
4155  free(msg2);
4156  flag = msg2 = lala;
4157  }
4158  }
4159  }
4160  // ds_align_comment (ds);
4161  {
4162  const char *refptrstr = "";
4163  if (core->print->flags & RZ_PRINT_FLAGS_SECSUB) {
4164  RzBinObject *bo = rz_bin_cur_object(core->bin);
4165  RzBinSection *s = bo ? rz_bin_get_section_at(bo, n, core->io->va) : NULL;
4166  if (s) {
4167  refptrstr = s->name;
4168  }
4169  }
4170  ds_begin_nl_comment(ds);
4171  ds_comment_start(ds, "; [");
4172  if (f && f2_in_opstr) {
4173  ds_comment_middle(ds, "%s", f->name);
4174  flag_printed = true;
4175  } else {
4176  ds_comment_middle(ds, "0x%" PFMT64x, refaddr);
4177  }
4178  ds_comment_end(ds, ":%d]=%s%s0x%" PFMT64x "%s%s",
4179  refptr, refptrstr, *refptrstr ? "." : "",
4180  n, (flag && *flag) ? " " : "", flag);
4181  }
4182  free(msg2);
4183  }
4184  refaddr_printed = true;
4185  }
4186  }
4187  if (!strcmp(ds->show_cmtoff, "true")) {
4188  ds_begin_comment(ds);
4189  ds_comment(ds, true, "; 0x%" PFMT64x, refaddr);
4190  } else if (!refaddr_printed && strcmp(ds->show_cmtoff, "false")) {
4191  char addrstr[32] = { 0 };
4192  snprintf(addrstr, sizeof(addrstr), "0x%" PFMT64x, refaddr);
4193  if (!ds->opstr || !strstr(ds->opstr, addrstr)) {
4194  snprintf(addrstr, sizeof(addrstr), "0x%08" PFMT64x, refaddr);
4195  if (!ds->opstr || !strstr(ds->opstr, addrstr)) {
4196  bool print_refaddr = true;
4197  if (refaddr < 10) {
4198  snprintf(addrstr, sizeof(addrstr), "%" PFMT64u, refaddr);
4199  if (ds->opstr && strstr(ds->opstr, addrstr)) {
4200  print_refaddr = false;
4201  }
4202  }
4203  if (print_refaddr) {
4204  if (!aligned) {
4205  ds_begin_nl_comment(ds);
4206  }
4207  ds_comment(ds, true, "; 0x%" PFMT64x, refaddr);
4208  }
4209  }
4210  }
4211  }
4212  bool print_msg = true;
4213 #if 1
4215  print_msg = false;
4216  } else {
4217  msg[len - 1] = 0;
4218  }
4219 #endif
4220  f = rz_flag_get_i(core->flags, refaddr);
4221  if (f) {
4222  if (strlen(msg) != 1) {
4223  char *msg2 = rz_str_new(msg);
4224  if (msg2) {
4225  rz_str_filter(msg2);
4226  if (!strncmp(msg2, "UH..", 4)) {
4227  print_msg = false;
4228  }
4229  free(msg2);
4230  }
4231  }
4232  if (print_msg) {
4233  if (!string_printed) {
4234  ds_print_str(ds, msg, len, refaddr);
4235  }
4236  } else if (!flag_printed && (!ds->opstr || (!strstr(ds->opstr, f->name) && !strstr(ds->opstr, f->realname)))) {
4237  ds_begin_nl_comment(ds);
4238  ds_comment(ds, true, "; %s", f->name);
4239  ds->printed_flag_addr = refaddr;
4240  }
4241  } else {
4242  if (refaddr == UT64_MAX || refaddr == UT32_MAX) {
4243  ds_begin_comment(ds);
4244  ds_comment(ds, true, "; -1");
4245  } else if (((char)refaddr > 0) && refaddr >= '!' && refaddr <= '~') {
4246  char ch = refaddr;
4247  if (canHaveChar && ch != ds->chref) {
4248  ds_begin_comment(ds);
4249  ds_comment(ds, true, "; '%c'", ch);
4250  }
4251  } else if (refaddr > 10) {
4252  if ((st64)refaddr < 0) {
4253  // resolve local var if possible
4255  RzAnalysisVar *v = fcn ? rz_analysis_function_get_var(fcn, 'v', (int)refaddr) : NULL;
4256  ds_begin_comment(ds);
4257  if (v) {
4258  ds_comment(ds, true, "; var %s", v->name);
4259  } else {
4260  ds_comment(ds, true, "; var %d", -(int)refaddr);
4261  }
4262  } else {
4264  if (!string_printed && print_msg) {
4265  ds_print_str(ds, msg, len, refaddr);
4266  string_printed = true;
4267  }
4268  }
4269  }
4270  }
4271  // XXX this should be refactored with along the above
4272  kind = rz_analysis_data_kind(core->analysis, refaddr, (const ut8 *)msg, len - 1);
4273  if (kind) {
4274  if (!strcmp(kind, "text")) {
4275  if (!string_printed && print_msg) {
4276  ds_print_str(ds, msg, len, refaddr);
4277  }
4278  } else if (!strcmp(kind, "invalid")) {
4279  int *n = (int *)&refaddr;
4280  ut64 p = ds->analysis_op.val;
4281  if (p == UT64_MAX || p == UT32_MAX) {
4282  p = ds->analysis_op.ptr;
4283  }
4284  /* avoid double ; -1 */
4285  if (p != UT64_MAX && p != UT32_MAX) {
4286  if (*n > -0xfff && *n < 0xfff) {
4287  if (!aligned) {
4288  ds_begin_comment(ds);
4289  }
4290  ds_comment(ds, true, "; %" PFMT64d, p);
4291  }
4292  }
4293  } else {
4294  // rz_cons_printf (" ; %s", kind);
4295  }
4296  // TODO: check for more data kinds
4297  }
4298  }
4299  free(msg);
4300  } else {
4301  ds_print_as_string(ds);
4302  }
4303  if (!ds->show_comment_right && ds->cmtcount > 0) {
4304  const char *p = rz_cons_get_buffer();
4305  if (p) {
4306  int l = strlen(p);
4307  if (p[l - 1] != '\n') {
4308  ds_newline(ds);
4309  }
4310  }
4311  }
4312 #if DEADCODE
4313  if (aligned && ds->show_color) {
4315  }
4316 #endif
4317 }
4318 
4320  if (!ds->show_cmt_esil) {
4321  return;
4322  }
4323  const char *esil = RZ_STRBUF_SAFEGET(&ds->analysis_op.esil);
4324  ds_begin_comment(ds);
4325  ds_comment(ds, true, "; %s", esil);
4326 }
4327 
4328 static void ds_print_cmt_il(RzDisasmState *ds) {
4329  if (!ds->show_cmt_il || !ds->analysis_op.il_op) {
4330  return;
4331  }
4332  RzStrBuf sb;
4333  rz_strbuf_init(&sb);
4335  ds_begin_comment(ds);
4336  ds_comment(ds, true, "; %s", rz_strbuf_get(&sb));
4337  rz_strbuf_fini(&sb);
4338 }
4339 
4341  if (!ds->show_comments || !ds->asm_demangle) {
4342  return;
4343  }
4344  RzCore *core = ds->core;
4345  RzFlagItem *f;
4346  int optype = ds->analysis_op.type & 0xFFFF;
4347  switch (optype) {
4352  if (f && f->demangled && f->realname && ds->opstr && !strstr(ds->opstr, f->realname)) {
4353  ds_begin_nl_comment(ds);
4354  ds_comment(ds, true, "; %s", f->realname);
4355  }
4356  }
4357 }
4358 
4359 static void ds_print_relocs(RzDisasmState *ds) {
4360  char *demname = NULL;
4361  if (!ds->showrelocs || !ds->show_slow) {
4362  return;
4363  }
4364  RzCore *core = ds->core;
4365  const char *lang = rz_config_get(core->config, "bin.lang");
4366  bool demangle = rz_config_get_b(core->config, "asm.demangle");
4367  bool keep_lib = rz_config_get_b(core->config, "bin.demangle.libs");
4368  RzBinReloc *rel = rz_core_getreloc(core, ds->at, ds->analysis_op.size);
4369  const char *rel_label = "RELOC";
4370  if (!rel) {
4371  rel = rz_core_get_reloc_to(core, ds->at);
4372  rel_label = "RELOC TARGET";
4373  }
4374  if (rel) {
4375  int cstrlen = 0;
4376  char *ll = rz_cons_lastline(&cstrlen);
4377  if (!ll) {
4378  return;
4379  }
4380  int ansilen = rz_str_ansi_len(ll);
4381  int utf8len = rz_utf8_strlen((const ut8 *)ll);
4382  int cells = utf8len - (cstrlen - ansilen);
4383  int len = ds->cmtcol - cells;
4384  rz_cons_memset(' ', len);
4385  if (rel->import) {
4386  if (demangle) {
4387  demname = rz_bin_demangle(core->bin->cur, lang, rel->import->name, rel->vaddr, keep_lib);
4388  }
4389  rz_cons_printf("; %s %d %s", rel_label, rel->type, demname ? demname : rel->import->name);
4390  } else if (rel->symbol) {
4391  if (demangle) {
4392  demname = rz_bin_demangle(core->bin->cur, lang, rel->symbol->name, rel->symbol->vaddr, keep_lib);
4393  }
4394  rz_cons_printf("; %s %d %s @ 0x%08" PFMT64x,
4395  rel_label,
4396  rel->type, demname ? demname : rel->symbol->name,
4397  rel->symbol->vaddr);
4398  if (rel->addend) {
4399  if (rel->addend > 0) {
4400  rz_cons_printf(" + 0x%" PFMT64x, rel->addend);
4401  } else {
4402  rz_cons_printf(" - 0x%" PFMT64x, -rel->addend);
4403  }
4404  }
4405  } else {
4406  rz_cons_printf("; %s %d ", rel_label, rel->type);
4407  }
4408  free(demname);
4409  }
4410 }
4411 
4412 static int mymemwrite0(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
4413  return 0;
4414 }
4415 
4416 static int mymemwrite1(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
4417  return 1;
4418 }
4419 
4420 static int mymemwrite2(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
4421  return (addr >= emustack_min && addr < emustack_max);
4422 }
4423 
4424 static char *ssa_get(RzAnalysisEsil *esil, const char *reg) {
4425  RzDisasmState *ds = esil->user;
4426  if (isdigit(*reg)) {
4427  return strdup(reg);
4428  }
4429  if (!ds->ssa) {
4430  ds->ssa = sdb_new0();
4431  }
4432  int n = sdb_num_get(ds->ssa, reg, NULL);
4433  return rz_str_newf("%s_%d", reg, n);
4434 }
4435 
4436 static void ssa_set(RzAnalysisEsil *esil, const char *reg) {
4437  RzDisasmState *ds = esil->user;
4438  (void)sdb_num_inc(ds->ssa, reg, 1, 0);
4439 }
4440 
4441 #define RZ_DISASM_MAX_STR 512
4442 static int myregread(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size) {
4443  RzDisasmState *ds = esil->user;
4444  if (ds && ds->show_emu_ssa) {
4445  if (!isdigit(*name)) {
4446  char *r = ssa_get(esil, name);
4447  ds_comment_esil(ds, true, false, "<%s", r);
4448  free(r);
4449  }
4450  }
4451  return 0;
4452 }
4453 
4454 static int myregwrite(RzAnalysisEsil *esil, const char *name, ut64 *val) {
4455  char str[64], *msg = NULL;
4456  ut32 *n32 = (ut32 *)str;
4457  RzDisasmState *ds = esil->user;
4458  if (!ds) {
4459  return 0;
4460  }
4462  // useful for ARM64
4463  // reduce false positives in emu.str=true when loading strings via adrp+add
4464  return 0;
4465  }
4466  ds->esil_likely = true;
4467  if (ds->show_emu_ssa) {
4468  ssa_set(esil, name);
4469  char *r = ssa_get(esil, name);
4470  ds_comment_esil(ds, true, false, ">%s", r);
4471  free(r);
4472  return 0;
4473  }
4474  if (!ds->show_slow) {
4475  return 0;
4476  }
4477  memset(str, 0, sizeof(str));
4478  if (*val) {
4479  bool emu_str_printed = false;
4480  char *type = NULL;
4481  (void)rz_io_read_at(esil->analysis->iob.io, *val, (ut8 *)str, sizeof(str) - 1);
4482  str[sizeof(str) - 1] = 0;
4483  ds->emuptr = *val;
4484  // support cstring here
4485  {
4486  ut64 *cstr = (ut64 *)str;
4487  ut64 addr = cstr[0];
4488  if (!(*val >> 32)) {
4489  addr = addr & UT32_MAX;
4490  }
4491  if (cstr[0] == 0 && cstr[1] < 0x1000) {
4492  ut64 addr = cstr[2];
4493  if (!(*val >> 32)) {
4494  addr = addr & UT32_MAX;
4495  }
4496  (void)rz_io_read_at(esil->analysis->iob.io, addr,
4497  (ut8 *)str, sizeof(str) - 1);
4498  // eprintf ("IS CSTRING 0x%llx %s\n", addr, str);
4499  type = rz_str_newf("(cstr 0x%08" PFMT64x ") ", addr);
4500  ds->printed_str_addr = cstr[2];
4501  } else if (rz_io_is_valid_offset(esil->analysis->iob.io, addr, 0)) {
4502  ds->printed_str_addr = cstr[0];
4503  type = rz_str_newf("(pstr 0x%08" PFMT64x ") ", addr);
4504  (void)rz_io_read_at(esil->analysis->iob.io, addr,
4505  (ut8 *)str, sizeof(str) - 1);
4506  // eprintf ("IS PSTRING 0x%llx %s\n", addr, str);
4507  }
4508  }
4509 
4511  bool jump_op = false;
4512  bool ignored = false;
4513  switch (ds->analysis_op.type) {
4522  jump_op = true;
4523  break;
4526  ignored = true;
4527  break;
4529  if (ds->core->rasm->bits == 64 && rz_str_startswith(rz_config_get(ds->core->config, "asm.arch"), "arm")) {
4530  ignored = true;
4531  }
4532  break;
4533  }
4534  if (!jump_op && !ignored) {
4535  const char *prefix;
4536  ut32 len = sizeof(str) - 1;
4537 #if 0
4538  RzCore *core = ds->core;
4539  ut32 len = core->blocksize + 256;
4540  if (len < core->blocksize || len > RZ_DISASM_MAX_STR) {
4542  }
4543 #endif
4544  ds->emuptr = *val;
4545  char *escstr = ds_esc_str(ds, str, (int)len, &prefix, false);
4546  if (escstr) {
4547  char *m;
4548  if (ds->show_color) {
4549  bool inv = ds->show_emu_strinv;
4550  m = rz_str_newf("%s%s%s\"%s\"%s",
4551  prefix, type ? type : "", inv ? Color_INVERT : "",
4552  escstr, inv ? Color_INVERT_RESET : "");
4553  } else {
4554  m = rz_str_newf("%s%s\"%s\"", prefix, type ? type : "", escstr);
4555  }
4557  emu_str_printed = true;
4558  free(escstr);
4559  }
4560  }
4561  } else {
4562  if (!*n32) {
4563  // msg = strdup ("NULL");
4564  } else if (*n32 == UT32_MAX) {
4565  /* nothing */
4566  } else {
4567  if (!ds->show_emu_str) {
4568  msg = rz_str_appendf(msg, "-> 0x%x", *n32);
4569  }
4570  }
4571  }
4572  RZ_FREE(type);
4573  if ((ds->printed_flag_addr == UT64_MAX || *val != ds->printed_flag_addr) && (ds->show_emu_strflag || !emu_str_printed)) {
4574  RzFlagItem *fi = rz_flag_get_i(esil->analysis->flb.f, *val);
4575  if (fi && (!ds->opstr || !strstr(ds->opstr, fi->name))) {
4576  msg = rz_str_appendf(msg, "%s%s", msg && *msg ? " " : "", fi->name);
4577  }
4578  }
4579  }
4580  if (ds->show_emu_str) {
4581  if (msg && *msg) {
4582  ds->emuptr = *val;
4583  if (ds->show_emu_stroff && *msg == '"') {
4584  ds_comment_esil(ds, true, false, "; 0x%" PFMT64x " %s", *val, msg);
4585  } else {
4586  ds_comment_esil(ds, true, false, "; %s", msg);
4587  }
4588  if (ds->show_comments && !ds->show_comment_right) {
4589  ds_newline(ds);
4590  }
4591  }
4592  } else {
4593  if (msg && *msg) {
4594  ds_comment_esil(ds, true, false, "; %s=0x%" PFMT64x " %s", name, *val, msg);
4595  } else {
4596  ds_comment_esil(ds, true, false, "; %s=0x%" PFMT64x, name, *val);
4597  }
4598  if (ds->show_comments && !ds->show_comment_right) {
4599  ds_newline(ds);
4600  }
4601  }
4602  free(msg);
4603  return 0;
4604 }
4605 
4607  bool do_esil = ds->show_emu;
4608  if (!ds->pre_emu) {
4609  return;
4610  }
4611  RzFlagItem *f = rz_flag_get_at(ds->core->flags, ds->core->offset, true);
4612  if (!f) {
4613  return;
4614  }
4615  ut64 base = f->offset;
4616  RzAnalysisEsil *esil = ds->core->analysis->esil;
4617  int i, end = ds->core->offset - base;
4618  int maxemu = 1024 * 1024;
4620  if (end < 0 || end > maxemu) {
4621  return;
4622  }
4623  ds->stackptr = ds->core->analysis->stackptr;
4624  esil->cb.hook_reg_write = NULL;
4625  for (i = 0; i < end; i++) {
4626  ut64 addr = base + i;
4628  if (op) {
4629  if (do_esil) {
4632  if (op->size > 0) {
4633  i += op->size - 1;
4634  }
4635  }
4636  ds_update_stackptr(ds, op);
4638  }
4639  }
4640  esil->cb.hook_reg_write = orig_cb;
4641 }
4642 
4644  RzCore *core = ds->core;
4645  const char *pc = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
4646  if (!pc) {
4647  return;
4648  }
4649  ds->esil_old_pc = rz_reg_getv(core->analysis->reg, pc);
4650  if (!ds->esil_old_pc || ds->esil_old_pc == UT64_MAX) {
4651  ds->esil_old_pc = core->offset;
4652  }
4653  if (!ds->show_emu) {
4654  // XXX. stackptr not computed without asm.emu, when its not required
4655  return;
4656  }
4657  if (!core->analysis->esil) {
4658  int iotrap = rz_config_get_i(core->config, "esil.iotrap");
4659  int esd = rz_config_get_i(core->config, "esil.stack.depth");
4660  unsigned int addrsize = rz_config_get_i(core->config, "esil.addr.size");
4661 
4662  if (!(core->analysis->esil = rz_analysis_esil_new(esd, iotrap, addrsize))) {
4663  RZ_FREE(ds->esil_regstate);
4664  return;
4665  }
4666  rz_analysis_esil_setup(core->analysis->esil, core->analysis, 0, 0, 1);
4667  }
4668  core->analysis->esil->user = ds;
4669  free(ds->esil_regstate);
4671  if (core->analysis->gp) {
4672  rz_reg_setv(core->analysis->reg, "gp", core->analysis->gp);
4673  }
4676  if (ds->esil_regstate && regset) {
4677  ds->esil_regstate_size = regset->arena->size;
4678  }
4679 
4680  // TODO: emulate N instructions BEFORE the current offset to get proper full function emulation
4681  ds_pre_emulation(ds);
4682 }
4683 
4684 static void ds_print_bbline(RzDisasmState *ds) {
4685  if (ds->show_bbline && ds->at) {
4686  RzAnalysisBlock *bb = NULL;
4687  RzAnalysisFunction *f_before = NULL;
4688  if (ds->fcn) {
4689  bb = rz_analysis_fcn_bbget_at(ds->core->analysis, ds->fcn, ds->at);
4690  } else {
4691  f_before = fcnIn(ds, ds->at - 1, RZ_ANALYSIS_FCN_TYPE_NULL);
4692  }
4693  if ((ds->fcn && bb && ds->fcn->addr != ds->at) || (!ds->fcn && f_before)) {
4694  ds_begin_line(ds);
4695  // adapted from ds_setup_pre ()
4696  ds->cmtcount = 0;
4697  if (!ds->show_functions || !ds->show_lines_fcn) {
4698  ds->pre = DS_PRE_NONE;
4699  } else {
4700  ds->pre = DS_PRE_EMPTY;
4701  if (!f_before) {
4702  f_before = fcnIn(ds, ds->at - 1, RZ_ANALYSIS_FCN_TYPE_NULL);
4703  }
4704  if (f_before == ds->fcn) {
4705  ds->pre = DS_PRE_FCN_MIDDLE;
4706  }
4707  }
4708  ds_print_pre(ds, true);
4709  if (!ds->linesright && ds->show_lines_bb && ds->line) {
4710  char *refline, *reflinecol = NULL;
4711  ds_update_ref_lines(ds);
4712  refline = ds->refline2;
4713  reflinecol = ds->prev_line_col;
4714  ds_print_ref_lines(refline, reflinecol, ds);
4715  }
4716  rz_cons_printf("|");
4717  ds_newline(ds);
4718  }
4719  }
4720 }
4721 
4722 static void print_fcn_arg(RzCore *core, RzType *type, const char *name,
4723  const char *fmt, const ut64 addr,
4724  const int on_stack, int asm_types) {
4725  if (on_stack == 1 && asm_types > 1) {
4726  char *typestr = rz_type_as_string(core->analysis->typedb, type);
4727  rz_cons_printf("%s", typestr);
4728  free(typestr);
4729  }
4730  if (addr != UT32_MAX && addr != UT64_MAX && addr != 0) {
4731  char *res = rz_core_cmd_strf(core, "pf%s %s%s %s @ 0x%08" PFMT64x,
4732  (asm_types == 2) ? "" : "q", (on_stack == 1) ? "*" : "", fmt, name, addr);
4733  rz_str_trim(res);
4734  rz_cons_printf("%s", res);
4735  free(res);
4736  } else {
4737  rz_cons_printf("-1");
4738  }
4739  rz_cons_chop();
4740 }
4741 
4743  if (!ds->show_comment_right_default) {
4744  return;
4745  }
4746  const char *ll = rz_cons_get_buffer();
4747  if (!ll) {
4748  return;
4749  }
4750  ll += ds->buf_line_begin;
4751  const char *begin = ll;
4752  if (begin) {
4753  ds_newline(ds);
4754  ds_begin_cont(ds);
4755  }
4756 }
4757 
4758 static bool can_emulate_metadata(RzCore *core, ut64 at) {
4759  // check if there is a meta at the addr that is unemulateable
4760  const char *emuskipmeta = rz_config_get(core->config, "emu.skip");
4761  bool ret = true;
4763  void **it;
4764  rz_pvector_foreach (metas, it) {
4765  RzAnalysisMetaItem *item = ((RzIntervalNode *)*it)->data;
4766  if (strchr(emuskipmeta, (char)item->type)) {
4767  ret = false;
4768  break;
4769  }
4770  }
4772  return ret;
4773 }
4774 
4775 static void mipsTweak(RzDisasmState *ds) {
4776  RzCore *core = ds->core;
4777  const char *asm_arch = rz_config_get(core->config, "asm.arch");
4778  if (asm_arch && *asm_arch && strstr(asm_arch, "mips")) {
4779  if (rz_config_get_b(core->config, "analysis.gpfixed")) {
4780  ut64 gp = rz_config_get_i(core->config, "analysis.gp");
4781  rz_reg_setv(core->analysis->reg, "gp", gp);
4782  }
4783  }
4784 }
4785 
4786 // modifies analysis register state
4788  RzCore *core = ds->core;
4789  RzAnalysisEsil *esil = core->analysis->esil;
4790  const char *pc;
4791  int (*hook_mem_write)(RzAnalysisEsil * esil, ut64 addr, const ut8 *buf, int len) = NULL;
4792  int i, nargs;
4793  ut64 at = rz_core_pava(core, ds->at);
4794  RzConfigHold *hc = rz_config_hold_new(core->config);
4795  if (!hc) {
4796  return;
4797  }
4798  if (!esil) {
4800  esil = core->analysis->esil;
4801  }
4802  if (!ds->show_emu) {
4803  goto beach;
4804  }
4805  if (!can_emulate_metadata(core, at)) {
4806  goto beach;
4807  }
4808  if (ds->show_color) {
4810  }
4811  esil = core->analysis->esil;
4813  if (pc) {
4814  rz_reg_setv(core->analysis->reg, pc, at + ds->analysis_op.size);
4815  esil->cb.user = ds;
4816  esil->cb.hook_reg_write = myregwrite;
4817  esil->cb.hook_reg_read = myregread;
4819  }
4820  if (ds->show_emu_stack) {
4821  esil->cb.hook_mem_write = mymemwrite2;
4822  } else {
4823  if (ds->show_emu_write) {
4824  esil->cb.hook_mem_write = mymemwrite0;
4825  } else {
4826  esil->cb.hook_mem_write = mymemwrite1;
4827  }
4828  }
4829  ds->esil_likely = 0;
4830  const char *esilstr = RZ_STRBUF_SAFEGET(&ds->analysis_op.esil);
4831  if (RZ_STR_ISNOTEMPTY(esilstr)) {
4832  mipsTweak(ds);
4833  rz_analysis_esil_set_pc(esil, at);
4834  rz_analysis_esil_parse(esil, esilstr);
4835  }
4837  rz_config_hold_i(hc, "io.cache", NULL);
4838  rz_config_set(core->config, "io.cache", "true");
4839  if (!ds->show_comments) {
4840  goto beach;
4841  }
4842  switch (ds->analysis_op.type) {
4843  case RZ_ANALYSIS_OP_TYPE_SWI: {
4844  char *s = rz_core_syscall_as_string(core, ds->analysis_op.val, at);
4845  if (s) {
4846  ds_comment_esil(ds, true, true, "; %s", s);
4847  free(s);
4848  }
4849  } break;
4851  ds_comment_esil(ds, true, true, ds->esil_likely ? "; likely" : "; unlikely");
4852  break;
4853  case RZ_ANALYSIS_OP_TYPE_JMP: {
4854  ut64 addr = ds->analysis_op.jump;
4855  if (!rz_analysis_get_function_at(ds->core->analysis, addr) && !rz_flag_get_at(core->flags, addr, false)) {
4856  break;
4857  }
4858  }
4859  // fallthrough
4864  case RZ_ANALYSIS_OP_TYPE_CALL: {
4865  RzAnalysisFunction *fcn;
4867  RzListIter *iter;
4868  RzListIter *nextele;
4869  const char *fcn_name = NULL;
4870  char *key = NULL;
4871  ut64 pcv = ds->analysis_op.jump;
4873  pcv = UT64_MAX;
4874  }
4875  if (pcv == UT64_MAX) {
4876  pcv = ds->analysis_op.ptr; // call [reloc-addr] // windows style
4877  if (pcv == UT64_MAX || !pcv) {
4878  rz_analysis_esil_reg_read(esil, "$jt", &pcv, NULL);
4879  if (pcv == UT64_MAX || !pcv) {
4880  pcv = rz_reg_getv(core->analysis->reg, pc);
4881  }
4882  }
4883  }
4884  fcn = rz_analysis_get_function_at(core->analysis, pcv);
4885  if (fcn) {
4886  fcn_name = fcn->name;
4887  } else {
4888  RzFlagItem *item = rz_flag_get_i(core->flags, pcv);
4889  if (item) {
4890  fcn_name = item->name;
4891  }
4892  }
4893  if (fcn_name) {
4894  key = resolve_fcn_name(core->analysis, fcn_name);
4895  }
4896  if (key) {
4897  if (ds->asm_types < 1) {
4898  free(key);
4899  break;
4900  }
4901  RzType *fcn_type = rz_type_func_ret(core->analysis->typedb, key);
4903  // remove other comments
4904  delete_last_comment(ds);
4905  // ds_comment_start (ds, "");
4906  ds_comment_esil(ds, true, false, "%s", ds->show_color ? ds->pal_comment : "");
4907  char *fcn_type_str = NULL;
4908  if (fcn_type) {
4909  fcn_type_str = rz_type_as_string(core->analysis->typedb, fcn_type);
4910  }
4911  const char *sp = fcn_type && fcn_type->kind == RZ_TYPE_KIND_POINTER ? "" : " ";
4912  ds_comment_middle(ds, "; %s%s%s(",
4913  fcn_type_str ? fcn_type_str : "", sp,
4914  rz_str_get_null(key));
4915  free(fcn_type_str);
4916  if (!nargs) {
4917  ds_comment_end(ds, "void)");
4918  break;
4919  }
4920  }
4921  ut64 s_width = (core->analysis->bits == 64) ? 8 : 4;
4922  const char *sp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP);
4923  ut64 spv = rz_reg_getv(core->analysis->reg, sp);
4924  rz_reg_setv(core->analysis->reg, sp, spv + s_width); // temporarily set stack ptr to sync with carg.c
4925  RzList *list = rz_core_get_func_args(core, fcn_name);
4926  if (!rz_list_empty(list)) {
4927  bool warning = false;
4928  bool on_stack = false;
4929  rz_list_foreach (list, iter, arg) {
4930  if (arg->cc_source && rz_str_startswith(arg->cc_source, "stack")) {
4931  on_stack = true;
4932  }
4933  if (!arg->size) {
4934  if (ds->asm_types == 2) {
4935  ds_comment_middle(ds, "%s: unk_size", arg->c_type);
4936  }
4937  warning = true;
4938  }
4939  nextele = rz_list_iter_get_next(iter);
4940  if (RZ_STR_ISEMPTY(arg->fmt)) {
4941  if (ds->asm_types > 1) {
4942  if (warning) {
4943  ds_comment_middle(ds, "_format");
4944  } else {
4945  ds_comment_middle(ds, "%s : unk_format", arg->c_type);
4946  }
4947  } else {
4948  ds_comment_middle(ds, "?");
4949  }
4950  ds_comment_middle(ds, nextele ? ", " : ")");
4951  } else {
4952  // TODO: may need ds_comment_esil
4953  print_fcn_arg(core, arg->orig_c_type, arg->name, arg->fmt, arg->src, on_stack, ds->asm_types);
4954  ds_comment_middle(ds, nextele ? ", " : ")");
4955  }
4956  }
4957  ds_comment_end(ds, "");
4958  rz_list_free(list);
4959  break;
4960  } else {
4961  rz_list_free(list);
4962  // function name not resolved
4963  rz_warn_if_fail(!key);
4964  nargs = DEFAULT_NARGS;
4965  if (fcn) {
4966  // @TODO: fcn->nargs should be updated somewhere and used here instead
4967  nargs = rz_analysis_var_count(core->analysis, fcn, 's', 1) +
4968  rz_analysis_var_count(core->analysis, fcn, 'b', 1) +
4969  rz_analysis_var_count(core->analysis, fcn, 'r', 1);
4970  }
4971  if (nargs > 0) {
4972  ds_comment_esil(ds, true, false, "%s", ds->show_color ? ds->pal_comment : "");
4973  if (fcn_name) {
4974  ds_comment_middle(ds, "; %s(", fcn_name);
4975  } else {
4976  ds_comment_middle(ds, "; 0x%" PFMT64x "(", pcv);
4977  }
4978  const char *cc = rz_analysis_syscc_default(core->analysis);
4979  for (i = 0; i < nargs; i++) {
4980  ut64 v = rz_core_arg_get(core, cc, i);
4981  ds_comment_middle(ds, "%s0x%" PFMT64x, i ? ", " : "", v);
4982  }
4983  ds_comment_end(ds, ")");
4984  }
4985  }
4986  rz_reg_setv(core->analysis->reg, sp, spv); // reset stack ptr
4987  } break;
4988  }
4990 beach:
4991  if (esil) {
4993  }
4995  rz_config_hold_free(hc);
4996 }
4997 
4999  bool emu = rz_config_get_b(ds->core->config, "asm.emu");
5000  bool emuwrite = rz_config_get_b(ds->core->config, "emu.write");
5001  if (emu && emuwrite) {
5002  // this is done by ESIL
5003  return;
5004  }
5005  RzAnalysis *analysis = ds->core->analysis;
5006  char *name;
5007  char *full_name = NULL;
5009  // RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (analysis, ds->analysis_op.jump, -1);
5010  RzAnalysisFunction *fcn = fcnIn(ds, ds->analysis_op.jump, -1);
5011  if (fcn) {
5012  full_name = fcn->name;
5013  }
5014  } else if (ds->analysis_op.ptr != UT64_MAX) {
5015  RzFlagItem *flag = rz_flag_get_i(ds->core->flags, ds->analysis_op.ptr);
5016  if (flag && flag->space && !strcmp(flag->space->name, RZ_FLAGS_FS_IMPORTS)) {
5017  full_name = flag->realname;
5018  }
5019  }
5020  if (!full_name) {
5021  return;
5022  }
5023  if (rz_type_func_exist(analysis->typedb, full_name)) {
5024  name = strdup(full_name);
5025  } else if (!(name = rz_analysis_function_name_guess(analysis->typedb, full_name))) {
5026  return;
5027  }
5028  ds_begin_comment(ds);
5029  RzType *fcn_type = rz_type_func_ret(analysis->typedb, name);
5030  char *fcn_type_str = NULL;
5031  if (fcn_type) {
5032  fcn_type_str = rz_type_as_string(analysis->typedb, fcn_type);
5033  }
5034  const char *sp = fcn_type && fcn_type->kind == RZ_TYPE_KIND_POINTER ? "" : " ";
5035  char *cmt = rz_str_newf("; %s%s%s(", fcn_type_str ? fcn_type_str : "", sp, name);
5036  int i, arg_max = rz_type_func_args_count(analysis->typedb, name);
5037  if (!arg_max) {
5038  cmt = rz_str_append(cmt, "void)");
5039  } else {
5040  for (i = 0; i < arg_max; i++) {
5041  RzType *arg_type = rz_type_func_args_type(analysis->typedb, name, i);
5042  const char *tname = rz_type_func_args_name(analysis->typedb, name, i);
5043  if (arg_type) {
5044  char *arg_type_str = rz_type_as_string(analysis->typedb, arg_type);
5045  const char *sp = arg_type->kind == RZ_TYPE_KIND_POINTER ? "" : " ";
5046  cmt = rz_str_appendf(cmt, "%s%s%s%s%s", i == 0 ? "" : " ", arg_type_str, sp,
5047  tname, i == arg_max - 1 ? ")" : ",");
5048  free(arg_type_str);
5049  } else if (tname && !strcmp(tname, "...")) {
5050  cmt = rz_str_appendf(cmt, "%s%s%s", i == 0 ? "" : " ",
5051  tname, i == arg_max - 1 ? ")" : ",");
5052  }
5053  }
5054  }
5055  ds_comment(ds, true, "%s", cmt);
5057  free(fcn_type_str);
5058  free(cmt);
5059  free(name);
5060 }
5061 
5063  char *desc = NULL;
5064  RzCore *core = ds->core;
5065  ds_print_relocs(ds);
5066  bool is_code = (!ds->hint) || (ds->hint && ds->hint->type != 'd');
5068  if (mi) {
5069  is_code = mi->type != 'd';
5070  mi = NULL;
5071  }
5072  if (is_code && ds->asm_describe && !ds->has_description) {
5073  char *op, *locase = strdup(rz_asm_op_get_asm(&ds->asmop));
5074  if (!locase) {
5075  return;
5076  }
5077  op = strchr(locase, ' ');
5078  if (op) {
5079  *op = 0;
5080  }
5081  rz_str_case(locase, 0);
5082  desc = rz_asm_describe(core->rasm, locase);
5083  free(locase);
5084  }
5085  if (ds->show_usercomments || ds->show_comments) {
5086  if (desc && *desc) {
5087  ds_align_comment(ds);
5088  if (ds->show_color) {
5090  }
5091  rz_cons_strcat("; ");
5094  }
5095  if (ds->show_comment_right && ds->comment) {
5096  char *comment = ds->comment;
5097  rz_str_trim(comment);
5098  if (*comment) {
5099  if (!desc) {
5100  ds_align_comment(ds);
5101  }
5102  if (strchr(comment, '\n')) {
5103  comment = strdup(comment);
5104  if (comment) {
5105  ds_newline(ds);
5106  ds_begin_line(ds);
5107  size_t lines_count;
5108  size_t *line_indexes = rz_str_split_lines(comment, &lines_count);
5109  if (line_indexes) {
5110  int i;
5111  for (i = 0; i < lines_count; i++) {
5112  char *c = comment + line_indexes[i];
5113  ds_print_pre(ds, true);
5114  if (ds->show_color) {
5116  }
5117  rz_cons_printf(i == 0 ? "%s" : "; %s", c);
5118  if (i < lines_count - 1) {
5119  ds_newline(ds);
5120  ds_begin_line(ds);
5121  }
5122  }
5123  }
5124  free(line_indexes);
5125  }
5126  free(comment);
5127  } else {
5128  if (comment) {
5129  rz_cons_strcat(comment);
5130  }
5131  }
5132  }
5133  // rz_cons_strcat_justify (comment, strlen (ds->refline) + 5, ';');
5135  RZ_FREE(ds->comment);
5136  }
5137  }
5138  free(desc);
5141  }
5142 }
5143 
5145  char *str = rz_num_as_string(NULL, ds->analysis_op.ptr, true);
5146  if (str) {
5147  ds_comment(ds, false, "%s; \"%s\"%s", COLOR(ds, pal_comment),
5148  str, COLOR_RESET(ds));
5149  }
5150  free(str);
5151 }
5152 
5153 static char *_find_next_number(char *op) {
5154  char *p = op;
5155  if (p) {
5156  while (*p) {
5157  // look for start of next separator or ANSI sequence
5158  while (*p && !IS_SEPARATOR(*p) && *p != 0x1b) {
5159  p++;
5160  }
5161  if (*p == 0x1b) {
5162  // skip to end of ANSI sequence (lower or uppercase char)
5163  while (*p && !(*p >= 'A' && *p <= 'Z') && !(*p >= 'a' && *p <= 'z')) {
5164  p++;
5165  }
5166  if (*p) {
5167  p++;
5168  }
5169  }
5170  if (IS_SEPARATOR(*p)) {
5171  // skip to end of separator
5172  while (*p && IS_SEPARATOR(*p)) {
5173  p++;
5174  }
5175  }
5176  if (IS_DIGIT(*p)) {
5177  // we found the start of the next number
5178  return p;
5179  }
5180  }
5181  }
5182  return NULL;
5183 }
5184 
5185 static bool set_jump_realname(RzDisasmState *ds, ut64 addr, const char **kw, const char **name) {
5186  RzFlag *f = ds->core->flags;
5187  if (!f) {
5188  return false;
5189  }
5190  if (!ds->asm_demangle && !f->realnames) {
5191  // nothing to do, neither demangled nor regular realnames should be shown
5192  return false;
5193  }
5195  if (!flag_sym || !flag_sym->realname) {
5196  // nothing to replace
5197  return false;
5198  }
5199  if (!flag_sym->demangled && !f->realnames) {
5200  // realname is not demangled and we don't want to show non-demangled realnames
5201  return false;
5202  }
5203  *name = flag_sym->realname;
5205  if (!f->realnames) {
5206  // for asm.flags.real, we don't want these prefixes
5207  if (flag_mthd && flag_mthd->name && rz_str_startswith(flag_mthd->name, "method.")) {
5208  *kw = "method ";
5209  } else {
5210  *kw = "sym ";
5211  }
5212  }
5213  return true;
5214 }
5215 
5216 // TODO: this should be moved into rz_parse
5217 static char *ds_sub_jumps(RzDisasmState *ds, char *str) {
5218  RzAnalysis *analysis = ds->core->analysis;
5219  RzFlag *f = ds->core->flags;
5220  const char *name = NULL;
5221  const char *kw = "";
5222  if (!ds->subjmp || !analysis) {
5223  return str;
5224  }
5225  int optype = ds->analysis_op.type & 0xFFFF;
5226  switch (optype) {
5230  break;
5231  default:
5232  return str;
5233  }
5234  ut64 addr = ds->analysis_op.jump;
5235 
5237  if (fcn) {
5238  if (!set_jump_realname(ds, addr, &kw, &name)) {
5239  name = fcn->name;
5240  }
5241  } else if (f && !set_jump_realname(ds, addr, &kw, &name)) {
5243  if (flag) {
5244  if (strchr(flag->name, '.')) {
5245  name = flag->name;
5246  if (f->realnames && flag->realname) {
5247  name = flag->realname;
5248  }
5249  }
5250  }
5251  }
5252 
5253  if (!name) {
5254  // If there are no functions and no flags, but there is a reloc, show that
5255  RzBinReloc *rel = NULL;
5256  if (!ds->core->bin->is_reloc_patched) {
5257  rel = rz_core_getreloc(ds->core, ds->analysis_op.addr, ds->analysis_op.size);
5258  }
5259  if (!rel) {
5260  rel = rz_core_get_reloc_to(ds->core, addr);
5261  }
5262  if (rel) {
5263  if (rel && rel->import && rel->import->name) {
5264  name = rel->import->name;
5265  } else if (rel && rel->symbol && rel->symbol->name) {
5266  name = rel->symbol->name;
5267  }
5268  }
5269  }
5270 
5271  if (name) {
5272  char *nptr, *ptr;
5273  ut64 numval;
5274  ptr = str;
5275  while ((nptr = _find_next_number(ptr))) {
5276  ptr = nptr;
5277  numval = rz_num_get(NULL, ptr);
5278  if (numval == addr) {
5279  while (*nptr && !IS_SEPARATOR(*nptr) && *nptr != 0x1b) {
5280  nptr++;
5281  }
5282  char *kwname = rz_str_newf("%s%s", kw, name);
5283  if (kwname) {
5284  char *numstr = rz_str_ndup(ptr, nptr - ptr);
5285  if (numstr) {
5286  str = rz_str_replace(str, numstr, kwname, 0);
5287  free(numstr);
5288  }
5289  free(kwname);
5290  }
5291  break;
5292  }
5293  }
5294  }
5295  return str;
5296 }
5297 
5299  return ds->asm_highlight != UT64_MAX && ds->vat == ds->asm_highlight;
5300 }
5301 
5303  if (ds->show_color && line_highlighted(ds)) {
5305  }
5306 }
5307 
5309  if (ds->show_color && line_highlighted(ds)) {
5311  }
5312 }
5313 
5318  if (!t) {
5319  return;
5320  }
5321  free(t->text);
5322  free(t);
5323 }
5324 
5337  RZ_NULLABLE RzCoreDisasmOptions *options) {
5338  rz_return_val_if_fail(core && buf, 0);
5339 
5340  PJ *pj = state ? state->d.pj : NULL;
5341  bool json = state && state->mode == RZ_OUTPUT_MODE_JSON;
5342 
5343  RzPrint *p = core->print;
5344  int continueoninvbreak = (len == nlines) && (options ? options->invbreak : 0);
5346  bool calc_row_offsets = p->calc_row_offsets;
5347  int ret, inc = 0, skip_bytes_flag = 0, skip_bytes_bb = 0, idx = 0;
5348  ut8 *nbuf = NULL;
5349  const int addrbytes = core->io->addrbytes;
5350 
5351  RzConfigHold *rch = rz_config_hold_new(core->config);
5352  if (!rch) {
5353  return 0;
5354  }
5355  rz_config_hold_i(rch, "asm.bits", NULL);
5356  rz_config_hold_s(rch, "asm.arch", NULL);
5357 
5358  // TODO: All those ds must be print flags
5359  RzDisasmState *ds = ds_init(core);
5360  ds->cbytes = options ? options->cbytes : 0;
5361  ds->print = p;
5362  ds->l = nlines;
5363  ds->buf = buf;
5364  ds->len = len;
5365  ds->addr = addr;
5366  ds->hint = NULL;
5367  ds->buf_line_begin = 0;
5368  ds->pdf = options ? options->function : NULL;
5369  ds->pj = NULL;
5370  ds->vec = options ? options->vec : NULL;
5371 
5372  if (!ds->vec && json) {
5373  ds->pj = pj ? pj : pj_new();
5374  if (!ds->pj) {
5375  ds_free(ds);
5377  rz_config_hold_free(rch);
5378  return 0;
5379  }
5380  rz_cons_push();
5381  }
5382 
5383  // disable row_offsets to prevent other commands to overwrite computed info
5384  p->calc_row_offsets = false;
5385 
5386  // rz_cons_printf ("len =%d nlines=%d ib=%d limit=%d\n", len, nlines, invbreak, p->limit);
5387  // TODO: import values from debugger is possible
5388  // TODO: allow to get those register snapshots from traces
5389  // TODO: per-function register state trace
5390  // XXX - is there a better way to reset a the analysis counter so that
5391  // when code is disassembled, it can actually find the correct offsets
5392  { /* used by asm.emu */
5393  rz_reg_arena_push(core->analysis->reg);
5394  }
5395 
5396  ds_reflines_init(ds);
5397  /* reset jmp table if not asked to keep it */
5398  if (!core->keep_asmqjmps) { // hack
5399  core->asmqjmps_count = 0;
5400  ut64 *p = realloc(core->asmqjmps, RZ_CORE_ASMQJMPS_NUM * sizeof(ut64));
5401  if (p) {
5402  core->asmqjmps_size = RZ_CORE_ASMQJMPS_NUM;
5403  core->asmqjmps = p;
5404  for (int i = 0; i < RZ_CORE_ASMQJMPS_NUM; i++) {
5405  core->asmqjmps[i] = UT64_MAX;
5406  }
5407  }
5408  }
5409  if (!ds->vec && ds->pj && !pj) {
5410  pj_a(ds->pj);
5411  }
5412 toro:
5413  // uhm... is this necessary? imho can be removed
5414  rz_asm_set_pc(core->rasm, rz_core_pava(core, ds->addr + idx));
5415  core->cons->vline = rz_config_get_b(core->config, "scr.utf8") ? (rz_config_get_b(core->config, "scr.utf8.curvy") ? rz_vline_uc : rz_vline_u) : rz_vline_a;
5416 
5417  if (core->print->cur_enabled) {
5418  // TODO: support in-the-middle-of-instruction too
5420  if (rz_analysis_op(core->analysis, &ds->analysis_op, core->offset + core->print->cur,
5421  buf + core->print->cur, (int)(len - core->print->cur), DS_ANALYSIS_OP_MASK) > 0) {
5422  // TODO: check for ds->analysis_op.type and ret
5423  ds->dest = ds->analysis_op.jump;
5424  }
5425  } else {
5426  /* highlight eip */
5427  RzReg *reg = rz_core_reg_default(core);
5428  const char *pc = rz_reg_get_name(reg, RZ_REG_NAME_PC);
5429  if (pc) {
5430  ds->dest = rz_reg_getv(reg, pc);
5431  }
5432  }
5433 
5435  inc = 0;
5436  if (!ds->l) {
5437  ds->l = core->blocksize;
5438  }
5440  for (idx = ret = 0; addrbytes * idx < len && ds->lines < ds->l; idx += inc, ds->index += inc, ds->lines++) {
5441  ds->at = ds->addr + idx;
5442  ds->vat = rz_core_pava(core, ds->at);
5443  if (rz_cons_is_breaked()) {
5444  RZ_FREE(nbuf);
5445  if (!ds->vec && ds->pj) {
5446  rz_cons_pop();
5447  }
5450  rz_config_hold_free(rch);
5451  ds_free(ds);
5452  return 0; // break;
5453  }
5454  if (core->print->flags & RZ_PRINT_FLAGS_UNALLOC) {
5455  if (!core->analysis->iob.is_valid_offset(core->analysis->iob.io, ds->at, 0)) {
5456  ds_begin_line(ds);
5457  ds_print_labels(ds, f);
5458  ds_setup_print_pre(ds, false, false);
5459  ds_print_lines_left(ds);
5460  core->print->resetbg = (ds->asm_highlight == UT64_MAX);
5462  ds_print_offset(ds);
5463  rz_cons_printf(" unmapped\n");
5464  inc = 1;
5465  continue;
5466  }
5467  }
5468  rz_core_seek_arch_bits(core, ds->at); // slow but safe
5469  ds->has_description = false;
5470  ds->hint = rz_core_hint_begin(core, ds->hint, ds->at);
5471  ds->printed_str_addr = UT64_MAX;
5473  // XXX. this must be done in ds_update_pc()
5474  // ds_update_pc (ds, ds->at);
5475  rz_asm_set_pc(core->rasm, ds->at);
5476  ds_update_ref_lines(ds);
5478  rz_analysis_op(core->analysis, &ds->analysis_op, ds->at, buf + addrbytes * idx, (int)(len - addrbytes * idx), DS_ANALYSIS_OP_MASK);
5479  if (ds_must_strip(ds)) {
5480  inc = ds->analysis_op.size;
5481  // inc = ds->asmop.payload + (ds->asmop.payload % ds->core->rasm->dataalign);
5483  continue;
5484  }
5485  // f = rz_analysis_get_fcn_in (core->analysis, ds->at, RZ_ANALYSIS_FCN_TYPE_NULL);
5486  f = ds->fcn = fcnIn(ds, ds->at, RZ_ANALYSIS_FCN_TYPE_NULL);
5488  // TRY adding here
5489  RzType *link_type = rz_analysis_type_link_at(core->analysis, ds->addr + idx);
5490  if (link_type) {
5491  char *fmt = rz_type_as_format_pair(core->analysis->typedb, link_type);
5492  const char *typename = rz_type_identifier(link_type);
5493  if (fmt && typename) {
5494  rz_cons_printf("(%s)\n", typename);
5495  rz_core_cmdf(core, "pf %s @ 0x%08" PFMT64x "\n", fmt, ds->addr + idx);
5496  const ut32 type_bitsize = rz_type_db_get_bitsize(core->analysis->typedb, link_type);
5497  // always round up when calculating byte_size from bit_size of types
5498  // could be struct with a bitfield entry
5499  inc = (type_bitsize >> 3) + (!!(type_bitsize & 0x7));
5500  free(fmt);
5502  continue;
5503  }
5504  free(link_type);
5505  } else {
5506  if (idx >= 0) {
5507  ret = ds_disassemble(ds, buf + addrbytes * idx, len - addrbytes * idx);
5508  if (ret == -31337) {
5509  inc = ds->oplen;
5511  continue;
5512  }
5513  }
5514  }
5515  if (ds->retry) {
5516  ds->retry = false;
5519  goto retry;
5520  }
5521  ds_atabs_option(ds);
5522  if (ds->analysis_op.addr != ds->at) {
5524  rz_analysis_op(core->analysis, &ds->analysis_op, ds->at, buf + addrbytes * idx, (int)(len - addrbytes * idx), DS_ANALYSIS_OP_MASK);
5525  }
5526  if (ret < 1) {
5530  }
5531  if (ds->hint) {
5532  if (ds->hint->size) {
5533  ds->analysis_op.size = ds->hint->size;
5534  }
5535  if (ds->hint->ptr) {
5536  ds->analysis_op.ptr = ds->hint->ptr;
5537  }
5538  }
5539  ds_print_bbline(ds);
5540  if (ds->at >= addr) {
5541  rz_print_set_rowoff(core->print, ds->lines, ds->at - addr, calc_row_offsets);
5542  }
5543  skip_bytes_flag = handleMidFlags(core, ds, true);
5544  if (ds->midbb) {
5545  skip_bytes_bb = handleMidBB(core, ds);
5546  }
5547  ds_show_xrefs(ds);
5548  ds_show_flags(ds, false);
5549  if (skip_bytes_flag && ds->midflags == RZ_MIDFLAGS_SHOW &&
5550  (!ds->midbb || !skip_bytes_bb || skip_bytes_bb > skip_bytes_flag)) {
5551  ds->at += skip_bytes_flag;
5552  ds_show_xrefs(ds);
5553  ds_show_flags(ds, true);
5554  ds->at -= skip_bytes_flag;
5555  }
5556  if (ds->pdf) {
5557  static bool sparse = false;
5558  RzAnalysisBlock *bb = rz_analysis_fcn_bbget_in(core->analysis, ds->pdf, ds->at);
5559  if (!bb) {
5560  for (inc = 1; inc < ds->oplen; inc++) {
5561  RzAnalysisBlock *bb = rz_analysis_fcn_bbget_in(core->analysis, ds->pdf, ds->at + inc);
5562  if (bb) {
5563  break;
5564  }
5565  }
5567  RZ_FREE(ds->opstr);
5568  if (!sparse) {
5569  rz_cons_printf("..\n");
5570  sparse = true;
5571  }
5572  continue;
5573  }
5574  sparse = false;
5575  }
5578  /* XXX: This is really cpu consuming.. need to be fixed */
5579  ds_show_functions(ds);
5580 
5581  if (ds->show_comments && !ds->show_comment_right) {
5582  ds_show_refs(ds);
5583  ds_build_op_str(ds, false);
5584  ds_print_cmt_esil(ds);
5585  ds_print_cmt_il(ds);
5586  ds_print_ptr(ds, len + 256, idx);
5587  ds_print_sysregs(ds);
5588  ds_print_fcn_name(ds);
5589  ds_print_demangled(ds);
5591  if (!ds->pseudo) {
5592  RZ_FREE(ds->opstr);
5593  }
5594  if (ds->show_emu) {
5596  }
5599  }
5601  }
5602 
5603  f = fcnIn(ds, ds->addr, 0);
5604  ds_begin_line(ds);
5605  ds_print_labels(ds, f);
5606  ds_setup_print_pre(ds, false, false);
5607  ds_print_lines_left(ds);
5608  core->print->resetbg = (ds->asm_highlight == UT64_MAX);
5610  ds_print_offset(ds);
5612  RzAnalysisFunction *fcn = f;
5613  if (fcn) {
5614  RzAnalysisBlock *bb = rz_analysis_fcn_bbget_in(core->analysis, fcn, ds->at);
5615  if (!bb) {
5616  fcn = rz_analysis_get_function_at(core->analysis, ds->at);
5617  if (fcn) {
5618  rz_analysis_fcn_bbget_in(core->analysis, fcn, ds->at);
5619  }
5620  }
5621  }
5623  int mi_type;
5624  bool mi_found = ds_print_meta_infos(ds, buf, len, idx, &mi_type);
5625  if (ds->asm_hint_pos == 0) {
5626  if (mi_found) {
5627  rz_cons_printf(" ");
5628  } else {
5630  }
5631  }
5632  ds_print_op_size(ds);
5633  ds_print_trace(ds);
5634  ds_print_cycles(ds);
5635  ds_print_family(ds);
5636  ds_print_stackptr(ds);
5637  if (mi_found) {
5638  ds_print_dwarf(ds);
5639  ret = ds_print_middle(ds, ret);
5640 
5641  ds_print_asmop_payload(ds, buf + addrbytes * idx);
5642  if (core->rasm->syntax != RZ_ASM_SYNTAX_INTEL) {
5643  RzAsmOp ao; /* disassemble for the vm .. */
5644  int os = core->rasm->syntax;
5646  rz_asm_disassemble(core->rasm, &ao, buf + addrbytes * idx,
5647  len - addrbytes * idx + 5);
5648  rz_asm_set_syntax(core->rasm, os);
5649  }
5650  if (mi_type == RZ_META_TYPE_FORMAT) {
5651  if ((ds->show_comments || ds->show_usercomments) && ds->show_comment_right) {
5652  // haveMeta = false;
5653  }
5654  }
5655  if (mi_type != RZ_META_TYPE_FORMAT) {
5656  if (ds->asm_hint_pos > 0) {
5658  }
5659  }
5660  {
5662  if ((ds->show_comments || ds->show_usercomments) && ds->show_comment_right) {
5665  }
5666  }
5667  } else {
5668  /* show cursor */
5670  if (!ds->show_bytes_right) {
5671  ds_print_show_bytes(ds);
5672  }
5674  ds_print_optype(ds);
5675  ds_build_op_str(ds, true);
5676  ds_print_opstr(ds);
5678  ds_print_dwarf(ds);
5679  ret = ds_print_middle(ds, ret);
5680 
5681  ds_print_asmop_payload(ds, buf + addrbytes * idx);
5682  if (core->rasm->syntax != RZ_ASM_SYNTAX_INTEL) {
5683  RzAsmOp ao; /* disassemble for the vm .. */
5684  int os = core->rasm->syntax;
5686  rz_asm_disassemble(core->rasm, &ao, buf + addrbytes * idx,
5687  len - addrbytes * idx + 5);
5688  rz_asm_set_syntax(core->rasm, os);
5689  }
5690  if (ds->show_bytes_right && ds->show_bytes) {
5691  ds_comment(ds, true, "");
5692  ds_print_show_bytes(ds);
5693  }
5694  if (ds->asm_hint_pos > 0) {
5696  }
5697  // ds_print_cc_update (ds);
5698 
5700  if ((ds->show_comments || ds->show_usercomments) && ds->show_comment_right) {
5701  ds_print_cmt_esil(ds);
5702  ds_print_cmt_il(ds);
5703  ds_print_ptr(ds, len + 256, idx);
5704  ds_print_sysregs(ds);
5705  ds_print_fcn_name(ds);
5706  ds_print_demangled(ds);
5710  ds_show_refs(ds);
5711  }
5712  }
5713  core->print->resetbg = true;
5714  ds_newline(ds);
5715  if (ds->line) {
5717  if (strchr(ds->line, '>')) {
5718  memset(ds->line, ' ', rz_str_len_utf8(ds->line));
5719  }
5720  ds_begin_line(ds);
5721  ds_print_pre(ds, true);
5722  ds_print_ref_lines(ds->line, ds->line_col, ds);
5723  rz_cons_printf("; --------------------------------------");
5724  ds_newline(ds);
5725  }
5726  RZ_FREE(ds->line);
5727  RZ_FREE(ds->line_col);
5728  RZ_FREE(ds->refline);
5729  RZ_FREE(ds->refline2);
5730  RZ_FREE(ds->prev_line_col);
5731  }
5732  RZ_FREE(ds->opstr);
5733  inc = ds->oplen;
5734 
5735  if (ds->midflags == RZ_MIDFLAGS_REALIGN && skip_bytes_flag) {
5736  inc = skip_bytes_flag;
5737  }
5738  if (skip_bytes_bb && skip_bytes_bb < inc) {
5739  inc = skip_bytes_bb;
5740  }
5741  if (inc < 1) {
5742  inc = 1;
5743  }
5744  inc += ds->asmop.payload + (ds->asmop.payload % ds->core->rasm->dataalign);
5745  }
5747 
5748  RZ_FREE(nbuf);
5750 
5751 #if HASRETRY
5752  if (!ds->cbytes && ds->lines < ds->l) {
5753  ds->addr = ds->at + inc;
5754  retry:
5755  if (len < 4) {
5756  len = 4;
5757  }
5758  free(nbuf);
5759  buf = nbuf = malloc(len);
5760  if (ds->tries > 0) {
5761  if (rz_io_read_at(core->io, ds->addr, buf, len)) {
5762  goto toro;
5763  }
5764  }
5765  if (ds->lines < ds->l) {
5766  // ds->addr += idx;
5767  if (!rz_io_read_at(core->io, ds->addr, buf, len)) {
5768  // ds->tries = -1;
5769  }
5770  goto toro;
5771  }
5772  if (continueoninvbreak) {
5773  goto toro;
5774  }
5775  RZ_FREE(nbuf);
5776  }
5777 #endif
5778  if (!ds->vec && ds->pj) {
5779  rz_cons_pop();
5780  if (!pj) {
5781  pj_end(ds->pj);
5782  rz_cons_printf("%s", pj_string(ds->pj));
5783  pj_free(ds->pj);
5784  }
5785  }
5786  rz_print_set_rowoff(core->print, ds->lines, ds->at - addr, calc_row_offsets);
5787  rz_print_set_rowoff(core->print, ds->lines + 1, UT32_MAX, calc_row_offsets);
5788  // TODO: this too (must review)
5790  ds_reflines_fini(ds);
5792  rz_config_hold_free(rch);
5793  ds_free(ds);
5794  RZ_FREE(nbuf);
5795  p->calc_row_offsets = calc_row_offsets;
5796  /* used by asm.emu */
5797  rz_reg_arena_pop(core->analysis->reg);
5798  return addrbytes * idx; //-ds->lastfail;
5799 }
5800 
5804 RZ_IPI bool rz_disasm_check_end(int nb_opcodes, int i_opcodes, int nb_bytes, int i_bytes) {
5805  if (nb_opcodes > 0) {
5806  if (nb_bytes > 0) {
5807  return i_opcodes < nb_opcodes && i_bytes < nb_bytes;
5808  }
5809  return i_opcodes < nb_opcodes;
5810  }
5811  return i_bytes < nb_bytes;
5812 }
5813 
5814 RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address, ut8 *buf, int nb_bytes, int nb_opcodes) {
5815  RzDisasmState *ds = NULL;
5816  int i, j, ret, len = 0;
5817  char *tmpopstr;
5818  const ut64 old_offset = core->offset;
5819  bool hasanalysis = false;
5820  const size_t addrbytes = buf ? 1 : core->io->addrbytes;
5821  int skip_bytes_flag = 0, skip_bytes_bb = 0;
5822 
5823  if (nb_bytes < 1 && nb_opcodes < 1) {
5824  return 0;
5825  }
5826 
5827  rz_reg_arena_push(core->analysis->reg);
5828 
5829  ds = ds_init(core);
5830  ds->l = nb_opcodes;
5831  ds->len = nb_opcodes * 8;
5832 
5833  if (!buf) {
5834  rz_core_seek(core, address, true);
5835  buf = core->block;
5836  }
5837 
5838  core->offset = address;
5839 
5841  // build ranges to map addr with bits
5842  j = 0;
5843 toro:
5844  for (i = 0; rz_disasm_check_end(nb_opcodes, j, nb_bytes, addrbytes * i); i += ret, j++) {
5845  ds->at = address + i;
5846  ds->vat = rz_core_pava(core, ds->at);
5847  int len = nb_bytes - addrbytes * i;
5848  hasanalysis = false;
5849  rz_core_seek_arch_bits(core, ds->at);
5850  if (rz_cons_is_breaked()) {
5851  break;
5852  }
5853  ds->hint = rz_core_hint_begin(core, ds->hint, ds->at);
5854  ds->has_description = false;
5855  rz_asm_set_pc(core->rasm, ds->at);
5856  // XXX copypasta from main disassembler function
5857  // rz_analysis_get_fcn_in (core->analysis, ds->at, RZ_ANALYSIS_FCN_TYPE_NULL);
5858  ret = rz_asm_disassemble(core->rasm, &ds->asmop,
5859  buf + addrbytes * i, len);
5860  ds->oplen = ret;
5861  skip_bytes_flag = handleMidFlags(core, ds, true);
5862  if (ds->midbb) {
5863  skip_bytes_bb = handleMidBB(core, ds);
5864  }
5865  if (skip_bytes_flag && ds->midflags > RZ_MIDFLAGS_SHOW) {
5866  ret = skip_bytes_flag;
5867  }
5868  if (skip_bytes_bb && skip_bytes_bb < ret) {
5869  ret = skip_bytes_bb;
5870  }
5872  if (!hasanalysis) {
5873  // XXX we probably don't need MASK_ALL
5874  rz_analysis_op(core->analysis, &ds->analysis_op, ds->at, buf + addrbytes * i, len, RZ_ANALYSIS_OP_MASK_ALL);
5875  hasanalysis = true;
5876  }
5877  if (ds_must_strip(ds)) {
5878  continue;
5879  }
5880 
5881  if (ds->hint && ds->hint->size > 0) {
5882  ret = ds->hint->size;
5883  ds->oplen = ret;
5884  ds->analysis_op.size = ret;
5885  ds->asmop.size = ret;
5886  }
5887  /* fix infinite loop */
5888  if (ret < 1) {
5889  ret = 1;
5890  }
5891  len += RZ_MAX(0, ret);
5892  if (ds->hint && ds->hint->opcode) {
5893  free(ds->opstr);
5894  ds->opstr = strdup(ds->hint->opcode);
5895  } else {
5896  if (ds->decode && !ds->immtrim) {
5897  RZ_FREE(ds->opstr);
5898  if (!hasanalysis) {
5899  rz_analysis_op(core->analysis, &ds->analysis_op, ds->at, buf + i, nb_bytes - i, RZ_ANALYSIS_OP_MASK_ALL);
5900  }
5901  tmpopstr = rz_analysis_op_to_string(core->analysis, &ds->analysis_op);
5902  ds->opstr = (tmpopstr) ? tmpopstr : strdup(rz_asm_op_get_asm(&ds->asmop));
5903  } else if (ds->immtrim) {
5904  free(ds->opstr);
5905  ds->opstr = strdup(rz_asm_op_get_asm(&ds->asmop));
5906  rz_parse_immtrim(ds->opstr);
5907  } else if (ds->use_esil) {
5908  if (!hasanalysis) {
5909  rz_analysis_op(core->analysis, &ds->analysis_op,
5910  ds->at, buf + i,
5912  }
5913  if (*RZ_STRBUF_SAFEGET(&ds->analysis_op.esil)) {
5914  free(ds->opstr);
5916  }
5917  } else if (ds->subnames) {
5918  RzSpace *ofs = core->parser->flagspace;
5919  RzSpace *fs = ds->flagspace_ports;
5921  core->parser->notin_flagspace = NULL;
5922  core->parser->flagspace = fs;
5923  } else {
5924  if (fs) {
5925  core->parser->notin_flagspace = fs;
5926  core->parser->flagspace = fs;
5927  } else {
5928  core->parser->notin_flagspace = NULL;
5929  core->parser->flagspace = NULL;
5930  }
5931  }
5932  ds_build_op_str(ds, true);
5933  free(ds->opstr);
5934  ds->opstr = strdup(ds->str);
5935 
5936  if (!(ds->show_color && ds->colorop) && !ds->opstr) {
5937  ds->opstr = strdup(rz_asm_op_get_asm(&ds->asmop));
5938  }
5939 
5940  core->parser->flagspace = ofs;
5941  } else {
5942  ds->opstr = strdup(rz_asm_op_get_asm(&ds->asmop));
5943  }
5944  if (ds->immtrim) {
5945  free(ds->opstr);
5946  ds->opstr = strdup(rz_asm_op_get_asm(&ds->asmop));
5947  ds->opstr = rz_parse_immtrim(ds->opstr);
5948  }
5949  }
5950  if (ds->asm_instr) {
5951  if (ds->show_color) {
5952  rz_cons_printf("%s\n", ds->opstr);
5953  } else {
5954  rz_cons_println(ds->opstr);
5955  }
5956  RZ_FREE(ds->opstr);
5957  }
5958  if (ds->hint) {
5960  ds->hint = NULL;
5961  }
5962  }
5963  if (buf == core->block && nb_opcodes > 0 && j < nb_opcodes) {
5964  rz_core_seek(core, core->offset + i, true);
5965  goto toro;
5966  }
5968  ds_free(ds);
5969  core->offset = old_offset;
5970  rz_reg_arena_pop(core->analysis->reg);
5971 
5972  return len;
5973 }
5974 
5985  RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes) {
5986  rz_return_val_if_fail(core && pn_opcodes && pn_bytes, false);
5987 
5988  if (*pn_opcodes > ST16_MAX || *pn_opcodes < ST16_MIN) {
5989  RZ_LOG_ERROR("the number of instructions is too big (%d < n_instrs < %d).\n", ST16_MAX, ST16_MIN);
5990  return false;
5991  }
5992  if (!*pn_opcodes && !*pn_bytes) {
5993  core->blocksize = 0;
5994  return true;
5995  }
5996  const ut64 old_offset = core->offset;
5997  const ut32 old_blocksize = core->blocksize;
5998  ut64 offset = old_offset;
5999  const int x_bytes = *pn_bytes
6000  ? RZ_MIN(RZ_ABS(*pn_bytes), RZ_CORE_MAX_DISASM)
6001  : (int)core->blocksize;
6002 
6003  if (*pn_opcodes < 0) {
6004  *pn_opcodes = -*pn_opcodes;
6005  *pn_bytes = x_bytes;
6006  if (!rz_core_prevop_addr(core, old_offset, *pn_opcodes, &offset)) {
6007  offset = rz_core_prevop_addr_force(core, old_offset, *pn_opcodes);
6008  }
6009  } else {
6010  if (*pn_bytes < 0) {
6011  offset = old_offset - x_bytes;
6012  }
6013  *pn_bytes = x_bytes;
6014  }
6015 
6016  if (*pn_bytes > old_blocksize) {
6017  rz_core_block_size(core, *pn_bytes);
6018  }
6019  if (offset != old_offset) {
6020  rz_core_seek(core, offset, true);
6021  } else {
6022  rz_core_block_read(core);
6023  }
6024  return true;
6025 }
6026 
6027 /* Disassemble either `nb_opcodes` instructions, or
6028  * `nb_bytes` bytes; both can be negative.
6029  * Set to 0 the parameter you don't use */
6030 RZ_API int rz_core_print_disasm_instructions(RzCore *core, int nb_bytes, int nb_opcodes) {
6031  const ut64 ocore_offset = core->offset;
6032  int ret = -1;
6033  if (rz_core_handle_backwards_disasm(core, &nb_opcodes, &nb_bytes)) {
6034  ret = rz_core_print_disasm_instructions_with_buf(core, core->offset, NULL, nb_bytes, nb_opcodes);
6035  }
6036  rz_core_seek(core, ocore_offset, true);
6037  return ret;
6038 }
6039 
6040 RZ_API int rz_core_print_disasm_json(RzCore *core, ut64 addr, ut8 *buf, int nb_bytes, int nb_opcodes, PJ *pj) {
6041  ut64 old_offset = core->offset;
6042  ut64 old_blocksize = core->blocksize;
6043  bool res = true;
6044  core->offset = addr;
6045  RzPVector *vec = NULL;
6046  if (!rz_core_handle_backwards_disasm(core, &nb_opcodes, &nb_bytes)) {
6047  res = false;
6048  goto clean_return;
6049  }
6050  vec = rz_core_analysis_bytes(core, buf, nb_bytes, nb_opcodes);
6051  if (!vec) {
6052  res = false;
6053  goto clean_return;
6054  }
6055 
6056  bool asm_pseudo = rz_config_get_i(core->config, "asm.pseudo");
6057 
6058  RzAnalysisBytes *ab;
6059  void **p;
6060  rz_pvector_foreach (vec, p) {
6061  if (!p || !*p) {
6062  continue;
6063  }
6064  ab = *p;
6065  RzAnalysisOp *op = ab->op;
6066  if (!op) {
6067  continue;
6068  }
6069  pj_o(pj);
6070  pj_kn(pj, "offset", op->addr);
6071  if (op->type == RZ_ANALYSIS_OP_TYPE_ILL) {
6072  pj_ki(pj, "size", 1);
6073  pj_ks(pj, "bytes", ab->bytes);
6074  pj_ks(pj, "opcode", "invalid");
6075  pj_end(pj);
6076  continue;
6077  }
6078  if (op->ptr != UT64_MAX) {
6079  pj_kn(pj, "ptr", op->ptr);
6080  }
6081  if (op->val != UT64_MAX) {
6082  pj_kn(pj, "val", op->val);
6083  }
6084 
6085  RzAnalysisHint *hint = ab->hint;
6086  pj_k(pj, "esil"); // split key and value to allow empty strings
6087  const char *esil = RZ_STRBUF_SAFEGET(&op->esil);
6088  pj_s(pj, hint && hint->esil ? hint->esil : (esil ? esil : ""));
6089 
6090  pj_kb(pj, "refptr", op->refptr);
6091 
6093  pj_kn(pj, "fcn_addr", f ? f->addr : 0);
6094  pj_kn(pj, "fcn_last", f ? rz_analysis_function_max_addr(f) - ab->oplen : 0);
6095  pj_ki(pj, "size", op->size);
6096  pj_ks(pj, "opcode", asm_pseudo ? ab->pseudo : ab->opcode);
6097  pj_ks(pj, "disasm", ab->disasm);
6098  pj_k(pj, "bytes");
6099  pj_s(pj, ab->bytes);
6100  pj_ks(pj, "family", rz_analysis_op_family_to_string(op->family));
6101  pj_ks(pj, "type", rz_analysis_optype_to_string(op->type));
6102  // indicate a relocated address
6103  RzBinReloc *rel = rz_core_getreloc(core, op->addr, op->size);
6104  // reloc is true if address in reloc table
6105  pj_kb(pj, "reloc", rel);
6106  // wanted the numerical values of the type information
6107  pj_kn(pj, "type_num", (ut64)(op->type & UT64_MAX));
6108  pj_kn(pj, "type2_num", (ut64)(op->type2 & UT64_MAX));
6109  // handle switch statements
6110  if (op->switch_op && rz_list_length(op->switch_op->cases) > 0) {
6111  // XXX - the java caseop will still be reported in the assembly,
6112  // this is an artifact to make ensure the disassembly is properly
6113  // represented during the analysis
6114  RzListIter *iter2;
6115  RzAnalysisCaseOp *caseop;
6116  pj_k(pj, "switch");
6117  pj_a(pj);
6118  rz_list_foreach (op->switch_op->cases, iter2, caseop) {
6119  pj_o(pj);
6120  pj_kn(pj, "addr", caseop->addr);
6121  pj_kN(pj, "value", (st64)caseop->value);
6122  pj_kn(pj, "jump", caseop->jump);
6123  pj_end(pj);
6124  }
6125  pj_end(pj);
6126  }
6127  if (op->jump != UT64_MAX) {
6128  pj_kN(pj, "jump", op->jump);
6129  if (op->fail != UT64_MAX) {
6130  pj_kn(pj, "fail", op->fail);
6131  }
6132  }
6133  /* add flags */
6134  {
6135  const RzList *flags = rz_flag_get_list(core->flags, op->addr);
6136  RzFlagItem *flag;
6137  RzListIter *iter2;
6138  if (flags && !rz_list_empty(flags)) {
6139  pj_k(pj, "flags");
6140  pj_a(pj);
6141  rz_list_foreach (flags, iter2, flag) {
6142  pj_s(pj, flag->name);
6143  }
6144  pj_end(pj);
6145  }
6146  }
6147  /* add comments */
6148  {
6149  // TODO: slow because we are encoding b64
6150  const char *comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, op->addr);
6151  if (comment) {
6152  char *b64comment = sdb_encode((const ut8 *)comment, -1);
6153  pj_ks(pj, "comment", b64comment);
6154  free(b64comment);
6155  }
6156  }
6157  /* add xrefs from */
6158  {
6159  RzAnalysisXRef *xref;
6160  RzListIter *iter2;
6161  RzList *xrefs = rz_analysis_xrefs_get_from(core->analysis, op->addr);
6162  if (xrefs && !rz_list_empty(xrefs)) {
6163  pj_k(pj, "xrefs_from");
6164  pj_a(pj);
6165  rz_list_foreach (xrefs, iter2, xref) {
6166  pj_o(pj);
6167  pj_kn(pj, "addr", xref->to);
6168  pj_ks(pj, "type", rz_analysis_xrefs_type_tostring(xref->type));
6169  pj_end(pj);
6170  }
6171  pj_end(pj);
6172  }
6173  rz_list_free(xrefs);
6174  }
6175  /* add xrefs to */
6176  {
6177  RzAnalysisXRef *xref;
6178  RzListIter *iter2;
6179  RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, op->addr);
6180  if (xrefs && !rz_list_empty(xrefs)) {
6181  pj_k(pj, "xrefs_to");
6182  pj_a(pj);
6183  rz_list_foreach (xrefs, iter2, xref) {
6184  pj_o(pj);
6185  pj_kn(pj, "addr", xref->from);
6186  pj_ks(pj, "type", rz_analysis_xrefs_type_tostring(xref->type));
6187  pj_end(pj);
6188  }
6189  pj_end(pj);
6190  }
6191  rz_list_free(xrefs);
6192  }
6193 
6194  pj_end(pj);
6195  }
6196 clean_return:
6197  rz_pvector_free(vec);
6198  rz_core_block_size(core, old_blocksize);
6199  if (core->offset != old_offset) {
6200  rz_core_seek(core, old_offset, true);
6201  }
6202  return res;
6203 }
6204 
6205 RZ_API int rz_core_print_disasm_all(RzCore *core, ut64 addr, int l, int len, int mode) {
6206  const bool scr_color = rz_config_get_i(core->config, "scr.color");
6207  int i, ret, count = 0;
6208  ut8 *buf = core->block;
6209  char str[128];
6210  RzAsmOp asmop;
6211  if (l < 1) {
6212  l = len;
6213  }
6214  RzDisasmState *ds = ds_init(core);
6215  if (l > core->blocksize || addr != core->offset) {
6216  buf = malloc(l + 1);
6217  rz_io_read_at(core->io, addr, buf, l);
6218  }
6219  PJ *pj = NULL;
6220  if (mode == 'j') {
6221  pj = pj_new();
6222  if (!pj) {
6223  return 0;
6224  }
6225  pj_a(pj);
6226  }
6228  for (i = 0; i < l; i++) {
6229  ds->at = addr + i;
6230  ds->vat = rz_core_pava(core, ds->at);
6231  rz_asm_set_pc(core->rasm, ds->vat);
6232  if (rz_cons_is_breaked()) {
6233  break;
6234  }
6235  ret = rz_asm_disassemble(core->rasm, &asmop, buf + i, l - i);
6236  if (ret < 1) {
6237  switch (mode) {
6238  case 'j':
6239  case '=':
6240  break;
6241  case 'i':
6242  rz_cons_printf("???\n");
6243  break;
6244  default:
6245  rz_cons_printf("0x%08" PFMT64x " ???\n", ds->vat);
6246  break;
6247  }
6248  } else {
6249  count++;
6250  switch (mode) {
6251  case 'i':
6252  rz_parse_filter(core->parser, ds->vat, core->flags, ds->hint, rz_asm_op_get_asm(&asmop),
6253  str, sizeof(str), core->print->big_endian);
6254  if (scr_color) {
6255  RzAnalysisOp aop;
6256  rz_analysis_op(core->analysis, &aop, addr, buf + i, l - i, RZ_ANALYSIS_OP_MASK_ALL);
6257  RzStrBuf *colored_asm;
6258  RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, aop.type);
6259  colored_asm = rz_asm_colorize_asm_str(&asmop.buf_asm, core->print, param, asmop.asm_toks);
6260  free(param);
6261  if (colored_asm) {
6262  rz_cons_printf("%s\n", rz_strbuf_get(colored_asm));
6263  rz_strbuf_free(colored_asm);
6264  }
6265  } else {
6267  }
6268  break;
6269  case '=':
6270  if (i < 28) {
6271  char *str = rz_str_newf("0x%08" PFMT64x " %60s %s\n", ds->vat, "", rz_asm_op_get_asm(&asmop));
6272  char *sp = strchr(str, ' ');
6273  if (sp) {
6274  char *end = sp + 60 + 1;
6275  char *src = rz_asm_op_get_hex(&asmop);
6276  char *dst = sp + 1 + (i * 2);
6277  int len = strlen(src);
6278  if (dst < end) {
6279  if (dst + len >= end) {
6280  len = end - dst;
6281  dst[len] = '.';
6282  }
6283  memcpy(dst, src, len);
6284  }
6285  free(src);
6286  }
6288  free(str);
6289  }
6290  break;
6291  case 'j': {
6292  char *op_hex = rz_asm_op_get_hex(&asmop);
6293  pj_o(pj);
6294  pj_kn(pj, "addr", addr + i);
6295  pj_ks(pj, "bytes", op_hex);
6296  pj_ks(pj, "inst", rz_asm_op_get_asm(&asmop));
6297  pj_end(pj);
6298  free(op_hex);
6299  break;
6300  }
6301  default: {
6302  char *op_hex = rz_asm_op_get_hex(&asmop);
6303  rz_cons_printf("0x%08" PFMT64x " %20s %s\n",
6304  addr + i, op_hex,
6305  rz_asm_op_get_asm(&asmop));
6306  free(op_hex);
6307  }
6308  }
6309  }
6310  }
6312  if (buf != core->block) {
6313  free(buf);
6314  }
6315  if (mode == 'j') {
6316  pj_end(pj);
6318  pj_free(pj);
6319  }
6320  ds_free(ds);
6321  return count;
6322 }
6323 
6324 RZ_API int rz_core_disasm_pdi_with_buf(RzCore *core, ut64 address, ut8 *buf, ut32 nb_opcodes, ut32 nb_bytes, int fmt) {
6325  bool show_offset = rz_config_get_b(core->config, "asm.offset");
6326  bool show_bytes = rz_config_get_b(core->config, "asm.bytes");
6327  bool decode = rz_config_get_b(core->config, "asm.decode");
6328  bool subnames = rz_config_get_b(core->config, "asm.sub.names");
6329  int show_color = rz_config_get_i(core->config, "scr.color");
6330  bool asm_ucase = rz_config_get_b(core->config, "asm.ucase");
6331  bool asm_instr = rz_config_get_b(core->config, "asm.instr");
6332  bool esil = rz_config_get_b(core->config, "asm.esil");
6333  bool flags = rz_config_get_b(core->config, "asm.flags");
6334  bool asm_immtrim = rz_config_get_b(core->config, "asm.imm.trim");
6335  int i = 0, j, ret, err = 0;
6336  ut64 old_offset = core->offset;
6337  RzAsmOp asmop;
6338  const size_t addrbytes = buf ? 1 : core->io->addrbytes;
6339 
6340  if (fmt == 'e') {
6341  show_bytes = false;
6342  decode = 1;
6343  }
6344 
6345  if (nb_opcodes < 1 && nb_bytes < 1) {
6346  return 0;
6347  }
6348 
6349  if (!buf) {
6350  rz_core_seek(core, address, true);
6351  buf = core->block;
6352  }
6353 
6355  rz_core_seek(core, address, false);
6356  int midflags = rz_config_get_i(core->config, "asm.flags.middle");
6357  bool midbb = rz_config_get_b(core->config, "asm.bb.middle");
6358  bool asmmarks = rz_config_get_b(core->config, "asm.marks");
6359  rz_config_set_i(core->config, "asm.marks", false);
6360  i = 0;
6361  j = 0;
6362  RzAnalysisMetaItem *meta = NULL;
6363 toro:
6364  for (; rz_disasm_check_end(nb_opcodes, j, nb_bytes, addrbytes * i); j++) {
6365  if (rz_cons_is_breaked()) {
6366  err = 1;
6367  break;
6368  }
6369  ut64 at = core->offset + i;
6370  if (flags) {
6371  if (fmt != 'e') { // pie
6372  RzFlagItem *item = rz_flag_get_i(core->flags, at);
6373  if (item) {
6374  if (show_offset) {
6375  const int show_offseg = (core->print->flags & RZ_PRINT_FLAGS_SEGOFF) != 0;
6376  const int show_offdec = (core->print->flags & RZ_PRINT_FLAGS_ADDRDEC) != 0;
6377  unsigned int seggrn = rz_config_get_i(core->config, "asm.seggrn");
6378  rz_print_offset_sg(core->print, at, 0, show_offseg, seggrn, show_offdec, 0, NULL);
6379  }
6380  rz_cons_printf(" %s:\n", item->name);
6381  }
6382  } // do not show flags in pie
6383  }
6384  if (show_offset) {
6385  const int show_offseg = (core->print->flags & RZ_PRINT_FLAGS_SEGOFF) != 0;
6386  const int show_offdec = (core->print->flags & RZ_PRINT_FLAGS_ADDRDEC) != 0;
6387  unsigned int seggrn = rz_config_get_i(core->config, "asm.seggrn");
6388  rz_print_offset_sg(core->print, at, 0, show_offseg, seggrn, show_offdec, 0, NULL);
6389  }
6390  ut64 meta_start = at;
6391  ut64 meta_size;
6392  meta = rz_meta_get_at(core->analysis, meta_start, RZ_META_TYPE_ANY, &meta_size);
6393  if (meta) {
6394  switch (meta->type) {
6395  case RZ_META_TYPE_DATA:
6396  // rz_cons_printf (".data: %s\n", meta->str);
6397  i += meta_size;
6398  {
6399  int idx = i;
6400  ut64 at = core->offset + i;
6401  int hexlen = nb_bytes - idx;
6402  int delta = at - meta_start;
6403  if (meta_size < hexlen) {
6404  hexlen = meta_size;
6405  }
6406  // int oplen = meta->size - delta;
6407  core->print->flags &= ~RZ_PRINT_FLAGS_HEADER;
6408  // TODO do not pass a copy in parameter buf that is possibly to small for this
6409  // print operation
6410  int size = RZ_MIN(meta_size, nb_bytes - idx);
6411  RzDisasmState ds = { 0 };
6412  ds.core = core;
6413  if (!ds_print_data_type(&ds, buf + i, 0, size)) {
6414  rz_cons_printf("hex length=%d delta=%d\n", size, delta);
6415  rz_core_print_hexdump(core, at, buf + idx, hexlen - delta, 16, 1, 1);
6416  } else {
6417  rz_cons_newline();
6418  }
6419  }
6420  continue;
6421  case RZ_META_TYPE_STRING:
6422  // rz_cons_printf (".string: %s\n", meta->str);
6423  i += meta_size;
6424  continue;
6425  case RZ_META_TYPE_FORMAT:
6426  // rz_cons_printf (".format : %s\n", meta->str);
6427  i += meta_size;
6428  continue;
6429  case RZ_META_TYPE_MAGIC:
6430  // rz_cons_printf (".magic : %s\n", meta->str);
6431  i += meta_size;
6432  continue;
6433  default:
6434  break;
6435  }
6436  }
6437  rz_asm_set_pc(core->rasm, core->offset + i);
6438  ret = rz_asm_disassemble(core->rasm, &asmop, buf + addrbytes * i,
6439  nb_bytes - addrbytes * i);
6440  if (midflags || midbb) {
6441  RzDisasmState ds = {
6442  .oplen = ret,
6443  .at = core->offset + i,
6444  .midflags = midflags
6445  };
6446  int skip_bytes_flag = 0, skip_bytes_bb = 0;
6447  skip_bytes_flag = handleMidFlags(core, &ds, true);
6448  if (midbb) {
6449  skip_bytes_bb = handleMidBB(core, &ds);
6450  }
6451  if (skip_bytes_flag && midflags > RZ_MIDFLAGS_SHOW) {
6452  asmop.size = ret = skip_bytes_flag;
6453  }
6454  if (skip_bytes_bb && skip_bytes_bb < ret) {
6455  asmop.size = ret = skip_bytes_bb;
6456  }
6457  }
6458  if (fmt == 'C') {
6459  const char *comment = rz_meta_get_string(core->analysis, RZ_META_TYPE_COMMENT, core->offset + i);
6460  if (comment) {
6461  rz_cons_printf("0x%08" PFMT64x " %s\n", core->offset + i, comment);
6462  }
6463  i += ret;
6464  continue;
6465  }
6466  // rz_cons_printf ("0x%08"PFMT64x" ", core->offset+i);
6467  if (ret < 1) {
6468  err = 1;
6469  ret = asmop.size;
6470  if (ret < 1) {
6471  ret = 1;
6472  }
6473  if (show_bytes) {
6474  rz_cons_printf("%18s%02x ", "", buf[i]);
6475  }
6476  rz_cons_println("invalid"); // ???");
6477  } else {
6478  if (show_bytes) {
6479  char *op_hex = rz_asm_op_get_hex(&asmop);
6480  rz_cons_printf("%20s ", op_hex);
6481  free(op_hex);
6482  }
6483  ret = asmop.size;
6484  if (!asm_instr) {
6485  rz_cons_newline();
6486  } else if (!asm_immtrim && (decode || esil)) {
6488  0
6489  };
6490  char *tmpopstr, *opstr = NULL;
6491  rz_analysis_op(core->analysis, &analysis_op, core->offset + i,
6492  buf + addrbytes * i, nb_bytes - addrbytes * i, RZ_ANALYSIS_OP_MASK_ALL);
6493  tmpopstr = rz_analysis_op_to_string(core->analysis, &analysis_op);
6494  if (fmt == 'e') { // pie
6495  char *esil = (RZ_STRBUF_SAFEGET(&analysis_op.esil));
6496  rz_cons_println(esil);
6497  } else {
6498  if (decode) {
6499  opstr = tmpopstr ? tmpopstr : rz_asm_op_get_asm(&(asmop));
6500  } else if (esil) {
6501  opstr = (RZ_STRBUF_SAFEGET(&analysis_op.esil));
6502  }
6503  if (asm_immtrim) {
6505  }
6507  }
6509  } else {
6510  char opstr[128] = {
6511  0
6512  };
6513  char *asm_str = rz_asm_op_get_asm(&asmop);
6514  if (asm_ucase) {
6515  rz_str_case(asm_str, 1);
6516  }
6517  if (asm_immtrim) {
6518  rz_parse_immtrim(asm_str);
6519  }
6520  if (subnames) {
6521  RzAnalysisHint *hint = rz_analysis_hint_get(core->analysis, at);
6522  rz_parse_filter(core->parser, at, core->flags, hint,
6523  asm_str, opstr, sizeof(opstr) - 1, core->print->big_endian);
6524  rz_analysis_hint_free(hint);
6525  asm_str = (char *)&opstr;
6526  }
6527  if (show_color) {
6528  RzAnalysisOp aop = {
6529  0
6530  };
6531  rz_analysis_op(core->analysis, &aop, core->offset + i,
6532  buf + addrbytes * i, nb_bytes - addrbytes * i, RZ_ANALYSIS_OP_MASK_BASIC);
6533  RzStrBuf *colored_asm, *bw_str = rz_strbuf_new(asm_str);
6534  RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, aop.type);
6535  colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, param, asmop.asm_toks);
6536  free(param);
6537  rz_cons_printf("%s" Color_RESET "\n", rz_strbuf_get(colored_asm));
6538  rz_strbuf_free(colored_asm);
6539  rz_analysis_op_fini(&aop);
6540  } else {
6541  rz_cons_println(asm_str);
6542  }
6543  }
6544  }
6545  i += ret;
6546  }
6547  if (buf == core->block && nb_opcodes > 0 && j < nb_opcodes) {
6548  rz_core_seek(core, core->offset + i, true);
6549  i = 0;
6550  goto toro;
6551  }
6552  rz_config_set_i(core->config, "asm.marks", asmmarks);
6554  rz_core_seek(core, old_offset, true);
6555  return err;
6556 }
6557 
6558 RZ_API int rz_core_disasm_pdi(RzCore *core, int nb_opcodes, int nb_bytes, int fmt) {
6559  const ut64 ocore_offset = core->offset;
6560  int ret = -1;
6561  if (rz_core_handle_backwards_disasm(core, &nb_opcodes, &nb_bytes)) {
6562  ret = rz_core_disasm_pdi_with_buf(core, core->offset, NULL, nb_opcodes, nb_bytes, fmt);
6563  }
6564  rz_core_seek(core, ocore_offset, true);
6565  return ret;
6566 }
6567 
6568 static bool read_ahead(RzIO *io, ut8 **buf, size_t *buf_sz, ut64 address, size_t offset_into_buf, size_t bytes_to_read) {
6569  if (offset_into_buf + bytes_to_read > *buf_sz) {
6570  const size_t new_sz = *buf_sz * 2;
6571  ut8 *tmp = realloc(*buf, new_sz);
6572  if (!tmp) {
6573  return false;
6574  }
6575  *buf_sz = new_sz;
6576  *buf = tmp;
6577  }
6578  return rz_io_read_at_mapped(io, address, *buf + offset_into_buf, bytes_to_read);
6579 }
6580 
6582  if (nb_opcodes < 1) {
6583  return 0;
6584  }
6585  RzReg *reg = core->analysis->reg;
6587  if (!pc) {
6588  return -1;
6589  }
6591  if (!core->analysis->esil) {
6593  if (!rz_config_get_b(core->config, "cfg.debug")) {
6595  }
6596  }
6597  RzAnalysisEsil *esil = core->analysis->esil;
6598  RzPVector ocache = core->io->cache;
6599  const int ocached = core->io->cached;
6600  if (ocache.v.a) {
6601  RzPVector *vec = (RzPVector *)rz_vector_clone((RzVector *)&ocache);
6602  vec->v.free = NULL;
6603  core->io->cache = *vec;
6604  free(vec);
6605  } else {
6606  rz_io_cache_init(core->io);
6607  }
6609  RzConfigHold *chold = rz_config_hold_new(core->config);
6610  rz_config_hold_i(chold, "io.cache", "asm.lines", NULL);
6611  rz_config_set_i(core->config, "io.cache", true);
6612  rz_config_set_i(core->config, "asm.lines", false);
6613  const char *strip = rz_config_get(core->config, "asm.strip");
6614  const int max_op_size = rz_analysis_archinfo(core->analysis, RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE);
6616  min_op_size = min_op_size > 0 ? min_op_size : 1;
6617  const ut64 read_len = max_op_size > 0 ? max_op_size : 32;
6618  size_t buf_sz = 0x100, block_sz = 0, block_instr = 0;
6619  ut64 block_start = rz_reg_get_value(reg, pc);
6620  ut8 *buf = malloc(buf_sz);
6621  size_t i;
6622  for (i = 0; i < nb_opcodes; i++) {
6623  const ut64 op_addr = rz_reg_get_value(reg, pc);
6624  if (!read_ahead(core->io, &buf, &buf_sz, op_addr, block_sz, read_len)) {
6625  break;
6626  }
6627  RzAnalysisOp op;
6628  int ret = rz_analysis_op(core->analysis, &op, op_addr, buf + block_sz, read_len, RZ_ANALYSIS_OP_MASK_ESIL);
6629  const bool invalid_instr = ret < 1 || op.size < 1 || op.type == RZ_ANALYSIS_OP_TYPE_ILL;
6630  bool end_of_block = false;
6637  end_of_block = true;
6638  break;
6639  }
6640  if (RZ_STR_ISNOTEMPTY(strip) && strstr(strip, rz_analysis_optype_to_string(op.type))) {
6641  i--;
6642  } else {
6643  if (invalid_instr) {
6644  block_sz += min_op_size;
6645  } else {
6646  block_sz += op.size;
6647  }
6648  if (invalid_instr || (i + 1 >= nb_opcodes)) {
6649  end_of_block = true;
6650  }
6651  block_instr++;
6652  }
6653  if (end_of_block) {
6654  if (op.delay) {
6655  const ut64 ops_to_read = RZ_MIN(op.delay, nb_opcodes - (i + 1));
6656  const ut64 bytes_to_read = ops_to_read * read_len;
6657  if (!read_ahead(core->io, &buf, &buf_sz, op_addr + op.size, block_sz, bytes_to_read)) {
6658  break;
6659  }
6660  block_instr += ops_to_read;
6661  block_sz += bytes_to_read;
6662  i += ops_to_read;
6663  }
6664  if (block_instr) {
6665  switch (state->mode) {
6666  case RZ_OUTPUT_MODE_JSON:
6667  rz_core_print_disasm_json(core, block_start, buf, block_sz, block_instr, state->d.pj);
6668  break;
6669  case RZ_OUTPUT_MODE_QUIET:
6670  rz_core_disasm_pdi_with_buf(core, block_start, buf, block_instr, block_sz, 0);
6671  break;
6673  rz_core_print_disasm_instructions_with_buf(core, block_start, buf, block_sz, block_instr);
6674  break;
6675  default:
6676  rz_core_print_disasm(core, block_start, buf, block_sz, block_instr, state, NULL);
6677  break;
6678  }
6679  }
6680  block_sz = 0;
6681  block_instr = 0;
6682  }
6683  if (invalid_instr) {
6684  break;
6685  }
6686  rz_analysis_esil_set_pc(core->analysis->esil, op_addr);
6687  rz_reg_set_value(reg, pc, op_addr + op.size);
6688  const char *e = rz_strbuf_get(&op.esil);
6689  if (RZ_STR_ISNOTEMPTY(e)) {
6690  rz_analysis_esil_parse(esil, e);
6691  }
6693 
6694  if (end_of_block) {
6695  block_start = rz_reg_get_value(reg, pc);
6696  rz_core_seek_arch_bits(core, block_start);
6697  }
6698  }
6699 
6701  free(buf);
6703  int len = rz_pvector_len(&ocache);
6704  if (rz_pvector_len(&core->io->cache) > len) {
6705  // TODO: Implement push/pop for IO.cache
6706  while (len > 0) {
6707  (void)rz_pvector_pop_front(&core->io->cache);
6708  len--;
6709  }
6710  core->io->cache.v.free = ocache.v.free;
6711  }
6712  rz_io_cache_fini(core->io);
6713  core->io->cache = ocache;
6715  void **it;
6716  rz_pvector_foreach (&ocache, it) {
6717  RzIOCache *c = (RzIOCache *)*it;
6718  rz_skyline_add(&core->io->cache_skyline, c->itv, c);
6719  }
6720  core->io->cached = ocached;
6721  rz_config_hold_restore(chold);
6722  rz_config_hold_free(chold);
6723  return i;
6724 }
6725 
6727  RzAnalysisBlock *b;
6728  RzListIter *locs_it = NULL;
6729  ut32 fcn_size = rz_analysis_function_realsize(fcn);
6730  const char *orig_bb_middle = rz_config_get(core->config, "asm.bb.middle");
6731  rz_config_set_i(core->config, "asm.bb.middle", false);
6732  pj_o(pj);
6733  pj_ks(pj, "name", fcn->name);
6734  pj_kn(pj, "size", fcn_size);
6735  pj_kn(pj, "addr", fcn->addr);
6736  pj_k(pj, "ops");
6737  pj_a(pj);
6738  rz_list_sort(fcn->bbs, bb_cmpaddr);
6739  rz_list_foreach (fcn->bbs, locs_it, b) {
6740 
6741  ut8 *buf = malloc(b->size);
6742  if (buf) {
6743  rz_io_read_at(core->io, b->addr, buf, b->size);
6744  rz_core_print_disasm_json(core, b->addr, buf, b->size, 0, pj);
6745  free(buf);
6746  } else {
6747  eprintf("cannot allocate %" PFMT64u " byte(s)\n", b->size);
6748  return false;
6749  }
6750  }
6751  pj_end(pj);
6752  pj_end(pj);
6753  rz_config_set(core->config, "asm.bb.middle", orig_bb_middle);
6754  return true;
6755 }
6756 
6771  rz_return_val_if_fail(core, NULL);
6772  int has_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
6773  char str[512];
6774  const int size = 12;
6775  ut8 buf[12];
6776  RzAsmOp asmop = { 0 };
6777  char *buf_asm = NULL;
6778  bool asm_subvar = rz_config_get_i(core->config, "asm.sub.var");
6779  core->parser->pseudo = rz_config_get_i(core->config, "asm.pseudo");
6780  core->parser->subrel = rz_config_get_i(core->config, "asm.sub.rel");
6781  core->parser->localvar_only = rz_config_get_i(core->config, "asm.sub.varonly");
6782 
6783  if (core->parser->subrel) {
6784  core->parser->subrel_addr = reladdr;
6785  }
6786  rz_io_read_at(core->io, addr, buf, size);
6787  rz_asm_set_pc(core->rasm, addr);
6788  rz_asm_disassemble(core->rasm, &asmop, buf, size);
6789  int ba_len = rz_strbuf_length(&asmop.buf_asm) + 128;
6790  char *ba = malloc(ba_len);
6791  strcpy(ba, rz_strbuf_get(&asmop.buf_asm));
6792  RzAnalysisOp op;
6794  if (asm_subvar) {
6797  rz_parse_subvar(core->parser, fcn, &op,
6798  ba, ba, sizeof(asmop.buf_asm));
6800  }
6802  rz_parse_filter(core->parser, addr, core->flags, hint,
6803  ba, str, sizeof(str), core->print->big_endian);
6804  rz_analysis_hint_free(hint);
6805  rz_asm_op_set_asm(&asmop, ba);
6806  free(ba);
6807  if (color && has_color) {
6808  RzStrBuf *colored_asm, *bw_str = rz_strbuf_new(str);
6809  RzAsmParseParam *param = rz_asm_get_parse_param(core->analysis->reg, op.type);
6810  colored_asm = rz_asm_colorize_asm_str(bw_str, core->print, param, asmop.asm_toks);
6811  free(param);
6812  return rz_strbuf_drain(colored_asm);
6813  } else {
6814  buf_asm = rz_str_new(str);
6815  }
6816  return buf_asm;
6817 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
RZ_API RZ_OWN char * rz_analysis_function_name_guess(RzTypeDB *typedb, RZ_NONNULL char *name)
Checks if varions function name variations present in the database.
Definition: function.c:458
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API ut64 rz_analysis_function_max_addr(RzAnalysisFunction *fcn)
Definition: function.c:328
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
Definition: function.c:318
RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn)
Definition: function.c:338
RZ_API ut64 rz_analysis_function_min_addr(RzAnalysisFunction *fcn)
Definition: function.c:323
RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr)
Definition: function.c:361
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
#define e(frag)
#define jmp
#define cjmp
static int analysis_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
#define imm
static int bb_cmpaddr(const void *_a, const void *_b)
Definition: analysis_tp.c:530
#define RZ_IPI
Definition: analysis_wasm.c:11
RZ_API int rz_asm_op_get_size(RzAsmOp *op)
Definition: aop.c:47
RZ_API void rz_asm_op_fini(RzAsmOp *op)
Definition: aop.c:21
RZ_API int rz_asm_op_set_hexbuf(RzAsmOp *op, const ut8 *buf, int len)
Definition: aop.c:71
RZ_API char * rz_asm_op_get_hex(RzAsmOp *op)
Definition: aop.c:28
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
RZ_API char * rz_asm_op_get_asm(RzAsmOp *op)
Definition: aop.c:37
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
@ invalid_instr
Definition: arc-dis.h:52
RZ_API ut8 * rz_reg_arena_peek(RzReg *reg)
Definition: arena.c:280
RZ_API int rz_reg_arena_push(RzReg *reg)
Definition: arena.c:236
RZ_API void rz_reg_arena_pop(RzReg *reg)
Definition: arena.c:216
RZ_API void rz_reg_arena_poke(RzReg *reg, const ut8 *ret)
Definition: arena.c:293
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
static RzILOpEffect * mov(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:351
ut16 val
Definition: armass64_const.h:6
static bool err
Definition: armass.c:435
RZ_API RZ_OWN RzAsmParseParam * rz_asm_get_parse_param(RZ_NULLABLE const RzReg *reg, ut32 ana_op_type)
Does all kinds of NULL checks on the parameters and returns an initialized RzAsmParseParam or NULL on...
Definition: asm.c:1763
RZ_API char * rz_asm_describe(RzAsm *a, const char *str)
Definition: asm.c:1187
RZ_API bool rz_asm_set_syntax(RzAsm *a, int syntax)
Definition: asm.c:518
RZ_DEPRECATE RZ_API RZ_OWN RzStrBuf * rz_asm_colorize_asm_str(RZ_BORROW RzStrBuf *asm_str, RZ_BORROW RzPrint *p, RZ_NULLABLE const RzAsmParseParam *param, RZ_NULLABLE const RzAsmTokenString *toks)
Colors a given asm string and returns it. If toks is not NULL it uses the tokens to color the asm str...
Definition: asm.c:1741
RZ_API int rz_asm_set_pc(RzAsm *a, ut64 pc)
Definition: asm.c:533
RZ_API int rz_asm_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm.c:543
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
RZ_API char * sdb_encode(const ut8 *bin, int len)
Definition: base64.c:18
int call(int a, int b)
Definition: bcj_test.c:25
RZ_API RzBinPlugin * rz_bin_file_cur_plugin(RzBinFile *bf)
Definition: bfile.c:348
RZ_API bool rz_bin_string_filter(RzBin *bin, const char *str, int len, ut64 addr)
Definition: filter.c:385
RZ_API bool rz_bin_strpurge(RzBin *bin, const char *str, ut64 refaddr)
Definition: filter.c:208
RZ_API RzBinObject * rz_bin_cur_object(RzBin *bin)
Definition: bin.c:900
RZ_API RZ_BORROW RzBinSection * rz_bin_get_section_at(RzBinObject *o, ut64 off, int va)
Find the binary section at offset off.
Definition: bin.c:611
RZ_API RZ_OWN char * rz_bin_demangle(RZ_NULLABLE RzBinFile *bf, RZ_NULLABLE const char *language, RZ_NULLABLE const char *symbol, ut64 vaddr, bool libs)
Demangles a symbol based on the language or the RzBinFile data.
Definition: bin.c:1295
static SblHeader sb
Definition: bin_mbn.c:26
const char * desc
Definition: bin_vsf.c:19
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API RzList * rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr)
Definition: block.c:133
RZ_API RzAnalysisBlock * rz_analysis_find_most_relevant_block_in(RzAnalysis *analysis, ut64 off)
Definition: block.c:997
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint at exactly addr.
Definition: bp.c:102
RZ_API RZ_OWN RzPVector * rz_core_analysis_bytes(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, int nops)
Definition: canalysis.c:6817
RZ_IPI char * rz_core_analysis_var_display(RzCore *core, RzAnalysisVar *var, bool add_name)
Definition: canalysis.c:6148
RZ_API ut64 rz_core_analysis_address(RzCore *core, ut64 addr)
Definition: canalysis.c:168
RZ_API bool rz_core_analysis_function_add(RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
Definition: canalysis.c:5298
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
Definition: canalysis.c:1033
RZ_API RZ_OWN RzList * rz_core_get_func_args(RzCore *core, const char *fcn_name)
Definition: carg.c:276
RZ_DEPRECATE RZ_API ut64 rz_core_arg_get(RzCore *core, const char *cc, int num)
Get the value of the num-th argument from the current debug or emulation state.
Definition: carg.c:13
RZ_API char * resolve_fcn_name(RzAnalysis *analysis, const char *func_name)
Definition: carg.c:86
RZ_API const char * rz_analysis_syscc_default(RzAnalysis *analysis)
Definition: cc.c:210
RZ_API void rz_core_analysis_esil_init_mem(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Definition: cil.c:149
RZ_API void rz_core_analysis_esil_reinit(RZ_NONNULL RzCore *core)
Reinitialize ESIL.
Definition: cil.c:54
RZ_API void rz_core_seek_arch_bits(RzCore *core, ut64 addr)
Definition: cio.c:132
RZ_API int rz_core_block_read(RzCore *core)
Definition: cio.c:243
RZ_API char * rz_core_cmd_strf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5472
RZ_API int rz_core_cmdf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5413
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state)
Mark the start of an array of elements in the output.
Definition: cmd_api.c:2558
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state)
Mark the end of an array of elements in the output.
Definition: cmd_api.c:2572
RZ_API void rz_print_offset_sg(RzPrint *p, ut64 off, int invert, int offseg, int seggrn, int offdec, int delta, const char *label)
Definition: cmd_print.c:5685
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API int rz_cons_get_buffer_len(void)
Definition: cons.c:832
RZ_API void rz_cons_memset(char ch, int len)
Definition: cons.c:1253
RZ_API bool rz_cons_drop(int n)
Definition: cons.c:1891
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API RZ_OWN char * rz_cons_get_buffer_dup(void)
Return a newly allocated buffer containing what's currently in RzCons buffer.
Definition: cons.c:827
RZ_API void rz_cons_strcat(const char *str)
Definition: cons.c:1263
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API char * rz_cons_lastline(int *len)
Definition: cons.c:1813
RZ_API void rz_cons_strcat_justify(const char *str, int j, char c)
Definition: cons.c:238
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_chop(void)
Definition: cons.c:1900
RZ_API const char * rz_cons_get_buffer(void)
Return the current RzCons buffer.
Definition: cons.c:819
RZ_API void rz_cons_printf_list(const char *format, va_list ap)
Definition: cons.c:1170
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API void rz_cons_reset(void)
Definition: cons.c:804
RZ_API void rz_cons_pop(void)
Definition: cons.c:876
RZ_API void rz_cons_push(void)
Definition: cons.c:860
#define RZ_API
RZ_IPI void rz_core_print_hexdump(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz)
Definition: cprint.c:161
RZ_API RzReg * rz_core_reg_default(RzCore *core)
Get the currently relevant RzReg.
Definition: creg.c:17
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
int mod(int a, int b)
Definition: crypto_rot.c:8
cs_arch arch
Definition: cstool.c:13
RZ_API RZ_OWN char * rz_core_syscall_as_string(RzCore *core, st64 n, ut64 addr)
Returns the syscall representation as a string.
Definition: csyscall.c:26
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 static offset struct stat static buf void nbytes
Definition: sflib.h:113
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 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 static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
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 static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
RZ_API const char * rz_analysis_data_kind(RzAnalysis *a, ut64 addr, const ut8 *buf, int len)
Definition: data.c:346
RZ_DEPRECATE RZ_API char * rz_bin_addr2text(RzBin *bin, ut64 addr, int origin)
Definition: dbginfo.c:217
#define true
#define false
uint32_t ut32
static void ds_print_cmt_esil(RzDisasmState *ds)
Definition: disasm.c:4319
static void ds_begin_comment(RzDisasmState *ds)
Definition: disasm.c:1325
RZ_IPI void rz_core_asm_bb_middle(RZ_NONNULL RzCore *core, ut64 at, RZ_INOUT RZ_NONNULL int *oplen, RZ_NONNULL int *ret)
Update oplen by "asm.bb.middle" and "asm.flags.middle".
Definition: disasm.c:1684
static void __replaceImports(RzDisasmState *ds)
Definition: disasm.c:960
static bool ds_print_data_type(RzDisasmState *ds, const ut8 *buf, int ib, int size)
Definition: disasm.c:3051
static void ds_print_demangled(RzDisasmState *ds)
Definition: disasm.c:4340
static void ds_print_relocs(RzDisasmState *ds)
Definition: disasm.c:4359
static void ds_show_functions(RzDisasmState *ds)
Definition: disasm.c:1904
static char * _find_next_number(char *op)
Definition: disasm.c:5153
static char * ds_sub_jumps(RzDisasmState *ds, char *str)
Definition: disasm.c:5217
static void ds_pre_line(RzDisasmState *ds)
Definition: disasm.c:1225
static void ds_print_color_reset(RzDisasmState *ds)
Definition: disasm.c:3467
#define DS_PRE_NONE
Definition: disasm.c:78
static void ds_print_ref_lines(char *line, char *line_col, RzDisasmState *ds)
Definition: disasm.c:397
static bool ds_print_core_vmode_jump_hit(RzDisasmState *ds, int pos)
Definition: disasm.c:3636
static void ds_comment(RzDisasmState *ds, bool align, const char *format,...)
Definition: disasm.c:522
static void ds_print_optype(RzDisasmState *ds)
Definition: disasm.c:3450
static int handleMidBB(RzCore *core, RzDisasmState *ds)
Definition: disasm.c:1657
static void ds_reflines_init(RzDisasmState *ds)
Definition: disasm.c:896
static int myregread(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size)
Definition: disasm.c:4442
static void ds_print_show_cursor(RzDisasmState *ds)
Definition: disasm.c:1722
static st64 get_ptr_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: disasm.c:977
static const char * get_utf8_char(const char line, RzDisasmState *ds)
Definition: disasm.c:381
#define P(x)
static st64 revert_cdiv_magic(st64 magic)
Definition: disasm.c:3290
RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address, ut8 *buf, int nb_bytes, int nb_opcodes)
Definition: disasm.c:5814
static void ds_print_dwarf(RzDisasmState *ds)
Definition: disasm.c:3826
static bool ds_must_strip(RzDisasmState *ds)
Definition: disasm.c:943
static const char * rz_vline_uc[]
Definition: disasm.c:61
RZ_API int rz_core_flag_in_middle(RzCore *core, ut64 at, int oplen, int *midflags)
Definition: disasm.c:1702
RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes)
Converting negative numbers n_opcodes and n_opcodes to positive numbers n_opcodes and n_opcodes and s...
Definition: disasm.c:5984
static void ds_print_family(RzDisasmState *ds)
Definition: disasm.c:2860
static ut64 lastaddr
Definition: disasm.c:885
#define DS_PRE_EMPTY
Definition: disasm.c:79
static void ds_print_lines_left(RzDisasmState *ds)
Definition: disasm.c:2803
static void ds_show_xrefs(RzDisasmState *ds)
Definition: disasm.c:1381
static RzDisasmState * ds_init(RzCore *core)
Definition: disasm.c:583
static int myregwrite(RzAnalysisEsil *esil, const char *name, ut64 *val)
Definition: disasm.c:4454
static void delete_last_comment(RzDisasmState *ds)
Definition: disasm.c:4742
static void ds_print_offset(RzDisasmState *ds)
Definition: disasm.c:2886
static void ds_show_functions_argvar(RzDisasmState *ds, RzAnalysisFunction *fcn, RzAnalysisVar *var, const char *base, bool is_var, char sign)
Definition: disasm.c:1774
static void ds_print_pre(RzDisasmState *ds, bool fcnline)
Definition: disasm.c:2159
RZ_API int rz_core_print_disasm_json(RzCore *core, ut64 addr, ut8 *buf, int nb_bytes, int nb_opcodes, PJ *pj)
Definition: disasm.c:6040
static bool empty_signature(const char *s)
Definition: disasm.c:1900
static void ds_show_flags(RzDisasmState *ds, bool overlapped)
Definition: disasm.c:2328
static void ssa_set(RzAnalysisEsil *esil, const char *reg)
Definition: disasm.c:4436
#define printPre
Definition: disasm.c:2327
static const char * get_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: disasm.c:981
#define COLOR_RESET(ds)
Definition: disasm.c:22
static void ds_comment_esil(RzDisasmState *ds, bool up, bool end, const char *format,...)
Definition: disasm.c:542
static void mipsTweak(RzDisasmState *ds)
Definition: disasm.c:4775
static bool set_jump_realname(RzDisasmState *ds, ut64 addr, const char **kw, const char **name)
Definition: disasm.c:5185
static int mymemwrite1(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: disasm.c:4416
RZ_API int rz_core_disasm_pdi_with_buf(RzCore *core, ut64 address, ut8 *buf, ut32 nb_opcodes, ut32 nb_bytes, int fmt)
Definition: disasm.c:6324
static void ds_comment_(RzDisasmState *ds, bool align, bool nl, const char *format, va_list ap)
Definition: disasm.c:507
#define COLOR_ARG(ds, field)
Definition: disasm.c:20
static void ds_setup_pre(RzDisasmState *ds, bool tail, bool middle)
Definition: disasm.c:2128
static bool can_emulate_metadata(RzCore *core, ut64 at)
Definition: disasm.c:4758
static ut64 emustack_max
Definition: disasm.c:29
static int ds_print_middle(RzDisasmState *ds, int ret)
Definition: disasm.c:3473
static int flagCmp(const void *a, const void *b)
Definition: disasm.c:2294
static void print_fcn_arg(RzCore *core, RzType *type, const char *name, const char *fmt, const ut64 addr, const int on_stack, int asm_types)
Definition: disasm.c:4722
static int mymemwrite0(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: disasm.c:4412
static void ds_cdiv_optimization(RzDisasmState *ds)
Definition: disasm.c:3314
#define DEFAULT_NARGS
Definition: disasm.c:16
static char * ds_esc_str(RzDisasmState *ds, const char *str, int len, const char **prefix_out, bool is_comment)
Definition: disasm.c:3903
static void ds_print_comments_right(RzDisasmState *ds)
Definition: disasm.c:5062
#define RZ_DISASM_MAX_STR
Definition: disasm.c:4441
RZ_API void rz_analysis_disasm_text_free(RzAnalysisDisasmText *t)
Free RzAnalysisDisasmText p.
Definition: disasm.c:5317
static void ds_newline(RzDisasmState *ds)
Definition: disasm.c:1286
static void ds_print_sysregs(RzDisasmState *ds)
Definition: disasm.c:3512
static int handleMidFlags(RzCore *core, RzDisasmState *ds, bool print)
Definition: disasm.c:1616
static void ds_print_as_string(RzDisasmState *ds)
Definition: disasm.c:5144
static void ds_end_line_highlight(RzDisasmState *ds)
Definition: disasm.c:5308
#define FLAG_PREFIX
Definition: disasm.c:17
static int ds_print_shortcut(RzDisasmState *ds, ut64 addr, int pos)
Definition: disasm.c:3596
static void ds_print_opstr(RzDisasmState *ds)
Definition: disasm.c:3459
static void ds_print_lines_right(RzDisasmState *ds)
Definition: disasm.c:2765
static void ds_print_esil_analysis_fini(RzDisasmState *ds)
Definition: disasm.c:559
RZ_API bool rz_core_print_function_disasm_json(RzCore *core, RzAnalysisFunction *fcn, PJ *pj)
Definition: disasm.c:6726
#define CMT_ALIGN
Definition: disasm.c:501
static void ds_reflines_fini(RzDisasmState *ds)
Definition: disasm.c:887
static void printVarSummary(RzDisasmState *ds, RzList *list)
Definition: disasm.c:1799
static bool read_ahead(RzIO *io, ut8 **buf, size_t *buf_sz, ut64 address, size_t offset_into_buf, size_t bytes_to_read)
Definition: disasm.c:6568
static bool calc_tab_buf_size(size_t len, size_t tabs, size_t *c)
Definition: disasm.c:1530
static void ds_print_ptr(RzDisasmState *ds, int len, int idx)
Definition: disasm.c:4022
static void printCol(RzDisasmState *ds, char *sect, int cols, const char *color)
Definition: disasm.c:2771
static void ds_show_comments_describe(RzDisasmState *ds)
Definition: disasm.c:2189
RZ_API const char * rz_core_get_section_name(RzCore *core, ut64 addr)
Definition: disasm.c:457
static void ds_print_cycles(RzDisasmState *ds)
Definition: disasm.c:2867
static void ds_build_op_str(RzDisasmState *ds, bool print_color)
Definition: disasm.c:985
static int ds_disassemble(RzDisasmState *ds, ut8 *buf, int len)
Definition: disasm.c:2579
static ut64 emustack_min
Definition: disasm.c:28
static bool ds_print_core_vmode(RzDisasmState *ds, int pos)
Definition: disasm.c:3676
static void ds_align_comment(RzDisasmState *ds)
Definition: disasm.c:3805
static void ds_print_esil_analysis(RzDisasmState *ds)
Definition: disasm.c:4787
RZ_API int rz_core_print_disasm_all(RzCore *core, ut64 addr, int l, int len, int mode)
Definition: disasm.c:6205
static void _ds_comment_align_(RzDisasmState *ds, bool up, bool nl)
Definition: disasm.c:485
static void ds_begin_cont(RzDisasmState *ds)
Definition: disasm.c:1314
static void ds_print_op_size(RzDisasmState *ds)
Definition: disasm.c:3015
static const char * rz_vline_u[]
Definition: disasm.c:45
#define DS_COMMENT_FUNC(name, align, nl)
Definition: disasm.c:530
static int mymemwrite2(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: disasm.c:4420
static void ds_pre_emulation(RzDisasmState *ds)
Definition: disasm.c:4606
static void ds_begin_line(RzDisasmState *ds)
Definition: disasm.c:1257
RZ_API int rz_core_bb_starts_in_middle(RzCore *core, ut64 at, int oplen)
Definition: disasm.c:1714
static void ds_print_stackptr(RzDisasmState *ds)
static bool is_filtered_flag(RzDisasmState *ds, const char *name)
Definition: disasm.c:4003
static void ds_begin_nl_comment(RzDisasmState *ds)
Definition: disasm.c:3791
static void ds_show_refs(RzDisasmState *ds)
Definition: disasm.c:1334
static void ds_print_trace(RzDisasmState *ds)
Definition: disasm.c:3022
static void ds_print_fcn_name(RzDisasmState *ds)
Definition: disasm.c:3544
static void get_bits_comment(RzCore *core, RzAnalysisFunction *f, char *cmt, int cmt_size)
Definition: disasm.c:438
#define DS_PRE_FCN_MIDDLE
Definition: disasm.c:81
static bool requires_op_size(RzDisasmState *ds)
Definition: disasm.c:2987
#define DS_PRE_FCN_TAIL
Definition: disasm.c:82
static void ds_comment_lineup(RzDisasmState *ds)
Definition: disasm.c:503
static RzAnalysisDisasmText * ds_disasm_text(RzDisasmState *ds, RzAnalysisDisasmText *t, char *text)
Definition: disasm.c:1237
#define DS_PRE_FCN_HEAD
Definition: disasm.c:80
static void ds_print_show_bytes(RzDisasmState *ds)
Definition: disasm.c:3345
static ut64 get_ptr(RzDisasmState *ds, ut64 addr)
Definition: disasm.c:3651
static void ds_print_str(RzDisasmState *ds, const char *str, int len, ut64 refaddr)
Definition: disasm.c:3981
static void ds_pre_xrefs(RzDisasmState *ds, bool no_fcnlines)
Definition: disasm.c:1756
RZ_API ut64 rz_core_pava(RzCore *core, ut64 addr)
Definition: disasm.c:364
static RzAnalysisFunction * fcnIn(RzDisasmState *ds, ut64 at, int type)
Definition: disasm.c:374
static void ds_print_asmop_payload(RzDisasmState *ds, const ut8 *buf)
Definition: disasm.c:3863
static void ds_adistrick_comments(RzDisasmState *ds)
Definition: disasm.c:3043
static bool ds_print_labels(RzDisasmState *ds, RzAnalysisFunction *f)
Definition: disasm.c:3488
static void ds_setup_print_pre(RzDisasmState *ds, bool tail, bool middle)
Definition: disasm.c:2123
static void ds_print_cmt_il(RzDisasmState *ds)
Definition: disasm.c:4328
static void ds_control_flow_comments(RzDisasmState *ds)
Definition: disasm.c:2737
#define DS_ANALYSIS_OP_MASK
Definition: disasm.c:24
static void ds_update_ref_lines(RzDisasmState *ds)
Definition: disasm.c:2537
static bool line_highlighted(RzDisasmState *ds)
Definition: disasm.c:5298
static void __preline_flag(RzDisasmState *ds, RzFlagItem *flag)
Definition: disasm.c:2303
static void ds_print_esil_analysis_init(RzDisasmState *ds)
Definition: disasm.c:4643
static void ds_highlight_word(RzDisasmState *ds, char *word, char *color)
Definition: disasm.c:953
static void ds_print_bbline(RzDisasmState *ds)
Definition: disasm.c:4684
static void ds_free(RzDisasmState *ds)
Definition: disasm.c:912
static void ds_print_indent(RzDisasmState *ds)
Definition: disasm.c:3434
static void ds_start_line_highlight(RzDisasmState *ds)
Definition: disasm.c:5302
static void ds_print_calls_hints(RzDisasmState *ds)
Definition: disasm.c:4998
static void ds_show_comments_right(RzDisasmState *ds)
Definition: disasm.c:2220
RZ_API RZ_OWN char * rz_core_disasm_instruction(RzCore *core, ut64 addr, ut64 reladdr, RZ_NULLABLE RzAnalysisFunction *fcn, bool color)
Returns a disassembly of one instruction.
Definition: disasm.c:6770
RZ_IPI bool rz_disasm_check_end(int nb_opcodes, int i_opcodes, int nb_bytes, int i_bytes)
Is i_opcodes < nb_opcodes and i_bytes < nb_bytes ?
Definition: disasm.c:5804
static void ds_atabs_option(RzDisasmState *ds)
Definition: disasm.c:1551
RZ_API int rz_core_print_disasm(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL ut8 *buf, int len, int nlines, RZ_NULLABLE RzCmdStateOutput *state, RZ_NULLABLE RzCoreDisasmOptions *options)
Disassemble len bytes and nlines opcodes restricted by len and nlines at the same time.
Definition: disasm.c:5336
RZ_API int rz_core_disasm_pdi(RzCore *core, int nb_opcodes, int nb_bytes, int fmt)
Definition: disasm.c:6558
static char * ssa_get(RzAnalysisEsil *esil, const char *reg)
Definition: disasm.c:4424
RZ_API int rz_core_disasm_pde(RzCore *core, int nb_opcodes, RzCmdStateOutput *state)
Definition: disasm.c:6581
RZ_API RzAnalysisHint * rz_core_hint_begin(RzCore *core, RzAnalysisHint *hint, ut64 at)
Definition: disasm.c:1192
RZ_API int rz_core_print_disasm_instructions(RzCore *core, int nb_bytes, int nb_opcodes)
Definition: disasm.c:6030
static const char * rz_vline_a[]
Definition: disasm.c:31
static bool ds_print_meta_infos(RzDisasmState *ds, ut8 *buf, int len, int idx, int *mi_type)
Definition: disasm.c:3141
static ut64 get_ptr_ble(RzDisasmState *ds, ut64 addr)
Definition: disasm.c:3663
#define COLOR(ds, field)
Definition: disasm.c:19
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
int(* decode)(const ut8 *, ebc_command_t *cmd)
Definition: ebc_disas.c:88
static int is_var(char *x)
Definition: egg_lang.c:8
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil)
Definition: esil.c:3103
RZ_API RzAnalysisEsil * rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize)
Definition: esil.c:85
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:155
RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size)
Definition: esil.c:507
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull)
Definition: esil.c:3298
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:2998
static int hook_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: esil_stats.c:21
RZ_API RzAnalysisBlock * rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr)
Definition: fcn.c:2063
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API RzAnalysisBlock * rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr)
Definition: fcn.c:2042
RZ_API RZ_OWN char * rz_analysis_function_get_signature(RZ_NONNULL RzAnalysisFunction *function)
Definition: fcn.c:1895
RZ_API RzFlagItem * rz_flag_get_i(RzFlag *f, ut64 off)
Definition: flag.c:317
RZ_API const RzList * rz_flag_get_list(RzFlag *f, ut64 off)
Definition: flag.c:475
RZ_API RzFlagItem * rz_flag_get_at(RzFlag *f, ut64 off, bool closest)
Definition: flag.c:404
RZ_API char * rz_flag_get_liststr(RzFlag *f, ut64 off)
Definition: flag.c:480
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
RZ_API RzFlagItem * rz_flag_get_by_spaces(RzFlag *f, ut64 off,...)
Definition: flag.c:326
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API RZ_OWN char * rz_type_as_format_pair(const RzTypeDB *typedb, RZ_NONNULL RzType *type)
Represents the RzType as a pf format string pair.
Definition: format.c:3075
RZ_API RZ_OWN char * rz_type_format_data(const RzTypeDB *typedb, RzPrint *p, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield)
Definition: format.c:2749
unsigned short prefix[65536]
Definition: gun.c:163
RZ_API RzAnalysisHint * rz_analysis_hint_get(RzAnalysis *a, ut64 addr)
Definition: hint.c:506
RZ_API void rz_analysis_hint_free(RzAnalysisHint *h)
Definition: hint.c:371
RZ_API void rz_config_hold_restore(RzConfigHold *h)
Restore whatever config options were previously saved in h.
Definition: hold.c:132
RZ_API RzConfigHold * rz_config_hold_new(RzConfig *cfg)
Create an opaque object to save/restore some configuration options.
Definition: hold.c:116
RZ_API bool rz_config_hold_s(RzConfigHold *h,...)
Save the current values of a list of config options that have string values.
Definition: hold.c:40
RZ_API bool rz_config_hold_i(RzConfigHold *h,...)
Save the current values of a list of config options that have integer values.
Definition: hold.c:81
RZ_API void rz_config_hold_free(RzConfigHold *h)
Free a RzConfigHold object h.
Definition: hold.c:152
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API char * rz_cons_html_filter(const char *ptr, int *newlen)
Definition: html.c:34
RZ_API void rz_il_op_effect_stringify(RZ_NONNULL RzILOpEffect *op, RZ_NONNULL RzStrBuf *sb)
Definition: il_export.c:711
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
RZ_API const char * rz_analysis_function_get_label_at(RzAnalysisFunction *fcn, ut64 addr)
Definition: labels.c:15
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define const
Definition: ansidecl.h:240
const char * spaces(int count)
RZ_API RzBinReloc * rz_core_getreloc(RzCore *core, ut64 addr, int size)
Definition: core.c:178
RZ_API RzFlagItem * rz_core_flag_get_by_spaces(RzFlag *f, ut64 off)
Definition: core.c:2280
RZ_API bool rz_core_block_size(RzCore *core, ut32 bsize)
Definition: core.c:2842
RZ_API char * rz_core_add_asmqjmp(RzCore *core, ut64 addr)
Definition: core.c:238
RZ_API RzBinReloc * rz_core_get_reloc_to(RzCore *core, ut64 addr)
Definition: core.c:189
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_iter_get_next(RzListIter *list)
returns the next RzList iterator in the list
Definition: list.c:20
RZ_API RZ_OWN RzList * rz_list_uniq(RZ_NONNULL const RzList *list, RZ_NONNULL RzListComparator cmp)
Returns a new RzList which contains only unique values.
Definition: list.c:756
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
Definition: list.c:209
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
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 times
Definition: sflib.h:70
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
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")
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
const char * source
Definition: lz4.h:699
char * dst
Definition: lz4.h:724
char * dest
Definition: lz4.h:697
@ RZ_ABS
RZ_API const char * rz_meta_get_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr)
Definition: meta.c:146
RZ_API RzPVector * rz_meta_get_all_at(RzAnalysis *a, ut64 at)
Definition: meta.c:219
RZ_API RzPVector * rz_meta_get_all_in(RzAnalysis *a, ut64 at, RzAnalysisMetaType type)
Definition: meta.c:223
RZ_API RzAnalysisMetaItem * rz_meta_get_at(RzAnalysis *a, ut64 addr, RzAnalysisMetaType type, RZ_OUT RZ_NULLABLE ut64 *size)
Definition: meta.c:207
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
line
Definition: setup.py:34
int idx
Definition: setup.py:197
RZ_API ut64 sdb_num_get(Sdb *s, const char *key, ut32 *cas)
Definition: num.c:13
RZ_API ut64 sdb_num_inc(Sdb *s, const char *key, ut64 n2, ut32 cas)
Definition: num.c:32
const char * name
Definition: op.c:541
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op)
Definition: op.c:37
RZ_API char * rz_analysis_op_to_string(RzAnalysis *analysis, RzAnalysisOp *op)
Definition: op.c:334
RZ_API const char * rz_analysis_optype_to_string(int type)
Definition: op.c:310
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
RZ_API const char * rz_analysis_op_family_to_string(int id)
Definition: op.c:560
RZ_API char * rz_cons_pal_parse(const char *str, RzColor *outcol)
Definition: pal.c:281
RZ_API bool rz_parse_filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
filter the opcode in data into str by following the flags and hints information
Definition: filter.c:592
RZ_API char * rz_parse_immtrim(char *opstr)
Definition: parse.c:127
RZ_API char * rz_parse_pseudocode(RzParse *p, const char *assembly)
Converts the assembly line into pseudocode.
Definition: parse.c:107
RZ_API bool rz_parse_subvar(RzParse *p, RZ_NULLABLE RzAnalysisFunction *f, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL RZ_IN char *data, RZ_BORROW RZ_NONNULL RZ_OUT char *str, int len)
Definition: parse.c:166
RZ_API RZ_BORROW const char * rz_platform_profile_resolve_extended_register(RZ_NONNULL RzPlatformProfile *profile, ut64 address)
Resolves an address and returns the linked extended register.
RZ_API RZ_BORROW const char * rz_platform_profile_resolve_mmio(RZ_NONNULL RzPlatformProfile *profile, ut64 address)
Resolves an address and returns the linked mmio.
RZ_API void rz_print_set_rowoff(RzPrint *p, int i, ut32 offset, bool overwrite)
Definition: print.c:1527
RZ_API void rz_print_set_screenbounds(RzPrint *p, ut64 addr)
Sets screen_bounds member of p to addr if the cursor is not visible on the screen.
Definition: print.c:376
RZ_API char * rz_print_hexpair(RzPrint *p, const char *str, int n)
Definition: print.c:172
static void pad(RzStrBuf *sb, ut32 count)
Definition: protobuf.c:36
RZ_API void rz_analysis_reflines_str_free(RzAnalysisRefStr *refstr)
Definition: reflines.c:483
RZ_API RzList * rz_analysis_reflines_get(RzAnalysis *analysis, ut64 addr, const ut8 *buf, ut64 len, int nlines, int linesout, int linescall)
Definition: reflines.c:82
RZ_API RzAnalysisRefStr * rz_analysis_reflines_str(void *_core, ut64 addr, int opts)
Definition: reflines.c:344
RZ_API int rz_analysis_reflines_middle(RzAnalysis *a, RzList *list, ut64 addr, int len)
Definition: reflines.c:266
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
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
RZ_API RzRegItem * rz_reg_index_get(RzReg *reg, int idx)
Definition: reg.c:262
RZ_API ut64 rz_reg_setv(RzReg *reg, const char *name, ut64 val)
Definition: reg.c:326
RZ_API RzRegSet * rz_reg_regset_get(RzReg *r, int type)
Definition: reg.c:452
#define eprintf(x, y...)
Definition: rlcc.c:7
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_ADDR_TYPE_ASCII
Definition: rz_analysis.h:95
#define RZ_ANALYSIS_OP_HINT_MASK
Definition: rz_analysis.h:359
@ RZ_ANALYSIS_FCN_TYPE_SYM
Definition: rz_analysis.h:195
@ RZ_ANALYSIS_FCN_TYPE_IMP
Definition: rz_analysis.h:196
@ RZ_ANALYSIS_FCN_TYPE_LOC
Definition: rz_analysis.h:194
@ RZ_ANALYSIS_FCN_TYPE_NULL
Definition: rz_analysis.h:192
@ RZ_ANALYSIS_FCN_TYPE_FCN
Definition: rz_analysis.h:193
@ RZ_ANALYSIS_STACK_SET
Definition: rz_analysis.h:459
@ RZ_ANALYSIS_STACK_GET
Definition: rz_analysis.h:458
@ RZ_ANALYSIS_XREF_TYPE_CODE
Definition: rz_analysis.h:900
@ RZ_ANALYSIS_XREF_TYPE_STRING
Definition: rz_analysis.h:903
@ RZ_ANALYSIS_XREF_TYPE_CALL
Definition: rz_analysis.h:901
@ RZ_ANALYSIS_XREF_TYPE_DATA
Definition: rz_analysis.h:902
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
int(* RzAnalysisEsilHookRegWriteCB)(ANALYSIS_ESIL *esil, const char *name, ut64 *val)
Definition: rz_analysis.h:1025
@ RZ_META_TYPE_VARTYPE
Definition: rz_analysis.h:297
@ RZ_META_TYPE_ANY
Definition: rz_analysis.h:288
@ RZ_META_TYPE_DATA
Definition: rz_analysis.h:289
@ RZ_META_TYPE_HIGHLIGHT
Definition: rz_analysis.h:296
@ RZ_META_TYPE_HIDE
Definition: rz_analysis.h:294
@ RZ_META_TYPE_MAGIC
Definition: rz_analysis.h:293
@ RZ_META_TYPE_STRING
Definition: rz_analysis.h:291
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
@ RZ_META_TYPE_FORMAT
Definition: rz_analysis.h:292
@ RZ_ANALYSIS_OP_MASK_ALL
Definition: rz_analysis.h:447
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_BEFORE
Definition: rz_analysis.h:467
@ RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_AFTER
Definition: rz_analysis.h:469
@ RZ_ANALYSIS_REFLINE_TYPE_WIDE
Definition: rz_analysis.h:466
@ RZ_ANALYSIS_REFLINE_TYPE_UTF8
Definition: rz_analysis.h:465
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
@ RZ_ANALYSIS_VAR_KIND_REG
Definition: rz_analysis.h:703
@ RZ_ANALYSIS_VAR_KIND_SPV
Definition: rz_analysis.h:705
@ RZ_ANALYSIS_VAR_KIND_BPV
Definition: rz_analysis.h:704
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_ICALL
Definition: rz_analysis.h:381
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_IJMP
Definition: rz_analysis.h:371
@ RZ_ANALYSIS_OP_TYPE_IO
Definition: rz_analysis.h:403
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_IND
Definition: rz_analysis.h:366
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_REG
Definition: rz_analysis.h:365
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_COND
Definition: rz_analysis.h:361
@ RZ_ANALYSIS_OP_TYPE_UCJMP
Definition: rz_analysis.h:377
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
@ RZ_ASM_SYNTAX_INTEL
Definition: rz_asm.h:50
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define LINE_UP
Definition: rz_cons.h:797
#define Color_BYELLOW
Definition: rz_cons.h:650
#define Color_RESET
Definition: rz_cons.h:617
#define CORNER_TR
Definition: rz_cons.h:801
#define Color_WHITE
Definition: rz_cons.h:625
#define Color_RESET_BG
Definition: rz_cons.h:619
#define CORNER_BL
Definition: rz_cons.h:800
#define Color_MAGENTA
Definition: rz_cons.h:629
#define Color_CYAN
Definition: rz_cons.h:633
#define CORNER_TL
Definition: rz_cons.h:798
#define Color_BRED
Definition: rz_cons.h:642
#define SELF_LOOP
Definition: rz_cons.h:804
#define Color_GREEN
Definition: rz_cons.h:627
#define Color_INVERT_RESET
Definition: rz_cons.h:607
#define Color_RED
Definition: rz_cons.h:623
#define Color_BGGRAY
Definition: rz_cons.h:638
#define LINE_CROSS
Definition: rz_cons.h:795
#define Color_BGREEN
Definition: rz_cons.h:646
#define LINE_VERT
Definition: rz_cons.h:794
#define ARROW_LEFT
Definition: rz_cons.h:803
#define Color_YELLOW
Definition: rz_cons.h:631
#define Color_RESET_NOBG
Definition: rz_cons.h:618
#define ARROW_RIGHT
Definition: rz_cons.h:802
#define Color_BLUE
Definition: rz_cons.h:635
#define LINE_HORIZ
Definition: rz_cons.h:796
#define Color_BGBLUE
Definition: rz_cons.h:636
#define Color_BLACK
Definition: rz_cons.h:621
#define Color_GRAY
Definition: rz_cons.h:637
#define Color_INVERT
Definition: rz_cons.h:606
#define RZ_FLAGS_FS_IMPORTS
Definition: rz_core.h:59
#define RZ_CORE_ASMQJMPS_NUM
Definition: rz_core.h:183
#define RZ_FLAGS_FS_CLASSES
Definition: rz_core.h:57
#define RZ_FLAGS_FS_RELOCS
Definition: rz_core.h:60
#define RZ_FLAGS_FS_SYMBOLS
Definition: rz_core.h:67
#define RZ_FLAGS_FS_FUNCTIONS
Definition: rz_core.h:58
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static ut64 rz_read_ble(const void *src, bool big_endian, int size)
Definition: rz_endian.h:517
RZ_API void rz_io_cache_init(RzIO *io)
Definition: io_cache.c:21
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
RZ_API int rz_io_fd_open(RzIO *io, const char *uri, int flags, int mode)
Definition: io_fd.c:6
RZ_API bool rz_io_read_i(RzIO *io, ut64 addr, ut64 *val, int size, bool endian)
Definition: ioutils.c:41
RZ_API RzIOMap * rz_io_map_get_paddr(RzIO *io, ut64 paddr)
Definition: io_map.c:163
RZ_API void rz_io_cache_fini(RzIO *io)
Definition: io_cache.c:28
RZ_API bool rz_io_read_at_mapped(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:318
RZ_API bool rz_io_is_valid_offset(RzIO *io, ut64 offset, int hasperm)
Definition: ioutils.c:20
RZ_API void rz_io_map_set_name(RzIOMap *map, const char *name)
Definition: io_map.c:332
RZ_API RzIOMap * rz_io_map_add(RzIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:151
RZ_API bool rz_io_fd_close(RzIO *io, int fd)
Definition: io_fd.c:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API const ut8 * rz_mem_mem_aligned(const ut8 *haystack, int hlen, const ut8 *needle, int nlen, int align)
Definition: mem.c:260
RZ_API bool rz_name_filter(char *name, int len, bool strict)
Definition: name.c:43
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_API void * rz_num_dup(ut64 n)
Definition: unum.c:915
RZ_API char * rz_num_as_string(RzNum *___, ut64 n, bool printable_only)
Definition: unum.c:705
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
#define RZ_PRINT_FLAGS_SECSUB
Definition: rz_print.h:28
#define RZ_PRINT_FLAGS_ADDRDEC
Definition: rz_print.h:24
#define RZ_PRINT_FLAGS_COLOR
Definition: rz_print.h:15
#define RZ_PRINT_FLAGS_HEADER
Definition: rz_print.h:18
#define RZ_PRINT_FLAGS_SEGOFF
Definition: rz_print.h:20
#define RZ_PRINT_FLAGS_UNALLOC
Definition: rz_print.h:34
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
@ 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
static void rz_skyline_clear(RzSkyline *skyline)
Definition: rz_skyline.h:29
RZ_API bool rz_skyline_add(RzSkyline *skyline, RzInterval itv, void *user)
Definition: skyline.c:12
RZ_API RzStrEnc rz_str_enc_string_as_type(RZ_NULLABLE const char *enc)
converts an encoding name to RzStrEnc
Definition: str.c:86
RZ_API char * rz_str_append_owned(char *ptr, char *string)
Definition: str.c:1050
RZ_API void rz_str_trim_char(RZ_NONNULL RZ_INOUT char *str, const char c)
Removes the character c from the beginning and end of a string.
Definition: str_trim.c:179
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
RZ_API const char * rz_str_rwx_i(int rwx)
Definition: str.c:332
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API char * rz_str_escape_utf16be(const char *buf, int buf_size, RzStrEscOptions *opt)
Definition: str.c:1715
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API char RZ_API char * rz_str_newlen(const char *str, int len)
Definition: str.c:871
RZ_API size_t rz_str_ansi_len(const char *str)
Definition: str.c:1945
#define rz_str_cat(x, y)
Definition: rz_str.h:110
RZ_API int rz_str_ansi_filter(char *str, char **out, int **cposs, int len)
Definition: str.c:2124
RZ_API void rz_str_case(char *str, bool up)
Definition: str.c:341
RZ_API const char * rz_str_ansi_chrn(const char *str, size_t n)
Definition: str.c:2098
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
#define rz_str_cpy(x, y)
Definition: rz_str.h:109
static const char * rz_str_get_null(const char *str)
Definition: rz_str.h:190
RZ_API char * rz_str_escape_utf32le(const char *buf, int buf_size, RzStrEscOptions *opt)
Definition: str.c:1711
RzStrEnc
Definition: rz_str.h:19
@ RZ_STRING_ENC_UTF32LE
Definition: rz_str.h:24
@ RZ_STRING_ENC_8BIT
Definition: rz_str.h:20
@ RZ_STRING_ENC_UTF32BE
Definition: rz_str.h:26
@ RZ_STRING_ENC_UTF8
Definition: rz_str.h:21
@ RZ_STRING_ENC_GUESS
Definition: rz_str.h:33
@ RZ_STRING_ENC_UTF16LE
Definition: rz_str.h:23
@ RZ_STRING_ENC_UTF16BE
Definition: rz_str.h:25
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API void rz_str_filter(char *str)
Convert all non-printable characters in str with '.'.
Definition: str.c:2359
RZ_API char * rz_str_escape_8bit(const char *buf, bool colors, RzStrEscOptions *opt)
Definition: str.c:1595
RZ_API char * rz_str_escape_utf8(const char *buf, RzStrEscOptions *opt)
Definition: str.c:1699
RZ_API size_t rz_str_len_utf8(const char *s)
Definition: str.c:2709
RZ_API int rz_str_bits(char *strout, const ut8 *buf, int len, const char *bitz)
Definition: str.c:195
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API bool rz_str_is_printable_incl_newlines(const char *str)
Definition: str.c:2069
RZ_API char * rz_str_escape_utf32be(const char *buf, int buf_size, RzStrEscOptions *opt)
Definition: str.c:1719
RZ_API char ** rz_str_argv(const char *str, int *_argc)
Definition: str.c:2509
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API char * rz_str_highlight(char *str, const char *word, const char *color, const char *color_reset)
Definition: str.c:3657
RZ_API char * rz_str_escape_utf16le(const char *buf, int buf_size, RzStrEscOptions *opt)
Definition: str.c:1707
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
RZ_API size_t rz_str_len_utf8_ansi(const char *str)
Definition: str.c:2723
RZ_API size_t * rz_str_split_lines(char *str, size_t *count)
Split the string str in lines and returns the result in an array.
Definition: str.c:3526
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
RZ_API char * rz_str_from_ut64(ut64 val)
Definition: str.c:3791
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
#define IS_SEPARATOR(x)
Definition: rz_str_util.h:6
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10
#define IS_WHITECHAR(x)
Definition: rz_str_util.h:5
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
#define RZ_STRBUF_SAFEGET(sb)
Definition: rz_strbuf.h:18
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
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
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API int rz_strbuf_length(RzStrBuf *sb)
Definition: strbuf.c:28
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_INOUT
Definition: rz_types.h:52
#define PFMT64u
Definition: rz_types.h:395
@ RZ_OUTPUT_MODE_JSON
Definition: rz_types.h:40
@ RZ_OUTPUT_MODE_QUIET
Definition: rz_types.h:42
@ RZ_OUTPUT_MODE_QUIETEST
Definition: rz_types.h:47
#define PFMT64o
Definition: rz_types.h:396
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define ST16_MAX
#define RZ_EMPTY
Definition: rz_types_base.h:68
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define st32
Definition: rz_types_base.h:12
#define ST64_MAX
Definition: rz_types_base.h:84
#define ST16_MIN
#define SZT_ADD_OVFCHK(x, y)
RZ_API int rz_utf32le_decode(const ut8 *ptr, int ptrlen, RzRune *ch)
Definition: utf32.c:39
RZ_API RzStrEnc rz_utf_bom_encoding(const ut8 *ptr, int ptrlen)
Definition: utf8.c:809
RZ_API int rz_utf8_decode(const ut8 *ptr, int ptrlen, RzRune *ch)
Definition: utf8.c:492
ut32 RzRune
Definition: rz_utf8.h:13
RZ_API int rz_utf8_strlen(const ut8 *str)
Definition: utf8.c:588
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void * rz_pvector_pop_front(RzPVector *vec)
Definition: vector.c:379
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
RZ_API RzVector * rz_vector_clone(RzVector *vec)
Definition: vector.c:101
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
#define isdigit(c)
Definition: safe-ctype.h:131
#define toupper(c)
Definition: safe-ctype.h:147
static bool is_comment(const char *s)
Definition: scanner.c:53
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
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
static int
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define ntohs(x)
Definition: sftypes.h:478
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
char strsub[1024]
Definition: disasm.c:88
RzAnalysisOp analysis_op
Definition: disasm.c:278
bool hinted_line
Definition: disasm.c:206
bool asm_hint_call_indirect
Definition: disasm.c:163
bool show_bbline
Definition: disasm.c:132
const char * color_flow2
Definition: disasm.c:220
bool bblined
Definition: disasm.c:152
bool capitalize
Definition: disasm.c:97
bool show_cmt_il
Definition: disasm.c:174
RzSpace * flagspace_ports
Definition: disasm.c:188
const char * color_fname
Definition: disasm.c:216
bool asm_hint_cdiv
Definition: disasm.c:161
bool show_nodup
Definition: disasm.c:288
const char * color_cjmp
Definition: disasm.c:230
const char * color_flag
Definition: disasm.c:221
ut64 printed_str_addr
Definition: disasm.c:299
const char * pal_comment
Definition: disasm.c:213
const char * color_num
Definition: disasm.c:239
bool show_usercomments
Definition: disasm.c:158
int show_comment_right
Definition: disasm.c:191
int stackptr
Definition: disasm.c:271
const ut8 * buf
Definition: disasm.c:281
int linesout
Definition: disasm.c:124
char * comment
Definition: disasm.c:268
int ostackptr
Definition: disasm.c:271
char * _tabsbuf
Definition: disasm.c:291
bool asm_hint_emu
Definition: disasm.c:165
bool midbb
Definition: disasm.c:209
bool showpayloads
Definition: disasm.c:295
bool asm_xrefs_code
Definition: disasm.c:127
bool show_trace
Definition: disasm.c:121
bool show_emu
Definition: disasm.c:133
const char * color_bin
Definition: disasm.c:226
int show_symbols_col
Definition: disasm.c:150
bool show_family
Definition: disasm.c:122
bool show_color_args
Definition: disasm.c:94
RzFlagItem * lastflag
Definition: disasm.c:252
bool show_bytes_right
Definition: disasm.c:154
bool showrelocs
Definition: disasm.c:296
const char * color_nop
Definition: disasm.c:225
int maxrefs
Definition: disasm.c:283
RzPVector * vec
Definition: disasm.c:309
int midflags
Definition: disasm.c:208
const char * color_fline
Definition: disasm.c:218
int asm_hint_pos
Definition: disasm.c:166
int foldxrefs
Definition: disasm.c:284
char chref
Definition: disasm.c:275
int cbytes
Definition: disasm.c:274
ut64 addr
Definition: disasm.c:273
bool asm_hint_lea
Definition: disasm.c:164
bool immtrim
Definition: disasm.c:89
int show_indent
Definition: disasm.c:118
bool asm_meta
Definition: disasm.c:126
char * prev_line_col
Definition: disasm.c:266
char str[1024]
Definition: disasm.c:88
int show_utf8
Definition: disasm.c:199
bool show_emu_ssa
Definition: disasm.c:143
bool esil_likely
Definition: disasm.c:259
bool show_cmtrefs
Definition: disasm.c:180
bool show_section_name
Definition: disasm.c:148
RzAnalysisFunction * pdf
Definition: disasm.c:280
bool pseudo
Definition: disasm.c:105
bool asm_hint_jmp
Definition: disasm.c:160
RzAsmOp asmop
Definition: disasm.c:277
const char * color_trap
Definition: disasm.c:234
const char * color_mov
Definition: disasm.c:240
bool show_stackptr
Definition: disasm.c:177
bool asm_hints
Definition: disasm.c:159
bool show_lines_bb
Definition: disasm.c:111
int indent_level
Definition: disasm.c:263
bool show_cmtflgrefs
Definition: disasm.c:172
char * refline2
Definition: disasm.c:267
bool show_emu_write
Definition: disasm.c:140
bool show_lines_call
Definition: disasm.c:113
int indent_space
Definition: disasm.c:264
Sdb * ssa
Definition: disasm.c:169
const char * color_offset
Definition: disasm.c:223
const char * color_func_var
Definition: disasm.c:248
bool show_functions
Definition: disasm.c:182
RzStrEnc strenc
Definition: disasm.c:185
bool dwarfAbspath
Definition: disasm.c:294
const char * color_func_var_type
Definition: disasm.c:249
const char * color_btext
Definition: disasm.c:228
bool show_fcnsig
Definition: disasm.c:204
char * refline
Definition: disasm.c:267
bool show_cmt_esil
Definition: disasm.c:173
bool show_lines
Definition: disasm.c:110
ut64 emuptr
Definition: disasm.c:167
bool show_emu_strflag
Definition: disasm.c:138
int cyclespace
Definition: disasm.c:117
char * sl
Definition: disasm.c:270
bool show_offset
Definition: disasm.c:130
int colorop
Definition: disasm.c:95
bool show_lines_fcn
Definition: disasm.c:114
bool hasMidbb
Definition: disasm.c:100
const char * color_push
Definition: disasm.c:236
bool show_bytes
Definition: disasm.c:153
bool show_calls
Definition: disasm.c:171
int middle
Definition: disasm.c:262
const char * color_floc
Definition: disasm.c:217
char * line_col
Definition: disasm.c:266
int asm_demangle
Definition: disasm.c:128
const char * color_func_var_addr
Definition: disasm.c:250
const char * strip
Definition: disasm.c:305
RzAnalysisFunction * fcn
Definition: disasm.c:279
bool retry
Definition: disasm.c:276
int adistrick
Definition: disasm.c:125
int tracespace
Definition: disasm.c:116
bool linesright
Definition: disasm.c:115
const char * show_cmtoff
Definition: disasm.c:181
int show_comment_right_default
Definition: disasm.c:187
bool show_emu_str
Definition: disasm.c:135
bool dwarfFile
Definition: disasm.c:293
const char * color_ret
Definition: disasm.c:235
bool show_reloff
Definition: disasm.c:155
bool show_dwarf
Definition: disasm.c:119
const char * color_usrcmt
Definition: disasm.c:215
bool midcursor
Definition: disasm.c:210
bool asm_describe
Definition: disasm.c:123
bool asm_analysis
Definition: disasm.c:298
int show_section_col
Definition: disasm.c:145
bool show_noisy_comments
Definition: disasm.c:211
bool show_section_perm
Definition: disasm.c:147
ut64 printed_flag_addr
Definition: disasm.c:300
bool show_emu_strinv
Definition: disasm.c:137
int lastfail
Definition: disasm.c:195
int subnames
Definition: disasm.c:106
const char * color_math
Definition: disasm.c:227
bool show_flag_in_bytes
Definition: disasm.c:189
bool show_lines_ret
Definition: disasm.c:112
bool show_emu_stroff
Definition: disasm.c:136
char * ocomment
Definition: disasm.c:193
const char * color_jmp
Definition: disasm.c:229
ut64 asm_highlight
Definition: disasm.c:212
bool has_description
Definition: disasm.c:289
bool show_cycles
Definition: disasm.c:175
ut64 vat
Definition: disasm.c:273
const char * color_invalid
Definition: disasm.c:241
RzCore * core
Definition: disasm.c:87
bool subvar
Definition: disasm.c:109
int linesopts
Definition: disasm.c:194
int decode
Definition: disasm.c:104
bool asm_instr
Definition: disasm.c:129
int _tabsoff
Definition: disasm.c:292
bool asm_hint_call
Definition: disasm.c:162
const char * color_reg
Definition: disasm.c:238
char * osl
Definition: disasm.c:270
int atabsonce
Definition: disasm.c:102
int prev_ins_count
Definition: disasm.c:287
RzPrint * print
Definition: disasm.c:254
RzAnalysisHint * hint
Definition: disasm.c:253
int show_varsum
Definition: disasm.c:207
int atabsoff
Definition: disasm.c:103
bool show_flgoff
Definition: disasm.c:98
bool show_comments
Definition: disasm.c:157
bool show_xrefs
Definition: disasm.c:179
int interactive
Definition: disasm.c:107
int buf_line_begin
Definition: disasm.c:304
bool show_reloff_flags
Definition: disasm.c:156
bool show_marks
Definition: disasm.c:183
bool flags_inline
Definition: disasm.c:146
bool show_section
Definition: disasm.c:144
bool show_color
Definition: disasm.c:92
int esil_regstate_size
Definition: disasm.c:258
bool show_fcnsize
Definition: disasm.c:205
int lbytes
Definition: disasm.c:190
const char * color_comment
Definition: disasm.c:214
const char * color_pop
Definition: disasm.c:237
bool show_offdec
Definition: disasm.c:131
const char * color_gui_cflow
Definition: disasm.c:242
const char * color_swi
Definition: disasm.c:233
const char * color_gui_background
Definition: disasm.c:244
bool show_refptr
Definition: disasm.c:176
bool show_varaccess
Definition: disasm.c:202
int nbytes
Definition: disasm.c:198
const char * color_cmp
Definition: disasm.c:232
bool use_esil
Definition: disasm.c:91
const char * color_label
Definition: disasm.c:222
bool show_asciidot
Definition: disasm.c:184
bool show_color_bytes
Definition: disasm.c:93
char * line
Definition: disasm.c:265
ut64 min_ref_addr
Definition: disasm.c:301
const char * color_gui_dataoffset
Definition: disasm.c:243
ut8 * esil_regstate
Definition: disasm.c:257
bool hasMidflag
Definition: disasm.c:99
const char * color_linehl
Definition: disasm.c:247
int asm_types
Definition: disasm.c:307
const char * color_flow
Definition: disasm.c:219
int cmtcount
Definition: disasm.c:297
bool show_size
Definition: disasm.c:120
bool show_emu_stack
Definition: disasm.c:139
bool prev_ins_eq
Definition: disasm.c:286
const char * color_other
Definition: disasm.c:224
bool subjmp
Definition: disasm.c:108
bool show_optype
Definition: disasm.c:141
bool show_emu_strlea
Definition: disasm.c:142
bool show_symbols
Definition: disasm.c:149
int cmtcol
Definition: disasm.c:170
ut64 dest
Definition: disasm.c:273
int maxflags
Definition: disasm.c:306
const char * color_call
Definition: disasm.c:231
char * prev_ins
Definition: disasm.c:285
char * opstr
Definition: disasm.c:269
const char * color_gui_alt_background
Definition: disasm.c:245
bool show_flags
Definition: disasm.c:151
bool show_slow
Definition: disasm.c:168
int acase
Definition: disasm.c:96
int cursor
Definition: disasm.c:186
const char * color_gui_border
Definition: disasm.c:246
ut64 esil_old_pc
Definition: disasm.c:256
bool immstr
Definition: disasm.c:90
bool show_vars
Definition: disasm.c:203
int stackFd
Definition: disasm.c:178
bool pre_emu
Definition: disasm.c:134
Group together some common options used by string escaping functions.
Definition: rz_str.h:39
bool esc_bslash
When true, backslashes \ are quoted with \\
Definition: rz_str.h:41
bool show_asciidot
When true, dots . are placed instead of unprintable characters.
Definition: rz_str.h:40
bool esc_double_quotes
When true, double quotes "</tt> are quoted with <tt>\\"
Definition: rz_str.h:42
const char * name
Definition: sparc-opc.c:1838
Definition: malloc.c:26
Definition: dis.h:35
Definition: z80asm.h:102
Definition: op.c:222
Definition: rz_pj.h:12
RzAnalysisSwitchOp * switch_op
Definition: rz_analysis.h:874
Message for pdJ
Definition: rz_core.h:443
ut64 arrow
In general, arrow = UT64_MAX, if there is a jump(jmp, ...), arrow = dst offset.
Definition: rz_core.h:445
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
RzAnalysisEsilHookRegWriteCB hook_reg_write
Definition: rz_analysis.h:1038
RzAnalysis * analysis
Definition: rz_analysis.h:1043
RzAnalysisEsilCallbacks cb
Definition: rz_analysis.h:1078
RzAnalysisMetaType type
Definition: rz_analysis.h:302
RzAnalysisOpFamily family
Definition: rz_analysis.h:823
RzAnalysisStackOp stackop
Definition: rz_analysis.h:817
RzAnalysisLiftedILOp il_op
Definition: rz_analysis.h:844
RzAnalysisXRefType type
Definition: rz_analysis.h:909
RzList * reflines
Definition: rz_analysis.h:609
RzPlatformTarget * arch_target
Definition: rz_analysis.h:622
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584
ut8 * last_disasm_reg
Definition: rz_analysis.h:569
RzSyscall * syscall
Definition: rz_analysis.h:570
RzFlagBind flb
Definition: rz_analysis.h:575
RzAnalysisOptions opt
Definition: rz_analysis.h:608
RzList * imports
Definition: rz_analysis.h:618
RzIOBind iob
Definition: rz_analysis.h:574
RzTypeDB * typedb
Definition: rz_analysis.h:602
RzAnalysisVarKind kind
Definition: rz_analysis.h:728
RzStrBuf buf_asm
Definition: rz_asm.h:72
int payload
Definition: rz_asm.h:69
int size
Definition: rz_asm.h:67
RzAsmTokenString * asm_toks
Tokenized asm string.
Definition: rz_asm.h:74
int big_endian
Definition: rz_asm.h:101
ut64 pc
Definition: rz_asm.h:103
int bits
Definition: rz_asm.h:100
int dataalign
Definition: rz_asm.h:119
RzBinObject * o
Definition: rz_bin.h:305
char * name
Definition: rz_bin.h:701
char *(* enrich_asm)(RzBinFile *bf, const char *asm_str, int asm_len)
Definition: rz_bin.h:545
RzBinRelocType type
Definition: rz_bin.h:712
ut64 vaddr
the vaddr where the value should be patched into
Definition: rz_bin.h:716
RzBinImport * import
Definition: rz_bin.h:714
st64 addend
Definition: rz_bin.h:715
RzBinSymbol * symbol
Definition: rz_bin.h:713
char * name
Definition: rz_bin.h:619
char * name
Definition: rz_bin.h:675
RZ_DEPRECATE RzBinFile * cur
never use this in new code! Get a file from the binfiles list or track it yourself.
Definition: rz_bin.h:330
bool is_reloc_patched
Definition: rz_bin.h:363
Represent the output state of a command handler.
Definition: rz_cmd.h:91
RzConsPrintablePalette pal
Definition: rz_cons.h:491
int columns
Definition: rz_cons.h:510
const char ** vline
Definition: rz_cons.h:554
bool use_utf8
Definition: rz_cons.h:559
RzConsContext * context
Definition: rz_cons.h:502
bool vmode
Definition: rz_core.h:309
RzCons * cons
Definition: rz_core.h:312
RzBin * bin
Definition: rz_core.h:298
ut64 offset
Definition: rz_core.h:301
RzAsm * rasm
Definition: rz_core.h:323
RzAnalysis * analysis
Definition: rz_core.h:322
RzDebug * dbg
Definition: rz_core.h:329
RzIO * io
Definition: rz_core.h:313
RzNum * num
Definition: rz_core.h:316
RzParse * parser
Definition: rz_core.h:326
ut8 * block
Definition: rz_core.h:305
RzFlag * flags
Definition: rz_core.h:330
RzPrint * print
Definition: rz_core.h:327
ut32 blocksize
Definition: rz_core.h:303
bool is_asmqjmps_letter
Definition: rz_core.h:349
RzConfig * config
Definition: rz_core.h:300
RzList * maps
Definition: rz_debug.h:306
RzBreakpoint * bp
Definition: rz_debug.h:288
RzFlag * f
Definition: rz_flag.h:78
RzSpace * space
Definition: rz_flag.h:40
char * color
Definition: rz_flag.h:41
ut64 offset
Definition: rz_flag.h:38
char * comment
Definition: rz_flag.h:42
char * realname
Definition: rz_flag.h:36
char * name
Definition: rz_flag.h:35
bool demangled
Definition: rz_flag.h:37
bool realnames
Definition: rz_flag.h:49
RzIO * io
Definition: rz_io.h:232
Definition: rz_io.h:59
int cached
Definition: rz_io.h:69
size_t addrbytes
Definition: rz_io.h:66
RzSkyline cache_skyline
Definition: rz_io.h:77
int va
Definition: rz_io.h:63
RzPVector cache
Definition: rz_io.h:76
RzListIter * head
Definition: rz_list.h:19
RzListIter * tail
Definition: rz_list.h:20
ut64 subrel_addr
Definition: rz_parse.h:29
bool subrel
Definition: rz_parse.h:26
const char *(* get_reg_at)(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: rz_parse.h:38
bool subreg
Definition: rz_parse.h:25
bool pseudo
Definition: rz_parse.h:24
bool localvar_only
Definition: rz_parse.h:28
RzSpace * notin_flagspace
Definition: rz_parse.h:23
char * retleave_asm
Definition: rz_parse.h:32
st64(* get_ptr_at)(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: rz_parse.h:37
RzSpace * flagspace
Definition: rz_parse.h:22
RzPlatformProfile * profile
Definition: rz_platform.h:34
bool resetbg
Definition: rz_print.h:145
int big_endian
Definition: rz_print.h:124
RzPrintAsmColorOpts colorize_opts
Coloize options for asm strings.
Definition: rz_print.h:182
const char * strconv_mode
Definition: rz_print.h:163
int flags
Definition: rz_print.h:137
int bytespace
Definition: rz_print.h:143
bool esc_bslash
Definition: rz_print.h:161
bool pava
Definition: rz_print.h:112
bool cur_enabled
Definition: rz_print.h:130
RzVector v
Definition: rz_vector.h:56
RzRegArena * arena
Definition: rz_reg.h:136
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
char * name
Definition: rz_spaces.h:29
RzTypeKind kind
Definition: rz_type.h:155
RzVectorFree free
Definition: rz_vector.h:50
void * a
Definition: rz_vector.h:46
Definition: sdb.h:63
Definition: dis.h:43
int pos
Definition: main.c:11
uint64_t blocks
Definition: list.c:104
static struct Type metas[]
Definition: swift.c:39
RZ_API const char * rz_sysreg_get(RzSyscall *s, const char *type, ut64 port)
Searches the sysregs SDB database inside librz/reg/d for the type (mmio/reg) and returns its value as...
Definition: syscall.c:433
static uv_once_t once
Definition: threadpool.c:32
RZ_API RzDebugTracepoint * rz_debug_trace_get(RzDebug *dbg, ut64 addr)
Definition: trace.c:200
RZ_API int rz_type_func_args_count(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns arguments' count.
Definition: function.c:262
RZ_API RZ_BORROW const char * rz_type_func_args_name(RzTypeDB *typedb, RZ_NONNULL const char *name, int i)
Searches for the RzCallable type in types database and returns argument name.
Definition: function.c:302
RZ_API RZ_BORROW RzType * rz_type_func_ret(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns return type.
Definition: function.c:215
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
Definition: function.c:203
RZ_API RZ_BORROW RzType * rz_type_func_args_type(RzTypeDB *typedb, RZ_NONNULL const char *name, int i)
Searches for the RzCallable type in types database and returns argument type.
Definition: function.c:278
RZ_API RZ_BORROW const char * rz_type_identifier(RZ_NONNULL const RzType *type)
Returns the type C identifier.
Definition: type.c:1155
RZ_API ut64 rz_type_db_get_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzType *type)
Returns the type size in bits (target dependent)
Definition: type.c:779
RZ_API RZ_BORROW const char * rz_type_db_enum_member_by_val(const RzTypeDB *typedb, RZ_NONNULL const char *name, ut64 val)
Returns the enum case name matching the cpecified value.
Definition: type.c:508
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
Definition: dis.c:32
RZ_API void rz_analysis_fcn_vars_cache_fini(RzAnalysisFcnVarsCache *cache)
Definition: var.c:1223
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var(RzAnalysisFunction *fcn, char kind, int delta)
Definition: var.c:259
RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kind, int type)
Definition: var.c:574
RZ_API char * rz_analysis_var_get_constraints_readable(RzAnalysisVar *var)
Definition: var.c:528
RZ_API st64 rz_analysis_function_get_var_stackptr_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: var.c:284
RZ_API char * rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE char *fcn_name, RZ_NULLABLE RzAnalysisFcnVarsCache *reuse_cache, RZ_NULLABLE const char *fcn_name_pre, RZ_NULLABLE const char *fcn_name_post)
Definition: var.c:1232
RZ_API const char * rz_analysis_function_get_var_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: var.c:314
RZ_API void rz_analysis_fcn_vars_cache_init(RzAnalysis *analysis, RzAnalysisFcnVarsCache *cache, RzAnalysisFunction *fcn)
Definition: var.c:1209
static int color
Definition: visual.c:20
RZ_API bool rz_core_prevop_addr(RzCore *core, ut64 start_addr, int numinstrs, ut64 *prev_addr)
Definition: visual.c:1173
static int blocksize
Definition: visual.c:15
RZ_API ut64 rz_core_prevop_addr_force(RzCore *core, ut64 start_addr, int numinstrs)
Definition: visual.c:1195
static st64 delta
Definition: vmenus.c:2425
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
RZ_API RzList * rz_analysis_xrefs_get_from(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:187
RZ_API RzList * rz_analysis_xrefs_get_to(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:173
RZ_API const char * rz_analysis_xrefs_type_tostring(RzAnalysisXRefType type)
Definition: xrefs.c:216
static int sp
Definition: z80asm.c:91
static int comma
Definition: z80asm.c:76
static int addr
Definition: z80asm.c:58
#define N
Definition: zip_err_str.c:8
#define E
Definition: zip_err_str.c:12