gcc-binary-analysis
Analyze compiled ELF binaries produced by GCC (S32Compiler 10.2/11.4). Identifies code size contributors, section layout, and symbol-level breakdown to diagnose large firmware and unexpected binary gr
SKILL.mdskills/compiler/gcc-binary-analysis/SKILL.md
GitHubGCC Binary Analysis (Embedded / S32Compiler)
Analyze a compiled ELF binary to determine what contributes to code size, which functions
or libraries dominate, how sections (.text, .data, .bss) are structured, and why the
binary is larger than expected. Targets linked ELFs produced by S32Compiler GCC.
When to use
Use this skill when:
- User asks "why is my firmware so large?"
- User asks "which function is taking up the most flash?"
- User asks "why did my binary grow after this change?"
- User asks "what got linked in unexpectedly?"
- User asks "why is libc so large in my binary?"
Do not use this skill for:
- Comparing optimization levels -> use
gcc-benchmark-optimization - Linking behavior and section placement -> use
gcc-linker-explorer - Assembly output inspection -> use
gcc-compiler-explorer
Available Capabilities
| Type | Name | Invocation |
|---|---|---|
This skill uses the standardized search_actions + execute_action MCP tool surface. |
| Action name | Purpose |
|---|---|
compiler.list_gcc_tools |
Call first to discover toolchain paths |
compiler.gcc_execute |
Run size, nm, and objdump on the ELF |
Quickstart
1. Discover the toolchain
Tool: list_gcc_compiler_tools
Input: (none)
Output: toolchain_bin_dir, binary prefix
2. Measure overall binary size
Tool: gcc_execute
Input: binary="arm-none-eabi-size", args="output.elf"
Output: .text / .data / .bss sizes in bytes
3. Rank symbols by size
Tool: gcc_execute
Input: binary="arm-none-eabi-nm", args="-C --size-sort output.elf"
Output: symbols sorted by size (largest at bottom)
Configuration
S32Compiler GCC is discovered automatically via list_gcc_compiler_tools. No YAML
config is needed. Always analyze the linked ELF -- .o file sizes are not
representative of real flash usage (dead code is only removed at link time).
Guardrails
Scope
- This skill analyzes existing ELF files. It does not recompile or modify source.
- Only calls
list_gcc_compiler_toolsandgcc_execute. No filesystem writes beyond the tool's own scratch directory.
Destructive actions
- No destructive operations. All analysis is read-only against the provided ELF.
Refuse-and-escalate
- If no GCC toolchain is found, stop and tell the user -- do not guess paths.
- If the user provides a
.ofile instead of a linked ELF, warn them that.osizes are not representative and ask for the final ELF. - If the ELF is for other target, explain this skill is ARM-only and stop.
Resource limits
- Do not run
objdump -Don very large ELFs (> 10 MB) without user confirmation.
Secrets
- Do not log or expose content from data sections that may contain sensitive material.
Workflow
Step 1 -- Discover the toolchain
Call list_gcc_compiler_tools() and identify the binary prefix (e.g. arm-none-eabi-).
Step 2 -- Measure overall binary size
{
"toolchain_bin_dir": "<bin dir>",
"binary": "arm-none-eabi-size",
"args": "output.elf"
}
Explain sections:
| Section | Contents | Memory cost |
|---|---|---|
.text |
Executable code | Flash |
.rodata |
Read-only constants | Flash |
.data |
Initialized variables | Flash + RAM |
.bss |
Zero-initialized variables | RAM only |
Step 3 -- Inspect section layout
{
"binary": "arm-none-eabi-objdump",
"args": "-h output.elf"
}
Look for unexpectedly large sections and constants in .data instead of .rodata.
Step 4 -- Rank symbols by size (core step)
{
"binary": "arm-none-eabi-nm",
"args": "-C --size-sort output.elf"
}
The largest symbols appear at the bottom. Focus on top contributors to .text and
unexpected libc symbols (printf, malloc, _printf_float).
Step 5 -- Trace symbol origins (optional)
{
"binary": "arm-none-eabi-objdump",
"args": "-t output.elf"
}
Use to trace unexpected symbols back to their source object or library.
Analysis checklist
- Identify the largest functions and whether they are user code or libc
- Check for
printffloat formatting (_printf_floatpulls in large float engine) - Check for missing dead code elimination (no
--gc-sectionsat link time) - Check for constants in
.datainstead of.rodata(missingconstkeyword)
Validation loop
list_gcc_compiler_tools()returns a non-empty toolchain list.arm-none-eabi-size output.elfproduces a section size table.arm-none-eabi-nm -C --size-sort output.elfproduces a ranked symbol list.- Each large symbol is explained with a root cause and actionable recommendation.
Out of scope
- Recompiling or relinking (use
gcc-linker-explorerfor that workflow) - Comparing optimization levels (use
gcc-benchmark-optimization) - LAX, or SPT targets
See Also
gcc-linker-explorer-- analyze why symbols are included and how to remove themgcc-benchmark-optimization-- compare size impact of different-Olevelsgcc-compiler-explorer-- inspect assembly for individual functions