From 59b15811c28e405b93f7babbd620da672ce3946c Mon Sep 17 00:00:00 2001 From: "liang.he@intel.com" Date: Sun, 5 Jan 2025 08:12:30 +0000 Subject: [PATCH] Refactor wasm interpreter to use predefined values and enhance argument logging in execution --- core/iwasm/interpreter/wasm_interp_fast.c | 7 +- .../wasm-mutator-fuzz/wasm_mutator_fuzz.cc | 143 ++++++++---------- 2 files changed, 67 insertions(+), 83 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 531468282f..f44644e456 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1670,7 +1670,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, { uint32 ret_idx; WASMFuncType *func_type; - uint32 off, ret_offset; + int32 off; + uint32 ret_offset; uint8 *ret_types; if (cur_func->is_import_func) func_type = cur_func->u.func_import->func_type; @@ -1682,9 +1683,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, ret_offset = prev_frame->ret_offset; for (ret_idx = 0, - off = sizeof(int16) * (func_type->result_count - 1); + off = (int32)sizeof(int16) * (func_type->result_count - 1); ret_idx < func_type->result_count; - ret_idx++, off -= sizeof(int16)) { + ret_idx++, off -= (int32)sizeof(int16)) { if (ret_types[ret_idx] == VALUE_TYPE_I64 || ret_types[ret_idx] == VALUE_TYPE_F64) { PUT_I64_TO_ADDR(prev_frame->lp + ret_offset, diff --git a/tests/fuzz/wasm-mutator-fuzz/wasm_mutator_fuzz.cc b/tests/fuzz/wasm-mutator-fuzz/wasm_mutator_fuzz.cc index fdbd2f8841..4b3d8d942d 100644 --- a/tests/fuzz/wasm-mutator-fuzz/wasm_mutator_fuzz.cc +++ b/tests/fuzz/wasm-mutator-fuzz/wasm_mutator_fuzz.cc @@ -13,70 +13,73 @@ using namespace std; -/* - * there is a unsigned integer overflow in - * /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/random.tcc:416 - * - * use srand() and rand() instead - */ - -static int32_t -generate_random_int32() -{ - return (int32_t)rand(); -} - -static int64_t -generate_random_int64() -{ - return ((int64_t)rand() << 32) | rand(); -} - -static float -generate_random_float() -{ - return (float)rand() / (float)RAND_MAX; -} - -static double -generate_random_double() +static bool +is_supported_val_kind(wasm_valkind_t kind) { - return (double)rand() / (double)RAND_MAX; + return kind == WASM_I32 || kind == WASM_I64 || kind == WASM_F32 + || kind == WASM_F64 || kind == WASM_EXTERNREF + || kind == WASM_FUNCREF; } static wasm_val_t -random_gen_val(wasm_valkind_t kind) +pre_defined_val(wasm_valkind_t kind) { - srand(1024); - if (kind == WASM_I32) { - return wasm_val_t{ .kind = WASM_I32, - .of = { .i32 = generate_random_int32() } }; + return wasm_val_t{ .kind = WASM_I32, .of = { .i32 = 2025 } }; } else if (kind == WASM_I64) { - return wasm_val_t{ .kind = WASM_I64, - .of = { .i64 = generate_random_int64() } }; + return wasm_val_t{ .kind = WASM_I64, .of = { .i64 = 168 } }; } else if (kind == WASM_F32) { - return wasm_val_t{ .kind = WASM_F32, - .of = { .f32 = generate_random_float() } }; + return wasm_val_t{ .kind = WASM_F32, .of = { .f32 = 3.14159f } }; } else if (kind == WASM_F64) { - return wasm_val_t{ .kind = WASM_F64, - .of = { .f64 = generate_random_double() } }; + return wasm_val_t{ .kind = WASM_F64, .of = { .f64 = 2.71828 } }; } else if (kind == WASM_EXTERNREF) { return wasm_val_t{ .kind = WASM_EXTERNREF, - .of = { .foreign = - (uintptr_t)generate_random_int64() } }; + .of = { .foreign = 0xabcddead } }; } - else if (kind == WASM_FUNCREF) { + // because aft is_supported_val_kind() check, so we can safely return as + // WASM_FUNCREF + else { return wasm_val_t{ .kind = WASM_FUNCREF, .of = { .ref = nullptr } }; } - // TODO:v128 - else { - assert(0 && "unsupported value kind"); +} +void +print_execution_args(const wasm_export_t &export_type, + const std::vector &args, unsigned param_count) +{ + std::cout << "[EXECUTION] " << export_type.name << "("; + for (unsigned p_i = 0; p_i < param_count; p_i++) { + if (p_i != 0) { + std::cout << ", "; + } + + switch (args[p_i].kind) { + case WASM_I32: + std::cout << "i32:" << args[p_i].of.i32; + break; + case WASM_I64: + std::cout << "i64:" << args[p_i].of.i64; + break; + case WASM_F32: + std::cout << "f32:" << args[p_i].of.f32; + break; + case WASM_F64: + std::cout << "f64:" << args[p_i].of.f64; + break; + case WASM_EXTERNREF: + std::cout << "externref:" << args[p_i].of.foreign; + break; + default: + // because aft is_supported_val_kind() check, so we can safely + // return as WASM_FUNCREF + std::cout << "funcref:" << args[p_i].of.ref; + break; + } } + std::cout << ")" << std::endl; } static bool @@ -108,7 +111,15 @@ execute_export_functions(wasm_module_t module, wasm_module_inst_t inst) for (unsigned p_i = 0; p_i < param_count; p_i++) { wasm_valkind_t param_type = wasm_func_type_get_param_valkind(func_type, p_i); - wasm_val_t arg = random_gen_val(param_type); + + if (!is_supported_val_kind(param_type)) { + std::cout + << "Bypass execution because of unsupported value kind: " + << param_type << std::endl; + return true; + } + + wasm_val_t arg = pre_defined_val(param_type); args.push_back(arg); } @@ -116,45 +127,17 @@ execute_export_functions(wasm_module_t module, wasm_module_inst_t inst) uint32_t result_count = wasm_func_type_get_result_count(func_type); std::vector results = std::vector(result_count); + print_execution_args(export_type, args, param_count); + /* execute the function */ wasm_exec_env_t exec_env = wasm_runtime_get_exec_env_singleton(inst); - - { - std::cout << "[EXECUTION] " << export_type.name << "("; - for (unsigned p_i = 0; p_i < param_count; p_i++) { - if (p_i != 0) { - std::cout << ", "; - } - - if (args[p_i].kind == WASM_I32) { - std::cout << "i32:" << args[p_i].of.i32; - } - else if (args[p_i].kind == WASM_I64) { - std::cout << "i64:" << args[p_i].of.i64; - } - else if (args[p_i].kind == WASM_F32) { - std::cout << "f32:" << args[p_i].of.f32; - } - else if (args[p_i].kind == WASM_F64) { - std::cout << "f64:" << args[p_i].of.f64; - } - else if (args[p_i].kind == WASM_EXTERNREF) { - std::cout << "externref:" << args[p_i].of.foreign; - } - else if (args[p_i].kind == WASM_FUNCREF) { - std::cout << "funcref:" << args[p_i].of.ref; - } - // TODO:v128 - else { - assert(0 && "unsupported value kind"); - } - } - - std::cout << ")" << std::endl; + if (!exec_env) { + std::cout << "Failed to get exec env" << std::endl; + return false; } bool ret = wasm_runtime_call_wasm_a(exec_env, func, result_count, - &results[0], param_count, &args[0]); + results.data(), param_count, args.data()); if (!ret) { const char *exception = wasm_runtime_get_exception(inst); if (!exception) {