Search code examples
embedded-linuxarm64u-boot

"undefined reference to memcpy" during u-boot-spl build. How can I use the archtecture assisted memcpy?


When I build u-boot-spl for our board, I see these link errors. (u-boot version v2021.10, commit 50c84208ad, Tom Rini, Oct 4 2021)

u-boot/common/spl/spl.c:669: undefined reference to `memcpy'
u-boot/common/spl/spl.c:684: undefined reference to `mem_malloc_init'
...

But arch/arm/Kconfig says (my board is ARM64)

config USE_ARCH_MEMCPY
    bool "Use an assembly optimized implementation of memcpy"
    default y if !ARM64
    depends on !ARM64 || (ARM64 && (GCC_VERSION >= 90400))
    help
      Enable the generation of an optimized version of memcpy.
      Such an implementation may be faster under some conditions
      but may increase the binary size.

So if ARM64 and GCC version is later then 9.04, USE_ARCH_MEMCPY should be turned on.
And in my case, I can check in include/config/auto.conf the two condition is true.

CONFIG_ARM64=y
CONFIG_GCC_VERSION=100201

But USE_ARCH_MEMCPY doesn't appare in include/cofig/auto.conf (is this normal?).
Anyway, I think this CONFIG_USE_ARCH_MEMCPY should be y. Why does it give me this memcpy undefined error?

I checked in lib/Makefile, I see

obj-y += string.o

which is unconditional and this string.c contains memcpy function. But of course this function is enclosed by #ifndef __HAVE_ARCH_MEMCPY, so it's not what I want anyway.

Is there any option I should turn on to make use of this hardware assisted memcpy?
ADD : I tried adding CONFIG_LTO but it didn't work.


Solution

  • I searched the Kconfig files and found there are CONFIG_USE_ARCH_MEMCPY, CONFIG_SPL_USE_ARCH_MEMCPY, CONFIG_USE_ARCH_MEMSET, CONFIG_SPL_USE_ARCH_MEMSET, etc. So I made those configs to be selected for my board. And those errors are gone (with CONFIG_LTO-link time optimization is set so that stdlib is not used). I still have some more 'undefined' errors for strncmp, timer_init, puts, hang, mem_malloc_init etc. I'm not sure I can fix the errors using similar methods or this approach is the correct, advisable method. And if I prefer software routine, what should I do?
    Waiting for a better answer.
    ADD (2021. 11. 29) : Ovidiu Panait from u-boot email list told me I can remove some 'undefined symbol' error by setting CONFIG_SPL_LIBGENERIC_SUPPORT and CONFIG_SPL_LIBCOMMON_SUPPORT to 'y'. After setting this I found those memcpy, memset link errors are also gone without setting USE_ARCH_xxx or USE_SPL_ARCH_xxx configs.