Turn a wall of linker output into a memory report your whole team can read.
Zero dependencies · One HTML file · CI-friendly · Your firmware never leaves your machine
LinkerLens reads a GNU linker .map file and answers the questions firmware teams ask every day:
- What is consuming FLASH and RAM?
- Which object file made this build bigger?
- Did
.dataget counted in both its RAM address and FLASH load image? - Can CI stop a change before the firmware no longer fits?
It produces a useful terminal summary, machine-readable JSON, a searchable self-contained HTML report, and build-to-build diffs. There is no server and no map-file upload.
LinkerLens uses only the Python standard library.
git clone https://github.com/269394628/LinkerLens.git
cd LinkerLens
python -m pip install -e .Try it with the included firmware map:
linkerlens summary examples/demo.map
linkerlens report examples/demo.mapThe report is written to demo.linkerlens.html. Open it in any modern browser; it contains all styles, data, and behavior in one file.
LinkerLens examples/demo.map
MEMORY REGIONS
FLASH [######------------------] 23.0% 59.0 KiB / 256 KiB
RAM [###########-------------] 43.8% 28.1 KiB / 64.0 KiB
LARGEST SECTIONS
.text 42.1 KiB
.bss 12.4 KiB
.rodata 10.8 KiB
Compare two builds from the command line:
linkerlens diff build/main-before.map build/main.mapMake a size regression fail:
linkerlens diff baseline.map current.map --fail-on-growth 4KUse --json result.json on summary or diff when another tool needs the data. Use --json - for stdout.
Limits can be percentages of the memory region declared by the linker script or absolute byte sizes:
linkerlens check build/main.map \
--limit FLASH=90% \
--limit RAM=48KThe command returns exit code 2 when a budget is exceeded. A minimal GitHub Actions step looks like this:
- name: Check firmware memory budgets
run: |
python -m pip install .
linkerlens check build/main.map --limit FLASH=90% --limit RAM=85%| Command | Purpose |
|---|---|
summary firmware.map |
Region usage plus the largest sections and objects |
report firmware.map -o report.html |
Searchable, self-contained HTML report |
diff old.map new.map |
Region, section, and object-level size changes |
check firmware.map --limit FLASH=90% |
CI-friendly memory budgets |
Run linkerlens <command> --help for all options.
LinkerLens assigns output sections to the memory regions declared under Memory Configuration. For initialized data such as:
.data 0x20000000 0x1680 load address 0x0800d560
the bytes are counted in RAM at their run address and in FLASH at their distinct load address. Debug sections and other sections outside declared memory regions remain visible in section data but do not inflate device-memory totals.
The parser currently targets GNU ld map files produced by GCC-based embedded toolchains, including common arm-none-eabi, RISC-V, and Xtensa layouts. Linker variants differ; a small sanitized fixture is welcome when yours is not recognized.
Powerful binary analysis suites exist, but a routine firmware code review often needs something smaller:
- no ELF symbols or debug information required;
- no Node.js, database, container, or native package;
- reports can be attached directly to a CI run;
- readable output for developers, testers, and project managers;
- deterministic results suitable for a pull-request gate.
LinkerLens is intentionally narrow. It aims to make the first 90% of embedded memory investigation take seconds.
- Arm/Keil and IAR map-file adapters
- Pull-request comments with a compact size diff
- Demangled symbol and namespace grouping
- Config file for repository-wide budgets
- Reproducible standalone executables for Windows, Linux, and macOS
If one of these would help your team, open an issue with a small example. Real toolchain cases will shape the order.
Bug reports, sanitized map snippets, and parser improvements are welcome. Start with CONTRIBUTING.md. Please never publish proprietary firmware paths or symbols in an issue.
LinkerLens is available under the MIT License.