xref: /plan9/sys/lib/acid/pool (revision 67031067871d8cd705958f437682c703f042b640)
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