1# 2# Copyright (c) 2023-2025, Arm Limited. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6 7from collections import defaultdict 8from re import match, search 9from typing import Dict, TextIO 10 11from memory.image import Image, Region 12 13 14class TfaMapParser(Image): 15 """A class representing a map file built for TF-A. 16 17 Provides a basic interface for reading the symbol table. The constructor 18 accepts a file-like object with the contents a Map file. Only GNU map files 19 are supported at this stage. 20 """ 21 22 def __init__(self, map_file: TextIO) -> None: 23 self._symbols: Dict[str, int] = self.read_symbols(map_file) 24 assert self._symbols, "Symbol table is empty!" 25 26 self._footprint: Dict[str, Region] = defaultdict(Region) 27 28 expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)" 29 for symbol in filter(lambda s: match(expr, s), self._symbols): 30 region, _, attr = symbol.lower().strip("__").split("_") 31 32 if attr == "start": 33 self._footprint[region].start = self._symbols[symbol] 34 elif attr == "end": 35 self._footprint[region].end = self._symbols[symbol] 36 if attr == "length": 37 self._footprint[region].length = self._symbols[symbol] 38 39 @property 40 def symbols(self) -> Dict[str, int]: 41 return self._symbols 42 43 @staticmethod 44 def read_symbols(file: TextIO) -> Dict[str, int]: 45 pattern = r"\b(0x\w*)\s*(\w*)\s=" 46 symbols: Dict[str, int] = {} 47 48 for line in file.readlines(): 49 match = search(pattern, line) 50 51 if match is not None: 52 value, name = match.groups() 53 symbols[name] = int(value, 16) 54 55 return symbols 56 57 @property 58 def footprint(self) -> Dict[str, Region]: 59 return self._footprint 60