at v5.13-rc7 180 lines 4.2 kB view raw
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_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 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, and this is not perf test -v 71 */ 72 if (!force && (verbose <= 0 && 73 !llvm_param.user_set_param && 74 llvm__search_clang())) { 75 pr_debug("No clang and no verbosive, skip this test\n"); 76 return TEST_SKIP; 77 } 78 79 /* 80 * llvm is verbosity when error. Suppress all error output if 81 * not 'perf test -v'. 82 */ 83 old_verbose = verbose; 84 if (verbose == 0) 85 verbose = -1; 86 87 *p_obj_buf = NULL; 88 *p_obj_buf_sz = 0; 89 90 if (!llvm_param.clang_bpf_cmd_template) 91 goto out; 92 93 if (!llvm_param.clang_opt) 94 llvm_param.clang_opt = strdup(""); 95 96 err = asprintf(&tmpl_new, "echo '%s' | %s%s", source, 97 llvm_param.clang_bpf_cmd_template, 98 old_verbose ? "" : " 2>/dev/null"); 99 if (err < 0) 100 goto out; 101 err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt); 102 if (err < 0) 103 goto out; 104 105 tmpl_old = llvm_param.clang_bpf_cmd_template; 106 llvm_param.clang_bpf_cmd_template = tmpl_new; 107 clang_opt_old = llvm_param.clang_opt; 108 llvm_param.clang_opt = clang_opt_new; 109 110 err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz); 111 112 llvm_param.clang_bpf_cmd_template = tmpl_old; 113 llvm_param.clang_opt = clang_opt_old; 114 115 verbose = old_verbose; 116 if (err) 117 goto out; 118 119 ret = TEST_OK; 120out: 121 free(tmpl_new); 122 free(clang_opt_new); 123 if (ret != TEST_OK) 124 pr_debug("Failed to compile test case: '%s'\n", desc); 125 return ret; 126} 127 128int test__llvm(struct test *test __maybe_unused, int subtest) 129{ 130 int ret; 131 void *obj_buf = NULL; 132 size_t obj_buf_sz = 0; 133 bool should_load_fail = false; 134 135 if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) 136 return TEST_FAIL; 137 138 ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, 139 subtest, false, &should_load_fail); 140 141 if (ret == TEST_OK && !should_load_fail) { 142 ret = test__bpf_parsing(obj_buf, obj_buf_sz); 143 if (ret != TEST_OK) { 144 pr_debug("Failed to parse test case '%s'\n", 145 bpf_source_table[subtest].desc); 146 } 147 } 148 free(obj_buf); 149 150 return ret; 151} 152 153int test__llvm_subtest_get_nr(void) 154{ 155 return __LLVM_TESTCASE_MAX; 156} 157 158const char *test__llvm_subtest_get_desc(int subtest) 159{ 160 if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) 161 return NULL; 162 163 return bpf_source_table[subtest].desc; 164} 165#else //HAVE_LIBBPF_SUPPORT 166int test__llvm(struct test *test __maybe_unused, int subtest __maybe_unused) 167{ 168 return TEST_SKIP; 169} 170 171int test__llvm_subtest_get_nr(void) 172{ 173 return 0; 174} 175 176const char *test__llvm_subtest_get_desc(int subtest __maybe_unused) 177{ 178 return NULL; 179} 180#endif // HAVE_LIBBPF_SUPPORT