Skip to content
Snippets Groups Projects
Commit 8455980b authored by rtm's avatar rtm
Browse files

exec arguments

parent c59361f1
No related branches found
No related tags found
No related merge requests found
......@@ -66,6 +66,10 @@ usertests : usertests.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)
$(OBJDUMP) -S usertests > usertests.asm
echo : echo.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o echo echo.o $(ULIB)
$(OBJDUMP) -S echo > echo.asm
userfs : userfs.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
$(OBJDUMP) -S userfs > userfs.asm
......@@ -73,12 +77,12 @@ userfs : userfs.o $(ULIB)
mkfs : mkfs.c fs.h
cc -o mkfs mkfs.c
fs.img : mkfs usertests
./mkfs fs.img usertests
fs.img : mkfs usertests echo
./mkfs fs.img usertests echo
-include *.d
clean :
rm -f *.o *.d *.asm vectors.S parport.out \
bootblock kernel xv6.img user1 userfs usertests \
fs.img mkfs
fs.img mkfs echo
......@@ -161,3 +161,5 @@ need to lock bufs in bio between bread and brelse
test 14-character file names
and file arguments longer than 14
and directories longer than one sector
kalloc() can return 0; do callers handle this right?
echo.c 0 → 100644
#include "user.h"
int
main(int argc, char *argv[])
{
int i;
for(i = 0; i < argc; i++){
puts(argv[i]);
puts(" ");
}
puts("\n");
exit();
}
......@@ -144,11 +144,6 @@ winode(uint inum, struct dinode *ip)
dip = ((struct dinode *) buf) + (inum % IPB);
*dip = *ip;
wsect(bn, buf);
printf("wi %d size %d addrs %d %d...\n",
inum,
xint(dip->size),
xint(dip->addrs[0]),
xint(dip->addrs[1]));
}
void
......
......@@ -58,17 +58,20 @@ fetcharg(int argno, void *ip)
return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
}
// check that an entire string is valid in user space
// check that an entire string is valid in user space.
// returns the length, not including null, or -1.
int
checkstring(uint s)
{
char c;
int len = 0;
while(1){
if(fetchbyte(curproc[cpu()], s, &c) < 0)
return -1;
if(c == '\0')
return 0;
return len;
len++;
s++;
}
}
......@@ -244,14 +247,17 @@ int
sys_exec(void)
{
struct proc *cp = curproc[cpu()];
uint arg0, sz;
int i;
uint arg0, arg1, sz=0, ap, sp, p1, p2;
int i, nargs, argbytes, len;
struct inode *ip;
struct elfhdr elf;
struct proghdr ph;
char *mem = 0;
if(fetcharg(0, &arg0) < 0)
return -1;
if(fetcharg(1, &arg1) < 0)
return -1;
if(checkstring(arg0) < 0)
return -1;
ip = namei(cp->mem + arg0);
......@@ -278,14 +284,62 @@ sys_exec(void)
sz += 4096 - (sz % 4096);
sz += 4096;
mem = kalloc(sz);
if(mem == 0)
goto bad;
memset(mem, 0, sz);
// arg1 is a pointer to an array of pointers to string.
nargs = 0;
argbytes = 0;
for(i = 0; ; i++){
if(fetchint(cp, arg1 + 4*i, &ap) < 0)
goto bad;
if(ap == 0)
break;
len = checkstring(ap);
if(len < 0)
goto bad;
nargs++;
argbytes += len + 1;
}
// argn\0
// ...
// arg0\0
// 0
// ptr to argn
// ...
// 12: ptr to arg0
// 8: argv (points to ptr to arg0)
// 4: argc
// 0: fake return pc
sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4;
*(uint*)(mem + sp) = 0xffffffff;
*(uint*)(mem + sp + 4) = nargs;
*(uint*)(mem + sp + 8) = (uint)(sp + 12);
p1 = sp + 12;
p2 = sp + 12 + (nargs + 1) * 4;
for(i = 0; i < nargs; i++){
fetchint(cp, arg1 + 4*i, &ap);
len = checkstring(ap);
memmove(mem + p2, cp->mem + ap, len + 1);
*(uint*)(mem + p1) = p2;
p1 += 4;
p2 += len + 1;
}
*(uint*)(mem + p1) = 0;
// commit to the new image.
kfree(cp->mem, cp->sz);
cp->sz = sz;
cp->mem = kalloc(cp->sz);
cp->mem = mem;
mem = 0;
for(i = 0; i < elf.phnum; i++){
if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
goto bad;
goto bad2;
if(ph.type != ELF_PROG_LOAD)
continue;
if(ph.va + ph.memsz > sz)
......@@ -298,13 +352,15 @@ sys_exec(void)
iput(ip);
cp->tf->eip = elf.entry;
cp->tf->esp = cp->sz;
cp->tf->esp = sp;
setupsegs(cp);
return 0;
bad:
cprintf("exec failed early\n");
if(mem)
kfree(mem, sz);
iput(ip);
return -1;
......
......@@ -3,12 +3,13 @@
// file system tests
char buf[1024];
char *args[] = { "echo", "hello", "goodbye", 0 };
int
main(void)
{
puts("userfs running\n");
block();
exec("usertests");
exec("echo", args);
return 0;
}
......@@ -115,7 +115,7 @@ exitwait(void)
}
int
main(void)
main(int argc, char *argv[])
{
puts("usertests starting\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment