hlfw.ca

drawcpu

Download patch

ref: 775400b52c5b473fe1528f3e31283fcfb730c18a
parent: fc8fc2b553fe537aa105b7b940727324ada55830
author: halfwit <michaelmisch1985@gmail.com>
date: Sun Jul 21 17:35:03 PDT 2024

Add in our structure from what we learned in our last branch

--- a/TODO
+++ b/TODO
@@ -1,37 +1,18 @@
-BUILTINS:
- - [x]' read'
- - [ ] 'write' ?
- - [x] 'ls'
- - [x] 'cat'
- - [ ] 'srv' ?
- - [~] 'mount' - currently not working
- - [x] 'bind'
- - [ ] 'mkdir'
- - [x] 'rm'
- - [ ] 'unmount'
- - [ ] 'ns'
- - [~] 'test' - only -d and maybe -f for now
- - [x] 'echo'
- - [ ] 'cp'
-
 TODO:
- - [ ] rc builtins (see above)
- - [x] Install rcmain properly on system, refer to it as needed
+ - [ ] set up initial connection before handing over to an rc session, to set up binds and mounts
+ - [x] remove rc builtins
+ - [ ] Import $objtype/bin from 9front instead of builtins
+ - [ ] Adapt github.com/michaelforney/nine to load and execute our binaries --> into the rc code for exec, instead of what they have
+ - [ ] Check the magic, run a normal exec if it's not a plan9 or p9p binary, or try wrapping everything we run
+ - [x] start.s in libmachdep for each posix-target, just do like tas.c
+ - [ ] darwin will use mach_vm_-family of functions, else we use mmap
  - [ ] have it export a var service=unix
  - [ ] Some people probably want aan?
- - [x] Move rc code to use our libc.h, u.h everywhere so our defs of open + such are correct
  - [ ] 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
+ - [ ] Use ScreenCaptureKit to get at the video/audio. Handle resizes the other direction
  - [ ] define the gui interface
  - [x] Makefile librc --> librc.a
- - [x] libc.h getwd plan9port/src/lib9/getwd.c 
- - [x] libc.h dirread /sys/src/libc/9sys/dirread.c
- - [x] libc.h notify plan9port/src/lib9/notify.c
- - [x] libc.h postnote plan9port/src/lib9/postnote.c
- - [x] libc.h await plan9port/src/lib9/await.c
- - [x] libc.h rfork plan9port/src/lib9/rfork.c 
- - [x] libc.h wait plan9port/src/lib9/wait.c
- - [x] libc.h time plan9port/src/lib9/time.c
  - [ ] RFREND + RFNOMEM could probably be handled in rfork
 
 Kernel space needs:
@@ -39,7 +20,7 @@
  - devkbd   - #b: !needed, We use the client exported /dev/kbd instead
  - devmouse - #m: !needed, We use the client exported /dev/mouse instead
  - devaudio - #A: !needed, We use the client exported /dev/audio instead
- - devcmd   - #C: !needed OS(1) commands, we already run on host
+ - devcmd   - #C: needed OS(1) commands, we already run on host
  - devcons  - #c: needed, /dev/cons
  - devenv   - #e: needed, /dev/env
  - devfs    - #U: needed, local files
@@ -48,8 +29,8 @@
  - devmnt   - #M: needed, client shares
  - devpipe  - #|: needed for pipes
  - devroot  - #/: needed, base of stack
- - devssl   - #D: !needed, ssl
- - devtls   - #a: !needed, tls
+ - devssl   - #D: !needed, ssl - eventually add
+ - devtls   - #a: !needed, tls - eventually add
  - devproc  - #p: needed, /dev/proc, overlay any existing 
- - devsrv   - #s: ~needed, if there's a compelling use case and interest
+ - devsrv   - #s: !needed, eventually add
  - devtab   - meta, needed - add/remove any devices that we add/remove, from here as well
--- a/include/lib.h
+++ b/include/lib.h
@@ -227,6 +227,29 @@
 	ulong	flags;
 };
 
+typedef struct Tos Tos;
+typedef struct Plink Plink;
+
+struct Tos {
+	struct				/* Per process profiling */
+	{
+		Plink		*pp;	/* known to be 0(ptr) */
+		Plink		*next;	/* known to be 4(ptr) */
+		Plink		*last;
+		Plink		*first;
+		u32int	pid;
+		u32int	what;
+	} prof;
+	u64int	cyclefreq;	/* cycle clock frequency if there is one, 0 otherwise */
+	ulong	kcycles;	/* cycles spent in kernel */
+	ulong	pcycles;	/* cycles spent in process (kernel + user) */
+	u32int	pid;		/* might as well put the pid here */
+	u32int	clock;
+	/* top of stack is here */
+};
+
+extern Tos *_tos;
+
 enum{
 	FmtWidth	= 1,
 	FmtLeft		= FmtWidth << 1,
@@ -316,7 +339,6 @@
 extern	int	__isInf(double, int);
 
 extern int (*fmtdoquote)(int);
-
 
 /*
  * Time-of-day
--- a/main.c
+++ b/main.c
@@ -67,6 +67,7 @@
 		panic("bind #U: %r");
     if(bind("/root", "/", MAFTER) < 0)
 		panic("bind /root: %r");
+	bind("#C", "/", MAFTER);
 
 	/* We have to be a bit pedantic about the fds, leave 0, 1, 2 alone */
 	ifd = open("/dev/null", OREAD);
--- a/posix-386/Makefile
+++ b/posix-386/Makefile
@@ -1,10 +1,13 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-386/start.c
@@ -1,0 +1,38 @@
+#include "u.h"
+#include "libc.h"
+
+void start(uintptr_t entry, Tos *_tos, int argc, char *argv[]) {
+    // entry point
+    register uintptr_t ebx asm("ebx") = entry;
+    register Tos *ecx asm("ecx") = _tos;
+    register int edx asm("edx") = argc;
+    register char **esi asm("esi") = argv;
+
+    __asm__ (
+        // Load values into registers
+        "mov ebx, %0\n\t"
+        "mov ecx, %1\n\t"
+        "mov edx, %2\n\t"
+        "mov esi, %3\n\t"
+
+        // push argv onto stack
+        "mov edi, edx\n\t"
+        "inc edi\n\t"
+        "shl edi, 2\n\t"
+        "sub esp, edi\n\t"
+        "mov edi, esp\n\t"
+        "rep movsb\n\t"
+
+        // push argc onto stack
+        "mov [esp], edx\n\t"
+        "sub esp, 4\n\t"
+
+        // jump to entry point
+        "jmp ebx\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (ebx), "r" (ecx), "r" (edx), "r" (esi)
+        : "edi"
+    );
+}
--- a/posix-amd64/Makefile
+++ b/posix-amd64/Makefile
@@ -1,10 +1,13 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-amd64/start.c
@@ -1,0 +1,38 @@
+#include "u.h"
+#include "libc.h"
+
+void start(uintptr_t entry, Tos *_tos, int argc, char *argv[]) {
+    // entry point
+    register uintptr_t rdi asm("rdi") = entry;
+    register Tos *rsi asm("rsi") = _tos;
+    register int edx asm("edx") = argc;
+    register char **rcx asm("rcx") = argv;
+
+    __asm__ (
+        // Load values into registers
+        "mov rdi, %0\n\t"
+        "mov rsi, %1\n\t"
+        "mov edx, %2\n\t"
+        "mov rcx, %3\n\t"
+
+        // push argv onto stack
+        "mov r8, rdx\n\t"
+        "add r8, r8, 1\n\t"
+        "shl r8, r8, 3\n\t"
+        "sub rsp, r8\n\t"
+        "mov r9, rsp\n\t"
+        "rep movsb\n\t"
+
+        // push argc onto stack
+        "mov [rsp], edx\n\t"
+        "sub rsp, 8\n\t"
+
+        // jump to entry point
+        "jmp rdi\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (rdi), "r" (rsi), "r" (edx), "r" (rcx)
+        : "r8", "r9"
+    );
+}
\ No newline at end of file
--- a/posix-arm/Makefile
+++ b/posix-arm/Makefile
@@ -1,10 +1,13 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-arm/start.c
@@ -1,0 +1,70 @@
+#include "u.h"
+#include "libc.h"
+
+void start(uintptr_t entry, Tos *_tos, int argc, char *argv[]) {
+    // entry point
+    register uintptr_t r0 asm("r0") = entry;
+    register Tos *r1 asm("r1") = _tos;
+    register int r2 asm("r2") = argc;
+    register char **r3 asm("r3") = argv;
+
+    __asm__ __volatile__ (
+        // Load values into registers
+        "mov r0, %0\n\t"
+        "mov r1, %1\n\t"
+        "mov r2, %2\n\t"
+        "mov r3, %3\n\t"
+
+    #ifdef ARMV5
+        // ARMv5 specific code
+        // push argv onto stack
+        "mov r4, r2\n\t"
+        "add r4, r4, #1\n\t"
+        "lsl r4, r4, #2\n\t"
+        "sub sp, sp, r4\n\t"
+        "mov r5, sp\n\t"
+        "cpy r6, r3\n\t"
+
+
+    "copy_argv_loop:\n\t"
+        "ldr r7, [r6], #4\n\t"
+        "str r7, [r5], #4\n\t"
+        "subs r4, r4, #1\n\t"
+        "bne copy_argv_loop\n\t"
+
+        // push argc onto stack
+        "sub sp, sp, #4\n\t"
+        "str r2, [sp]\n\t"
+
+    #else
+        // Generic ARM code
+        // push argv onto stack
+        "ldr r4, [r3]\n\t"
+        "add r4, r4, #1\n\t"
+        "lsl r4, r4, #2\n\t"
+        "sub sp, sp, r4\n\t"
+        "mov r5, sp\n\t"
+        "cpy r6, r3\n\t"
+
+    "copy_argv_loop:\n\t"
+        "ldr r7, [r6], #4\n\t"
+        "str r7, [r5], #4\n\t"
+        "subs r4, r4, #1\n\t"
+        "bne copy_argv_loop\n\t"
+
+        // push argc onto stack
+        "sub sp, sp, #4\n\t"
+        "str r2, [sp]\n\t"
+
+    #endif
+
+        // jump to entry point
+        "mov lr, r0\n\t"
+        "bx lr\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (r0), "r" (r1), "r" (r2), "r" (r3)
+        : "r4", "r5", "r6", "r7"
+    );
+}
\ No newline at end of file
--- a/posix-arm64/Makefile
+++ b/posix-arm64/Makefile
@@ -1,10 +1,13 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-arm64/start.c
@@ -1,0 +1,44 @@
+#include "u.h"
+#include "libc.h"
+
+void start(uintptr_t entry, Tos *_tos, int argc, char *argv[]) {
+    // entry point
+    register uintptr_t r0 asm("x0") = entry;
+    register Tos *r1 asm("x1") = _tos;
+    register int r2 asm("w2") = argc;
+    register char **r3 asm("x3") = argv;
+
+    __asm__ (
+        // Load values into registers
+        "mov x0, %0\n\t"
+        "mov x1, %1\n\t"
+        "mov w2, %w2\n\t"
+        "mov x3, %3\n\t"
+
+        // push argv onto stack
+        "mov x4, x2\n\t"
+        "add x4, x4, #1\n\t"
+        "lsl x4, x4, #3\n\t"
+        "sub sp, sp, x4\n\t"
+        "mov x5, sp\n\t"
+        "mov x6, x3\n\t"
+
+    "copy_argv_loop:\n\t"
+        "ldr x7, [x6], #8\n\t"
+        "str x7, [x5], #8\n\t"  
+        "subs x4, x4, #1\n\t"
+        "bne copy_argv_loop\n\t"
+
+        // push argc onto stack
+        "sub sp, sp, #16\n\t"
+        "str w2, [sp, #8]\n\t"
+
+        // jump to entry point
+        "br x0\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (r0), "r" (r1), "r" (r2), "r" (r3)
+        : "x4", "x5", "x6", "x7"
+    );
+}
\ No newline at end of file
--- a/posix-mips/Makefile
+++ b/posix-mips/Makefile
@@ -1,11 +1,14 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
-
+	tas.$O\
+	start.$O\
+	
 default: $(LIB)
 $(LIB): $(OFILES)
 	$(AR) r $(LIB) $(OFILES)
--- /dev/null
+++ b/posix-mips/start.s
@@ -1,0 +1,41 @@
+.data
+argc:   .word 0
+_tos:   .word 0
+argv:   .word 0
+sp:     .word 0
+
+.text
+.globl start
+start:
+    # entry point
+    lw $t0, argc       # $t0 = argc
+    lw $t1, _tos       # $t1 = _tos
+    lw $t2, argv       # $t2 = argv
+    lw $t3, sp         # $t3 = stack pointer
+
+    # push argv onto stack
+    move $t4, $t0      # $t4 = argc
+    addi $t4, $t4, 1   # $t4 = argc + 1
+    sll $t4, $t4, 2    # $t4 = (argc + 1) * 4
+    subu $sp, $sp, $t4 # $sp = $sp - ((argc + 1) * 4)
+    move $t4, $sp      # $t4 = stack pointer
+    move $t5, $t2      # $t5 = argv
+    move $t6, $t4      # $t6 = destination pointer
+
+copy_argv_loop:
+    lw $t7, 0($t5)     # Load argv[i] to $t7
+    sw $t7, 0($t6)     # Store argv[i] to stack
+    addiu $t5, $t5, 4  # Increment argv
+    addiu $t6, $t6, 4  # Increment destination pointer
+    addi $t0, $t0, -1  # Decrement argc
+    bne $t0, $zero, copy_argv_loop # Loop if argc != 0
+
+    # push argc onto stack
+    subu $sp, $sp, 4   # $sp = $sp - 4
+    sw $t3, ($sp)      # Push stack pointer
+
+    # jump to entry point
+    j $t0
+    nop
+
+.section .note.GNU-stack,"",@progbits
\ No newline at end of file
--- a/posix-power/Makefile
+++ b/posix-power/Makefile
@@ -1,12 +1,15 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+LAGS+= -Wa,-mregnames,-fpie
+LDFLAGS+=-fpie
 
 CFLAGS+= -Wa,-mregnames
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-power/start.c
@@ -1,0 +1,49 @@
+#include "u.h"
+#include "libc.h"
+
+void start() {
+    // entry point
+    register int argc asm("r3");
+    register int _tos asm("r4");
+    register int argv asm("r5");
+    register int sp asm("r6");
+
+    __asm__ (
+        // Load values into registers
+        "lwz %0, argc\n\t"
+        "lwz %1, _tos\n\t"
+        "lwz %2, argv\n\t"
+        "lwz %3, sp\n\t"
+
+        // push argv onto stack
+        "mr r4, r3\n\t"
+        "addi r4, r4, 1\n\t"
+        "slwi r4, r4, 2\n\t"
+        "subi sp, sp, r4\n\t"
+        "mr r4, sp\n\t"
+        "mr r5, r5\n\t"
+        "mr r6, r4\n\t"
+
+    "copy_argv_loop:\n\t"
+        "lwz r7, 0(r5)\n\t"
+        "stw r7, 0(r6)\n\t"
+        "addi r5, r5, 4\n\t"
+        "addi r6, r6, 4\n\t"
+        "addi r3, r3, -1\n\t"
+        "cmpwi r3, 0\n\t"
+        "bne copy_argv_loop\n\t"
+
+        // push argc onto stack
+        "subi sp, sp, 4\n\t"
+        "stw r4, 0(sp)\n\t"
+
+        // jump to entry point
+        "mtctr r3\n\t"
+        "bctr\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (argc), "r" (_tos), "r" (argv), "r" (sp)
+        : "r4", "r5", "r6", "r7"
+    );
+}
\ No newline at end of file
--- a/posix-riscv64/Makefile
+++ b/posix-riscv64/Makefile
@@ -1,10 +1,13 @@
 ROOT=..
 include ../Make.config
 LIB=../libmachdep.a
+CFLAGS+=-fpie
+LDFLAGS+=-fpie
 
 OFILES=\
 	getcallerpc.$O\
-	tas.$O
+	tas.$O\
+	start.$O\
 
 default: $(LIB)
 $(LIB): $(OFILES)
--- /dev/null
+++ b/posix-riscv64/start.c
@@ -1,0 +1,47 @@
+#include "u.h"
+#include "libc.h"
+
+void start() {
+    // entry point
+    register int argc asm("t0");
+    register int _tos asm("t1");
+    register int argv asm("t2");
+    register int sp asm("t3");
+
+    __asm__ (
+        // Load values into registers
+        "lw %0, argc\n\t"
+        "lw %1, _tos\n\t"
+        "lw %2, argv\n\t"
+        "lw %3, sp\n\t"
+
+        // push argv onto stack
+        "mv t4, t0\n\t"
+        "addi t4, t4, 1\n\t"
+        "slli t4, t4, 2\n\t"
+        "sub sp, sp, t4\n\t"
+        "mv t4, sp\n\t"
+        "mv t5, t2\n\t"
+        "mv t6, t4\n\t"
+
+    "copy_argv_loop:\n\t"
+        "lw t7, 0(t5)\n\t"
+        "sw t7, 0(t6)\n\t"
+        "addi t5, t5, 4\n\t"
+        "addi t6, t6, 4\n\t"
+        "addi t0, t0, -1\n\t"
+        "bnez t0, copy_argv_loop\n\t"
+
+        // push argc onto stack
+        "addi sp, sp, -4\n\t"
+        "sw t3, 0(sp)\n\t"
+
+        // jump to entry point
+        "jr t0\n\t"
+        "nop\n\t"
+
+        :
+        : "r" (argc), "r" (_tos), "r" (argv), "r" (sp)
+        : "t4", "t5", "t6", "t7"
+    );
+}
\ No newline at end of file
--- a/rc/drawcpu.c
+++ b/rc/drawcpu.c
@@ -1,5 +1,5 @@
 /*
- * Plan 9 versions of system-specific functions
+ * Drawcpu versions of system-specific functions
  *	By convention, exported routines herein have names beginning with an
  *	upper case letter.
  */
@@ -23,18 +23,7 @@
 	".",		execdot,
 	"flag",		execflag,
 	"finit",	execfinit,
-	"rfork",	execrfork,
-	"read",     execread,
-	"ns",       execns,
-	"bind",		execbind,
-	"mount",	execmount,
-	"unmount",	execunmount,
-	"ls", 		execls,
-	"cat",		execcat,
-	"rm",       execrm,
-	"mkdir",    execmkdir,
-	"test",     exectest,
-	"echo",     exececho,
+	//"rfork",	execrfork,
 	0
 };
 
@@ -274,6 +263,8 @@
 void
 Exec(char **argv)
 {
+	// TODO: this will call our vm code
+	// execvm();
 	execvp(argv[0], argv+1);
 }
 
@@ -357,11 +348,10 @@
 static int interrupted = 0;
 
 static void
-notifyf(void* u, char *s)
+notifyf(void*, char *s)
 {
 	int i;
 
-	USED(u);
 	for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
 		if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
 		goto Out;
@@ -420,6 +410,7 @@
 	int fd;
 	static int tab[] = {OREAD,OWRITE,ORDWR,OREAD|ORCLOSE};
 	fd = open(file, tab[mode&3]);
+	/* TODO: Remove the need for this */
 	if(fd != 0 && strcmp(file, "/fd/0") == 0)
 		fd = lfdfd(0);
 	if(fd != 1 && strcmp(file, "/fd/1") == 0)
@@ -494,6 +485,7 @@
 	if(newwdir){
 		char dir[4096];
 		int fd;
+		/* TODO: We should have this in our stack, test after */
 		if((fd=Creat("/dev/wdir"))>=0){
 			getwd(dir, sizeof(dir));
 			Write(fd, dir, strlen(dir));
--- a/rc/exec.h
+++ b/rc/exec.h
@@ -74,13 +74,10 @@
 };
 extern void (*builtinfunc(char *name))(void);
 
-void execread(void), execns(void), execls(void), execcat(void);
-void execrm(void), execmkdir(void), exectest(void), exececho(void);
-void execbind(void), execmount(void), execunmount(void);
 void execcd(void), execwhatis(void), execeval(void), execexec(void);
 int execforkexec(void);
 void execexit(void), execshift(void);
-void execwait(void), execumask(void), execdot(void), execflag(void);
+void execwait(void), execdot(void), execflag(void);
 void execfunc(var*), execcmds(io*, char*, var*, redir*);
 
 void startfunc(var*, word*, var*, redir*);
--- a/rc/simple.c
+++ b/rc/simple.c
@@ -240,251 +240,6 @@
 	return n;
 }
 
-void
-execread(void)
-{
-//	print("Execread\n");
-	int (*proc)(int, int, vlong, char*);
-	word *a;
-	int fd, multi = 0;
-	vlong num = 0;
-	popword(); /* "read" */
-	proc = lines;
-	while(runq->argv->words && runq->argv->words->word[0]=='-'){
-		char *f = runq->argv->words->word+1;
-		if(*f == '-'){
-			popword();
-			break;
-		}
-		proc = lines;
-		for(; *f; f++){
-			switch(*f){
-			case 'c':
-				num = atoll(runq->argv->words->next->word);
-				proc = chars;
-				break;
-			case 'n':
-				num = atoi(runq->argv->words->next->word);
-				break;
-			case 'm':
-				multi = 1;
-				break;
-			default:
-				goto Usage;
-			}
-			popword();
-		}
-	}
-	if(count(runq->argv->words)==0){
-		(*proc)(0, multi, num, "<stdin>");
-	} else {
-		a = runq->argv->words->next;
-		for(;a;a = a->next){
-			fd = open(a->word, OREAD);
-			if(fd < 0){
-				goto Error;
-			}
-			if((*proc)(fd, multi, num, a->word) < 0)
-				goto Error;
-			close(fd);
-		}
-	}
-	return;
-Error:
-	pfmt(err, "read: %s\n", strerror(errno));
-	setstatus("read error");
-	poplist();
-	return;
-Usage:
-	pfmt(err, "Usage: read [ -m | -n nlines | -c nbytes | -r nrunes ] [ file ... ]\n");
-	setstatus("read usage");
-	poplist();
-}
-
-void
-execrm(void)
-{
-	int i, recurse, force;
-	char *fd;
-	Dir *db;
-	word *a;
-
-	force = recurse = 0;
-	popword(); /* rm */
-	while(runq->argv->words && runq->argv->words->word[0]=='-'){
-		char *f = runq->argv->words->word+1;
-		if(*f == '-'){
-			popword();
-			break;
-		}
-		for(; *f; f++){
-			switch(*f){
-			case 'r':
-				recurse = 1;
-				break;
-			case 'f':
-				force = 1;
-				break;
-			default:
-				goto Usage;
-			}
-			popword();
-		}
-	}
-	a = runq->argv->words;
-	for(;a;a = a->next){
-		if(remove(a->word) != -1)
-			continue;
-		db = nil;
-		if(recurse && (db=dirstat(a->word))!=nil && (db->qid.type&QTDIR))
-			rmdir(a->word);
-		else
-			goto Error;
-		free(db);
-	}
-	return;
-Error:
-	pfmt(err, "rm: %r\n", strerror(errno));
-	poplist();
-	return;
-Usage:
-	pfmt(err, "usage: rm [-fr] file ...\n");
-	setstatus("rm usage");
-	poplist();
-	return;
-}
-
-void
-execns(void)
-{
-//print("Execns\n");
-}
-
-void
-execbind(void)
-{
-//print("Execbind\n");
-	ulong flag = 0;
-	int qflag = 0;
-	popword(); /* "bind" */
-	while(runq->argv->words && runq->argv->words->word[0]=='-'){
-		char *f = runq->argv->words->word+1;
-		if(*f == '-'){
-			popword();
-			break;
-		}
-		for(; *f; f++){
-			switch(*f){
-			case 'a':
-				flag |= MAFTER;
-				break;
-			case 'b':
-				flag |= MBEFORE;
-				break;
-			case 'c':
-				flag |= MCREATE;
-				break;
-			case 'q':
-				qflag = 1;
-				break;
-			default:
-				goto Usage;
-			}
-			popword();
-		}
-	}
-	if(count(runq->argv->words)!=2 || ((flag & MAFTER) && (flag & MBEFORE)))
-		goto Usage;
-	if(bind(runq->argv->words->word, runq->argv->words->next->word, flag) == -1)
-		goto Error;
-	return;
-Error:
-	poplist();
-	if(qflag)
-		return;
-	pfmt(err, "bind: %s\n", strerror(errno));
-	return;
-Usage:
-	pfmt(err, "usage: bind [-b|-a|-c|-bc|-ac] new old\n");
-	setstatus("bind usage");
-	poplist();
-	return;
-}
-
-void
-execmount(void)
-{
-//print("Execmount\n");
-	char *spec = "";
-	int flag = MREPL;
-	int qflag, noauth, fd;
-	qflag = noauth = 0;
-
-	popword(); /* mount */
-	while(runq->argv->words && runq->argv->words->word[0]=='-'){
-		char *f = runq->argv->words->word+1;
-		if(*f == '-'){
-			popword();
-			break;
-		}
-		for(; *f; f++){
-			switch(*f){
-			case 'a':
-				flag |= MAFTER;
-				break;
-			case 'b':
-				flag |= MBEFORE;
-				break;
-			case 'c':
-				flag |= MCREATE;
-				break;
-			case 'C':
-				flag |= MCACHE;
-				break;
-			case 'n':
-				noauth = 1;
-				break;
-			case 'q':
-				qflag = 1;
-				break;
-			default:
-				goto Usage;
-			}
-			popword();
-		}
-	}
-	if(count(runq->argv->words)==3)
-		spec = runq->argv->words->next->next->word;
-	else if(count(runq->argv->words)!=2)
-		goto Usage;
-	if((flag&MAFTER)&&(flag&MBEFORE))
-		goto Usage;
-	fd = Open(runq->argv->words->word, ORDWR);
-	if(fd < 0)
-		goto Error;
-	if(mount(fd, -1, runq->argv->words->next->word, flag, spec) < 0)
-		goto Error;
-	poplist();
-	return;
-Error:
-	setstatus("mount error");
-	poplist();
-	if(qflag)
-		return;
-	pfmt(err, "mount: %s\n", strerror(errno));
-	return;
-Usage:
-	pfmt(err, "usage: mount [-a|-b] [-cCnNq] [-k keypattern] /srv/service dir [spec]\n");
-	setstatus("mount usage");
-	return;
-}
-
-void
-execunmount(void)
-{
-	//unmount
-}
-
 int
 cat(int f, char *s)
 {
@@ -497,30 +252,6 @@
 		pfmt(err, "error reading %s: %s\n", s, strerror(errno));
 }
 
-void
-execcat(void)
-{
-	int f;
-	popword(); /* cat */
-	word *a;
-
-	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\n", a->word, strerror(errno));
-			break;
-		}
-		cat(f, a->word);
-		close(f);
-		write(1, "\n", 1);
-	}
-	poplist();
-}
-
 int
 hasmode(char *f, ulong m)
 {
@@ -532,105 +263,6 @@
 	r = (dir->mode & m) != 0;
 	free(dir);
 	return r;
-}
-
-void
-exectest(void)
-{
-	/* TODO(halfwit): Only care about -d for my needs, but test has a ton of things */
-	setstatus("no such file");
-	if(strcmp(runq->argv->words->next->word, "-d")==0)
-		if(hasmode(runq->argv->words->next->next->word, DMDIR))
-			setstatus("");
-	poplist();
-}
-
-void
-execmkdir(void)
-{
-
-}
-
-void
-exececho(void)
-{
-	int nflag;
-	int i, len;
-	char *buf, *p;
-	word *a, *c;
-
-	nflag = 0;
-	popword(); /* echo */
-	a = runq->argv->words;
-	if(count(a) > 0 && strcmp(a->word, "-n") == 0){
-		a = a->next; // move up our counter as well
-		nflag = 1;
-	}
-	len = 1;
-	for(c = a; c; c = c->next)
-		len += strlen(c->word)+1;
-	buf = malloc(len);
-	if(buf == 0)
-		panic("no memory");
-	p = buf;
-	for(c = a; c; c = c->next){
-		strcpy(p, c->word);
-		p += strlen(p);
-		if(c->next)
-			*p++ = ' ';
-	}
-	if(!nflag)
-		*p++ = '\n';
-	write(1, buf, p-buf);
-}
-
-void
-execls(void)
-{
-	Dir *db;
-	int fd, n, i;
-	char *path;
-
-	/* Read in our dir and just output name in a row */
-	popword(); /* "ls" */
-	switch(count(runq->argv->words)){
-	case 0:
-		path = ".";
-		break;
-	case 1:
-		path = runq->argv->words->word;
-		break;
-	default:
-		pfmt(err, "ls: listing multiple files not supported\n");
-		return;
-	}
-	db = dirstat(path);
-	if(db == nil)
-		goto Error;
-	if((db->qid.type&QTDIR)) {
-		free(db);
-		fd = open(path, OREAD);
-		if(fd == -1)
-			goto Error;
-		n = dirreadall(fd, &db);
-		if(n < 0)
-			goto Error;
-		for(i = 0; i < n; i++){
-			write(1, db->name, strlen(db->name));
-			write(1, "\n", 1);
-			db++;
-		}
-		close(fd);
-	} else {
-		write(1, db->name, strlen(db->name));
-		write(1, "\n", 1);
-	}
-	return;
-Error:
-	pfmt(err, "ls: %sr\n", strerror(errno));
-	setstatus("ls error");
-	poplist();
-	return;
 }
 
 void