mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-06 10:16:07 +00:00
feat(tools): add a script for printing Rust stacks' sizes
[no changelog]
This commit is contained in:
parent
e7680edac5
commit
11517f46fd
1
.github/workflows/core.yml
vendored
1
.github/workflows/core.yml
vendored
@ -84,6 +84,7 @@ jobs:
|
||||
- run: nix-shell --run "poetry run make -C core build_prodtest"
|
||||
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
||||
- run: nix-shell --run "poetry run make -C core build_firmware"
|
||||
- run: nix-shell --run "poetry run ./tools/print-rust-stack-sizes.py | sort -k1 -n | tail -n 50"
|
||||
- run: nix-shell --run "poetry run make -C core sizecheck"
|
||||
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
||||
- run: nix-shell --run "poetry run ./tools/check-bitcoin-only core/build/firmware/firmware.bin"
|
||||
|
13
poetry.lock
generated
13
poetry.lock
generated
@ -1163,6 +1163,17 @@ files = [
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyelftools"
|
||||
version = "0.32"
|
||||
description = "Library for analyzing ELF files and DWARF debugging information"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pyelftools-0.32-py3-none-any.whl", hash = "sha256:013df952a006db5e138b1edf6d8a68ecc50630adbd0d83a2d41e7f846163d738"},
|
||||
{file = "pyelftools-0.32.tar.gz", hash = "sha256:6de90ee7b8263e740c8715a925382d4099b354f29ac48ea40d840cf7aa14ace5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "3.2.0"
|
||||
@ -1905,4 +1916,4 @@ test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-it
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "dc9c84386e9b6cf621114845c095bba59d9a5cc169b1622208de2b270d71cbb8"
|
||||
content-hash = "1257cb4cd905c3a00c46535ffa5767cf7bc5af0ac33b80f0adbd5776a8c49d31"
|
||||
|
@ -76,6 +76,7 @@ toiftool = {path = "./python/tools/toiftool", develop = true, python = ">=3.8"}
|
||||
trezor-pylint-plugin = {path = "./tools/trezor-pylint-plugin", develop = true}
|
||||
trezor-core-tools = {path = "./core/tools", develop = true}
|
||||
flake8-annotations = "^3.1.1"
|
||||
pyelftools = "^0.32"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
scan-build = "*"
|
||||
|
58
tools/print-rust-stack-sizes.py
Executable file
58
tools/print-rust-stack-sizes.py
Executable file
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
|
||||
from elftools.construct import Struct, ULInt32, GreedyRange
|
||||
from elftools.common.construct_utils import ULEB128
|
||||
from elftools.elf.elffile import ELFFile
|
||||
|
||||
SYMBOL_TYPES = ("t", "w") # text, weak
|
||||
|
||||
ROOT = Path(__file__).parent.parent.resolve()
|
||||
|
||||
FIRMWARE_ELF = ROOT / "core" / "build" / "firmware" / "firmware.elf"
|
||||
elf = ELFFile(FIRMWARE_ELF.open("rb"))
|
||||
|
||||
|
||||
def load_address_map():
|
||||
"""Load address map from firmware ELF file using `nm`."""
|
||||
out = subprocess.check_output(
|
||||
args=["arm-none-eabi-nm", "--radix=d", "--demangle", FIRMWARE_ELF]
|
||||
)
|
||||
symbols = (line.decode().split(maxsplit=2) for line in out.splitlines())
|
||||
return {
|
||||
int(addr): name for addr, type, name in symbols if type.lower() in SYMBOL_TYPES
|
||||
}
|
||||
|
||||
|
||||
def load_stack_sizes():
|
||||
"""Load Rust stack sizes from firmware ELF section generated by `-Z emit-stack-sizes`."""
|
||||
stack_sizes = elf.get_section_by_name(".stack_sizes")
|
||||
|
||||
Entries = GreedyRange(
|
||||
Struct(
|
||||
"Entry",
|
||||
ULInt32("symbol_addr"),
|
||||
ULEB128("stack_size"),
|
||||
)
|
||||
)
|
||||
return Entries.parse(stack_sizes.data())
|
||||
|
||||
|
||||
@click.command()
|
||||
def main():
|
||||
"""Print Rust functions' stack size.
|
||||
|
||||
See https://blog.japaric.io/stack-analysis/ for more details.
|
||||
"""
|
||||
address_map = load_address_map()
|
||||
for entry in load_stack_sizes():
|
||||
symbol_name = address_map[entry.symbol_addr]
|
||||
print(f"{entry.stack_size}\t{symbol_name}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user