1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2017 Jason King 14 * Copyright 2019, Joyent, Inc. 15 */ 16 17 #include <errno.h> 18 #include <limits.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include "demangle-sys.h" 22 #include "demangle_int.h" 23 24 void * 25 zalloc(sysdem_ops_t *ops, size_t len) 26 { 27 void *p = ops->alloc(len); 28 29 if (p != NULL) 30 (void) memset(p, 0, len); 31 32 #ifdef DEBUG 33 /* 34 * In normal operation, we should never exhaust memory. Either 35 * something's wrong, or the system is so hosed that aborting 36 * shouldn't hurt anything, and it gives us a more useful stack 37 * trace. 38 */ 39 if (p == NULL) 40 abort(); 41 #endif 42 43 return (p); 44 } 45 46 void * 47 xcalloc(sysdem_ops_t *ops, size_t n, size_t elsize) 48 { 49 uint64_t sz; 50 51 if (mul_overflow(n, elsize, &sz)) { 52 errno = ENOMEM; 53 return (NULL); 54 } 55 56 #ifndef _LP64 57 if (sz > SIZE_MAX) { 58 errno = ENOMEM; 59 return (NULL); 60 } 61 #endif 62 63 return (zalloc(ops, sz)); 64 } 65 void 66 xfree(sysdem_ops_t *ops, void *p, size_t len) 67 { 68 if (p == NULL || len == 0) 69 return; 70 71 ops->free(p, len); 72 } 73 74 void * 75 xrealloc(sysdem_ops_t *ops, void *p, size_t oldsz, size_t newsz) 76 { 77 if (newsz == oldsz) 78 return (p); 79 80 VERIFY3U(newsz, >, oldsz); 81 82 void *temp = zalloc(ops, newsz); 83 84 if (temp == NULL) 85 return (NULL); 86 87 if (oldsz > 0) { 88 (void) memcpy(temp, p, oldsz); 89 xfree(ops, p, oldsz); 90 } 91 92 return (temp); 93 } 94 95 char * 96 xstrdup(sysdem_ops_t *ops, const char *src) 97 { 98 size_t len = strlen(src); 99 char *str = zalloc(ops, len + 1); 100 101 if (str == NULL) 102 return (NULL); 103 104 /* zalloc(len+1) guarantees this will be NUL-terminated */ 105 (void) memcpy(str, src, len); 106 return (str); 107 } 108 109 /*ARGSUSED*/ 110 static void 111 def_free(void *p, size_t len) 112 { 113 free(p); 114 } 115 116 static sysdem_ops_t i_sysdem_ops_default = { 117 .alloc = malloc, 118 .free = def_free 119 }; 120 sysdem_ops_t *sysdem_ops_default = &i_sysdem_ops_default; 121