[CRIU] [PATCH 2/3] pie: provide memcpy/memcmp/memset for noglibc case

Kir Kolyshkin kir at openvz.org
Thu Nov 10 16:32:27 PST 2016


Use alias function attribute to provide memcpy(), memcmp()
and memset() in case we're not linking with libc. This is
needed as compiler can generate calls to those functions
(clang actually does that).

[v2: add comment, move aliases to under HAS_BUILTIN_*]

Idea-by: Andrei Vagin <avagin at openvz.org>
Signed-off-by: Kir Kolyshkin <kir at openvz.org>
Reviewed-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/include/asm-generic/string.h | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/criu/include/asm-generic/string.h b/criu/include/asm-generic/string.h
index 1448a32..ff91968 100644
--- a/criu/include/asm-generic/string.h
+++ b/criu/include/asm-generic/string.h
@@ -3,8 +3,16 @@
 
 #include "common/compiler.h"
 
+/* C compiler may generate calls to memcmp, memset, memcpy and memmove,
+ * so it relies on those to be available during linking.
+ * In case we are not linking our code against glibc, we set CR_NOGLIBC
+ * and have to provide our own implementations of mem*() functions.
+ *
+ * For now, not having memmove() seems OK for both gcc and clang.
+ */
+
 #ifndef HAS_BUILTIN_MEMCPY
-static always_inline void *builtin_memcpy(void *to, const void *from, size_t n)
+static __maybe_unused void *builtin_memcpy(void *to, const void *from, size_t n)
 {
 	size_t i;
 	unsigned char *cto = to;
@@ -16,10 +24,14 @@ static always_inline void *builtin_memcpy(void *to, const void *from, size_t n)
 
 	return to;
 }
+#ifdef CR_NOGLIBC
+void *memcpy(void *to, const void *from, size_t n)	\
+	     __attribute__ ((weak, alias ("builtin_memcpy")));
+#endif
 #endif
 
 #ifndef HAS_BUILTIN_MEMCMP
-static always_inline int builtin_memcmp(const void *cs, const void *ct, size_t count)
+static __maybe_unused int builtin_memcmp(const void *cs, const void *ct, size_t count)
 {
 	const unsigned char *su1, *su2;
 	int res = 0;
@@ -29,6 +41,10 @@ static always_inline int builtin_memcmp(const void *cs, const void *ct, size_t c
 			break;
 	return res;
 }
+#ifdef CR_NOGLIBC
+int memcmp(const void *cs, const void *ct, size_t count)	\
+	     __attribute__ ((weak, alias ("builtin_memcmp")));
+#endif
 #endif
 
 #ifndef HAS_BUILTIN_STRNCMP
@@ -47,7 +63,7 @@ static always_inline int builtin_strncmp(const char *cs, const char *ct, size_t
 #endif
 
 #ifndef HAS_BUILTIN_MEMSET
-static always_inline void *builtin_memset(void *s, const int c, size_t count)
+static __maybe_unused void *builtin_memset(void *s, const int c, size_t count)
 {
 	char *dest = s;
 	size_t i = 0;
@@ -57,6 +73,10 @@ static always_inline void *builtin_memset(void *s, const int c, size_t count)
 
 	return s;
 }
+#ifdef CR_NOGLIBC
+void *memset(void *s, const int c, size_t count)	\
+	     __attribute__ ((weak, alias ("builtin_memset")));
+#endif
 #endif
 
 #endif /* __CR_ASM_GENERIC_STRING_H__ */
-- 
2.7.4



More information about the CRIU mailing list