blob: e4c4c975d79ca10f69de4deecb64c6a63705dcfd [file] [log] [blame]
Jerome Forissierabaf1202017-11-08 13:31:29 +01001#!/usr/bin/env python3
2#
3# Copyright (c) 2014-2017, Linaro Limited
Jerome Forissierabaf1202017-11-08 13:31:29 +01004#
5# SPDX-License-Identifier: BSD-3-Clause
6
7import argparse
8import os
9import subprocess
10import sys
11
12
13def get_args():
Jerome Forissier3be77732017-11-09 15:54:46 +010014 parser = argparse.ArgumentParser(description='Shows the memory usage '
15 'of an OP-TEE based on ELF sections')
16 parser.add_argument('tee_elf', help='the OP-TEE ELF file (tee.elf)')
17 parser.add_argument('-a', '--all', action='store_true',
18 help=' same as -i -p -u -U')
19 parser.add_argument('-n', '--no-map', action='store_true',
20 help=' do not show the detailed section mappings and '
21 'RAM usage')
22 parser.add_argument('-i', '--init', action='store_true',
23 help='report the total size of the .*_init sections')
24 parser.add_argument('-p', '--paged', action='store_true',
25 help='report the total size of the .*_pageable '
26 'sections')
27 parser.add_argument('-u', '--unpaged', action='store_true',
28 help='report the total size of the unpaged sections, '
29 'that is, all sections but the ones in --init or '
30 '--paged')
31 parser.add_argument('-U', '--unpaged-no-heap', action='store_true',
32 help='report the size of all unpaged sections '
33 'excluding heap space. Reflects the size of unpaged '
34 'code and data (.text, .rodata, .data, .bss, .nozi '
35 'and possibly unwind tables)')
36 parser.add_argument('-r', '--raw', action='store_true',
37 help='when processing -i, -p, -u, or -U, show only '
38 'the size (in decimal) and no other text')
Jerome Forissierabaf1202017-11-08 13:31:29 +010039 return parser.parse_args()
40
41
42def printf(format, *args):
43 sys.stdout.write(format % args)
44
45
46def print_sect(name, addr, size, round_up=False, print_num_pages=False):
Jerome Forissier3be77732017-11-09 15:54:46 +010047 if args.no_map:
48 return
Jerome Forissierabaf1202017-11-08 13:31:29 +010049 if size == 0:
50 size_kib = 0
51 num_pages = 0
52 else:
53 if round_up:
54 size_kib = (size - 1) / 1024 + 1
55 else:
56 size_kib = size / 1024
57 num_pages = (size - 1) / 4096 + 1
58
59 printf('%-16s %.8X - %.8X size %.8X %3d KiB', name, addr, addr + size,
60 size, size_kib)
61 if print_num_pages:
62 printf(' %d pages', num_pages)
63 printf('\n')
64
65
Jerome Forissier3be77732017-11-09 15:54:46 +010066def print_pager_stat(name, size):
67 size_kib = size / 1024
68 if args.raw:
69 printf('%d ', size)
70 else:
71 printf('%-36s size %.8X %3d KiB\n', name, size, size_kib)
72
73
Jerome Forissierabaf1202017-11-08 13:31:29 +010074def readelf_cmd():
75 return os.getenv('CROSS_COMPILE', '') + 'readelf'
76
77
78def main():
Jerome Forissier3be77732017-11-09 15:54:46 +010079 global args
80
Jerome Forissierabaf1202017-11-08 13:31:29 +010081 in_shdr = False
82 sects = []
Jerome Forissier3be77732017-11-09 15:54:46 +010083 init_size = 0
84 paged_size = 0
85 unpaged_size = 0
86 unpaged_no_heap_size = 0
Jerome Forissierabaf1202017-11-08 13:31:29 +010087
88 args = get_args()
89 env = os.environ.copy()
90 env['LC_ALL'] = 'C'
Jerome Forissier479c49d2019-11-29 12:01:34 +000091 readelf = subprocess.Popen(str.split(readelf_cmd()) + ['-s',
92 args.tee_elf],
93 stdout=subprocess.PIPE, env=env,
94 universal_newlines=True)
95 for line in iter(readelf.stdout.readline, ''):
96 words = line.split()
97 if len(words) == 8 and words[7] == '_end_of_ram':
98 end_of_ram = int(words[1], 16)
99 break
100 readelf.terminate()
Jerome Forissieredbeddc2017-11-21 08:53:54 +0100101 readelf = subprocess.Popen(str.split(readelf_cmd()) + ['-S', '-W',
Jerome Forissier146cbc42018-11-14 11:02:49 +0100102 args.tee_elf],
Jerome Forissierabaf1202017-11-08 13:31:29 +0100103 stdout=subprocess.PIPE, env=env,
104 universal_newlines=True)
105 for line in iter(readelf.stdout.readline, ''):
106 if 'Section Headers:' in line:
107 in_shdr = True
108 continue
109 if 'Key to Flags:' in line:
110 in_shdr = False
111 continue
112 if in_shdr:
113 words = line.split()
114 if words[0] == '[':
115 words.pop(0)
116 try:
117 (_, name, _, addr, offs, size, _,
118 flags) = words[:8]
Jerome Forissier146cbc42018-11-14 11:02:49 +0100119 except BaseException:
Jerome Forissierabaf1202017-11-08 13:31:29 +0100120 continue
Jerome Forissier5e70edb2021-05-18 20:32:45 +0200121 if ('A' in flags):
Jerome Forissierabaf1202017-11-08 13:31:29 +0100122 sects.append({'name': name, 'addr': addr,
123 'offs': offs, 'size': size})
Jerome Forissier479c49d2019-11-29 12:01:34 +0000124 first_addr = None
Jerome Forissierabaf1202017-11-08 13:31:29 +0100125 for sect in sects:
126 if sect['addr'] != 0:
Jerome Forissier479c49d2019-11-29 12:01:34 +0000127 addr = sect['addr']
128 if not first_addr:
129 first_addr = addr
130 if int(addr, 16) >= end_of_ram:
131 break
132 last_addr = addr
133 last_size = sect['size']
Jerome Forissierabaf1202017-11-08 13:31:29 +0100134
135 ram_usage = int(last_addr, 16) + int(last_size, 16) - int(first_addr, 16)
136 print_sect('RAM Usage', int(first_addr, 16), ram_usage, True, True)
137
138 last_addr = 0
139 last_size = 0
140 for sect in sects:
141 name = sect['name']
142 addr = int(sect['addr'], 16)
143 size = int(sect['size'], 16)
144
Jerome Forissier479c49d2019-11-29 12:01:34 +0000145 if addr >= end_of_ram:
146 break
Jerome Forissierabaf1202017-11-08 13:31:29 +0100147 if last_addr != 0 and addr != last_addr + last_size:
148 print_sect('*hole*', last_addr + last_size,
149 addr - (last_addr + last_size))
150 print_sect(name, addr, size)
Jerome Forissier3be77732017-11-09 15:54:46 +0100151 if name.endswith('_init'):
152 init_size += size
153 elif name.endswith('_pageable'):
154 paged_size += size
155 else:
156 if not name.startswith('.heap'):
157 unpaged_no_heap_size += size
158 unpaged_size += size
Jerome Forissierabaf1202017-11-08 13:31:29 +0100159 last_addr = addr
160 last_size = size
161
Jerome Forissier3be77732017-11-09 15:54:46 +0100162 if args.all or args.init:
163 print_pager_stat('Init sections (.*_init)', init_size)
164 if args.all or args.paged:
165 print_pager_stat('Paged sections (.*_pageable)', paged_size)
166 if args.all or args.unpaged:
167 print_pager_stat('Unpaged sections ', unpaged_size)
168 if args.all or args.unpaged_no_heap:
169 print_pager_stat('Unpaged sections (heap excluded)',
170 unpaged_no_heap_size)
171 if (args.raw and (args.all or args.init or args.paged or
172 args.unpaged or args.unpaged_no_heap)):
173 printf('\n')
174
Jerome Forissierabaf1202017-11-08 13:31:29 +0100175
176if __name__ == "__main__":
177 main()