Linux Perf
llvm.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include <stdio.h>
3 #include <bpf/libbpf.h>
4 #include <util/llvm-utils.h>
5 #include <util/cache.h>
6 #include "llvm.h"
7 #include "tests.h"
8 #include "debug.h"
9 #include "util.h"
10 
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 
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
23 static 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 
31 static struct {
32  const char *source;
33  const char *desc;
36  [LLVM_TESTCASE_BASE] = {
37  .source = test_llvm__bpf_base_prog,
38  .desc = "Basic BPF llvm compile",
39  },
42  .desc = "kbuild searching",
43  },
46  .desc = "Compile source for BPF prologue generation",
47  },
50  .desc = "Compile source for BPF relocation",
51  .should_load_fail = true,
52  },
53 };
54 
55 int
56 test_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 &&
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 
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,
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 
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 
121  llvm_param.clang_opt = clang_opt_old;
122 
123  verbose = old_verbose;
124  if (err)
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 }
135 
136 int 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 
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;
172 }
const char * clang_bpf_cmd_template
Definition: llvm-utils.h:23
int int err
Definition: 5sec.c:44
static bool force
Definition: builtin-diff.c:68
const char test_llvm__bpf_base_prog[]
Definition: llvm-src-base.c:2
const char test_llvm__bpf_test_prologue_prog[]
static int test__bpf_parsing(void *obj_buf __maybe_unused, size_t obj_buf_sz __maybe_unused)
Definition: llvm.c:23
#define pr_debug(fmt,...)
Definition: json.h:27
const char * test__llvm_subtest_get_desc(int subtest)
Definition: llvm.c:166
int test__llvm_subtest_get_nr(void)
Definition: llvm.c:161
bool user_set_param
Definition: llvm-utils.h:44
const char * clang_opt
Definition: llvm-utils.h:25
const char test_llvm__bpf_test_kbuild_prog[]
const char * desc
Definition: llvm.c:33
int test__llvm(struct test *test __maybe_unused, int subtest)
Definition: llvm.c:136
const char * source
Definition: llvm.c:32
const char test_llvm__bpf_test_relocation[]
test_llvm__testcase
Definition: llvm.h:17
int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz, enum test_llvm__testcase idx, bool force, bool *should_load_fail)
Definition: llvm.c:56
static struct @29 bpf_source_table[__LLVM_TESTCASE_MAX]
int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz)
Definition: llvm-utils.c:424
int llvm__search_clang(void)
Definition: llvm-utils.c:545
Definition: tests.h:30
bool should_load_fail
Definition: llvm.c:34
void free(void *)
int verbose
Definition: jevents.c:53
Definition: tests.h:25