On Tue, Jul 21, 2020 at 11:58 PM Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote: > > On Tue, Jul 21, 2020 at 10:44 PM Ian Rogers <irogers@xxxxxxxxxx> wrote: > > > > When bpftool dumps types and enum members into a header file for > > inclusion the names match those in the original source. If the same > > header file needs to be included in the original source and the bpf > > program, the names of structs, unions, typedefs and enum members will > > have naming collisions. > > vmlinux.h is not really intended to be used from user-space, because > it's incompatible with pretty much any other header that declares any > type. Ideally we should make this better, but that might require some > compiler support. We've been discussing with Yonghong extending Clang > with a compile-time check for whether some type is defined or not, > which would allow to guard every type and only declare it > conditionally, if it's missing. But that's just an idea at this point. Thanks Andrii! We're not looking at user-space code but the BPF code. The prefix idea comes from a way to solve this problem in C++ with namespaces: namespace vmlinux { #include "vmlinux.h" } As the BPF programs are C code then the prefix acts like the namespace. It seems strange to need to extend the language. > Regardless, vmlinux.h is also very much Clang-specific, and shouldn't > work well with GCC. Could you elaborate on the specifics of the use > case you have in mind? That could help me see what might be the right > solution. Thanks! So the use-case is similar to btf_iter.h: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/testing/selftests/bpf/progs/bpf_iter.h To avoid collisions with somewhat cleaner macro or not games. Prompted by your concern I was looking into changing bpf_iter.h to use a prefix to show what the difference would be like. I also think that there may be issues with our kernel and tool set up that may mean that the prefix is unnecessary, if I fix something else. Anyway, to give an example I needed to build the selftests but this is failing for me. What I see is: $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git $ cd bpf-next $ make defconfig $ cat >>.config <<EOF CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_BTF=y EOF $ make -j all $ mkdir /tmp/selftests $ make O=/tmp/selftests/ TARGETS=bpf kselftest ... CLANG /tmp/selftests//kselftest/bpf/tools/build/bpftool/profiler.bpf.o skeleton/profiler.bpf.c:18:21: error: invalid application of 'sizeof' to an incomplete type 'struct bpf_perf_event_value' __uint(value_size, sizeof(struct bpf_perf_event_value)); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checking with bpftool the vmlinux lacks struct bpf_perf_event_value but as this is unconditionally defined in bpf.h this seems wrong. Do you have any suggestions and getting a working build? > > To avoid these collisions an approach is to redeclare the header file > > types and enum members, which leads to duplication and possible > > inconsistencies. Another approach is to use preprocessor macros > > to rename conflicting names, but this can be cumbersome if there are > > many conflicts. > > > > This patch adds a prefix option for the dumped names. Use of this option > > can avoid name conflicts and compile time errors. > > > > Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx> > > --- > > .../bpf/bpftool/Documentation/bpftool-btf.rst | 7 ++++++- > > tools/bpf/bpftool/btf.c | 18 ++++++++++++++--- > > tools/lib/bpf/btf.h | 1 + > > tools/lib/bpf/btf_dump.c | 20 +++++++++++++------ > > 4 files changed, 36 insertions(+), 10 deletions(-) > > > > [...] > > > diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h > > index 491c7b41ffdc..fea4baab00bd 100644 > > --- a/tools/lib/bpf/btf.h > > +++ b/tools/lib/bpf/btf.h > > @@ -117,6 +117,7 @@ struct btf_dump; > > > > struct btf_dump_opts { > > void *ctx; > > + const char *name_prefix; > > }; > > BTW, we can't do that, this breaks ABI. btf_dump_opts were added > before we understood the problem of backward/forward compatibility of > libbpf APIs, unfortunately. This could be fixed by adding a "new" API for the parameter, which would be unfortunate compared to just amending the existing API. There may be solutions that are less duplicative. Thanks, Ian > > > > typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args); > > diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c > > index e1c344504cae..baf2b4d82e1e 100644 > > --- a/tools/lib/bpf/btf_dump.c > > +++ b/tools/lib/bpf/btf_dump.c > > [...]