1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
18*4887Schin *                  David Korn <dgk@research.att.com>                   *
19*4887Schin *                   Phong Vo <kpv@research.att.com>                    *
20*4887Schin *                                                                      *
21*4887Schin ***********************************************************************/
22*4887Schin #if defined(_UWIN) && defined(_BLD_ast)
23*4887Schin 
24*4887Schin void _STUB_malloc(){}
25*4887Schin 
26*4887Schin #else
27*4887Schin 
28*4887Schin #if _UWIN
29*4887Schin 
30*4887Schin #define calloc		______calloc
31*4887Schin #define _ast_free	______free
32*4887Schin #define malloc		______malloc
33*4887Schin #define mallinfo	______mallinfo
34*4887Schin #define mallopt		______mallopt
35*4887Schin #define mstats		______mstats
36*4887Schin #define realloc		______realloc
37*4887Schin 
38*4887Schin #define _STDLIB_H_	1
39*4887Schin 
40*4887Schin extern int		atexit(void(*)(void));
41*4887Schin extern char*		getenv(const char*);
42*4887Schin 
43*4887Schin #endif
44*4887Schin 
45*4887Schin #include	"vmhdr.h"
46*4887Schin 
47*4887Schin #if _UWIN
48*4887Schin 
49*4887Schin #include	<malloc.h>
50*4887Schin 
51*4887Schin #define _map_malloc	1
52*4887Schin #define _mal_alloca	1
53*4887Schin 
54*4887Schin #undef	calloc
55*4887Schin #define calloc		_ast_calloc
56*4887Schin #undef	_ast_free
57*4887Schin #define free		_ast_free
58*4887Schin #undef	malloc
59*4887Schin #define malloc		_ast_malloc
60*4887Schin #undef	mallinfo
61*4887Schin typedef struct ______mallinfo Mallinfo_t;
62*4887Schin #undef	mallopt
63*4887Schin #undef	mstats
64*4887Schin typedef struct ______mstats Mstats_t;
65*4887Schin #undef	realloc
66*4887Schin #define realloc		_ast_realloc
67*4887Schin 
68*4887Schin #endif
69*4887Schin 
70*4887Schin #if __STD_C
71*4887Schin #define F0(f,t0)		f(t0)
72*4887Schin #define F1(f,t1,a1)		f(t1 a1)
73*4887Schin #define F2(f,t1,a1,t2,a2)	f(t1 a1, t2 a2)
74*4887Schin #else
75*4887Schin #define F0(f,t0)		f()
76*4887Schin #define F1(f,t1,a1)		f(a1) t1 a1;
77*4887Schin #define F2(f,t1,a1,t2,a2)	f(a1, a2) t1 a1; t2 a2;
78*4887Schin #endif
79*4887Schin 
80*4887Schin /*
81*4887Schin  * define _AST_std_malloc=1 to force the standard malloc
82*4887Schin  * if _map_malloc is also defined then _ast_malloc etc.
83*4887Schin  * will simply call malloc etc.
84*4887Schin  */
85*4887Schin 
86*4887Schin #if !defined(_AST_std_malloc) && __CYGWIN__
87*4887Schin #define _AST_std_malloc	1
88*4887Schin #endif
89*4887Schin 
90*4887Schin #if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
91*4887Schin 
92*4887Schin /*	malloc compatibility functions.
93*4887Schin **	These are aware of debugging/profiling and driven by the environment variables:
94*4887Schin **	VMETHOD: select an allocation method by name.
95*4887Schin **
96*4887Schin **	VMPROFILE: if is a file name, write profile data to it.
97*4887Schin **	VMTRACE: if is a file name, write trace data to it.
98*4887Schin **	The pattern %p in a file name will be replaced by the process ID.
99*4887Schin **
100*4887Schin **	VMDEBUG:
101*4887Schin **		a:			abort on any warning.
102*4887Schin **		w[decimal]:		file descriptor for warnings.
103*4887Schin **		[decimal]:		period to check arena.
104*4887Schin **		0x[hexadecimal]:	address to watch.
105*4887Schin **
106*4887Schin **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
107*4887Schin */
108*4887Schin 
109*4887Schin #if _sys_stat
110*4887Schin #include	<sys/stat.h>
111*4887Schin #endif
112*4887Schin #include	<fcntl.h>
113*4887Schin 
114*4887Schin #ifdef S_IRUSR
115*4887Schin #define CREAT_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
116*4887Schin #else
117*4887Schin #define CREAT_MODE	0644
118*4887Schin #endif
119*4887Schin 
120*4887Schin #if !_map_malloc
121*4887Schin #undef calloc
122*4887Schin #undef cfree
123*4887Schin #undef free
124*4887Schin #undef mallinfo
125*4887Schin #undef malloc
126*4887Schin #undef mallopt
127*4887Schin #undef memalign
128*4887Schin #undef mstats
129*4887Schin #undef realloc
130*4887Schin #undef valloc
131*4887Schin #endif
132*4887Schin 
133*4887Schin #if _WINIX
134*4887Schin 
135*4887Schin #include <ast_windows.h>
136*4887Schin 
137*4887Schin #if _UWIN
138*4887Schin 
139*4887Schin #define VMRECORD(p)	_vmrecord(p)
140*4887Schin #define VMBLOCK		{ int _vmblock = _sigblock();
141*4887Schin #define VMUNBLOCK	_sigunblock(_vmblock); }
142*4887Schin 
143*4887Schin extern int		_sigblock(void);
144*4887Schin extern void		_sigunblock(int);
145*4887Schin extern unsigned long	_record[2048];
146*4887Schin 
147*4887Schin __inline Void_t* _vmrecord(Void_t* p)
148*4887Schin {
149*4887Schin 	register unsigned long	v = ((unsigned long)p)>>16;
150*4887Schin 
151*4887Schin 	_record[v>>5] |= 1<<((v&0x1f));
152*4887Schin 	return p;
153*4887Schin }
154*4887Schin 
155*4887Schin #else
156*4887Schin 
157*4887Schin #define getenv(s)	lcl_getenv(s)
158*4887Schin 
159*4887Schin static char*
160*4887Schin lcl_getenv(const char* s)
161*4887Schin {
162*4887Schin 	int		n;
163*4887Schin 	static char	buf[512];
164*4887Schin 
165*4887Schin 	if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
166*4887Schin 		return 0;
167*4887Schin 	return buf;
168*4887Schin }
169*4887Schin 
170*4887Schin #endif /* _UWIN */
171*4887Schin 
172*4887Schin #endif /* _WINIX */
173*4887Schin 
174*4887Schin #ifndef VMRECORD
175*4887Schin #define VMRECORD(p)	(p)
176*4887Schin #define VMBLOCK
177*4887Schin #define VMUNBLOCK
178*4887Schin #endif
179*4887Schin 
180*4887Schin #if defined(__EXPORT__)
181*4887Schin #define extern		extern __EXPORT__
182*4887Schin #endif
183*4887Schin 
184*4887Schin #if __STD_C
185*4887Schin static Vmulong_t atou(char** sp)
186*4887Schin #else
187*4887Schin static Vmulong_t atou(sp)
188*4887Schin char**	sp;
189*4887Schin #endif
190*4887Schin {
191*4887Schin 	char*		s = *sp;
192*4887Schin 	Vmulong_t	v = 0;
193*4887Schin 
194*4887Schin 	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
195*4887Schin 	{	for(s += 2; *s; ++s)
196*4887Schin 		{	if(*s >= '0' && *s <= '9')
197*4887Schin 				v = (v << 4) + (*s - '0');
198*4887Schin 			else if(*s >= 'a' && *s <= 'f')
199*4887Schin 				v = (v << 4) + (*s - 'a') + 10;
200*4887Schin 			else if(*s >= 'A' && *s <= 'F')
201*4887Schin 				v = (v << 4) + (*s - 'A') + 10;
202*4887Schin 			else break;
203*4887Schin 		}
204*4887Schin 	}
205*4887Schin 	else
206*4887Schin 	{	for(; *s; ++s)
207*4887Schin 		{	if(*s >= '0' && *s <= '9')
208*4887Schin 				v = v*10 + (*s - '0');
209*4887Schin 			else break;
210*4887Schin 		}
211*4887Schin 	}
212*4887Schin 
213*4887Schin 	*sp = s;
214*4887Schin 	return v;
215*4887Schin }
216*4887Schin 
217*4887Schin static int		_Vmflinit = 0;
218*4887Schin static Vmulong_t	_Vmdbstart = 0;
219*4887Schin static Vmulong_t	_Vmdbcheck = 0;
220*4887Schin static Vmulong_t	_Vmdbtime = 0;
221*4887Schin static int		_Vmpffd = -1;
222*4887Schin #define VMFLINIT() \
223*4887Schin 	{ if(!_Vmflinit)	vmflinit(); \
224*4887Schin 	  if(_Vmdbcheck) \
225*4887Schin 	  { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
226*4887Schin 	    else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
227*4887Schin 	    if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
228*4887Schin 	       Vmregion->meth.meth == VM_MTDEBUG) \
229*4887Schin 		vmdbcheck(Vmregion); \
230*4887Schin 	  } \
231*4887Schin 	}
232*4887Schin 
233*4887Schin #if __STD_C
234*4887Schin static char* insertpid(char* begs, char* ends)
235*4887Schin #else
236*4887Schin static char* insertpid(begs,ends)
237*4887Schin char*	begs;
238*4887Schin char*	ends;
239*4887Schin #endif
240*4887Schin {	int	pid;
241*4887Schin 	char*	s;
242*4887Schin 
243*4887Schin 	if((pid = getpid()) < 0)
244*4887Schin 		return NIL(char*);
245*4887Schin 
246*4887Schin 	s = ends;
247*4887Schin 	do
248*4887Schin 	{	if(s == begs)
249*4887Schin 			return NIL(char*);
250*4887Schin 		*--s = '0' + pid%10;
251*4887Schin 	} while((pid /= 10) > 0);
252*4887Schin 	while(s < ends)
253*4887Schin 		*begs++ = *s++;
254*4887Schin 
255*4887Schin 	return begs;
256*4887Schin }
257*4887Schin 
258*4887Schin #if __STD_C
259*4887Schin static int createfile(char* file)
260*4887Schin #else
261*4887Schin static int createfile(file)
262*4887Schin char*	file;
263*4887Schin #endif
264*4887Schin {
265*4887Schin 	char	buf[1024];
266*4887Schin 	char	*next, *endb;
267*4887Schin 
268*4887Schin 	next = buf;
269*4887Schin 	endb = buf + sizeof(buf);
270*4887Schin 	while(*file)
271*4887Schin 	{	if(*file == '%')
272*4887Schin 		{	switch(file[1])
273*4887Schin 			{
274*4887Schin 			case 'p' :
275*4887Schin 				if(!(next = insertpid(next,endb)) )
276*4887Schin 					return -1;
277*4887Schin 				file += 2;
278*4887Schin 				break;
279*4887Schin 			default :
280*4887Schin 				goto copy;
281*4887Schin 			}
282*4887Schin 		}
283*4887Schin 		else
284*4887Schin 		{ copy:
285*4887Schin 			*next++ = *file++;
286*4887Schin 		}
287*4887Schin 
288*4887Schin 		if(next >= endb)
289*4887Schin 			return -1;
290*4887Schin 	}
291*4887Schin 
292*4887Schin 	*next = '\0';
293*4887Schin #if _PACKAGE_ast
294*4887Schin 	{	int	fd;
295*4887Schin 		fd = open(buf,O_WRONLY|O_CREAT|O_TRUNC,CREAT_MODE);
296*4887Schin #ifdef FD_CLOEXEC
297*4887Schin 		if (fd >= 0)
298*4887Schin 			fcntl(fd, F_SETFD, FD_CLOEXEC);
299*4887Schin #endif
300*4887Schin 		return fd;
301*4887Schin 	}
302*4887Schin #else
303*4887Schin 	return creat(buf,CREAT_MODE);
304*4887Schin #endif
305*4887Schin }
306*4887Schin 
307*4887Schin #if __STD_C
308*4887Schin static void pfprint(void)
309*4887Schin #else
310*4887Schin static void pfprint()
311*4887Schin #endif
312*4887Schin {
313*4887Schin 	if(Vmregion->meth.meth == VM_MTPROFILE)
314*4887Schin 		vmprofile(Vmregion,_Vmpffd);
315*4887Schin }
316*4887Schin 
317*4887Schin #if __STD_C
318*4887Schin static int vmflinit(void)
319*4887Schin #else
320*4887Schin static int vmflinit()
321*4887Schin #endif
322*4887Schin {
323*4887Schin 	char*		env;
324*4887Schin 	Vmalloc_t*	vm;
325*4887Schin 	int		fd;
326*4887Schin 	Vmulong_t	addr;
327*4887Schin 	char*		file;
328*4887Schin 	int		line;
329*4887Schin 	Void_t*		func;
330*4887Schin 
331*4887Schin 	/* this must be done now to avoid any inadvertent recursion (more below) */
332*4887Schin 	_Vmflinit = 1;
333*4887Schin 	VMFLF(Vmregion,file,line,func);
334*4887Schin 
335*4887Schin 	/* if getenv() calls malloc(), the eventual region may not see this */
336*4887Schin 	vm = NIL(Vmalloc_t*);
337*4887Schin 	if((env = getenv("VMETHOD")) )
338*4887Schin 	{	if(strcmp(env,"Vmdebug") == 0 || strcmp(env,"vmdebug") == 0)
339*4887Schin 			vm = vmopen(Vmdcsbrk,Vmdebug,0);
340*4887Schin 		else if(strcmp(env,"Vmprofile") == 0 || strcmp(env,"vmprofile") == 0 )
341*4887Schin 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
342*4887Schin 		else if(strcmp(env,"Vmlast") == 0 || strcmp(env,"vmlast") == 0 )
343*4887Schin 			vm = vmopen(Vmdcsbrk,Vmlast,0);
344*4887Schin 		else if(strcmp(env,"Vmbest") == 0 || strcmp(env,"vmbest") == 0 )
345*4887Schin 			vm = Vmheap;
346*4887Schin 	}
347*4887Schin 
348*4887Schin 	if((!vm || vm->meth.meth == VM_MTDEBUG) &&
349*4887Schin 	   (env = getenv("VMDEBUG")) && env[0] )
350*4887Schin 	{	if(vm || (vm = vmopen(Vmdcsbrk,Vmdebug,0)) )
351*4887Schin 		{	reg int	setcheck = 0;
352*4887Schin 
353*4887Schin 			while(*env)
354*4887Schin 			{	if(*env == 'a')
355*4887Schin 				{	vmset(vm,VM_DBABORT,1);
356*4887Schin 					env += 1;
357*4887Schin 				}
358*4887Schin 				else if(*env =='w')
359*4887Schin 				{	env += 1;
360*4887Schin 					if((fd = atou(&env)) >= 0 )
361*4887Schin 						vmdebug(fd);
362*4887Schin 				}
363*4887Schin 				else if(*env < '0' || *env > '9')
364*4887Schin 					env += 1;
365*4887Schin 				else if(env[0] == '0' && (env[1] == 'x' || env[1] == 'X') )
366*4887Schin 				{	if((addr = atou(&env)) != 0)
367*4887Schin 						vmdbwatch((Void_t*)addr);
368*4887Schin 				}
369*4887Schin 				else
370*4887Schin 				{	_Vmdbcheck = atou(&env);
371*4887Schin 					setcheck = 1;
372*4887Schin 					if(*env == ',')
373*4887Schin 					{	env += 1;
374*4887Schin 						_Vmdbstart = atou(&env);
375*4887Schin 					}
376*4887Schin 				}
377*4887Schin 			}
378*4887Schin 			if(!setcheck)
379*4887Schin 				_Vmdbcheck = 1;
380*4887Schin 		}
381*4887Schin 	}
382*4887Schin 
383*4887Schin 	if((!vm || vm->meth.meth == VM_MTPROFILE) &&
384*4887Schin 	   (env = getenv("VMPROFILE")) && env[0] )
385*4887Schin 	{	_Vmpffd = createfile(env);
386*4887Schin 		if(!vm)
387*4887Schin 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
388*4887Schin 	}
389*4887Schin 
390*4887Schin 	/* slip in the new region now so that malloc() will work fine */
391*4887Schin 	if(vm)
392*4887Schin 		Vmregion = vm;
393*4887Schin 
394*4887Schin 	/* turn on tracing if requested */
395*4887Schin 	if((env = getenv("VMTRACE")) && env[0] && (fd = createfile(env)) >= 0)
396*4887Schin 	{	vmset(Vmregion,VM_TRACE,1);
397*4887Schin 		vmtrace(fd);
398*4887Schin 	}
399*4887Schin 
400*4887Schin 	/* make sure that profile data is output upon exiting */
401*4887Schin 	if(vm && vm->meth.meth == VM_MTPROFILE)
402*4887Schin 	{	if(_Vmpffd < 0)
403*4887Schin 			_Vmpffd = 2;
404*4887Schin 		/* this may wind up calling malloc(), but region is ok now */
405*4887Schin 		atexit(pfprint);
406*4887Schin 	}
407*4887Schin 	else if(_Vmpffd >= 0)
408*4887Schin 	{	close(_Vmpffd);
409*4887Schin 		_Vmpffd = -1;
410*4887Schin 	}
411*4887Schin 
412*4887Schin 	/* reset file and line number to correct values for the call */
413*4887Schin 	Vmregion->file = file;
414*4887Schin 	Vmregion->line = line;
415*4887Schin 	Vmregion->func = func;
416*4887Schin 
417*4887Schin 	return 0;
418*4887Schin }
419*4887Schin 
420*4887Schin #if __STD_C
421*4887Schin extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
422*4887Schin #else
423*4887Schin extern Void_t* calloc(n_obj, s_obj)
424*4887Schin reg size_t	n_obj;
425*4887Schin reg size_t	s_obj;
426*4887Schin #endif
427*4887Schin {
428*4887Schin 	VMFLINIT();
429*4887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO));
430*4887Schin }
431*4887Schin 
432*4887Schin #if __STD_C
433*4887Schin extern Void_t* malloc(reg size_t size)
434*4887Schin #else
435*4887Schin extern Void_t* malloc(size)
436*4887Schin reg size_t	size;
437*4887Schin #endif
438*4887Schin {
439*4887Schin 	VMFLINIT();
440*4887Schin 	return VMRECORD((*Vmregion->meth.allocf)(Vmregion,size));
441*4887Schin }
442*4887Schin 
443*4887Schin #if __STD_C
444*4887Schin extern Void_t* realloc(reg Void_t* data, reg size_t size)
445*4887Schin #else
446*4887Schin extern Void_t* realloc(data,size)
447*4887Schin reg Void_t*	data;	/* block to be reallocated	*/
448*4887Schin reg size_t	size;	/* new size			*/
449*4887Schin #endif
450*4887Schin {
451*4887Schin #if USE_NATIVE
452*4887Schin #undef	realloc
453*4887Schin #if __STD_C
454*4887Schin 	extern Void_t*	realloc(Void_t*, size_t);
455*4887Schin #else
456*4887Schin 	extern Void_t*	realloc();
457*4887Schin #endif
458*4887Schin #endif
459*4887Schin 
460*4887Schin 	VMFLINIT();
461*4887Schin 
462*4887Schin #if _PACKAGE_ast
463*4887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
464*4887Schin #if !USE_NATIVE
465*4887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
466*4887Schin #endif
467*4887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0 )
468*4887Schin 	{
469*4887Schin #if USE_NATIVE
470*4887Schin 		return realloc(data, size);
471*4887Schin #else
472*4887Schin 		Void_t*	newdata;
473*4887Schin 		if((newdata = (*Vmregion->meth.allocf)(Vmregion,size)) )
474*4887Schin 			memcpy(newdata,data,size);
475*4887Schin 		return VMRECORD(newdata);
476*4887Schin #endif
477*4887Schin 	}
478*4887Schin #endif
479*4887Schin 
480*4887Schin #if USE_NATIVE
481*4887Schin 	{	Void_t*	newdata;
482*4887Schin 		if (newdata = (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE))
483*4887Schin 			return newdata;
484*4887Schin 		return VMRECORD(realloc(data, size));
485*4887Schin 	}
486*4887Schin #else
487*4887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE));
488*4887Schin #endif
489*4887Schin }
490*4887Schin 
491*4887Schin #if __STD_C
492*4887Schin extern void free(reg Void_t* data)
493*4887Schin #else
494*4887Schin extern void free(data)
495*4887Schin reg Void_t*	data;
496*4887Schin #endif
497*4887Schin {
498*4887Schin #if USE_NATIVE
499*4887Schin #undef	free
500*4887Schin #if __STD_C
501*4887Schin 	extern void	free(Void_t*);
502*4887Schin #else
503*4887Schin 	extern void	free();
504*4887Schin #endif
505*4887Schin #endif
506*4887Schin 
507*4887Schin 	VMFLINIT();
508*4887Schin 
509*4887Schin #if _PACKAGE_ast
510*4887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
511*4887Schin #if !USE_NATIVE
512*4887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
513*4887Schin #endif
514*4887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0)
515*4887Schin 	{
516*4887Schin #if USE_NATIVE
517*4887Schin 		free(data);
518*4887Schin #endif
519*4887Schin 		return;
520*4887Schin 	}
521*4887Schin #endif
522*4887Schin 
523*4887Schin #if USE_NATIVE
524*4887Schin 	if ((*Vmregion->meth.freef)(Vmregion,data) != 0)
525*4887Schin 		free(data);
526*4887Schin #else
527*4887Schin 	(void)(*Vmregion->meth.freef)(Vmregion,data);
528*4887Schin #endif
529*4887Schin }
530*4887Schin 
531*4887Schin #if __STD_C
532*4887Schin extern void cfree(reg Void_t* data)
533*4887Schin #else
534*4887Schin extern void cfree(data)
535*4887Schin reg Void_t*	data;
536*4887Schin #endif
537*4887Schin {
538*4887Schin 	free(data);
539*4887Schin }
540*4887Schin 
541*4887Schin #if __STD_C
542*4887Schin extern Void_t* memalign(reg size_t align, reg size_t size)
543*4887Schin #else
544*4887Schin extern Void_t* memalign(align, size)
545*4887Schin reg size_t	align;
546*4887Schin reg size_t	size;
547*4887Schin #endif
548*4887Schin {
549*4887Schin 	Void_t*	addr;
550*4887Schin 
551*4887Schin 	VMFLINIT();
552*4887Schin 	VMBLOCK
553*4887Schin 	addr = VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,align));
554*4887Schin 	VMUNBLOCK
555*4887Schin 	return addr;
556*4887Schin }
557*4887Schin 
558*4887Schin #if __STD_C
559*4887Schin extern Void_t* valloc(reg size_t size)
560*4887Schin #else
561*4887Schin extern Void_t* valloc(size)
562*4887Schin reg size_t	size;
563*4887Schin #endif
564*4887Schin {
565*4887Schin 	VMFLINIT();
566*4887Schin 	GETPAGESIZE(_Vmpagesize);
567*4887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize));
568*4887Schin }
569*4887Schin 
570*4887Schin #if __STD_C
571*4887Schin extern Void_t* pvalloc(reg size_t size)
572*4887Schin #else
573*4887Schin extern Void_t* pvalloc(size)
574*4887Schin reg size_t	size;
575*4887Schin #endif
576*4887Schin {
577*4887Schin 	VMFLINIT();
578*4887Schin 	GETPAGESIZE(_Vmpagesize);
579*4887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,ROUND(size,_Vmpagesize),_Vmpagesize));
580*4887Schin }
581*4887Schin 
582*4887Schin #if !_PACKAGE_ast
583*4887Schin #if __STD_C
584*4887Schin char* strdup(const char* s)
585*4887Schin #else
586*4887Schin char* strdup(s)
587*4887Schin char*	s;
588*4887Schin #endif
589*4887Schin {
590*4887Schin 	char	*ns;
591*4887Schin 	size_t	n;
592*4887Schin 
593*4887Schin 	if(!s)
594*4887Schin 		return NIL(char*);
595*4887Schin 	else
596*4887Schin 	{	n = strlen(s);
597*4887Schin 		if((ns = malloc(n+1)) )
598*4887Schin 			memcpy(ns,s,n+1);
599*4887Schin 		return ns;
600*4887Schin 	}
601*4887Schin }
602*4887Schin #endif /* _PACKAGE_ast */
603*4887Schin 
604*4887Schin #if !_lib_alloca || _mal_alloca
605*4887Schin #ifndef _stk_down
606*4887Schin #define _stk_down	0
607*4887Schin #endif
608*4887Schin typedef struct _alloca_s	Alloca_t;
609*4887Schin union _alloca_u
610*4887Schin {	struct
611*4887Schin 	{	char*		addr;
612*4887Schin 		Alloca_t*	next;
613*4887Schin 	} head;
614*4887Schin 	char	array[ALIGN];
615*4887Schin };
616*4887Schin struct _alloca_s
617*4887Schin {	union _alloca_u	head;
618*4887Schin 	Vmuchar_t	data[1];
619*4887Schin };
620*4887Schin 
621*4887Schin #if __STD_C
622*4887Schin extern Void_t* alloca(size_t size)
623*4887Schin #else
624*4887Schin extern Void_t* alloca(size)
625*4887Schin size_t	size;
626*4887Schin #endif
627*4887Schin {	char		array[ALIGN];
628*4887Schin 	char*		file;
629*4887Schin 	int		line;
630*4887Schin 	Void_t*		func;
631*4887Schin 	reg Alloca_t*	f;
632*4887Schin 	static Alloca_t* Frame;
633*4887Schin 
634*4887Schin 	VMFLINIT();
635*4887Schin 	VMFLF(Vmregion,file,line,func);
636*4887Schin 	while(Frame)
637*4887Schin 	{	if(( _stk_down && &array[0] > Frame->head.head.addr) ||
638*4887Schin 		   (!_stk_down && &array[0] < Frame->head.head.addr) )
639*4887Schin 		{	f = Frame;
640*4887Schin 			Frame = f->head.head.next;
641*4887Schin 			(void)(*Vmregion->meth.freef)(Vmregion,f);
642*4887Schin 		}
643*4887Schin 		else	break;
644*4887Schin 	}
645*4887Schin 
646*4887Schin 	Vmregion->file = file;
647*4887Schin 	Vmregion->line = line;
648*4887Schin 	Vmregion->func = func;
649*4887Schin 	f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
650*4887Schin 
651*4887Schin 	f->head.head.addr = &array[0];
652*4887Schin 	f->head.head.next = Frame;
653*4887Schin 	Frame = f;
654*4887Schin 
655*4887Schin 	return (Void_t*)f->data;
656*4887Schin }
657*4887Schin #endif /*!_lib_alloca || _mal_alloca*/
658*4887Schin 
659*4887Schin #if _map_malloc
660*4887Schin 
661*4887Schin /* not sure of all the implications -- 0 is conservative for now */
662*4887Schin #define USE_NATIVE	0	/* native free/realloc on non-vmalloc ptrs */
663*4887Schin 
664*4887Schin #else
665*4887Schin 
666*4887Schin /* intercept _* __* __libc_* variants */
667*4887Schin 
668*4887Schin #if __lib__malloc
669*4887Schin extern Void_t*	F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
670*4887Schin extern Void_t	F1(_cfree, Void_t*,p) { free(p); }
671*4887Schin extern Void_t	F1(_free, Void_t*,p) { free(p); }
672*4887Schin extern Void_t*	F1(_malloc, size_t,n) { return malloc(n); }
673*4887Schin #if _lib_memalign
674*4887Schin extern Void_t*	F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
675*4887Schin #endif
676*4887Schin #if _lib_pvalloc
677*4887Schin extern Void_t*	F1(_pvalloc, size_t,n) { return pvalloc(n); }
678*4887Schin #endif
679*4887Schin extern Void_t*	F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
680*4887Schin #if _lib_valloc
681*4887Schin extern Void_t*	F1(_valloc, size_t,n) { return valloc(n); }
682*4887Schin #endif
683*4887Schin #endif
684*4887Schin 
685*4887Schin #if _lib___malloc
686*4887Schin extern Void_t*	F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
687*4887Schin extern Void_t	F1(__cfree, Void_t*,p) { free(p); }
688*4887Schin extern Void_t	F1(__free, Void_t*,p) { free(p); }
689*4887Schin extern Void_t*	F1(__malloc, size_t,n) { return malloc(n); }
690*4887Schin #if _lib_memalign
691*4887Schin extern Void_t*	F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
692*4887Schin #endif
693*4887Schin #if _lib_pvalloc
694*4887Schin extern Void_t*	F1(__pvalloc, size_t,n) { return pvalloc(n); }
695*4887Schin #endif
696*4887Schin extern Void_t*	F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
697*4887Schin #if _lib_valloc
698*4887Schin extern Void_t*	F1(__valloc, size_t,n) { return valloc(n); }
699*4887Schin #endif
700*4887Schin #endif
701*4887Schin 
702*4887Schin #if _lib___libc_malloc
703*4887Schin extern Void_t*	F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
704*4887Schin extern Void_t	F1(__libc_cfree, Void_t*,p) { free(p); }
705*4887Schin extern Void_t	F1(__libc_free, Void_t*,p) { free(p); }
706*4887Schin extern Void_t*	F1(__libc_malloc, size_t,n) { return malloc(n); }
707*4887Schin #if _lib_memalign
708*4887Schin extern Void_t*	F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
709*4887Schin #endif
710*4887Schin #if _lib_pvalloc
711*4887Schin extern Void_t*	F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
712*4887Schin #endif
713*4887Schin extern Void_t*	F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
714*4887Schin #if _lib_valloc
715*4887Schin extern Void_t*	F1(__libc_valloc, size_t,n) { return valloc(n); }
716*4887Schin #endif
717*4887Schin #endif
718*4887Schin 
719*4887Schin #endif /* _map_malloc */
720*4887Schin 
721*4887Schin #undef	extern
722*4887Schin 
723*4887Schin #if _hdr_malloc /* need the mallint interface for statistics, etc. */
724*4887Schin 
725*4887Schin #undef	calloc
726*4887Schin #define calloc		______calloc
727*4887Schin #undef	cfree
728*4887Schin #define cfree		______cfree
729*4887Schin #undef	free
730*4887Schin #define free		______free
731*4887Schin #undef	malloc
732*4887Schin #define malloc		______malloc
733*4887Schin #undef	pvalloc
734*4887Schin #define pvalloc		______pvalloc
735*4887Schin #undef	realloc
736*4887Schin #define realloc		______realloc
737*4887Schin #undef	valloc
738*4887Schin #define valloc		______valloc
739*4887Schin 
740*4887Schin #if !_UWIN
741*4887Schin 
742*4887Schin #include	<malloc.h>
743*4887Schin 
744*4887Schin typedef struct mallinfo Mallinfo_t;
745*4887Schin typedef struct mstats Mstats_t;
746*4887Schin 
747*4887Schin #endif
748*4887Schin 
749*4887Schin #if defined(__EXPORT__)
750*4887Schin #define extern		__EXPORT__
751*4887Schin #endif
752*4887Schin 
753*4887Schin #if _lib_mallopt
754*4887Schin #if __STD_C
755*4887Schin extern int mallopt(int cmd, int value)
756*4887Schin #else
757*4887Schin extern int mallopt(cmd, value)
758*4887Schin int	cmd;
759*4887Schin int	value;
760*4887Schin #endif
761*4887Schin {
762*4887Schin 	VMFLINIT();
763*4887Schin 	return 0;
764*4887Schin }
765*4887Schin #endif /*_lib_mallopt*/
766*4887Schin 
767*4887Schin #if _lib_mallinfo && _mem_arena_mallinfo
768*4887Schin #if __STD_C
769*4887Schin extern Mallinfo_t mallinfo(void)
770*4887Schin #else
771*4887Schin extern Mallinfo_t mallinfo()
772*4887Schin #endif
773*4887Schin {
774*4887Schin 	Vmstat_t	sb;
775*4887Schin 	Mallinfo_t	mi;
776*4887Schin 
777*4887Schin 	VMFLINIT();
778*4887Schin 	memset(&mi,0,sizeof(mi));
779*4887Schin 	if(vmstat(Vmregion,&sb) >= 0)
780*4887Schin 	{	mi.arena = sb.extent;
781*4887Schin 		mi.ordblks = sb.n_busy+sb.n_free;
782*4887Schin 		mi.uordblks = sb.s_busy;
783*4887Schin 		mi.fordblks = sb.s_free;
784*4887Schin 	}
785*4887Schin 	return mi;
786*4887Schin }
787*4887Schin #endif /* _lib_mallinfo */
788*4887Schin 
789*4887Schin #if _lib_mstats && _mem_bytes_total_mstats
790*4887Schin #if __STD_C
791*4887Schin extern Mstats_t mstats(void)
792*4887Schin #else
793*4887Schin extern Mstats_t mstats()
794*4887Schin #endif
795*4887Schin {
796*4887Schin 	Vmstat_t	sb;
797*4887Schin 	Mstats_t	ms;
798*4887Schin 
799*4887Schin 	VMFLINIT();
800*4887Schin 	memset(&ms,0,sizeof(ms));
801*4887Schin 	if(vmstat(Vmregion,&sb) >= 0)
802*4887Schin 	{	ms.bytes_total = sb.extent;
803*4887Schin 		ms.chunks_used = sb.n_busy;
804*4887Schin 		ms.bytes_used = sb.s_busy;
805*4887Schin 		ms.chunks_free = sb.n_free;
806*4887Schin 		ms.bytes_free = sb.s_free;
807*4887Schin 	}
808*4887Schin 	return ms;
809*4887Schin }
810*4887Schin #endif /*_lib_mstats*/
811*4887Schin 
812*4887Schin #undef	extern
813*4887Schin 
814*4887Schin #endif/*_hdr_malloc*/
815*4887Schin 
816*4887Schin #else
817*4887Schin 
818*4887Schin /*
819*4887Schin  * even though there is no malloc override, still provide
820*4887Schin  * _ast_* counterparts for object compatibility
821*4887Schin  */
822*4887Schin 
823*4887Schin #undef	calloc
824*4887Schin extern Void_t*	calloc _ARG_((size_t, size_t));
825*4887Schin 
826*4887Schin #undef	cfree
827*4887Schin extern void	cfree _ARG_((Void_t*));
828*4887Schin 
829*4887Schin #undef	free
830*4887Schin extern void	free _ARG_((Void_t*));
831*4887Schin 
832*4887Schin #undef	malloc
833*4887Schin extern Void_t*	malloc _ARG_((size_t));
834*4887Schin 
835*4887Schin #if _lib_memalign
836*4887Schin #undef	memalign
837*4887Schin extern Void_t*	memalign _ARG_((size_t, size_t));
838*4887Schin #endif
839*4887Schin 
840*4887Schin #if _lib_pvalloc
841*4887Schin #undef	pvalloc
842*4887Schin extern Void_t*	pvalloc _ARG_((size_t));
843*4887Schin #endif
844*4887Schin 
845*4887Schin #undef	realloc
846*4887Schin extern Void_t*	realloc _ARG_((Void_t*, size_t));
847*4887Schin 
848*4887Schin #if _lib_valloc
849*4887Schin #undef	valloc
850*4887Schin extern Void_t*	valloc _ARG_((size_t));
851*4887Schin #endif
852*4887Schin 
853*4887Schin #if defined(__EXPORT__)
854*4887Schin #define extern		__EXPORT__
855*4887Schin #endif
856*4887Schin 
857*4887Schin extern Void_t*	F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
858*4887Schin extern Void_t	F1(_ast_cfree, Void_t*,p) { free(p); }
859*4887Schin extern Void_t	F1(_ast_free, Void_t*,p) { free(p); }
860*4887Schin extern Void_t*	F1(_ast_malloc, size_t,n) { return malloc(n); }
861*4887Schin #if _lib_memalign
862*4887Schin extern Void_t*	F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
863*4887Schin #endif
864*4887Schin #if _lib_pvalloc
865*4887Schin extern Void_t*	F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
866*4887Schin #endif
867*4887Schin extern Void_t*	F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
868*4887Schin #if _lib_valloc
869*4887Schin extern Void_t*	F1(_ast_valloc, size_t,n) { return valloc(n); }
870*4887Schin #endif
871*4887Schin 
872*4887Schin #undef	extern
873*4887Schin 
874*4887Schin #if _hdr_malloc
875*4887Schin 
876*4887Schin #undef	mallinfo
877*4887Schin #undef	mallopt
878*4887Schin #undef	mstats
879*4887Schin 
880*4887Schin #define calloc		______calloc
881*4887Schin #define cfree		______cfree
882*4887Schin #define free		______free
883*4887Schin #define malloc		______malloc
884*4887Schin #define pvalloc		______pvalloc
885*4887Schin #define realloc		______realloc
886*4887Schin #define valloc		______valloc
887*4887Schin 
888*4887Schin #if !_UWIN
889*4887Schin 
890*4887Schin #include	<malloc.h>
891*4887Schin 
892*4887Schin typedef struct mallinfo Mallinfo_t;
893*4887Schin typedef struct mstats Mstats_t;
894*4887Schin 
895*4887Schin #endif
896*4887Schin 
897*4887Schin #if defined(__EXPORT__)
898*4887Schin #define extern		__EXPORT__
899*4887Schin #endif
900*4887Schin 
901*4887Schin #if _lib_mallopt
902*4887Schin extern int	F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
903*4887Schin #endif
904*4887Schin 
905*4887Schin #if _lib_mallinfo && _mem_arena_mallinfo
906*4887Schin extern Mallinfo_t	F0(_ast_mallinfo, void) { return mallinfo(); }
907*4887Schin #endif
908*4887Schin 
909*4887Schin #if _lib_mstats && _mem_bytes_total_mstats
910*4887Schin extern Mstats_t		F0(_ast_mstats, void) { return mstats(); }
911*4887Schin #endif
912*4887Schin 
913*4887Schin #undef	extern
914*4887Schin 
915*4887Schin #endif /*_hdr_malloc*/
916*4887Schin 
917*4887Schin #endif /*!_std_malloc*/
918*4887Schin 
919*4887Schin #endif /*_UWIN*/
920