The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c29ee08204ce4106d4992474005c5f2fb7d5fbf1

commit c29ee08204ce4106d4992474005c5f2fb7d5fbf1
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2023-07-22 04:21:45 +0000
Commit:     Konstantin Belousov <[email protected]>
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);

Reply via email to