#!/usr/bin/env python
#
# 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

def usage():
    sys.stderr.write("usage: %s [-t] file1 file2 [-- <readelf options>]\n"
                        % sys.argv[0])
    sys.stderr.write("\t-t\tShow time spent on parsing/processing\n")
    sys.stderr.write("\t--\tPass additional parameters to readelf\n")
    sys.exit(1)

f1, f2 = (None, None)
flag_timing, dashes = (False, False)

for f in sys.argv[1:]:
    if f.startswith("-"):
        if f == "--": # sym_args
            dashes = True
            break
        if f == "-t": # timings
            flag_timing = True
    else:
        if not os.path.exists(f):
            sys.stderr.write("Error: file '%s' does not exist\n" % f)
            usage()
        if f1 is None:
            f1 = f
        elif f2 is None:
            f2 = f
        else:
            usage()
if flag_timing:
    import time
if f1 is None or f2 is None:
    usage()

sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
def getsizes(file):
    sym, alias, lut, section = {}, {}, {}, {}
    for l in os.popen("readelf -W -S " + file).readlines():
        x = l.replace("[ ", "[", 1).split()
        if len(x)<6: continue
        # Should take these into account too!
        #if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
        if x[1] not in [".rodata"]: continue
        sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
        section[x[0][1:-1]] = {"name" : x[1]}
    for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
        l = l.strip()
        if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
            continue
        num, value, size, typ, bind, vis, ndx, name = l.split()
        if ndx == "UND": continue # skip undefined
        if typ in ["SECTION", "FILES"]: continue # skip sections and files
        if "." in name: name = "static." + name.split(".")[0]
        value = int(value, 16)
        size = int(size, 16) if size.startswith('0x') else int(size)
        if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
            alias[(value, size)] = {"name" : name}
        else:
            sym[name] = {"addr" : value, "size":  size}
            lut[(value, size)] = 0
            # If this item is in a known section deduct its size from
            # the size of the section
            if ndx in section:
                sym[section[ndx]["name"]]["size"] -= size
    for addr, sz in iter(alias.keys()):
        # If the non-GLOBAL sym has an implementation elsewhere then
        # it's an alias, disregard it.
        if not (addr, sz) in lut:
            # If this non-GLOBAL sym does not have an implementation at
            # another address, then treat it as a normal symbol.
            sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
    return sym

if flag_timing:
    start_t1 = int(time.time() * 1e9)
old = getsizes(f1)
if flag_timing:
    end_t1 = int(time.time() * 1e9)
    start_t2 = int(time.time() * 1e9)
new = getsizes(f2)
if flag_timing:
    end_t2 = int(time.time() * 1e9)
    start_t3 = int(time.time() * 1e9)
grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
delta, common = [], {}

for name in iter(old.keys()):
    if name in new:
        common[name] = 1

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

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

for name in common:
        d = new[name].get("size", 0) - old[name].get("size", 0)
        if d>0: grow, up = grow+1, up+d
        elif d<0: shrink, down = shrink+1, down-d
        else:
            continue
        delta.append((d, name))

delta.sort()
delta.reverse()
if flag_timing:
    end_t3 = int(time.time() * 1e9)

print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
for d, n in delta:
    if d:
        old_sz = old.get(n, {}).get("size", "-")
        new_sz = new.get(n, {}).get("size", "-")
        print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
print("-"*78)
total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
    % (add, remove, grow, shrink, up, -down, up-down)
print(total % (" "*(80-len(total))))
if flag_timing:
    print("\n%d/%d; %d Parse origin/new; processing nsecs" %
        (end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
    print("total nsecs: %d" % (end_t3-start_t1))
