[PATCH u-boot 12/39] string: make memcpy() and memset() visible to fix LTO linking errors

Bin Meng bmeng.cn at gmail.com
Mon Mar 8 11:40:58 CET 2021


On Mon, Mar 8, 2021 at 6:23 PM Pali Rohár <pali at kernel.org> wrote:
>
> 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.

Yeah I know this. My question was why when LTO is enabled, we have to
explicitly mark these APIs as __used? I should have asked clearly, is
this a bug of LTO?

Regards,
Bin


More information about the U-Boot mailing list