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") 1861fc4708SMatteo Croce sys.stderr.write("-c categorize output based on symbol 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 33e145242eSDominik Brodowski if name.startswith("__se_sys"): continue 34*5ac9efa3SDominik Brodowski if name.startswith("__se_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 86edbddb83SAndy Shevchenko if otot: 87edbddb83SAndy Shevchenko percent = (ntot - otot) * 100.0 / otot 88edbddb83SAndy Shevchenko else: 89edbddb83SAndy Shevchenko percent = 0 90edbddb83SAndy 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