pool (4898B)
1 include("/sys/src/libc/port/pool.acid"); 2 3 aggr Byte { 4 'b' 0 byte; 5 }; 6 7 defn 8 byteat(addr) 9 { 10 local x; 11 complex Byte addr; 12 x = addr.byte; 13 return x\d; 14 } 15 16 defn 17 B2T(addr) { 18 complex Bhdr addr; 19 addr = addr+addr.size-sizeofBtail; 20 complex Btail addr; 21 return addr; 22 } 23 24 defn 25 B2D(addr) { 26 local x; 27 x = addr+sizeofBhdr; 28 return x\X; 29 } 30 31 defn 32 D2B(addr) { 33 local x; 34 x = addr-sizeofBhdr; 35 complex Bhdr x; 36 return x; 37 } 38 39 defn 40 B2NB(addr) { 41 complex Bhdr addr; 42 addr = addr+addr.size; 43 complex Bhdr addr; 44 return addr; 45 } 46 47 defn 48 A2TB(addr) { 49 local b; 50 complex Arena addr; 51 b = addr+addr.asize-sizeofBhdr; 52 complex Bhdr b; 53 return b; 54 } 55 56 defn 57 A2B(addr) { 58 return B2NB(addr); 59 } 60 61 defn 62 B2PT(addr) { 63 complex Bhdr addr; 64 addr = addr-sizeofBtail; 65 complex Btail addr; 66 return addr; 67 } 68 69 defn 70 SHORT(addr) { 71 local hi, lo; 72 73 hi = byteat(addr); 74 lo = byteat(addr+1); 75 return lo+hi*256; 76 } 77 78 defn 79 Btail(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 88 defn 89 Tail(addr) 90 { 91 print(" ", B2T(addr)\X, "\n"); 92 Btail(B2T(addr)); 93 } 94 95 defn 96 Magic(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 113 defn 114 Block(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 124 defn 125 getdsize(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 135 defn 136 datamagic(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 145 defn 146 checkblock(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 202 defn 203 checkarena(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 224 defn 225 checkpool(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 238 defn 239 gendumptree(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 251 defn 252 dumptree(f) 253 { 254 gendumptree(f, 0, "*"); 255 } 256 257 defn 258 poolwhopointsat(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 271 defn 272 arenawhopointsat(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 286 defn 287 whopointsat(addr) 288 { 289 poolwhopointsat(*mainmem, addr); 290 } 291 292 defn 293 blockhdr(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