[PATCH v2] bloat-o-meter: avoid double counting

Ron Yorston rmy at pobox.com
Mon Mar 8 19:30:57 UTC 2021


Disable 'echo' in the default config, run 'make baseline', then
re-enable 'echo' and run 'make bloatcheck':

function                                             old     new   delta
.rodata                                           182521  182622    +101
packed_usage                                       33714   33792     +78
applet_main                                         3168    3176      +8
applet_names                                        2730    2735      +5
applet_suid                                           99     100      +1
applet_install_loc                                   198     199      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/0 up/down: 194/0)             Total: 194 bytes
   text	   data	    bss	    dec	    hex	filename
 955052	   4195	   1808	 961055	  eaa1f	busybox_old
 955153	   4195	   1808	 961156	  eaa84	busybox_unstripped

The Total bytes value doesn't equal the change in the size of the
binary.  The packed_usage and applet_* items are in .rodata and
are counted twice.  With this modified bloat-o-meter the size of
named items is deducted from .rodata:

function                                             old     new   delta
packed_usage                                       33714   33792     +78
applet_main                                         3168    3176      +8
.rodata                                           105105  105113      +8
applet_names                                        2730    2735      +5
applet_suid                                           99     100      +1
applet_install_loc                                   198     199      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/0 up/down: 101/0)             Total: 101 bytes
   text	   data	    bss	    dec	    hex	filename
 955052	   4195	   1808	 961055	  eaa1f	busybox_old
 955153	   4195	   1808	 961156	  eaa84	busybox_unstripped

v2: Sections numbered less than 10 were always being omitted from
    consideration because splitting "[ 1] .interp" leaves "1]" in
    x[1] where the section name is expected.  This wasn't a problem
    for .rodata (numbered 15 in my testing) but let's fix it anyway.

Signed-off-by: Ron Yorston <rmy at pobox.com>
---
 scripts/bloat-o-meter | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index cb861b8e9..b4a1d2811 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -43,7 +43,15 @@ if f1 is None or f2 is None:
 
 sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
 def getsizes(file):
-    sym, alias, lut = {}, {}, {}
+    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):
@@ -59,6 +67,10 @@ def getsizes(file):
         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.
@@ -66,13 +78,6 @@ def getsizes(file):
             # 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}
-    for l in os.popen("readelf -W -S " + file).readlines():
-        x = l.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)}
     return sym
 
 if flag_timing:
-- 
2.29.2



More information about the busybox mailing list