Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / heap.c
index d6d9a40..71e3d6d 100644 (file)
@@ -8,6 +8,8 @@
 #include <acess/sys.h>\r
 #include <stdlib.h>\r
 #include <string.h>\r
+#include <assert.h>\r
+#include <stdbool.h>\r
 #include "lib.h"\r
 \r
 #if 0\r
@@ -71,6 +73,7 @@ static const heap_head        _heap_zero_allocation;
 EXPORT void    *malloc(size_t bytes);\r
 void   *_malloc(size_t bytes, void *owner);\r
 EXPORT void    *calloc(size_t bytes, size_t count);\r
+bool   _libc_free(void *mem);\r
 EXPORT void    free(void *mem);\r
 EXPORT void    *realloc(void *mem, size_t bytes);\r
 EXPORT void    *sbrk(int increment);\r
@@ -221,26 +224,31 @@ EXPORT void *calloc(size_t __nmemb, size_t __size)
  \param mem    Pointer - Memory to free\r
 */\r
 EXPORT void free(void *mem)\r
+{\r
+       if( !_libc_free(mem) ) {\r
+               Heap_Validate(1);\r
+               exit(0);\r
+       }\r
+}\r
+\r
+// Exported for libc++\r
+EXPORT bool _libc_free(void *mem)\r
 {\r
        heap_head       *head = (heap_head*)mem - 1;\r
 \r
        // Free of NULL or the zero allocation does nothing\r
        if(!mem || mem == _heap_zero_allocation.data)\r
-               return ;\r
+               return true;\r
        \r
        // Sanity check the head address\r
        if(head->magic != MAGIC) {\r
                if( head->magic != MAGIC_FREE ) {\r
-                       _SysDebug("Double free of %p", mem);\r
-                       Heap_Validate(1);\r
-                       exit(0);\r
+                       _SysDebug("Double free of %p by %p", mem, __builtin_return_address(0));\r
                }\r
                else {\r
-                       _SysDebug("Free of invalid pointer %p", mem);\r
-                       Heap_Validate(1);\r
-                       exit(0);\r
+                       _SysDebug("Free of invalid pointer %p by ", mem, __builtin_return_address(0));\r
                }\r
-               return;\r
+               return false;\r
        }\r
        \r
        head->magic = MAGIC_FREE;\r
@@ -265,8 +273,9 @@ EXPORT void free(void *mem)
                heap_foot *prevFoot = PREV_FOOT(head);\r
                if( prevFoot->magic != MAGIC )\r
                {\r
+                       _SysDebug("Heap corruption, previous foot magic invalid");\r
                        Heap_Validate(1);\r
-                       exit(1);\r
+                       return false;\r
                }\r
                \r
                heap_head *prevHead = prevFoot->header;\r
@@ -281,6 +290,8 @@ EXPORT void free(void *mem)
                        prevFoot->header = NULL;\r
                }\r
        }\r
+       \r
+       return true;\r
 }\r
 \r
 /**\r
@@ -308,7 +319,8 @@ EXPORT void *realloc(void *oldPos, size_t bytes)
        \r
        // Check for free space after the block\r
        heap_head *nexthead = NEXT_HEAD(head);\r
-       if( nexthead && nexthead->magic == MAGIC_FREE && head->size + nexthead->size >= reqd_size )\r
+       assert( nexthead <= _heap_end );\r
+       if( nexthead != _heap_end && nexthead->magic == MAGIC_FREE && head->size + nexthead->size >= reqd_size )\r
        {\r
                // Split next block\r
                if( head->size + nexthead->size > reqd_size )\r
@@ -337,12 +349,12 @@ EXPORT void *realloc(void *oldPos, size_t bytes)
        void *ret = _malloc(bytes, __builtin_return_address(0));\r
        if(ret == NULL)\r
                return NULL;\r
+       heap_head *newhead = (heap_head*)ret - 1;\r
        \r
-       //Copy Old Data\r
+       // Copy Old Data\r
+       assert( head->size < newhead->size );\r
        size_t copy_size = head->size-sizeof(heap_head)-sizeof(heap_foot);\r
-       if( copy_size > bytes )\r
-               copy_size = bytes;\r
-       memcpy(ret, oldPos, bytes);\r
+       memcpy(ret, oldPos, copy_size);\r
        free(oldPos);\r
        \r
        //Return\r

UCC git Repository :: git.ucc.asn.au