1 #include <lunaix/elf.h>
4 #include <lunaix/mm/mmap.h>
5 #include <lunaix/mm/vmm.h>
6 #include <lunaix/process.h>
7 #include <lunaix/spike.h>
8 #include <lunaix/status.h>
9 #include <lunaix/syscall.h>
11 #include <klibc/string.h>
14 exec_str_size(const char** str_arr, size_t* length)
16 const char* chr = *str_arr;
17 size_t sz = 0, len = 0;
23 chr = *(str_arr + sz);
31 exec_loadto(struct ld_param* param,
32 struct v_file* executable,
38 size_t argv_len, envp_len;
39 size_t sz_argv = exec_str_size(argv, &argv_len);
40 size_t sz_envp = exec_str_size(envp, &envp_len);
41 size_t total_sz = ROUNDUP(sz_argv + sz_envp, PG_SIZE);
43 if (total_sz / PG_SIZE > MAX_VAR_PAGES) {
48 if ((errno = elf_load(param, executable))) {
52 struct mmap_param map_param = { .regions = ¶m->proc->mm.regions,
53 .vms_mnt = param->vms_mnt,
54 .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED,
55 .type = REGION_TYPE_VARS,
57 .length = MAX_VAR_PAGES * PG_SIZE };
60 isr_param* intr_ctx = ¶m->proc->intr_ctx;
62 // TODO reinitialize heap
64 if (param->vms_mnt == VMS_SELF) {
65 // we are loading executable into current addr space
66 if ((errno = mem_map(&mapped, NULL, UMMAP_END, NULL, &map_param))) {
70 memcpy(mapped, (void*)argv, sz_argv);
71 memcpy(mapped + sz_argv, (void*)envp, sz_envp);
73 ptr_t* ustack = (void*)USTACK_TOP;
74 size_t* argc = &((size_t*)&ustack[-1])[-1];
76 ustack[-1] = (ptr_t)mapped;
83 // TODO need to find a way to inject argv and envp remotely
84 fail("not implemented");
87 intr_ctx->eip = param->ehdr_out.e_entry;
88 // we will jump to new entry point upon syscall's return
89 // so execve will not return from the perspective of it's invoker
95 __DEFINE_LXSYSCALL3(int,
105 struct v_dnode* dnode;
108 if ((errno = vfs_walk_proc(filename, &dnode, NULL, 0))) {
112 if ((errno = vfs_open(dnode, &file))) {
116 struct ld_param ldparam;
117 ld_create_param(&ldparam, __current, VMS_SELF);
119 if ((errno = exec_loadto(&ldparam, file, argv, envp))) {
120 vfs_pclose(file, __current->pid);
122 if ((ldparam.status & LD_STAT_FKUP)) {
123 // we fucked up our address space.
124 terminate_proc(11451);
126 fail("should not reach");