This patch: http://sourceware.org/ml/binutils/2008-09/msg00214.html may have caused: [hjl@gnu-31 tmp]$ cat foo.c extern int foo; int * foo1 () { return &foo; } [hjl@gnu-31 tmp]$ cat bar.c extern int bar; int * bar1 () { return &bar; } [hjl@gnu-31 tmp]$ gcc -fPIC -c bar.c foo.c [hjl@gnu-31 tmp]$ ld -r -o libbar.o bar.o [hjl@gnu-31 tmp]$ ld -shared libbar.o foo.o foo.o: In function `__i686.get_pc_thunk.cx': foo.c:(.text.__i686.get_pc_thunk.cx[__i686.get_pc_thunk.cx]+0x0): multiple definition of `__i686.get_pc_thunk.cx' libbar.o:(.text.__i686.get_pc_thunk.cx[.group]+0x0): first defined here [hjl@gnu-31 tmp]$
It happens on Linux/ia32 with gcc 4.3.
The bug is in bfd_elf_set_group_contents: symindx = 0; if (elf_group_id (sec) != NULL) symindx = elf_group_id (sec)->udata.i; if (symindx == 0) { /* If called from the assembler, swap_out_syms will have set up elf_section_syms; If called for "ld -r", use target_index. */ if (elf_section_syms (abfd) != NULL) symindx = elf_section_syms (abfd)[sec->index]->udata.i; else symindx = sec->target_index; } elf_section_data (sec)->this_hdr.sh_info = symindx; "ld -r" is incorrect. We need to find the symbol index for group signature which isn't the same as the section name.
Created attachment 2974 [details] Testcases Those tests failed: FAIL: ld-elf/group4 FAIL: ld-elf/group5 FAIL: ld-elf/group6
Testing a fix. I know now why I hacked the group signature into the SEC_GROUP name...
http://sourceware.org/ml/binutils-cvs/2008-10/msg00013.html http://sourceware.org/ml/binutils/2008-10/msg00030.html HJ, please commit the new tests.
It still isn't right: bash-3.2$ cat /export/gnu/src/binutils/binutils/binutils/testsuite/binutils-all/group.s .section .text.foo,"axG",%progbits,foo_group,comdat .global foo foo: .word 0 .section .data.foo,"awG",%progbits,foo_group,comdat .global bar bar: .word 0 bash-3.2$ cat /export/gnu/src/binutils/binutils/binutils/testsuite/binutils-all/group-2.s .section .text.foo,"axG",%progbits,.text.foo,comdat .global foo2 foo2: .word 0 .section .data.bar,"awG",%progbits,.text.foo,comdat .global bar2 bar2: .word 0 bash-3.2$ gcc -c /export/gnu/src/binutils/binutils/binutils/testsuite/binutils-all/group.s /export/gnu/src/binutils/binutils/binutils/testsuite/binutils-all/group-2.s bash-3.2$ ./ld-new -r group.o group-2.o bash-3.2$ readelf -g group-2.o COMDAT group section [ 1] `.group' [.text.foo] contains 2 sections: [Index] Name [ 5] .text.foo [ 6] .data.bar bash-3.2$ readelf -g a.out COMDAT group section [ 1] `foo_group' [foo_group] contains 2 sections: [Index] Name [ 4] .text.foo [ 7] .data.foo COMDAT group section [ 2] `.group' [.text.foo.1] contains 2 sections: [Index] Name [ 5] .text.foo.1 [ 8] .data.bar bash-3.2$ "ld -r" generates wrong group signature.
http://sourceware.org/ml/binutils-cvs/2008-10/msg00022.html http://sourceware.org/ml/binutils/2008-10/msg00045.html