1111#include " aot_export.h"
1212#include " wasm_export.h"
1313#include " bh_read_file.h"
14+ #include " ../common/fuzzer_common.h"
1415
1516static void
1617handle_aot_recent_error (const char *tag)
@@ -23,155 +24,13 @@ handle_aot_recent_error(const char *tag)
2324 std::cout << tag << " " << error << std::endl;
2425}
2526
26- static bool
27- is_supported_val_kind (wasm_valkind_t kind)
28- {
29- return kind == WASM_I32 || kind == WASM_I64 || kind == WASM_F32
30- || kind == WASM_F64 || kind == WASM_EXTERNREF
31- || kind == WASM_FUNCREF;
32- }
33-
34- static wasm_val_t
35- pre_defined_val (wasm_valkind_t kind)
36- {
37- if (kind == WASM_I32) {
38- return wasm_val_t { .kind = WASM_I32, .of = { .i32 = 2025 } };
39- }
40- else if (kind == WASM_I64) {
41- return wasm_val_t { .kind = WASM_I64, .of = { .i64 = 168 } };
42- }
43- else if (kind == WASM_F32) {
44- return wasm_val_t { .kind = WASM_F32, .of = { .f32 = 3 .14159f } };
45- }
46- else if (kind == WASM_F64) {
47- return wasm_val_t { .kind = WASM_F64, .of = { .f64 = 2.71828 } };
48- }
49- else if (kind == WASM_EXTERNREF) {
50- return wasm_val_t { .kind = WASM_EXTERNREF,
51- .of = { .foreign = 0xabcddead } };
52- }
53- // because aft is_supported_val_kind() check, so we can safely return as
54- // WASM_FUNCREF
55- else {
56- return wasm_val_t { .kind = WASM_FUNCREF, .of = { .ref = nullptr } };
57- }
58- }
59- void
60- print_execution_args (const wasm_export_t &export_type,
61- const std::vector<wasm_val_t > &args, unsigned param_count)
62- {
63- std::cout << " [EXECUTION] " << export_type.name << " (" ;
64- for (unsigned p_i = 0 ; p_i < param_count; p_i++) {
65- if (p_i != 0 ) {
66- std::cout << " , " ;
67- }
68-
69- switch (args[p_i].kind ) {
70- case WASM_I32:
71- std::cout << " i32:" << args[p_i].of .i32 ;
72- break ;
73- case WASM_I64:
74- std::cout << " i64:" << args[p_i].of .i64 ;
75- break ;
76- case WASM_F32:
77- std::cout << " f32:" << args[p_i].of .f32 ;
78- break ;
79- case WASM_F64:
80- std::cout << " f64:" << args[p_i].of .f64 ;
81- break ;
82- case WASM_EXTERNREF:
83- std::cout << " externref:" << args[p_i].of .foreign ;
84- break ;
85- default :
86- // because aft is_supported_val_kind() check, so we can safely
87- // return as WASM_FUNCREF
88- std::cout << " funcref:" << args[p_i].of .ref ;
89- break ;
90- }
91- }
92- std::cout << " )" << std::endl;
93- }
94-
95- static bool
96- execute_export_functions (wasm_module_t module , wasm_module_inst_t inst)
97- {
98- int32_t export_count = wasm_runtime_get_export_count (module );
99-
100- for (int e_i = 0 ; e_i < export_count; e_i++) {
101- wasm_export_t export_type = { 0 };
102- wasm_runtime_get_export_type (module , e_i, &export_type);
103-
104- if (export_type.kind != WASM_IMPORT_EXPORT_KIND_FUNC) {
105- continue ;
106- }
107-
108- wasm_function_inst_t func =
109- wasm_runtime_lookup_function (inst, export_type.name );
110- if (!func) {
111- std::cout << " Failed to lookup function: " << export_type.name
112- << std::endl;
113- continue ;
114- }
115-
116- wasm_func_type_t func_type = export_type.u .func_type ;
117- uint32_t param_count = wasm_func_type_get_param_count (func_type);
118-
119- /* build arguments */
120- std::vector<wasm_val_t > args;
121- for (unsigned p_i = 0 ; p_i < param_count; p_i++) {
122- wasm_valkind_t param_type =
123- wasm_func_type_get_param_valkind (func_type, p_i);
124-
125- if (!is_supported_val_kind (param_type)) {
126- std::cout
127- << " Bypass execution because of unsupported value kind: "
128- << param_type << std::endl;
129- return true ;
130- }
131-
132- wasm_val_t arg = pre_defined_val (param_type);
133- args.push_back (arg);
134- }
135-
136- /* build results storage */
137- uint32_t result_count = wasm_func_type_get_result_count (func_type);
138- std::vector<wasm_val_t > results = std::vector<wasm_val_t >(result_count);
139-
140- print_execution_args (export_type, args, param_count);
141-
142- /* execute the function */
143- wasm_exec_env_t exec_env = wasm_runtime_get_exec_env_singleton (inst);
144- if (!exec_env) {
145- std::cout << " Failed to get exec env" << std::endl;
146- return false ;
147- }
148-
149- bool ret =
150- wasm_runtime_call_wasm_a (exec_env, func, result_count,
151- results.data (), param_count, args.data ());
152- if (!ret) {
153- const char *exception = wasm_runtime_get_exception (inst);
154- if (!exception) {
155- std::cout << " [EXECUTION] " << export_type.name
156- << " () failed. No exception info." << std::endl;
157- }
158- else {
159- std::cout << " [EXECUTION] " << export_type.name << " () failed. "
160- << exception << std::endl;
161- }
162- }
163-
164- wasm_runtime_clear_exception (inst);
165- }
166-
167- return true ;
168- }
169-
17027extern " C" int
17128LLVMFuzzerTestOneInput (const uint8_t *Data, size_t Size)
17229{
30+ char kTargetArch [] = " x86_64" ;
31+ char kTargetAbi [] = " gnu" ;
17332 wasm_module_t module = NULL ;
174- char error_buf[128 ] = { 0 };
33+ char error_buf[ERROR_BUF_SIZE ] = { 0 };
17534 AOTCompOption option = { 0 };
17635 aot_comp_data_t comp_data = NULL ;
17736 aot_comp_context_t comp_ctx = NULL ;
@@ -180,26 +39,27 @@ LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
18039 wasm_module_t aot_module = NULL ;
18140 wasm_module_inst_t inst = NULL ;
18241
183- /* libfuzzer don't allow to modify the given Data, so make a copy here */
184- std::vector<uint8_t > myData (Data, Data + Size);
185-
42+ /* libfuzzer don't allow to modify the given Data, but get_package_type and
43+ * wasm_runtime_load only read the data, so we can safely use const_cast */
18644 if (Size >= 4
187- && get_package_type (myData.data (), Size) != Wasm_Module_Bytecode) {
45+ && get_package_type (const_cast <uint8_t *>(Data), Size)
46+ != Wasm_Module_Bytecode) {
18847 printf (" Invalid wasm file: magic header not detected\n " );
18948 return 0 ;
19049 }
19150
19251 wasm_runtime_init ();
19352
194- module = wasm_runtime_load ((uint8_t *)myData.data (), Size, error_buf, 120 );
53+ module = wasm_runtime_load (const_cast <uint8_t *>(Data), Size, error_buf,
54+ MAX_ERROR_BUF_SIZE);
19555 if (!module ) {
19656 std::cout << " [LOADING] " << error_buf << std::endl;
19757 goto DESTROY_RUNTIME;
19858 }
19959
20060 // TODO: target_arch and other fields
201- option.target_arch = " x86_64 " ;
202- option.target_abi = " gnu " ;
61+ option.target_arch = kTargetArch ;
62+ option.target_abi = kTargetAbi ;
20363 option.enable_bulk_memory = true ;
20464 option.enable_thread_mgr = true ;
20565 option.enable_tail_call = true ;
@@ -232,14 +92,15 @@ LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
23292 goto DESTROY_COMP_CTX;
23393 }
23494
235- aot_module =
236- wasm_runtime_load (aot_file_buf, aot_file_size, error_buf, 128 );
95+ aot_module = wasm_runtime_load (aot_file_buf, aot_file_size, error_buf,
96+ ERROR_BUF_SIZE );
23797 if (!aot_module) {
23898 std::cout << " [LOADING AOT MODULE] " << error_buf << std::endl;
23999 goto RELEASE_AOT_FILE_BUF;
240100 }
241101
242- inst = wasm_runtime_instantiate (aot_module, 1024 *8 , 0 , error_buf, 128 );
102+ inst = wasm_runtime_instantiate (aot_module, 1024 * 8 , 0 , error_buf,
103+ ERROR_BUF_SIZE);
243104 if (!inst) {
244105 std::cout << " [INSTANTIATING AOT MODULE] " << error_buf << std::endl;
245106 goto UNLOAD_AOT_MODULE;
0 commit comments