151839e29SAndy Shevchenko#!/usr/bin/env python3 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: 291d35b605SNikolay Borisov if line.startswith("\n") or ":" in line: 301d35b605SNikolay 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 39*dec81a53SPaul Gortmaker if name == "vermagic": continue 4021cf6e58SAndi Kleen # statics and some other optimizations adds random .NUMBER 410d7bbb43SAlexey Dobriyan name = re_NUMBER.sub('', name) 4251849738SRob Landley sym[name] = sym.get(name, 0) + int(size, 16) 43d960600dSMatt Mackall return sym 44d960600dSMatt Mackall 45192efb7aSManinder Singhdef calc(oldfile, newfile, format): 46192efb7aSManinder Singh old = getsizes(oldfile, format) 47192efb7aSManinder Singh new = getsizes(newfile, format) 48d960600dSMatt Mackall grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 49d960600dSMatt Mackall delta, common = [], {} 50b21e91c3SVineet Gupta otot, ntot = 0, 0 51d960600dSMatt Mackall 52d960600dSMatt Mackall for a in old: 53d960600dSMatt Mackall if a in new: 54d960600dSMatt Mackall common[a] = 1 55d960600dSMatt Mackall 56d960600dSMatt Mackall for name in old: 57b21e91c3SVineet Gupta otot += old[name] 58d960600dSMatt Mackall if name not in common: 59d960600dSMatt Mackall remove += 1 60d960600dSMatt Mackall down += old[name] 61d960600dSMatt Mackall delta.append((-old[name], name)) 62d960600dSMatt Mackall 63d960600dSMatt Mackall for name in new: 64b21e91c3SVineet Gupta ntot += new[name] 65d960600dSMatt Mackall if name not in common: 66d960600dSMatt Mackall add += 1 67d960600dSMatt Mackall up += new[name] 68d960600dSMatt Mackall delta.append((new[name], name)) 69d960600dSMatt Mackall 70d960600dSMatt Mackall for name in common: 71d960600dSMatt Mackall d = new.get(name, 0) - old.get(name, 0) 72d960600dSMatt Mackall if d>0: grow, up = grow+1, up+d 73d960600dSMatt Mackall if d<0: shrink, down = shrink+1, down-d 74d960600dSMatt Mackall delta.append((d, name)) 75d960600dSMatt Mackall 76d960600dSMatt Mackall delta.sort() 77d960600dSMatt Mackall delta.reverse() 78192efb7aSManinder Singh return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot 79192efb7aSManinder Singh 80192efb7aSManinder Singhdef print_result(symboltype, symbolformat, argc): 81192efb7aSManinder Singh grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ 82192efb7aSManinder Singh calc(sys.argv[argc - 1], sys.argv[argc], symbolformat) 83d960600dSMatt Mackall 8472214a24SSergey Senozhatsky print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ 8572214a24SSergey Senozhatsky (add, remove, grow, shrink, up, -down, up-down)) 86192efb7aSManinder Singh print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta")) 87d960600dSMatt Mackall for d, n in delta: 8872214a24SSergey Senozhatsky if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) 89b21e91c3SVineet Gupta 90edbddb83SAndy Shevchenko if otot: 91edbddb83SAndy Shevchenko percent = (ntot - otot) * 100.0 / otot 92edbddb83SAndy Shevchenko else: 93edbddb83SAndy Shevchenko percent = 0 94edbddb83SAndy Shevchenko print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) 95192efb7aSManinder Singh 96192efb7aSManinder Singhif sys.argv[1] == "-c": 97192efb7aSManinder Singh print_result("Function", "tT", 3) 98192efb7aSManinder Singh print_result("Data", "dDbB", 3) 99192efb7aSManinder Singh print_result("RO Data", "rR", 3) 100192efb7aSManinder Singhelif sys.argv[1] == "-d": 101192efb7aSManinder Singh print_result("Data", "dDbBrR", 3) 102192efb7aSManinder Singhelif sys.argv[1] == "-t": 103192efb7aSManinder Singh print_result("Function", "tT", 3) 104192efb7aSManinder Singhelse: 105192efb7aSManinder Singh print_result("Function", "tTdDbBrR", 2) 106