The ->filename only points out to the ELF file when we're not writing to
a raw, detached BTF file, so reuse it to store the detached filename
when using that mode.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To move creation to pahole.c, i.e. outside the library, to the user,
then move the other methods still using the global variable.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
And this reduces the btf_encoder__encode_tag() signature, since we don't
have to pass this variable, as it is now in the 'encoder' parameter.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Start grouping all the state associated with the BTF encoder into a new
class, do it transparently to the user, pahole, until the last moment,
when it will call btf_encoder__new(), etc.
First step is just encapsulating the btf_elf instance, we'll adding the
globals one by one and at the end probably the btf_elf class will be
completely fagocitated. 8-)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We'll get rid of the 'base_btf' global variable in libbtf.c, so stop
using it in the BTF encoder.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
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>
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>
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>