mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-08-15 17:07:04 +02:00
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>
76 lines
2.4 KiB
Python
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
|