diff options
Diffstat (limited to 'com32/lib')
-rw-r--r-- | com32/lib/Makefile | 4 | ||||
-rw-r--r-- | com32/lib/free.c | 37 | ||||
-rw-r--r-- | com32/lib/malloc.c | 2 |
3 files changed, 41 insertions, 2 deletions
diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 57348a8d..50862e00 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -151,7 +151,9 @@ LIBOTHER_OBJS = \ pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \ pci/writeb.o pci/writew.o pci/writel.o pci/writebios.o \ \ - sys/x86_init_fpu.o math/pow.o math/strtod.o + sys/x86_init_fpu.o math/pow.o math/strtod.o \ + \ + syslinux/memscan.o MINLIBOBJS = \ $(LIBOTHER_OBJS) \ diff --git a/com32/lib/free.c b/com32/lib/free.c index f8a2e1f4..a91ad8ef 100644 --- a/com32/lib/free.c +++ b/com32/lib/free.c @@ -79,6 +79,43 @@ void free(void *ptr) /* Here we could insert code to return memory to the system. */ } +/* + * This is used to insert a block which is not previously on the + * free list. Only the a.size field of the arena header is assumed + * to be valid. + */ +void __inject_free_block(struct free_arena_header *ah) +{ + struct free_arena_header *nah; + size_t a_end = (size_t) ah + ARENA_SIZE_GET(ah->a.attrs); + size_t n_end; + + for (nah = __malloc_head.a.next; ARENA_TYPE_GET(nah->a.attrs) != ARENA_TYPE_HEAD; + nah = nah->a.next) { + n_end = (size_t) nah + ARENA_SIZE_GET(nah->a.attrs); + + /* Is nah entirely beyond this block? */ + if ((size_t) nah >= a_end) + break; + + /* Is this block entirely beyond nah? */ + if ((size_t) ah >= n_end) + continue; + + /* Otherwise we have some sort of overlap - reject this block */ + return; + } + + /* Now, nah should point to the successor block */ + ah->a.next = nah; + ah->a.prev = nah->a.prev; + nah->a.prev = ah; + ah->a.prev->a.next = ah; + + __free_block(ah); +} + + void __free_tagged(void *tag) { struct free_arena_header *fp, *nfp; diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c index 4b113221..ff6e5b9e 100644 --- a/com32/lib/malloc.c +++ b/com32/lib/malloc.c @@ -64,7 +64,7 @@ static int consider_memory_area(void *dummy, addr_t start, if (len >= 2 * sizeof(struct arena_header)) { fp = (struct free_arena_header *)start; - fp->a.size = len; + ARENA_SIZE_SET(fp->a.attrs, len); __inject_free_block(fp); } } |