C/C++ SBOM Generation with Heimdall
Heimdall extracts C/C++-specific metadata from object files, executables, and debug information and stores this comprehensive information in SPDX and CycloneDX SBOM formats.
Overview
Heimdall's C/C++ extractor provides comprehensive SBOM generation for C/C++ applications by combining:
- Binary analysis of object files and executables
- DWARF debug information parsing for C/C++-specific metadata
- Symbol table analysis for function and variable information
- Cross-referencing between binary and source information
Data Sources
1. Object Files and Executables
Extracted Information:
- File format: ELF, PE, Mach-O detection
- Architecture: Target platform information (x86_64, ARM64, etc.)
- Symbols: Function and variable names with mangling
- Sections: Code, data, debug sections
- Dependencies: Dynamic and static library dependencies
- Debug information: DWARF debug info (if available)
- Checksums: SHA1, SHA256 file integrity
- File type: Executable, shared library, object file
- Compiler information: Compiler version and flags
Example Extraction:
# Binary analysis of C++ executable
./heimdall-sbom lib/heimdall-lld.so myapp --format cyclonedx
Output includes:
- File checksums and integrity information
- Dynamic library dependencies (libstdc++.so.6, libc.so.6, libm.so.6, etc)
- Symbol table information with C++ name mangling
- Debug section analysis
- Dependency linking for direct and transivitive dependencies
- Compiler identification (GCC, Clang, MSVC)
2. DWARF Debug Information
Extracted Information:
Source File Information:
- Source file names:
.cpp
,.c
,.h
,.hpp
file mappings - File paths: Absolute and relative paths
- File timestamps: When files were compiled
- File checksums: Integrity verification
- Include relationships: Header file dependencies
Function Information:
- Function names: Demangled C++ function names
- Function signatures: Parameter types and return types
- Function locations: Source file and line numbers
- Function scope: Namespace and class membership
- Function attributes: Inline, static, virtual, etc.
Variable Information:
- Variable names: Local and global variables
- Variable types: C/C++ type information
- Variable scope: Local, global, static, thread-local
- Variable locations: Source file and line numbers
- Variable attributes: Const, volatile, etc.
Type Information:
- Class definitions: C++ class and struct information
- Template instantiations: C++ template specializations
- Type hierarchies: Inheritance relationships
- Type sizes: Memory layout information
- Type attributes: POD, trivial, standard layout
Namespace Information:
- Namespace names: C++ namespace hierarchy
- Namespace contents: Functions and classes in namespaces
- Using declarations: Imported namespaces
- Namespace aliases: Type aliases and using declarations
Example DWARF Information:
DW_TAG_compile_unit
DW_AT_name: "main.cpp"
DW_AT_comp_dir: "/home/user/project/src"
DW_AT_producer: "GNU C++17 11.2.0"
DW_AT_language: DW_LANG_C_plus_plus_17
DW_TAG_namespace
DW_AT_name: "myapp"
DW_TAG_class_type
DW_AT_name: "Calculator"
DW_AT_byte_size: 24
DW_TAG_member
DW_AT_name: "value"
DW_AT_type: DW_TAG_base_type (int)
DW_TAG_subprogram
DW_AT_name: "add"
DW_AT_linkage_name: "_ZN5myapp10Calculator3addEi"
DW_AT_decl_file: 1
DW_AT_decl_line: 15
3. Symbol Table Analysis
Extracted Information:
C++ Name Mangling:
- Demangled names: Human-readable function names
- Mangled names: Linker symbols for function resolution
- Overload resolution: C++ function overloading
- Template specializations: Template instantiation names
Symbol Types:
- Function symbols: Global and static functions
- Variable symbols: Global and static variables
- Weak symbols: Weakly linked symbols
- Undefined symbols: External dependencies
Linkage Information:
- Internal linkage: Static functions and variables
- External linkage: Exported functions and variables
- Weak linkage: Weakly linked symbols
- Hidden visibility: Symbol visibility attributes
Example Symbol Analysis:
Symbol: _ZN5myapp10Calculator3addEi
Demangled: myapp::Calculator::add(int)
Type: Function
Linkage: External
Visibility: Default
Section: .text
SBOM Format Storage
SPDX 2.3 Format
Package Information:
PackageName: myapp
PackageVersion: 1.0.0
PackageSupplier: Organization: MyCompany
PackageDownloadLocation: NOASSERTION
FilesAnalyzed: true
PackageVerificationCode: 4e3211c67a2d28fced849ee1bb76e7391b93feba
PackageChecksum: SHA256: a1b2c3d4e5f6...
PackageHomePage: https://github.com/mycompany/myapp
PackageLicenseDeclared: MIT
PackageLicenseConcluded: MIT
PackageCopyrightText: Copyright (c) 2025 MyCompany
PackageSummary: A C++ calculator application
PackageDescription: A simple calculator application demonstrating C++ SBOM generation
PackageComment: Generated by Heimdall SBOM Generator
File Information:
FileName: src/main.cpp
FileType: SOURCE
FileChecksum: SHA256: f1e2d3c4b5a6...
LicenseConcluded: MIT
LicenseInfoInFile: MIT
FileCopyrightText: Copyright (c) 2025 MyCompany
FileComment: Main application entry point
Dependencies:
Relationship: myapp CONTAINS src/main.cpp
Relationship: myapp CONTAINS src/calculator.cpp
Relationship: myapp DEPENDS_ON libstdc++
Relationship: myapp DEPENDS_ON libc
CycloneDX Format
Component Information:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"timestamp": "2025-07-19T22:27:55Z",
"tools": [
{
"vendor": "Heimdall",
"name": "SBOM Generator",
"version": "2.0.0"
}
]
},
"components": [
{
"type": "application",
"name": "myapp",
"version": "1.0.0",
"purl": "pkg:generic/myapp@1.0.0",
"properties": [
{
"name": "compiler",
"value": "GNU C++17 11.2.0"
},
{
"name": "sourceFiles",
"value": "main.cpp, calculator.cpp, calculator.h, utils.cpp, utils.h"
},
{
"name": "buildFlags",
"value": "-std=c++17 -O2 -g -Wall -Wextra"
},
{
"name": "architecture",
"value": "x86_64"
},
{
"name": "fileFormat",
"value": "ELF"
}
],
"dependencies": [
"libstdc++",
"libc",
"libm"
]
}
]
}
Enhanced Metadata Extraction
Currently Extracted
From Binary Files:
- File format and architecture
- Symbol table information with demangling
- Dynamic library dependencies
- Debug information (if available)
- File integrity checksums
- Section information
- Compiler identification
From DWARF Information:
- Source file mappings and relationships
- Function and variable type information
- C++ class and namespace hierarchies
- Template instantiation details
- Build configuration and compiler flags
- Debug symbol information
Security Information:
{
"properties": [
{
"name": "security.compiler",
"value": "GNU C++17 11.2.0"
},
{
"name": "security.buildFlags",
"value": "-std=c++17 -O2 -g -Wall -Wextra -fstack-protector-strong"
},
{
"name": "security.architecture",
"value": "x86_64"
},
{
"name": "security.fileFormat",
"value": "ELF"
}
]
}
Function Call Graph:
{
"properties": [
{
"name": "functions.calls",
"value": "[main] -> [Calculator::add], [main] -> [Calculator::subtract], [Calculator::add] -> [validate_input]"
},
{
"name": "functions.namespaces",
"value": "myapp::Calculator, myapp::Utils, std::"
},
{
"name": "functions.templates",
"value": "std::vector<int>, std::string, std::unique_ptr<Calculator>"
}
]
}
Type System Information:
{
"properties": [
{
"name": "types.classes",
"value": "Calculator, Utils, InputValidator"
},
{
"name": "types.inheritance",
"value": "Calculator extends BaseCalculator, InputValidator implements Validator"
},
{
"name": "types.templates",
"value": "std::vector<T>, std::unique_ptr<T>, std::shared_ptr<T>"
},
{
"name": "types.variables",
"value": "int result, std::string input, Calculator calc"
}
]
}
Build Reproducibility:
{
"properties": [
{
"name": "build.timestamps",
"value": "main.cpp: 20250719161512, calculator.cpp: 20250719161443"
},
{
"name": "build.checksums",
"value": "main.cpp: b2efb2f5, calculator.cpp: f03e478f"
},
{
"name": "build.compiler",
"value": "GNU C++17 11.2.0"
},
{
"name": "build.flags",
"value": "-std=c++17 -O2 -g -Wall -Wextra"
}
]
}
Source File Analysis:
{
"properties": [
{
"name": "source.files",
"value": "main.cpp, calculator.cpp, calculator.h, utils.cpp, utils.h"
},
{
"name": "source.includes",
"value": "#include <iostream>, #include <vector>, #include \"calculator.h\""
},
{
"name": "source.namespaces",
"value": "myapp, std, boost"
},
{
"name": "source.templates",
"value": "std::vector, std::unique_ptr, std::shared_ptr"
}
]
}
Usage Examples
Basic SBOM Generation
# Generate SPDX 2.3 SBOM
./heimdall-sbom lib/heimdall-lld.so myapp --format spdx-2.3 --output cpp_sbom.spdx.json
# Generate CycloneDX SBOM
./heimdall-sbom lib/heimdall-lld.so myapp --format cyclonedx-1.6 --output cpp_sbom.cdx.json
Integration with Build Systems
CMake Integration with Heimdall Module:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(myapp)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find and configure Heimdall
find_package(Heimdall REQUIRED)
add_executable(myapp main.cpp calculator.cpp utils.cpp)
target_compile_options(myapp PRIVATE -g -Wall -Wextra)
# Enable SBOM generation for the target
heimdall_enable_sbom(myapp
FORMATS "spdx-2.3;cyclonedx-1.6"
OUTPUT_DIR "${CMAKE_BINARY_DIR}/sbom"
INCLUDE_DEBUG_INFO ON
VERBOSE ON
)
# Alternative: Configure SBOM generation with specific options
heimdall_configure_sbom(myapp
SPDX_VERSION "2.3"
CYCLONEDX_VERSION "1.6"
OUTPUT_PREFIX "myapp"
INCLUDE_SYSTEM_LIBS OFF
EXTRACT_DEBUG_INFO ON
)
# Example with multiple targets and shared library
add_library(calculator_lib SHARED calculator.cpp calculator.h)
add_executable(calculator_app main.cpp)
target_link_libraries(calculator_app PRIVATE calculator_lib)
# Enable SBOM for both targets
heimdall_enable_sbom(calculator_lib
FORMATS "cyclonedx-1.6"
OUTPUT_DIR "${CMAKE_BINARY_DIR}/sbom"
)
heimdall_enable_sbom(calculator_app
FORMATS "spdx-2.3;cyclonedx-1.6"
OUTPUT_DIR "${CMAKE_BINARY_DIR}/sbom"
INCLUDE_DEBUG_INFO ON
)
Heimdall CMake Module Features:
The Heimdall CMake module provides seamless integration for SBOM generation:
- Automatic SBOM Generation: SBOMs are generated automatically during the build process
- Multiple Format Support: Generate SPDX and CycloneDX formats simultaneously
- Debug Information Integration: Automatically extract debug information when available
- Dependency Analysis: Analyze both direct and transitive dependencies
- Customizable Output: Configure output directories, file names, and formats
- Build System Integration: Works with any CMake-based build system
Makefile Integration:
# Makefile
CXX = g++
CXXFLAGS = -std=c++17 -O2 -g -Wall -Wextra
TARGET = myapp
SOURCES = main.cpp calculator.cpp utils.cpp
$(TARGET): $(SOURCES)
$(CXX) $(CXXFLAGS) -o $@ $^
./heimdall-sbom lib/heimdall-lld.so $@ --format spdx-2.3 --output sbom.spdx.json
CI/CD Integration with Heimdall Module
# GitHub Actions example
name: Build and Generate SBOM
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake
- name: Build Application with SBOM Generation
run: |
mkdir build && cd build
cmake ..
make
# SBOM files are automatically generated during build
- name: Upload SBOM Artifacts
uses: actions/upload-artifact@v3
with:
name: sbom-files
path: |
build/sbom/*.spdx.json
build/sbom/*.cdx.json
Advanced Usage with Debug Information
# Build with full debug information
g++ -std=c++17 -O2 -g3 -Wall -Wextra -fstack-protector-strong main.cpp calculator.cpp utils.cpp -o myapp
# Generate comprehensive SBOM with debug info
./heimdall-sbom lib/heimdall-lld.so myapp \
--format spdx-2.3 \
--output sbom.spdx.json \
--include-debug-info \
--verbose
C++-Specific Features
Template Analysis
Heimdall can analyze C++ template instantiations and provide detailed information about:
- Template parameter types
- Instantiated template classes and functions
- Template specialization information
- Template dependency relationships
Namespace Analysis
Comprehensive namespace analysis including:
- Namespace hierarchies and nesting
- Using declarations and namespace aliases
- Namespace-scoped functions and classes
- Cross-namespace dependencies
Class Hierarchy Analysis
Detailed class and inheritance analysis:
- Base class and derived class relationships
- Virtual function tables and polymorphism
- Class member functions and variables
- Access specifiers and visibility
Modern C++ Features
Support for modern C++ language features:
- C++11/14/17/20/23 language standards
- Lambda expressions and closures
- Smart pointers (unique_ptr, shared_ptr, weak_ptr)
- Move semantics and rvalue references
- Constexpr and consteval functions
- Concepts and constraints (C++20)
Conclusion
Heimdall's C/C++ extractor provides comprehensive SBOM generation by combining binary analysis with DWARF debug information parsing. This approach captures both the compiled binary information and the rich C/C++-specific metadata available in debug symbols, resulting in detailed, accurate SBOMs that support security analysis, compliance auditing, and dependency management.
The integration of DWARF debug information parsing significantly enhances the SBOM quality by providing C/C++-specific information that would not be available from binary analysis alone, including source file mappings, function signatures, class hierarchies, template instantiations, and namespace relationships.
The C/C++ extractor is particularly valuable for complex C++ applications on embedded devices that use modern language features, templates, and sophisticated class hierarchies, providing detailed insights into the application's structure and dependencies.