From a471c825e257a391292d4aa20067bc5aca420a2e Mon Sep 17 00:00:00 2001 From: cyanpencil Date: Sun, 20 May 2018 19:49:06 +0200 Subject: [PATCH 1/3] Added agA global graph and agR global graph --- libr/core/canal.c | 3 --- libr/core/cmd_anal.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/libr/core/canal.c b/libr/core/canal.c index 2c80ba7ecb003..456999a226361 100644 --- a/libr/core/canal.c +++ b/libr/core/canal.c @@ -1729,9 +1729,6 @@ R_API void r_core_anal_datarefs(RCore *core, ut64 addr) { r_cons_printf ("age %s %s\n", me, dst); } } - if (!found) { - eprintf ("No data refs in this function.\n"); - } r_list_free (refs); } else { eprintf ("Not in a function. Use 'df' to define it.\n"); diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index dc77aabc0b496..72373851f41d6 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -5951,6 +5951,34 @@ static void cmd_anal_graph(RCore *core, const char *input) { break; } break; + case 'R': // "agR" global refs + switch (input[1]) { + case 'v': + case 't': + case 'd': + case 'J': + case 'j': + case 'g': + case 'k': + case 'w': + case ' ': + case 0: { + r_core_cmdf (core, "ag-; .agR*; agg%c;", input[1]); + break; + } + case '*': { + RListIter *it; + RAnalFunction *fcn; + r_list_foreach (core->anal->fcns, it, fcn) { + r_core_anal_coderefs (core, fcn->addr); + } + break; + } + default: + eprintf ("Usage: see ag?\n"); + break; + } + break; case 'x': // agx "cross refs" switch (input[1]) { case 'v': @@ -6095,6 +6123,34 @@ static void cmd_anal_graph(RCore *core, const char *input) { break; } break; + case 'A': // "agA" global data refs + switch (input[1]) { + case 'v': + case 't': + case 'd': + case 'J': + case 'j': + case 'g': + case 'k': + case 'w': + case ' ': + case 0: { + r_core_cmdf (core, "ag-; .agA*; agg%c;", input[1]); + break; + } + case '*': { + RListIter *it; + RAnalFunction *fcn; + r_list_foreach (core->anal->fcns, it, fcn) { + r_core_anal_datarefs (core, fcn->addr); + } + break; + } + default: + eprintf ("Usage: see ag?\n"); + break; + } + break; case 'd': // "agd" switch (input[1]) { case 'v': From 3816697e58a9b61c16d9a7632c3d9a7650e40444 Mon Sep 17 00:00:00 2001 From: cyanpencil Date: Mon, 21 May 2018 19:53:24 +0200 Subject: [PATCH 2/3] Added r_str_trunc_ellipsis() to truncate node titles too long Removed comments and fixed r_agraph_get_node() --- libr/core/graph.c | 16 +++++++++++----- libr/include/r_util/r_str.h | 1 + libr/util/str.c | 11 +++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libr/core/graph.c b/libr/core/graph.c index 16d575f902a17..8dc714ed9078e 100644 --- a/libr/core/graph.c +++ b/libr/core/graph.c @@ -3317,7 +3317,8 @@ R_API RANode *r_agraph_add_node(const RAGraph *g, const char *title, const char if (!res) { return NULL; } - res->title = title? strdup (title): strdup (""); + + res->title = title? r_str_trunc_ellipsis (title, 255) : strdup (""); res->body = body? strdup (body): strdup (""); res->layer = -1; res->pos_in_layer = -1; @@ -3325,7 +3326,7 @@ R_API RANode *r_agraph_add_node(const RAGraph *g, const char *title, const char res->is_reversed = false; res->klass = -1; res->gnode = r_graph_add_node (g->graph, res); - sdb_num_set (g->nodes, title, (ut64) (size_t) res, 0); + sdb_num_set (g->nodes, res->title, (ut64) (size_t) res, 0); if (res->title) { char *s, *estr, *b; size_t len; @@ -3345,7 +3346,9 @@ R_API RANode *r_agraph_add_node(const RAGraph *g, const char *title, const char } R_API bool r_agraph_del_node(const RAGraph *g, const char *title) { - RANode *an, *res = r_agraph_get_node (g, title); + char *title_trunc = r_str_trunc_ellipsis (title, 255); + RANode *an, *res = r_agraph_get_node (g, title_trunc); + free (title_trunc); const RList *innodes; RGraphNode *gn; RListIter *it; @@ -3353,7 +3356,7 @@ R_API bool r_agraph_del_node(const RAGraph *g, const char *title) { if (!res) { return false; } - sdb_set (g->nodes, title, NULL, 0); + sdb_set (g->nodes, res->title, NULL, 0); sdb_array_remove (g->db, "agraph.nodes", res->title, 0); sdb_set (g->db, sdb_fmt ("agraph.nodes.%s", res->title), NULL, 0); sdb_set (g->db, sdb_fmt ("agraph.nodes.%s.body", res->title), 0, 0); @@ -3426,7 +3429,10 @@ R_API RANode *r_agraph_get_first_node(const RAGraph *g) { } R_API RANode *r_agraph_get_node(const RAGraph *g, const char *title) { - return (RANode *) (size_t) sdb_num_get (g->nodes, title, NULL); + char *title_trunc = r_str_trunc_ellipsis (title, 255); + RANode *node = (RANode *) (size_t) sdb_num_get (g->nodes, title_trunc, NULL); + free (title_trunc); + return node; } R_API void r_agraph_add_edge(const RAGraph *g, RANode *a, RANode *b) { diff --git a/libr/include/r_util/r_str.h b/libr/include/r_util/r_str.h index f07b3251129ee..2d9535f06556f 100644 --- a/libr/include/r_util/r_str.h +++ b/libr/include/r_util/r_str.h @@ -67,6 +67,7 @@ R_API bool r_str_is_printable_incl_newlines(const char *str); R_API char *r_str_appendlen(char *ptr, const char *string, int slen); R_API char *r_str_newf(const char *fmt, ...); R_API char *r_str_newlen(const char *str, int len); +R_API char *r_str_trunc_ellipsis(const char *str, int len); R_API const char *r_str_bool(int b); R_API const char *r_str_ansi_chrn(const char *str, int n); R_API int r_str_ansi_len(const char *str); diff --git a/libr/util/str.c b/libr/util/str.c index 5e5e5e215131e..713686f8c2b82 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -652,6 +652,17 @@ R_API char *r_str_newlen(const char *str, int len) { return buf; } +R_API char *r_str_trunc_ellipsis(const char *str, int len) { + char *buf; + if (strlen (str) < len) { + buf = strdup (str); + } else { + buf = r_str_newlen (str, len); + strcpy (buf + len - 4, "..."); + } + return buf; +} + // Returns a new heap-allocated string that matches the format-string // specification. R_API char *r_str_newf(const char *fmt, ...) { From 8452114d31dbdee12b94a005db9cae118123dc6a Mon Sep 17 00:00:00 2001 From: cyanpencil Date: Mon, 21 May 2018 21:26:25 +0200 Subject: [PATCH 3/3] Updated ag? help Fixed segfault in r_str_trunc_ellipsis() Fix agC* command Fix callgraph bug not resetting is_callgraph --- libr/core/cmd_anal.c | 8 +++++++- libr/core/graph.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index 72373851f41d6..4bd6202544dfd 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -388,6 +388,9 @@ static const char *help_msg_ag[] = { "aga", "[format] [fcn addr]", "Data references graph", "agd", "[format] [fcn addr]", "Diff graph", "agi", "[format]", "Imports graph", + "agC", "[format]", "Global callgraph", + "agR", "[format]", "Global references graph", + "agA", "[format]", "Global data references graph", "agg", "[format]", "Custom graph", "ag-", "", "Clear the custom graph", "agn", "[?] title body", "Add a node to the custom graph", @@ -5894,11 +5897,12 @@ static void cmd_anal_graph(RCore *core, const char *input) { case ' ': case 0: { core->graph->is_callgraph = true; - char *cmd = r_str_newf ("ag-; .agc* %lld; agg%c;", UT64_MAX, input[1]); + char *cmd = r_str_newf ("ag-; .agC*; agg%c;", input[1]); if (cmd && *cmd) { r_core_cmd0 (core, cmd); } free (cmd); + core->graph->is_callgraph = false; break; } case 'J': @@ -6046,12 +6050,14 @@ static void cmd_anal_graph(RCore *core, const char *input) { if (cmd && *cmd) { r_core_cmd0 (core, cmd); } + core->graph->is_callgraph = false; free (cmd); break; } case 0: core->graph->is_callgraph = true; r_core_cmd0 (core, "ag-; .agc* $$; agg;"); + core->graph->is_callgraph = false; break; case 'g': { ut64 addr = input[2] ? r_num_math (core->num, input + 2): core->offset; diff --git a/libr/core/graph.c b/libr/core/graph.c index 8dc714ed9078e..aa43b09ea442e 100644 --- a/libr/core/graph.c +++ b/libr/core/graph.c @@ -3429,7 +3429,7 @@ R_API RANode *r_agraph_get_first_node(const RAGraph *g) { } R_API RANode *r_agraph_get_node(const RAGraph *g, const char *title) { - char *title_trunc = r_str_trunc_ellipsis (title, 255); + char *title_trunc = title ? r_str_trunc_ellipsis (title, 255) : NULL; RANode *node = (RANode *) (size_t) sdb_num_get (g->nodes, title_trunc, NULL); free (title_trunc); return node;