arm-trusted-firmware/tools/memory/memory/mapparser.py
Harrison Mutai d0e3053c4f fix(memmap): reintroduce support for GNU map files
The intial patch stack only supported ELF files, which proved
particularly problematic when dealing with incomplete builds (i.e. build
didn't complete due to linker errors). This adds support for GNU map
files. Most analysis performed by the tool should be possible with map
files alone.

Change-Id: I89f775a98efc5aef6671a17d0e6e973df555a6fa
Signed-off-by: Harrison Mutai <harrison.mutai@arm.com>
2023-06-08 14:06:00 +01:00

76 lines
2.4 KiB
Python

#
# Copyright (c) 2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
from re import match, search
from typing import TextIO
class TfaMapParser:
"""A class representing a map file built for TF-A.
Provides a basic interface for reading the symbol table. The constructor
accepts a file-like object with the contents a Map file. Only GNU map files
are supported at this stage.
"""
def __init__(self, map_file: TextIO):
self._symbols = self.read_symbols(map_file)
@property
def symbols(self):
return self._symbols.items()
@staticmethod
def read_symbols(file: TextIO, pattern: str = None) -> dict:
pattern = r"\b(0x\w*)\s*(\w*)\s=" if not pattern else pattern
symbols = {}
for line in file.readlines():
match = search(pattern, line)
if match is not None:
value, name = match.groups()
symbols[name] = int(value, 16)
return symbols
def get_memory_layout(self) -> dict:
"""Get the total memory consumed by this module from the memory
configuration.
{"rom": {"start": 0x0, "end": 0xFF, "length": ... }
"""
assert len(self._symbols), "Symbol table is empty!"
expr = r".*(.?R.M)_REGION.*(START|END|LENGTH)"
memory_layout = {}
region_symbols = filter(lambda s: match(expr, s), self._symbols)
for symbol in region_symbols:
region, _, attr = tuple(symbol.lower().strip("__").split("_"))
if region not in memory_layout:
memory_layout[region] = {}
memory_layout[region][attr] = self._symbols[symbol]
if "start" and "length" and "end" in memory_layout[region]:
memory_layout[region]["limit"] = (
memory_layout[region]["end"]
+ memory_layout[region]["length"]
)
memory_layout[region]["free"] = (
memory_layout[region]["limit"]
- memory_layout[region]["end"]
)
memory_layout[region]["total"] = memory_layout[region][
"length"
]
memory_layout[region]["size"] = (
memory_layout[region]["end"]
- memory_layout[region]["start"]
)
return memory_layout