#!/usr/bin/env python3
#
# Copyright 2004 Matt Mackall <mpm@selenic.com>
#
# inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

import sys, os, re, argparse
from signal import signal, SIGPIPE, SIG_DFL

signal(SIGPIPE, SIG_DFL)

parser = argparse.ArgumentParser(description="Simple script used to compare the symbol sizes of 2 object files")
group = parser.add_mutually_exclusive_group()
group.add_argument('-c', help='categorize output based on symbol type', action='store_true')
group.add_argument('-d', help='Show delta of Data Section', action='store_true')
group.add_argument('-t', help='Show delta of text Section', action='store_true')
parser.add_argument('-p', dest='prefix', help='Arch prefix for the tool being used. Useful in cross build scenarios')
parser.add_argument('file1', help='First file to compare')
parser.add_argument('file2', help='Second file to compare')

args = parser.parse_args()

re_NUMBER = re.compile(r'\.[0-9]+')

def getsizes(file, format):
    sym = {}
    nm = "nm"
    if args.prefix:
        nm = "{}nm".format(args.prefix)

    with os.popen("{} --size-sort {}".format(nm, file)) as f:
        for line in f:
            if line.startswith("\n") or ":" in line:
                continue
            size, type, name = line.split()
            if type in format:
                # strip generated symbols
                if name.startswith("__mod_"): continue
                if name.startswith("__se_sys"): continue
                if name.startswith("__se_compat_sys"): continue
                if name.startswith("__addressable_"): continue
                if name == "linux_banner": continue
                if name == "vermagic": continue
                # statics and some other optimizations adds random .NUMBER
                name = re_NUMBER.sub('', name)
                sym[name] = sym.get(name, 0) + int(size, 16)
    return sym

def calc(oldfile, newfile, format):
    old = getsizes(oldfile, format)
    new = getsizes(newfile, format)
    grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
    delta, common = [], {}
    otot, ntot = 0, 0

    for a in old:
        if a in new:
            common[a] = 1

    for name in old:
        otot += old[name]
        if name not in common:
            remove += 1
            down += old[name]
            delta.append((-old[name], name))

    for name in new:
        ntot += new[name]
        if name not in common:
            add += 1
            up += new[name]
            delta.append((new[name], name))

    for name in common:
        d = new.get(name, 0) - old.get(name, 0)
        if d>0: grow, up = grow+1, up+d
        if d<0: shrink, down = shrink+1, down-d
        delta.append((d, name))

    delta.sort()
    delta.reverse()
    return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot

def print_result(symboltype, symbolformat):
    grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \
    calc(args.file1, args.file2, symbolformat)

    print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
          (add, remove, grow, shrink, up, -down, up-down))
    print("%-40s %7s %7s %+7s" % (symboltype, "old", "new", "delta"))
    for d, n in delta:
        if d: print("%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d))

    if otot:
        percent = (ntot - otot) * 100.0 / otot
    else:
        percent = 0
    print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent))

if args.c:
    print_result("Function", "tT")
    print_result("Data", "dDbB")
    print_result("RO Data", "rR")
elif args.d:
    print_result("Data", "dDbBrR")
elif args.t:
    print_result("Function", "tT")
else:
    print_result("Function", "tTdDbBrR")
