Use Clang's OverlayFileSystem, add '-include' options to make builtin clang define BPF functions. After this patch BPF script writer needn't define BPF functions by their own.
Add -DBUILTIN_CLANG_DEFAULT_INCLUDE to builtin clang so when adopting builtin clang BPF functions can be automatically defined, and keep undefined when using external clang. Passing a -UBUILTIN_CLANG_DEFAULT_INCLUDE to cancel this defaudefinition. Test cases are updated to avoid redefinition of these functions. 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/tests/bpf-script-example.c | 18 +++++++++------ tools/perf/tests/bpf-script-test-prologue.c | 2 ++ tools/perf/tests/bpf-script-test-relocation.c | 18 +++++++++------ tools/perf/util/c++/clang.cpp | 33 ++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c index ccbc19c..42dc341 100644 --- a/tools/perf/tests/bpf-script-example.c +++ b/tools/perf/tests/bpf-script-example.c @@ -8,13 +8,6 @@ #endif #define BPF_ANY 0 #define BPF_MAP_TYPE_ARRAY 2 -#define BPF_FUNC_map_lookup_elem 1 -#define BPF_FUNC_map_update_elem 2 - -static void *(*bpf_map_lookup_elem)(void *map, void *key) = - (void *) BPF_FUNC_map_lookup_elem; -static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = - (void *) BPF_FUNC_map_update_elem; struct bpf_map_def { unsigned int type; @@ -24,6 +17,17 @@ struct bpf_map_def { }; #define SEC(NAME) __attribute__((section(NAME), used)) + +#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE +#define BPF_FUNC_map_lookup_elem 1 +#define BPF_FUNC_map_update_elem 2 + +static void *(*bpf_map_lookup_elem)(void *map, void *key) = + (void *) BPF_FUNC_map_lookup_elem; +static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = + (void *) BPF_FUNC_map_update_elem; +#endif + struct bpf_map_def SEC("maps") flip_table = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index 7230e62..ada812b 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -13,8 +13,10 @@ #define FMODE_READ 0x1 #define FMODE_WRITE 0x2 +#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; +#endif SEC("func=null_lseek file->f_mode offset orig") int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, diff --git a/tools/perf/tests/bpf-script-test-relocation.c b/tools/perf/tests/bpf-script-test-relocation.c index 93af774..57c96a3 100644 --- a/tools/perf/tests/bpf-script-test-relocation.c +++ b/tools/perf/tests/bpf-script-test-relocation.c @@ -8,13 +8,6 @@ #endif #define BPF_ANY 0 #define BPF_MAP_TYPE_ARRAY 2 -#define BPF_FUNC_map_lookup_elem 1 -#define BPF_FUNC_map_update_elem 2 - -static void *(*bpf_map_lookup_elem)(void *map, void *key) = - (void *) BPF_FUNC_map_lookup_elem; -static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = - (void *) BPF_FUNC_map_update_elem; struct bpf_map_def { unsigned int type; @@ -24,6 +17,17 @@ struct bpf_map_def { }; #define SEC(NAME) __attribute__((section(NAME), used)) + +#ifndef BUILTIN_CLANG_DEFAULT_INCLUDE +#define BPF_FUNC_map_lookup_elem 1 +#define BPF_FUNC_map_update_elem 2 + +static void *(*bpf_map_lookup_elem)(void *map, void *key) = + (void *) BPF_FUNC_map_lookup_elem; +static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = + (void *) BPF_FUNC_map_update_elem; +#endif + struct bpf_map_def SEC("maps") my_table = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index 48bd3ee..926dae1 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp @@ -39,9 +39,17 @@ #include "util-cxx.h" #include "perf-hooks.h" #include "jit-helpers.h" +#include "clang-bpf-includes.h" namespace perf { +static struct BPFHeader { + llvm::StringRef Path; + llvm::StringRef Content; +} BPFHeaders[] = { + {"/virtual/bpf-funcs.h", clang_builtin_bpf_funcs_str}, +}; + static std::unique_ptr<llvm::LLVMContext> LLVMCtx; using namespace clang; @@ -66,6 +74,11 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path, "-x", "c"}; CCArgs.append(CFlags.begin(), CFlags.end()); + for (BPFHeader &h : BPFHeaders) { + CCArgs.append(1, "-include"); + CCArgs.append(1, h.Path.begin()); + } + CompilerInvocation *CI = tooling::newInvocation(&Diags, CCArgs); FrontendOptions& Opts = CI->getFrontendOpts(); @@ -74,6 +87,22 @@ createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path, return CI; } +static IntrusiveRefCntPtr<vfs::FileSystem> +addBPFHeaders(IntrusiveRefCntPtr<vfs::FileSystem> VFS) +{ + using namespace vfs; + + llvm::IntrusiveRefCntPtr<OverlayFileSystem> OverlayFS( + new OverlayFileSystem(VFS)); + llvm::IntrusiveRefCntPtr<InMemoryFileSystem> MemFS( + new InMemoryFileSystem(true)); + OverlayFS->pushOverlay(MemFS); + + for (BPFHeader &h : BPFHeaders) + MemFS->addFile(h.Path, 0, llvm::MemoryBuffer::getMemBuffer(h.Content)); + return OverlayFS; +} + static std::unique_ptr<PerfModule> getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path, IntrusiveRefCntPtr<vfs::FileSystem> VFS) @@ -81,7 +110,8 @@ getModuleFromSource(llvm::opt::ArgStringList CFlags, CompilerInstance Clang; Clang.createDiagnostics(); - Clang.setVirtualFileSystem(&*VFS); + IntrusiveRefCntPtr<vfs::FileSystem> OverlayVFS = addBPFHeaders(VFS); + Clang.setVirtualFileSystem(&*OverlayVFS); IntrusiveRefCntPtr<CompilerInvocation> CI = createCompilerInvocation(std::move(CFlags), Path, @@ -363,6 +393,7 @@ public: { CFlags.push_back(KVerDef.c_str()); CFlags.push_back(NRCpusDef.c_str()); + CFlags.push_back("-DBUILTIN_CLANG_DEFAULT_INCLUDE"); fillCFlagsFromString(CFlags, clang_opt); fillCFlagsFromString(CFlags, kbuild_include_opts, true); -- 2.10.1