Commit Graph

72 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo 2499920ac8 btf_loader: No need for the 'strings' extern, not used
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 3d3b7b3287 core: Remove unused debug_fmt_ops->dwarf__strings_ptr()
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo a7d789a4f8 core: Make variable->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 713239bc00 core: Make enumerator->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the enumerator->name case we get the bonus of removing the last user
of dwarves__active_loader in the btf_encoder class.

This covers unions, enums, structs and classes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo b99c4008ac core: Make namespace->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the namespace->name case we get the bonus of removing another
user of dwarves__active_loader.

This covers unions, enums, structs and classes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 379a73c6eb core: Make class_member->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the class_member->name case we get the bonus of removing another
user of dwarves__active_loader.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 3280cb4176 core: Make parameter->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the parameter->name case we get the bonus of removing a user of
dwarves__active_loader.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo f009162fd1 core: Make base_type->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the base_type->name case we get the bonus of removing some more
functions related base types and a user of dwarves__active_loader.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:39:46 -03:00
Arnaldo Carvalho de Melo 82e5b5101a core: Make function->name a real string
For the threaded code we want to access strings in tags at the same time
that the string table may grow in another thread making the previous
pointer invalid, so, to avoid excessive locking, use plain strings.

The way the tools work will either consume the just produced CU straight
away or keep just one copy of each data structure when we keep all CUs
in memory, so lets try stopping using strings_t for strings.

For the function->name case we get the bonus of removing the need of a
debug_fmt_ops->function() callback receiving the 'cu', just access the
string directly.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-07-28 15:18:16 -03:00
Luca Boccassi ae2581647e libbpf: Allow to use packaged version
Add a new CMake option, LIBBPF_EMBEDDED, to switch between the embedded
version and the system version (searched via pkg-config) of libbpf. Set
the embedded version as the default.

Committer testing:

The default build works as before:

  ⬢[acme@toolbox pahole]$ rm -rf build ; mkdir build ; cd build ; cmake -DCMAKE_BUILD_TYPE=Release .. ; cd ..
  -- The C compiler identification is GNU 11.1.1
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Check for working C compiler: /usr/bin/cc - skipped
  -- Detecting C compile features
  -- Detecting C compile features - done
  -- Checking availability of DWARF and ELF development libraries
  -- Looking for dwfl_module_build_id in elf
  -- Looking for dwfl_module_build_id in elf - found
  -- Found dwarf.h header: /usr/include
  -- Found elfutils/libdw.h header: /usr/include
  -- Found libdw library: /usr/lib64/libdw.so
  -- Found libelf library: /usr/lib64/libelf.so
  -- Checking availability of DWARF and ELF development libraries - done
  -- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11")
  -- Submodule update
  -- Submodule update - done
  -- Performing Test HAVE_REALLOCARRAY_SUPPORT
  -- Performing Test HAVE_REALLOCARRAY_SUPPORT - Success
  -- Configuring done
  -- Generating done
  -- Build files have been written to: /var/home/acme/git/pahole/build
  ⬢[acme@toolbox pahole]$ make -j28 -C build
  make: Entering directory '/var/home/acme/git/pahole/build'
  make[1]: Entering directory '/var/home/acme/git/pahole/build'
  make[2]: Entering directory '/var/home/acme/git/pahole/build'
  Scanning dependencies of target bpf
  make[2]: Leaving directory '/var/home/acme/git/pahole/build'
  make[2]: Entering directory '/var/home/acme/git/pahole/build'
  [  5%] Building C object CMakeFiles/bpf.dir/lib/bpf/src/btf.c.o
  [  5%] Building C object CMakeFiles/bpf.dir/lib/bpf/src/bpf_prog_linfo.c.o
  [  5%] Building C object CMakeFiles/bpf.dir/lib/bpf/src/bpf.c.o
  [  7%] Building C object CMakeFiles/bpf.dir/lib/bpf/src/libbpf_errno.c.o
  <SNIP>
  make[2]: Leaving directory '/var/home/acme/git/pahole/build'
  [ 98%] Built target ctracer
  [100%] Linking C executable pahole
  make[2]: Leaving directory '/var/home/acme/git/pahole/build'
  [100%] Built target pahole
  make[1]: Leaving directory '/var/home/acme/git/pahole/build'
  make: Leaving directory '/var/home/acme/git/pahole/build'
  ⬢[acme@toolbox pahole]$ ldd build/pahole
  	linux-vdso.so.1 (0x00007ffcf4d92000)
  	libdwarves_reorganize.so.1 => /var/home/acme/git/pahole/build/libdwarves_reorganize.so.1 (0x00007f059c289000)
  	libdwarves.so.1 => /var/home/acme/git/pahole/build/libdwarves.so.1 (0x00007f059c226000)
  	libdw.so.1 => /lib64/libdw.so.1 (0x00007f059c186000)
  	libelf.so.1 => /lib64/libelf.so.1 (0x00007f059c16b000)
  	libz.so.1 => /lib64/libz.so.1 (0x00007f059c151000)
  	libc.so.6 => /lib64/libc.so.6 (0x00007f059bf82000)
  	libdl.so.2 => /lib64/libdl.so.2 (0x00007f059bf79000)
  	libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f059be83000)
  	liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f059be57000)
  	libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f059be44000)
  	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f059be23000)
  	/lib64/ld-linux-x86-64.so.2 (0x00007f059c290000)
  ⬢[acme@toolbox pahole]$

Then, trying to use the libbpf-devel present in Fedora 34:

  ⬢[acme@toolbox pahole]$ rm -rf build ; mkdir build ; cd build ; cmake -DCMAKE_BUILD_TYPE=Release -DLIBBPF_EMBEDDED=Off .. ; cd ..
  -- The C compiler identification is GNU 11.1.1
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Check for working C compiler: /usr/bin/cc - skipped
  -- Detecting C compile features
  -- Detecting C compile features - done
  -- Found PkgConfig: /usr/bin/pkg-config (found version "1.7.3")
  -- Checking for module 'libbpf>=0.3.0'
  --   Found libbpf, version 0.3.0
  -- Checking availability of DWARF and ELF development libraries
  -- Looking for dwfl_module_build_id in elf
  -- Looking for dwfl_module_build_id in elf - found
  -- Found dwarf.h header: /usr/include
  -- Found elfutils/libdw.h header: /usr/include
  -- Found libdw library: /usr/lib64/libdw.so
  -- Found libelf library: /usr/lib64/libelf.so
  -- Checking availability of DWARF and ELF development libraries - done
  -- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11")
  -- Submodule update
  -- Submodule update - done
  -- Performing Test HAVE_REALLOCARRAY_SUPPORT
  -- Performing Test HAVE_REALLOCARRAY_SUPPORT - Success
  -- Configuring done
  -- Generating done
  -- Build files have been written to: /var/home/acme/git/pahole/build
  ⬢[acme@toolbox pahole]$ m
  make: Entering directory '/var/home/acme/git/pahole/build'
  make[1]: Entering directory '/var/home/acme/git/pahole/build'
  make[2]: Entering directory '/var/home/acme/git/pahole/build'
  Scanning dependencies of target dwarves
  make[2]: Leaving directory '/var/home/acme/git/pahole/build'
  make[2]: Entering directory '/var/home/acme/git/pahole/build'
  [  2%] Building C object CMakeFiles/dwarves.dir/dwarves.c.o
  [  5%] Building C object CMakeFiles/dwarves.dir/dwarves_fprintf.c.o
  [  7%] Building C object CMakeFiles/dwarves.dir/gobuffer.c.o
  <SNIP>
  [ 33%] Building C object CMakeFiles/dwarves.dir/rbtree.c.o
  /var/home/acme/git/pahole/btf_encoder.c:84:10: error: ‘BTF_KIND_FLOAT’ undeclared here (not in a function); did you mean ‘BTF_KIND_INT’?
     84 |         [BTF_KIND_FLOAT]        = "FLOAT",
        |          ^~~~~~~~~~~~~~
        |          BTF_KIND_INT
  /var/home/acme/git/pahole/btf_encoder.c:84:10: error: array index in initializer not of integer type
  /var/home/acme/git/pahole/btf_encoder.c:84:10: note: (near initialization for ‘btf_kind_str’)
  /var/home/acme/git/pahole/btf_encoder.c:84:35: warning: excess elements in array initializer
     84 |         [BTF_KIND_FLOAT]        = "FLOAT",
        |                                   ^~~~~~~
  /var/home/acme/git/pahole/btf_encoder.c:84:35: note: (near initialization for ‘btf_kind_str’)
  /var/home/acme/git/pahole/btf_encoder.c: In function ‘btf_encoder__add_float’:
  /var/home/acme/git/pahole/btf_encoder.c:224:22: warning: implicit declaration of function ‘btf__add_float’; did you mean ‘btf__add_var’? [-Wimplicit-function-declaration]
    224 |         int32_t id = btf__add_float(encoder->btf, name, BITS_ROUNDUP_BYTES(bt->bit_size));
        |                      ^~~~~~~~~~~~~~
        |                      btf__add_var
  /var/home/acme/git/pahole/btf_loader.c: In function ‘btf__load_types’:
  /var/home/acme/git/pahole/btf_loader.c:455:22: error: ‘BTF_KIND_FLOAT’ undeclared (first use in this function); did you mean ‘BTF_KIND_INT’?
    455 |                 case BTF_KIND_FLOAT:
        |                      ^~~~~~~~~~~~~~
        |                      BTF_KIND_INT
  /var/home/acme/git/pahole/btf_loader.c:455:22: note: each undeclared identifier is reported only once for each function it appears in
  make[2]: *** [CMakeFiles/dwarves.dir/build.make:173: CMakeFiles/dwarves.dir/btf_encoder.c.o] Error 1
  make[2]: *** Waiting for unfinished jobs....
  make[2]: *** [CMakeFiles/dwarves.dir/build.make:186: CMakeFiles/dwarves.dir/btf_loader.c.o] Error 1
  make[2]: Leaving directory '/var/home/acme/git/pahole/build'
  make[1]: *** [CMakeFiles/Makefile2:173: CMakeFiles/dwarves.dir/all] Error 2
  make[1]: Leaving directory '/var/home/acme/git/pahole/build'
  make: *** [Makefile:149: all] Error 2
  make: Leaving directory '/var/home/acme/git/pahole/build'
  ⬢[acme@toolbox pahole]$

It doesn't build as libbpf is old and doesn't have support for
BTF_KIND_FLOAT.

Signed-off-by: Luca Boccassi <bluca@debian.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-09 13:34:18 -03:00
Arnaldo Carvalho de Melo 7fb31d787d btf_loader: Stop using libbtf.h and the btf_elf class
Now we just use libbpf's API to do everything.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo e431c18b80 btf_loader: cu__fixup_btf_bitfields doesn'n need btfe parameter, ditch it
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 8c1919c10d btf_loader: class__fixup_btf_bitfields doesn'n need btfe parameter, ditch it
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 4d2ae0d904 btf_elf: Remove unused btfe->priv member
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo b54b74edfc btf_loader: Add a local 'btf' var to prep next patches
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 52bedef0fd btf_loader: Move load_sections() from btf_elf to btf
As it is all it needs.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo ac3f2952a8 btf_loader: Move load_types() from btf_elf to btf
As it is all it needs.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 1a33deae14 btf_loader: Move create_new_tag() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 8323cb33bc btf_loader: Move create_new_datasec() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 6fb41bbf8e btf_loader: Move create_new_variable() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 9122424dda btf_loader: Move create_new_typedef() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo dd3e9ab4a0 btf_loader: Move create_new_forward_decl() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo cca6b51d29 btf_loader: Move create_new_subroutine_type() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo ba1b77d01d btf_loader: Move create_new_enumeration() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo a58bc8300f btf_loader: Move create_new_union() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 367f5fe74c btf_loader: Move create_new_class() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 2460bead8a btf_loader: The create_members() function doesn't need the btfe arg
Not used at all.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 1136795fec btf_loader: Move create_new_array() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo ab2f502891 btf_loader: Move create_new_float_type() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 6b452a1cc5 btf_loader: Move create_new_int_type() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 073a5f69ef btf_loader: Move create_new_function() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 29ad464f73 btf_loader: Move load_ftype() from btfe to cu
As all it needs is btfe->priv that is cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 407693e2ca btf_loader: Pass cu to the load_sections/types routines
This will allow us to stop using btfe->priv and eventually btf_elf
altogether for the BTF loader.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 0e77be4099 btf_loader: Use conf_load->base_btf instead of the global btf_base var
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo ecc888b855 btf_loader: Use btf__pointer_size() to set cu->addr_size
To use libbpf APIs and go on removing the btf_elf class.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo 81fe7d688d btf_loader: Use btf__endianness() instead of to be removed btfe member
When loading a file, via btf__parse_split() libbtf will read the header
and have the endianness made available via the btf__endianness() API,
use it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-04 17:28:56 -03:00
Arnaldo Carvalho de Melo cba940fb86 btf_loader: Fix some memory leaks found by covscan
Error: RESOURCE_LEAK (CWE-772):
  dwarves-1.21/btf_loader.c:554: alloc_fn: Storage is returned from allocation function "btf_elf__new".
  dwarves-1.21/btf_loader.c:554: var_assign: Assigning: "btfe" = storage returned from "btf_elf__new(filename, NULL, base_btf)".
  dwarves-1.21/btf_loader.c:561: leaked_storage: Variable "btfe" going out of scope leaks the storage it points to.
  #  559|         struct cu *cu = cu__new(filename, btfe->wordsize, NULL, 0, filename);
  #  560|         if (cu == NULL)
  #  561|->               return -1;
  #  562|
  #  563|         cu->language = LANG_C;

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-05-27 11:00:14 -03:00
Ilya Leoshkevich de708b3311 btf: Add support for the floating-point types
Some BPF programs compiled on s390 fail to load, because s390
arch-specific linux headers contain float and double types.

Fix as follows:

- Make the DWARF loader fill base_type.float_type.

- Introduce the --btf_gen_floats command-line parameter, so that
  pahole could be used to build both the older and the newer kernels.

- libbpf introduced the support for the floating-point types in commit
  986962fade5, so update the libbpf submodule to that version and use
  the new btf__add_float() function in order to emit the floating-point
  types when not in the compatibility mode.

- Make the BTF loader recognize the new BTF kind.

Example of the resulting entry in the vmlinux BTF:

    [7164] FLOAT 'double' size=8

when building with:

    LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} --btf_gen_floats

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-03-11 14:45:38 -03:00
Arnaldo Carvalho de Melo 7943374ac5 Revert "libbpf: allow to use packaged version"
This reverts commit 82749180b2.

Getting in the way of releasing 1.20, breaking the build of a dwarves
rpm when a libbpf package is installed in a fedora 33 system:

In file included from /home/acme/rpmbuild/BUILD/dwarves-1.20/strings.c:7:
/home/acme/rpmbuild/BUILD/dwarves-1.20/pahole_strings.h:9:10: fatal error: bpf/btf.h: No such file or directory
    9 | #include <bpf/btf.h>
      |          ^~~~~~~~~~~

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-02-03 21:45:00 -03:00
Luca Boccassi 82749180b2 libbpf: allow to use packaged version
Add a new CMake option, LIBBPF_EMBEDDED, to switch between the
embedded version and the system version (searched via pkg-config)
of libbpf. Set the embedded version as the default.

Signed-off-by: Luca Boccassi <bluca@debian.org>
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-01-21 10:26:25 -03:00
Andrii Nakryiko ace05ba941 btf: Add support for split BTF loading and encoding
Add support for generating split BTF, in which there is a designated base
BTF, containing a base set of types, and a split BTF, which extends main BTF
with extra types, that can reference types and strings from the main BTF.

This is going to be used to generate compact BTFs for kernel modules, with
vmlinux BTF being a main BTF, which all kernel modules are based off of.

These changes rely on patch set [0] to be present in libbpf submodule.

  [0] https://patchwork.kernel.org/project/netdevbpf/list/?series=377859&state=*

Committer notes:

Fixed up wrt ARGP_numeric_version and added a man page entry.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-11 09:12:44 -03:00
Andrii Nakryiko 5e7ab5b9e0 btf_loader: Handle union forward declaration properly
Differentiate between struct and union forwards in BTF. BTF type
representing forward declaration (BTF_KIND_FWD) encodes whether the
forward declaration is for struct or union type by using kflag. So use
that kflag to create a proper internal representation of forward
declaration.

Tested with btfdiff on vmlinux:

  $ PAHOLE=build/pahole ./btfdiff ~/linux-build/default/vmlinux | wc -l
  0
  $

Also tested manually:

  $ cat test.c
  struct struct_fwd;

  union union_fwd;

  struct s {
          struct struct_fwd *f1;
          union union_fwd *f2;
  };

  int func(struct s *s) {
          return !!s->f1 + !!s->f2;
  }
  $ clang -g -target bpf -c test.c -o test.o
  $ bpftool btf dump file test.o | grep fwd_kind
  [6] FWD 'struct_fwd' fwd_kind=struct
  [8] FWD 'union_fwd' fwd_kind=union
  $ build/pahole -F btf test.o
  struct s {
          struct struct_fwd *        f1;                   /*     0     8 */
          union union_fwd *          f2;                   /*     8     8 */

          /* size: 16, cachelines: 1, members: 2 */
          /* last cacheline: 16 bytes */
  };

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-10-27 08:52:37 -03:00
Andrii Nakryiko 5d863aa7ce btf_loader: Use libbpf to load BTF
Switch BTF loading to completely use libbpf's own struct btf and related
APIs.

BTF encoding is still happening with pahole's own code, so these two
code paths are not sharing anything now. String fetching is happening
based on whether btfe->strings were set to non-NULL pointer by
btf_encoder.

Committer testing:

  $ cp ~/git/build/bpf-next-v5.9.0-rc8+/vmlinux .
  $ readelf -SW vmlinux  | grep BTF
    [24] .BTF      PROGBITS  ffffffff82494ac0 1694ac0 340207 00   A  0  0  1
    [25] .BTF_ids  PROGBITS  ffffffff827d4cc8 19d4cc8 0000a4 00   A  0  0  1
  $ ./btfdiff vmlinux
  $

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-10-09 12:43:42 -03:00
Arnaldo Carvalho de Melo aee6808c47 btf_loader: Initialize function->lexblock.tags to fix segfault in pdwtags
pdwtags -F btf vmlinux

Was segfaulting when trying to iterate on the function main lexblock,
which was zeroed instead of INIT_LIST_HEAD'ed, fix it.

This also made pfunct misbehave when used with BTF. pahole unnafected as
it doesn't try to go thru functions in most cases.

Fixes: ccf3eebfcd ("btf_loader: Add support for BTF_KIND_FUNC")
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-10-02 16:23:24 -03:00
Arnaldo Carvalho de Melo dd3c0e9eb0 dwarves: Move the common initialization of fields for 'struct type'
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-08-05 15:16:19 -03:00
Arnaldo Carvalho de Melo 4ece15c37b dwarves: Find common enumerators prefix
Allowing for filters such as 'type==MMAP', equivalent to
'type==PERF_RECORD_MMAP'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-08-05 15:16:19 -03:00
Arnaldo Carvalho de Melo e0773683fa dwarves: Allow setting a struct/class member as the source of sizeof()
This one just allows that to be set, i.e.:

  $ pahole -C perf_event_header ~/bin/perf
  struct perf_event_header {
  	__u32                      type;                 /*     0     4 */
  	__u16                      misc;                 /*     4     2 */
  	__u16                      size;                 /*     6     2 */

  	/* size: 8, cachelines: 1, members: 3 */
  	/* last cacheline: 8 bytes */
  };
  $ pahole -C 'perf_event_header(sizeof=size)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data
  {
  	.type = 0xa,
  	.misc = 0x2,
  	.size = 0x68,
  },
  $

But:

  $ pahole -C 'perf_event_header(sizeof=bla)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data
  pahole: the sizeof member 'bla' not found in the 'perf_event_header' type
  $

And:

  $ pahole -C 'perf_event_header(size=misc)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data
  pahole: invalid arg 'size' in 'perf_event_header(size=misc)' (known args: sizeof=member)
  $

The next cset will implement sizeof(type) with that modifier, using the
stdin bytes to obtain the size (0x68) in the above case, and then we'll
be able to print a sequence of variable-sized records correctly.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-08-05 15:16:19 -03:00
Arnaldo Carvalho de Melo ccf3eebfcd btf_loader: Add support for BTF_KIND_FUNC
Some changes to the fprintf routines were needed, as BTF has as the
function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type
for a function its return value type. With a function->btf flag this was
overcome and all the other goodies in pfunct are present, for instance:

  $ pahole -JV examples/tcp.o | grep -w FUNC | head
  [4068] FUNC tcp_init type_id=4067
  [4070] FUNC tcp_abort type_id=4069
  [4072] FUNC tcp_done type_id=4071
  [4074] FUNC tcp_md5_hash_key type_id=4073
  [4076] FUNC tcp_md5_hash_skb_data type_id=4075
  [4078] FUNC tcp_get_md5sig_pool type_id=4077
  [4080] FUNC tcp_alloc_md5sig_pool type_id=4079
  [4082] FUNC compat_tcp_getsockopt type_id=4081
  [4084] FUNC tcp_getsockopt type_id=4083
  [4086] FUNC tcp_get_timestamping_opt_stats type_id=4085
  $

  $ pfunct -F btf examples/tcp.o  | head
  memset
  memcpy
  tcp_enter_memory_pressure
  tcp_leave_memory_pressure
  tcp_init_sock
  tcp_init_transfer
  tcp_poll
  tcp_ioctl
  tcp_splice_read
  sk_stream_alloc_skb
  $

  $ pfunct --prototype -F btf examples/tcp.o | head
  void * memset(void * p, int c, __kernel_size_t size);
  void * memcpy(void * p, const void  * q, __kernel_size_t size);
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  __poll_t tcp_poll(struct file * file, struct socket * sock, poll_table * wait);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  ssize_t tcp_splice_read(struct socket * sock, loff_t * ppos, struct pipe_inode_info * pipe, size_t len, unsigned int flags);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  $

Now to ask just for the 'struct sock' 'methods', i.e. functions that
have as one of its arguments a pointer to the given 'class' name:

  $ pfunct --class sock -F btf examples/tcp.o | head
  tcp_abort
  tcp_done
  compat_tcp_getsockopt
  tcp_getsockopt
  tcp_get_info
  compat_tcp_setsockopt
  tcp_setsockopt
  tcp_disconnect
  tcp_write_queue_purge
  tcp_close
  $

Then ask for the prototypes, which requires -V, should have that fixed:

  $ pfunct -V --prototypes --class sock -F btf examples/tcp.o | head
  int tcp_abort(struct sock * sk, int err);
  void tcp_done(struct sock * sk);
  int compat_tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen);
  int tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen);
  void tcp_get_info(struct sock * sk, struct tcp_info * info);
  int compat_tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  int tcp_disconnect(struct sock * sk, int flags);
  void tcp_write_queue_purge(struct sock * sk);
  void tcp_close(struct sock * sk, long int timeout);
  $

Don't like prototypes with parm names, got you covered:

  $ pfunct --no_parm_names -V --prototypes --class sock -F btf examples/tcp.o | head
  int tcp_abort(struct sock *, int);
  void tcp_done(struct sock *);
  int compat_tcp_getsockopt(struct sock *, int, int, char *, int *);
  int tcp_getsockopt(struct sock *, int, int, char *, int *);
  void tcp_get_info(struct sock *, struct tcp_info *);
  int compat_tcp_setsockopt(struct sock *, int, int, char *, unsigned int);
  int tcp_setsockopt(struct sock *, int, int, char *, unsigned int);
  int tcp_disconnect(struct sock *, int);
  void tcp_write_queue_purge(struct sock *);
  void tcp_close(struct sock *, long int);
  $

Don't like long options and want just one function?

  $ pfunct -f tcp_setsockopt -F btf examples/tcp.o
  int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen);
  $

Want to generate compileable code for all of those functions, full with
the necessary types, etc?

  $ pfunct -F btf --compile examples/tcp.o  > a.c
  $ gcc -c -o a.o a.c
  $ pfunct -F dwarf --prototypes --class sock a.o | head
  pfunct: a.o: No debugging information found
  $ gcc -g -c -o a.o a.c
  $ pfunct -V -F dwarf --prototypes --class sock a.o | head
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size);
  $

Now lets go full circle and encode BTF for this a.o generated from
source code generated from the original BTF info in that examples/tcp.o
file:

  $ pahole -JV a.o | tail
  [465] FUNC_PROTO (anon) return=35 args=(392 hp, 393 skb, 5 header_len)
  [466] FUNC tcp_md5_hash_skb_data type_id=465
  [467] FUNC_PROTO (anon) return=35 args=(392 hp, 394 key)
  [468] FUNC tcp_md5_hash_key type_id=467
  [469] FUNC_PROTO (anon) return=0 args=(49 sk)
  [470] FUNC tcp_done type_id=469
  [471] FUNC_PROTO (anon) return=35 args=(49 sk, 35 err)
  [472] FUNC tcp_abort type_id=471
  [473] FUNC_PROTO (anon) return=0 args=(void)
  [474] FUNC tcp_init type_id=473
  $

  $ pfunct -F btf -V --prototypes --class=sock a.o | head
  void tcp_enter_memory_pressure(struct sock * sk);
  void tcp_leave_memory_pressure(struct sock * sk);
  void tcp_init_sock(struct sock * sk);
  void tcp_init_transfer(struct sock * sk, int bpf_op);
  int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg);
  struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule);
  ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags);
  int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size);
  $

Curious about the code generated by 'pfunct -F btf --compile examples/tcp.o?

  http://vger.kernel.org/~acme/pahole/pfunct-F-BTF--compile-examples-tcp.o.txt

Cc: Alexei Starovoitov <ast@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-11-05 12:04:23 -03:00
Arnaldo Carvalho de Melo 910e060b5c btf_loader: Skip BTF_KIND_DATASEC entries
Just skip them, we have no use for them so far, skipping them will allow
us to process the other kinds we have use for.

Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-24 21:02:33 -03:00
Arnaldo Carvalho de Melo 96235a74a3 btf_loader: Replace if/else series with a proper switch {}
A switch is the right thing here, use it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-10-24 20:56:31 -03:00