14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*8462SApril.Chin@Sun.COM *          Copyright (c) 1985-2008 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
7*8462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #if defined(_UWIN) && defined(_BLD_ast)
234887Schin 
244887Schin void _STUB_malloc(){}
254887Schin 
264887Schin #else
274887Schin 
284887Schin #if _UWIN
294887Schin 
304887Schin #define calloc		______calloc
314887Schin #define _ast_free	______free
324887Schin #define malloc		______malloc
334887Schin #define mallinfo	______mallinfo
344887Schin #define mallopt		______mallopt
354887Schin #define mstats		______mstats
364887Schin #define realloc		______realloc
374887Schin 
384887Schin #define _STDLIB_H_	1
394887Schin 
404887Schin extern int		atexit(void(*)(void));
414887Schin extern char*		getenv(const char*);
424887Schin 
434887Schin #endif
444887Schin 
454887Schin #include	"vmhdr.h"
464887Schin 
474887Schin #if _UWIN
484887Schin 
494887Schin #include	<malloc.h>
504887Schin 
514887Schin #define _map_malloc	1
524887Schin #define _mal_alloca	1
534887Schin 
544887Schin #undef	calloc
554887Schin #define calloc		_ast_calloc
564887Schin #undef	_ast_free
574887Schin #define free		_ast_free
584887Schin #undef	malloc
594887Schin #define malloc		_ast_malloc
604887Schin #undef	mallinfo
614887Schin typedef struct ______mallinfo Mallinfo_t;
624887Schin #undef	mallopt
634887Schin #undef	mstats
644887Schin typedef struct ______mstats Mstats_t;
654887Schin #undef	realloc
664887Schin #define realloc		_ast_realloc
674887Schin 
684887Schin #endif
694887Schin 
704887Schin #if __STD_C
714887Schin #define F0(f,t0)		f(t0)
724887Schin #define F1(f,t1,a1)		f(t1 a1)
734887Schin #define F2(f,t1,a1,t2,a2)	f(t1 a1, t2 a2)
744887Schin #else
754887Schin #define F0(f,t0)		f()
764887Schin #define F1(f,t1,a1)		f(a1) t1 a1;
774887Schin #define F2(f,t1,a1,t2,a2)	f(a1, a2) t1 a1; t2 a2;
784887Schin #endif
794887Schin 
804887Schin /*
814887Schin  * define _AST_std_malloc=1 to force the standard malloc
824887Schin  * if _map_malloc is also defined then _ast_malloc etc.
834887Schin  * will simply call malloc etc.
844887Schin  */
854887Schin 
864887Schin #if !defined(_AST_std_malloc) && __CYGWIN__
874887Schin #define _AST_std_malloc	1
884887Schin #endif
894887Schin 
904887Schin #if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
914887Schin 
924887Schin /*	malloc compatibility functions.
934887Schin **	These are aware of debugging/profiling and driven by the environment variables:
944887Schin **	VMETHOD: select an allocation method by name.
954887Schin **
964887Schin **	VMPROFILE: if is a file name, write profile data to it.
974887Schin **	VMTRACE: if is a file name, write trace data to it.
984887Schin **	The pattern %p in a file name will be replaced by the process ID.
994887Schin **
1004887Schin **	VMDEBUG:
1014887Schin **		a:			abort on any warning.
1024887Schin **		w[decimal]:		file descriptor for warnings.
1034887Schin **		[decimal]:		period to check arena.
1044887Schin **		0x[hexadecimal]:	address to watch.
1054887Schin **
1064887Schin **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
1074887Schin */
1084887Schin 
1094887Schin #if _sys_stat
1104887Schin #include	<sys/stat.h>
1114887Schin #endif
1124887Schin #include	<fcntl.h>
1134887Schin 
1144887Schin #ifdef S_IRUSR
1154887Schin #define CREAT_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
1164887Schin #else
1174887Schin #define CREAT_MODE	0644
1184887Schin #endif
1194887Schin 
1204887Schin #if !_map_malloc
1214887Schin #undef calloc
1224887Schin #undef cfree
1234887Schin #undef free
1244887Schin #undef mallinfo
1254887Schin #undef malloc
1264887Schin #undef mallopt
1274887Schin #undef memalign
1284887Schin #undef mstats
1294887Schin #undef realloc
1304887Schin #undef valloc
1314887Schin #endif
1324887Schin 
1334887Schin #if _WINIX
1344887Schin 
1354887Schin #include <ast_windows.h>
1364887Schin 
1374887Schin #if _UWIN
1384887Schin 
1394887Schin #define VMRECORD(p)	_vmrecord(p)
1404887Schin #define VMBLOCK		{ int _vmblock = _sigblock();
1414887Schin #define VMUNBLOCK	_sigunblock(_vmblock); }
1424887Schin 
1434887Schin extern int		_sigblock(void);
1444887Schin extern void		_sigunblock(int);
1454887Schin extern unsigned long	_record[2048];
1464887Schin 
1474887Schin __inline Void_t* _vmrecord(Void_t* p)
1484887Schin {
1494887Schin 	register unsigned long	v = ((unsigned long)p)>>16;
1504887Schin 
1514887Schin 	_record[v>>5] |= 1<<((v&0x1f));
1524887Schin 	return p;
1534887Schin }
1544887Schin 
1554887Schin #else
1564887Schin 
1574887Schin #define getenv(s)	lcl_getenv(s)
1584887Schin 
1594887Schin static char*
1604887Schin lcl_getenv(const char* s)
1614887Schin {
1624887Schin 	int		n;
1634887Schin 	static char	buf[512];
1644887Schin 
1654887Schin 	if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
1664887Schin 		return 0;
1674887Schin 	return buf;
1684887Schin }
1694887Schin 
1704887Schin #endif /* _UWIN */
1714887Schin 
1724887Schin #endif /* _WINIX */
1734887Schin 
1744887Schin #ifndef VMRECORD
1754887Schin #define VMRECORD(p)	(p)
1764887Schin #define VMBLOCK
1774887Schin #define VMUNBLOCK
1784887Schin #endif
1794887Schin 
1804887Schin #if defined(__EXPORT__)
1814887Schin #define extern		extern __EXPORT__
1824887Schin #endif
1834887Schin 
1844887Schin #if __STD_C
1854887Schin static Vmulong_t atou(char** sp)
1864887Schin #else
1874887Schin static Vmulong_t atou(sp)
1884887Schin char**	sp;
1894887Schin #endif
1904887Schin {
1914887Schin 	char*		s = *sp;
1924887Schin 	Vmulong_t	v = 0;
1934887Schin 
1944887Schin 	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
1954887Schin 	{	for(s += 2; *s; ++s)
1964887Schin 		{	if(*s >= '0' && *s <= '9')
1974887Schin 				v = (v << 4) + (*s - '0');
1984887Schin 			else if(*s >= 'a' && *s <= 'f')
1994887Schin 				v = (v << 4) + (*s - 'a') + 10;
2004887Schin 			else if(*s >= 'A' && *s <= 'F')
2014887Schin 				v = (v << 4) + (*s - 'A') + 10;
2024887Schin 			else break;
2034887Schin 		}
2044887Schin 	}
2054887Schin 	else
2064887Schin 	{	for(; *s; ++s)
2074887Schin 		{	if(*s >= '0' && *s <= '9')
2084887Schin 				v = v*10 + (*s - '0');
2094887Schin 			else break;
2104887Schin 		}
2114887Schin 	}
2124887Schin 
2134887Schin 	*sp = s;
2144887Schin 	return v;
2154887Schin }
2164887Schin 
2174887Schin static int		_Vmflinit = 0;
2184887Schin static Vmulong_t	_Vmdbstart = 0;
2194887Schin static Vmulong_t	_Vmdbcheck = 0;
2204887Schin static Vmulong_t	_Vmdbtime = 0;
2214887Schin static int		_Vmpffd = -1;
2224887Schin #define VMFLINIT() \
2234887Schin 	{ if(!_Vmflinit)	vmflinit(); \
2244887Schin 	  if(_Vmdbcheck) \
2254887Schin 	  { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
2264887Schin 	    else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
2274887Schin 	    if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
2284887Schin 	       Vmregion->meth.meth == VM_MTDEBUG) \
2294887Schin 		vmdbcheck(Vmregion); \
2304887Schin 	  } \
2314887Schin 	}
2324887Schin 
2334887Schin #if __STD_C
2344887Schin static char* insertpid(char* begs, char* ends)
2354887Schin #else
2364887Schin static char* insertpid(begs,ends)
2374887Schin char*	begs;
2384887Schin char*	ends;
2394887Schin #endif
2404887Schin {	int	pid;
2414887Schin 	char*	s;
2424887Schin 
2434887Schin 	if((pid = getpid()) < 0)
2444887Schin 		return NIL(char*);
2454887Schin 
2464887Schin 	s = ends;
2474887Schin 	do
2484887Schin 	{	if(s == begs)
2494887Schin 			return NIL(char*);
2504887Schin 		*--s = '0' + pid%10;
2514887Schin 	} while((pid /= 10) > 0);
2524887Schin 	while(s < ends)
2534887Schin 		*begs++ = *s++;
2544887Schin 
2554887Schin 	return begs;
2564887Schin }
2574887Schin 
2584887Schin #if __STD_C
2594887Schin static int createfile(char* file)
2604887Schin #else
2614887Schin static int createfile(file)
2624887Schin char*	file;
2634887Schin #endif
2644887Schin {
2654887Schin 	char	buf[1024];
2664887Schin 	char	*next, *endb;
2674887Schin 
2684887Schin 	next = buf;
2694887Schin 	endb = buf + sizeof(buf);
2704887Schin 	while(*file)
2714887Schin 	{	if(*file == '%')
2724887Schin 		{	switch(file[1])
2734887Schin 			{
2744887Schin 			case 'p' :
2754887Schin 				if(!(next = insertpid(next,endb)) )
2764887Schin 					return -1;
2774887Schin 				file += 2;
2784887Schin 				break;
2794887Schin 			default :
2804887Schin 				goto copy;
2814887Schin 			}
2824887Schin 		}
2834887Schin 		else
2844887Schin 		{ copy:
2854887Schin 			*next++ = *file++;
2864887Schin 		}
2874887Schin 
2884887Schin 		if(next >= endb)
2894887Schin 			return -1;
2904887Schin 	}
2914887Schin 
2924887Schin 	*next = '\0';
2934887Schin #if _PACKAGE_ast
2944887Schin 	{	int	fd;
2954887Schin 		fd = open(buf,O_WRONLY|O_CREAT|O_TRUNC,CREAT_MODE);
2964887Schin #ifdef FD_CLOEXEC
2974887Schin 		if (fd >= 0)
2984887Schin 			fcntl(fd, F_SETFD, FD_CLOEXEC);
2994887Schin #endif
3004887Schin 		return fd;
3014887Schin 	}
3024887Schin #else
3034887Schin 	return creat(buf,CREAT_MODE);
3044887Schin #endif
3054887Schin }
3064887Schin 
3074887Schin #if __STD_C
3084887Schin static void pfprint(void)
3094887Schin #else
3104887Schin static void pfprint()
3114887Schin #endif
3124887Schin {
3134887Schin 	if(Vmregion->meth.meth == VM_MTPROFILE)
3144887Schin 		vmprofile(Vmregion,_Vmpffd);
3154887Schin }
3164887Schin 
3174887Schin #if __STD_C
3184887Schin static int vmflinit(void)
3194887Schin #else
3204887Schin static int vmflinit()
3214887Schin #endif
3224887Schin {
3234887Schin 	char*		env;
3244887Schin 	Vmalloc_t*	vm;
3254887Schin 	int		fd;
3264887Schin 	Vmulong_t	addr;
3274887Schin 	char*		file;
3284887Schin 	int		line;
3294887Schin 	Void_t*		func;
3304887Schin 
3314887Schin 	/* this must be done now to avoid any inadvertent recursion (more below) */
3324887Schin 	_Vmflinit = 1;
3334887Schin 	VMFLF(Vmregion,file,line,func);
3344887Schin 
3354887Schin 	/* if getenv() calls malloc(), the eventual region may not see this */
3364887Schin 	vm = NIL(Vmalloc_t*);
3374887Schin 	if((env = getenv("VMETHOD")) )
3384887Schin 	{	if(strcmp(env,"Vmdebug") == 0 || strcmp(env,"vmdebug") == 0)
3394887Schin 			vm = vmopen(Vmdcsbrk,Vmdebug,0);
3404887Schin 		else if(strcmp(env,"Vmprofile") == 0 || strcmp(env,"vmprofile") == 0 )
3414887Schin 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
3424887Schin 		else if(strcmp(env,"Vmlast") == 0 || strcmp(env,"vmlast") == 0 )
3434887Schin 			vm = vmopen(Vmdcsbrk,Vmlast,0);
3444887Schin 		else if(strcmp(env,"Vmbest") == 0 || strcmp(env,"vmbest") == 0 )
3454887Schin 			vm = Vmheap;
3464887Schin 	}
3474887Schin 
3484887Schin 	if((!vm || vm->meth.meth == VM_MTDEBUG) &&
3494887Schin 	   (env = getenv("VMDEBUG")) && env[0] )
3504887Schin 	{	if(vm || (vm = vmopen(Vmdcsbrk,Vmdebug,0)) )
3514887Schin 		{	reg int	setcheck = 0;
3524887Schin 
3534887Schin 			while(*env)
3544887Schin 			{	if(*env == 'a')
3554887Schin 				{	vmset(vm,VM_DBABORT,1);
3564887Schin 					env += 1;
3574887Schin 				}
3584887Schin 				else if(*env =='w')
3594887Schin 				{	env += 1;
3604887Schin 					if((fd = atou(&env)) >= 0 )
3614887Schin 						vmdebug(fd);
3624887Schin 				}
3634887Schin 				else if(*env < '0' || *env > '9')
3644887Schin 					env += 1;
3654887Schin 				else if(env[0] == '0' && (env[1] == 'x' || env[1] == 'X') )
3664887Schin 				{	if((addr = atou(&env)) != 0)
3674887Schin 						vmdbwatch((Void_t*)addr);
3684887Schin 				}
3694887Schin 				else
3704887Schin 				{	_Vmdbcheck = atou(&env);
3714887Schin 					setcheck = 1;
3724887Schin 					if(*env == ',')
3734887Schin 					{	env += 1;
3744887Schin 						_Vmdbstart = atou(&env);
3754887Schin 					}
3764887Schin 				}
3774887Schin 			}
3784887Schin 			if(!setcheck)
3794887Schin 				_Vmdbcheck = 1;
3804887Schin 		}
3814887Schin 	}
3824887Schin 
3834887Schin 	if((!vm || vm->meth.meth == VM_MTPROFILE) &&
3844887Schin 	   (env = getenv("VMPROFILE")) && env[0] )
3854887Schin 	{	_Vmpffd = createfile(env);
3864887Schin 		if(!vm)
3874887Schin 			vm = vmopen(Vmdcsbrk,Vmprofile,0);
3884887Schin 	}
3894887Schin 
3904887Schin 	/* slip in the new region now so that malloc() will work fine */
3914887Schin 	if(vm)
3924887Schin 		Vmregion = vm;
3934887Schin 
3944887Schin 	/* turn on tracing if requested */
3954887Schin 	if((env = getenv("VMTRACE")) && env[0] && (fd = createfile(env)) >= 0)
3964887Schin 	{	vmset(Vmregion,VM_TRACE,1);
3974887Schin 		vmtrace(fd);
3984887Schin 	}
3994887Schin 
4004887Schin 	/* make sure that profile data is output upon exiting */
4014887Schin 	if(vm && vm->meth.meth == VM_MTPROFILE)
4024887Schin 	{	if(_Vmpffd < 0)
4034887Schin 			_Vmpffd = 2;
4044887Schin 		/* this may wind up calling malloc(), but region is ok now */
4054887Schin 		atexit(pfprint);
4064887Schin 	}
4074887Schin 	else if(_Vmpffd >= 0)
4084887Schin 	{	close(_Vmpffd);
4094887Schin 		_Vmpffd = -1;
4104887Schin 	}
4114887Schin 
4124887Schin 	/* reset file and line number to correct values for the call */
4134887Schin 	Vmregion->file = file;
4144887Schin 	Vmregion->line = line;
4154887Schin 	Vmregion->func = func;
4164887Schin 
4174887Schin 	return 0;
4184887Schin }
4194887Schin 
4204887Schin #if __STD_C
4214887Schin extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
4224887Schin #else
4234887Schin extern Void_t* calloc(n_obj, s_obj)
4244887Schin reg size_t	n_obj;
4254887Schin reg size_t	s_obj;
4264887Schin #endif
4274887Schin {
4284887Schin 	VMFLINIT();
4294887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO));
4304887Schin }
4314887Schin 
4324887Schin #if __STD_C
4334887Schin extern Void_t* malloc(reg size_t size)
4344887Schin #else
4354887Schin extern Void_t* malloc(size)
4364887Schin reg size_t	size;
4374887Schin #endif
4384887Schin {
4394887Schin 	VMFLINIT();
4404887Schin 	return VMRECORD((*Vmregion->meth.allocf)(Vmregion,size));
4414887Schin }
4424887Schin 
4434887Schin #if __STD_C
4444887Schin extern Void_t* realloc(reg Void_t* data, reg size_t size)
4454887Schin #else
4464887Schin extern Void_t* realloc(data,size)
4474887Schin reg Void_t*	data;	/* block to be reallocated	*/
4484887Schin reg size_t	size;	/* new size			*/
4494887Schin #endif
4504887Schin {
4514887Schin #if USE_NATIVE
4524887Schin #undef	realloc
4534887Schin #if __STD_C
4544887Schin 	extern Void_t*	realloc(Void_t*, size_t);
4554887Schin #else
4564887Schin 	extern Void_t*	realloc();
4574887Schin #endif
4584887Schin #endif
4594887Schin 
4604887Schin 	VMFLINIT();
4614887Schin 
4624887Schin #if _PACKAGE_ast
4634887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
4644887Schin #if !USE_NATIVE
4654887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
4664887Schin #endif
4674887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0 )
4684887Schin 	{
4694887Schin #if USE_NATIVE
4704887Schin 		return realloc(data, size);
4714887Schin #else
4724887Schin 		Void_t*	newdata;
4734887Schin 		if((newdata = (*Vmregion->meth.allocf)(Vmregion,size)) )
4744887Schin 			memcpy(newdata,data,size);
4754887Schin 		return VMRECORD(newdata);
4764887Schin #endif
4774887Schin 	}
4784887Schin #endif
4794887Schin 
4804887Schin #if USE_NATIVE
4814887Schin 	{	Void_t*	newdata;
4824887Schin 		if (newdata = (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE))
4834887Schin 			return newdata;
4844887Schin 		return VMRECORD(realloc(data, size));
4854887Schin 	}
4864887Schin #else
4874887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE));
4884887Schin #endif
4894887Schin }
4904887Schin 
4914887Schin #if __STD_C
4924887Schin extern void free(reg Void_t* data)
4934887Schin #else
4944887Schin extern void free(data)
4954887Schin reg Void_t*	data;
4964887Schin #endif
4974887Schin {
4984887Schin #if USE_NATIVE
4994887Schin #undef	free
5004887Schin #if __STD_C
5014887Schin 	extern void	free(Void_t*);
5024887Schin #else
5034887Schin 	extern void	free();
5044887Schin #endif
5054887Schin #endif
5064887Schin 
5074887Schin 	VMFLINIT();
5084887Schin 
5094887Schin #if _PACKAGE_ast
5104887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
5114887Schin #if !USE_NATIVE
5124887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
5134887Schin #endif
5144887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0)
5154887Schin 	{
5164887Schin #if USE_NATIVE
5174887Schin 		free(data);
5184887Schin #endif
5194887Schin 		return;
5204887Schin 	}
5214887Schin #endif
5224887Schin 
5234887Schin #if USE_NATIVE
5244887Schin 	if ((*Vmregion->meth.freef)(Vmregion,data) != 0)
5254887Schin 		free(data);
5264887Schin #else
5274887Schin 	(void)(*Vmregion->meth.freef)(Vmregion,data);
5284887Schin #endif
5294887Schin }
5304887Schin 
5314887Schin #if __STD_C
5324887Schin extern void cfree(reg Void_t* data)
5334887Schin #else
5344887Schin extern void cfree(data)
5354887Schin reg Void_t*	data;
5364887Schin #endif
5374887Schin {
5384887Schin 	free(data);
5394887Schin }
5404887Schin 
5414887Schin #if __STD_C
5424887Schin extern Void_t* memalign(reg size_t align, reg size_t size)
5434887Schin #else
5444887Schin extern Void_t* memalign(align, size)
5454887Schin reg size_t	align;
5464887Schin reg size_t	size;
5474887Schin #endif
5484887Schin {
5494887Schin 	Void_t*	addr;
5504887Schin 
5514887Schin 	VMFLINIT();
5524887Schin 	VMBLOCK
5534887Schin 	addr = VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,align));
5544887Schin 	VMUNBLOCK
5554887Schin 	return addr;
5564887Schin }
5574887Schin 
5584887Schin #if __STD_C
5594887Schin extern Void_t* valloc(reg size_t size)
5604887Schin #else
5614887Schin extern Void_t* valloc(size)
5624887Schin reg size_t	size;
5634887Schin #endif
5644887Schin {
5654887Schin 	VMFLINIT();
5664887Schin 	GETPAGESIZE(_Vmpagesize);
5674887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize));
5684887Schin }
5694887Schin 
5704887Schin #if __STD_C
5714887Schin extern Void_t* pvalloc(reg size_t size)
5724887Schin #else
5734887Schin extern Void_t* pvalloc(size)
5744887Schin reg size_t	size;
5754887Schin #endif
5764887Schin {
5774887Schin 	VMFLINIT();
5784887Schin 	GETPAGESIZE(_Vmpagesize);
5794887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,ROUND(size,_Vmpagesize),_Vmpagesize));
5804887Schin }
5814887Schin 
5824887Schin #if !_PACKAGE_ast
5834887Schin #if __STD_C
5844887Schin char* strdup(const char* s)
5854887Schin #else
5864887Schin char* strdup(s)
5874887Schin char*	s;
5884887Schin #endif
5894887Schin {
5904887Schin 	char	*ns;
5914887Schin 	size_t	n;
5924887Schin 
5934887Schin 	if(!s)
5944887Schin 		return NIL(char*);
5954887Schin 	else
5964887Schin 	{	n = strlen(s);
5974887Schin 		if((ns = malloc(n+1)) )
5984887Schin 			memcpy(ns,s,n+1);
5994887Schin 		return ns;
6004887Schin 	}
6014887Schin }
6024887Schin #endif /* _PACKAGE_ast */
6034887Schin 
6044887Schin #if !_lib_alloca || _mal_alloca
6054887Schin #ifndef _stk_down
6064887Schin #define _stk_down	0
6074887Schin #endif
6084887Schin typedef struct _alloca_s	Alloca_t;
6094887Schin union _alloca_u
6104887Schin {	struct
6114887Schin 	{	char*		addr;
6124887Schin 		Alloca_t*	next;
6134887Schin 	} head;
6144887Schin 	char	array[ALIGN];
6154887Schin };
6164887Schin struct _alloca_s
6174887Schin {	union _alloca_u	head;
6184887Schin 	Vmuchar_t	data[1];
6194887Schin };
6204887Schin 
6214887Schin #if __STD_C
6224887Schin extern Void_t* alloca(size_t size)
6234887Schin #else
6244887Schin extern Void_t* alloca(size)
6254887Schin size_t	size;
6264887Schin #endif
6274887Schin {	char		array[ALIGN];
6284887Schin 	char*		file;
6294887Schin 	int		line;
6304887Schin 	Void_t*		func;
6314887Schin 	reg Alloca_t*	f;
6324887Schin 	static Alloca_t* Frame;
6334887Schin 
6344887Schin 	VMFLINIT();
6354887Schin 	VMFLF(Vmregion,file,line,func);
6364887Schin 	while(Frame)
6374887Schin 	{	if(( _stk_down && &array[0] > Frame->head.head.addr) ||
6384887Schin 		   (!_stk_down && &array[0] < Frame->head.head.addr) )
6394887Schin 		{	f = Frame;
6404887Schin 			Frame = f->head.head.next;
6414887Schin 			(void)(*Vmregion->meth.freef)(Vmregion,f);
6424887Schin 		}
6434887Schin 		else	break;
6444887Schin 	}
6454887Schin 
6464887Schin 	Vmregion->file = file;
6474887Schin 	Vmregion->line = line;
6484887Schin 	Vmregion->func = func;
6494887Schin 	f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
6504887Schin 
6514887Schin 	f->head.head.addr = &array[0];
6524887Schin 	f->head.head.next = Frame;
6534887Schin 	Frame = f;
6544887Schin 
6554887Schin 	return (Void_t*)f->data;
6564887Schin }
6574887Schin #endif /*!_lib_alloca || _mal_alloca*/
6584887Schin 
6594887Schin #if _map_malloc
6604887Schin 
6614887Schin /* not sure of all the implications -- 0 is conservative for now */
6624887Schin #define USE_NATIVE	0	/* native free/realloc on non-vmalloc ptrs */
6634887Schin 
6644887Schin #else
6654887Schin 
6664887Schin /* intercept _* __* __libc_* variants */
6674887Schin 
6684887Schin #if __lib__malloc
6694887Schin extern Void_t*	F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
6704887Schin extern Void_t	F1(_cfree, Void_t*,p) { free(p); }
6714887Schin extern Void_t	F1(_free, Void_t*,p) { free(p); }
6724887Schin extern Void_t*	F1(_malloc, size_t,n) { return malloc(n); }
6734887Schin #if _lib_memalign
6744887Schin extern Void_t*	F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
6754887Schin #endif
6764887Schin #if _lib_pvalloc
6774887Schin extern Void_t*	F1(_pvalloc, size_t,n) { return pvalloc(n); }
6784887Schin #endif
6794887Schin extern Void_t*	F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
6804887Schin #if _lib_valloc
6814887Schin extern Void_t*	F1(_valloc, size_t,n) { return valloc(n); }
6824887Schin #endif
6834887Schin #endif
6844887Schin 
6854887Schin #if _lib___malloc
6864887Schin extern Void_t*	F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
6874887Schin extern Void_t	F1(__cfree, Void_t*,p) { free(p); }
6884887Schin extern Void_t	F1(__free, Void_t*,p) { free(p); }
6894887Schin extern Void_t*	F1(__malloc, size_t,n) { return malloc(n); }
6904887Schin #if _lib_memalign
6914887Schin extern Void_t*	F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
6924887Schin #endif
6934887Schin #if _lib_pvalloc
6944887Schin extern Void_t*	F1(__pvalloc, size_t,n) { return pvalloc(n); }
6954887Schin #endif
6964887Schin extern Void_t*	F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
6974887Schin #if _lib_valloc
6984887Schin extern Void_t*	F1(__valloc, size_t,n) { return valloc(n); }
6994887Schin #endif
7004887Schin #endif
7014887Schin 
7024887Schin #if _lib___libc_malloc
7034887Schin extern Void_t*	F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
7044887Schin extern Void_t	F1(__libc_cfree, Void_t*,p) { free(p); }
7054887Schin extern Void_t	F1(__libc_free, Void_t*,p) { free(p); }
7064887Schin extern Void_t*	F1(__libc_malloc, size_t,n) { return malloc(n); }
7074887Schin #if _lib_memalign
7084887Schin extern Void_t*	F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
7094887Schin #endif
7104887Schin #if _lib_pvalloc
7114887Schin extern Void_t*	F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
7124887Schin #endif
7134887Schin extern Void_t*	F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
7144887Schin #if _lib_valloc
7154887Schin extern Void_t*	F1(__libc_valloc, size_t,n) { return valloc(n); }
7164887Schin #endif
7174887Schin #endif
7184887Schin 
7194887Schin #endif /* _map_malloc */
7204887Schin 
7214887Schin #undef	extern
7224887Schin 
7234887Schin #if _hdr_malloc /* need the mallint interface for statistics, etc. */
7244887Schin 
7254887Schin #undef	calloc
7264887Schin #define calloc		______calloc
7274887Schin #undef	cfree
7284887Schin #define cfree		______cfree
7294887Schin #undef	free
7304887Schin #define free		______free
7314887Schin #undef	malloc
7324887Schin #define malloc		______malloc
7334887Schin #undef	pvalloc
7344887Schin #define pvalloc		______pvalloc
7354887Schin #undef	realloc
7364887Schin #define realloc		______realloc
7374887Schin #undef	valloc
7384887Schin #define valloc		______valloc
7394887Schin 
7404887Schin #if !_UWIN
7414887Schin 
7424887Schin #include	<malloc.h>
7434887Schin 
7444887Schin typedef struct mallinfo Mallinfo_t;
7454887Schin typedef struct mstats Mstats_t;
7464887Schin 
7474887Schin #endif
7484887Schin 
7494887Schin #if defined(__EXPORT__)
7504887Schin #define extern		__EXPORT__
7514887Schin #endif
7524887Schin 
7534887Schin #if _lib_mallopt
7544887Schin #if __STD_C
7554887Schin extern int mallopt(int cmd, int value)
7564887Schin #else
7574887Schin extern int mallopt(cmd, value)
7584887Schin int	cmd;
7594887Schin int	value;
7604887Schin #endif
7614887Schin {
7624887Schin 	VMFLINIT();
7634887Schin 	return 0;
7644887Schin }
7654887Schin #endif /*_lib_mallopt*/
7664887Schin 
7674887Schin #if _lib_mallinfo && _mem_arena_mallinfo
7684887Schin #if __STD_C
7694887Schin extern Mallinfo_t mallinfo(void)
7704887Schin #else
7714887Schin extern Mallinfo_t mallinfo()
7724887Schin #endif
7734887Schin {
7744887Schin 	Vmstat_t	sb;
7754887Schin 	Mallinfo_t	mi;
7764887Schin 
7774887Schin 	VMFLINIT();
7784887Schin 	memset(&mi,0,sizeof(mi));
7794887Schin 	if(vmstat(Vmregion,&sb) >= 0)
7804887Schin 	{	mi.arena = sb.extent;
7814887Schin 		mi.ordblks = sb.n_busy+sb.n_free;
7824887Schin 		mi.uordblks = sb.s_busy;
7834887Schin 		mi.fordblks = sb.s_free;
7844887Schin 	}
7854887Schin 	return mi;
7864887Schin }
7874887Schin #endif /* _lib_mallinfo */
7884887Schin 
7894887Schin #if _lib_mstats && _mem_bytes_total_mstats
7904887Schin #if __STD_C
7914887Schin extern Mstats_t mstats(void)
7924887Schin #else
7934887Schin extern Mstats_t mstats()
7944887Schin #endif
7954887Schin {
7964887Schin 	Vmstat_t	sb;
7974887Schin 	Mstats_t	ms;
7984887Schin 
7994887Schin 	VMFLINIT();
8004887Schin 	memset(&ms,0,sizeof(ms));
8014887Schin 	if(vmstat(Vmregion,&sb) >= 0)
8024887Schin 	{	ms.bytes_total = sb.extent;
8034887Schin 		ms.chunks_used = sb.n_busy;
8044887Schin 		ms.bytes_used = sb.s_busy;
8054887Schin 		ms.chunks_free = sb.n_free;
8064887Schin 		ms.bytes_free = sb.s_free;
8074887Schin 	}
8084887Schin 	return ms;
8094887Schin }
8104887Schin #endif /*_lib_mstats*/
8114887Schin 
8124887Schin #undef	extern
8134887Schin 
8144887Schin #endif/*_hdr_malloc*/
8154887Schin 
8164887Schin #else
8174887Schin 
8184887Schin /*
8194887Schin  * even though there is no malloc override, still provide
8204887Schin  * _ast_* counterparts for object compatibility
8214887Schin  */
8224887Schin 
8234887Schin #undef	calloc
8244887Schin extern Void_t*	calloc _ARG_((size_t, size_t));
8254887Schin 
8264887Schin #undef	cfree
8274887Schin extern void	cfree _ARG_((Void_t*));
8284887Schin 
8294887Schin #undef	free
8304887Schin extern void	free _ARG_((Void_t*));
8314887Schin 
8324887Schin #undef	malloc
8334887Schin extern Void_t*	malloc _ARG_((size_t));
8344887Schin 
8354887Schin #if _lib_memalign
8364887Schin #undef	memalign
8374887Schin extern Void_t*	memalign _ARG_((size_t, size_t));
8384887Schin #endif
8394887Schin 
8404887Schin #if _lib_pvalloc
8414887Schin #undef	pvalloc
8424887Schin extern Void_t*	pvalloc _ARG_((size_t));
8434887Schin #endif
8444887Schin 
8454887Schin #undef	realloc
8464887Schin extern Void_t*	realloc _ARG_((Void_t*, size_t));
8474887Schin 
8484887Schin #if _lib_valloc
8494887Schin #undef	valloc
8504887Schin extern Void_t*	valloc _ARG_((size_t));
8514887Schin #endif
8524887Schin 
8534887Schin #if defined(__EXPORT__)
8544887Schin #define extern		__EXPORT__
8554887Schin #endif
8564887Schin 
8574887Schin extern Void_t*	F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
8584887Schin extern Void_t	F1(_ast_cfree, Void_t*,p) { free(p); }
8594887Schin extern Void_t	F1(_ast_free, Void_t*,p) { free(p); }
8604887Schin extern Void_t*	F1(_ast_malloc, size_t,n) { return malloc(n); }
8614887Schin #if _lib_memalign
8624887Schin extern Void_t*	F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
8634887Schin #endif
8644887Schin #if _lib_pvalloc
8654887Schin extern Void_t*	F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
8664887Schin #endif
8674887Schin extern Void_t*	F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
8684887Schin #if _lib_valloc
8694887Schin extern Void_t*	F1(_ast_valloc, size_t,n) { return valloc(n); }
8704887Schin #endif
8714887Schin 
8724887Schin #undef	extern
8734887Schin 
8744887Schin #if _hdr_malloc
8754887Schin 
8764887Schin #undef	mallinfo
8774887Schin #undef	mallopt
8784887Schin #undef	mstats
8794887Schin 
8804887Schin #define calloc		______calloc
8814887Schin #define cfree		______cfree
8824887Schin #define free		______free
8834887Schin #define malloc		______malloc
8844887Schin #define pvalloc		______pvalloc
8854887Schin #define realloc		______realloc
8864887Schin #define valloc		______valloc
8874887Schin 
8884887Schin #if !_UWIN
8894887Schin 
8904887Schin #include	<malloc.h>
8914887Schin 
8924887Schin typedef struct mallinfo Mallinfo_t;
8934887Schin typedef struct mstats Mstats_t;
8944887Schin 
8954887Schin #endif
8964887Schin 
8974887Schin #if defined(__EXPORT__)
8984887Schin #define extern		__EXPORT__
8994887Schin #endif
9004887Schin 
9014887Schin #if _lib_mallopt
9024887Schin extern int	F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
9034887Schin #endif
9044887Schin 
9054887Schin #if _lib_mallinfo && _mem_arena_mallinfo
9064887Schin extern Mallinfo_t	F0(_ast_mallinfo, void) { return mallinfo(); }
9074887Schin #endif
9084887Schin 
9094887Schin #if _lib_mstats && _mem_bytes_total_mstats
9104887Schin extern Mstats_t		F0(_ast_mstats, void) { return mstats(); }
9114887Schin #endif
9124887Schin 
9134887Schin #undef	extern
9144887Schin 
9154887Schin #endif /*_hdr_malloc*/
9164887Schin 
9174887Schin #endif /*!_std_malloc*/
9184887Schin 
9194887Schin #endif /*_UWIN*/
920