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