backported malloc fixes from 256boss, plus the addition of calloc and
[bootcensus] / src / libc / malloc.c
index 4e5991d..3610d24 100644 (file)
@@ -15,9 +15,12 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <errno.h>
 #include "mem.h"
+#include "panic.h"
 
 struct mem_desc {
        size_t size;
@@ -91,6 +94,7 @@ void *malloc(size_t sz)
                                add_to_pool(other);
                        }
 
+                       mem->magic = MAGIC;
                        return DESC_PTR(mem);
                }
 
@@ -119,6 +123,10 @@ void free(void *p)
        int pg0;
        struct mem_desc *mem = PTR_DESC(p);
 
+       if(mem->magic != MAGIC) {
+               panic("free: corrupted magic!\n");
+       }
+
        if(mem->size > MAX_POOL_SIZE) {
                /*printf("foo_free(%p): %ld bytes. block too large for pools, returning to system\n",
                                (void*)p, (unsigned long)mem->size);*/
@@ -131,6 +139,38 @@ void free(void *p)
        add_to_pool(mem);
 }
 
+
+void *calloc(size_t num, size_t size)
+{
+       void *ptr = malloc(num * size);
+       if(ptr) {
+               memset(ptr, 0, num * size);
+       }
+       return ptr;
+}
+
+void *realloc(void *ptr, size_t size)
+{
+       struct mem_desc *mem;
+       void *newp;
+
+       if(!ptr) {
+               return malloc(size);
+       }
+
+       mem = PTR_DESC(ptr);
+       if(mem->size >= size) {
+               return ptr;     /* TODO: shrink */
+       }
+
+       if(!(newp = malloc(size))) {
+               return 0;
+       }
+       free(ptr);
+       return newp;
+}
+
+
 static int add_to_pool(struct mem_desc *mem)
 {
        int pidx;
@@ -148,7 +188,7 @@ static int add_to_pool(struct mem_desc *mem)
                pnode = iter->next;
                if(mem->size == pnode->size) {  /* only coalesce same-sized blocks */
                        if((char*)mem == (char*)pnode - pnode->size) {
-                               iter = pnode->next;     /* unlink pnode */
+                               iter->next = pnode->next;       /* unlink pnode */
                                pools[pidx] = head.next;
                                mem->next = 0;
                                mem->size += pnode->size;
@@ -157,7 +197,7 @@ static int add_to_pool(struct mem_desc *mem)
                                return add_to_pool(mem);
                        }
                        if((char*)mem == (char*)pnode + pnode->size) {
-                               iter = pnode->next;     /* unlink pnode */
+                               iter->next = pnode->next;       /* unlink pnode */
                                pools[pidx] = head.next;
                                pnode->next = 0;
                                pnode->size += mem->size;