summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorrsc <rsc>2007-08-14 04:56:30 +0000
committerrsc <rsc>2007-08-14 04:56:30 +0000
commit8c4b5fc5b33c49f74af3547df9e60012758ab5d3 (patch)
tree830a58cf214d80933e4e473a44faeff60121f906 /main.c
parent2ef3a64bb4923d3458bac1393dd9e205f0acd93a (diff)
downloadxv6-labs-8c4b5fc5b33c49f74af3547df9e60012758ab5d3.tar.gz
xv6-labs-8c4b5fc5b33c49f74af3547df9e60012758ab5d3.tar.bz2
xv6-labs-8c4b5fc5b33c49f74af3547df9e60012758ab5d3.zip
Gcc expects to be able to pick up the return
address off the stack, so put one there for it. (Bug was hidden by bad segment limits.)
Diffstat (limited to 'main.c')
-rw-r--r--main.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/main.c b/main.c
index 10a448e..3652461 100644
--- a/main.c
+++ b/main.c
@@ -128,12 +128,12 @@ process0(void)
p0->cwd = iget(rootdev, 1);
iunlock(p0->cwd);
- // dummy user memory to make copyproc() happy.
- // must be big enough to hold the init binary.
- p0->sz = PAGE;
+ // Dummy user memory to make copyproc() happy.
+ // Must be big enough to hold the init binary and stack.
+ p0->sz = 2*PAGE;
p0->mem = kalloc(p0->sz);
- // fake a trap frame as if a user process had made a system
+ // Fake a trap frame as if a user process had made a system
// call, so that copyproc will have a place for the new
// process to return to.
p0->tf = &tf;
@@ -142,6 +142,13 @@ process0(void)
p0->tf->cs = (SEG_UCODE << 3) | DPL_USER;
p0->tf->eflags = FL_IF;
p0->tf->esp = p0->sz;
+
+ // Push bogus return address, both to cause problems
+ // if main returns and also because gcc can generate
+ // function prologs that expect to be able to read the
+ // return address off the stack without causing a fault.
+ p0->tf->esp -= 4;
+ *(uint*)(p0->mem + p0->tf->esp) = 0xefefefef;
p1 = copyproc(p0);