Implement colors for tables and move RzListInfo out of table.c (#5729)

This commit is contained in:
Giovanni 2026-01-05 21:34:41 +08:00 committed by GitHub
parent f935f96323
commit ea21a4a7b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1160 additions and 750 deletions

View file

@ -304,7 +304,7 @@ RZ_API ut64 rz_core_analysis_address(RzCore *core, ut64 addr) {
}
RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn) {
RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
RzList *flist = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!flist) {
return;
}
@ -314,14 +314,14 @@ RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn)
rz_pvector_foreach (fcn->bbs, iter) {
b = (RzAnalysisBlock *)*iter;
RzInterval inter = (RzInterval){ b->addr, b->size };
RzListInfo *info = rz_listinfo_new(NULL, inter, inter, -1, NULL);
RzDbgListInfo *info = rz_debug_listinfo_new(NULL, inter, inter, -1, NULL);
if (!info) {
break;
}
rz_list_append(flist, info);
}
RzTable *table = rz_core_table(core);
rz_table_visual_list(table, flist, core->offset, core->blocksize,
rz_core_debug_listinfo_to_table(table, flist, core->offset, core->blocksize,
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
rz_cons_printf("\n%s\n", rz_table_tostring(table));
rz_table_free(table);

View file

@ -41,8 +41,7 @@
static RZ_NULLABLE RZ_BORROW const RzPVector /*<RzBinString *>*/ *core_bin_strings(RzCore *r, RzBinFile *file);
static void table_add_row_bool(RzTable *t, const char *key, bool val) {
RzTableColumnType *typeString = rz_table_type("bool");
const char *b = val || typeString ? rz_str_bool(val) : "";
const char *b = rz_str_bool(val);
rz_table_add_rowf(t, "ss", key, b);
}
@ -319,9 +318,9 @@ static bool add_footer(RzCmdStateOutput *main_state, RzCmdStateOutput *state) {
return true;
}
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode default_mode, const char *header) {
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode default_mode, const char *header, RzCore *core) {
RzCmdStateOutput *state = RZ_NEW(RzCmdStateOutput);
rz_cmd_state_output_init(state, main_state->mode == RZ_OUTPUT_MODE_STANDARD ? default_mode : main_state->mode);
rz_cmd_state_output_init(state, main_state->mode == RZ_OUTPUT_MODE_STANDARD ? default_mode : main_state->mode, core);
if (state->mode == RZ_OUTPUT_MODE_TABLE || state->mode == RZ_OUTPUT_MODE_STANDARD) {
rz_cons_printf("[%c%s]\n", toupper(header[0]), header + 1);
} else if (state->mode == RZ_OUTPUT_MODE_JSON || state->mode == RZ_OUTPUT_MODE_LONG_JSON) {
@ -354,7 +353,7 @@ RZ_API bool rz_core_bin_print(RzCore *core, RZ_NONNULL RzBinFile *bf, ut32 mask,
#define wrap_mode(header, default_mode, method) \
do { \
RzCmdStateOutput *st = add_header(state, default_mode, header); \
RzCmdStateOutput *st = add_header(state, default_mode, header, core); \
res &= (method); \
add_footer(state, st); \
} while (0)
@ -447,7 +446,7 @@ RZ_API bool rz_core_bin_print(RzCore *core, RZ_NONNULL RzBinFile *bf, ut32 mask,
}
if (mask & RZ_CORE_BIN_ACC_PDB) {
if (state->mode & (RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON)) {
RzCmdStateOutput *st = add_header(state, RZ_OUTPUT_MODE_STANDARD, "pdb");
RzCmdStateOutput *st = add_header(state, RZ_OUTPUT_MODE_STANDARD, "pdb", core);
RzPdb *pdb = rz_core_pdb_load_info(core, core->bin->file);
if (!pdb) {
rz_cmd_state_output_free(st);
@ -3122,7 +3121,7 @@ RZ_API bool rz_core_file_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFil
pj_end(state->d.pj);
break;
case RZ_OUTPUT_MODE_TABLE: {
rz_table_hide_header(state->d.t);
rz_table_show_header(state->d.t, false);
if (desc) {
rz_table_add_rowf(state->d.t, "sd", "fd", desc->fd);
}
@ -3168,6 +3167,44 @@ static const char *str2na(const char *s) {
return RZ_STR_ISEMPTY(s) ? "N/A" : s;
}
static bool core_bin_info_is_number(const char *value) {
if (RZ_STR_ISEMPTY(value)) {
return false;
}
for (size_t i = 0; value[i]; ++i) {
if (!IS_DIGIT(value[i])) {
return false;
}
}
return true;
}
static const char *core_bin_info_color_selector(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
if (!column || !value) {
return NULL;
}
const RzCore *core = (const RzCore *)user;
const RzConsContext *ctx = core->cons->context;
if (RZ_STR_EQ(value, "N/A")) {
return ctx->pal.invalid;
} else if (value[0] == '0' && value[1] == 'x') {
return ctx->pal.offset;
} else if (core_bin_info_is_number(value)) {
return ctx->pal.num;
} else if (rz_str_is_true(value)) {
return ctx->pal.graph_true;
} else if (rz_str_is_false(value)) {
return ctx->pal.graph_false;
} else if (RZ_STR_EQ(value, "BE")) {
return ctx->pal.ai_seq;
} else if (RZ_STR_EQ(value, "LE")) {
return ctx->pal.ai_write;
}
return column_n ? ctx->pal.diff_match : ctx->pal.label;
}
RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state) {
rz_return_val_if_fail(core && state, false);
@ -3183,6 +3220,11 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile
bool havecode;
int bits;
rz_cmd_state_output_set_columnsf(state, "ss", "field", "value");
if (core->cons->context->color_mode != COLOR_MODE_DISABLED) {
rz_cmd_state_output_set_color_selector(state, core_bin_info_color_selector, core);
}
havecode = is_executable(obj) || rz_pvector_len(obj->entries) > 0;
compiled = rz_core_bin_get_compile_time(bf);
bits = (plugin && !strcmp(plugin->name, "any")) ? rz_config_get_i(core->config, "asm.bits") : info->bits;
@ -3353,8 +3395,7 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile
break;
case RZ_OUTPUT_MODE_TABLE:
rz_table_set_columnsf(t, "ss", "field", "value");
rz_table_hide_header(t);
rz_table_show_header(t, false);
rz_table_add_rowf(t, "ss", "arch", str2na(info->arch));
rz_table_add_rowf(t, "ss", "cpu", str2na(info->cpu));

View file

@ -416,7 +416,7 @@ static bool cb_asmcpu(void *user, void *data) {
update_asmcpu_options(core, node);
/* print verbose help instead of plain option listing */
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
rz_core_asm_cpu_plugin_print(core, &state, rz_config_get(core->config, "asm.arch"));
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -508,7 +508,7 @@ static bool cb_asmarch(void *user, void *data) {
if (strlen(node->value) > 1 && node->value[1] == '?') {
/* print more verbose help instead of plain option values */
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
rz_core_asm_plugins_print(core, &state, NULL);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -1563,9 +1563,9 @@ static bool cb_dbg_args(void *user, void *data) {
static bool cb_dbgbackend(void *user, void *data) {
RzCore *core = (RzCore *)user;
RzConfigNode *node = (RzConfigNode *)data;
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
if (!strcmp(node->value, "?")) {
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
rz_core_debug_plugins_print(core, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);

View file

@ -763,8 +763,17 @@ RZ_API void rz_debug_traces_ascii(RzDebug *dbg, ut64 offset) {
rz_return_if_fail(dbg);
RzList *info_list = rz_debug_traces_info(dbg, offset);
RzTable *table = rz_table_new();
table->cons = rz_cons_singleton();
rz_table_visual_list(table, info_list, offset, 1,
RzCons *cons = rz_cons_singleton();
if (cons) {
if (cons->use_utf8_curvy) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
} else if (cons->use_utf8) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
}
}
rz_core_debug_listinfo_to_table(table, info_list, offset, 1,
rz_cons_get_size(NULL), dbg->iob.io->va);
char *s = rz_table_tostring(table);
rz_cons_printf("\n%s\n", s);
@ -1320,3 +1329,98 @@ RZ_IPI void rz_core_debug_signal_print(RzDebug *dbg, RzCmdStateOutput *state) {
}
rz_cmd_state_output_array_end(state);
}
/**
* \brief Populates a RzTable with a given RzList of RzDbgListInfo
*
* \param table The table to fill
* \param list The list to use for filling
* \param[in] seek The seek is used as selector to show the current seek
* \param[in] len The length of the current selected section
* \param[in] width The width max width for printing
* \param[in] va When true, seek is a virtual address.
*/
RZ_IPI void rz_core_debug_listinfo_to_table(RZ_NONNULL RzTable *table, RZ_NULLABLE RzList /*<RzDbgListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va) {
rz_return_if_fail(table);
ut64 mul, min = -1, max = -1;
RzListIter *iter;
RzDbgListInfo *info;
table->showHeader = false;
const char *h_line = table->char_mode != RZ_TABLE_CHAR_MODE_ASCII ? RUNE_LONG_LINE_HORIZ : "-";
const char *block = table->char_mode != RZ_TABLE_CHAR_MODE_ASCII ? UTF_BLOCK : "#";
int j, i;
width -= 80;
if (width < 1) {
width = 30;
}
rz_table_set_columnsf(table, "sxsxsss", "No.", "start", "blocks", "end", "perms", "extra", "name");
rz_list_foreach (list, iter, info) {
if (min == -1 || info->pitv.addr < min) {
min = info->pitv.addr;
}
if (max == -1 || info->pitv.addr + info->pitv.size > max) {
max = info->pitv.addr + info->pitv.size;
}
}
mul = (max - min) / width;
if (min != -1 && mul > 0) {
i = 0;
rz_list_foreach (list, iter, info) {
RzStrBuf *buf = rz_strbuf_new("");
for (j = 0; j < width; j++) {
ut64 pos = min + j * mul;
ut64 npos = min + (j + 1) * mul;
const char *arg = (info->pitv.addr < npos && (info->pitv.addr + info->pitv.size) > pos)
? block
: h_line;
rz_strbuf_append(buf, arg);
}
char *b = rz_strbuf_drain(buf);
char no[64];
if (va) {
rz_table_add_rowf(table, "sxsxsss",
rz_strf(no, "%d%c", i, rz_itv_contain(info->vitv, seek) ? '*' : ' '),
info->vitv.addr,
b,
rz_itv_end(info->vitv),
(info->perm != -1) ? rz_str_rwx_i(info->perm) : "",
(info->extra) ? info->extra : "",
(info->name) ? info->name : "");
} else {
rz_table_add_rowf(table, "sxsxsss",
rz_strf(no, "%d%c", i, rz_itv_contain(info->pitv, seek) ? '*' : ' '),
info->pitv.addr,
b,
rz_itv_end(info->pitv),
(info->perm != -1) ? rz_str_rwx_i(info->perm) : "",
(info->extra) ? info->extra : "",
(info->name) ? info->name : "");
}
free(b);
i++;
}
RzStrBuf *buf = rz_strbuf_new("");
/* current seek */
if (i > 0 && len != 0) {
if (seek == UT64_MAX) {
seek = 0;
}
for (j = 0; j < width; j++) {
rz_strbuf_append(buf, ((j * mul) + min >= seek && (j * mul) + min <= seek + len) ? "^" : h_line);
}
char *s = rz_strbuf_drain(buf);
char *seekstart = rz_str_newf("0x%08" PFMT64x, seek);
char *seekend = rz_str_newf("0x%08" PFMT64x, seek + len);
rz_table_add_rowf(table, "sssssss", "=>", seekstart, s, seekend, "", "", "");
free(seekend);
free(seekstart);
free(s);
} else {
rz_strbuf_free(buf);
}
}
}

View file

@ -3203,27 +3203,25 @@ static int RzAnalysisRef_cmp(const RzAnalysisXRef *xref1, const RzAnalysisXRef *
}
static void function_list_print_to_table(RzCore *core, RzList /*<RzAnalysisFunction *>*/ *list, RzTable *t, bool verbose) {
RzTableColumnType *typeString = rz_table_type("string");
RzTableColumnType *typeNumber = rz_table_type("number");
rz_table_add_column(t, typeNumber, "addr", 0);
rz_table_add_column(t, typeString, "name", 0);
rz_table_add_column(t, typeNumber, "size", 0);
rz_table_add_column(t, typeNumber, "xrefsTo", 0);
rz_table_add_column(t, typeNumber, "xrefsFrom", 0);
rz_table_add_column(t, typeNumber, "calls", 0);
rz_table_add_column(t, typeNumber, "nbbs", 0);
rz_table_add_column(t, typeNumber, "edges", 0);
rz_table_add_column(t, typeNumber, "cc", 0);
rz_table_add_column(t, typeNumber, "cost", 0);
rz_table_add_column(t, rz_table_type("boolean"), "noreturn", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "size");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "xrefsTo");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "xrefsFrom");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "calls");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "nbbs");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "edges");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "cc");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "cost");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_BOOL, "noreturn");
if (verbose) {
rz_table_add_column(t, typeNumber, "min bound", 0);
rz_table_add_column(t, typeNumber, "range", 0);
rz_table_add_column(t, typeNumber, "max bound", 0);
rz_table_add_column(t, typeNumber, "locals", 0);
rz_table_add_column(t, typeNumber, "args", 0);
rz_table_add_column(t, typeNumber, "frame", 0);
rz_table_add_column(t, typeNumber, "loops", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "min bound");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "range");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "max bound");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "locals");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "args");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "frame");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "loops");
}
RzListIter *iter;
@ -3444,7 +3442,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_handler(RzCore *core, int argc, con
break;
case RZ_OUTPUT_MODE_LONG:
rz_cmd_state_output_fini(state);
if (rz_cmd_state_output_init(state, RZ_OUTPUT_MODE_TABLE)) {
if (rz_cmd_state_output_init(state, RZ_OUTPUT_MODE_TABLE, core)) {
function_list_print_to_table(core, list, state->d.t, true);
} else {
res = RZ_CMD_STATUS_ERROR;
@ -3583,7 +3581,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_ascii_handler(RzCore *core, int arg
if (!fcns) {
return RZ_CMD_STATUS_ERROR;
}
RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
RzList *flist = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!flist) {
rz_list_free(fcns);
return RZ_CMD_STATUS_ERROR;
@ -3593,14 +3591,14 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_ascii_handler(RzCore *core, int arg
RzAnalysisFunction *fcn;
rz_list_foreach (fcns, iter, fcn) {
RzInterval inter = { rz_analysis_function_min_addr(fcn), rz_analysis_function_linear_size(fcn) };
RzListInfo *info = rz_listinfo_new(fcn->name, inter, inter, -1, rz_strf(temp, "%d", fcn->bits));
RzDbgListInfo *info = rz_debug_listinfo_new(fcn->name, inter, inter, -1, rz_strf(temp, "%d", fcn->bits));
if (!info) {
break;
}
rz_list_append(flist, info);
}
RzTable *table = rz_core_table(core);
rz_table_visual_list(table, flist, core->offset, core->blocksize,
rz_core_debug_listinfo_to_table(table, flist, core->offset, core->blocksize,
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
char *tablestr = rz_table_tostring(table);
rz_cons_printf("\n%s\n", tablestr);
@ -3852,11 +3850,9 @@ static void print_stats(RzCore *core, HtSU *ht, RzAnalysisFunction *fcn, RzCmdSt
rz_list_sort(list, (RzListComparator)strcmp, NULL);
if (state->mode == RZ_OUTPUT_MODE_TABLE) {
RzTable *t = state->d.t;
RzTableColumnType *typeString = rz_table_type("string");
RzTableColumnType *typeNumber = rz_table_type("number");
rz_table_add_column(t, typeString, "name", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
rz_list_foreach (list, iter, name) {
rz_table_add_column(t, typeNumber, name, 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, name);
}
RzPVector *items = rz_pvector_new(free);
if (!items) {
@ -3942,14 +3938,12 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in
rz_list_sort(keys, (RzListComparator)strcmp, NULL);
RzTable *t = state->d.t;
RzTableColumnType *typeString = rz_table_type("string");
RzTableColumnType *typeNumber = rz_table_type("number");
rz_table_add_column(t, typeString, "name", 0);
rz_table_add_column(t, typeNumber, "addr", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
char *key;
rz_list_foreach (keys, iter, key) {
rz_table_add_column(t, typeNumber, key, 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, key);
}
RzListIter *iter2;

View file

@ -759,7 +759,7 @@ static RzCmdStatus argv_call_cb(RzCmd *cmd, RzCmdDesc *cd, RzCmdParsedArgs *args
return RZ_CMD_STATUS_WRONG_ARGS;
}
RzCmdStateOutput state;
if (!rz_cmd_state_output_init(&state, mode)) {
if (!rz_cmd_state_output_init(&state, mode, cmd->core)) {
return RZ_CMD_STATUS_INVALID;
}
RzCmdStatus res = cd->d.argv_state_data.cb(cmd->core, args->argc, (const char **)args->argv, &state);
@ -2453,6 +2453,14 @@ RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char
va_end(ap);
}
RZ_API void rz_cmd_state_output_set_color_selector(RzCmdStateOutput *state, RzTableColorSelector color_cb, void *user) {
rz_return_if_fail(state);
if (state->mode == RZ_OUTPUT_MODE_TABLE) {
rz_return_if_fail(state->d.t);
rz_table_set_color_selector(state->d.t, color_cb, user);
}
}
/**
* \brief Clear the inner fields of RzCmdStateOutput structure, but do not free it.
*/
@ -2488,10 +2496,100 @@ RZ_API void rz_cmd_state_output_free(RZ_NONNULL RzCmdStateOutput *state) {
free(state);
}
static inline bool table_value_is_invalid(const char *value) {
if (RZ_STR_ISEMPTY(value)) {
return true;
}
for (size_t i = 0; value[i]; ++i) {
if (value[i] != '-') {
return false;
}
}
return true;
}
static inline bool table_value_is_flags(const char *column) {
if (!column) {
return false;
}
return rz_str_startswith(column, "perm") ||
rz_str_startswith(column, "flag");
}
static inline bool table_value_is_offset(const char *column) {
if (!column) {
return false;
}
return RZ_STR_EQ(column, "vaddr") ||
RZ_STR_EQ(column, "paddr") ||
RZ_STR_EQ(column, "va") ||
RZ_STR_EQ(column, "pa") ||
RZ_STR_EQ(column, "va_end") ||
RZ_STR_EQ(column, "pa_end") ||
RZ_STR_EQ(column, "addr") ||
RZ_STR_EQ(column, "offset");
}
static inline bool table_value_is_meta(const char *column) {
if (!column) {
return false;
}
return rz_str_startswith(column, "type") ||
rz_str_startswith(column, "meta") ||
RZ_STR_EQ(column, "fd");
}
static inline bool table_value_is_name(const char *column) {
if (!column) {
return false;
}
return rz_str_startswith(column, "name");
}
static inline bool table_value_is_comment(const char *column) {
if (!column) {
return false;
}
return rz_str_startswith(column, "comment");
}
static const char *core_cmd_default_table_color(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
const RzCore *core = (const RzCore *)user;
const RzConsContext *ctx = core->cons->context;
if (ctx->color_mode == COLOR_MODE_DISABLED) {
return NULL;
}
if (table_value_is_invalid(value)) {
return ctx->pal.invalid;
} else if (table_value_is_flags(column)) {
return ctx->pal.flag;
} else if (table_value_is_name(column)) {
return ctx->pal.fname;
} else if (table_value_is_meta(column)) {
return ctx->pal.meta;
} else if (table_value_is_comment(column)) {
return ctx->pal.comment;
} else if (table_value_is_offset(column)) {
return ctx->pal.offset;
}
switch (type) {
case RZ_TABLE_COLUMN_TYPE_STRING:
return ctx->pal.label;
case RZ_TABLE_COLUMN_TYPE_NUMBER:
return ctx->pal.num;
case RZ_TABLE_COLUMN_TYPE_BOOL:
return ctx->pal.cjmp;
default:
return NULL;
}
}
/**
* \brief Initialize a RzCmdStateOutput structure and its inner fields based on the provided mode
*/
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode) {
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode, RZ_NULLABLE const RzCore *core) {
rz_return_val_if_fail(state, false);
state->mode = mode;
@ -2501,6 +2599,16 @@ RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutpu
if (!state->d.t) {
return false;
}
if (core && core->cons && core->cons->context) {
if (core->cons->use_utf8_curvy) {
rz_table_set_char_mode(state->d.t, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
} else if (core->cons->use_utf8) {
rz_table_set_char_mode(state->d.t, RZ_TABLE_CHAR_MODE_UTF8);
}
if (core->cons->context->color_mode != COLOR_MODE_DISABLED) {
rz_table_set_color_selector(state->d.t, core_cmd_default_table_color, (void *)core);
}
}
break;
case RZ_OUTPUT_MODE_STR_BUF:
state->d.sbuf = rz_strbuf_new("");

View file

@ -745,7 +745,7 @@ RZ_IPI RzCmdStatus rz_cmd_debug_map_current_handler(RzCore *core, int argc, cons
ut64 addr = core->offset;
// RZ_OUTPUT_MODE_LONG is workaround for '.'
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG, core);
rz_core_debug_map_print(core, addr, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);

View file

@ -319,7 +319,7 @@ RZ_IPI RzCmdStatus rz_cmd_eval_color_load_next_theme_handler(RzCore *core, int a
RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_list_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, mode);
rz_cmd_state_output_init(&state, mode, core);
rz_core_meta_print_list_all(core, RZ_META_TYPE_HIGHLIGHT, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -413,7 +413,7 @@ RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_instruction_word_handler(RzCore *
RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_list_current_handler(RzCore *core, int argc, const char **argv) {
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
rz_core_meta_print_list_in_function(core, RZ_META_TYPE_COMMENT, core->offset, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -434,7 +434,7 @@ static void print_all_plugin_configs(const RzCore *core) {
// Incomplete plugin config key.
RzConfig **cfg;
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
RzIterator *it = ht_sp_as_iter(core->plugin_configs);
rz_iterator_foreach(it, cfg) {
rz_core_config_print_all(*cfg, "", &state);
@ -498,7 +498,7 @@ RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **a
if (llen == 1 && rz_str_endswith(key, ".")) {
// no value was set, only key with ".". List possible sub-keys.
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
rz_core_config_print_all(cfg, key, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);

View file

@ -186,7 +186,7 @@ RZ_IPI RzCmdStatus rz_cmd_help_search_interactive_handler(RzCore *core, int argc
// "?**e"
RZ_IPI RzCmdStatus rz_cmd_help_search_interactive_settings_handler(RzCore *core, int argc, const char **argv) {
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STR_BUF);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STR_BUF, core);
rz_core_config_print_all(core->config, "", &state);
RzConfig **cfg;

View file

@ -266,7 +266,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
}
int cols = rz_cons_get_size(NULL);
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!list) {
goto sections_err;
}
@ -280,7 +280,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
RzInterval vitv = (RzInterval){ section->vaddr, section->vsize };
rz_num_units(humansz, sizeof(humansz), section->size);
RzListInfo *info = rz_listinfo_new(section->name, pitv, vitv, section->perm, humansz);
RzDbgListInfo *info = rz_debug_listinfo_new(section->name, pitv, vitv, section->perm, humansz);
if (!info) {
RZ_LOG_ERROR("Cannot print section bars\n");
goto list_err;
@ -292,7 +292,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
RZ_LOG_ERROR("Cannot print section bars\n");
goto list_err;
}
rz_table_visual_list(table, list, core->offset, 1, cols, core->io->va);
rz_core_debug_listinfo_to_table(table, list, core->offset, 1, cols, core->io->va);
char *s = rz_table_tostring(table);
if (!s) {

View file

@ -36,7 +36,7 @@ RZ_IPI RzCmdStatus rz_cmd_heap_chunk_print_handler(RzCore *core, int argc, const
RZ_IPI RzCmdStatus rz_cmd_heap_chunks_graph_handler(RzCore *core, int argc, const char **argv) {
// RZ_OUTPUT_MODE_LONG_JSON mode workaround for graph
RzCmdStateOutput state = { 0 };
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG_JSON)) {
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG_JSON, core)) {
return RZ_CMD_STATUS_ERROR;
}
RzCmdStatus res;

View file

@ -244,7 +244,7 @@ RZ_IPI RzCmdStatus rz_open_maps_remove_all_handler(RzCore *core, int argc, const
}
RZ_IPI RzCmdStatus rz_open_maps_list_ascii_handler(RzCore *core, int argc, const char **argv) {
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!list) {
return RZ_CMD_STATUS_ERROR;
}
@ -254,14 +254,14 @@ RZ_IPI RzCmdStatus rz_open_maps_list_ascii_handler(RzCore *core, int argc, const
RzIOMap *map = *it;
char temp[32];
rz_strf(temp, "%d", map->fd);
RzListInfo *info = rz_listinfo_new(map->name, map->itv, map->itv, map->perm, temp);
RzDbgListInfo *info = rz_debug_listinfo_new(map->name, map->itv, map->itv, map->perm, temp);
if (!info) {
break;
}
rz_list_append(list, info);
}
RzTable *table = rz_core_table(core);
rz_table_visual_list(table, list, core->offset, core->blocksize,
rz_core_debug_listinfo_to_table(table, list, core->offset, core->blocksize,
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
char *tablestr = rz_table_tostring(table);
rz_cons_printf("%s", tablestr);
@ -678,7 +678,7 @@ RZ_IPI RzCmdStatus rz_open_binary_list_ascii_handler(RzCore *core, int argc, con
if (!bin) {
return RZ_CMD_STATUS_ERROR;
}
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!list) {
return RZ_CMD_STATUS_ERROR;
}
@ -687,14 +687,14 @@ RZ_IPI RzCmdStatus rz_open_binary_list_ascii_handler(RzCore *core, int argc, con
rz_list_foreach (bin->binfiles, iter, bf) {
char temp[64];
RzInterval inter = (RzInterval){ bf->o->opts.baseaddr, bf->o->size };
RzListInfo *info = rz_listinfo_new(bf->file, inter, inter, -1, sdb_itoa(bf->fd, temp, 10));
RzDbgListInfo *info = rz_debug_listinfo_new(bf->file, inter, inter, -1, sdb_itoa(bf->fd, temp, 10));
if (!info) {
break;
}
rz_list_append(list, info);
}
RzTable *table = rz_core_table(core);
rz_table_visual_list(table, list, core->offset, core->blocksize,
rz_core_debug_listinfo_to_table(table, list, core->offset, core->blocksize,
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
char *table_text = rz_table_tostring(table);
rz_cons_printf("\n%s\n", table_text);

View file

@ -1712,18 +1712,15 @@ static bool cmd_pxr(RzCore *core, ut64 at, int len, RzCmdStateOutput *state, int
}
const ut8 *buf = core->block;
bool be = core->analysis->big_endian;
int end = RZ_MIN(core->blocksize, len);
int bitsize = wordsize * 8;
RzOutputMode mode = state->mode;
if (mode == RZ_OUTPUT_MODE_TABLE) {
RzTable *t = state->d.t;
RzTableColumnType *n = rz_table_type("number");
RzTableColumnType *s = rz_table_type("string");
rz_table_add_column(t, n, "addr", 0);
rz_table_add_column(t, n, "value", 0);
rz_table_add_column(t, s, "refs", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "value");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "refs");
for (ut64 i = 0; i + wordsize < end; i += wordsize) {
ut64 addr = at + i;
ut64 val = rz_read_ble(buf + i, be, bitsize);
@ -4724,7 +4721,7 @@ static void print_stack(RzCore *core) {
RzCmdStateOutput so;
ut64 sp_addr = rz_core_reg_getv_by_role_or_name(core, "SP");
if (rz_config_get_b(core->config, "dbg.slow")) {
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
int wordsize = rz_analysis_get_address_bits(core->analysis) / 8;
cmd_pxr(core, sp_addr, 128, &so, wordsize, NULL);
rz_cmd_state_output_print(&so);
@ -4741,7 +4738,7 @@ static void print_stack(RzCore *core) {
} else if (core->rasm->bits == 32) {
rz_core_print_dump(core, RZ_OUTPUT_MODE_STANDARD, sp_addr, 4, 128, RZ_CORE_PRINT_FORMAT_TYPE_HEXADECIMAL);
}
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
core_disassembly(core, core->blocksize, 0, &so, false);
rz_cmd_state_output_fini(&so);
}
@ -4778,7 +4775,7 @@ RZ_IPI RzCmdStatus rz_print_columns_debug_handler(RzCore *core, int argc, const
rz_cons_push();
rz_debug_regs_args_handler(core, 0, NULL, RZ_OUTPUT_MODE_STANDARD);
rz_cons_print("\nbacktrace:\n");
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
rz_cmd_debug_display_bt_handler(core, 0, NULL, &so);
rz_cmd_state_output_print(&so);
rz_cmd_state_output_fini(&so);
@ -5399,12 +5396,10 @@ static bool print_rising_and_falling_entropy_table(RzCore *core, RzCmdStateOutpu
bool resetFlag = 1;
st8 lastEdge = 0;
RzTable *t = state->d.t;
RzTableColumnType *n = rz_table_type("number");
RzTableColumnType *s = rz_table_type("string");
rz_table_add_column(t, n, "addr", 0);
rz_table_add_column(t, n, "index", 0);
rz_table_add_column(t, s, "edge_type", 0);
rz_table_add_column(t, n, "entropy_value", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "index");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "edge_type");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "entropy_value");
for (int i = 0; i < brange->nblocks; i++) {
ut64 off = brange->from + (brange->blocksize * (i));
if (!rz_io_read_at(core->io, off, tmp, brange->blocksize))

View file

@ -2257,8 +2257,13 @@ RZ_API RzBuffer *rz_core_syscall(RzCore *core, const char *name, const char *arg
RZ_API RzTable *rz_core_table(RzCore *core) {
RzTable *table = rz_table_new();
if (table) {
table->cons = core->cons;
if (!table || !core->cons) {
return table;
}
if (core->cons->use_utf8_curvy) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
} else if (core->cons->use_utf8) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
}
return table;
}

View file

@ -140,6 +140,7 @@ RZ_IPI bool rz_core_debug_pid_print(RzDebug *dbg, int pid, RzCmdStateOutput *sta
RZ_IPI bool rz_core_debug_thread_print(RzDebug *dbg, int pid, RzCmdStateOutput *state);
RZ_IPI bool rz_core_debug_desc_print(RzDebug *dbg, RzCmdStateOutput *state);
RZ_IPI void rz_core_debug_signal_print(RzDebug *dbg, RzCmdStateOutput *state);
RZ_IPI void rz_core_debug_listinfo_to_table(RZ_NONNULL RzTable *table, RZ_NULLABLE RzList /*<RzDbgListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va);
/* cfile.c */
RZ_IPI RzCoreIOMapInfo *rz_core_io_map_info_new(RzCoreFile *cf, int perm_orig);

View file

@ -18,14 +18,12 @@ rz_core_sources = [
'basefind.c',
'caddr.c',
'cagraph.c',
'cgraph.c',
'canalysis.c',
'cannotated_code.c',
'carg.c',
'casm.c',
'cautocmpl.c',
'cbin.c',
'cmark.c',
'cbounds.c',
'cconfig.c',
'ccrypto.c',
@ -33,11 +31,13 @@ rz_core_sources = [
'cesil.c',
'cfile.c',
'cflag.c',
'cgraph.c',
'chash.c',
'cheap.c',
'cil.c',
'cio.c',
'clang.c',
'cmark.c',
'cmeta.c',
'cmp.c',
'core.c',
@ -48,9 +48,9 @@ rz_core_sources = [
'creg.c',
'csearch.c',
'csign.c',
'csyscall.c',
'ctypes.c',
'cvfile.c',
'csyscall.c',
'devirtualize_cxx.c',
'devirtualize_objc.c',
'disasm.c',

View file

@ -1204,7 +1204,7 @@ repeat:
bool asm_bytes = rz_config_get_b(core->config, "asm.bytes");
rz_config_set_b(core->config, "asm.bytes", false);
RzCmdStateOutput state;
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD)) {
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core)) {
return RZ_CMD_STATUS_INVALID;
}
rz_core_flag_describe(core, core->offset, false, &state);

View file

@ -1230,14 +1230,17 @@ err:
}
static RzTable *__new_heapblock_tbl(void) {
RzTable *tbl = rz_table_new();
rz_table_add_column(tbl, rz_table_type("number"), "HeaderAddress", -1);
rz_table_add_column(tbl, rz_table_type("number"), "UserAddress", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Size", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Granularity", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Unused", -1);
rz_table_add_column(tbl, rz_table_type("String"), "Type", -1);
return tbl;
RzTable *t = rz_table_new();
if (!t) {
return NULL;
}
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "HeaderAddress");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "UserAddress");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Size");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Granularity");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Unused");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "Type");
return t;
}
RZ_IPI void rz_heap_list_w32(RzCore *core, RzOutputMode mode) {
@ -1257,10 +1260,10 @@ RZ_IPI void rz_heap_list_w32(RzCore *core, RzOutputMode mode) {
CHECK_INFO(heapInfo);
int i;
RzTable *tbl = rz_table_new();
rz_table_add_column(tbl, rz_table_type("number"), "Address", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Blocks", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Allocated", -1);
rz_table_add_column(tbl, rz_table_type("number"), "Commited", -1);
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Address");
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Blocks");
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Allocated");
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Commited");
PJ *pj = pj_new();
pj_a(pj);
for (i = 0; i < heapInfo->count; i++) {

View file

@ -287,15 +287,15 @@ static window *window_from_handle(HANDLE hwnd) {
}
static RzTable *create_window_table(void) {
RzTable *tbl = rz_table_new();
if (!tbl) {
RzTable *t = rz_table_new();
if (!t) {
return NULL;
}
rz_table_add_column(tbl, rz_table_type("number"), "Handle", ST32_MAX);
rz_table_add_column(tbl, rz_table_type("number"), "PID", ST32_MAX);
rz_table_add_column(tbl, rz_table_type("number"), "TID", ST32_MAX);
rz_table_add_column(tbl, rz_table_type("string"), "Class Name", ST32_MAX);
return tbl;
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Handle");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "PID");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "TID");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "Class Name");
return t;
}
static void add_window_to_table(RzTable *tbl, window *win) {

View file

@ -212,7 +212,7 @@ RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr) {
}
static int cmpaddr(const void *_a, const void *_b, void *user) {
const RzListInfo *a = _a, *b = _b;
const RzDbgListInfo *a = _a, *b = _b;
return (rz_itv_begin(a->pitv) > rz_itv_begin(b->pitv)) ? 1 : (rz_itv_begin(a->pitv) < rz_itv_begin(b->pitv)) ? -1
: 0;
}
@ -221,13 +221,13 @@ static int cmpaddr(const void *_a, const void *_b, void *user) {
* Get all trace info
* \param dbg core->dbg
* \param offset offset of address
* \return a RzList of RzListInfo
* \return a RzList of RzDbgListInfo
*/
RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset) {
RZ_API RZ_OWN RzList /*<RzDbgListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset) {
rz_return_val_if_fail(dbg, NULL);
int tag = dbg->trace->tag;
RzListIter *iter;
RzList *info_list = rz_list_new();
RzList *info_list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
if (!info_list) {
return NULL;
}
@ -237,7 +237,7 @@ RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64
if (trace->tag && !(tag & trace->tag)) {
continue;
}
RzListInfo *info = RZ_NEW0(RzListInfo);
RzDbgListInfo *info = RZ_NEW0(RzDbgListInfo);
if (!info) {
rz_list_free(info_list);
return NULL;
@ -283,3 +283,25 @@ RZ_API void rz_debug_trace_reset(RzDebug *dbg) {
t->traces = rz_list_new();
t->traces->free = free;
}
RZ_API RZ_OWN RzDbgListInfo *rz_debug_listinfo_new(RZ_NULLABLE const char *name, RzInterval pitv, RzInterval vitv, int perm, RZ_NULLABLE const char *extra) {
RzDbgListInfo *info = RZ_NEW(RzDbgListInfo);
if (!info) {
return NULL;
}
info->name = rz_str_dup(name);
info->pitv = pitv;
info->vitv = vitv;
info->perm = perm;
info->extra = rz_str_dup(extra);
return info;
}
RZ_API void rz_debug_listinfo_free(RZ_NULLABLE RzDbgListInfo *info) {
if (!info) {
return;
}
free(info->name);
free(info->extra);
free(info);
}

View file

@ -594,7 +594,8 @@ RZ_API char *rz_cmd_unescape_arg(const char *arg, RzCmdEscape escape);
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char *fmt, ...);
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode);
RZ_API void rz_cmd_state_output_set_color_selector(RzCmdStateOutput *state, RzTableColorSelector color_cb, void *user);
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode, RZ_NULLABLE const RzCore *core);
RZ_API void rz_cmd_state_output_fini(RZ_NONNULL RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_free(RZ_NONNULL RzCmdStateOutput *state);
RZ_API void rz_cmd_state_output_print(RZ_NONNULL RzCmdStateOutput *state);

View file

@ -428,6 +428,14 @@ typedef struct rz_debug_esil_watchpoint_t {
char *expr;
} RzDebugEsilWatchpoint;
typedef struct {
char *name; ///< Name of the information
RzInterval pitv; ///< Offset interval
RzInterval vitv; ///< Virtual address interval
int perm; ///< Permissions
char *extra; ///< Extra printable information
} RzDbgListInfo;
#ifdef RZ_API
/**
@ -556,7 +564,7 @@ RZ_API int rz_debug_trace_pc(RzDebug *dbg, ut64 pc);
RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op);
RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr);
RZ_API void rz_debug_trace_print(RzDebug *dbg, RzCmdStateOutput *state, ut64 offset);
RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset);
RZ_API RZ_OWN RzList /*<RzDbgListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset);
RZ_API void rz_debug_traces_ascii(RzDebug *dbg, ut64 offset);
RZ_API RzDebugTracepoint *rz_debug_trace_add(RzDebug *dbg, ut64 addr, int size);
RZ_API RzDebugTrace *rz_debug_trace_new(void);
@ -607,6 +615,9 @@ RZ_API bool rz_debug_goto_cnum(RzDebug *dbg, ut32 cnum);
RZ_API int rz_debug_step_cnum(RzDebug *dbg, int steps);
RZ_API bool rz_debug_continue_back(RzDebug *dbg);
RZ_API RZ_OWN RzDbgListInfo *rz_debug_listinfo_new(RZ_NULLABLE const char *name, RzInterval pitv, RzInterval vitv, int perm, RZ_NULLABLE const char *extra);
RZ_API void rz_debug_listinfo_free(RZ_NULLABLE RzDbgListInfo *info);
/* serialize */
RZ_API void rz_serialize_debug_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzDebug *dbg);
RZ_API bool rz_serialize_debug_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzDebug *dbg, RZ_NULLABLE RzSerializeResultInfo *res);

View file

@ -7,88 +7,89 @@
extern "C" {
#endif
typedef struct {
const char *name;
RzListComparator cmp;
typedef enum {
RZ_TABLE_ALIGN_LEFT = 0,
RZ_TABLE_ALIGN_RIGHT,
RZ_TABLE_ALIGN_CENTER,
// size
RZ_TABLE_ALIGN_ENUM_MAX,
} RzTableAlign;
typedef enum {
RZ_TABLE_COLUMN_TYPE_STRING = 0,
RZ_TABLE_COLUMN_TYPE_NUMBER,
RZ_TABLE_COLUMN_TYPE_BOOL,
// size
RZ_TABLE_COLUMN_TYPE_ENUM_MAX,
} RzTableColumnType;
typedef int (*RzTableColumnTypeComparator)(const void *a, const void *b);
typedef struct {
char *name;
RzTableColumnType *type;
int align; // left, right, center
int width; // computed
int maxWidth;
bool forceUppercase;
int total;
char *name; ///< Column name
RzTableColumnType type; ///< Inferred type of the data
RzTableColumnTypeComparator type_cmp; ///< Column comparator used for sorting
RzTableAlign align; ///< Column alignment left, right, center
int width; ///< Computed column width
int total; ///< Sum of the rows associated to this column.
} RzTableColumn;
typedef struct {
char *name;
RzInterval pitv;
RzInterval vitv;
int perm;
char *extra;
} RzListInfo;
enum {
RZ_TABLE_ALIGN_LEFT,
RZ_TABLE_ALIGN_RIGHT,
RZ_TABLE_ALIGN_CENTER
};
typedef struct {
RzPVector /*<char *>*/ *items;
} RzTableRow;
typedef void (*RzTableSelector)(RzTableRow *acc, RzTableRow *new_row, size_t nth);
typedef const char *(*RzTableColorSelector)(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user);
typedef enum {
RZ_TABLE_CHAR_MODE_ASCII = 0,
RZ_TABLE_CHAR_MODE_UTF8,
RZ_TABLE_CHAR_MODE_UTF8_CURVY,
// size
RZ_TABLE_CHAR_MODE_ENUM_MAX,
} RzTableCharMode;
typedef struct {
RzVector /*<RzTableRow>*/ *rows;
RzVector /*<RzTableColumn>*/ *cols;
int totalCols;
bool showHeader;
bool showFancy;
bool showJSON;
bool showCSV;
bool showSum;
bool adjustedCols;
void *cons;
RzVector /*<RzTableRow>*/ *rows; ///< Rows data
RzVector /*<RzTableColumn>*/ *cols; ///< Columns data
size_t totalCols; ///< Total number of columns
bool showHeader; ///< When true, upon call of rz_table_tostring, it will show the header
bool showFancy; ///< When true, upon call of rz_table_tostring, it will use the fancy table output
bool showJSON; ///< When true, upon call of rz_table_tostring, it will return a json structure
bool showCSV; ///< When true, upon call of rz_table_tostring, it will return a csv structure
bool showSum; ///< When true, upon call of rz_table_tostring, it will show the toal sum of each row
RzTableCharMode char_mode; ///< Sets the charset type used for the string output
RzTableColorSelector color; ///< It is used to retrieve a color palette to use in each column data.
void *color_user; ///< Additional data that is passed via RzTableColorSelector()
} RzTable;
typedef void (*RzTableSelector)(RzTableRow *acc, RzTableRow *new_row, int nth);
RZ_API RzListInfo *rz_listinfo_new(const char *name, RzInterval pitv, RzInterval vitv, int perm, const char *extra);
RZ_API void rz_listinfo_free(RzListInfo *info);
RZ_API void rz_table_row_fini(RZ_NONNULL void *_row);
RZ_API void rz_table_column_fini(RZ_NONNULL void *_col);
RZ_API RzTableColumn *rz_table_column_clone(RzTableColumn *col);
RZ_API RzTableColumnType *rz_table_type(const char *name);
RZ_API RzTable *rz_table_new(void);
RZ_API void rz_table_free(RzTable *t);
RZ_API int rz_table_column_nth(RzTable *t, const char *name);
RZ_API void rz_table_add_column(RzTable *t, RzTableColumnType *type, const char *name, int maxWidth);
RZ_API void rz_table_set_columnsf(RzTable *t, const char *fmt, ...);
RZ_API void rz_table_set_vcolumnsf(RzTable *t, const char *fmt, va_list ap);
RZ_API RzTableRow *rz_table_row_new(RzPVector /*<char *>*/ *items);
RZ_API void rz_table_add_row(RZ_NONNULL RzTable *t, const char *name, ...);
RZ_API void rz_table_add_vrowf(RZ_NONNULL RzTable *t, const char *fmt, va_list ap);
RZ_API void rz_table_add_rowf(RzTable *t, const char *fmt, ...);
RZ_API void rz_table_add_row_columnsf(RzTable *t, const char *fmt, ...);
RZ_API void rz_table_add_row_vec(RZ_NONNULL RzTable *t, RZ_NONNULL RzPVector /*<char *>*/ *items);
RZ_API RZ_OWN RzTable *rz_table_new(void);
RZ_API void rz_table_free(RZ_NULLABLE RzTable *t);
RZ_API void rz_table_add_column(RZ_NONNULL RzTable *t, const RzTableColumnType type, RZ_NONNULL const char *name);
RZ_API void rz_table_set_columnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
RZ_API void rz_table_set_vcolumnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, va_list ap);
RZ_API void rz_table_add_row(RZ_NONNULL RzTable *t, RZ_NONNULL const char *name, ...);
RZ_API void rz_table_add_vrowf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, va_list ap);
RZ_API void rz_table_add_rowf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
RZ_API void rz_table_add_row_columnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
RZ_API void rz_table_add_row_vec(RZ_NONNULL RzTable *t, RZ_NONNULL RZ_OWN RzPVector /*<char *>*/ *items);
RZ_API RZ_OWN char *rz_table_tofancystring(RZ_NONNULL RzTable *t);
RZ_API char *rz_table_tosimplestring(RzTable *t);
RZ_API char *rz_table_tostring(RzTable *t);
RZ_API char *rz_table_tocsv(RzTable *t);
RZ_API RZ_OWN char *rz_table_tojson(RzTable *t);
RZ_API void rz_table_filter(RzTable *t, int nth, int op, const char *un);
RZ_API void rz_table_sort(RzTable *t, int nth, bool inc);
RZ_API void rz_table_uniq(RzTable *t);
RZ_API void rz_table_group(RzTable *t, int nth, RzTableSelector fcn);
RZ_API bool rz_table_query(RzTable *t, const char *q);
RZ_API void rz_table_hide_header(RzTable *t);
RZ_API bool rz_table_align(RzTable *t, int nth, int align);
RZ_API void rz_table_visual_list(RzTable *table, RzList /*<RzListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va);
RZ_API RZ_OWN char *rz_table_tosimplestring(RZ_NONNULL RzTable *t);
RZ_API RZ_OWN char *rz_table_tostring(RZ_NONNULL RzTable *t);
RZ_API RZ_OWN char *rz_table_tocsv(RZ_NONNULL RzTable *t);
RZ_API RZ_OWN char *rz_table_tojson(RZ_NONNULL RzTable *t);
RZ_API void rz_table_sort(RZ_NONNULL RzTable *t, size_t nth, bool reverse);
RZ_API void rz_table_sortlen(RZ_NONNULL RzTable *t, size_t nth, bool reverse);
RZ_API void rz_table_uniq(RZ_NONNULL RzTable *t);
RZ_API void rz_table_group(RZ_NONNULL RzTable *t, size_t nth, RZ_NULLABLE RzTableSelector selector);
RZ_API bool rz_table_query(RZ_NONNULL RzTable *t, RZ_NULLABLE const char *q);
RZ_API bool rz_table_align(RZ_NONNULL RzTable *t, size_t nth, RzTableAlign align);
RZ_API RZ_OWN RzTable *rz_table_transpose(RZ_NONNULL RzTable *t);
RZ_API void rz_table_columns(RzTable *t, RzList /*<char *>*/ *cols); // const char *name, ...);
RZ_API void rz_table_columns_select(RZ_NONNULL RzTable *t, RZ_NONNULL RzList /*<char *>*/ *col_names);
RZ_API void rz_table_show_header(RZ_NONNULL RzTable *t, bool show_header);
RZ_API void rz_table_set_char_mode(RZ_NONNULL RzTable *t, RzTableCharMode mode);
RZ_API void rz_table_set_color_selector(RZ_NONNULL RzTable *t, RZ_NULLABLE RzTableColorSelector color_cb, void *user);
#ifdef __cplusplus
}
#endif

View file

@ -567,7 +567,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
free(debugbackend);
debugbackend = rz_str_dup(opt.arg);
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, r);
if (!strcmp(opt.arg, "?")) {
rz_core_debug_plugins_print(r, &state);
rz_cmd_state_output_print(&state);
@ -781,7 +781,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
}
run_commands(r, NULL, prefiles, false, do_analysis);
run_commands(r, cmds, files, quiet, do_analysis);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, r);
rz_core_io_plugins_print(r->io, &state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);

View file

@ -646,7 +646,7 @@ RZ_API int rz_main_rz_asm(int argc, const char *argv[]) {
core->rasm = as->a;
core->analysis = as->analysis;
RzCmdStateOutput state = { 0 };
rz_cmd_state_output_init(&state, as->json ? RZ_OUTPUT_MODE_JSON : RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, as->json ? RZ_OUTPUT_MODE_JSON : RZ_OUTPUT_MODE_STANDARD, core);
if (opt.argv[opt.ind]) {
rz_core_asm_cpu_plugin_print(core, &state, opt.argv[opt.ind]);
} else {

View file

@ -42,9 +42,9 @@ static bool add_footer(RzCmdStateOutput *main_state, RzCmdStateOutput *state) {
return true;
}
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode mode, const char *header) {
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode mode, const char *header, RzCore *core) {
RzCmdStateOutput *state = RZ_NEW(RzCmdStateOutput);
rz_cmd_state_output_init(state, mode);
rz_cmd_state_output_init(state, mode, core);
if (mode == RZ_OUTPUT_MODE_TABLE || mode == RZ_OUTPUT_MODE_STANDARD) {
rz_cons_printf("[%c%s]\n", toupper(header[0]), header + 1);
} else if (mode == RZ_OUTPUT_MODE_JSON) {
@ -621,12 +621,12 @@ static void __listPlugins(RzBin *bin, const char *plugin_name, PJ *pj, int rad)
RzCmdStateOutput state = { 0 };
if (rad == RZ_MODE_JSON) {
format = 'j';
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL);
} else if (rad) {
format = 'q';
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, NULL);
} else {
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, NULL);
}
bin->cb_printf = (PrintfCallback)printf;
if (plugin_name) {
@ -1251,7 +1251,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
#define ismodejson (out_mode == RZ_MODE_JSON && actions > 0)
#define run_action(n, x, y) \
if (action & (x)) { \
RzCmdStateOutput *st = add_header(&state, mode, n); \
RzCmdStateOutput *st = add_header(&state, mode, n, &core); \
y(&core, st); \
add_footer(&state, st); \
}
@ -1272,7 +1272,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
RzCmdStateOutput state;
RzOutputMode mode = rad2outputmode(out_mode);
if (!rz_cmd_state_output_init(&state, mode)) {
if (!rz_cmd_state_output_init(&state, mode, &core)) {
result = 1;
goto chksum_err;
}
@ -1280,7 +1280,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
// List fatmach0 sub-binaries, etc
if (action & RZ_BIN_REQ_LISTARCHS || (arch && bits && !rz_bin_select(bin, arch, bits, machine, NULL))) {
RzCmdStateOutput *st = add_header(&state, mode == RZ_OUTPUT_MODE_STANDARD ? RZ_OUTPUT_MODE_TABLE : mode, "archs");
RzCmdStateOutput *st = add_header(&state, mode == RZ_OUTPUT_MODE_STANDARD ? RZ_OUTPUT_MODE_TABLE : mode, "archs", &core);
rz_core_bin_archs_print(bin, st);
add_footer(&state, st);
}

View file

@ -83,6 +83,7 @@ typedef struct diff_context_t {
const char *input_b;
const char *file_a;
const char *file_b;
const char *theme_name;
DiffScreen screen;
RzList /*<char *>*/ *evars;
} DiffContext;
@ -215,6 +216,7 @@ static void rz_diff_show_help(bool usage_only) {
"-q", "", "Quiet output",
"-V", "", "Show version information",
"-v", "", "Be more verbose (stderr output)",
"-K", "theme", "Set a give color theme (see rizin 'eco' command)",
"-e", "k=v", "Set an evaluable config variable",
"-A", "", "Compare virtual and physical addresses",
"-B", "", "Run 'aaa' when loading the bin",
@ -277,7 +279,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct
RzGetopt opt;
int c;
rz_getopt_init(&opt, argc, argv, "hHjqvViABCTa:b:e:d:t:0:1:S:");
rz_getopt_init(&opt, argc, argv, "hHjqvViABCTa:b:K:e:d:t:0:1:S:");
while ((c = rz_getopt_next(&opt)) != -1) {
switch (c) {
case '0': rz_diff_ctx_set_def(ctx, input_a, NULL, opt.arg); break;
@ -299,6 +301,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct
case 'S': rz_diff_set_def(screen, NULL, opt.arg); break;
case 'H': rz_diff_ctx_set_opt(ctx, DIFF_OPT_HEX_VISUAL); break;
case 'e': rz_diff_ctx_add_evar(ctx, opt.arg); break;
case 'K': rz_diff_set_def(ctx->theme_name, NULL, opt.arg); break;
default:
rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "unknown flag '%c'\n", c);
}
@ -1992,7 +1995,7 @@ static void diff_similarity_as_json(RzAnalysisFunction *fcn_a, RzAnalysisFunctio
pj_end(pj); // } -- match object end
}
static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFunction *fcn_b, double similarity, bool color, bool no_name, RzTable *table) {
static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFunction *fcn_b, double similarity, bool no_name, RzTable *table) {
char tmp[128];
const char *type_s = NULL;
const char *type_n = NULL;
@ -2003,18 +2006,18 @@ static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFuncti
if (similarity > 0.0 && fcn_a && fcn_b) {
type_n = tmp;
if (similarity >= 1.0) {
rz_strf(tmp, color ? Color_BGREEN "%.6f" Color_RESET : "%.6f", similarity);
type_s = color ? Color_BGREEN "COMPLETE" Color_RESET : "COMPLETE";
rz_strf(tmp, "%.6f", similarity);
type_s = "COMPLETE";
} else if (similarity >= RZ_ANALYSIS_SIMILARITY_THRESHOLD) {
rz_strf(tmp, color ? Color_BYELLOW "%.6f" Color_RESET : "%.6f", similarity);
type_s = color ? Color_BYELLOW "PARTIAL " Color_RESET : "PARTIAL ";
rz_strf(tmp, "%.6f", similarity);
type_s = "PARTIAL";
} else {
rz_strf(tmp, color ? Color_BRED "%.4f" Color_RESET : "%.4f", similarity);
type_s = color ? Color_BRED "UNLIKE " Color_RESET : "UNLIKE ";
rz_strf(tmp, "%.4f", similarity);
type_s = "UNLIKE";
}
} else {
type_n = color ? Color_BRED "0.000000" Color_RESET : "0.000000";
type_s = color ? Color_BRED "UNLIKE " Color_RESET : "UNLIKE ";
type_n = "0.000000";
type_s = "UNLIKE";
}
if (no_name) {
@ -2044,6 +2047,29 @@ static int comparePairFunctions(const RzAnalysisMatchPair *ma, const RzAnalysisM
return (a && b && a->addr && b->addr ? (a->addr > b->addr) - (a->addr < b->addr) : 0);
}
static const char *diff_table_color_selector(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
if (!column || !value) {
return NULL;
}
const RzConsContext *ctx = (const RzConsContext *)user;
if (RZ_STR_EQ(column, "type")) {
if (RZ_STR_EQ(value, "COMPLETE")) {
return ctx->pal.diff_match;
} else if (RZ_STR_EQ(value, "PARTIAL")) {
return ctx->pal.diff_unmatch;
}
return ctx->pal.diff_unknown;
}
if (RZ_STR_EQ(column, "similarity")) {
return ctx->pal.cjmp;
} else if (rz_str_startswith(column, "size")) {
return ctx->pal.num;
} else if (rz_str_startswith(column, "addr")) {
return ctx->pal.offset;
}
return ctx->pal.label;
}
/**
* \brief Performs function matching and shows the result in a table.
*
@ -2140,7 +2166,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
if (mode == DIFF_MODE_JSON) {
diff_similarity_as_json(fcn_a, fcn_b, pair->similarity, pj);
} else {
diff_similarity_as_table(fcn_a, fcn_b, pair->similarity, color, no_name, table);
diff_similarity_as_table(fcn_a, fcn_b, pair->similarity, no_name, table);
}
}
@ -2152,7 +2178,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
if (mode == DIFF_MODE_JSON) {
diff_similarity_as_json(fcn_a, NULL, 0.0, pj);
} else {
diff_similarity_as_table(fcn_a, NULL, 0.0, color, no_name, table);
diff_similarity_as_table(fcn_a, NULL, 0.0, no_name, table);
}
}
@ -2164,7 +2190,18 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
if (mode == DIFF_MODE_JSON) {
diff_similarity_as_json(NULL, fcn_b, 0.0, pj);
} else {
diff_similarity_as_table(NULL, fcn_b, 0.0, color, no_name, table);
diff_similarity_as_table(NULL, fcn_b, 0.0, no_name, table);
}
}
if (table) {
if (color) {
rz_table_set_color_selector(table, diff_table_color_selector, core_a->cons->context);
}
if (core_a->cons->use_utf8_curvy) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
} else if (core_a->cons->use_utf8) {
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
}
}
@ -2181,7 +2218,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
break;
default: // DIFF_MODE_QUIET
rz_table_align(table, 0, RZ_TABLE_ALIGN_RIGHT);
rz_table_hide_header(table);
rz_table_show_header(table, false);
output = rz_table_tosimplestring(table);
rz_cons_printf("%s", output);
break;
@ -2289,6 +2326,9 @@ static bool rz_diff_graphs_files(DiffContext *ctx) {
if (ctx->verbose) {
fprintf(stderr, "rz-diff: start diffing.\n");
}
if (ctx->colors) {
rz_core_theme_load(a->core, ctx->theme_name ? ctx->theme_name : "default");
}
core_diff_show(a->core, b->core, ctx->input_a, ctx->mode, ctx->verbose);
}

View file

@ -331,7 +331,7 @@ RZ_API int rz_str_rwx(const char *str) {
return ret;
}
// Returns the string representation of the permission of the inputted integer.
// Returns the string representation of the permission of the input integer.
RZ_API const char *rz_str_rwx_i(int rwx) {
if (rwx < 0 || rwx >= RZ_ARRAY_SIZE(rwxstr)) {
rwx = 0;

File diff suppressed because it is too large Load diff

View file

@ -420,6 +420,9 @@ CMDS=<<EOF
obl~?
i
oc =
# oc resets RzCore completely
e scr.utf8=false
e scr.color=0
echo --
obl~?
i

View file

@ -462,45 +462,46 @@ Environment:
RZ_NOPLUGINS: # do not load plugins
Usage: rz-diff [options] <file0> <file1>
-a arch Specify architecture plugin to use (x86, arm, ..)
-b bits Specify register size for arch (16 (thumb), 32, 64, ..)
-d algo Compute edit distance based on the chosen algorithm:
  myers | Eugene W. Myers' O(ND) algorithm (no substitution)
  leven | Levenshtein O(N^2) algorithm (with substitution)
  ssdeep | Context triggered piecewise hashing comparison
-i Use command line arguments instead of files (only for -d)
-H Hexadecimal visual mode
-h Show this help
-j JSON output
-q Quiet output
-V Show version information
-v Be more verbose (stderr output)
-e k=v  Set an evaluable config variable
-A Compare virtual and physical addresses
-B Run 'aaa' when loading the bin
-C Disable colors
-T Show timestamp information
-S WxH  Set the width and height of the terminal for visual mode
-0 cmd  Input for file0 when option -t 'commands' is given.
 The same value will be set for file1, if -1 is not set.
-1 cmd  Input for file1 when option -t 'commands' is given.
-t type Compute the difference between two files based on its type:
  bytes | compare raw bytes in the files (only for small files)
  lines | compare text files
  functions | compare functions found in the files
  | optional -0 <fcn name|offset> to compare only one function
  classes | compare classes found in the files
  command | compare command output returned when executed in both files
  | require -0 <cmd> and -1 <cmd> is optional
  entries | compare entries found in the files
  fields | compare fields found in the files
  graphs | compare 2 functions and outputs in graphviz/dot format
  | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional
  imports | compare imports found in the files
  libraries | compare libraries found in the files
  sections | compare sections found in the files
  strings | compare strings found in the files
  symbols | compare symbols found in the files
-a arch  Specify architecture plugin to use (x86, arm, ..)
-b bits  Specify register size for arch (16 (thumb), 32, 64, ..)
-d algo  Compute edit distance based on the chosen algorithm:
  myers | Eugene W. Myers' O(ND) algorithm (no substitution)
  leven | Levenshtein O(N^2) algorithm (with substitution)
  ssdeep | Context triggered piecewise hashing comparison
-i Use command line arguments instead of files (only for -d)
-H Hexadecimal visual mode
-h Show this help
-j JSON output
-q Quiet output
-V Show version information
-v Be more verbose (stderr output)
-K theme Set a give color theme (see rizin 'eco' command)
-e k=v  Set an evaluable config variable
-A Compare virtual and physical addresses
-B Run 'aaa' when loading the bin
-C Disable colors
-T Show timestamp information
-S WxH  Set the width and height of the terminal for visual mode
-0 cmd  Input for file0 when option -t 'commands' is given.
 The same value will be set for file1, if -1 is not set.
-1 cmd  Input for file1 when option -t 'commands' is given.
-t type  Compute the difference between two files based on its type:
  bytes | compare raw bytes in the files (only for small files)
  lines | compare text files
  functions | compare functions found in the files
  | optional -0 <fcn name|offset> to compare only one function
  classes | compare classes found in the files
  command | compare command output returned when executed in both files
  | require -0 <cmd> and -1 <cmd> is optional
  entries | compare entries found in the files
  fields | compare fields found in the files
  graphs | compare 2 functions and outputs in graphviz/dot format
  | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional
  imports | compare imports found in the files
  libraries | compare libraries found in the files
  sections | compare sections found in the files
  strings | compare strings found in the files
  symbols | compare symbols found in the files
palette colors can be changed by adding the following lines
inside the $HOME/.rizinrc file
ec diff.unknown blue | offset color
@ -527,7 +528,7 @@ ec diff.unmatch red | mismatch color
-S str  Search for a symbol in symbol table.
-t to  Stop search at address 'to'
-q Quiet - do not show headings (filenames) above matching contents (default for searching a single file)
-v Show version information
-v Show version information
-V Verbose: prints each file scanned
-x hex  Search for hexpair string (909090) (can be used multiple times)
-X Show hexdump of search results

View file

@ -945,7 +945,7 @@ RUN
NAME=rz-diff functions comparison
FILE==
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions bins/other/rz-diff/true bins/other/rz-diff/false
CMDS=!rz-diff -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions bins/other/rz-diff/true bins/other/rz-diff/false
EXPECT=<<EOF
.-------------------------------------------------------------------------------------------------.
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
@ -964,38 +964,38 @@ RUN
NAME=rz-diff functions comparison (colored)
FILE==
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -t functions bins/other/rz-diff/true bins/other/rz-diff/false
CMDS=!rz-diff -K ayu -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -t functions bins/other/rz-diff/true bins/other/rz-diff/false
EXPECT=<<EOF
.-------------------------------------------------------------------------------------------------.
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
)-------------------------------------------------------------------------------------------------(
| test.00401460 | 41 | 0x00401460 | COMPLETE | 1.000000 | 0x00401470 | 41 | test.00401470 |
| test.00401990 | 137 | 0x00401990 | PARTIAL  | 0.985401 | 0x004019a0 | 137 | test.004019a0 |
| test.00401a20 | 162 | 0x00401a20 | COMPLETE | 1.000000 | 0x00401a30 | 162 | test.00401a30 |
| test.00401ae0 | 228 | 0x00401ae0 | PARTIAL  | 0.964912 | 0x00401af0 | 228 | test.00401af0 |
| test.00401be0 | 2728 | 0x00401be0 | PARTIAL  | 0.991569 | 0x00401bf0 | 2728 | test.00401bf0 |
| test.00402730 | 425 | 0x00402730 | PARTIAL  | 0.971765 | 0x00402740 | 425 | test.00402740 |
| test.004029a0 | 50 | 0x004029a0 | PARTIAL  | 0.980000 | 0x004029b0 | 50 | test.004029b0 |
| test.00402e20 | 204 | 0x00402e20 | PARTIAL  | 0.960784 | 0x00402e30 | 204 | test.00402e30 |
| test.00401460 | 41 | 0x00401460 | COMPLETE | 1.000000 | 0x00401470 | 41 | test.00401470 |
| test.00401990 | 137 | 0x00401990 | PARTIAL | 0.985401 | 0x004019a0 | 137 | test.004019a0 |
| test.00401a20 | 162 | 0x00401a20 | COMPLETE | 1.000000 | 0x00401a30 | 162 | test.00401a30 |
| test.00401ae0 | 228 | 0x00401ae0 | PARTIAL | 0.964912 | 0x00401af0 | 228 | test.00401af0 |
| test.00401be0 | 2728 | 0x00401be0 | PARTIAL | 0.991569 | 0x00401bf0 | 2728 | test.00401bf0 |
| test.00402730 | 425 | 0x00402730 | PARTIAL | 0.971765 | 0x00402740 | 425 | test.00402740 |
| test.004029a0 | 50 | 0x004029a0 | PARTIAL | 0.980000 | 0x004029b0 | 50 | test.004029b0 |
| test.00402e20 | 204 | 0x00402e20 | PARTIAL | 0.960784 | 0x00402e30 | 204 | test.00402e30 |
`-------------------------------------------------------------------------------------------------'
EOF
RUN
NAME=rz-diff functions comparison against only one function
FILE==
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions -0 test.00401ae0 bins/other/rz-diff/true bins/other/rz-diff/false
CMDS=!rz-diff -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions -0 test.00401ae0 bins/other/rz-diff/true bins/other/rz-diff/false
EXPECT=<<EOF
.-------------------------------------------------------------------------------------------------.
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
)-------------------------------------------------------------------------------------------------(
| test.00401470 | 41 | 0x00401470 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
| test.004019a0 | 137 | 0x004019a0 | UNLIKE | 0.1228 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401a30 | 162 | 0x00401a30 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401af0 | 228 | 0x00401af0 | PARTIAL | 0.964912 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401bf0 | 2728 | 0x00401bf0 | UNLIKE | 0.0433 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00402740 | 425 | 0x00402740 | UNLIKE | 0.1106 | 0x00401ae0 | 228 | test.00401ae0 |
| test.004029b0 | 50 | 0x004029b0 | UNLIKE | 0.0702 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00402e30 | 204 | 0x00402e30 | UNLIKE | 0.1140 | 0x00401ae0 | 228 | test.00401ae0 |
`-------------------------------------------------------------------------------------------------'
.------------------------------------------------------------------------------------------------.
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
)------------------------------------------------------------------------------------------------(
| test.00401470 | 41 | 0x00401470 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
| test.004019a0 | 137 | 0x004019a0 | UNLIKE | 0.1228 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401a30 | 162 | 0x00401a30 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401af0 | 228 | 0x00401af0 | PARTIAL | 0.964912 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00401bf0 | 2728 | 0x00401bf0 | UNLIKE | 0.0433 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00402740 | 425 | 0x00402740 | UNLIKE | 0.1106 | 0x00401ae0 | 228 | test.00401ae0 |
| test.004029b0 | 50 | 0x004029b0 | UNLIKE | 0.0702 | 0x00401ae0 | 228 | test.00401ae0 |
| test.00402e30 | 204 | 0x00402e30 | UNLIKE | 0.1140 | 0x00401ae0 | 228 | test.00401ae0 |
`------------------------------------------------------------------------------------------------'
EOF
RUN

View file

@ -1089,7 +1089,7 @@ static void func2_output(RzCmdStateOutput *state) {
bool test_state_output_concat_standard(void) {
RzCmdStateOutput state;
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, NULL), "state is initialized correctly");
rz_cons_flush();
rz_cons_push();
@ -1118,11 +1118,11 @@ bool test_state_output_concat_table(void) {
rz_cons_flush();
rz_cons_push();
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
func1_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
func2_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -1145,11 +1145,11 @@ bool test_state_output_concat_mix(void) {
rz_cons_flush();
rz_cons_push();
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
func1_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, NULL), "state is initialized correctly");
func2_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -1170,11 +1170,11 @@ bool test_state_output_concat_json(void) {
rz_cons_flush();
rz_cons_push();
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
func1_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
func2_output(&state);
rz_cmd_state_output_print(&state);
rz_cmd_state_output_fini(&state);
@ -1186,7 +1186,7 @@ bool test_state_output_concat_json(void) {
rz_cons_flush();
rz_cons_push();
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
pj_o(state.d.pj);
pj_k(state.d.pj, "first");
func1_output(&state);

View file

@ -11,11 +11,8 @@ bool test_rz_table(void) {
RzTable *t = rz_table_new();
// rz_table_fromcsv (t, csv);
RzTableColumnType *typeString = rz_table_type("string");
RzTableColumnType *typeNumber = rz_table_type("number");
rz_table_add_column(t, typeString, "name", 0);
rz_table_add_column(t, typeNumber, "address", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "address");
rz_table_add_row(t, "hello", "100", NULL);
rz_table_add_row(t, "namings", "20000", NULL);
@ -37,8 +34,8 @@ bool test_rz_table(void) {
RzTable *__table_test_data1() {
RzTable *t = rz_table_new();
rz_table_add_column(t, rz_table_type("string"), "ascii", 0);
rz_table_add_column(t, rz_table_type("number"), "code", 0);
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "ascii");
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "code");
rz_table_add_row(t, "a", "97", NULL);
rz_table_add_row(t, "b", "98", NULL);
@ -47,24 +44,6 @@ RzTable *__table_test_data1() {
return t;
}
bool test_rz_table_column_type(void) {
RzTable *t = __table_test_data1();
RzTableColumn *c = rz_vector_index_ptr(t->cols, 1);
c->type = rz_table_type("NUMBER");
rz_table_sort(t, 1, true);
char *s = rz_table_tostring(t);
mu_assert_streq(s,
"ascii code \n"
"-----------\n"
"a 97\n"
"b 98\n"
"c 99\n",
"not sorted by second column due to undefined type");
free(s);
rz_table_free(t);
mu_end;
}
bool test_rz_table_tostring(void) {
RzTable *t = __table_test_data1();
char buf[BUF_LENGTH];
@ -156,29 +135,29 @@ bool test_rz_table_uniq(void) {
mu_end;
}
static void simple_merge(RzTableRow *acc, RzTableRow *new_row, int nth) {
static void simple_merge(RzTableRow *acc, RzTableRow *new_row, size_t nth) {
RzPVector *lhs = acc->items;
RzPVector *rhs = new_row->items;
char *item_lhs;
int cnt;
for (cnt = 0; cnt < rz_pvector_len(lhs) && cnt < rz_pvector_len(rhs); cnt++) {
for (size_t cnt = 0; cnt < rz_pvector_len(lhs) && cnt < rz_pvector_len(rhs); cnt++) {
if (cnt == nth) {
continue;
}
item_lhs = rz_pvector_at(lhs, cnt);
if (cnt != nth) {
if (!strcmp(item_lhs, "a")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("a | e"));
} else if (!strcmp(item_lhs, "b")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("b | f"));
} else if (!strcmp(item_lhs, "c")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("c | h"));
} else if (!strcmp(item_lhs, "d")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("d | g"));
}
if (!strcmp(item_lhs, "a")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("a | e"));
} else if (!strcmp(item_lhs, "b")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("b | f"));
} else if (!strcmp(item_lhs, "c")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("c | h"));
} else if (!strcmp(item_lhs, "d")) {
free(item_lhs);
rz_pvector_set(lhs, cnt, rz_str_dup("d | g"));
}
}
}
@ -243,13 +222,13 @@ bool test_rz_table_group(void) {
mu_end;
}
bool test_rz_table_columns() {
bool test_rz_table_columns_select() {
RzTable *t = NULL;
#define CREATE_TABLE \
rz_table_free(t); \
t = rz_table_new(); \
rz_table_add_column(t, rz_table_type("number"), "name", 0); \
rz_table_add_column(t, rz_table_type("number"), "address", 0); \
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "name"); \
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "address"); \
rz_table_add_row(t, "hello", "100", NULL); \
rz_table_add_row(t, "namings", "20000", NULL);
@ -263,18 +242,14 @@ bool test_rz_table_columns() {
free(s);
RzList *newcols = rz_list_new();
rz_table_columns(t, newcols);
rz_table_columns_select(t, newcols);
s = rz_table_tocsv(t);
mu_assert_streq(s,
"\n"
"\n"
"\n",
"no cols");
mu_assert_streq(s, "", "no cols");
free(s);
CREATE_TABLE
rz_list_push(newcols, "address");
rz_table_columns(t, newcols);
rz_table_columns_select(t, newcols);
s = rz_table_tocsv(t);
mu_assert_streq(s,
"address\n"
@ -285,7 +260,7 @@ bool test_rz_table_columns() {
CREATE_TABLE
rz_list_push(newcols, "name");
rz_table_columns(t, newcols);
rz_table_columns_select(t, newcols);
s = rz_table_tocsv(t);
mu_assert_streq(s,
"address,name\n"
@ -297,7 +272,7 @@ bool test_rz_table_columns() {
CREATE_TABLE
rz_list_push(newcols, "name");
rz_list_push(newcols, "address");
rz_table_columns(t, newcols);
rz_table_columns_select(t, newcols);
s = rz_table_tocsv(t);
mu_assert_streq(s,
"address,name,name,address\n"
@ -350,7 +325,7 @@ bool test_rz_table_add_row_columnsf() {
bool test_rz_table_query(void) {
RzTable *t = __table_test_data1();
bool qr = rz_table_query(t, "code/sort/dec");
bool qr = rz_table_query(t, "code/sort/rev");
mu_assert_true(qr, "table sorted decrementally");
char *s = rz_table_tostring(t);
mu_assert_streq(s,
@ -361,7 +336,7 @@ bool test_rz_table_query(void) {
"a 97\n",
"sort table by number column");
free(s);
qr = rz_table_query(t, "code/sort/dec");
qr = rz_table_query(t, "code/sort/rev");
mu_assert_true(qr, "table sorted incrementally");
qr = rz_table_query(t, "code/le/98");
mu_assert_true(qr, "table filter by <=98");
@ -410,12 +385,11 @@ bool test_rz_table_query(void) {
bool all_tests() {
mu_run_test(test_rz_table);
mu_run_test(test_rz_table_column_type);
mu_run_test(test_rz_table_tostring);
mu_run_test(test_rz_table_sort1);
mu_run_test(test_rz_table_uniq);
mu_run_test(test_rz_table_group);
mu_run_test(test_rz_table_columns);
mu_run_test(test_rz_table_columns_select);
mu_run_test(test_rz_table_transpose);
mu_run_test(test_rz_table_add_row_columnsf);
mu_run_test(test_rz_table_query);