17 int load_one_elf(struct proc* p, int fd, int pgoffset, struct elf_info* ei)
23 char* elf = (char*)kmalloc(PGSIZE,0);
24 if(!elf || read_page(p,fd,PADDR(elf),0) == -1)
27 elf_t* elfhdr = (elf_t*)elf;
28 proghdr_t* proghdrs = (proghdr_t*)(elf+elfhdr->e_phoff);
29 if(elfhdr->e_phoff+elfhdr->e_phnum*sizeof(proghdr_t) > PGSIZE)
31 if(elfhdr->e_phentsize != sizeof(proghdr_t))
34 for(int i = 0; i < elfhdr->e_phnum; i++)
36 proghdr_t* ph = proghdrs+i;
37 if(ph->p_type == ELF_PROG_PHDR)
39 if(ph->p_type == ELF_PROG_INTERP)
41 int maxlen = MIN(PGSIZE-ph->p_offset,sizeof(ei->interp));
42 int len = strnlen(elf+ph->p_offset,maxlen);
45 memcpy(ei->interp,elf+ph->p_offset,maxlen+1);
52 if(ph->p_type == ELF_PROG_LOAD && ph->p_memsz)
54 if(ph->p_align % PGSIZE)
56 if(ph->p_offset % PGSIZE != ph->p_va % PGSIZE)
59 uintptr_t filestart = ROUNDDOWN(ph->p_offset,PGSIZE);
60 uintptr_t fileend = ph->p_offset+ph->p_filesz;
61 uintptr_t filesz = fileend-filestart;
63 uintptr_t memstart = ROUNDDOWN(ph->p_va,PGSIZE);
64 uintptr_t memend = ROUNDUP(ph->p_va + ph->p_memsz,PGSIZE);
65 uintptr_t memsz = memend-memstart;
67 // mmap will zero the rest of the page if filesz % PGSIZE != 0
69 // TODO: waterman, figure out proper permissions
70 if(mmap(p, memstart+pgoffset*PGSIZE, filesz,
71 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED,
72 fd, filestart/PGSIZE) == MAP_FAILED)
75 filesz = ROUNDUP(filesz,PGSIZE);
77 if(mmap(p, memstart+filesz+pgoffset*PGSIZE, memsz-filesz,
78 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_ANON,
84 ei->entry = elfhdr->e_entry + pgoffset*PGSIZE;
85 ei->phnum = elfhdr->e_phnum;
93 int load_elf(struct proc* p, const char* fn)
95 struct elf_info ei,interp_ei;
96 int fd = open_file(p,fn,0,0);
97 if(fd == -1 || load_one_elf(p,fd,0,&ei))
103 int fd2 = open_file(p,ei.interp,0,0);
104 if(fd2 == -1 || load_one_elf(p,fd2,1,&interp_ei))
108 // fill in info for dynamic linker
109 elf_aux_t auxp[] = {{ELF_AUX_PHDR,ei.phdr},
110 {ELF_AUX_PHENT,sizeof(proghdr_t)},
111 {ELF_AUX_PHNUM,ei.phnum},
112 {ELF_AUX_ENTRY,ei.entry},
115 // put auxp after argv, envp in procinfo
117 for(int i = 0, zeros = 0; i < PROCINFO_MAX_ARGP; i++)
118 if(p->env_procinfo->argp[i] == NULL)
122 auxp_pos+sizeof(auxp)/sizeof(char*) >= PROCINFO_MAX_ARGP)
124 memcpy(p->env_procinfo->argp+auxp_pos,auxp,sizeof(auxp));
127 intptr_t core0_entry = ei.dynamic ? interp_ei.entry : ei.entry;
128 proc_init_trapframe(&p->env_tf,0,core0_entry,USTACKTOP);
129 p->env_entry = ei.entry;
131 uintptr_t stacksz = USTACK_NUM_PAGES*PGSIZE;
132 if(mmap(p,USTACKTOP-stacksz,stacksz,PROT_READ|PROT_WRITE,
133 MAP_FIXED|MAP_ANON,-1,0) == MAP_FAILED)
139 intreg_t sys_exec(struct proc* p, const char fn[MAX_PATH_LEN], procinfo_t* pi)
141 if(p->state != PROC_RUNNING_S)
144 char kfn[MAX_PATH_LEN];
145 if(memcpy_from_user(p,kfn,fn,MAX_PATH_LEN))
148 if(memcpy_from_user(p,p->env_procinfo,pi,sizeof(procinfo_t)))
153 proc_init_procinfo(p);
155 env_segment_free(p,0,USTACKTOP);
162 *current_tf = p->env_tf;