aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/amd64/proc_machdep.c60
-rw-r--r--sys/include/sys/exec.h16
-rw-r--r--sys/include/sys/proc.h5
3 files changed, 81 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/proc_machdep.c b/sys/arch/amd64/amd64/proc_machdep.c
index ee38f21..2b4368b 100644
--- a/sys/arch/amd64/amd64/proc_machdep.c
+++ b/sys/arch/amd64/amd64/proc_machdep.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/errno.h>
+#include <sys/exec.h>
#include <machine/frame.h>
#include <machine/gdt.h>
#include <vm/physmem.h>
@@ -39,6 +40,65 @@
#include <string.h>
void
+md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog)
+{
+ uintptr_t *sp = stack_top;
+ uintptr_t old_sp;
+ size_t argc, envc, len;
+ char **argvp = prog->argp;
+ char **envp = prog->envp;
+ struct auxval auxval = prog->auxval;
+ struct trapframe *tfp;
+
+ /* Copy strings */
+ old_sp = (uintptr_t)sp;
+ for (argc = 0; argvp[argc] != NULL; ++argc) {
+ len = strlen(argvp[argc]) + 1;
+ sp = (void *)((char *)sp - len);
+ memcpy((char *)sp, argvp[argc], len);
+ }
+ for (envc = 0; envp[envc] != NULL; ++envc) {
+ len = strlen(envp[envc]) + 1;
+ sp = (void *)((char *)sp - len);
+ memcpy((char *)sp, envp[envc], len);
+ }
+
+ /* Ensure the stack is aligned */
+ sp = (void *)ALIGN_DOWN((uintptr_t)sp, 16);
+ if (((argc + envc + 1) & 1) != 0)
+ --sp;
+
+ AUXVAL(sp, AT_NULL, 0x0);
+ AUXVAL(sp, AT_SECURE, 0x0);
+ AUXVAL(sp, AT_ENTRY, auxval.at_entry);
+ AUXVAL(sp, AT_PHDR, auxval.at_phdr);
+ AUXVAL(sp, AT_PHNUM, auxval.at_phnum);
+ AUXVAL(sp, AT_PAGESIZE, DEFAULT_PAGESIZE);
+ STACK_PUSH(sp, 0);
+
+ /* Copy envp pointers */
+ sp -= envc;
+ for (int i = 0; i < envc; ++i) {
+ len = strlen(envp[i]) + 1;
+ old_sp -= len;
+ sp[i] = (uintptr_t)old_sp - VM_HIGHER_HALF;
+ }
+
+ /* Copy argvp pointers */
+ STACK_PUSH(sp, 0);
+ sp -= argc;
+ for (int i = 0; i < argc; ++i) {
+ len = strlen(argvp[i]) + 1;
+ old_sp -= len;
+ sp[i] = (uintptr_t)old_sp - VM_HIGHER_HALF;
+ }
+
+ STACK_PUSH(sp, argc);
+ tfp = &td->tf;
+ tfp->rsp = (uintptr_t)sp - VM_HIGHER_HALF;
+}
+
+void
setregs(struct proc *td, struct exec_prog *prog, uintptr_t stack)
{
struct trapframe *tfp = &td->tf;
diff --git a/sys/include/sys/exec.h b/sys/include/sys/exec.h
index 4910ff2..73eae01 100644
--- a/sys/include/sys/exec.h
+++ b/sys/include/sys/exec.h
@@ -34,7 +34,23 @@
#if defined(_KERNEL)
+/* Danger: Do not change these !! */
+#define AT_NULL 0
+#define AT_ENTRY 1
+#define AT_PHDR 2
+#define AT_PHENT 3
+#define AT_PHNUM 4
+#define AT_EXECPATH 5
+#define AT_SECURE 6
+#define AT_RANDOM 7
+#define AT_EXECFN 8
+#define AT_PAGESIZE 9
+
#define MAX_PHDRS 32
+#define STACK_PUSH(PTR, VAL) *(--(PTR)) = VAL
+#define AUXVAL(PTR, TAG, VAL) \
+ STACK_PUSH(PTR, VAL); \
+ STACK_PUSH(PTR, TAG);
struct exec_range {
uintptr_t start;
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
index 5303072..0c3cd33 100644
--- a/sys/include/sys/proc.h
+++ b/sys/include/sys/proc.h
@@ -43,6 +43,8 @@
#define PROC_STACK_PAGES 8
#define PROC_STACK_SIZE (PROC_STACK_PAGES * DEFAULT_PAGESIZE)
+struct exec_prog;
+
struct proc {
pid_t pid;
struct trapframe tf;
@@ -57,6 +59,9 @@ struct proc {
struct proc *this_td(void);
int md_fork(struct proc *p, struct proc *parent, uintptr_t ip);
+
+void md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog);
+
int fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp);
int exit1(struct proc *td);