ARM cross-compiler with newlib, LTO, undefined reference to libc symbols

Alexander Monakov amonakov@ispras.ru
Wed Jun 2 08:57:59 GMT 2021


> Most likely, I'm leveraging Gentoo's crossdev functionality to build
> GCC/binutils/newlib, and I do have a global -flto flag enabled on my system,
> which I selectively disable for specific packages whenever I find problems. Can
> newlib not be built with -flto? Does it need something like -ffat-lto-objects?
> And why does it matter if it was built with lto (or is this behavior just due
> to the special treatment of libc's in general when linking/building)?

It matters because the compiler recognizes several libc functions by name
(including 'malloc'); recognizing such so-called "builtins" is necessary
to optimize their uses. Unfortunately, builtins are different from common
functions in LTO bytecode, and sometimes behave in unexpected ways. You
can find examples searching GCC Bugzilla for stuff like "LTO built-in".

In your case the reference to built-in malloc is not visible to the linker when
it invokes the plugin while scanning input files, so it does not unpack malloc.o
from libc.a. This is a simple case of a more general problem where a compiler
creates new references to built-in functions after optimizations (e.g.
transforming 'printf("Hello\n")' to 'puts("Hello")'). Somehow it happens to work
when libc is not slim-LTO (I guess it is rescanned), but rescanning for LTO
code-generation is not implemented, as far as I know.

More importantly, building libc with LTO is sufficiently unusual, so you should
have prominently mentioned that in early emails; nobody expects that by default.
Also, checking if the minimal example works with non-LTO Newlib would be
appropriate.

LTO'd libc is considerably more tricky than usual LTO scenarios, so expect
surprises and be prepared.

Alexander


More information about the Gcc-help mailing list