cilium / ebpf

ebpf-go is a pure-Go library to read, modify and load eBPF programs and attach them to various hooks in the Linux kernel.
https://ebpf-go.dev
MIT License
6.31k stars 696 forks source link

Support for BTF_KIND_DECL_TAG and BTF_KIND_TYPE_TAG #713

Open lmb opened 2 years ago

lmb commented 2 years ago

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:

clang-14 is also required: https://reviews.llvm.org/D111199

ti-mo commented 2 years ago

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? :)

lmb commented 2 years ago

BTF isn't self describing unfortunately, so skipping unknown types is not possible.

lmb commented 2 years ago

My current reading of this is that vmlinux BTF will only contain these new types if:

Not sure how many production kernels use clang instead of gcc.

lmb commented 1 year ago

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: