ref: 808dd0b3d75a5c3eadd1da5c1b57bf550dccb30b
parent: f9198297ea2bc1c3971f5b3fd473e45a8fb0d10c
author: Ori Bernstein <[email protected]>
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