diff --git a/runtime/compiletime/memory/64bit_nix.c b/runtime/compiletime/memory/64bit_nix.c index b63ebe1..9e1ab28 100644 --- a/runtime/compiletime/memory/64bit_nix.c +++ b/runtime/compiletime/memory/64bit_nix.c @@ -58,6 +58,24 @@ get_i64(i32 offset) return *(i64 *)address; } +INLINE i32 +get_global_i32(i32 offset) +{ + char *mem_as_chars = (char *)sandbox_lmbase; + void *address = &mem_as_chars[offset]; + + return *(i32 *)address; +} + +INLINE i64 +get_global_i64(i32 offset) +{ + char *mem_as_chars = (char *)sandbox_lmbase; + void *address = &mem_as_chars[offset]; + + return *(i64 *)address; +} + // Now setting routines INLINE void set_f32(i32 offset, float v) @@ -113,6 +131,24 @@ set_i64(i32 offset, i64 v) *(i64 *)address = v; } +INLINE void +set_global_i32(i32 offset, i32 v) +{ + char *mem_as_chars = (char *)sandbox_lmbase; + void *address = &mem_as_chars[offset]; + + *(i32 *)address = v; +} + +INLINE void +set_global_i64(i32 offset, i64 v) +{ + char *mem_as_chars = (char *)sandbox_lmbase; + void *address = &mem_as_chars[offset]; + + *(i64 *)address = v; +} + // Table handling functionality INLINE char * get_function_from_table(u32 idx, u32 type_id) diff --git a/runtime/include/module.h b/runtime/include/module.h index 6764967..751e732 100644 --- a/runtime/include/module.h +++ b/runtime/include/module.h @@ -13,6 +13,7 @@ struct module { mod_glb_fn_t glb_init_fn; mod_mem_fn_t mem_init_fn; mod_tbl_fn_t tbl_init_fn; + mod_libc_fn_t libc_init_fn; struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE]; @@ -71,12 +72,26 @@ module_is_valid(struct module *mod) } static inline void -module_table_init(struct module *mod) +module_globals_init(struct module *mod) { // called in a sandbox. + mod->glb_init_fn(); +} + +static inline void +module_table_init(struct module *mod) +{ + // called at module creation time (once only per module). mod->tbl_init_fn(); } +static inline void +module_libc_init(struct module *mod, i32 env, i32 args) +{ + // called in a sandbox. + mod->libc_init_fn(env, args); +} + static inline void module_memory_init(struct module *mod) { diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index 9161de8..bd15555 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -42,7 +42,7 @@ get_memory_string(u32 offset) INLINE char *get_function_from_table(u32 idx, u32 type_id); // libc/* might need to do some setup for the libc setup -void stub_init(char *modulename, i32 offset, mod_init_libc_fn_t fn); +void stub_init(i32 offset); void runtime_init(void); void runtime_thd_init(void); diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index dcf4383..e4b99c0 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -144,6 +144,15 @@ sandbox_current_set(struct sandbox *sbox) module_indirect_table = sbox->mod->indirect_table; } +static inline void +sandbox_current_check(void) +{ + struct sandbox *c = sandbox_current(); + + assert(c && c->linear_start == sandbox_lmbase && c->linear_size == sandbox_lmbound); + assert(c->mod->indirect_table == module_indirect_table); +} + static inline struct module * sandbox_module(struct sandbox *s) { diff --git a/runtime/include/types.h b/runtime/include/types.h index b71f4d5..b2e34a6 100644 --- a/runtime/include/types.h +++ b/runtime/include/types.h @@ -71,7 +71,7 @@ void populate_table(void); // memory/* also provides the table access functions // TODO: Change this to use a compiled in size -#define INDIRECT_TABLE_SIZE 1024 +#define INDIRECT_TABLE_SIZE (1<<10) struct indirect_table_entry { u32 type_id; @@ -90,7 +90,7 @@ typedef i32 (*mod_main_fn_t)(i32 a, i32 b); typedef void (*mod_glb_fn_t)(void); typedef void (*mod_mem_fn_t)(void); typedef void (*mod_tbl_fn_t)(void); -typedef void (*mod_init_libc_fn_t)(i32, i32); +typedef void (*mod_libc_fn_t)(i32, i32); typedef enum { MOD_ARG_MODPATH = 0, @@ -104,7 +104,7 @@ typedef enum { #define MOD_GLB_FN "populate_globals" #define MOD_MEM_FN "populate_memory" #define MOD_TBL_FN "populate_table" -#define MOD_INIT_LIBC_FN "wasmf___init_libc" +#define MOD_LIBC_FN "wasmf___init_libc" #define MOD_MAX_ARGS 16 #define MOD_ARG_MAX_SZ 64 diff --git a/runtime/src/libc/syscall.c b/runtime/src/libc/syscall.c index b337091..0f39af0 100644 --- a/runtime/src/libc/syscall.c +++ b/runtime/src/libc/syscall.c @@ -2,6 +2,7 @@ /* code from https://github.com/gwsystems/silverfish/blob/master/runtime/libc/libc_backing.c */ #include +#include #include #include @@ -32,9 +33,41 @@ // offset = a WASM ptr to memory the runtime can use void -stub_init(char *program_name, i32 offset, mod_init_libc_fn_t libcfn) +stub_init(i32 offset) { - printf("Don't think we should reinit libc! so ignore for now!\n"); + // What program name will we put in the auxiliary vectors + char *program_name = sandbox_current()->mod->name; + // Copy the program name into WASM accessible memory + i32 program_name_offset = offset; + strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name); + offset += sizeof(program_name); + + // The construction of this is: + // evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL + i32 env_vec[] = { + // Env variables would live here, but we don't supply any + 0, + // We supply only the bare minimum AUX vectors + AT_PAGESZ, + WASM_PAGE_SIZE, + AT_UID, + UID, + AT_EUID, + UID, + AT_GID, + GID, + AT_EGID, + GID, + AT_SECURE, + 0, + AT_RANDOM, + (i32) rand(), // It's pretty stupid to use rand here, but w/e + 0, + }; + i32 env_vec_offset = offset; + memcpy(get_memory_ptr_for_runtime(env_vec_offset, sizeof(env_vec)), env_vec, sizeof(env_vec)); + + module_libc_init(sandbox_current()->mod, env_vec_offset, program_name_offset); } // Emulated syscall implementations diff --git a/runtime/src/libc/uvio.c b/runtime/src/libc/uvio.c index e615722..c8e6132 100644 --- a/runtime/src/libc/uvio.c +++ b/runtime/src/libc/uvio.c @@ -1,5 +1,6 @@ #ifdef USE_UVIO #include +#include #include #include @@ -30,9 +31,41 @@ // offset = a WASM ptr to memory the runtime can use void -stub_init(char *program_name, i32 offset, mod_init_libc_fn_t libcfn) +stub_init(i32 offset) { - printf("Don't think we should reinit libc! so ignore for now!\n"); + // What program name will we put in the auxiliary vectors + char *program_name = sandbox_current()->mod->name; + // Copy the program name into WASM accessible memory + i32 program_name_offset = offset; + strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name); + offset += sizeof(program_name); + + // The construction of this is: + // evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL + i32 env_vec[] = { + // Env variables would live here, but we don't supply any + 0, + // We supply only the bare minimum AUX vectors + AT_PAGESZ, + WASM_PAGE_SIZE, + AT_UID, + UID, + AT_EUID, + UID, + AT_GID, + GID, + AT_EGID, + GID, + AT_SECURE, + 0, + AT_RANDOM, + (i32) rand(), // It's pretty stupid to use rand here, but w/e + 0, + }; + i32 env_vec_offset = offset; + memcpy(get_memory_ptr_for_runtime(env_vec_offset, sizeof(env_vec)), env_vec, sizeof(env_vec)); + + module_libc_init(sandbox_current()->mod, env_vec_offset, program_name_offset); } // Emulated syscall implementations @@ -120,13 +153,11 @@ wasm_write(i32 fd, i32 buf_offset, i32 buf_size) uv_fs_t req = UV_FS_REQ_INIT(); char* buf = get_memory_ptr_void(buf_offset, buf_size); - printf("[%p] start[%d:%d, n%d]\n", uv_fs_get_data(&req), fd, f, buf_size); uv_buf_t bufv = uv_buf_init(buf, buf_size); uv_fs_write(runtime_uvio(), &req, f, &bufv, 1, -1, wasm_fs_callback); sandbox_block(); int ret = uv_fs_get_result(&req); - printf("[%p] end[%d]\n", uv_fs_get_data(&req), ret); uv_fs_req_cleanup(&req); return ret; diff --git a/runtime/src/module.c b/runtime/src/module.c index 264f744..f0d5f4c 100644 --- a/runtime/src/module.c +++ b/runtime/src/module.c @@ -91,9 +91,8 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap, mod->entry_fn = (mod_main_fn_t)dlsym(mod->dl_handle, MOD_MAIN_FN); if (mod->entry_fn == NULL) goto dl_error; - // TODO: don't think this is necessary or implemented. - //mod->glb_init_fn = (mod_glb_fn_t)dlsym(mod->dl_handle, MOD_GLB_FN); - //if (mod->glb_init_fn == NULL) goto dl_error; + mod->glb_init_fn = (mod_glb_fn_t)dlsym(mod->dl_handle, MOD_GLB_FN); + if (mod->glb_init_fn == NULL) goto dl_error; mod->mem_init_fn = (mod_mem_fn_t)dlsym(mod->dl_handle, MOD_MEM_FN); if (mod->mem_init_fn == NULL) goto dl_error; @@ -101,6 +100,9 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap, mod->tbl_init_fn = (mod_tbl_fn_t)dlsym(mod->dl_handle, MOD_TBL_FN); if (mod->tbl_init_fn == NULL) goto dl_error; + mod->libc_init_fn = (mod_libc_fn_t)dlsym(mod->dl_handle, MOD_LIBC_FN); + if (mod->libc_init_fn == NULL) goto dl_error; + strncpy(mod->name, modname, MOD_NAME_MAX); strncpy(mod->path, modpath, MOD_PATH_MAX); diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index 4d7f7e1..7ff4347 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -113,7 +113,7 @@ sandbox_local_free(unsigned int n) { int i = 0; - while (i < n) { + while (i < n && !ps_list_head_empty(&endq)) { i++; struct sandbox *s = ps_list_head_first_d(&endq, struct sandbox); if (!s) break; diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 3f500ec..4502ed6 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -46,7 +46,6 @@ sandbox_args_setup(i32 argc) { struct sandbox *curr = sandbox_current(); char *args = sandbox_args(); - if (!args) return; // whatever gregor has, to be able to pass args to a module! curr->args_offset = sandbox_lmbound; @@ -66,6 +65,7 @@ sandbox_args_setup(i32 argc) string_off += str_sz; } + stub_init(string_off); } static inline void @@ -249,7 +249,6 @@ sandbox_entry(void) assert(f == 1); f = io_handle_open(2); assert(f == 2); - sandbox_args_setup(argc); #ifndef STANDALONE http_parser_init(&curr->hp, HTTP_REQUEST); @@ -266,10 +265,12 @@ sandbox_entry(void) { curr->rr_data_len = 0; // TODO: do this on first write to body. alloc_linear_memory(); - // perhaps only initialized for the first instance? or TODO! //module_table_init(curr_mod); + module_globals_init(curr_mod); module_memory_init(curr_mod); + sandbox_args_setup(argc); + curr->retval = module_entry(curr_mod, argc, curr->args_offset); sandbox_client_response_set(); diff --git a/runtime/tests/Makefile b/runtime/tests/Makefile index de00ce6..36e2104 100644 --- a/runtime/tests/Makefile +++ b/runtime/tests/Makefile @@ -2,7 +2,7 @@ include Makefile.inc BENCH_DIR=../../silverfish/code_benches/ -TESTS=fibonacci #empty work +TESTS=fibonacci empty work #TESTS=forever filesys sockserver sockclient empty TESTSRT=$(TESTS:%=%_rt) BENCHES=adpcm basic_math binarytrees bitcount blowfish crc dijkstra fft function_pointers \ @@ -38,6 +38,7 @@ clean: ${WASMCC} ${$(@:%_sf=%)_CFLAGS} ${WASMCFLAGS} ${OPTFLAGS} ${BENCH_DIR}/$(@:%_sf=%)/*.c $(DUMMY) -o ${TMP_DIR}/$(@:%_sf=%).wasm ${SFCC} ${TMP_DIR}/$(@:%_sf=%).wasm -o ${TMP_DIR}/$(@:%_sf=%).bc ${CC} ${CFLAGS} ${OPTFLAGS} -D${USE_MEM} ${TMP_DIR}/$(@:%_sf=%).bc ${MEMC} ${RT_LIBC} ${RT_RT} -o ${TMP_DIR}/$(@:%_sf=%)_wasm.out + ${SFCC} --inline-constant-globals --runtime-globals ${TMP_DIR}/$(@:%_sf=%).wasm -o ${TMP_DIR}/$(@:%_sf=%).bc ${CC} --shared -fPIC ${OPTFLAGS} -I${ART_INC} -D${USE_MEM} ${TMP_DIR}/$(@:%_sf=%).bc ${AMEMC} ${WASMISA} -o ${TMP_DIR}/$(@:%_sf=%)_wasm.so @cp ${TMP_DIR}/$(@:%_sf=%)_wasm.so ${ABIN_DIR} # @rm -rf ${TMP_DIR} @@ -48,6 +49,7 @@ clean: ${WASMCC} ${$(@:%_rt=%)_CFLAGS} ${WASMCFLAGS} ${OPTFLAGS} $(@:%_rt=%)/*.c $(DUMMY) -o ${TMP_DIR}/$(@:%_rt=%).wasm ${SFCC} ${TMP_DIR}/$(@:%_rt=%).wasm -o ${TMP_DIR}/$(@:%_rt=%).bc ${CC} ${CFLAGS} ${OPTFLAGS} -D${USE_MEM} ${TMP_DIR}/$(@:%_rt=%).bc ${MEMC} ${RT_LIBC} ${RT_RT} -o ${TMP_DIR}/$(@:%_rt=%)_wasm.out + ${SFCC} --inline-constant-globals --runtime-globals ${TMP_DIR}/$(@:%_rt=%).wasm -o ${TMP_DIR}/$(@:%_rt=%).bc ${CC} --shared -fPIC ${OPTFLAGS} -I${ART_INC} -D${USE_MEM} ${TMP_DIR}/$(@:%_rt=%).bc ${AMEMC} ${WASMISA} -o ${TMP_DIR}/$(@:%_rt=%)_wasm.so @cp ${TMP_DIR}/$(@:%_rt=%)_wasm.so ${ABIN_DIR} # @rm -rf ${TMP_DIR}