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: 29*1d35b605SNikolay Borisov if line.startswith("\n") or ":" in line: 30*1d35b605SNikolay Borisov continue 313af06fd9SAlexey Dobriyan size, type, name = line.split() 32192efb7aSManinder Singh if type in format: 33c50e3f51SJean Delvare # strip generated symbols 34c2e182faSJosh Triplett if name.startswith("__mod_"): continue 35e145242eSDominik Brodowski if name.startswith("__se_sys"): continue 365ac9efa3SDominik Brodowski if name.startswith("__se_compat_sys"): continue 37e0b2475aSRasmus Villemoes if name.startswith("__addressable_"): continue 385a7b2d27SJosh Triplett if name == "linux_banner": continue 3921cf6e58SAndi Kleen # statics and some other optimizations adds random .NUMBER 400d7bbb43SAlexey Dobriyan name = re_NUMBER.sub('', name) 4151849738SRob Landley sym[name] = sym.get(name, 0) + int(size, 16) 42d960600dSMatt Mackall return sym 43d960600dSMatt Mackall 44192efb7aSManinder Singhdef calc(oldfile, newfile, format): 45192efb7aSManinder Singh old = getsizes(oldfile, format) 46192efb7aSManinder Singh new = getsizes(newfile, format) 47d960600dSMatt Mackall grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 48d960600dSMatt Mackall delta, common = [], {} 49b21e91c3SVineet Gupta otot, ntot = 0, 0 50d960600dSMatt Mackall 51d960600dSMatt Mackall for a in old: 52d960600dSMatt Mackall if a in new: 53d960600dSMatt Mackall common[a] = 1 54d960600dSMatt Mackall 55d960600dSMatt Mackall for name in old: 56b21e91c3SVineet Gupta otot += old[name] 57d960600dSMatt Mackall if name not in common: 58d960600dSMatt Mackall remove += 1 59d960600dSMatt Mackall down += old[name] 60d960600dSMatt Mackall delta.append((-old[name], name)) 61d960600dSMatt Mackall 62d960600dSMatt Mackall for name in new: 63b21e91c3SVineet Gupta ntot += new[name] 64d960600dSMatt Mackall if name not in common: 65d960600dSMatt Mackall add += 1 66d960600dSMatt Mackall up += new[name] 67d960600dSMatt Mackall delta.append((new[name], name)) 68d960600dSMatt Mackall 69d960600dSMatt Mackall for name in common: 70d960600dSMatt Mackall d = new.get(name, 0) - old.get(name, 0) 71d960600dSMatt Mackall if d>0: grow, up = grow+1, up+d 72d960600dSMatt Mackall if d<0: shrink, down = shrink+1, down-d 73d960600dSMatt Mackall delta.append((d, name)) 74d960600dSMatt Mackall 75d960600dSMatt Mackall delta.sort() 76d960600dSMatt Mackall delta.reverse() 77192efb7aSManinder Singh return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot 78192efb7aSManinder Singh 79192efb7aSManinder Singhdef print_result(symboltype, symbolformat, argc): 80192efb7aSManinder Singh grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ 81192efb7aSManinder Singh calc(sys.argv[argc - 1], sys.argv[argc], symbolformat) 82d960600dSMatt Mackall 8372214a24SSergey Senozhatsky print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ 8472214a24SSergey Senozhatsky (add, remove, grow, shrink, up, -down, up-down)) 85192efb7aSManinder Singh print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta")) 86d960600dSMatt Mackall for d, n in delta: 8772214a24SSergey Senozhatsky if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) 88b21e91c3SVineet Gupta 89edbddb83SAndy Shevchenko if otot: 90edbddb83SAndy Shevchenko percent = (ntot - otot) * 100.0 / otot 91edbddb83SAndy Shevchenko else: 92edbddb83SAndy Shevchenko percent = 0 93edbddb83SAndy Shevchenko print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) 94192efb7aSManinder Singh 95192efb7aSManinder Singhif sys.argv[1] == "-c": 96192efb7aSManinder Singh print_result("Function", "tT", 3) 97192efb7aSManinder Singh print_result("Data", "dDbB", 3) 98192efb7aSManinder Singh print_result("RO Data", "rR", 3) 99192efb7aSManinder Singhelif sys.argv[1] == "-d": 100192efb7aSManinder Singh print_result("Data", "dDbBrR", 3) 101192efb7aSManinder Singhelif sys.argv[1] == "-t": 102192efb7aSManinder Singh print_result("Function", "tT", 3) 103192efb7aSManinder Singhelse: 104192efb7aSManinder Singh print_result("Function", "tTdDbBrR", 2) 105