# eBPF from Go; First Steps


So I had this itch that I wanted to make a Go program compile to eBPF and be able to load that
program in the Linux kernel by use of `bpftool`.

As I [say in github.com/miekg/ebpf](https://github.com/miekg/ebpf/blob/main/README.md)

> eBPF in C? What am I, a farmer?

After much reading about eBPF and thinking about how that would work from Go, I figured that would
involve writing a Go compiler.

So I could:

1. hack the official Go compiler and (try to) add a eBPF target (which would probably never
be added as an official target because of all the constraints eBPF has).

2. create a complete stand-alone and new compiler that parses Go code and emits eBPF binary in
an ELF object.

3. find something else that already does (2) and works with constraint backends.

I thought a while about doing (2), but that just seemed A LOT OF WORK.

While searching I found [TinyGo](https://tinygo.org) which seems to do everything I want it to do,
except of course [output eBPF bytecode](https://github.com/tinygo-org/tinygo/issues/1015).

So TinyGo it is! For now at least, (2) is still an option -- although a distant one.

## First Steps

After forking and building TinyGo I need it to recognize (e)BPF (going to drop the 'e' going
forward) as a valid target.

Turns out this is relative easy: just create a `target/bpf.json` file with the "correct" values,
recompile tinygo (`make`), and voila:

~~~
% ./build/tinygo targets | grep bpf
bpf
~~~

The top of `target/bpf.json` now looks as:

~~~ json
{
	"llvm-target":   "bpf",
	"cpu":           "generic",
	"features":      "+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext",
	"build-tags":    ["tinygo.bpf"],
	"goos":          "linux",
    ...
~~~

The `llvm-target` might actually be correct, the rest is still BS (well `GOOS` might be OK too). But
my main goal here is to make TinyGo output (via llvm) BPF bytecode and take it from there.

