blob: d49c4ea1338dee9109a5733ebef99c1e05e52fd9 [file] [log] [blame]
rsc0a61c072004-04-19 18:18:37 +00001include("/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