Skip to content

Commit 50b6474

Browse files
authored
Add WASI ABI compatibility check for multi-module (#913)
Refer to https://github.com/WebAssembly/WASI/blob/main/design/application-abi.md to check the WASI ABI compatibility: - Command (main module) may export _start function with signature "()" - Reactor (sub module) may export _initialize function with signature "()" - _start and _initialize can not be exported at the same time - Reactor cannot export _start function - Command and Reactor must export memory And - Rename module->is_wasi_module to module->import_wasi_api - Refactor wasm_loader_find_export() - Remove MULTI_MODULE related codes from mini_loader - Update multi-module samples - Fix a "use-after-free" issue. Since we reuse the memory instance of sub module, just to protect it from freeing an imported memory instance
1 parent 936206f commit 50b6474

File tree

20 files changed

+655
-220
lines changed

20 files changed

+655
-220
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
/.idea
55
**/cmake-build-*/
66
**/*build/
7+
*.obj
8+
*.a
9+
*.so
10+
711
core/deps/**
812
core/shared/mem-alloc/tlsf
913
core/app-framework/wgl
@@ -12,6 +16,9 @@ wamr-sdk/out/
1216
wamr-sdk/runtime/build_runtime_sdk/
1317
test-tools/host-tool/bin/
1418
product-mini/app-samples/hello-world/test.wasm
19+
product-mini/platforms/linux-sgx/enclave-sample/App/
20+
product-mini/platforms/linux-sgx/enclave-sample/Enclave/
21+
product-mini/platforms/linux-sgx/enclave-sample/iwasm
1522

1623
build_out
1724
tests/wamr-test-suites/workspace

core/iwasm/aot/aot_loader.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
12841284
#if WASM_ENABLE_LIBC_WASI != 0
12851285
if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
12861286
|| !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1"))
1287-
module->is_wasi_module = true;
1287+
module->import_wasi_api = true;
12881288
#endif
12891289
}
12901290

@@ -2925,7 +2925,7 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
29252925
module->comp_data = comp_data;
29262926

29272927
#if WASM_ENABLE_LIBC_WASI != 0
2928-
module->is_wasi_module = comp_data->wasm_module->is_wasi_module;
2928+
module->import_wasi_api = comp_data->wasm_module->import_wasi_api;
29292929
#endif
29302930

29312931
return module;

core/iwasm/aot/aot_runtime.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
10591059

10601060
#if WASM_ENABLE_BULK_MEMORY != 0
10611061
#if WASM_ENABLE_LIBC_WASI != 0
1062-
if (!module->is_wasi_module) {
1062+
if (!module->import_wasi_api) {
10631063
#endif
10641064
/* Only execute the memory init function for main instance because
10651065
the data segments will be dropped once initialized.

core/iwasm/aot/aot_runtime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ typedef struct AOTModule {
256256

257257
#if WASM_ENABLE_LIBC_WASI != 0
258258
WASIArguments wasi_args;
259-
bool is_wasi_module;
259+
bool import_wasi_api;
260260
#endif
261261
#if WASM_ENABLE_DEBUG_AOT != 0
262262
void *elf_hdr;

core/iwasm/common/wasm_application.c

Lines changed: 53 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ static union {
4848
/**
4949
* Implementation of wasm_application_execute_main()
5050
*/
51-
52-
static WASMFunctionInstanceCommon *
53-
resolve_function(const WASMModuleInstanceCommon *module_inst, const char *name);
54-
5551
static bool
5652
check_main_func_type(const WASMType *type)
5753
{
@@ -96,23 +92,29 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
9692
bool ret, is_import_func = true;
9793

9894
#if WASM_ENABLE_LIBC_WASI != 0
99-
if (wasm_runtime_is_wasi_mode(module_inst)) {
100-
/* In wasi mode, we should call function named "_start"
101-
which initializes the wasi envrionment and then calls
102-
the actual main function. Directly call main function
103-
may cause exception thrown. */
104-
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst)))
105-
return wasm_runtime_create_exec_env_and_call_wasm(module_inst, func,
106-
0, NULL);
107-
/* If no start function was found, we execute
108-
the main function as normal */
95+
/* In wasi mode, we should call function named "_start"
96+
which initializes the wasi envrionment and then calls
97+
the actual main function. Directly call main function
98+
may cause exception thrown. */
99+
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
100+
return wasm_runtime_create_exec_env_and_call_wasm(module_inst, func, 0,
101+
NULL);
109102
}
110103
#endif /* end of WASM_ENABLE_LIBC_WASI */
111104

112-
if (!(func = resolve_function(module_inst, "main"))
113-
&& !(func = resolve_function(module_inst, "__main_argc_argv"))
114-
&& !(func = resolve_function(module_inst, "_main"))) {
115-
wasm_runtime_set_exception(module_inst, "lookup main function failed");
105+
if (!(func = wasm_runtime_lookup_function(module_inst, "main", NULL))
106+
&& !(func = wasm_runtime_lookup_function(module_inst,
107+
"__main_argc_argv", NULL))
108+
&& !(func = wasm_runtime_lookup_function(module_inst, "_main", NULL))) {
109+
#if WASM_ENABLE_LIBC_WASI != 0
110+
wasm_runtime_set_exception(
111+
module_inst, "lookup the entry point symbol (like _start, main, "
112+
"_main, __main_argc_argv) failed");
113+
#else
114+
wasm_runtime_set_exception(module_inst,
115+
"lookup the entry point symbol (like main, "
116+
"_main, __main_argc_argv) failed");
117+
#endif
116118
return false;
117119
}
118120

@@ -238,21 +240,23 @@ parse_function_name(char *orig_function_name, char **p_module_name,
238240
* Implementation of wasm_application_execute_func()
239241
*/
240242

241-
static WASMFunctionInstanceCommon *
242-
resolve_function(const WASMModuleInstanceCommon *module_inst, const char *name)
243+
static bool
244+
resolve_function(WASMModuleInstanceCommon *module_inst, const char *name,
245+
WASMFunctionInstanceCommon **out_func,
246+
WASMModuleInstanceCommon **out_module_inst)
243247
{
244-
uint32 i = 0;
245-
WASMFunctionInstanceCommon *ret = NULL;
248+
WASMFunctionInstanceCommon *target_func = NULL;
249+
WASMModuleInstanceCommon *target_inst = NULL;
250+
246251
#if WASM_ENABLE_MULTI_MODULE != 0
247-
WASMModuleInstance *sub_module_inst = NULL;
252+
char *function_name = NULL;
248253
char *orig_name = NULL;
249254
char *sub_module_name = NULL;
250-
char *function_name = NULL;
251255
uint32 length = (uint32)(strlen(name) + 1);
252256

253257
orig_name = runtime_malloc(sizeof(char) * length, NULL, NULL, 0);
254258
if (!orig_name) {
255-
return NULL;
259+
goto LEAVE;
256260
}
257261

258262
strncpy(orig_name, name, length);
@@ -264,53 +268,33 @@ resolve_function(const WASMModuleInstanceCommon *module_inst, const char *name)
264268
LOG_DEBUG("%s -> %s and %s", name, sub_module_name, function_name);
265269

266270
if (sub_module_name) {
267-
sub_module_inst = get_sub_module_inst((WASMModuleInstance *)module_inst,
268-
sub_module_name);
269-
if (!sub_module_inst) {
271+
target_inst = (WASMModuleInstanceCommon *)get_sub_module_inst(
272+
(WASMModuleInstance *)module_inst, sub_module_name);
273+
if (!target_inst) {
270274
LOG_DEBUG("can not find a sub module named %s", sub_module_name);
271275
goto LEAVE;
272276
}
273277
}
278+
else {
279+
target_inst = module_inst;
280+
}
274281
#else
275282
const char *function_name = name;
283+
target_inst = module_inst;
276284
#endif
277285

278-
#if WASM_ENABLE_INTERP != 0
279-
if (module_inst->module_type == Wasm_Module_Bytecode) {
280-
WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst;
281-
282-
#if WASM_ENABLE_MULTI_MODULE != 0
283-
wasm_inst = sub_module_inst ? sub_module_inst : wasm_inst;
284-
#endif /* WASM_ENABLE_MULTI_MODULE */
285-
286-
for (i = 0; i < wasm_inst->export_func_count; i++) {
287-
if (!strcmp(wasm_inst->export_functions[i].name, function_name)) {
288-
ret = wasm_inst->export_functions[i].function;
289-
break;
290-
}
291-
}
292-
}
293-
#endif /* WASM_ENABLE_INTERP */
294-
295-
#if WASM_ENABLE_AOT != 0
296-
if (module_inst->module_type == Wasm_Module_AoT) {
297-
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
298-
AOTFunctionInstance *export_funcs =
299-
(AOTFunctionInstance *)aot_inst->export_funcs.ptr;
300-
for (i = 0; i < aot_inst->export_func_count; i++) {
301-
if (!strcmp(export_funcs[i].func_name, function_name)) {
302-
ret = &export_funcs[i];
303-
break;
304-
}
305-
}
306-
}
307-
#endif
286+
target_func =
287+
wasm_runtime_lookup_function(target_inst, function_name, NULL);
308288

309289
#if WASM_ENABLE_MULTI_MODULE != 0
310290
LEAVE:
311-
wasm_runtime_free(orig_name);
291+
if (orig_name)
292+
wasm_runtime_free(orig_name);
312293
#endif
313-
return ret;
294+
295+
*out_func = target_func;
296+
*out_module_inst = target_inst;
297+
return target_func;
314298
}
315299

316300
union ieee754_float {
@@ -358,7 +342,8 @@ bool
358342
wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
359343
const char *name, int32 argc, char *argv[])
360344
{
361-
WASMFunctionInstanceCommon *func;
345+
WASMFunctionInstanceCommon *target_func;
346+
WASMModuleInstanceCommon *target_inst;
362347
WASMType *type = NULL;
363348
uint32 argc1, *argv1 = NULL, cell_num = 0, j, k = 0;
364349
int32 i, p, module_type;
@@ -368,31 +353,15 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
368353

369354
bh_assert(argc >= 0);
370355
LOG_DEBUG("call a function \"%s\" with %d arguments", name, argc);
371-
func = resolve_function(module_inst, name);
372356

373-
if (!func) {
357+
if (!resolve_function(module_inst, name, &target_func, &target_inst)) {
374358
snprintf(buf, sizeof(buf), "lookup function %s failed", name);
375359
wasm_runtime_set_exception(module_inst, buf);
376360
goto fail;
377361
}
378362

379-
#if WASM_ENABLE_INTERP != 0
380-
if (module_inst->module_type == Wasm_Module_Bytecode) {
381-
WASMFunctionInstance *wasm_func = (WASMFunctionInstance *)func;
382-
if (wasm_func->is_import_func
383-
#if WASM_ENABLE_MULTI_MODULE != 0
384-
&& !wasm_func->import_func_inst
385-
#endif
386-
) {
387-
snprintf(buf, sizeof(buf), "lookup function %s failed", name);
388-
wasm_runtime_set_exception(module_inst, buf);
389-
goto fail;
390-
}
391-
}
392-
#endif
393-
394-
module_type = module_inst->module_type;
395-
type = wasm_runtime_get_function_type(func, module_type);
363+
module_type = target_inst->module_type;
364+
type = wasm_runtime_get_function_type(target_func, module_type);
396365

397366
if (!type) {
398367
LOG_ERROR("invalid module instance type");
@@ -408,7 +377,7 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
408377
cell_num = (argc1 > type->ret_cell_num) ? argc1 : type->ret_cell_num;
409378

410379
total_size = sizeof(uint32) * (uint64)(cell_num > 2 ? cell_num : 2);
411-
if ((!(argv1 = runtime_malloc((uint32)total_size, module_inst, NULL, 0)))) {
380+
if ((!(argv1 = runtime_malloc((uint32)total_size, target_inst, NULL, 0)))) {
412381
goto fail;
413382
}
414383

@@ -538,7 +507,7 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
538507
void *extern_obj = (void *)(uintptr_t)val;
539508
uint32 externref_idx;
540509

541-
if (!wasm_externref_obj2ref(module_inst, extern_obj,
510+
if (!wasm_externref_obj2ref(target_inst, extern_obj,
542511
&externref_idx)) {
543512
wasm_runtime_set_exception(
544513
module_inst, "map extern object to ref failed");
@@ -563,8 +532,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
563532
bh_assert(p == (int32)argc1);
564533

565534
wasm_runtime_set_exception(module_inst, NULL);
566-
if (!wasm_runtime_create_exec_env_and_call_wasm(module_inst, func, argc1,
567-
argv1)) {
535+
if (!wasm_runtime_create_exec_env_and_call_wasm(target_inst, target_func,
536+
argc1, argv1)) {
568537
goto fail;
569538
}
570539

core/iwasm/common/wasm_runtime_common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,13 +2294,13 @@ wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst)
22942294
{
22952295
#if WASM_ENABLE_INTERP != 0
22962296
if (module_inst->module_type == Wasm_Module_Bytecode
2297-
&& ((WASMModuleInstance *)module_inst)->module->is_wasi_module)
2297+
&& ((WASMModuleInstance *)module_inst)->module->import_wasi_api)
22982298
return true;
22992299
#endif
23002300
#if WASM_ENABLE_AOT != 0
23012301
if (module_inst->module_type == Wasm_Module_AoT
23022302
&& ((AOTModule *)((AOTModuleInstance *)module_inst)->aot_module.ptr)
2303-
->is_wasi_module)
2303+
->import_wasi_api)
23042304
return true;
23052305
#endif
23062306
return false;

core/iwasm/interpreter/wasm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ struct WASMModule {
403403

404404
#if WASM_ENABLE_LIBC_WASI != 0
405405
WASIArguments wasi_args;
406-
bool is_wasi_module;
406+
bool import_wasi_api;
407407
#endif
408408

409409
#if WASM_ENABLE_MULTI_MODULE != 0

0 commit comments

Comments
 (0)