hlfw.ca

drawcpu

Download patch

ref: 847cd0b5262ebdf9deb3c294bedffc162b4a80d2
parent: e4df0925260ce4f14ba6db4025d1ed4913b0f9ec
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Sep 5 13:58:00 PDT 2024

Some movement of some things

--- a/include/lib.h
+++ b/include/lib.h
@@ -315,7 +315,7 @@
 extern	char*	utfecpy(char*, char*, char*);
 extern	int	tas(int*);
 extern  int trampoline(void*);
-extern  void run(uintptr_t, Tos *, int, char **);
+extern  void start(uintptr_t, Tos *, int, char **);
 extern  long sysintercept(void*, void*, void*, void*, void*, void*, void*);
 extern  int patch(void*, int);
 extern	void	quotefmtinstall(void);
--- a/kern/posix.c
+++ b/kern/posix.c
@@ -147,7 +147,7 @@
 	argc = nelem((char**)p->arg);
 	if(pthread_setspecific(prdakey, p))
 		panic("cannot setspecific");
-	run(up->bin->text, &tos, argc, p->arg);
+	start(up->bin->text, &tos, argc, p->arg);
 	pexit("", 0);
 	return 0;
 }
@@ -193,7 +193,7 @@
 void
 ospatchtext(void)
 {
-	int n;
+	int n, flag;
 	void *text, *final;
 
 	/* Set up trampoline. Mach dependent */
@@ -202,9 +202,14 @@
 	if(n != TRAMPSIZE)
 		error("building trampoline failed");
 
-	final = mmap(0, (up->bin->ts)+n, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	flag = MAP_PRIVATE|MAP_ANONYMOUS;
+
+	#ifdef __APPLE__
+	flag |= MAP_JIT;
+	#endif
+	final = mmap(0, up->bin->ts+n, PROT_READ|PROT_WRITE, flag, -1, 0);
 	memmove(final, text, n);
-	memmove(final+n+1, (void*)up->bin->text, up->bin->ts);
+	memmove(final+n, (void*)up->bin->text, up->bin->ts);
 	if(!final)
 		error("unable to set up text segment with trampoline");
 
@@ -211,8 +216,9 @@
 	/* Patch. Mach dependent */
 	if(patch(final+n+1, up->bin->ts) < 0)
 		error("unable to patch syscalls");
-	mprotect(final, n, PROT_EXEC);
-	up->bin->text = (uintptr)final+n+1;
+
+	mprotect(final, n + up->bin->ts, PROT_READ|PROT_EXEC);
+	up->bin->text = (uintptr)final+n;
 	poperror();
 }
 
@@ -226,7 +232,7 @@
 	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;
+	up->bin->data = (uintptr)data;
 }
 
 void
@@ -237,7 +243,7 @@
 	bss = mmap((void*)up->bin->bss, up->bin->bssz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
 	if(!bss)
 		error("unable to set up bss segment");
-	//up->bin->bss = (uintptr)bss;
+	up->bin->bss = (uintptr)bss;
 }
 
 void
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -261,8 +261,8 @@
 					error(Ebadexec);
 				up->bin->text += beswal(u.ehdr.ex.text);
 				// BUG: This errors, errors seem broken currently
-//				if(text <= entry || text >= (uintptr)(USTKTOP-USTKSIZE))
-//					error(Ebadexec);
+				if(up->bin->text <= up->bin->entry || up->bin->text >= (uintptr)(USTKTOP-USTKSIZE))
+					error(Ebadexec);
 				switch(magic){
 				case S_MAGIC:	/* 2MB segment alignment for amd64 */
 					align = 0x1fffff;
@@ -299,16 +299,14 @@
 		// Check the actual sysproc, there's some missing bits here still
 		up->arg = progarg;
 	}
-
 	up->bin->ts = ((up->bin->text+align) & ~align) / BY2WD;
-	up->bin->text -= UTZERO;
 	up->bin->data = beswal(u.ehdr.ex.data);
 	up->bin->bss = beswal(u.ehdr.ex.bss);
+	up->bin->text -= UTZERO;
 	align = BY2PG-1;
 	up->bin->ds = ((up->bin->ts + up->bin->data + align) & ~align) / BY2WD;
 	bssend = up->bin->ts + up->bin->data + up->bin->bss;
 	up->bin->bssz = ((bssend + align) & ~align) / BY2WD;
-
 	if(up->bin->ts >= (ulong)(USTKTOP-USTKSIZE) || up->bin->ds >= (ulong)(USTKTOP-USTKSIZE) || up->bin->bss >= (ulong)(USTKTOP-USTKSIZE))
 		error(Ebadexec);
 
@@ -315,21 +313,25 @@
 	/* 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();
 	}
--- a/librc/exec.c
+++ b/librc/exec.c
@@ -16,7 +16,7 @@
  * Start executing the given code at the given pc with the given redirection
  */
 void
-start(code *c, int pc, var *local, redir *redir)
+startexec(code *c, int pc, var *local, redir *redir)
 {
 	thread *p = new(thread);
 	p->code = codecopy(c);
@@ -36,7 +36,7 @@
 void
 startfunc(var *func, word *starval, var *local, redir *redir)
 {
-	start(func->fn, func->pc, local, redir);
+	startexec(func->fn, func->pc, local, redir);
 	runq->local = newvar("*", runq->local);
 	runq->local->val = starval;
 	runq->local->changed = 1;
@@ -272,7 +272,7 @@
 	bootstrap[17].f = Xsimple;
 	bootstrap[18].f = Xexit;
 	bootstrap[19].f = 0;
-	start(bootstrap, 2, (var*)0, (redir*)0);
+	startexec(bootstrap, 2, (var*)0, (redir*)0);
 	/* prime bootstrap argv */
 	pushlist();
 	for(i = argc-1;i!=0;--i) pushword(argv[i]);
@@ -1038,7 +1038,7 @@
 			p->lex = 0;
 		} else
 			--p->pc;	/* re-execute Xrdcmds after codebuf runs */
-		start(codebuf, 2, p->local, p->redir);
+		startexec(codebuf, 2, p->local, p->redir);
 	}
 	lex = 0;
 	freenodes();
--- a/librc/fns.h
+++ b/librc/fns.h
@@ -60,7 +60,7 @@
 void	heredoc(tree*);
 void	setstatus(char*);
 void	skipnl(void);
-void	start(code*, int, var*, redir*);
+void    startexec(code*, int, var*, redir*);
 int	truestatus(void);
 void	usage(char*);
 int	wordchr(int);
--- a/librc/havefork.c
+++ b/librc/havefork.c
@@ -54,7 +54,7 @@
 		break;
 	case 0:
 		clearwaitpids();
-		start(runq->code, runq->pc+1, runq->local, runq->redir);
+		startexec(runq->code, runq->pc+1, runq->local, runq->redir);
 		runq->ret = 0;
 		break;
 	default:
@@ -86,7 +86,7 @@
 	case 0:
 		clearwaitpids();
 		Close(pfd[PRD]);
-		start(p->code, pc+2, runq->local, runq->redir);
+		startexec(p->code, pc+2, runq->local, runq->redir);
 		runq->ret = 0;
 		pushredir(ROPEN, pfd[PWR], lfd);
 		break;
@@ -93,7 +93,7 @@
 	default:
 		addwaitpid(pid);
 		Close(pfd[PWR]);
-		start(p->code, p->code[pc].i, runq->local, runq->redir);
+		startexec(p->code, p->code[pc].i, runq->local, runq->redir);
 		pushredir(ROPEN, pfd[PRD], rfd);
 		p->pc = p->code[pc+1].i;
 		p->pid = pid;
@@ -126,7 +126,7 @@
 	case 0:
 		clearwaitpids();
 		Close(pfd[PRD]);
-		start(runq->code, runq->pc+1, runq->local, runq->redir);
+		startexec(runq->code, runq->pc+1, runq->local, runq->redir);
 		pushredir(ROPEN, pfd[PWR], 1);
 		return;
 	default:
@@ -181,7 +181,7 @@
 	case 0:
 		clearwaitpids();
 		Close(mainfd);
-		start(p->code, pc+2, runq->local, runq->redir);
+		startexec(p->code, pc+2, runq->local, runq->redir);
 		pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
 		runq->ret = 0;
 		break;
@@ -209,7 +209,7 @@
 		break;
 	case 0:
 		clearwaitpids();
-		start(runq->code, runq->pc+1, runq->local, runq->redir);
+		startexec(runq->code, runq->pc+1, runq->local, runq->redir);
 		runq->ret = 0;
 		break;
 	default:
--- a/librc/simple.c
+++ b/librc/simple.c
@@ -324,7 +324,7 @@
 
 	if(exitnext()) turfstack(local);
 
-	start(rdcmds, 2, local, redir);
+	startexec(rdcmds, 2, local, redir);
 	runq->lex = newlexer(input, file);
 }
 
--- a/posix-amd64/Makefile
+++ b/posix-amd64/Makefile
@@ -7,7 +7,7 @@
 OFILES=\
 	getcallerpc.$O\
 	tas.$O\
-	run.$O\
+	start.$O\
 	trampoline.$O\
 
 default: $(LIB)
--- a/posix-amd64/run.c
+++ /dev/null
@@ -1,38 +1,0 @@
-#include "u.h"
-#include "libc.h"
-
-void run(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__ __volatile__ (
-        // 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
--- /dev/null
+++ b/posix-amd64/start.s
@@ -1,0 +1,22 @@
+.text
+.globl start
+start:
+	mov %rdi, %rbp /* entry */
+	mov %rsi, %rax /* _tos */
+	mov %rdx, %rbx /* argc */
+	mov %rcx, %rsi /* argv */
+
+	/* push argv onto stack */
+	mov %rbx, %rcx
+	add $1, %rcx
+	sal $3, %rcx
+	sub %rcx, %rsp
+	mov %rsp, %rdi
+	rep movsb
+
+	/* push argc onto stack */
+	push %rbx
+
+	jmp *%rbp
+
+.section .note.GNU-stack,"",@progbits
\ No newline at end of file
--- a/posix-arm64/Makefile
+++ b/posix-arm64/Makefile
@@ -7,7 +7,7 @@
 OFILES=\
 	getcallerpc.$O\
 	tas.$O\
-	run.$O\
+	start.$O\
 	trampoline.$O\
 	patch.$O\
 
--- a/posix-arm64/patch.c
+++ b/posix-arm64/patch.c
@@ -11,10 +11,11 @@
         // MOV X0, #immediate (could be D2800000 | syscall_number)
         // BL X0 (could be D4000000 | offset)
         // 0xD63F0000 is our BLR X0
+        // This sets up our jump to the trampoline code
         if ((*(ulong*)&text[i] & 0xFFFF0000) == 0xD2800000 && (*(ulong*)&text[i+BY2SE] & 0xFFFF0000) == 0xD4000000) {
-            long *ptr = (ulong*)&text[i];
-            ptr[1] = 0xD6;
-            ptr[0] = 0x3F;
+            ulong *ptr = (ulong*)&text[i];
+            ptr[1] = 0x3F;
+            ptr[0] = 0xD6;
             ret++;
         }
     }
--- a/posix-arm64/run.s
+++ /dev/null
@@ -1,24 +1,0 @@
-/* SPDX-License-Identifier: Unlicense */
-.text
-.global _run
-_run:
-    mov x29, x0         // entry (x0 is the first argument, equivalent to rdi)
-    mov x9, x1          // _tos (x1 is the second argument, equivalent to rsi)
-    mov x19, x2         // argc (x2 is the third argument, equivalent to rdx)
-    mov x20, x3         // argv (x3 is the fourth argument, equivalent to rcx)
-
-    // Push argv onto stack
-    mov x10, x19        // x10 = argc
-    add x10, x10, #1    // x10 = argc + 1
-    lsl x10, x10, #3    // x10 = (argc + 1) * 8 (shifting left by 3 is multiplying by 8)
-    sub sp, sp, x10     // Allocate space on stack
-    mov x0, sp          // x0 = new stack pointer (destination for memcpy)
-    mov x1, x20         // x1 = argv (source for memcpy)
-    mov x2, x10         // x2 = number of bytes to copy
-    bl _memcpy           // Call memcpy to copy argv to stack
-
-    // Push argc onto stack
-    str x19, [sp, #-16]!  // Push argc onto stack and update stack pointer
-
-    // Jump to entry point
-    br x29
\ No newline at end of file
--- /dev/null
+++ b/posix-arm64/start.s
@@ -1,0 +1,48 @@
+.text
+.global _start
+.align 4
+_start:
+    // Function prologue
+    stp x29, x30, [sp, #-16]!  // Save frame pointer and link register
+    mov x29, sp                // Set up frame pointer
+
+    // Save callee-saved registers
+    stp x19, x20, [sp, #-16]!
+
+    // Your original code starts here
+    mov x19, x0         // entry (x0 is the first argument)
+    mov x9, x1          // _tos (x1 is the second argument)
+    mov x20, x2         // argc (x2 is the third argument)
+    mov x21, x3         // argv (x3 is the fourth argument)
+
+    // Push argv onto stack
+    mov x10, x20        // x10 = argc
+    add x10, x10, #1    // x10 = argc + 1
+    lsl x10, x10, #3    // x10 = (argc + 1) * 8
+    sub sp, sp, x10     // Allocate space on stack
+    
+    // Ensure 16-byte stack alignment
+    and x11, x10, #15   // Get the misalignment amount
+    sub sp, sp, x11     // Adjust stack to ensure alignment
+
+    mov x0, sp          // x0 = new stack pointer (destination for memcpy)
+    mov x1, x21         // x1 = argv (source for memcpy)
+    mov x2, x10         // x2 = number of bytes to copy
+    bl _memcpy
+
+    // Push argc onto stack (after the argv data)
+    str x20, [sp, x10]
+
+    // Call the entry point
+    blr x19
+
+    // Restore stack pointer
+    mov sp, x29
+
+    // Restore callee-saved registers
+    ldp x19, x20, [sp], #16
+
+    // Function epilogue
+    ldp x29, x30, [sp], #16
+
+    ret
\ No newline at end of file