11 exec(char *path
, char **argv
)
15 uint argc
, sz
, sp
, ustack
[3+MAXARG
+1];
19 pde_t
*pgdir
, *oldpgdir
;
21 if((ip
= namei(path
)) == 0)
27 if(readi(ip
, (char*)&elf
, 0, sizeof(elf
)) < sizeof(elf
))
29 if(elf
.magic
!= ELF_MAGIC
)
32 if((pgdir
= setupkvm(kalloc
)) == 0)
35 // Load program into memory.
37 for(i
=0, off
=elf
.phoff
; i
<elf
.phnum
; i
++, off
+=sizeof(ph
)){
38 if(readi(ip
, (char*)&ph
, off
, sizeof(ph
)) != sizeof(ph
))
40 if(ph
.type
!= ELF_PROG_LOAD
)
42 if(ph
.memsz
< ph
.filesz
)
44 if((sz
= allocuvm(pgdir
, sz
, ph
.vaddr
+ ph
.memsz
)) == 0)
46 if(loaduvm(pgdir
, (char*)ph
.vaddr
, ip
, ph
.off
, ph
.filesz
) < 0)
52 // Allocate two pages at the next page boundary.
53 // Make the first inaccessible. Use the second as the user stack.
55 if((sz
= allocuvm(pgdir
, sz
, sz
+ 2*PGSIZE
)) == 0)
57 clearpteu(pgdir
, (char*)(sz
- 2*PGSIZE
));
60 // Push argument strings, prepare rest of stack in ustack.
61 for(argc
= 0; argv
[argc
]; argc
++) {
64 sp
= (sp
- (strlen(argv
[argc
]) + 1)) & ~3;
65 if(copyout(pgdir
, sp
, argv
[argc
], strlen(argv
[argc
]) + 1) < 0)
71 ustack
[0] = 0xffffffff; // fake return PC
73 ustack
[2] = sp
- (argc
+1)*4; // argv pointer
76 if(copyout(pgdir
, sp
, ustack
, (3+argc
+1)*4) < 0)
79 // Save program name for debugging.
80 for(last
=s
=path
; *s
; s
++)
83 safestrcpy(proc
->name
, last
, sizeof(proc
->name
));
85 // Commit to the user image.
86 oldpgdir
= proc
->pgdir
;
89 proc
->tf
->eip
= elf
.entry
; // main