1570af302Sopenharmony_ci#ifndef __LITEOS__
2570af302Sopenharmony_ci#include <stdlib.h>
3570af302Sopenharmony_ci#include <stdint.h>
4570af302Sopenharmony_ci#include <string.h>
5570af302Sopenharmony_ci#include <errno.h>
6570af302Sopenharmony_ci#include "dynlink.h"
7570af302Sopenharmony_ci
8570af302Sopenharmony_cistatic size_t mal0_clear(char *p, size_t n)
9570af302Sopenharmony_ci{
10570af302Sopenharmony_ci	const size_t pagesz = 4096; /* arbitrary */
11570af302Sopenharmony_ci	if (n < pagesz) return n;
12570af302Sopenharmony_ci#ifdef __GNUC__
13570af302Sopenharmony_ci	typedef uint64_t __attribute__((__may_alias__)) T;
14570af302Sopenharmony_ci#else
15570af302Sopenharmony_ci	typedef unsigned char T;
16570af302Sopenharmony_ci#endif
17570af302Sopenharmony_ci	char *pp = p + n;
18570af302Sopenharmony_ci	size_t i = (uintptr_t)pp & (pagesz - 1);
19570af302Sopenharmony_ci	for (;;) {
20570af302Sopenharmony_ci		pp = memset(pp - i, 0, i);
21570af302Sopenharmony_ci		if (pp - p < pagesz) return pp - p;
22570af302Sopenharmony_ci		for (i = pagesz; i; i -= 2 * sizeof(T), pp -= 2 * sizeof(T))
23570af302Sopenharmony_ci		        if (((T *)pp)[-1] | ((T *)pp)[-2])
24570af302Sopenharmony_ci				break;
25570af302Sopenharmony_ci	}
26570af302Sopenharmony_ci}
27570af302Sopenharmony_ci
28570af302Sopenharmony_cistatic int allzerop(void *p)
29570af302Sopenharmony_ci{
30570af302Sopenharmony_ci	return 0;
31570af302Sopenharmony_ci}
32570af302Sopenharmony_ciweak_alias(allzerop, __malloc_allzerop);
33570af302Sopenharmony_ci
34570af302Sopenharmony_civoid *__libc_calloc(size_t m, size_t n)
35570af302Sopenharmony_ci{
36570af302Sopenharmony_ci	if (n && m > (size_t)-1 / n) {
37570af302Sopenharmony_ci		errno = ENOMEM;
38570af302Sopenharmony_ci		return 0;
39570af302Sopenharmony_ci	}
40570af302Sopenharmony_ci	n *= m;
41570af302Sopenharmony_ci	void *p = __libc_malloc(n);
42570af302Sopenharmony_ci	if (!p || (!__malloc_replaced && __malloc_allzerop(p)))
43570af302Sopenharmony_ci		return p;
44570af302Sopenharmony_ci	n = mal0_clear(p, n);
45570af302Sopenharmony_ci	return memset(p, 0, n);
46570af302Sopenharmony_ci}
47570af302Sopenharmony_ci
48570af302Sopenharmony_ci#ifdef HOOK_ENABLE
49570af302Sopenharmony_civoid *hook_calloc(size_t m, size_t n)
50570af302Sopenharmony_ci{
51570af302Sopenharmony_ci	if (n && m > (size_t)-1/n) {
52570af302Sopenharmony_ci		errno = ENOMEM;
53570af302Sopenharmony_ci		return 0;
54570af302Sopenharmony_ci	}
55570af302Sopenharmony_ci	n *= m;
56570af302Sopenharmony_ci#ifndef __LITEOS__
57570af302Sopenharmony_ci	void *p = __libc_malloc(n);
58570af302Sopenharmony_ci#else
59570af302Sopenharmony_ci	void *p = malloc(n);
60570af302Sopenharmony_ci#endif
61570af302Sopenharmony_ci	if (!p || (!__malloc_replaced && __malloc_allzerop(p)))
62570af302Sopenharmony_ci		return p;
63570af302Sopenharmony_ci	n = mal0_clear(p, n);
64570af302Sopenharmony_ci	return memset(p, 0, n);
65570af302Sopenharmony_ci}
66570af302Sopenharmony_ci#endif
67570af302Sopenharmony_ci#else
68570af302Sopenharmony_ci#define calloc __libc_calloc
69570af302Sopenharmony_ci#define malloc __libc_malloc
70570af302Sopenharmony_ci
71570af302Sopenharmony_ci#include "calloc.c"
72570af302Sopenharmony_ci#endif
73