hlfw.ca

drawcpu

Download patch

ref: 4f64a0294ee182f54c5ec341ab13163f43038af0
parent: 1e20174e3d54631d81b0ab310bef356e01179ad5
author: halfwit <michaelmisch1985@gmail.com>
date: Sun Aug 11 14:31:29 PDT 2024

osbuildexec is currently erroring

--- a/TODO
+++ b/TODO
@@ -1,14 +1,11 @@
 TODO:
- - [ ] Look into args address space prior to hitting exec
- - [ ] /env/fn# to init functions?
- - [ ] set up initial connection before handing over to an rc session, to set up binds and mounts?
-       This can be done in rcmain, mount in the namespace below drawcpu, then mount it in
- - [ ] Import our $objtype/bin and /rc from 9front instead of builtins as #9
- - [x] remove rc builtins, possibly add os() as it uses devcmd locally, if needed
- - [ ] Adapt github.com/michaelforney/nine to load and execute our binaries (exec)
+ - [x] /env/fn# to init functions?
+ - [-] set up initial connection before handing over to an rc session, to set up binds and mounts?
+ - [ ] Set up $path with \#9/$objtype/bin and \#9/rc/bin
+ - [x] remove rc builtins aside from mount/bind
  - [x] start.s in libmachdep for each posix-target, just do like tas.c
        - investigate if we want to run this another way instead!
- - [ ] have it export a var service=unix
+ - [x] have it export a var service=unix
  - [ ] Some people probably want aan?
  - [ ] gui-cocoa try to capture the windows we create so we can send mouse/keyboard to it, plist for launchd
  - [ ] gui-wl cannibalize the wayland shims
@@ -25,7 +22,7 @@
  - devaudio - #A: !needed, We use the client exported /dev/audio instead
  - devcmd   - #C: needed OS(1) commands, we already run on host
  - devcons  - #c: needed, /dev/cons
- - devenv   - #e: needed, /dev/env
+ - devenv   - #e: needed, /env
  - devfs    - #U: needed, local files
  - devip    - #I: needed, networking
  - devlfd   - #L: needed, local fd
--- a/kern/chan.c
+++ b/kern/chan.c
@@ -1158,8 +1158,8 @@
 {
 	int len, n, t, nomount;
 	Chan *c;
-	Chan *volatile cnew;
-	Path *volatile path;
+	Chan */*volatile*/ cnew;
+	Path */*volatile*/ path;
 	Elemlist e;
 	Rune r;
 	Mhead *m;
@@ -1520,8 +1520,8 @@
 	/*BKS*/	1, 1, 1, 1, 1, 1, 1, 1,
 	/*DLE*/	1, 1, 1, 1, 1, 1, 1, 1,
 	/*CAN*/	1, 1, 1, 1, 1, 1, 1, 1,
-	['/']	1,
-	[0x7f]	1,
+	['/']=	1,
+	[0x7f]=	1,
 };
 
 /*
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -383,6 +383,16 @@
 
 	Proc	*qnext;
 
+	long	stext;
+	long	sdata;
+	long	sbss;
+	long	sentry;
+	
+	uintptr t;
+	uintptr d;
+	uintptr e;
+	uintptr b;
+	
 	void	(*fn)(void*);
 	void	*arg;
 
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -222,6 +222,7 @@
 ulong	ticks(void);
 void	osproc(Proc*);
 void    osexec(Proc*);
+void    osbuildexec(Chan *);
 void	osnewproc(Proc*);
 void	procsleep(void);
 void	procwakeup(Proc*);
--- a/kern/parse.c
+++ b/kern/parse.c
@@ -35,7 +35,7 @@
 Cmdbuf*
 parsecmd(char *p, int n)
 {
-	Cmdbuf *volatile cb;
+	Cmdbuf */*volatile*/ cb;
 	int nf;
 	char *sp;
 
--- a/kern/posix.c
+++ b/kern/posix.c
@@ -139,16 +139,9 @@
 {
 	Proc *p;
 	void *run;
-	int flag;
 
 	p = vp;
-	flag = MAP_PRIVATE | MAP_ANONYMOUS;
-#ifdef __APPLE__
-	flag |= MAP_JIT;
-#endif
-print("Made it here\n");
-	//run = mmap(NULL, p->nentry, PROT_READ |	PROT_WRITE | PROT_EXEC, flag, -1, 0);
-	//memcpy(run, &p->entry, p->nentry);
+	memcpy(run, &p->e, p->sentry);
 	// This will be start() instead
 	__asm__ volatile (
 		"mov x0, %0 \n\t"
@@ -161,14 +154,12 @@
 	return 0;
 }
 
-// set up the thread correctly instead, then in this cb set it up
 void
 osexec(Proc *p)
 {
 	pthread_t pid;
 	pthread_attr_t attr;
-	// give proc some stack knowledge, set it up here
-	//pthread_attr_setstack(&attr, p->sbase, p->ssize);
+	print("Building and running and all that\n");
 	if(pthread_create(&pid, &attr, trex, p)){
 		oserrstr();
 		panic("osexec: %r");
@@ -369,38 +360,36 @@
 	tcsetattr(0, TCSAFLUSH, &t);
 }
 
-/*
-Segment *
-newseg(int type, uintptr base, ulong size)
+void
+osbuildexec(Chan *tc)
 {
-	Segment *s;
 	int fd;
-	// NOTE: This path may not be perfectly portable
-	fd = shm_open("drawcpu", O_CREAT | O_RDWR, 0600);
-	if(fd < 0)
-		error("shm_open failed");
+	void *exec, *text, *data;
+	int flag;
 
-	if(ftruncate(fd, size) < 0)
-		error("truncate failed");
-	
-	// tidy up the fs entry
-	shm_unlink("drawcpu");
-
-	s = mallocz(sizeof(Segment*), 1);
-	s->type = type;
-	s->base = base;
-	s->size = size;
-	s->top = base+(size*BY2WD);
-	s->fd = fd;
-
-	// TODO: mmap these based on type
-	// APPLE will need some MAP_JIT like pthread_jit_write_protect_np to turn off before it can be executable
-	// also looks like sys_icache_invalidate as well
-	// So that means calling it as RX, toggling on write, writing the data, then toggling off write
-	// We could use the imagealloc for this, realistically; or some other methodology just in an #ifdef __APPLE__
-	// but that won't work quiiite the same with segs, so allocimage is our best approach
-	s->ptr = mmap((void*)s->base, s->size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, s->fd, 0);
-
-	return s;
+	flag = MAP_PRIVATE | MAP_ANONYMOUS;
+#ifdef __APPLE__ // mmap runs R W|X on newer Apple silicon
+	flag |= MAP_JIT;
+#endif
+	fd = newfd(tc);
+	exec = mmap(nil, up->stext + up->sdata, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (exec == MAP_FAILED) {
+		print("Yeah we failed\n");
+		error("mmap");
+		return;
+	}
+	text = mmap((void*)up->t, up->stext, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if(text == MAP_FAILED) {
+		error("mmap");
+		return;
+	}
+	data = mmap((void*)up->d, up->sdata + up->sbss, PROT_READ | PROT_WRITE, flag, -1, 0);
+	if(data == MAP_FAILED) {
+		error("mmap");
+		return;
+	}
+	up->e = (uintptr)exec;
+	up->sentry = up->stext + up->sdata + up->sbss;
+	print("Bottom: 0, top: %d\n", up->sentry);
+	fdclose(fd, 0);
 }
-*/
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -272,6 +272,7 @@
 					align = 0xffff;
 					break;
 				}
+				up->arg = argv;
 				break; /* for binary */
 			}
 		}
@@ -290,9 +291,12 @@
 		argv++;
 		file = progarg[0];
 		progarg[0] = elem;
+		up->arg = progarg;
+		strcpy(up->arg, file);
 		poperror();
 		cclose(tc);
 	}
+
 	t = (text+align) & ~align;
 	text -= UTZERO;
 	data = beswal(u.ehdr.ex.data);
@@ -302,13 +306,29 @@
 	bssend = t + data + bss;
 	b = (bssend + align) & ~align;
 
+	up->t = t;
+	up->d = data;
+	up->b = bss;
+
+	up->sentry = entry;
+	up->sdata = data;
+	up->sbss = bss;
+
 	if(t >= (ulong)(USTKTOP-USTKSIZE) || d >= (ulong)(USTKTOP-USTKSIZE) || b >= (ulong)(USTKTOP-USTKSIZE))
 		error(Ebadexec);
-	print("%x %x %x %x\n", entry, text, data, bss);
 	/* Load in to memory. OS dependent. */
-	// we could just attach this all to the proc
-	
-	///osexec(up);
+	osbuildexec(tc);
+	if(waserror()){
+		cclose(tc);
+		nexterror();
+	}
 
+	osexec(up);
+
+	// Clean up the proc after
+	up->arg = nil;
+	cclose(tc);
+	poperror();
+	poperror();
 	return 0;
 }
\ No newline at end of file
--- a/libip/eipfmt.c
+++ b/libip/eipfmt.c
@@ -9,15 +9,15 @@
 
 uchar prefixvals[256] =
 {
-[0x00] 0 | Isprefix,
-[0x80] 1 | Isprefix,
-[0xC0] 2 | Isprefix,
-[0xE0] 3 | Isprefix,
-[0xF0] 4 | Isprefix,
-[0xF8] 5 | Isprefix,
-[0xFC] 6 | Isprefix,
-[0xFE] 7 | Isprefix,
-[0xFF] 8 | Isprefix,
+[0x00] = 0 | Isprefix,
+[0x80] = 1 | Isprefix,
+[0xC0] = 2 | Isprefix,
+[0xE0] = 3 | Isprefix,
+[0xF0] = 4 | Isprefix,
+[0xF8] = 5 | Isprefix,
+[0xFC] = 6 | Isprefix,
+[0xFE] = 7 | Isprefix,
+[0xFF] = 8 | Isprefix,
 };
 
 int
--- a/librc/drawcpu.c
+++ b/librc/drawcpu.c
@@ -9,7 +9,6 @@
 #include "fns.h"
 #include "getflags.h"
 
-static void execrfork(void);
 static void execfinit(void);
 
 builtin Builtin[] = {
@@ -26,7 +25,8 @@
 	"rfork",	execrfork,
     "mount",    execmount,
     "bind",     execbind,
-    "ls",       execls,
+    "ls",       execls, // TODO: Remove
+    "cat",      execcat, // TODO: Remove
 	0
 };
 
@@ -59,13 +59,12 @@
 static void
 execfinit(void)
 {
-	// TODO: /env/fn# is empty
-	//char *cmds = estrdup("for(i in '/env/fn#'*){. -bq $i}\n");
-	//int line = runq->line;
-	//poplist();
-	//execcmds(openiocore(cmds, strlen(cmds)), estrdup(srcfile(runq)), runq->local, runq->redir);
-	//runq->lex->line = line;
-	//runq->lex->qflag = 1;
+	char *cmds = estrdup("for(i in '/env/fn#'*){. -bq $i}\n");
+	int line = runq->line;
+	poplist();
+	execcmds(openiocore(cmds, strlen(cmds)), estrdup(srcfile(runq)), runq->local, runq->redir);
+	runq->lex->line = line;
+	runq->lex->qflag = 1;
 }
 
 char*
@@ -212,7 +211,7 @@
 void
 Exec(char **argv)
 {
-	exec(sizeof(argv), argv);
+	exec(nelem(argv), argv);
 }
 
 int
@@ -295,7 +294,7 @@
 static int interrupted = 0;
 
 static void
-notifyf(void*, char *s)
+notifyf(void* _, char *s)
 {
 	int i;
 
--- a/librc/exec.c
+++ b/librc/exec.c
@@ -231,7 +231,7 @@
 	char num[12];
 	char *rcmain=Rcmain;
 
-	int i, fd;
+	int i;
 	argv0 = argv[0];
 	argc = getflags(argc, argv, "srdiIlxebpvVc:1m:1[command]", 1);
 	if(argc==-1)
--- a/librc/exec.h
+++ b/librc/exec.h
@@ -76,10 +76,11 @@
 
 void execcd(void), execwhatis(void), execeval(void), execexec(void);
 int execforkexec(void);
-void execexit(void), execshift(void);
+void execexit(void), execshift(void), execrfork(void);
 void execwait(void), execdot(void), execflag(void);
 void execfunc(var*), execcmds(io*, char*, var*, redir*);
-void execmount(void), execbind(void), execls(void);
+void execmount(void), execbind(void);
+void execls(void), execcat(void); // TODO: Remove
 
 void startfunc(var*, word*, var*, redir*);
 
--- a/librc/rcmain
+++ b/librc/rcmain
@@ -2,15 +2,13 @@
 if(~ $#home 0) home=$HOME
 if(~ $#ifs 0) ifs=' 	
 '
+service=unix
 profile=$home/.rcrc
-switch($#prompt){
-case 0
-	prompt=('% ' '	')
-case 1
-	prompt=($prompt '	')
+prompt=('unix% ' '	')
+fn unix% {
+    $x*
 }
-if(~ $rcname ?.out) prompt=('broken! ' '	')
-# TODO: mount in our /bin with #9/$objtype/bin and #9/rc/bin
+if(~ $rcname ?./drawcpu) prompt=('broken! ' '	')
 
 if(flag p) path=/bin
 if not {
@@ -17,6 +15,7 @@
 	finit
 	if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin)
 }
+
 fn sigexit
 if(! ~ $#cflag 0){
 	if(flag l) {
--- a/librc/simple.c
+++ b/librc/simple.c
@@ -608,6 +608,46 @@
 	return;
 }
 
+// TODO: Remove
+int
+cat(int f, char *s)
+{
+	char buf[IOUNIT];
+	long n;
+	while((n=Read(f, buf, sizeof buf))>0)
+		if(Write(1, buf, n)!=n)
+			pfmt(err, "write error copying %s: %s\n", s, strerror(errno));
+	if(n < 0)
+		pfmt(err, "error reading %s: %s\n", s, strerror(errno));
+	return n;
+}
+
+void
+execcat(void)
+{
+	int f;
+	popword(); /* cat */
+	word *a;
+
+	f = 0;
+	a = runq->argv->words;
+	if(count(a) == 0){
+		cat(f, "<stdin>");
+		close(f);
+	} else for(;a;a = a->next){
+		f = Open(a->word, OREAD);
+		if(f < 0){
+			pfmt(err, "can't open %s: %s", a->word, strerror(errno));
+			break;
+		}
+		cat(f, a->word);
+		close(f);
+		write(1, "\n", 1);
+	}
+	poplist();
+}
+
+// TODO: Remove
 void
 execls(void)
 {
--- a/main.c
+++ b/main.c
@@ -108,7 +108,7 @@
 
 	char *cmd[] = {
 		"drawcpu",
-		"-c"
+		"-c",
 		". <{n=`{read} && ! ~ $#n 0 && read -c $n} >[2=1]"	
 	};