SGX Environment App Code
Big Picture
- An ecall
ecall_handle_command
to serve incoming commands from the app part - Memory management?
runtime_malloc
void
ecall_handle_command(unsigned cmd,
unsigned char *cmd_buf,
unsigned cmd_buf_size)
{
uint64 *args = (uint64 *)cmd_buf;
uint32 argc = cmd_buf_size / sizeof(uint64);
switch (cmd) {
case CMD_INIT_RUNTIME:
handle_cmd_init_runtime(args, argc);
break;
case CMD_LOAD_MODULE:
handle_cmd_load_module(args, argc);
break;
case CMD_SET_WASI_ARGS:
handle_cmd_set_wasi_args(args, argc);
break;
case CMD_INSTANTIATE_MODULE:
handle_cmd_instantiate_module(args, argc);
break;
case CMD_LOOKUP_FUNCTION:
break;
case CMD_CREATE_EXEC_ENV:
break;
case CMD_CALL_WASM:
break;
case CMD_EXEC_APP_FUNC:
handle_cmd_exec_app_func(args, argc);
break;
case CMD_EXEC_APP_MAIN:
handle_cmd_exec_app_main(args, argc);
break;
case CMD_GET_EXCEPTION:
handle_cmd_get_exception(args, argc);
break;
case CMD_DEINSTANTIATE_MODULE:
handle_cmd_deinstantiate_module(args, argc);
break;
case CMD_UNLOAD_MODULE:
handle_cmd_unload_module(args, argc);
break;
case CMD_DESTROY_RUNTIME:
handle_cmd_destroy_runtime();
break;
case CMD_SET_LOG_LEVEL:
handle_cmd_set_log_level(args, argc);
break;
default:
LOG_ERROR("Unknown command %d\n", cmd);
break;
}
}
Initialization Steps
enclave_init
- Argument parsing
- WAMR `init_runtime` (in enclave)
- Set log level
- Read in WASM file to a buffer and load it as a module into the enclave
- Instantiate the module
- Execute the main function
- Do cleaning jobs:
wasm_runtime_deinstantiate
, wasm_runtime_unload
and wasm_runtime_destroy
int
main(int argc, char *argv[])
{
char *wasm_file = NULL;
const char *func_name = NULL;
uint8_t *wasm_file_buf = NULL;
uint32_t wasm_file_size;
uint32_t stack_size = 16 * 1024, heap_size = 16 * 1024;
void *wasm_module = NULL;
void *wasm_module_inst = NULL;
char error_buf[128] = { 0 };
int log_verbose_level = 2;
bool is_repl_mode = false, alloc_with_pool = false;
const char *dir_list[8] = { NULL };
uint32_t dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32_t env_list_size = 0;
uint32_t max_thread_num = 4;
if (enclave_init(&g_eid) < 0) {
std::cout << "Fail to initialize enclave." << std::endl;
return 1;
}
#if TEST_OCALL_API != 0
{
if (!init_runtime(alloc_with_pool, max_thread_num)) {
return -1;
}
ecall_iwasm_test(g_eid);
destroy_runtime();
return 0;
}
#endif
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
argc--, argv++;
if (argc < 2) {
print_help();
return 0;
}
func_name = argv[0];
}
else if (!strncmp(argv[0], "-v=", 3)) {
log_verbose_level = atoi(argv[0] + 3);
if (log_verbose_level < 0 || log_verbose_level > 5)
return print_help();
}
else if (!strcmp(argv[0], "--repl")) {
is_repl_mode = true;
}
else if (!strncmp(argv[0], "--stack-size=", 13)) {
if (argv[0][13] == '\0')
return print_help();
stack_size = atoi(argv[0] + 13);
}
else if (!strncmp(argv[0], "--heap-size=", 12)) {
if (argv[0][12] == '\0')
return print_help();
heap_size = atoi(argv[0] + 12);
}
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
return print_help();
if (dir_list_size >= sizeof(dir_list) / sizeof(char *)) {
printf("Only allow max dir number %d\n",
(int)(sizeof(dir_list) / sizeof(char *)));
return -1;
}
dir_list[dir_list_size++] = argv[0] + 6;
}
else if (!strncmp(argv[0], "--env=", 6)) {
char *tmp_env;
if (argv[0][6] == '\0')
return print_help();
if (env_list_size >= sizeof(env_list) / sizeof(char *)) {
printf("Only allow max env number %d\n",
(int)(sizeof(env_list) / sizeof(char *)));
return -1;
}
tmp_env = argv[0] + 6;
if (validate_env_str(tmp_env))
env_list[env_list_size++] = tmp_env;
else {
printf("Wasm parse env string failed: expect \"key=value\", "
"got \"%s\"\n",
tmp_env);
return print_help();
}
}
else if (!strncmp(argv[0], "--max-threads=", 14)) {
if (argv[0][14] == '\0')
return print_help();
max_thread_num = atoi(argv[0] + 14);
}
else
return print_help();
}
if (argc == 0)
return print_help();
wasm_file = argv[0];
if (!init_runtime(alloc_with_pool, max_thread_num)) {
return -1;
}
if (!set_log_verbose_level(log_verbose_level)) {
goto fail1;
}
if (!(wasm_file_buf =
(uint8_t *)read_file_to_buffer(wasm_file, &wasm_file_size))) {
goto fail1;
}
if (!(wasm_module = load_module(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail2;
}
if (!set_wasi_args(wasm_module, dir_list, dir_list_size,
env_list, env_list_size, argv, argc)) {
printf("%s\n", "set wasi arguments failed.\n");
goto fail3;
}
if (!(wasm_module_inst = instantiate_module(wasm_module,
stack_size, heap_size,
error_buf,
sizeof(error_buf)))) {
printf("%s\n", error_buf);
goto fail3;
}
if (is_repl_mode)
app_instance_repl(wasm_module_inst, argc, argv);
else if (func_name)
app_instance_func(wasm_module_inst, func_name,
argc - 1, argv + 1);
else
app_instance_main(wasm_module_inst, argc, argv);
deinstantiate_module(wasm_module_inst);
fail3:
unload_module(wasm_module);
fail2:
free(wasm_file_buf);
fail1:
destroy_runtime();
return 0;
}