| #include <stdio.h> | |
| #include <bpf/libbpf.h> | |
| #include <util/llvm-utils.h> | |
| #include <util/cache.h> | |
| #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 (!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) | |
| { | |
| fprintf(stderr, " (skip bpf parsing)"); | |
| 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()) { | |
| fprintf(stderr, " (no clang, try 'perf test -v LLVM')"); | |
| 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) { | |
| if (!verbose) | |
| fprintf(stderr, " (use -v to see error message)"); | |
| return -1; | |
| } | |
| err = test__bpf_parsing(obj_buf, obj_buf_sz); | |
| free(obj_buf); | |
| return err; | |
| } |