## Understanding `vmlinux.h` in BPF The `vmlinux.h` header is crucial for building BPF (Berkeley Packet Filter) programs that inspect core kernel data structures. ### What is `vmlinux.h`? `vmlinux.h` is a C header file that contains the layout of internal kernel data structures. This allows a BPF program to access internal information from the kernel. BPF programs that inspect internel kernel data structures should utilize a feature called CO-RE (Compile Once - Run Everywhere). In essence, CO-RE allows BPF programs to work safely across different kernel versions without needing to be recompiled for each one. NOTE: While a BPF program doesn't need a `vmlinux.h` file that perfectly matches the target kernel, it's important to regenerate it in some cases. For instance, if the program makes use of a new field added to a structure, you must create a new vmlinux.h to access that new field. ### How is `vmlinux.h` Generated? A `vmlinux.h` file is created from a `vmlinux` file (the raw, uncompressed kernel image with BTF info) using the `bpftool` utility. The command for this is: ```sh bpftool btf dump file /path/to/vmlinux format c > vmlinux.h ``` ### Architecture Considerations on Android A BPF program must be compiled with a vmlinux.h file that matches the architecture of the target kernel. + *`64-bit` Systems*: On `64-bit` Android systems (either `arm64` or `x86_64`), this is straightforward. The `64-bit` userspace (where the application runs) matches the `64-bit` kernel. + *`32-bit` Systems*: This is more complex on devices with a `32-bit` Android userspace (arm or x86). At the time the BPF program is built, it's impossible to know if the device's kernel will be `32-bit` or `64-bit`. Because of this uncertainty, the system defaults to assuming a `32-bit` userspace running on a `64-bit` kernel. As a result, BPF programs that rely on libbpf will be disabled at runtime on systems that have a `32-bit` kernel. ### How to Generate vmlinux.h for New Kernels When a new Android kernel version is released, a corresponding `vmlinux.h` can be generated by adding a new build rule to `system/bpf/include/vmlinux/Android.bp`. You can do this by simply copying the existing rule for the latest kernel version and modifying it for the new one.