#include #include #include #include #include "tests.h" #include "debug.h" static int perf_config_cb(const char *var, const char *val, void *arg __maybe_unused) { return perf_default_config(var, val, arg); } /* * Randomly give it a "version" section since we don't really load it * into kernel */ static const char test_bpf_prog[] = "__attribute__((section(\"do_fork\"), used)) " "int fork(void *ctx) {return 0;} " "char _license[] __attribute__((section(\"license\"), used)) = \"GPL\";" "int _version __attribute__((section(\"version\"), used)) = 0x40100;"; #ifdef HAVE_LIBBPF_SUPPORT static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) { struct bpf_object *obj; obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); if (IS_ERR(obj)) return -1; bpf_object__close(obj); return 0; } #else static int test__bpf_parsing(void *obj_buf __maybe_unused, size_t obj_buf_sz __maybe_unused) { pr_debug("Skip bpf parsing\n"); return 0; } #endif int test__llvm(void) { char *tmpl_new, *clang_opt_new; void *obj_buf; size_t obj_buf_sz; int err, old_verbose; perf_config(perf_config_cb, NULL); /* * Skip this test if user's .perfconfig doesn't set [llvm] section * and clang is not found in $PATH, and this is not perf test -v */ if (verbose == 0 && !llvm_param.user_set_param && llvm__search_clang()) { pr_debug("No clang and no verbosive, skip this test\n"); return TEST_SKIP; } old_verbose = verbose; /* * llvm is verbosity when error. Suppress all error output if * not 'perf test -v'. */ if (verbose == 0) verbose = -1; if (!llvm_param.clang_bpf_cmd_template) return -1; if (!llvm_param.clang_opt) llvm_param.clang_opt = strdup(""); err = asprintf(&tmpl_new, "echo '%s' | %s", test_bpf_prog, llvm_param.clang_bpf_cmd_template); if (err < 0) return -1; err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); if (err < 0) return -1; llvm_param.clang_bpf_cmd_template = tmpl_new; llvm_param.clang_opt = clang_opt_new; err = llvm__compile_bpf("-", &obj_buf, &obj_buf_sz); verbose = old_verbose; if (err) return TEST_FAIL; err = test__bpf_parsing(obj_buf, obj_buf_sz); free(obj_buf); return err; }