Rizin
unix-like reverse engineering framework and cli tools
print.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2007-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <ctype.h>
5 #include <rz_util/rz_str.h>
6 #include <rz_list.h>
7 #include <rz_regex.h>
8 #include <rz_types.h>
9 #include <rz_util/rz_assert.h>
10 #include <rz_util/rz_log.h>
11 #include <rz_util/rz_strbuf.h>
12 #include <rz_vector.h>
13 #include <rz_util/rz_print.h>
14 #include <rz_analysis.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #define DFLT_ROWS 16
20 
21 static const char hex[16] = "0123456789ABCDEF";
22 
23 static int nullprinter(const char *a, ...) {
24  return 0;
25 }
26 
27 static int libc_printf(const char *format, ...) {
28  va_list ap;
29  va_start(ap, format);
30  vprintf(format, ap);
31  va_end(ap);
32  return 0;
33 }
34 
35 static int libc_eprintf(const char *format, ...) {
36  va_list ap;
37  va_start(ap, format);
38  vfprintf(stderr, format, ap);
39  va_end(ap);
40  return 0;
41 }
42 
43 static RzPrintIsInterruptedCallback is_interrupted_cb = NULL;
44 
46  if (is_interrupted_cb) {
47  return is_interrupted_cb();
48  }
49  return false;
50 }
51 
52 RZ_API void rz_print_set_is_interrupted_cb(RzPrintIsInterruptedCallback cb) {
54 }
55 
58  if (!p) {
59  return NULL;
60  }
61  strcpy(p->datefmt, "%Y-%m-%d %H:%M:%S %z");
62  rz_io_bind_init(p->iob);
63  p->pairs = true;
64  p->resetbg = true;
65  p->cb_printf = libc_printf;
66  p->cb_eprintf = libc_eprintf;
67  p->oprintf = nullprinter;
68  p->bits = 32;
69  p->stride = 0;
70  p->bytespace = 0;
71  p->big_endian = false;
72  p->datezone = 0;
73  p->col = 0;
74  p->width = 78;
75  p->cols = 16;
76  p->cur_enabled = false;
77  p->cur = p->ocur = -1;
78  p->addrmod = 4;
79  p->flags =
84  p->seggrn = 4;
85  p->zoom = RZ_NEW0(RzPrintZoom);
86  p->reg = NULL;
87  p->get_register = NULL;
88  p->get_register_value = NULL;
89  p->calc_row_offsets = true;
90  p->row_offsets_sz = 0;
91  p->row_offsets = NULL;
92  p->vflush = true;
93  p->screen_bounds = 0;
94  p->esc_bslash = false;
95  p->strconv_mode = NULL;
96  memset(&p->consbind, 0, sizeof(p->consbind));
97  p->io_unalloc_ch = '.';
98  return p;
99 }
100 
102  if (!p) {
103  return NULL;
104  }
105  RZ_FREE(p->strconv_mode);
106  if (p->zoom) {
107  free(p->zoom->buf);
108  free(p->zoom);
109  p->zoom = NULL;
110  }
111  RZ_FREE(p->row_offsets);
112  free(p);
113  return NULL;
114 }
115 
116 // dummy setter can be removed
117 RZ_API void rz_print_set_flags(RzPrint *p, int _flags) {
118  p->flags = _flags;
119 }
120 
121 RZ_API void rz_print_set_cursor(RzPrint *p, int enable, int ocursor, int cursor) {
122  if (!p) {
123  return;
124  }
125  p->cur_enabled = enable;
126  p->ocur = ocursor;
127  if (cursor < 0) {
128  cursor = 0;
129  }
130  p->cur = cursor;
131 }
132 
133 RZ_API bool rz_print_have_cursor(RzPrint *p, int cur, int len) {
134  if (!p || !p->cur_enabled) {
135  return false;
136  }
137  if (p->ocur != -1) {
138  int from = p->ocur;
139  int to = p->cur;
141  do {
142  if (cur + len - 1 >= from && cur + len - 1 <= to) {
143  return true;
144  }
145  } while (--len);
146  } else if (p->cur >= cur && p->cur <= cur + len - 1) {
147  return true;
148  }
149  return false;
150 }
151 
153  rz_return_val_if_fail(p, false);
154  if (!p->cur_enabled) {
155  return false;
156  }
157  int to = p->cur;
158  do {
159  if (cur + len - 1 == to) {
160  return true;
161  }
162  } while (--len);
163  return false;
164 }
165 
166 RZ_API void rz_print_cursor(RzPrint *p, int cur, int len, int set) {
167  if (rz_print_have_cursor(p, cur, len)) {
168  p->cb_printf("%s", RZ_CONS_INVERT(set, 1));
169  }
170 }
171 
172 RZ_API char *rz_print_hexpair(RzPrint *p, const char *str, int n) {
173  const char *s, *lastcol = Color_WHITE;
174  char *d, *dst = (char *)calloc((strlen(str) + 2), 32);
175  int colors = p->flags & RZ_PRINT_FLAGS_COLOR;
176  const char *color_0x00 = "";
177  const char *color_0x7f = "";
178  const char *color_0xff = "";
179  const char *color_text = "";
180  const char *color_other = "";
181  int bs = p->bytespace;
182  /* XXX That is hacky but it partially works */
183  /* TODO: Use rz_print_set_cursor for win support */
184  int cur = RZ_MIN(p->cur, p->ocur);
185  int ocur = RZ_MAX(p->cur, p->ocur);
186  int ch, i;
187 
188  if (colors) {
189 #define P(x) (p->cons && p->cons->context->pal.x) ? p->cons->context->pal.x
190  color_0x00 = P(b0x00)
191  : Color_GREEN;
192  color_0x7f = P(b0x7f)
193  : Color_YELLOW;
194  color_0xff = P(b0xff)
195  : Color_RED;
196  color_text = P(btext)
197  : Color_MAGENTA;
198  color_other = P(other)
199  : "";
200  }
201  if (p->cur_enabled && cur == -1) {
202  cur = ocur;
203  }
204  ocur++;
205  d = dst;
206 // XXX: overflow here
207 // TODO: Use rz_cons primitives here
208 #define memcat(x, y) \
209  { \
210  memcpy(x, y, strlen(y)); \
211  (x) += strlen(y); \
212  }
213  for (s = str, i = 0; s[0]; i++) {
214  int d_inc = 2;
215  if (p->cur_enabled) {
216  if (i == ocur - n) {
217  memcat(d, Color_RESET);
218  }
219  if (colors) {
220  memcat(d, lastcol);
221  }
222  if (i >= cur - n && i < ocur - n) {
224  }
225  }
226  if (colors) {
227  if (s[0] == '0' && s[1] == '0') {
228  lastcol = color_0x00;
229  } else if (s[0] == '7' && s[1] == 'f') {
230  lastcol = color_0x7f;
231  } else if (s[0] == 'f' && s[1] == 'f') {
232  lastcol = color_0xff;
233  } else {
234  ch = rz_hex_pair2bin(s);
235  if (ch == -1) {
236  break;
237  }
238  if (IS_PRINTABLE(ch)) {
239  lastcol = color_text;
240  } else {
241  lastcol = color_other;
242  }
243  }
244  memcat(d, lastcol);
245  }
246  if (s[0] == '.') {
247  d_inc = 1;
248  }
249  memcpy(d, s, d_inc);
250  d += d_inc;
251  s += d_inc;
252  if (bs) {
253  memcat(d, " ");
254  }
255  }
256  if (colors || p->cur_enabled) {
257  if (p->resetbg) {
258  memcat(d, Color_RESET);
259  } else {
261  }
262  }
263  *d = '\0';
264  return dst;
265 }
266 
267 static char colorbuffer[64];
268 #define P(x) (p->cons && p->cons->context->pal.x) ? p->cons->context->pal.x
269 RZ_API const char *rz_print_byte_color(RzPrint *p, int ch) {
270  if (p->flags & RZ_PRINT_FLAGS_RAINBOW) {
271  // EXPERIMENTAL
272  int bg = (p->flags & RZ_PRINT_FLAGS_NONHEX) ? 48 : 38;
273  snprintf(colorbuffer, sizeof(colorbuffer), "\033[%d;5;%dm", bg, ch);
274  return colorbuffer;
275  }
276  const bool use_color = p->flags & RZ_PRINT_FLAGS_COLOR;
277  if (!use_color) {
278  return NULL;
279  }
280  switch (ch) {
281  case 0x00: return P(b0x00)
282  : Color_GREEN;
283  case 0x7F: return P(b0x7f)
284  : Color_YELLOW;
285  case 0xFF: return P(b0xff)
286  : Color_RED;
287  default: return IS_PRINTABLE(ch) ? P(btext) : Color_MAGENTA : P(other)
288  : Color_WHITE;
289  }
290  return NULL;
291 }
292 
293 static bool checkSparse(const ut8 *p, int len, int ch) {
294  int i;
295  ut8 q = *p;
296  if (ch && ch != q) {
297  return false;
298  }
299  for (i = 1; i < len; i++) {
300  if (p[i] != q) {
301  return false;
302  }
303  }
304  return true;
305 }
306 
307 static bool isAllZeros(const ut8 *buf, int len) {
308  int i;
309  for (i = 0; i < len; i++) {
310  if (buf[i] != 0) {
311  return false;
312  }
313  }
314  return true;
315 }
316 
317 #define Pal(x, y) (x->cons && x->cons->context->pal.y) ? x->cons->context->pal.y
318 RZ_API void rz_print_hexii(RzPrint *rp, ut64 addr, const ut8 *buf, int len, int step) {
319  PrintfCallback p = (PrintfCallback)rp->cb_printf;
320  bool c = rp->flags & RZ_PRINT_FLAGS_COLOR;
321  const char *color_0xff = c ? (Pal(rp, b0xff)
322  : Color_RED)
323  : "";
324  const char *color_text = c ? (Pal(rp, btext)
325  : Color_MAGENTA)
326  : "";
327  const char *color_other = c ? (Pal(rp, other)
328  : Color_WHITE)
329  : "";
330  const char *color_reset = c ? Color_RESET : "";
331  int i, j;
332  bool show_offset = rp->show_offset;
333 
334  if (rp->flags & RZ_PRINT_FLAGS_HEADER) {
335  p(" ");
336  for (i = 0; i < step; i++) {
337  p("%3X", i);
338  }
339  p("\n");
340  }
341 
342  for (i = 0; i < len; i += step) {
343  int inc = RZ_MIN(step, (len - i));
344  if (isAllZeros(buf + i, inc)) {
345  continue;
346  }
347  if (show_offset) {
348  p("%8" PFMT64x ":", addr + i);
349  }
350  for (j = 0; j < inc; j++) {
351  ut8 ch = buf[i + j];
352  if (ch == 0x00) {
353  p(" ");
354  } else if (ch == 0xff) {
355  p("%s ##%s", color_0xff, color_reset);
356  } else if (IS_PRINTABLE(ch)) {
357  p("%s .%c%s", color_text, ch, color_reset);
358  } else {
359  p("%s %02x%s", color_other, ch, color_reset);
360  }
361  }
362  p("\n");
363  }
364  p("%8" PFMT64x " ]\n", addr + i);
365 }
366 
378 
379  if (!p->screen_bounds) {
380  return;
381  }
382  if (!p->consbind.get_size) {
383  return;
384  }
385  if (!p->consbind.get_cursor) {
386  return;
387  }
388 
389  if (p->screen_bounds == 1) {
390  int rc;
391  if (!p->rows) {
392  (void)p->consbind.get_size(&p->rows);
393  }
394  (void)p->consbind.get_cursor(&rc);
395 
396  if (rc > p->rows - 1) {
397  p->screen_bounds = addr;
398  p->rows = 0;
399  }
400  }
401 }
402 
403 static inline void print_addr(RzStrBuf *sb, RzPrint *p, ut64 addr) {
404  char space[32] = {
405  0
406  };
407  const char *white = "";
408 #define PREOFF(x) (p && p->cons && p->cons->context && p->cons->context->pal.x) ? p->cons->context->pal.x
409  bool use_segoff = p ? (p->flags & RZ_PRINT_FLAGS_SEGOFF) : false;
410  bool use_color = p ? (p->flags & RZ_PRINT_FLAGS_COLOR) : false;
411  bool dec = p ? (p->flags & RZ_PRINT_FLAGS_ADDRDEC) : false;
412  bool mod = p ? (p->flags & RZ_PRINT_FLAGS_ADDRMOD) : false;
413  char ch = p ? ((p->addrmod && mod) ? ((addr % p->addrmod) ? ' ' : ',') : ' ') : ' ';
414  if (p && p->flags & RZ_PRINT_FLAGS_COMPACT && p->col == 1) {
415  ch = '|';
416  }
417  if (p && p->pava) {
418  ut64 va = p->iob.p2v(p->iob.io, addr);
419  if (va != UT64_MAX) {
420  addr = va;
421  }
422  }
423  if (use_segoff) {
424  ut32 s, a;
425  a = addr & 0xffff;
426  s = (addr - a) >> (p ? p->seggrn : 0);
427  if (dec) {
428  snprintf(space, sizeof(space), "%d:%d", s & 0xffff, a & 0xffff);
429  white = rz_str_pad(' ', 9 - strlen(space));
430  }
431  if (use_color) {
432  const char *pre = PREOFF(offset)
433  : Color_GREEN;
434  const char *fin = Color_RESET;
435  if (dec) {
436  rz_strbuf_appendf(sb, "%s%s%s%s%c", pre, white, space, fin, ch);
437  } else {
438  rz_strbuf_appendf(sb, "%s%04x:%04x%s%c", pre, s & 0xffff, a & 0xffff, fin, ch);
439  }
440  } else {
441  if (dec) {
442  rz_strbuf_appendf(sb, "%s%s%c", white, space, ch);
443  } else {
444  rz_strbuf_appendf(sb, "%04x:%04x%c", s & 0xffff, a & 0xffff, ch);
445  }
446  }
447  } else {
448  if (dec) {
449  snprintf(space, sizeof(space), "%" PFMT64d, addr);
450  int w = RZ_MAX(10 - strlen(space), 0);
451  white = rz_str_pad(' ', w);
452  }
453  if (use_color) {
454  const char *pre = PREOFF(offset)
455  : Color_GREEN;
456  const char *fin = Color_RESET;
457  if (p && p->flags & RZ_PRINT_FLAGS_RAINBOW) {
458  // pre = rz_cons_rgb_str_off (rgbstr, addr);
459  if (p->cons && p->cons->rgbstr) {
460  static char rgbstr[32];
461  pre = p->cons->rgbstr(rgbstr, sizeof(rgbstr), addr);
462  }
463  }
464  if (dec) {
465  rz_strbuf_appendf(sb, "%s%s%" PFMT64d "%s%c", pre, white, addr, fin, ch);
466  } else {
467  if (p && p->wide_offsets) {
468  // TODO: make %016 depend on asm.bits
469  rz_strbuf_appendf(sb, "%s0x%016" PFMT64x "%s%c", pre, addr, fin, ch);
470  } else {
471  rz_strbuf_appendf(sb, "%s0x%08" PFMT64x "%s%c", pre, addr, fin, ch);
472  }
473  }
474  } else {
475  if (dec) {
476  rz_strbuf_appendf(sb, "%s%" PFMT64d "%c", white, addr, ch);
477  } else {
478  if (p && p->wide_offsets) {
479  // TODO: make %016 depend on asm.bits
480  rz_strbuf_appendf(sb, "0x%016" PFMT64x "%c", addr, ch);
481  } else {
482  rz_strbuf_appendf(sb, "0x%08" PFMT64x "%c", addr, ch);
483  }
484  }
485  }
486  }
487 }
488 
491  RzStrBuf sb;
492  rz_strbuf_init(&sb);
493  print_addr(&sb, p, addr);
494  char *s = rz_strbuf_drain_nofree(&sb);
495  p->cb_printf("%s", s);
496  free(s);
497 }
498 
499 static inline void print_section(RzStrBuf *sb, RzPrint *p, ut64 at) {
500  bool use_section = p && p->flags & RZ_PRINT_FLAGS_SECTION;
501  if (!use_section) {
502  return;
503  }
504  const char *s = p->get_section_name(p->user, at);
505  if (!s) {
506  s = "";
507  }
508  rz_strbuf_appendf(sb, "%20s ", s);
509 }
510 
513  RzStrBuf sb;
514  rz_strbuf_init(&sb);
515  print_section(&sb, p, at);
516  return rz_strbuf_drain_nofree(&sb);
517 }
518 
519 static inline void print_cursor_l(RzStrBuf *sb, RzPrint *p, int cur, int len) {
520  if (rz_print_have_cursor(p, cur, len)) {
521  rz_strbuf_append(sb, RZ_CONS_INVERT(1, 1));
522  }
523 }
524 
525 static inline void print_cursor_r(RzStrBuf *sb, RzPrint *p, int cur, int len) {
526  if (rz_print_have_cursor(p, cur, len)) {
527  rz_strbuf_append(sb, RZ_CONS_INVERT(0, 1));
528  }
529 }
530 
531 static inline void print_byte(RzStrBuf *sb, RzPrint *p, const char *fmt, int idx, ut8 ch) {
532  ut8 rch = ch;
533  if (!IS_PRINTABLE(ch) && fmt[0] == '%' && fmt[1] == 'c') {
534  rch = '.';
535  }
536  print_cursor_l(sb, p, idx, 1);
537  if (p && p->flags & RZ_PRINT_FLAGS_COLOR) {
538  const char *bytecolor = rz_print_byte_color(p, ch);
539  if (bytecolor) {
540  rz_strbuf_append(sb, bytecolor);
541  }
542  rz_strbuf_appendf(sb, fmt, rch);
543  if (bytecolor) {
545  }
546  } else {
547  rz_strbuf_appendf(sb, fmt, rch);
548  }
549  print_cursor_r(sb, p, idx, 1);
550 }
551 
552 RZ_API void rz_print_byte(RzPrint *p, const char *fmt, int idx, ut8 ch) {
553  rz_return_if_fail(p && fmt);
554  RzStrBuf sb;
555  rz_strbuf_init(&sb);
556  print_byte(&sb, p, fmt, idx, ch);
557  char *s = rz_strbuf_drain_nofree(&sb);
558  p->cb_printf("%s", s);
559  free(s);
560 }
561 
574  int len, int base, int step, size_t zoomsz) {
575  rz_return_val_if_fail(p && buf && len > 0, NULL);
577  if (!sb) {
578  return NULL;
579  }
580  bool pairs = p->pairs;
581  bool use_sparse = p->flags & RZ_PRINT_FLAGS_SPARSE;
582  bool use_header = p->flags & RZ_PRINT_FLAGS_HEADER;
583  bool use_hdroff = p->flags & RZ_PRINT_FLAGS_HDROFF;
584  bool use_segoff = p->flags & RZ_PRINT_FLAGS_SEGOFF;
585  bool use_align = p->flags & RZ_PRINT_FLAGS_ALIGN;
586  bool use_offset = p->flags & RZ_PRINT_FLAGS_OFFSET;
587  bool hex_style = p->flags & RZ_PRINT_FLAGS_STYLE;
588  bool use_hexa = !(p->flags & RZ_PRINT_FLAGS_NONHEX);
589  bool use_unalloc = p->flags & RZ_PRINT_FLAGS_UNALLOC;
590  bool compact = p->flags & RZ_PRINT_FLAGS_COMPACT;
591  int inc = p->cols; // row width
592  int col = p->col; // selected column (0=none, 1=hex, 2=ascii)
593  int stride = p->stride;
594 
595  size_t i, j;
596  int sparse_char = 0;
597  const char *bytefmt = "%02x";
598  const char *pre = "";
599  int last_sparse = 0;
600  const char *a, *b;
601 
602  if (step < len) {
603  len = len - (len % step);
604  }
605  if (!use_hexa) {
606  inc *= 4;
607  }
608  if (step < 1) {
609  step = 1;
610  }
611  if (inc < 1) {
612  inc = 1;
613  }
614  if (zoomsz < 1) {
615  zoomsz = 1;
616  }
617  switch (base) {
618  case -10:
619  bytefmt = "0x%08x ";
620  pre = " ";
621  if (inc < 4) {
622  inc = 4;
623  }
624  break;
625  case -1:
626  bytefmt = "0x%08x ";
627  pre = " ";
628  if (inc < 4) {
629  inc = 4;
630  }
631  break;
632  case 8:
633  bytefmt = "%03o";
634  pre = " ";
635  break;
636  case 10:
637  bytefmt = "%3d";
638  pre = " ";
639  break;
640  case 16:
641  if (inc < 2) {
642  inc = 2;
643  use_header = false;
644  }
645  break;
646  case 32:
647  bytefmt = "0x%08x ";
648  pre = " ";
649  if (inc < 4) {
650  inc = 4;
651  }
652  break;
653  case 64:
654  bytefmt = "0x%016x ";
655  pre = " ";
656  if (inc < 8) {
657  inc = 8;
658  }
659  break;
660  }
661  const char *space = hex_style ? "." : " ";
662  // TODO: Use base to change %03o and so on
663  if (step == 1 && base < 0) {
664  use_header = false;
665  }
666  if (use_header) {
667  bool c = p->flags & RZ_PRINT_FLAGS_COLOR;
668  if (c) {
669  const char *color_title = Pal(p, offset)
670  : Color_MAGENTA;
671  rz_strbuf_append(sb, color_title);
672  }
673  if (base < 32) {
674  { // XXX: use rz_print_addr_header
675  int i, delta;
676  char soff[32];
677  if (hex_style) {
678  rz_strbuf_append(sb, "..offset..");
679  } else {
680  rz_strbuf_append(sb, "- offset -");
681  if (p->wide_offsets) {
682  rz_strbuf_append(sb, " ");
683  }
684  }
685  if (use_segoff) {
686  ut32 s, a;
687  a = addr & 0xffff;
688  s = ((addr - a) >> p->seggrn) & 0xffff;
689  snprintf(soff, sizeof(soff), "%04x:%04x ", s, a);
690  delta = strlen(soff) - 10;
691  } else {
692  snprintf(soff, sizeof(soff), "0x%08" PFMT64x, addr);
693  delta = strlen(soff) - 9;
694  }
695  if (compact) {
696  delta--;
697  }
698  for (i = 0; i < delta; i++) {
699  rz_strbuf_append(sb, space);
700  }
701  }
702  ut32 K = 0;
703  ut32 k = 0;
704  /* column after number, before hex data */
705  rz_strbuf_append(sb, (col == 1) ? "|" : space);
706  if (use_hdroff) {
707  k = addr & 0xf;
708  K = (addr >> 4) & 0xf;
709  } else {
710  k = 0; // TODO: ??? SURE??? config.seek & 0xF;
711  }
712  if (use_hexa) {
713  /* extra padding for offsets > 8 digits */
714  for (i = 0; i < inc; i++) {
715  rz_strbuf_append(sb, pre);
716  if (base < 0) {
717  if (i & 1) {
718  rz_strbuf_append(sb, space);
719  }
720  }
721  if (use_hdroff) {
722  if (pairs) {
723  rz_strbuf_appendf(sb, "%c%c",
724  hex[(((i + k) >> 4) + K) % 16],
725  hex[(i + k) % 16]);
726  } else {
727  rz_strbuf_appendf(sb, " %c", hex[(i + k) % 16]);
728  }
729  } else {
730  rz_strbuf_appendf(sb, " %c", hex[(i + k) % 16]);
731  }
732  if (i & 1 || !pairs) {
733  if (!compact) {
734  rz_strbuf_append(sb, col != 1 ? space : ((i + 1) < inc) ? space
735  : "|");
736  }
737  }
738  }
739  }
740  /* ascii column */
741  if (compact) {
742  rz_strbuf_append(sb, col > 0 ? "|" : space);
743  } else {
744  rz_strbuf_append(sb, col == 2 ? "|" : space);
745  }
746  if (!(p->flags & RZ_PRINT_FLAGS_NONASCII)) {
747  for (i = 0; i < inc; i++) {
748  rz_strbuf_appendf(sb, "%c", hex[(i + k) % 16]);
749  }
750  }
751  if (col == 2) {
752  rz_strbuf_append(sb, "|");
753  }
754  /* print comment header*/
755  if (p->use_comments && !compact) {
756  if (col != 2) {
757  rz_strbuf_append(sb, " ");
758  }
759  if (!hex_style) {
760  rz_strbuf_append(sb, " comment");
761  }
762  }
763  rz_strbuf_append(sb, "\n");
764  }
765 
766  if (c) {
768  }
769  }
770 
771  // is this necessary?
773  int rowbytes;
774  int rows = 0;
775  int bytes = 0;
776  bool printValue = true;
777  bool oPrintValue = true;
778  bool isPxr = p->flags & RZ_PRINT_FLAGS_REFS;
779 
780  for (i = j = 0; i < len; i += (stride ? stride : inc)) {
781  if (p->cons && p->cons->context && p->cons->context->breaked) {
782  break;
783  }
784  rowbytes = inc;
785  if (use_align) {
786  int sz = p->offsize ? p->offsize(p->user, addr + j) : -1;
787  if (sz > 0) { // flags with size 0 dont work
788  rowbytes = sz;
789  }
790  }
791 
792  if (use_sparse) {
793  if (checkSparse(buf + i, inc, sparse_char)) {
794  if (i + inc >= len || checkSparse(buf + i + inc, inc, sparse_char)) {
795  if (i + inc + inc >= len ||
796  checkSparse(buf + i + inc + inc, inc, sparse_char)) {
797  sparse_char = buf[j];
798  last_sparse++;
799  if (last_sparse == 2) {
800  rz_strbuf_append(sb, " ...\n");
801  continue;
802  }
803  if (last_sparse > 2) {
804  continue;
805  }
806  }
807  }
808  } else {
809  last_sparse = 0;
810  }
811  }
812  ut64 at = addr + (j * zoomsz);
813  if (use_offset && (!isPxr || inc < 4)) {
814  print_section(sb, p, at);
815  print_addr(sb, p, at);
816  }
817  int row_have_cursor = -1;
818  ut64 row_have_addr = UT64_MAX;
819  if (use_hexa) {
820  if (!compact && !isPxr) {
821  rz_strbuf_append(sb, (col == 1) ? "|" : " ");
822  }
823  for (j = i; j < i + inc; j++) {
824  if (j != i && use_align && rowbytes == inc) {
825  int sz = p->offsize ? p->offsize(p->user, addr + j) : -1;
826  if (sz >= 0) {
827  rowbytes = bytes;
828  }
829  }
830  if (row_have_cursor == -1) {
831  if (rz_print_cursor_pointer(p, j, 1)) {
832  row_have_cursor = j - i;
833  row_have_addr = addr + j;
834  }
835  }
836  if (!compact && ((j >= len) || bytes >= rowbytes)) {
837  if (col == 1) {
838  if (j + 1 >= inc + i) {
839  rz_strbuf_append(sb, j % 2 ? " |" : "| ");
840  } else {
841  rz_strbuf_append(sb, j % 2 ? " " : " ");
842  }
843  } else {
844  if (base == 32) {
845  rz_strbuf_append(sb, (j % 4) ? " " : " ");
846  } else if (base == 10) {
847  rz_strbuf_append(sb, j % 2 ? " " : " ");
848  } else {
849  rz_strbuf_append(sb, j % 2 ? " " : " ");
850  }
851  }
852  continue;
853  }
854  const char *hl = (hex_style && p->offname(p->user, addr + j)) ? Color_INVERT : NULL;
855  if (hl) {
856  rz_strbuf_append(sb, hl);
857  }
858  if ((base == 32 || base == 64)) {
859  int left = len - i;
860  /* TODO: check step. it should be 2/4 for base(32) and 8 for
861  * base(64) */
862  ut64 n = 0;
863  size_t sz_n = (base == 64)
864  ? sizeof(ut64)
865  : (step == 2)
866  ? sizeof(ut16)
867  : sizeof(ut32);
868  sz_n = RZ_MIN(left, sz_n);
869  if (j + sz_n > len) {
870  // oob
871  j += sz_n;
872  continue;
873  }
874  rz_mem_swaporcopy((ut8 *)&n, buf + j, sz_n, p->big_endian);
875  print_cursor_l(sb, p, j, sz_n);
876  // stub for colors
877  if (p->colorfor) {
878  if (!p->iob.addr_is_mapped(p->iob.io, addr + j)) {
879  a = p->cons->context->pal.ai_unmap;
880  } else {
881  a = p->colorfor(p->user, n, true);
882  }
883  if (a && *a) {
884  b = Color_RESET;
885  } else {
886  a = b = "";
887  }
888  } else {
889  a = b = "";
890  }
891  printValue = true;
892  bool hasNull = false;
893  if (isPxr) {
894  if (n == 0) {
895  if (oPrintValue) {
896  hasNull = true;
897  }
898  printValue = false;
899  }
900  }
901  if (printValue) {
902  if (use_offset && !hasNull && isPxr) {
903  print_section(sb, p, at);
904  print_addr(sb, p, addr + j * zoomsz);
905  }
906  if (base == 64) {
907  rz_strbuf_appendf(sb, "%s0x%016" PFMT64x "%s ", a, (ut64)n, b);
908  } else if (step == 2) {
909  rz_strbuf_appendf(sb, "%s0x%04x%s ", a, (ut16)n, b);
910  } else {
911  rz_strbuf_appendf(sb, "%s0x%08x%s ", a, (ut32)n, b);
912  }
913  } else {
914  if (hasNull) {
915  const char *n = p->offname(p->user, addr + j);
916  print_section(sb, p, at);
917  print_addr(sb, p, addr + j * zoomsz);
918  rz_strbuf_appendf(sb, "..[ null bytes ].. 00000000 %s\n", n ? n : "");
919  }
920  }
921  print_cursor_r(sb, p, j, sz_n);
922  oPrintValue = printValue;
923  j += step - 1;
924  } else if (base == -8) {
925  long long w = rz_read_ble64(buf + j, p->big_endian);
926  print_cursor_l(sb, p, j, 8);
927  rz_strbuf_appendf(sb, "%23" PFMT64d " ", w);
928  print_cursor_r(sb, p, j, 8);
929  j += 7;
930  } else if (base == -1) {
931  st8 w = rz_read_ble8(buf + j);
932  print_cursor_l(sb, p, j, 1);
933  rz_strbuf_appendf(sb, "%4d ", w);
934  print_cursor_r(sb, p, j, 1);
935  } else if (base == -10) {
936  if (j + 1 < len) {
937  st16 w = rz_read_ble16(buf + j, p->big_endian);
938  print_cursor_l(sb, p, j, 2);
939  rz_strbuf_appendf(sb, "%7d ", w);
940  print_cursor_r(sb, p, j, 2);
941  }
942  j += 1;
943  } else if (base == 10) { // "pxd"
944  if (j + 3 < len) {
945  int w = rz_read_ble32(buf + j, p->big_endian);
946  print_cursor_l(sb, p, j, 4);
947  rz_strbuf_appendf(sb, "%13d ", w);
948  print_cursor_r(sb, p, j, 4);
949  }
950  j += 3;
951  } else {
952  if (j >= len) {
953  break;
954  }
955  if (use_unalloc && !p->iob.is_valid_offset(p->iob.io, addr + j, false)) {
956  char ch = p->io_unalloc_ch;
957  char dbl_ch_str[] = { ch, ch, 0 };
958  rz_strbuf_appendf(sb, "%s", dbl_ch_str);
959  } else {
960  print_byte(sb, p, bytefmt, j, buf[j]);
961  }
962  if (pairs && !compact && (inc & 1)) {
963  bool mustspace = (rows % 2) ? !(j & 1) : (j & 1);
964  if (mustspace) {
965  rz_strbuf_append(sb, " ");
966  }
967  } else if (bytes % 2 || !pairs) {
968  if (col == 1) {
969  if (j + 1 < inc + i) {
970  if (!compact) {
971  rz_strbuf_append(sb, " ");
972  }
973  } else {
974  rz_strbuf_append(sb, "|");
975  }
976  } else {
977  if (!compact) {
978  rz_strbuf_append(sb, " ");
979  }
980  }
981  }
982  }
983  if (hl) {
985  }
986  bytes++;
987  }
988  }
989  if (printValue) {
990  if (compact) {
991  if (col == 0) {
992  rz_strbuf_append(sb, " ");
993  } else if (col == 1) {
994  // print (" ");
995  } else {
996  rz_strbuf_append(sb, (col == 2) ? "|" : "");
997  }
998  } else {
999  rz_strbuf_append(sb, (col == 2) ? "|" : " ");
1000  }
1001  if (!p || !(p->flags & RZ_PRINT_FLAGS_NONASCII)) {
1002  bytes = 0;
1003  size_t end = i + inc;
1004  for (j = i; j < end; j++) {
1005  if (j != i && use_align && bytes >= rowbytes) {
1006  int sz = (p->offsize) ? p->offsize(p->user, addr + j) : -1;
1007  if (sz >= 0) {
1008  rz_strbuf_append(sb, " ");
1009  break;
1010  }
1011  }
1012  if (j >= len || (use_align && bytes >= rowbytes)) {
1013  break;
1014  }
1015  ut8 ch = (use_unalloc && !p->iob.is_valid_offset(p->iob.io, addr + j, false))
1016  ? ' '
1017  : buf[j];
1018  print_byte(sb, p, "%c", j, ch);
1019  bytes++;
1020  }
1021  }
1022  /* ascii column */
1023  if (col == 2) {
1024  rz_strbuf_append(sb, "|");
1025  }
1026  bool eol = false;
1027  if (!eol && p->flags & RZ_PRINT_FLAGS_REFS) {
1028  ut64 off = UT64_MAX;
1029  if (inc == 8) {
1030  if (i + sizeof(ut64) - 1 < len) {
1031  off = rz_read_le64(buf + i);
1032  }
1033  } else if (inc == 4) {
1034  if (i + sizeof(ut32) - 1 < len) {
1035  off = rz_read_le32(buf + i);
1036  }
1037  } else if (inc == 2 && base == 16) {
1038  if (i + sizeof(ut16) - 1 < len) {
1039  off = rz_read_le16(buf + i);
1040  if (off == 0) {
1041  off = UT64_MAX;
1042  }
1043  }
1044  }
1045  if (p->hasrefs && off != UT64_MAX) {
1046  char *rstr = p->hasrefs(p->user, addr + i, false);
1047  if (rstr && *rstr) {
1048  rz_strbuf_appendf(sb, " @ %s", rstr);
1049  }
1050  free(rstr);
1051  rstr = p->hasrefs(p->user, off, true);
1052  if (rstr && *rstr) {
1053  rz_strbuf_appendf(sb, " %s", rstr);
1054  }
1055  free(rstr);
1056  }
1057  }
1058  if (!eol && p->use_comments) {
1059  for (; j < i + inc; j++) {
1060  rz_strbuf_append(sb, " ");
1061  }
1062  for (j = i; j < i + inc; j++) {
1063  if (use_align && (j - i) >= rowbytes) {
1064  break;
1065  }
1066  if (p->offname) {
1067  a = p->offname(p->user, addr + j);
1068  if (p->colorfor && a && *a) {
1069  const char *color = p->colorfor(p->user, addr + j, true);
1070  rz_strbuf_appendf(sb, "%s ; %s%s", color ? color : "", a,
1071  color ? Color_RESET : "");
1072  }
1073  }
1074  char *comment = p->get_comments(p->user, addr + j);
1075  if (comment) {
1076  if (p->colorfor) {
1077  a = p->colorfor(p->user, addr + j, true);
1078  if (!a || !*a) {
1079  a = "";
1080  }
1081  } else {
1082  a = "";
1083  }
1084  rz_strbuf_appendf(sb, "%s ; %s", a, comment);
1085  free(comment);
1086  }
1087  }
1088  }
1089  if (use_align && rowbytes < inc && bytes >= rowbytes) {
1090  i -= (inc - bytes);
1091  }
1092  rz_strbuf_append(sb, "\n");
1093  }
1094  rows++;
1095  bytes = 0;
1096  if (p->cfmt && *p->cfmt) {
1097  if (row_have_cursor != -1) {
1098  int i = 0;
1099  rz_strbuf_append(sb, " _________");
1100  if (!compact) {
1101  rz_strbuf_append(sb, "_");
1102  }
1103  for (i = 0; i < row_have_cursor; i++) {
1104  if (!pairs || (!compact && i % 2)) {
1105  rz_strbuf_append(sb, "___");
1106  } else {
1107  rz_strbuf_append(sb, "__");
1108  }
1109  }
1110  rz_strbuf_append(sb, "__|\n");
1111  rz_strbuf_appendf(sb, "| cmd.hexcursor = %s\n", p->cfmt);
1112  p->coreb.cmdf(p->coreb.core,
1113  "%s @ 0x%08" PFMT64x, p->cfmt, row_have_addr);
1114  }
1115  }
1116  }
1117  return rz_strbuf_drain(sb);
1118 }
1119 
1120 static const char *getbytediff(RzPrint *p, char *fmt, ut8 a, ut8 b) {
1121  if (*fmt) {
1122  if (a == b) {
1123  sprintf(fmt, "%s%02x" Color_RESET, p->cons->context->pal.graph_true, a);
1124  } else {
1125  sprintf(fmt, "%s%02x" Color_RESET, p->cons->context->pal.graph_false, a);
1126  }
1127  } else {
1128  sprintf(fmt, "%02x", a);
1129  }
1130  return fmt;
1131 }
1132 
1133 static const char *getchardiff(RzPrint *p, char *fmt, ut8 a, ut8 b) {
1134  char ch = IS_PRINTABLE(a) ? a : '.';
1135  if (*fmt) {
1136  if (a == b) {
1137  sprintf(fmt, "%s%c" Color_RESET, p->cons->context->pal.graph_true, ch);
1138  } else {
1139  sprintf(fmt, "%s%c" Color_RESET, p->cons->context->pal.graph_false, ch);
1140  }
1141  } else {
1142  sprintf(fmt, "%c", ch);
1143  }
1144  // else { fmt[0] = ch; fmt[1]=0; }
1145  return fmt;
1146 }
1147 
1148 #define BD(a, b) getbytediff(p, fmt, (a)[i + j], (b)[i + j])
1149 #define CD(a, b) getchardiff(p, fmt, (a)[i + j], (b)[i + j])
1150 
1151 static ut8 *M(const ut8 *b, int len) {
1152  ut8 *r = malloc(len + 16);
1153  if (r) {
1154  memset(r, 0xff, len + 16);
1155  memcpy(r, b, len);
1156  }
1157  return r;
1158 }
1159 
1171 // TODO: add support for cursor
1173  ut64 ba, RZ_NONNULL const ut8 *_b, int len, int scndcol) {
1174  rz_return_val_if_fail(p && _a && _b && len > 0, NULL);
1175  ut8 *a, *b;
1176  char linediff, fmt[64];
1177  int color = p->flags & RZ_PRINT_FLAGS_COLOR;
1178  int diffskip = p->flags & RZ_PRINT_FLAGS_DIFFOUT;
1179  int i, j, min;
1181  if (!((a = M(_a, len)))) {
1182  return NULL;
1183  }
1184  if (!((b = M(_b, len)))) {
1185  free(a);
1186  return NULL;
1187  }
1188  for (i = 0; i < len; i += 16) {
1189  min = RZ_MIN(16, len - i);
1190  linediff = (memcmp(a + i, b + i, min)) ? '!' : '|';
1191  if (diffskip && linediff == '|') {
1192  continue;
1193  }
1194  rz_strbuf_appendf(sb, "0x%08" PFMT64x " ", aa + i);
1195  for (j = 0; j < min; j++) {
1196  *fmt = color;
1197  print_cursor_l(sb, p, i + j, 1);
1198  rz_strbuf_appendf(sb, "%s", BD(a, b));
1199  print_cursor_r(sb, p, i + j, 1);
1200  }
1201  rz_strbuf_append(sb, " ");
1202  for (j = 0; j < min; j++) {
1203  *fmt = color;
1204  print_cursor_l(sb, p, i + j, 1);
1205  rz_strbuf_appendf(sb, "%s", CD(a, b));
1206  print_cursor_r(sb, p, i + j, 1);
1207  }
1208  if (scndcol) {
1209  rz_strbuf_appendf(sb, " %c 0x%08" PFMT64x " ", linediff, ba + i);
1210  for (j = 0; j < min; j++) {
1211  *fmt = color;
1212  print_cursor_r(sb, p, i + j, 1);
1213  rz_strbuf_appendf(sb, "%s", BD(b, a));
1214  print_cursor_r(sb, p, i + j, 1);
1215  }
1216  rz_strbuf_append(sb, " ");
1217  for (j = 0; j < min; j++) {
1218  *fmt = color;
1219  print_cursor_r(sb, p, i + j, 1);
1220  rz_strbuf_appendf(sb, "%s", CD(b, a));
1221  print_cursor_r(sb, p, i + j, 1);
1222  }
1223  rz_strbuf_append(sb, "\n");
1224  } else {
1225  rz_strbuf_appendf(sb, " %c\n", linediff);
1226  }
1227  }
1228  free(a);
1229  free(b);
1230  return rz_strbuf_drain(sb);
1231 }
1232 
1233 RZ_API void rz_print_bytes(RzPrint *p, const ut8 *buf, int len, const char *fmt) {
1234  rz_return_if_fail(fmt);
1235  int i;
1236  if (p) {
1237  for (i = 0; i < len; i++) {
1238  p->cb_printf(fmt, buf[i]);
1239  }
1240  p->cb_printf("\n");
1241  } else {
1242  for (i = 0; i < len; i++) {
1243  printf(fmt, buf[i]);
1244  }
1245  printf("\n");
1246  }
1247 }
1248 
1249 RZ_API void rz_print_raw(RzPrint *p, ut64 addr, const ut8 *buf, int len) {
1250  p->write(buf, len);
1251 }
1252 
1253 // HACK :D
1254 static RzPrint staticp = {
1256 };
1257 
1258 /* TODO: handle screen width */
1259 RZ_API void rz_print_progressbar(RzPrint *p, int pc, int _cols) {
1260  // TODO: add support for colors
1261  int i, cols = (_cols == -1) ? 78 : _cols;
1262  if (!p) {
1263  p = &staticp;
1264  }
1265  const char *h_line = p->cons->use_utf8 ? RUNE_LONG_LINE_HORIZ : "-";
1266  const char *block = p->cons->use_utf8 ? UTF_BLOCK : "#";
1267 
1268  pc = RZ_MAX(0, RZ_MIN(100, pc));
1269  if (p->flags & RZ_PRINT_FLAGS_HEADER) {
1270  p->cb_printf("%4d%% ", pc);
1271  }
1272  cols -= 15;
1273  p->cb_printf("[");
1274  for (i = cols * pc / 100; i; i--) {
1275  p->cb_printf("%s", block);
1276  }
1277  for (i = cols - (cols * pc / 100); i; i--) {
1278  p->cb_printf("%s", h_line);
1279  }
1280  p->cb_printf("]");
1281 }
1282 
1283 RZ_API void rz_print_rangebar(RzPrint *p, ut64 startA, ut64 endA, ut64 min, ut64 max, int cols) {
1284  const char *h_line = p->cons->use_utf8 ? RUNE_LONG_LINE_HORIZ : "-";
1285  const char *block = p->cons->use_utf8 ? UTF_BLOCK : "#";
1286  const bool show_colors = p->flags & RZ_PRINT_FLAGS_COLOR;
1287  int j = 0;
1288  p->cb_printf("|");
1289  if (cols < 1) {
1290  cols = 1;
1291  }
1292  int mul = (max - min) / cols;
1293  bool isFirst = true;
1294  for (j = 0; j < cols; j++) {
1295  ut64 startB = min + (j * mul);
1296  ut64 endB = min + ((j + 1) * mul);
1297  if (startA <= endB && endA >= startB) {
1298  if (show_colors & isFirst) {
1299  p->cb_printf(Color_GREEN);
1300  isFirst = false;
1301  }
1302  p->cb_printf("%s", block);
1303  } else {
1304  if (!isFirst) {
1305  p->cb_printf(Color_RESET);
1306  }
1307  p->cb_printf("%s", h_line);
1308  }
1309  }
1310  p->cb_printf("|");
1311 }
1312 
1313 static inline void printHistBlock(RzPrint *p, int k, int cols) {
1314  RzConsPrintablePalette *pal = &p->cons->context->pal;
1315  const char *h_line = p->cons->use_utf8 ? RUNE_LONG_LINE_HORIZ : "-";
1316  const char *block = p->cons->use_utf8 ? UTF_BLOCK : "#";
1317  const char *kol[5];
1318  kol[0] = pal->nop;
1319  kol[1] = pal->mov;
1320  kol[2] = pal->cjmp;
1321  kol[3] = pal->jmp;
1322  kol[4] = pal->call;
1323  if (cols < 1) {
1324  cols = 1;
1325  }
1326  const bool show_colors = (p && (p->flags & RZ_PRINT_FLAGS_COLOR));
1327  if (show_colors) {
1328  int idx = (int)((k * 4) / cols);
1329  if (idx < 5) {
1330  const char *str = kol[idx];
1331  if (p->histblock) {
1332  p->cb_printf("%s%s%s", str, block, Color_RESET);
1333  } else {
1334  p->cb_printf("%s%s%s", str, h_line, Color_RESET);
1335  }
1336  }
1337  } else {
1338  if (p->histblock) {
1339  p->cb_printf("%s", block);
1340  } else {
1341  p->cb_printf("%s", h_line);
1342  }
1343  }
1344 }
1345 
1346 RZ_API void rz_print_fill(RzPrint *p, const ut8 *arr, int size, ut64 addr, int step) {
1347  rz_return_if_fail(p && arr);
1348  const bool show_colors = (p && (p->flags & RZ_PRINT_FLAGS_COLOR));
1349  const bool show_offset = (p && (p->flags & RZ_PRINT_FLAGS_OFFSET));
1350  bool useUtf8 = p->cons->use_utf8;
1351  const char *v_line = useUtf8 ? RUNE_LINE_VERT : "|";
1352  int i = 0, j;
1353 
1354 #define INC 5
1355 #if TOPLINE
1356  if (arr[0] > 1) {
1357  p->cb_printf(" ");
1358  if (addr != UT64_MAX && step > 0) {
1359  p->cb_printf(" ");
1360  }
1361  if (arr[0] > 1) {
1362  for (i = 0; i < arr[0]; i += INC) {
1363  p->cb_printf(h_line);
1364  }
1365  }
1366  p->cb_printf("\n");
1367  }
1368 #endif
1369  // get the max of columns
1370  int cols = 0;
1371  for (i = 0; i < size; i++) {
1372  cols = arr[i] > cols ? arr[i] : cols;
1373  }
1374  cols /= 5;
1375  for (i = 0; i < size; i++) {
1376  ut8 next = (i + 1 < size) ? arr[i + 1] : 0;
1377  int base = 0, k = 0;
1378  if (addr != UT64_MAX && step > 0) {
1379  ut64 at = addr + (i * step);
1380  if (show_offset) {
1381  if (p->cur_enabled) {
1382  if (i == p->cur) {
1383  p->cb_printf(Color_INVERT "> 0x%08" PFMT64x " " Color_RESET, at);
1384  if (p->num) {
1385  p->num->value = at;
1386  }
1387  } else {
1388  p->cb_printf(" 0x%08" PFMT64x " ", at);
1389  }
1390  } else {
1391  p->cb_printf("0x%08" PFMT64x " ", at);
1392  }
1393  }
1394  p->cb_printf("%03x %04x %s", i, arr[i], v_line);
1395  } else {
1396  p->cb_printf("%s", v_line);
1397  }
1398  if (next < INC) {
1399  base = 1;
1400  }
1401  if (next < arr[i]) {
1402  if (arr[i] > INC) {
1403  for (j = 0; j < next + base; j += INC) {
1404  printHistBlock(p, k, cols);
1405  k++;
1406  }
1407  }
1408  for (j = next + INC; j + base < arr[i]; j += INC) {
1409  printHistBlock(p, k, cols);
1410  k++;
1411  }
1412  } else {
1413  printHistBlock(p, k, cols);
1414  k++;
1415  }
1416  if (i + 1 == size) {
1417  for (j = arr[i] + INC + base; j + base < next; j += INC) {
1418  printHistBlock(p, k, cols);
1419  k++;
1420  }
1421  } else if (arr[i + 1] > arr[i]) {
1422  for (j = arr[i] + INC + base; j + base < next; j += INC) {
1423  printHistBlock(p, k, cols);
1424  k++;
1425  }
1426  }
1427  if (show_colors) {
1428  p->cb_printf("%s", Color_RESET);
1429  }
1430  p->cb_printf("\n");
1431  }
1432 }
1433 
1434 // Probably move somewhere else. RzPrint doesn't need to know about the RZ_ANALYSIS_ enums
1435 RZ_API const char *rz_print_color_op_type(RZ_NONNULL RzPrint *p, ut32 /* RzAnalaysisOpType */ analysis_type) {
1437  RzConsPrintablePalette *pal = &p->cons->context->pal;
1438  switch (analysis_type & RZ_ANALYSIS_OP_TYPE_MASK) {
1440  return pal->nop;
1447  return pal->math;
1459  return pal->bin;
1461  return pal->swi;
1464  return pal->ujmp;
1469  return pal->jmp;
1473  return pal->cjmp;
1476  return pal->cmp;
1478  return pal->ucall;
1485  return pal->call;
1488  return pal->swi;
1491  return pal->trap;
1494  return pal->ret;
1498  case RZ_ANALYSIS_OP_TYPE_CMOV: // TODO: add cmov cathegory?
1499  return pal->mov;
1504  return pal->push;
1507  return pal->pop;
1509  return pal->crypto;
1511  return pal->other;
1513  default:
1514  return pal->invalid;
1515  }
1516 }
1517 
1518 // reset the status of row_offsets
1520  if (p->calc_row_offsets) {
1521  RZ_FREE(p->row_offsets);
1522  p->row_offsets_sz = 0;
1523  }
1524 }
1525 
1526 // set the offset, from the start of the printing, of the i-th row
1527 RZ_API void rz_print_set_rowoff(RzPrint *p, int i, ut32 offset, bool overwrite) {
1528  if (!overwrite) {
1529  return;
1530  }
1531  if (i < 0) {
1532  return;
1533  }
1534  if (!p->row_offsets || !p->row_offsets_sz) {
1535  p->row_offsets_sz = RZ_MAX(i + 1, DFLT_ROWS);
1536  p->row_offsets = RZ_NEWS(ut32, p->row_offsets_sz);
1537  }
1538  if (i >= p->row_offsets_sz) {
1539  size_t new_size;
1540  p->row_offsets_sz *= 2;
1541  // XXX dangerous
1542  while (i >= p->row_offsets_sz) {
1543  p->row_offsets_sz *= 2;
1544  }
1545  new_size = sizeof(ut32) * p->row_offsets_sz;
1546  p->row_offsets = realloc(p->row_offsets, new_size);
1547  }
1548  p->row_offsets[i] = offset;
1549 }
1550 
1551 // return the offset, from the start of the printing, of the i-th row.
1552 // if the line index is not valid, UT32_MAX is returned.
1554  if (i < 0 || i >= p->row_offsets_sz) {
1555  return UT32_MAX;
1556  }
1557  return p->row_offsets[i];
1558 }
1559 
1560 // return the index of the row that contains the given offset or -1 if
1561 // that row doesn't exist.
1563  int i = 0;
1564  ut32 tt;
1565  while ((tt = rz_print_rowoff(p, i)) != UT32_MAX && tt <= offset) {
1566  i++;
1567  }
1568  return tt != UT32_MAX ? i - 1 : -1;
1569 }
1570 
1572  return p->cur_enabled ? p->cur : 0;
1573 }
1574 
1584  rz_return_val_if_fail(p && buf && len > 0 && wordsize > 0, 0);
1585  int bytesize = wordsize / 8;
1586  if (bytesize < 1) {
1587  bytesize = 8;
1588  }
1589  PJ *j = pj_new();
1590  if (!j) {
1591  return NULL;
1592  }
1593  pj_a(j);
1594  for (int i = 0; i + bytesize < len; i += bytesize) {
1595  ut64 word = rz_read_ble(buf + i, p->big_endian, wordsize);
1596  pj_n(j, word);
1597  }
1598  pj_end(j);
1599  char *str = strdup(pj_string(j));
1600  pj_free(j);
1601  return str;
1602 }
1603 
1614  rz_return_val_if_fail(p && toks, NULL);
1615  // Color palette.
1616  RzConsPrintablePalette palette = p->cons->context->pal;
1617  // Black white asm string.
1618  char *bw_str = rz_strbuf_get(toks->str);
1619  rz_return_val_if_fail(bw_str, NULL);
1620  char *reset = p->colorize_opts.reset_bg ? Color_RESET_NOBG : Color_RESET;
1621  // mnemonic color
1622  const char *mnem_col = rz_print_color_op_type(p, toks->op_type);
1623 
1624  RzStrBuf *out = rz_strbuf_new("");
1626 
1627  const char *color;
1628  RzAsmToken *tok;
1629  rz_vector_foreach(toks->tokens, tok) {
1630  switch (tok->type) {
1631  default:
1634  return NULL;
1635  case RZ_ASM_TOKEN_UNKNOWN:
1636  color = palette.other;
1637  break;
1638  case RZ_ASM_TOKEN_MNEMONIC:
1639  color = mnem_col;
1640  break;
1641  case RZ_ASM_TOKEN_NUMBER:
1642  if (tok->val.number == p->colorize_opts.hl_addr && tok->val.number != 0) {
1643  color = palette.func_var_type;
1644  } else {
1645  color = palette.num;
1646  }
1647  break;
1648  case RZ_ASM_TOKEN_OPERATOR:
1650  color = palette.other;
1651  break;
1652  case RZ_ASM_TOKEN_REGISTER:
1653  color = palette.reg;
1654  break;
1655  case RZ_ASM_TOKEN_META:
1656  color = palette.meta;
1657  break;
1658  }
1659 
1661  rz_strbuf_append_n(out, bw_str + tok->start, tok->len);
1662  rz_strbuf_append(out, reset);
1663  }
1664  rz_strbuf_append(out, "\0");
1665  return out;
1666 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
static RzILOpEffect * mul(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:539
static ut8 bytes[32]
Definition: asm_arc.c:23
static SblHeader sb
Definition: bin_mbn.c:26
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define useUtf8
Definition: canvas_line.c:9
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.c:13
int mod(int a, int b)
Definition: crypto_rot.c:8
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
uint16_t ut16
uint32_t ut32
const char * k
Definition: dsignal.c:11
static states step(struct re_guts *, sopno, sopno, states, int, states)
Definition: engine.c:888
int max
Definition: enough.c:225
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static char * rp[]
Definition: i8080dis.c:36
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
sprintf
Definition: kernel.h:365
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))
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
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
char * dst
Definition: lz4.h:724
int n
Definition: mipsasm.c:19
int idx
Definition: setup.py:197
int off
Definition: pal.c:13
struct @219 colors[]
RZ_API RZ_OWN RzStrBuf * rz_print_colorize_asm_str(RZ_BORROW RzPrint *p, const RzAsmTokenString *toks)
Colorizes a tokenized asm string.
Definition: print.c:1613
RZ_API void rz_print_set_flags(RzPrint *p, int _flags)
Definition: print.c:117
RZ_API void rz_print_fill(RzPrint *p, const ut8 *arr, int size, ut64 addr, int step)
Definition: print.c:1346
#define Pal(x, y)
Definition: print.c:317
RZ_API void rz_print_init_rowoffsets(RzPrint *p)
Definition: print.c:1519
#define P(x)
Definition: print.c:268
RZ_API bool rz_print_have_cursor(RzPrint *p, int cur, int len)
Definition: print.c:133
#define DFLT_ROWS
Definition: print.c:19
RZ_API void rz_print_cursor(RzPrint *p, int cur, int len, int set)
Definition: print.c:166
RZ_API void rz_print_byte(RzPrint *p, const char *fmt, int idx, ut8 ch)
Definition: print.c:552
#define BD(a, b)
Definition: print.c:1148
RZ_API void rz_print_bytes(RzPrint *p, const ut8 *buf, int len, const char *fmt)
Definition: print.c:1233
static int libc_printf(const char *format,...)
Definition: print.c:27
RZ_API void rz_print_hexii(RzPrint *rp, ut64 addr, const ut8 *buf, int len, int step)
Definition: print.c:318
RZ_API const char * rz_print_byte_color(RzPrint *p, int ch)
Definition: print.c:269
RZ_API RZ_OWN char * rz_print_hexdiff_str(RZ_NONNULL RzPrint *p, ut64 aa, RZ_NONNULL const ut8 *_a, ut64 ba, RZ_NONNULL const ut8 *_b, int len, int scndcol)
Print hexdump diff between _a and _b.
Definition: print.c:1172
RZ_API int rz_print_row_at_off(RzPrint *p, ut32 offset)
Definition: print.c:1562
RZ_API ut32 rz_print_rowoff(RzPrint *p, int i)
Definition: print.c:1553
static const char * getchardiff(RzPrint *p, char *fmt, ut8 a, ut8 b)
Definition: print.c:1133
static void print_byte(RzStrBuf *sb, RzPrint *p, const char *fmt, int idx, ut8 ch)
Definition: print.c:531
static void print_section(RzStrBuf *sb, RzPrint *p, ut64 at)
Definition: print.c:499
RZ_API void rz_print_rangebar(RzPrint *p, ut64 startA, ut64 endA, ut64 min, ut64 max, int cols)
Definition: print.c:1283
RZ_API void rz_print_progressbar(RzPrint *p, int pc, int _cols)
Definition: print.c:1259
RZ_API void rz_print_set_cursor(RzPrint *p, int enable, int ocursor, int cursor)
Definition: print.c:121
RZ_API bool rz_print_is_interrupted(void)
Definition: print.c:45
RZ_API void rz_print_set_rowoff(RzPrint *p, int i, ut32 offset, bool overwrite)
Definition: print.c:1527
static int nullprinter(const char *a,...)
Definition: print.c:23
static void print_addr(RzStrBuf *sb, RzPrint *p, ut64 addr)
Definition: print.c:403
static void print_cursor_l(RzStrBuf *sb, RzPrint *p, int cur, int len)
Definition: print.c:519
static RzPrint staticp
Definition: print.c:1254
RZ_API RzPrint * rz_print_new(void)
Definition: print.c:56
RZ_API bool rz_print_cursor_pointer(RzPrint *p, int cur, int len)
Definition: print.c:152
static void printHistBlock(RzPrint *p, int k, int cols)
Definition: print.c:1313
#define memcat(x, y)
static void print_cursor_r(RzStrBuf *sb, RzPrint *p, int cur, int len)
Definition: print.c:525
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 RzPrint * rz_print_free(RzPrint *p)
Definition: print.c:101
#define CD(a, b)
Definition: print.c:1149
RZ_API RZ_OWN char * rz_print_hexdump_str(RZ_NONNULL RzPrint *p, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz)
Prints a hexdump of buf at addr.
Definition: print.c:573
#define PREOFF(x)
static bool checkSparse(const ut8 *p, int len, int ch)
Definition: print.c:293
static int libc_eprintf(const char *format,...)
Definition: print.c:35
RZ_API char * rz_print_hexpair(RzPrint *p, const char *str, int n)
Definition: print.c:172
RZ_API RZ_OWN char * rz_print_jsondump_str(RZ_NONNULL RzPrint *p, RZ_NONNULL const ut8 *buf, int len, int wordsize)
Print dump in json format.
Definition: print.c:1583
static char colorbuffer[64]
Definition: print.c:267
static const char * getbytediff(RzPrint *p, char *fmt, ut8 a, ut8 b)
Definition: print.c:1120
static bool isAllZeros(const ut8 *buf, int len)
Definition: print.c:307
RZ_API char * rz_print_section_str(RzPrint *p, ut64 at)
Definition: print.c:511
RZ_API int rz_print_get_cursor(RzPrint *p)
Definition: print.c:1571
static RzPrintIsInterruptedCallback is_interrupted_cb
Definition: print.c:43
RZ_API void rz_print_raw(RzPrint *p, ut64 addr, const ut8 *buf, int len)
Definition: print.c:1249
RZ_API void rz_print_set_is_interrupted_cb(RzPrintIsInterruptedCallback cb)
Definition: print.c:52
static ut8 * M(const ut8 *b, int len)
Definition: print.c:1151
static const char hex[16]
Definition: print.c:21
#define INC
RZ_API const char * rz_print_color_op_type(RZ_NONNULL RzPrint *p, ut32 analysis_type)
Definition: print.c:1435
RZ_API void rz_print_addr(RzPrint *p, ut64 addr)
Definition: print.c:489
#define min(a, b)
Definition: qsort.h:83
static RzSocket * s
Definition: rtr.c:28
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_ICALL
Definition: rz_analysis.h:381
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_CRYPTO
Definition: rz_analysis.h:430
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_ROL
Definition: rz_analysis.h:420
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAL
Definition: rz_analysis.h:408
@ RZ_ANALYSIS_OP_TYPE_MOD
Definition: rz_analysis.h:422
@ RZ_ANALYSIS_OP_TYPE_UPUSH
Definition: rz_analysis.h:395
@ RZ_ANALYSIS_OP_TYPE_RPUSH
Definition: rz_analysis.h:396
@ 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_UCCALL
Definition: rz_analysis.h:384
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_ROR
Definition: rz_analysis.h:419
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_NULL
Definition: rz_analysis.h:367
@ RZ_ANALYSIS_OP_TYPE_CMOV
Definition: rz_analysis.h:391
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_SWITCH
Definition: rz_analysis.h:423
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_CPL
Definition: rz_analysis.h:429
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_DIV
Definition: rz_analysis.h:405
@ RZ_ANALYSIS_OP_TYPE_CAST
Definition: rz_analysis.h:426
@ RZ_ANALYSIS_OP_TYPE_UCJMP
Definition: rz_analysis.h:377
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_NOT
Definition: rz_analysis.h:414
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
@ RZ_ANALYSIS_OP_TYPE_NEW
Definition: rz_analysis.h:427
@ RZ_ANALYSIS_OP_TYPE_LENGTH
Definition: rz_analysis.h:425
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#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 Color_RESET
Definition: rz_cons.h:617
#define Color_WHITE
Definition: rz_cons.h:625
#define Color_MAGENTA
Definition: rz_cons.h:629
#define Color_GREEN
Definition: rz_cons.h:627
#define Color_RED
Definition: rz_cons.h:623
#define RUNE_LONG_LINE_HORIZ
Definition: rz_cons.h:417
#define UTF_BLOCK
Definition: rz_cons.h:419
#define Color_YELLOW
Definition: rz_cons.h:631
#define Color_RESET_NOBG
Definition: rz_cons.h:618
#define Color_INVERT
Definition: rz_cons.h:606
#define RUNE_LINE_VERT
Definition: rz_cons.h:401
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
static ut8 rz_read_ble8(const void *src)
Definition: rz_endian.h:12
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static ut16 rz_read_ble16(const void *src, bool big_endian)
Definition: rz_endian.h:493
static ut64 rz_read_le64(const void *src)
Definition: rz_endian.h:266
static ut64 rz_read_ble(const void *src, bool big_endian, int size)
Definition: rz_endian.h:517
RZ_API int rz_hex_pair2bin(const char *arg)
Definition: hex.c:360
#define rz_io_bind_init(x)
Definition: rz_io.h:344
RZ_API void rz_mem_swaporcopy(ut8 *dest, const ut8 *src, int len, bool big_endian)
Definition: mem.c:192
RZ_API void rz_num_minmax_swap_i(int *a, int *b)
Definition: unum.c:67
RZ_API PJ * pj_new(void)
Definition: pj.c:25
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_n(PJ *j, ut64 n)
Definition: pj.c:252
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
#define RZ_PRINT_FLAGS_ADDRDEC
Definition: rz_print.h:24
#define RZ_PRINT_FLAGS_ALIGN
Definition: rz_print.h:33
#define RZ_PRINT_FLAGS_SPARSE
Definition: rz_print.h:19
#define RZ_PRINT_FLAGS_REFS
Definition: rz_print.h:22
#define RZ_PRINT_FLAGS_NONHEX
Definition: rz_print.h:27
#define RZ_PRINT_FLAGS_RAINBOW
Definition: rz_print.h:29
#define RZ_PRINT_FLAGS_DIFFOUT
Definition: rz_print.h:23
#define RZ_PRINT_FLAGS_HDROFF
Definition: rz_print.h:30
#define RZ_PRINT_FLAGS_COLOR
Definition: rz_print.h:15
#define RZ_PRINT_FLAGS_NONASCII
Definition: rz_print.h:32
#define RZ_PRINT_FLAGS_ADDRMOD
Definition: rz_print.h:16
#define RZ_PRINT_FLAGS_HEADER
Definition: rz_print.h:18
#define RZ_PRINT_FLAGS_OFFSET
Definition: rz_print.h:21
#define RZ_PRINT_FLAGS_SEGOFF
Definition: rz_print.h:20
#define RZ_PRINT_FLAGS_STYLE
Definition: rz_print.h:31
#define RZ_PRINT_FLAGS_SECTION
Definition: rz_print.h:36
@ RZ_ASM_TOKEN_MNEMONIC
Definition: rz_print.h:47
@ RZ_ASM_TOKEN_REGISTER
Definition: rz_print.h:50
@ RZ_ASM_TOKEN_OPERATOR
Definition: rz_print.h:48
@ RZ_ASM_TOKEN_META
Definition: rz_print.h:52
@ RZ_ASM_TOKEN_NUMBER
Definition: rz_print.h:49
@ RZ_ASM_TOKEN_SEPARATOR
Definition: rz_print.h:51
@ RZ_ASM_TOKEN_UNKNOWN
Definition: rz_print.h:46
#define RZ_PRINT_FLAGS_COMPACT
Definition: rz_print.h:26
#define RZ_PRINT_FLAGS_UNALLOC
Definition: rz_print.h:34
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RZ_OWN char * rz_strbuf_drain_nofree(RzStrBuf *sb)
Definition: strbuf.c:349
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
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 bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
#define PFMT64d
Definition: rz_types.h:394
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
int(* PrintfCallback)(const char *str,...) RZ_PRINTF_CHECK(1
Definition: rz_types.h:233
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define RZ_BORROW
Definition: rz_types.h:63
#define st8
Definition: rz_types_base.h:16
#define RZ_MIN(x, y)
#define UT32_MAX
Definition: rz_types_base.h:99
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define st16
Definition: rz_types_base.h:14
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
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 int
Definition: sfsocketcall.h:114
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
An tokenized asm string.
Definition: rz_print.h:72
RzVector * tokens
Definition: rz_print.h:75
ut32 op_type
RzAnalysisOpType. Mnemonic color depends on this.
Definition: rz_print.h:73
RzStrBuf * str
Definition: rz_print.h:74
A token of an asm string holding meta data.
Definition: rz_print.h:60
size_t len
Definition: rz_print.h:62
size_t start
Definition: rz_print.h:61
union RzAsmToken::@310 val
RzAsmTokenType type
Definition: rz_print.h:63
ut64 number
Definition: rz_print.h:65
Definition: rz_pj.h:12
PrintfCallback cb_printf
Definition: rz_print.h:118
static int color
Definition: visual.c:20
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const char * cb[]
Definition: z80_tab.h:176
static int addr
Definition: z80asm.c:58