Conversation
c5aba68 to
3b71af2
Compare
…n metadata Also removed ExtInfos.Assign and AssignMetadataToInstructions, their functionality was moved to the root package. The *Offsets types were converted to type aliases to make them passable to generic functions like take(). As discrete types, they would need explicit conversions, making them awkward to work with. Signed-off-by: Timo Beckers <[email protected]>
This was only opening the -el.elf file. Signed-off-by: Timo Beckers <[email protected]>
Programs (functions) can be defined as weak, allowing the program text to be overwritten by a non-weak candidate during a linking step. During linking, the linker will simply append all affected symbols' function bodies. The resulting ELF will contain both the original and the new instructions. However, the symbol table will only contain an entry for the 'winning' symbol. The bytes between the end of the symbol and the next symbol can be safely ignored. Up until now, we've made the assumption that whole sections should always be translated into Instructions. However, this will result in unnecessary Instructions being decoded in linked objects, and requires us to split the Instructions into symbols without knowledge of the original symbol size in the ELF. Instead of decoding in multiple stages, decode one symbol at a time and stop processing bytecode when the end of the symbol has been reached. This avoids unnecessary work and saves on allocations when decoding linked objects. Signed-off-by: Timo Beckers <[email protected]> Suggested-by: Dylan Reimerink <[email protected]>
Similar to the previous commit, legacy struct bpf_map_def map definitions are appended in the 'maps' ELF section, but only the winning one receives a symbol. This commit uses the BufferedSectionReader and only reads exactly what's mentioned in the symbol table. Some redundant btf.Var conversions/lookups were removed, along with some BTF sanity checks we've never seen fail. The library's job isn't strictly to scrutinize the ELF and BTF. The only checks that were kept exist to reduce the likelyhood of out-of-bounds reads. Signed-off-by: Timo Beckers <[email protected]> Suggested-by: Dylan Reimerink <[email protected]>
The ELF reader was updated to support per-symbol instruction decoding in a previous commit. This commit removes the guardrails that were supposed to prevent the user from loading invalid program sections if they contained multiple candidates for a function symbol. Loading weak functions is now allowed. Signed-off-by: Dylan Reimerink <[email protected]>
This commit adds testdata for ELF linking. `linked1.c` and `linked2.c` contain strong and weak symbols and are linked together using `bpftool gen object`. This commit also updates the toolchain image to include `bpftool`. Signed-off-by: Dylan Reimerink <[email protected]> Co-authored-by: Timo Beckers <[email protected]>
Test whether all maps in the ELF have a MaxEntries of 1 after linking, and whether all programs return 0 when running them after linking. Also adds a new testutils.SkipNonNativeEndian to skip a test when a given endianness doesn't match the host's endianness. Signed-off-by: Timo Beckers <[email protected]>
3b71af2 to
e928b3d
Compare
Contributor
|
Quick bench on the new instruction unmarshaler code: Alloc totals are down a significant amount, but LoadCollectionManyProgs is a pathological example. At least good to know we haven't regressed there. 🙂 |
ti-mo
approved these changes
Feb 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lets add support for ELF object linking, that is loading ELF files that have been linked.
In normal non-eBPF C programs it is very normal to have multiple compilation units (C files that compile to .o files) and then at the end to have a separate linker combine these into an executable. In the eBPF world we typically work with single compilation units which we turn into CollectionSpec's and then Collections.
However, libbpf does offer linker logic which can be used via the bpftool utility. You invoke it like
bpftool gen object out.o in1.o in2.o in3.o ..... In this linking process the contents of the sections are simply appended to each other, and the linker, and the linker keeps only the symbols that "win". The rule being that a strong symbol overwrites a weak symbol, so a strong symbol from in3.o will overwrite a weak symbol from in1.o. If multiple weak symbols are present then the first takes precedence. So a weak symbol in in1.o wins over one in in3.o.So, a practical example is our new testdata added in the PR, this is linker1.o (edited to only show .text symbols):
And here is linker2.o
This is the linked object:
Here you can see, specifically from the second column of the .text dump that both sections are combined. Crucially for the assumptions of the library, is that not the whole contents of the section should be used. We need to collect all symbols for a given section, and only consider the bits of the section indicated by a symbol (offset ; offset+size). The same is also true for maps.
Fixes: #466