Repository navigation
Description
Background and Motivation
Currently, the bpf2go tool only supports compiling a single source file at a time. This limits our ability to create modular eBPF programs composed of multiple source files. Supporting multiple source files would enable better code organization, reusability, and testability for eBPF programs -- improving the developer experience.
Use Cases
- Modular Components: Develop reusable eBPF components that can be shared across multiple programs. Complex eBPF programs could be broken into logical components with separate source files
- Testability: Create test harnesses for eBPF code without including test code in production builds
Concrete Example - RMID Allocation in Unvariance Collector
In the Unvariance Collector project, we need to allocate Resource Monitoring IDs (RMIDs) to processes. These RMIDs come from a limited space (typically 0 to ~460 on certain processors). We want to:
- Create a library for RMID allocation/deallocation with a free list
- Track metadata for each RMID and maintain state consistency
- Test this functionality in isolation
- Include this code in the main collector without the test harness
Ideally, we would:
- Develop the RMID allocation as a self-contained package with its own header file
- Create a test harness in a separate file that includes and tests this functionality
- Link both during testing
- Link just the RMID allocation code (without test harness) with the main collector
unvariance/collector#109 for more info
Proposed Implementation
After examining the codebase (particularly in cmd/bpf2go), I suggest the following changes:
-
Modify the
b2gstruct in main.go to accept multiple source files:- Change
SourceFile stringtoSourceFiles []string - Update the command-line parsing to collect multiple positional arguments
- Change
-
Refactor the convert() function:
- Extract the compilation logic in
convertfunction intocompileOne - When multiple source files are provided, compile each one in sequence
- This separation allows compiling multiple source files before linking
- Extract the compilation logic in
-
Add a linking step when multiple source files are provided:
- Create a new function in the gen package (e.g.,
Link) similar to existingCompile - The function would invoke
bpftool gen objectto combine multiple object files into one - Add the linking step when multiple source files are provided
- Create a new function in the gen package (e.g.,
-
Handle dependencies correctly when multiple files are used:
- Parse dependencies for each source file (already present)
- Merge the dependencies into a single set for the final object file (new functionality)
- Write dependencies (already present)
Backward Compatibility
When only one source file is provided, the tool should behave exactly as it does now. This ensures backward compatibility with existing workflows.
Related Issues and Discussions
-
[Discussion #1142](bpf2go should be able to generate Go code from object files built out-of-band #1142): This discussion considered generating Go code from a given object file, which would support this use case by allowing users to create multiple object files out-of-band and use bpftool to link them together. However, as mentioned in that discussion, this approach would require users to understand internal plumbing and handle target-specific details manually. Our proposal solves this by using bpf2go to build all object files automatically without exposing internal complexity.
-
[Issue #466](elf: support bpf object linking (
bpftool gen object) #466): This issue calls for support of BPF object linking and explicitly mentions bpftool gen object, which we intend to use. However, it focuses specifically on handling weak symbols. While this remains an open issue, users who don't use weak symbols shouldn't encounter these problems with our proposed multi-file support.
I'd be happy to work on implementing this feature. Looking forward to your feedback!
Activity
yonch commentedon Apr 23, 2025
@lmb I submitted a PR #1762 -- is this a contribution the team will accept, and if so, who would be a good reviewer to approach?
yonch commentedon Apr 28, 2025
@ti-mo can you help with #1762 ?
The project moved to libbpf-rs for now, but I'm happy to see this contribution through if done in the next few days while it's fresh. Would appreciate guidance!
ti-mo commentedon May 6, 2025
Thanks for the PR! What's the reason for the move to Rust, if I may ask? I've pulled in a few reviewers explicitly to get things moving.
Ack on the decision to require bpf2go manage the compilation of all objects, that will keep overall internal complexity and API surface down. If users want more control over the compilation process, we can always cater to specific use cases and add more knobs later on. This looks good as a first approach.
On the question of weak symbols, that's not an issue about bpf2go specifically, but rather of the library as a whole. The way bpf2go handles compilation and linking has little impact on this. However, including the feature in bpf2go may give a user the false impression that linked objects are fully supported in the lib, which may not be the case. It would be ideal if someone (you 🙂) could dogfood the implementation so the overall support gets iterated on quickly as issues pop up.
yonch commentedon May 7, 2025
The move to Rust was due to parquet libraries; we needed good object store support, and wanted to have control over the amount of buffer memory, and the arrow+parquet implementation in Rust provided an easy pathway.
On weak symbols, I did not deliberately use weak symbols, and this patch worked in our repository. I'll keep an eye out for any issues in future dealings with bpf2go.
Thank you for the PR comments! I'll try and get to those today.
ti-mo commentedon May 12, 2025
@yonch Thanks for elaborating! Let us know when you've got something ready.
yonch commentedon May 23, 2025
Hi folks I've been pretty swamped and haven't gotten around to these. Still on my plate but it is taking a back burner. If you find someone who wants to pick up where I left off I have no objection.