Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | #!/usr/bin/env python3 # # Copyright (c) 2014-2017, Linaro Limited # # SPDX-License-Identifier: BSD-3-Clause import argparse import os import subprocess import sys def get_args(): parser = argparse.ArgumentParser(description='Shows the memory usage ' 'of an OP-TEE based on ELF sections') parser.add_argument('tee_elf', help='the OP-TEE ELF file (tee.elf)') parser.add_argument('-a', '--all', action='store_true', help=' same as -i -p -u -U') parser.add_argument('-n', '--no-map', action='store_true', help=' do not show the detailed section mappings and ' 'RAM usage') parser.add_argument('-i', '--init', action='store_true', help='report the total size of the .*_init sections') parser.add_argument('-p', '--paged', action='store_true', help='report the total size of the .*_pageable ' 'sections') parser.add_argument('-u', '--unpaged', action='store_true', help='report the total size of the unpaged sections, ' 'that is, all sections but the ones in --init or ' '--paged') parser.add_argument('-U', '--unpaged-no-heap', action='store_true', help='report the size of all unpaged sections ' 'excluding heap space. Reflects the size of unpaged ' 'code and data (.text, .rodata, .data, .bss, .nozi ' 'and possibly unwind tables)') parser.add_argument('-r', '--raw', action='store_true', help='when processing -i, -p, -u, or -U, show only ' 'the size (in decimal) and no other text') return parser.parse_args() def printf(format, *args): sys.stdout.write(format % args) def print_sect(name, addr, size, round_up=False, print_num_pages=False): if args.no_map: return if size == 0: size_kib = 0 num_pages = 0 else: if round_up: size_kib = (size - 1) / 1024 + 1 else: size_kib = size / 1024 num_pages = (size - 1) / 4096 + 1 printf('%-16s %.8X - %.8X size %.8X %3d KiB', name, addr, addr + size, size, size_kib) if print_num_pages: printf(' %d pages', num_pages) printf('\n') def print_pager_stat(name, size): size_kib = size / 1024 if args.raw: printf('%d ', size) else: printf('%-36s size %.8X %3d KiB\n', name, size, size_kib) def readelf_cmd(): return os.getenv('CROSS_COMPILE', '') + 'readelf' def main(): global args in_shdr = False sects = [] init_size = 0 paged_size = 0 unpaged_size = 0 unpaged_no_heap_size = 0 args = get_args() env = os.environ.copy() env['LC_ALL'] = 'C' readelf = subprocess.Popen(str.split(readelf_cmd()) + ['-S', '-W', args.tee_elf], stdout=subprocess.PIPE, env=env, universal_newlines=True) for line in iter(readelf.stdout.readline, ''): if 'Section Headers:' in line: in_shdr = True continue if 'Key to Flags:' in line: in_shdr = False continue if in_shdr: words = line.split() if words[0] == '[': words.pop(0) try: (_, name, _, addr, offs, size, _, flags) = words[:8] except BaseException: continue if (flags == 'AX' or flags == 'WA' or flags == 'A' or flags == 'AL'): sects.append({'name': name, 'addr': addr, 'offs': offs, 'size': size}) for sect in sects: if sect['addr'] != 0: first_addr = sect['addr'] break last_addr = sects[-1]['addr'] last_size = sects[-1]['size'] ram_usage = int(last_addr, 16) + int(last_size, 16) - int(first_addr, 16) print_sect('RAM Usage', int(first_addr, 16), ram_usage, True, True) last_addr = 0 last_size = 0 for sect in sects: name = sect['name'] addr = int(sect['addr'], 16) size = int(sect['size'], 16) if last_addr != 0 and addr != last_addr + last_size: print_sect('*hole*', last_addr + last_size, addr - (last_addr + last_size)) print_sect(name, addr, size) if name.endswith('_init'): init_size += size elif name.endswith('_pageable'): paged_size += size else: if not name.startswith('.heap'): unpaged_no_heap_size += size unpaged_size += size last_addr = addr last_size = size if args.all or args.init: print_pager_stat('Init sections (.*_init)', init_size) if args.all or args.paged: print_pager_stat('Paged sections (.*_pageable)', paged_size) if args.all or args.unpaged: print_pager_stat('Unpaged sections ', unpaged_size) if args.all or args.unpaged_no_heap: print_pager_stat('Unpaged sections (heap excluded)', unpaged_no_heap_size) if (args.raw and (args.all or args.init or args.paged or args.unpaged or args.unpaged_no_heap)): printf('\n') if __name__ == "__main__": main() |