> Why transpile, not generate BPF directly
> gc, the Go compiler, has no LLVM-based BPF backend. Adding one is a multi-year compiler project. rustc is built on LLVM and that's why Aya works. So gobee emits C and reuses clang's BPF backend, which gives us mature codegen, BTF, and CO-RE relocations for free.
I wonder if TinyGo (https://tinygo.org/) might be a better fit here:
> TinyGo brings the Go programming language to embedded systems and to the modern web by creating a new compiler based on LLVM.
I've not played with TinyGo much so would be interested to hear other peoples experiences.
We write quite a bit of BPF at work for the Parca-Agent project[1]. And we find that even C is sometimes too high level of a language paired with modern optimization techniques as the code you write often doesn’t come out that way the other and and we have to resort to weird hacks or write assembly directly to appease the verifier.
Apart from that, the usual qualms one might have about C are not really relevant in eBPF land, so I’ve actually found it the nicest experience writing C I’ve ever had, the verifier is just the price we have to pay.
I'm primarily a Go developer and love the language and will defend it for most use-cases, but to be honest BPF seems like Rust's place to shine.
Johannes Bechberge mades a blog post series about writing ebpf in pure Java : https://mostlynerdless.de/?s=ebpf&submit=Search Also several talks on youtube about this.
Remember, a lot of the memory safety benefits from go and rust and eBPF don't apply to the kernel eBPF! Kernel eBPF enforces semantics that verify array and loop bounds, memory accesses, and correctness of programs via the verifier. I think for most usecases, it is still best to write eBPF in C!
Noob question: why did they not choose to use WebAssembly in the kernel instead?
Lately I’ve been using Go for a personal project and I am so so happy about it. So so happy.
Fun fact: naming identifiers with leading underscores in C conflicts with reserved use and should always be avoided. I noticed Gobee declares double-underscores liberally.
Per 6.4.3 (Identifiers) of C23 (ISO/IEC 9899:202y N3886):
— All identifiers that begin with a double underscore (__) or begin with an underscore (_) followed by an uppercase letter are reserved for any use, except those identifiers which are lexically identical to keywords.
— All identifiers that begin with an underscore are reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
https://open-std.org/JTC1/SC22/WG14/www/docs/n3886.pdfAnd per 7.1.3 (Reserved identifiers) of C11 (ISO/IEC 9899:201x N1570):
— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdfClean implementation. One thing I always look for: how does this degrade when things go wrong? Good error handling is what separates weekend projects from tools people actually use.
Sorry, why wouldn’t I write in the native language?
The readme is an immediate giveaway of sloppiness
try adding bindings to it from javascript and using it to render jsx in the terminal
[dead]
[dead]
[flagged]
In eBPF-land you're going to be calling C functions in the kernel, and using (generally) C data types like structs and null-terminated strings. You can't do loops (loops are unrolled by the compiler), you can't do variadic functions, and you definitely can't take advantage of all the cool Go stuff like goroutines, select, context, etc.
I'm not really sure why you'd want to use this. If you're writing eBPF, you already need to know how to read C kernel source.