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