Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support every output format for the xrefs graph (agx) #10084

Merged
merged 3 commits into from May 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 35 additions & 1 deletion libr/core/cmd_anal.c
Expand Up @@ -5745,6 +5745,7 @@ static void cmd_agraph_print(RCore *core, const char *input) {
r_core_visual_graph (core, core->graph, NULL, true);
r_config_set_i (core->config, "scr.interactive", ov);
r_cons_show_cursor (true);
r_cons_enable_mouse (false);
} else {
eprintf ("This graph contains no nodes\n");
}
Expand Down Expand Up @@ -5806,6 +5807,7 @@ static void cmd_anal_graph(RCore *core, const char *input) {
case 'v':// "agfv"
eprintf ("\rRendering graph...");
r_core_visual_graph (core, NULL, NULL, 1);
r_cons_enable_mouse (false);
r_cons_show_cursor (true);
break;
case 't':// "agft" - tiny graph
Expand Down Expand Up @@ -5890,7 +5892,7 @@ static void cmd_anal_graph(RCore *core, const char *input) {
case 'C': // "agC"
r_core_anal_callgraph (core, UT64_MAX, input[1] == 'j'? 2 : 1);
break;
case 'r': // "refs"
case 'r': // agr "refs"
switch (input[1]) {
case 'v':
case 't':
Expand Down Expand Up @@ -5922,6 +5924,38 @@ static void cmd_anal_graph(RCore *core, const char *input) {
break;
}
break;
case 'x': // agx "cross refs"
switch (input[1]) {
case 'v':
case 't':
case 'd':
case 'J':
case 'j':
case 'g':
case 'k':
case 'w':
case ' ': {
char *cmd = r_str_newf ("ag-; .agx* %lld; agg%c;",
input[2] ? r_num_math (core->num, input + 2) : core->offset, input[1]);
if (cmd && *cmd) {
r_core_cmd0 (core, cmd);
}
free (cmd);
break;
}
case '*': {
ut64 addr = input[2] ? r_num_math (core->num, input + 2) : core->offset;
r_core_anal_codexrefs (core, addr);
}
break;
case 0:
r_core_cmd0 (core, "ag-; .agx* $$; agg;");
break;
default:
eprintf ("Usage: see ag?\n");
break;
}
break;
case 'c': // "agc"
if (input[1] == '*') {
ut64 addr = input[2]? r_num_math (core->num, input + 2): UT64_MAX;
Expand Down
34 changes: 26 additions & 8 deletions libr/core/graph.c
Expand Up @@ -3157,6 +3157,10 @@ static int agraph_refresh(struct agraph_refresh_data *grd) {
RAnalFunction *f = NULL;
RAnalFunction **fcn = grd->fcn;

if (!fcn) {
return agraph_print (g, grd->fs, core, NULL);
}

// allow to change the current function during debugging
if (g->is_instep && core->io->debug) {
// seek only when the graph node changes
Expand Down Expand Up @@ -3198,7 +3202,7 @@ static int agraph_refresh(struct agraph_refresh_data *grd) {
r_cons_flush ();
}

return agraph_print (g, grd->fs, core, fcn ? *fcn: NULL);
return agraph_print (g, grd->fs, core, *fcn);
}

static void agraph_toggle_speed(RAGraph *g, RCore *core) {
Expand Down Expand Up @@ -3816,13 +3820,15 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
#if 1
// disabled for now, ultraslow in most situations
case '>':
if (r_cons_yesno ('y', "Compute function callgraph? (Y/n)")) {
if (fcn && r_cons_yesno ('y', "Compute function callgraph? (Y/n)")) {
r_core_cmd0 (core, "ag-;.agc* $$;.axtg $$;aggi");
}
break;
case '<':
// r_core_visual_refs (core, true);
r_core_cmd0 (core, "ag-;.axtg $$;aggi");
if (fcn) {
r_core_cmd0 (core, "ag-;.axtg $$;aggi");
}
break;
#endif
case 'G':
Expand All @@ -3839,6 +3845,9 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
}
break;
case 's':
if (!fcn) {
break;
}
key_s = r_config_get (core->config, "key.s");
if (key_s && *key_s) {
r_core_cmd0 (core, key_s);
Expand All @@ -3847,7 +3856,9 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
}
break;
case 'S':
graph_single_step_over (core, g);
if (fcn) {
graph_single_step_over (core, g);
}
break;
case 'x':
case 'X':
Expand Down Expand Up @@ -3945,6 +3956,9 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
visual_offset (g, core);
break;
case 'O':
if (!fcn) {
break;
}
disMode = (disMode + 1) % 3;
applyDisMode (core);
g->need_reload_nodes = true;
Expand Down Expand Up @@ -4032,12 +4046,16 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
}
break;
case '(':
r_core_cmd0 (core, "wao recj@B:-1");
g->need_reload_nodes = true;
if (fcn) {
r_core_cmd0 (core, "wao recj@B:-1");
g->need_reload_nodes = true;
}
break;
case ')':
rotateAsmemu (core);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this needs a fcn to work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is not rotateAsmemu (core) itself, but it's the next instruction, g->need_reload_nodes...
In fact if need_reload_nodes is set the next time check_changes () is called it will call agraph_reload_nodes (), which does a r_agraph_reset () (that deletes every node in the graph) and after that a reload_nodes (), which calls get_bbnodes () that should create again the graph from scratch, but if fcn is NULL, it simply exits without doing anything.

The consequence is that if I create a custom graph and display it with aggv and then I press ')' the graph I built is lost.

g->need_reload_nodes = true;
if (fcn) {
rotateAsmemu (core);
g->need_reload_nodes = true;
}
break;
case 'd':
{
Expand Down