[PATCH u-boot 12/39] string: make memcpy() and memset() visible to fix LTO linking errors
Pali Rohár
pali at kernel.org
Mon Mar 8 11:23:34 CET 2021
On Monday 08 March 2021 11:19:33 Marek Behun wrote:
> On Mon, 8 Mar 2021 15:56:01 +0800
> Bin Meng <bmeng.cn at gmail.com> wrote:
>
> > Hi Marek,
> >
> > On Sun, Mar 7, 2021 at 12:26 PM Marek Behún <marek.behun at nic.cz> wrote:
> > >
> > > 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.
> > > memset() can be generated sometimes as well.
> > >
> > > This then results in the following linking error:
> > > .../lz4.c:93: undefined reference to `memcpy'
> > > .../uuid.c:206: more undefined references to `memcpy' follow
> > >
> > > Make memcpy() and memset() visible by using the __used macro to avoid
> > > this error.
> >
> > This sounds like a GCC bug of using -fno-builtin and -flto. Could you
> > file a bugzilla to GCC people to get some comments?
>
> This is not LTO related. -fno-builtin still generates memcpy() call for
> the following code:
>
> typedef struct {
> int a[40];
> char b[50];
> int c[60];
> } a;
>
> void cp(a *d, const a *s) {
> *d = *s;
> }
>
> when compiled with
> armv7a-hardfloat-linux-gnueabi-gcc -O2 -fno-builtin -ffreestanding \
> -nostdlib -S
>
> it produces code
>
> push {r4, lr}
> mov ip, #4096
> sub ip, sp, ip
> str r0, [ip, #4088]
> mov r2, #452
> bl memcpy
> pop {r4, pc}
> .size cp, .-cp
>
> I don't think this is a bug. Or if it is, it is a wontfix. Just
> implement memcpy into your code, so that gcc does not have to emit
> shitstorms of instructions because of assignment operator :)
>
> Marek
This is not a bug but rather a feature of gcc. Documentation for
-nodefaultlibs and -nostdlib contains:
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.
More information about the U-Boot
mailing list