1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <stdlib.h>
9 #include <sys/reent.h>
10 #include <errno.h>
11 #include <malloc.h>
12 #include "esp_heap_caps.h"
13
14
15 /*
16 These contain the business logic for the malloc() and realloc() implementation. Because of heap tracing
17 wrapping reasons, we do not want these to be a public api, however, so they're not defined publicly.
18 */
19 extern void *heap_caps_malloc_default( size_t size );
20 extern void *heap_caps_realloc_default( void *ptr, size_t size );
21
malloc(size_t size)22 void* malloc(size_t size)
23 {
24 return heap_caps_malloc_default(size);
25 }
26
calloc(size_t n,size_t size)27 void* calloc(size_t n, size_t size)
28 {
29 return _calloc_r(_REENT, n, size);
30 }
31
realloc(void * ptr,size_t size)32 void* realloc(void* ptr, size_t size)
33 {
34 return heap_caps_realloc_default(ptr, size);
35 }
36
free(void * ptr)37 void free(void *ptr)
38 {
39 heap_caps_free(ptr);
40 }
41
_malloc_r(struct _reent * r,size_t size)42 void* _malloc_r(struct _reent *r, size_t size)
43 {
44 return heap_caps_malloc_default(size);
45 }
46
_free_r(struct _reent * r,void * ptr)47 void _free_r(struct _reent *r, void* ptr)
48 {
49 heap_caps_free(ptr);
50 }
51
_realloc_r(struct _reent * r,void * ptr,size_t size)52 void* _realloc_r(struct _reent *r, void* ptr, size_t size)
53 {
54 return heap_caps_realloc_default( ptr, size );
55 }
56
_calloc_r(struct _reent * r,size_t nmemb,size_t size)57 void* _calloc_r(struct _reent *r, size_t nmemb, size_t size)
58 {
59 void *result;
60 size_t size_bytes;
61 if (__builtin_mul_overflow(nmemb, size, &size_bytes)) {
62 return NULL;
63 }
64
65 result = heap_caps_malloc_default(size_bytes);
66 if (result != NULL) {
67 bzero(result, size_bytes);
68 }
69 return result;
70 }
71
memalign(size_t alignment,size_t n)72 void* memalign(size_t alignment, size_t n)
73 {
74 return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT);
75 }
76
aligned_alloc(size_t alignment,size_t n)77 void* aligned_alloc(size_t alignment, size_t n)
78 {
79 return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT);
80 }
81
posix_memalign(void ** out_ptr,size_t alignment,size_t size)82 int posix_memalign(void **out_ptr, size_t alignment, size_t size)
83 {
84 if (size == 0) {
85 /* returning NULL for zero size is allowed, don't treat this as an error */
86 *out_ptr = NULL;
87 return 0;
88 }
89 void *result = heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT);
90 if (result != NULL) {
91 /* Modify output pointer only on success */
92 *out_ptr = result;
93 return 0;
94 }
95 /* Note: error returned, not set via errno! */
96 return ENOMEM;
97 }
98
99 /* No-op function, used to force linking this file,
100 instead of the heap implementation from newlib.
101 */
newlib_include_heap_impl(void)102 void newlib_include_heap_impl(void)
103 {
104 }
105
106 /* The following functions are implemented by newlib's heap allocator,
107 but aren't available in the heap component.
108 Define them as non-functional stubs here, so that the application
109 can not cause the newlib heap implementation to be linked in
110 */
111
malloc_trim(size_t pad)112 int malloc_trim(size_t pad)
113 {
114 return 0; // indicates failure
115 }
116
malloc_usable_size(void * p)117 size_t malloc_usable_size(void* p)
118 {
119 return 0;
120 }
121
malloc_stats(void)122 void malloc_stats(void)
123 {
124 }
125
mallopt(int parameter_number,int parameter_value)126 int mallopt(int parameter_number, int parameter_value)
127 {
128 return 0; // indicates failure
129 }
130
mallinfo(void)131 struct mallinfo mallinfo(void)
132 {
133 struct mallinfo dummy = {0};
134 return dummy;
135 }
136
137 void* valloc(size_t n) __attribute__((alias("malloc")));
138 void* pvalloc(size_t n) __attribute__((alias("malloc")));
139 void cfree(void* p) __attribute__((alias("free")));
140