From 46c3e29219e445de150e60e371cfec75f6fee524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 20 May 2021 13:23:55 +0200 Subject: [PATCH] string: make memcpy(), memset(), memcmp() and memmove() visible for LTO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that sometimes (happening on ARM64, for example with turris_mox_defconfig) GCC, when linking with LTO, changes the symbol names of some functions, for example lib/string.c's memcpy() function to memcpy.isra.0. This is a problem however when GCC for a code such as this: struct some_struct *info = get_some_struct(); struct some struct tmpinfo; tmpinfo = *info; emits a call to memcpy() by builtin behaviour, to copy *info to tmpinfo. This then results in the following linking error: .../lz4.c:93: undefined reference to `memcpy' .../uuid.c:206: more undefined references to `memcpy' follow GCC's documentation says this about -nodefaultlibs option: The compiler may generate calls to "memcmp", "memset", "memcpy" and "memmove". These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified. Make these functions visible by using the __used macro to avoid this error. Signed-off-by: Marek BehĂșn Reviewed-by: Simon Glass --- lib/string.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/string.c b/lib/string.c index a0cff8fe88..ba176fb08f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -513,7 +514,7 @@ char *strswab(const char *s) * * Do not use memset() to access IO space, use memset_io() instead. */ -void * memset(void * s,int c,size_t count) +__used void * memset(void * s,int c,size_t count) { unsigned long *sl = (unsigned long *) s; char *s8; @@ -552,7 +553,7 @@ void * memset(void * s,int c,size_t count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void *dest, const void *src, size_t count) +__used void * memcpy(void *dest, const void *src, size_t count) { unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; char *d8, *s8; @@ -586,7 +587,7 @@ void * memcpy(void *dest, const void *src, size_t count) * * Unlike memcpy(), memmove() copes with overlapping areas. */ -void * memmove(void * dest,const void *src,size_t count) +__used void * memmove(void * dest,const void *src,size_t count) { char *tmp, *s; @@ -622,7 +623,7 @@ void * memmove(void * dest,const void *src,size_t count) * @ct: Another area of memory * @count: The size of the area. */ -int memcmp(const void * cs,const void * ct,size_t count) +__used int memcmp(const void * cs,const void * ct,size_t count) { const unsigned char *su1, *su2; int res = 0;