bpftool: Make skeleton C code compilable with C++ compiler
authorAndrii Nakryiko <andriin@fb.com>
Thu, 26 Dec 2019 21:02:53 +0000 (13:02 -0800)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 27 Dec 2019 09:11:05 +0000 (10:11 +0100)
When auto-generated BPF skeleton C code is included from C++ application, it
triggers compilation error due to void * being implicitly casted to whatever
target pointer type. This is supported by C, but not C++. To solve this
problem, add explicit casts, where necessary.

To ensure issues like this are captured going forward, add skeleton usage in
test_cpp test.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191226210253.3132060-1-andriin@fb.com
tools/bpf/bpftool/gen.c
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/test_cpp.cpp

index a14d8bc..7ce09a9 100644 (file)
@@ -397,7 +397,7 @@ static int do_skeleton(int argc, char **argv)
                {                                                           \n\
                        struct %1$s *obj;                                   \n\
                                                                            \n\
-                       obj = calloc(1, sizeof(*obj));                      \n\
+                       obj = (typeof(obj))calloc(1, sizeof(*obj));         \n\
                        if (!obj)                                           \n\
                                return NULL;                                \n\
                        if (%1$s__create_skeleton(obj))                     \n\
@@ -461,7 +461,7 @@ static int do_skeleton(int argc, char **argv)
                {                                                           \n\
                        struct bpf_object_skeleton *s;                      \n\
                                                                            \n\
-                       s = calloc(1, sizeof(*s));                          \n\
+                       s = (typeof(s))calloc(1, sizeof(*s));               \n\
                        if (!s)                                             \n\
                                return -1;                                  \n\
                        obj->skeleton = s;                                  \n\
@@ -479,7 +479,7 @@ static int do_skeleton(int argc, char **argv)
                                /* maps */                                  \n\
                                s->map_cnt = %zu;                           \n\
                                s->map_skel_sz = sizeof(*s->maps);          \n\
-                               s->maps = calloc(s->map_cnt, s->map_skel_sz);\n\
+                               s->maps = (typeof(s->maps))calloc(s->map_cnt, s->map_skel_sz);\n\
                                if (!s->maps)                               \n\
                                        goto err;                           \n\
                        ",
@@ -515,7 +515,7 @@ static int do_skeleton(int argc, char **argv)
                                /* programs */                              \n\
                                s->prog_cnt = %zu;                          \n\
                                s->prog_skel_sz = sizeof(*s->progs);        \n\
-                               s->progs = calloc(s->prog_cnt, s->prog_skel_sz);\n\
+                               s->progs = (typeof(s->progs))calloc(s->prog_cnt, s->prog_skel_sz);\n\
                                if (!s->progs)                              \n\
                                        goto err;                           \n\
                        ",
@@ -538,7 +538,7 @@ static int do_skeleton(int argc, char **argv)
                \n\
                                                                            \n\
                        s->data_sz = %d;                                    \n\
-                       s->data = \"\\                                      \n\
+                       s->data = (void *)\"\\                              \n\
                ",
                file_sz);
 
index 866fc1c..41691fb 100644 (file)
@@ -371,7 +371,7 @@ $(OUTPUT)/test_verifier: test_verifier.c verifier/tests.h $(BPFOBJ) | $(OUTPUT)
        $(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
 
 # Make sure we are able to include and link libbpf against c++.
-$(OUTPUT)/test_cpp: test_cpp.cpp $(BPFOBJ)
+$(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ)
        $(call msg,        CXX,,$@)
        $(CXX) $(CFLAGS) $^ $(LDLIBS) -o $@
 
index f0eb272..6fe23a1 100644 (file)
@@ -1,12 +1,16 @@
 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+#include <iostream>
 #include "libbpf.h"
 #include "bpf.h"
 #include "btf.h"
+#include "test_core_extern.skel.h"
 
 /* do nothing, just make sure we can link successfully */
 
 int main(int argc, char *argv[])
 {
+       struct test_core_extern *skel;
+
        /* libbpf.h */
        libbpf_set_print(NULL);
 
@@ -16,5 +20,11 @@ int main(int argc, char *argv[])
        /* btf.h */
        btf__new(NULL, 0);
 
+       /* BPF skeleton */
+       skel = test_core_extern__open_and_load();
+       test_core_extern__destroy(skel);
+
+       std::cout << "DONE!" << std::endl;
+
        return 0;
 }