xref: /openbmc/linux/scripts/bloat-o-meter (revision edbddb83a15b4361d8c3bf00aabee85fd3ef4d80)
1d960600dSMatt Mackall#!/usr/bin/python
2d960600dSMatt Mackall#
3d960600dSMatt Mackall# Copyright 2004 Matt Mackall <mpm@selenic.com>
4d960600dSMatt Mackall#
5d960600dSMatt Mackall# inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
6d960600dSMatt Mackall#
7d960600dSMatt Mackall# This software may be used and distributed according to the terms
8d960600dSMatt Mackall# of the GNU General Public License, incorporated herein by reference.
9d960600dSMatt Mackall
10d960600dSMatt Mackallimport sys, os, re
11eef06b82SAlexey Dobriyanfrom signal import signal, SIGPIPE, SIG_DFL
12eef06b82SAlexey Dobriyan
13eef06b82SAlexey Dobriyansignal(SIGPIPE, SIG_DFL)
14d960600dSMatt Mackall
15192efb7aSManinder Singhif len(sys.argv) < 3:
16192efb7aSManinder Singh    sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0])
17192efb7aSManinder Singh    sys.stderr.write("The options are:\n")
18192efb7aSManinder Singh    sys.stderr.write("-c	cateogrize output based on symbole type\n")
19192efb7aSManinder Singh    sys.stderr.write("-d	Show delta of Data Section\n")
20192efb7aSManinder Singh    sys.stderr.write("-t	Show delta of text Section\n")
21d960600dSMatt Mackall    sys.exit(-1)
22d960600dSMatt Mackall
230d7bbb43SAlexey Dobriyanre_NUMBER = re.compile(r'\.[0-9]+')
240d7bbb43SAlexey Dobriyan
25192efb7aSManinder Singhdef getsizes(file, format):
26d960600dSMatt Mackall    sym = {}
273af06fd9SAlexey Dobriyan    with os.popen("nm --size-sort " + file) as f:
283af06fd9SAlexey Dobriyan        for line in f:
293af06fd9SAlexey Dobriyan            size, type, name = line.split()
30192efb7aSManinder Singh            if type in format:
31c50e3f51SJean Delvare                # strip generated symbols
32c2e182faSJosh Triplett                if name.startswith("__mod_"): continue
33b25c2ff5SJosh Triplett                if name.startswith("SyS_"): continue
34b25c2ff5SJosh Triplett                if name.startswith("compat_SyS_"): continue
355a7b2d27SJosh Triplett                if name == "linux_banner": continue
3621cf6e58SAndi Kleen                # statics and some other optimizations adds random .NUMBER
370d7bbb43SAlexey Dobriyan                name = re_NUMBER.sub('', name)
3851849738SRob Landley                sym[name] = sym.get(name, 0) + int(size, 16)
39d960600dSMatt Mackall    return sym
40d960600dSMatt Mackall
41192efb7aSManinder Singhdef calc(oldfile, newfile, format):
42192efb7aSManinder Singh    old = getsizes(oldfile, format)
43192efb7aSManinder Singh    new = getsizes(newfile, format)
44d960600dSMatt Mackall    grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
45d960600dSMatt Mackall    delta, common = [], {}
46b21e91c3SVineet Gupta    otot, ntot = 0, 0
47d960600dSMatt Mackall
48d960600dSMatt Mackall    for a in old:
49d960600dSMatt Mackall        if a in new:
50d960600dSMatt Mackall            common[a] = 1
51d960600dSMatt Mackall
52d960600dSMatt Mackall    for name in old:
53b21e91c3SVineet Gupta        otot += old[name]
54d960600dSMatt Mackall        if name not in common:
55d960600dSMatt Mackall            remove += 1
56d960600dSMatt Mackall            down += old[name]
57d960600dSMatt Mackall            delta.append((-old[name], name))
58d960600dSMatt Mackall
59d960600dSMatt Mackall    for name in new:
60b21e91c3SVineet Gupta        ntot += new[name]
61d960600dSMatt Mackall        if name not in common:
62d960600dSMatt Mackall            add += 1
63d960600dSMatt Mackall            up += new[name]
64d960600dSMatt Mackall            delta.append((new[name], name))
65d960600dSMatt Mackall
66d960600dSMatt Mackall    for name in common:
67d960600dSMatt Mackall        d = new.get(name, 0) - old.get(name, 0)
68d960600dSMatt Mackall        if d>0: grow, up = grow+1, up+d
69d960600dSMatt Mackall        if d<0: shrink, down = shrink+1, down-d
70d960600dSMatt Mackall        delta.append((d, name))
71d960600dSMatt Mackall
72d960600dSMatt Mackall    delta.sort()
73d960600dSMatt Mackall    delta.reverse()
74192efb7aSManinder Singh    return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
75192efb7aSManinder Singh
76192efb7aSManinder Singhdef print_result(symboltype, symbolformat, argc):
77192efb7aSManinder Singh    grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \
78192efb7aSManinder Singh    calc(sys.argv[argc - 1], sys.argv[argc], symbolformat)
79d960600dSMatt Mackall
8072214a24SSergey Senozhatsky    print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
8172214a24SSergey Senozhatsky          (add, remove, grow, shrink, up, -down, up-down))
82192efb7aSManinder Singh    print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta"))
83d960600dSMatt Mackall    for d, n in delta:
8472214a24SSergey Senozhatsky        if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d))
85b21e91c3SVineet Gupta
86*edbddb83SAndy Shevchenko    if otot:
87*edbddb83SAndy Shevchenko        percent = (ntot - otot) * 100.0 / otot
88*edbddb83SAndy Shevchenko    else:
89*edbddb83SAndy Shevchenko        percent = 0
90*edbddb83SAndy Shevchenko    print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent))
91192efb7aSManinder Singh
92192efb7aSManinder Singhif sys.argv[1] == "-c":
93192efb7aSManinder Singh    print_result("Function", "tT", 3)
94192efb7aSManinder Singh    print_result("Data", "dDbB", 3)
95192efb7aSManinder Singh    print_result("RO Data", "rR", 3)
96192efb7aSManinder Singhelif sys.argv[1] == "-d":
97192efb7aSManinder Singh    print_result("Data", "dDbBrR", 3)
98192efb7aSManinder Singhelif sys.argv[1] == "-t":
99192efb7aSManinder Singh    print_result("Function", "tT", 3)
100192efb7aSManinder Singhelse:
101192efb7aSManinder Singh    print_result("Function", "tTdDbBrR", 2)
102