xref: /linux/tools/bpf/bpftool/Documentation/bpftool-gen.rst (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
143448428SQuentin Monnet.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
243448428SQuentin Monnet
3cb21ac58SAndrii Nakryiko================
4cb21ac58SAndrii Nakryikobpftool-gen
5cb21ac58SAndrii Nakryiko================
6cb21ac58SAndrii Nakryiko-------------------------------------------------------------------------------
7cb21ac58SAndrii Nakryikotool for BPF code-generation
8cb21ac58SAndrii Nakryiko-------------------------------------------------------------------------------
9cb21ac58SAndrii Nakryiko
10cb21ac58SAndrii Nakryiko:Manual section: 8
11cb21ac58SAndrii Nakryiko
12b6231815SQuentin Monnet.. include:: substitutions.rst
13b6231815SQuentin Monnet
14cb21ac58SAndrii NakryikoSYNOPSIS
15cb21ac58SAndrii Nakryiko========
16cb21ac58SAndrii Nakryiko
17cb21ac58SAndrii Nakryiko**bpftool** [*OPTIONS*] **gen** *COMMAND*
18cb21ac58SAndrii Nakryiko
19b6231815SQuentin Monnet*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } }
20cb21ac58SAndrii Nakryiko
21d80b2fcbSAndrii Nakryiko*COMMAND* := { **object** | **skeleton** | **help** }
22cb21ac58SAndrii Nakryiko
23cb21ac58SAndrii NakryikoGEN COMMANDS
24cb21ac58SAndrii Nakryiko=============
25cb21ac58SAndrii Nakryiko
26d80b2fcbSAndrii Nakryiko| **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
27c4122665SAndrii Nakryiko| **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*]
2800389c58SDelyan Kratunov| **bpftool** **gen subskeleton** *FILE* [**name** *OBJECT_NAME*]
291d1ffbf7SRafael David Tinoco| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
30cb21ac58SAndrii Nakryiko| **bpftool** **gen help**
31cb21ac58SAndrii Nakryiko
32cb21ac58SAndrii NakryikoDESCRIPTION
33cb21ac58SAndrii Nakryiko===========
34ea379b3cSRameez Rehmanbpftool gen object *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...]
35f7b68543SRameez Rehman    Statically link (combine) together one or more *INPUT_FILE*'s into a single
36f7b68543SRameez Rehman    resulting *OUTPUT_FILE*. All the files involved are BPF ELF object files.
37d80b2fcbSAndrii Nakryiko
38f7b68543SRameez Rehman    The rules of BPF static linking are mostly the same as for user-space
39f7b68543SRameez Rehman    object files, but in addition to combining data and instruction sections,
40f7b68543SRameez Rehman    .BTF and .BTF.ext (if present in any of the input files) data are combined
41f7b68543SRameez Rehman    together. .BTF data is deduplicated, so all the common types across
42f7b68543SRameez Rehman    *INPUT_FILE*'s will only be represented once in the resulting BTF
43f7b68543SRameez Rehman    information.
44d80b2fcbSAndrii Nakryiko
45f7b68543SRameez Rehman    BPF static linking allows to partition BPF source code into individually
46f7b68543SRameez Rehman    compiled files that are then linked into a single resulting BPF object
47f7b68543SRameez Rehman    file, which can be used to generated BPF skeleton (with **gen skeleton**
48f7b68543SRameez Rehman    command) or passed directly into **libbpf** (using **bpf_object__open()**
49d80b2fcbSAndrii Nakryiko    family of APIs).
50d80b2fcbSAndrii Nakryiko
51ea379b3cSRameez Rehmanbpftool gen skeleton *FILE*
52cb21ac58SAndrii Nakryiko    Generate BPF skeleton C header file for a given *FILE*.
53cb21ac58SAndrii Nakryiko
54f7b68543SRameez Rehman    BPF skeleton is an alternative interface to existing libbpf APIs for
55f7b68543SRameez Rehman    working with BPF objects. Skeleton code is intended to significantly
56f7b68543SRameez Rehman    shorten and simplify code to load and work with BPF programs from userspace
57f7b68543SRameez Rehman    side. Generated code is tailored to specific input BPF object *FILE*,
58f7b68543SRameez Rehman    reflecting its structure by listing out available maps, program, variables,
59f7b68543SRameez Rehman    etc. Skeleton eliminates the need to lookup mentioned components by name.
60f7b68543SRameez Rehman    Instead, if skeleton instantiation succeeds, they are populated in skeleton
61f7b68543SRameez Rehman    structure as valid libbpf types (e.g., **struct bpf_map** pointer) and can
62f7b68543SRameez Rehman    be passed to existing generic libbpf APIs.
63cb21ac58SAndrii Nakryiko
64f7b68543SRameez Rehman    In addition to simple and reliable access to maps and programs, skeleton
65f7b68543SRameez Rehman    provides a storage for BPF links (**struct bpf_link**) for each BPF program
66f7b68543SRameez Rehman    within BPF object. When requested, supported BPF programs will be
67f7b68543SRameez Rehman    automatically attached and resulting BPF links stored for further use by
68f7b68543SRameez Rehman    user in pre-allocated fields in skeleton struct. For BPF programs that
69f7b68543SRameez Rehman    can't be automatically attached by libbpf, user can attach them manually,
70f7b68543SRameez Rehman    but store resulting BPF link in per-program link field. All such set up
71f7b68543SRameez Rehman    links will be automatically destroyed on BPF skeleton destruction. This
72f7b68543SRameez Rehman    eliminates the need for users to manage links manually and rely on libbpf
73f7b68543SRameez Rehman    support to detach programs and free up resources.
74cb21ac58SAndrii Nakryiko
75f7b68543SRameez Rehman    Another facility provided by BPF skeleton is an interface to global
76f7b68543SRameez Rehman    variables of all supported kinds: mutable, read-only, as well as extern
77f7b68543SRameez Rehman    ones. This interface allows to pre-setup initial values of variables before
78f7b68543SRameez Rehman    BPF object is loaded and verified by kernel. For non-read-only variables,
79f7b68543SRameez Rehman    the same interface can be used to fetch values of global variables on
80cb21ac58SAndrii Nakryiko    userspace side, even if they are modified by BPF code.
81cb21ac58SAndrii Nakryiko
82f7b68543SRameez Rehman    During skeleton generation, contents of source BPF object *FILE* is
83f7b68543SRameez Rehman    embedded within generated code and is thus not necessary to keep around.
84f7b68543SRameez Rehman    This ensures skeleton and BPF object file are matching 1-to-1 and always
85f7b68543SRameez Rehman    stay in sync. Generated code is dual-licensed under LGPL-2.1 and
86cb21ac58SAndrii Nakryiko    BSD-2-Clause licenses.
87cb21ac58SAndrii Nakryiko
88f7b68543SRameez Rehman    It is a design goal and guarantee that skeleton interfaces are
89f7b68543SRameez Rehman    interoperable with generic libbpf APIs. User should always be able to use
90f7b68543SRameez Rehman    skeleton API to create and load BPF object, and later use libbpf APIs to
91f7b68543SRameez Rehman    keep working with specific maps, programs, etc.
92cb21ac58SAndrii Nakryiko
93f7b68543SRameez Rehman    As part of skeleton, few custom functions are generated. Each of them is
94f7b68543SRameez Rehman    prefixed with object name. Object name can either be derived from object
95f7b68543SRameez Rehman    file name, i.e., if BPF object file name is **example.o**, BPF object name
96f7b68543SRameez Rehman    will be **example**. Object name can be also specified explicitly through
97f7b68543SRameez Rehman    **name** *OBJECT_NAME* parameter. The following custom functions are
98f7b68543SRameez Rehman    provided (assuming **example** as the object name):
99cb21ac58SAndrii Nakryiko
100cb21ac58SAndrii Nakryiko    - **example__open** and **example__open_opts**.
101f7b68543SRameez Rehman      These functions are used to instantiate skeleton. It corresponds to
102f7b68543SRameez Rehman      libbpf's **bpf_object__open**\ () API. **_opts** variants accepts extra
103f7b68543SRameez Rehman      **bpf_object_open_opts** options.
104cb21ac58SAndrii Nakryiko
105cb21ac58SAndrii Nakryiko    - **example__load**.
106f7b68543SRameez Rehman      This function creates maps, loads and verifies BPF programs, initializes
107a86857d2SLin Yikai      global data maps. It corresponds to libbpf's **bpf_object__load**\ ()
108f7b68543SRameez Rehman      API.
109cb21ac58SAndrii Nakryiko
110cb21ac58SAndrii Nakryiko    - **example__open_and_load** combines **example__open** and
111f7b68543SRameez Rehman      **example__load** invocations in one commonly used operation.
112cb21ac58SAndrii Nakryiko
113a70f5d84SRameez Rehman    - **example__attach** and **example__detach**.
114f7b68543SRameez Rehman      This pair of functions allow to attach and detach, correspondingly,
115f7b68543SRameez Rehman      already loaded BPF object. Only BPF programs of types supported by libbpf
116f7b68543SRameez Rehman      for auto-attachment will be auto-attached and their corresponding BPF
117f7b68543SRameez Rehman      links instantiated. For other BPF programs, user can manually create a
118f7b68543SRameez Rehman      BPF link and assign it to corresponding fields in skeleton struct.
119f7b68543SRameez Rehman      **example__detach** will detach both links created automatically, as well
120f7b68543SRameez Rehman      as those populated by user manually.
121cb21ac58SAndrii Nakryiko
122a70f5d84SRameez Rehman    - **example__destroy**.
123f7b68543SRameez Rehman      Detach and unload BPF programs, free up all the resources used by
124f7b68543SRameez Rehman      skeleton and BPF object.
125cb21ac58SAndrii Nakryiko
126f7b68543SRameez Rehman    If BPF object has global variables, corresponding structs with memory
127f7b68543SRameez Rehman    layout corresponding to global data data section layout will be created.
128f7b68543SRameez Rehman    Currently supported ones are: *.data*, *.bss*, *.rodata*, and *.kconfig*
129f7b68543SRameez Rehman    structs/data sections. These data sections/structs can be used to set up
130f7b68543SRameez Rehman    initial values of variables, if set before **example__load**. Afterwards,
131f7b68543SRameez Rehman    if target kernel supports memory-mapped BPF arrays, same structs can be
132f7b68543SRameez Rehman    used to fetch and update (non-read-only) data from userspace, with same
133f7b68543SRameez Rehman    simplicity as for BPF side.
134cb21ac58SAndrii Nakryiko
135ea379b3cSRameez Rehmanbpftool gen subskeleton *FILE*
13600389c58SDelyan Kratunov    Generate BPF subskeleton C header file for a given *FILE*.
13700389c58SDelyan Kratunov
138f7b68543SRameez Rehman    Subskeletons are similar to skeletons, except they do not own the
139f7b68543SRameez Rehman    corresponding maps, programs, or global variables. They require that the
140f7b68543SRameez Rehman    object file used to generate them is already loaded into a *bpf_object* by
141f7b68543SRameez Rehman    some other means.
14200389c58SDelyan Kratunov
143f7b68543SRameez Rehman    This functionality is useful when a library is included into a larger BPF
144f7b68543SRameez Rehman    program. A subskeleton for the library would have access to all objects and
145f7b68543SRameez Rehman    globals defined in it, without having to know about the larger program.
14600389c58SDelyan Kratunov
147f7b68543SRameez Rehman    Consequently, there are only two functions defined for subskeletons:
14800389c58SDelyan Kratunov
149a70f5d84SRameez Rehman    - **example__open(bpf_object\*)**.
150f7b68543SRameez Rehman      Instantiates a subskeleton from an already opened (but not necessarily
151f7b68543SRameez Rehman      loaded) **bpf_object**.
15200389c58SDelyan Kratunov
153a70f5d84SRameez Rehman    - **example__destroy()**.
154f7b68543SRameez Rehman      Frees the storage for the subskeleton but *does not* unload any BPF
155f7b68543SRameez Rehman      programs or maps.
15600389c58SDelyan Kratunov
157ea379b3cSRameez Rehmanbpftool gen min_core_btf *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...]
158f7b68543SRameez Rehman    Generate a minimum BTF file as *OUTPUT*, derived from a given *INPUT* BTF
159f7b68543SRameez Rehman    file, containing all needed BTF types so one, or more, given eBPF objects
160f7b68543SRameez Rehman    CO-RE relocations may be satisfied.
1611d1ffbf7SRafael David Tinoco
162f7b68543SRameez Rehman    When kernels aren't compiled with CONFIG_DEBUG_INFO_BTF, libbpf, when
163f7b68543SRameez Rehman    loading an eBPF object, has to rely on external BTF files to be able to
164f7b68543SRameez Rehman    calculate CO-RE relocations.
1651d1ffbf7SRafael David Tinoco
166f7b68543SRameez Rehman    Usually, an external BTF file is built from existing kernel DWARF data
167f7b68543SRameez Rehman    using pahole. It contains all the types used by its respective kernel image
168f7b68543SRameez Rehman    and, because of that, is big.
1691d1ffbf7SRafael David Tinoco
170f7b68543SRameez Rehman    The min_core_btf feature builds smaller BTF files, customized to one or
171f7b68543SRameez Rehman    multiple eBPF objects, so they can be distributed together with an eBPF
172f7b68543SRameez Rehman    CO-RE based application, turning the application portable to different
173f7b68543SRameez Rehman    kernel versions.
1741d1ffbf7SRafael David Tinoco
175*f028d771SAndrew Kreimer    Check examples below for more information on how to use it.
1761d1ffbf7SRafael David Tinoco
177ea379b3cSRameez Rehmanbpftool gen help
178cb21ac58SAndrii Nakryiko    Print short help message.
179cb21ac58SAndrii Nakryiko
180cb21ac58SAndrii NakryikoOPTIONS
181cb21ac58SAndrii Nakryiko=======
182f28ef96dSQuentin Monnet.. include:: common_options.rst
183cb21ac58SAndrii Nakryiko
1848cc8c635SQuentin Monnet-L, --use-loader
1858cc8c635SQuentin Monnet    For skeletons, generate a "light" skeleton (also known as "loader"
186f7b68543SRameez Rehman    skeleton). A light skeleton contains a loader eBPF program. It does not use
187f7b68543SRameez Rehman    the majority of the libbpf infrastructure, and does not need libelf.
1888cc8c635SQuentin Monnet
189cb21ac58SAndrii NakryikoEXAMPLES
190cb21ac58SAndrii Nakryiko========
191d80b2fcbSAndrii Nakryiko**$ cat example1.bpf.c**
19216f3ddfbSQuentin Monnet
193cb21ac58SAndrii Nakryiko::
194cb21ac58SAndrii Nakryiko
195cb21ac58SAndrii Nakryiko  #include <stdbool.h>
196cb21ac58SAndrii Nakryiko  #include <linux/ptrace.h>
197cb21ac58SAndrii Nakryiko  #include <linux/bpf.h>
198d80b2fcbSAndrii Nakryiko  #include <bpf/bpf_helpers.h>
199cb21ac58SAndrii Nakryiko
200cb21ac58SAndrii Nakryiko  const volatile int param1 = 42;
201cb21ac58SAndrii Nakryiko  bool global_flag = true;
202cb21ac58SAndrii Nakryiko  struct { int x; } data = {};
203cb21ac58SAndrii Nakryiko
204cb21ac58SAndrii Nakryiko  SEC("raw_tp/sys_enter")
205cb21ac58SAndrii Nakryiko  int handle_sys_enter(struct pt_regs *ctx)
206cb21ac58SAndrii Nakryiko  {
207cb21ac58SAndrii Nakryiko  	static long my_static_var;
208cb21ac58SAndrii Nakryiko  	if (global_flag)
209cb21ac58SAndrii Nakryiko  		my_static_var++;
210cb21ac58SAndrii Nakryiko  	else
211cb21ac58SAndrii Nakryiko  		data.x += param1;
212cb21ac58SAndrii Nakryiko  	return 0;
213cb21ac58SAndrii Nakryiko  }
214cb21ac58SAndrii Nakryiko
215d80b2fcbSAndrii Nakryiko**$ cat example2.bpf.c**
216d80b2fcbSAndrii Nakryiko
217d80b2fcbSAndrii Nakryiko::
218d80b2fcbSAndrii Nakryiko
219d80b2fcbSAndrii Nakryiko  #include <linux/ptrace.h>
220d80b2fcbSAndrii Nakryiko  #include <linux/bpf.h>
221d80b2fcbSAndrii Nakryiko  #include <bpf/bpf_helpers.h>
222d80b2fcbSAndrii Nakryiko
223d80b2fcbSAndrii Nakryiko  struct {
224d80b2fcbSAndrii Nakryiko  	__uint(type, BPF_MAP_TYPE_HASH);
225d80b2fcbSAndrii Nakryiko  	__uint(max_entries, 128);
226d80b2fcbSAndrii Nakryiko  	__type(key, int);
227d80b2fcbSAndrii Nakryiko  	__type(value, long);
228d80b2fcbSAndrii Nakryiko  } my_map SEC(".maps");
229d80b2fcbSAndrii Nakryiko
230cb21ac58SAndrii Nakryiko  SEC("raw_tp/sys_exit")
231cb21ac58SAndrii Nakryiko  int handle_sys_exit(struct pt_regs *ctx)
232cb21ac58SAndrii Nakryiko  {
233cb21ac58SAndrii Nakryiko  	int zero = 0;
234cb21ac58SAndrii Nakryiko  	bpf_map_lookup_elem(&my_map, &zero);
235cb21ac58SAndrii Nakryiko  	return 0;
236cb21ac58SAndrii Nakryiko  }
237cb21ac58SAndrii Nakryiko
238f2e81192SKui-Feng Lee**$ cat example3.bpf.c**
239f2e81192SKui-Feng Lee
240f2e81192SKui-Feng Lee::
241f2e81192SKui-Feng Lee
242f2e81192SKui-Feng Lee  #include <linux/ptrace.h>
243f2e81192SKui-Feng Lee  #include <linux/bpf.h>
244f2e81192SKui-Feng Lee  #include <bpf/bpf_helpers.h>
245f2e81192SKui-Feng Lee  /* This header file is provided by the bpf_testmod module. */
246f2e81192SKui-Feng Lee  #include "bpf_testmod.h"
247f2e81192SKui-Feng Lee
248f2e81192SKui-Feng Lee  int test_2_result = 0;
249f2e81192SKui-Feng Lee
250f2e81192SKui-Feng Lee  /* bpf_Testmod.ko calls this function, passing a "4"
251f2e81192SKui-Feng Lee   * and testmod_map->data.
252f2e81192SKui-Feng Lee   */
253f2e81192SKui-Feng Lee  SEC("struct_ops/test_2")
254f2e81192SKui-Feng Lee  void BPF_PROG(test_2, int a, int b)
255f2e81192SKui-Feng Lee  {
256f2e81192SKui-Feng Lee	test_2_result = a + b;
257f2e81192SKui-Feng Lee  }
258f2e81192SKui-Feng Lee
259f2e81192SKui-Feng Lee  SEC(".struct_ops")
260f2e81192SKui-Feng Lee  struct bpf_testmod_ops testmod_map = {
261f2e81192SKui-Feng Lee	.test_2 = (void *)test_2,
262f2e81192SKui-Feng Lee	.data = 0x1,
263f2e81192SKui-Feng Lee  };
264f2e81192SKui-Feng Lee
265f2e81192SKui-Feng LeeThis is example BPF application with three BPF programs and a mix of BPF
266f2e81192SKui-Feng Leemaps and global variables. Source code is split across three source code
267f2e81192SKui-Feng Leefiles.
268cb21ac58SAndrii Nakryiko
269bbaf1ff0SFangrui Song**$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o**
2701d1ffbf7SRafael David Tinoco
271bbaf1ff0SFangrui Song**$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o**
2721d1ffbf7SRafael David Tinoco
273f2e81192SKui-Feng Lee**$ clang --target=bpf -g example3.bpf.c -o example3.bpf.o**
274d80b2fcbSAndrii Nakryiko
275f2e81192SKui-Feng Lee**$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o example3.bpf.o**
276f2e81192SKui-Feng Lee
277f2e81192SKui-Feng LeeThis set of commands compiles *example1.bpf.c*, *example2.bpf.c* and
278f2e81192SKui-Feng Lee*example3.bpf.c* individually and then statically links respective object
279f2e81192SKui-Feng Leefiles into the final BPF ELF object file *example.bpf.o*.
280d80b2fcbSAndrii Nakryiko
281d80b2fcbSAndrii Nakryiko**$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h**
28216f3ddfbSQuentin Monnet
283cb21ac58SAndrii Nakryiko::
284cb21ac58SAndrii Nakryiko
285cb21ac58SAndrii Nakryiko  /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
286cb21ac58SAndrii Nakryiko
287cb21ac58SAndrii Nakryiko  /* THIS FILE IS AUTOGENERATED! */
288cb21ac58SAndrii Nakryiko  #ifndef __EXAMPLE_SKEL_H__
289cb21ac58SAndrii Nakryiko  #define __EXAMPLE_SKEL_H__
290cb21ac58SAndrii Nakryiko
291cb21ac58SAndrii Nakryiko  #include <stdlib.h>
292229c3b47SToke Høiland-Jørgensen  #include <bpf/libbpf.h>
293cb21ac58SAndrii Nakryiko
294cb21ac58SAndrii Nakryiko  struct example {
295cb21ac58SAndrii Nakryiko  	struct bpf_object_skeleton *skeleton;
296cb21ac58SAndrii Nakryiko  	struct bpf_object *obj;
297cb21ac58SAndrii Nakryiko  	struct {
298cb21ac58SAndrii Nakryiko  		struct bpf_map *rodata;
299cb21ac58SAndrii Nakryiko  		struct bpf_map *data;
300cb21ac58SAndrii Nakryiko  		struct bpf_map *bss;
301cb21ac58SAndrii Nakryiko  		struct bpf_map *my_map;
302f2e81192SKui-Feng Lee		struct bpf_map *testmod_map;
303cb21ac58SAndrii Nakryiko  	} maps;
304cb21ac58SAndrii Nakryiko	struct {
305f2e81192SKui-Feng Lee		struct example__testmod_map__bpf_testmod_ops {
306f2e81192SKui-Feng Lee			const struct bpf_program *test_1;
307f2e81192SKui-Feng Lee			const struct bpf_program *test_2;
308f2e81192SKui-Feng Lee			int data;
309f2e81192SKui-Feng Lee		} *testmod_map;
310f2e81192SKui-Feng Lee	} struct_ops;
311f2e81192SKui-Feng Lee  	struct {
312cb21ac58SAndrii Nakryiko  		struct bpf_program *handle_sys_enter;
313cb21ac58SAndrii Nakryiko  		struct bpf_program *handle_sys_exit;
314cb21ac58SAndrii Nakryiko  	} progs;
315cb21ac58SAndrii Nakryiko  	struct {
316cb21ac58SAndrii Nakryiko  		struct bpf_link *handle_sys_enter;
317cb21ac58SAndrii Nakryiko  		struct bpf_link *handle_sys_exit;
318cb21ac58SAndrii Nakryiko  	} links;
319cb21ac58SAndrii Nakryiko  	struct example__bss {
320cb21ac58SAndrii Nakryiko  		struct {
321cb21ac58SAndrii Nakryiko  			int x;
322cb21ac58SAndrii Nakryiko  		} data;
323f2e81192SKui-Feng Lee		int test_2_result;
324cb21ac58SAndrii Nakryiko  	} *bss;
325cb21ac58SAndrii Nakryiko  	struct example__data {
326cb21ac58SAndrii Nakryiko  		_Bool global_flag;
327cb21ac58SAndrii Nakryiko  		long int handle_sys_enter_my_static_var;
328cb21ac58SAndrii Nakryiko  	} *data;
329cb21ac58SAndrii Nakryiko  	struct example__rodata {
330cb21ac58SAndrii Nakryiko  		int param1;
331cb21ac58SAndrii Nakryiko  	} *rodata;
332cb21ac58SAndrii Nakryiko  };
333cb21ac58SAndrii Nakryiko
334cb21ac58SAndrii Nakryiko  static void example__destroy(struct example *obj);
335cb21ac58SAndrii Nakryiko  static inline struct example *example__open_opts(
336cb21ac58SAndrii Nakryiko                const struct bpf_object_open_opts *opts);
337cb21ac58SAndrii Nakryiko  static inline struct example *example__open();
338cb21ac58SAndrii Nakryiko  static inline int example__load(struct example *obj);
339cb21ac58SAndrii Nakryiko  static inline struct example *example__open_and_load();
340cb21ac58SAndrii Nakryiko  static inline int example__attach(struct example *obj);
341cb21ac58SAndrii Nakryiko  static inline void example__detach(struct example *obj);
342cb21ac58SAndrii Nakryiko
343cb21ac58SAndrii Nakryiko  #endif /* __EXAMPLE_SKEL_H__ */
344cb21ac58SAndrii Nakryiko
345d80b2fcbSAndrii Nakryiko**$ cat example.c**
34616f3ddfbSQuentin Monnet
347cb21ac58SAndrii Nakryiko::
348cb21ac58SAndrii Nakryiko
349cb21ac58SAndrii Nakryiko  #include "example.skel.h"
350cb21ac58SAndrii Nakryiko
351cb21ac58SAndrii Nakryiko  int main()
352cb21ac58SAndrii Nakryiko  {
353cb21ac58SAndrii Nakryiko  	struct example *skel;
354cb21ac58SAndrii Nakryiko  	int err = 0;
355cb21ac58SAndrii Nakryiko
356cb21ac58SAndrii Nakryiko  	skel = example__open();
357cb21ac58SAndrii Nakryiko  	if (!skel)
358cb21ac58SAndrii Nakryiko  		goto cleanup;
359cb21ac58SAndrii Nakryiko
360cb21ac58SAndrii Nakryiko  	skel->rodata->param1 = 128;
361cb21ac58SAndrii Nakryiko
362f2e81192SKui-Feng Lee	/* Change the value through the pointer of shadow type */
363f2e81192SKui-Feng Lee	skel->struct_ops.testmod_map->data = 13;
364f2e81192SKui-Feng Lee
365cb21ac58SAndrii Nakryiko  	err = example__load(skel);
366cb21ac58SAndrii Nakryiko  	if (err)
367cb21ac58SAndrii Nakryiko  		goto cleanup;
368cb21ac58SAndrii Nakryiko
369f2e81192SKui-Feng Lee	/* The result of the function test_2() */
370f2e81192SKui-Feng Lee	printf("test_2_result: %d\n", skel->bss->test_2_result);
371f2e81192SKui-Feng Lee
372cb21ac58SAndrii Nakryiko  	err = example__attach(skel);
373cb21ac58SAndrii Nakryiko  	if (err)
374cb21ac58SAndrii Nakryiko  		goto cleanup;
375cb21ac58SAndrii Nakryiko
376cb21ac58SAndrii Nakryiko  	/* all libbpf APIs are usable */
377cb21ac58SAndrii Nakryiko  	printf("my_map name: %s\n", bpf_map__name(skel->maps.my_map));
378cb21ac58SAndrii Nakryiko  	printf("sys_enter prog FD: %d\n",
379cb21ac58SAndrii Nakryiko  	       bpf_program__fd(skel->progs.handle_sys_enter));
380cb21ac58SAndrii Nakryiko
381cb21ac58SAndrii Nakryiko  	/* detach and re-attach sys_exit program */
382cb21ac58SAndrii Nakryiko  	bpf_link__destroy(skel->links.handle_sys_exit);
383cb21ac58SAndrii Nakryiko  	skel->links.handle_sys_exit =
384cb21ac58SAndrii Nakryiko  		bpf_program__attach(skel->progs.handle_sys_exit);
385cb21ac58SAndrii Nakryiko
386cb21ac58SAndrii Nakryiko  	printf("my_static_var: %ld\n",
387cb21ac58SAndrii Nakryiko  	       skel->bss->handle_sys_enter_my_static_var);
388cb21ac58SAndrii Nakryiko
389cb21ac58SAndrii Nakryiko  cleanup:
390cb21ac58SAndrii Nakryiko  	example__destroy(skel);
391cb21ac58SAndrii Nakryiko  	return err;
392cb21ac58SAndrii Nakryiko  }
393cb21ac58SAndrii Nakryiko
394d80b2fcbSAndrii Nakryiko**# ./example**
39516f3ddfbSQuentin Monnet
396cb21ac58SAndrii Nakryiko::
397cb21ac58SAndrii Nakryiko
398f2e81192SKui-Feng Lee  test_2_result: 17
399cb21ac58SAndrii Nakryiko  my_map name: my_map
400cb21ac58SAndrii Nakryiko  sys_enter prog FD: 8
401cb21ac58SAndrii Nakryiko  my_static_var: 7
402cb21ac58SAndrii Nakryiko
403cb21ac58SAndrii NakryikoThis is a stripped-out version of skeleton generated for above example code.
4041d1ffbf7SRafael David Tinoco
4051d1ffbf7SRafael David Tinocomin_core_btf
4061d1ffbf7SRafael David Tinoco------------
4071d1ffbf7SRafael David Tinoco
4081d1ffbf7SRafael David Tinoco**$ bpftool btf dump file 5.4.0-example.btf format raw**
4091d1ffbf7SRafael David Tinoco
4101d1ffbf7SRafael David Tinoco::
4111d1ffbf7SRafael David Tinoco
4121d1ffbf7SRafael David Tinoco  [1] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
4131d1ffbf7SRafael David Tinoco  [2] CONST '(anon)' type_id=1
4141d1ffbf7SRafael David Tinoco  [3] VOLATILE '(anon)' type_id=1
4151d1ffbf7SRafael David Tinoco  [4] ARRAY '(anon)' type_id=1 index_type_id=21 nr_elems=2
4161d1ffbf7SRafael David Tinoco  [5] PTR '(anon)' type_id=8
4171d1ffbf7SRafael David Tinoco  [6] CONST '(anon)' type_id=5
4181d1ffbf7SRafael David Tinoco  [7] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=(none)
4191d1ffbf7SRafael David Tinoco  [8] CONST '(anon)' type_id=7
4201d1ffbf7SRafael David Tinoco  [9] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)
4211d1ffbf7SRafael David Tinoco  <long output>
4221d1ffbf7SRafael David Tinoco
4231d1ffbf7SRafael David Tinoco**$ bpftool btf dump file one.bpf.o format raw**
4241d1ffbf7SRafael David Tinoco
4251d1ffbf7SRafael David Tinoco::
4261d1ffbf7SRafael David Tinoco
4271d1ffbf7SRafael David Tinoco  [1] PTR '(anon)' type_id=2
4281d1ffbf7SRafael David Tinoco  [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=4
4291d1ffbf7SRafael David Tinoco        'ent' type_id=3 bits_offset=0
4301d1ffbf7SRafael David Tinoco        'id' type_id=7 bits_offset=64
4311d1ffbf7SRafael David Tinoco        'args' type_id=9 bits_offset=128
4321d1ffbf7SRafael David Tinoco        '__data' type_id=12 bits_offset=512
4331d1ffbf7SRafael David Tinoco  [3] STRUCT 'trace_entry' size=8 vlen=4
4341d1ffbf7SRafael David Tinoco        'type' type_id=4 bits_offset=0
4351d1ffbf7SRafael David Tinoco        'flags' type_id=5 bits_offset=16
4361d1ffbf7SRafael David Tinoco        'preempt_count' type_id=5 bits_offset=24
4371d1ffbf7SRafael David Tinoco  <long output>
4381d1ffbf7SRafael David Tinoco
4391d1ffbf7SRafael David Tinoco**$ bpftool gen min_core_btf 5.4.0-example.btf 5.4.0-smaller.btf one.bpf.o**
4401d1ffbf7SRafael David Tinoco
4411d1ffbf7SRafael David Tinoco**$ bpftool btf dump file 5.4.0-smaller.btf format raw**
4421d1ffbf7SRafael David Tinoco
4431d1ffbf7SRafael David Tinoco::
4441d1ffbf7SRafael David Tinoco
4451d1ffbf7SRafael David Tinoco  [1] TYPEDEF 'pid_t' type_id=6
4461d1ffbf7SRafael David Tinoco  [2] STRUCT 'trace_event_raw_sys_enter' size=64 vlen=1
4471d1ffbf7SRafael David Tinoco        'args' type_id=4 bits_offset=128
4481d1ffbf7SRafael David Tinoco  [3] STRUCT 'task_struct' size=9216 vlen=2
4491d1ffbf7SRafael David Tinoco        'pid' type_id=1 bits_offset=17920
4501d1ffbf7SRafael David Tinoco        'real_parent' type_id=7 bits_offset=18048
4511d1ffbf7SRafael David Tinoco  [4] ARRAY '(anon)' type_id=5 index_type_id=8 nr_elems=6
4521d1ffbf7SRafael David Tinoco  [5] INT 'long unsigned int' size=8 bits_offset=0 nr_bits=64 encoding=(none)
4531d1ffbf7SRafael David Tinoco  [6] TYPEDEF '__kernel_pid_t' type_id=8
4541d1ffbf7SRafael David Tinoco  [7] PTR '(anon)' type_id=3
4551d1ffbf7SRafael David Tinoco  [8] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
4561d1ffbf7SRafael David Tinoco  <end>
4571d1ffbf7SRafael David Tinoco
4581d1ffbf7SRafael David TinocoNow, the "5.4.0-smaller.btf" file may be used by libbpf as an external BTF file
4591d1ffbf7SRafael David Tinocowhen loading the "one.bpf.o" object into the "5.4.0-example" kernel. Note that
4601d1ffbf7SRafael David Tinocothe generated BTF file won't allow other eBPF objects to be loaded, just the
4611d1ffbf7SRafael David Tinocoones given to min_core_btf.
4621d1ffbf7SRafael David Tinoco
4631d1ffbf7SRafael David Tinoco::
4641d1ffbf7SRafael David Tinoco
4651d1ffbf7SRafael David Tinoco  LIBBPF_OPTS(bpf_object_open_opts, opts, .btf_custom_path = "5.4.0-smaller.btf");
4661d1ffbf7SRafael David Tinoco  struct bpf_object *obj;
4671d1ffbf7SRafael David Tinoco
4681d1ffbf7SRafael David Tinoco  obj = bpf_object__open_file("one.bpf.o", &opts);
4691d1ffbf7SRafael David Tinoco
4701d1ffbf7SRafael David Tinoco  ...
471