ref: 76acae031bbc63582596374842056452c6062772
parent: bc67178c247505d72696611797c6a3879dce84fd
author: 9ferno <gophone2015@gmail.com>
date: Wed Dec 29 06:31:03 EST 2021
fixed stack leak in forth bindings
--- a/libinterp/load.c
+++ b/libinterp/load.c
@@ -4,7 +4,7 @@
#include "raise.h"
#include <kernel.h>
-#define DP if(1){}else print
+#define DP if(0){}else print
#define DNP if(1){}else print
#define A(r) *((Array**)(r))
@@ -136,22 +136,22 @@
int c;
USED(offset);
- DP("\tstring\t@mp+%zd=0x%p,len %d at 0x%p:\"", offset, absoluteoffset, len, stored);
+ DNP("\tstring\t@mp+%zd=0x%p,len %d at 0x%p:\"", offset, absoluteoffset, len, stored);
se = s + len;
for(; s < se; s++){
c = *s;
if(c == '\n')
- DP("\\n");
+ DNP("\\n");
else if(c == '\0')
- DP("\\z");
+ DNP("\\z");
else if(c == '"')
- DP("\\\"");
+ DNP("\\\"");
else if(c == '\\')
- DP("\\\\");
+ DNP("\\\\");
else
- DP("%c", c);
+ DNP("%c", c);
}
- DP("\"\n");
+ DNP("\"\n");
}
Module*
@@ -171,7 +171,7 @@
Link *l;
intptr i, n, v, pc, entry, entryt;
- DP("\tsource\t\"%s\"\n", path);
+ DNP("\tsource\t\"%s\"\n", path);
istream = code;
isp = &istream;
@@ -225,7 +225,7 @@
goto bad;
}
- DP("parsemod before instructions isize %d dsize %d hsize %d"
+ DNP("parsemod before instructions isize %d dsize %d hsize %d"
" lsize %d entry 0x%zx entryt 0x%zx sizeof(Inst) %d\n",
isize, dsize, hsize, lsize, entry, entryt, sizeof(Inst));
m->nprog = isize;
@@ -281,12 +281,12 @@
break;
}
if(i % 10 == 0)
- DP("#%p\n", ip);
- DP(" %d %zd %D\n", i, (intptr)ip, ip);
+ DNP("#%p\n", ip);
+ DNP(" %d %zd %D\n", i, (intptr)ip, ip);
ip++;
}
- DP("\tentry\t0,%d\n",hsize);
+ DNP("\tentry\t0,%d\n",hsize);
m->ntype = hsize;
m->type = malloc(hsize*sizeof(Type*));
if(m->type == nil) {
@@ -310,11 +310,11 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\tdesc\t$%d 0x%p has 0x%p of size %d nptrs %d:\"",
+ DNP("\tdesc\t$%d 0x%p has 0x%p of size %d nptrs %d:\"",
id, m->type+id, pt, tsz, tnp);
for(e = istream; e < istream+tnp; e++)
- DP("%.2x", *e);
- DP("\"\n");
+ DNP("%.2x", *e);
+ DNP("\"\n");
istream += tnp;
m->type[id] = pt;
}
@@ -327,12 +327,12 @@
}
h = heapz(pt);
m->origmp = H2D(uchar*, h);
- DP("\tm->origmp 0x%p belongs to heap at 0x%p, uses type at 0x%p\n",
+ DNP("\tm->origmp 0x%p belongs to heap at 0x%p, uses type at 0x%p\n",
m->origmp, h, pt);
}
addr = m->origmp;
dasp = 0;
- DP("\tvar\t@mp, size %d\n", dsize);
+ DNP("\tvar\t@mp, size %d\n", dsize);
for(;;) {
sm = *istream++;
if(sm == 0)
@@ -353,62 +353,62 @@
*(String**)si = s;
break;
case DEFB:
- DP("\tbyte\t@mp+%d", v);
+ DNP("\tbyte\t@mp+%d", v);
for(i = 0; i < n; i++){
- DP(",%d", *istream & 0xff);
+ DNP(",%d", *istream & 0xff);
*si++ = *istream++;
}
- DP(" n=%d\n", n);
+ DNP(" n=%d\n", n);
break;
case DEFW:
- DP("\tword\t@mp+%d len %d:", v, n);
+ DNP("\tword\t@mp+%d len %d:", v, n);
for(i = 0; i < n; i++) {
*(WORD*)si = disw(isp);
- DP(" 0x%zx", *(WORD*)si);
+ DNP(" 0x%zx", *(WORD*)si);
si += sizeof(WORD);
}
- DP("\n");
+ DNP("\n");
break;
case DEFL:
- DP("\tlong\t@mp+%d", v);
+ DNP("\tlong\t@mp+%d", v);
for(i = 0; i < n; i++) {
hi = disw(isp);
lo = disw(isp);
*(LONG*)si = (LONG)hi << 32 | (LONG)(u32)lo;
- DP(",%lld 0x%zx", *(LONG*)si, *(LONG*)si);
+ DNP(",%lld 0x%zx", *(LONG*)si, *(LONG*)si);
si += sizeof(LONG);
}
- DP("\n");
+ DNP("\n");
break;
case DEFF:
- DP("\treal\t@mp+%d", v);
+ DNP("\treal\t@mp+%d", v);
for(i = 0; i < n; i++) {
- DP(" raw: ");
+ DNP(" raw: ");
for(int j = 0; j<8; j++){
- DP(" 0x%x", ((u8*)isp)[j]);
+ DNP(" 0x%x", ((u8*)isp)[j]);
}
ul[0] = disw(isp);
ul[1] = disw(isp);
/*print("canontod ul[0] 0x%x ul[1] 0x%x ", ul[0], ul[1]);*/
*(REAL*)si = canontod(ul);
- /*DP("__");
- DP(",%g", *(REAL*)si);
- DP("--");*/
+ /*DNP("__");
+ DNP(",%g", *(REAL*)si);
+ DNP("--");*/
si += sizeof(REAL);
}
- DP("\n");
+ DNP("\n");
break;
case DEFA: /* Array */
- DP("\tarray\t@mp+%d", v);
+ DNP("\tarray\t@mp+%d", v);
v = disw(isp);
if(v < 0 || v > m->ntype) {
kwerrstr("bad array type");
goto bad;
}
- DP(",$%d", v);
+ DNP(",$%d", v);
pt = m->type[v];
v = disw(isp);
- DP(",%d", v);
+ DNP(",%d", v);
h = nheap(sizeof(Array)+(pt->size*v));
h->t = &Tarray;
h->t->ref++;
@@ -421,9 +421,9 @@
for(i=(intptr)ary->data;
i < v;
i++){
- DP(",%d",*(uchar*)(i+ary));
+ DNP(",%d",*(uchar*)(i+ary));
}
- DP("\n");
+ DNP("\n");
initarray(pt, ary);
A(si) = ary;
break;
@@ -433,7 +433,7 @@
kwerrstr("ind not array");
goto bad;
}
- DP("\tindir\t@mp+%d", v);
+ DNP("\tindir\t@mp+%d", v);
v = disw(isp);
if(v > ary->len || v < 0 || dasp >= DADEPTH) {
kwerrstr("array init range");
@@ -441,7 +441,7 @@
}
dastack[dasp++] = addr;
addr = ary->data+v*ary->t->size;
- DP(",%d,%zd 0x%zx\n",
+ DNP(",%d,%zd 0x%zx\n",
v, (intptr)ary->data+v*ary->t->size,
(intptr)ary->data+v*ary->t->size);
break;
@@ -450,14 +450,14 @@
kwerrstr("pop range");
goto bad;
}
- DP("\tapop\n");
+ DNP("\tapop\n");
addr = dastack[--dasp];
break;
}
}
- /*DP(" Initialized origmp\n");
+ /*DNP(" Initialized origmp\n");
for(int i = 0; i < m->type[0]->size/(sizeof(intptr)); i++){
- DP("\t\t0x%p\t%zx\n", (intptr*)m->origmp+i, *((intptr*) m->origmp+i));
+ DNP("\t\t0x%p\t%zx\n", (intptr*)m->origmp+i, *((intptr*) m->origmp+i));
}*/
mod = istream;
if(memchr(mod, 0, 128) == 0) {
@@ -469,7 +469,7 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\tmodule\t%s\n", m->name);
+ DNP("\tmodule\t%s\n", m->name);
while(*istream++)
;
@@ -487,18 +487,18 @@
pt = m->type[de];
mlink(m, l, istream, v, pc, pt);
if(de != -1){
- DP("\tlink\tidx %d, type %d size %d np %d ",
+ DNP("\tlink\tidx %d, type %d size %d np %d ",
i, de, pt->size, pt->np);
if(pt->np > 0){
- DP("map");
+ DNP("map");
for(b = pt->map; b < pt->map+pt->np; b++)
- DP(" %.2x", *b);
- DP(" ");
+ DNP(" %.2x", *b);
+ DNP(" ");
}
- DP(", pc %zd, sig 0x%ux,\"%s\"\n",
+ DNP(", pc %zd, sig 0x%ux,\"%s\"\n",
pc, v, (char*)istream);
}else
- DP("\tlink\tidx %d type %d, pc %zd, sig 0x%ux,\"%s\"\n",
+ DNP("\tlink\tidx %d type %d, pc %zd, sig 0x%ux,\"%s\"\n",
i, de, pc, v, (char*)istream);
while(*istream++)
;
@@ -520,10 +520,10 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\tldts\t@ldt,%d\n", nl);
+ DNP("\tldts\t@ldt,%d\n", nl);
for(i = 0; i < nl; i++, i2++){
n = operand(isp);
- DP("\text\t@ldts+%d,%d,%zd\n",
+ DNP("\text\t@ldts+%d,%d,%zd\n",
i, n, (intptr)i2-(intptr)m->ldt);
i1 = *i2 = (Import*)malloc((n+1)*sizeof(Import));
if(i1 == nil){
@@ -537,7 +537,7 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\text\t@ldt+%zd,idx %d, sig 0x%ux,\"%s\"\n",
+ DNP("\text\t@ldt+%zd,idx %d, sig 0x%ux,\"%s\"\n",
(intptr)i1-(intptr)m->ldt,
j, i1->sig, (char*)istream);
while(*istream++)
@@ -558,7 +558,7 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\texceptions\t%d\n", nh);
+ DNP("\texceptions\t%d\n", nh);
h = m->htab;
for(i = 0; i < nh; i++, h++){
h->eoff = operand(isp);
@@ -576,7 +576,7 @@
goto bad;
}
e = h->etab;
- DP("\texception\t%d: offset %zd pc1 %zd pc2 %zd"
+ DNP("\texception\t%d: offset %zd pc1 %zd pc2 %zd"
" desc %d nlab %d ne %zd\n",
i, h->eoff, h->pc1, h->pc2,
descid, n, h->ne);
@@ -589,11 +589,11 @@
while(*istream++)
;
e->pc = operand(isp);
- DP("\texctab\t\"%s\", %zd\n", e->s, e->pc);
+ DNP("\texctab\t\"%s\", %zd\n", e->s, e->pc);
}
e->s = nil;
e->pc = operand(isp);
- DP("\texctab\t*, %zd\n", e->pc);
+ DNP("\texctab\t*, %zd\n", e->pc);
}
istream++;
}
@@ -622,7 +622,7 @@
kwerrstr(exNomem);
goto bad;
}
- DP("\tsource\t\"%s\"\n", m->path);
+ DNP("\tsource\t\"%s\"\n", m->path);
m->link = modules;
modules = m;
--- a/os/pc64/bindings.s
+++ b/os/pc64/bindings.s
@@ -97,6 +97,7 @@
CALL kopen(SB)
MOVQ 16(SP), UP
C_TO_F_1
+ ADDQ $24, SP
NEXT
TEXT fthclose(SB), 1, $16 /* ( fd -- n ) */
@@ -105,6 +106,7 @@
CALL kclose(SB)
MOVQ 24(SP), UP
C_TO_F_1
+ ADDQ $16, SP
NEXT
TEXT fthread(SB), 1, $32 /* ( n a fd -- n2 ) */
@@ -121,6 +123,7 @@
CALL kread(SB)
MOVQ 24(SP), UP
C_TO_F_1
+ ADDQ $32, SP
NEXT
/* no link register in amd64
@@ -142,6 +145,7 @@
CALL kwrite(SB)
MOVQ 24(SP), UP
C_TO_F_1
+ ADDQ $32, SP
NEXT
TEXT fthseek(SB), 1, $32 /* ( type pos fd -- n ) */
@@ -150,4 +154,5 @@
CALL kseek(SB)
MOVQ 24(SP), UP
C_TO_F_1
+ ADDQ $32, SP
NEXT
--- a/os/pc64/trap.c
+++ b/os/pc64/trap.c
@@ -124,12 +124,15 @@
}
void
-dumprstack(intptr h, intptr rsp)
+dumprstack(intptr h, intptr rsp, intptr he)
{
intptr i;
int l=0;
- print("Forth return stack RSTACK 0x%zx\n", h+RSTACK);
+ print("Forth return stack h 0x%zx rsp 0x%zx RSTACK 0x%zx he 0x%zx\n",
+ h, rsp, h+RSTACK, he);
+ if(he == 0 || h == 0 || rsp < h || rsp >= he || h+RSTACK < h || h+RSTACK >= he)
+ return;
for(i = h + RSTACK-8; i >= rsp; i-=8){
print(" 0x%zx: 0x%zx", i, *(intptr*)i);
l++;
@@ -142,12 +145,15 @@
}
void
-dumppstack(intptr h, intptr psp)
+dumppstack(intptr h, intptr psp, intptr he)
{
intptr i;
int l=0;
- print("Forth parameter stack PSTACK 0x%zx\n", h+PSTACK);
+ print("Forth parameter stack h 0x%zx psp 0x%zx PSTACK 0x%zx he 0x%zx\n",
+ h, psp, h+PSTACK, he);
+ if(he == 0 || h == 0 || psp < h || psp >= he || h+PSTACK < h || h+PSTACK >= he)
+ return;
for(i = h + PSTACK-8; i >= psp; i-=8){
print(" 0x%zx: 0x%zx", i, *(intptr*)i);
l++;
@@ -260,8 +266,9 @@
}
dumpregs(ureg);
if(vno < nelem(excname)){
- dumprstack(ureg->r11, ureg->r8);
- dumppstack(ureg->r11, ureg->dx);
+ dumprstack(ureg->r11, ureg->r8, ureg->r12);
+ dumppstack(ureg->r11, ureg->dx, ureg->r12);
+ _dumpstack(ureg);
panic("%s", excname[vno]);
}
panic("unknown trap/intr: %d\n", vno);
@@ -299,6 +306,8 @@
" R11 UP %8.8zux R12 UPE %8.8zux R13 %8.8zux\n",
ureg->r8, ureg->r9, ureg->r10,
ureg->r11, ureg->r12, ureg->r13);
+ print(" R14 up %8.8zux R15 m %8.8zux\n",
+ ureg->r14, ureg->r15);
}
void
@@ -362,13 +371,20 @@
i = 0;
if(up &&
(uintptr)&l >= (uintptr)up->kstack &&
- (uintptr)&l <= (uintptr)up->kstack+KSTACK)
+ (uintptr)&l <= (uintptr)up->kstack+KSTACK){
estack = (uintptr)up->kstack+KSTACK;
- else if((uintptr)&l >= (uintptr)m->stack &&
- (uintptr)&l <= (uintptr)m+BY2PG)
+ print("up->kstack 0x%zux estack 0x%zux\n",(uintptr)up->kstack, estack);
+ }else if((uintptr)&l >= (uintptr)m->stack &&
+ (uintptr)&l <= (uintptr)m+BY2PG){
estack = (uintptr)m+MACHSIZE;
- else
+ print("m->stack 0x%zux estack 0x%zux\n",(uintptr)m->stack, estack);
+ }else{
+ if(up)
+ print("up->kstack 0x%zux\n", (uintptr)up->kstack);
+ else
+ print("m->stack 0x%zux\n", (uintptr)m->stack);
return;
+ }
for(l=(uintptr)&l; l<estack; l+=sizeof(intptr)){
v = *(uintptr*)l;
@@ -447,8 +463,8 @@
read ? "read" : "write", ureg->pc, addr);
print(buf);
dumpregs(ureg);
- dumprstack(ureg->r11, ureg->r8);
- dumppstack(ureg->r11, ureg->dx);
+ dumprstack(ureg->r11, ureg->r8, ureg->r12);
+ dumppstack(ureg->r11, ureg->dx, ureg->r12);
dumpstack();
if(up->type == Interp)
disfault(ureg, buf);
--- a/os/port/allocb.c
+++ b/os/port/allocb.c
@@ -14,7 +14,7 @@
struct
{
Lock;
- u32 bytes;
+ uintptr bytes;
} ialloc;
/*
@@ -50,6 +50,17 @@
return b;
}
+/* TODO Add Bhdr attributes here */
+void
+showblockheader(Block *b, intptr pc, char *str)
+{
+ iprint("%s called by 0x%8.8luX, pid %d base 0x%8.8luX lim 0x%8.8luX\n"
+ " next 0x%8.8luX rp 0x%8.8luX wp 0x%8.8luX malloctag 0x%8.8luX\n",
+ str, pc, up->pid,
+ b->base, b->lim, b->next,
+ b->rp, b->wp, getmalloctag(b));
+}
+
Block*
allocb(int size)
{
@@ -61,6 +72,7 @@
if(b == 0)
exhausted("Blocks");
setmalloctag(b, getcallerpc(&size));
+ /* showblockheader(b, getcallerpc(&size), "allocb()"); */
return b;
}
@@ -92,6 +104,7 @@
return b;
}
+void checkbl(Block *b, char *msg, intptr pc);
void
freeb(Block *b)
{
@@ -105,6 +118,8 @@
* pool of uncached buffers and provide their own free routine.
*/
if(b->free) {
+ /* checkbl(b, "checking block before free'ing\n", getcallerpc(&b));
+ print("freeb b 0x%zx b->free 0x%zx\n", b, (intptr)b->free); */
b->free(b);
return;
}
@@ -124,6 +139,36 @@
free(b);
}
+/* same as checkb but with more details for debugging */
+void
+checkbl(Block *b, char *msg, intptr pc)
+{
+ void *dead = (void*)Bdead;
+
+ if(b == dead)
+ panic("checkb b %s %lux", msg, b);
+ if(b->base == dead || b->lim == dead || b->next == dead
+ || b->rp == dead || b->wp == dead){
+ showblockheader(b, pc, "freeb() dead");
+ panic("checkb dead: %s\n", msg);
+ }
+
+ if(b->base > b->lim){
+ showblockheader(b, pc, "freeb() 0");
+ panic("checkb 0 %s %lux %lux", msg, b->base, b->lim);
+ }
+ if(b->rp < b->base){
+ showblockheader(b, pc, "freeb() 1");
+ panic("checkb 1 %s %lux %lux", msg, b->base, b->rp);
+ }
+ if(b->wp < b->base)
+ panic("checkb 2 %s %lux %lux", msg, b->base, b->wp);
+ if(b->rp > b->lim)
+ panic("checkb 3 %s %lux %lux", msg, b->rp, b->lim);
+ if(b->wp > b->lim)
+ panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim);
+
+}
void
checkb(Block *b, char *msg)
{
--- a/os/port/chan.c
+++ b/os/port/chan.c
@@ -530,11 +530,8 @@
void
cclose(Chan *c)
{
- if(c == nil || c->ref < 1 || c->flag&CFREE){
- print("cclose before panic\n");
- panic("cclose %#p c->path %s c->ref %d c->flag 0x%ux",
- getcallerpc(&c), chanpath(c), c->ref, c->flag);
- }
+ if(c == nil || c->ref < 1 || c->flag&CFREE)
+ panic("cclose %#p", getcallerpc(&c));
if(decref(c))
return;
--- a/os/port/devforth.c
+++ b/os/port/devforth.c
@@ -91,8 +91,8 @@
Fentry *f;
u8 *h, *dtop, *vh;
int n;
+ Bhdr *b;
-debug = 0;
h = fmem+DICTIONARY;
dtop = nil;
vh = fmem+WORDBEND+8;
@@ -99,11 +99,13 @@
print("loadforthdictionary fmem 0x%zx h 0x%zx dtop 0x%zx vh 0x%zx\n"
" (intptr*)(fmem + DTOP) 0x%zx *(intptr*)(fmem + DTOP) 0x%zx\n"
" RSTACK 0x%zx (intptr*)(fmem + RSTACK) 0x%zx\n"
- " PSTACK 0x%zx (intptr*)(fmem + PSTACK) 0x%zx\n",
+ " PSTACK 0x%zx (intptr*)(fmem + PSTACK) 0x%zx\n"
+ " FORTHEND 0x%zx (intptr*)(fmem + FORTHEND) 0x%zx\n",
fmem, (intptr)h, (intptr)dtop, (intptr)vh,
(intptr*)(fmem + DTOP), *(intptr*)(fmem + DTOP),
RSTACK, (intptr*)(fmem + RSTACK),
- PSTACK, (intptr*)(fmem + PSTACK));
+ PSTACK, (intptr*)(fmem + PSTACK),
+ FORTHEND, (intptr*)(fmem + FORTHEND));
for(i=0; i < nelem(fentries); i++){
f = &fentries[i];
if(f->type == Header){
@@ -172,7 +174,19 @@
*(intptr*)(fmem + HERE) = (intptr)h;
*(intptr*)(fmem + DTOP) = (intptr)dtop;
*(intptr*)(fmem + VHERE) = (intptr)vh;
-debug = 0;
+ print("loadforthdictionary fmem 0x%zx h 0x%zx dtop 0x%zx vh 0x%zx\n"
+ " (intptr*)(fmem + DTOP) 0x%zx *(intptr*)(fmem + DTOP) 0x%zx\n"
+ " RSTACK 0x%zx (intptr*)(fmem + RSTACK) 0x%zx\n"
+ " PSTACK 0x%zx (intptr*)(fmem + PSTACK) 0x%zx\n"
+ " FORTHEND 0x%zx (intptr*)(fmem + FORTHEND) 0x%zx\n",
+ fmem, (intptr)h, (intptr)dtop, (intptr)vh,
+ (intptr*)(fmem + DTOP), *(intptr*)(fmem + DTOP),
+ RSTACK, (intptr*)(fmem + RSTACK),
+ PSTACK, (intptr*)(fmem + PSTACK),
+ FORTHEND, (intptr*)(fmem + FORTHEND));
+ b = D2B(b,fmem);
+ print("Bhdr b 0x%p b->magic 0x%x b->size %zd b->allocpc 0x%zx\n",
+ b, b->magic, b->size, b->allocpc);
}
extern intptr forthmain(u8 *);
@@ -296,7 +310,7 @@
p->kp = 0;
/* TODO align fmem to a page boundary */
- p->fmem = malloc(FORTHHEAPSIZE);
+ p->fmem = mallocalign(FORTHHEAPSIZE, BY2PG, 0, 0);
if(p->fmem == nil)
panic("newforthproc p->fmem == nil\n");