2011-03-30 13:53:33 +00:00
|
|
|
include("/sys/src/libc/port/pool.acid");
|
|
|
|
|
|
|
|
aggr Byte {
|
|
|
|
'b' 0 byte;
|
|
|
|
};
|
|
|
|
|
|
|
|
defn
|
|
|
|
byteat(addr)
|
|
|
|
{
|
|
|
|
local x;
|
|
|
|
complex Byte addr;
|
|
|
|
x = addr.byte;
|
|
|
|
return x\d;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
B2T(addr) {
|
|
|
|
complex Bhdr addr;
|
|
|
|
addr = addr+addr.size-sizeofBtail;
|
|
|
|
complex Btail addr;
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
B2D(addr) {
|
|
|
|
local x;
|
|
|
|
x = addr+sizeofBhdr;
|
|
|
|
return x\X;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
D2B(addr) {
|
|
|
|
local x;
|
|
|
|
x = addr-sizeofBhdr;
|
|
|
|
complex Bhdr x;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
B2NB(addr) {
|
|
|
|
complex Bhdr addr;
|
|
|
|
addr = addr+addr.size;
|
|
|
|
complex Bhdr addr;
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
A2TB(addr) {
|
|
|
|
local b;
|
|
|
|
complex Arena addr;
|
|
|
|
b = addr+addr.asize-sizeofBhdr;
|
|
|
|
complex Bhdr b;
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
A2B(addr) {
|
|
|
|
return B2NB(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
B2PT(addr) {
|
|
|
|
complex Bhdr addr;
|
|
|
|
addr = addr-sizeofBtail;
|
|
|
|
complex Btail addr;
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
SHORT(addr) {
|
|
|
|
local hi, lo;
|
|
|
|
|
|
|
|
hi = byteat(addr);
|
|
|
|
lo = byteat(addr+1);
|
|
|
|
return lo+hi*256;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
Btail(addr) {
|
|
|
|
complex Btail addr;
|
|
|
|
print(" magic0 ", addr.magic0, "\n");
|
|
|
|
print(" datadiff ", SHORT(addr.datasize), "\n");
|
|
|
|
print(" magic1 ", addr.magic1, "\n");
|
|
|
|
print(" size ", addr.size\X, "\n");
|
|
|
|
print(" hdr ", addr+sizeofBtail-addr.size\X, "\n");
|
|
|
|
};
|
|
|
|
|
|
|
|
defn
|
|
|
|
Tail(addr)
|
|
|
|
{
|
|
|
|
print(" ", B2T(addr)\X, "\n");
|
|
|
|
Btail(B2T(addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
Magic(m)
|
|
|
|
{
|
2011-06-30 10:20:30 +00:00
|
|
|
if m == DEAD_MAGIC then
|
|
|
|
return "dead";
|
2011-03-30 13:53:33 +00:00
|
|
|
if m == FREE_MAGIC then
|
|
|
|
return "free";
|
2011-06-30 10:20:30 +00:00
|
|
|
if m == ALLOC_MAGIC then
|
|
|
|
return "alloc";
|
|
|
|
if m == UNALLOC_MAGIC then
|
|
|
|
return "unalloc";
|
2011-03-30 13:53:33 +00:00
|
|
|
if m == ARENA_MAGIC then
|
|
|
|
return "arena";
|
|
|
|
if m == ARENATAIL_MAGIC then
|
|
|
|
return "arenatail";
|
2011-06-30 10:20:30 +00:00
|
|
|
if m == ALIGN_MAGIC then
|
|
|
|
return "align";
|
|
|
|
if m == FLOATING_MAGIC then
|
|
|
|
return "floating";
|
2011-03-30 13:53:33 +00:00
|
|
|
return "unknown magic";
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
Block(addr)
|
|
|
|
{
|
|
|
|
complex Bhdr addr;
|
|
|
|
print(" ", Magic(addr.magic), "\n");
|
|
|
|
print(" data ", B2D(addr), "\n");
|
|
|
|
print(" datasize ", getdsize(addr), "\n");
|
|
|
|
Bhdr(addr);
|
|
|
|
Tail(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
getdsize(addr)
|
|
|
|
{
|
|
|
|
complex Bhdr addr;
|
|
|
|
local x;
|
|
|
|
|
|
|
|
x = addr.size\d;
|
|
|
|
x = x-SHORT(B2T(addr).datasize);
|
|
|
|
return x\d;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
datamagic(x)
|
|
|
|
{
|
|
|
|
x = x%4;
|
|
|
|
if x == 0 then return 0xFE;
|
|
|
|
if x == 1 then return 0xF1;
|
|
|
|
if x == 2 then return 0xF0;
|
|
|
|
if x == 3 then return 0xFA;
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
checkblock(addr)
|
|
|
|
{
|
|
|
|
local badmagic, datamagic, a, b, t, q, n, dsize, taddr, checked;
|
|
|
|
complex Bhdr addr;
|
|
|
|
taddr = B2T(addr);
|
|
|
|
complex Btail taddr;
|
|
|
|
|
2011-06-30 10:20:30 +00:00
|
|
|
if addr.magic == FREE_MAGIC || addr.magic == UNALLOC_MAGIC then {
|
2011-03-30 13:53:33 +00:00
|
|
|
if taddr.magic0 != TAIL_MAGIC0 || taddr.magic1 != TAIL_MAGIC1 then
|
|
|
|
print(addr\X, " corrupt tail magic\n");
|
|
|
|
if taddr.size != addr.size then
|
|
|
|
print(addr\X, " corrupt tail header pointer\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if addr.magic == ARENA_MAGIC then {
|
|
|
|
taddr = A2TB(addr);
|
|
|
|
if taddr.magic != ARENATAIL_MAGIC then
|
|
|
|
print(addr\X, " arena with bad tail block\n");
|
|
|
|
else
|
|
|
|
addr = taddr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if addr.magic == ARENATAIL_MAGIC then {
|
|
|
|
if addr.size != 0 then
|
|
|
|
print(addr\X, " bad size in arena tail\n");
|
|
|
|
}
|
|
|
|
|
2011-06-30 10:20:30 +00:00
|
|
|
if addr.magic == ALLOC_MAGIC then {
|
2011-03-30 13:53:33 +00:00
|
|
|
a = addr;
|
|
|
|
complex Alloc a;
|
|
|
|
if a.size > 1024*1024*1024 then
|
|
|
|
print(addr\X, " block ridiculously large\n");
|
|
|
|
t = B2T(addr);
|
|
|
|
if t.magic0 != TAIL_MAGIC0 || t.magic1 != TAIL_MAGIC1 then
|
|
|
|
print(addr\X, " bad tail magic\n");
|
|
|
|
if t.size != addr.size then
|
|
|
|
print(addr\X, " bad tail pointer\n");
|
|
|
|
dsize = getdsize(a);
|
|
|
|
if dsize > a.size then
|
|
|
|
print(addr\X, " too much data in block\n");
|
|
|
|
q = B2D(a)\X+dsize;
|
|
|
|
n = 4;
|
|
|
|
if q+4 > t then
|
|
|
|
n = t-q;
|
|
|
|
badmagic = 0;
|
|
|
|
loop 0,n-1 do {
|
|
|
|
if byteat(q) != datamagic(q) then {
|
|
|
|
badmagic=1;
|
|
|
|
}
|
|
|
|
q = q+1;
|
|
|
|
}
|
|
|
|
if badmagic then
|
|
|
|
print(addr\X, " size ", dsize, " user has overwritten boundary\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
checkarena(arena)
|
|
|
|
{
|
|
|
|
local atail, b;
|
|
|
|
|
|
|
|
atail = A2TB(arena);
|
|
|
|
complex Bhdr arena;
|
|
|
|
b = arena;
|
|
|
|
while b.magic != ARENATAIL_MAGIC && b < atail do {
|
|
|
|
checkblock(b);
|
|
|
|
if B2NB(b) == b then {
|
|
|
|
print("B2NB(", b\X, ") = b\n");
|
|
|
|
b = atail; // end loop
|
|
|
|
}
|
|
|
|
b = B2NB(b);
|
|
|
|
}
|
|
|
|
|
|
|
|
checkblock(b);
|
|
|
|
if b != atail then
|
|
|
|
print("found wrong tail to arena ", arena\X, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
checkpool(p)
|
|
|
|
{
|
|
|
|
complex Pool p;
|
|
|
|
local a;
|
|
|
|
a = p.arenalist;
|
|
|
|
|
|
|
|
while a != 0 do {
|
|
|
|
complex Arena a;
|
|
|
|
checkarena(a);
|
|
|
|
a = a.down;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
gendumptree(f, in, s)
|
|
|
|
{
|
|
|
|
complex Free f;
|
|
|
|
|
|
|
|
loop 1,in do {print(" ");}
|
|
|
|
print(s, " size ", f.size\D, " left ", f.left\X, " right ", f.right\X, "\n");
|
|
|
|
if f.left != 0 && f.left < 0x7FFFFFFF then
|
|
|
|
gendumptree(f.left, in+1, "l");
|
|
|
|
if f.right != 0 && f.right < 0x7FFFFFFF then
|
|
|
|
gendumptree(f.right, in+1, "r");
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
dumptree(f)
|
|
|
|
{
|
|
|
|
gendumptree(f, 0, "*");
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
poolwhopointsat(p, addr)
|
|
|
|
{
|
|
|
|
complex Pool p;
|
|
|
|
local a;
|
|
|
|
|
|
|
|
a = p.arenalist;
|
|
|
|
while a != 0 do {
|
|
|
|
complex Arena a;
|
|
|
|
arenawhopointsat(a, addr);
|
|
|
|
a = a.down;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
arenawhopointsat(arena, addr)
|
|
|
|
{
|
|
|
|
local atail, b;
|
|
|
|
|
|
|
|
atail = A2TB(arena);
|
|
|
|
complex Bhdr arena;
|
|
|
|
b = arena;
|
|
|
|
while b < atail do {
|
|
|
|
if *b == addr then
|
|
|
|
print(b\X, "\n");
|
|
|
|
b = b+4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
whopointsat(addr)
|
|
|
|
{
|
|
|
|
poolwhopointsat(*mainmem, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
defn
|
|
|
|
blockhdr(addr)
|
|
|
|
{
|
|
|
|
addr = addr & ~3;
|
|
|
|
|
|
|
|
while *addr != FREE_MAGIC
|
|
|
|
&& *addr != ARENA_MAGIC
|
2011-06-30 10:20:30 +00:00
|
|
|
&& *addr != UNALLOC_MAGIC
|
|
|
|
&& *addr != ALLOC_MAGIC
|
2011-03-30 13:53:33 +00:00
|
|
|
&& *addr != ARENATAIL_MAGIC
|
|
|
|
do
|
|
|
|
addr = addr-4;
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|