#!/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(reverse=True)
    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")
