fuzzer_common.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (C) 2025 Intel Corporation. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  3. #include "fuzzer_common.h"
  4. #include <iostream>
  5. #include <string.h>
  6. void
  7. print_execution_args(const wasm_export_t &export_type,
  8. const std::vector<wasm_val_t> &args, unsigned param_count)
  9. {
  10. std::cout << "[EXECUTION] " << export_type.name << "(";
  11. for (unsigned p_i = 0; p_i < param_count; p_i++) {
  12. if (p_i != 0) {
  13. std::cout << ", ";
  14. }
  15. switch (args[p_i].kind) {
  16. case WASM_I32:
  17. std::cout << "i32:" << args[p_i].of.i32;
  18. break;
  19. case WASM_I64:
  20. std::cout << "i64:" << args[p_i].of.i64;
  21. break;
  22. case WASM_F32:
  23. std::cout << "f32:" << args[p_i].of.f32;
  24. break;
  25. case WASM_F64:
  26. std::cout << "f64:" << args[p_i].of.f64;
  27. break;
  28. case WASM_EXTERNREF:
  29. std::cout << "externref:" << args[p_i].of.foreign;
  30. break;
  31. default:
  32. // because aft is_supported_val_kind() check, so we can safely
  33. // return as WASM_FUNCREF
  34. std::cout << "funcref:" << args[p_i].of.ref;
  35. break;
  36. }
  37. }
  38. std::cout << ")" << std::endl;
  39. }
  40. bool
  41. execute_export_functions(wasm_module_t module, wasm_module_inst_t inst)
  42. {
  43. int32_t export_count = wasm_runtime_get_export_count(module);
  44. for (int e_i = 0; e_i < export_count; e_i++) {
  45. wasm_export_t export_type;
  46. memset(&export_type, 0, sizeof(export_type));
  47. wasm_runtime_get_export_type(module, e_i, &export_type);
  48. if (export_type.kind != WASM_IMPORT_EXPORT_KIND_FUNC) {
  49. continue;
  50. }
  51. wasm_function_inst_t func =
  52. wasm_runtime_lookup_function(inst, export_type.name);
  53. if (!func) {
  54. std::cout << "Failed to lookup function: " << export_type.name
  55. << std::endl;
  56. continue;
  57. }
  58. wasm_func_type_t func_type = export_type.u.func_type;
  59. uint32_t param_count = wasm_func_type_get_param_count(func_type);
  60. /* build arguments with capacity reservation */
  61. std::vector<wasm_val_t> args;
  62. args.reserve(param_count); // Optimization: prevent reallocations
  63. for (unsigned p_i = 0; p_i < param_count; p_i++) {
  64. wasm_valkind_t param_type =
  65. wasm_func_type_get_param_valkind(func_type, p_i);
  66. if (!is_supported_val_kind(param_type)) {
  67. std::cout
  68. << "Bypass execution because of unsupported value kind: "
  69. << param_type << std::endl;
  70. return true;
  71. }
  72. wasm_val_t arg = pre_defined_val(param_type);
  73. args.push_back(arg);
  74. }
  75. /* build results storage */
  76. uint32_t result_count = wasm_func_type_get_result_count(func_type);
  77. std::vector<wasm_val_t> results(
  78. result_count); // Optimization: direct initialization
  79. print_execution_args(export_type, args, param_count);
  80. /* execute the function */
  81. wasm_exec_env_t exec_env = wasm_runtime_get_exec_env_singleton(inst);
  82. if (!exec_env) {
  83. std::cout << "Failed to get exec env" << std::endl;
  84. return false;
  85. }
  86. bool ret =
  87. wasm_runtime_call_wasm_a(exec_env, func, result_count,
  88. results.data(), param_count, args.data());
  89. if (!ret) {
  90. const char *exception = wasm_runtime_get_exception(inst);
  91. if (!exception) {
  92. std::cout << "[EXECUTION] " << export_type.name
  93. << "() failed. No exception info." << std::endl;
  94. }
  95. else {
  96. std::cout << "[EXECUTION] " << export_type.name << "() failed. "
  97. << exception << std::endl;
  98. }
  99. }
  100. wasm_runtime_clear_exception(inst);
  101. }
  102. return true;
  103. }
  104. void
  105. report_fuzzer_error(FuzzerErrorPhase phase, const char *message)
  106. {
  107. const char *phase_name = "";
  108. switch (phase) {
  109. case FuzzerErrorPhase::LOADING:
  110. phase_name = "LOADING";
  111. break;
  112. case FuzzerErrorPhase::INSTANTIATING:
  113. phase_name = "INSTANTIATING";
  114. break;
  115. case FuzzerErrorPhase::COMPILING:
  116. phase_name = "COMPILING";
  117. break;
  118. case FuzzerErrorPhase::EXECUTION:
  119. phase_name = "EXECUTION";
  120. break;
  121. case FuzzerErrorPhase::CLEANUP:
  122. phase_name = "CLEANUP";
  123. break;
  124. }
  125. std::cout << "[" << phase_name << "] " << message << std::endl;
  126. }