X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/74926d2db1d9f3228acdfca03013a8ba0ac1d8c0..c316c28e6c8a165111d6bbc208555f5c53489818:/lunaix-os/kernel/loader/exec.c?ds=inline diff --git a/lunaix-os/kernel/loader/exec.c b/lunaix-os/kernel/loader/exec.c index 6c33495..3c40f6c 100644 --- a/lunaix-os/kernel/loader/exec.c +++ b/lunaix-os/kernel/loader/exec.c @@ -27,6 +27,36 @@ exec_str_size(const char** str_arr, size_t* length) return sz + 1; } +void +__heap_copied(struct mm_region* region) +{ + mm_index((void**)®ion->proc_vms->heap, region); +} + +int +__exec_remap_heap(struct ld_param* param, struct proc_mm* pvms) +{ + if (pvms->heap) { + mem_unmap_region(param->vms_mnt, pvms->heap); + } + + struct mmap_param map_param = { .pvms = pvms, + .vms_mnt = param->vms_mnt, + .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED, + .type = REGION_TYPE_HEAP, + .proct = PROT_READ | PROT_WRITE, + .mlen = DEFAULT_HEAP_PAGES * PG_SIZE }; + int status = 0; + struct mm_region* heap; + if ((status = mem_map(NULL, &heap, param->info.end, NULL, &map_param))) { + param->status |= LD_STAT_FKUP; + return status; + } + + heap->region_copied = __heap_copied; + mm_index((void**)&pvms->heap, heap); +} + int exec_loadto(struct ld_param* param, struct v_file* executable, @@ -49,44 +79,50 @@ exec_loadto(struct ld_param* param, goto done; } - struct mmap_param map_param = { .regions = ¶m->proc->mm.regions, - .vms_mnt = param->vms_mnt, - .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED, - .type = REGION_TYPE_VARS, - .proct = PROT_READ, - .length = MAX_VAR_PAGES * PG_SIZE }; + struct proc_mm* pvms = ¶m->proc->mm; + struct mmap_param map_vars = { .pvms = pvms, + .vms_mnt = param->vms_mnt, + .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED, + .type = REGION_TYPE_VARS, + .proct = PROT_READ, + .mlen = MAX_VAR_PAGES * PG_SIZE }; void* mapped; isr_param* intr_ctx = ¶m->proc->intr_ctx; - // TODO reinitialize heap + if ((errno = __exec_remap_heap(param, pvms))) { + goto done; + } + + if ((errno = mem_map(&mapped, NULL, UMMAP_END, NULL, &map_vars))) { + goto done; + } if (param->vms_mnt == VMS_SELF) { // we are loading executable into current addr space - if ((errno = mem_map(&mapped, NULL, UMMAP_END, NULL, &map_param))) { - goto done; - } - - memcpy(mapped, (void*)argv, sz_argv); - memcpy(mapped + sz_argv, (void*)envp, sz_envp); - - ptr_t* ustack = (void*)USTACK_TOP; - size_t* argc = &((size_t*)&ustack[-1])[-1]; + // 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 }; + ptr_t* ustack = (ptr_t*)USTACK_TOP; ustack[-1] = (ptr_t)mapped; - *argc = argv_len; - - // TODO handle envp. - - intr_ctx->esp = argc; + intr_ctx->esp = &ustack[-1]; } else { // TODO need to find a way to inject argv and envp remotely fail("not implemented"); } - intr_ctx->eip = param->ehdr_out.e_entry; - // we will jump to new entry point upon syscall's return - // so execve will not return from the perspective of it's invoker + 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 done: return errno;