
On Mon, 8 Mar 2021 11:55:32 +0100 Pali Rohár pali@kernel.org wrote:
On Monday 08 March 2021 18:40:58 Bin Meng wrote:
On Mon, Mar 8, 2021 at 6:23 PM Pali Rohár pali@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@gmail.com wrote:
Hi Marek,
On Sun, Mar 7, 2021 at 12:26 PM Marek Behún marek.behun@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?
I see... What is the _exact_ command line arguments called when this linking issue happen? I know that when gcc's LTO is enabled it depends on other of objects and libraries which are linking. And I'm not sure if all -whole-archive option can make order of archives independent when dealing with these builtin function references. At least I cannot find exact gcc documentation about linking order.
Soo, it seems that the compiler generates a copy of memcpy called memcpy.isra.0 which is a version with -fipa-sra optimization.
Then it thinks the original memcpy is not used, since it replaces all calls to memcpy.isra.0, but the original memcpy is still being called for assignment operator. So maybe it is a bug of gcc, and gcc should use memcpy.isra.0 for the assignment operator as well...