The segfault happens in 2.23.2. Starting program: ld -m elf64btsmip -X -N -r --fatal-warnings -o ../lib/x.a /tmp/a.o /tmp/b.o Program received signal SIGSEGV, Segmentation fault. elf_link_input_bfd (input_bfd=0xc109d0, flinfo=0x7fffffffd430) at elflink.c:9771 9771 irela->r_info = 0; (gdb) bt #0 elf_link_input_bfd (input_bfd=0xc109d0, flinfo=0x7fffffffd430) at elflink.c:9771 #1 bfd_elf_final_link (abfd=0x7767f0, info=0x7603e0 <link_info>) at elflink.c:10852 #2 0x0000000000458834 in _bfd_mips_elf_final_link (abfd=<optimized out>, info=0x7603e0 <link_info>) at elfxx-mips.c:13571 #3 0x000000000041766b in ldwrite () at ldwrite.c:582 #4 0x000000000041656a in main (argc=11, argv=0x7fffffffdd88) at ./ldmain.c:420 (gdb) p /x irela $27 = 0x7ffff1790ff8 (gdb) p /x *irela $8 = { r_offset = 0xffffffffffffffff, r_info = 0xde020109, r_addend = 0x2d900000038 } elflink.c in 2.23.2 9763 if (irela->r_offset >= (bfd_vma) -2) 9764 { 9765 /* This is a reloc for a deleted entry or somesuch. 9766 Turn it into an R_*_NONE reloc, at the same 9767 offset as the last reloc. elf_eh_frame.c and 9768 bfd_elf_discard_info rely on reloc offsets 9769 being ordered. */ 9770 irela->r_offset = last_offset; 9771 irela->r_info = 0; 9772 irela->r_addend = 0; 9773 continue; 9774 } The key difference between crashing/asserting and working just fine is that I have enabled debugging. Dwarf-4 debug symbols where each type is placed into its own .debug_types section. I'm using GCC 4.6. In binutils 2.22 there is an assert at ld: BFD (GNU Binutils) 2.22 assertion fail elf64-mips.c:2521 ld: BFD (GNU Binutils) 2.22 assertion fail elf64-mips.c:2522 ld: BFD (GNU Binutils) 2.22 assertion fail elf64-mips.c:2527 ld: BFD (GNU Binutils) 2.22 assertion fail elf64-mips.c:2528 2512 /* Swap out a MIPS 64-bit Rela reloc. */ 2513 2514 static void 2515 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src, 2516 bfd_byte *dst) 2517 { 2518 Elf64_Mips_Internal_Rela mirela; 2519 2520 mirela.r_offset = src[0].r_offset; 2521 BFD_ASSERT(src[0].r_offset == src[1].r_offset); 2522 BFD_ASSERT(src[0].r_offset == src[2].r_offset); 2523 2524 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info); 2525 mirela.r_sym = ELF64_R_SYM (src[0].r_info); 2526 mirela.r_addend = src[0].r_addend; 2527 BFD_ASSERT(src[1].r_addend == 0); 2528 BFD_ASSERT(src[2].r_addend == 0); 2529 2530 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info); 2531 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info); 2532 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info); 2533 2534 mips_elf64_swap_reloca_out (abfd, &mirela, 2535 (Elf64_Mips_External_Rela *) dst); 2536 } Unfortunately this bug is preventing me to roll out a new debugging infrastructure. Thank you for your help.
Please attach a.o and b.o from your testcase.
CVSROOT: /cvs/src Module name: src Changes by: amodra@sourceware.org 2013-04-22 15:03:01 Modified files: bfd : ChangeLog elf-bfd.h Log message: PR ld/15382 * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Don't multiply sh_size or reloc_count adjustment by count. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.6032&r2=1.6033 http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-bfd.h.diff?cvsroot=src&r1=1.369&r2=1.370
Thanks for the patch. I currently running some new builds with the patch. Is this the same bug that triggered the assertions in 2.22 ? In 2.22 the bfd-elf.h file does not have the multiplication.
From the symptoms I'd say it is the same area of code. In 2.22 a single internal reloc is deleted instead of a group of three. That destroys the grouping so when you output relocs you are trying to package together relocs from different groups with different offsets.