From 8c4b5fc5b33c49f74af3547df9e60012758ab5d3 Mon Sep 17 00:00:00 2001
From: rsc <rsc>
Date: Tue, 14 Aug 2007 04:56:30 +0000
Subject: [PATCH] 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.)

---
 main.c | 15 +++++++++++----
 1 file 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);
 
-- 
GitLab