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