2026-02-19
Tags: bpf
A while back I was messing around with eBPF and I couldn't find any
good materials on using BPF [3mwithout[23m libbpf/LLVM/GCC (i.e.
rawdogging bytecode), so here's the resource I wished I had.
I'll be using Linux version 6.18 in this post; eBPF moves pretty
fast and the verifier gets smarter with every release, so the
information in this post might be out of date when you read this.
In conjunction with this post, I would recommend reading the
documentation (especially to supplement parts that might be
confusing):
== [1m[4meBPF Hello World[22m[24m
Linux exposes eBPF functionality to user space through the
[40m[35m`bpf`[39m[49m syscall, whose functionality is split
into several subcommands.
The basic flow of eBPF is to create an array of eBPF bytecode
instructions, pass it to the [40m`BPF_PROG_LOAD`[49m subcommand
along with a program type (e.g. socket filter), and then attach it
to the corresponding resource (like a socket or a kprobe).
[33mconst[0m[1m[37m [0m[1m[37mstd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@import[0m[1m[37m([0m[33m"std"[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mos[0m[1m[37m.[0m[1m[37mlinux[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mposix[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mposix[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mBPF[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mAF[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mAF[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mSOCK[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mSOCK[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mSOL[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mSOL[0m[1m[37m;[0m[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mSO[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mSO[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[33mpub[0m[1m[37m [0m[33mfn[0m[1m[37m [0m[37mmain[0m[1m[37m()[0m[1m[37m [0m[1m[36m![0m[1m[36mvoid[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37minsns[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m_[0m[1m[37m][0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33m// drop everything after the first 4 bytes[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m4[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mverifier_log[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x10000[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mlog[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mLog[0m[1m[37m{[0m[1m[37m [0m[1m[37m.[0m[1m[37mbuf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37mverifier_log[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mlevel[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m2[0m[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mprogfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[37mprog_load[0m[1m[37m(.[0m[1m[37msocket_filter[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37minsns[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mlog[0m[1m[37m,[0m[1m[37m [0m[33m"GPL v2"[0m[1m[36m<<[0m[37mfootnote[0m[1m[37m([0m[33m"2"[0m[1m[37m)[0m[1m[36m>>[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mdebug[0m[1m[37m.[0m[37mprint[0m[1m[37m([0m[33m"BPF Verifier output:[0m[33m\n[0m[33m{s}"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37msliceTo[0m[1m[37m([0m[1m[36m&[0m[1m[37mverifier_log[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)});[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37msocks[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m2[0m[1m[37m][0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mlinux[0m[1m[37m.[0m[37msocketpair[0m[1m[37m([0m[1m[37mAF[0m[1m[37m.[0m[1m[37mUNIX[0m[1m[37m,[0m[1m[37m [0m[1m[37mSOCK[0m[1m[37m.[0m[1m[37mDGRAM[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37msocks[0m[1m[37m)))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37me[0m[1m[36m|[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37me[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mlinux[0m[1m[37m.[0m[37msetsockopt[0m[1m[37m([0m[1m[37msocks[0m[1m[37m[[0m[1m[36m0[0m[1m[37m],[0m[1m[37m [0m[1m[37mSOL[0m[1m[37m.[0m[1m[37mSOCKET[0m[1m[37m,[0m[1m[37m [0m[1m[37mSO[0m[1m[37m.[0m[1m[37mATTACH_BPF[0m[1m[37m,[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mprogfd[0m[1m[37m),[0m[1m[37m [0m[1m[36m4[0m[1m[37m)))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37me[0m[1m[36m|[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37me[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37minput[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"Hello"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37mwrite[0m[1m[37m([0m[1m[37msocks[0m[1m[37m[[0m[1m[36m1[0m[1m[37m],[0m[1m[37m [0m[1m[37minput[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mbuf[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[37minput[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mn_read[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37mread[0m[1m[37m([0m[1m[37msocks[0m[1m[37m[[0m[1m[36m0[0m[1m[37m],[0m[1m[37m [0m[1m[36m&[0m[1m[37mbuf[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mlog[0m[1m[37m.[0m[37minfo[0m[1m[37m([0m[33m"Sent '{s}', received '{s}'"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37minput[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuf[0m[1m[37m[[0m[1m[36m0[0m[1m[37m..[0m[1m[37mn_read[0m[1m[37m][0m[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[1m[37mBPF Verifier output:[0m
[1m[37mfunc#0 @0[0m
[1m[37mLive regs before insn:[0m
[1m[37m 0: .......... (b7) r0 = 4[0m
[1m[37m 1: 0......... (95) exit[0m
[1m[37m0: R1=ctx() R10=fp0[0m
[1m[37m0: (b7) r0 = 4 ; R0=4[0m
[1m[37m1: (95) exit[0m
[1m[37mprocessed 2 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0[0m
[1m[37minfo: Sent 'Hello', received 'Hell'[0m
A socket filter is the OG type of eBPF program (and the namesake
for BPF), but in addition to high performance packet filtering,
eBPF can be used for syscall tracing, perf counter monitoring,
security policy enforcement, and everything in between
([40m`BPF_PROG_TYPE_XDP`[49m programs can even be offloaded to
run directly on the NIC, bypassing the kernel entirely[^fn:3]).
Now is a good time to mention that there are many restrictions on
how unprivileged users (i.e. processes without
[40m`CAP_SYS_ADMIN`[49m or [40m`CAP_BPF`[49m) can interact with
eBPF—as there should be, because a verified eBPF program runs with
more or less the same privileges as a kernel module.
The restrictions that I know of (not exhaustive) are as follows:
users are only allowed to use socket filters and cgroup socket
buffers
- Even for processes with [40m`CAP_BPF`[49m, many program
types are gated behind [40m`CAP_NET_ADMIN`[49m [6] and/or
[40m`CAP_PERFMON`[49m [7]
- Arithmetic with constant values in registers is changed to
use those constants directly (ALU sanitation)[^fn:5]
- Dead code is turned into [40m[35m`ja -1`[39m[49m to
force either an infinite loop or exit instead of
potentially executing beyond the bounds of the program
Clearly a lot of the more interesting stuff is beyond the reach of
unprivileged users, so I will henceforth be assuming that our
process has [40m`CAP_BPF`[49m, [40m`CAP_NET_ADMIN`[49m and
[40m`CAP_PERFMON`[49m (although not root).
== [1m[4mPassing data between kernel and user space[22m[24m
eBPF maps are data structures used for sharing data between eBPF
programs and user space (or other eBPF programs).
Contrary to the name, there are more types of eBPF maps than just
hashmaps, and eBPF maps are also used for other purposes like
storing string constants.
To demonstrate usage of eBPF maps, let's write a simple eBPF
program that drops a packet if it contains the substring "foobar".
The [40m[35m`strncmp`[39m[49m helper function looks like it
could be useful, but it's a little unclear what the eBPF equivalent
of a [40m`char *`[49m[24m is.
Let's check the source:
[33mstatic[0m[1m[37m [0m[33mconst[0m[1m[37m [0m[33mstruct[0m[1m[37m [0m[1m[37mbpf_func_proto[0m[1m[37m [0m[1m[37mbpf_strncmp_proto[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mfunc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mbpf_strncmp[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mgpl_only[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mret_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mRET_INTEGER[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37marg1_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mARG_PTR_TO_MEM[0m[1m[37m [0m[1m[36m|[0m[1m[37m [0m[1m[37mMEM_RDONLY[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37marg2_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mARG_CONST_SIZE[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37marg3_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mARG_PTR_TO_CONST_STR[0m[1m[37m,[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
Arguments 1 and 2 are self-explanatory, but what about argument 3?
Further inspection reveals that [40m`ARG_PTR_TO_CONST_STR`[49m is
checked by the function [40m[35m`check_reg_const_str`[39m[49m,
which ensures that a register points to an element (a null-
terminated string) of a read-only eBPF map.
Here's how we'll create such a map:
[33mfn[0m[1m[37m [0m[37mbpfStringMap[0m[1m[37m([0m[1m[37mstr[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m:[0m[1m[36m0[0m[1m[37m][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m)[0m[1m[37m [0m[1m[36m![0m[1m[37mposix[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mattr[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttr[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mzeroes[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mMapCreateAttr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m.[0m[1m[37mmap_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mMapType[0m[1m[37m.[0m[1m[37marray[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m.[0m[1m[37mkey_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[36mi32[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m.[0m[1m[37mvalue_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[36mu64[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m.[0m[1m[37mmax_entries[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33m// make this map read-only from the ebpf program[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_create[0m[1m[37m.[0m[1m[37mmap_flags[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mBPF_F_RDONLY_PROG[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[37mbpf[0m[1m[37m(.[0m[1m[37mmap_create[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mattr[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mMapCreateAttr[0m[1m[37m));[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mfd[0m[1m[36m:[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mrc[0m[1m[37m))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mrc[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mINVAL[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mMapTypeOrAttrInvalid[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mNOMEM[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mSystemResources[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mPERM[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mAccessDenied[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37merr[0m[1m[36m|[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37merr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[37mmap_update_elem[0m[1m[37m([0m[1m[37mfd[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mtoBytes[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mi32[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)),[0m[1m[37m [0m[1m[37mstr[0m[1m[37m,[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mANY[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttr[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mmap_elem[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mzeroes[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mMapElemAttr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mmap_elem[0m[1m[37m.[0m[1m[37mmap_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mfd[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33m// make this map read-only from userspace[0m
[1m[37m [0m[33mtry[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mlinux[0m[1m[37m.[0m[37mbpf[0m[1m[37m(.[0m[1m[37mmap_freeze[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mattr[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mMapElemAttr[0m[1m[37m))))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37merr[0m[1m[36m|[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37merr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mfd[0m[1m[37m;[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
Now we can iterate over the packet data one byte at a time,
returning [40m`DROP`[49m if [40m[35m`strncmp`[39m[49m returns
0.
[33mconst[0m[1m[37m [0m[1m[37mSK[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33menum[0m[1m[37m([0m[1m[36mi32[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mDROP[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37mPASS[0m[1m[37m,[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mmapfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[37mbpfStringMap[0m[1m[37m([0m[33m"foobar"[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37minsns[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m_[0m[1m[37m][0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr6[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mstx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mst[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// return if packet_len < 6 bytes[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mword[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr7[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjge[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr7[0m[1m[37m,[0m[1m[37m [0m[1m[36m6[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mPASS[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// load "foobar" into r9[0m
[1m[37m [0m[1m[37m.[0m[37mld_map_fd1[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37mmapfd[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mld_map_fd2[0m[1m[37m([0m[1m[37mmapfd[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mcall[0m[1m[37m(.[0m[1m[37mmap_lookup_elem[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjne[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mDROP[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr9[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// begin checking for "foobar"[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr8[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr6[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr8[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr4[0m[1m[37m,[0m[1m[37m [0m[1m[36m6[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mcall[0m[1m[37m(.[0m[1m[37mskb_load_bytes[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjlt[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// drop packet if it contains "foobar"[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[36m6[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr9[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[33m// bug in Zig std, call helper manually[0m
[1m[37m [0m[33m// .call(.strncmp),[0m
[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mcode[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mCALL[0m[1m[37m [0m[1m[36m|[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mJMP[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mdst[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37moff[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mimm[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m182[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjne[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mDROP[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr8[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjlt[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr8[0m[1m[37m,[0m[1m[37m [0m[1m[36m0x200[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m17[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mPASS[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mvar[0m[1m[37m [0m[1m[37mverifier_log[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x10000[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[33mvar[0m[1m[37m [0m[1m[37mlog[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mLog[0m[1m[37m{[0m[1m[37m [0m[1m[37m.[0m[1m[37mbuf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37mverifier_log[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mlevel[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m4[0m[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[33merrdefer[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mdebug[0m[1m[37m.[0m[37mprint[0m[1m[37m([0m[33m"BPF Verifier output:[0m[33m\n[0m[33m{s}"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37msliceTo[0m[1m[37m([0m[1m[36m&[0m[1m[37mverifier_log[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)});[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mprogfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[37mprog_load[0m[1m[37m(.[0m[1m[37msk_skb[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37minsns[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mlog[0m[1m[37m,[0m[1m[37m [0m[33m"GPL v2"[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37msockmapfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[37mmap_create[0m[1m[37m(.[0m[1m[37msockmap[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[36mi32[0m[1m[37m),[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[36mi32[0m[1m[37m),[0m[1m[37m [0m[1m[36m1[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mattr[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttr[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mprog_attach[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mtarget_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37msockmapfd[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mattach_bpf_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mprogfd[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mattach_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttachType[0m[1m[37m.[0m[1m[37msk_skb_stream_verdict[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mattach_flags[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mreplace_bpf_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mtry[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mlinux[0m[1m[37m.[0m[37mbpf[0m[1m[37m(.[0m[1m[37mprog_attach[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mattr[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mProgAttachAttr[0m[1m[37m))))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mACCES[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mUnsafeProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mFAULT[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33munreachable[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mINVAL[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mInvalidProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mPERM[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mPermissionDenied[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37merr[0m[1m[36m|[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37merr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[33mvar[0m[1m[37m [0m[1m[37msocks[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m2[0m[1m[37m][0m[1m[37mlinux[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mlinux[0m[1m[37m.[0m[37msocketpair[0m[1m[37m([0m[1m[37mAF[0m[1m[37m.[0m[1m[37mUNIX[0m[1m[37m,[0m[1m[37m [0m[1m[37mSOCK[0m[1m[37m.[0m[1m[37mDGRAM[0m[1m[37m [0m[1m[36m|[0m[1m[37m [0m[1m[37mSOCK[0m[1m[37m.[0m[1m[37mNONBLOCK[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37msocks[0m[1m[37m)))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37me[0m[1m[36m|[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37me[0m[1m[37m),[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[33mtry[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[37mmap_update_elem[0m[1m[37m([0m[1m[37msockmapfd[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mtoBytes[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mi32[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)),[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37msocks[0m[1m[37m[[0m[1m[36m0[0m[1m[37m]),[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mANY[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mpackets[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m_[0m[1m[37m][][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33m"foo"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"bar"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"foobar"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"fooba"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"snafu"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"ffoobarbaz"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33m"bazbarfoo"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mvar[0m[1m[37m [0m[1m[37mbuf[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x10[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[37mpackets[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mp[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37mwrite[0m[1m[37m([0m[1m[37msocks[0m[1m[37m[[0m[1m[36m1[0m[1m[37m],[0m[1m[37m [0m[1m[37mp[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mn_read[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37mread[0m[1m[37m([0m[1m[37msocks[0m[1m[37m[[0m[1m[36m0[0m[1m[37m],[0m[1m[37m [0m[1m[36m&[0m[1m[37mbuf[0m[1m[37m)[0m[1m[37m [0m[33mcatch[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mlog[0m[1m[37m.[0m[37minfo[0m[1m[37m([0m[33m"Sent '{s}', received '{s}'"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37mp[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuf[0m[1m[37m[[0m[1m[36m0[0m[1m[37m..[0m[1m[37mn_read[0m[1m[37m][0m[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[1m[37minfo: Sent 'foo', received 'foo'[0m
[1m[37minfo: Sent 'bar', received 'bar'[0m
[1m[37minfo: Sent 'foobar', received ''[0m
[1m[37minfo: Sent 'fooba', received 'fooba'[0m
[1m[37minfo: Sent 'snafu', received 'snafu'[0m
[1m[37minfo: Sent 'ffoobarbaz', received ''[0m
[1m[37minfo: Sent 'bazbarfoo', received 'bazbarfoo'[0m
== [1m[4mType information (BTF)[22m[24m
Even though the eBPF verifier uses type information extensively to
prove correctness of a program, almost all eBPF instructions don't
encode type information (besides integer width), so how do we
represent types in eBPF?
That's where BTF (BPF type format) comes in.
It's described as a format that "encodes the debug info related to
BPF program/map," but in my opinion this is misleading as it
encodes information useful for debugging [1mand[22m information
that is used by the eBPF verifier to check that your program is
valid.
That is to say, eBPF programs that use certain features
[1mrequire[22m BTF information in order to pass
verification.[^fn:6]
To see this in action, let's rewrite the previous program using the
[40m[35m`bpf_loop`[39m[49m helper and the
[40m[35m`bpf_strcmp`[39m[49m KFunc.
According to the docs the second argument of
[40m[35m`bpf_loop`[39m[49m, [40m`void *callback`[49m[24m, is
a pointer to a static function.
But wait, how do you define a (static) function within an eBPF
program?
The preferred verbiage for functions within a program seems to be
"subprograms", which are subsequences of instructions within the
list of instructions that you pass to the [40m[35m`bpf`[39m[49m
syscall.
To let the verifier know that your subprogram exists, you need to
use a special variant of the [40m`CALL`[49m or [40m`LD`[49m
opcodes, which jump to a program-local function or load a program-
local function pointer into a register, respectively.
[33mconst[0m[1m[37m [0m[1m[37mmain_insns[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m_[0m[1m[37m][0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mstx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mst[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mstx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// return if packet_len < 6 bytes[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mword[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr7[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjge[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr7[0m[1m[37m,[0m[1m[37m [0m[1m[36m6[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mPASS[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr7[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m5[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[37m_ld_funcall1[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[36m11[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[37m_ld_funcall2[0m[1m[37m([0m[1m[36m11[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr4[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[33m// .call(.loop),[0m
[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mcode[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mCALL[0m[1m[37m [0m[1m[36m|[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mJMP[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mdst[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37moff[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mimm[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m181[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjeq[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mPASS[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mSK[0m[1m[37m.[0m[1m[37mDROP[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mhelper_insns[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m_[0m[1m[37m][0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33m// r1 = loop index, r2 = ctx[0m
[1m[37m [0m[1m[37m.[0m[37mstx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mst[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// load skb->data[index..][0..6] onto the stack[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr3[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr3[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr4[0m[1m[37m,[0m[1m[37m [0m[1m[36m6[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mcall[0m[1m[37m(.[0m[1m[37mskb_load_bytes[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjeq[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33m// load "foobar" into r9[0m
[1m[37m [0m[1m[37m.[0m[37mld_map_fd1[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37mmapfd[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mld_map_fd2[0m[1m[37m([0m[1m[37mmapfd[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mcall[0m[1m[37m(.[0m[1m[37mmap_lookup_elem[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjne[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr9[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37madd[0m[1m[37m(.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x18[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr2[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr9[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mcode[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mCALL[0m[1m[37m [0m[1m[36m|[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mJMP[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mdst[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m2[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37moff[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mimm[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstrcmp_btf_id[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mjmp[0m[1m[37m(.[0m[1m[37mjne[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m [0m[1m[36m5[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr10[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mldx[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mst[0m[1m[37m(.[0m[1m[37mdouble_word[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mr1[0m[1m[37m,[0m[1m[37m [0m[1m[36m-[0m[1m[36m0x8[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m),[0m[1m[37m [0m[33m// store "1" on the callee's stack past the sk_buff ctx pointer[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m1[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mmov[0m[1m[37m(.[0m[1m[37mr0[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[37mexit[0m[1m[37m(),[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37mBPF Verifier output:[0m
[1m[37mmissing btf func_info[0m
[1m[37mverification time 13905 usec[0m
[1m[37mstack depth 24+0[0m
[1m[37mprocessed 13 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 0[0m
[1m[37merror: InvalidProgram[0m
[1m[37m/nix/store/pp3rdgdy6pnji9zm91qqcd6c86wljw58-zig-0.15.2/lib/zig/std/os/linux/bpf.zig:1710:5: 0x10c0602 in prog_load (tmp.vvZfe6NDKR)[0m
[1m[37m/tmp/nix-shell.6Qivnq/tmp.vvZfe6NDKR.zig:167:20: 0x10c15cf in main (tmp.vvZfe6NDKR)[0m
Ok, now the verifier is upset because we're missing [40m[35m`btf
func_info`[39m[49m.
Basically, if we want to use callbacks, we need to tell the
verifier the type signatures of all of our subprograms.
When loading our program, one of the attributes we can pass in is
[40m[35m`func_info`[39m[49m, which is a pointer to an array of
[40m[35m`bpf_func_info`[39m[49m structs, each of which contains
an offset of a subprogram and a "type id" for a
[40m`BTF_KIND_FUNC_PROTO`[49m representing that subprogram's type
information.
A type id is basically an index into the list of types contained
within a BTF object; because a BPF map or program can only
reference types within a single BTF object (not counting
btf_vmlinux), for all intents and purposes you should shove any
type information your program will need into one BTF object.
Fortunately, constructing a BTF object is fairly straightforward
(if not a little tedious), so I will let the code do the talking:
[33mconst[0m[1m[37m [0m[1m[37mBTF_FUNC[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33menum[0m[1m[37m([0m[1m[36mu32[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mSTATIC[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37mGLOBAL[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37mEXTERN[0m[1m[37m,[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mbpf_func_info[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mextern[0m[1m[37m [0m[33mstruct[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37minsn_off[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37mtype_id[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m,[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mBPFContext[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mopaque[0m[1m[37m [0m[1m[37m{};[0m[1m[37m[0m
[1m[37m[0m
[33mconst[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mstruct[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mtype_map[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[33mstruct[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m,[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[37m}[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{.{[0m[1m[37m [0m[33m"void"[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m [0m[1m[37m}},[0m[1m[37m[0m
[1m[37m [0m[1m[37mstrings[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"[0m[33m\x00[0m[33m"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37mbtf_bytes[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{},[0m[1m[37m[0m
[1m[37m [0m[1m[37mtype_id[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m1[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mpub[0m[1m[37m [0m[33mfn[0m[1m[37m [0m[37mindexOf[0m[1m[37m([0m[1m[37mself[0m[1m[36m:[0m[1m[37m [0m[1m[36m*[0m[33mconst[0m[1m[37m [0m[37m@This[0m[1m[37m(),[0m[1m[37m [0m[1m[37mT[0m[1m[36m:[0m[1m[37m [0m[1m[36mtype[0m[1m[37m)[0m[1m[37m [0m[1m[36m?[0m[1m[36musize[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33minline[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[37mself[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mtyp[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37meql[0m[1m[37m([0m[1m[36mu8[0m[1m[37m,[0m[1m[37m [0m[37m@typeName[0m[1m[37m([0m[1m[37mT[0m[1m[37m),[0m[1m[37m [0m[1m[37mtyp[0m[1m[37m.[0m[1m[37m@[0m[33m"0"[0m[1m[37m))[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mtyp[0m[1m[37m.[0m[1m[37m@[0m[33m"1"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[36mnull[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[33mfn[0m[1m[37m [0m[37mtypeToBtfContext[0m[1m[37m([0m[1m[37mT[0m[1m[36m:[0m[1m[37m [0m[1m[36mtype[0m[1m[37m,[0m[1m[37m [0m[33mcomptime[0m[1m[37m [0m[1m[37mctx[0m[1m[36m:[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m)[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mcomptime[0m[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mret[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mctx[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[37m@setEvalBranchQuota[0m[1m[37m([0m[1m[36m2000000[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37mctx[0m[1m[37m,[0m[1m[37m [0m[1m[37mT[0m[1m[37m))[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mctx[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m [0m[33melse[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37m.{.{[0m[1m[37m [0m[37m@typeName[0m[1m[37m([0m[1m[37mT[0m[1m[37m),[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[37m}};[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[37m@typeInfo[0m[1m[37m([0m[1m[37mT[0m[1m[37m))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mint[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37minfo[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mencoding[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37msignedness[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[37m.[0m[1m[37msigned[0m[1m[37m)[0m[1m[37m [0m[1m[36m1[0m[1m[37m [0m[33melse[0m[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mT[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[36mu8[0m[1m[37m)[0m[1m[37m [0m[1m[36m2[0m[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mint[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37msize[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mbits[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[1m[36m7[0m[1m[37m)[0m[1m[37m [0m[1m[36m/[0m[1m[37m [0m[1m[36m8[0m[1m[37m [0m[1m[36m*[0m[1m[37m [0m[1m[36m8[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mtoBytes[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[1m[37m([0m[1m[37mencoding[0m[1m[37m [0m[1m[36m<<[0m[1m[37m [0m[1m[36m24[0m[1m[37m)[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m [0m[1m[36m<<[0m[1m[37m [0m[1m[36m16[0m[1m[37m)[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37mbits[0m[1m[37m));[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[36mbool[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mencoding[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m4[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mint[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37msize[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[36mbool[0m[1m[37m)[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mtoBytes[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[1m[37m([0m[1m[37mencoding[0m[1m[37m [0m[1m[36m<<[0m[1m[37m [0m[1m[36m24[0m[1m[37m)[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m [0m[1m[36m<<[0m[1m[37m [0m[1m[36m16[0m[1m[37m)[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[37m@bitSizeOf[0m[1m[37m([0m[1m[36mbool[0m[1m[37m)));[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mfloat[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37minfo[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mfloat[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37msize[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mbits[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[1m[36m7[0m[1m[37m)[0m[1m[37m [0m[1m[36m/[0m[1m[37m [0m[1m[36m8[0m[1m[37m [0m[1m[36m*[0m[1m[37m [0m[1m[36m8[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"enum"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37minfo[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37menum_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[37m@sizeOf[0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mtag_type[0m[1m[37m))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[36m1[0m[1m[37m,[0m[1m[37m [0m[1m[36m2[0m[1m[37m,[0m[1m[37m [0m[1m[36m4[0m[1m[37m,[0m[1m[37m [0m[1m[36m8[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37ms[0m[1m[36m|[0m[1m[37m [0m[1m[37ms[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@compileError[0m[1m[37m([0m[33m"enum size must be 1/2/4/8 bytes"[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37mfields[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37menum_size[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[36m8[0m[1m[37m)[0m[1m[37m [0m[1m[37m.[0m[1m[37menum64[0m[1m[37m [0m[33melse[0m[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"enum"[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37msignedness[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37msize[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37menum_size[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33minline[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mfields[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mf[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37menum_size[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[36m8[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mEnum64[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mval_lo32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[36mi32[0m[1m[37m,[0m[1m[37m [0m[37m@bitCast[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[37m@truncate[0m[1m[37m([0m[1m[37mf[0m[1m[37m.[0m[1m[37mvalue[0m[1m[37m)))),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mval_hi32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[36mi32[0m[1m[37m,[0m[1m[37m [0m[37m@bitCast[0m[1m[37m([0m[37m@as[0m[1m[37m([0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[37m@truncate[0m[1m[37m([0m[1m[37mf[0m[1m[37m.[0m[1m[37mvalue[0m[1m[37m [0m[1m[36m>>[0m[1m[37m [0m[1m[36m32[0m[1m[37m)))),[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m [0m[33melse[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mEnum[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mval[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@bitCast[0m[1m[37m([0m[1m[37mf[0m[1m[37m.[0m[1m[37mvalue[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mf[0m[1m[37m.[0m[1m[37mname[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mpointer[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37minfo[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mchild[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[37mBPFContext[0m[1m[37m [0m[33mand[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37mret[0m[1m[37m,[0m[1m[37m [0m[1m[37mBPFContext[0m[1m[37m)[0m[1m[37m [0m[1m[36m==[0m[1m[37m [0m[1m[36mnull[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m[0m
[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mdecl_tag[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m1[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mDeclTag[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mcomponent_idx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mptr[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[33m"arg:ctx[0m[33m\x00[0m[33m"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37m.{.{[0m[1m[37m [0m[37m@typeName[0m[1m[37m([0m[1m[36m*[0m[1m[36mvoid[0m[1m[37m),[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m-[0m[1m[37m [0m[1m[36m1[0m[1m[37m [0m[1m[37m}};[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m [0m[33melse[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mcomptime[0m[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{};[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mnew[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37mtypeToBtfContext[0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mchild[0m[1m[37m,[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m[0m
[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mptr[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37mnew[0m[1m[37m,[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37mchild[0m[1m[37m).[0m[1m[36m?[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mDeclTag[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mcomponent_idx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mnew[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mnew[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mnew[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"fn"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37minfo[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mcc[0m[1m[36m:[0m[1m[37m [0m[1m[36mu16[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mcalling_convention[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mauto[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mBTF_FUNC[0m[1m[37m.[0m[1m[37mSTATIC[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mnaked[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mBTF_FUNC[0m[1m[37m.[0m[1m[37mGLOBAL[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@compileError[0m[1m[37m([0m[33m"only auto and naked calling conventions are allowed"[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mcomptime[0m[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{};[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37mtypeToBtfContext[0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mreturn_type[0m[1m[37m.[0m[1m[36m?[0m[1m[37m,[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mcc[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mfunc[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37minfo[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37mparams[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_1[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mfunc_proto[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37munused_2[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mkind_flag[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mfalse[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37msize_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37m_ctx[0m[1m[37m,[0m[1m[37m [0m[1m[37minfo[0m[1m[37m.[0m[1m[37mreturn_type[0m[1m[37m.[0m[1m[36m?[0m[1m[37m).[0m[1m[36m?[0m[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[33m"foo[0m[33m\x00[0m[33m"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33minline[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[37minfo[0m[1m[37m.[0m[1m[37mparams[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mp[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mp[0m[1m[37m.[0m[1m[36mtype[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mt[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37mtypeToBtfContext[0m[1m[37m([0m[1m[37mt[0m[1m[37m,[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m-=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mParam[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mtyp[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37m_ctx[0m[1m[37m,[0m[1m[37m [0m[1m[37mt[0m[1m[37m).[0m[1m[36m?[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m});[0m[1m[37m[0m
[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[33m"foo[0m[33m\x00[0m[33m"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m [0m[33melse[0m[1m[37m [0m[37m@compileError[0m[1m[37m([0m[33m"param type cannot be null"[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mret[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m_ctx[0m[1m[37m.[0m[1m[37mtype_map[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37marray[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"struct"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"union"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@compileError[0m[1m[37m([0m[33m"unimplemented"[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@compileError[0m[1m[37m([0m[37m@typeName[0m[1m[37m([0m[1m[37mT[0m[1m[37m)[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[33m" is unimplemented or unsupported"[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mret[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[33mfn[0m[1m[37m [0m[37mprogLoadWithBtf[0m[1m[37m([0m[1m[37mprog_type[0m[1m[36m:[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mProgType[0m[1m[37m,[0m[1m[37m [0m[1m[37mprogs[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m,[0m[1m[37m [0m[33mcomptime[0m[1m[37m [0m[1m[37mfuncs[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[36mtype[0m[1m[37m)[0m[1m[37m [0m[1m[36m![0m[1m[37mposix[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mfuncs[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m [0m[1m[36m>[0m[1m[37m [0m[1m[36m32[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[37m@compileError[0m[1m[37m([0m[33m"32 arguments max are supported"[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mcomptime[0m[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m{};[0m[1m[37m[0m
[1m[37m [0m[33mcomptime[0m[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mfunc_type_ids[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[37mfuncs[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m][0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33minline[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[37mfuncs[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mfunc_type_ids[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37mf[0m[1m[37m,[0m[1m[37m [0m[1m[36m*[0m[1m[37mft[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mctx[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mcomptime[0m[1m[37m [0m[37mtypeToBtfContext[0m[1m[37m([0m[1m[37mf[0m[1m[37m,[0m[1m[37m [0m[1m[37mctx[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mft[0m[1m[37m.[0m[1m[36m*[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mcomptime[0m[1m[37m [0m[1m[37mBTFContext[0m[1m[37m.[0m[37mindexOf[0m[1m[37m([0m[1m[36m&[0m[1m[37mctx[0m[1m[37m,[0m[1m[37m [0m[1m[37mf[0m[1m[37m).[0m[1m[36m?[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mbtf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37masBytes[0m[1m[37m([0m[1m[36m&[0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mHeader[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mmagic[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mmagic[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mversion[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m1[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mflags[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mhdr_len[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mHeader[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mtype_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mtype_len[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mstr_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mstr_len[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mbtf_bytes[0m[1m[37m [0m[1m[36m++[0m[1m[37m [0m[1m[37mctx[0m[1m[37m.[0m[1m[37mstrings[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mbtf_log[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x10000[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mdefer[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mdebug[0m[1m[37m.[0m[37mprint[0m[1m[37m([0m[33m"BTF Verifier output:[0m[33m\n[0m[33m{s}"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37msliceTo[0m[1m[37m([0m[1m[36m&[0m[1m[37mbtf_log[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)});[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mattr[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttr[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mzeroes[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mBtfLoadAttr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[37mbtf[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m.[0m[1m[37mbtf_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m.[0m[1m[37mbtf_log_buf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[36m&[0m[1m[37mbtf_log[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m.[0m[1m[37mbtf_log_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mbtf_log[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mbtf_load[0m[1m[37m.[0m[1m[37mbtf_log_level[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m2[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[37mbpf[0m[1m[37m(.[0m[1m[37mbtf_load[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mattr[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mBtfLoadAttr[0m[1m[37m));[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mbtf_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mrc[0m[1m[37m))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m,[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mrc[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mACCES[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mUnsafeProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mFAULT[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33munreachable[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mINVAL[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mInvalidProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mPERM[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mAccessDenied[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37merr[0m[1m[36m|[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37merr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mfunc_info[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[37mfuncs[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m][0m[1m[37mbpf_func_info[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37moffset[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37minsns[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m4096[0m[1m[37m][0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mInsn[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m&[0m[1m[37mfunc_info[0m[1m[37m,[0m[1m[37m [0m[1m[37mfunc_type_ids[0m[1m[37m,[0m[1m[37m [0m[1m[37mprogs[0m[1m[37m)[0m[1m[37m [0m[1m[36m|*[0m[1m[37mfi[0m[1m[37m,[0m[1m[37m [0m[1m[37mft[0m[1m[37m,[0m[1m[37m [0m[1m[37mp[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mfi[0m[1m[37m.[0m[1m[36m*[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37minsn_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37moffset[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37mtype_id[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mft[0m[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[37m@memcpy[0m[1m[37m([0m[1m[37minsns[0m[1m[37m[[0m[1m[37moffset[0m[1m[37m..][[0m[1m[36m0[0m[1m[37m..[0m[1m[37mp[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m],[0m[1m[37m [0m[1m[37mp[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37moffset[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mp[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mlicense[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"GPL v2"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mkernel_version[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mflags[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mbpf_log[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x10000[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33merrdefer[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mdebug[0m[1m[37m.[0m[37mprint[0m[1m[37m([0m[33m"BPF Verifier output:[0m[33m\n[0m[33m{s}"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37msliceTo[0m[1m[37m([0m[1m[36m&[0m[1m[37mbpf_log[0m[1m[37m,[0m[1m[37m [0m[1m[36m0[0m[1m[37m)});[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mAttr[0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37mzeroes[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mProgLoadAttr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mprog_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromEnum[0m[1m[37m([0m[1m[37mprog_type[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37minsns[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[36m&[0m[1m[37minsns[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37minsn_cnt[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37moffset[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mlicense[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[37mlicense[0m[1m[37m.[0m[1m[37mptr[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mkern_version[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mkernel_version[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mprog_flags[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mflags[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mlog_buf[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[36m&[0m[1m[37mbpf_log[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mlog_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mbpf_log[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mlog_level[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m2[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mprog_btf_fd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mbtf_fd[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mfunc_info_rec_size[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mbpf_func_info[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mfunc_info[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intFromPtr[0m[1m[37m([0m[1m[36m&[0m[1m[37mfunc_info[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37mattr[0m[1m[37m.[0m[1m[37mprog_load[0m[1m[37m.[0m[1m[37mfunc_info_cnt[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mfunc_info[0m[1m[37m.[0m[1m[37mlen[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mlinux[0m[1m[37m.[0m[37mbpf[0m[1m[37m(.[0m[1m[37mprog_load[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mattr[0m[1m[37m,[0m[1m[37m [0m[37m@sizeOf[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mProgLoadAttr[0m[1m[37m));[0m[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[37merrno[0m[1m[37m([0m[1m[37mrc[0m[1m[37m))[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mSUCCESS[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[37m@as[0m[1m[37m([0m[1m[37mposix[0m[1m[37m.[0m[1m[37mfd_t[0m[1m[37m,[0m[1m[37m [0m[37m@intCast[0m[1m[37m([0m[1m[37mrc[0m[1m[37m)),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mACCES[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mUnsafeProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mFAULT[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33munreachable[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mINVAL[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mInvalidProgram[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mPERM[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mAccessDenied[0m[1m[37m,[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[36m|[0m[1m[37merr[0m[1m[36m|[0m[1m[37m [0m[1m[37mposix[0m[1m[37m.[0m[37munexpectedErrno[0m[1m[37m([0m[1m[37merr[0m[1m[37m),[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
I make no claims that the code above is fundamentally correct
(several BTF types are left unimplemented, not to mention I doubt
it's idiomatic Zig), but it gets the job done for our purposes.
Once we have our BTF, we load it using the [40m`BPF_BTF_LOAD`[49m
subcommand, and we can then reference it by its fd when creating
maps or programs.
[33mconst[0m[1m[37m [0m[1m[37mprogfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[37mprogLoadWithBtf[0m[1m[37m(.[0m[1m[37msk_skb[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{[0m[1m[36m&[0m[1m[37mmain_insns[0m[1m[37m,[0m[1m[37m [0m[1m[36m&[0m[1m[37mhelper_insns[0m[1m[37m},[0m[1m[37m [0m[1m[36m&[0m[1m[37m.{[0m[33mfn[0m[1m[37m [0m[1m[37m([0m[1m[36m*[0m[1m[37mBPFContext[0m[1m[37m)[0m[1m[37m [0m[37mcallconv[0m[1m[37m(.[0m[1m[37mnaked[0m[1m[37m)[0m[1m[37m [0m[1m[36mu32[0m[1m[37m,[0m[1m[37m [0m[33mfn[0m[1m[37m [0m[1m[37m([0m[1m[36mu64[0m[1m[37m,[0m[1m[37m [0m[1m[36m*[0m[1m[36mvoid[0m[1m[37m)[0m[1m[37m [0m[1m[36mu64[0m[1m[37m});[0m[1m[37m[0m
The next thing to deal with is how to call a KFunc.
There's a variant of the [40m`CALL`[49m opcode that calls a
function by BTF ID for exactly this purpose, so the next logical
question is: how do we find the BTF ID for our KFunc?
The normal way to do this is generate [40m`vmlinux.h`[49m with
pahole/bpftools ([40m`bpftool btf dump file
/sys/kernel/btf/vmlinux format c > vmlinux.h`[49m[24m), but in
the spirit of roughing it, we'll forego that in favor of parsing
btf_vmlinux directly.
I say "parse", but we actually only care about a specific
[40m`BTF_KIND_FUNC`[49m with the name we're searching for, so my
implementation ignores everything besides that.
[33mconst[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[37m@import[0m[1m[37m([0m[33m"builtin"[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[33mfn[0m[1m[37m [0m[37mgetVmlinuxBtfIdFromName[0m[1m[37m([0m[1m[37mname[0m[1m[36m:[0m[1m[37m [0m[1m[37m[][0m[33mconst[0m[1m[37m [0m[1m[36mu8[0m[1m[37m)[0m[1m[37m [0m[1m[36m![0m[1m[36mu32[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mfd[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mposix[0m[1m[37m.[0m[37mopen[0m[1m[37m([0m[33m"/sys/kernel/btf/vmlinux"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mACCMODE[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m.[0m[1m[37mRDONLY[0m[1m[37m [0m[1m[37m},[0m[1m[37m [0m[1m[36m0o550[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[33mdefer[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mposix[0m[1m[37m.[0m[37mclose[0m[1m[37m([0m[1m[37mfd[0m[1m[37m);[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mbuf[0m[1m[36m:[0m[1m[37m [0m[1m[37m[[0m[1m[36m0x80[0m[1m[37m][0m[1m[36mu8[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36mundefined[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mf_reader[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mstd[0m[1m[37m.[0m[1m[37mfs[0m[1m[37m.[0m[1m[37mFile[0m[1m[37m.[0m[37mreader[0m[1m[37m(.{[0m[1m[37m [0m[1m[37m.[0m[1m[37mhandle[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mfd[0m[1m[37m [0m[1m[37m},[0m[1m[37m [0m[1m[36m&[0m[1m[37mbuf[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mreader[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m&[0m[1m[37mf_reader[0m[1m[37m.[0m[1m[37minterface[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mvar[0m[1m[37m [0m[1m[37mbtf_id[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[36m0[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mheader[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mHeader[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mstring_off[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mheader[0m[1m[37m.[0m[1m[37mhdr_len[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[1m[37mheader[0m[1m[37m.[0m[1m[37mstr_off[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mwhile[0m[1m[37m [0m[1m[37m([0m[1m[37mf_reader[0m[1m[37m.[0m[37mlogicalPos[0m[1m[37m()[0m[1m[37m [0m[1m[36m<[0m[1m[37m [0m[1m[37mstring_off[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mbtf_id[0m[1m[37m [0m[1m[36m+=[0m[1m[37m [0m[1m[36m1[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mbtf_type[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mType[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[33mswitch[0m[1m[37m [0m[1m[37m([0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mkind[0m[1m[37m)[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mfunc[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[33mconst[0m[1m[37m [0m[1m[37mpos[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mf_reader[0m[1m[37m.[0m[37mlogicalPos[0m[1m[37m();[0m[1m[37m[0m
[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mf_reader[0m[1m[37m.[0m[37mseekTo[0m[1m[37m([0m[1m[37mstring_off[0m[1m[37m [0m[1m[36m+[0m[1m[37m [0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37mname_off[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[33mif[0m[1m[37m [0m[1m[37m([0m[1m[37mstd[0m[1m[37m.[0m[1m[37mmem[0m[1m[37m.[0m[37meql[0m[1m[37m([0m[1m[36mu8[0m[1m[37m,[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeDelimiterExclusive[0m[1m[37m([0m[33m'\x00'[0m[1m[37m),[0m[1m[37m [0m[1m[37mname[0m[1m[37m))[0m[1m[37m [0m[33mreturn[0m[1m[37m [0m[1m[37mbtf_id[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mf_reader[0m[1m[37m.[0m[37mseekTo[0m[1m[37m([0m[1m[37mpos[0m[1m[37m);[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mint[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[33mextern[0m[1m[37m [0m[33mstruct[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[1m[37m_[0m[1m[36m:[0m[1m[37m [0m[1m[36mu32[0m[1m[37m [0m[1m[37m},[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m()),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37marray[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mArray[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m()),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"struct"[0m[1m[37m,[0m[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"union"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m0[0m[1m[37m..[0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mMember[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"enum"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m0[0m[1m[37m..[0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mEnum[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37menum64[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m0[0m[1m[37m..[0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mEnum64[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mfunc_proto[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m0[0m[1m[37m..[0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mParam[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37m@[0m[33m"var"[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mVar[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m()),[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mdatasec[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[33mfor[0m[1m[37m [0m[1m[37m([0m[1m[36m0[0m[1m[37m..[0m[1m[37mbtf_type[0m[1m[37m.[0m[1m[37minfo[0m[1m[37m.[0m[1m[37mvlen[0m[1m[37m)[0m[1m[37m [0m[1m[36m|[0m[1m[37m_[0m[1m[36m|[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mVarSecInfo[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m());[0m[1m[37m[0m
[1m[37m [0m[1m[37m},[0m[1m[37m[0m
[1m[37m [0m[1m[37m.[0m[1m[37mdecl_tag[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m_[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mtry[0m[1m[37m [0m[1m[37mreader[0m[1m[37m.[0m[37mtakeStruct[0m[1m[37m([0m[1m[37mBPF[0m[1m[37m.[0m[1m[37mbtf[0m[1m[37m.[0m[1m[37mDeclTag[0m[1m[37m,[0m[1m[37m [0m[1m[37mbuiltin[0m[1m[37m.[0m[1m[37mcpu[0m[1m[37m.[0m[1m[37march[0m[1m[37m.[0m[37mendian[0m[1m[37m()),[0m[1m[37m[0m
[1m[37m [0m[33melse[0m[1m[37m [0m[1m[36m=>[0m[1m[37m [0m[1m[37m{},[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[33mreturn[0m[1m[37m [0m[33merror[0m[1m[37m.[0m[1m[37mNotFound[0m[1m[37m;[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[1m[37mBTF Verifier output:[0m
[1m[37mmagic: 0xeb9f[0m
[1m[37mversion: 1[0m
[1m[37mflags: 0x0[0m
[1m[37mhdr_len: 24[0m
[1m[37mtype_off: 0[0m
[1m[37mtype_len: 132[0m
[1m[37mstr_off: 132[0m
[1m[37mstr_len: 29[0m
[1m[37mbtf_total_size: 185[0m
[1m[37m[1] FUNC foo type_id=2[0m
[1m[37m[2] FUNC_PROTO (anon) return=3 args=(5 foo)[0m
[1m[37m[3] INT (anon) size=32 bits_offset=0 nr_bits=32 encoding=(none)[0m
[1m[37m[4] DECL_TAG arg:ctx type=1 component_idx=0[0m
[1m[37m[5] PTR (anon) type_id=0[0m
[1m[37m[6] FUNC foo type_id=7[0m
[1m[37m[7] FUNC_PROTO (anon) return=8 args=(8 foo, 5 foo)[0m
[1m[37m[8] INT (anon) size=64 bits_offset=0 nr_bits=64 encoding=(none)[0m
[1m[37minfo: Sent 'foo', received 'foo'[0m
[1m[37minfo: Sent 'bar', received 'bar'[0m
[1m[37minfo: Sent 'foobar', received ''[0m
[1m[37minfo: Sent 'fooba', received 'fooba'[0m
[1m[37minfo: Sent 'snafu', received 'snafu'[0m
[1m[37minfo: Sent 'ffoobarbaz', received ''[0m
[1m[37minfo: Sent 'bazbarfoo', received 'bazbarfoo'[0m
Hopefully this has been educational and helpful if you have the
[9mmisfortune[29m pleasure of working with eBPF at the bytecode
level, whether you're a security researcher hunting for bugs in the
kernel or you just want to better understand how libbpf works.
Happy hacking!
[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mdescription[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"Rush E(bpf)"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37minputs[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mnixpkgs[0m[1m[36m.[0m[1m[37murl[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"github:NixOS/nixpkgs/nixpkgs-unstable"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mflake-utils[0m[1m[36m.[0m[1m[37murl[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"github:numtide/flake-utils"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37moutputs[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[1m[37mself[0m[1m[36m,[0m[1m[37m [0m[1m[37mnixpkgs[0m[1m[36m,[0m[1m[37m [0m[1m[37mflake-utils[0m[1m[37m [0m[1m[37m}:[0m[1m[37m[0m
[1m[37m [0m[1m[37m([0m[1m[37mflake-utils[0m[1m[36m.[0m[1m[37mlib[0m[1m[36m.[0m[1m[37meachDefaultSystem[0m[1m[37m [0m[1m[37m([0m[1m[37msystem[0m[1m[37m:[0m[1m[37m[0m
[1m[37m [0m[33mlet[0m[1m[37m[0m
[1m[37m [0m[33minherit[0m[1m[37m [0m[1m[37m([0m[1m[37mnixpkgs[0m[1m[37m)[0m[1m[37m [0m[1m[37mlib[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mfetchpatch'[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m([0m[33mimport[0m[1m[37m [0m[1m[37mnixpkgs[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[33minherit[0m[1m[37m [0m[1m[37msystem[0m[1m[37m;[0m[1m[37m [0m[1m[37m})[0m[1m[36m.[0m[1m[37mfetchpatch[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mpkgs'[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m([0m[33mimport[0m[1m[37m [0m[1m[37mnixpkgs[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[33minherit[0m[1m[37m [0m[1m[37msystem[0m[1m[37m;[0m[1m[37m [0m[1m[37m})[0m[1m[36m.[0m[1m[37mapplyPatches[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mname[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"fix-libcap-cross-compile"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37msrc[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mnixpkgs[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mpatches[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m [0m[1m[37m([0m[1m[37mfetchpatch'[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37murl[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"https://patch-diff.githubusercontent.com/raw/NixOS/nixpkgs/pull/461685.patch"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mhash[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"sha256-FXDc234uF05woQLYRvfVyA3FboWSmXnPhYOm8PeVs6Y="[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m})[0m[1m[37m [0m[1m[37m];[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[1m[37mpkgs[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mimport[0m[1m[37m [0m[1m[37mpkgs'[0m[1m[37m [0m[1m[37m{[0m[1m[37m [0m[33minherit[0m[1m[37m [0m[1m[37msystem[0m[1m[37m;[0m[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[33min[0m[1m[37m[0m
[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mpackages[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mkernel[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mpkgsCross[0m[1m[36m.[0m[1m[37mgnu64[0m[1m[36m.[0m[1m[37mlinuxKernel[0m[1m[36m.[0m[1m[37mkernels[0m[1m[36m.[0m[1m[37mlinux_6_18[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37minitramfs[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mrunCommand[0m[1m[37m [0m[33m"build-initramfs"[0m[1m[37m [0m[1m[37m{}[0m[1m[37m[0m
[1m[37m [0m[33m''[0m
[33m mkdir initramfs; cd initramfs[0m
[33m mkdir -pv {etc,proc,sys,usr/{bin,sbin}}[0m
[33m cp -a [0m[33m${[0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mpkgsCross[0m[1m[36m.[0m[1m[37mgnu64[0m[1m[36m.[0m[1m[37mpkgsStatic[0m[1m[36m.[0m[1m[37mbusybox[0m[33m}[0m[33m/{bin,sbin} .[0m
[33m chmod 755 ./{bin,sbin}[0m
[33m cp -a [0m[33m${[0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mpkgsCross[0m[1m[36m.[0m[1m[37mgnu64[0m[1m[36m.[0m[1m[37mpkgsStatic[0m[1m[36m.[0m[1m[37mlibcap[0m[33m}[0m[33m/bin .[0m
[33m[0m
[33m cat <<EOF > init[0m
[33m #!/bin/sh[0m
[33m mount -t proc none /proc[0m
[33m mount -t sysfs none /sys[0m
[33m mount -t devtmpfs devtmpfs /dev[0m
[33m[0m
[33m setcap 'cap_bpf=eip cap_net_admin=eip cap_perfmon=eip' /prog[0m
[33m[0m
[33m echo -e "\nBoot took \$(cut -d' ' -f1 /proc/uptime) seconds\n"[0m
[33m[0m
[33m setsid cttyhack setuidgid 1337 sh[0m
[33m[0m
[33m umount /proc[0m
[33m poweroff -d 0 -f[0m
[33m EOF[0m
[33m chmod +x init[0m
[33m[0m
[33m find . -print0 | [0m[33m${[0m[1m[37mlib[0m[1m[36m.[0m[1m[37mgetExe[0m[1m[37m [0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mcpio[0m[33m}[0m[33m --null -ov --format=newc > $out[0m
[33m ''[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37mrun[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mwriteShellScript[0m[1m[37m [0m[33m"run.sh"[0m[1m[37m [0m[33m''[0m
[33m [0m[33m${[0m[1m[37mpkgs[0m[1m[36m.[0m[1m[37mqemu[0m[33m}[0m[33m/bin/qemu-system-x86_64 \[0m
[33m [0m[33m''$[0m[33m{DEBUG:+ -s} \[0m
[33m -m 512 \[0m
[33m -kernel [0m[33m${[0m[1m[37mself[0m[1m[36m.[0m[1m[37mpackages[0m[1m[36m.[0m[33m${[0m[1m[37msystem[0m[33m}[0m[1m[36m.[0m[1m[37mkernel[0m[33m}[0m[33m/bzImage \[0m
[33m -initrd rootfs.cpio \[0m
[33m -append "console=ttyS0 loglevel=3 oops=panic panic=-1" \[0m
[33m -no-reboot \[0m
[33m -nographic \[0m
[33m -monitor /dev/null \[0m
[33m -serial unix:vm.sock,server,nowait[0m
[33m ''[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m[0m
[1m[37m [0m[1m[37mdevShells[0m[1m[36m.[0m[1m[37mdefault[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33mwith[0m[1m[37m [0m[1m[37mpkgs[0m[1m[37m;[0m[1m[37m [0m[1m[37mmkShellNoCC[0m[1m[37m [0m[1m[37m{[0m[1m[37m[0m
[1m[37m [0m[1m[37mpackages[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[1m[37m[[0m[1m[37m[0m
[1m[37m [0m[1m[37mzig_0_15[0m[1m[37m[0m
[1m[37m [0m[1m[37mlinux-scripts[0m[1m[37m[0m
[1m[37m [0m[1m[37m];[0m[1m[37m[0m
[1m[37m [0m[33m# https://github.com/NixOS/nixpkgs/pull/479423[0m[1m[37m[0m
[1m[37m [0m[1m[37mshellHook[0m[1m[37m [0m[1m[36m=[0m[1m[37m [0m[33m"unset ZIG_GLOBAL_CACHE_DIR"[0m[1m[37m;[0m[1m[37m[0m
[1m[37m [0m[1m[37m};[0m[1m[37m[0m
[1m[37m [0m[1m[37m}[0m[1m[37m[0m
[1m[37m [0m[1m[37m));[0m[1m[37m[0m
[1m[37m}[0m[1m[37m[0m
[^fn:1]: The original title of this post was "eBPF the Hard Way,"
which I have since realized is easily confused with Xmigrate's eBPF
tutorial [10] and Zhenzhong Wu's blog post [11] of the same name.
[^fn:2]: All of the code in this blog post is dual licensed under
the GPLv2-only [12] and the CC BY 4.0 [13]image [14]image [15].
[^fn:3]: eBPF programs will normally run as interpreted bytecode,
or native machine code if
[40m`/proc/sys/net/core/bpf_jit_enable`[49m is set to 1 (it may
be permanently set to 1 if your kernel was built with
[40m`CONFIG_BPF_JIT_ALWAYS_ON`[49m). There are security
implications for a system choosing to let users use the interpreter
or the JIT, the nuances of which are out of scope for this post.]
[^fn:4]: Including the rather exotic
[40m`BPF_PROG_TYPE_LIRC_MODE2`[49m for IR remotes.
[^fn:5]: While this was originally done to counter Spectre-style
attacks [16], it also has the effect of serving as a second line of
defense in case an attacker is able to convince the verifier that a
register is equal to some constant when it actually isn't.
[^fn:6]: This also means that if your kernel was configured with
[40m`CONFIG_BPF_SYSCALL`[49m but [4mwithout[24m
[40m`CONFIG_DEBUG_INFO_BTF`[49m, eBPF programs that require
information from btf_vmlinux cannot be verified.
References:
(HTM) [1] BPF ISA reference
(HTM) [2] BPF syscall reference
(HTM) [3] BTF reference
(HTM) [4] ebpf.io docs
(HTM) [5] 79
(HTM) [6] [40m`CAP_NET_ADMIN`[49m
(HTM) [7] [40m`CAP_PERFMON`[49m
(HTM) [8] KFuncs
(HTM) [9] Most
(HTM) [10] eBPF tutorial
(HTM) [11] blog post
(HTM) [12] GPLv2-only
(HTM) [13] CC BY 4.0
(HTM) [14] image
(HTM) [15] image
(HTM) [16] Spectre-style attacks
>=================================================================<
(DIR) Blog
(DIR) Writeups
(DIR) jp
copyright 2026 George Huebner
(HTM) email