1#!/usr/bin/env python3 2# 3# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved. 4# 5# SPDX-License-Identifier: BSD-3-Clause 6# 7 8import re 9import os 10import sys 11import operator 12 13# List of folder/map to parse 14bl_images = ['bl1', 'bl2', 'bl31'] 15 16# List of symbols to search for 17blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__', 18 '__BL2_END__', 19 '__BL31_END__', 20 '__RO_START__', '__RO_END_UNALIGNED__', '__RO_END__', 21 '__TEXT_START__', '__TEXT_END__', 22 '__TEXT_RESIDENT_START__', '__TEXT_RESIDENT_END__', 23 '__RODATA_START__', '__RODATA_END__', 24 '__DATA_START__', '__DATA_END__', 25 '__STACKS_START__', '__STACKS_END__', 26 '__BSS_START__', '__BSS_END__', 27 '__COHERENT_RAM_START__', '__COHERENT_RAM_END__', 28 '__CPU_OPS_START__', '__CPU_OPS_END__', 29 '__FCONF_POPULATOR_START__', '__FCONF_POPULATOR_END__', 30 '__GOT_START__', '__GOT_END__', 31 '__PARSER_LIB_DESCS_START__', '__PARSER_LIB_DESCS_END__', 32 '__PMF_TIMESTAMP_START__', '__PMF_TIMESTAMP_END__', 33 '__PMF_SVC_DESCS_START__', '__PMF_SVC_DESCS_END__', 34 '__RELA_START__', '__RELA_END__', 35 '__RT_SVC_DESCS_START__', '__RT_SVC_DESCS_END__', 36 '__BASE_XLAT_TABLE_START__', '__BASE_XLAT_TABLE_END__', 37 '__XLAT_TABLE_START__', '__XLAT_TABLE_END__', 38 ] 39 40# Regex to extract address from map file 41address_pattern = re.compile(r"\b0x\w*") 42 43# List of found element: [address, symbol, file] 44address_list = [] 45 46# Get the directory from command line or use a default one 47inverted_print = True 48if len(sys.argv) >= 2: 49 build_dir = sys.argv[1] 50 if len(sys.argv) >= 3: 51 inverted_print = sys.argv[2] == '0' 52else: 53 build_dir = 'build/fvp/debug' 54 55max_len = max(len(word) for word in blx_symbols) + 2 56if (max_len % 2) != 0: 57 max_len += 1 58 59# Extract all the required symbols from the map files 60for image in bl_images: 61 file_path = os.path.join(build_dir, image, '{}.map'.format(image)) 62 if os.path.isfile(file_path): 63 with open (file_path, 'rt') as mapfile: 64 for line in mapfile: 65 for symbol in blx_symbols: 66 skip_symbol = 0 67 # Regex to find symbol definition 68 line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .") 69 match = line_pattern.search(line) 70 if match: 71 # Extract address from line 72 match = address_pattern.search(line) 73 if match: 74 if '_END__' in symbol: 75 sym_start = symbol.replace('_END__', '_START__') 76 if [match.group(0), sym_start, image] in address_list: 77 address_list.remove([match.group(0), sym_start, image]) 78 skip_symbol = 1 79 if skip_symbol == 0: 80 address_list.append([match.group(0), symbol, image]) 81 82# Sort by address 83address_list.sort(key=operator.itemgetter(0)) 84 85# Invert list for lower address at bottom 86if inverted_print: 87 address_list = reversed(address_list) 88 89# Generate memory view 90print(('{:-^%d}' % (max_len * 3 + 20 + 7)).format('Memory Map from: ' + build_dir)) 91for address in address_list: 92 if "bl1" in address[2]: 93 print(address[0], ('+{:-^%d}+ |{:^%d}| |{:^%d}|' % (max_len, max_len, max_len)).format(address[1], '', '')) 94 elif "bl2" in address[2]: 95 print(address[0], ('|{:^%d}| +{:-^%d}+ |{:^%d}|' % (max_len, max_len, max_len)).format('', address[1], '')) 96 elif "bl31" in address[2]: 97 print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1])) 98 else: 99 print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1])) 100 101print(('{:^20}{:_^%d} {:_^%d} {:_^%d}' % (max_len, max_len, max_len)).format('', '', '', '')) 102print(('{:^20}{:^%d} {:^%d} {:^%d}' % (max_len, max_len, max_len)).format('address', 'bl1', 'bl2', 'bl31')) 103