Linux Audio

Check our new training course

Loading...
v4.6
 
  1#include <stdio.h>
  2#include <bpf/libbpf.h>
  3#include <util/llvm-utils.h>
  4#include <util/cache.h>
  5#include "llvm.h"
  6#include "tests.h"
  7#include "debug.h"
  8
  9#ifdef HAVE_LIBBPF_SUPPORT
 
 
 
 10static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
 11{
 12	struct bpf_object *obj;
 13
 14	obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
 15	if (IS_ERR(obj))
 16		return TEST_FAIL;
 17	bpf_object__close(obj);
 18	return TEST_OK;
 19}
 20#else
 21static int test__bpf_parsing(void *obj_buf __maybe_unused,
 22			     size_t obj_buf_sz __maybe_unused)
 23{
 24	pr_debug("Skip bpf parsing\n");
 25	return TEST_OK;
 26}
 27#endif
 28
 29static struct {
 30	const char *source;
 31	const char *desc;
 32	bool should_load_fail;
 33} bpf_source_table[__LLVM_TESTCASE_MAX] = {
 34	[LLVM_TESTCASE_BASE] = {
 35		.source = test_llvm__bpf_base_prog,
 36		.desc = "Basic BPF llvm compiling test",
 37	},
 38	[LLVM_TESTCASE_KBUILD] = {
 39		.source = test_llvm__bpf_test_kbuild_prog,
 40		.desc = "Test kbuild searching",
 41	},
 42	[LLVM_TESTCASE_BPF_PROLOGUE] = {
 43		.source = test_llvm__bpf_test_prologue_prog,
 44		.desc = "Compile source for BPF prologue generation test",
 45	},
 46	[LLVM_TESTCASE_BPF_RELOCATION] = {
 47		.source = test_llvm__bpf_test_relocation,
 48		.desc = "Compile source for BPF relocation test",
 49		.should_load_fail = true,
 50	},
 51};
 52
 53int
 54test_llvm__fetch_bpf_obj(void **p_obj_buf,
 55			 size_t *p_obj_buf_sz,
 56			 enum test_llvm__testcase idx,
 57			 bool force,
 58			 bool *should_load_fail)
 59{
 60	const char *source;
 61	const char *desc;
 62	const char *tmpl_old, *clang_opt_old;
 63	char *tmpl_new = NULL, *clang_opt_new = NULL;
 64	int err, old_verbose, ret = TEST_FAIL;
 65
 66	if (idx >= __LLVM_TESTCASE_MAX)
 67		return TEST_FAIL;
 68
 69	source = bpf_source_table[idx].source;
 70	desc = bpf_source_table[idx].desc;
 71	if (should_load_fail)
 72		*should_load_fail = bpf_source_table[idx].should_load_fail;
 73
 74	/*
 75	 * Skip this test if user's .perfconfig doesn't set [llvm] section
 76	 * and clang is not found in $PATH, and this is not perf test -v
 77	 */
 78	if (!force && (verbose == 0 &&
 79		       !llvm_param.user_set_param &&
 80		       llvm__search_clang())) {
 81		pr_debug("No clang and no verbosive, skip this test\n");
 82		return TEST_SKIP;
 83	}
 84
 85	/*
 86	 * llvm is verbosity when error. Suppress all error output if
 87	 * not 'perf test -v'.
 88	 */
 89	old_verbose = verbose;
 90	if (verbose == 0)
 91		verbose = -1;
 92
 93	*p_obj_buf = NULL;
 94	*p_obj_buf_sz = 0;
 95
 96	if (!llvm_param.clang_bpf_cmd_template)
 97		goto out;
 98
 99	if (!llvm_param.clang_opt)
100		llvm_param.clang_opt = strdup("");
101
102	err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
103		       llvm_param.clang_bpf_cmd_template,
104		       old_verbose ? "" : " 2>/dev/null");
105	if (err < 0)
106		goto out;
107	err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
108	if (err < 0)
109		goto out;
110
111	tmpl_old = llvm_param.clang_bpf_cmd_template;
112	llvm_param.clang_bpf_cmd_template = tmpl_new;
113	clang_opt_old = llvm_param.clang_opt;
114	llvm_param.clang_opt = clang_opt_new;
115
116	err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
117
118	llvm_param.clang_bpf_cmd_template = tmpl_old;
119	llvm_param.clang_opt = clang_opt_old;
120
121	verbose = old_verbose;
122	if (err)
123		goto out;
124
125	ret = TEST_OK;
126out:
127	free(tmpl_new);
128	free(clang_opt_new);
129	if (ret != TEST_OK)
130		pr_debug("Failed to compile test case: '%s'\n", desc);
131	return ret;
132}
133
134int test__llvm(int subtest)
135{
136	int ret;
137	void *obj_buf = NULL;
138	size_t obj_buf_sz = 0;
139	bool should_load_fail = false;
140
141	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
142		return TEST_FAIL;
143
144	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
145				       subtest, false, &should_load_fail);
146
147	if (ret == TEST_OK && !should_load_fail) {
148		ret = test__bpf_parsing(obj_buf, obj_buf_sz);
149		if (ret != TEST_OK) {
150			pr_debug("Failed to parse test case '%s'\n",
151				 bpf_source_table[subtest].desc);
152		}
153	}
154	free(obj_buf);
155
156	return ret;
157}
 
158
159int test__llvm_subtest_get_nr(void)
 
160{
161	return __LLVM_TESTCASE_MAX;
 
 
 
 
 
162}
163
164const char *test__llvm_subtest_get_desc(int subtest)
 
165{
166	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
167		return NULL;
 
 
 
 
 
168
169	return bpf_source_table[subtest].desc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170}
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2#include <stdio.h>
  3#include <stdlib.h>
  4#include <string.h>
 
 
  5#include "tests.h"
  6#include "debug.h"
  7
  8#ifdef HAVE_LIBBPF_SUPPORT
  9#include <bpf/libbpf.h>
 10#include <util/llvm-utils.h>
 11#include "llvm.h"
 12static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
 13{
 14	struct bpf_object *obj;
 15
 16	obj = bpf_object__open_mem(obj_buf, obj_buf_sz, NULL);
 17	if (libbpf_get_error(obj))
 18		return TEST_FAIL;
 19	bpf_object__close(obj);
 20	return TEST_OK;
 21}
 
 
 
 
 
 
 
 
 22
 23static struct {
 24	const char *source;
 25	const char *desc;
 26	bool should_load_fail;
 27} bpf_source_table[__LLVM_TESTCASE_MAX] = {
 28	[LLVM_TESTCASE_BASE] = {
 29		.source = test_llvm__bpf_base_prog,
 30		.desc = "Basic BPF llvm compile",
 31	},
 32	[LLVM_TESTCASE_KBUILD] = {
 33		.source = test_llvm__bpf_test_kbuild_prog,
 34		.desc = "kbuild searching",
 35	},
 36	[LLVM_TESTCASE_BPF_PROLOGUE] = {
 37		.source = test_llvm__bpf_test_prologue_prog,
 38		.desc = "Compile source for BPF prologue generation",
 39	},
 40	[LLVM_TESTCASE_BPF_RELOCATION] = {
 41		.source = test_llvm__bpf_test_relocation,
 42		.desc = "Compile source for BPF relocation",
 43		.should_load_fail = true,
 44	},
 45};
 46
 47int
 48test_llvm__fetch_bpf_obj(void **p_obj_buf,
 49			 size_t *p_obj_buf_sz,
 50			 enum test_llvm__testcase idx,
 51			 bool force,
 52			 bool *should_load_fail)
 53{
 54	const char *source;
 55	const char *desc;
 56	const char *tmpl_old, *clang_opt_old;
 57	char *tmpl_new = NULL, *clang_opt_new = NULL;
 58	int err, old_verbose, ret = TEST_FAIL;
 59
 60	if (idx >= __LLVM_TESTCASE_MAX)
 61		return TEST_FAIL;
 62
 63	source = bpf_source_table[idx].source;
 64	desc = bpf_source_table[idx].desc;
 65	if (should_load_fail)
 66		*should_load_fail = bpf_source_table[idx].should_load_fail;
 67
 68	/*
 69	 * Skip this test if user's .perfconfig doesn't set [llvm] section
 70	 * and clang is not found in $PATH
 71	 */
 72	if (!force && (!llvm_param.user_set_param &&
 
 73		       llvm__search_clang())) {
 74		pr_debug("No clang, skip this test\n");
 75		return TEST_SKIP;
 76	}
 77
 78	/*
 79	 * llvm is verbosity when error. Suppress all error output if
 80	 * not 'perf test -v'.
 81	 */
 82	old_verbose = verbose;
 83	if (verbose == 0)
 84		verbose = -1;
 85
 86	*p_obj_buf = NULL;
 87	*p_obj_buf_sz = 0;
 88
 89	if (!llvm_param.clang_bpf_cmd_template)
 90		goto out;
 91
 92	if (!llvm_param.clang_opt)
 93		llvm_param.clang_opt = strdup("");
 94
 95	err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
 96		       llvm_param.clang_bpf_cmd_template,
 97		       old_verbose ? "" : " 2>/dev/null");
 98	if (err < 0)
 99		goto out;
100	err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
101	if (err < 0)
102		goto out;
103
104	tmpl_old = llvm_param.clang_bpf_cmd_template;
105	llvm_param.clang_bpf_cmd_template = tmpl_new;
106	clang_opt_old = llvm_param.clang_opt;
107	llvm_param.clang_opt = clang_opt_new;
108
109	err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
110
111	llvm_param.clang_bpf_cmd_template = tmpl_old;
112	llvm_param.clang_opt = clang_opt_old;
113
114	verbose = old_verbose;
115	if (err)
116		goto out;
117
118	ret = TEST_OK;
119out:
120	free(tmpl_new);
121	free(clang_opt_new);
122	if (ret != TEST_OK)
123		pr_debug("Failed to compile test case: '%s'\n", desc);
124	return ret;
125}
126
127static int test__llvm(int subtest)
128{
129	int ret;
130	void *obj_buf = NULL;
131	size_t obj_buf_sz = 0;
132	bool should_load_fail = false;
133
134	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
135		return TEST_FAIL;
136
137	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
138				       subtest, false, &should_load_fail);
139
140	if (ret == TEST_OK && !should_load_fail) {
141		ret = test__bpf_parsing(obj_buf, obj_buf_sz);
142		if (ret != TEST_OK) {
143			pr_debug("Failed to parse test case '%s'\n",
144				 bpf_source_table[subtest].desc);
145		}
146	}
147	free(obj_buf);
148
149	return ret;
150}
151#endif //HAVE_LIBBPF_SUPPORT
152
153static int test__llvm__bpf_base_prog(struct test_suite *test __maybe_unused,
154				     int subtest __maybe_unused)
155{
156#ifdef HAVE_LIBBPF_SUPPORT
157	return test__llvm(LLVM_TESTCASE_BASE);
158#else
159	pr_debug("Skip LLVM test because BPF support is not compiled\n");
160	return TEST_SKIP;
161#endif
162}
163
164static int test__llvm__bpf_test_kbuild_prog(struct test_suite *test __maybe_unused,
165					    int subtest __maybe_unused)
166{
167#ifdef HAVE_LIBBPF_SUPPORT
168	return test__llvm(LLVM_TESTCASE_KBUILD);
169#else
170	pr_debug("Skip LLVM test because BPF support is not compiled\n");
171	return TEST_SKIP;
172#endif
173}
174
175static int test__llvm__bpf_test_prologue_prog(struct test_suite *test __maybe_unused,
176					      int subtest __maybe_unused)
177{
178#ifdef HAVE_LIBBPF_SUPPORT
179	return test__llvm(LLVM_TESTCASE_BPF_PROLOGUE);
180#else
181	pr_debug("Skip LLVM test because BPF support is not compiled\n");
182	return TEST_SKIP;
183#endif
184}
185
186static int test__llvm__bpf_test_relocation(struct test_suite *test __maybe_unused,
187					   int subtest __maybe_unused)
188{
189#ifdef HAVE_LIBBPF_SUPPORT
190	return test__llvm(LLVM_TESTCASE_BPF_RELOCATION);
191#else
192	pr_debug("Skip LLVM test because BPF support is not compiled\n");
193	return TEST_SKIP;
194#endif
195}
196
197
198static struct test_case llvm_tests[] = {
199#ifdef HAVE_LIBBPF_SUPPORT
200	TEST_CASE("Basic BPF llvm compile", llvm__bpf_base_prog),
201	TEST_CASE("kbuild searching", llvm__bpf_test_kbuild_prog),
202	TEST_CASE("Compile source for BPF prologue generation",
203		  llvm__bpf_test_prologue_prog),
204	TEST_CASE("Compile source for BPF relocation", llvm__bpf_test_relocation),
205#else
206	TEST_CASE_REASON("Basic BPF llvm compile", llvm__bpf_base_prog, "not compiled in"),
207	TEST_CASE_REASON("kbuild searching", llvm__bpf_test_kbuild_prog, "not compiled in"),
208	TEST_CASE_REASON("Compile source for BPF prologue generation",
209			llvm__bpf_test_prologue_prog, "not compiled in"),
210	TEST_CASE_REASON("Compile source for BPF relocation",
211			llvm__bpf_test_relocation, "not compiled in"),
212#endif
213	{ .name = NULL, }
214};
215
216struct test_suite suite__llvm = {
217	.desc = "LLVM search and compile",
218	.test_cases = llvm_tests,
219};