llvm.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. static int perf_config_cb(const char *var, const char *val,
  9. void *arg __maybe_unused)
  10. {
  11. return perf_default_config(var, val, arg);
  12. }
  13. #ifdef HAVE_LIBBPF_SUPPORT
  14. static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
  15. {
  16. struct bpf_object *obj;
  17. obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
  18. if (IS_ERR(obj))
  19. return TEST_FAIL;
  20. bpf_object__close(obj);
  21. return TEST_OK;
  22. }
  23. #else
  24. static int test__bpf_parsing(void *obj_buf __maybe_unused,
  25. size_t obj_buf_sz __maybe_unused)
  26. {
  27. pr_debug("Skip bpf parsing\n");
  28. return TEST_OK;
  29. }
  30. #endif
  31. static struct {
  32. const char *source;
  33. const char *desc;
  34. } bpf_source_table[__LLVM_TESTCASE_MAX] = {
  35. [LLVM_TESTCASE_BASE] = {
  36. .source = test_llvm__bpf_base_prog,
  37. .desc = "Basic BPF llvm compiling test",
  38. },
  39. [LLVM_TESTCASE_KBUILD] = {
  40. .source = test_llvm__bpf_test_kbuild_prog,
  41. .desc = "Test kbuild searching",
  42. },
  43. [LLVM_TESTCASE_BPF_PROLOGUE] = {
  44. .source = test_llvm__bpf_test_prologue_prog,
  45. .desc = "Compile source for BPF prologue generation test",
  46. },
  47. };
  48. int
  49. test_llvm__fetch_bpf_obj(void **p_obj_buf,
  50. size_t *p_obj_buf_sz,
  51. enum test_llvm__testcase idx,
  52. bool force)
  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. if (idx >= __LLVM_TESTCASE_MAX)
  60. return TEST_FAIL;
  61. source = bpf_source_table[idx].source;
  62. desc = bpf_source_table[idx].desc;
  63. perf_config(perf_config_cb, NULL);
  64. /*
  65. * Skip this test if user's .perfconfig doesn't set [llvm] section
  66. * and clang is not found in $PATH, and this is not perf test -v
  67. */
  68. if (!force && (verbose == 0 &&
  69. !llvm_param.user_set_param &&
  70. llvm__search_clang())) {
  71. pr_debug("No clang and no verbosive, skip this test\n");
  72. return TEST_SKIP;
  73. }
  74. /*
  75. * llvm is verbosity when error. Suppress all error output if
  76. * not 'perf test -v'.
  77. */
  78. old_verbose = verbose;
  79. if (verbose == 0)
  80. verbose = -1;
  81. *p_obj_buf = NULL;
  82. *p_obj_buf_sz = 0;
  83. if (!llvm_param.clang_bpf_cmd_template)
  84. goto out;
  85. if (!llvm_param.clang_opt)
  86. llvm_param.clang_opt = strdup("");
  87. err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
  88. llvm_param.clang_bpf_cmd_template,
  89. old_verbose ? "" : " 2>/dev/null");
  90. if (err < 0)
  91. goto out;
  92. err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
  93. if (err < 0)
  94. goto out;
  95. tmpl_old = llvm_param.clang_bpf_cmd_template;
  96. llvm_param.clang_bpf_cmd_template = tmpl_new;
  97. clang_opt_old = llvm_param.clang_opt;
  98. llvm_param.clang_opt = clang_opt_new;
  99. err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
  100. llvm_param.clang_bpf_cmd_template = tmpl_old;
  101. llvm_param.clang_opt = clang_opt_old;
  102. verbose = old_verbose;
  103. if (err)
  104. goto out;
  105. ret = TEST_OK;
  106. out:
  107. free(tmpl_new);
  108. free(clang_opt_new);
  109. if (ret != TEST_OK)
  110. pr_debug("Failed to compile test case: '%s'\n", desc);
  111. return ret;
  112. }
  113. int test__llvm(int subtest)
  114. {
  115. int ret;
  116. void *obj_buf = NULL;
  117. size_t obj_buf_sz = 0;
  118. if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
  119. return TEST_FAIL;
  120. ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
  121. subtest, false);
  122. if (ret == TEST_OK) {
  123. ret = test__bpf_parsing(obj_buf, obj_buf_sz);
  124. if (ret != TEST_OK) {
  125. pr_debug("Failed to parse test case '%s'\n",
  126. bpf_source_table[subtest].desc);
  127. }
  128. }
  129. free(obj_buf);
  130. return ret;
  131. }
  132. int test__llvm_subtest_get_nr(void)
  133. {
  134. return __LLVM_TESTCASE_MAX;
  135. }
  136. const char *test__llvm_subtest_get_desc(int subtest)
  137. {
  138. if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
  139. return NULL;
  140. return bpf_source_table[subtest].desc;
  141. }