diff options
author | Anton Kling <anton@kling.gg> | 2024-04-11 17:22:00 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-04-11 17:23:39 +0200 |
commit | ca082f686fd2dc7ee6f0284421f6212d6d4acee8 (patch) | |
tree | 493b1047661174816f0d1d300952e40e2846b24b /userland/libc/malloc | |
parent | e25a47fcc4db09ab9b845a691297da67243e6049 (diff) |
bug fixes
Diffstat (limited to 'userland/libc/malloc')
-rw-r--r-- | userland/libc/malloc/malloc.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/userland/libc/malloc/malloc.c b/userland/libc/malloc/malloc.c index d1bc5ca..1c992ef 100644 --- a/userland/libc/malloc/malloc.c +++ b/userland/libc/malloc/malloc.c @@ -1,5 +1,6 @@ #include <assert.h> #include <math.h> +#include <stdarg.h> #include <stddef.h> #include <stdlib.h> #include <typedefs.h> @@ -23,6 +24,26 @@ MallocHeader *head = NULL; MallocHeader *final = NULL; u32 total_heap_size = 0; +// printf without using malloc() so that it can be used internally by +// malloc() such that it does not have a stack overflow. +int debug_vprintf(const char *fmt, va_list ap) { + const char buffer[4096]; + int rc = vsnprintf(buffer, 4096, fmt, ap); + if (0 > rc) { + return -1; + } + write(1, buffer, rc); + return rc; +} + +int debug_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int rc = debug_vprintf(fmt, ap); + va_end(ap); + return rc; +} + int init_heap(void) { head = (MallocHeader *)sbrk(NEW_ALLOC_SIZE); total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); @@ -63,8 +84,10 @@ MallocHeader *next_header(MallocHeader *a) { assert(a->magic == 0xdde51ab9410268b1); if (a->n) { if (a->n->magic != 0xdde51ab9410268b1) { - printf("Real magic value is: %x\n", a->n->magic); - printf("location: %x\n", &(a->n->magic)); + debug_printf("a->n: %x\n", a->n); + debug_printf("Real magic value is: %x\n", a->n->magic); + debug_printf("size: %x\n", a->n->size); + debug_printf("location: %x\n", &(a->n->magic)); assert(0); } return a->n; @@ -74,7 +97,7 @@ MallocHeader *next_header(MallocHeader *a) { MallocHeader *next_close_header(MallocHeader *a) { if (!a) { - printf("next close header fail\n"); + debug_printf("next close header fail\n"); for (;;) ; } @@ -122,13 +145,16 @@ void merge_headers(MallocHeader *b) { b->size += n->size; b->flags |= n->flags & IS_FINAL; b->n = n->n; + assert(b->magic == 0xdde51ab9410268b1); + if (b->n) { + assert(b->n->magic == 0xdde51ab9410268b1); + } if (n == final) { final = b; } } -void *malloc(size_t s) { - s += 0x1000; +void *int_malloc(size_t s, int recursion) { size_t n = s; MallocHeader *free_entry = find_free_entry(s); if (!free_entry) { @@ -136,7 +162,11 @@ void *malloc(size_t s) { assert(0); return NULL; } - return malloc(s); + if (recursion) { + debug_printf("RECURSION IN MALLOC :(\n"); + assert(0); + } + return int_malloc(s, 1); } void *rc = (void *)(free_entry + 1); @@ -158,12 +188,14 @@ void *malloc(size_t s) { free_entry->flags = 0; free_entry->n = new_entry; free_entry->magic = 0xdde51ab9410268b1; - for (int i = 0; i < s; i++) { - *(char *)rc = 'A'; - } + randomfill(rc, s); return rc; } +void *malloc(size_t s) { + return int_malloc(s, 0); +} + size_t get_mem_size(void *ptr) { if (!ptr) { return 0; @@ -216,13 +248,9 @@ void free(void *p) { if (!p) { return; } - // FIXME: This assumes that p is at the start of a allocated area. - // Could this be avoided in a simple way? MallocHeader *h = (MallocHeader *)((uintptr_t)p - sizeof(MallocHeader)); assert(h->magic == 0xdde51ab9410268b1); - if (h->flags & IS_FREE) { - return; - } + assert(!(h->flags & IS_FREE)); h->flags |= IS_FREE; merge_headers(h); |