On Tue, Feb 15, 2022 at 2:59 PM Mauricio Vásquez <mauricio@xxxxxxxxxx> wrote: > > From: Rafael David Tinoco <rafaeldtinoco@xxxxxxxxx> > > Add "min_core_btf" feature explanation and one example of how to use it > to bpftool-gen man page. > > Signed-off-by: Mauricio Vásquez <mauricio@xxxxxxxxxx> > Signed-off-by: Rafael David Tinoco <rafael.tinoco@xxxxxxxxxxx> > Signed-off-by: Lorenzo Fontana <lorenzo.fontana@xxxxxxxxxx> > Signed-off-by: Leonardo Di Donato <leonardo.didonato@xxxxxxxxxx> > --- > .../bpf/bpftool/Documentation/bpftool-gen.rst | 91 +++++++++++++++++++ > 1 file changed, 91 insertions(+) > > diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst > index bc276388f432..4bf8e6447718 100644 > --- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst > +++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst > @@ -25,6 +25,7 @@ GEN COMMANDS > > | **bpftool** **gen object** *OUTPUT_FILE* *INPUT_FILE* [*INPUT_FILE*...] > | **bpftool** **gen skeleton** *FILE* [**name** *OBJECT_NAME*] > +| **bpftool** **gen min_core_btf** *INPUT* *OUTPUT* *OBJECT* [*OBJECT*...] > | **bpftool** **gen help** > > DESCRIPTION > @@ -149,6 +150,26 @@ DESCRIPTION > (non-read-only) data from userspace, with same simplicity > as for BPF side. > > + **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 in external typo: in -> on > + 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 bellow for more information how to use it. > + > **bpftool gen help** > Print short help message. > > @@ -215,7 +236,9 @@ This is example BPF application with two BPF programs and a mix of BPF maps > and global variables. Source code is split across two 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** > + > **$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o** > > This set of commands compiles *example1.bpf.c* and *example2.bpf.c* > @@ -329,3 +352,71 @@ BPF ELF object file *example.bpf.o*. > 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** I dropped ./ everywhere, they are not needed and create bad impression that they do matter > + > +:: > + > + [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. > + > +:: > + > + struct bpf_object *obj = NULL; > + > + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, .btf_custom_path = "5.4.0-smaller.btf"); nit: still prefer LIBBPF_OPTS here, adjusted this piece of code a bit > + > + obj = bpf_object__open_file("one.bpf.o", &opts); > + > + ... > -- > 2.25.1 >