1# * Copyright 2016, NICTA
2# *
3# * This software may be distributed and modified according to the terms
4# of
5# * the BSD 2-Clause license. Note that NO WARRANTY is provided.
6# * See "LICENSE_BSD2.txt" for details.
7# *
8# * @TAG(NICTA_BSD)
9
10import pydot
11from elf_file import *
12
13'''
14All functions in this file will be updated to reflect changes made, they are currently outdated and produce misleading outputs if called.
15This file was used for debugging the toolchains.
16'''
17
18def loopDot(head,p):
19    from elf_correlate import immFunc
20    graph = pydot.Dot(graph_type='digraph')
21    nodes = {}
22    ns = list(p.loop_data[head][1])
23    print 'len: %d' % len(ns)
24    for n in ns:
25      phy_n = immFunc().phyAddrP(n,p)
26      if isinstance(phy_n,int) and phy_n %4 == 0:
27        text, _ = rawVals(phy_n)
28      else:
29        text = ''
30      n_cap = '%s / %d \n %s' % (hex(phy_n),n, text)
31      if [x for x in p.nodes[n].get_conts() if x not in ns and not x == 'Err']:
32        print 'found exit node ! %d' % n
33        nodes[n] = pydot.Node(n_cap,color="blue")
34      else:
35        nodes[n] = pydot.Node(n_cap)
36    for n in nodes:
37      graph.add_node(nodes[n])
38
39    for n in ns:
40        conts = p.nodes[n].get_conts()
41        for c in conts:
42          if c in ns:
43            graph.add_edge(pydot.Edge(nodes[n],nodes[c]))
44
45    graph.write_svg('graphs/loop.svg' )
46    graph.write('graphs/loop.dot' )
47    return
48
49
50def toDot(imm_fun):
51    #FIXME: add in return tracing
52    graph = pydot.Dot(graph_type='digraph')
53    nodes = {}
54    #add all nodes
55    for n in imm_fun.imm_nodes:
56      text, _ = rawVals(n)
57      nodes[n] = pydot.Node('addr_%s \n %s' % (hex(n), text))
58      assert rawVals(n)
59
60    #artificially insert the return node
61    nodes['Ret'] = pydot.Node('Ret')
62
63    #print 'nodes added to graph'
64    for n in imm_fun.imm_nodes:
65      imm_node = imm_fun.imm_nodes[n]
66      for e in imm_node.edges:
67          #print'%s -> %s' % (n,e.targ)
68          graph.add_edge(pydot.Edge(nodes[n],nodes[e.targ]))
69    #print 'edges added'
70    graph.write_svg('graphs/ii_%s.svg' % imm_fun.g_f.name)
71    #graph.write_png('/mnt/hgfs/imgs/ii_%s.png' % imm_fun.g_f.name)
72    #print 'imm graph for %s generated' % self.g_f.name
73
74def toDotBB(imm_fun):
75    #FIXME as above
76    graph = pydot.Dot(graph_type='digraph')
77    nodes = {}
78    #add all bbs
79    print 'generating dot graph...'
80    for bb_n in imm_fun.bbs:
81      bb = imm_fun.bbs[bb_n]
82      #print 'BB[%s]: %s' % (bb_n, bb)
83      if len(bb) == 1:
84        n_cap = '0x%x\n' % bb[0]
85      else:
86        n_cap = '0x%x - 0x%x\n' % (min(bb), max(bb))
87      is_loophead = False
88      for n in bb:
89        i_node = imm_fun.imm_nodes[n]
90        if n in imm_fun.imm_loopheads:
91          is_loophead = True
92        #only the entry can have >1 incoming edges
93        assert n == bb[0] or i_node.n_edges_to <= 1
94        #only the last node can have >1 outgoing edges
95        if not (n == bb[-1] or i_node.nEdgesOut() == 1):
96          print 'edges %s' % i_node
97          print 'nEdgesOut %s' % i_node.nEdgesOut()
98        assert (n == bb[-1] or i_node.nEdgesOut() == 1)
99        assert rawVals(n)
100        text,_ = rawVals(n)
101        n_cap += '%s; %s\n' % (hex(n),text)
102
103      if len(bb) > 2:
104        is_jt = False
105        #is_jt = imm_fun.isJumpTable(imm_fun.gToPAddr(bb[-2],no_match_expected = True, may_multi= True))
106      else:
107        is_jt = False
108      if is_loophead:
109        nodes[bb[0]] = pydot.Node(n_cap,Nodestyle="bold",color="hotpink")
110      elif is_jt:
111        nodes[bb[0]] = pydot.Node(n_cap,Nodestyle="bold",color="blue")
112      else:
113        nodes[bb[0]] = pydot.Node(n_cap)
114
115    #artificially insert the return node
116    nodes['Ret'] = pydot.Node('Ret')
117    for n in nodes:
118      graph.add_node(nodes[n])
119
120    #print 'nodes added to graph'
121    for bb in imm_fun.bbs:
122      BB = imm_fun.bbs[bb]
123      #for n in BB:
124      n = BB[len(BB)-1]
125      for e in imm_fun.imm_nodes[n].edges:
126        #print'%s -> %s' % (n,e.targ)
127        graph.add_edge(pydot.Edge(nodes[BB[0]],nodes[e.targ]))
128    #print 'edges added'
129    graph.write_svg('graphs/i_%s.svg' % imm_fun.g_f.name)
130    #graph.write_png('/mnt/hgfs/imgs/i_%s.png' % imm_fun.g_f.name)
131    print 'imm graph for %s generated' % imm_fun.g_f.name
132
133def toGraph(p,f_name):
134    p.save_graph('graphs/%s.dot' % f_name)
135    p = subprocess.Popen(["dot","graphs/%s.dot"%f_name,"-Tsvg","-o","graphs/%s.svg" % f_name])
136    p.communicate()
137    ret = p.returncode
138    assert not ret
139    p = subprocess.Popen(["rm","graphs/%s.dot" % f_name])
140    p.communicate()
141    ret = p.returncode
142    assert not ret
143    #p = subprocess.Popen(["dot","graphs/%s.dot"%f_name,"-Tpng","-o","/mnt/hgfs/imgs/%s.png" % f_name])
144