diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 5f8d824e3ed..c8300e04e03 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -2235,5 +2235,3 @@ RZ_API RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFuncti rz_list_free(type_used); return uniq; } - - diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 4e94ab2eebe..43517d6be04 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -7603,5 +7603,3 @@ RZ_API void rz_core_analysis_cc_init(RzCore *core) { free(dbpath); free(dbhomepath); } - - diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 0baa0f31250..37c7213baf5 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -229,7 +229,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { free(error_msg); } if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(core->analysis->type, out); free(out); } } @@ -250,7 +250,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { if (IS_MODE_RZCMD(mode)) { rz_cons_printf("pf.%s %s\n", flagname, v); } else if (IS_MODE_SET(mode)) { - sdb_set(core->print->formats, flagname, v, 0); + rz_type_format_set(core->analysis->type, flagname, v); } } free(dup); @@ -265,7 +265,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { offset = strdup("0"); } flagname = dup; - int fmtsize = rz_print_format_struct_size(core->print, v, 0, 0); + int fmtsize = rz_type_format_struct_size(core->analysis->type, v, 0, 0); char *offset_key = rz_str_newf("%s.offset", flagname); const char *off = sdb_const_get(db, offset_key, 0); free(offset_key); @@ -277,11 +277,14 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { ut8 *buf = malloc(fmtsize); if (buf) { rz_io_read_at(core->io, addr, buf, fmtsize); - int res = rz_print_format(core->print, addr, buf, + char *format = rz_type_format_data(core->analysis->type, core->print, addr, buf, fmtsize, v, 0, NULL, NULL); free(buf); - if (res < 0) { + if (!format) { eprintf("Warning: Cannot register invalid format (%s)\n", v); + } else { + rz_cons_println(format); + free(format); } } } diff --git a/librz/core/cmd_meta.c b/librz/core/cmd_meta.c index 78dd52cd3e7..f9441f1bb5d 100644 --- a/librz/core/cmd_meta.c +++ b/librz/core/cmd_meta.c @@ -750,7 +750,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (p) { p = (char *)rz_str_trim_head_ro(p); if (*p == '.') { - const char *realformat = rz_type_format_byname(core->print, p + 1); + const char *realformat = rz_type_format_byname(core->analysis->type, p + 1); if (realformat) { p = (char *)realformat; } else { @@ -759,7 +759,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { } } if (n < 1) { - n = rz_type_format_struct_size(core->print, p, 0, 0); + n = rz_type_format_struct_size(core->analysis->type, p, 0, 0); if (n < 1) { eprintf("Warning: Cannot resolve struct size for '%s'\n", p); n = 32; // @@ -769,10 +769,13 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (n > core->blocksize) { n = core->blocksize; } - int r = rz_type_format(core->print, addr, core->block, + char *format = rz_type_format_data(core->analysis->type, core->print, addr, core->block, n, p, 0, NULL, NULL); - if (r < 0) { + if (!format) { n = -1; + } else { + rz_cons_println(format); + free(format); } } else { eprintf("Usage: Cf [size] [pf-format-string]\n"); diff --git a/librz/core/cmd_print.c b/librz/core/cmd_print.c index 693ba9736f7..7a87df15e7f 100644 --- a/librz/core/cmd_print.c +++ b/librz/core/cmd_print.c @@ -5,6 +5,7 @@ #include "rz_core.h" #include "rz_config.h" #include "rz_util.h" +#include "rz_type.h" #include "rz_types.h" #include @@ -1603,9 +1604,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input += 2; if (*_input == '.') { _input++; - val = sdb_get(core->print->formats, _input, NULL); + val = rz_type_format_get(core->analysis->type, _input); if (val) { - rz_cons_printf("%d\n", rz_print_format_struct_size(core->print, val, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, val, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1614,7 +1615,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input++; } if (*_input) { - rz_cons_printf("%d\n", rz_print_format_struct_size(core->print, _input, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, _input, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1640,7 +1641,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } } else { const char *struct_name = rz_str_trim_head_ro(_input); - const char *val = sdb_get(core->print->formats, struct_name, NULL); + const char *val = rz_type_format_get(core->analysis->type, struct_name); if (val) { rz_cons_printf("%s\n", val); } else { @@ -1743,19 +1744,19 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, core->print->num = core->num; /* print all stored format */ if (!input[1] || !input[2]) { // "pf." - SdbListIter *iter; - SdbKv *kv; - SdbList *sdbls = sdb_foreach_list(core->print->formats, true); - ls_foreach (sdbls, iter, kv) { - rz_cons_printf("pf.%s %s\n", sdbkv_key(kv), sdbkv_value(kv)); + RzListIter *iter; + char *fmt = NULL; + RzList *fmtl = rz_type_format_all(core->analysis->type); + rz_list_foreach (fmtl, iter, fmt) { + rz_cons_printf("pf.%s\n", fmt); } + rz_list_free(fmtl); /* delete a format */ } else if (input[1] && input[2] == '-') { // "pf-" if (input[3] == '*') { // "pf-*" - sdb_free(core->print->formats); - core->print->formats = sdb_new0(); + rz_type_format_purge(core->analysis->type); } else { // "pf-xxx" - sdb_unset(core->print->formats, input + 3, 0); + rz_type_format_delete(core->analysis->type, input + 3); } } else { char *name = strdup(input + (input[1] ? 2 : 1)); @@ -1776,7 +1777,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, eprintf("Struct or fields name can not contain dot symbol (.)\n"); } else { // pf.foo=xxx - sdb_set(core->print->formats, name, space, 0); + rz_type_format_set(core->analysis->type, name, space); } free(name); free(input); @@ -1784,7 +1785,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } if (!strchr(name, '.') && - !sdb_get(core->print->formats, name, NULL)) { + !rz_type_format_get(core->analysis->type, name)) { eprintf("Cannot find '%s' format.\n", name); free(name); free(input); @@ -1802,9 +1803,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, /* Load format from name into fmt to get the size */ /* This make sure the whole structure will be printed */ const char *fmt = NULL; - fmt = sdb_get(core->print->formats, name, NULL); + fmt = rz_type_format_get(core->analysis->type, name); if (fmt) { - int size = rz_print_format_struct_size(core->print, fmt, mode, 0) + 10; + int size = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0) + 10; if (size > core->blocksize) { rz_core_block_size(core, size); } @@ -1816,22 +1817,34 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (eq) { // Write mode (pf.field=value) *eq++ = 0; mode = RZ_PRINT_MUSTSET; - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, eq, dot); + if (format) { + rz_cons_println(format); + free(format); + } } else { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, dot); + if (format) { + rz_cons_println(format); + free(format); + } } } else { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, NULL); + if (format) { + rz_cons_println(format); + free(format); + } } free(name); } } else { /* This make sure the structure will be printed entirely */ const char *fmt = rz_str_trim_head_ro(input + 1); - int struct_sz = rz_print_format_struct_size(core->print, fmt, mode, 0); + int struct_sz = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0); int size = RZ_MAX(core->blocksize, struct_sz); ut8 *buf = calloc(1, size); if (!buf) { @@ -1854,8 +1867,12 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } free(args); if (syntax_ok) { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, buf, size, fmt, mode, NULL, NULL); + if (format) { + rz_cons_println(format); + free(format); + } } free(buf); } diff --git a/librz/core/core.c b/librz/core/core.c index 8f638ab1674..a2395bd65e2 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1152,7 +1152,7 @@ static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char *key, char *pfx, int idx, char *ptr) { int i, ret = 0; int len = strlen(ptr); - char *fmt = sdb_get(core->print->formats, key, NULL); + char *fmt = rz_type_format_get(core->analysis->type, key); if (fmt) { int nargs = rz_str_word_set0_stack(fmt); if (nargs > 1) { @@ -1666,6 +1666,7 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com ADDARG("gui.alt_background") ADDARG("gui.border") } + /* } else if (!strncmp(buf->data, "pf.", 3) || !strncmp(buf->data, "pf*.", 4) || !strncmp(buf->data, "pfd.", 4) || !strncmp(buf->data, "pfv.", 4) || !strncmp(buf->data, "pfj.", 4)) { char pfx[2]; int chr = (buf->data[2] == '.') ? 3 : 4; @@ -1675,10 +1676,10 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } else { *pfx = 0; } - SdbList *sls = sdb_foreach_list(core->print->formats, false); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (sls, iter, kv) { + // FIXME: FORMATS + RzListIter *iter; + RzList *fmtl = rz_type_format_all(core->analysis->type); + rz_list_foreach (fmtl, iter, kv) { int len = strlen(buf->data + chr); int minlen = RZ_MIN(len, strlen(sdbkv_key(kv))); if (!len || !strncmp(buf->data + chr, sdbkv_key(kv), minlen)) { @@ -1693,6 +1694,7 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } } } + */ } else if ((!strncmp(buf->data, "afvn ", 5)) || (!strncmp(buf->data, "afan ", 5))) { RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0); RzList *vars; diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 4c589c35684..220cb6f949d 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -1098,4 +1098,3 @@ RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename) { } free(str); } - diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 7d35c62e3dc..40eb9268c73 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -3123,8 +3123,12 @@ static bool ds_print_meta_infos(RDisasmState *ds, ut8 *buf, int len, int idx, in case RZ_META_TYPE_FORMAT: { rz_cons_printf("pf %s # size=%" PFMT64d "\n", mi->str, mi_size); int len_before = rz_cons_get_buffer_len(); - rz_print_format(core->print, ds->at, buf + idx, + char *format = rz_type_format_data(core->analysis->type, core->print, ds->at, buf + idx, len - idx, mi->str, RZ_PRINT_MUSTSEE, NULL, NULL); + if (format) { + rz_cons_println(format); + free(format); + } int len_after = rz_cons_get_buffer_len(); const char *cons_buf = rz_cons_get_buffer(); if (len_after > len_before && buf && cons_buf[len_after - 1] == '\n') { diff --git a/librz/core/vmenus.c b/librz/core/vmenus.c index 2de2792b593..158e4102fab 100644 --- a/librz/core/vmenus.c +++ b/librz/core/vmenus.c @@ -755,7 +755,7 @@ RZ_API int rz_core_visual_types(RzCore *core) { } } break; case 'd': - rz_analysis_remove_parsed_type(core->analysis, vt.curname); + rz_type_remove_parsed_type(core->analysis->type, vt.curname); break; case '-': rz_types_open_editor(core, NULL); diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 044947f26f4..ae8f8acc70d 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -5,6 +5,10 @@ #define RZ_TYPE_H #include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -16,12 +20,16 @@ typedef struct rz_type_target_t { const char *cpu; int bits; const char *os; + bool big_endian; } RzTypeTarget; typedef struct rz_type_t { void *user; Sdb *sdb_types; + Sdb *formats; // for `pf` formats RzTypeTarget *target; + RNum *num; + RzIOBind iob; // for RzIO in formats } RzType; typedef struct rz_type_enum_case_t { @@ -132,9 +140,18 @@ RZ_API bool rz_type_unlink(RzType *t, ut64 addr); RZ_API bool rz_type_unlink_all(RzType *t); RZ_API bool rz_type_link_offset(RzType *t, const char *val, ut64 addr); +// Type formats (`tp` and `pf` commands) +RZ_API const char *rz_type_format_get(RzType *t, const char *name); +RZ_API void rz_type_format_set(RzType *t, const char *name, const char *fmt); +RZ_API RZ_OWN RzList *rz_type_format_all(RzType *t); +RZ_API void rz_type_format_delete(RzType *t, const char *name); +RZ_API void rz_type_format_purge(RzType *t); + RZ_API char *rz_type_format(RzType *type, const char *t); -RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n); -RZ_API const char *rz_type_format_byname(RzPrint *p, const char *name); +RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n); +RZ_API const char *rz_type_format_byname(RzType *t, const char *name); +RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, + const char *formatname, int mode, const char *setval, char *ofield); // Function prototypes api RZ_API bool rz_type_func_exist(RzType *t, const char *func_name); @@ -159,7 +176,6 @@ RZ_API RzList *rz_type_links(RzType *type); RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types); RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types, RZ_NULLABLE RzSerializeResultInfo *res); - #endif #ifdef __cplusplus diff --git a/librz/include/rz_util/rz_print.h b/librz/include/rz_util/rz_print.h index 9139efa217c..6c2fcaa093f 100644 --- a/librz/include/rz_util/rz_print.h +++ b/librz/include/rz_util/rz_print.h @@ -94,7 +94,6 @@ typedef struct rz_print_t { RzPrintHasRefs hasrefs; RzPrintCommentCallback get_comments; RzPrintSectionGet get_section_name; - Sdb *formats; Sdb *sdb_types; RzCons *cons; RzConsBind consbind; @@ -176,9 +175,7 @@ RZ_API void rz_print_code(RzPrint *p, ut64 addr, const ut8 *buf, int len, char l #define RZ_PRINT_DOT (1 << 7) #define RZ_PRINT_QUIET (1 << 8) #define RZ_PRINT_STRUCT (1 << 9) -RZ_API int rz_print_format_struct_size(RzPrint *p, const char *format, int mode, int n); -RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *buf, const int len, const char *fmt, int elem, const char *setval, char *field); -RZ_API const char *rz_print_format_byname(RzPrint *p, const char *name); + RZ_API void rz_print_offset(RzPrint *p, ut64 off, int invert, int opt, int dec, int delta, const char *label); RZ_API void rz_print_offset_sg(RzPrint *p, ut64 off, int invert, int offseg, int seggrn, int offdec, int delta, const char *label); #define RZ_PRINT_STRING_WIDE 1 diff --git a/librz/type/base.c b/librz/type/base.c index dde2a02523b..134aea3b5eb 100644 --- a/librz/type/base.c +++ b/librz/type/base.c @@ -563,4 +563,3 @@ RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type) { break; } } - diff --git a/librz/type/format.c b/librz/type/format.c index c2e0d580ee4..3d05e2055fb 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -67,29 +67,29 @@ static int rz_get_size(RNum *num, ut8 *buf, int endian, const char *s) { return rz_num_math(num, s); } -static void rz_print_format_u128(const RzPrint *p, int endian, int mode, +static void rz_type_format_u128(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 low = rz_read_ble64(buf, endian); ut64 hig = rz_read_ble64(buf + 8, endian); if (MUSTSEEJSON) { - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); } else if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = (uint128_t)", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = (uint128_t)", seeki); } if (endian) { - p->cb_printf("0x%016" PFMT64x "", low); - p->cb_printf("%016" PFMT64x, hig); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x "", low); + rz_strbuf_appendf(outbuf, "%016" PFMT64x, hig); } else { - p->cb_printf("0x%016" PFMT64x "", hig); - p->cb_printf("%016" PFMT64x, low); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x "", hig); + rz_strbuf_appendf(outbuf, "%016" PFMT64x, low); } if (MUSTSEEJSON) { const char *end = endian ? "big" : "little"; - p->cb_printf("\",\"endian\":\"%s\",\"ctype\":\"uint128_t\"}", end); + rz_strbuf_appendf(outbuf, "\",\"endian\":\"%s\",\"ctype\":\"uint128_t\"}", end); } } -static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, +static void rz_type_format_quadword(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr64; int elem = -1; @@ -99,32 +99,32 @@ static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, NULL, &addr64); if (MUSTSET) { - p->cb_printf("wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); + rz_strbuf_appendf(outbuf, "wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = (qword)", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = (qword)", seeki + ((elem >= 0) ? elem * 8 : 0)); } if (size == -1) { if (addr64 == UT32_MAX || ((st64)addr64 < 0 && (st64)addr64 > -4096)) { - p->cb_printf("%d", (int)(addr64)); + rz_strbuf_appendf(outbuf, "%d", (int)(addr64)); } else { - p->cb_printf("0x%016" PFMT64x, addr64); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x, addr64); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, NULL, &addr64); if (elem == -1 || elem == 0) { - p->cb_printf("0x%016" PFMT64x, addr64); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x, addr64); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -132,39 +132,39 @@ static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, i += 8; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr64); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr64); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, NULL, &addr64); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr64); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr64); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 8; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_byte(const RzPrint *p, int endian, int mode, +static void rz_type_format_byte(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -172,26 +172,26 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); } if (size == -1) { - p->cb_printf("0x%02x", buf[i]); + rz_strbuf_appendf(outbuf, "0x%02x", buf[i]); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("0x%02x", buf[i]); + rz_strbuf_appendf(outbuf, "0x%02x", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -199,18 +199,18 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); const char *comma = ""; while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("%s%d", comma, buf[i]); + rz_strbuf_appendf(outbuf, "%s%d", comma, buf[i]); comma = ","; if (elem == 0) { elem = -2; @@ -221,16 +221,17 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } +// FIXME: Port to the PJ API // Return number of consumed bytes -static int rz_print_format_uleb(const RzPrint *p, int endian, int mode, +static int rz_type_format_uleb(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; int s = 0, offset = 0; @@ -249,74 +250,74 @@ static int rz_print_format_uleb(const RzPrint *p, int endian, int mode, } while (elem--); tmp = (ut8 *)rz_uleb128_encode(rz_num_math(NULL, setval), &s); nbr = rz_hex_bin2strdup(tmp, s); - p->cb_printf("\"wx %s\" @ 0x%08" PFMT64x "\n", nbr, seeki + offset - s); + rz_strbuf_appendf(outbuf, "\"wx %s\" @ 0x%08" PFMT64x "\n", nbr, seeki + offset - s); free(tmp); free(nbr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } if (size == -1) { rz_uleb128_decode(buf + i, &offset, &value); - p->cb_printf("%" PFMT64d, value); + rz_strbuf_appendf(outbuf, "%" PFMT64d, value); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { rz_uleb128_decode(buf + i, &s, &value); i += s; offset += s; - p->cb_printf("%" PFMT64d, value); + rz_strbuf_appendf(outbuf, "%" PFMT64d, value); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { rz_uleb128_decode(buf + i, &offset, &value); - p->cb_printf("\"%" PFMT64d "\"", value); + rz_strbuf_appendf(outbuf, "\"%" PFMT64d "\"", value); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { rz_uleb128_decode(buf + i, &s, &value); i += s; offset += s; - p->cb_printf("\"%" PFMT64d "\"", value); + rz_strbuf_appendf(outbuf, "\"%" PFMT64d "\"", value); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } return offset; } -static void rz_print_format_char(const RzPrint *p, int endian, int mode, +static void rz_type_format_char(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -324,26 +325,26 @@ static void rz_print_format_char(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); //XXX:: shouldn't it be elem*1?? + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); //XXX:: shouldn't it be elem*1?? } if (size == -1) { - p->cb_printf("'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -351,38 +352,38 @@ static void rz_print_format_char(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, +static void rz_type_format_decchar(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -390,26 +391,26 @@ static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); } if (size == -1) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; @@ -417,83 +418,79 @@ static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("\"%d\"", buf[i]); + rz_strbuf_appendf(outbuf, "\"%d\"", buf[i]); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("\"%d\"", buf[i]); + rz_strbuf_appendf(outbuf, "\"%d\"", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static int rz_print_format_string(const RzPrint *p, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { +static int rz_type_format_string(RzType *t, RzStrBuf *outbuf, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { ut8 buffer[255]; buffer[0] = 0; - if (!p->iob.read_at) { - eprintf("(cannot read memory)\n"); - return -1; - } const ut64 at = (is64 == 1) ? addr64 : (ut64)addr; - int res = p->iob.read_at(p->iob.io, at, buffer, sizeof(buffer) - 8); + int res = t->iob.read_at(t->iob.io, at, buffer, sizeof(buffer) - 8); if (MUSTSEEJSON) { char *encstr = rz_str_utf16_encode((const char *)buffer, -1); if (encstr) { - p->cb_printf("%" PFMT64d ",\"string\":\"%s\"}", seeki, encstr); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"string\":\"%s\"}", seeki, encstr); free(encstr); } } else if (MUSTSEESTRUCT) { char *encstr = rz_str_utf16_encode((const char *)buffer, -1); if (encstr) { - p->cb_printf("\"%s\"", encstr); + rz_strbuf_appendf(outbuf, "\"%s\"", encstr); free(encstr); } } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } if (!SEEVALUE) { if (ISQUIET) { if (addr == 0LL) { - p->cb_printf("NULL"); + rz_strbuf_append(outbuf, "NULL"); } else if (addr == UT32_MAX || addr == UT64_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("0x%08" PFMT64x " ", addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " ", addr); } } else { - p->cb_printf("0x%08" PFMT64x " -> 0x%08" PFMT64x " ", seeki, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " -> 0x%08" PFMT64x " ", seeki, addr); } } if (res > 0 && buffer[0] != 0xff && buffer[1] != 0xff) { - p->cb_printf("\"%s\"", buffer); + rz_strbuf_appendf(outbuf, "\"%s\"", buffer); } } return 0; } -static void rz_print_format_time(const RzPrint *p, int endian, int mode, +static void rz_type_format_time(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; struct tm timestruct; @@ -504,7 +501,7 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if (MUSTSEE) { char *timestr = malloc(ASCTIME_BUF_MINLEN); if (!timestr) { @@ -513,26 +510,26 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { - p->cb_printf("%s", timestr); + rz_strbuf_appendf(outbuf, "%s", timestr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_appendf(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (elem == -1 || elem == 0) { - p->cb_printf("%s", timestr); + rz_strbuf_appendf(outbuf, "%s", timestr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; @@ -540,7 +537,7 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_appendf(outbuf, " ]"); } } free(timestr); @@ -552,38 +549,38 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (size == -1) { - p->cb_printf("\"%s\"", timestr); + rz_strbuf_appendf(outbuf, "\"%s\"", timestr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (elem == -1 || elem == 0) { - p->cb_printf("\"%s\"", timestr); + rz_strbuf_appendf(outbuf, "\"%s\"", timestr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } free(timestr); if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } // TODO: support unsigned int? -static void rz_print_format_hex(const RzPrint *p, int endian, int mode, +static void rz_type_format_hex(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -593,41 +590,41 @@ static void rz_print_format_hex(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { if (addr == UT64_MAX || addr == UT32_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { if (ISQUIET) { if (addr == UT64_MAX || addr == UT32_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -635,37 +632,37 @@ static void rz_print_format_hex(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_int(const RzPrint *p, int endian, int mode, +static void rz_type_format_int(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -675,29 +672,29 @@ static void rz_print_format_int(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ %" PFMT64d "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ %" PFMT64d "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0x%08" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { - p->cb_printf("%" PFMT64d, (st64)(st32)addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, (st64)(st32)addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, (st64)(st32)addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, (st64)(st32)addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -705,37 +702,38 @@ static void rz_print_format_int(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static int rz_print_format_disasm(const RzPrint *p, ut64 seeki, int size) { +/* +static int rz_type_format_disasm(const RzPrint *p, ut64 seeki, int size) { ut64 prevseeki = seeki; if (!p->disasm || !p->user) { @@ -750,8 +748,9 @@ static int rz_print_format_disasm(const RzPrint *p, ut64 seeki, int size) { return seeki - prevseeki; } +*/ -static void rz_print_format_octal(const RzPrint *p, int endian, int mode, +static void rz_type_format_octal(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -761,32 +760,32 @@ static void rz_print_format_octal(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0%" PFMT64o, addr); + rz_strbuf_appendf(outbuf, "0%" PFMT64o, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (!SEEVALUE) { - p->cb_printf("(octal) "); + rz_strbuf_append(outbuf, "(octal) "); } if (size == -1) { - p->cb_printf(" 0%08" PFMT64o, addr); + rz_strbuf_appendf(outbuf, " 0%08" PFMT64o, addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("0%08" PFMT64o, addr); + rz_strbuf_appendf(outbuf, "0%08" PFMT64o, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -794,37 +793,37 @@ static void rz_print_format_octal(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf, i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, +static void rz_type_format_hexflag(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr = 0; int elem = -1; @@ -834,34 +833,34 @@ static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0x%08" PFMT64x, addr & UT32_MAX); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr & UT32_MAX); } else if (MUSTSEE) { ut32 addr32 = (ut32)addr; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { if (ISQUIET && (addr32 == UT32_MAX)) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("0x%08" PFMT64x, (ut64)addr32); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, (ut64)addr32); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("0x%08" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -869,139 +868,130 @@ static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static int rz_print_format_10bytes(const RzPrint *p, int mode, const char *setval, +static int rz_type_format_10bytes(RzType *t, RzStrBuf *outbuf, int mode, const char *setval, ut64 seeki, ut64 addr, ut8 *buf) { ut8 buffer[255]; int j; if (MUSTSET) { - p->cb_printf("?e pf B not yet implemented\n"); + rz_strbuf_append(outbuf, "?e pf B not yet implemented\n"); } else if (mode & RZ_PRINT_DOT) { for (j = 0; j < 10; j++) { - p->cb_printf("%02x ", buf[j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[j]); } } else if (MUSTSEE) { - if (!p->iob.read_at) { - printf("(cannot read memory)\n"); - return -1; - } - p->iob.read_at(p->iob.io, (ut64)addr, buffer, 248); + t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (j = 0; j < 10; j++) { - p->cb_printf("%02x ", buf[j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[j]); } if (!SEEVALUE) { - p->cb_printf(" ... ("); + rz_strbuf_append(outbuf, " ... ("); } for (j = 0; j < 10; j++) { if (!SEEVALUE) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } if (!SEEVALUE) { - p->cb_printf(")"); + rz_strbuf_append(outbuf, ")"); } } else if (MUSTSEEJSON) { - if (!p->iob.read_at) { - printf("(cannot read memory)\n"); - return -1; - } else { - p->iob.read_at(p->iob.io, (ut64)addr, buffer, 248); - } - p->cb_printf("[ %d", buf[0]); + t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); + rz_strbuf_appendf(outbuf, "[ %d", buf[0]); j = 1; for (; j < 10; j++) { - p->cb_printf(", %d", buf[j]); + rz_strbuf_appendf(outbuf, ", %d", buf[j]); } - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); return 0; } return 0; } -static int rz_print_format_hexpairs(const RzPrint *p, int endian, int mode, +static int rz_type_format_hexpairs(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int j; size = (size == -1) ? 1 : size; if (MUSTSET) { - p->cb_printf("?e pf X not yet implemented\n"); + rz_strbuf_append(outbuf, "?e pf X not yet implemented\n"); } else if (mode & RZ_PRINT_DOT) { for (j = 0; j < size; j++) { - p->cb_printf("%02x", buf[i + j]); + rz_strbuf_appendf(outbuf, "%02x", buf[i + j]); } } else if (MUSTSEE) { size = (size < 1) ? 1 : size; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (j = 0; j < size; j++) { - p->cb_printf("%02x ", buf[i + j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[i + j]); } if (!SEEVALUE) { - p->cb_printf(" ... ("); + rz_strbuf_append(outbuf, " ... ("); } for (j = 0; j < size; j++) { if (!SEEVALUE) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[i + j]); + rz_strbuf_appendf(outbuf, "%c", buf[i + j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } - p->cb_printf(")"); + rz_strbuf_append(outbuf, ")"); } else if (MUSTSEEJSON || MUSTSEESTRUCT) { size = (size < 1) ? 1 : size; - p->cb_printf("[ %d", buf[0]); + rz_strbuf_appendf(outbuf, "[ %d", buf[0]); j = 1; for (; j < 10; j++) { - p->cb_printf(", %d", buf[j]); + rz_strbuf_appendf(outbuf, ", %d", buf[j]); } - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } return size; } return size; } -static void rz_print_format_float(const RzPrint *p, int endian, int mode, +static void rz_type_format_float(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { float val_f = 0.0f; ut64 addr = 0; @@ -1012,33 +1002,33 @@ static void rz_print_format_float(const RzPrint *p, int endian, int mode, } val_f = updateAddr(buf + i, 999, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); } else { if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } } if (size == -1) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { val_f = updateAddr(buf + i, 9999, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1046,16 +1036,16 @@ static void rz_print_format_float(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_double(const RzPrint *p, int endian, int mode, +static void rz_type_format_double(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { double val_f = 0.0; ut64 addr = 0; @@ -1067,35 +1057,35 @@ static void rz_print_format_double(const RzPrint *p, int endian, int mode, updateAddr(buf + i, 999, endian, &addr, NULL); rz_mem_swaporcopy((ut8 *)&val_f, buf + i, sizeof(double), endian); if (MUSTSET) { - p->cb_printf("wv8 %s @ 0x%08" PFMT64x "\n", setval, + rz_strbuf_appendf(outbuf, "wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); } else { if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 8 : 0)); } } if (size == -1) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { // XXX this 999 is scary updateAddr(buf + i, 9999, endian, &addr, NULL); rz_mem_swaporcopy((ut8 *)&val_f, buf + i, sizeof(double), endian); if (elem == -1 || elem == 0) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1103,16 +1093,16 @@ static void rz_print_format_double(const RzPrint *p, int endian, int mode, i += 8; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_appendf(outbuf, "}"); } } } -static void rz_print_format_word(const RzPrint *p, int endian, int mode, +static void rz_type_format_word(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -1124,23 +1114,23 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (MUSTSET) { - p->cb_printf("wv2 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 2 : 0)); + rz_strbuf_appendf(outbuf, "wv2 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 2 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); } while ((size -= 2) > 0) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; @@ -1149,26 +1139,26 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, } } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); } if (size == -1) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1176,63 +1166,63 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, i += 2; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while ((size -= 2) > 0) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; } i += 2; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_byte_escape(const RzPrint *p, const char *src, char **dst, int dot_nl) { +static void rz_type_byte_escape(const RzPrint *p, const char *src, char **dst, int dot_nl) { rz_return_if_fail(p->strconv_mode); rz_str_byte_escape(src, dst, dot_nl, !strcmp(p->strconv_mode, "asciidot"), p->esc_bslash); } -static void rz_print_format_nulltermstring(const RzPrint *p, int len, int endian, int mode, +static void rz_type_format_nulltermstring(RzType *t, RzPrint *p, RzStrBuf *outbuf, int len, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { - if (!p->iob.is_valid_offset(p->iob.io, seeki, 1)) { + if (!t->iob.is_valid_offset(t->iob.io, seeki, 1)) { ut8 ch = 0xff; // XXX there are some cases where the memory is there but is_valid_offset fails - if (p->iob.read_at(p->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { - p->cb_printf("-1"); + if (t->iob.read_at(t->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { + rz_strbuf_append(outbuf, "-1"); return; } } - if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(p->iob.io->cached & RZ_PERM_R)) { + if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(t->iob.io->cached & RZ_PERM_R)) { ut64 total_map_left = 0; ut64 addr = seeki; RzIOMap *map; - while (total_map_left < len && (map = p->iob.io->va ? p->iob.map_get(p->iob.io, addr) : p->iob.map_get_paddr(p->iob.io, addr)) && map->perm & RZ_PERM_R) { + while (total_map_left < len && (map = t->iob.io->va ? t->iob.map_get(t->iob.io, addr) : t->iob.map_get_paddr(t->iob.io, addr)) && map->perm & RZ_PERM_R) { if (!map->itv.size) { total_map_left = addr == 0 ? UT64_MAX : UT64_MAX - addr + 1; break; } - total_map_left += map->itv.size - (addr - (p->iob.io->va ? map->itv.addr : map->delta)); + total_map_left += map->itv.size - (addr - (t->iob.io->va ? map->itv.addr : map->delta)); addr += total_map_left; } if (total_map_left < len) { @@ -1253,62 +1243,62 @@ static void rz_print_format_nulltermstring(const RzPrint *p, int len, int endian if (vallen > buflen) { eprintf("Warning: new string is longer than previous one\n"); } - p->cb_printf("wx "); + rz_strbuf_append(outbuf, "wx "); for (i = 0; i < vallen; i++) { if (i < vallen - 3 && newstring[i] == '\\' && newstring[i + 1] == 'x') { - p->cb_printf("%c%c", newstring[i + 2], newstring[i + 3]); + rz_strbuf_appendf(outbuf, "%c%c", newstring[i + 2], newstring[i + 3]); i += 3; } else { - p->cb_printf("%2x", newstring[i]); + rz_strbuf_appendf(outbuf, "%2x", newstring[i]); } } - p->cb_printf(" @ 0x%08" PFMT64x "\n", seeki); + rz_strbuf_appendf(outbuf, " @ 0x%08" PFMT64x "\n", seeki); free(ons); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { int j = i; - (MUSTSEESTRUCT) ? p->cb_printf("\"") : p->cb_printf("\\\""); + (MUSTSEESTRUCT) ? rz_strbuf_append(outbuf, "\"") : rz_strbuf_append(outbuf, "\\\""); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j++) { char ch = buf[j]; if (ch == '"') { - p->cb_printf("\\\""); + rz_strbuf_append(outbuf, "\\\""); } else if (IS_PRINTABLE(ch)) { - p->cb_printf("%c", ch); + rz_strbuf_appendf(outbuf, "%c", ch); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } - (MUSTSEESTRUCT) ? p->cb_printf("\"") : p->cb_printf("\\\""); + (MUSTSEESTRUCT) ? rz_strbuf_append(outbuf, "\"") : rz_strbuf_append(outbuf, "\\\""); } else if (MUSTSEE) { int j = i; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = %s", seeki, overflow ? "ovf " : ""); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = %s", seeki, overflow ? "ovf " : ""); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j++) { char esc_str[5] = { 0 }; char *ptr = esc_str; - rz_print_byte_escape(p, (char *)&buf[j], &ptr, false); - p->cb_printf("%s", esc_str); + rz_type_byte_escape(p, (char *)&buf[j], &ptr, false); + rz_strbuf_appendf(outbuf, "%s", esc_str); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); } else if (MUSTSEEJSON) { char *utf_encoded_buf = NULL; - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); utf_encoded_buf = rz_str_escape_utf8_for_json( (char *)buf + i, size == -1 ? str_len : RZ_MIN(size, str_len)); if (utf_encoded_buf) { - p->cb_printf("%s", utf_encoded_buf); + rz_strbuf_appendf(outbuf, "%s", utf_encoded_buf); free(utf_encoded_buf); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); if (overflow) { - p->cb_printf(",\"overflow\":true"); + rz_strbuf_append(outbuf, ",\"overflow\":true"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_nulltermwidestring(const RzPrint *p, const int len, int endian, int mode, +static void rz_type_format_nulltermwidestring(RzPrint *p, RzStrBuf *outbuf, const int len, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { if (MUSTSET) { int vallen = strlen(setval); @@ -1322,90 +1312,91 @@ static void rz_print_format_nulltermwidestring(const RzPrint *p, const int len, if (vallen > rz_wstr_clen((char *)(buf + seeki))) { eprintf("Warning: new string is longer than previous one\n"); } - p->cb_printf("ww %s @ 0x%08" PFMT64x "\n", newstring, seeki); + rz_strbuf_appendf(outbuf, "ww %s @ 0x%08" PFMT64x "\n", newstring, seeki); free(ons); } else if (MUSTSEE) { int j = i; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j += 2) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } else if (MUSTSEEJSON) { int j = i; - p->cb_printf("%" PFMT64d ",\"string\":\"", seeki); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"string\":\"", seeki); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j += 2) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } - p->cb_printf("\"}"); + rz_strbuf_append(outbuf, "\"}"); } } -static void rz_print_format_bitfield(const RzPrint *p, ut64 seeki, char *fmtname, +static void rz_type_format_bitfield(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *bitfield = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - bitfield = rz_type_enum_getbitfield(p->sdb_types, fmtname, addr); + bitfield = rz_type_enum_getbitfield(t, fmtname, addr); if (bitfield && *bitfield) { if (MUSTSEEJSON) { - p->cb_printf("\"%s\"}", bitfield); + rz_strbuf_appendf(outbuf, "\"%s\"}", bitfield); } else if (MUSTSEE) { - p->cb_printf("%s (bitfield) = %s\n", fieldname, bitfield); + rz_strbuf_appendf(outbuf, "%s (bitfield) = %s\n", fieldname, bitfield); } } else { if (MUSTSEEJSON) { - p->cb_printf("\"`tb %s 0x%" PFMT64x "`\"}", fmtname, addr); + rz_strbuf_appendf(outbuf, "\"`tb %s 0x%" PFMT64x "`\"}", fmtname, addr); } else if (MUSTSEE) { - p->cb_printf("%s (bitfield) = `tb %s 0x%" PFMT64x "`\n", + rz_strbuf_appendf(outbuf, "%s (bitfield) = `tb %s 0x%" PFMT64x "`\n", fieldname, fmtname, addr); } } free(bitfield); } -static void rz_print_format_enum(const RzPrint *p, ut64 seeki, char *fmtname, +static void rz_type_format_enum(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *enumvalue = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - enumvalue = rz_type_enum_member(p->sdb_types, fmtname, NULL, addr); + enumvalue = rz_type_enum_member(t, fmtname, NULL, addr); if (enumvalue && *enumvalue) { if (mode & RZ_PRINT_DOT) { - p->cb_printf("%s.%s", fmtname, enumvalue); + rz_strbuf_appendf(outbuf, "%s.%s", fmtname, enumvalue); } else if (MUSTSEEJSON) { - p->cb_printf("%" PFMT64d ",\"label\":\"%s\",\"enum\":\"%s\"}", + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"label\":\"%s\",\"enum\":\"%s\"}", addr, enumvalue, fmtname); } else if (MUSTSEE) { - p->cb_printf("%s (enum %s) = 0x%" PFMT64x " ; %s\n", + rz_strbuf_appendf(outbuf, "%s (enum %s) = 0x%" PFMT64x " ; %s\n", fieldname, fmtname, addr, enumvalue); } else if (MUSTSEESTRUCT) { - p->cb_printf("%s", enumvalue); + rz_strbuf_appendf(outbuf, "%s", enumvalue); } } else { if (MUSTSEEJSON) { - p->cb_printf("%" PFMT64d ",\"enum\":\"%s\"}", addr, fmtname); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"enum\":\"%s\"}", addr, fmtname); } else if (MUSTSEE) { - p->cb_printf("%s (enum %s) = 0x%" PFMT64x "\n", //`te %s 0x%x`\n", + rz_strbuf_appendf(outbuf, "%s (enum %s) = 0x%" PFMT64x "\n", //`te %s 0x%x`\n", fieldname, fmtname, addr); //enumvalue); //fmtname, addr); } } free(enumvalue); } +/* static void rz_print_format_register(const RzPrint *p, int mode, const char *name, const char *setval) { if (!p || !p->get_register || !p->reg) { @@ -1428,24 +1419,25 @@ static void rz_print_format_register(const RzPrint *p, int mode, p->cb_printf("Register %s does not exists\n", name); } } +*/ -static void rz_print_format_num_specifier(const RzPrint *p, ut64 addr, int bytes, int sign) { +static void rz_type_format_num_specifier(RzStrBuf *outbuf, ut64 addr, int bytes, int sign) { #define EXT(T) (sign ? (signed T)(addr) : (unsigned T)(addr)) const char *fs64 = sign ? "%" PFMT64d : "%" PFMT64u; const char *fs = sign ? "%d" : "%u"; if (bytes == 1) { - p->cb_printf(fs, EXT(char)); + rz_strbuf_appendf(outbuf, fs, EXT(char)); } else if (bytes == 2) { - p->cb_printf(fs, EXT(short)); + rz_strbuf_appendf(outbuf, fs, EXT(short)); } else if (bytes == 4) { - p->cb_printf(fs, EXT(int)); //XXX: int is not necessarily 4 bytes I guess. + rz_strbuf_appendf(outbuf, fs, EXT(int)); //XXX: int is not necessarily 4 bytes I guess. } else if (bytes == 8) { - p->cb_printf(fs64, addr); + rz_strbuf_appendf(outbuf, fs64, addr); } #undef EXT } -static void rz_print_format_num(const RzPrint *p, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int bytes, int sign, int size) { +static void rz_type_format_num(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int bytes, int sign, int size) { ut64 addr = 0LL; int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -1458,18 +1450,18 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size - i, endian, &addr, NULL); } if (MUSTSET) { - p->cb_printf("wv%d %s @ 0x%08" PFMT64x "\n", bytes, setval, seeki + ((elem >= 0) ? elem * (bytes) : 0)); + rz_strbuf_appendf(outbuf, "wv%d %s @ 0x%08" PFMT64x "\n", bytes, setval, seeki + ((elem >= 0) ? elem * (bytes) : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * bytes : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * bytes : 0)); } if (size == -1) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (bytes == 8) { @@ -1478,13 +1470,13 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size - i, endian, &addr, NULL); } if (elem == -1 || elem == 0) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1492,14 +1484,14 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch i += bytes; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (bytes == 8) { updateAddr(buf + i, size, endian, NULL, &addr); @@ -1507,27 +1499,27 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size, endian, &addr, NULL); } if (elem == -1 || elem == 0) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += bytes; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -RZ_API const char *rz_type_format_byname(RzPrint *p, const char *name) { - return sdb_const_get(p->formats, name, NULL); +RZ_API const char *rz_type_format_byname(RzType *t, const char *name) { + return sdb_const_get(t->formats, name, NULL); } static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { @@ -1613,7 +1605,7 @@ static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { RZ_API char *rz_type_format(RzType *type, const char *t) { char var[130], var2[132]; - Sdb *TDB = type->sdb_types + Sdb *TDB = type->sdb_types; const char *kind = sdb_const_get(TDB, t, NULL); if (!kind) { return NULL; @@ -1640,7 +1632,7 @@ RZ_API char *rz_type_format(RzType *type, const char *t) { } // XXX: this is somewhat incomplete. must be updated to handle all format chars -RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n) { +RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) { char *end, *args, *fmt; int size = 0, tabsize = 0, i, idx = 0, biggest = 0, fmt_len = 0, times = 1; bool tabsize_set = false; @@ -1650,7 +1642,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n if (n >= 5) { // This is the nesting level, is this not a bit arbitrary?! return 0; } - const char *fmt2 = sdb_get(p->formats, f, NULL); + const char *fmt2 = sdb_get(t->formats, f, NULL); if (!fmt2) { fmt2 = f; } @@ -1745,7 +1737,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n size += tabsize; break; case '*': - size += tabsize * (p->bits / 8); + size += tabsize * (t->target->bits / 8); i++; idx--; //no need to go ahead for args break; @@ -1792,14 +1784,14 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n tmp = *format; } } else { - format = sdb_get(p->formats, structname + 1, NULL); + format = sdb_get(t->formats, structname + 1, NULL); if (format && !strncmp(format, f, strlen(format) - 1)) { // Avoid recursion here free(o); free(structname); return -1; } if (!format) { // Fetch format from types db - format = rz_type_format(p->sdb_types, structname + 1); + format = rz_type_format(t, structname + 1); } } if (!format) { @@ -1808,7 +1800,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n free(o); return 0; } - int newsize = rz_print_format_struct_size(p, format, mode, n + 1); + int newsize = rz_type_format_struct_size(t, format, mode, n + 1); if (newsize < 1) { eprintf("Cannot find size for `%s'\n", format); free(structname); @@ -1848,7 +1840,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n } else if (fmt[i + 1] == '8') { size += tabsize * 8; } else { - size += tabsize * (p->bits / 8); + size += tabsize * (t->target->bits / 8); break; } i++; @@ -1895,7 +1887,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n return (mode & RZ_PRINT_UNIONMODE) ? biggest : size; } -static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, const char *name, +static int rz_type_format_struct(RzType *t, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, int len, const char *name, int slide, int mode, const char *setval, char *field, int anon) { const char *fmt; char namefmt[128]; @@ -1907,9 +1899,9 @@ static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, if (anon) { fmt = name; } else { - fmt = sdb_get(p->formats, name, NULL); + fmt = sdb_get(t->formats, name, NULL); if (!fmt) { // Fetch struct info from types DB - fmt = rz_type_format(p->sdb_types, name); + fmt = rz_type_format(t, name); } } if (!fmt || !*fmt) { @@ -1919,14 +1911,14 @@ static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, if (MUSTSEE && !SEEVALUE) { snprintf(namefmt, sizeof(namefmt), "%%%ds", 10 + 6 * slide % STRUCTPTR); if (fmt[0] == '0') { - p->cb_printf(namefmt, "union"); + rz_strbuf_appendf(outbuf, namefmt, "union"); } else { - p->cb_printf(namefmt, "struct"); + rz_strbuf_appendf(outbuf, namefmt, "struct"); } - p->cb_printf("<%s>\n", name); + rz_strbuf_appendf(outbuf, "<%s>\n", name); } - rz_print_format(p, seek, b, len, fmt, mode, setval, field); - return rz_print_format_struct_size(p, fmt, mode, 0); + rz_type_format_data(t, p, seek, b, len, fmt, mode, setval, field); + return rz_type_format_struct_size(t, fmt, mode, 0); } static char *get_args_offset(const char *arg) { @@ -2013,10 +2005,306 @@ static char *get_format_type(const char fmt, const char arg) { #define MINUSONE ((void *)(size_t)-1) #define ISSTRUCT (tmp == '?' || (tmp == '*' && *(arg + 1) == '?')) -RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, + +static int format_character_data(RzType *t, RzPrint *p, RzStrBuf *outbuf, int len, char fmtchar, char **fmtname, + int endian, int mode, const char *setval, ut64 addr, ut64 addr64, ut64 seek, ut64 seeki, ut8 *buf, int i, int size, + int isptr, int *ident, int *slide, int *oldslide, int *invalid, bool *noline, int *elem, char *field, char *fieldname, char *ofield, char *arg) { + /* format chars */ + // before to enter in the switch statement check buf boundaries due to updateAddr + // might go beyond its len and it's usually called in each of the following functions + switch (fmtchar) { + case 'u': + i += rz_type_format_uleb(outbuf, endian, mode, setval, seeki, buf, i, size); + break; + case 't': + rz_type_format_time(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + case 'q': + rz_type_format_quadword(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 8 : 8 * size; + break; + case 'Q': + rz_type_format_u128(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 16 : 16 * size; + break; + case 'b': + rz_type_format_byte(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 1 : size; + break; + case 'C': + rz_type_format_decchar(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 1 : size; + break; + case 'c': + rz_type_format_char(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 1 : size; + break; + case 'X': + size = rz_type_format_hexpairs(outbuf, endian, mode, setval, seeki, buf, i, size); + i += size; + break; + case 'T': + if (rz_type_format_10bytes(t, outbuf, mode, + setval, seeki, addr, buf) == 0) { + i += (size == -1) ? 4 : 4 * size; + } + break; + case 'f': + rz_type_format_float(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + case 'F': + rz_type_format_double(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 8 : 8 * size; + break; + case 'i': + rz_type_format_int(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + case 'd': //WHY?? help says: 0x%%08x hexadecimal value (4 bytes) + rz_type_format_hex(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + // TODO: Not sure if it's even necessary + /* + case 'D': + if (isptr) { + if (t->target->bits == 64) { + i += rz_type_format_disasm(p, addr64, size); + } else { + i += rz_type_format_disasm(p, addr, size); + } + } else { + i += rz_type_format_disasm(p, seeki, size); + } + break; + */ + case 'o': + rz_type_format_octal(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + case ';': + *noline = true; + i -= (size == -1) ? 4 : 4 * size; + if (i < 0) { + i = 0; + } + break; + case ',': + *noline = true; + i -= (size == -1) ? 1 : size; + if (i < 0) { + i = 0; + } + break; + case 'x': + rz_type_format_hexflag(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 4 : 4 * size; + break; + case 'w': + rz_type_format_word(outbuf, endian, mode, setval, seeki, buf, i, size); + i += (size == -1) ? 2 : 2 * size; + break; + case 'z': // zero terminated string + rz_type_format_nulltermstring(t, p, outbuf, len, endian, mode, setval, seeki, buf, i, size); + if (size == -1) { + i += strlen((char *)buf + i) + 1; + } else { + while (size--) { + i++; + } + } + break; + case 'Z': // zero terminated wide string + rz_type_format_nulltermwidestring(p, outbuf, len, endian, mode, setval, seeki, buf, i, size); + if (size == -1) { + i += rz_wstr_clen((char *)(buf + i)) * 2 + 2; + } else { + while (size--) { + i += 2; + } + } + break; + case 's': + if (rz_type_format_string(t, outbuf, seeki, addr64, addr, 0, mode) == 0) { + i += (size == -1) ? 4 : 4 * size; + } + break; + case 'S': + if (rz_type_format_string(t, outbuf, seeki, addr64, addr, 1, mode) == 0) { + i += (size == -1) ? 8 : 8 * size; + } + break; + case 'B': // resolve bitfield + if (size >= ARRAYINDEX_COEF) { + size %= ARRAYINDEX_COEF; + } + rz_type_format_bitfield(t, outbuf, seeki, *fmtname, fieldname, addr, mode, size); + i += (size == -1) ? 1 : size; + break; + case 'E': // resolve enum + if (size >= ARRAYINDEX_COEF) { + size %= ARRAYINDEX_COEF; + } + rz_type_format_enum(t, outbuf, seeki, *fmtname, fieldname, addr, mode, size); + i += (size == -1) ? 1 : size; + break; + /* + case 'r': + if (*fmtname) { + rz_type_format_register(p, mode, *fmtname, setval); + } else { + eprintf("Unknown register\n"); + } + break; + */ + case '?': { + int s = 0; + char *nxtfield = NULL; + char *format = NULL; + int anon = 0; + if (size >= ARRAYINDEX_COEF) { + *elem = size / ARRAYINDEX_COEF - 1; + size %= ARRAYINDEX_COEF; + } + if (!(mode & RZ_PRINT_ISFIELD)) { + nxtfield = MINUSONE; + } else if (field) { + nxtfield = strchr(ofield, '.'); + } + if (nxtfield != MINUSONE && nxtfield) { + nxtfield++; + } + + if (MUSTSEE) { + if (!SEEVALUE) { + rz_strbuf_append(outbuf, "\n"); + } + } + if (MUSTSEEJSON) { + if (isptr) { + rz_strbuf_appendf(outbuf, "%" PFMT64d "},", seeki); + } else { + rz_strbuf_append(outbuf, "["); + } + } + if (MUSTSEESTRUCT) { + if (isptr) { + rz_strbuf_appendf(outbuf, "%" PFMT64d, seeki); + } else { + *ident += 4; + rz_strbuf_append(outbuf, "\n"); + } + } + if (mode & RZ_PRINT_SEEFLAGS) { + slide += STRUCTFLAG; + } + if (!*fmtname) { + break; + } + format = strchr(*fmtname, ' '); + if (format) { + anon = 1; + *fmtname = format; + while (**fmtname == ' ') { + (*fmtname)++; + } + } + *oldslide = *slide; + //*slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT; + *slide += NESTEDSTRUCT; + if (size == -1) { + s = rz_type_format_struct(t, p, outbuf, seeki, + buf + i, len - i, *fmtname, *slide, + mode, setval, nxtfield, anon); + i += (isptr) ? (t->target->bits / 8) : s; + if (MUSTSEEJSON) { + if (!isptr && (!arg[1] || arg[1] == ' ')) { + rz_strbuf_append(outbuf, "]}"); + } + } + } else { + if (mode & RZ_PRINT_ISFIELD) { + if (!SEEVALUE) { + rz_strbuf_append(outbuf, "[\n"); + } + } + while (size--) { + if (mode && (*elem == -1 || *elem == 0)) { + mode |= RZ_PRINT_MUSTSEE; + if (*elem == 0) { + *elem = -2; + } + } else { + mode &= ~RZ_PRINT_MUSTSEE; + } + s = rz_type_format_struct(t, p, outbuf, seek + i, + buf + i, len - i, *fmtname, *slide, mode, setval, nxtfield, anon); + if ((MUSTSEE || MUSTSEEJSON || MUSTSEESTRUCT) && size != 0 && *elem == -1) { + if (MUSTSEEJSON) { + rz_strbuf_append(outbuf, ","); + } else if (MUSTSEE || MUSTSEESTRUCT) { + rz_strbuf_append(outbuf, "\n"); + } + } + if (*elem > -1) { + (*elem)--; + } + i += (isptr) ? (t->target->bits / 8) : s; + } + if (mode & RZ_PRINT_ISFIELD) { + if (!SEEVALUE) { + rz_strbuf_append(outbuf, "]\n"); + } + } + if (MUSTSEEJSON) { + rz_strbuf_append(outbuf, "]}"); + } + } + *oldslide = *slide; + //*slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT; + *slide -= NESTEDSTRUCT; + if (mode & RZ_PRINT_SEEFLAGS) { + *oldslide = *slide; + *slide -= STRUCTFLAG; + } + break; + } + case 'n': + case 'N': { + int bytes = 0; + int sign = (fmtchar == 'n') ? 1 : 0; + if (arg[1] == '1') { + bytes = 1; + } else if (arg[1] == '2') { + bytes = 2; + } else if (arg[1] == '4') { + bytes = 4; + } else if (arg[1] == '8') { + bytes = 8; + } else { + *invalid = 1; + break; + //or goto beach;??? + } + rz_type_format_num(outbuf, endian, mode, setval, seeki, buf, i, bytes, sign, size); + i += (size == -1) ? bytes : size * bytes; + arg++; + break; + } + default: + /* ignore unknown chars */ + *invalid = 1; + break; + } //switch + return i; +} + +RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield) { int nargs, i, invalid, nexti, idx, times, otimes, endian, isptr = 0; - const int old_bits = p->bits; + const int old_bits = t->target->bits; char *args = NULL, *bracket, tmp, last = 0; ut64 addr = 0, addr64 = 0, seeki = 0; static int slide = 0, oldslide = 0, ident = 4; @@ -2032,7 +2320,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (!formatname) { return 0; } - fmt = sdb_get(p->formats, formatname, NULL); + fmt = sdb_get(t->formats, formatname, NULL); if (!fmt) { fmt = formatname; } @@ -2050,6 +2338,9 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, free(internal_format); return 0; } + + RzStrBuf *outbuf = rz_strbuf_new(""); + // len+2 to save space for the null termination in wide strings ut8 *buf = calloc(1, len + 2); if (!buf) { @@ -2057,7 +2348,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, return 0; } memcpy(buf, b, len); - endian = p->big_endian; + endian = t->target->big_endian; if (ofield && ofield != MINUSONE) { field = strdup(ofield); @@ -2114,20 +2405,21 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, snprintf(namefmt, sizeof(namefmt), "%%%ds :%s", ((maxl + 1) * (1 + slide)) % STRUCTPTR, ends); } + #define ISPOINTED ((slide % STRUCTFLAG) / STRUCTPTR <= (oldslide % STRUCTFLAG) / STRUCTPTR) #define ISNESTED ((slide % STRUCTPTR) <= (oldslide % STRUCTPTR)) if (mode == RZ_PRINT_JSON && slide == 0) { - p->cb_printf("["); + rz_strbuf_append(outbuf, "["); } if (mode == RZ_PRINT_STRUCT) { if (formatname && *formatname) { if (strchr(formatname, ' ')) { - p->cb_printf("struct {\n"); + rz_strbuf_append(outbuf, "struct {\n"); } else { - p->cb_printf("struct %s {\n", formatname); + rz_strbuf_appendf(outbuf, "struct %s {\n", formatname); } } else { - p->cb_printf("struct {\n"); + rz_strbuf_append(outbuf, "struct {\n"); } } if (mode && arg[0] == '0') { @@ -2147,8 +2439,8 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } else { fmtname = rz_str_newf("0x%" PFMT64x, seek); } - p->cb_printf("digraph g { graph [ rank=same; rankdir=LR; ];\n"); - p->cb_printf("root [ rank=1; shape=record\nlabel=\"%s", fmtname); + rz_strbuf_append(outbuf, "digraph g { graph [ rank=same; rankdir=LR; ];\n"); + rz_strbuf_appendf(outbuf, "root [ rank=1; shape=record\nlabel=\"%s", fmtname); } /* go format */ @@ -2162,11 +2454,11 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (otimes > 1) { if (mode & RZ_PRINT_JSON) { if (otimes > times) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } - p->cb_printf("[{\"index\":%d,\"offset\":%" PFMT64d "},", otimes - times, seek + i); + rz_strbuf_appendf(outbuf, "[{\"index\":%d,\"offset\":%" PFMT64d "},", otimes - times, seek + i); } else if (mode) { - p->cb_printf("0x%08" PFMT64x " [%d] {\n", seek + i, otimes - times); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " [%d] {\n", seek + i, otimes - times); } } arg = orig; @@ -2179,7 +2471,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, seeki = seek + i; addr = 0LL; invalid = 0; - p->bits = old_bits; + t->target->bits = old_bits; if (arg[0] == '[') { char *end = strchr(arg, ']'); if (!end) { @@ -2187,13 +2479,13 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, goto beach; } *end = '\0'; - size = rz_get_size(p->num, buf, endian, arg + 1); + size = rz_get_size(t->num, buf, endian, arg + 1); arg = end + 1; *end = ']'; } else { size = -1; } - int fs = rz_print_format_struct_size(p, arg, 0, idx); + int fs = rz_type_format_struct_size(t, arg, 0, idx); if (fs == -2) { i = -1; goto beach; @@ -2208,7 +2500,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } else { updateAddr(buf + i, len - i, endian, &addr, &addr64); } - if (p->bits == 64) { + if (t->target->bits == 64) { addr = addr64; } } else { @@ -2223,7 +2515,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } if (!(mode & RZ_PRINT_QUIET)) { if (mode & RZ_PRINT_MUSTSEE && otimes > 1) { - p->cb_printf(" "); + rz_strbuf_append(outbuf, " "); } } if (idx < nargs && tmp != 'e' && isptr == 0) { @@ -2277,7 +2569,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, idx++; if (MUSTSEE && !SEEVALUE) { if (!ISQUIET) { - p->cb_printf(namefmt, fieldname); + rz_strbuf_appendf(outbuf, namefmt, fieldname); } } } @@ -2285,31 +2577,24 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, feed_me_again: switch (isptr) { case PTRSEEK: { - nexti = i + (p->bits / 8); + nexti = i + (t->target->bits / 8); i = 0; if (tmp == '?') { seeki = addr; } memset(buf, '\0', len); if (MUSTSEE && !ISQUIET) { - p->cb_printf("(*0x%" PFMT64x ")", addr); + rz_strbuf_appendf(outbuf, "(*0x%" PFMT64x ")", addr); } isptr = (addr) ? PTRBACK : NULLPTR; - if (p->iob.read_at) { - p->iob.read_at(p->iob.io, (ut64)addr, buf, len - 4); - if (((i + 3) < len) || ((i + 7) < len)) { - // XXX this breaks pf *D - if (tmp != 'D') { - updateAddr(buf + i, len - i, endian, &addr, &addr64); - } - } else { - eprintf("Likely a heap buffer overflow.\n"); - goto beach; + t->iob.read_at(t->iob.io, (ut64)addr, buf, len - 4); + if (((i + 3) < len) || ((i + 7) < len)) { + // XXX this breaks pf *D + if (tmp != 'D') { + updateAddr(buf + i, len - i, endian, &addr, &addr64); } } else { - eprintf("(cannot read at 0x%08" PFMT64x ", block: %s, blocksize: 0x%x)\n", - addr, b, len); - p->cb_printf("\n"); + eprintf("Likely a heap buffer overflow.\n"); goto beach; } } break; @@ -2361,7 +2646,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, tmp = 'q'; arg++; } else { //If pointer reference is not mentioned explicitly - switch (p->bits) { + switch (t->target->bits) { case 16: tmp = 'w'; break; case 32: tmp = 'x'; break; default: tmp = 'q'; break; @@ -2377,16 +2662,16 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, newname = fieldname = rz_str_newf("pf.%" PFMT64u, seeki); } if (mode & RZ_PRINT_UNIONMODE) { - p->cb_printf("f %s=0x%08" PFMT64x "\n", formatname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", formatname, seeki); goto beach; } else if (tmp == '?') { - p->cb_printf("f %s.%s_", fmtname, fieldname); + rz_strbuf_appendf(outbuf, "f %s.%s_", fmtname, fieldname); } else if (tmp == 'E') { - p->cb_printf("f %s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", fieldname, seeki); } else if (slide / STRUCTFLAG > 0 && idx == 1) { - p->cb_printf("%s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "%s=0x%08" PFMT64x "\n", fieldname, seeki); } else { - p->cb_printf("f %s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", fieldname, seeki); } if (newname) { RZ_FREE(newname); @@ -2397,10 +2682,10 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, /* dot */ if (mode & RZ_PRINT_DOT) { if (fieldname) { - p->cb_printf("|{0x%" PFMT64x "|%c|%s|<%s>", + rz_strbuf_appendf(outbuf, "|{0x%" PFMT64x "|%c|%s|<%s>", seeki, tmp, fieldname, fieldname); } else { - p->cb_printf("|{0x%" PFMT64x "|%c|", + rz_strbuf_appendf(outbuf, "|{0x%" PFMT64x "|%c|", seeki, tmp); } } @@ -2411,40 +2696,40 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (first) { first = 0; } else { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } } else if (oldslide) { - p->cb_printf("]},"); + rz_strbuf_append(outbuf, "]},"); oldslide -= NESTEDSTRUCT; } if (fieldname) { - p->cb_printf("{\"name\":\"%s\",\"type\":\"", fieldname); + rz_strbuf_appendf(outbuf, "{\"name\":\"%s\",\"type\":\"", fieldname); } else { - p->cb_printf("{\"type\":\""); + rz_strbuf_append(outbuf, "{\"type\":\""); } if (ISSTRUCT) { - p->cb_printf("%s", fmtname); + rz_strbuf_appendf(outbuf, "%s", fmtname); } else { if (tmp == 'n' || tmp == 'N') { - p->cb_printf("%c%c", tmp, *(arg + 1)); + rz_strbuf_appendf(outbuf, "%c%c", tmp, *(arg + 1)); } else { - p->cb_printf("%c", tmp); + rz_strbuf_appendf(outbuf, "%c", tmp); } } if (isptr) { - p->cb_printf("*"); + rz_strbuf_append(outbuf, "*"); } - p->cb_printf("\",\"offset\":%" PFMT64d ",\"value\":", - isptr ? (seek + nexti - (p->bits / 8)) : seek + i); + rz_strbuf_appendf(outbuf, "\",\"offset\":%" PFMT64d ",\"value\":", + isptr ? (seek + nexti - (t->target->bits / 8)) : seek + i); } /* c struct */ if (MUSTSEESTRUCT) { char *type = get_format_type(tmp, (tmp == 'n' || tmp == 'N') ? arg[1] : 0); if (type) { - p->cb_printf("%*c%s %s; // ", ident, ' ', type, fieldname); + rz_strbuf_appendf(outbuf, "%*c%s %s; // ", ident, ' ', type, fieldname); } else { - p->cb_printf("%*cstruct %s {", ident, ' ', fieldname); + rz_strbuf_appendf(outbuf, "%*cstruct %s {", ident, ' ', fieldname); } free(type); } @@ -2453,327 +2738,44 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, int oi = i; if (isptr == NULLPTR) { if (MUSTSEEJSON) { - p->cb_printf("\"NULL\"}"); + rz_strbuf_append(outbuf, "\"NULL\"}"); } else if (MUSTSEE) { - p->cb_printf(" NULL\n"); + rz_strbuf_append(outbuf, " NULL\n"); } isptr = PTRBACK; } else { - /* format chars */ - // before to enter in the switch statement check buf boundaries due to updateAddr - // might go beyond its len and it's usually called in each of the following functions - switch (tmp) { - case 'u': - i += rz_print_format_uleb(p, endian, mode, setval, seeki, buf, i, size); - break; - case 't': - rz_print_format_time(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case 'q': - rz_print_format_quadword(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 8 : 8 * size; - break; - case 'Q': - rz_print_format_u128(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 16 : 16 * size; - break; - case 'b': - rz_print_format_byte(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 1 : size; - break; - case 'C': - rz_print_format_decchar(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 1 : size; - break; - case 'c': - rz_print_format_char(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 1 : size; - break; - case 'X': - size = rz_print_format_hexpairs(p, endian, mode, setval, seeki, buf, i, size); - i += size; - break; - case 'T': - if (rz_print_format_10bytes(p, mode, - setval, seeki, addr, buf) == 0) { - i += (size == -1) ? 4 : 4 * size; - } - break; - case 'f': - rz_print_format_float(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case 'F': - rz_print_format_double(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 8 : 8 * size; - break; - case 'i': - rz_print_format_int(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case 'd': //WHY?? help says: 0x%%08x hexadecimal value (4 bytes) - rz_print_format_hex(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case 'D': - if (isptr) { - if (p->bits == 64) { - i += rz_print_format_disasm(p, addr64, size); - } else { - i += rz_print_format_disasm(p, addr, size); - } - } else { - i += rz_print_format_disasm(p, seeki, size); - } - break; - case 'o': - rz_print_format_octal(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case ';': - noline = true; - i -= (size == -1) ? 4 : 4 * size; - if (i < 0) { - i = 0; - } - break; - case ',': - noline = true; - i -= (size == -1) ? 1 : size; - if (i < 0) { - i = 0; - } - break; - case 'x': - rz_print_format_hexflag(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 4 : 4 * size; - break; - case 'w': - rz_print_format_word(p, endian, mode, setval, seeki, buf, i, size); - i += (size == -1) ? 2 : 2 * size; - break; - case 'z': // zero terminated string - rz_print_format_nulltermstring(p, len, endian, mode, setval, seeki, buf, i, size); - if (size == -1) { - i += strlen((char *)buf + i) + 1; - } else { - while (size--) { - i++; - } - } - break; - case 'Z': // zero terminated wide string - rz_print_format_nulltermwidestring(p, len, endian, mode, setval, seeki, buf, i, size); - if (size == -1) { - i += rz_wstr_clen((char *)(buf + i)) * 2 + 2; - } else { - while (size--) { - i += 2; - } - } - break; - case 's': - if (rz_print_format_string(p, seeki, addr64, addr, 0, mode) == 0) { - i += (size == -1) ? 4 : 4 * size; - } - break; - case 'S': - if (rz_print_format_string(p, seeki, addr64, addr, 1, mode) == 0) { - i += (size == -1) ? 8 : 8 * size; - } - break; - case 'B': // resolve bitfield - if (size >= ARRAYINDEX_COEF) { - size %= ARRAYINDEX_COEF; - } - rz_print_format_bitfield(p, seeki, fmtname, fieldname, addr, mode, size); - i += (size == -1) ? 1 : size; - break; - case 'E': // resolve enum - if (size >= ARRAYINDEX_COEF) { - size %= ARRAYINDEX_COEF; - } - rz_print_format_enum(p, seeki, fmtname, fieldname, addr, mode, size); - i += (size == -1) ? 1 : size; - break; - case 'r': - if (fmtname) { - rz_print_format_register(p, mode, fmtname, setval); - } else { - eprintf("Unknown register\n"); - } - break; - case '?': { - int s = 0; - char *nxtfield = NULL; - char *format = NULL; - int anon = 0; - if (size >= ARRAYINDEX_COEF) { - elem = size / ARRAYINDEX_COEF - 1; - size %= ARRAYINDEX_COEF; - } - if (!(mode & RZ_PRINT_ISFIELD)) { - nxtfield = MINUSONE; - } else if (field) { - nxtfield = strchr(ofield, '.'); - } - if (nxtfield != MINUSONE && nxtfield) { - nxtfield++; - } - - if (MUSTSEE) { - if (!SEEVALUE) { - p->cb_printf("\n"); - } - } - if (MUSTSEEJSON) { - if (isptr) { - p->cb_printf("%" PFMT64d "},", seeki); - } else { - p->cb_printf("["); - } - } - if (MUSTSEESTRUCT) { - if (isptr) { - p->cb_printf("%" PFMT64d, seeki); - } else { - ident += 4; - p->cb_printf("\n"); - } - } - if (mode & RZ_PRINT_SEEFLAGS) { - slide += STRUCTFLAG; - } - if (!fmtname) { - break; - } - format = strchr(fmtname, ' '); - if (format) { - anon = 1; - fmtname = format; - while (*fmtname == ' ') { - fmtname++; - } - } - oldslide = slide; - //slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT; - slide += NESTEDSTRUCT; - if (size == -1) { - s = rz_print_format_struct(p, seeki, - buf + i, len - i, fmtname, slide, - mode, setval, nxtfield, anon); - i += (isptr) ? (p->bits / 8) : s; - if (MUSTSEEJSON) { - if (!isptr && (!arg[1] || arg[1] == ' ')) { - p->cb_printf("]}"); - } - } - } else { - if (mode & RZ_PRINT_ISFIELD) { - if (!SEEVALUE) { - p->cb_printf("[\n"); - } - } - while (size--) { - if (mode && (elem == -1 || elem == 0)) { - mode |= RZ_PRINT_MUSTSEE; - if (elem == 0) { - elem = -2; - } - } else { - mode &= ~RZ_PRINT_MUSTSEE; - } - s = rz_print_format_struct(p, seek + i, - buf + i, len - i, fmtname, slide, mode, setval, nxtfield, anon); - if ((MUSTSEE || MUSTSEEJSON || MUSTSEESTRUCT) && size != 0 && elem == -1) { - if (MUSTSEEJSON) { - p->cb_printf(","); - } else if (MUSTSEE || MUSTSEESTRUCT) { - p->cb_printf("\n"); - } - } - if (elem > -1) { - elem--; - } - i += (isptr) ? (p->bits / 8) : s; - } - if (mode & RZ_PRINT_ISFIELD) { - if (!SEEVALUE) { - p->cb_printf("]\n"); - } - } - if (MUSTSEEJSON) { - p->cb_printf("]}"); - } - } - oldslide = slide; - //slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT; - slide -= NESTEDSTRUCT; - if (mode & RZ_PRINT_SEEFLAGS) { - oldslide = slide; - slide -= STRUCTFLAG; - } - break; - } - case 'n': - case 'N': { - int bytes = 0; - int sign = (tmp == 'n') ? 1 : 0; - if (arg[1] == '1') { - bytes = 1; - } else if (arg[1] == '2') { - bytes = 2; - } else if (arg[1] == '4') { - bytes = 4; - } else if (arg[1] == '8') { - bytes = 8; - } else { - invalid = 1; - break; - //or goto beach;??? - } - rz_print_format_num(p, endian, mode, setval, seeki, buf, i, bytes, sign, size); - i += (size == -1) ? bytes : size * bytes; - arg++; - break; - } - default: - /* ignore unknown chars */ - invalid = 1; - break; - } //switch + i = format_character_data(t, p, outbuf, len, tmp, &fmtname, endian, mode, setval, addr, addr64, seek, seeki, buf, i, size, isptr, &ident, &slide, &oldslide, &invalid, &noline, &elem, field, fieldname, ofield, arg); } if (MUSTSEESTRUCT) { if (oldslide) { ident -= 4; - p->cb_printf("%*c}", ident, ' '); + rz_strbuf_appendf(outbuf, "%*c}", ident, ' '); oldslide -= NESTEDSTRUCT; } - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } if (mode & RZ_PRINT_DOT) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } if (mode & RZ_PRINT_SEEFLAGS && isptr != NULLPTR) { int sz = i - oi; if (sz > 1) { - p->cb_printf("fl %d @ 0x%08" PFMT64x "\n", sz, seeki); - p->cb_printf("Cd %d @ 0x%08" PFMT64x "\n", sz, seeki); + rz_strbuf_appendf(outbuf, "fl %d @ 0x%08" PFMT64x "\n", sz, seeki); + rz_strbuf_appendf(outbuf, "Cd %d @ 0x%08" PFMT64x "\n", sz, seeki); } } if (viewflags && p->offname) { const char *s = p->offname(p->user, seeki); if (s) { - p->cb_printf("@(%s)", s); + rz_strbuf_appendf(outbuf, "@(%s)", s); } s = p->offname(p->user, addr); if (s) { - p->cb_printf("*(%s)", s); + rz_strbuf_appendf(outbuf, "*(%s)", s); } } if (!noline && tmp != 'D' && !invalid && !fmtname && MUSTSEE) { - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } last = tmp; @@ -2796,22 +2798,22 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } if (otimes > 1) { if (MUSTSEEJSON) { - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); } else if (mode) { - p->cb_printf("}\n"); + rz_strbuf_append(outbuf, "}\n"); } } arg = orig; oldslide = 0; } if (mode & RZ_PRINT_JSON && slide == 0) { - p->cb_printf("]\n"); + rz_strbuf_append(outbuf, "]\n"); } if (MUSTSEESTRUCT && slide == 0) { - p->cb_printf("}\n"); + rz_strbuf_append(outbuf, "}\n"); } if (mode & RZ_PRINT_DOT) { - p->cb_printf("\"];\n}\n"); + rz_strbuf_append(outbuf, "\"];\n}\n"); // TODO: show nested structs and field reference lines } beach: @@ -2823,5 +2825,36 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, free(buf); free(field); free(args); - return i; + //return i; + char *outstr = rz_strbuf_drain(outbuf); + return outstr; +} + +RZ_API const char *rz_type_format_get(RzType *t, const char *name) { + return sdb_get(t->formats, name, NULL); +} + +RZ_API void rz_type_format_set(RzType *t, const char *name, const char *fmt) { + sdb_set(t->formats, name, fmt, 0); +} + +RZ_API RZ_OWN RzList *rz_type_format_all(RzType *t) { + SdbListIter *iter; + SdbKv *kv; + RzList *fmtl = rz_list_newf(free); + SdbList *sdbls = sdb_foreach_list(t->formats, true); + ls_foreach (sdbls, iter, kv) { + char *fmt = rz_str_newf("%s %s", sdbkv_key(kv), sdbkv_value(kv)); + rz_list_append(fmtl, fmt); + } + return fmtl; +} + +RZ_API void rz_type_format_delete(RzType *t, const char *name) { + sdb_unset(t->formats, name, 0); +} + +RZ_API void rz_type_format_purge(RzType *t) { + sdb_free(t->formats); + t->formats = sdb_new0(); } diff --git a/librz/type/function.c b/librz/type/function.c index ddf35941757..354be132e74 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -261,4 +261,3 @@ RZ_API RzList *rz_type_noreturn_functions(RzType *type) { ls_free(l); return noretl; } - diff --git a/librz/type/link.c b/librz/type/link.c index 34592af48da..ed65cc9c8d9 100644 --- a/librz/type/link.c +++ b/librz/type/link.c @@ -117,5 +117,3 @@ RZ_API bool rz_type_unlink_all(RzType *t) { sdb_foreach(TDB, sdbdeletelink, TDB); return true; } - - diff --git a/librz/type/meson.build b/librz/type/meson.build index bbdf1566c75..b4c9951e4c0 100644 --- a/librz/type/meson.build +++ b/librz/type/meson.build @@ -1,6 +1,7 @@ rz_type_sources = [ 'base.c', 'code.c', + 'format.c', 'function.c', 'link.c', 'serialize_types.c', diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c index 7c3b51fd834..39e73aa5c2a 100644 --- a/librz/type/serialize_types.c +++ b/librz/type/serialize_types.c @@ -15,5 +15,3 @@ RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types sdb_copy(db, types->sdb_types); return true; } - - diff --git a/librz/type/type.c b/librz/type/type.c index 661d490e2b5..849b830a494 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -15,13 +15,21 @@ RZ_API RzType *rz_type_new() { if (!type) { return NULL; } + type->target = RZ_NEW0(RzTypeTarget); + if (!type->target) { + return NULL; + } Sdb *sdb = sdb_new0(); type->sdb_types = sdb_ns(sdb, "types", 1); + type->formats = sdb_new0(); + rz_io_bind_init(type->iob); return type; } RZ_API void rz_type_free(RzType *t) { sdb_free(t->sdb_types); + sdb_free(t->formats); + free(t->target); free(t); } @@ -275,5 +283,3 @@ RZ_API RzList *rz_type_links(RzType *type) { ls_free(l); return ccl; } - - diff --git a/librz/type/utype.c b/librz/type/utype.c index 4e9eb433d29..127204c2eac 100644 --- a/librz/type/utype.c +++ b/librz/type/utype.c @@ -337,5 +337,3 @@ RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset) { ls_free(ls); return offtypes; } - - diff --git a/librz/util/print.c b/librz/util/print.c index b2d52ef04d0..f0be69b6985 100644 --- a/librz/util/print.c +++ b/librz/util/print.c @@ -172,7 +172,6 @@ RZ_API RzPrint *rz_print_new(void) { p->cols = 16; p->cur_enabled = false; p->cur = p->ocur = -1; - p->formats = sdb_new0(); p->addrmod = 4; p->flags = RZ_PRINT_FLAGS_COLOR | @@ -200,8 +199,6 @@ RZ_API RzPrint *rz_print_free(RzPrint *p) { if (!p) { return NULL; } - sdb_free(p->formats); - p->formats = NULL; RZ_FREE(p->strconv_mode); if (p->zoom) { free(p->zoom->buf); diff --git a/test/unit/test_type.c b/test/unit/test_type.c index cf3f2c8a8ad..767f1fd93b5 100644 --- a/test/unit/test_type.c +++ b/test/unit/test_type.c @@ -351,7 +351,6 @@ static bool test_types_get_base_type_not_found(void) { mu_end; } - bool test_dll_names(void) { RzType *T = rz_type_new(); T->sdb_types = setup_sdb_for_function();