162306a36Sopenharmony_ci.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci================ 462306a36Sopenharmony_cibpftool-gen 562306a36Sopenharmony_ci================ 662306a36Sopenharmony_ci------------------------------------------------------------------------------- 762306a36Sopenharmony_citool for BPF code-generation 862306a36Sopenharmony_ci------------------------------------------------------------------------------- 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci:Manual section: 8 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci.. include:: substitutions.rst 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciSYNOPSIS 1562306a36Sopenharmony_ci======== 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci **bpftool** [*OPTIONS*] **gen** *COMMAND* 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci *OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } } 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci *COMMAND* := { **object** | **skeleton** | **help** } 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciGEN COMMANDS 2462306a36Sopenharmony_ci============= 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...] 2762306a36Sopenharmony_ci| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*] 2862306a36Sopenharmony_ci| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*] 2962306a36Sopenharmony_ci| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...] 3062306a36Sopenharmony_ci| **bpftool** **gen help** 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciDESCRIPTION 3362306a36Sopenharmony_ci=========== 3462306a36Sopenharmony_ci **bpftool gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...] 3562306a36Sopenharmony_ci Statically link (combine) together one or more *INPUT_FILE*'s 3662306a36Sopenharmony_ci into a single resulting *OUTPUT_FILE*. All the files involved 3762306a36Sopenharmony_ci are BPF ELF object files. 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci The rules of BPF static linking are mostly the same as for 4062306a36Sopenharmony_ci user-space object files, but in addition to combining data 4162306a36Sopenharmony_ci and instruction sections, .BTF and .BTF.ext (if present in 4262306a36Sopenharmony_ci any of the input files) data are combined together. .BTF 4362306a36Sopenharmony_ci data is deduplicated, so all the common types across 4462306a36Sopenharmony_ci *INPUT_FILE*'s will only be represented once in the resulting 4562306a36Sopenharmony_ci BTF information. 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci BPF static linking allows to partition BPF source code into 4862306a36Sopenharmony_ci individually compiled files that are then linked into 4962306a36Sopenharmony_ci a single resulting BPF object file, which can be used to 5062306a36Sopenharmony_ci generated BPF skeleton (with **gen skeleton** command) or 5162306a36Sopenharmony_ci passed directly into **libbpf** (using **bpf_object__open()** 5262306a36Sopenharmony_ci family of APIs). 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci **bpftool gen skeleton** *FILE* 5562306a36Sopenharmony_ci Generate BPF skeleton C header file for a given *FILE*. 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci BPF skeleton is an alternative interface to existing libbpf 5862306a36Sopenharmony_ci APIs for working with BPF objects. Skeleton code is intended 5962306a36Sopenharmony_ci to significantly shorten and simplify code to load and work 6062306a36Sopenharmony_ci with BPF programs from userspace side. Generated code is 6162306a36Sopenharmony_ci tailored to specific input BPF object *FILE*, reflecting its 6262306a36Sopenharmony_ci structure by listing out available maps, program, variables, 6362306a36Sopenharmony_ci etc. Skeleton eliminates the need to lookup mentioned 6462306a36Sopenharmony_ci components by name. Instead, if skeleton instantiation 6562306a36Sopenharmony_ci succeeds, they are populated in skeleton structure as valid 6662306a36Sopenharmony_ci libbpf types (e.g., **struct bpf_map** pointer) and can be 6762306a36Sopenharmony_ci passed to existing generic libbpf APIs. 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci In addition to simple and reliable access to maps and 7062306a36Sopenharmony_ci programs, skeleton provides a storage for BPF links (**struct 7162306a36Sopenharmony_ci bpf_link**) for each BPF program within BPF object. When 7262306a36Sopenharmony_ci requested, supported BPF programs will be automatically 7362306a36Sopenharmony_ci attached and resulting BPF links stored for further use by 7462306a36Sopenharmony_ci user in pre-allocated fields in skeleton struct. For BPF 7562306a36Sopenharmony_ci programs that can't be automatically attached by libbpf, 7662306a36Sopenharmony_ci user can attach them manually, but store resulting BPF link 7762306a36Sopenharmony_ci in per-program link field. All such set up links will be 7862306a36Sopenharmony_ci automatically destroyed on BPF skeleton destruction. This 7962306a36Sopenharmony_ci eliminates the need for users to manage links manually and 8062306a36Sopenharmony_ci rely on libbpf support to detach programs and free up 8162306a36Sopenharmony_ci resources. 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci Another facility provided by BPF skeleton is an interface to 8462306a36Sopenharmony_ci global variables of all supported kinds: mutable, read-only, 8562306a36Sopenharmony_ci as well as extern ones. This interface allows to pre-setup 8662306a36Sopenharmony_ci initial values of variables before BPF object is loaded and 8762306a36Sopenharmony_ci verified by kernel. For non-read-only variables, the same 8862306a36Sopenharmony_ci interface can be used to fetch values of global variables on 8962306a36Sopenharmony_ci userspace side, even if they are modified by BPF code. 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci During skeleton generation, contents of source BPF object 9262306a36Sopenharmony_ci *FILE* is embedded within generated code and is thus not 9362306a36Sopenharmony_ci necessary to keep around. This ensures skeleton and BPF 9462306a36Sopenharmony_ci object file are matching 1-to-1 and always stay in sync. 9562306a36Sopenharmony_ci Generated code is dual-licensed under LGPL-2.1 and 9662306a36Sopenharmony_ci BSD-2-Clause licenses. 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci It is a design goal and guarantee that skeleton interfaces 9962306a36Sopenharmony_ci are interoperable with generic libbpf APIs. User should 10062306a36Sopenharmony_ci always be able to use skeleton API to create and load BPF 10162306a36Sopenharmony_ci object, and later use libbpf APIs to keep working with 10262306a36Sopenharmony_ci specific maps, programs, etc. 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci As part of skeleton, few custom functions are generated. 10562306a36Sopenharmony_ci Each of them is prefixed with object name. Object name can 10662306a36Sopenharmony_ci either be derived from object file name, i.e., if BPF object 10762306a36Sopenharmony_ci file name is **example.o**, BPF object name will be 10862306a36Sopenharmony_ci **example**. Object name can be also specified explicitly 10962306a36Sopenharmony_ci through **name** *OBJECT_NAME* parameter. The following 11062306a36Sopenharmony_ci custom functions are provided (assuming **example** as 11162306a36Sopenharmony_ci the object name): 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci - **example__open** and **example__open_opts**. 11462306a36Sopenharmony_ci These functions are used to instantiate skeleton. It 11562306a36Sopenharmony_ci corresponds to libbpf's **bpf_object__open**\ () API. 11662306a36Sopenharmony_ci **_opts** variants accepts extra **bpf_object_open_opts** 11762306a36Sopenharmony_ci options. 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci - **example__load**. 12062306a36Sopenharmony_ci This function creates maps, loads and verifies BPF 12162306a36Sopenharmony_ci programs, initializes global data maps. It corresponds to 12262306a36Sopenharmony_ci libppf's **bpf_object__load**\ () API. 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci - **example__open_and_load** combines **example__open** and 12562306a36Sopenharmony_ci **example__load** invocations in one commonly used 12662306a36Sopenharmony_ci operation. 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci - **example__attach** and **example__detach** 12962306a36Sopenharmony_ci This pair of functions allow to attach and detach, 13062306a36Sopenharmony_ci correspondingly, already loaded BPF object. Only BPF 13162306a36Sopenharmony_ci programs of types supported by libbpf for auto-attachment 13262306a36Sopenharmony_ci will be auto-attached and their corresponding BPF links 13362306a36Sopenharmony_ci instantiated. For other BPF programs, user can manually 13462306a36Sopenharmony_ci create a BPF link and assign it to corresponding fields in 13562306a36Sopenharmony_ci skeleton struct. **example__detach** will detach both 13662306a36Sopenharmony_ci links created automatically, as well as those populated by 13762306a36Sopenharmony_ci user manually. 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci - **example__destroy** 14062306a36Sopenharmony_ci Detach and unload BPF programs, free up all the resources 14162306a36Sopenharmony_ci used by skeleton and BPF object. 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci If BPF object has global variables, corresponding structs 14462306a36Sopenharmony_ci with memory layout corresponding to global data data section 14562306a36Sopenharmony_ci layout will be created. Currently supported ones are: *.data*, 14662306a36Sopenharmony_ci *.bss*, *.rodata*, and *.kconfig* structs/data sections. 14762306a36Sopenharmony_ci These data sections/structs can be used to set up initial 14862306a36Sopenharmony_ci values of variables, if set before **example__load**. 14962306a36Sopenharmony_ci Afterwards, if target kernel supports memory-mapped BPF 15062306a36Sopenharmony_ci arrays, same structs can be used to fetch and update 15162306a36Sopenharmony_ci (non-read-only) data from userspace, with same simplicity 15262306a36Sopenharmony_ci as for BPF side. 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci **bpftool gen subskeleton** *FILE* 15562306a36Sopenharmony_ci Generate BPF subskeleton C header file for a given *FILE*. 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci Subskeletons are similar to skeletons, except they do not own 15862306a36Sopenharmony_ci the corresponding maps, programs, or global variables. They 15962306a36Sopenharmony_ci require that the object file used to generate them is already 16062306a36Sopenharmony_ci loaded into a *bpf_object* by some other means. 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci This functionality is useful when a library is included into a 16362306a36Sopenharmony_ci larger BPF program. A subskeleton for the library would have 16462306a36Sopenharmony_ci access to all objects and globals defined in it, without 16562306a36Sopenharmony_ci having to know about the larger program. 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci Consequently, there are only two functions defined 16862306a36Sopenharmony_ci for subskeletons: 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci - **example__open(bpf_object\*)** 17162306a36Sopenharmony_ci Instantiates a subskeleton from an already opened (but not 17262306a36Sopenharmony_ci necessarily loaded) **bpf_object**. 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci - **example__destroy()** 17562306a36Sopenharmony_ci Frees the storage for the subskeleton but *does not* unload 17662306a36Sopenharmony_ci any BPF programs or maps. 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...] 17962306a36Sopenharmony_ci Generate a minimum BTF file as *OUTPUT*, derived from a given 18062306a36Sopenharmony_ci *INPUT* BTF file, containing all needed BTF types so one, or 18162306a36Sopenharmony_ci more, given eBPF objects CO-RE relocations may be satisfied. 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF, 18462306a36Sopenharmony_ci libbpf, when loading an eBPF object, has to rely on external 18562306a36Sopenharmony_ci BTF files to be able to calculate CO-RE relocations. 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci Usually, an external BTF file is built from existing kernel 18862306a36Sopenharmony_ci DWARF data using pahole. It contains all the types used by 18962306a36Sopenharmony_ci its respective kernel image and, because of that, is big. 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci The min_core_btf feature builds smaller BTF files, customized 19262306a36Sopenharmony_ci to one or multiple eBPF objects, so they can be distributed 19362306a36Sopenharmony_ci together with an eBPF CO-RE based application, turning the 19462306a36Sopenharmony_ci application portable to different kernel versions. 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci Check examples bellow for more information how to use it. 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci **bpftool gen help** 19962306a36Sopenharmony_ci Print short help message. 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ciOPTIONS 20262306a36Sopenharmony_ci======= 20362306a36Sopenharmony_ci .. include:: common_options.rst 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci -L, --use-loader 20662306a36Sopenharmony_ci For skeletons, generate a "light" skeleton (also known as "loader" 20762306a36Sopenharmony_ci skeleton). A light skeleton contains a loader eBPF program. It does 20862306a36Sopenharmony_ci not use the majority of the libbpf infrastructure, and does not need 20962306a36Sopenharmony_ci libelf. 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciEXAMPLES 21262306a36Sopenharmony_ci======== 21362306a36Sopenharmony_ci**$ cat example1.bpf.c** 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci:: 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci #include <stdbool.h> 21862306a36Sopenharmony_ci #include <linux/ptrace.h> 21962306a36Sopenharmony_ci #include <linux/bpf.h> 22062306a36Sopenharmony_ci #include <bpf/bpf_helpers.h> 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci const volatile int param1 = 42; 22362306a36Sopenharmony_ci bool global_flag = true; 22462306a36Sopenharmony_ci struct { int x; } data = {}; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci SEC("raw_tp/sys_enter") 22762306a36Sopenharmony_ci int handle_sys_enter(struct pt_regs *ctx) 22862306a36Sopenharmony_ci { 22962306a36Sopenharmony_ci static long my_static_var; 23062306a36Sopenharmony_ci if (global_flag) 23162306a36Sopenharmony_ci my_static_var++; 23262306a36Sopenharmony_ci else 23362306a36Sopenharmony_ci data.x += param1; 23462306a36Sopenharmony_ci return 0; 23562306a36Sopenharmony_ci } 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci**$ cat example2.bpf.c** 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci:: 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci #include <linux/ptrace.h> 24262306a36Sopenharmony_ci #include <linux/bpf.h> 24362306a36Sopenharmony_ci #include <bpf/bpf_helpers.h> 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci struct { 24662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 24762306a36Sopenharmony_ci __uint(max_entries, 128); 24862306a36Sopenharmony_ci __type(key, int); 24962306a36Sopenharmony_ci __type(value, long); 25062306a36Sopenharmony_ci } my_map SEC(".maps"); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci SEC("raw_tp/sys_exit") 25362306a36Sopenharmony_ci int handle_sys_exit(struct pt_regs *ctx) 25462306a36Sopenharmony_ci { 25562306a36Sopenharmony_ci int zero = 0; 25662306a36Sopenharmony_ci bpf_map_lookup_elem(&my_map, &zero); 25762306a36Sopenharmony_ci return 0; 25862306a36Sopenharmony_ci } 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciThis is example BPF application with two BPF programs and a mix of BPF maps 26162306a36Sopenharmony_ciand global variables. Source code is split across two source code files. 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci**$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o** 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci**$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o** 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci**$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o** 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ciThis set of commands compiles *example1.bpf.c* and *example2.bpf.c* 27062306a36Sopenharmony_ciindividually and then statically links respective object files into the final 27162306a36Sopenharmony_ciBPF ELF object file *example.bpf.o*. 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci**$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h** 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci:: 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci /* THIS FILE IS AUTOGENERATED! */ 28062306a36Sopenharmony_ci #ifndef __EXAMPLE_SKEL_H__ 28162306a36Sopenharmony_ci #define __EXAMPLE_SKEL_H__ 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci #include <stdlib.h> 28462306a36Sopenharmony_ci #include <bpf/libbpf.h> 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci struct example { 28762306a36Sopenharmony_ci struct bpf_object_skeleton *skeleton; 28862306a36Sopenharmony_ci struct bpf_object *obj; 28962306a36Sopenharmony_ci struct { 29062306a36Sopenharmony_ci struct bpf_map *rodata; 29162306a36Sopenharmony_ci struct bpf_map *data; 29262306a36Sopenharmony_ci struct bpf_map *bss; 29362306a36Sopenharmony_ci struct bpf_map *my_map; 29462306a36Sopenharmony_ci } maps; 29562306a36Sopenharmony_ci struct { 29662306a36Sopenharmony_ci struct bpf_program *handle_sys_enter; 29762306a36Sopenharmony_ci struct bpf_program *handle_sys_exit; 29862306a36Sopenharmony_ci } progs; 29962306a36Sopenharmony_ci struct { 30062306a36Sopenharmony_ci struct bpf_link *handle_sys_enter; 30162306a36Sopenharmony_ci struct bpf_link *handle_sys_exit; 30262306a36Sopenharmony_ci } links; 30362306a36Sopenharmony_ci struct example__bss { 30462306a36Sopenharmony_ci struct { 30562306a36Sopenharmony_ci int x; 30662306a36Sopenharmony_ci } data; 30762306a36Sopenharmony_ci } *bss; 30862306a36Sopenharmony_ci struct example__data { 30962306a36Sopenharmony_ci _Bool global_flag; 31062306a36Sopenharmony_ci long int handle_sys_enter_my_static_var; 31162306a36Sopenharmony_ci } *data; 31262306a36Sopenharmony_ci struct example__rodata { 31362306a36Sopenharmony_ci int param1; 31462306a36Sopenharmony_ci } *rodata; 31562306a36Sopenharmony_ci }; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci static void example__destroy(struct example *obj); 31862306a36Sopenharmony_ci static inline struct example *example__open_opts( 31962306a36Sopenharmony_ci const struct bpf_object_open_opts *opts); 32062306a36Sopenharmony_ci static inline struct example *example__open(); 32162306a36Sopenharmony_ci static inline int example__load(struct example *obj); 32262306a36Sopenharmony_ci static inline struct example *example__open_and_load(); 32362306a36Sopenharmony_ci static inline int example__attach(struct example *obj); 32462306a36Sopenharmony_ci static inline void example__detach(struct example *obj); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci #endif /* __EXAMPLE_SKEL_H__ */ 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci**$ cat example.c** 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci:: 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci #include "example.skel.h" 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci int main() 33562306a36Sopenharmony_ci { 33662306a36Sopenharmony_ci struct example *skel; 33762306a36Sopenharmony_ci int err = 0; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci skel = example__open(); 34062306a36Sopenharmony_ci if (!skel) 34162306a36Sopenharmony_ci goto cleanup; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci skel->rodata->param1 = 128; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci err = example__load(skel); 34662306a36Sopenharmony_ci if (err) 34762306a36Sopenharmony_ci goto cleanup; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci err = example__attach(skel); 35062306a36Sopenharmony_ci if (err) 35162306a36Sopenharmony_ci goto cleanup; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci /* all libbpf APIs are usable */ 35462306a36Sopenharmony_ci printf("my_map name: %s\n", bpf_map__name(skel->maps.my_map)); 35562306a36Sopenharmony_ci printf("sys_enter prog FD: %d\n", 35662306a36Sopenharmony_ci bpf_program__fd(skel->progs.handle_sys_enter)); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci /* detach and re-attach sys_exit program */ 35962306a36Sopenharmony_ci bpf_link__destroy(skel->links.handle_sys_exit); 36062306a36Sopenharmony_ci skel->links.handle_sys_exit = 36162306a36Sopenharmony_ci bpf_program__attach(skel->progs.handle_sys_exit); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci printf("my_static_var: %ld\n", 36462306a36Sopenharmony_ci skel->bss->handle_sys_enter_my_static_var); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci cleanup: 36762306a36Sopenharmony_ci example__destroy(skel); 36862306a36Sopenharmony_ci return err; 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci**# ./example** 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci:: 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci my_map name: my_map 37662306a36Sopenharmony_ci sys_enter prog FD: 8 37762306a36Sopenharmony_ci my_static_var: 7 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ciThis is a stripped-out version of skeleton generated for above example code. 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cimin_core_btf 38262306a36Sopenharmony_ci------------ 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci**$ bpftool btf dump file 5.4.0-example.btf format raw** 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci:: 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci [1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none) 38962306a36Sopenharmony_ci [2] CONST '(anon)' type_id=1 39062306a36Sopenharmony_ci [3] VOLATILE '(anon)' type_id=1 39162306a36Sopenharmony_ci [4] ARRAY '(anon)' type_id=1 index_type_id=21 nr_elems=2 39262306a36Sopenharmony_ci [5] PTR '(anon)' type_id=8 39362306a36Sopenharmony_ci [6] CONST '(anon)' type_id=5 39462306a36Sopenharmony_ci [7] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=(none) 39562306a36Sopenharmony_ci [8] CONST '(anon)' type_id=7 39662306a36Sopenharmony_ci [9] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none) 39762306a36Sopenharmony_ci <long output> 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci**$ bpftool btf dump file one.bpf.o format raw** 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci:: 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci [1] PTR '(anon)' type_id=2 40462306a36Sopenharmony_ci [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=4 40562306a36Sopenharmony_ci 'ent' type_id=3 bits_offset=0 40662306a36Sopenharmony_ci 'id' type_id=7 bits_offset=64 40762306a36Sopenharmony_ci 'args' type_id=9 bits_offset=128 40862306a36Sopenharmony_ci '__data' type_id=12 bits_offset=512 40962306a36Sopenharmony_ci [3] STRUCT 'trace_entry' size=8 vlen=4 41062306a36Sopenharmony_ci 'type' type_id=4 bits_offset=0 41162306a36Sopenharmony_ci 'flags' type_id=5 bits_offset=16 41262306a36Sopenharmony_ci 'preempt_count' type_id=5 bits_offset=24 41362306a36Sopenharmony_ci <long output> 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci**$ bpftool gen min_core_btf 5.4.0-example.btf 5.4.0-smaller.btf one.bpf.o** 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci**$ bpftool btf dump file 5.4.0-smaller.btf format raw** 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci:: 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci [1] TYPEDEF 'pid_t' type_id=6 42262306a36Sopenharmony_ci [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=1 42362306a36Sopenharmony_ci 'args' type_id=4 bits_offset=128 42462306a36Sopenharmony_ci [3] STRUCT 'task_struct' size=9216 vlen=2 42562306a36Sopenharmony_ci 'pid' type_id=1 bits_offset=17920 42662306a36Sopenharmony_ci 'real_parent' type_id=7 bits_offset=18048 42762306a36Sopenharmony_ci [4] ARRAY '(anon)' type_id=5 index_type_id=8 nr_elems=6 42862306a36Sopenharmony_ci [5] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none) 42962306a36Sopenharmony_ci [6] TYPEDEF '__kernel_pid_t' type_id=8 43062306a36Sopenharmony_ci [7] PTR '(anon)' type_id=3 43162306a36Sopenharmony_ci [8] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED 43262306a36Sopenharmony_ci <end> 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ciNow, the "5.4.0-smaller.btf" file may be used by libbpf as an external BTF file 43562306a36Sopenharmony_ciwhen loading the "one.bpf.o" object into the "5.4.0-example" kernel. Note that 43662306a36Sopenharmony_cithe generated BTF file won't allow other eBPF objects to be loaded, just the 43762306a36Sopenharmony_ciones given to min_core_btf. 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci:: 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci LIBBPF_OPTS(bpf_object_open_opts, opts, .btf_custom_path = "5.4.0-smaller.btf"); 44262306a36Sopenharmony_ci struct bpf_object *obj; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci obj = bpf_object__open_file("one.bpf.o", &opts); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci ... 447