On Sat, Nov 26, 2016 at 07:03:50AM +0000, Wang Nan wrote: > Use a shell script to generate BPF functions declarations from kernel > source code, embed the generated header into a C string. Following > commits will utilizes clang's virtual file system to automatically > include this header to all BPF scripts. > > The generated header is wrapped by a BUILTIN_CLANG_NO_DEFAULT_INCLUDE. > This macro will be used by following commits to allow user disable this > and other builtin includes. > > Signed-off-by: Wang Nan <wangn...@huawei.com> > Cc: Arnaldo Carvalho de Melo <a...@redhat.com> > Cc: Alexei Starovoitov <a...@fb.com> > Cc: He Kuang <heku...@huawei.com> > Cc: Jiri Olsa <jo...@kernel.org> > Cc: Zefan Li <lize...@huawei.com> > Cc: pi3or...@163.com > --- > tools/perf/util/c++/Build | 1 + > tools/perf/util/c++/bpf-funcs-str.c | 228 > +++++++++++++++++++++++++++++++ > tools/perf/util/c++/clang-bpf-includes.h | 12 ++ > 3 files changed, 241 insertions(+) > create mode 100644 tools/perf/util/c++/bpf-funcs-str.c > create mode 100644 tools/perf/util/c++/clang-bpf-includes.h > > diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build > index 988fef1..bd71abf 100644 > --- a/tools/perf/util/c++/Build > +++ b/tools/perf/util/c++/Build > @@ -1,2 +1,3 @@ > libperf-$(CONFIG_CLANGLLVM) += clang.o > libperf-$(CONFIG_CLANGLLVM) += clang-test.o > +libperf-$(CONFIG_CLANGLLVM) += bpf-funcs-str.o > diff --git a/tools/perf/util/c++/bpf-funcs-str.c > b/tools/perf/util/c++/bpf-funcs-str.c > new file mode 100644 > index 0000000..f6bcf76 > --- /dev/null > +++ b/tools/perf/util/c++/bpf-funcs-str.c > @@ -0,0 +1,228 @@ > +/* > + * This file is generated by following script: > + * > + * #!/bin/bash > + * TEMP_KBUILD=$(mktemp -d) > + * KERNEL_DIR=$(pwd) > + * OUTPUT=tools/perf/util/c++/bpf-funcs-str.c > + * rm -rf $OUTPUT > + * echo "Use temp dir: $TEMP_KBUILD" > + * function finish() > + * { > + * rm -rf $TEMP_KBUILD > + * } > + * trap finish EXIT > + * SRCLIST=$(find -name "*.c" | xargs grep bpf_func_proto -l) > + * cd $TEMP_KBUILD > + * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig > + * cat << EOF >> ./.config > + * CONFIG_BPF=y > + * CONFIG_BPF_SYSCALL=y > + * CONFIG_PERF_EVENTS=y > + * CONFIG_SOCK_CGROUP_DATA=y > + * EOF > + * yes '' | make -C $KERNEL_DIR O=`pwd` oldconfig > + * FIXOBJLIST="" > + * for src in ${SRCLIST} > + * do > + * mkdir -p $(dirname $src) > + * cat << EOF > "${src}-fix.c" > + * #include <linux/init.h> > + * #undef __init > + * #define __init __attribute__((constructor)) > + * #include "`basename $src`" > + * EOF > + * if [ $(basename $src) == "syscall.c" ] > + * then > + * cat << EOF >> "${src}-fix.c" > + * const struct bpf_verifier_ops * > + * find_prog_type_export(enum bpf_prog_type type) > + * { > + * struct bpf_prog_aux aux; > + * struct bpf_prog p = {.aux = &aux }; > + * if (find_prog_type(type, &p)) > + * return NULL; > + * return p.aux->ops; > + * } > + * EOF > + * fi > + * FIXOBJLIST="$FIXOBJLIST ${src}-fix.o" > + * done > + * function dolink() > + * { > + * touch ./syms.c > + * echo gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen > + * gcc kernel/bpf/main.o ./syms.c $FIXOBJLIST -o ./gen > + * } > + * MAIN=kernel/bpf/main.c > + * cat << EOF > $MAIN > + * #include <uapi/linux/bpf.h> > + * #include <linux/bpf.h> > + * struct bpf_func { > + * const char *name; > + * int id; > + * } bpf_funcs[] = { > + * EOF > + * grep '^[[:space:]]BPF_FUNC_[^ ]*,' $KERNEL_DIR/include/uapi/linux/bpf.h | > \ > + * sed -e 's/.*BPF_FUNC_\([^,]*\),.*$/\1/g' | \ > + * xargs -n 1 sh -c 'echo {.name = \"$1\", .id = BPF_FUNC_$1}, >> '"$MAIN" > sh > + * cat << EOF >> $MAIN
This is pretty fragile and already broken. Please just hardcode them as-is. There is no need to be so fancy. > +"static void *(*bpf_map_lookup_elem)(void *, void *) = (void *)1;\n" > +"static long (*bpf_map_update_elem)(void *, void *, void *, unsigned long) = > (void *)2;\n" > +"static long (*bpf_map_delete_elem)(void *, void *) = (void *)3;\n" just hard code this way.