Firmware SBOM Accuracy: Source vs Binary, and How to Prove What Ships
| Interlynk

Why firmware SBOMs disagree: source scanning sees what is present, binary analysis sees the image but infers identity, and build-aware generation reads the real build. How to tell which is accurate and prove what actually shipped.
Present in the repository is not the same as shipped in the binary
Run three SBOM tools over the same firmware project and you may get three different answers. That does not necessarily mean one of them is broken. Each approach is looking at a different part of the path from source code to shipped image.
A source scan reports what it can identify in the repository and project metadata. A binary analyzer reports what it can recognize in the firmware image. A build-aware generator reports which inputs the build selected and, when reconciled with the linker map, which of those inputs remained in the final image.
For embedded software, the gap between "present" and "shipped" is where SBOM accuracy gets difficult. It also determines whether a vulnerability alert represents a real exposure or a component your team now has to investigate for applicability.
This guide explains how the three approaches differ, where each one works best, and how to create an evidence trail for what actually shipped.
The short answer
A source scan is useful for understanding what a project contains, but it can report components that never reach a particular image. Binary and firmware analysis start with the artifact that ships and can identify code that is really present, although component identity and version are often inferred from the binary. Build-aware generation reads the build's inputs and configuration to establish which components are in scope and why, then reconciles them against the linker map for the specific image. When you control the build, combining build evidence with image-specific evidence, while recording what remains unknown, gives you the strongest basis for a defensible firmware SBOM.
The right method depends on the question you need to answer.
Four layers between your source tree and your firmware
Many SBOM accuracy problems come from treating several different questions as one. A typical embedded build has at least four technical layers, plus a fifth question about attribution:
Present in the repository. This includes vendor SDKs, RTOS ports, HAL drivers, cryptography and networking libraries, test utilities, sample applications, and old compatibility code.
Selected by the build configuration. These are the targets and files pulled in by the specific CMake, Make, or IAR configuration being built.
Compiled or supplied as build inputs. This includes the source compiled for the build, prebuilt static archives, and other artifacts passed into the link.
Retained in the final firmware image. These are the parts that survive linking and dead-code elimination and actually ship.
Attributable to a component with provenance. The retained code must be tied to a known component and version using evidence that your team can defend.
A vulnerable component in a shared third_party directory may exist at the first layer and never reach the final image. Reporting the entire directory as shipped can create a large set of vulnerability alerts that do not apply to that image.
The reverse situation is also common. A static archive or toolchain runtime can enter the build at layer three or four without appearing in a package manifest. A manifest-only scan can miss code that really does ship.
Source-code SBOMs are strong for project inventory
Source-tree scanning is a useful starting point. The tool walks the repository, reads package manifests, lockfiles, and vendored source, then produces a CycloneDX or SPDX document. It is quick and requires no build.
That makes it useful for answering a basic question: what does this project contain?
Suppose the repository includes third_party/mbedtls. A source scan can establish that the project contains mbedTLS. It cannot establish that mbedTLS was compiled for a particular board, linked into a particular image, or retained after dead-code elimination.
For server-side applications, where most of the repository often ships, project inventory and shipped software may be fairly close. Firmware is different. A large source tree can resolve into a small, target-specific image. As a result, a source scan can report many more potential components than are present in any one image.
Binary and firmware analysis starts with the artifact
Binary analysis works from the other end of the process. It inspects a compiled binary or firmware image and identifies the components it can recognize. This is the right approach when the shipped artifact is all you have, such as third-party or legacy firmware that your team did not build. Vendors such as ONEKEY and Binarly are built around this use case.
Binary analysis can be highly effective when the image retains strong evidence, including symbols, embedded metadata, or recognizable version strings. In those cases, it may provide high-confidence results from the artifact itself.
The more difficult question is provenance. Identity and version are often inferred from signatures, strings, and heuristics. Confidence can drop significantly for stripped or statically linked builds. A binary analyzer may be able to show that a particular implementation is probably present while lacking enough information to identify the exact upstream source, fork, or version.
That makes binary analysis especially valuable when you only have the image. When you control the build, build records can provide additional evidence about where the code came from and why it belongs to a particular target.
Build-aware generation uses the evidence from the build
Build-aware generation reads the build itself. It runs after your existing build with no rebuild and reads the compiler and linker invocations that the build emits. This exposes details that a repository scan cannot see, including the selected configuration, source files, compile options, include paths, archive inputs, and linker inputs.
It provides two related types of evidence:
Build evidence shows why an input belongs to the target being built.
Linker-map evidence shows whether and how that input was retained in the final image.
Together, these records give a more precise view than assuming everything in the repository shipped. They also avoid treating a binary signature as proof of an exact upstream version.
Build evidence establishes scope and provenance. Component identity and version still depend on source or supplier metadata. When those details cannot be confirmed, the SBOM should say so rather than fill the fields with a guess.
This is the approach that closes much of the gap between what is present and what ships in firmware. It is what Interlynk's lynkctl is designed to do.
Source vs binary vs build-aware, at a glance
Question | Source-oriented scan | Binary or firmware analysis | Build-aware generation |
|---|---|---|---|
Sees what is present in the project | Yes | No | Yes |
Sees what the image retained | Limited | Yes | Yes, when reconciled with the linker map |
Knows which configuration selected it | Sometimes | No | Yes |
Component identity and version | From manifests and source, when available | Inferred from the artifact, with varying confidence | From build evidence plus source or supplier metadata |
Handles static archives and vendored code | Partial | Can detect contributed code, but identity may be opaque | Visible as build and link inputs, although provenance may need more evidence |
Requires the source and build | Source only | Neither | Runs after the build with no rebuild |
Best fit | Understanding project contents | Analyzing an artifact when the build is unavailable | Building firmware and needing image-specific provenance |
How to prove what actually shipped
SBOM accuracy is not about creating the largest possible component list. It is about making the scope of each component clear and preserving the evidence behind it.
These practices help produce an SBOM that engineering, security, and compliance teams can use:
Reconcile the SBOM against the image's linker map. The map file is specific to an image. A bootloader, secure firmware image, and application image are separate SBOM subjects when they ship or update separately. Generate and reconcile an SBOM for each one.
Keep detection separate from provenance. If a component was found through a binary signature, record that as detection evidence. If its source revision is known from the build or a supplier record, record that as provenance. These are related claims, but they are not the same claim.
Treat versions as inferred until confirmed. When identity comes from binary heuristics, mark it that way. Confirm it against build or source evidence before using it to make decisions about remediation.
Record what remains unknown. If the supplier or version of a prebuilt archive cannot be established, say so. A transparent SBOM is more useful than one that fills every field with an unsupported value.
Keep build tools separate from shipped components. The compiler, linker, and build system belong to the build environment. A runtime archive that actually links into the image, such as
libgcc.a, is different and should be treated as shipped software.
For a worked example, see Trusted Firmware-M on an STM32H5. For more background on the underlying challenge, read why C/C++ SBOMs are hard.
How Interlynk fits
Interlynk's generator, lynkctl, is the build-aware option. It runs after an existing Make, CMake, IAR, or TI Code Composer build with no rebuild. It reads the compiler and linker invocations and reconciles them against the linker map so the SBOM reflects what the image retained, rather than only what exists in the repository.
Each component includes an evidence record with details such as the source file, compile line, and confidence tier. This lets engineering and security teams see why a component appears and distinguish established evidence from remaining uncertainty.
lynkctl can run in an air-gapped environment and outputs CycloneDX 1.6+ and SPDX 3+.
For regulated products, this evidence can strengthen the technical documentation supporting an SBOM. It is an implementation choice rather than a regulatory format. FDA 524B sets SBOM obligations for cyber devices within its scope, and the EU Cyber Resilience Act requires a machine-readable SBOM covering at least top-level dependencies. The specific evidence collected behind that SBOM depends on the workflow and tools you choose.
Learn more about the C/C++ SBOM generator for embedded software, read the broader guide to SBOMs for embedded and IoT systems, or compare the options in four ways to generate an SBOM from a CMake build.
Frequently asked questions
Why do two SBOM tools give different results for the same firmware?
They are using different evidence. A source scan reports what it can identify in the project. A binary analyzer reports what it recognizes in the shipped image. A build-aware generator reports which inputs the target build selected and, when reconciled with the linker map, which of those inputs the image retained.
The differences are largest in firmware, where a large source tree can resolve into a small, target-specific image.
Is a source-code SBOM or a binary SBOM more accurate for firmware?
Neither is universally more accurate. They answer different questions.
A source SBOM is useful for understanding project contents and potential dependencies. Binary analysis is useful for identifying code in a shipped artifact. When you control the build, build evidence can provide stronger provenance for the target, especially when it is reconciled against image-specific evidence.
How do I know what actually shipped in my firmware image?
Start with the exact release configuration. Capture the build inputs and generate the corresponding linker map. Reconcile those records against the final image, then generate one SBOM for each independently shipped image instead of merging the bootloader and application into one subject.
Keep per-component evidence so every entry can be traced back to the information that supports it.
Does binary analysis get static libraries right?
It can detect code from a static library when that code leaves recognizable evidence in the image. The harder part is attribution. The binary may not contain enough information to identify the exact library, version, or fork.
When you control the build, build evidence can establish the archive's identity and role. The linker map can then show whether it contributed to the image.
Which approach should I use for an FDA or CRA submission?
The regulations do not prescribe one SBOM-generation method. Choose a workflow that produces a complete, machine-readable SBOM for the relevant product and keeps the supporting evidence required by your quality, security, and regulatory processes.
For a build you control, build-aware generation can provide useful, image-specific provenance. For third-party or legacy firmware where you only have the image, binary analysis may be necessary. Some teams use both approaches.
See FDA 524B for more information.
Where to go next
Compare the generation methods in four ways to generate an SBOM from a CMake build, review the worked example in Trusted Firmware-M on an STM32H5, and explore the category in our guide to the best SBOM tools.