hlfw.ca

drawcpu

Download patch

ref: 07665995b1973c612a8874badec060114393fa4d
parent: a374e069c66850906eaa241b8fcc0e312ff298bd
author: halfwit <michaelmisch1985@gmail.com>
date: Mon Apr 28 17:18:30 PDT 2025

Odd commit issue

--- a/kern/posix.c
+++ b/kern/posix.c
@@ -35,7 +35,6 @@
 };
 
 static pthread_key_t prdakey;
-//typedef void (*startfn)(int, char**);
 
 Proc*
 _getproc(void)
@@ -136,118 +135,7 @@
 	sched_yield();
 }
 
-
-static void*
-trex(void *vp)
-{
-	Proc *p;
-	Tos tos;
-	int argc;
-
-	p = vp;
-	tos.pid = p->pid;
-	argc = nelem((char**)p->arg);
-	if(pthread_setspecific(prdakey, p))
-		panic("cannot setspecific");
-	/* Our entrypoint moves forward to accomodate the trampoline code */
-	start(up->bin->entry+(TRAMPSIZE*BY2SE), &tos, argc, p->arg);
-	pexit("", 0);
-	return 0;
-}
-
 void
-osexec(Proc *p)
-{
-	pthread_t pid;
-	pthread_attr_t attr;
-	pthread_attr_init(&attr);
-	if(pthread_create(&pid, &attr, trex, p)){
-		oserrstr();
-		panic("osexec: %r");
-	}
-	pthread_join(pid, nil);
-	pthread_attr_destroy(&attr);
-}
-
-void
-osclrmem(void)
-{
-	/* Clean up text, data, bss */
-	if(up->bin->text)
-		munmap((void*)up->bin->text, up->bin->ts);
-	if(up->bin->data)
-		munmap((void*)up->bin->data, up->bin->ds);
-	if(up->bin->bss)
-		munmap((void*)up->bin->bss, up->bin->bs);
-}
-
-void
-osbuildtext(Chan *tc)
-{
-	int n;
-	void *text;
-
-	text = mmap(nil, up->bin->ts, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-	n = devtab[tc->type]->read(tc, text, up->bin->ts, 0);
-	if(!text || n == 0)
-		error("unable to set up text segment");
-	/* Stash this in text for now, we will be moving and rewriting in the patch */
-	up->bin->text = (uintptr)text;
-}
-
-void
-ospatchtext(void)
-{
-	void *text, *final;
-	int flag;
-
-	/* Set up trampoline. Mach dependent */
-	text = mallocz(TRAMPSIZE, 1);
-	trampoline(text);
-
-	flag = MAP_PRIVATE|MAP_ANONYMOUS;
-#ifdef __APPLE__
-	flag |= MAP_JIT;
-#endif
-	final = mmap(nil, up->bin->ts+TRAMPSIZE, PROT_WRITE|PROT_READ, flag, -1, 0);
-	memmove(final, text, TRAMPSIZE);
-	memmove(final+TRAMPSIZE, (void*)up->bin->text, up->bin->ts);
-	if(!final)
-		error("unable to set up text segment with trampoline");
-
-	/* Patch. Mach dependent */
-	if(patch(final-TRAMPSIZE, up->bin->ts) < 0)
-		error("unable to patch syscalls");
-	if(mprotect((void*)up->bin->text, up->bin->ts+TRAMPSIZE, PROT_EXEC) != 0)
-		error("Unable to mprotect: %r");
-	up->bin->text = (uintptr)final;
-}
-
-void
-osbuilddata(Chan *tc)
-{
-	int n;
-	void *data;
-
-	data = mmap((void*)up->bin->data, up->bin->ds, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-	n = devtab[tc->type]->read(tc, data, up->bin->ds, up->bin->ts);
-	if(!data || n == 0)
-		error("unable to set up data segment");
-	up->bin->data = (uintptr)data;
-}
-
-void
-osbuildbss(Chan *tc)
-{
-	void *bss;
-	// BSS - set it up in READ/WRITE
-	bss = mmap((void*)up->bin->bss, up->bin->bs, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-	if(!bss)
-		error("unable to set up bss segment");
-	up->bin->bss = (uintptr)bss;
-}
-
-void
 osexit(void)
 {
 	pthread_setspecific(prdakey, 0);
@@ -360,6 +248,39 @@
 		return snprint(status, nstatus, "%d 0 0 0 'signal: %d'", pid, s);
 	}
 	return snprint(status, nstatus, "%d 0 0 0 'odd status: 0x%x'", pid, s);
+}
+
+void
+osclrmem(uintptr mem, uintptr ms)
+{
+	if(mem)
+		munmap((void*)mem, ms);
+}
+
+void *
+osbuildmem(Chan *tc, uintptr ts, uintptr ds, uintptr bss, int offset)
+{
+	int n;
+	void *exec, *binary;
+
+	/* Read in initial datum */
+	exec = mallocz(ts+ds, 1);
+	n = devtab[tc->type]->read(tc, exec, ts+ds, offset);
+	if(!exec || n < (ts+ds))
+		error("read error");
+
+	/* Contiguous memory block for text/data/bss */
+	binary = mmap(nil, UTZERO+n+bss, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	if(binary == MAP_FAILED)
+		error("Failed: %r");
+
+	/* Mark text portion executable */
+	memcpy(binary+UTZERO, exec, n);
+	if(mprotect(binary+UTZERO, ts, PROT_EXEC|PROT_READ) != 0)
+		error("Unable to mprotect: %r");
+
+	free(exec);
+	return binary;
 }
 
 int
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -1,213 +1,218 @@
-#include    "u.h"
-#include    "lib.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"error.h"
-#include    "user.h"
-#include	"mem.h"
-#include    <a.out.h>
-#include 	<signal.h>
-#include    <sys/mman.h>
+#include "u.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "error.h"
+#include "user.h"
+#include "mem.h"
+#include <a.out.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <setjmp.h>
 
 #undef rfork
 
+jmp_buf exec_jmp;
+typedef void (*Entry)(int, char**);
+
 static void
 nop(int x)
 {
-	USED(x);
+    USED(x);
 }
 
+static void
+sigsegv(int sig)
+{
+    print("Segfaultin'\n");
+    longjmp(exec_jmp, 2);
+}
+
+static void
+sigquit(int sig)
+{
+    print("Sigquittin'\n");
+    longjmp(exec_jmp, 1);
+}
+
+static void
+sigsys(int sig)
+{
+    print("We here!!! sig %d\n", sig);
+}
+
 int
 sysrfork(int flags)
 {
-	int pid, status;
-	int p[2];
-	int n;
-	char buf[128], *q;
-	extern char **environ;
-	struct sigaction oldchld;
+    int pid, status;
+    int p[2];
+    int n;
+    char buf[128], *q;
+    extern char **environ;
+    struct sigaction oldchld;
 
-	memset(&oldchld, 0, sizeof oldchld);
+    memset(&oldchld, 0, sizeof oldchld);
 
-	if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
-		/* check other flags before we commit */
-		flags &= ~(RFPROC|RFFDG|RFENVG);
-		n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG));
-		if(n){
-			werrstr("unknown flags %08ux in rfork", n);
-			return -1;
-		}
-		if(flags&RFNOWAIT){
-			sigaction(SIGCHLD, nil, &oldchld);
-			signal(SIGCHLD, nop);
-			if(pipe(p) < 0)
-				return -1;
-		}
-		pid = fork();
-		if(pid == -1)
-			return -1;
-		if(flags&RFNOWAIT){
-			flags &= ~RFNOWAIT;
-			if(pid){
-				/*
-				 * Parent - wait for child to fork wait-free child.
-				 * Then read pid from pipe.  Assume pipe buffer can absorb the write.
-				 */
-				close(p[1]);
-				status = 0;
-				if(wait4(pid, &status, 0, 0) < 0){
-					werrstr("pipe dance - wait4 - %r");
-					close(p[0]);
-					return -1;
-				}
-				n = readn(p[0], buf, sizeof buf-1);
-				close(p[0]);
-				if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){
-					if(!WIFEXITED(status))
-						werrstr("pipe dance - !exited 0x%ux", status);
-					else if(WEXITSTATUS(status) != 0)
-						werrstr("pipe dance - non-zero status 0x%ux", status);
-					else if(n < 0)
-						werrstr("pipe dance - pipe read error - %r");
-					else if(n == 0)
-						werrstr("pipe dance - pipe read eof");
-					else
-						werrstr("pipe dance - unknown failure");
-					return -1;
-				}
-				buf[n] = 0;
-				if(buf[0] == 'x'){
-					werrstr("%s", buf+2);
-					return -1;
-				}
-				pid = strtol(buf, &q, 0);
-			}else{
-				/*
-				 * Child - fork a new child whose wait message can't
-				 * get back to the parent because we're going to exit!
-				 */
-				signal(SIGCHLD, SIG_IGN);
-				close(p[0]);
-				pid = fork();
-				if(pid){
-					/* Child parent - send status over pipe and exit. */
-					if(pid > 0)
-						fprint(p[1], "%d", pid);
-					else
-						fprint(p[1], "x %r");
-					close(p[1]);
-					_exit(0);
-				}else{
-					/* Child child - close pipe. */
-					close(p[1]);
-				}
-			}
-			sigaction(SIGCHLD, &oldchld, nil);
-		}
-		if(pid != 0)
-			return pid;
-		if(flags&RFCENVG)
-			if(environ)
-				*environ = nil;
-	}
-	if(flags&RFPROC){
-		werrstr("cannot use rfork for shared memory -- use libthread");
-		return -1;
-	}
-	if(flags&RFNAMEG){
-		/* XXX set $NAMESPACE to a new directory */
-		flags &= ~RFNAMEG;
-	}
-	if(flags&RFNOTEG){
-		setpgid(0, getpid());
-		flags &= ~RFNOTEG;
-	}
-	if(flags&RFNOWAIT){
-		werrstr("cannot use RFNOWAIT without RFPROC");
-		return -1;
-	}
-	if(flags){
-		werrstr("unknown flags %08ux in rfork", flags);
-		return -1;
-	}
-	return 0;
-}
+    if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
+        flags &= ~(RFPROC|RFFDG|RFENVG);
+        n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG));
+        if(n){
+            werrstr("unknown flags %08ux in rfork", n);
+            return -1;
+        }
+        if(flags&RFNOWAIT){
+            sigaction(SIGCHLD, nil, &oldchld);
+            signal(SIGCHLD, nop);
+            if(pipe(p) < 0)
+                return -1;
+        }
+        pid = fork();
+        if(pid == -1)
+            return -1;
+        if(flags&RFNOWAIT){
+            flags &= ~RFNOWAIT;
+            if(pid){
+                close(p[1]);
+                status = 0;
+                if(wait4(pid, &status, 0, 0) < 0){
+                    werrstr("pipe dance - wait4 - %r");
+                    close(p[0]);
+                    return -1;
+                }
+                n = readn(p[0], buf, sizeof buf-1);
+                close(p[0]);
+                if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){
+                    if(!WIFEXITED(status))
+                        werrstr("pipe dance - !exited 0x%ux", status);
+                    else if(WEXITSTATUS(status) != 0)
+                        werrstr("pipe dance - non-zero status 0x%ux", status);
+                    else if(n < 0)
+                        werrstr("pipe dance - pipe read error - %r");
+                    else if(n == 0)
+                        werrstr("pipe dance - pipe read eof");
+                    else
+                        werrstr("pipe dance - unknown failure");
+                    return -1;
+                }
+                buf[n] = 0;
+                if(buf[0] == 'x'){
+                    werrstr("%s", buf+2);
+                    return -1;
+                }
+                pid = strtol(buf, &q, 0);
+            }else{
+                signal(SIGCHLD, SIG_IGN);
+                close(p[0]);
+                pid = fork();
+                if(pid){
+                    if(pid > 0)
+                        fprint(p[1], "%d", pid);
+                    else
+                        fprint(p[1], "x %r");
+                    close(p[1]);
+                    _exit(0);
+                }else{
+                    close(p[1]);
+                }
+            }
+            sigaction(SIGCHLD, &oldchld, nil);
+        }
+        if(pid != 0)
+            return pid;
+        if(flags&RFCENVG)
+            if(environ)
+                *environ = nil;
+    }
+    if(flags&RFPROC){
+        werrstr("cannot use rfork for shared memory -- use libthread");
+        return -1;
+    }
+    if(flags&RFNAMEG){
+        flags &= ~RFNAMEG;
+    }
+    if(flags&RFNOTEG){
+        setpgid(0, getpid());
+        flags &= ~RFNOTEG;
+    }
+    if(flags&RFNOWAIT){
+        werrstr("cannot use RFNOWAIT without RFPROC");
+        return -1;
+    }
+    if(flags){
+        werrstr("unknown flags %08ux in rfork", flags);
+        return -1;
+    }
+    return 0;
+}
 
 static int
 shargs(char *s, int n, char **ap, int nap)
 {
-	char *p;
-	int i;
+    char *p;
+    int i;
 
-	if(n <= 2 || s[0] != '#' || s[1] != '!')
-		return -1;
-	s += 2;
-	n -= 2;		/* skip #! */
-	if((p = memchr(s, '\n', n)) == nil)
-		return 0;
-	*p = 0;
-	i = tokenize(s, ap, nap-1);
-	ap[i] = nil;
-	return i;
+    if(n <= 2 || s[0] != '#' || s[1] != '!')
+        return -1;
+    s += 2;
+    n -= 2;
+    if((p = memchr(s, '\n', n)) == nil)
+        return 0;
+    *p = 0;
+    i = tokenize(s, ap, nap-1);
+    ap[i] = nil;
+    return i;
 }
 
 ulong
 beswal(ulong l)
 {
-	uchar *p;
-
-	p = (uchar*)&l;
-	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+    uchar *p;
+    p = (uchar*)&l;
+    return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
 }
 
 uvlong
 beswav(uvlong v)
 {
-	uchar *p;
-
-	p = (uchar*)&v;
-	return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
-				  | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
-				  | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
-				  | (uvlong)p[7];
+    uchar *p;
+    p = (uchar*)&v;
+    return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
+           | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
+           | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
+           | (uvlong)p[7];
 }
 
 void
 evenaddr(uintptr addr)
 {
-	if(addr & 3){
-		postnote(up, 1, "sys: odd address", NDebug);
-		error(Ebadarg);
-	}
+    if(addr & 3){
+        postnote(up, 1, "sys: odd address", NDebug);
+        error(Ebadarg);
+    }
 }
 
-/*
- * &s[0] is known to be a valid address.
- */
 void*
 vmemchr(void *s, int c, ulong n)
 {
-	uintptr a;
-	ulong m, i;
-	void *t;
+    uintptr a;
+    ulong m, i;
+    void *t;
 
-	i = n;
-	a = (uintptr)s;
-	for(;;){
-		m = BY2PG - (a & (BY2PG-1));
-		if(i <= m)
-			break;
-		/* spans pages; handle this page */
-		t = memchr((void*)a, c, m);
-		if(t != nil)
-			return t;
-		a += m;
-		i -= m;
-		if(a < KZERO)
-			validaddr(a, 1, 0);
-	}
-	/* fits in one page */
-	return memchr((void*)a, c, i);
+    i = n;
+    a = (uintptr)s;
+    for(;;){
+        m = BY2PG - (a & (BY2PG-1));
+        if(i <= m)
+            break;
+        t = memchr((void*)a, c, m);
+        if(t != nil)
+            return t;
+        a += m;
+        i -= m;
+        if(a < KZERO)
+            validaddr(a, 1, 0);
+    }
+    return memchr((void*)a, c, i);
 }
 
 #undef read
@@ -214,144 +219,119 @@
 int
 sysexec(int argc, char **argv)
 {
-	union {
-		struct {
-			Exec ex;
-			uvlong	hdr[1];
-		} ehdr;
-		char buf[256];
-	} u;
+    union {
+        struct {
+            Exec ex;
+            uvlong hdr[1];
+        } ehdr;
+        char buf[256];
+    } u;
 
-	char line[256];
-	char *progarg[32+1];
-	char *file, *elem;
-	Chan *tc;
-	ulong magic;
-	uintptr align, bssend;
-	int n, indir;
+    char line[256];
+    char *progarg[32+1];
+    char *file, *elem;
+    void *base;
+    Chan *tc;
+    Tos tos;
+    ulong magic;
+    uintptr t, b, entry, text, data, bss, align;
+    int n, indir;
 
-	elem = nil;
-	align = BY2PG-1;
-	indir = 0;
-	file = argv[0];
-	up->bin = mallocz(sizeof(Binary*), 1);
+    elem = nil;
+    align = BY2PG-1;
+    indir = 0;
+    file = argv[0];
 
-	for(;;){
-		tc = namec(file, Aopen, OEXEC, 0);
-		if(waserror()){
-			cclose(tc);
-			nexterror();
-		}
-		if(!indir)
-			kstrdup(&elem, up->genbuf);
-		// TODO: Triple check this for accurate text/entry. Ensure they are right, our ts should not be the same each time, for example
-		n = devtab[tc->type]->read(tc, u.buf, sizeof(u.buf), 0);
-		if (n >= sizeof(Exec)){
-			magic = beswal(u.ehdr.ex.magic);
-			if(magic & AOUT_MAGIC) {
+    for(;;){
+        tc = namec(file, Aopen, OEXEC, 0);
+        if(waserror()){
+            cclose(tc);
+            nexterror();
+        }
+        if(!indir)
+            kstrdup(&elem, up->genbuf);
+        n = devtab[tc->type]->read(tc, u.buf, sizeof(u.buf), 0);
+        if (n >= sizeof(Exec)){
+            magic = beswal(u.ehdr.ex.magic);
+            if(magic & AOUT_MAGIC) {
 				if(magic & HDR_MAGIC){
-					if(n < sizeof(u.ehdr))
-						error(Ebadexec);
-					up->bin->entry = beswav(u.ehdr.hdr[0]);
-					up->bin->ts = UTZERO+sizeof(u.ehdr);
-				} else {
-					up->bin->entry = beswal(u.ehdr.ex.entry);
-					up->bin->ts = UTZERO+sizeof(Exec);
-				}
-				if(up->bin->entry < up->bin->ts)
+                    if(n < sizeof(u.ehdr))
+                        error(Ebadexec);
+                    entry = beswav(u.ehdr.hdr[0]);
+                    text = UTZERO+sizeof(u.ehdr);
+                } else {
+                    entry = beswal(u.ehdr.ex.entry);
+                    text = UTZERO+sizeof(u.ehdr);
+                }
+                if(entry < text)
+                    error(Ebadexec);
+                text += beswal(u.ehdr.ex.text);
+                if(text <= entry || text >= (USTKTOP-USTKSIZE))
 					error(Ebadexec);
+                switch(magic){
+                case S_MAGIC:
+                    align = 0x1fffff;
+                    break;
+                case P_MAGIC:
+                case V_MAGIC:
+                    align = 0x3fff;
+                    break;
+                case R_MAGIC:
+                    align = 0xffff;
+                    break;
+                }
+                break;
+            }
+        }
+        if(indir++)
+            error(Ebadexec);
 
-				up->bin->ts += beswal(u.ehdr.ex.text);
-				if(up->bin->ts <= up->bin->entry || up->bin->ts >= (uintptr)(USTKTOP-USTKSIZE))
-					error(Ebadexec);
-				switch(magic){
-				case S_MAGIC:	/* 2MB segment alignment for amd64 */
-					align = 0x1fffff;
-					break;
-				case P_MAGIC:	/* 16K segment alignment for spim */
-				case V_MAGIC:	/* 16K segment alignment for mips */
-					align = 0x3fff;
-					break;
-				case R_MAGIC:	/* 64K segment alignment for arm64 */
-					align = 0xffff;
-					break;
-				}
-				up->arg = argv;
-				argv[argc] = nil;
-				break; /* for binary */
-			}
-		}
-		if(indir++)
-			error(Ebadexec);
+        memmove(line, u.buf, sizeof(u.buf));
+        n = shargs(line, n, progarg, nelem(progarg));
+        if(n < 1)
+            error(Ebadexec);
+        progarg[n++] = file;
+        progarg[n] = nil;
+        file = progarg[0];
+        progarg[0] = elem;
+        poperror();
+        cclose(tc);
+    }
 
-		/* Process #!/bin/sh args */
-		memmove(line, u.buf, n);
-		n = shargs(line, n, progarg, nelem(progarg));
-		if(n < 1)
-			error(Ebadexec);
+    entry -= sizeof(u.ehdr);
+    text = beswal(u.ehdr.ex.text);
+	data = beswal(u.ehdr.ex.data);
+	bss = beswal(u.ehdr.ex.bss);
 
-		progarg[n++] = file;
-		progarg[n] = nil;
-		argv++;
-		file = progarg[0];
-		progarg[0] = elem;
-		strcpy(up->text, elem);
-		poperror();
-		cclose(tc);
-		// Check the actual sysproc, there's some missing bits here still
-		up->arg = progarg;
-	}
+    /* Set up text, data, and bss. OS dependent. */
+    base = osbuildmem(tc, text, data, bss, sizeof(u.ehdr));
+    b = ((uintptr)base + align) & ~align;
 
-	up->bin->ds = beswal(u.ehdr.ex.data);
-	up->bin->bs = beswal(u.ehdr.ex.bss);
-	up->bin->text = align;
-	up->bin->ts -= UTZERO;
-	align = BY2PG-1;
-	up->bin->data = ((up->bin->ts+align) & ~align) / BY2WD;
-	bssend = up->bin->ts + up->bin->ds + up->bin->bs;
-	up->bin->bss = ((bssend + align) & ~align) / BY2WD;
-	up->bin->bss -= up->bin->bs;
+    poperror();
+    cclose(tc);
 
-	/* Set up text, data, and bss. Patch syscalls. OS dependent. */
-	osbuildtext(tc);
-	if(waserror()){
-		print("%s\n", up->errstr);
-		osclrmem();
-		nexterror();
-	}
-	ospatchtext();
-	if(waserror()){
-		print("%s\n", up->errstr);
-		osclrmem();
-		nexterror();
-	}
-	osbuilddata(tc);
-	if(waserror()){
-		print("%s\n", up->errstr);
-		osclrmem();
-		nexterror();
-	}
-	osbuildbss(tc);
-	if(waserror()){
-		print("%s\n", up->errstr);
-		osclrmem();
-		nexterror();
-	}
+    /* Meaningful signals to us */
+    signal(SIGSEGV, sigsegv);
+    signal(SIGQUIT, sigquit);
+    signal(SIGINT, sigquit);
+    signal(SIGSYS, sigsys);
 
-	/* Run binary. OS dependent. */
-	osexec(up);
+    switch(setjmp(exec_jmp)) {
+    case 0:
+        tos.pid = getpid();
+        print("Base %ux, Entry %ux, Text %ux\n", b, entry, text);
+        start(b+entry, &tos, argc, argv);
+        longjmp(exec_jmp, 1);
+        break;
+    case 1:
+        print("Normal exit\n");
+        osclrmem((uintptr)base, text+data+bss);
+        return 0;
+    case 2:
+        print("SIGSEGV!\n");
+        return -1;
+    }
 
-	print("Exiting sysproc\n");
-	/* Clean up */
-	osclrmem();
-	up->arg = nil;
-	free(up->bin);
-
-	poperror(); /* osbuildtext */
-	poperror(); /* ospatchtext */
-	poperror(); /* osbuilddata */
-	poperror(); /* osbuildbss */
-	cclose(tc);
-	
-	return 0;
+    /* Can't happen */
+    return 1;
 }
\ No newline at end of file