xref: /optee_os/scripts/mem_usage.py (revision abaf1209a673c6bd93df24cda245e65b45140578)
1#!/usr/bin/env python3
2#
3# Copyright (c) 2014-2017, Linaro Limited
4# All rights reserved.
5#
6# SPDX-License-Identifier: BSD-3-Clause
7
8import argparse
9import os
10import subprocess
11import sys
12
13
14def get_args():
15    parser = argparse.ArgumentParser(
16        description='Shows the memory layout of the TEE ELF file. '
17        'Size is provided for each section.')
18    parser.add_argument('tee_elf', help='The OP-TEE ELF file (tee.elf)')
19    return parser.parse_args()
20
21
22def printf(format, *args):
23    sys.stdout.write(format % args)
24
25
26def print_sect(name, addr, size, round_up=False, print_num_pages=False):
27    if size == 0:
28        size_kib = 0
29        num_pages = 0
30    else:
31        if round_up:
32            size_kib = (size - 1) / 1024 + 1
33        else:
34            size_kib = size / 1024
35        num_pages = (size - 1) / 4096 + 1
36
37    printf('%-16s %.8X - %.8X size %.8X %3d KiB', name, addr, addr + size,
38           size, size_kib)
39    if print_num_pages:
40        printf(' %d pages', num_pages)
41    printf('\n')
42
43
44def readelf_cmd():
45    return os.getenv('CROSS_COMPILE', '') + 'readelf'
46
47
48def main():
49    in_shdr = False
50    sects = []
51
52    args = get_args()
53    env = os.environ.copy()
54    env['LC_ALL'] = 'C'
55    readelf = subprocess.Popen([readelf_cmd(), '-S', '-W', args.tee_elf],
56                               stdout=subprocess.PIPE, env=env,
57                               universal_newlines=True)
58    for line in iter(readelf.stdout.readline, ''):
59        if 'Section Headers:' in line:
60            in_shdr = True
61            continue
62        if 'Key to Flags:' in line:
63            in_shdr = False
64            continue
65        if in_shdr:
66            words = line.split()
67            if words[0] == '[':
68                words.pop(0)
69            try:
70                (_, name, _, addr, offs, size, _,
71                 flags) = words[:8]
72            except:
73                continue
74            if (flags == 'AX' or flags == 'WA' or flags == 'A' or
75                    flags == 'AL'):
76                sects.append({'name': name, 'addr': addr,
77                              'offs': offs, 'size': size})
78    for sect in sects:
79        if sect['addr'] != 0:
80            first_addr = sect['addr']
81            break
82    last_addr = sects[-1]['addr']
83    last_size = sects[-1]['size']
84
85    ram_usage = int(last_addr, 16) + int(last_size, 16) - int(first_addr, 16)
86    print_sect('RAM Usage', int(first_addr, 16), ram_usage, True, True)
87
88    last_addr = 0
89    last_size = 0
90    for sect in sects:
91        name = sect['name']
92        addr = int(sect['addr'], 16)
93        size = int(sect['size'], 16)
94
95        if last_addr != 0 and addr != last_addr + last_size:
96            print_sect('*hole*', last_addr + last_size,
97                       addr - (last_addr + last_size))
98        print_sect(name, addr, size)
99        last_addr = addr
100        last_size = size
101
102
103if __name__ == "__main__":
104    main()
105