This repository has been archived by the owner on Oct 14, 2024. It is now read-only.
forked from cooperative-computing-lab/cctools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
make_call_graph
executable file
·64 lines (51 loc) · 1.92 KB
/
make_call_graph
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
#!/usr/bin/python
#
# This program scans a set of object (.o) files and produces
# a call graph showing the relationships between each modules.
# The command line arguments are just the files to scan,
# and the output is the graph, in the DOT graphviz language.
#
# Example use:
# ./make_call_graph.py makeflow/src/*.o | dot -T pdf > makeflow.pdf
#
import subprocess
import sys
import os
import collections
# fileof[symbol] -> filename
fileof = {}
# uses[filename][symbol] -> True if filename uses but does not define symbol
uses = collections.defaultdict(lambda: collections.defaultdict(lambda: False))
# links[source][target] -> True if module source calls module target
links = collections.defaultdict(lambda: collections.defaultdict(lambda: False))
print "digraph \"G\" {"
print "node [shape=box]"
# Pass 1: Run nm on each of the input files.
# Scrape out the T records, which indicate a symbol definition.
# Scrape out the U records, which indicate a symbol reference.
for file in sys.argv[1:]:
filename = os.path.basename(file)
p = subprocess.Popen(["/usr/bin/nm","-f","posix",file],stdout=subprocess.PIPE)
for line in iter(p.stdout.readline,''):
words = line.split(" ")
symbol = words[0]
symtype = words[1]
if symtype=='T':
fileof[symbol] = filename
elif symtype=='U':
uses[filename][symbol] = True
# Pass 2: Match up each undefined reference with its definition,
# and mark it in the links[source][target] dictionary. (Could be
# more than one instance of a link.)
for file in uses.keys():
for symbol in uses[file].keys():
if symbol in fileof:
source = file
target = fileof[symbol]
if not links[source][target]:
links[source][target] = True
# Pass 3: Print out each of the module-module links.
for source in links.keys():
for target in links[source].keys():
print "\"%s\" -> \"%s\"" % (source,target)
print "}"