Commit 3671bdbcd214("[BPF] Fix a BTF type pruning bug") fixed a
pruning bug to allow generate more types. But the commit has a bug
which permits to generate more types than necessary. The following
is an example to illustrate the problem.
struct t1 { int a; }; struct t2 { struct t1 *p1; struct t1 *p2; int b; }; int foo(struct t2 *arg) { return arg->b; }
The following is the part of BTF generation sequence:
(1). 'struct t2 *arg' -> 'struct t1 *p1' In this step, the type 'struct t1' will be generated as a forward decl and the ptr type (to 'struct t1') will be stored in the internal type table. (2). now the second field 'struct t1 *p2' will be processed. Since the ptr type (to 'struct t1') already in the type table, the existing logic strips out ptr modifier and is able to generate BTF type for 'struct t1'.
In the above step (2), if CheckPointer is true (the type traversal
chain including a struct member), 'ptr' modifier should be checked
and the subsequent type generation should be skipped since
the same case has been processed in visitDerivedType().
The issue is exposed when I am trying to use llvm15 to compile
some internal bpf programs. The bpf skeleton put the whole
ELF section (after striping some sections like dwarf) as a string.
The large BTF section triggered the following error:
bpf_object_with_struct_ops_test_prog_bpf/BpfObjectWithStructOpsTestProg.skel.h:222:23: error: string literal of length 140144 exceeds maximum length 65536 that C++ compilers are required to support [-Werror,-Woverlength-strings] return (const void *)"\ ^~ 1 error generated.
Although adding -Wno-overlength-strings could workaround the issue,
improving llvm BTF generation sounds better esp. for users using vmlinux.h.
Looks reasonable.
To be honest, I find the logic with CheckPointer / SeenPointer a bit confusing. As far as I understand the main thing is the following code:
And setting CheckPointer to true means that visitor should generate forward declarations when possible. Adding a comment describing behavior of these parameters somewhere would be really helpful.