Loading...
#include <stdlib.h> #include <stdint.h> #include <string.h> #include <errno.h> #include "dynlink.h" static size_t mal0_clear(char *p, size_t n) { const size_t pagesz = 4096; /* arbitrary */ if (n < pagesz) return n; #ifdef __GNUC__ typedef uint64_t __attribute__((__may_alias__)) T; #else typedef unsigned char T; #endif char *pp = p + n; size_t i = (uintptr_t)pp & (pagesz - 1); for (;;) { pp = memset(pp - i, 0, i); if (pp - p < pagesz) return pp - p; for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T)) if (((T *)pp)[-1] | ((T *)pp)[-2]) break; } } static int allzerop(void *p) { return 0; } weak_alias(allzerop, __malloc_allzerop); void *calloc(size_t m, size_t n) { if (n && m > (size_t)-1/n) { errno = ENOMEM; return 0; } n *= m; void *p = malloc(n); if (!p || (!__malloc_replaced && __malloc_allzerop(p))) return p; n = mal0_clear(p, n); return memset(p, 0, n); } |