1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #if defined(_UWIN) && defined(_BLD_ast)
23da2e3ebdSchin 
_STUB_vmdebug()24da2e3ebdSchin void _STUB_vmdebug(){}
25da2e3ebdSchin 
26da2e3ebdSchin #else
27da2e3ebdSchin 
28da2e3ebdSchin #include	"vmhdr.h"
29da2e3ebdSchin 
30da2e3ebdSchin /*	Method to help with debugging. This does rigorous checks on
31da2e3ebdSchin **	addresses and arena integrity.
32da2e3ebdSchin **
33da2e3ebdSchin **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
34da2e3ebdSchin */
35da2e3ebdSchin 
36da2e3ebdSchin /* structure to keep track of file names */
37da2e3ebdSchin typedef struct _dbfile_s	Dbfile_t;
38da2e3ebdSchin struct _dbfile_s
39da2e3ebdSchin {	Dbfile_t*	next;
40da2e3ebdSchin 	char		file[1];
41da2e3ebdSchin };
42da2e3ebdSchin static Dbfile_t*	Dbfile;
43da2e3ebdSchin 
44da2e3ebdSchin /* global watch list */
45da2e3ebdSchin #define S_WATCH	32
46da2e3ebdSchin static int	Dbnwatch;
47da2e3ebdSchin static Void_t*	Dbwatch[S_WATCH];
48da2e3ebdSchin 
49da2e3ebdSchin /* types of warnings reported by dbwarn() */
50da2e3ebdSchin #define	DB_CHECK	0
51da2e3ebdSchin #define DB_ALLOC	1
52da2e3ebdSchin #define DB_FREE		2
53da2e3ebdSchin #define DB_RESIZE	3
54da2e3ebdSchin #define DB_WATCH	4
55da2e3ebdSchin #define DB_RESIZED	5
56da2e3ebdSchin 
57da2e3ebdSchin static int Dbinit = 0;
58da2e3ebdSchin #define DBINIT()	(Dbinit ? 0 : (dbinit(), Dbinit=1) )
dbinit()59da2e3ebdSchin static void dbinit()
60da2e3ebdSchin {	int	fd;
61da2e3ebdSchin 	if((fd = vmtrace(-1)) >= 0)
62da2e3ebdSchin 		vmtrace(fd);
63da2e3ebdSchin }
64da2e3ebdSchin 
65da2e3ebdSchin static int	Dbfd = 2;	/* default warning file descriptor */
66da2e3ebdSchin #if __STD_C
vmdebug(int fd)67da2e3ebdSchin int vmdebug(int fd)
68da2e3ebdSchin #else
69da2e3ebdSchin int vmdebug(fd)
70da2e3ebdSchin int	fd;
71da2e3ebdSchin #endif
72da2e3ebdSchin {
73da2e3ebdSchin 	int	old = Dbfd;
74da2e3ebdSchin 	Dbfd = fd;
75da2e3ebdSchin 	return old;
76da2e3ebdSchin }
77da2e3ebdSchin 
78*b30d1939SAndy Fiddaman 
79da2e3ebdSchin /* just an entry point to make it easy to set break point */
80da2e3ebdSchin #if __STD_C
vmdbwarn(Vmalloc_t * vm,char * mesg,int n)81da2e3ebdSchin static void vmdbwarn(Vmalloc_t* vm, char* mesg, int n)
82da2e3ebdSchin #else
83da2e3ebdSchin static void vmdbwarn(vm, mesg, n)
84da2e3ebdSchin Vmalloc_t*	vm;
85da2e3ebdSchin char*		mesg;
86da2e3ebdSchin int		n;
87da2e3ebdSchin #endif
88da2e3ebdSchin {
89da2e3ebdSchin 	reg Vmdata_t*	vd = vm->data;
90da2e3ebdSchin 
91da2e3ebdSchin 	write(Dbfd,mesg,n);
92da2e3ebdSchin 	if(vd->mode&VM_DBABORT)
93da2e3ebdSchin 		abort();
94da2e3ebdSchin }
95da2e3ebdSchin 
96da2e3ebdSchin /* issue a warning of some type */
97da2e3ebdSchin #if __STD_C
dbwarn(Vmalloc_t * vm,Void_t * data,int where,char * file,int line,Void_t * func,int type)98da2e3ebdSchin static void dbwarn(Vmalloc_t* vm, Void_t* data, int where,
99*b30d1939SAndy Fiddaman 		   char* file, int line, Void_t* func, int type)
100da2e3ebdSchin #else
101da2e3ebdSchin static void dbwarn(vm, data, where, file, line, func, type)
102da2e3ebdSchin Vmalloc_t*	vm;	/* region holding the block	*/
103da2e3ebdSchin Void_t*		data;	/* data block			*/
104da2e3ebdSchin int		where;	/* byte that was corrupted	*/
105*b30d1939SAndy Fiddaman char*		file;	/* file where call originates	*/
106da2e3ebdSchin int		line;	/* line number of call		*/
107*b30d1939SAndy Fiddaman Void_t*		func;	/* function called from		*/
108da2e3ebdSchin int		type;	/* operation being done		*/
109da2e3ebdSchin #endif
110da2e3ebdSchin {
111da2e3ebdSchin 	char	buf[1024], *bufp, *endbuf, *s;
112da2e3ebdSchin #define SLOP	64	/* enough for a message and an int */
113da2e3ebdSchin 
114da2e3ebdSchin 	DBINIT();
115da2e3ebdSchin 
116da2e3ebdSchin 	bufp = buf;
117da2e3ebdSchin 	endbuf = buf + sizeof(buf);
118da2e3ebdSchin 
119da2e3ebdSchin 	if(type == DB_ALLOC)
120da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, "alloc error", ':');
121da2e3ebdSchin 	else if(type == DB_FREE)
122da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, "free error", ':');
123da2e3ebdSchin 	else if(type == DB_RESIZE)
124da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, "resize error", ':');
125da2e3ebdSchin 	else if(type == DB_CHECK)
126da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, "corrupted data", ':');
127da2e3ebdSchin 	else if(type == DB_WATCH)
128da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, "alert", ':');
129da2e3ebdSchin 
130da2e3ebdSchin 	/* region info */
131da2e3ebdSchin 	bufp = (*_Vmstrcpy)(bufp, "region", '=');
132da2e3ebdSchin 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(vm), 0), ':');
133da2e3ebdSchin 
134da2e3ebdSchin 	if(data)
135da2e3ebdSchin 	{	bufp = (*_Vmstrcpy)(bufp,"block",'=');
136da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(data),0),':');
137da2e3ebdSchin 	}
138da2e3ebdSchin 
139da2e3ebdSchin 	if(!data)
140da2e3ebdSchin 	{	if(where == DB_ALLOC)
141da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp, "can't get memory", ':');
142da2e3ebdSchin 		else	bufp = (*_Vmstrcpy)(bufp, "region is locked", ':');
143da2e3ebdSchin 	}
144da2e3ebdSchin 	else if(type == DB_FREE || type == DB_RESIZE)
145da2e3ebdSchin 	{	if(where == 0)
146da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp, "unallocated block", ':');
147da2e3ebdSchin 		else	bufp = (*_Vmstrcpy)(bufp, "already freed", ':');
148da2e3ebdSchin 	}
149da2e3ebdSchin 	else if(type == DB_WATCH)
150da2e3ebdSchin 	{	bufp = (*_Vmstrcpy)(bufp, "size", '=');
151*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)((Vmulong_t)DBSIZE(data),-1), ':');
152da2e3ebdSchin 		if(where == DB_ALLOC)
153da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp,"just allocated", ':');
154da2e3ebdSchin 		else if(where == DB_FREE)
155da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp,"being freed", ':');
156da2e3ebdSchin 		else if(where == DB_RESIZE)
157da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp,"being resized", ':');
158da2e3ebdSchin 		else if(where == DB_RESIZED)
159da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp,"just resized", ':');
160da2e3ebdSchin 	}
161da2e3ebdSchin 	else if(type == DB_CHECK)
162da2e3ebdSchin 	{	bufp = (*_Vmstrcpy)(bufp, "bad byte at", '=');
163*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(where),-1), ':');
164da2e3ebdSchin 		if((s = DBFILE(data)) && (bufp + strlen(s) + SLOP) < endbuf)
165da2e3ebdSchin 		{	bufp = (*_Vmstrcpy)(bufp,"allocated at", '=');
166da2e3ebdSchin 			bufp = (*_Vmstrcpy)(bufp, s, ',');
167*b30d1939SAndy Fiddaman 			bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(DBLINE(data)),-1),':');
168da2e3ebdSchin 		}
169da2e3ebdSchin 	}
170da2e3ebdSchin 
171da2e3ebdSchin 	/* location where offending call originates from */
172da2e3ebdSchin 	if(file && file[0] && line > 0 && (bufp + strlen(file) + SLOP) < endbuf)
173da2e3ebdSchin 	{	bufp = (*_Vmstrcpy)(bufp, "detected at", '=');
174da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, file, ',');
175*b30d1939SAndy Fiddaman 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(line),-1), ',');
176da2e3ebdSchin 		bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(func),-1), ':');
177da2e3ebdSchin 	}
178da2e3ebdSchin 
179*b30d1939SAndy Fiddaman 	*bufp++ = '\n';
180da2e3ebdSchin 	*bufp = '\0';
181da2e3ebdSchin 
182*b30d1939SAndy Fiddaman 	vmdbwarn(vm,buf,(int)(bufp-buf));
183da2e3ebdSchin }
184da2e3ebdSchin 
185da2e3ebdSchin /* check for watched address and issue warnings */
186da2e3ebdSchin #if __STD_C
dbwatch(Vmalloc_t * vm,Void_t * data,char * file,int line,Void_t * func,int type)187da2e3ebdSchin static void dbwatch(Vmalloc_t* vm, Void_t* data,
188*b30d1939SAndy Fiddaman 		    char* file, int line, Void_t* func, int type)
189da2e3ebdSchin #else
190da2e3ebdSchin static void dbwatch(vm, data, file, line, func, type)
191da2e3ebdSchin Vmalloc_t*	vm;
192da2e3ebdSchin Void_t*		data;
193*b30d1939SAndy Fiddaman char*		file;
194da2e3ebdSchin int		line;
195*b30d1939SAndy Fiddaman Void_t*		func;
196da2e3ebdSchin int		type;
197da2e3ebdSchin #endif
198da2e3ebdSchin {
199da2e3ebdSchin 	reg int		n;
200da2e3ebdSchin 
201da2e3ebdSchin 	for(n = Dbnwatch; n >= 0; --n)
202da2e3ebdSchin 	{	if(Dbwatch[n] == data)
203da2e3ebdSchin 		{	dbwarn(vm,data,type,file,line,func,DB_WATCH);
204da2e3ebdSchin 			return;
205da2e3ebdSchin 		}
206da2e3ebdSchin 	}
207da2e3ebdSchin }
208da2e3ebdSchin 
209da2e3ebdSchin /* record information about the block */
210da2e3ebdSchin #if __STD_C
dbsetinfo(Vmuchar_t * data,size_t size,char * file,int line)211*b30d1939SAndy Fiddaman static void dbsetinfo(Vmuchar_t* data, size_t size, char* file, int line)
212da2e3ebdSchin #else
213da2e3ebdSchin static void dbsetinfo(data, size, file, line)
214da2e3ebdSchin Vmuchar_t*	data;	/* real address not the one from Vmbest	*/
215da2e3ebdSchin size_t		size;	/* the actual requested size		*/
216*b30d1939SAndy Fiddaman char*		file;	/* file where the request came from	*/
217da2e3ebdSchin int		line;	/* and line number			*/
218da2e3ebdSchin #endif
219da2e3ebdSchin {
220da2e3ebdSchin 	reg Vmuchar_t	*begp, *endp;
221da2e3ebdSchin 	reg Dbfile_t	*last, *db;
222da2e3ebdSchin 
223da2e3ebdSchin 	DBINIT();
224da2e3ebdSchin 
225da2e3ebdSchin 	/* find the file structure */
226da2e3ebdSchin 	if(!file || !file[0])
227da2e3ebdSchin 		db = NIL(Dbfile_t*);
228da2e3ebdSchin 	else
229da2e3ebdSchin 	{	for(last = NIL(Dbfile_t*), db = Dbfile; db; last = db, db = db->next)
230da2e3ebdSchin 			if(strcmp(db->file,file) == 0)
231da2e3ebdSchin 				break;
232da2e3ebdSchin 		if(!db)
233da2e3ebdSchin 		{	db = (Dbfile_t*)vmalloc(Vmheap,sizeof(Dbfile_t)+strlen(file));
234da2e3ebdSchin 			if(db)
235da2e3ebdSchin 			{	(*_Vmstrcpy)(db->file,file,0);
236da2e3ebdSchin 				db->next = Dbfile;
237*b30d1939SAndy Fiddaman 				Dbfile = db;
238da2e3ebdSchin 			}
239da2e3ebdSchin 		}
240da2e3ebdSchin 		else if(last) /* move-to-front heuristic */
241da2e3ebdSchin 		{	last->next = db->next;
242da2e3ebdSchin 			db->next = Dbfile;
243*b30d1939SAndy Fiddaman 			Dbfile = db;
244da2e3ebdSchin 		}
245da2e3ebdSchin 	}
246da2e3ebdSchin 
247da2e3ebdSchin 	DBSETFL(data,(db ? db->file : NIL(char*)),line);
248da2e3ebdSchin 	DBSIZE(data) = size;
249da2e3ebdSchin 	DBSEG(data)  = SEG(DBBLOCK(data));
250da2e3ebdSchin 
251da2e3ebdSchin 	DBHEAD(data,begp,endp);
252da2e3ebdSchin 	while(begp < endp)
253da2e3ebdSchin 		*begp++ = DB_MAGIC;
254da2e3ebdSchin 	DBTAIL(data,begp,endp);
255da2e3ebdSchin 	while(begp < endp)
256da2e3ebdSchin 		*begp++ = DB_MAGIC;
257da2e3ebdSchin }
258da2e3ebdSchin 
259da2e3ebdSchin /* Check to see if an address is in some data block of a region.
260da2e3ebdSchin ** This returns -(offset+1) if block is already freed, +(offset+1)
261da2e3ebdSchin ** if block is live, 0 if no match.
262da2e3ebdSchin */
263da2e3ebdSchin #if __STD_C
dbaddr(Vmalloc_t * vm,Void_t * addr,int local)264*b30d1939SAndy Fiddaman static long dbaddr(Vmalloc_t* vm, Void_t* addr, int local)
265da2e3ebdSchin #else
266*b30d1939SAndy Fiddaman static long dbaddr(vm, addr, local)
267da2e3ebdSchin Vmalloc_t*	vm;
268da2e3ebdSchin Void_t*		addr;
269*b30d1939SAndy Fiddaman int		local;
270da2e3ebdSchin #endif
271da2e3ebdSchin {
272da2e3ebdSchin 	reg Block_t	*b, *endb;
273*b30d1939SAndy Fiddaman 	reg Seg_t	*seg;
274*b30d1939SAndy Fiddaman 	reg Vmuchar_t	*data;
275da2e3ebdSchin 	reg long	offset = -1L;
276*b30d1939SAndy Fiddaman 	reg Vmdata_t	*vd = vm->data;
277da2e3ebdSchin 
278*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
279da2e3ebdSchin 
280da2e3ebdSchin 	b = endb = NIL(Block_t*);
281da2e3ebdSchin 	for(seg = vd->seg; seg; seg = seg->next)
282da2e3ebdSchin 	{	b = SEGBLOCK(seg);
283da2e3ebdSchin 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
284da2e3ebdSchin 		if((Vmuchar_t*)addr > (Vmuchar_t*)b &&
285da2e3ebdSchin 		   (Vmuchar_t*)addr < (Vmuchar_t*)endb)
286da2e3ebdSchin 			break;
287da2e3ebdSchin 	}
288da2e3ebdSchin 	if(!seg)
289da2e3ebdSchin 		goto done;
290da2e3ebdSchin 
291*b30d1939SAndy Fiddaman 	if(local) /* must be vmfree or vmresize checking address */
292da2e3ebdSchin 	{	if(DBSEG(addr) == seg)
293da2e3ebdSchin 		{	b = DBBLOCK(addr);
294da2e3ebdSchin 			if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
295da2e3ebdSchin 				offset = 0;
296da2e3ebdSchin 			else	offset = -2L;
297da2e3ebdSchin 		}
298da2e3ebdSchin 		goto done;
299da2e3ebdSchin 	}
300da2e3ebdSchin 
301da2e3ebdSchin 	while(b < endb)
302da2e3ebdSchin 	{	data = (Vmuchar_t*)DATA(b);
303da2e3ebdSchin 		if((Vmuchar_t*)addr >= data && (Vmuchar_t*)addr < data+SIZE(b))
304da2e3ebdSchin 		{	if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
305da2e3ebdSchin 			{	data = DB2DEBUG(data);
306da2e3ebdSchin 				if((Vmuchar_t*)addr >= data &&
307da2e3ebdSchin 				   (Vmuchar_t*)addr < data+DBSIZE(data))
308*b30d1939SAndy Fiddaman 					offset = (long)((Vmuchar_t*)addr - data);
309da2e3ebdSchin 			}
310da2e3ebdSchin 			goto done;
311da2e3ebdSchin 		}
312da2e3ebdSchin 
313da2e3ebdSchin 		b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
314da2e3ebdSchin 	}
315da2e3ebdSchin 
316da2e3ebdSchin done:
317*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
318da2e3ebdSchin 	return offset;
319da2e3ebdSchin }
320da2e3ebdSchin 
321da2e3ebdSchin 
322da2e3ebdSchin #if __STD_C
dbsize(Vmalloc_t * vm,Void_t * addr,int local)323*b30d1939SAndy Fiddaman static long dbsize(Vmalloc_t* vm, Void_t* addr, int local)
324da2e3ebdSchin #else
325*b30d1939SAndy Fiddaman static long dbsize(vm, addr, local)
326da2e3ebdSchin Vmalloc_t*	vm;
327da2e3ebdSchin Void_t*		addr;
328*b30d1939SAndy Fiddaman int		local;
329da2e3ebdSchin #endif
330da2e3ebdSchin {
331*b30d1939SAndy Fiddaman 	Block_t		*b, *endb;
332*b30d1939SAndy Fiddaman 	Seg_t		*seg;
333*b30d1939SAndy Fiddaman 	long		size;
334*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
335da2e3ebdSchin 
336*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
337da2e3ebdSchin 
338da2e3ebdSchin 	size = -1L;
339da2e3ebdSchin 	for(seg = vd->seg; seg; seg = seg->next)
340da2e3ebdSchin 	{	b = SEGBLOCK(seg);
341da2e3ebdSchin 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
342da2e3ebdSchin 		if((Vmuchar_t*)addr <= (Vmuchar_t*)b ||
343da2e3ebdSchin 		   (Vmuchar_t*)addr >= (Vmuchar_t*)endb)
344da2e3ebdSchin 			continue;
345da2e3ebdSchin 		while(b < endb)
346da2e3ebdSchin 		{	if(addr == (Void_t*)DB2DEBUG(DATA(b)))
347da2e3ebdSchin 			{	if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
348da2e3ebdSchin 					size = (long)DBSIZE(addr);
349da2e3ebdSchin 				goto done;
350da2e3ebdSchin 			}
351da2e3ebdSchin 
352da2e3ebdSchin 			b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
353da2e3ebdSchin 		}
354da2e3ebdSchin 	}
355*b30d1939SAndy Fiddaman 
356da2e3ebdSchin done:
357*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
358da2e3ebdSchin 	return size;
359da2e3ebdSchin }
360da2e3ebdSchin 
361da2e3ebdSchin #if __STD_C
dballoc(Vmalloc_t * vm,size_t size,int local)362*b30d1939SAndy Fiddaman static Void_t* dballoc(Vmalloc_t* vm, size_t size, int local)
363da2e3ebdSchin #else
364*b30d1939SAndy Fiddaman static Void_t* dballoc(vm, size, local)
365da2e3ebdSchin Vmalloc_t*	vm;
366da2e3ebdSchin size_t		size;
367*b30d1939SAndy Fiddaman int		local;
368da2e3ebdSchin #endif
369da2e3ebdSchin {
370*b30d1939SAndy Fiddaman 	size_t		s;
371*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
372*b30d1939SAndy Fiddaman 	char		*file;
373*b30d1939SAndy Fiddaman 	int		line;
374*b30d1939SAndy Fiddaman 	Void_t		*func;
375*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
376da2e3ebdSchin 	VMFLF(vm,file,line,func);
377da2e3ebdSchin 
378*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
379da2e3ebdSchin 
380da2e3ebdSchin 	if(vd->mode&VM_DBCHECK)
381da2e3ebdSchin 		vmdbcheck(vm);
382da2e3ebdSchin 
383da2e3ebdSchin 	s = ROUND(size,ALIGN) + DB_EXTRA;
384da2e3ebdSchin 	if(s < sizeof(Body_t))	/* no tiny blocks during Vmdebug */
385da2e3ebdSchin 		s = sizeof(Body_t);
386da2e3ebdSchin 
387da2e3ebdSchin 	if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
388da2e3ebdSchin 	{	dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_ALLOC);
389da2e3ebdSchin 		goto done;
390da2e3ebdSchin 	}
391da2e3ebdSchin 
392da2e3ebdSchin 	data = DB2DEBUG(data);
393da2e3ebdSchin 	dbsetinfo(data,size,file,line);
394da2e3ebdSchin 
395da2e3ebdSchin 	if((vd->mode&VM_TRACE) && _Vmtrace)
396da2e3ebdSchin 	{	vm->file = file; vm->line = line; vm->func = func;
397da2e3ebdSchin 		(*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,0);
398da2e3ebdSchin 	}
399da2e3ebdSchin 
400da2e3ebdSchin 	if(Dbnwatch > 0 )
401da2e3ebdSchin 		dbwatch(vm,data,file,line,func,DB_ALLOC);
402da2e3ebdSchin 
403da2e3ebdSchin done:
404*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
405*b30d1939SAndy Fiddaman 
406da2e3ebdSchin 	return (Void_t*)data;
407da2e3ebdSchin }
408da2e3ebdSchin 
409da2e3ebdSchin 
410da2e3ebdSchin #if __STD_C
dbfree(Vmalloc_t * vm,Void_t * data,int local)411*b30d1939SAndy Fiddaman static int dbfree(Vmalloc_t* vm, Void_t* data, int local )
412da2e3ebdSchin #else
413*b30d1939SAndy Fiddaman static int dbfree(vm, data, local )
414da2e3ebdSchin Vmalloc_t*	vm;
415da2e3ebdSchin Void_t*		data;
416*b30d1939SAndy Fiddaman int		local;
417da2e3ebdSchin #endif
418da2e3ebdSchin {
419*b30d1939SAndy Fiddaman 	char		*file;
420da2e3ebdSchin 	int		line;
421*b30d1939SAndy Fiddaman 	Void_t		*func;
422*b30d1939SAndy Fiddaman 	long		offset;
423*b30d1939SAndy Fiddaman 	int		rv, *ip, *endip;
424*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
425da2e3ebdSchin 	VMFLF(vm,file,line,func);
426da2e3ebdSchin 
427da2e3ebdSchin 	if(!data)
428da2e3ebdSchin 		return 0;
429da2e3ebdSchin 
430*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
431da2e3ebdSchin 
432da2e3ebdSchin 	if(vd->mode&VM_DBCHECK)
433da2e3ebdSchin 		vmdbcheck(vm);
434da2e3ebdSchin 
435da2e3ebdSchin 	if((offset = KPVADDR(vm,data,dbaddr)) != 0)
4363e14f97fSRoger A. Faulkner 	{	dbwarn(vm,(Vmuchar_t*)data,offset == -1L ? 0 : 1,file,line,func,DB_FREE);
437*b30d1939SAndy Fiddaman 		rv = -1;
438da2e3ebdSchin 	}
439*b30d1939SAndy Fiddaman 	else
440*b30d1939SAndy Fiddaman 	{	if(Dbnwatch > 0)
441*b30d1939SAndy Fiddaman 			dbwatch(vm,data,file,line,func,DB_FREE);
442da2e3ebdSchin 
443*b30d1939SAndy Fiddaman 		if((vd->mode&VM_TRACE) && _Vmtrace)
444*b30d1939SAndy Fiddaman 		{	vm->file = file; vm->line = line; vm->func = func;
445*b30d1939SAndy Fiddaman 			(*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),DBSIZE(data),0);
446*b30d1939SAndy Fiddaman 		}
447da2e3ebdSchin 
448*b30d1939SAndy Fiddaman 		/* clear free space */
449*b30d1939SAndy Fiddaman 		ip = (int*)data;
450*b30d1939SAndy Fiddaman 		endip = ip + (DBSIZE(data)+sizeof(int)-1)/sizeof(int);
451*b30d1939SAndy Fiddaman 		while(ip < endip)
452*b30d1939SAndy Fiddaman 			*ip++ = 0;
453da2e3ebdSchin 
454*b30d1939SAndy Fiddaman 		rv = KPVFREE((vm), (Void_t*)DB2BEST(data), (*Vmbest->freef));
455*b30d1939SAndy Fiddaman 	}
456da2e3ebdSchin 
457*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
458da2e3ebdSchin 	return rv;
459da2e3ebdSchin }
460da2e3ebdSchin 
461da2e3ebdSchin /*	Resizing an existing block */
462da2e3ebdSchin #if __STD_C
dbresize(Vmalloc_t * vm,Void_t * addr,reg size_t size,int type,int local)463*b30d1939SAndy Fiddaman static Void_t* dbresize(Vmalloc_t* vm, Void_t* addr, reg size_t size, int type, int local)
464da2e3ebdSchin #else
465*b30d1939SAndy Fiddaman static Void_t* dbresize(vm, addr, size, type, local)
466*b30d1939SAndy Fiddaman Vmalloc_t*	vm;	/* region allocating from	*/
467*b30d1939SAndy Fiddaman Void_t*		addr;	/* old block of data		*/
468*b30d1939SAndy Fiddaman reg size_t	size;	/* new size			*/
469*b30d1939SAndy Fiddaman int		type;	/* !=0 for movable, >0 for copy	*/
470*b30d1939SAndy Fiddaman int		local;
471da2e3ebdSchin #endif
472da2e3ebdSchin {
473*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
474*b30d1939SAndy Fiddaman 	long		offset;
475*b30d1939SAndy Fiddaman 	size_t		s, oldsize;
476da2e3ebdSchin 	char		*file, *oldfile;
477da2e3ebdSchin 	int		line, oldline;
478*b30d1939SAndy Fiddaman 	Void_t		*func;
479*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
480*b30d1939SAndy Fiddaman 	VMFLF(vm,file,line,func);
481da2e3ebdSchin 
482da2e3ebdSchin 	if(!addr)
483*b30d1939SAndy Fiddaman 	{	vm->file = file; vm->line = line;
484*b30d1939SAndy Fiddaman 		data = (Vmuchar_t*)dballoc(vm, size, local);
485*b30d1939SAndy Fiddaman 		if(data && (type&VM_RSZERO) )
486*b30d1939SAndy Fiddaman 			memset((Void_t*)data, 0, size);
487*b30d1939SAndy Fiddaman 		return data;
488da2e3ebdSchin 	}
489da2e3ebdSchin 	if(size == 0)
490*b30d1939SAndy Fiddaman 	{	vm->file = file; vm->line = line;
491*b30d1939SAndy Fiddaman 		(void)dbfree(vm, addr, local);
492da2e3ebdSchin 		return NIL(Void_t*);
493da2e3ebdSchin 	}
494da2e3ebdSchin 
495*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
496da2e3ebdSchin 
497da2e3ebdSchin 	if(vd->mode&VM_DBCHECK)
498da2e3ebdSchin 		vmdbcheck(vm);
499da2e3ebdSchin 
500da2e3ebdSchin 	if((offset = KPVADDR(vm,addr,dbaddr)) != 0)
5013e14f97fSRoger A. Faulkner 	{	dbwarn(vm,(Vmuchar_t*)addr,offset == -1L ? 0 : 1,file,line,func,DB_RESIZE);
502*b30d1939SAndy Fiddaman 		data = NIL(Vmuchar_t*);
503da2e3ebdSchin 	}
504da2e3ebdSchin 	else
505*b30d1939SAndy Fiddaman 	{	if(Dbnwatch > 0)
506*b30d1939SAndy Fiddaman 			dbwatch(vm,addr,file,line,func,DB_RESIZE);
507*b30d1939SAndy Fiddaman 
508*b30d1939SAndy Fiddaman 		/* Vmbest data block */
509*b30d1939SAndy Fiddaman 		data = DB2BEST(addr);
510*b30d1939SAndy Fiddaman 		oldsize = DBSIZE(addr);
511*b30d1939SAndy Fiddaman 		oldfile = DBFILE(addr);
512*b30d1939SAndy Fiddaman 		oldline = DBLINE(addr);
513*b30d1939SAndy Fiddaman 
514*b30d1939SAndy Fiddaman 		/* do the resize */
515*b30d1939SAndy Fiddaman 		s = ROUND(size,ALIGN) + DB_EXTRA;
516*b30d1939SAndy Fiddaman 		if(s < sizeof(Body_t))
517*b30d1939SAndy Fiddaman 			s = sizeof(Body_t);
518*b30d1939SAndy Fiddaman 		data = (Vmuchar_t*)KPVRESIZE(vm,(Void_t*)data,s,
519*b30d1939SAndy Fiddaman 					 (type&~VM_RSZERO),(*(Vmbest->resizef)) );
520*b30d1939SAndy Fiddaman 		if(!data) /* failed, reset data for old block */
521*b30d1939SAndy Fiddaman 		{	dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_RESIZE);
522*b30d1939SAndy Fiddaman 			dbsetinfo((Vmuchar_t*)addr,oldsize,oldfile,oldline);
523*b30d1939SAndy Fiddaman 		}
524*b30d1939SAndy Fiddaman 		else
525*b30d1939SAndy Fiddaman 		{	data = DB2DEBUG(data);
526*b30d1939SAndy Fiddaman 			dbsetinfo(data,size,file,line);
527*b30d1939SAndy Fiddaman 
528*b30d1939SAndy Fiddaman 			if((vd->mode&VM_TRACE) && _Vmtrace)
529*b30d1939SAndy Fiddaman 			{	vm->file = file; vm->line = line;
530*b30d1939SAndy Fiddaman 				(*_Vmtrace)(vm,(Vmuchar_t*)addr,data,size,0);
531*b30d1939SAndy Fiddaman 			}
532*b30d1939SAndy Fiddaman 			if(Dbnwatch > 0)
533*b30d1939SAndy Fiddaman 				dbwatch(vm,data,file,line,func,DB_RESIZED);
534*b30d1939SAndy Fiddaman 		}
535da2e3ebdSchin 
536*b30d1939SAndy Fiddaman 		if(data && (type&VM_RSZERO) && size > oldsize)
537*b30d1939SAndy Fiddaman 		{	Vmuchar_t *d = data+oldsize, *ed = data+size;
538*b30d1939SAndy Fiddaman 			do { *d++ = 0; } while(d < ed);
539da2e3ebdSchin 		}
540da2e3ebdSchin 	}
541da2e3ebdSchin 
542*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
543da2e3ebdSchin 
544da2e3ebdSchin 	return (Void_t*)data;
545da2e3ebdSchin }
546da2e3ebdSchin 
547da2e3ebdSchin /* compact any residual free space */
548da2e3ebdSchin #if __STD_C
dbcompact(Vmalloc_t * vm,int local)549*b30d1939SAndy Fiddaman static int dbcompact(Vmalloc_t* vm, int local)
550da2e3ebdSchin #else
551*b30d1939SAndy Fiddaman static int dbcompact(vm, local)
552da2e3ebdSchin Vmalloc_t*	vm;
553*b30d1939SAndy Fiddaman int		local;
554da2e3ebdSchin #endif
555da2e3ebdSchin {
556*b30d1939SAndy Fiddaman 	return (*(Vmbest->compactf))(vm, local);
557da2e3ebdSchin }
558da2e3ebdSchin 
559da2e3ebdSchin /* check for memory overwrites over all live blocks */
560da2e3ebdSchin #if __STD_C
vmdbcheck(Vmalloc_t * vm)561da2e3ebdSchin int vmdbcheck(Vmalloc_t* vm)
562da2e3ebdSchin #else
563da2e3ebdSchin int vmdbcheck(vm)
564da2e3ebdSchin Vmalloc_t*	vm;
565da2e3ebdSchin #endif
566da2e3ebdSchin {
567da2e3ebdSchin 	reg Block_t	*b, *endb;
568da2e3ebdSchin 	reg Seg_t*	seg;
569da2e3ebdSchin 	int		rv;
570da2e3ebdSchin 	reg Vmdata_t*	vd = vm->data;
571da2e3ebdSchin 
572da2e3ebdSchin 	/* check the meta-data of this region */
573da2e3ebdSchin 	if(vd->mode & (VM_MTDEBUG|VM_MTBEST|VM_MTPROFILE))
574da2e3ebdSchin 	{	if(_vmbestcheck(vd, NIL(Block_t*)) < 0)
575da2e3ebdSchin 			return -1;
576*b30d1939SAndy Fiddaman 		if(!(vd->mode&VM_MTDEBUG) )
577da2e3ebdSchin 			return 0;
578da2e3ebdSchin 	}
579da2e3ebdSchin 	else	return -1;
580da2e3ebdSchin 
581da2e3ebdSchin 	rv = 0;
582da2e3ebdSchin 	for(seg = vd->seg; seg; seg = seg->next)
583da2e3ebdSchin 	{	b = SEGBLOCK(seg);
584da2e3ebdSchin 		endb = (Block_t*)(seg->baddr - sizeof(Head_t));
585da2e3ebdSchin 		while(b < endb)
586da2e3ebdSchin 		{	reg Vmuchar_t	*data, *begp, *endp;
587da2e3ebdSchin 
588da2e3ebdSchin 			if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
589da2e3ebdSchin 				goto next;
590da2e3ebdSchin 
591da2e3ebdSchin 			data = DB2DEBUG(DATA(b));
592da2e3ebdSchin 			if(DBISBAD(data))	/* seen this before */
593da2e3ebdSchin 			{	rv += 1;
594da2e3ebdSchin 				goto next;
595da2e3ebdSchin 			}
596da2e3ebdSchin 
597da2e3ebdSchin 			DBHEAD(data,begp,endp);
598da2e3ebdSchin 			for(; begp < endp; ++begp)
599da2e3ebdSchin 				if(*begp != DB_MAGIC)
600da2e3ebdSchin 					goto set_bad;
601da2e3ebdSchin 
602da2e3ebdSchin 			DBTAIL(data,begp,endp);
603da2e3ebdSchin 			for(; begp < endp; ++begp)
604da2e3ebdSchin 			{	if(*begp == DB_MAGIC)
605da2e3ebdSchin 					continue;
606da2e3ebdSchin 			set_bad:
607*b30d1939SAndy Fiddaman 				dbwarn(vm,data,(long)(begp-data),vm->file,vm->line,0,DB_CHECK);
608da2e3ebdSchin 				DBSETBAD(data);
609da2e3ebdSchin 				rv += 1;
610da2e3ebdSchin 				goto next;
611da2e3ebdSchin 			}
612da2e3ebdSchin 
613da2e3ebdSchin 		next:	b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS));
614da2e3ebdSchin 		}
615da2e3ebdSchin 	}
616da2e3ebdSchin 
617da2e3ebdSchin 	return rv;
618da2e3ebdSchin }
619da2e3ebdSchin 
620da2e3ebdSchin /* set/delete an address to watch */
621da2e3ebdSchin #if __STD_C
vmdbwatch(Void_t * addr)622da2e3ebdSchin Void_t* vmdbwatch(Void_t* addr)
623da2e3ebdSchin #else
624da2e3ebdSchin Void_t* vmdbwatch(addr)
625*b30d1939SAndy Fiddaman Void_t*		addr;	/* address to insert	*/
626da2e3ebdSchin #endif
627da2e3ebdSchin {
628da2e3ebdSchin 	reg int		n;
629da2e3ebdSchin 	reg Void_t*	out;
630da2e3ebdSchin 
631da2e3ebdSchin 	out = NIL(Void_t*);
632da2e3ebdSchin 	if(!addr)
633da2e3ebdSchin 		Dbnwatch = 0;
634da2e3ebdSchin 	else
635da2e3ebdSchin 	{	for(n = Dbnwatch - 1; n >= 0; --n)
636da2e3ebdSchin 			if(Dbwatch[n] == addr)
637da2e3ebdSchin 				break;
638da2e3ebdSchin 		if(n < 0)	/* insert */
639da2e3ebdSchin 		{	if(Dbnwatch == S_WATCH)
640da2e3ebdSchin 			{	/* delete left-most */
641da2e3ebdSchin 				out = Dbwatch[0];
642da2e3ebdSchin 				Dbnwatch -= 1;
643da2e3ebdSchin 				for(n = 0; n < Dbnwatch; ++n)
644da2e3ebdSchin 					Dbwatch[n] = Dbwatch[n+1];
645da2e3ebdSchin 			}
646da2e3ebdSchin 			Dbwatch[Dbnwatch] = addr;
647da2e3ebdSchin 			Dbnwatch += 1;
648da2e3ebdSchin 		}
649da2e3ebdSchin 	}
650da2e3ebdSchin 	return out;
651da2e3ebdSchin }
652da2e3ebdSchin 
653da2e3ebdSchin #if __STD_C
dbalign(Vmalloc_t * vm,size_t size,size_t align,int local)654*b30d1939SAndy Fiddaman static Void_t* dbalign(Vmalloc_t* vm, size_t size, size_t align, int local)
655da2e3ebdSchin #else
656*b30d1939SAndy Fiddaman static Void_t* dbalign(vm, size, align, local)
657da2e3ebdSchin Vmalloc_t*	vm;
658da2e3ebdSchin size_t		size;
659da2e3ebdSchin size_t		align;
660*b30d1939SAndy Fiddaman int		local;
661da2e3ebdSchin #endif
662da2e3ebdSchin {
663*b30d1939SAndy Fiddaman 	Vmuchar_t	*data;
664*b30d1939SAndy Fiddaman 	size_t		s;
665*b30d1939SAndy Fiddaman 	char		*file;
666*b30d1939SAndy Fiddaman 	int		line;
667*b30d1939SAndy Fiddaman 	Void_t		*func;
668*b30d1939SAndy Fiddaman 	Vmdata_t	*vd = vm->data;
669da2e3ebdSchin 	VMFLF(vm,file,line,func);
670da2e3ebdSchin 
671da2e3ebdSchin 	if(size <= 0 || align <= 0)
672da2e3ebdSchin 		return NIL(Void_t*);
673da2e3ebdSchin 
674*b30d1939SAndy Fiddaman 	SETLOCK(vm, local);
675da2e3ebdSchin 
676da2e3ebdSchin 	if((s = ROUND(size,ALIGN) + DB_EXTRA) < sizeof(Body_t))
677da2e3ebdSchin 		s = sizeof(Body_t);
678da2e3ebdSchin 
679*b30d1939SAndy Fiddaman 	if((data = (Vmuchar_t*)KPVALIGN(vm,s,align,(*(Vmbest->alignf)))) )
680*b30d1939SAndy Fiddaman 	{	data += DB_HEAD;
681*b30d1939SAndy Fiddaman 		dbsetinfo(data,size,file,line);
682da2e3ebdSchin 
683*b30d1939SAndy Fiddaman 		if((vd->mode&VM_TRACE) && _Vmtrace)
684*b30d1939SAndy Fiddaman 		{	vm->file = file; vm->line = line; vm->func = func;
685*b30d1939SAndy Fiddaman 			(*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,align);
686*b30d1939SAndy Fiddaman 		}
687da2e3ebdSchin 	}
688da2e3ebdSchin 
689*b30d1939SAndy Fiddaman 	CLRLOCK(vm, local);
690*b30d1939SAndy Fiddaman 
691da2e3ebdSchin 	return (Void_t*)data;
692da2e3ebdSchin }
693da2e3ebdSchin 
6943e14f97fSRoger A. Faulkner /* print statistics of region vm. If vm is NULL, use Vmregion */
6953e14f97fSRoger A. Faulkner #if __STD_C
vmdbstat(Vmalloc_t * vm)6963e14f97fSRoger A. Faulkner ssize_t vmdbstat(Vmalloc_t* vm)
6973e14f97fSRoger A. Faulkner #else
6983e14f97fSRoger A. Faulkner ssize_t vmdbstat(vm)
6993e14f97fSRoger A. Faulkner Vmalloc_t*	vm;
7003e14f97fSRoger A. Faulkner #endif
7013e14f97fSRoger A. Faulkner {	Vmstat_t	st;
7023e14f97fSRoger A. Faulkner 	char		buf[1024], *bufp;
7033e14f97fSRoger A. Faulkner 
7043e14f97fSRoger A. Faulkner 	vmstat(vm ? vm : Vmregion, &st);
7053e14f97fSRoger A. Faulkner 	bufp = buf;
7063e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, "n_busy", '=');
707*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_busy),-1), ',');
7083e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, " s_busy", '=');
7093e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_busy),-1), '\n');
7103e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, "n_free", '=');
711*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_free),-1), ',');
7123e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, " s_free", '=');
7133e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_free),-1), '\n');
7143e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, "m_busy", '=');
7153e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_busy),-1), ',');
7163e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, " m_free", '=');
7173e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_free),-1), '\n');
7183e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, "n_segment", '=');
719*b30d1939SAndy Fiddaman 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_seg),-1), ',');
7203e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, " extent", '=');
7213e14f97fSRoger A. Faulkner 	bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.extent),-1), '\n');
7223e14f97fSRoger A. Faulkner 	*bufp = 0;
7233e14f97fSRoger A. Faulkner 	write(Dbfd, buf, strlen(buf));
7243e14f97fSRoger A. Faulkner 	return strlen(buf);
7253e14f97fSRoger A. Faulkner }
7263e14f97fSRoger A. Faulkner 
727da2e3ebdSchin static Vmethod_t _Vmdebug =
728da2e3ebdSchin {
729da2e3ebdSchin 	dballoc,
730da2e3ebdSchin 	dbresize,
731da2e3ebdSchin 	dbfree,
732da2e3ebdSchin 	dbaddr,
733da2e3ebdSchin 	dbsize,
734da2e3ebdSchin 	dbcompact,
735da2e3ebdSchin 	dbalign,
736da2e3ebdSchin 	VM_MTDEBUG
737da2e3ebdSchin };
738da2e3ebdSchin 
739da2e3ebdSchin __DEFINE__(Vmethod_t*,Vmdebug,&_Vmdebug);
740da2e3ebdSchin 
741da2e3ebdSchin #ifdef NoF
742da2e3ebdSchin NoF(vmdebug)
743da2e3ebdSchin #endif
744da2e3ebdSchin 
745da2e3ebdSchin #endif
746