llvm.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #include "util.h"
  9. #ifdef HAVE_LIBBPF_SUPPORT
  10. static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
  11. {
  12. struct bpf_object *obj;
  13. obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL);
  14. if (IS_ERR(obj))
  15. return TEST_FAIL;
  16. bpf_object__close(obj);
  17. return TEST_OK;
  18. }
  19. #else
  20. static int test__bpf_parsing(void *obj_buf __maybe_unused,
  21. size_t obj_buf_sz __maybe_unused)
  22. {
  23. pr_debug("Skip bpf parsing\n");
  24. return TEST_OK;
  25. }
  26. #endif
  27. static struct {
  28. const char *source;
  29. const char *desc;
  30. bool should_load_fail;
  31. } bpf_source_table[__LLVM_TESTCASE_MAX] = {
  32. [LLVM_TESTCASE_BASE] = {
  33. .source = test_llvm__bpf_base_prog,
  34. .desc = "Basic BPF llvm compiling test",
  35. },
  36. [LLVM_TESTCASE_KBUILD] = {
  37. .source = test_llvm__bpf_test_kbuild_prog,
  38. .desc = "Test kbuild searching",
  39. },
  40. [LLVM_TESTCASE_BPF_PROLOGUE] = {
  41. .source = test_llvm__bpf_test_prologue_prog,
  42. .desc = "Compile source for BPF prologue generation test",
  43. },
  44. [LLVM_TESTCASE_BPF_RELOCATION] = {
  45. .source = test_llvm__bpf_test_relocation,
  46. .desc = "Compile source for BPF relocation test",
  47. .should_load_fail = true,
  48. },
  49. };
  50. int
  51. test_llvm__fetch_bpf_obj(void **p_obj_buf,
  52. size_t *p_obj_buf_sz,
  53. enum test_llvm__testcase idx,
  54. bool force,
  55. bool *should_load_fail)
  56. {
  57. const char *source;
  58. const char *desc;
  59. const char *tmpl_old, *clang_opt_old;
  60. char *tmpl_new = NULL, *clang_opt_new = NULL;
  61. int err, old_verbose, ret = TEST_FAIL;
  62. if (idx >= __LLVM_TESTCASE_MAX)
  63. return TEST_FAIL;
  64. source = bpf_source_table[idx].source;
  65. desc = bpf_source_table[idx].desc;
  66. if (should_load_fail)
  67. *should_load_fail = bpf_source_table[idx].should_load_fail;
  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. * 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. *p_obj_buf = NULL;
  86. *p_obj_buf_sz = 0;
  87. if (!llvm_param.clang_bpf_cmd_template)
  88. goto out;
  89. if (!llvm_param.clang_opt)
  90. llvm_param.clang_opt = strdup("");
  91. err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
  92. llvm_param.clang_bpf_cmd_template,
  93. old_verbose ? "" : " 2>/dev/null");
  94. if (err < 0)
  95. goto out;
  96. err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
  97. if (err < 0)
  98. goto out;
  99. tmpl_old = llvm_param.clang_bpf_cmd_template;
  100. llvm_param.clang_bpf_cmd_template = tmpl_new;
  101. clang_opt_old = llvm_param.clang_opt;
  102. llvm_param.clang_opt = clang_opt_new;
  103. err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
  104. llvm_param.clang_bpf_cmd_template = tmpl_old;
  105. llvm_param.clang_opt = clang_opt_old;
  106. verbose = old_verbose;
  107. if (err)
  108. goto out;
  109. ret = TEST_OK;
  110. out:
  111. free(tmpl_new);
  112. free(clang_opt_new);
  113. if (ret != TEST_OK)
  114. pr_debug("Failed to compile test case: '%s'\n", desc);
  115. return ret;
  116. }
  117. int test__llvm(int subtest)
  118. {
  119. int ret;
  120. void *obj_buf = NULL;
  121. size_t obj_buf_sz = 0;
  122. bool should_load_fail = false;
  123. if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
  124. return TEST_FAIL;
  125. ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
  126. subtest, false, &should_load_fail);
  127. if (ret == TEST_OK && !should_load_fail) {
  128. ret = test__bpf_parsing(obj_buf, obj_buf_sz);
  129. if (ret != TEST_OK) {
  130. pr_debug("Failed to parse test case '%s'\n",
  131. bpf_source_table[subtest].desc);
  132. }
  133. }
  134. free(obj_buf);
  135. return ret;
  136. }
  137. int test__llvm_subtest_get_nr(void)
  138. {
  139. return __LLVM_TESTCASE_MAX;
  140. }
  141. const char *test__llvm_subtest_get_desc(int subtest)
  142. {
  143. if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
  144. return NULL;
  145. return bpf_source_table[subtest].desc;
  146. }