source: MondoRescue/branches/3.3/mindi-busybox/scripts/bloat-o-meter@ 3621

Last change on this file since 3621 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:executable set to *
File size: 4.4 KB
Line 
1#!/usr/bin/env python
2#
3# Copyright 2004 Matt Mackall <mpm@selenic.com>
4#
5# Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
6#
7# This software may be used and distributed according to the terms
8# of the GNU General Public License, incorporated herein by reference.
9
10import sys, os
11
12def usage():
13 sys.stderr.write("usage: %s [-t] file1 file2 [-- <readelf options>]\n"
14 % sys.argv[0])
15 sys.stderr.write("\t-t\tShow time spent on parsing/processing\n")
16 sys.stderr.write("\t--\tPass additional parameters to readelf\n")
17 sys.exit(1)
18
19f1, f2 = (None, None)
20flag_timing, dashes = (False, False)
21
22for f in sys.argv[1:]:
23 if f.startswith("-"):
24 if f == "--": # sym_args
25 dashes = True
26 break
27 if f == "-t": # timings
28 flag_timing = True
29 else:
30 if not os.path.exists(f):
31 sys.stderr.write("Error: file '%s' does not exist\n" % f)
32 usage()
33 if f1 is None:
34 f1 = f
35 elif f2 is None:
36 f2 = f
37 else:
38 usage()
39if flag_timing:
40 import time
41if f1 is None or f2 is None:
42 usage()
43
44sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
45def getsizes(file):
46 sym, alias, lut = {}, {}, {}
47 for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
48 l = l.strip()
49 if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
50 continue
51 num, value, size, typ, bind, vis, ndx, name = l.split()
52 if ndx == "UND": continue # skip undefined
53 if typ in ["SECTION", "FILES"]: continue # skip sections and files
54 if "." in name: name = "static." + name.split(".")[0]
55 value = int(value, 16)
56 size = int(size, 16) if size.startswith('0x') else int(size)
57 if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
58 alias[(value, size)] = {"name" : name}
59 else:
60 sym[name] = {"addr" : value, "size": size}
61 lut[(value, size)] = 0
62 for addr, sz in iter(alias.keys()):
63 # If the non-GLOBAL sym has an implementation elsewhere then
64 # it's an alias, disregard it.
65 if not (addr, sz) in lut:
66 # If this non-GLOBAL sym does not have an implementation at
67 # another address, then treat it as a normal symbol.
68 sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
69 for l in os.popen("readelf -W -S " + file).readlines():
70 x = l.split()
71 if len(x)<6: continue
72 # Should take these into account too!
73 #if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
74 if x[1] not in [".rodata"]: continue
75 sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
76 return sym
77
78if flag_timing:
79 start_t1 = int(time.time() * 1e9)
80old = getsizes(f1)
81if flag_timing:
82 end_t1 = int(time.time() * 1e9)
83 start_t2 = int(time.time() * 1e9)
84new = getsizes(f2)
85if flag_timing:
86 end_t2 = int(time.time() * 1e9)
87 start_t3 = int(time.time() * 1e9)
88grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
89delta, common = [], {}
90
91for name in iter(old.keys()):
92 if name in new:
93 common[name] = 1
94
95for name in old:
96 if name not in common:
97 remove += 1
98 sz = old[name]["size"]
99 down += sz
100 delta.append((-sz, name))
101
102for name in new:
103 if name not in common:
104 add += 1
105 sz = new[name]["size"]
106 up += sz
107 delta.append((sz, name))
108
109for name in common:
110 d = new[name].get("size", 0) - old[name].get("size", 0)
111 if d>0: grow, up = grow+1, up+d
112 elif d<0: shrink, down = shrink+1, down-d
113 else:
114 continue
115 delta.append((d, name))
116
117delta.sort()
118delta.reverse()
119if flag_timing:
120 end_t3 = int(time.time() * 1e9)
121
122print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
123for d, n in delta:
124 if d:
125 old_sz = old.get(n, {}).get("size", "-")
126 new_sz = new.get(n, {}).get("size", "-")
127 print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
128print("-"*78)
129total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
130 % (add, remove, grow, shrink, up, -down, up-down)
131print(total % (" "*(80-len(total))))
132if flag_timing:
133 print("\n%d/%d; %d Parse origin/new; processing nsecs" %
134 (end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
135 print("total nsecs: %d" % (end_t3-start_t1))
Note: See TracBrowser for help on using the repository browser.