- Fix error handling priority: check waitErr first, then parseErr, then closeErr - Optimize O(n²) symbol lookup by checking next symbol first - Add ELF section constants (SHN_LORESERVE, SHN_ABS, etc.) and use them - Fix documentation: add missing --elf-output-style=LLVM flag - Fix documentation: correct field names from pkg.ID to pkg.PkgPath Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: cpunion <8459+cpunion@users.noreply.github.com>
2.5 KiB
2.5 KiB
Size Report Options
The llgo build -size flag emits a TinyGo-style table showing how much code,
rodata, data, and BSS each component contributes to the final binary. This
document captures the parsing strategy and new aggregation controls.
Parsing Strategy
- We invoke
llvm-readelf --elf-output-style=LLVM --all <binary>and parse the textual output with an indentation-sensitive state machine (no JSON). Only theSectionsandSymbolsblocks are inspected. - Section metadata records the index, address, size, name, and segment. Each section is classified into text/rodata/data/bss buckets.
- Symbols are attached to their containing sections with start addresses. By sorting symbols and walking their ranges, we compute byte spans that can be attributed to packages/modules.
- Sections with no symbols fall back to
(unknown <section>), and gaps become(padding <section>)entries so totals still add up.
Aggregation Levels
-size:level controls how symbol names are grouped prior to reporting:
| Level | Behavior |
|---|---|
full |
Keeps the raw owner from the symbol name (previous behavior). |
package |
Uses the list of packages built in build.Do and groups by pkg.PkgPath. |
module* |
Default. Groups by pkg.Module.Path (or pkg.PkgPath if the module is nil). |
Matching is performed by checking whether the demangled symbol name begins with
pkg.PkgPath + ".". Symbols that do not match any package and contain llgo are
bucketed into llgo-stubs; other unmatched entries keep their original owner
names so we can inspect them later.
Examples:
llgo build -size . # module-level aggregation (default)
llgo build -size -size:level=package . # collapse by package ID
llgo build -size -size:level=full . # show raw symbol owners
llgo build -size -size:format=json . # JSON output (works with all levels)
Validation
- Unit tests:
go test ./internal/build -run TestParseReadelfOutput -count=1. - Real binary test:
cd cl/_testgo/rewrite ../../../llgo.sh build . LLGO_SIZE_REPORT_BIN=$(pwd)/rewrite \ go test ./internal/build -run TestParseReadelfRealBinary -count=1 - Manual smoke test:
../../../llgo.sh build -size -size:level=module .(orpackage/fullas desired).
The parser works across Mach-O and ELF targets as long as llvm-readelf is in
PATH.