#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/process.h>
+#include <lunaix/sched.h>
#include <lunaix/spike.h>
#include <lunaix/status.h>
#include <lunaix/syscall.h>
#include <lunaix/syscall_utils.h>
#include <sys/abi.h>
-#include <sys/mm/mempart.h>
+#include <sys/mm/mm_defs.h>
#include <klibc/string.h>
void
-exec_container(struct exec_container* param,
- struct proc_info* proc,
+exec_init_container(struct exec_container* param,
+ struct thread* thread,
ptr_t vms,
const char** argv,
const char** envp)
{
- *param = (struct exec_container){ .proc = proc,
+ assert(thread->ustack);
+ ptr_t ustack_top = align_stack(thread->ustack->end - 1);
+ *param = (struct exec_container){ .proc = thread->process,
.vms_mnt = vms,
.exe = { .container = param },
.argv_pp = { 0, 0 },
.argv = argv,
- .envp = envp };
+ .envp = envp,
+ .stack_top = ustack_top };
}
size_t
return (sz + 1) * sizeof(ptr_t);
}
-ptr_t
+static ptr_t
copy_to_ustack(ptr_t stack_top, ptr_t* paramv)
{
ptr_t ptr;
return stack_top;
}
+static void
+save_process_cmd(struct proc_info* proc, ptr_t* argv)
+{
+ ptr_t ptr, *_argv = argv;
+ size_t total_sz = 0;
+ while ((ptr = *_argv)) {
+ total_sz += strlen((const char*)ptr) + 1;
+ _argv++;
+ }
+
+ if (proc->cmd) {
+ vfree(proc->cmd);
+ }
+
+ char* cmd_ = (char*)valloc(total_sz);
+ proc->cmd = cmd_;
+ proc->cmd_len = total_sz;
+
+ while ((ptr = *argv)) {
+ cmd_ = strcpy(cmd_, (const char*)ptr);
+ cmd_[-1] = ' ';
+ argv++;
+ }
+ cmd_[-1] = '\0';
+}
+
// externed from mm/dmm.c
extern int
create_heap(struct proc_mm* pvms, ptr_t addr);
goto done;
}
- struct proc_mm* pvms = &container->proc->mm;
+ struct proc_info* proc = container->proc;
+ struct proc_mm* pvms = vmspace(proc);
if (pvms->heap) {
mem_unmap_region(container->vms_mnt, pvms->heap);
if (!argv_extra[1]) {
// If loading a statically linked file, then heap remapping we can do,
// otherwise delayed.
- create_heap(&container->proc->mm, PG_ALIGN(container->exe.end));
+ create_heap(vmspace(proc), page_aligned(container->exe.end));
}
if (container->vms_mnt == VMS_SELF) {
// we are loading executable into current addr space
- ptr_t ustack = USR_STACK_END;
+ ptr_t ustack = container->stack_top;
size_t argv_len = 0, envp_len = 0;
ptr_t argv_ptr = 0, envp_ptr = 0;
memcpy((void*)ustack, (const void*)envp, envp_len);
ustack = copy_to_ustack(ustack, (ptr_t*)ustack);
+ } else {
+ ustack -= sizeof(ptr_t);
+ *((ptr_t*)ustack) = 0;
}
- if (argv) {
+ if (argv) {
argv_len = args_ptr_size(argv);
ustack -= argv_len;
memcpy((void*)ustack, (const void**)argv, argv_len);
- for (size_t i = 0; i < 2 && argv_extra[i]; i++) {
- ustack -= sizeof(ptr_t);
- *((ptr_t*)ustack) = (ptr_t)argv_extra[i];
- argv_len += sizeof(ptr_t);
- }
+ } else {
+ ustack -= sizeof(ptr_t);
+ *((ptr_t*)ustack) = 0;
+ }
- argv_ptr = ustack;
- ustack = copy_to_ustack(ustack, (ptr_t*)ustack);
+ for (size_t i = 0; i < 2 && argv_extra[i]; i++) {
+ ustack -= sizeof(ptr_t);
+ *((ptr_t*)ustack) = (ptr_t)argv_extra[i];
+ argv_len += sizeof(ptr_t);
}
+ argv_ptr = ustack;
+ ustack = copy_to_ustack(ustack, (ptr_t*)ustack);
+
+ save_process_cmd(proc, (ptr_t*)argv_ptr);
+
// four args (arg{c|v}, env{c|p}) for main
struct uexec_param* exec_param = &((struct uexec_param*)ustack)[-1];
.envp = (char**)envp_ptr };
} 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
-
- IDEA
- 1. Allocate a orphaned physical page (i.e., do not belong to any
- VMA)
- 2. Mounted to a temporary mount point in current VMA, (i.e.,
- PG_MOUNT_*)
- 3. Do setup there.
- 4. Unmount then mounted to the foreign VMA as the first stack
- page.
+ TODO Inject to remote user stack with our procvm_remote toolsets
+ Need a better way to factorise the argv/envp length calculating
*/
fail("not implemented");
+
}
done:
goto done;
}
+ if (!check_itype_any(dnode->inode, F_FILE)) {
+ errno = EISDIR;
+ goto done;
+ }
+
errno = exec_load(container, file);
+ // It shouldn't matter which pid we passed. As the only reader is
+ // in current context and we must finish read at this point,
+ // therefore the dead-lock condition will not exist and the pid
+ // for arbitration has no use.
+ vfs_pclose(file, container->proc->pid);
+
done:
return errno;
}
int errno = 0;
struct exec_container container;
- exec_container(
- &container, (struct proc_info*)__current, VMS_SELF, argv, envp);
+ exec_init_container(&container, current_thread, VMS_SELF, argv, envp);
errno = exec_load_byname(&container, filename);
int errno = 0;
struct exec_container container;
- exec_container(
- &container, (struct proc_info*)__current, VMS_SELF, argv, envp);
+ exec_init_container(
+ &container, current_thread, VMS_SELF, argv, envp);
if ((errno = exec_load_byname(&container, filename))) {
goto done;
// 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
- eret_target(__current) = container.exe.entry;
- eret_stack(__current) = container.stack_top;
+ hart_flow_redirect(current_thread->hstate,
+ container.exe.entry, container.stack_top);
// these become meaningless once execved!
- __current->ustack_top = 0;
- proc_clear_signal(__current);
+ current_thread->ustack_top = 0;
+ signal_reset_context(¤t_thread->sigctx);
+ signal_reset_registry(__current->sigreg);
done:
// set return value