Skip to content
heliaPROFILER
Reference
HELIA

elf_inventory

The measured memory inventory of a linked image, read with the toolchain’s own tools: every section with its address and size, the load segments, and how many rows could not be parsed.

Every name on this page is imported from helia_profiler.

API tier: experimental

Generated from the src/helia_profiler tree f38e378c801d34438affb680257217e0b58d2cd1.

Machine-readable model

  • ElfSectionclassOne section of the linked image, address included.
  • LoadSegmentclassOne PTLOAD program header: where bytes load (physical) vs run (virtual) — the fact that makes initialized data's MRAM load image accountable (#133 D3).
  • SectionInventoryclassThe measured memory inventory of one linked binary.
  • section_inventoryfunctionThe measured section/segment inventory of binarypath, or None.
class

One section of the linked image, address included.

src/helia_profiler/hostenv/elf_inventory.py:68

ElfSection(
name: str,
address: int,
size: int,
nobits: bool,
allocated: bool,
index: int = -1,
linker_reserved: bool = False,
) -> None

dataclass

One section of the linked image, address included.

index is the ELF section-header index — the section’s IDENTITY. Section NAMES are not unique: armlink emits one section per execution region per content class all named after the region (a real NSX AP510 scatter link yields two MCU_TCM sections, PROGBITS + NOBITS), and NSX’s own gcc scripts declare .text twice. Never key a collection of these on name alone — bytes vanish (#176).

linker_reserved marks the NOBITS+allocated regions the linker manufactures rather than the program needing them (today: fill-to-end heaps, armlink’s ARM_LIB_HEAP — the #24/#131 rule, same predicate as the BinarySections.reserved split). .stack/ARM_LIB_STACK are deliberately NOT reserved: the stack is live memory the firmware needs — but note it usually sits OUTSIDE the per-family app window (LinkedRegionWindow.app_window), which is how the free-space math stays consistent.

API tier: experimental

class

One PTLOAD program header: where bytes load (physical) vs run (virtual) — the fact that makes initialized data's MRAM load image accountable (#133 D3).

src/helia_profiler/hostenv/elf_inventory.py:97

LoadSegment(virtual_address: int, physical_address: int, file_size: int, memory_size: int) -> None

dataclass

One PT_LOAD program header: where bytes load (physical) vs run (virtual) — the fact that makes initialized data’s MRAM load image accountable (#133 D3).

Toolchain shape caveat (#176, measured on real links against the NSX AP510 scripts): GNU ld emits one PT_LOAD per load region (.data gets vaddr in DTCM, paddr in MRAM — per-section recovery works). armlink emits a SINGLE PT_LOAD whose vaddr==paddr is the image base and whose memory_size SUMS discontiguous execution regions — paddr + memory_size is a phantom span, and mapping sections into segments by vaddr containment understates armlink MRAM ~400x. Region-level load-image accounting that works on BOTH families: sum file_size grouped by classify_address(physical_address), never walk sections into segments. Per-symbol load-image attribution on armlink is NOT recoverable from these primitives.

API tier: experimental

class

The measured memory inventory of one linked binary.

src/helia_profiler/hostenv/elf_inventory.py:121

SectionInventory(
sections: tuple[ElfSection, ...],
segments: tuple[LoadSegment, ...] = (),
unparsed_rows: int = 0,
) -> None

dataclass

The measured memory inventory of one linked binary.

unparsed_rows counts SECTION rows/blocks that LOOKED like inventory entries but failed to parse. When nonzero the section inventory is PARTIAL — occupancy computed from it is understated, and a consumer must treat the measured view as unavailable rather than publish a silently-low number (#131’s discipline, structural instead of a debug log). Segment parse failures are NOT counted: segments refine the inventory and their absence degrades independently (empty tuple), on both tool paths.

API tier: experimental

function

The measured section/segment inventory of binarypath, or None.

src/helia_profiler/hostenv/elf_inventory.py:335

section_inventory(binary_path: Path, toolchain: str, *, timeout_s: int = 30) -> SectionInventory | None

The measured section/segment inventory of binary_path, or None.

Dispatches like :func:binary_sections: readelf for the size-probed toolchains, fromelf --text -v for armclang. Degrades to None on any tool or parse failure — the measured memory view simply does not exist for that run, exactly like an absent reserved split.

API tier: experimental


Machine-readable: elf_inventory.json · elf_inventory.md, complete and lossless.