Hi

here a little proposal to use this specific clang builtin, only placed
in few places but over time can be expanded cautiously.

Kindest regards.

Thanks.
From 9d7b6448a2407451c3115b701c51f97ab2bf6a59 Mon Sep 17 00:00:00 2001
From: David Carlier <devne...@gmail.com>
Date: Sat, 18 Jun 2022 12:41:11 +0100
Subject: [PATCH] MINOR: compiler __builtin_memcpy_inline usage introduction.

Optimised version of the existing __builtin_memcpy builtin, differences
reside by the fact it works only with constant time sizes and does
 generate extra calls.
At the moment, is clang exclusive even tough GCC does not seem to
 want to implement it, the comments try not to reflect this current
state.
Usage can be expanded, used purposely only in few places for starter.
---
 include/haproxy/compiler.h | 12 ++++++++++++
 src/haproxy.c              |  4 ++--
 src/log.c                  |  2 +-
 src/proxy.c                |  2 +-
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h
index 66b5f5835..dca9f6aef 100644
--- a/include/haproxy/compiler.h
+++ b/include/haproxy/compiler.h
@@ -192,6 +192,18 @@
 #endif
 #endif
 
+/*
+ * This builtin works only with compile time lengths unlike __builtin_memcpy.
+ * Also guarantees no external call is generated.
+ * We could `replicate` the aforementioned constraint with a
+ * _Static_assert/__builtin_constant_p theoretically, but that might be
+ * too much trouble to make it happens (C11 min)
+ * so here we trust the proper usage with other compilers (and the CI infrastructure).
+ */
+#if !defined(__clang__) || __clang_major__ < 11
+#define __builtin_memcpy_inline(x, y, s) memcpy(x, y, s)
+#endif
+
 /* Linux-like "container_of". It returns a pointer to the structure of type
  * <type> which has its member <name> stored at address <ptr>.
  */
diff --git a/src/haproxy.c b/src/haproxy.c
index 32eb4bdc6..1464d29ee 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1265,11 +1265,11 @@ static void ha_random_boot(char *const *argv)
 
 	/* stack address (benefit form operating system's ASLR) */
 	l = (unsigned long)&m;
-	memcpy(m, &l, sizeof(l)); m += sizeof(l);
+	__builtin_memcpy_inline(m, &l, sizeof(l)); m += sizeof(l);
 
 	/* argv address (benefit form operating system's ASLR) */
 	l = (unsigned long)&argv;
-	memcpy(m, &l, sizeof(l)); m += sizeof(l);
+	__builtin_memcpy_inline(m, &l, sizeof(l)); m += sizeof(l);
 
 	/* use tv_usec again after all the operations above */
 	gettimeofday(&tv, NULL);
diff --git a/src/log.c b/src/log.c
index 304e3cb68..a631b1e46 100644
--- a/src/log.c
+++ b/src/log.c
@@ -808,7 +808,7 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, const char *file
 			}
 
 			node = malloc(sizeof(*node));
-			memcpy(node, logsrv, sizeof(struct logsrv));
+			__builtin_memcpy_inline(node, logsrv, sizeof(struct logsrv));
 			node->ref = logsrv;
 			LIST_INIT(&node->list);
 			LIST_APPEND(logsrvs, &node->list);
diff --git a/src/proxy.c b/src/proxy.c
index c10a8cf83..7d02f8c19 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1818,7 +1818,7 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
 			memprintf(errmsg, "proxy '%s': out of memory", curproxy->id);
 			return 1;
 		}
-		memcpy(node, tmplogsrv, sizeof(struct logsrv));
+		__builtin_memcpy_inline(node, tmplogsrv, sizeof(struct logsrv));
 		node->ref = tmplogsrv->ref;
 		LIST_INIT(&node->list);
 		LIST_APPEND(&curproxy->logsrvs, &node->list);
-- 
2.34.1

Reply via email to