Commit Graph

6 Commits

Author SHA1 Message Date
Hao Luo da4ad2f650 btf_encoder: Allow disabling BTF var encoding.
A new feature was introduced in commit f3d9054ba8 ("btf_encoder: Teach
pahole to store percpu variables in vmlinux BTF.") which encodes kernel
percpu variables into BTF. Add a flag --skip_encoding_btf_vars to allow
users to toggle this feature off, so that the rollout of pahole v1.18
can be protected by potential bugs in this feature.

Committer notes:

Added missing man page entry.

Signed-off-by: Hao Luo <haoluo@google.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-09-21 17:00:16 -03:00
Hao Luo f3d9054ba8 btf_encoder: Teach pahole to store percpu variables in vmlinux BTF.
On SMP systems, the global percpu variables are placed in a special
'.data..percpu' section, which is stored in a segment whose initial
address is set to 0, the addresses of per-CPU variables are relative
positive addresses [1].

This patch extracts these variables from vmlinux and places them with
their type information in BTF. More specifically, when BTF is encoded,
we find the index of the '.data..percpu' section and then traverse the
symbol table to find those global objects which are in this section.
For each of these objects, we push a BTF_KIND_VAR into the types buffer,
and a BTF_VAR_SECINFO into another buffer, percpu_secinfo. When all the
CUs have finished processing, we push a BTF_KIND_DATASEC into the
btfe->types buffer, followed by the percpu_secinfo's content.

In a v5.8-rc3 linux kernel, I was able to extract 288 such variables.
The build time overhead is small and the space overhead is also small.
See testings below.

A found variable can be invalid in two ways:

 - Its name found in elf_sym__name is invalid.
 - Its size identified by elf_sym__size is 0.

In either case, the BTF containing such symbols will be rejected by the
BTF verifier. Normally we should not see such symbols. But if one is
seen during BTF encoding, the encoder will exit with error. An new flag
'-j' (or '--force') is implemented to help testing, which skips the
invalid symbols and force emit a BTF.

Testing:

- vmlinux size has increased by ~12kb.
  Before:
   $ readelf -SW vmlinux | grep BTF
   [25] .BTF              PROGBITS        ffffffff821a905c 13a905c 2d2bf8 00
  After:
   $ pahole -J vmlinux
   $ readelf -SW vmlinux  | grep BTF
   [25] .BTF              PROGBITS        ffffffff821a905c 13a905c 2d5bca 00

- Common global percpu VARs and DATASEC are found in BTF section.
  $ bpftool btf dump file vmlinux | grep runqueues
  [14152] VAR 'runqueues' type_id=13778, linkage=global-alloc

  $ bpftool btf dump file vmlinux | grep 'cpu_stopper'
  [17582] STRUCT 'cpu_stopper' size=72 vlen=5
  [17601] VAR 'cpu_stopper' type_id=17582, linkage=static

  $ bpftool btf dump file vmlinux | grep ' DATASEC '
  [63652] DATASEC '.data..percpu' size=179288 vlen=288

- Tested bpf selftests.

- pahole exits with error if an invalid symbol is seen during encoding,
  make -f Makefile -j 36 -s
  PAHOLE: Error: Found symbol of zero size when encoding btf (sym: 'yyy', cu: 'xxx.c').
  PAHOLE: Error: Use '-j' or '--force_emit' to ignore such symbols and force emit the btf.
  scripts/link-vmlinux.sh: line 137: 2475712 Segmentation fault      LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1}

- With the flag '-j' or '--force', the invalid symbols are ignored.

- Further in verbose mode and with '-j' or '--force' set, a warning is generated:
  PAHOLE: Warning: Found symbol of zero size when encoding btf, ignored (sym: 'yyy', cu: 'xxx.c').
  PAHOLE: Warning: Found symbol of invalid name when encoding btf, ignored (sym: 'zzz', cu: 'sss.c').

References:
 [1] https://lwn.net/Articles/531148/

Signed-off-by: Hao Luo <haoluo@google.com>
Tested-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Oleg Rombakh <olegrom@google.com>
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-08-05 14:51:17 -03:00
Martin Lau a58c746c4c Fixup copyright notices for BTF files authored by Facebook engineers
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Domenico Andreoli <domenico.andreoli@linux.com>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Martin Lau <kafai@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-18 20:34:05 -03:00
Domenico Andreoli e714d2eaa1 Adopt SPDX-License-Identifier
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-18 15:41:48 -03:00
Andrii Nakryiko 65bd17abc7 btf: Allow multiple cu's in dwarf->btf conversion
Currently, the pahole dwarf->btf conversion only supports one
compilation unit. This is not ideal since we would like using pahole to
generate BTF for vmlinux which has a lot of compilation units.

This patch added support to process multiple compilation units per ELF
file. Multiple ELF files are also supported properly.

The following is a demonstration example:
  -bash-4.4$ cat t1.c
  struct t1 {
    int a1;
  } g1;
  int main(void) { return 0; }
  -bash-4.4$ cat t2.c
  struct t2 {
    char a2;
  } g2;
  int main() { return 0; }
  -bash-4.4$ cat t3.c
  struct t3 {
    unsigned char a1:4;
  } g1;
  int main(void) { return 0; }
  -bash-4.4$ cat t4.c
  struct t4 {
    volatile char a4;
  } g2;
  int main() { return 0; }
  -bash-4.4$ gcc -O2 -o t1 -g t1.c t2.c
  -bash-4.4$ gcc -O2 -o t3 -g t3.c t4.c

Note that both the binary "t1" and "t3" have two compilation units in
their respective dwarf debug_info sections. The following is the pahole
verbose output for BTF conversion for these two binaries.

  -bash-4.4$ pahole -JV t1 t3
  File t1:
  [1] STRUCT t1 size=4 vlen=1
        a1 type_id=2 bits_offset=0
  [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  [3] STRUCT t2 size=1 vlen=1
        a2 type_id=4 bits_offset=0
  [4] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [5] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED

  File t3:
  [1] STRUCT t3 size=1 vlen=1
        a1 type_id=3 bits_offset=0
  [2] INT unsigned char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [3] INT unsigned char size=1 bit_offset=0 nr_bits=4 encoding=(none)
  [4] INT (anon) size=4 bit_offset=0 nr_bits=32 encoding=(none)
  [5] STRUCT t4 size=1 vlen=1
        a4 type_id=6 bits_offset=0
  [6] VOLATILE (anon) type_id=7
  [7] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [8] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-12-20 10:44:48 -03:00
Martin KaFai Lau 68645f7fac btf: Add BTF support
This patch introduces BPF Type Format (BTF).

BTF (BPF Type Format) is the meta data format which describes
the data types of BPF program/map.  Hence, it basically focus
on the C programming language which the modern BPF is primary
using.  The first use case is to provide a generic pretty print
capability for a BPF map.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-07-25 14:42:06 -03:00