1# 2# Copyright (c) 2023-2024, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6 7from re import match, search 8from typing import TextIO 9 10 11class TfaMapParser: 12 """A class representing a map file built for TF-A. 13 14 Provides a basic interface for reading the symbol table. The constructor 15 accepts a file-like object with the contents a Map file. Only GNU map files 16 are supported at this stage. 17 """ 18 19 def __init__(self, map_file: TextIO): 20 self._symbols = self.read_symbols(map_file) 21 22 @property 23 def symbols(self): 24 return self._symbols.items() 25 26 @staticmethod 27 def read_symbols(file: TextIO, pattern: str = None) -> dict: 28 pattern = r"\b(0x\w*)\s*(\w*)\s=" if not pattern else pattern 29 symbols = {} 30 31 for line in file.readlines(): 32 match = search(pattern, line) 33 34 if match is not None: 35 value, name = match.groups() 36 symbols[name] = int(value, 16) 37 38 return symbols 39 40 def get_memory_layout(self) -> dict: 41 """Get the total memory consumed by this module from the memory 42 configuration. 43 {"rom": {"start": 0x0, "end": 0xFF, "length": ... } 44 """ 45 assert len(self._symbols), "Symbol table is empty!" 46 expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)" 47 memory_layout = {} 48 49 region_symbols = filter(lambda s: match(expr, s), self._symbols) 50 51 for symbol in region_symbols: 52 region, _, attr = tuple(symbol.lower().strip("__").split("_")) 53 if region not in memory_layout: 54 memory_layout[region] = {} 55 56 memory_layout[region][attr] = self._symbols[symbol] 57 58 if "start" and "length" and "end" in memory_layout[region]: 59 memory_layout[region]["limit"] = ( 60 memory_layout[region]["start"] 61 + memory_layout[region]["length"] 62 ) 63 memory_layout[region]["free"] = ( 64 memory_layout[region]["limit"] 65 - memory_layout[region]["end"] 66 ) 67 memory_layout[region]["total"] = memory_layout[region][ 68 "length" 69 ] 70 memory_layout[region]["size"] = ( 71 memory_layout[region]["end"] 72 - memory_layout[region]["start"] 73 ) 74 75 return memory_layout 76