shithub: 5v

Download patch

ref: 808dd0b3d75a5c3eadd1da5c1b57bf550dccb30b
parent: f9198297ea2bc1c3971f5b3fd473e45a8fb0d10c
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Aug 29 03:04:20 EDT 2023

5v: fix bugs

--- a/5e.c
+++ b/5e.c
@@ -7,7 +7,7 @@
 int vfp = 1;
 int nflag, pflag, bflag;
 int check;
-u32int mallocaddr, freeaddr, reallocaddr;
+u32int mallocaddr, freeaddr, reallocaddr, vtraceaddr;
 Ref nproc;
 
 void
@@ -121,13 +121,14 @@
 	atexit(cleanup);
 	if(!nflag)
 		adjustns();
-	if(pflag)
+	if(pflag || check)
 		initfs("armproc", "/proc");
 	initproc();
 	dotext(argc, argv);
 	atnotify(notehandler, 1);
 	for(;;) {
-		if(ultraverbose)
+extern int vtrace;
+		if(ultraverbose || vtrace)
 			dump();
 		step();
 		while((P->notein - P->noteout) % NNOTE) {
--- a/arm.c
+++ b/arm.c
@@ -19,11 +19,16 @@
 	fH = 1<<5,
 };
 
+int vtrace;
+
 static u32int
 arg(int n)
 {
 	/* no locking necessary, since we're on the stack */
-	return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
+	if(n == 0)
+		return P->R[0];
+	else
+		return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
 }
 
 static u32int
@@ -320,9 +325,9 @@
 				P->hookfn = hookmalloc;
 				P->hookpc = P->R[15];
 			}else if(npc == reallocaddr){
-				P->hookarg[0] = arg(1);	/* old */
+				P->hookarg[0] = arg(1);		/* old */
 				P->hookarg[1] = asize(1);	/* oldsz */
-				P->hookarg[2] = arg(2);	/* size */
+				P->hookarg[2] = arg(2);		/* newsz */
 				P->hookfn = hookrealloc;
 				P->hookpc = P->R[15];
 			}else if(npc == freeaddr){
@@ -330,6 +335,8 @@
 				P->hookarg[1] = asize(1);
 				P->hookfn = hookfree;
 				P->hookpc = P->R[15];
+			}else if(npc == vtraceaddr){
+				vtrace = arg(0);
 			}
 		}
 	}
@@ -549,7 +556,7 @@
 
 	instr = *(u32int*) vaddr(P->R[15], 4, 0, &seg);
 	segunlock(seg);
-	if(fulltrace) {
+	if(fulltrace || vtrace) {
 		print("%d ", P->pid);
 		if(havesymbols) {
 			Symbol s;
@@ -567,7 +574,6 @@
 			(P->CPSR & flV) ? 'V' : ' '
 			);
 	}
-print("hookpc=%#ux\n", P->hookpc);
 	if(P->R[15] == P->hookpc){
 		P->hookfn(P->hookarg);
 		P->hookpc = 0;
--- a/chk.c
+++ b/chk.c
@@ -5,7 +5,33 @@
 #include <mach.h>
 #include "dat.h"
 #include "fns.h"
+extern int vtrace;
 
+void
+dumpmap(Segment *seg, u32int off, char *fmt, ...)
+{
+	char buf[16*1024], *p, *e;
+	va_list ap;
+	int i;
+
+	p = buf;
+	e = p + sizeof(buf)-1;
+	va_start(ap, fmt);
+	p = vseprint(p, e, fmt, ap);
+	va_end(ap);
+	if(seg->shadow == nil){
+		print("not tracing\n");
+		return;
+	}
+	for(i = (off&~0x4095)/8; i < (seg->size + 7)/8; i++){
+		if(i % 40 == 0)
+			p = seprint(p, e, "\n[%04x] ", seg->start+i*8);
+		p = seprint(p, e, "%02ux", seg->shadow[i]);
+	}
+	*p++ = '\n';
+	write(1, buf, p - buf);
+}
+
 static u32int
 arg(int n)
 {
@@ -14,8 +40,9 @@
 }
 
 void
-validmem(Segment *s, u32int off, u32int len)
+validmem(Segment *seg, u32int off, u32int len)
 {
+	static int never;
 	u32int end;
 
 	/*
@@ -26,33 +53,23 @@
 	if(P->hookpc != 0)
 		return;
 	for(end = off+len; off != end; off++){
-		if((s->shadow[off>>3] & 1<<(off&3)) == 0){
-			print("invalid read of %#x at %#x\n", off, P->R[15] - 4);
-			abort();
+		if((seg->shadow[off>>3] & 1<<(off&7)) == 0){
+			print("invalid read of %#x at %#x\n", seg->start+off, P->R[15] - 4);
+dumpmap(seg, off, "broken");
+			rendezvous(&never, nil);
+			exits("bad access");
 		}
 	}
 }
-
 void
-dumpmap(Segment *seg)
+markvalid(Segment *seg, u32int off, u32int len)
 {
-	int i;
-
-	for(i = 0; i < (seg->size + 7)/8; i++){
-		if(i % 40 == 0)
-			print("\n[%04x] ", seg->start+i*8);
-		print("%02ux", seg->shadow[i]);
-	}
-	print("\n");
-}
-
-void
-markvalid(Segment *s, u32int off, u32int len)
-{
 	u32int end;
 
+//print("seg: %#p\n", seg);
+//print("mark[shadow=%#p] %#x+%x [%#x+%#x]\n", seg->shadow, seg->start + off, len, seg->start, off);
 	for(end = off+len; off != end; off++)
-		s->shadow[off>>3] |= (1<<(off&3));
+		seg->shadow[off>>3] |= (1<<(off&7));
 }
 
 void
@@ -61,7 +78,7 @@
 	u32int end;
 
 	for(end = off+len; off != end; off++)
-		s->shadow[off>>3] &= ~(1<<(off&3));
+		s->shadow[off>>3] &= ~(1<<(off&7));
 }
 
 void
@@ -70,11 +87,12 @@
 	Segment *seg;
 	uchar *p;
 
-	print("malloced %#x+%d\n", P->R[0], av[0]);
 	p = vaddr(P->R[0], 0, 0, &seg);
-	dumpmap(seg);
+	if(mallocverbose)
+		dumpmap(seg, p-(uchar*)seg->start, "malloced %#x+%d\n", P->R[0], av[0]);
 	markinvalid(seg, p - (uchar*)seg->data, av[0]);
-	dumpmap(seg);
+	if(mallocverbose)
+		dumpmap(seg, p-(uchar*)seg->start, "postmalloc");
 }
 
 
@@ -81,14 +99,26 @@
 void
 hookrealloc(u32int *av)
 {
+	uchar *oldp, *newp;
+	u32int oldsz, newsz, sz;
+	u32int oldoff, newoff;
 	Segment *seg;
-	uchar *p;
 
-	print("malloced %#x+%d => %#x+%d\n", av[0], av[1], P->R[0], av[2]);
-	p = vaddr(av[0], 0, 0, &seg);
-	markinvalid(seg, p - (uchar*)seg->data, av[1]);
-	p = vaddr(P->R[0], 0, 0, &seg);
-	markinvalid(seg, p - (uchar*)seg->data, av[2]);
+	oldp = vaddr(av[0], 0, 0, &seg);
+	newp = vaddr(P->R[0], 0, 0, &seg);
+	oldsz = av[1];
+	newsz = av[2];
+	oldoff = oldp - (uchar*)seg->data;
+	newoff = newp - (uchar*)seg->data;
+	sz = (oldsz < newsz) ? oldsz : newsz;
+	if(mallocverbose)
+		dumpmap(seg, oldp-(uchar*)seg->start, "realloc %#x+%d => %#x+%d\n", av[0], av[1], P->R[0], av[2]);
+	if(oldp != newp)
+		memcpy(seg->shadow+oldoff/8, seg->shadow+newoff/8, (sz+7)/8);
+	if(newsz > oldsz)
+		markinvalid(seg, oldoff+oldsz, newsz-oldsz);
+	if(mallocverbose)
+		dumpmap(seg, newp-(uchar*)seg->start, "postrealloc");
 }
 
 void
@@ -97,9 +127,10 @@
 	Segment *seg;
 	uchar *p;
 
-	print("freed %#x+%d\n", av[0], av[1]);
 	p = vaddr(av[0], 0, 0, &seg);
-	dumpmap(seg);
+	if(mallocverbose)
+		dumpmap(seg, p-(uchar*)seg->start, "free %#x+%d\n", av[0], av[1]);
 	markinvalid(seg, p - (uchar*)seg->data, av[1]);
-	dumpmap(seg);
+	if(mallocverbose)
+		dumpmap(seg, p-(uchar*)seg->start, "postfree");
 }
--- a/dat.h
+++ b/dat.h
@@ -70,7 +70,10 @@
 extern Process plist;
 extern Lock plistlock;
 extern int check;
-u32int mallocaddr, freeaddr, reallocaddr;
+u32int mallocaddr;
+u32int freeaddr;
+u32int reallocaddr;
+u32int vtraceaddr;
 
 enum {
 	SEGFLLOCK = 1,
@@ -93,7 +96,8 @@
 	int nfds;
 };
 
-#define fulltrace 1
+#define fulltrace 0
 #define havesymbols 1
 #define ultraverbose 0
+#define mallocverbose 1
 #define systrace 0
--- a/fns.h
+++ b/fns.h
@@ -31,6 +31,7 @@
 void donote(char *, ulong);
 void addnote(char *);
 void dump(void);
+void dumpmap(Segment *, u32int, char *, ...);
 void resetfpa(void);
 void invalid(u32int);
 u32int evenaddr(u32int,u32int);
--- a/proc.c
+++ b/proc.c
@@ -212,7 +212,10 @@
 		freeaddr = -1;
 	else
 		freeaddr = s.value;
-print("malloc: %#x, realloc: %#x, free %#x\n", mallocaddr, reallocaddr, freeaddr);
+	if(lookup("vtrace", nil, &s) == -1)
+		vtraceaddr = -1;
+	else
+		vtraceaddr = s.value;
 }
 
 int
@@ -399,6 +402,7 @@
 void
 donote(char *msg, ulong type)
 {
+extern int vtrace;
 	int rc;
 	u32int *ureg, *sp, uregp, msgp;
 	char *msgb;
@@ -427,7 +431,7 @@
 	switch(rc = setjmp(P->notejmp) - 1) {
 	case -1:
 		for(;;) {
-			if(ultraverbose)
+			if(ultraverbose || vtrace)
 				dump();
 			step();
 		}
--- a/seg.c
+++ b/seg.c
@@ -18,7 +18,7 @@
 	incref(s->dref);
 	s->data = s->dref + 1;
 	if(check)
-		s->shadow = emalloc((size+7)/8);
+		s->shadow = emallocz((size+7)/8);
 	if(idx == SEGBSS)
 		s->flags = SEGFLLOCK;
 	P->S[idx] = s;
@@ -65,6 +65,7 @@
 			return (char *)s->data + off;
 		}
 	}
+	abort();
 	suicide("fault %.8ux (%d) @ %.8ux", addr, len, P->R[15]);
 	return nil;
 }
--- a/sys.c
+++ b/sys.c
@@ -12,13 +12,6 @@
 	return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4, ARD);
 }
 
-static u32int
-args(int n, Segment **s)
-{
-	/* no locking necessary, since we're on the stack */
-	return *(u32int*) vaddr(P->R[13] + 4 + 4 * n, 4, ARD, s);
-}
-
 static u64int
 argv(int n)
 {
@@ -96,7 +89,7 @@
 	void *targ;
 	Segment *seg;
 	
-	fd = args(0, &seg);
+	fd = arg(0);
 	buf = arg(1);
 	size = arg(2);
 	off = argv(3);
@@ -106,8 +99,10 @@
 	P->R[0] = noteerr(pread(fd, targ, size, off), size);
 	if(buffered)
 		copyback(buf, P->R[0], targ);
-	if(check)
+	if(check && (s32int)P->R[0] > 0){
+		vaddr(buf, 0, 0, &seg);
 		markvalid(seg, buf-seg->start, P->R[0]);
+	}
 }
 
 static void
@@ -173,6 +168,7 @@
 	char *namet;
 	void *edirt;
 	int copied, buffered;
+	Segment *seg;
 	
 	name = arg(0);
 	namet = copyifnec(name, -1, &copied);
@@ -186,6 +182,10 @@
 		free(namet);
 	if(buffered)
 		copyback(edir, P->R[0], edirt);
+	if(check && (s32int)P->R[0] > 0){
+		vaddr(edir, 0, 0, &seg);
+		markvalid(seg, edir-seg->start, P->R[0]);
+	}
 }
 
 static void
@@ -194,6 +194,7 @@
 	u32int fd, edir, nedir;
 	void *edirt;
 	int buffered;
+	Segment *seg;
 	
 	fd = arg(0);
 	edir = arg(1);
@@ -204,6 +205,10 @@
 	P->R[0] = noteerr(fstat(fd, edirt, nedir), nedir);
 	if(buffered)
 		copyback(edir, P->R[0], edirt);
+	if(check && (s32int)P->R[0] > 0){
+		vaddr(edir, 0, 0, &seg);
+		markvalid(seg, edir-seg->start, P->R[0]);
+	}
 }
 
 static void