I am building a bare-metal code for ARM926 and I need the generated output to be as tight as possible.
In my best effort, though, I still receive this error:
yocto/poky/build-idprint/tmp/work/idprint-poky-linux-gnueabi/idpr/1.0-r0/
recipe-sysroot/usr/lib/libc.a(raise.o):
(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1'
In my Makefile I put this linker flags:
LD_OPT = -Wl,-gc-sections -Wl,-build-id=none -flto
LD_LINK = -static -nostartfiles -nostdlib -Wl,--start-group,-lgcc,-lc,--end-group
LDFLAGS = -T $(BINARY).ld -Xlinker -Map=$(BINARY).map $(LD_OPT)
And the link command is
$(LINK.cc) $(OBJS) $(LD_LINK) src/lib_dummies.o -o $(BINARY).elf
Finally I have a custom linker script as simple as possible:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(fiq_main)
SECTIONS
{
. = 0x0;
.text : {
KEEP(*(.textEntry));
*(.text*)
*(.text .gnu.linkonce.t.*)
}
. = ALIGN(1024);
_bss_start = .;
.data : { *(.data) }
.bss : { *(.bss) }
_bss_end = .;
}
I added a custom dummy __aeabi_unwind_cpp_pr1 to my code (inspired from libgcc sources) but it didn't help.
I have read about quite a few pages around the web but none explained me why is libgcc trying to link a C++ function to my C-only project.
Okay, $(LINK.cc) is evaluated to arm-poky-linux-gnueabi-g++ but I still se no sense trying to link a C++ function to libgcc. It would make sense if I was linking libstdc++. Moreover, $(LD) fails for othre reasons (can't find -lgcc).
No optimization flags I could find helped me with this either.
Look, it is very important that my code doesn't add any uneeded stuff.
Everything started only because I need to use integer division (unresolved __aeabi_idiv...)
I omitted the optimization flags for simplicity but, if needed, please tell me and I'll add them.
Any help will be greatly appreciated. Thanks.
In my case, I found this issue only exists on arm32 but not aarch64. And it happens even when built with pure C code (so apparently no C++ exceptions). The linker complains about missing __aeabi_unwind_cpp_prX, but actually, they are never invoked by disassembling the binaries. Probably there's a bug in the linker? Anyway, the solution is to define their stub symbols and they will be orphan symbols in the final binary.
By the way, adding -fno-exceptions option to the compiler doesn't help with this problem.
Well,
after a very long battle, I ended with a relatively simple solution.
In my Makefile, I changed the LD_LINK line to:
LD_LINK = -static -nostartfiles -nostdlib -lgcc
(removed -Wl,--start-group,-lgcc,-lc,--end-group)
This led me to an undefined reference to raise.
Then I added this few lines to an assembly source file:
.global raise
raise:
b raise
Note:
I tried creating a raise function in C but, due to name mangling and despite any tricks I've tried, the linker could never find it.
I'd be really happy if someone could show me how to do that in plain C.
Bonus:
My final binary is way smaller than what I was getting before, and it is just what I needed!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With