> Date: Mon, 3 Jul 2023 07:45:27 +0000 (UTC) > From: RVP <r...@sdf.org> > > On Mon, 3 Jul 2023, RVP wrote: > > > Somebody should maybe add calloc() to bsdmalloc. > > And posix_memalign() (any others?) too, else you end up with 2 > different arenas and free()/realloc() operating on the wrong one.
The attached patch adds calloc, posix_memalign, and C11 aligned_alloc to libbsdmalloc. However, if I try to link something that calls malloc or realloc with -static -lbsdmalloc, ld objects: $ cat null.c #include <stdlib.h> int main(void) { return malloc(1) != NULL; } $ make null LDLIBS=-static\ -lbsdmalloc\ -Wl,-Map=null.map cc -O2 -o null null.c -static -lbsdmalloc -Wl,-Map=null.map ld: /usr/lib/libc.a(jemalloc.o): in function `malloc': jemalloc.c:(.text+0x30a6): multiple definition of `malloc'; /usr/lib/libbsdmalloc.a(malloc.o):malloc.c:(.text+0x0): first defined here ld: /usr/lib/libc.a(jemalloc.o): in function `realloc': jemalloc.c:(.text+0x49c6): multiple definition of `realloc'; /usr/lib/libbsdmalloc.a(malloc.o):malloc.c:(.text+0x282): first defined here ld: /usr/lib/libc.a(jemalloc.o): in function `free': jemalloc.c:(.text+0x4ca0): multiple definition of `free'; /usr/lib/libbsdmalloc.a(malloc.o):malloc.c:(.text+0x22b): first defined here calloc, free, posix_memalign, and aligned_alloc all work fine here. Not sure why calling malloc or realloc still causes jemalloc.o to be pulled in, in the presence of -lbsdmalloc. Not investigating further; if someone wants to investigate and make sure this actually works, feel free to commit this patch.
>From 4c1ca44f21e0d12ad2eac22dc8c3acbf56cfe23b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <riastr...@netbsd.org> Date: Mon, 3 Jul 2023 12:58:34 +0000 Subject: [PATCH] libbsdmalloc: Provide more allocator frontends. - aligned_alloc - calloc - posix_memalign Otherwise these will pull in the jemalloc definitions from libc, which defeats the purpose. Note: libbsdmalloc doesn't set errno=ENOMEM on malloc failure, but these front ends do (even aligned_alloc, which is from C11, which doesn't define ENOMEM at all, but this pacifies our aligned_alloc tests in t_posix_memalign.c). Might want to fix that. --- lib/libbsdmalloc/Makefile | 12 ++++++- lib/libbsdmalloc/aligned_alloc.c | 58 +++++++++++++++++++++++++++++++ lib/libbsdmalloc/calloc.c | 52 +++++++++++++++++++++++++++ lib/libbsdmalloc/posix_memalign.c | 56 +++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 lib/libbsdmalloc/aligned_alloc.c create mode 100644 lib/libbsdmalloc/calloc.c create mode 100644 lib/libbsdmalloc/posix_memalign.c diff --git a/lib/libbsdmalloc/Makefile b/lib/libbsdmalloc/Makefile index 03384670b2b9..b3e5d40fd12a 100644 --- a/lib/libbsdmalloc/Makefile +++ b/lib/libbsdmalloc/Makefile @@ -7,7 +7,17 @@ WARNS= 2 .include <bsd.own.mk> LIB= bsdmalloc -SRCS= malloc.c +SRCS+= aligned_alloc.c +SRCS+= calloc.c +SRCS+= malloc.c +SRCS+= posix_memalign.c + +CFLAGS+= -fno-builtin-aligned_alloc +CFLAGS+= -fno-builtin-calloc +CFLAGS+= -fno-builtin-free +CFLAGS+= -fno-builtin-malloc +CFLAGS+= -fno-builtin-posix_memalign +CFLAGS+= -fno-builtin-realloc CPPFLAGS+= -D_REENT -D_REENTRANT -I${.CURDIR}/../libc/include/ diff --git a/lib/libbsdmalloc/aligned_alloc.c b/lib/libbsdmalloc/aligned_alloc.c new file mode 100644 index 000000000000..76c427557075 --- /dev/null +++ b/lib/libbsdmalloc/aligned_alloc.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2023 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD$"); + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +void * +aligned_alloc(size_t alignment, size_t size) +{ + char *p; + + if (alignment == 0 || (alignment & (alignment - 1)) != 0) { + errno = EINVAL; + return NULL; + } + if (size > SIZE_MAX - (alignment - 1)) { + errno = ENOMEM; + return NULL; + } + + p = malloc(size + alignment - 1); + if (p == NULL) + return NULL; + if ((uintptr_t)p % alignment) + p += alignment - ((uintptr_t)p % alignment); + return p; +} diff --git a/lib/libbsdmalloc/calloc.c b/lib/libbsdmalloc/calloc.c new file mode 100644 index 000000000000..10bb52226ce8 --- /dev/null +++ b/lib/libbsdmalloc/calloc.c @@ -0,0 +1,52 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2023 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD$"); + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +void * +calloc(size_t nelem, size_t nbytes) +{ + void *p; + size_t n; + + if (__builtin_mul_overflow_p(nelem, nbytes, (size_t)0)) { + errno = ENOMEM; + return NULL; + } + n = nelem * nbytes; + p = malloc(n); + if (p != NULL) + memset(p, 0, n); + return p; +} diff --git a/lib/libbsdmalloc/posix_memalign.c b/lib/libbsdmalloc/posix_memalign.c new file mode 100644 index 000000000000..f04f8417d445 --- /dev/null +++ b/lib/libbsdmalloc/posix_memalign.c @@ -0,0 +1,56 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2023 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD$"); + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +int +posix_memalign(void **memptr, size_t alignment, size_t size) +{ + char *p; + size_t alignwords = alignment/sizeof(void *); + + if (alignwords == 0 || (alignwords & (alignwords - 1)) != 0) + return EINVAL; + if (size > SIZE_MAX - (alignment - 1)) + return ENOMEM; + + p = malloc(size + alignment - 1); + if (p == NULL) + return ENOMEM; + if ((uintptr_t)p % alignment) + p += alignment - ((uintptr_t)p % alignment); + *memptr = p; + return 0; +}