1570af302Sopenharmony_ci#include <stdlib.h> 2570af302Sopenharmony_ci#include <stdint.h> 3570af302Sopenharmony_ci#include <string.h> 4570af302Sopenharmony_ci#include <errno.h> 5570af302Sopenharmony_ci#include "dynlink.h" 6570af302Sopenharmony_ci 7570af302Sopenharmony_cistatic size_t mal0_clear(char *p, size_t n) 8570af302Sopenharmony_ci{ 9570af302Sopenharmony_ci const size_t pagesz = 4096; /* arbitrary */ 10570af302Sopenharmony_ci if (n < pagesz) return n; 11570af302Sopenharmony_ci#ifdef __GNUC__ 12570af302Sopenharmony_ci typedef uint64_t __attribute__((__may_alias__)) T; 13570af302Sopenharmony_ci#else 14570af302Sopenharmony_ci typedef unsigned char T; 15570af302Sopenharmony_ci#endif 16570af302Sopenharmony_ci char *pp = p + n; 17570af302Sopenharmony_ci size_t i = (uintptr_t)pp & (pagesz - 1); 18570af302Sopenharmony_ci for (;;) { 19570af302Sopenharmony_ci pp = memset(pp - i, 0, i); 20570af302Sopenharmony_ci if (pp - p < pagesz) return pp - p; 21570af302Sopenharmony_ci for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T)) 22570af302Sopenharmony_ci if (((T *)pp)[-1] | ((T *)pp)[-2]) 23570af302Sopenharmony_ci break; 24570af302Sopenharmony_ci } 25570af302Sopenharmony_ci} 26570af302Sopenharmony_ci 27570af302Sopenharmony_cistatic int allzerop(void *p) 28570af302Sopenharmony_ci{ 29570af302Sopenharmony_ci return 0; 30570af302Sopenharmony_ci} 31570af302Sopenharmony_ciweak_alias(allzerop, __malloc_allzerop); 32570af302Sopenharmony_ci 33570af302Sopenharmony_civoid *calloc(size_t m, size_t n) 34570af302Sopenharmony_ci{ 35570af302Sopenharmony_ci if (n && m > (size_t)-1/n) { 36570af302Sopenharmony_ci errno = ENOMEM; 37570af302Sopenharmony_ci return 0; 38570af302Sopenharmony_ci } 39570af302Sopenharmony_ci n *= m; 40570af302Sopenharmony_ci void *p = malloc(n); 41570af302Sopenharmony_ci if (!p || (!__malloc_replaced && __malloc_allzerop(p))) 42570af302Sopenharmony_ci return p; 43570af302Sopenharmony_ci n = mal0_clear(p, n); 44570af302Sopenharmony_ci return memset(p, 0, n); 45570af302Sopenharmony_ci} 46