| .. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| |
| ================ |
| bpftool-gen |
| ================ |
| ------------------------------------------------------------------------------- |
| tool for BPF code-generation |
| ------------------------------------------------------------------------------- |
| |
| :Manual section: 8 |
| |
| .. include:: substitutions.rst |
| |
| SYNOPSIS |
| ======== |
| |
| **bpftool** [*OPTIONS*] **gen** *COMMAND* |
| |
| *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } } |
| |
| *COMMAND* := { **object** | **skeleton** | **help** } |
| |
| GEN COMMANDS |
| ============= |
| |
| | **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...] |
| | **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*] |
| | **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*] |
| | **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...] |
| | **bpftool** **gen help** |
| |
| DESCRIPTION |
| =========== |
| bpftool gen object *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...] |
| Statically link (combine) together one or more *INPUT_FILE*'s into a single |
| resulting *OUTPUT_FILE*. All the files involved are BPF ELF object files. |
| |
| The rules of BPF static linking are mostly the same as for user-space |
| object files, but in addition to combining data and instruction sections, |
| .BTF and .BTF.ext (if present in any of the input files) data are combined |
| together. .BTF data is deduplicated, so all the common types across |
| *INPUT_FILE*'s will only be represented once in the resulting BTF |
| information. |
| |
| BPF static linking allows to partition BPF source code into individually |
| compiled files that are then linked into a single resulting BPF object |
| file, which can be used to generated BPF skeleton (with **gen skeleton** |
| command) or passed directly into **libbpf** (using **bpf_object__open()** |
| family of APIs). |
| |
| bpftool gen skeleton *FILE* |
| Generate BPF skeleton C header file for a given *FILE*. |
| |
| BPF skeleton is an alternative interface to existing libbpf APIs for |
| working with BPF objects. Skeleton code is intended to significantly |
| shorten and simplify code to load and work with BPF programs from userspace |
| side. Generated code is tailored to specific input BPF object *FILE*, |
| reflecting its structure by listing out available maps, program, variables, |
| etc. Skeleton eliminates the need to lookup mentioned components by name. |
| Instead, if skeleton instantiation succeeds, they are populated in skeleton |
| structure as valid libbpf types (e.g., **struct bpf_map** pointer) and can |
| be passed to existing generic libbpf APIs. |
| |
| In addition to simple and reliable access to maps and programs, skeleton |
| provides a storage for BPF links (**struct bpf_link**) for each BPF program |
| within BPF object. When requested, supported BPF programs will be |
| automatically attached and resulting BPF links stored for further use by |
| user in pre-allocated fields in skeleton struct. For BPF programs that |
| can't be automatically attached by libbpf, user can attach them manually, |
| but store resulting BPF link in per-program link field. All such set up |
| links will be automatically destroyed on BPF skeleton destruction. This |
| eliminates the need for users to manage links manually and rely on libbpf |
| support to detach programs and free up resources. |
| |
| Another facility provided by BPF skeleton is an interface to global |
| variables of all supported kinds: mutable, read-only, as well as extern |
| ones. This interface allows to pre-setup initial values of variables before |
| BPF object is loaded and verified by kernel. For non-read-only variables, |
| the same interface can be used to fetch values of global variables on |
| userspace side, even if they are modified by BPF code. |
| |
| During skeleton generation, contents of source BPF object *FILE* is |
| embedded within generated code and is thus not necessary to keep around. |
| This ensures skeleton and BPF object file are matching 1-to-1 and always |
| stay in sync. Generated code is dual-licensed under LGPL-2.1 and |
| BSD-2-Clause licenses. |
| |
| It is a design goal and guarantee that skeleton interfaces are |
| interoperable with generic libbpf APIs. User should always be able to use |
| skeleton API to create and load BPF object, and later use libbpf APIs to |
| keep working with specific maps, programs, etc. |
| |
| As part of skeleton, few custom functions are generated. Each of them is |
| prefixed with object name. Object name can either be derived from object |
| file name, i.e., if BPF object file name is **example.o**, BPF object name |
| will be **example**. Object name can be also specified explicitly through |
| **name** *OBJECT_NAME* parameter. The following custom functions are |
| provided (assuming **example** as the object name): |
| |
| - **example__open** and **example__open_opts**. |
| These functions are used to instantiate skeleton. It corresponds to |
| libbpf's **bpf_object__open**\ () API. **_opts** variants accepts extra |
| **bpf_object_open_opts** options. |
| |
| - **example__load**. |
| This function creates maps, loads and verifies BPF programs, initializes |
| global data maps. It corresponds to libbpf's **bpf_object__load**\ () |
| API. |
| |
| - **example__open_and_load** combines **example__open** and |
| **example__load** invocations in one commonly used operation. |
| |
| - **example__attach** and **example__detach**. |
| This pair of functions allow to attach and detach, correspondingly, |
| already loaded BPF object. Only BPF programs of types supported by libbpf |
| for auto-attachment will be auto-attached and their corresponding BPF |
| links instantiated. For other BPF programs, user can manually create a |
| BPF link and assign it to corresponding fields in skeleton struct. |
| **example__detach** will detach both links created automatically, as well |
| as those populated by user manually. |
| |
| - **example__destroy**. |
| Detach and unload BPF programs, free up all the resources used by |
| skeleton and BPF object. |
| |
| If BPF object has global variables, corresponding structs with memory |
| layout corresponding to global data data section layout will be created. |
| Currently supported ones are: *.data*, *.bss*, *.rodata*, and *.kconfig* |
| structs/data sections. These data sections/structs can be used to set up |
| initial values of variables, if set before **example__load**. Afterwards, |
| if target kernel supports memory-mapped BPF arrays, same structs can be |
| used to fetch and update (non-read-only) data from userspace, with same |
| simplicity as for BPF side. |
| |
| bpftool gen subskeleton *FILE* |
| Generate BPF subskeleton C header file for a given *FILE*. |
| |
| Subskeletons are similar to skeletons, except they do not own the |
| corresponding maps, programs, or global variables. They require that the |
| object file used to generate them is already loaded into a *bpf_object* by |
| some other means. |
| |
| This functionality is useful when a library is included into a larger BPF |
| program. A subskeleton for the library would have access to all objects and |
| globals defined in it, without having to know about the larger program. |
| |
| Consequently, there are only two functions defined for subskeletons: |
| |
| - **example__open(bpf_object\*)**. |
| Instantiates a subskeleton from an already opened (but not necessarily |
| loaded) **bpf_object**. |
| |
| - **example__destroy()**. |
| Frees the storage for the subskeleton but *does not* unload any BPF |
| programs or maps. |
| |
| bpftool gen min_core_btf *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...] |
| Generate a minimum BTF file as *OUTPUT*, derived from a given *INPUT* BTF |
| file, containing all needed BTF types so one, or more, given eBPF objects |
| CO-RE relocations may be satisfied. |
| |
| When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF, libbpf, when |
| loading an eBPF object, has to rely on external BTF files to be able to |
| calculate CO-RE relocations. |
| |
| Usually, an external BTF file is built from existing kernel DWARF data |
| using pahole. It contains all the types used by its respective kernel image |
| and, because of that, is big. |
| |
| The min_core_btf feature builds smaller BTF files, customized to one or |
| multiple eBPF objects, so they can be distributed together with an eBPF |
| CO-RE based application, turning the application portable to different |
| kernel versions. |
| |
| Check examples below for more information on how to use it. |
| |
| bpftool gen help |
| Print short help message. |
| |
| OPTIONS |
| ======= |
| .. include:: common_options.rst |
| |
| -L, --use-loader |
| For skeletons, generate a "light" skeleton (also known as "loader" |
| skeleton). A light skeleton contains a loader eBPF program. It does not use |
| the majority of the libbpf infrastructure, and does not need libelf. |
| |
| EXAMPLES |
| ======== |
| **$ cat example1.bpf.c** |
| |
| :: |
| |
| #include <stdbool.h> |
| #include <linux/ptrace.h> |
| #include <linux/bpf.h> |
| #include <bpf/bpf_helpers.h> |
| |
| const volatile int param1 = 42; |
| bool global_flag = true; |
| struct { int x; } data = {}; |
| |
| SEC("raw_tp/sys_enter") |
| int handle_sys_enter(struct pt_regs *ctx) |
| { |
| static long my_static_var; |
| if (global_flag) |
| my_static_var++; |
| else |
| data.x += param1; |
| return 0; |
| } |
| |
| **$ cat example2.bpf.c** |
| |
| :: |
| |
| #include <linux/ptrace.h> |
| #include <linux/bpf.h> |
| #include <bpf/bpf_helpers.h> |
| |
| struct { |
| __uint(type, BPF_MAP_TYPE_HASH); |
| __uint(max_entries, 128); |
| __type(key, int); |
| __type(value, long); |
| } my_map SEC(".maps"); |
| |
| SEC("raw_tp/sys_exit") |
| int handle_sys_exit(struct pt_regs *ctx) |
| { |
| int zero = 0; |
| bpf_map_lookup_elem(&my_map, &zero); |
| return 0; |
| } |
| |
| **$ cat example3.bpf.c** |
| |
| :: |
| |
| #include <linux/ptrace.h> |
| #include <linux/bpf.h> |
| #include <bpf/bpf_helpers.h> |
| /* This header file is provided by the bpf_testmod module. */ |
| #include "bpf_testmod.h" |
| |
| int test_2_result = 0; |
| |
| /* bpf_Testmod.ko calls this function, passing a "4" |
| * and testmod_map->data. |
| */ |
| SEC("struct_ops/test_2") |
| void BPF_PROG(test_2, int a, int b) |
| { |
| test_2_result = a + b; |
| } |
| |
| SEC(".struct_ops") |
| struct bpf_testmod_ops testmod_map = { |
| .test_2 = (void *)test_2, |
| .data = 0x1, |
| }; |
| |
| This is example BPF application with three BPF programs and a mix of BPF |
| maps and global variables. Source code is split across three source code |
| files. |
| |
| **$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o** |
| |
| **$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o** |
| |
| **$ clang --target=bpf -g example3.bpf.c -o example3.bpf.o** |
| |
| **$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o example3.bpf.o** |
| |
| This set of commands compiles *example1.bpf.c*, *example2.bpf.c* and |
| *example3.bpf.c* individually and then statically links respective object |
| files into the final BPF ELF object file *example.bpf.o*. |
| |
| **$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h** |
| |
| :: |
| |
| /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
| |
| /* THIS FILE IS AUTOGENERATED! */ |
| #ifndef __EXAMPLE_SKEL_H__ |
| #define __EXAMPLE_SKEL_H__ |
| |
| #include <stdlib.h> |
| #include <bpf/libbpf.h> |
| |
| struct example { |
| struct bpf_object_skeleton *skeleton; |
| struct bpf_object *obj; |
| struct { |
| struct bpf_map *rodata; |
| struct bpf_map *data; |
| struct bpf_map *bss; |
| struct bpf_map *my_map; |
| struct bpf_map *testmod_map; |
| } maps; |
| struct { |
| struct example__testmod_map__bpf_testmod_ops { |
| const struct bpf_program *test_1; |
| const struct bpf_program *test_2; |
| int data; |
| } *testmod_map; |
| } struct_ops; |
| struct { |
| struct bpf_program *handle_sys_enter; |
| struct bpf_program *handle_sys_exit; |
| } progs; |
| struct { |
| struct bpf_link *handle_sys_enter; |
| struct bpf_link *handle_sys_exit; |
| } links; |
| struct example__bss { |
| struct { |
| int x; |
| } data; |
| int test_2_result; |
| } *bss; |
| struct example__data { |
| _Bool global_flag; |
| long int handle_sys_enter_my_static_var; |
| } *data; |
| struct example__rodata { |
| int param1; |
| } *rodata; |
| }; |
| |
| static void example__destroy(struct example *obj); |
| static inline struct example *example__open_opts( |
| const struct bpf_object_open_opts *opts); |
| static inline struct example *example__open(); |
| static inline int example__load(struct example *obj); |
| static inline struct example *example__open_and_load(); |
| static inline int example__attach(struct example *obj); |
| static inline void example__detach(struct example *obj); |
| |
| #endif /* __EXAMPLE_SKEL_H__ */ |
| |
| **$ cat example.c** |
| |
| :: |
| |
| #include "example.skel.h" |
| |
| int main() |
| { |
| struct example *skel; |
| int err = 0; |
| |
| skel = example__open(); |
| if (!skel) |
| goto cleanup; |
| |
| skel->rodata->param1 = 128; |
| |
| /* Change the value through the pointer of shadow type */ |
| skel->struct_ops.testmod_map->data = 13; |
| |
| err = example__load(skel); |
| if (err) |
| goto cleanup; |
| |
| /* The result of the function test_2() */ |
| printf("test_2_result: %d\n", skel->bss->test_2_result); |
| |
| err = example__attach(skel); |
| if (err) |
| goto cleanup; |
| |
| /* all libbpf APIs are usable */ |
| printf("my_map name: %s\n", bpf_map__name(skel->maps.my_map)); |
| printf("sys_enter prog FD: %d\n", |
| bpf_program__fd(skel->progs.handle_sys_enter)); |
| |
| /* detach and re-attach sys_exit program */ |
| bpf_link__destroy(skel->links.handle_sys_exit); |
| skel->links.handle_sys_exit = |
| bpf_program__attach(skel->progs.handle_sys_exit); |
| |
| printf("my_static_var: %ld\n", |
| skel->bss->handle_sys_enter_my_static_var); |
| |
| cleanup: |
| example__destroy(skel); |
| return err; |
| } |
| |
| **# ./example** |
| |
| :: |
| |
| test_2_result: 17 |
| my_map name: my_map |
| sys_enter prog FD: 8 |
| my_static_var: 7 |
| |
| This is a stripped-out version of skeleton generated for above example code. |
| |
| min_core_btf |
| ------------ |
| |
| **$ bpftool btf dump file 5.4.0-example.btf format raw** |
| |
| :: |
| |
| [1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none) |
| [2] CONST '(anon)' type_id=1 |
| [3] VOLATILE '(anon)' type_id=1 |
| [4] ARRAY '(anon)' type_id=1 index_type_id=21 nr_elems=2 |
| [5] PTR '(anon)' type_id=8 |
| [6] CONST '(anon)' type_id=5 |
| [7] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=(none) |
| [8] CONST '(anon)' type_id=7 |
| [9] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none) |
| <long output> |
| |
| **$ bpftool btf dump file one.bpf.o format raw** |
| |
| :: |
| |
| [1] PTR '(anon)' type_id=2 |
| [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=4 |
| 'ent' type_id=3 bits_offset=0 |
| 'id' type_id=7 bits_offset=64 |
| 'args' type_id=9 bits_offset=128 |
| '__data' type_id=12 bits_offset=512 |
| [3] STRUCT 'trace_entry' size=8 vlen=4 |
| 'type' type_id=4 bits_offset=0 |
| 'flags' type_id=5 bits_offset=16 |
| 'preempt_count' type_id=5 bits_offset=24 |
| <long output> |
| |
| **$ bpftool gen min_core_btf 5.4.0-example.btf 5.4.0-smaller.btf one.bpf.o** |
| |
| **$ bpftool btf dump file 5.4.0-smaller.btf format raw** |
| |
| :: |
| |
| [1] TYPEDEF 'pid_t' type_id=6 |
| [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=1 |
| 'args' type_id=4 bits_offset=128 |
| [3] STRUCT 'task_struct' size=9216 vlen=2 |
| 'pid' type_id=1 bits_offset=17920 |
| 'real_parent' type_id=7 bits_offset=18048 |
| [4] ARRAY '(anon)' type_id=5 index_type_id=8 nr_elems=6 |
| [5] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none) |
| [6] TYPEDEF '__kernel_pid_t' type_id=8 |
| [7] PTR '(anon)' type_id=3 |
| [8] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED |
| <end> |
| |
| Now, the "5.4.0-smaller.btf" file may be used by libbpf as an external BTF file |
| when loading the "one.bpf.o" object into the "5.4.0-example" kernel. Note that |
| the generated BTF file won't allow other eBPF objects to be loaded, just the |
| ones given to min_core_btf. |
| |
| :: |
| |
| LIBBPF_OPTS(bpf_object_open_opts, opts, .btf_custom_path = "5.4.0-smaller.btf"); |
| struct bpf_object *obj; |
| |
| obj = bpf_object__open_file("one.bpf.o", &opts); |
| |
| ... |