Linux Audio

Check our new training course

Loading...
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};
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2#include <stdio.h>
  3#include <stdlib.h>
  4#include <string.h>
  5#include <bpf/libbpf.h>
  6#include <util/llvm-utils.h>
  7#include "llvm.h"
  8#include "tests.h"
  9#include "debug.h"
 10
 11#ifdef HAVE_LIBBPF_SUPPORT
 
 
 
 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_buffer(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#else
 23static int test__bpf_parsing(void *obj_buf __maybe_unused,
 24			     size_t obj_buf_sz __maybe_unused)
 25{
 26	pr_debug("Skip bpf parsing\n");
 27	return TEST_OK;
 28}
 29#endif
 30
 31static struct {
 32	const char *source;
 33	const char *desc;
 34	bool should_load_fail;
 35} bpf_source_table[__LLVM_TESTCASE_MAX] = {
 36	[LLVM_TESTCASE_BASE] = {
 37		.source = test_llvm__bpf_base_prog,
 38		.desc = "Basic BPF llvm compile",
 39	},
 40	[LLVM_TESTCASE_KBUILD] = {
 41		.source = test_llvm__bpf_test_kbuild_prog,
 42		.desc = "kbuild searching",
 43	},
 44	[LLVM_TESTCASE_BPF_PROLOGUE] = {
 45		.source = test_llvm__bpf_test_prologue_prog,
 46		.desc = "Compile source for BPF prologue generation",
 47	},
 48	[LLVM_TESTCASE_BPF_RELOCATION] = {
 49		.source = test_llvm__bpf_test_relocation,
 50		.desc = "Compile source for BPF relocation",
 51		.should_load_fail = true,
 52	},
 53};
 54
 55int
 56test_llvm__fetch_bpf_obj(void **p_obj_buf,
 57			 size_t *p_obj_buf_sz,
 58			 enum test_llvm__testcase idx,
 59			 bool force,
 60			 bool *should_load_fail)
 61{
 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
 68	if (idx >= __LLVM_TESTCASE_MAX)
 69		return TEST_FAIL;
 70
 71	source = bpf_source_table[idx].source;
 72	desc = bpf_source_table[idx].desc;
 73	if (should_load_fail)
 74		*should_load_fail = bpf_source_table[idx].should_load_fail;
 75
 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	 */
 80	if (!force && (verbose <= 0 &&
 81		       !llvm_param.user_set_param &&
 82		       llvm__search_clang())) {
 83		pr_debug("No clang and no verbosive, skip this test\n");
 84		return TEST_SKIP;
 85	}
 86
 87	/*
 88	 * llvm is verbosity when error. Suppress all error output if
 89	 * not 'perf test -v'.
 90	 */
 91	old_verbose = verbose;
 92	if (verbose == 0)
 93		verbose = -1;
 94
 95	*p_obj_buf = NULL;
 96	*p_obj_buf_sz = 0;
 97
 98	if (!llvm_param.clang_bpf_cmd_template)
 99		goto out;
100
101	if (!llvm_param.clang_opt)
102		llvm_param.clang_opt = strdup("");
103
104	err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
105		       llvm_param.clang_bpf_cmd_template,
106		       old_verbose ? "" : " 2>/dev/null");
107	if (err < 0)
108		goto out;
109	err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
110	if (err < 0)
111		goto out;
112
113	tmpl_old = llvm_param.clang_bpf_cmd_template;
114	llvm_param.clang_bpf_cmd_template = tmpl_new;
115	clang_opt_old = llvm_param.clang_opt;
116	llvm_param.clang_opt = clang_opt_new;
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;
122
123	verbose = old_verbose;
124	if (err)
125		goto out;
126
127	ret = TEST_OK;
128out:
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}
135
136int test__llvm(struct test *test __maybe_unused, int subtest)
137{
138	int ret;
139	void *obj_buf = NULL;
140	size_t obj_buf_sz = 0;
141	bool should_load_fail = false;
142
143	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
144		return TEST_FAIL;
145
146	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
147				       subtest, false, &should_load_fail);
148
149	if (ret == TEST_OK && !should_load_fail) {
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);
154		}
155	}
156	free(obj_buf);
157
158	return ret;
159}
 
160
161int test__llvm_subtest_get_nr(void)
 
162{
163	return __LLVM_TESTCASE_MAX;
 
 
 
 
 
164}
165
166const 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;
 
 
 
 
 
 
 
 
172}