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

Gabriel Marcano
Wed Jun 2 09:30:09 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

Sorry, I've been building most of my regular system with LTO for a while now,
and it just had not crossed my mind as a possible source of problems for
newlib. As I don't normally work with deeper parts of GCC and binutils, I'm not
familiar with how they all interconnect (I had no idea builtins were a thing,
for example).

Out of curiosity, digging into my glibc, Gentoo's build configuration files do
make sure to strip *FLAGS of anything not whitelisted, of which -flto is not.
Oddly enough, I don't know why newlib doesn't get the same treatment, but this
is a Gentoo detail, maybe I'll raise a bug report against our scripts to prevent
others from meeting my fate unwittingly.

And yes, if I do not build newlib with -flto, I no longer get strange linking
errors, which makes sense if the issue is as you describe.

I don't know much about compiler internals, else I'd try to figure out what's
going on and to see if there's any way I can help. As I don't know enough, I'm
just going to disable LTO for newlib and move on.

Thanks for the help!


More information about the Gcc-help mailing list