+
+/*
+ * For MMU hosts we need to track the size of the allocations otherwise
+ * munmap will fail to free the memory (EINVAL).
+ */
+
#include <features.h>
#include <unistd.h>
#include <stdio.h>
void *malloc(size_t size)
{
void *result;
-#if 1
+
/* Some programs will call malloc (0). Lets be strict and return NULL */
if (size == 0)
- return NULL;
-#endif
- result = mmap((void *) 0, size, PROT_READ | PROT_WRITE,
+ return NULL;
+
#ifdef __UCLIBC_HAS_MMU__
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0
+ result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
#else
- MAP_SHARED | MAP_ANONYMOUS, 0, 0
+ result = mmap((void *) 0, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, 0, 0);
#endif
- );
if (result == MAP_FAILED)
return 0;
-
- return result;
+
+#ifdef __UCLIBC_HAS_MMU__
+ * (size_t *) result = size;
+ return(result + sizeof(size_t));
+#else
+ return(result);
+#endif
}
#endif
void free(void *ptr)
{
+#ifdef __UCLIBC_HAS_MMU__
+ if (ptr) {
+ ptr -= sizeof(size_t);
+ munmap(ptr, * (size_t *) ptr);
+ }
+#else
munmap(ptr, 0);
+#endif
}
#endif
if (size > 0) {
newptr = malloc(size);
if (newptr && ptr) {
+#ifdef __UCLIBC_HAS_MMU__
+ memcpy(newptr, ptr, * ((size_t *) (ptr - sizeof(size_t))));
+#else
memcpy(newptr, ptr, size);
+#endif
free(ptr);
}
}