ref: 6994c1f22746af217fb4226dd6be7ddd74622bf8
parent: 5afb6d1c1439fa549ba8bb3586c51178faef8022
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;
--
⑨