ref: 717237303d368378283ad719ee4f2c580b99fd2b
parent: 09f2ec3bbc9aeb432f4f2be3056ac0dfa74039ac
author: Jacob Moody <moody@posixcafe.org>
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;