depgraph for r2 ascii graphs, agn doesnt requires body now

This commit is contained in:
pancake 2015-12-10 22:45:00 +01:00
parent c07c288f19
commit 6dc0bd41c1
3 changed files with 80 additions and 78 deletions

View File

@ -2662,25 +2662,29 @@ static void cmd_agraph_node(RCore *core, const char *input) {
input++;
args = r_str_argv (input, &n_args);
if (n_args != 2) {
if (n_args < 1 || n_args>2) {
r_cons_printf ("Wrong arguments\n");
r_str_argv_free (args);
break;
}
//strdup cause there is double free in r_str_argv_free due to a realloc call
body = strdup (args[1]);
if (strncmp (body, "base64:", B_LEN) == 0) {
body = r_str_replace (body, "\\n", "", true);
newbody = (char *)r_base64_decode_dyn (body + B_LEN, -1);
free (body);
if (!newbody){
eprintf ("Not enough space to allocate %s at %d\n", __FILE__,__LINE__);
r_str_argv_free (args);
break;
if (n_args>1) {
body = strdup (args[1]);
if (strncmp (body, "base64:", B_LEN) == 0) {
body = r_str_replace (body, "\\n", "", true);
newbody = (char *)r_base64_decode_dyn (body + B_LEN, -1);
free (body);
if (!newbody){
eprintf ("Not enough space to allocate %s at %d\n", __FILE__,__LINE__);
r_str_argv_free (args);
break;
}
body = newbody;
}
body = newbody;
body = r_str_concat (body, "\n");
} else {
body = strdup ("");
}
body = r_str_concat (body, "\n");
r_agraph_add_node (core->graph, args[0], body);
r_str_argv_free (args);
free (body);
@ -2809,13 +2813,13 @@ static void cmd_anal_graph(RCore *core, const char *input) {
case '-':
r_agraph_reset (core->graph);
break;
case 'n':
case 'n': // "agn"
cmd_agraph_node (core, input + 1);
break;
case 'e':
case 'e': // "age"
cmd_agraph_edge (core, input + 1);
break;
case 'g':
case 'g': // "agg"
cmd_agraph_print (core, input + 1);
break;
case 't':

View File

@ -1,4 +1,4 @@
/* Copyright radare2 2014-2015 - Author: pancake, ret2libc */
/* Copyright radare2 - 2014-2015 - pancake, ret2libc */
#include <r_core.h>
#include <r_cons.h>
@ -777,18 +777,14 @@ static RGraphNode *get_sibling (const RAGraph *g, const RANode *n, int is_left,
return res;
}
static int adjust_class_val (const RAGraph *g, const RGraphNode *gn,
const RGraphNode *sibl, Sdb *res, int is_left) {
if (is_left)
return hash_get_int (res, sibl) - hash_get_int (res, gn) - dist_nodes (g, gn, sibl);
else
return hash_get_int (res, gn) - hash_get_int (res, sibl) - dist_nodes (g, sibl, gn);
static int adjust_class_val (const RAGraph *g, const RGraphNode *gn, const RGraphNode *sibl, Sdb *res, int is_left) {
if (is_left) return hash_get_int (res, sibl) - hash_get_int (res, gn) - dist_nodes (g, gn, sibl);
return hash_get_int (res, gn) - hash_get_int (res, sibl) - dist_nodes (g, sibl, gn);
}
/* adjusts the position of previously placed left/right classes */
/* tries to place classes as close as possible */
static void adjust_class (const RAGraph *g, int is_left,
RList **classes, Sdb *res, int c) {
static void adjust_class (const RAGraph *g, int is_left, RList **classes, Sdb *res, int c) {
const RGraphNode *gn;
const RListIter *it;
const RANode *an;
@ -841,26 +837,19 @@ static void adjust_class (const RAGraph *g, int is_left,
}
}
static int place_nodes_val (const RAGraph *g, const RGraphNode *gn,
const RGraphNode *sibl, Sdb *res, int is_left) {
if (is_left)
return hash_get_int (res, sibl) + dist_nodes (g, sibl, gn);
static int place_nodes_val (const RAGraph *g, const RGraphNode *gn, const RGraphNode *sibl, Sdb *res, int is_left) {
if (is_left) return hash_get_int (res, sibl) + dist_nodes (g, sibl, gn);
return hash_get_int (res, sibl) - dist_nodes (g, gn, sibl);
}
static int place_nodes_sel_p (int newval, int oldval, int is_first, int is_left) {
if (is_first)
return newval;
if (is_left)
return R_MAX (oldval, newval);
else
return R_MIN (oldval, newval);
if (is_first) return newval;
if (is_left) return R_MAX (oldval, newval);
return R_MIN (oldval, newval);
}
/* places left/right the nodes of a class */
static void place_nodes (const RAGraph *g, const RGraphNode *gn, int is_left,
Sdb *v_nodes, RList **classes, Sdb *res, Sdb *placed) {
static void place_nodes (const RAGraph *g, const RGraphNode *gn, int is_left, Sdb *v_nodes, RList **classes, Sdb *res, Sdb *placed) {
const RList *lv = hash_get_rlist (v_nodes, gn);
int p = 0, v, is_first = true;
const RGraphNode *gk;
@ -1068,8 +1057,7 @@ static int RP_listcmp (const struct len_pos_t *a, const struct len_pos_t *b) {
return a->pos >= b->pos;
}
static void collect_changes (const RAGraph *g, int l, const RGraphNode *b,
int from_up, int s, int e, RList *list, int is_left) {
static void collect_changes (const RAGraph *g, int l, const RGraphNode *b, int from_up, int s, int e, RList *list, int is_left) {
const RGraphNode *vt = g->layers[l].nodes[e - 1];
const RGraphNode *vtp = g->layers[l].nodes[s];
RListComparator lcmp;
@ -1112,10 +1100,8 @@ static void collect_changes (const RAGraph *g, int l, const RGraphNode *b,
cx = R_NEW0 (struct len_pos_t);
cx->len = c;
cx->pos = avi->x;
if (is_left)
cx->pos += dist_nodes (g, vi, vt);
else
cx->pos -= dist_nodes (g, vtp, vi);
if (is_left) cx->pos += dist_nodes (g, vi, vt);
else cx->pos -= dist_nodes (g, vtp, vi);
r_list_add_sorted (list, cx, lcmp);
}
@ -1125,17 +1111,13 @@ static void collect_changes (const RAGraph *g, int l, const RGraphNode *b,
cx = R_NEW (struct len_pos_t);
cx->len = is_left ? INT_MAX : INT_MIN;
cx->pos = ab->x;
if (is_left)
cx->pos += dist_nodes (g, b, vt);
else
cx->pos -= dist_nodes (g, vtp, b);
if (is_left) cx->pos += dist_nodes (g, b, vt);
else cx->pos -= dist_nodes (g, vtp, b);
r_list_add_sorted (list, cx, lcmp);
}
}
static void combine_sequences (const RAGraph *g, int l,
const RGraphNode *bm, const RGraphNode *bp,
int from_up, int a, int r) {
static void combine_sequences (const RAGraph *g, int l, const RGraphNode *bm, const RGraphNode *bp, int from_up, int a, int r) {
RList *Rm = r_list_new (), *Rp = r_list_new ();
const RGraphNode *vt, *vtp;
RANode *at, *atp;
@ -1186,14 +1168,12 @@ static void combine_sequences (const RAGraph *g, int l,
for (i = t - 2; i >= a; --i) {
const RGraphNode *gv = g->layers[l].nodes[i];
RANode *av = get_anode (gv);
av->x = R_MIN (av->x, at->x - dist_nodes (g, gv, vt));
}
for (i = t + 1; i < r; ++i) {
const RGraphNode *gv = g->layers[l].nodes[i];
RANode *av = get_anode (gv);
av->x = R_MAX (av->x, atp->x + dist_nodes (g, vtp, gv));
}
}
@ -1203,9 +1183,7 @@ static void combine_sequences (const RAGraph *g, int l,
* neighbours in the "previous" layer. Those neighbours are considered as
* "fixed". The previous layer depends on the direction used during the layers
* traversal */
static void place_sequence (const RAGraph *g, int l,
const RGraphNode *bm, const RGraphNode *bp,
int from_up, int va, int vr) {
static void place_sequence (const RAGraph *g, int l, const RGraphNode *bm, const RGraphNode *bp, int from_up, int va, int vr) {
int vt;
if (vr == va + 1) {
@ -1563,7 +1541,6 @@ static char *get_body (RCore *core, ut64 addr, int size, bool with_offset,
static void get_bbupdate(RAGraph *g, RCore *core, RAnalFunction *fcn) {
RAnalBlock *bb;
RListIter *iter;
core->keep_asmqjmps = false;
r_list_foreach (fcn->bbs, iter, bb) {
RANode *node;
@ -1858,7 +1835,7 @@ static void agraph_set_layout(RAGraph *g, bool is_interactive) {
RGraphNode *n;
RANode *a;
set_layout(g);
set_layout (g);
update_graph_sizes (g);
graph_foreach_anode (r_graph_get_nodes (g->graph), it, n, a) {
@ -1884,9 +1861,9 @@ static void agraph_print_node(const RAGraph *g, RANode *n) {
const int cur = g->curnode && get_anode (g->curnode) == n;
if (is_mini (g)) {
small_RANode_print(g, n, cur);
small_RANode_print (g, n, cur);
} else {
normal_RANode_print(g, n, cur);
normal_RANode_print (g, n, cur);
}
}
@ -2024,13 +2001,13 @@ static void follow_nth(RAGraph *g, int nth) {
}
static void agraph_follow_true(RAGraph *g) {
follow_nth(g, 0);
agraph_update_seek(g, get_anode (g->curnode), false);
follow_nth (g, 0);
agraph_update_seek (g, get_anode (g->curnode), false);
}
static void agraph_follow_false(RAGraph *g) {
follow_nth(g, 1);
agraph_update_seek(g, get_anode (g->curnode), false);
follow_nth (g, 1);
agraph_update_seek (g, get_anode (g->curnode), false);
}
/* seek the next node in visual order */
@ -2046,8 +2023,7 @@ static void agraph_prev_node(RAGraph *g) {
}
static void agraph_update_title (RAGraph *g, RAnalFunction *fcn) {
const char *mode_str = g->is_callgraph ? mode2str(g, "CG") :
mode2str (g, "BB");
const char *mode_str = g->is_callgraph ? mode2str(g, "CG") : mode2str (g, "BB");
char *new_title = r_str_newf(
"[0x%08"PFMT64x"]> VV @ %s (nodes %d edges %d zoom %d%%) %s mouse:%s movements-speed:%d",
fcn->addr, fcn->name, g->graph->n_nodes, g->graph->n_edges,
@ -2271,8 +2247,8 @@ R_API RANode *r_agraph_add_node(const RAGraph *g, const char *title, const char
if (res) return res;
res = R_NEW0 (RANode);
if (!res) return NULL;
res->title = title ? strdup(title) : strdup("");
res->body = body ? strdup(body) : strdup("");
res->title = title ? strdup(title) : strdup ("");
res->body = body ? strdup(body) : strdup ("");
res->layer = -1;
res->pos_in_layer = -1;
res->is_dummy = false;
@ -2318,9 +2294,8 @@ R_API bool r_agraph_del_node(const RAGraph *g, const char *title) {
innodes = r_graph_innodes (g->graph, res->gnode);
graph_foreach_anode (innodes, it, gn, an) {
sdb_array_remove (g->db,
sdb_fmt (2, "agraph.nodes.%s.neighbours", an->title),
res->title, 0);
const char *key = sdb_fmt (2, "agraph.nodes.%s.neighbours", an->title);
sdb_array_remove (g->db, key, res->title, 0);
}
r_graph_del_node (g->graph, res->gnode);
@ -2330,8 +2305,7 @@ R_API bool r_agraph_del_node(const RAGraph *g, const char *title) {
return true;
}
static int user_node_cb(struct g_cb *user, const char *k UNUSED,
const char *v) {
static int user_node_cb(struct g_cb *user, const char *k UNUSED, const char *v) {
RANodeCallback cb = user->node_cb;
void *user_data = user->data;
RANode *n = (RANode *)(size_t)sdb_atoi (v);
@ -2339,8 +2313,7 @@ static int user_node_cb(struct g_cb *user, const char *k UNUSED,
return 1;
}
static int user_edge_cb(struct g_cb *user, const char *k UNUSED,
const char *v) {
static int user_edge_cb(struct g_cb *user, const char *k UNUSED, const char *v) {
RAEdgeCallback cb = user->edge_cb;
RAGraph *g = user->graph;
void *user_data = user->data;

View File

@ -4,12 +4,37 @@
#
grep -e DEPS */Makefile | sed -e 's,/Makefile,,' > /tmp/rdeps.txt
MODE=dot
#MODE=gml
if [ -z "$1" ]; then
MODE=dot
#MODE=gml
MODE=r2
else
MODE="$1"
fi
if [ $MODE = "dot" ]; then
if [ "$MODE" = "-h" ]; then
echo "digraph G {";
echo "Usage: depgraph [r2|dot|gml]"
exit 0
elif [ $MODE = "r2" ]; then
cat /tmp/rdeps.txt | perl -ne '
use List::MoreUtils qw(uniq);
/(.*):(.*)=(.*)$/;
my $lib=$1;
@deps=split(/ /, $3);
foreach $dep (uniq @deps) {
print "agn $dep\n";
}
foreach $dep (@deps) {
print "age $dep r_$lib\n";
}'
echo "agg"
elif [ $MODE = "dot" ]; then
echo "digraph G {"
cat /tmp/rdeps.txt | perl -ne '
/(.*):(.*)=(.*)$/;
my $lib=$1;