Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
9bc898c7 WN |
2 | #include <stdio.h> |
3 | #include <bpf/libbpf.h> | |
4 | #include <util/llvm-utils.h> | |
5 | #include <util/cache.h> | |
b31de018 | 6 | #include "llvm.h" |
9bc898c7 WN |
7 | #include "tests.h" |
8 | #include "debug.h" | |
175729fc | 9 | #include "util.h" |
9bc898c7 | 10 | |
9bc898c7 WN |
11 | #ifdef HAVE_LIBBPF_SUPPORT |
12 | static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) | |
13 | { | |
14 | struct bpf_object *obj; | |
15 | ||
acf860ae | 16 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); |
e28ff1a8 | 17 | if (libbpf_get_error(obj)) |
b31de018 | 18 | return TEST_FAIL; |
9bc898c7 | 19 | bpf_object__close(obj); |
b31de018 | 20 | return TEST_OK; |
9bc898c7 WN |
21 | } |
22 | #else | |
23 | static int test__bpf_parsing(void *obj_buf __maybe_unused, | |
24 | size_t obj_buf_sz __maybe_unused) | |
25 | { | |
597bdeb4 | 26 | pr_debug("Skip bpf parsing\n"); |
b31de018 | 27 | return TEST_OK; |
9bc898c7 WN |
28 | } |
29 | #endif | |
30 | ||
b31de018 WN |
31 | static struct { |
32 | const char *source; | |
33 | const char *desc; | |
7b6982ce | 34 | bool should_load_fail; |
b31de018 WN |
35 | } bpf_source_table[__LLVM_TESTCASE_MAX] = { |
36 | [LLVM_TESTCASE_BASE] = { | |
37 | .source = test_llvm__bpf_base_prog, | |
030910c0 | 38 | .desc = "Basic BPF llvm compile", |
b31de018 | 39 | }, |
7af3f3d5 WN |
40 | [LLVM_TESTCASE_KBUILD] = { |
41 | .source = test_llvm__bpf_test_kbuild_prog, | |
030910c0 | 42 | .desc = "kbuild searching", |
7af3f3d5 | 43 | }, |
bbb7d492 WN |
44 | [LLVM_TESTCASE_BPF_PROLOGUE] = { |
45 | .source = test_llvm__bpf_test_prologue_prog, | |
030910c0 | 46 | .desc = "Compile source for BPF prologue generation", |
bbb7d492 | 47 | }, |
7b6982ce WN |
48 | [LLVM_TESTCASE_BPF_RELOCATION] = { |
49 | .source = test_llvm__bpf_test_relocation, | |
030910c0 | 50 | .desc = "Compile source for BPF relocation", |
7b6982ce WN |
51 | .should_load_fail = true, |
52 | }, | |
b31de018 WN |
53 | }; |
54 | ||
b31de018 WN |
55 | int |
56 | test_llvm__fetch_bpf_obj(void **p_obj_buf, | |
57 | size_t *p_obj_buf_sz, | |
916d4092 | 58 | enum test_llvm__testcase idx, |
7b6982ce WN |
59 | bool force, |
60 | bool *should_load_fail) | |
9bc898c7 | 61 | { |
b31de018 WN |
62 | const char *source; |
63 | const char *desc; | |
64 | const char *tmpl_old, *clang_opt_old; | |
65 | char *tmpl_new = NULL, *clang_opt_new = NULL; | |
66 | int err, old_verbose, ret = TEST_FAIL; | |
67 | ||
916d4092 | 68 | if (idx >= __LLVM_TESTCASE_MAX) |
b31de018 WN |
69 | return TEST_FAIL; |
70 | ||
916d4092 ACM |
71 | source = bpf_source_table[idx].source; |
72 | desc = bpf_source_table[idx].desc; | |
7b6982ce WN |
73 | if (should_load_fail) |
74 | *should_load_fail = bpf_source_table[idx].should_load_fail; | |
9bc898c7 | 75 | |
9bc898c7 WN |
76 | /* |
77 | * Skip this test if user's .perfconfig doesn't set [llvm] section | |
78 | * and clang is not found in $PATH, and this is not perf test -v | |
79 | */ | |
bb963e16 | 80 | if (!force && (verbose <= 0 && |
b31de018 WN |
81 | !llvm_param.user_set_param && |
82 | llvm__search_clang())) { | |
597bdeb4 | 83 | pr_debug("No clang and no verbosive, skip this test\n"); |
9bc898c7 WN |
84 | return TEST_SKIP; |
85 | } | |
86 | ||
9bc898c7 WN |
87 | /* |
88 | * llvm is verbosity when error. Suppress all error output if | |
89 | * not 'perf test -v'. | |
90 | */ | |
b31de018 | 91 | old_verbose = verbose; |
9bc898c7 WN |
92 | if (verbose == 0) |
93 | verbose = -1; | |
94 | ||
b31de018 WN |
95 | *p_obj_buf = NULL; |
96 | *p_obj_buf_sz = 0; | |
97 | ||
9bc898c7 | 98 | if (!llvm_param.clang_bpf_cmd_template) |
b31de018 | 99 | goto out; |
9bc898c7 WN |
100 | |
101 | if (!llvm_param.clang_opt) | |
102 | llvm_param.clang_opt = strdup(""); | |
103 | ||
b31de018 WN |
104 | err = asprintf(&tmpl_new, "echo '%s' | %s%s", source, |
105 | llvm_param.clang_bpf_cmd_template, | |
106 | old_verbose ? "" : " 2>/dev/null"); | |
9bc898c7 | 107 | if (err < 0) |
b31de018 | 108 | goto out; |
9bc898c7 WN |
109 | err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); |
110 | if (err < 0) | |
b31de018 | 111 | goto out; |
9bc898c7 | 112 | |
b31de018 | 113 | tmpl_old = llvm_param.clang_bpf_cmd_template; |
9bc898c7 | 114 | llvm_param.clang_bpf_cmd_template = tmpl_new; |
b31de018 | 115 | clang_opt_old = llvm_param.clang_opt; |
9bc898c7 | 116 | llvm_param.clang_opt = clang_opt_new; |
b31de018 WN |
117 | |
118 | err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz); | |
119 | ||
120 | llvm_param.clang_bpf_cmd_template = tmpl_old; | |
121 | llvm_param.clang_opt = clang_opt_old; | |
9bc898c7 WN |
122 | |
123 | verbose = old_verbose; | |
597bdeb4 | 124 | if (err) |
b31de018 WN |
125 | goto out; |
126 | ||
127 | ret = TEST_OK; | |
128 | out: | |
129 | free(tmpl_new); | |
130 | free(clang_opt_new); | |
131 | if (ret != TEST_OK) | |
132 | pr_debug("Failed to compile test case: '%s'\n", desc); | |
133 | return ret; | |
134 | } | |
9bc898c7 | 135 | |
81f17c90 | 136 | int test__llvm(struct test *test __maybe_unused, int subtest) |
b31de018 | 137 | { |
e8c6d500 WN |
138 | int ret; |
139 | void *obj_buf = NULL; | |
140 | size_t obj_buf_sz = 0; | |
7b6982ce | 141 | bool should_load_fail = false; |
b31de018 | 142 | |
e8c6d500 WN |
143 | if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) |
144 | return TEST_FAIL; | |
b31de018 | 145 | |
e8c6d500 | 146 | ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, |
7b6982ce | 147 | subtest, false, &should_load_fail); |
b31de018 | 148 | |
7b6982ce | 149 | if (ret == TEST_OK && !should_load_fail) { |
e8c6d500 WN |
150 | ret = test__bpf_parsing(obj_buf, obj_buf_sz); |
151 | if (ret != TEST_OK) { | |
152 | pr_debug("Failed to parse test case '%s'\n", | |
153 | bpf_source_table[subtest].desc); | |
b31de018 WN |
154 | } |
155 | } | |
e8c6d500 WN |
156 | free(obj_buf); |
157 | ||
158 | return ret; | |
159 | } | |
160 | ||
161 | int test__llvm_subtest_get_nr(void) | |
162 | { | |
163 | return __LLVM_TESTCASE_MAX; | |
164 | } | |
165 | ||
166 | const char *test__llvm_subtest_get_desc(int subtest) | |
167 | { | |
168 | if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) | |
169 | return NULL; | |
170 | ||
171 | return bpf_source_table[subtest].desc; | |
9bc898c7 | 172 | } |