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

Gabriel Marcano
Sat May 29 06:51:28 GMT 2021

 > This is a continuation of trying to build some software for the Nintendo 3DS,
> which is an ARM platform. After applying the patches in
>, I no longer get an ICE,
> but now I'm getting a lot of undefined references to libc symbols, like free
> and snprintf and malloc. Thing is, if I build this application without LTO, it
> builds fine, so there appears to be something strange going on in the LTO
> process that makes it so ld can't figure out how to link libc with everything
> else.
> Some things I've tried and done:
> - I've confirmed that the libc being linked has those symbols by checking the
>   output of nm against that libc.a.
> - I spent a few hours trying to step through ld to figure out how it
>   determines when a symbol is undefined, but I didn't make much headway. I did
>   find a place (_bfd_generic_link_add_one_symbol) where it appears to be
>   setting some data structures to undefined, but I can't figure out how it's
>   making that decision (it's some sort of table???).
> - I replaced the libc.a (and honestly all of lib/ for the cross-compiler, I
>   made a backup to restore it after the test) with the one from devKitARM
>   (from the devKitPro group, they provide GCC toolchains for a bunch of
>   Nintendo platforms), and I was still getting undefined references, so it
>   doesn't seem to be a problem of how I'm building my own newlib library (or both
>   of these libraries are built wrong).
> - I tried to reproduce the problem with a simpler example, but I wasn't able
>   to (I probably just don't know what I'm doing).
> I'm more than willing to help collect information to track down the source of
> the problem, but I'm going to need some pointers in the right direction. The
> application in question has a somewhat convoluted build process (what is it
> with embedded development communities and super fancy Makefiles?) and it also
> requires specific patches against newlib (adds a new system library), so it's a
> little hard for me to have someone else try to build this and reproduce it (the
> "official" 3DS GCC toolchain suffers from the LTO ICE bug, so I can't check if
> their libc behaves properly, and their toolchain is even more annoying to
> build).
> In summary, any tips on what I should be looking for to track down the cause?
> Let me know if you need more information from me also.
> Thanks,
> Gabe Marcano

I was able to reproduce the problem with a small example:

 #include <string.h>

 int f();

 int main() {
         return f();

 void _exit(int v)

 #include <stdlib.h>

 int f() { return (int)malloc(0x0);}

With commands:
arm-none-eabi-gcc -O -flto -g -c -o main.o main.c
arm-none-eabi-gcc -O0 -flto -g -c -o t1.o t1.c
arm-none-eabi-gcc -O -flto -g main.o t1.o -o main

I was able to reproduce this with my non-3ds arm cross compiler that doesn't
have the patch, so it seems
unrelated to that issue. I had to pass -O0 to the t1.c compilation so it
wouldn't just optimize the malloc out.

Let me know if you need any more information, or if you think this is a
binutils bug and I should go and report an issue there.


Gabe Marcano

More information about the Gcc-help mailing list