tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Trivial program size inflation
> Date: Mon, 3 Jul 2023 07:45:27 +0000 (UTC)
> From: RVP <rvp%SDF.ORG@localhost>
>
> 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 <riastradh%NetBSD.org@localhost>
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;
+}
Home |
Main Index |
Thread Index |
Old Index