Skip to content
Snippets Groups Projects
Commit 46c3e292 authored by Marek Behún's avatar Marek Behún Committed by Tom Rini
Browse files

string: make memcpy(), memset(), memcmp() and memmove() visible for LTO


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: default avatarMarek Behún <marek.behun@nic.cz>
Reviewed-by: Simon Glass's avatarSimon Glass <sjg@chromium.org>
parent 6f243e25
No related branches found
No related tags found
No related merge requests found
......@@ -16,6 +16,7 @@
*/
#include <config.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/ctype.h>
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment