llvm.c 3.9 KB

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