ebpf
                                
                                 ebpf copied to clipboard
                                
                                    ebpf copied to clipboard
                            
                            
                            
                        Support for BTF_KIND_DECL_TAG and BTF_KIND_TYPE_TAG
Linux 5.18 added a two new BTF kinds DECL_TAG and TYPE_TAG. TYPE_TAG seems fine, the encoding for DECL_TAG looks like a headache.
Most relevant Linux commit: https://github.com/torvalds/linux/commit/7472d5a642c94a0ee1882ff3038de72ffe803a01
pahole only generates these kinds from v1.23 onwards:
- DECL_TAG https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?h=next&id=ec62499774c4bcac720706018385ced0c1f060ab
- TYPE_TAG https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?h=next&id=d99d551930cf4b4bc41eb5d68b7da69d718a6553
clang-14 is also required: https://reviews.llvm.org/D111199
- [x] Parse / skip the new types
- [ ] Omit encoding new types in Spec.marshal if the kernel doesn't understand them
- [ ] Export types from btf
With BTF-enabled kernels becoming generally available in distro's, we might need to think about tolerating/ignoring unknown types so older tools written with CO-RE are forwards-compatible with newer kernels.
Time for a btf.ReaderOptions of some sort? :)
BTF isn't self describing unfortunately, so skipping unknown types is not possible.
My current reading of this is that vmlinux BTF will only contain these new types if:
- clang >= 14
- pahole >= 1.23
- the kernel is built with clang instead of gcc
Not sure how many production kernels use clang instead of gcc.
An idea I've been kicking around: DECL_TAG and TYPE_TAG are a bit of a bodge to add stringly typed metadata to the BTF wire format. What if we didn't represent them as Type, but instead added the metadata to Pointer or whatever?
type Pointer struct {
	...
	Tags []string
}
When decoding BTF we'd add TYPE_TAGs to Pointer.Tags and during marshaling we'd create TYPE_TAG on the fly. Similar for DECL_TAG which applies to Struct and Union (and others?) This is the best solution from an API perspective, it's very easy to add and remove tags from a Type.
Downsides:
- We're creating a mismatch with upstream BTF. With this approach it would be impossible to get the type ID of a *_TAG, so if we ever need to pass such an ID to the kernel we'd be in a pickle.
- We might also have to add Tagsto a large number of Types.
- We'd have to follow tag2 -> tag1 -> typechains during decoding somehow.