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