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

Improve jmptbl edges, second try #10662

Merged
merged 3 commits into from Jul 8, 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
1 change: 0 additions & 1 deletion libr/core/cconfig.c
Expand Up @@ -2828,7 +2828,6 @@ R_API int r_core_config_init(RCore *core) {
SETCB ("graph.extension", "gif", &cb_graphformat, "Graph extension when using 'w' format (png, jpg, pdf, ps, svg, json)");
SETPREF ("graph.refs", "false", "Graph references in callgraphs (.agc*;aggi)");
SETI ("graph.edges", 2, "0=no edges, 1=simple edges, 2=avoid collisions");
SETPREF ("graph.altedgepos", "false", "Switch to alternative (very experimental) positioning of edges");
SETI ("graph.layout", 0, "Graph layout (0=vertical, 1=horizontal)");
SETI ("graph.linemode", 1, "Graph edges (0=diagonal, 1=square)");
SETPREF ("graph.font", "Courier", "Font for dot graphs");
Expand Down
61 changes: 47 additions & 14 deletions libr/core/graph.c
Expand Up @@ -2641,6 +2641,24 @@ static void agraph_print_edges_simple(RAGraph *g) {
}
}

static int first_x_cmp (RGraphNode *ga, RGraphNode *gb) {
RANode *a = (RANode*) ga->data;
RANode *b = (RANode*) gb->data;
if (b->y < a->y) {
return -1;
}
if (b->y > a->y) {
return 1;
}
if (a->x < b->x) {
return 1;
} else if (a->x > b->x) {
return -1;
} else {
return 0;
}
}

static void agraph_print_edges(RAGraph *g) {
if (!g->edgemode) {
return;
Expand All @@ -2649,7 +2667,7 @@ static void agraph_print_edges(RAGraph *g) {
agraph_print_edges_simple (g);
return;
}
int out_nth, in_nth;
int out_nth, in_nth, bendpoint;
RListIter *itn, *itm, *ito;
RCanvasLineStyle style = {0};
const RList *nodes = r_graph_get_nodes (g->graph);
Expand Down Expand Up @@ -2706,13 +2724,27 @@ static void agraph_print_edges(RAGraph *g) {
}
}


bool many = r_list_length (neighbours) > 2;

if (many && !g->is_callgraph) {
ga->out_nodes->sorted = false;
r_list_sort (neighbours, first_x_cmp);
}

graph_foreach_anode (neighbours, itn, gb, b) {
out_nth = get_edge_number (g, a, b, true);
in_nth = get_edge_number (g, a, b, false);

if (many) {
bool parent_many = false;
if (a->is_dummy) {
RANode *in = (RANode *) (((RGraphNode *)r_list_first (ga->in_nodes))->data);
while (in && in->is_dummy) {
in = (RANode *) (((RGraphNode *)r_list_first ((in->gnode)->in_nodes))->data);
}
parent_many = r_list_length ((in->gnode)->out_nodes) > 2;
}

if (many || parent_many) {
style.color = LINE_UNCJMP;
} else {
switch (out_nth) {
Expand All @@ -2739,35 +2771,37 @@ static void agraph_print_edges(RAGraph *g) {
a_x_inc = R_EDGES_X_INC + 2 * (out_nth + 1);
b_x_inc = R_EDGES_X_INC + 2 * (in_nth + 1);

if (g->altedgepos) {
ax = a->is_dummy ? a->x : (a->x + a->w - a_x_inc);
bx = b->is_dummy ? b->x : (b->x + b_x_inc);
bx = b->is_dummy ? b->x : (b->x + b_x_inc);
ay = a->y + a->h;
by = b->y - 1;

if (many && !g->is_callgraph) {
int t = R_EDGES_X_INC + 2 * (neighbours->length + 1);
ax = a->is_dummy ? a->x : (a->x + a->w/2 + (t/2 - a_x_inc));
bendpoint = bx < ax ? neighbours->length - out_nth : out_nth;
} else {
ax = a->is_dummy ? a->x : (a->x + a_x_inc);
bx = b->is_dummy ? b->x : (b->x + a_x_inc);
bendpoint = tm->edgectr;
}

ay = a->y + a->h;
by = b->y - 1;

if (!a->is_dummy && itn == neighbours->head && out_nth == 0 && bx > ax) {
a_x_inc += 4;
ax += g->altedgepos ? -4 : 4;
ax += (many && !g->is_callgraph) ? 0 : 4;
}
if (a->h < a->layer_height) {
r_cons_canvas_line (g->can, ax, ay, ax, ay + a->layer_height - a->h, &style);
ay = a->y + a->layer_height;
style.symbol = LINE_NOSYM_VERT;
}
if (by >= ay) {
r_cons_canvas_line_square_defined (g->can, ax, ay, bx, by, &style, tm->edgectr, true);
r_cons_canvas_line_square_defined (g->can, ax, ay, bx, by, &style, bendpoint, true);
} else {
struct tmpbackedgeinfo *tmp = calloc (1, sizeof (struct tmpbackedgeinfo));
tmp->ax = ax;
tmp->bx = bx;
tmp->ay = ay;
tmp->by = by;
tmp->edgectr = tm->edgectr;
tmp->edgectr = bendpoint;
tmp->fromlayer = a->layer;
tmp->tolayer = b->layer;
tmp->style = style;
Expand Down Expand Up @@ -3731,7 +3765,6 @@ R_API int r_core_visual_graph(RCore *core, RAGraph *g, RAnalFunction *_fcn, int
g->on_curnode_change = (RANodeCallback) seek_to_node;
g->on_curnode_change_data = core;
g->edgemode = r_config_get_i (core->config, "graph.edges");
g->altedgepos = r_config_get_i (core->config, "graph.altedgepos");
g->is_interactive = is_interactive;
bool asm_comments = r_config_get_i (core->config, "asm.comments");
r_config_set (core->config, "asm.comments",
Expand Down
1 change: 0 additions & 1 deletion libr/include/r_cons.h
Expand Up @@ -906,7 +906,6 @@ typedef struct r_ascii_graph_t {
bool is_tiny;
bool is_dis;
int edgemode;
bool altedgepos;
int mode;
bool is_callgraph;
bool is_interactive;
Expand Down
12 changes: 7 additions & 5 deletions libr/util/graph.c
Expand Up @@ -182,11 +182,13 @@ R_API void r_graph_add_edge (RGraph *t, RGraphNode *from, RGraphNode *to) {

R_API void r_graph_add_edge_at (RGraph *t, RGraphNode *from, RGraphNode *to, int nth) {
if (from && to) {
r_list_insert (from->out_nodes, nth, to);
r_list_append (from->all_neighbours, to);
r_list_append (to->in_nodes, from);
r_list_append (to->all_neighbours, from);
t->n_edges++;
if (!r_list_contains (from->out_nodes, to)) {
r_list_insert (from->out_nodes, nth, to);
r_list_append (from->all_neighbours, to);
r_list_append (to->in_nodes, from);
r_list_append (to->all_neighbours, from);
t->n_edges++;
}
}
}

Expand Down