-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_graph.py
executable file
·84 lines (63 loc) · 2.42 KB
/
generate_graph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from collections import defaultdict
import json
import networkx as nx
import os
import sys
VISUALIZE_PASSING = False
VISUALIZE_FAILING = True
def draw_passing(graph, data):
for node in data['passing']:
function = node['function']
from_node = function['def_id']
if node['allowlisted']:
graph.add_node(from_node, label=from_node + " -A",
fillcolor="orchid", style="filled")
elif len(node['important_locals']) == 0:
graph.add_node(from_node, label=from_node + " -I",
fillcolor="khaki", style="filled")
else:
graph.add_node(from_node, label=from_node,
fillcolor="lightgreen", style="filled")
for call in function.get('calls', []):
if not graph.has_edge(call['def_id'], from_node):
graph.add_edge(from_node, call['def_id'])
def draw_failing(graph, data):
for node in data['failing']:
function = node['function']
from_node = function['def_id']
label = from_node
fillcolor = "tomato"
if node['raw_pointer_deref']:
label += " -R"
fillcolor = "orange"
if node['has_transmute']:
label += " -T"
fillcolor = "orange"
if not function['has_body']:
label += " -B"
fillcolor = "orange"
graph.add_node(from_node, label=label,
fillcolor=fillcolor, style="filled")
for call in function.get('calls', []):
if not graph.has_edge(call['def_id'], from_node):
graph.add_edge(from_node, call['def_id'])
with open(sys.argv[1]) as file:
input = json.loads(file.read())
for graph in input['results']:
G = nx.DiGraph()
if VISUALIZE_PASSING:
draw_passing(G, graph)
if VISUALIZE_FAILING:
draw_failing(G, graph)
B = nx.dag_to_branching(G)
sources = defaultdict(set)
for v, source in B.nodes(data="source"):
sources[source].add(v)
for source, nodes in sources.items():
for v in nodes:
B.nodes[v].update(G.nodes[source])
A = nx.nx_agraph.to_agraph(B)
if not os.path.exists("callgraphs"):
os.mkdir("callgraphs")
A.draw(f"callgraphs/{graph['def_id']
}.callgraph.svg", format="svg", prog="dot")