When objects have been built with gcc's "-fasynchronous-unwind-tables" option, linking them can produce a segfault in ld. This occurred when trying to build a recent Linux kernel with frame unwinding information. I've narrowed it down to a simpler test case, which uses the kernel's link script and a couple of test C files. Enabling "-fasynchronous-unwind-tables" when building the objects causes a subsequent link to crash ld, while disabling that option causes ld to continue successfully (giving the user an error and then exiting). ARM EABI toolchain: binutils 2.17, gcc 4.1.1, built with CrossTool 0.42 Also tried CodeSourcery's 2006q1-6 toolchain (uses binutils 2.16.91), which experiences the same problem Will follow up with test files
Created attachment 1296 [details] Tarball of test files 1. Install arm[-none]-linux-gnueabi toolchain 2. Extract tarball contents 3. Set CROSS_COMPILE appropriately 4. Type 'make' to build and attempt to link the objects You should see a segfault at the link stage. Note that changing the CFLAGS to omit "-fasynchronous-unwind-tables" will stop the segfault from occurring.
Additional info. provided by Kevin Kilman at MontaVista: [Quote] FYI... I've seen the same thing using a MontaVista gcc 4.1.2, ld 2.17. However, after a binutils update to 2.17.50 20060808, it no longer segfaults, but fails to link with the following error: LD init/built-in.o LD .tmp_vmlinux1 /opt/fdb060906_0601451/montavista/foundation/devkit/arm/xscale_be/bin/xscale_be\-ld: .tmp_vmlinux1: sh_link of section `.ARM.exidx.exit.text' points to discard\ed section `.exit.text' of `arch/arm/kernel/built-in.o' /opt/fdb060906_0601451/montavista/foundation/devkit/arm/xscale_be/bin/xscale_be\-ld: final link failed: Bad value I also noted that gcc-3.4.3/ldd-2.15.94 compiled and linked the same kernel and .config just fine.
It is because -fasynchronous-unwind-tables adds .ARM.exidx sections. Please try to change kernel linker script from /DISCARD/ : { /* Exit code and data */ *(.exit.text) *(.exit.data) *(.exitcall.exit) } to /DISCARD/ : { /* Exit code and data */ *(.exit.text) *(.ARM.exidx.exit.text) ^^^^^^^^^^^^^^^^^^^^^^^ A new line. *(.exit.data) *(.exitcall.exit) }
I tried both: *(.exit.text) *(.ARM.exidx.exit.text) *(.exit.data) *(.exitcall.exit) as well as *(.ARM.exidx.exit.text) *(.exit.data) *(.exitcall.exit) and both still trigger a segfault.
Interestingly, though, if I change this portion to: *(.exit.text) *(.ARM.exidx) *(.ARM.extab) *(.exit.data) *(.exitcall.exit) it no longer segfaults for this test case. This isn't a proper fix, though, as within the larger kernel build the segfault still occurs.
Please check out binutils in CVS. If you can provide a testcase with assembly files so that I can produce it with binutils only, I will take a look.
Okay, I got around to building a binutils snapshot (9/13), and I now get the behavior described by Kevin Hilman: LD .tmp_vmlinux1 arm-linux-gnueabi-ld: .tmp_vmlinux1: sh_link of section `.ARM.exidx.exit.text' points to discarded section `.exit.text' of `fs/built-in.o' arm-linux-gnueabi-ld: final link failed: Bad value So it's still not working, but no more segfault, so the ball now seems to be back in the kernel guys' court. Thanks for the help