14226f635SJason King /*
24226f635SJason King * This file and its contents are supplied under the terms of the
34226f635SJason King * Common Development and Distribution License ("CDDL"), version 1.0.
44226f635SJason King * You may only use this file in accordance with the terms of version
54226f635SJason King * 1.0 of the CDDL.
64226f635SJason King *
74226f635SJason King * A full copy of the text of the CDDL should have accompanied this
84226f635SJason King * source. A copy of the CDDL is also available via the Internet at
94226f635SJason King * http://www.illumos.org/license/CDDL.
104226f635SJason King */
114226f635SJason King
124226f635SJason King /*
134226f635SJason King * Copyright 2017 Jason King
146a6cfa5dSJason King * Copyright 2019, Joyent, Inc.
154226f635SJason King */
164226f635SJason King
17*1cd08393SJason King #include <errno.h>
18*1cd08393SJason King #include <limits.h>
194226f635SJason King #include <stdlib.h>
204226f635SJason King #include <string.h>
214226f635SJason King #include "demangle-sys.h"
224226f635SJason King #include "demangle_int.h"
234226f635SJason King
244226f635SJason King void *
zalloc(sysdem_ops_t * ops,size_t len)254226f635SJason King zalloc(sysdem_ops_t *ops, size_t len)
264226f635SJason King {
274226f635SJason King void *p = ops->alloc(len);
284226f635SJason King
294226f635SJason King if (p != NULL)
304226f635SJason King (void) memset(p, 0, len);
314226f635SJason King
324226f635SJason King #ifdef DEBUG
334226f635SJason King /*
344226f635SJason King * In normal operation, we should never exhaust memory. Either
354226f635SJason King * something's wrong, or the system is so hosed that aborting
364226f635SJason King * shouldn't hurt anything, and it gives us a more useful stack
374226f635SJason King * trace.
384226f635SJason King */
394226f635SJason King if (p == NULL)
404226f635SJason King abort();
414226f635SJason King #endif
424226f635SJason King
434226f635SJason King return (p);
444226f635SJason King }
454226f635SJason King
46*1cd08393SJason King void *
xcalloc(sysdem_ops_t * ops,size_t n,size_t elsize)47*1cd08393SJason King xcalloc(sysdem_ops_t *ops, size_t n, size_t elsize)
48*1cd08393SJason King {
49*1cd08393SJason King uint64_t sz;
50*1cd08393SJason King
51*1cd08393SJason King if (mul_overflow(n, elsize, &sz)) {
52*1cd08393SJason King errno = ENOMEM;
53*1cd08393SJason King return (NULL);
54*1cd08393SJason King }
55*1cd08393SJason King
56*1cd08393SJason King #ifndef _LP64
57*1cd08393SJason King if (sz > SIZE_MAX) {
58*1cd08393SJason King errno = ENOMEM;
59*1cd08393SJason King return (NULL);
60*1cd08393SJason King }
61*1cd08393SJason King #endif
62*1cd08393SJason King
63*1cd08393SJason King return (zalloc(ops, sz));
64*1cd08393SJason King }
654226f635SJason King void
xfree(sysdem_ops_t * ops,void * p,size_t len)664226f635SJason King xfree(sysdem_ops_t *ops, void *p, size_t len)
674226f635SJason King {
684226f635SJason King if (p == NULL || len == 0)
694226f635SJason King return;
704226f635SJason King
714226f635SJason King ops->free(p, len);
724226f635SJason King }
734226f635SJason King
744226f635SJason King void *
xrealloc(sysdem_ops_t * ops,void * p,size_t oldsz,size_t newsz)754226f635SJason King xrealloc(sysdem_ops_t *ops, void *p, size_t oldsz, size_t newsz)
764226f635SJason King {
774226f635SJason King if (newsz == oldsz)
784226f635SJason King return (p);
794226f635SJason King
804226f635SJason King VERIFY3U(newsz, >, oldsz);
814226f635SJason King
824226f635SJason King void *temp = zalloc(ops, newsz);
834226f635SJason King
844226f635SJason King if (temp == NULL)
854226f635SJason King return (NULL);
864226f635SJason King
874226f635SJason King if (oldsz > 0) {
884226f635SJason King (void) memcpy(temp, p, oldsz);
894226f635SJason King xfree(ops, p, oldsz);
904226f635SJason King }
914226f635SJason King
924226f635SJason King return (temp);
934226f635SJason King }
944226f635SJason King
956a6cfa5dSJason King char *
xstrdup(sysdem_ops_t * ops,const char * src)966a6cfa5dSJason King xstrdup(sysdem_ops_t *ops, const char *src)
976a6cfa5dSJason King {
986a6cfa5dSJason King size_t len = strlen(src);
996a6cfa5dSJason King char *str = zalloc(ops, len + 1);
1006a6cfa5dSJason King
1016a6cfa5dSJason King if (str == NULL)
1026a6cfa5dSJason King return (NULL);
1036a6cfa5dSJason King
1046a6cfa5dSJason King /* zalloc(len+1) guarantees this will be NUL-terminated */
1056a6cfa5dSJason King (void) memcpy(str, src, len);
1066a6cfa5dSJason King return (str);
1076a6cfa5dSJason King }
1086a6cfa5dSJason King
1094226f635SJason King /*ARGSUSED*/
1104226f635SJason King static void
def_free(void * p,size_t len)1114226f635SJason King def_free(void *p, size_t len)
1124226f635SJason King {
1134226f635SJason King free(p);
1144226f635SJason King }
1154226f635SJason King
1164226f635SJason King static sysdem_ops_t i_sysdem_ops_default = {
1174226f635SJason King .alloc = malloc,
1184226f635SJason King .free = def_free
1194226f635SJason King };
1204226f635SJason King sysdem_ops_t *sysdem_ops_default = &i_sysdem_ops_default;
121