rsc | 0a61c07 | 2004-04-19 18:18:37 +0000 | [diff] [blame] | 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 | |