xref: /openbmc/openbmc/poky/scripts/tiny/ksum.py (revision 96ff1984133494bf6a3451ddeb7f14548d3697e1)
1 #!/usr/bin/env python3
2 #
3 # Copyright (c) 2016, Intel Corporation.
4 #
5 # SPDX-License-Identifier: GPL-2.0-only
6 #
7 # DESCRIPTION 'ksum.py' generates a combined summary of vmlinux and
8 # module sizes for a built kernel, as a quick tool for comparing the
9 # overall effects of systemic tinification changes.  Execute from the
10 # base directory of the kernel build you want to summarize.  Setting
11 # the 'verbose' flag will display the sizes for each file included in
12 # the summary.
13 #
14 # AUTHORS
15 # Tom Zanussi <tom.zanussi (at] linux.intel.com>
16 #
17 
18 __version__ = "0.1.0"
19 
20 # Python Standard Library modules
21 import os
22 import sys
23 import getopt
24 from subprocess import *
25 
26 def usage():
27     prog = os.path.basename(sys.argv[0])
28     print('Usage: %s [OPTION]...' % prog)
29     print('  -v,                 display sizes for each file')
30     print('  -h, --help          display this help and exit')
31     print('')
32     print('Run %s from the top-level Linux kernel build directory.' % prog)
33 
34 verbose = False
35 
36 n_ko_files = 0
37 ko_file_list = []
38 
39 ko_text = 0
40 ko_data = 0
41 ko_bss = 0
42 ko_total = 0
43 
44 vmlinux_file = ""
45 vmlinux_level = 0
46 
47 vmlinux_text = 0
48 vmlinux_data = 0
49 vmlinux_bss = 0
50 vmlinux_total = 0
51 
52 def is_vmlinux_file(filename):
53     global vmlinux_level
54     if filename == ("vmlinux") and vmlinux_level == 0:
55         vmlinux_level += 1
56         return True
57     return False
58 
59 def is_ko_file(filename):
60     if filename.endswith(".ko"):
61         return True
62     return False
63 
64 def collect_object_files():
65     print("Collecting object files recursively from %s..." % os.getcwd())
66     for dirpath, dirs, files in os.walk(os.getcwd()):
67         for filename in files:
68             if is_ko_file(filename):
69                 ko_file_list.append(os.path.join(dirpath, filename))
70             elif is_vmlinux_file(filename):
71                 global vmlinux_file
72                 vmlinux_file = os.path.join(dirpath, filename)
73     print("Collecting object files [DONE]")
74 
75 def add_ko_file(filename):
76         p = Popen("size -t " + filename, shell=True, stdout=PIPE, stderr=PIPE)
77         output = p.communicate()[0].splitlines()
78         if len(output) > 2:
79             sizes = output[-1].split()[0:4]
80             if verbose:
81                 print("     %10d %10d %10d %10d\t" % \
82                     (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')
83                 print("%s" % filename[len(os.getcwd()) + 1:])
84             global n_ko_files, ko_text, ko_data, ko_bss, ko_total
85             ko_text += int(sizes[0])
86             ko_data += int(sizes[1])
87             ko_bss += int(sizes[2])
88             ko_total += int(sizes[3])
89             n_ko_files += 1
90 
91 def get_vmlinux_totals():
92         p = Popen("size -t " + vmlinux_file, shell=True, stdout=PIPE, stderr=PIPE)
93         output = p.communicate()[0].splitlines()
94         if len(output) > 2:
95             sizes = output[-1].split()[0:4]
96             if verbose:
97                 print("     %10d %10d %10d %10d\t" % \
98                     (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])), end=' ')
99                 print("%s" % vmlinux_file[len(os.getcwd()) + 1:])
100             global vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total
101             vmlinux_text += int(sizes[0])
102             vmlinux_data += int(sizes[1])
103             vmlinux_bss += int(sizes[2])
104             vmlinux_total += int(sizes[3])
105 
106 def sum_ko_files():
107     for ko_file in ko_file_list:
108         add_ko_file(ko_file)
109 
110 def main():
111     try:
112         opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"])
113     except getopt.GetoptError as err:
114         print('%s' % str(err))
115         usage()
116         sys.exit(2)
117 
118     for o, a in opts:
119         if o == '-v':
120             global verbose
121             verbose = True
122         elif o in ('-h', '--help'):
123             usage()
124             sys.exit(0)
125         else:
126             assert False, "unhandled option"
127 
128     collect_object_files()
129     sum_ko_files()
130     get_vmlinux_totals()
131 
132     print("\nTotals:")
133     print("\nvmlinux:")
134     print("    text\tdata\t\tbss\t\ttotal")
135     print("    %-10d\t%-10d\t%-10d\t%-10d" % \
136         (vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total))
137     print("\nmodules (%d):" % n_ko_files)
138     print("    text\tdata\t\tbss\t\ttotal")
139     print("    %-10d\t%-10d\t%-10d\t%-10d" % \
140         (ko_text, ko_data, ko_bss, ko_total))
141     print("\nvmlinux + modules:")
142     print("    text\tdata\t\tbss\t\ttotal")
143     print("    %-10d\t%-10d\t%-10d\t%-10d" % \
144         (vmlinux_text + ko_text, vmlinux_data + ko_data, \
145          vmlinux_bss + ko_bss, vmlinux_total + ko_total))
146 
147 if __name__ == "__main__":
148     try:
149         ret = main()
150     except Exception:
151         ret = 1
152         import traceback
153         traceback.print_exc(5)
154     sys.exit(ret)
155