aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-02-07 19:26:18 +0100
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2010-02-07 19:26:18 +0100
commitf16d7c4bdf0d3e97760f9567ad449a968e2bc4eb (patch)
tree31018bad2dd04b125d140de915df70a515823c4d
parent343dfd7abe44a32b329379ec9039f2560543518d (diff)
downloadbusybox-w32-f16d7c4bdf0d3e97760f9567ad449a968e2bc4eb.tar.gz
busybox-w32-f16d7c4bdf0d3e97760f9567ad449a968e2bc4eb.tar.bz2
busybox-w32-f16d7c4bdf0d3e97760f9567ad449a968e2bc4eb.zip
bloat-o-meter: fix quadric behavior in alias resolution
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
-rwxr-xr-xscripts/bloat-o-meter97
1 files changed, 68 insertions, 29 deletions
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index aa126969c..acee6bea9 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -7,44 +7,69 @@
7# This software may be used and distributed according to the terms 7# This software may be used and distributed according to the terms
8# of the GNU General Public License, incorporated herein by reference. 8# of the GNU General Public License, incorporated herein by reference.
9 9
10import sys, os, re 10import sys, os#, re
11 11
12def usage(): 12def usage():
13 sys.stderr.write("usage: %s file1 file2\n" % sys.argv[0]) 13 sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0])
14 sys.exit(-1) 14 sys.exit(-1)
15 15
16if len(sys.argv) < 3: 16f1, f2 = (None, None)
17 usage() 17flag_timing, dashes = (False, False)
18 18
19for f in sys.argv[1:3]: 19for f in sys.argv[1:]:
20 if not os.path.exists(f): 20 if f.startswith("-"):
21 sys.stderr.write("Error: file '%s' does not exist\n" % f) 21 if f == "--": # sym_args
22 usage() 22 dashes = True
23 break
24 if f == "-t": # timings
25 flag_timing = True
26 else:
27 if not os.path.exists(f):
28 sys.stderr.write("Error: file '%s' does not exist\n" % f)
29 usage()
30 if f1 is None:
31 f1 = f
32 elif f2 is None:
33 f2 = f
34if flag_timing:
35 import time
36if f1 is None or f2 is None:
37 usage()
23 38
24sym_args = " ".join(sys.argv[3:]) 39sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
25def getsizes(file): 40def getsizes(file):
26 sym, alias = {}, {} 41 sym, alias, lut = {}, {}, {}
27 dynsym_filter = re.compile("^\s+\d+:\s+[\dA-Fa-f]+\s+\d+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+\n$") 42 #dynsym_filter = re.compile("^\d+:\s+[\dA-Fa-f]+\s+\d+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+$")
28 for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines(): 43 for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
29 if not dynsym_filter.match(l): continue 44 if True:
30 num, value, size, typ, bind, vis, ndx, name = l.strip().split() 45 l = l.strip()
31 if ndx == "UND": continue # skip undefined 46 if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
32 if typ in ["SECTION", "FILES"]: continue # skip sections and files 47 continue
48 num, value, size, typ, bind, vis, ndx, name = l.split()
49 if ndx == "UND": continue # skip undefined
50 if typ in ["SECTION", "FILES"]: continue # skip sections and files
51 #else:
52 # l = l.strip()
53 # match = dynsym_filter.match(l)
54 # if not match: continue
55 # x, value, size, typ, bind, x, ndx, name = l.split()
56 # if ndx == "UND": continue # skip undefined
57 # if typ in ["SECTION", "FILES"]: continue # skip sections and files
33 if "." in name: name = "static." + name.split(".")[0] 58 if "." in name: name = "static." + name.split(".")[0]
34 value = int(value, 16) 59 value = int(value, 16)
35 size = int(size) 60 size = int(size)
36 if bind != "GLOBAL": # see if it is an alias 61 if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
37 alias[name] = {"addr" : value, "size": size} 62 alias[(value, size)] = {"name" : name}
38 else: 63 else:
39 sym[name] = {"addr" : value, "size": size} 64 sym[name] = {"addr" : value, "size": size}
40 for a_nam, a_dat in alias.iteritems(): 65 lut[(value, size)] = 0
41 impl = [k for k, v in sym.iteritems() if v.get("addr") == a_dat["addr"]] 66 for addr, sz in alias.iterkeys():
42 # If the non-GLOBAL sym has an implementation elsewhere then 67 # If the non-GLOBAL sym has an implementation elsewhere then
43 # it's an alias, disregard it. 68 # it's an alias, disregard it.
44 if not impl: 69 if not (addr, sz) in lut:
45 # If this non-GLOBAL sym does not have an implementation at 70 # If this non-GLOBAL sym does not have an implementation at
46 # another address, then treat it as a normal symbol. 71 # another address, then treat it as a normal symbol.
47 sym[a_nam] = a_dat 72 sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
48 for l in os.popen("readelf -W -S " + file).readlines(): 73 for l in os.popen("readelf -W -S " + file).readlines():
49 x = l.split() 74 x = l.split()
50 if len(x)<6: continue 75 if len(x)<6: continue
@@ -54,26 +79,34 @@ def getsizes(file):
54 sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)} 79 sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
55 return sym 80 return sym
56 81
57old = getsizes(sys.argv[1]) 82if flag_timing:
58new = getsizes(sys.argv[2]) 83 start_t1 = int(time.time() * 1e9)
84old = getsizes(f1)
85if flag_timing:
86 end_t1 = int(time.time() * 1e9)
87 start_t2 = int(time.time() * 1e9)
88new = getsizes(f2)
89if flag_timing:
90 end_t2 = int(time.time() * 1e9)
91 start_t3 = int(time.time() * 1e9)
59grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 92grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
60delta, common = [], [] 93delta, common = [], {}
61 94
62for a in old.iterkeys(): 95for name in old.iterkeys():
63 if a in new: 96 if name in new:
64 common.append(a) 97 common[name] = 1
65 98
66for name in old: 99for name in old:
67 if name not in common: 100 if name not in common:
68 remove += 1 101 remove += 1
69 sz = old[name].get("size", 0) 102 sz = old[name]["size"]
70 down += sz 103 down += sz
71 delta.append((-sz, name)) 104 delta.append((-sz, name))
72 105
73for name in new: 106for name in new:
74 if name not in common: 107 if name not in common:
75 add += 1 108 add += 1
76 sz = new[name].get("size", 0) 109 sz = new[name]["size"]
77 up += sz 110 up += sz
78 delta.append((sz, name)) 111 delta.append((sz, name))
79 112
@@ -87,6 +120,8 @@ for name in common:
87 120
88delta.sort() 121delta.sort()
89delta.reverse() 122delta.reverse()
123if flag_timing:
124 end_t3 = int(time.time() * 1e9)
90 125
91print "%-48s %7s %7s %+7s" % ("function", "old", "new", "delta") 126print "%-48s %7s %7s %+7s" % ("function", "old", "new", "delta")
92for d, n in delta: 127for d, n in delta:
@@ -98,3 +133,7 @@ print "-"*78
98total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\ 133total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
99 % (add, remove, grow, shrink, up, -down, up-down) 134 % (add, remove, grow, shrink, up, -down, up-down)
100print total % (" "*(80-len(total))) 135print total % (" "*(80-len(total)))
136if flag_timing:
137 print("\n%d/%d; %d Parse origin/new; processing nsecs" %
138 (end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
139 print("total nsecs: %d" % (end_t3-start_t1))