xref: /freebsd/contrib/ntp/libntp/emalloc.c (revision f0574f5cf69e168cc4ea71ebbe5fdec9ec9a3dfe)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * emalloc - return new memory obtained from the system.  Belch if none.
3c0b746e5SOllivier Robert  */
42b15cb3dSCy Schubert #include <config.h>
5c0b746e5SOllivier Robert #include "ntp_types.h"
6c0b746e5SOllivier Robert #include "ntp_malloc.h"
7c0b746e5SOllivier Robert #include "ntp_syslog.h"
8224ba2bdSOllivier Robert #include "ntp_stdlib.h"
9c0b746e5SOllivier Robert 
10c0b746e5SOllivier Robert 
112b15cb3dSCy Schubert /*
122b15cb3dSCy Schubert  * When using the debug MS CRT allocator, each allocation stores the
132b15cb3dSCy Schubert  * callsite __FILE__ and __LINE__, which is then displayed at process
142b15cb3dSCy Schubert  * termination, to track down leaks.  We don't want all of our
152b15cb3dSCy Schubert  * allocations to show up as coming from emalloc.c, so we preserve the
162b15cb3dSCy Schubert  * original callsite's source file and line using macros which pass
172b15cb3dSCy Schubert  * __FILE__ and __LINE__ as parameters to these routines.
182b15cb3dSCy Schubert  * Other debug malloc implementations can be used by defining
192b15cb3dSCy Schubert  * EREALLOC_IMPL() as ports/winnt/include/config.h does.
202b15cb3dSCy Schubert  */
21c0b746e5SOllivier Robert 
22c0b746e5SOllivier Robert void *
ereallocz(void * ptr,size_t newsz,size_t priorsz,int zero_init,const char * file,int line)232b15cb3dSCy Schubert ereallocz(
242b15cb3dSCy Schubert 	void *	ptr,
252b15cb3dSCy Schubert 	size_t	newsz,
262b15cb3dSCy Schubert 	size_t	priorsz,
272b15cb3dSCy Schubert 	int	zero_init
282b15cb3dSCy Schubert #ifdef EREALLOC_CALLSITE		/* ntp_malloc.h */
292b15cb3dSCy Schubert 			 ,
302b15cb3dSCy Schubert 	const char *	file,
31c0b746e5SOllivier Robert 	int		line
32c0b746e5SOllivier Robert #endif
332b15cb3dSCy Schubert 	)
342b15cb3dSCy Schubert {
352b15cb3dSCy Schubert 	char *	mem;
362b15cb3dSCy Schubert 	size_t	allocsz;
372b15cb3dSCy Schubert 
382b15cb3dSCy Schubert 	if (0 == newsz)
392b15cb3dSCy Schubert 		allocsz = 1;
402b15cb3dSCy Schubert 	else
412b15cb3dSCy Schubert 		allocsz = newsz;
422b15cb3dSCy Schubert 
432b15cb3dSCy Schubert 	mem = EREALLOC_IMPL(ptr, allocsz, file, line);
442b15cb3dSCy Schubert 	if (NULL == mem) {
452b15cb3dSCy Schubert 		msyslog_term = TRUE;
462b15cb3dSCy Schubert #ifndef EREALLOC_CALLSITE
472b15cb3dSCy Schubert 		msyslog(LOG_ERR, "fatal out of memory (%lu bytes)",
482b15cb3dSCy Schubert 			(u_long)newsz);
492b15cb3dSCy Schubert #else
502b15cb3dSCy Schubert 		msyslog(LOG_ERR,
512b15cb3dSCy Schubert 			"fatal out of memory %s line %d (%lu bytes)",
522b15cb3dSCy Schubert 			file, line, (u_long)newsz);
532b15cb3dSCy Schubert #endif
542b15cb3dSCy Schubert 		exit(1);
552b15cb3dSCy Schubert 	}
562b15cb3dSCy Schubert 
572b15cb3dSCy Schubert 	if (zero_init && newsz > priorsz)
582b15cb3dSCy Schubert 		zero_mem(mem + priorsz, newsz - priorsz);
592b15cb3dSCy Schubert 
602b15cb3dSCy Schubert 	return mem;
612b15cb3dSCy Schubert }
622b15cb3dSCy Schubert 
63276da39aSCy Schubert /* oreallocarray.c is licensed under the following:
64276da39aSCy Schubert  * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
65276da39aSCy Schubert  *
66276da39aSCy Schubert  * Permission to use, copy, modify, and distribute this software for any
67276da39aSCy Schubert  * purpose with or without fee is hereby granted, provided that the above
68276da39aSCy Schubert  * copyright notice and this permission notice appear in all copies.
69276da39aSCy Schubert  *
70276da39aSCy Schubert  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
71276da39aSCy Schubert  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
72276da39aSCy Schubert  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
73276da39aSCy Schubert  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
74276da39aSCy Schubert  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
75276da39aSCy Schubert  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
76276da39aSCy Schubert  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
77276da39aSCy Schubert  */
78276da39aSCy Schubert 
79276da39aSCy Schubert /*
80276da39aSCy Schubert  * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
81276da39aSCy Schubert  * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
82276da39aSCy Schubert  */
83276da39aSCy Schubert #define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
84276da39aSCy Schubert 
85276da39aSCy Schubert void *
oreallocarrayxz(void * optr,size_t nmemb,size_t size,size_t extra,const char * file,int line)86*f0574f5cSXin LI oreallocarrayxz(
87276da39aSCy Schubert 	void *optr,
88276da39aSCy Schubert 	size_t nmemb,
89*f0574f5cSXin LI 	size_t size,
90*f0574f5cSXin LI 	size_t extra
91276da39aSCy Schubert #ifdef EREALLOC_CALLSITE		/* ntp_malloc.h */
92276da39aSCy Schubert 	,
93276da39aSCy Schubert 	const char *	file,
94276da39aSCy Schubert 	int		line
95276da39aSCy Schubert #endif
96276da39aSCy Schubert 	)
97276da39aSCy Schubert {
98276da39aSCy Schubert 	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
99276da39aSCy Schubert 	    nmemb > 0 && SIZE_MAX / nmemb < size) {
100276da39aSCy Schubert #ifndef EREALLOC_CALLSITE
101276da39aSCy Schubert 		msyslog(LOG_ERR, "fatal allocation size overflow");
102276da39aSCy Schubert #else
103276da39aSCy Schubert 		msyslog(LOG_ERR,
104276da39aSCy Schubert 			"fatal allocation size overflow %s line %d",
105276da39aSCy Schubert 			file, line);
106276da39aSCy Schubert #endif
107276da39aSCy Schubert 		exit(1);
108276da39aSCy Schubert 	}
109276da39aSCy Schubert #ifndef EREALLOC_CALLSITE
110*f0574f5cSXin LI 	return ereallocz(optr, extra + (size * nmemb), 0, TRUE);
111276da39aSCy Schubert #else
112*f0574f5cSXin LI 	return ereallocz(optr, extra + (size * nmemb), 0, TRUE, file, line);
113276da39aSCy Schubert #endif
114276da39aSCy Schubert }
1152b15cb3dSCy Schubert 
1162b15cb3dSCy Schubert char *
estrdup_impl(const char * str,const char * file,int line)1172b15cb3dSCy Schubert estrdup_impl(
1182b15cb3dSCy Schubert 	const char *	str
1192b15cb3dSCy Schubert #ifdef EREALLOC_CALLSITE
1202b15cb3dSCy Schubert 			   ,
1212b15cb3dSCy Schubert 	const char *	file,
1222b15cb3dSCy Schubert 	int		line
1232b15cb3dSCy Schubert #endif
1242b15cb3dSCy Schubert 	)
1252b15cb3dSCy Schubert {
1262b15cb3dSCy Schubert 	char *	copy;
1272b15cb3dSCy Schubert 	size_t	bytes;
1282b15cb3dSCy Schubert 
1292b15cb3dSCy Schubert 	bytes = strlen(str) + 1;
1302b15cb3dSCy Schubert 	copy = ereallocz(NULL, bytes, 0, FALSE
1312b15cb3dSCy Schubert #ifdef EREALLOC_CALLSITE
1322b15cb3dSCy Schubert 			 , file, line
1332b15cb3dSCy Schubert #endif
1342b15cb3dSCy Schubert 			 );
1352b15cb3dSCy Schubert 	memcpy(copy, str, bytes);
1362b15cb3dSCy Schubert 
1372b15cb3dSCy Schubert 	return copy;
1382b15cb3dSCy Schubert }
1392b15cb3dSCy Schubert 
1402b15cb3dSCy Schubert 
1412b15cb3dSCy Schubert #if 0
1422b15cb3dSCy Schubert #ifndef EREALLOC_CALLSITE
1432b15cb3dSCy Schubert void *
1442b15cb3dSCy Schubert emalloc(size_t newsz)
1452b15cb3dSCy Schubert {
1462b15cb3dSCy Schubert 	return ereallocz(NULL, newsz, 0, FALSE);
1472b15cb3dSCy Schubert }
1482b15cb3dSCy Schubert #endif
1492b15cb3dSCy Schubert #endif
1502b15cb3dSCy Schubert 
151