X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/c316c28e6c8a165111d6bbc208555f5c53489818..f8bd95b7a13dfe54d800e2d7ecdb0329f0798289:/lunaix-os/kernel/loader/exec.c diff --git a/lunaix-os/kernel/loader/exec.c b/lunaix-os/kernel/loader/exec.c index 3c40f6c..6a18ffc 100644 --- a/lunaix-os/kernel/loader/exec.c +++ b/lunaix-os/kernel/loader/exec.c @@ -7,12 +7,18 @@ #include #include #include +#include #include size_t exec_str_size(const char** str_arr, size_t* length) { + if (!str_arr) { + *length = 0; + return 0; + } + const char* chr = *str_arr; size_t sz = 0, len = 0; @@ -20,11 +26,11 @@ exec_str_size(const char** str_arr, size_t* length) sz += strlen(chr); len++; - chr = *(str_arr + sz); + chr = *(str_arr++); } *length = len; - return sz + 1; + return sz + sizeof(char*); } void @@ -42,10 +48,10 @@ __exec_remap_heap(struct ld_param* param, struct proc_mm* pvms) struct mmap_param map_param = { .pvms = pvms, .vms_mnt = param->vms_mnt, - .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED, + .flags = MAP_ANON | MAP_PRIVATE, .type = REGION_TYPE_HEAP, .proct = PROT_READ | PROT_WRITE, - .mlen = DEFAULT_HEAP_PAGES * PG_SIZE }; + .mlen = PG_SIZE }; int status = 0; struct mm_region* heap; if ((status = mem_map(NULL, &heap, param->info.end, NULL, &map_param))) { @@ -55,13 +61,15 @@ __exec_remap_heap(struct ld_param* param, struct proc_mm* pvms) heap->region_copied = __heap_copied; mm_index((void**)&pvms->heap, heap); + + return status; } int -exec_loadto(struct ld_param* param, - struct v_file* executable, - const char** argv, - const char** envp) +exec_load(struct ld_param* param, + struct v_file* executable, + const char** argv, + const char** envp) { int errno = 0; @@ -88,7 +96,6 @@ exec_loadto(struct ld_param* param, .mlen = MAX_VAR_PAGES * PG_SIZE }; void* mapped; - isr_param* intr_ctx = ¶m->proc->intr_ctx; if ((errno = __exec_remap_heap(param, pvms))) { goto done; @@ -103,39 +110,39 @@ exec_loadto(struct ld_param* param, // make some handy infos available to user space ptr_t arg_start = mapped + sizeof(struct usr_exec_param); - memcpy(arg_start, (void*)argv, sz_argv); - memcpy(arg_start + sz_argv, (void*)envp, sz_envp); - - struct usr_exec_param* param = mapped; - *param = (struct usr_exec_param){ .argc = argv_len, - .argv = arg_start, - .envc = envp_len, - .envp = arg_start + sz_argv, - .info = param->info }; + if (argv) + memcpy(arg_start, (void*)argv, sz_argv); + if (envp) + memcpy(arg_start + sz_argv, (void*)envp, sz_envp); + ptr_t* ustack = (ptr_t*)USTACK_TOP; + struct usr_exec_param* exec_param = (struct usr_exec_param*)mapped; + ustack[-1] = (ptr_t)mapped; - intr_ctx->esp = &ustack[-1]; + param->info.stack_top = &ustack[-1]; + + *exec_param = (struct usr_exec_param){ .argc = argv_len, + .argv = arg_start, + .envc = envp_len, + .envp = arg_start + sz_argv, + .info = param->info }; } else { // TODO need to find a way to inject argv and envp remotely + // this is for the support of kernel level implementation of + // posix_spawn fail("not implemented"); } - intr_ctx->eip = param->info.ehdr_out.e_entry; - // we will jump to new entry point (_u_start) upon syscall's - // return so execve 'will not return' from the perspective of it's invoker - + param->info.entry = param->info.ehdr_out.e_entry; done: return errno; } -__DEFINE_LXSYSCALL3(int, - execve, - const char*, - filename, - const char*, - argv[], - const char*, - envp[]) +int +exec_load_byname(struct ld_param* param, + const char* filename, + const char** argv, + const char** envp) { int errno = 0; struct v_dnode* dnode; @@ -149,20 +156,44 @@ __DEFINE_LXSYSCALL3(int, goto done; } + if ((errno = exec_load(param, file, argv, envp))) { + vfs_pclose(file, __current->pid); + } + +done: + return errno; +} + +__DEFINE_LXSYSCALL3(int, + execve, + const char*, + filename, + const char*, + argv[], + const char*, + envp[]) +{ + int errno = 0; struct ld_param ldparam; ld_create_param(&ldparam, __current, VMS_SELF); - if ((errno = exec_loadto(&ldparam, file, argv, envp))) { - vfs_pclose(file, __current->pid); - + if ((errno = exec_load_byname(&ldparam, filename, argv, envp))) { if ((ldparam.status & LD_STAT_FKUP)) { // we fucked up our address space. terminate_proc(11451); schedule(); fail("should not reach"); } + goto done; } + volatile struct exec_param* execp = __current->intr_ctx.execp; + execp->esp = ldparam.info.stack_top; + execp->eip = ldparam.info.entry; + + // we will jump to new entry point (_u_start) upon syscall's + // return so execve 'will not return' from the perspective of it's invoker + done: - return errno; + return DO_STATUS(errno); } \ No newline at end of file