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"
|
- run: nix-shell --run "poetry run make -C core build_prodtest"
|
||||||
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
||||||
- run: nix-shell --run "poetry run make -C core build_firmware"
|
- 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"
|
- run: nix-shell --run "poetry run make -C core sizecheck"
|
||||||
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
if: matrix.coins == 'universal' && matrix.type != 'debuglink'
|
||||||
- run: nix-shell --run "poetry run ./tools/check-bitcoin-only core/build/firmware/firmware.bin"
|
- 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"},
|
{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]]
|
[[package]]
|
||||||
name = "pyflakes"
|
name = "pyflakes"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
@ -1905,4 +1916,4 @@ test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-it
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.9"
|
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-pylint-plugin = {path = "./tools/trezor-pylint-plugin", develop = true}
|
||||||
trezor-core-tools = {path = "./core/tools", develop = true}
|
trezor-core-tools = {path = "./core/tools", develop = true}
|
||||||
flake8-annotations = "^3.1.1"
|
flake8-annotations = "^3.1.1"
|
||||||
|
pyelftools = "^0.32"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
scan-build = "*"
|
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