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 345ac9efa3SDominik Brodowski if name.startswith("__se_compat_sys"): continue 35*e0b2475aSRasmus Villemoes if name.startswith("__addressable_"): continue 365a7b2d27SJosh Triplett if name == "linux_banner": continue 3721cf6e58SAndi Kleen # statics and some other optimizations adds random .NUMBER 380d7bbb43SAlexey Dobriyan name = re_NUMBER.sub('', name) 3951849738SRob Landley sym[name] = sym.get(name, 0) + int(size, 16) 40d960600dSMatt Mackall return sym 41d960600dSMatt Mackall 42192efb7aSManinder Singhdef calc(oldfile, newfile, format): 43192efb7aSManinder Singh old = getsizes(oldfile, format) 44192efb7aSManinder Singh new = getsizes(newfile, format) 45d960600dSMatt Mackall grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 46d960600dSMatt Mackall delta, common = [], {} 47b21e91c3SVineet Gupta otot, ntot = 0, 0 48d960600dSMatt Mackall 49d960600dSMatt Mackall for a in old: 50d960600dSMatt Mackall if a in new: 51d960600dSMatt Mackall common[a] = 1 52d960600dSMatt Mackall 53d960600dSMatt Mackall for name in old: 54b21e91c3SVineet Gupta otot += old[name] 55d960600dSMatt Mackall if name not in common: 56d960600dSMatt Mackall remove += 1 57d960600dSMatt Mackall down += old[name] 58d960600dSMatt Mackall delta.append((-old[name], name)) 59d960600dSMatt Mackall 60d960600dSMatt Mackall for name in new: 61b21e91c3SVineet Gupta ntot += new[name] 62d960600dSMatt Mackall if name not in common: 63d960600dSMatt Mackall add += 1 64d960600dSMatt Mackall up += new[name] 65d960600dSMatt Mackall delta.append((new[name], name)) 66d960600dSMatt Mackall 67d960600dSMatt Mackall for name in common: 68d960600dSMatt Mackall d = new.get(name, 0) - old.get(name, 0) 69d960600dSMatt Mackall if d>0: grow, up = grow+1, up+d 70d960600dSMatt Mackall if d<0: shrink, down = shrink+1, down-d 71d960600dSMatt Mackall delta.append((d, name)) 72d960600dSMatt Mackall 73d960600dSMatt Mackall delta.sort() 74d960600dSMatt Mackall delta.reverse() 75192efb7aSManinder Singh return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot 76192efb7aSManinder Singh 77192efb7aSManinder Singhdef print_result(symboltype, symbolformat, argc): 78192efb7aSManinder Singh grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ 79192efb7aSManinder Singh calc(sys.argv[argc - 1], sys.argv[argc], symbolformat) 80d960600dSMatt Mackall 8172214a24SSergey Senozhatsky print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ 8272214a24SSergey Senozhatsky (add, remove, grow, shrink, up, -down, up-down)) 83192efb7aSManinder Singh print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta")) 84d960600dSMatt Mackall for d, n in delta: 8572214a24SSergey Senozhatsky if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) 86b21e91c3SVineet Gupta 87edbddb83SAndy Shevchenko if otot: 88edbddb83SAndy Shevchenko percent = (ntot - otot) * 100.0 / otot 89edbddb83SAndy Shevchenko else: 90edbddb83SAndy Shevchenko percent = 0 91edbddb83SAndy Shevchenko print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) 92192efb7aSManinder Singh 93192efb7aSManinder Singhif sys.argv[1] == "-c": 94192efb7aSManinder Singh print_result("Function", "tT", 3) 95192efb7aSManinder Singh print_result("Data", "dDbB", 3) 96192efb7aSManinder Singh print_result("RO Data", "rR", 3) 97192efb7aSManinder Singhelif sys.argv[1] == "-d": 98192efb7aSManinder Singh print_result("Data", "dDbBrR", 3) 99192efb7aSManinder Singhelif sys.argv[1] == "-t": 100192efb7aSManinder Singh print_result("Function", "tT", 3) 101192efb7aSManinder Singhelse: 102192efb7aSManinder Singh print_result("Function", "tTdDbBrR", 2) 103