Have switch_{to,back} use an opaque uintptr_t
[akaros.git] / kern / src / elf.c
index 8e80fdc..9d1ab58 100644 (file)
@@ -21,7 +21,7 @@ bool is_valid_elf(struct file *f)
 {
        elf64_t h;
        off64_t o = 0;
 {
        elf64_t h;
        off64_t o = 0;
-       struct proc *c = switch_to(0);
+       uintptr_t c = switch_to(0);
 
        if (f->f_op->read(f, (char*)&h, sizeof(elf64_t), &o) != sizeof(elf64_t)) {
                goto fail;
 
        if (f->f_op->read(f, (char*)&h, sizeof(elf64_t), &o) != sizeof(elf64_t)) {
                goto fail;
@@ -135,7 +135,7 @@ static uintptr_t populate_stack(struct proc *p, int argc, char *argv[],
 /* We need the writable flag for ld.  Even though the elf header says it wants
  * RX (and not W) for its main program header, it will page fault (eip 56f0,
  * 46f0 after being relocated to 0x1000, va 0x20f4). */
 /* We need the writable flag for ld.  Even though the elf header says it wants
  * RX (and not W) for its main program header, it will page fault (eip 56f0,
  * 46f0 after being relocated to 0x1000, va 0x20f4). */
-static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
+static int load_one_elf(struct proc *p, struct file *f, uintptr_t pg_num,
                         elf_info_t *ei, bool writable)
 {
        int ret = -1;
                         elf_info_t *ei, bool writable)
 {
        int ret = -1;
@@ -148,7 +148,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
        
        /* When reading on behalf of the kernel, we need to make sure no proc is
         * "current".  This is a bit ghetto (TODO: KFOP) */
        
        /* When reading on behalf of the kernel, we need to make sure no proc is
         * "current".  This is a bit ghetto (TODO: KFOP) */
-       struct proc *old_proc = switch_to(0);
+       uintptr_t old_proc = switch_to(0);
 
        /* Read in ELF header. */
        elf64_t elfhdr_storage;
 
        /* Read in ELF header. */
        elf64_t elfhdr_storage;
@@ -254,7 +254,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
 
                        uintptr_t memstart = ROUNDDOWN(p_va, PGSIZE);
                        uintptr_t memsz = ROUNDUP(p_va + p_memsz, PGSIZE) - memstart;
 
                        uintptr_t memstart = ROUNDDOWN(p_va, PGSIZE);
                        uintptr_t memsz = ROUNDUP(p_va + p_memsz, PGSIZE) - memstart;
-                       memstart += pgoffset * PGSIZE;
+                       memstart += pg_num * PGSIZE;
 
                        if (memstart + memsz > ei->highest_addr)
                                ei->highest_addr = memstart + memsz;
 
                        if (memstart + memsz > ei->highest_addr)
                                ei->highest_addr = memstart + memsz;
@@ -342,7 +342,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
                }
                ei->phdr = (long)phdr_addr + e_phoff;
        }
                }
                ei->phdr = (long)phdr_addr + e_phoff;
        }
-       ei->entry = elf_field(elfhdr, e_entry) + pgoffset*PGSIZE;
+       ei->entry = elf_field(elfhdr, e_entry) + pg_num * PGSIZE;
        ei->phnum = e_phnum;
        ei->elf64 = elf64;
        ret = 0;
        ei->phnum = e_phnum;
        ei->elf64 = elf64;
        ret = 0;
@@ -362,7 +362,7 @@ int load_elf(struct proc* p, struct file* f,
                return -1;
 
        if (ei.dynamic) {
                return -1;
 
        if (ei.dynamic) {
-               struct file *interp = do_file_open(ei.interp, 0, 0);
+               struct file *interp = do_file_open(ei.interp, O_READ, 0);
                if (!interp)
                        return -1;
                /* Load dynamic linker at 1M. Obvious MIB joke avoided.
                if (!interp)
                        return -1;
                /* Load dynamic linker at 1M. Obvious MIB joke avoided.
@@ -371,7 +371,8 @@ int load_elf(struct proc* p, struct file* f,
                 * helped us waste a full day debugging a bug in the Go runtime. True!
                 * Note that MMAP_LOWEST_VA also has this value but we want to make this
                 * explicit. */
                 * helped us waste a full day debugging a bug in the Go runtime. True!
                 * Note that MMAP_LOWEST_VA also has this value but we want to make this
                 * explicit. */
-               int error = load_one_elf(p, interp, MiB>>12, &interp_ei, TRUE);
+               int error = load_one_elf(p, interp, MMAP_LD_FIXED_VA >> PGSHIFT,
+                                        &interp_ei, TRUE);
                kref_put(&interp->f_kref);
                if (error)
                        return -1;
                kref_put(&interp->f_kref);
                if (error)
                        return -1;
@@ -397,7 +398,43 @@ int load_elf(struct proc* p, struct file* f,
         * loaded. */
        p->heap_top = (void*)ei.highest_addr;
        p->procinfo->heap_bottom = p->heap_top;
         * loaded. */
        p->heap_top = (void*)ei.highest_addr;
        p->procinfo->heap_bottom = p->heap_top;
+       p->args_base = (void *) stack_top;
 
        return 0;
 }
 
 
        return 0;
 }
 
+ssize_t get_startup_argc(struct proc *p)
+{
+       const char *sptr = (const char *) p->args_base;
+       ssize_t argc = 0;
+
+       /* TODO,DL: Use copy_from_user() when available.
+        */
+       if (memcpy_from_user(p, &argc, sptr, sizeof(size_t)))
+               return -1;
+
+       return argc;
+}
+
+char *get_startup_argv(struct proc *p, size_t idx, char *argp,
+                                          size_t max_size)
+{
+       size_t stack_space = (const char *) USTACKTOP - (const char *) p->args_base;
+       const char *sptr = (const char *) p->args_base + sizeof(size_t) +
+               idx * sizeof(char *);
+       const char *argv = NULL;
+
+       /* TODO,DL: Use copy_from_user() when available.
+        */
+       if (memcpy_from_user(p, &argv, sptr, sizeof(char *)))
+               return NULL;
+
+       /* TODO,DL: Use strncpy_from_user() when available.
+        */
+       max_size = MIN(max_size, stack_space);
+       if (memcpy_from_user(p, argp, argv, max_size))
+               return NULL;
+       argp[max_size - 1] = 0;
+
+       return argp;
+}