From bdf60512deb8899f85a523d7931558f847447d0b Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 10 Nov 2016 16:32:27 -0800 Subject: [PATCH] pie: provide memcpy/memcmp/memset for noglibc case 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_*] https://travis-ci.org/kolyshkin/criu/builds/174634847 Idea-by: Andrei Vagin Signed-off-by: Kir Kolyshkin Reviewed-by: Dmitry Safonov Signed-off-by: Pavel Emelyanov --- 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 1448a3200..ff91968a0 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__ */