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