shithub: riscv

Download patch

ref: 717237303d368378283ad719ee4f2c580b99fd2b
parent: 09f2ec3bbc9aeb432f4f2be3056ac0dfa74039ac
author: Jacob Moody <[email protected]>
date: Thu Feb 8 13:34:34 EST 2024

/sys/src/cmd/?i: correct memory access

Syscall handlers were not converting long's to
vlong's in a portable manner, failing on little endian.

Segments were not created w.r.t. segment allignment, which
now differs from the page size on mips and power. DATA reads
need to then also allow for accessing data between the end of
the defined DATA segment from the source text, and the end of
the segment.

--- a/sys/src/cmd/ki/ki.c
+++ b/sys/src/cmd/ki/ki.c
@@ -51,6 +51,8 @@
 	cmd();
 }
 
+#define SEGROUND mach->pgsize
+
 void
 initmap(void)
 {
@@ -58,10 +60,10 @@
 	ulong t, d, b, bssend;
 	Segment *s;
 
-	t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
-	d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
+	t = (fhdr.txtaddr+fhdr.txtsz+(SEGROUND-1)) & ~(SEGROUND-1);
+	d = (t + fhdr.datsz + (SEGROUND-1)) & ~(SEGROUND-1);
 	bssend = t + fhdr.datsz + fhdr.bsssz;
-	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
+	b = (bssend + (SEGROUND-1)) & ~(SEGROUND-1);
 
 	s = &memory.seg[Text];
 	s->type = Text;
--- a/sys/src/cmd/ki/mem.c
+++ b/sys/src/cmd/ki/mem.c
@@ -51,6 +51,12 @@
 	return val;
 }
 
+uvlong
+getmem_v(ulong addr)
+{
+	return ((uvlong)getmem_w(addr) << 32) | getmem_w(addr+4);
+}
+
 ulong
 getmem_w(ulong addr)
 {
@@ -101,6 +107,13 @@
 }
 
 void
+putmem_v(ulong addr, uvlong data)
+{
+	putmem_w(addr, data>>32);
+	putmem_w(addr+4, data);
+}
+
+void
 putmem_w(ulong addr, ulong data)
 {
 	uchar *va;
@@ -208,17 +221,17 @@
 				fatal(0, "vaddr");
 			case Text:
 				*p = emalloc(BY2PG);
-				if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
-					fatal(1, "vaddr text seek");
-				if(read(text, *p, BY2PG) < 0)
+				if(pread(text, *p, BY2PG, s->fileoff+off*BY2PG) < 0)
 					fatal(1, "vaddr text read");
 				return *p;
 			case Data:
 				*p = emalloc(BY2PG);
 				foff = s->fileoff+(off*BY2PG);
-				if(seek(text, foff, 0) < 0)
-					fatal(1, "vaddr text seek");
-				n = read(text, *p, BY2PG);
+				if(foff >= s->fileend){
+					memset(*p, 0, BY2PG);
+					return *p;
+				}
+				n = pread(text, *p, BY2PG, foff);
 				if(n < 0)
 					fatal(1, "vaddr text read");
 				if(foff + n > s->fileend) {
--- a/sys/src/cmd/ki/sparc.h
+++ b/sys/src/cmd/ki/sparc.h
@@ -155,6 +155,8 @@
 ulong		getmem_4(ulong);
 ulong		getmem_2(ulong);
 void		putmem_h(ulong, short);
+void		putmem_v(ulong, uvlong);
+uvlong		getmem_v(ulong);
 Mul		mul(long, long);
 Mulu		mulu(ulong, ulong);
 void		isum(void);
--- a/sys/src/cmd/ki/syscall.c
+++ b/sys/src/cmd/ki/syscall.c
@@ -296,14 +296,7 @@
 void
 syspread(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	sysread(o.v);
+	sysread(getmem_v(reg.r[REGSP]+16));
 }
 
 void
@@ -312,24 +305,20 @@
 	int fd;
 	ulong mode;
 	ulong retp;
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
+	vlong v;
 
 	retp = getmem_w(reg.r[REGSP]+4);
 	fd = getmem_w(reg.r[REGSP]+8);
-	o.u[0] = getmem_w(reg.r[REGSP]+12);
-	o.u[1] = getmem_w(reg.r[REGSP]+16);
+	v = getmem_v(reg.r[REGSP]+12);
 	mode = getmem_w(reg.r[REGSP]+20);
 	if(sysdbg)
-		itrace("seek(%d, %lld, %d)", fd, o.v, mode);
+		itrace("seek(%d, %lld, %d)", fd, v, mode);
 
-	o.v = seek(fd, o.v, mode);
-	if(o.v < 0)
-		errstr(errbuf, sizeof errbuf);	
+	v = seek(fd, v, mode);
+	if(v < 0)
+		errstr(errbuf, sizeof errbuf);
 
-	memio((char*)o.u, retp, sizeof(vlong), MemWrite);
+	putmem_v(retp, v);
 }
 
 void
@@ -514,14 +503,7 @@
 void
 syspwrite(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	syswrite(o.v);
+	syswrite(getmem_v(reg.r[REGSP]+16));
 }
 
 void
--- a/sys/src/cmd/qi/mem.c
+++ b/sys/src/cmd/qi/mem.c
@@ -239,17 +239,17 @@
 				fatal(0, "vaddr");
 			case Text:
 				*p = emalloc(BY2PG);
-				if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
-					fatal(1, "vaddr text seek");
-				if(read(text, *p, BY2PG) < 0)
+				if(pread(text, *p, BY2PG, s->fileoff+off*BY2PG) < 0)
 					fatal(1, "vaddr text read");
 				return *p;
 			case Data:
 				*p = emalloc(BY2PG);
 				foff = s->fileoff+(off*BY2PG);
-				if(seek(text, foff, 0) < 0)
-					fatal(1, "vaddr text seek");
-				n = read(text, *p, BY2PG);
+				if(foff >= s->fileend){
+					memset(*p, 0, BY2PG);
+					return *p;
+				}
+				n = pread(text, *p, BY2PG, foff);
 				if(n < 0)
 					fatal(1, "vaddr text read");
 				if(foff + n > s->fileend) {
--- a/sys/src/cmd/qi/power.h
+++ b/sys/src/cmd/qi/power.h
@@ -150,10 +150,10 @@
 void		putmem_w(ulong, ulong);
 uchar		getmem_b(ulong);
 void		putmem_b(ulong, uchar);
-uvlong	getmem_v(ulong);
+uvlong		getmem_v(ulong);
 ulong		getmem_4(ulong);
 ulong		getmem_2(ulong);
-void	putmem_v(ulong, uvlong);
+void		putmem_v(ulong, uvlong);
 void		putmem_h(ulong, short);
 void		isum(void);
 void		initicache(void);
--- a/sys/src/cmd/qi/syscall.c
+++ b/sys/src/cmd/qi/syscall.c
@@ -306,14 +306,7 @@
 void
 syspread(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	sysread(o.v);
+	sysread(getmem_v(reg.r[REGSP]+16));
 }
 
 void
@@ -322,24 +315,20 @@
 	int fd;
 	ulong mode;
 	ulong retp;
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
+	vlong v;
 
 	retp = getmem_w(reg.r[REGSP]+4);
 	fd = getmem_w(reg.r[REGSP]+8);
-	o.u[0] = getmem_w(reg.r[REGSP]+12);
-	o.u[1] = getmem_w(reg.r[REGSP]+16);
+	v = getmem_v(reg.r[REGSP]+12);
 	mode = getmem_w(reg.r[REGSP]+20);
 	if(sysdbg)
-		itrace("seek(%d, %lld, %d)", fd, o.v, mode);
+		itrace("seek(%d, %lld, %d)", fd, v, mode);
 
-	o.v = seek(fd, o.v, mode);
-	if(o.v < 0)
-		errstr(errbuf, sizeof errbuf);	
+	v = seek(fd, v, mode);
+	if(v < 0)
+		errstr(errbuf, sizeof errbuf);
 
-	memio((char*)o.u, retp, sizeof(vlong), MemWrite);
+	putmem_v(retp, v);
 }
 
 void
@@ -524,14 +513,7 @@
 void
 syspwrite(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	syswrite(o.v);
+	syswrite(getmem_v(reg.r[REGSP]+16));
 }
 
 void
--- a/sys/src/cmd/vi/mem.c
+++ b/sys/src/cmd/vi/mem.c
@@ -51,6 +51,12 @@
 	return val;
 }
 
+uvlong
+getmem_v(ulong addr)
+{
+	return ((uvlong)getmem_w(addr) << 32) | getmem_w(addr+4);
+}
+
 ulong
 getmem_w(ulong addr)
 {
@@ -101,6 +107,13 @@
 }
 
 void
+putmem_v(ulong addr, uvlong data)
+{
+	putmem_w(addr, data>>32);
+	putmem_w(addr+4, data);
+}
+
+void
 putmem_w(ulong addr, ulong data)
 {
 	uchar *va;
@@ -229,17 +242,17 @@
 				fatal(0, "vaddr");
 			case Text:
 				*p = emalloc(BY2PG);
-				if(seek(text, s->fileoff+(off*BY2PG), 0) < 0)
-					fatal(1, "vaddr text seek");
-				if(read(text, *p, BY2PG) < 0)
+				if(pread(text, *p, BY2PG, s->fileoff+off*BY2PG) < 0)
 					fatal(1, "vaddr text read");
 				return *p;
 			case Data:
 				*p = emalloc(BY2PG);
 				foff = s->fileoff+(off*BY2PG);
-				if(seek(text, foff, 0) < 0)
-					fatal(1, "vaddr text seek");
-				n = read(text, *p, BY2PG);
+				if(foff >= s->fileend){
+					memset(*p, 0, BY2PG);
+					return *p;
+				}
+				n = pread(text, *p, BY2PG, foff);
 				if(n < 0)
 					fatal(1, "vaddr text read");
 				if(foff + n > s->fileend) {
--- a/sys/src/cmd/vi/mips.h
+++ b/sys/src/cmd/vi/mips.h
@@ -174,6 +174,8 @@
 ulong		getmem_4(ulong);
 ulong		getmem_2(ulong);
 void		putmem_h(ulong, short);
+void		putmem_v(ulong, uvlong);
+uvlong		getmem_v(ulong);
 Mul		mul(long, long);
 Mulu		mulu(ulong, ulong);
 void		isum(void);
--- a/sys/src/cmd/vi/syscall.c
+++ b/sys/src/cmd/vi/syscall.c
@@ -297,14 +297,7 @@
 void
 syspread(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	sysread(o.v);
+	sysread(getmem_v(reg.r[REGSP]+16));
 }
 
 void
@@ -313,24 +306,20 @@
 	int fd;
 	ulong mode;
 	ulong retp;
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
+	vlong v;
 
 	retp = getmem_w(reg.r[REGSP]+4);
 	fd = getmem_w(reg.r[REGSP]+8);
-	o.u[0] = getmem_w(reg.r[REGSP]+12);
-	o.u[1] = getmem_w(reg.r[REGSP]+16);
+	v = getmem_v(reg.r[REGSP]+12);
 	mode = getmem_w(reg.r[REGSP]+20);
 	if(sysdbg)
-		itrace("seek(%d, %lld, %d)", fd, o.v, mode);
+		itrace("seek(%d, %lld, %d)", fd, v, mode);
 
-	o.v = seek(fd, o.v, mode);
-	if(o.v < 0)
-		errstr(errbuf, sizeof errbuf);	
+	v = seek(fd, v, mode);
+	if(v < 0)
+		errstr(errbuf, sizeof errbuf);
 
-	memio((char*)o.u, retp, sizeof(vlong), MemWrite);
+	putmem_v(retp, v);
 }
 
 void
@@ -515,14 +504,7 @@
 void
 syspwrite(void)
 {
-	union {
-		vlong v;
-		ulong u[2];
-	} o;
-
-	o.u[0] = getmem_w(reg.r[REGSP]+16);
-	o.u[1] = getmem_w(reg.r[REGSP]+20);
-	syswrite(o.v);
+	syswrite(getmem_v(reg.r[REGSP]+16));
 }
 
 void
--- a/sys/src/cmd/vi/vi.c
+++ b/sys/src/cmd/vi/vi.c
@@ -58,6 +58,8 @@
 	cmd();
 }
 
+#define SEGROUND mach->pgsize
+
 void
 initmap()
 {
@@ -64,10 +66,10 @@
 	ulong t, d, b, bssend;
 	Segment *s;
 
-	t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
-	d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
+	t = (fhdr.txtaddr+fhdr.txtsz+(SEGROUND-1)) & ~(SEGROUND-1);
+	d = (t + fhdr.datsz + (SEGROUND-1)) & ~(SEGROUND-1);
 	bssend = t + fhdr.datsz + fhdr.bsssz;
-	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
+	b = (bssend + (SEGROUND-1)) & ~(SEGROUND-1);
 
 	s = &memory.seg[Text];
 	s->type = Text;