1 #ifndef __LITEOS__
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <errno.h>
6 #include "dynlink.h"
7
mal0_clear(char * p,size_t n)8 static size_t mal0_clear(char *p, size_t n)
9 {
10 const size_t pagesz = 4096; /* arbitrary */
11 if (n < pagesz) return n;
12 #ifdef __GNUC__
13 typedef uint64_t __attribute__((__may_alias__)) T;
14 #else
15 typedef unsigned char T;
16 #endif
17 char *pp = p + n;
18 size_t i = (uintptr_t)pp & (pagesz - 1);
19 for (;;) {
20 pp = memset(pp - i, 0, i);
21 if (pp - p < pagesz) return pp - p;
22 for (i = pagesz; i; i -= 2 * sizeof(T), pp -= 2 * sizeof(T))
23 if (((T *)pp)[-1] | ((T *)pp)[-2])
24 break;
25 }
26 }
27
allzerop(void * p)28 static int allzerop(void *p)
29 {
30 return 0;
31 }
32 weak_alias(allzerop, __malloc_allzerop);
33
__libc_calloc(size_t m,size_t n)34 void *__libc_calloc(size_t m, size_t n)
35 {
36 if (n && m > (size_t)-1 / n) {
37 errno = ENOMEM;
38 return 0;
39 }
40 n *= m;
41 void *p = __libc_malloc(n);
42 if (!p || (!__malloc_replaced && __malloc_allzerop(p)))
43 return p;
44 n = mal0_clear(p, n);
45 return memset(p, 0, n);
46 }
47
48 #ifdef HOOK_ENABLE
hook_calloc(size_t m,size_t n)49 void *hook_calloc(size_t m, size_t n)
50 {
51 if (n && m > (size_t)-1/n) {
52 errno = ENOMEM;
53 return 0;
54 }
55 n *= m;
56 #ifndef __LITEOS__
57 void *p = __libc_malloc(n);
58 #else
59 void *p = malloc(n);
60 #endif
61 if (!p || (!__malloc_replaced && __malloc_allzerop(p)))
62 return p;
63 n = mal0_clear(p, n);
64 return memset(p, 0, n);
65 }
66 #endif
67 #else
68 #define calloc __libc_calloc
69 #define malloc __libc_malloc
70
71 #include "calloc.c"
72 #endif
73