From 6df402044146695816883a4528b4662d2ac09523 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Mon, 20 Jan 2025 08:03:34 +0100 Subject: [PATCH] libutils: refactor the MDBG malloc functions Replace the MDBG malloc functions and macros with a new function __mdbg_alloc() handling all the memory allocations similar to mem_alloc(). The old MDBG macros are replace by new macros calling __mdbg_alloc(). mem_alloc(), mem_alloc_unlocked(), and mem_free() are updated to handle configuration with and without MDBG, removing the all the ENABLE_MDBG ifdefs in the C file. Signed-off-by: Jens Wiklander Reviewed-by: Jerome Forissier --- lib/libutils/isoc/bget_malloc.c | 331 +++++++++-------------------- lib/libutils/isoc/include/malloc.h | 64 +++--- 2 files changed, 127 insertions(+), 268 deletions(-) diff --git a/lib/libutils/isoc/bget_malloc.c b/lib/libutils/isoc/bget_malloc.c index 040392d0bbd..83fc9ed60b2 100644 --- a/lib/libutils/isoc/bget_malloc.c +++ b/lib/libutils/isoc/bget_malloc.c @@ -502,16 +502,14 @@ void *raw_realloc(void *ptr, size_t hdr_size, size_t ftr_size, pl_size, ctx); } -#ifdef ENABLE_MDBG - struct mdbg_hdr { const char *fname; uint16_t line; - uint32_t pl_size; - uint32_t magic; -#if defined(ARM64) +#ifdef __LP64__ uint64_t pad; #endif + uint32_t pl_size; + uint32_t magic; }; #define MDBG_HEADER_MAGIC 0xadadadad @@ -548,128 +546,119 @@ static void mdbg_update_hdr(struct mdbg_hdr *hdr, const char *fname, *footer = MDBG_FOOTER_MAGIC; } -static void *gen_mdbg_malloc(struct malloc_ctx *ctx, const char *fname, - int lineno, size_t size) +static void assert_header(struct mdbg_hdr *hdr __maybe_unused) { - struct mdbg_hdr *hdr; - uint32_t exceptions = malloc_lock(ctx); + assert(hdr->magic == MDBG_HEADER_MAGIC); + assert(*mdbg_get_footer(hdr) == MDBG_FOOTER_MAGIC); +} + +static void *mem_alloc_unlocked(uint32_t flags, void *ptr, size_t alignment, + size_t nmemb, size_t size, const char *fname, + int lineno, struct malloc_ctx *ctx) +{ + struct mdbg_hdr *hdr = NULL; + size_t ftr_size = 0; + size_t hdr_size = 0; /* * Check struct mdbg_hdr works with BGET_HDR_QUANTUM. */ - COMPILE_TIME_ASSERT((sizeof(struct mdbg_hdr) % BGET_HDR_QUANTUM) == 0); + static_assert((sizeof(struct mdbg_hdr) % BGET_HDR_QUANTUM) == 0); + + if (IS_ENABLED2(ENABLE_MDBG)) { + if (ptr) { + hdr = ptr; + hdr--; + assert_header(hdr); + } + ftr_size = mdbg_get_ftr_size(nmemb * size); + hdr_size = sizeof(struct mdbg_hdr); + ptr = hdr; + } + + ptr = raw_mem_alloc(flags, ptr, hdr_size, ftr_size, alignment, nmemb, + size, ctx); - hdr = raw_malloc(sizeof(struct mdbg_hdr), - mdbg_get_ftr_size(size), size, ctx); - if (hdr) { - mdbg_update_hdr(hdr, fname, lineno, size); + if (IS_ENABLED2(ENABLE_MDBG) && ptr) { + hdr = ptr; + mdbg_update_hdr(hdr, fname, lineno, nmemb * size); hdr++; + ptr = hdr; } - malloc_unlock(ctx, exceptions); - return hdr; + return ptr; } -static void assert_header(struct mdbg_hdr *hdr __maybe_unused) +static struct malloc_ctx *get_ctx(uint32_t flags __maybe_unused) { - assert(hdr->magic == MDBG_HEADER_MAGIC); - assert(*mdbg_get_footer(hdr) == MDBG_FOOTER_MAGIC); +#ifdef CFG_NS_VIRTUALIZATION + if (flags & MAF_NEX) + return &nex_malloc_ctx; +#endif + return &malloc_ctx; } -static void gen_mdbg_free(struct malloc_ctx *ctx, void *ptr, bool wipe) +static void *mem_alloc(uint32_t flags, void *ptr, size_t alignment, + size_t nmemb, size_t size, const char *fname, int lineno) { - struct mdbg_hdr *hdr = ptr; - - if (hdr) { - hdr--; - assert_header(hdr); - hdr->magic = 0; - *mdbg_get_footer(hdr) = 0; - raw_free(hdr, ctx, wipe); - } -} + struct malloc_ctx *ctx = get_ctx(flags); + uint32_t exceptions = 0; + void *p = NULL; -static void free_helper(void *ptr, bool wipe) -{ - uint32_t exceptions = malloc_lock(&malloc_ctx); + exceptions = malloc_lock(ctx); + p = mem_alloc_unlocked(flags, ptr, alignment, nmemb, size, fname, + lineno, ctx); + malloc_unlock(ctx, exceptions); - gen_mdbg_free(&malloc_ctx, ptr, wipe); - malloc_unlock(&malloc_ctx, exceptions); + return p; } -static void *gen_mdbg_calloc(struct malloc_ctx *ctx, const char *fname, int lineno, - size_t nmemb, size_t size) +static void mem_free(void *ptr, bool wipe, uint32_t flags) { - struct mdbg_hdr *hdr; - uint32_t exceptions = malloc_lock(ctx); + struct malloc_ctx *ctx = get_ctx(flags); + uint32_t exceptions = 0; - hdr = raw_calloc(sizeof(struct mdbg_hdr), - mdbg_get_ftr_size(nmemb * size), nmemb, size, - ctx); - if (hdr) { - mdbg_update_hdr(hdr, fname, lineno, nmemb * size); - hdr++; - } - malloc_unlock(ctx, exceptions); - return hdr; -} + exceptions = malloc_lock(ctx); -static void *gen_mdbg_realloc_unlocked(struct malloc_ctx *ctx, const char *fname, - int lineno, void *ptr, size_t size) -{ - struct mdbg_hdr *hdr = ptr; + if (IS_ENABLED2(ENABLE_MDBG) && ptr) { + struct mdbg_hdr *hdr = ptr; - if (hdr) { hdr--; assert_header(hdr); + hdr->magic = 0; + *mdbg_get_footer(hdr) = 0; + ptr = hdr; } - hdr = raw_realloc(hdr, sizeof(struct mdbg_hdr), - mdbg_get_ftr_size(size), size, ctx); - if (hdr) { - mdbg_update_hdr(hdr, fname, lineno, size); - hdr++; - } - return hdr; -} -static void *gen_mdbg_realloc(struct malloc_ctx *ctx, const char *fname, - int lineno, void *ptr, size_t size) -{ - void *p; - uint32_t exceptions = malloc_lock(ctx); + raw_free(ptr, ctx, wipe); - p = gen_mdbg_realloc_unlocked(ctx, fname, lineno, ptr, size); malloc_unlock(ctx, exceptions); - return p; } -#define realloc_unlocked(ctx, ptr, size) \ - gen_mdbg_realloc_unlocked(ctx, __FILE__, __LINE__, (ptr), (size)) - -static void *gen_mdbg_memalign(struct malloc_ctx *ctx, const char *fname, - int lineno, size_t alignment, size_t size) +static void *get_payload_start_size(void *raw_buf, size_t *size) { - struct mdbg_hdr *hdr; - uint32_t exceptions = malloc_lock(ctx); + if (IS_ENABLED2(ENABLE_MDBG)) { + struct mdbg_hdr *hdr = raw_buf; - hdr = raw_memalign(sizeof(struct mdbg_hdr), mdbg_get_ftr_size(size), - alignment, size, ctx); - if (hdr) { - mdbg_update_hdr(hdr, fname, lineno, size); - hdr++; + assert(bget_buf_size(hdr) >= hdr->pl_size); + *size = hdr->pl_size; + return hdr + 1; } - malloc_unlock(ctx, exceptions); - return hdr; + + *size = bget_buf_size(raw_buf); + return raw_buf; } +/* For use in raw_malloc_add_pool() below */ +#define realloc_unlocked(ctx, ptr, size) \ + mem_alloc_unlocked(MAF_NULL, (ptr), 1, 1, (size), __FILE__, __LINE__, \ + (ctx)) -static void *get_payload_start_size(void *raw_buf, size_t *size) +#ifdef ENABLE_MDBG +void *__mdbg_alloc(uint32_t flags, void *ptr, size_t alignment, size_t nmemb, + size_t size, const char *fname, int lineno) { - struct mdbg_hdr *hdr = raw_buf; - - assert(bget_buf_size(hdr) >= hdr->pl_size); - *size = hdr->pl_size; - return hdr + 1; + return mem_alloc(flags, ptr, alignment, nmemb, size, fname, lineno); } static void gen_mdbg_check(struct malloc_ctx *ctx, int bufdump) @@ -699,150 +688,65 @@ static void gen_mdbg_check(struct malloc_ctx *ctx, int bufdump) malloc_unlock(ctx, exceptions); } -void *mdbg_malloc(const char *fname, int lineno, size_t size) -{ - return gen_mdbg_malloc(&malloc_ctx, fname, lineno, size); -} - -void *mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size) -{ - return gen_mdbg_calloc(&malloc_ctx, fname, lineno, nmemb, size); -} - -void *mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size) -{ - return gen_mdbg_realloc(&malloc_ctx, fname, lineno, ptr, size); -} - -void *mdbg_memalign(const char *fname, int lineno, size_t alignment, - size_t size) -{ - return gen_mdbg_memalign(&malloc_ctx, fname, lineno, alignment, size); -} - -#if __STDC_VERSION__ >= 201112L -void *mdbg_aligned_alloc(const char *fname, int lineno, size_t alignment, - size_t size) -{ - if (size % alignment) - return NULL; - - return gen_mdbg_memalign(&malloc_ctx, fname, lineno, alignment, size); -} -#endif /* __STDC_VERSION__ */ - void mdbg_check(int bufdump) { gen_mdbg_check(&malloc_ctx, bufdump); } +#endif /* - * Since malloc debug is enabled, malloc() and friends are redirected by macros - * to mdbg_malloc() etc. + * If malloc debug is enabled, malloc() and friends are redirected by macros + * to __mdbg_alloc() etc. * We still want to export the standard entry points in case they are referenced * by the application, either directly or via external libraries. */ + #undef malloc void *malloc(size_t size) { - return mdbg_malloc(__FILE__, __LINE__, size); + return mem_alloc(MAF_NULL, NULL, 1, 1, size, __FILE__, __LINE__); } #undef calloc void *calloc(size_t nmemb, size_t size) { - return mdbg_calloc(__FILE__, __LINE__, nmemb, size); + return mem_alloc(MAF_ZERO_INIT, NULL, 1, nmemb, size, __FILE__, + __LINE__); } #undef realloc void *realloc(void *ptr, size_t size) { - return mdbg_realloc(__FILE__, __LINE__, ptr, size); -} - -#else /* ENABLE_MDBG */ - -static struct malloc_ctx *get_ctx(uint32_t flags __maybe_unused) -{ -#ifdef CFG_NS_VIRTUALIZATION - if (flags & MAF_NEX) - return &nex_malloc_ctx; -#endif - return &malloc_ctx; -} - -static void *mem_alloc(uint32_t flags, void *ptr, size_t alignment, - size_t nmemb, size_t size) -{ - struct malloc_ctx *ctx = get_ctx(flags); - uint32_t exceptions = 0; - void *p = NULL; - - exceptions = malloc_lock(ctx); - p = raw_mem_alloc(flags, ptr, 0, 0, alignment, nmemb, size, ctx); - malloc_unlock(ctx, exceptions); - - return p; -} - -void *malloc(size_t size) -{ - return mem_alloc(MAF_NULL, NULL, 1, 1, size); -} - -static void free_helper(void *ptr, bool wipe) -{ - uint32_t exceptions = malloc_lock(&malloc_ctx); - - raw_free(ptr, &malloc_ctx, wipe); - malloc_unlock(&malloc_ctx, exceptions); -} - -void *calloc(size_t nmemb, size_t size) -{ - return mem_alloc(MAF_ZERO_INIT, NULL, 1, nmemb, size); -} - -/* For use in raw_malloc_add_pool() below */ -#define realloc_unlocked(ctx, ptr, size) \ - raw_mem_alloc(MAF_NULL, ptr, 0, 0, 1, 1, size, ctx) - -void *realloc(void *ptr, size_t size) -{ - return mem_alloc(MAF_NULL, ptr, 1, 1, size); + return mem_alloc(MAF_NULL, ptr, 1, 1, size, __FILE__, __LINE__); } +#undef memalign void *memalign(size_t alignment, size_t size) { - return mem_alloc(MAF_NULL, NULL, alignment, 1, size); + return mem_alloc(MAF_NULL, NULL, alignment, 1, size, __FILE__, + __LINE__); } #if __STDC_VERSION__ >= 201112L +#undef aligned_alloc void *aligned_alloc(size_t alignment, size_t size) { if (size % alignment) return NULL; - return mem_alloc(MAF_NULL, NULL, alignment, 1, size); + return mem_alloc(MAF_NULL, NULL, alignment, 1, size, __FILE__, + __LINE__); } #endif /* __STDC_VERSION__ */ -static void *get_payload_start_size(void *ptr, size_t *size) -{ - *size = bget_buf_size(ptr); - return ptr; -} - -#endif - void free(void *ptr) { - free_helper(ptr, false); + mem_free(ptr, false, MAF_NULL); } void free_wipe(void *ptr) { - free_helper(ptr, true); + mem_free(ptr, true, MAF_NULL); } static void gen_malloc_add_pool(struct malloc_ctx *ctx, void *buf, size_t len) @@ -1005,70 +909,39 @@ bool malloc_buffer_overlaps_heap(void *buf, size_t len) void *nex_malloc(size_t size) { - return mem_alloc(MAF_NEX, NULL, 1, 1, size); + return mem_alloc(MAF_NEX, NULL, 1, 1, size, __FILE__, __LINE__); } void *nex_calloc(size_t nmemb, size_t size) { - return mem_alloc(MAF_NEX | MAF_ZERO_INIT, NULL, 1, nmemb, size); + return mem_alloc(MAF_NEX | MAF_ZERO_INIT, NULL, 1, nmemb, size, + __FILE__, __LINE__); } void *nex_realloc(void *ptr, size_t size) { - return mem_alloc(MAF_NEX, ptr, 1, 1, size); + return mem_alloc(MAF_NEX, ptr, 1, 1, size, __FILE__, __LINE__); } void *nex_memalign(size_t alignment, size_t size) { - return mem_alloc(MAF_NEX, NULL, alignment, 1, size); -} - -void nex_free(void *ptr) -{ - uint32_t exceptions = malloc_lock(&nex_malloc_ctx); - - raw_free(ptr, &nex_malloc_ctx, false /* !wipe */); - malloc_unlock(&nex_malloc_ctx, exceptions); + return mem_alloc(MAF_NEX, NULL, alignment, 1, size, __FILE__, __LINE__); } #else /* ENABLE_MDBG */ -void *nex_mdbg_malloc(const char *fname, int lineno, size_t size) -{ - return gen_mdbg_malloc(&nex_malloc_ctx, fname, lineno, size); -} - -void *nex_mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size) -{ - return gen_mdbg_calloc(&nex_malloc_ctx, fname, lineno, nmemb, size); -} - -void *nex_mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size) -{ - return gen_mdbg_realloc(&nex_malloc_ctx, fname, lineno, ptr, size); -} - -void *nex_mdbg_memalign(const char *fname, int lineno, size_t alignment, - size_t size) -{ - return gen_mdbg_memalign(&nex_malloc_ctx, fname, lineno, alignment, size); -} - void nex_mdbg_check(int bufdump) { gen_mdbg_check(&nex_malloc_ctx, bufdump); } +#endif /* ENABLE_MDBG */ + void nex_free(void *ptr) { - uint32_t exceptions = malloc_lock(&nex_malloc_ctx); - - gen_mdbg_free(&nex_malloc_ctx, ptr, false /* !wipe */); - malloc_unlock(&nex_malloc_ctx, exceptions); + mem_free(ptr, false, MAF_NEX); } -#endif /* ENABLE_MDBG */ - void nex_malloc_add_pool(void *buf, size_t len) { gen_malloc_add_pool(&nex_malloc_ctx, buf, len); diff --git a/lib/libutils/isoc/include/malloc.h b/lib/libutils/isoc/include/malloc.h index 1660191e524..fa15bdc4384 100644 --- a/lib/libutils/isoc/include/malloc.h +++ b/lib/libutils/isoc/include/malloc.h @@ -28,31 +28,23 @@ void *aligned_alloc(size_t alignment, size_t size); #endif #ifdef ENABLE_MDBG - -void *mdbg_malloc(const char *fname, int lineno, size_t size); -void *mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size); -void *mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size); -void *mdbg_memalign(const char *fname, int lineno, size_t alignment, - size_t size); - -#if __STDC_VERSION__ >= 201112L -void *mdbg_aligned_alloc(const char *fname, int lineno, size_t alignment, - size_t size); -#endif +void *__mdbg_alloc(uint32_t flags, void *ptr, size_t alignment, size_t nmemb, + size_t size, const char *fname, int lineno); void mdbg_check(int bufdump); -#define malloc(size) mdbg_malloc(__FILE__, __LINE__, (size)) -#define calloc(nmemb, size) \ - mdbg_calloc(__FILE__, __LINE__, (nmemb), (size)) -#define realloc(ptr, size) \ - mdbg_realloc(__FILE__, __LINE__, (ptr), (size)) -#define memalign(alignment, size) \ - mdbg_memalign(__FILE__, __LINE__, (alignment), (size)) +#define malloc(size) __mdbg_alloc(MAF_NULL, NULL, 1, 1, \ + (size), __FILE__, __LINE__) +#define calloc(nmemb, size) __mdbg_alloc(MAF_ZERO_INIT, NULL, 1, (nmemb), \ + (size), __FILE__, __LINE__) +#define realloc(ptr, size) __mdbg_alloc(MAF_NULL, (ptr), 1, 1, \ + (size), __FILE__, __LINE__) +#define memalign(align, size) __mdbg_alloc(MAF_NULL, NULL, (align), 1, \ + (size), __FILE__, __LINE__) #if __STDC_VERSION__ >= 201112L -#define aligned_alloc(alignment, size) \ - mdbg_aligned_alloc(__FILE__, __LINE__, (alignment), (size)) +#define aligned_alloc(align, size) \ + __mdbg_alloc(MAF_NULL, NULL, (align), 1, (size), __FILE__, __LINE__) #endif /* __STDC_VERSION__ */ #else @@ -91,33 +83,27 @@ void malloc_reset_stats(void); #ifdef CFG_NS_VIRTUALIZATION +void *nex_malloc(size_t size); +void *nex_calloc(size_t nmemb, size_t size); +void *nex_realloc(void *ptr, size_t size); +void *nex_memalign(size_t alignment, size_t size); void nex_free(void *ptr); #ifdef ENABLE_MDBG -void *nex_mdbg_malloc(const char *fname, int lineno, size_t size); -void *nex_mdbg_calloc(const char *fname, int lineno, size_t nmemb, size_t size); -void *nex_mdbg_realloc(const char *fname, int lineno, void *ptr, size_t size); -void *nex_mdbg_memalign(const char *fname, int lineno, size_t alignment, - size_t size); - void nex_mdbg_check(int bufdump); -#define nex_malloc(size) nex_mdbg_malloc(__FILE__, __LINE__, (size)) -#define nex_calloc(nmemb, size) \ - nex_mdbg_calloc(__FILE__, __LINE__, (nmemb), (size)) -#define nex_realloc(ptr, size) \ - nex_mdbg_realloc(__FILE__, __LINE__, (ptr), (size)) -#define nex_memalign(alignment, size) \ - nex_mdbg_memalign(__FILE__, __LINE__, (alignment), (size)) - +#define nex_malloc(size) __mdbg_alloc(MAF_NEX, NULL, 1, 1, \ + (size), __FILE__, __LINE__) +#define nex_calloc(nmemb, size) __mdbg_alloc(MAF_NEX | MAF_ZERO_INIT, NULL, 1, \ + (nmemb), (size), __FILE__, \ + __LINE__) +#define nex_realloc(ptr, size) __mdbg_alloc(MAF_NEX, (ptr), 1, 1, \ + (size), __FILE__, __LINE__) +#define nex_memalign(align, size) __mdbg_alloc(MAF_NEX, NULL, (align), 1, \ + (size), __FILE__, __LINE__) #else /* ENABLE_MDBG */ -void *nex_malloc(size_t size); -void *nex_calloc(size_t nmemb, size_t size); -void *nex_realloc(void *ptr, size_t size); -void *nex_memalign(size_t alignment, size_t size); - #define nex_mdbg_check(x) do { } while (0) #endif /* ENABLE_MDBG */