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 21import os 22import sys 23import getopt 24from subprocess import * 25 26def 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 34verbose = False 35 36n_ko_files = 0 37ko_file_list = [] 38 39ko_text = 0 40ko_data = 0 41ko_bss = 0 42ko_total = 0 43 44vmlinux_file = "" 45vmlinux_level = 0 46 47vmlinux_text = 0 48vmlinux_data = 0 49vmlinux_bss = 0 50vmlinux_total = 0 51 52def 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 59def is_ko_file(filename): 60 if filename.endswith(".ko"): 61 return True 62 return False 63 64def 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 75def 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 91def 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 106def sum_ko_files(): 107 for ko_file in ko_file_list: 108 add_ko_file(ko_file) 109 110def 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 147if __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