git: c29ee08204ce - main - rtld_malloc: add __crt_aligned_alloc_offset()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Aug 2023 14:17:17 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=c29ee08204ce4106d4992474005c5f2fb7d5fbf1 commit c29ee08204ce4106d4992474005c5f2fb7d5fbf1 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-07-22 04:21:45 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-08-21 14:16:42 +0000 rtld_malloc: add __crt_aligned_alloc_offset() It is modelled after aligned_alloc(3). Most importantly, to free the allocation, __crt_free() can be used. Additionally, caller may specify offset into the aligned allocation, so that we return offset-ed from alignment pointer. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D41150 --- libexec/rtld-elf/rtld_malloc.c | 34 +++++++++++++++++++++++++++++++--- libexec/rtld-elf/rtld_malloc.h | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/libexec/rtld-elf/rtld_malloc.c b/libexec/rtld-elf/rtld_malloc.c index ac8af4d6b6e1..6e011e88ba5a 100644 --- a/libexec/rtld-elf/rtld_malloc.c +++ b/libexec/rtld-elf/rtld_malloc.c @@ -86,13 +86,15 @@ static void morecore(int bucket); static int morepages(int n); #define MAGIC 0xef /* magic # on accounting info */ +#define AMAGIC 0xdf /* magic # for aligned alloc */ /* * nextf[i] is the pointer to the next free block of size * (FIRST_BUCKET_SIZE << i). The overhead information precedes the data * area returned to the user. */ -#define FIRST_BUCKET_SIZE 8 +#define LOW_BITS 3 +#define FIRST_BUCKET_SIZE (1U << LOW_BITS) #define NBUCKETS 30 static union overhead *nextf[NBUCKETS]; @@ -169,6 +171,28 @@ __crt_calloc(size_t num, size_t size) return (ret); } +void * +__crt_aligned_alloc_offset(size_t align, size_t size, size_t offset) +{ + void *mem, *ov; + union overhead ov1; + uintptr_t x; + + if (align < FIRST_BUCKET_SIZE) + align = FIRST_BUCKET_SIZE; + offset &= align - 1; + mem = __crt_malloc(size + align + offset + sizeof(union overhead)); + if (mem == NULL) + return (NULL); + x = roundup2((uintptr_t)mem + sizeof(union overhead), align); + x += offset; + ov = cp2op((void *)x); + ov1.ov_magic = AMAGIC; + ov1.ov_index = x - (uintptr_t)mem - sizeof(union overhead); + memcpy(ov, &ov1, sizeof(ov1)); + return ((void *)x); +} + /* * Allocate more memory to the indicated bucket. */ @@ -210,12 +234,16 @@ morecore(int bucket) void __crt_free(void *cp) { + union overhead *op, op1; + void *opx; int size; - union overhead *op; if (cp == NULL) return; - op = cp2op(cp); + opx = cp2op(cp); + memcpy(&op1, opx, sizeof(op1)); + op = op1.ov_magic == AMAGIC ? (void *)((caddr_t)cp - op1.ov_index) : + opx; if (op->ov_magic != MAGIC) return; /* sanity */ size = op->ov_index; diff --git a/libexec/rtld-elf/rtld_malloc.h b/libexec/rtld-elf/rtld_malloc.h index f9780c552821..247726b9f470 100644 --- a/libexec/rtld-elf/rtld_malloc.h +++ b/libexec/rtld-elf/rtld_malloc.h @@ -32,6 +32,7 @@ #ifndef RTLD_MALLOC_H #define RTLD_MALLOC_H +void *__crt_aligned_alloc_offset(size_t align, size_t size, size_t offset); void *__crt_calloc(size_t num, size_t size); void __crt_free(void *cp); void *__crt_malloc(size_t nbytes);