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 10b62eb273SNikolay Borisovimport sys, os, re, argparse 11eef06b82SAlexey Dobriyanfrom signal import signal, SIGPIPE, SIG_DFL 12eef06b82SAlexey Dobriyan 13eef06b82SAlexey Dobriyansignal(SIGPIPE, SIG_DFL) 14d960600dSMatt Mackall 15b62eb273SNikolay Borisovparser = argparse.ArgumentParser(description="Simple script used to compare the symbol sizes of 2 object files") 16b62eb273SNikolay Borisovgroup = parser.add_mutually_exclusive_group() 17b62eb273SNikolay Borisovgroup.add_argument('-c', help='categorize output based on symbol type', action='store_true') 18b62eb273SNikolay Borisovgroup.add_argument('-d', help='Show delta of Data Section', action='store_true') 19b62eb273SNikolay Borisovgroup.add_argument('-t', help='Show delta of text Section', action='store_true') 20*8b5db667SNikolay Borisovparser.add_argument('-p', dest='prefix', help='Arch prefix for the tool being used. Useful in cross build scenarios') 21b62eb273SNikolay Borisovparser.add_argument('file1', help='First file to compare') 22b62eb273SNikolay Borisovparser.add_argument('file2', help='Second file to compare') 23b62eb273SNikolay Borisov 24b62eb273SNikolay Borisovargs = parser.parse_args() 25d960600dSMatt Mackall 260d7bbb43SAlexey Dobriyanre_NUMBER = re.compile(r'\.[0-9]+') 270d7bbb43SAlexey Dobriyan 28192efb7aSManinder Singhdef getsizes(file, format): 29d960600dSMatt Mackall sym = {} 30*8b5db667SNikolay Borisov nm = "nm" 31*8b5db667SNikolay Borisov if args.prefix: 32*8b5db667SNikolay Borisov nm = "{}nm".format(args.prefix) 33*8b5db667SNikolay Borisov 34*8b5db667SNikolay Borisov with os.popen("{} --size-sort {}".format(nm, file)) as f: 353af06fd9SAlexey Dobriyan for line in f: 361d35b605SNikolay Borisov if line.startswith("\n") or ":" in line: 371d35b605SNikolay Borisov continue 383af06fd9SAlexey Dobriyan size, type, name = line.split() 39192efb7aSManinder Singh if type in format: 40c50e3f51SJean Delvare # strip generated symbols 41c2e182faSJosh Triplett if name.startswith("__mod_"): continue 42e145242eSDominik Brodowski if name.startswith("__se_sys"): continue 435ac9efa3SDominik Brodowski if name.startswith("__se_compat_sys"): continue 44e0b2475aSRasmus Villemoes if name.startswith("__addressable_"): continue 455a7b2d27SJosh Triplett if name == "linux_banner": continue 46dec81a53SPaul Gortmaker if name == "vermagic": continue 4721cf6e58SAndi Kleen # statics and some other optimizations adds random .NUMBER 480d7bbb43SAlexey Dobriyan name = re_NUMBER.sub('', name) 4951849738SRob Landley sym[name] = sym.get(name, 0) + int(size, 16) 50d960600dSMatt Mackall return sym 51d960600dSMatt Mackall 52192efb7aSManinder Singhdef calc(oldfile, newfile, format): 53192efb7aSManinder Singh old = getsizes(oldfile, format) 54192efb7aSManinder Singh new = getsizes(newfile, format) 55d960600dSMatt Mackall grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 56d960600dSMatt Mackall delta, common = [], {} 57b21e91c3SVineet Gupta otot, ntot = 0, 0 58d960600dSMatt Mackall 59d960600dSMatt Mackall for a in old: 60d960600dSMatt Mackall if a in new: 61d960600dSMatt Mackall common[a] = 1 62d960600dSMatt Mackall 63d960600dSMatt Mackall for name in old: 64b21e91c3SVineet Gupta otot += old[name] 65d960600dSMatt Mackall if name not in common: 66d960600dSMatt Mackall remove += 1 67d960600dSMatt Mackall down += old[name] 68d960600dSMatt Mackall delta.append((-old[name], name)) 69d960600dSMatt Mackall 70d960600dSMatt Mackall for name in new: 71b21e91c3SVineet Gupta ntot += new[name] 72d960600dSMatt Mackall if name not in common: 73d960600dSMatt Mackall add += 1 74d960600dSMatt Mackall up += new[name] 75d960600dSMatt Mackall delta.append((new[name], name)) 76d960600dSMatt Mackall 77d960600dSMatt Mackall for name in common: 78d960600dSMatt Mackall d = new.get(name, 0) - old.get(name, 0) 79d960600dSMatt Mackall if d>0: grow, up = grow+1, up+d 80d960600dSMatt Mackall if d<0: shrink, down = shrink+1, down-d 81d960600dSMatt Mackall delta.append((d, name)) 82d960600dSMatt Mackall 83d960600dSMatt Mackall delta.sort() 84d960600dSMatt Mackall delta.reverse() 85192efb7aSManinder Singh return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot 86192efb7aSManinder Singh 87b62eb273SNikolay Borisovdef print_result(symboltype, symbolformat): 88192efb7aSManinder Singh grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \ 89b62eb273SNikolay Borisov calc(args.file1, args.file2, symbolformat) 90d960600dSMatt Mackall 9172214a24SSergey Senozhatsky print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \ 9272214a24SSergey Senozhatsky (add, remove, grow, shrink, up, -down, up-down)) 93192efb7aSManinder Singh print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta")) 94d960600dSMatt Mackall for d, n in delta: 9572214a24SSergey Senozhatsky if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)) 96b21e91c3SVineet Gupta 97edbddb83SAndy Shevchenko if otot: 98edbddb83SAndy Shevchenko percent = (ntot - otot) * 100.0 / otot 99edbddb83SAndy Shevchenko else: 100edbddb83SAndy Shevchenko percent = 0 101edbddb83SAndy Shevchenko print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent)) 102192efb7aSManinder Singh 103b62eb273SNikolay Borisovif args.c: 104b62eb273SNikolay Borisov print_result("Function", "tT") 105b62eb273SNikolay Borisov print_result("Data", "dDbB") 106b62eb273SNikolay Borisov print_result("RO Data", "rR") 107b62eb273SNikolay Borisovelif args.d: 108b62eb273SNikolay Borisov print_result("Data", "dDbBrR") 109b62eb273SNikolay Borisovelif args.t: 110b62eb273SNikolay Borisov print_result("Function", "tT") 111192efb7aSManinder Singhelse: 112b62eb273SNikolay Borisov print_result("Function", "tTdDbBrR") 113