xref: /onnv-gate/usr/src/lib/libast/common/vmalloc/malloc.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.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 
_STUB_malloc()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"
4610898Sroland.mainz@nrubsig.org #include	<errno.h>
474887Schin 
484887Schin #if _UWIN
494887Schin 
504887Schin #include	<malloc.h>
514887Schin 
524887Schin #define _map_malloc	1
534887Schin #define _mal_alloca	1
544887Schin 
554887Schin #undef	calloc
564887Schin #define calloc		_ast_calloc
574887Schin #undef	_ast_free
584887Schin #define free		_ast_free
594887Schin #undef	malloc
604887Schin #define malloc		_ast_malloc
614887Schin #undef	mallinfo
624887Schin typedef struct ______mallinfo Mallinfo_t;
634887Schin #undef	mallopt
644887Schin #undef	mstats
654887Schin typedef struct ______mstats Mstats_t;
664887Schin #undef	realloc
674887Schin #define realloc		_ast_realloc
684887Schin 
694887Schin #endif
704887Schin 
714887Schin #if __STD_C
724887Schin #define F0(f,t0)		f(t0)
734887Schin #define F1(f,t1,a1)		f(t1 a1)
744887Schin #define F2(f,t1,a1,t2,a2)	f(t1 a1, t2 a2)
754887Schin #else
764887Schin #define F0(f,t0)		f()
774887Schin #define F1(f,t1,a1)		f(a1) t1 a1;
784887Schin #define F2(f,t1,a1,t2,a2)	f(a1, a2) t1 a1; t2 a2;
794887Schin #endif
804887Schin 
814887Schin /*
824887Schin  * define _AST_std_malloc=1 to force the standard malloc
834887Schin  * if _map_malloc is also defined then _ast_malloc etc.
844887Schin  * will simply call malloc etc.
854887Schin  */
864887Schin 
874887Schin #if !defined(_AST_std_malloc) && __CYGWIN__
884887Schin #define _AST_std_malloc	1
894887Schin #endif
904887Schin 
91*12068SRoger.Faulkner@Oracle.COM /*	malloc compatibility functions
92*12068SRoger.Faulkner@Oracle.COM **
93*12068SRoger.Faulkner@Oracle.COM **	These are aware of debugging/profiling and are driven by the
94*12068SRoger.Faulkner@Oracle.COM **	VMALLOC_OPTIONS environment variable which is a space-separated
95*12068SRoger.Faulkner@Oracle.COM **	list of [no]name[=value] options:
964887Schin **
97*12068SRoger.Faulkner@Oracle.COM **	    abort	if Vmregion==Vmdebug then VM_DBABORT is set,
98*12068SRoger.Faulkner@Oracle.COM **			otherwise _BLD_debug enabled assertions abort()
99*12068SRoger.Faulkner@Oracle.COM **			on failure
100*12068SRoger.Faulkner@Oracle.COM **	    check	if Vmregion==Vmbest then the region is checked every op
101*12068SRoger.Faulkner@Oracle.COM **	    method=m	sets Vmregion=m if not defined, m (Vm prefix optional)
102*12068SRoger.Faulkner@Oracle.COM **			may be one of { best debug last profile }
103*12068SRoger.Faulkner@Oracle.COM **	    mmap	prefer mmap() over brk() for region allocation
104*12068SRoger.Faulkner@Oracle.COM **	    period=n	sets Vmregion=Vmdebug if not defined, if
105*12068SRoger.Faulkner@Oracle.COM **			Vmregion==Vmdebug the region is checked every n ops
106*12068SRoger.Faulkner@Oracle.COM **	    profile=f	sets Vmregion=Vmprofile if not set, if
107*12068SRoger.Faulkner@Oracle.COM **			Vmregion==Vmprofile then profile info printed to file f
108*12068SRoger.Faulkner@Oracle.COM **	    region	if Vmregion==Vmbest then block free verifies
109*12068SRoger.Faulkner@Oracle.COM **			that the block belongs to the region
110*12068SRoger.Faulkner@Oracle.COM **	    start=n	sets Vmregion=Vmdebug if not defined, if
111*12068SRoger.Faulkner@Oracle.COM **			Vmregion==Vmdebug region checking starts after n ops
112*12068SRoger.Faulkner@Oracle.COM **	    trace=f	enables tracing to file f
113*12068SRoger.Faulkner@Oracle.COM **	    warn=f	sets Vmregion=Vmdebug if not defined, if
114*12068SRoger.Faulkner@Oracle.COM **			Vmregion==Vmdebug then warnings printed to file f
115*12068SRoger.Faulkner@Oracle.COM **	    watch=a	sets Vmregion=Vmdebug if not defined, if
116*12068SRoger.Faulkner@Oracle.COM **			Vmregion==Vmdebug then address a is watched
1174887Schin **
118*12068SRoger.Faulkner@Oracle.COM **	Output files are created if they don't exist. &n and /dev/fd/n name
119*12068SRoger.Faulkner@Oracle.COM **	the file descriptor n which must be open for writing. The pattern %p
120*12068SRoger.Faulkner@Oracle.COM **	in a file name is replaced by the process ID.
121*12068SRoger.Faulkner@Oracle.COM **
122*12068SRoger.Faulkner@Oracle.COM **	VMALLOC_OPTIONS combines the features of these previously used env vars:
123*12068SRoger.Faulkner@Oracle.COM **	    { VMDEBUG VMETHOD VMPROFILE VMTRACE }
1244887Schin **
1254887Schin **	Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
1264887Schin */
1274887Schin 
1284887Schin #if _sys_stat
1294887Schin #include	<sys/stat.h>
1304887Schin #endif
1314887Schin #include	<fcntl.h>
1324887Schin 
1334887Schin #ifdef S_IRUSR
1344887Schin #define CREAT_MODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
1354887Schin #else
1364887Schin #define CREAT_MODE	0644
1374887Schin #endif
1384887Schin 
139*12068SRoger.Faulkner@Oracle.COM static Vmulong_t	_Vmdbstart = 0;
140*12068SRoger.Faulkner@Oracle.COM static Vmulong_t	_Vmdbcheck = 0;
141*12068SRoger.Faulkner@Oracle.COM static Vmulong_t	_Vmdbtime = 0;
142*12068SRoger.Faulkner@Oracle.COM static int		_Vmpffd = -1;
143*12068SRoger.Faulkner@Oracle.COM 
144*12068SRoger.Faulkner@Oracle.COM #if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
145*12068SRoger.Faulkner@Oracle.COM 
1464887Schin #if !_map_malloc
1474887Schin #undef calloc
1484887Schin #undef cfree
1494887Schin #undef free
1504887Schin #undef mallinfo
1514887Schin #undef malloc
1524887Schin #undef mallopt
1534887Schin #undef memalign
1544887Schin #undef mstats
1554887Schin #undef realloc
1564887Schin #undef valloc
1574887Schin #endif
1584887Schin 
1594887Schin #if _WINIX
1604887Schin 
1614887Schin #include <ast_windows.h>
1624887Schin 
1634887Schin #if _UWIN
1644887Schin 
1654887Schin #define VMRECORD(p)	_vmrecord(p)
1664887Schin #define VMBLOCK		{ int _vmblock = _sigblock();
1674887Schin #define VMUNBLOCK	_sigunblock(_vmblock); }
1684887Schin 
1694887Schin extern int		_sigblock(void);
1704887Schin extern void		_sigunblock(int);
1714887Schin extern unsigned long	_record[2048];
1724887Schin 
_vmrecord(Void_t * p)1734887Schin __inline Void_t* _vmrecord(Void_t* p)
1744887Schin {
1754887Schin 	register unsigned long	v = ((unsigned long)p)>>16;
1764887Schin 
1774887Schin 	_record[v>>5] |= 1<<((v&0x1f));
1784887Schin 	return p;
1794887Schin }
1804887Schin 
1814887Schin #else
1824887Schin 
1834887Schin #define getenv(s)	lcl_getenv(s)
1844887Schin 
1854887Schin static char*
lcl_getenv(const char * s)1864887Schin lcl_getenv(const char* s)
1874887Schin {
1884887Schin 	int		n;
1894887Schin 	static char	buf[512];
1904887Schin 
1914887Schin 	if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
1924887Schin 		return 0;
1934887Schin 	return buf;
1944887Schin }
1954887Schin 
1964887Schin #endif /* _UWIN */
1974887Schin 
1984887Schin #endif /* _WINIX */
1994887Schin 
2004887Schin #ifndef VMRECORD
2014887Schin #define VMRECORD(p)	(p)
2024887Schin #define VMBLOCK
2034887Schin #define VMUNBLOCK
2044887Schin #endif
2054887Schin 
2064887Schin #if defined(__EXPORT__)
2074887Schin #define extern		extern __EXPORT__
2084887Schin #endif
2094887Schin 
2104887Schin static int		_Vmflinit = 0;
2114887Schin #define VMFLINIT() \
2124887Schin 	{ if(!_Vmflinit)	vmflinit(); \
2134887Schin 	  if(_Vmdbcheck) \
2144887Schin 	  { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
2154887Schin 	    else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
2164887Schin 	    if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
2174887Schin 	       Vmregion->meth.meth == VM_MTDEBUG) \
2184887Schin 		vmdbcheck(Vmregion); \
2194887Schin 	  } \
2204887Schin 	}
2214887Schin 
2224887Schin #if __STD_C
vmflinit(void)2234887Schin static int vmflinit(void)
2244887Schin #else
2254887Schin static int vmflinit()
2264887Schin #endif
2274887Schin {
2284887Schin 	char*		file;
2294887Schin 	int		line;
2304887Schin 	Void_t*		func;
2314887Schin 
2324887Schin 	/* this must be done now to avoid any inadvertent recursion (more below) */
2334887Schin 	_Vmflinit = 1;
2344887Schin 	VMFLF(Vmregion,file,line,func);
2354887Schin 
236*12068SRoger.Faulkner@Oracle.COM 	/* if getenv() calls malloc(), the options may not affect the eventual region */
237*12068SRoger.Faulkner@Oracle.COM 	VMOPTIONS();
2384887Schin 
2394887Schin 	/* reset file and line number to correct values for the call */
2404887Schin 	Vmregion->file = file;
2414887Schin 	Vmregion->line = line;
2424887Schin 	Vmregion->func = func;
2434887Schin 
2444887Schin 	return 0;
2454887Schin }
2464887Schin 
2474887Schin #if __STD_C
calloc(reg size_t n_obj,reg size_t s_obj)2484887Schin extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
2494887Schin #else
2504887Schin extern Void_t* calloc(n_obj, s_obj)
2514887Schin reg size_t	n_obj;
2524887Schin reg size_t	s_obj;
2534887Schin #endif
2544887Schin {
2554887Schin 	VMFLINIT();
2564887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,NIL(Void_t*),n_obj*s_obj,VM_RSZERO));
2574887Schin }
2584887Schin 
2594887Schin #if __STD_C
malloc(reg size_t size)2604887Schin extern Void_t* malloc(reg size_t size)
2614887Schin #else
2624887Schin extern Void_t* malloc(size)
2634887Schin reg size_t	size;
2644887Schin #endif
2654887Schin {
2664887Schin 	VMFLINIT();
2674887Schin 	return VMRECORD((*Vmregion->meth.allocf)(Vmregion,size));
2684887Schin }
2694887Schin 
2704887Schin #if __STD_C
realloc(reg Void_t * data,reg size_t size)2714887Schin extern Void_t* realloc(reg Void_t* data, reg size_t size)
2724887Schin #else
2734887Schin extern Void_t* realloc(data,size)
2744887Schin reg Void_t*	data;	/* block to be reallocated	*/
2754887Schin reg size_t	size;	/* new size			*/
2764887Schin #endif
2774887Schin {
2784887Schin #if USE_NATIVE
2794887Schin #undef	realloc
2804887Schin #if __STD_C
2814887Schin 	extern Void_t*	realloc(Void_t*, size_t);
2824887Schin #else
2834887Schin 	extern Void_t*	realloc();
2844887Schin #endif
2854887Schin #endif
2864887Schin 
2874887Schin 	VMFLINIT();
2884887Schin 
2894887Schin #if _PACKAGE_ast
2904887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
2914887Schin #if !USE_NATIVE
2924887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
2934887Schin #endif
2944887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0 )
2954887Schin 	{
2964887Schin #if USE_NATIVE
2974887Schin 		return realloc(data, size);
2984887Schin #else
2994887Schin 		Void_t*	newdata;
3004887Schin 		if((newdata = (*Vmregion->meth.allocf)(Vmregion,size)) )
3014887Schin 			memcpy(newdata,data,size);
3024887Schin 		return VMRECORD(newdata);
3034887Schin #endif
3044887Schin 	}
3054887Schin #endif
3064887Schin 
3074887Schin #if USE_NATIVE
3084887Schin 	{	Void_t*	newdata;
3094887Schin 		if (newdata = (*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE))
3104887Schin 			return newdata;
3114887Schin 		return VMRECORD(realloc(data, size));
3124887Schin 	}
3134887Schin #else
3144887Schin 	return VMRECORD((*Vmregion->meth.resizef)(Vmregion,data,size,VM_RSCOPY|VM_RSMOVE));
3154887Schin #endif
3164887Schin }
3174887Schin 
3184887Schin #if __STD_C
free(reg Void_t * data)3194887Schin extern void free(reg Void_t* data)
3204887Schin #else
3214887Schin extern void free(data)
3224887Schin reg Void_t*	data;
3234887Schin #endif
3244887Schin {
3254887Schin #if USE_NATIVE
3264887Schin #undef	free
3274887Schin #if __STD_C
3284887Schin 	extern void	free(Void_t*);
3294887Schin #else
3304887Schin 	extern void	free();
3314887Schin #endif
3324887Schin #endif
3334887Schin 
3344887Schin 	VMFLINIT();
3354887Schin 
3364887Schin #if _PACKAGE_ast
3374887Schin 	if(data && Vmregion->meth.meth != VM_MTDEBUG &&
3384887Schin #if !USE_NATIVE
3394887Schin 	   !(Vmregion->data->mode&VM_TRUST) &&
3404887Schin #endif
3414887Schin 	   (*Vmregion->meth.addrf)(Vmregion,data) != 0)
3424887Schin 	{
3434887Schin #if USE_NATIVE
3444887Schin 		free(data);
3454887Schin #endif
3464887Schin 		return;
3474887Schin 	}
3484887Schin #endif
3494887Schin 
3504887Schin #if USE_NATIVE
3514887Schin 	if ((*Vmregion->meth.freef)(Vmregion,data) != 0)
3524887Schin 		free(data);
3534887Schin #else
3544887Schin 	(void)(*Vmregion->meth.freef)(Vmregion,data);
3554887Schin #endif
3564887Schin }
3574887Schin 
3584887Schin #if __STD_C
cfree(reg Void_t * data)3594887Schin extern void cfree(reg Void_t* data)
3604887Schin #else
3614887Schin extern void cfree(data)
3624887Schin reg Void_t*	data;
3634887Schin #endif
3644887Schin {
3654887Schin 	free(data);
3664887Schin }
3674887Schin 
3684887Schin #if __STD_C
memalign(reg size_t align,reg size_t size)3694887Schin extern Void_t* memalign(reg size_t align, reg size_t size)
3704887Schin #else
3714887Schin extern Void_t* memalign(align, size)
3724887Schin reg size_t	align;
3734887Schin reg size_t	size;
3744887Schin #endif
3754887Schin {
3764887Schin 	Void_t*	addr;
3774887Schin 
3784887Schin 	VMFLINIT();
3794887Schin 	VMBLOCK
3804887Schin 	addr = VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,align));
3814887Schin 	VMUNBLOCK
3824887Schin 	return addr;
3834887Schin }
3844887Schin 
3854887Schin #if __STD_C
posix_memalign(reg Void_t ** memptr,reg size_t align,reg size_t size)38610898Sroland.mainz@nrubsig.org extern int posix_memalign(reg Void_t **memptr, reg size_t align, reg size_t size)
38710898Sroland.mainz@nrubsig.org #else
38810898Sroland.mainz@nrubsig.org extern int posix_memalign(memptr, align, size)
38910898Sroland.mainz@nrubsig.org reg Void_t**	memptr;
39010898Sroland.mainz@nrubsig.org reg size_t	align;
39110898Sroland.mainz@nrubsig.org reg size_t	size;
39210898Sroland.mainz@nrubsig.org #endif
39310898Sroland.mainz@nrubsig.org {
39410898Sroland.mainz@nrubsig.org 	Void_t	*mem;
39510898Sroland.mainz@nrubsig.org 
39610898Sroland.mainz@nrubsig.org 	if(align == 0 || (align%sizeof(Void_t*)) != 0 || ((align-1)&align) != 0 )
39710898Sroland.mainz@nrubsig.org 		return EINVAL;
39810898Sroland.mainz@nrubsig.org 
39910898Sroland.mainz@nrubsig.org 	if(!(mem = memalign(align, size)) )
40010898Sroland.mainz@nrubsig.org 		return ENOMEM;
40110898Sroland.mainz@nrubsig.org 
40210898Sroland.mainz@nrubsig.org 	*memptr = mem;
40310898Sroland.mainz@nrubsig.org 	return 0;
40410898Sroland.mainz@nrubsig.org }
40510898Sroland.mainz@nrubsig.org 
40610898Sroland.mainz@nrubsig.org #if __STD_C
valloc(reg size_t size)4074887Schin extern Void_t* valloc(reg size_t size)
4084887Schin #else
4094887Schin extern Void_t* valloc(size)
4104887Schin reg size_t	size;
4114887Schin #endif
4124887Schin {
4134887Schin 	VMFLINIT();
4144887Schin 	GETPAGESIZE(_Vmpagesize);
4154887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,size,_Vmpagesize));
4164887Schin }
4174887Schin 
4184887Schin #if __STD_C
pvalloc(reg size_t size)4194887Schin extern Void_t* pvalloc(reg size_t size)
4204887Schin #else
4214887Schin extern Void_t* pvalloc(size)
4224887Schin reg size_t	size;
4234887Schin #endif
4244887Schin {
4254887Schin 	VMFLINIT();
4264887Schin 	GETPAGESIZE(_Vmpagesize);
4274887Schin 	return VMRECORD((*Vmregion->meth.alignf)(Vmregion,ROUND(size,_Vmpagesize),_Vmpagesize));
4284887Schin }
4294887Schin 
4304887Schin #if !_PACKAGE_ast
4314887Schin #if __STD_C
strdup(const char * s)4324887Schin char* strdup(const char* s)
4334887Schin #else
4344887Schin char* strdup(s)
4354887Schin char*	s;
4364887Schin #endif
4374887Schin {
4384887Schin 	char	*ns;
4394887Schin 	size_t	n;
4404887Schin 
4414887Schin 	if(!s)
4424887Schin 		return NIL(char*);
4434887Schin 	else
4444887Schin 	{	n = strlen(s);
4454887Schin 		if((ns = malloc(n+1)) )
4464887Schin 			memcpy(ns,s,n+1);
4474887Schin 		return ns;
4484887Schin 	}
4494887Schin }
4504887Schin #endif /* _PACKAGE_ast */
4514887Schin 
4524887Schin #if !_lib_alloca || _mal_alloca
4534887Schin #ifndef _stk_down
4544887Schin #define _stk_down	0
4554887Schin #endif
4564887Schin typedef struct _alloca_s	Alloca_t;
4574887Schin union _alloca_u
4584887Schin {	struct
4594887Schin 	{	char*		addr;
4604887Schin 		Alloca_t*	next;
4614887Schin 	} head;
4624887Schin 	char	array[ALIGN];
4634887Schin };
4644887Schin struct _alloca_s
4654887Schin {	union _alloca_u	head;
4664887Schin 	Vmuchar_t	data[1];
4674887Schin };
4684887Schin 
4694887Schin #if __STD_C
alloca(size_t size)4704887Schin extern Void_t* alloca(size_t size)
4714887Schin #else
4724887Schin extern Void_t* alloca(size)
4734887Schin size_t	size;
4744887Schin #endif
4754887Schin {	char		array[ALIGN];
4764887Schin 	char*		file;
4774887Schin 	int		line;
4784887Schin 	Void_t*		func;
4794887Schin 	reg Alloca_t*	f;
4804887Schin 	static Alloca_t* Frame;
4814887Schin 
4824887Schin 	VMFLINIT();
4834887Schin 	VMFLF(Vmregion,file,line,func);
4844887Schin 	while(Frame)
4854887Schin 	{	if(( _stk_down && &array[0] > Frame->head.head.addr) ||
4864887Schin 		   (!_stk_down && &array[0] < Frame->head.head.addr) )
4874887Schin 		{	f = Frame;
4884887Schin 			Frame = f->head.head.next;
4894887Schin 			(void)(*Vmregion->meth.freef)(Vmregion,f);
4904887Schin 		}
4914887Schin 		else	break;
4924887Schin 	}
4934887Schin 
4944887Schin 	Vmregion->file = file;
4954887Schin 	Vmregion->line = line;
4964887Schin 	Vmregion->func = func;
4974887Schin 	f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion,size+sizeof(Alloca_t)-1);
4984887Schin 
4994887Schin 	f->head.head.addr = &array[0];
5004887Schin 	f->head.head.next = Frame;
5014887Schin 	Frame = f;
5024887Schin 
5034887Schin 	return (Void_t*)f->data;
5044887Schin }
5054887Schin #endif /*!_lib_alloca || _mal_alloca*/
5064887Schin 
5074887Schin #if _map_malloc
5084887Schin 
5094887Schin /* not sure of all the implications -- 0 is conservative for now */
5104887Schin #define USE_NATIVE	0	/* native free/realloc on non-vmalloc ptrs */
5114887Schin 
5124887Schin #else
5134887Schin 
5144887Schin /* intercept _* __* __libc_* variants */
5154887Schin 
5164887Schin #if __lib__malloc
F2(_calloc,size_t,n,size_t,m)5174887Schin extern Void_t*	F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(_cfree,Void_t *,p)5184887Schin extern Void_t	F1(_cfree, Void_t*,p) { free(p); }
F1(_free,Void_t *,p)5194887Schin extern Void_t	F1(_free, Void_t*,p) { free(p); }
F1(_malloc,size_t,n)5204887Schin extern Void_t*	F1(_malloc, size_t,n) { return malloc(n); }
5214887Schin #if _lib_memalign
F2(_memalign,size_t,a,size_t,n)5224887Schin extern Void_t*	F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
5234887Schin #endif
5244887Schin #if _lib_pvalloc
F1(_pvalloc,size_t,n)5254887Schin extern Void_t*	F1(_pvalloc, size_t,n) { return pvalloc(n); }
5264887Schin #endif
F2(_realloc,Void_t *,p,size_t,n)5274887Schin extern Void_t*	F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
5284887Schin #if _lib_valloc
F1(_valloc,size_t,n)5294887Schin extern Void_t*	F1(_valloc, size_t,n) { return valloc(n); }
5304887Schin #endif
5314887Schin #endif
5324887Schin 
5334887Schin #if _lib___malloc
F2(__calloc,size_t,n,size_t,m)5344887Schin extern Void_t*	F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(__cfree,Void_t *,p)5354887Schin extern Void_t	F1(__cfree, Void_t*,p) { free(p); }
F1(__free,Void_t *,p)5364887Schin extern Void_t	F1(__free, Void_t*,p) { free(p); }
F1(__malloc,size_t,n)5374887Schin extern Void_t*	F1(__malloc, size_t,n) { return malloc(n); }
5384887Schin #if _lib_memalign
F2(__memalign,size_t,a,size_t,n)5394887Schin extern Void_t*	F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
5404887Schin #endif
5414887Schin #if _lib_pvalloc
F1(__pvalloc,size_t,n)5424887Schin extern Void_t*	F1(__pvalloc, size_t,n) { return pvalloc(n); }
5434887Schin #endif
F2(__realloc,Void_t *,p,size_t,n)5444887Schin extern Void_t*	F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
5454887Schin #if _lib_valloc
F1(__valloc,size_t,n)5464887Schin extern Void_t*	F1(__valloc, size_t,n) { return valloc(n); }
5474887Schin #endif
5484887Schin #endif
5494887Schin 
5504887Schin #if _lib___libc_malloc
F2(__libc_calloc,size_t,n,size_t,m)5514887Schin extern Void_t*	F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(__libc_cfree,Void_t *,p)5524887Schin extern Void_t	F1(__libc_cfree, Void_t*,p) { free(p); }
F1(__libc_free,Void_t *,p)5534887Schin extern Void_t	F1(__libc_free, Void_t*,p) { free(p); }
F1(__libc_malloc,size_t,n)5544887Schin extern Void_t*	F1(__libc_malloc, size_t,n) { return malloc(n); }
5554887Schin #if _lib_memalign
F2(__libc_memalign,size_t,a,size_t,n)5564887Schin extern Void_t*	F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
5574887Schin #endif
5584887Schin #if _lib_pvalloc
F1(__libc_pvalloc,size_t,n)5594887Schin extern Void_t*	F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
5604887Schin #endif
F2(__libc_realloc,Void_t *,p,size_t,n)5614887Schin extern Void_t*	F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
5624887Schin #if _lib_valloc
F1(__libc_valloc,size_t,n)5634887Schin extern Void_t*	F1(__libc_valloc, size_t,n) { return valloc(n); }
5644887Schin #endif
5654887Schin #endif
5664887Schin 
5674887Schin #endif /* _map_malloc */
5684887Schin 
5694887Schin #undef	extern
5704887Schin 
5714887Schin #if _hdr_malloc /* need the mallint interface for statistics, etc. */
5724887Schin 
5734887Schin #undef	calloc
5744887Schin #define calloc		______calloc
5754887Schin #undef	cfree
5764887Schin #define cfree		______cfree
5774887Schin #undef	free
5784887Schin #define free		______free
5794887Schin #undef	malloc
5804887Schin #define malloc		______malloc
5814887Schin #undef	pvalloc
5824887Schin #define pvalloc		______pvalloc
5834887Schin #undef	realloc
5844887Schin #define realloc		______realloc
5854887Schin #undef	valloc
5864887Schin #define valloc		______valloc
5874887Schin 
5884887Schin #if !_UWIN
5894887Schin 
5904887Schin #include	<malloc.h>
5914887Schin 
5924887Schin typedef struct mallinfo Mallinfo_t;
5934887Schin typedef struct mstats Mstats_t;
5944887Schin 
5954887Schin #endif
5964887Schin 
5974887Schin #if defined(__EXPORT__)
5984887Schin #define extern		__EXPORT__
5994887Schin #endif
6004887Schin 
6014887Schin #if _lib_mallopt
6024887Schin #if __STD_C
mallopt(int cmd,int value)6034887Schin extern int mallopt(int cmd, int value)
6044887Schin #else
6054887Schin extern int mallopt(cmd, value)
6064887Schin int	cmd;
6074887Schin int	value;
6084887Schin #endif
6094887Schin {
6104887Schin 	VMFLINIT();
6114887Schin 	return 0;
6124887Schin }
6134887Schin #endif /*_lib_mallopt*/
6144887Schin 
6154887Schin #if _lib_mallinfo && _mem_arena_mallinfo
6164887Schin #if __STD_C
mallinfo(void)6174887Schin extern Mallinfo_t mallinfo(void)
6184887Schin #else
6194887Schin extern Mallinfo_t mallinfo()
6204887Schin #endif
6214887Schin {
6224887Schin 	Vmstat_t	sb;
6234887Schin 	Mallinfo_t	mi;
6244887Schin 
6254887Schin 	VMFLINIT();
6264887Schin 	memset(&mi,0,sizeof(mi));
6274887Schin 	if(vmstat(Vmregion,&sb) >= 0)
6284887Schin 	{	mi.arena = sb.extent;
6294887Schin 		mi.ordblks = sb.n_busy+sb.n_free;
6304887Schin 		mi.uordblks = sb.s_busy;
6314887Schin 		mi.fordblks = sb.s_free;
6324887Schin 	}
6334887Schin 	return mi;
6344887Schin }
6354887Schin #endif /* _lib_mallinfo */
6364887Schin 
6374887Schin #if _lib_mstats && _mem_bytes_total_mstats
6384887Schin #if __STD_C
mstats(void)6394887Schin extern Mstats_t mstats(void)
6404887Schin #else
6414887Schin extern Mstats_t mstats()
6424887Schin #endif
6434887Schin {
6444887Schin 	Vmstat_t	sb;
6454887Schin 	Mstats_t	ms;
6464887Schin 
6474887Schin 	VMFLINIT();
6484887Schin 	memset(&ms,0,sizeof(ms));
6494887Schin 	if(vmstat(Vmregion,&sb) >= 0)
6504887Schin 	{	ms.bytes_total = sb.extent;
6514887Schin 		ms.chunks_used = sb.n_busy;
6524887Schin 		ms.bytes_used = sb.s_busy;
6534887Schin 		ms.chunks_free = sb.n_free;
6544887Schin 		ms.bytes_free = sb.s_free;
6554887Schin 	}
6564887Schin 	return ms;
6574887Schin }
6584887Schin #endif /*_lib_mstats*/
6594887Schin 
6604887Schin #undef	extern
6614887Schin 
6624887Schin #endif/*_hdr_malloc*/
6634887Schin 
6644887Schin #else
6654887Schin 
6664887Schin /*
6674887Schin  * even though there is no malloc override, still provide
6684887Schin  * _ast_* counterparts for object compatibility
6694887Schin  */
6704887Schin 
6714887Schin #undef	calloc
6724887Schin extern Void_t*	calloc _ARG_((size_t, size_t));
6734887Schin 
6744887Schin #undef	cfree
6754887Schin extern void	cfree _ARG_((Void_t*));
6764887Schin 
6774887Schin #undef	free
6784887Schin extern void	free _ARG_((Void_t*));
6794887Schin 
6804887Schin #undef	malloc
6814887Schin extern Void_t*	malloc _ARG_((size_t));
6824887Schin 
6834887Schin #if _lib_memalign
6844887Schin #undef	memalign
6854887Schin extern Void_t*	memalign _ARG_((size_t, size_t));
6864887Schin #endif
6874887Schin 
6884887Schin #if _lib_pvalloc
6894887Schin #undef	pvalloc
6904887Schin extern Void_t*	pvalloc _ARG_((size_t));
6914887Schin #endif
6924887Schin 
6934887Schin #undef	realloc
6944887Schin extern Void_t*	realloc _ARG_((Void_t*, size_t));
6954887Schin 
6964887Schin #if _lib_valloc
6974887Schin #undef	valloc
6984887Schin extern Void_t*	valloc _ARG_((size_t));
6994887Schin #endif
7004887Schin 
7014887Schin #if defined(__EXPORT__)
7024887Schin #define extern		__EXPORT__
7034887Schin #endif
7044887Schin 
F2(_ast_calloc,size_t,n,size_t,m)7054887Schin extern Void_t*	F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
F1(_ast_cfree,Void_t *,p)7064887Schin extern Void_t	F1(_ast_cfree, Void_t*,p) { free(p); }
F1(_ast_free,Void_t *,p)7074887Schin extern Void_t	F1(_ast_free, Void_t*,p) { free(p); }
F1(_ast_malloc,size_t,n)7084887Schin extern Void_t*	F1(_ast_malloc, size_t,n) { return malloc(n); }
7094887Schin #if _lib_memalign
F2(_ast_memalign,size_t,a,size_t,n)7104887Schin extern Void_t*	F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
7114887Schin #endif
7124887Schin #if _lib_pvalloc
F1(_ast_pvalloc,size_t,n)7134887Schin extern Void_t*	F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
7144887Schin #endif
F2(_ast_realloc,Void_t *,p,size_t,n)7154887Schin extern Void_t*	F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
7164887Schin #if _lib_valloc
F1(_ast_valloc,size_t,n)7174887Schin extern Void_t*	F1(_ast_valloc, size_t,n) { return valloc(n); }
7184887Schin #endif
7194887Schin 
7204887Schin #undef	extern
7214887Schin 
7224887Schin #if _hdr_malloc
7234887Schin 
7244887Schin #undef	mallinfo
7254887Schin #undef	mallopt
7264887Schin #undef	mstats
7274887Schin 
7284887Schin #define calloc		______calloc
7294887Schin #define cfree		______cfree
7304887Schin #define free		______free
7314887Schin #define malloc		______malloc
7324887Schin #define pvalloc		______pvalloc
7334887Schin #define realloc		______realloc
7344887Schin #define valloc		______valloc
7354887Schin 
7364887Schin #if !_UWIN
7374887Schin 
7384887Schin #include	<malloc.h>
7394887Schin 
7404887Schin typedef struct mallinfo Mallinfo_t;
7414887Schin typedef struct mstats Mstats_t;
7424887Schin 
7434887Schin #endif
7444887Schin 
7454887Schin #if defined(__EXPORT__)
7464887Schin #define extern		__EXPORT__
7474887Schin #endif
7484887Schin 
7494887Schin #if _lib_mallopt
F2(_ast_mallopt,int,cmd,int,value)7504887Schin extern int	F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
7514887Schin #endif
7524887Schin 
7534887Schin #if _lib_mallinfo && _mem_arena_mallinfo
F0(_ast_mallinfo,void)7544887Schin extern Mallinfo_t	F0(_ast_mallinfo, void) { return mallinfo(); }
7554887Schin #endif
7564887Schin 
7574887Schin #if _lib_mstats && _mem_bytes_total_mstats
F0(_ast_mstats,void)7584887Schin extern Mstats_t		F0(_ast_mstats, void) { return mstats(); }
7594887Schin #endif
7604887Schin 
7614887Schin #undef	extern
7624887Schin 
7634887Schin #endif /*_hdr_malloc*/
7644887Schin 
7654887Schin #endif /*!_std_malloc*/
7664887Schin 
767*12068SRoger.Faulkner@Oracle.COM #if __STD_C
atou(char ** sp)768*12068SRoger.Faulkner@Oracle.COM static Vmulong_t atou(char** sp)
769*12068SRoger.Faulkner@Oracle.COM #else
770*12068SRoger.Faulkner@Oracle.COM static Vmulong_t atou(sp)
771*12068SRoger.Faulkner@Oracle.COM char**	sp;
772*12068SRoger.Faulkner@Oracle.COM #endif
773*12068SRoger.Faulkner@Oracle.COM {
774*12068SRoger.Faulkner@Oracle.COM 	char*		s = *sp;
775*12068SRoger.Faulkner@Oracle.COM 	Vmulong_t	v = 0;
776*12068SRoger.Faulkner@Oracle.COM 
777*12068SRoger.Faulkner@Oracle.COM 	if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
778*12068SRoger.Faulkner@Oracle.COM 	{	for(s += 2; *s; ++s)
779*12068SRoger.Faulkner@Oracle.COM 		{	if(*s >= '0' && *s <= '9')
780*12068SRoger.Faulkner@Oracle.COM 				v = (v << 4) + (*s - '0');
781*12068SRoger.Faulkner@Oracle.COM 			else if(*s >= 'a' && *s <= 'f')
782*12068SRoger.Faulkner@Oracle.COM 				v = (v << 4) + (*s - 'a') + 10;
783*12068SRoger.Faulkner@Oracle.COM 			else if(*s >= 'A' && *s <= 'F')
784*12068SRoger.Faulkner@Oracle.COM 				v = (v << 4) + (*s - 'A') + 10;
785*12068SRoger.Faulkner@Oracle.COM 			else break;
786*12068SRoger.Faulkner@Oracle.COM 		}
787*12068SRoger.Faulkner@Oracle.COM 	}
788*12068SRoger.Faulkner@Oracle.COM 	else
789*12068SRoger.Faulkner@Oracle.COM 	{	for(; *s; ++s)
790*12068SRoger.Faulkner@Oracle.COM 		{	if(*s >= '0' && *s <= '9')
791*12068SRoger.Faulkner@Oracle.COM 				v = v*10 + (*s - '0');
792*12068SRoger.Faulkner@Oracle.COM 			else break;
793*12068SRoger.Faulkner@Oracle.COM 		}
794*12068SRoger.Faulkner@Oracle.COM 	}
795*12068SRoger.Faulkner@Oracle.COM 
796*12068SRoger.Faulkner@Oracle.COM 	*sp = s;
797*12068SRoger.Faulkner@Oracle.COM 	return v;
798*12068SRoger.Faulkner@Oracle.COM }
799*12068SRoger.Faulkner@Oracle.COM 
800*12068SRoger.Faulkner@Oracle.COM #if __STD_C
insertpid(char * begs,char * ends)801*12068SRoger.Faulkner@Oracle.COM static char* insertpid(char* begs, char* ends)
802*12068SRoger.Faulkner@Oracle.COM #else
803*12068SRoger.Faulkner@Oracle.COM static char* insertpid(begs,ends)
804*12068SRoger.Faulkner@Oracle.COM char*	begs;
805*12068SRoger.Faulkner@Oracle.COM char*	ends;
806*12068SRoger.Faulkner@Oracle.COM #endif
807*12068SRoger.Faulkner@Oracle.COM {	int	pid;
808*12068SRoger.Faulkner@Oracle.COM 	char*	s;
809*12068SRoger.Faulkner@Oracle.COM 
810*12068SRoger.Faulkner@Oracle.COM 	if((pid = getpid()) < 0)
811*12068SRoger.Faulkner@Oracle.COM 		return NIL(char*);
812*12068SRoger.Faulkner@Oracle.COM 
813*12068SRoger.Faulkner@Oracle.COM 	s = ends;
814*12068SRoger.Faulkner@Oracle.COM 	do
815*12068SRoger.Faulkner@Oracle.COM 	{	if(s == begs)
816*12068SRoger.Faulkner@Oracle.COM 			return NIL(char*);
817*12068SRoger.Faulkner@Oracle.COM 		*--s = '0' + pid%10;
818*12068SRoger.Faulkner@Oracle.COM 	} while((pid /= 10) > 0);
819*12068SRoger.Faulkner@Oracle.COM 	while(s < ends)
820*12068SRoger.Faulkner@Oracle.COM 		*begs++ = *s++;
821*12068SRoger.Faulkner@Oracle.COM 
822*12068SRoger.Faulkner@Oracle.COM 	return begs;
823*12068SRoger.Faulkner@Oracle.COM }
824*12068SRoger.Faulkner@Oracle.COM 
825*12068SRoger.Faulkner@Oracle.COM #if __STD_C
createfile(char * file)826*12068SRoger.Faulkner@Oracle.COM static int createfile(char* file)
827*12068SRoger.Faulkner@Oracle.COM #else
828*12068SRoger.Faulkner@Oracle.COM static int createfile(file)
829*12068SRoger.Faulkner@Oracle.COM char*	file;
830*12068SRoger.Faulkner@Oracle.COM #endif
831*12068SRoger.Faulkner@Oracle.COM {
832*12068SRoger.Faulkner@Oracle.COM 	char	buf[1024];
833*12068SRoger.Faulkner@Oracle.COM 	char	*next, *endb;
834*12068SRoger.Faulkner@Oracle.COM 	int	fd;
835*12068SRoger.Faulkner@Oracle.COM 
836*12068SRoger.Faulkner@Oracle.COM 	next = buf;
837*12068SRoger.Faulkner@Oracle.COM 	endb = buf + sizeof(buf);
838*12068SRoger.Faulkner@Oracle.COM 	while(*file)
839*12068SRoger.Faulkner@Oracle.COM 	{	if(*file == '%')
840*12068SRoger.Faulkner@Oracle.COM 		{	switch(file[1])
841*12068SRoger.Faulkner@Oracle.COM 			{
842*12068SRoger.Faulkner@Oracle.COM 			case 'p' :
843*12068SRoger.Faulkner@Oracle.COM 				if(!(next = insertpid(next,endb)) )
844*12068SRoger.Faulkner@Oracle.COM 					return -1;
845*12068SRoger.Faulkner@Oracle.COM 				file += 2;
846*12068SRoger.Faulkner@Oracle.COM 				break;
847*12068SRoger.Faulkner@Oracle.COM 			default :
848*12068SRoger.Faulkner@Oracle.COM 				goto copy;
849*12068SRoger.Faulkner@Oracle.COM 			}
850*12068SRoger.Faulkner@Oracle.COM 		}
851*12068SRoger.Faulkner@Oracle.COM 		else
852*12068SRoger.Faulkner@Oracle.COM 		{ copy:
853*12068SRoger.Faulkner@Oracle.COM 			*next++ = *file++;
854*12068SRoger.Faulkner@Oracle.COM 		}
855*12068SRoger.Faulkner@Oracle.COM 
856*12068SRoger.Faulkner@Oracle.COM 		if(next >= endb)
857*12068SRoger.Faulkner@Oracle.COM 			return -1;
858*12068SRoger.Faulkner@Oracle.COM 	}
859*12068SRoger.Faulkner@Oracle.COM 
860*12068SRoger.Faulkner@Oracle.COM 	*next = '\0';
861*12068SRoger.Faulkner@Oracle.COM 	file = buf;
862*12068SRoger.Faulkner@Oracle.COM 	if (*file == '&' && *(file += 1) || strncmp(file, "/dev/fd/", 8) == 0 && *(file += 8))
863*12068SRoger.Faulkner@Oracle.COM 		fd = dup((int)atou(&file));
864*12068SRoger.Faulkner@Oracle.COM 	else if (*file)
865*12068SRoger.Faulkner@Oracle.COM #if _PACKAGE_ast
866*12068SRoger.Faulkner@Oracle.COM 		fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, CREAT_MODE);
867*12068SRoger.Faulkner@Oracle.COM #else
868*12068SRoger.Faulkner@Oracle.COM 		fd = creat(file, CREAT_MODE);
869*12068SRoger.Faulkner@Oracle.COM #endif
870*12068SRoger.Faulkner@Oracle.COM 	else
871*12068SRoger.Faulkner@Oracle.COM 		return -1;
872*12068SRoger.Faulkner@Oracle.COM #if _PACKAGE_ast
873*12068SRoger.Faulkner@Oracle.COM #ifdef FD_CLOEXEC
874*12068SRoger.Faulkner@Oracle.COM 	if (fd >= 0)
875*12068SRoger.Faulkner@Oracle.COM 		fcntl(fd, F_SETFD, FD_CLOEXEC);
876*12068SRoger.Faulkner@Oracle.COM #endif
877*12068SRoger.Faulkner@Oracle.COM #endif
878*12068SRoger.Faulkner@Oracle.COM 	return fd;
879*12068SRoger.Faulkner@Oracle.COM }
880*12068SRoger.Faulkner@Oracle.COM 
881*12068SRoger.Faulkner@Oracle.COM #if __STD_C
pfprint(void)882*12068SRoger.Faulkner@Oracle.COM static void pfprint(void)
883*12068SRoger.Faulkner@Oracle.COM #else
884*12068SRoger.Faulkner@Oracle.COM static void pfprint()
885*12068SRoger.Faulkner@Oracle.COM #endif
886*12068SRoger.Faulkner@Oracle.COM {
887*12068SRoger.Faulkner@Oracle.COM 	if(Vmregion->meth.meth == VM_MTPROFILE)
888*12068SRoger.Faulkner@Oracle.COM 		vmprofile(Vmregion,_Vmpffd);
889*12068SRoger.Faulkner@Oracle.COM }
890*12068SRoger.Faulkner@Oracle.COM 
891*12068SRoger.Faulkner@Oracle.COM /*
892*12068SRoger.Faulkner@Oracle.COM  * initialize runtime options from the VMALLOC_OPTIONS env var
893*12068SRoger.Faulkner@Oracle.COM  */
894*12068SRoger.Faulkner@Oracle.COM 
895*12068SRoger.Faulkner@Oracle.COM #define COPY(t,e,f)	while ((*t = *f++) && t < e) t++
896*12068SRoger.Faulkner@Oracle.COM 
897*12068SRoger.Faulkner@Oracle.COM #if __STD_C
_vmoptions(void)898*12068SRoger.Faulkner@Oracle.COM void _vmoptions(void)
899*12068SRoger.Faulkner@Oracle.COM #else
900*12068SRoger.Faulkner@Oracle.COM void _vmoptions()
901*12068SRoger.Faulkner@Oracle.COM #endif
902*12068SRoger.Faulkner@Oracle.COM {
903*12068SRoger.Faulkner@Oracle.COM 	Vmalloc_t*	vm = 0;
904*12068SRoger.Faulkner@Oracle.COM 	char*		trace = 0;
905*12068SRoger.Faulkner@Oracle.COM 	char*		s;
906*12068SRoger.Faulkner@Oracle.COM 	char*		t;
907*12068SRoger.Faulkner@Oracle.COM 	char*		v;
908*12068SRoger.Faulkner@Oracle.COM 	Vmulong_t	n;
909*12068SRoger.Faulkner@Oracle.COM 	int		fd;
910*12068SRoger.Faulkner@Oracle.COM 	char		buf[1024];
911*12068SRoger.Faulkner@Oracle.COM 
912*12068SRoger.Faulkner@Oracle.COM 	_Vmoptions = 1;
913*12068SRoger.Faulkner@Oracle.COM 	t = buf;
914*12068SRoger.Faulkner@Oracle.COM 	v = &buf[sizeof(buf)-1];
915*12068SRoger.Faulkner@Oracle.COM 	if (s = getenv("VMALLOC_OPTIONS"))
916*12068SRoger.Faulkner@Oracle.COM 		COPY(t, v, s);
917*12068SRoger.Faulkner@Oracle.COM #if 1 /* backwards compatibility until 2011 */
918*12068SRoger.Faulkner@Oracle.COM 	else
919*12068SRoger.Faulkner@Oracle.COM 	{
920*12068SRoger.Faulkner@Oracle.COM 		char*	p;
921*12068SRoger.Faulkner@Oracle.COM 
922*12068SRoger.Faulkner@Oracle.COM 		if (s = getenv("VMDEBUG"))
923*12068SRoger.Faulkner@Oracle.COM 		{
924*12068SRoger.Faulkner@Oracle.COM 			switch (*s++)
925*12068SRoger.Faulkner@Oracle.COM 			{
926*12068SRoger.Faulkner@Oracle.COM 			case 0:
927*12068SRoger.Faulkner@Oracle.COM 				break;
928*12068SRoger.Faulkner@Oracle.COM 			case 'a':
929*12068SRoger.Faulkner@Oracle.COM 				p = " abort";
930*12068SRoger.Faulkner@Oracle.COM 				COPY(t, v, p);
931*12068SRoger.Faulkner@Oracle.COM 				break;
932*12068SRoger.Faulkner@Oracle.COM 			case 'w':
933*12068SRoger.Faulkner@Oracle.COM 				p = " warn";
934*12068SRoger.Faulkner@Oracle.COM 				COPY(t, v, p);
935*12068SRoger.Faulkner@Oracle.COM 				break;
936*12068SRoger.Faulkner@Oracle.COM 			case '0':
937*12068SRoger.Faulkner@Oracle.COM 				if (*s-- == 'x')
938*12068SRoger.Faulkner@Oracle.COM 				{
939*12068SRoger.Faulkner@Oracle.COM 					p = " watch=";
940*12068SRoger.Faulkner@Oracle.COM 					COPY(t, v, p);
941*12068SRoger.Faulkner@Oracle.COM 					COPY(t, v, s);
942*12068SRoger.Faulkner@Oracle.COM 					break;
943*12068SRoger.Faulkner@Oracle.COM 				}
944*12068SRoger.Faulkner@Oracle.COM 				/*FALLTHROUGH*/
945*12068SRoger.Faulkner@Oracle.COM 			default:
946*12068SRoger.Faulkner@Oracle.COM 				p = " period=";
947*12068SRoger.Faulkner@Oracle.COM 				COPY(t, v, p);
948*12068SRoger.Faulkner@Oracle.COM 				COPY(t, v, s);
949*12068SRoger.Faulkner@Oracle.COM 				break;
950*12068SRoger.Faulkner@Oracle.COM 			}
951*12068SRoger.Faulkner@Oracle.COM 		}
952*12068SRoger.Faulkner@Oracle.COM 		if ((s = getenv("VMETHOD")) && *s)
953*12068SRoger.Faulkner@Oracle.COM 		{
954*12068SRoger.Faulkner@Oracle.COM 			p = " method=";
955*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, p);
956*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, s);
957*12068SRoger.Faulkner@Oracle.COM 		}
958*12068SRoger.Faulkner@Oracle.COM 		if ((s = getenv("VMPROFILE")) && *s)
959*12068SRoger.Faulkner@Oracle.COM 		{
960*12068SRoger.Faulkner@Oracle.COM 			p = " profile=";
961*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, p);
962*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, s);
963*12068SRoger.Faulkner@Oracle.COM 		}
964*12068SRoger.Faulkner@Oracle.COM 		if ((s = getenv("VMTRACE")) && *s)
965*12068SRoger.Faulkner@Oracle.COM 		{
966*12068SRoger.Faulkner@Oracle.COM 			p = " trace=";
967*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, p);
968*12068SRoger.Faulkner@Oracle.COM 			COPY(t, v, s);
969*12068SRoger.Faulkner@Oracle.COM 		}
970*12068SRoger.Faulkner@Oracle.COM 	}
971*12068SRoger.Faulkner@Oracle.COM #endif
972*12068SRoger.Faulkner@Oracle.COM 	if (t > buf)
973*12068SRoger.Faulkner@Oracle.COM 	{
974*12068SRoger.Faulkner@Oracle.COM 		*t = 0;
975*12068SRoger.Faulkner@Oracle.COM 		s = buf;
976*12068SRoger.Faulkner@Oracle.COM 		for (;;)
977*12068SRoger.Faulkner@Oracle.COM 		{
978*12068SRoger.Faulkner@Oracle.COM 			while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
979*12068SRoger.Faulkner@Oracle.COM 				s++;
980*12068SRoger.Faulkner@Oracle.COM 			if (!*(t = s))
981*12068SRoger.Faulkner@Oracle.COM 				break;
982*12068SRoger.Faulkner@Oracle.COM 			v = 0;
983*12068SRoger.Faulkner@Oracle.COM 			while (*s)
984*12068SRoger.Faulkner@Oracle.COM 				if (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
985*12068SRoger.Faulkner@Oracle.COM 				{
986*12068SRoger.Faulkner@Oracle.COM 					*s++ = 0;
987*12068SRoger.Faulkner@Oracle.COM 					break;
988*12068SRoger.Faulkner@Oracle.COM 				}
989*12068SRoger.Faulkner@Oracle.COM 				else if (!v && *s == '=')
990*12068SRoger.Faulkner@Oracle.COM 				{
991*12068SRoger.Faulkner@Oracle.COM 					*s++ = 0;
992*12068SRoger.Faulkner@Oracle.COM 					if (!*(v = s))
993*12068SRoger.Faulkner@Oracle.COM 						v = 0;
994*12068SRoger.Faulkner@Oracle.COM 				}
995*12068SRoger.Faulkner@Oracle.COM 				else
996*12068SRoger.Faulkner@Oracle.COM 					s++;
997*12068SRoger.Faulkner@Oracle.COM 			if (t[0] == 'n' && t[1] == 'o')
998*12068SRoger.Faulkner@Oracle.COM 				continue;
999*12068SRoger.Faulkner@Oracle.COM 			switch (t[0])
1000*12068SRoger.Faulkner@Oracle.COM 			{
1001*12068SRoger.Faulkner@Oracle.COM 			case 'a':		/* abort */
1002*12068SRoger.Faulkner@Oracle.COM 				if (!vm)
1003*12068SRoger.Faulkner@Oracle.COM 					vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1004*12068SRoger.Faulkner@Oracle.COM 				if (vm && vm->meth.meth == VM_MTDEBUG)
1005*12068SRoger.Faulkner@Oracle.COM 					vmset(vm, VM_DBABORT, 1);
1006*12068SRoger.Faulkner@Oracle.COM 				else
1007*12068SRoger.Faulkner@Oracle.COM 					_Vmassert |= VM_abort;
1008*12068SRoger.Faulkner@Oracle.COM 				break;
1009*12068SRoger.Faulkner@Oracle.COM 			case 'c':		/* check */
1010*12068SRoger.Faulkner@Oracle.COM 				_Vmassert |= VM_check;
1011*12068SRoger.Faulkner@Oracle.COM 				break;
1012*12068SRoger.Faulkner@Oracle.COM 			case 'm':
1013*12068SRoger.Faulkner@Oracle.COM 				switch (t[1])
1014*12068SRoger.Faulkner@Oracle.COM 				{
1015*12068SRoger.Faulkner@Oracle.COM 				case 'e':	/* method=<method> */
1016*12068SRoger.Faulkner@Oracle.COM 					if (v && !vm)
1017*12068SRoger.Faulkner@Oracle.COM 					{
1018*12068SRoger.Faulkner@Oracle.COM 						if ((v[0] == 'V' || v[0] == 'v') && (v[1] == 'M' || v[1] == 'm'))
1019*12068SRoger.Faulkner@Oracle.COM 							v += 2;
1020*12068SRoger.Faulkner@Oracle.COM 						if (strcmp(v, "debug") == 0)
1021*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1022*12068SRoger.Faulkner@Oracle.COM 						else if (strcmp(v, "profile") == 0)
1023*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmprofile, 0);
1024*12068SRoger.Faulkner@Oracle.COM 						else if (strcmp(v, "last") == 0)
1025*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmlast, 0);
1026*12068SRoger.Faulkner@Oracle.COM 						else if (strcmp(v, "best") == 0)
1027*12068SRoger.Faulkner@Oracle.COM 							vm = Vmheap;
1028*12068SRoger.Faulkner@Oracle.COM 					}
1029*12068SRoger.Faulkner@Oracle.COM 					break;
1030*12068SRoger.Faulkner@Oracle.COM 				case 'm':	/* mmap */
1031*12068SRoger.Faulkner@Oracle.COM #if _mem_mmap_anon || _mem_mmap_zero
1032*12068SRoger.Faulkner@Oracle.COM 					_Vmassert |= VM_mmap;
1033*12068SRoger.Faulkner@Oracle.COM #endif
1034*12068SRoger.Faulkner@Oracle.COM 					break;
1035*12068SRoger.Faulkner@Oracle.COM 				}
1036*12068SRoger.Faulkner@Oracle.COM 				break;
1037*12068SRoger.Faulkner@Oracle.COM 			case 'p':
1038*12068SRoger.Faulkner@Oracle.COM 				if (v)
1039*12068SRoger.Faulkner@Oracle.COM 					switch (t[1])
1040*12068SRoger.Faulkner@Oracle.COM 					{
1041*12068SRoger.Faulkner@Oracle.COM 					case 'e':	/* period=<count> */
1042*12068SRoger.Faulkner@Oracle.COM 						if (!vm)
1043*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1044*12068SRoger.Faulkner@Oracle.COM 						if (vm && vm->meth.meth == VM_MTDEBUG)
1045*12068SRoger.Faulkner@Oracle.COM 							_Vmdbcheck = atou(&v);
1046*12068SRoger.Faulkner@Oracle.COM 						break;
1047*12068SRoger.Faulkner@Oracle.COM 					case 'r':	/* profile=<path> */
1048*12068SRoger.Faulkner@Oracle.COM 						if (!vm)
1049*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmprofile, 0);
1050*12068SRoger.Faulkner@Oracle.COM 						if (v && vm && vm->meth.meth == VM_MTPROFILE)
1051*12068SRoger.Faulkner@Oracle.COM 							_Vmpffd = createfile(v);
1052*12068SRoger.Faulkner@Oracle.COM 						break;
1053*12068SRoger.Faulkner@Oracle.COM 					}
1054*12068SRoger.Faulkner@Oracle.COM 				break;
1055*12068SRoger.Faulkner@Oracle.COM 			case 'r':		/* region */
1056*12068SRoger.Faulkner@Oracle.COM 				_Vmassert |= VM_region;
1057*12068SRoger.Faulkner@Oracle.COM 				break;
1058*12068SRoger.Faulkner@Oracle.COM 			case 's':		/* start=<count> */
1059*12068SRoger.Faulkner@Oracle.COM 				if (!vm)
1060*12068SRoger.Faulkner@Oracle.COM 					vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1061*12068SRoger.Faulkner@Oracle.COM 				if (v && vm && vm->meth.meth == VM_MTDEBUG)
1062*12068SRoger.Faulkner@Oracle.COM 					_Vmdbstart = atou(&v);
1063*12068SRoger.Faulkner@Oracle.COM 				break;
1064*12068SRoger.Faulkner@Oracle.COM 			case 't':		/* trace=<path> */
1065*12068SRoger.Faulkner@Oracle.COM 				trace = v;
1066*12068SRoger.Faulkner@Oracle.COM 				break;
1067*12068SRoger.Faulkner@Oracle.COM 			case 'w':
1068*12068SRoger.Faulkner@Oracle.COM 				if (t[1] == 'a')
1069*12068SRoger.Faulkner@Oracle.COM 					switch (t[2])
1070*12068SRoger.Faulkner@Oracle.COM 					{
1071*12068SRoger.Faulkner@Oracle.COM 					case 'r':	/* warn=<path> */
1072*12068SRoger.Faulkner@Oracle.COM 						if (!vm)
1073*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1074*12068SRoger.Faulkner@Oracle.COM 						if (v && vm && vm->meth.meth == VM_MTDEBUG && (fd = createfile(v)) >= 0)
1075*12068SRoger.Faulkner@Oracle.COM 							vmdebug(fd);
1076*12068SRoger.Faulkner@Oracle.COM 						break;
1077*12068SRoger.Faulkner@Oracle.COM 					case 't':	/* watch=<addr> */
1078*12068SRoger.Faulkner@Oracle.COM 						if (!vm)
1079*12068SRoger.Faulkner@Oracle.COM 							vm = vmopen(Vmdcsbrk, Vmdebug, 0);
1080*12068SRoger.Faulkner@Oracle.COM 						if (v && vm && vm->meth.meth == VM_MTDEBUG && (n = atou(&v)) >= 0)
1081*12068SRoger.Faulkner@Oracle.COM 							vmdbwatch((Void_t*)n);
1082*12068SRoger.Faulkner@Oracle.COM 						break;
1083*12068SRoger.Faulkner@Oracle.COM 					}
1084*12068SRoger.Faulkner@Oracle.COM 				break;
1085*12068SRoger.Faulkner@Oracle.COM 			}
1086*12068SRoger.Faulkner@Oracle.COM 		}
1087*12068SRoger.Faulkner@Oracle.COM 	}
1088*12068SRoger.Faulkner@Oracle.COM 
1089*12068SRoger.Faulkner@Oracle.COM 	/* slip in the new region now so that malloc() will work fine */
1090*12068SRoger.Faulkner@Oracle.COM 
1091*12068SRoger.Faulkner@Oracle.COM 	if (vm)
1092*12068SRoger.Faulkner@Oracle.COM 	{
1093*12068SRoger.Faulkner@Oracle.COM 		if (vm->meth.meth == VM_MTDEBUG)
1094*12068SRoger.Faulkner@Oracle.COM 			_Vmdbcheck = 1;
1095*12068SRoger.Faulkner@Oracle.COM 		Vmregion = vm;
1096*12068SRoger.Faulkner@Oracle.COM 	}
1097*12068SRoger.Faulkner@Oracle.COM 
1098*12068SRoger.Faulkner@Oracle.COM 	/* enable tracing */
1099*12068SRoger.Faulkner@Oracle.COM 
1100*12068SRoger.Faulkner@Oracle.COM 	if (trace && (fd = createfile(trace)) >= 0)
1101*12068SRoger.Faulkner@Oracle.COM 	{
1102*12068SRoger.Faulkner@Oracle.COM 		vmset(Vmregion, VM_TRACE, 1);
1103*12068SRoger.Faulkner@Oracle.COM 		vmtrace(fd);
1104*12068SRoger.Faulkner@Oracle.COM 	}
1105*12068SRoger.Faulkner@Oracle.COM 
1106*12068SRoger.Faulkner@Oracle.COM 	/* make sure that profile data is output upon exiting */
1107*12068SRoger.Faulkner@Oracle.COM 
1108*12068SRoger.Faulkner@Oracle.COM 	if (vm && vm->meth.meth == VM_MTPROFILE)
1109*12068SRoger.Faulkner@Oracle.COM 	{
1110*12068SRoger.Faulkner@Oracle.COM 		if (_Vmpffd < 0)
1111*12068SRoger.Faulkner@Oracle.COM 			_Vmpffd = 2;
1112*12068SRoger.Faulkner@Oracle.COM 		/* this may wind up calling malloc(), but region is ok now */
1113*12068SRoger.Faulkner@Oracle.COM 		atexit(pfprint);
1114*12068SRoger.Faulkner@Oracle.COM 	}
1115*12068SRoger.Faulkner@Oracle.COM 	else if (_Vmpffd >= 0)
1116*12068SRoger.Faulkner@Oracle.COM 	{
1117*12068SRoger.Faulkner@Oracle.COM 		close(_Vmpffd);
1118*12068SRoger.Faulkner@Oracle.COM 		_Vmpffd = -1;
1119*12068SRoger.Faulkner@Oracle.COM 	}
1120*12068SRoger.Faulkner@Oracle.COM }
1121*12068SRoger.Faulkner@Oracle.COM 
11224887Schin #endif /*_UWIN*/
1123