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

Gabriel Marcano gabemarcano@yahoo.com
Sat May 29 09:10:25 GMT 2021


> To be clear, the error I'm seeing with the example is this:
>
>  /usr/libexec/gcc/arm-3ds-none-eabi/ld: warning: cannot find entry symbol _start; defaulting to 0000000000008018
>  /usr/libexec/gcc/arm-3ds-none-eabi/ld: /tmp/ccPp7lyA.ltrans0.ltrans.o: in function `f':
>  /home/gabriel/tmp/t1.c:3: undefined reference to `malloc'
>  collect2: error: ld returned 1 exit status
>
>
> I would start by adding -Wl,-y,malloc to last gcc command line (the link step
> with '-o main') to see how linker sees references to malloc. You can do that
> both with and without -flto to compare successful/failing scenarios.
>
> If you have both BFD and Gold linker, try both (-fuse-ld=gold or =bfd).
>
> You can also pass -Wl,-v to see the linker command line and compare it with
> non-LTO compilation (or even native compilation).
>
> Does it work if you pass -fno-builtin-malloc to compilation of t.c?
>
> It looks like without the option, GCC LTO plugin does not see malloc as an
> undefined symbol in t.o, the linker does not unpack malloc from libc, and when
> LTO plugin passes a new object file that references malloc, it's too late.
>
> I believe linkers had some hacks to help this case (rescanning libc for new
> references from LTO object files), but I'm not exactly sure, it's been a while
> since I looked at a related area.
>
> Alexander

So, on a native x86_64 build -Wm,-y,malloc returns:
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../x86_64-pc-linux-gnu/bin/ld:
  /lib64/libc.so.6: definition of malloc
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../x86_64-pc-linux-gnu/bin/ld:
  /tmp/ccJJ05Rd.ltrans0.ltrans.o: reference to malloc

With the arm cross compiler:
/usr/libexec/gcc/arm-none-eabi/ld: /tmp/ccupVhtJ.ltrans0.ltrans.o: reference to malloc
/usr/libexec/gcc/arm-none-eabi/ld: /tmp/ccupVhtJ.ltrans0.ltrans.o: in function `f':
/home/gabriel/tmp/t1.c:3: undefined reference to `malloc'
collect2: error: ld returned 1 exit status

So it's just not finding the symbol?

With gold it looks like it's having problems loading the LTO plugin:
/tmp/ccUp7UC6.ltrans0.ltrans.o: reference to malloc
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/libg.a(lib_a-malloc.o):
  plugin needed to handle lto object
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/libg.a(lib_a-malloc.o):
  plugin needed to handle lto object
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/libc.a(lib_a-malloc.o):
  plugin needed to handle lto object
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/libc.a(lib_a-malloc.o):
  plugin needed to handle lto object
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/crt0.o(.text+0x11c):
  error: undefined reference to '__bss_start__'
/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/crt0.o(.text+0x120):
  error: undefined reference to '__bss_end__'
t1.c:3: error: undefined reference to 'malloc'
collect2: error: ld returned 1 exit status

But I see the plugin specified in the ld.gold invocation with -Wl,-v as
-plugin /usr/libexec/gcc/arm-none-eabi/11.1.0/liblto_plugin.so

There are also some additional plugin-opts being passed on.

The gold linker works fine on the native x86_64 build.

I'm not seeing anything glaringly different between the ld invocation for the
native build and arm. I'll try to format the arm ld output:
/usr/libexec/gcc/arm-none-eabi/ld -plugin
 /usr/libexec/gcc/arm-none-eabi/11.1.0/liblto_plugin.so
 -plugin-opt=/usr/libexec/gcc/arm-none-eabi/11.1.0/lto-wrapper
 -plugin-opt=-fresolution=/tmp/ccxcs2NR.res -plugin-opt=-pass-through=-lgcc
 -plugin-opt=-pass-through=-lg -plugin-opt=-pass-through=-lc
 --sysroot=/usr/arm-none-eabi -X -o main
 /usr/lib/gcc/arm-none-eabi/11.1.0/crti.o
 /usr/lib/gcc/arm-none-eabi/11.1.0/crtbegin.o
 /usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib/crt0.o
 -L/usr/lib/gcc/arm-none-eabi/11.1.0
 -L/usr/lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/lib
 -L/usr/arm-none-eabi/lib -L/usr/arm-none-eabi/usr/lib -y malloc -v main.o t1.o
 --start-group -lgcc -lg -lc --end-group
 /usr/lib/gcc/arm-none-eabi/11.1.0/crtend.o
 /usr/lib/gcc/arm-none-eabi/11.1.0/crtn.o

And... yeah, with -fno-builtin-malloc, it appears to build!

So, it looks like a bug in the linker? Although, I'm somewhat surprised gold is
also having issues.

Gabe Marcano


More information about the Gcc-help mailing list