1include("/sys/src/libc/port/pool.acid"); 2 3aggr Byte { 4 'b' 0 byte; 5}; 6 7defn 8byteat(addr) 9{ 10 local x; 11 complex Byte addr; 12 x = addr.byte; 13 return x\d; 14} 15 16defn 17B2T(addr) { 18 complex Bhdr addr; 19 addr = addr+addr.size-sizeofBtail; 20 complex Btail addr; 21 return addr; 22} 23 24defn 25B2D(addr) { 26 local x; 27 x = addr+sizeofBhdr; 28 return x\X; 29} 30 31defn 32D2B(addr) { 33 local x; 34 x = addr-sizeofBhdr; 35 complex Bhdr x; 36 return x; 37} 38 39defn 40B2NB(addr) { 41 complex Bhdr addr; 42 addr = addr+addr.size; 43 complex Bhdr addr; 44 return addr; 45} 46 47defn 48A2TB(addr) { 49 local b; 50 complex Arena addr; 51 b = addr+addr.asize-sizeofBhdr; 52 complex Bhdr b; 53 return b; 54} 55 56defn 57A2B(addr) { 58 return B2NB(addr); 59} 60 61defn 62B2PT(addr) { 63 complex Bhdr addr; 64 addr = addr-sizeofBtail; 65 complex Btail addr; 66 return addr; 67} 68 69defn 70SHORT(addr) { 71 local hi, lo; 72 73 hi = byteat(addr); 74 lo = byteat(addr+1); 75 return lo+hi*256; 76} 77 78defn 79Btail(addr) { 80 complex Btail addr; 81 print(" magic0 ", addr.magic0, "\n"); 82 print(" datadiff ", SHORT(addr.datasize), "\n"); 83 print(" magic1 ", addr.magic1, "\n"); 84 print(" size ", addr.size\X, "\n"); 85 print(" hdr ", addr+sizeofBtail-addr.size\X, "\n"); 86}; 87 88defn 89Tail(addr) 90{ 91 print(" ", B2T(addr)\X, "\n"); 92 Btail(B2T(addr)); 93} 94 95defn 96Magic(m) 97{ 98 if m == FREE_MAGIC then 99 return "free"; 100 if m == ARENA_MAGIC then 101 return "arena"; 102 if m == UNKEMPT_MAGIC then 103 return "unkempt"; 104 if m == KEMPT_MAGIC then 105 return "kempt"; 106 if m == ARENATAIL_MAGIC then 107 return "arenatail"; 108 if m == DEAD_MAGIC then 109 return "dead"; 110 return "unknown magic"; 111} 112 113defn 114Block(addr) 115{ 116 complex Bhdr addr; 117 print(" ", Magic(addr.magic), "\n"); 118 print(" data ", B2D(addr), "\n"); 119 print(" datasize ", getdsize(addr), "\n"); 120 Bhdr(addr); 121 Tail(addr); 122} 123 124defn 125getdsize(addr) 126{ 127 complex Bhdr addr; 128 local x; 129 130 x = addr.size\d; 131 x = x-SHORT(B2T(addr).datasize); 132 return x\d; 133} 134 135defn 136datamagic(x) 137{ 138 x = x%4; 139 if x == 0 then return 0xFE; 140 if x == 1 then return 0xF1; 141 if x == 2 then return 0xF0; 142 if x == 3 then return 0xFA; 143} 144 145defn 146checkblock(addr) 147{ 148 local badmagic, datamagic, a, b, t, q, n, dsize, taddr, checked; 149 complex Bhdr addr; 150 taddr = B2T(addr); 151 complex Btail taddr; 152 153 if addr.magic == FREE_MAGIC || addr.magic == UNKEMPT_MAGIC then { 154 if taddr.magic0 != TAIL_MAGIC0 || taddr.magic1 != TAIL_MAGIC1 then 155 print(addr\X, " corrupt tail magic\n"); 156 if taddr.size != addr.size then 157 print(addr\X, " corrupt tail header pointer\n"); 158 } 159 160 if addr.magic == ARENA_MAGIC then { 161 taddr = A2TB(addr); 162 if taddr.magic != ARENATAIL_MAGIC then 163 print(addr\X, " arena with bad tail block\n"); 164 else 165 addr = taddr; 166 } 167 168 if addr.magic == ARENATAIL_MAGIC then { 169 if addr.size != 0 then 170 print(addr\X, " bad size in arena tail\n"); 171 } 172 173 if addr.magic == KEMPT_MAGIC then { 174 a = addr; 175 complex Alloc a; 176 if a.size > 1024*1024*1024 then 177 print(addr\X, " block ridiculously large\n"); 178 t = B2T(addr); 179 if t.magic0 != TAIL_MAGIC0 || t.magic1 != TAIL_MAGIC1 then 180 print(addr\X, " bad tail magic\n"); 181 if t.size != addr.size then 182 print(addr\X, " bad tail pointer\n"); 183 dsize = getdsize(a); 184 if dsize > a.size then 185 print(addr\X, " too much data in block\n"); 186 q = B2D(a)\X+dsize; 187 n = 4; 188 if q+4 > t then 189 n = t-q; 190 badmagic = 0; 191 loop 0,n-1 do { 192 if byteat(q) != datamagic(q) then { 193 badmagic=1; 194 } 195 q = q+1; 196 } 197 if badmagic then 198 print(addr\X, " size ", dsize, " user has overwritten boundary\n"); 199 } 200} 201 202defn 203checkarena(arena) 204{ 205 local atail, b; 206 207 atail = A2TB(arena); 208 complex Bhdr arena; 209 b = arena; 210 while b.magic != ARENATAIL_MAGIC && b < atail do { 211 checkblock(b); 212 if B2NB(b) == b then { 213 print("B2NB(", b\X, ") = b\n"); 214 b = atail; // end loop 215 } 216 b = B2NB(b); 217 } 218 219 checkblock(b); 220 if b != atail then 221 print("found wrong tail to arena ", arena\X, "\n"); 222} 223 224defn 225checkpool(p) 226{ 227 complex Pool p; 228 local a; 229 a = p.arenalist; 230 231 while a != 0 do { 232 complex Arena a; 233 checkarena(a); 234 a = a.down; 235 } 236} 237 238defn 239gendumptree(f, in, s) 240{ 241 complex Free f; 242 243 loop 1,in do {print(" ");} 244 print(s, " size ", f.size\D, " left ", f.left\X, " right ", f.right\X, "\n"); 245 if f.left != 0 && f.left < 0x7FFFFFFF then 246 gendumptree(f.left, in+1, "l"); 247 if f.right != 0 && f.right < 0x7FFFFFFF then 248 gendumptree(f.right, in+1, "r"); 249} 250 251defn 252dumptree(f) 253{ 254 gendumptree(f, 0, "*"); 255} 256 257defn 258poolwhopointsat(p, addr) 259{ 260 complex Pool p; 261 local a; 262 263 a = p.arenalist; 264 while a != 0 do { 265 complex Arena a; 266 arenawhopointsat(a, addr); 267 a = a.down; 268 } 269} 270 271defn 272arenawhopointsat(arena, addr) 273{ 274 local atail, b; 275 276 atail = A2TB(arena); 277 complex Bhdr arena; 278 b = arena; 279 while b < atail do { 280 if *b == addr then 281 print(b\X, "\n"); 282 b = b+4; 283 } 284} 285 286defn 287whopointsat(addr) 288{ 289 poolwhopointsat(*mainmem, addr); 290} 291 292defn 293blockhdr(addr) 294{ 295 addr = addr & ~3; 296 297 while *addr != FREE_MAGIC 298 && *addr != ARENA_MAGIC 299 && *addr != UNKEMPT_MAGIC 300 && *addr != KEMPT_MAGIC 301 && *addr != ARENATAIL_MAGIC 302 do 303 addr = addr-4; 304 return addr; 305} 306 307