From bd25bb84784338f849a9377c682b5ca978a6b6f1 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Sat, 30 Mar 2024 20:56:46 +0100 Subject: [PATCH] Add calloc, realloc, memmove. Sync klibc and libc --- Makefile | 1 + core/klibc.h | 4 +-- userspace/libc.c | 72 +++++++++++++++++++++++++++++++++++++++++------- userspace/libc.h | 11 +++++++- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index e1057de..997769c 100644 --- a/Makefile +++ b/Makefile @@ -102,6 +102,7 @@ screenshot: ## Take a screenshot of the qemu window clean: $(RM) kernel $(asmobj) $(gasmobj) $(cobj) $(deps) $(cinc) fd.iso kernel.debug kernel.map $(docobj) $(RM) -r isodir + $(MAKE) -C userspace clean .PHONY: userspace screenshot diff --git a/core/klibc.h b/core/klibc.h index 8b59f20..3d6b13a 100644 --- a/core/klibc.h +++ b/core/klibc.h @@ -37,8 +37,8 @@ int vprintf(const char *format, va_list ap) __attribute__ ((__format__ (printf, int printf(const char *format, ...) __attribute__ ((__format__ (printf, 1, 2))); // Could be used after malloc is available -int asprintf(char **strp, const char *fmt, ...); -int vasprintf(char **strp, const char *fmt, va_list ap); +int asprintf(char **strp, const char *fmt, ...) __attribute__ ((__format__ (printf, 2, 3))); +int vasprintf(char **strp, const char *fmt, va_list ap) __attribute__ ((__format__ (printf, 2, 0))); /* * Dummy printk for disabled debugging statements to use whilst maintaining diff --git a/userspace/libc.c b/userspace/libc.c index 4b1dff0..991b192 100644 --- a/userspace/libc.c +++ b/userspace/libc.c @@ -80,6 +80,16 @@ void *memcpy(void *dst0, const void *src0, size_t len0) #endif } +void *memmove(void *dst, const void *src, size_t n) +{ + char *dstChar = dst; + const char *srcChar = src; + for (size_t i = 0; i < n; i++) { + *(dstChar++) = *(srcChar++); + } + return dst; +} + void *memset(void *src, int c, size_t n) { for (char *ptr = (char *)src; n > 0; n--, ptr++) { @@ -602,20 +612,25 @@ struct heapBlock { static struct heapBlock *heapBlkList = NULL; -struct heapBlock *findFreeBlock(size_t size){ - struct heapBlock *cur = NULL; +static struct heapBlock *findFreeBlock(size_t size) +{ + struct heapBlock *cur = NULL; struct heapBlock *found = NULL; int idx; - list_foreach(heapBlkList, cur, idx){ - if(cur->size >= size && cur->free){ + + list_foreach(heapBlkList, cur, idx) + { + if (cur->size >= size && cur->free) { found = cur; break; } } + return found; } -struct heapBlock *allocNewBlock(size_t size) { +static struct heapBlock *allocNewBlock(size_t size) +{ struct heapBlock *blk = sbrk(size + sizeof(struct heapBlock)); struct heapBlock *head = sbrk(0); size_t blkSize = (intptr_t)head - (intptr_t)blk - sizeof(struct heapBlock); @@ -625,10 +640,11 @@ struct heapBlock *allocNewBlock(size_t size) { blk->size = blkSize; blk->free = 1; list_add_tail(heapBlkList, blk); + return blk; } -struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize) +static struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize) { if (blk->size < neededSize + sizeof(struct heapBlock) + 1) { return NULL; @@ -637,6 +653,7 @@ struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize) newBlk->free = 1; newBlk->size = blk->size - sizeof(struct heapBlock) - neededSize; blk->size = neededSize; + return newBlk; } @@ -655,16 +672,18 @@ void *malloc(size_t size) list_add_head(heapBlkList, remainBlock); } blk->free = 0; + return blk + 1; // return the area after the blk description } -struct heapBlock *getHeapBlock(void *ptr) { +static struct heapBlock *getHeapBlock(void *ptr) +{ return (struct heapBlock *)ptr - 1; } - -void free(void *ptr){ - if(!ptr) +void free(void *ptr) +{ + if (!ptr) return; struct heapBlock *blk = getHeapBlock(ptr); @@ -673,3 +692,36 @@ void free(void *ptr){ blk->free = 1; } +void *calloc(size_t nmemb, size_t size) +{ + size_t allocSize = nmemb * size; + void *ptr = malloc(allocSize); + + if (ptr != NULL) + memset(ptr, 0, allocSize); + + return ptr; +} + +void *realloc(void *ptr, size_t size) +{ + if (!ptr) { + return malloc(size); + } + + struct heapBlock *blk = getHeapBlock(ptr); + if (blk->size >= size) { + return ptr; + } + + void *new_ptr; + new_ptr = malloc(size); + if (!new_ptr) { + return NULL; + } + memmove(new_ptr, ptr, blk->size); + free(ptr); + + return new_ptr; +} + diff --git a/userspace/libc.h b/userspace/libc.h index 4e2a4a5..eb4c313 100644 --- a/userspace/libc.h +++ b/userspace/libc.h @@ -14,8 +14,15 @@ #define isprint(c) ((' ' <= (c)) && ((c) <= '~')) #define EOF (-1) - +/** compares the first @param n bytes (each interpreted as + * unsigned char) of the memory areas @param s1 and @param s2. + */ __attribute__ ((access (read_only, 1, 3), access (read_only, 2, 3))) int memcmp(const void *s1, const void *s2, size_t n); + +/** + * copies n bytes from memory area src to memory area dest. The memory areas may overlap + */ +__attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void *memmove(void *dest, const void *src, size_t n); __attribute__ ((access (write_only, 1, 3), access (read_only, 2, 3))) void *memcpy(void *dest, const void *src, size_t n); __attribute__ ((access (write_only, 1, 3))) void *memset(void *s, int c, size_t n); char *itoa(long long int value, char *str, int base); @@ -51,4 +58,6 @@ int readline(char *buf, int size); int brk(void *addr); void *sbrk(intptr_t increment); void *malloc(size_t size); +void *calloc(size_t nmemb, size_t size); +void *realloc(void *ptr, size_t size); void free(void *ptr);