1#!/usr/bin/env python3
2
3#
4# Copyright (c) 2023, Arm Limited. All rights reserved.
5#
6# SPDX-License-Identifier: BSD-3-Clause
7#
8
9from pathlib import Path
10
11import click
12from memory.buildparser import TfaBuildParser
13from memory.printer import TfaPrettyPrinter
14
15
16@click.command()
17@click.option(
18    "-r",
19    "--root",
20    type=Path,
21    default=None,
22    help="Root containing build output.",
23)
24@click.option(
25    "-p",
26    "--platform",
27    show_default=True,
28    default="fvp",
29    help="The platform targeted for analysis.",
30)
31@click.option(
32    "-b",
33    "--build-type",
34    default="release",
35    help="The target build type.",
36    type=click.Choice(["debug", "release"], case_sensitive=False),
37)
38@click.option(
39    "-f",
40    "--footprint",
41    is_flag=True,
42    show_default=True,
43    help="Generate a high level view of memory usage by memory types.",
44)
45@click.option(
46    "-t",
47    "--tree",
48    is_flag=True,
49    help="Generate a hierarchical view of the modules, segments and sections.",
50)
51@click.option(
52    "--depth",
53    default=3,
54    help="Generate a virtual address map of important TF symbols.",
55)
56@click.option(
57    "-s",
58    "--symbols",
59    is_flag=True,
60    help="Generate a map of important TF symbols.",
61)
62@click.option("-w", "--width", type=int, envvar="COLUMNS")
63@click.option(
64    "-d",
65    is_flag=True,
66    default=False,
67    help="Display numbers in decimal base.",
68)
69@click.option(
70    "--no-elf-images",
71    is_flag=True,
72    help="Analyse the build's map files instead of ELF images.",
73)
74def main(
75    root: Path,
76    platform: str,
77    build_type: str,
78    footprint: str,
79    tree: bool,
80    symbols: bool,
81    depth: int,
82    width: int,
83    d: bool,
84    no_elf_images: bool,
85):
86    build_path = root if root else Path("build/", platform, build_type)
87    click.echo(f"build-path: {build_path.resolve()}")
88
89    parser = TfaBuildParser(build_path, map_backend=no_elf_images)
90    printer = TfaPrettyPrinter(columns=width, as_decimal=d)
91
92    if footprint or not (tree or symbols):
93        printer.print_footprint(parser.get_mem_usage_dict())
94
95    if tree:
96        printer.print_mem_tree(
97            parser.get_mem_tree_as_dict(), parser.module_names, depth=depth
98        )
99
100    if symbols:
101        expr = (
102            r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
103            r"|R.M)(.*)(START|UNALIGNED|END)__$"
104        )
105        printer.print_symbol_table(
106            parser.filter_symbols(parser.symbols, expr), parser.module_names
107        )
108
109
110if __name__ == "__main__":
111    main()
112