[LEDE-DEV] undefined reference to `memmove' caused by __builtin_memmove()

Hauke Mehrtens hauke at hauke-m.de
Tue Feb 28 10:10:27 PST 2017


Hi Felix,

On 2017-02-28 07:11, Felix Fietkau wrote:
> On 2017-02-20 15:10, Mehrtens, Hauke wrote:
>> When I compile MIPS malta with the LEDE patches on kernel 4.9 I get 
>> this error in the kernel build:
>> 
>>   CC      arch/mips/boot/compressed/decompress.o
>>   OBJCOPY arch/mips/boot/compressed/vmlinux.bin
>>   XZKERN  arch/mips/boot/compressed/vmlinux.bin.z
>>   OBJCOPY arch/mips/boot/compressed/piggy.o
>>   LD      vmlinuz
>> arch/mips/boot/compressed/decompress.o: In function `lzma2_lzma':
>> /tmp2/mehrtens/linux/arch/mips/boot/compressed/../../../../lib/xz/xz_dec_lzma2.c:884: 
>> undefined reference to `memmove'
>> make[1]: *** [vmlinuz] Error 1
>> make: *** [vmlinuz] Error 2
>> 
>> This is caused by this option selected in the MIPS Malta target: 
>> SYS_SUPPORTS_ZBOOT
>> 
>> This is caused by this patch from LEDE:
>> https://git.lede-project.org/?p=source.git;a=blob;f=target/linux/generic/patches-4.9/306-mips_mem_functions_performance.patch
>> This was initially committed here:
>> https://git.lede-project.org/?p=source.git;a=commitdiff;h=07e59c7bc7f375f792ec9734be42fe4fa391a8bb
> I've pushed a fix to my staging tree, please test.

I tested it and this commit fixes my problem:
https://git.lede-project.org/?p=lede/nbd/staging.git;a=commitdiff;h=1cb69f5542b1a17b46d2c0849a35ece52ef20fb5

Thank you for looking into this.

>> When I remove the "#define memmove ..." from the string.h it works
>> for me, I also checked the GCC documentation and it does not list
>> __builtin_memmove() as an official interface here:
>> https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
> There's nothing wrong with __builtin_memmove or the function references
> that it generates. The problem lies within decompress_unxz.c:
> 
> #ifndef memmove
> /* Not static to avoid a conflict with the prototype in the Linux
> headers. */
> void *memmove(void *dest, const void *src, size_t size)
> {
> ...
> }
> #endif
> 
> Since the patch adds a #define to string.h, the the custom memmove
> function no longer gets emitted, and gcc generates references to it
> through __builtin_memmove

I haven't seen this #ifndef memmove in the code, that explains the 
behavior.

>> I would like to remove the optimization for memmove as it uses an 
>> unofficial GCC API.
> It is used in quite a few places, and I it's safe to rely on it.
> 
>> The problem is that I do not fully understand this patch and it is not 
>> good documented.
>> Why are the __buildin_ functions only called when the length is *not* 
>> a __builtin_constant_p() or smaller than 64 bytes?
> The length >= 64 check (to force gcc not to inline larger copies) can
> only be guaranteed to run at compile time if the pointer is constant.
> If it's not constant, the decision on whether to inline it or not is
> left to gcc.

Would be nice to have this in the patch comment, if you do not add it I 
will do it later.

>> Doesn't the compiler automatically replaces a call to memcpy() and 
>> similar functions with the build in version when he things it is good 
>> to do so?
> When I first added the patch, there were some issues with that. I don't
> know if there are any corner cases with current gcc, but the code 
> should
> be safe the way it is.
> 
> - Felix




More information about the Lede-dev mailing list