fixes of some warnings
[nao-ulib.git] / src / xmalloc.c
blob424ce77b05737c521c16d0e6beaf1d1643678f75
1 /*
2 * nao-ulib
3 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
4 * Subject to the GPL.
5 * Nao-Team HTWK,
6 * Faculty of Computer Science, Mathematics and Natural Sciences,
7 * Leipzig University of Applied Sciences (HTWK Leipzig)
8 */
11 * Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland,
12 * All rights reserved
13 * Copyright (C) 2010 Daniel Borkmann <daniel@netyack.org>,
14 * Ported from SSH and added several other functions and
15 * heap consistency checks
17 * Versions of malloc and friends that check their results, and never return
18 * failure (they call fatal if they encounter an error).
20 * As far as I am concerned, the code I have written for this software
21 * can be used freely for any purpose. Any derived versions of this
22 * software must be clearly marked as such, and if the derived work is
23 * incompatible with the protocol description in the RFC file, it must be
24 * called by a name other than "ssh" or "Secure Shell".
27 #define _GNU_SOURCE
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <signal.h>
33 #include <mcheck.h>
34 #include <unistd.h>
35 #include <malloc.h>
36 #include <sys/ioctl.h>
38 #ifndef SIZE_T_MAX
39 # define SIZE_T_MAX ((size_t) ~0)
40 #endif
42 #include "comp_x86.h"
43 #include "cache_x86.h"
44 #include "xmalloc.h"
45 #include "strlcpy.h"
46 #include "die.h"
47 #include "stacktrace.h"
49 static void mcheck_abort(enum mcheck_status stat)
51 if (stat != MCHECK_OK)
52 panic("mcheck: mem inconsistency detected: %d\n", stat);
55 static void xmalloc_mcheck_init(void)
57 /*
58 * If we would use mcheck_pedantic() here, then libloudmouth
59 * is not able to perform SSL/TLS authentication. Weird.
61 int ret = mcheck(mcheck_abort);
62 if (ret < 0)
63 panic("xmalloc: cannot init mcheck! bug\n");
65 mtrace();
68 static void xmalloc_init_hook(void)
70 xmalloc_mcheck_init();
73 void (*__malloc_initialize_hook)(void) = xmalloc_init_hook;
75 __hidden void muntrace_handler(int signal)
77 if (signal != SIGSEGV) {
78 muntrace();
79 return;
82 info("Oops, SIGSEGV received!\n");
83 info("Stacktrace:\n");
84 stacktrace();
85 info("@('_')@ __.-<^*Panic!*^>\n");
86 sync_o();
87 muntrace();
88 abort();
91 __hidden int xmem_used(void)
93 struct mallinfo mi = mallinfo();
94 return mi.uordblks;
97 __hidden int xmem_free(void)
99 struct mallinfo mi = mallinfo();
100 return mi.fordblks;
103 __hidden int xmem_totalarena(void)
105 struct mallinfo mi = mallinfo();
106 return mi.arena;
109 __hidden void *xmalloc(size_t size)
111 void *ptr;
112 enum mcheck_status stat;
114 if (size == 0)
115 panic("xmalloc: zero size\n");
117 ptr = malloc(size);
118 if (ptr == NULL)
119 panic("xmalloc: out of memory (allocating %lu bytes)\n",
120 (u_long) size);
121 stat = mprobe(ptr);
122 if (stat != MCHECK_OK)
123 panic("xmalloc: mem inconsistency detected: %d\n", stat);
125 debug("%p: %zu", ptr, size);
126 return ptr;
129 __hidden void *xvalloc(size_t size)
131 void *ptr;
132 enum mcheck_status stat;
134 if (size == 0)
135 panic("xmalloc: zero size\n");
137 ptr = valloc(size);
138 if (ptr == NULL)
139 panic("xvalloc: out of memory (allocating %lu bytes)\n",
140 (u_long) size);
141 stat = mprobe(ptr);
142 if (stat != MCHECK_OK)
143 panic("xvalloc: mem inconsistency detected: %d\n", stat);
145 debug("%p: %zu", ptr, size);
146 return ptr;
149 __hidden void *xzmalloc(size_t size)
151 void *ptr;
152 enum mcheck_status stat;
154 if (size == 0)
155 panic("xzmalloc: zero size\n");
157 ptr = malloc(size);
158 if (ptr == NULL)
159 panic("xzmalloc: out of memory (allocating %lu bytes)\n",
160 (u_long) size);
161 stat = mprobe(ptr);
162 if (stat != MCHECK_OK)
163 panic("xzmalloc: mem inconsistency detected: %d\n", stat);
164 memset(ptr, 0, size);
166 debug("%p: %zu", ptr, size);
167 return ptr;
170 __hidden void *xmalloc_aligned(size_t size, size_t alignment)
172 int ret;
173 void *ptr;
174 enum mcheck_status stat;
176 if (size == 0)
177 panic("xmalloc_aligned: zero size\n");
179 ret = posix_memalign(&ptr, alignment, size);
180 if (ret != 0)
181 panic("xmalloc_aligned: out of memory (allocating %lu bytes)\n",
182 (u_long) size);
183 stat = mprobe(ptr);
184 if (stat != MCHECK_OK)
185 panic("xmalloc_aligned: mem inconsistency detected: %d\n", stat);
187 debug("%p: %zu", ptr, size);
188 return ptr;
191 __hidden void *xmalloc_geode_l1_cl_aligned(size_t size)
193 return xmalloc_aligned(size, GEODE_CACHE_LINE_SIZE);
196 __hidden void *xmalloc_geode_l2_cl_aligned(size_t size)
198 return xmalloc_aligned(size, GEODE_CACHE_LINE_SIZE);
201 __hidden void *xmallocz(size_t size)
203 void *ptr;
205 if (size + 1 < size)
206 panic("xmallocz: data too large to fit into virtual "
207 "memory space\n");
209 ptr = xmalloc(size + 1);
210 ((char*) ptr)[size] = 0;
212 return ptr;
215 __hidden void *xmemdupz(const void *data, size_t len)
217 return memcpy(xmallocz(len), data, len);
220 __hidden void *xcalloc(size_t nmemb, size_t size)
222 void *ptr;
223 enum mcheck_status stat;
225 if (size == 0 || nmemb == 0)
226 panic("xcalloc: zero size\n");
227 if (SIZE_T_MAX / nmemb < size)
228 panic("xcalloc: nmemb * size > SIZE_T_MAX\n");
230 ptr = calloc(nmemb, size);
231 if (ptr == NULL)
232 panic("xcalloc: out of memory (allocating %lu bytes)\n",
233 (u_long) (size * nmemb));
234 stat = mprobe(ptr);
235 if (stat != MCHECK_OK)
236 panic("xcalloc: mem inconsistency detected: %d\n", stat);
238 debug("%p: %zu", ptr, size);
239 return ptr;
242 __hidden void *xrealloc(void *ptr, size_t nmemb, size_t size)
244 void *new_ptr;
245 size_t new_size = nmemb * size;
246 enum mcheck_status stat;
248 if (new_size == 0)
249 panic("xrealloc: zero size\n");
250 if (SIZE_T_MAX / nmemb < size)
251 panic("xrealloc: nmemb * size > SIZE_T_MAX\n");
253 if (ptr == NULL)
254 new_ptr = malloc(new_size);
255 else
256 new_ptr = realloc(ptr, new_size);
258 if (new_ptr == NULL)
259 panic("xrealloc: out of memory (new_size %lu bytes)\n",
260 (u_long) new_size);
261 stat = mprobe(ptr);
262 if (stat != MCHECK_OK)
263 panic("xrealloc: mem inconsistency detected: %d\n", stat);
265 debug("%p: %zu => %p: %zu", ptr, size, new_ptr, new_size);
266 return new_ptr;
269 __hidden void xfree(void *ptr)
271 enum mcheck_status stat;
273 if (ptr == NULL)
274 panic("xfree: NULL pointer given as argument\n");
276 stat = mprobe(ptr);
277 if (stat != MCHECK_OK)
278 panic("xfree: mem inconsistency detected: %d\n", stat);
280 debug("%p => 0", ptr);
281 free(ptr);
284 __hidden char *xstrdup(const char *str)
286 size_t len;
287 char *cp;
289 len = strlen(str) + 1;
290 cp = xmalloc(len);
291 strlcpy(cp, str, len);
293 return cp;
296 __hidden char *xstrndup(const char *str, size_t size)
298 size_t len;
299 char *cp;
301 len = strlen(str) + 1;
302 if (size < len)
303 len = size;
305 cp = xmalloc(len);
306 strlcpy(cp, str, len);
308 return cp;
311 __hidden int xdup(int fd)
313 int ret = dup(fd);
314 if (ret < 0)
315 panic("xdup: dup failed\n");
317 return ret;
320 int __xioctl(int fd, int req, void *arg)
322 int ret;
324 do ret = ioctl(fd, req, arg);
325 while (ret < 0 && EINTR == errno);
327 return ret;