I have a toolcahin working quite well: gcc-4.1.2 binutils-2.17, generic
arm softfloat supporting EABI. This works with kernel and userspace
well. Only on u-boot it fails at the final stage:
UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/scb9328/libscb9328.a cpu/arm920t/libarm920t.a cpu/arm920t/imx/libimx.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/sk98lin/libsk98lin.a post/libpost.a post/cpu/libcpu.a common/libcommon.a |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /usr/src/u-boot/1.2.0 && arm-linux-ld -Bstatic -T /usr/src/u-boot/1.2.0/board/scb9328/u-boot.lds -Ttext 0x08f00000 $UNDEF_SYM cpu/arm920t/start.o \
--start-group lib_generic/libgeneric.a board/scb9328/libscb9328.a cpu/arm920t/libarm920t.a cpu/arm920t/imx/libimx.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/sk98lin/libsk98lin.a post/libpost.a post/cpu/libcpu.a common/libcommon.a --end-group -L /usr/local/arm/gcc-4.1.2/lib/gcc/arm-linux-uclibcgnueabi/4.1.2 -lgcc \
-Map u-boot.map -o u-boot
/usr/local/arm/gcc-4.1.2/lib/gcc/arm-linux-uclibcgnueabi/4.1.2/libgcc.a(_dvmd_lnx.o): In function `__div0':
/usr/src/br/buildroot-20070206/toolchain_build_arm_nofpu/gcc-4.1.2-20070128/gcc/config/arm/lib1funcs.asm:1000: undefined reference to `raise'
make: *** [u-boot] Error 1
Well, compiling u-boot works fine with another arch (pxa xscale), only my arm9
i.MX arch triggers a bug here. Does somebody have an advise or tip for
me how to fix this?
I digged around and added an (empty) raise() function to my u-boot, which compiles fine.
Kind Regards, Konsti
The __div0 function is called by the division routines when an attempt to divide by zero is detected. On a linux system, it is expected that this will cause SIGFPE to be raise(3)d, so the default implementation of this call does precisely this.
There's two ways you can avoid this problem when trying to build uboot (which isn't a linux application).
1) Provide your own implementation of __div0 that does the right thing for your system.
2) Use a different configuration of the compiler.
Either way, this isn't a bug in the compiler.
This does seem to be real, so please reopen it. The problem is that the final command line to the linker looks like:
... $(objs) -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed $(endfiles)
Assuming the main program itself does not do any division or call raise, the first -lgcc does not pull in __div0, and the -lc does not pull in raise. However, if any function from libc which does get pulled in performs division, then a reference to __div0 is generated, and the second -lgcc pulls in __div0, which contains a reference to raise. This reference is never resolved.
It seems the intent is that link_gcc_c_sequence uses --start-group and --end-group to avoid this problem when -static is used. However, this does not cover the case where no libc.so exists at all, and libc.a is all that's available. I wonder why the --start-group logic is only used for static linking and not unconditionally, since it should be a no-op for shared libraries anyway.
FYI, I have received new reports of this bug from musl users, one who wanted to have libc.so be used but who installed it in the wrong location causing libc.a to get used instead, but the rest were users doing purely static-linked systems with no shared libraries at all.
Please re-open this bug. I'm affected by it with GCC 4.8.3, when I build static ARMv7 binaries against musl 1.0.4.
Did this bug ever get resolved satisfactorily?
For now, the only solution, as suggested by Rich Felker, is to have for example a dummy division instruction somewhere in the code that's being compiled.
I'm using gcc 4.8.5 with musl-libc 1.1.12.