[go: up one dir, main page]

File: make_call_graph

package info (click to toggle)
cctools 9.9-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 44,624 kB
  • sloc: ansic: 192,539; python: 20,827; cpp: 20,199; sh: 11,719; perl: 4,106; xml: 3,688; makefile: 1,224
file content (64 lines) | stat: -rwxr-xr-x 1,964 bytes parent folder | download | duplicates (2)
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
#!/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 "}"