From: Jan Kratochvil Date: Sun, 11 Jan 2009 21:09:49 +0000 (+0000) Subject: bfd/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=80c29487db33cf7e597402790cdf62785e7a89cb;hp=5f61c20e05b3752fb9ab5b2aeea6adc8bf515db5;p=binutils-gdb.git bfd/ * elflink.c (_bfd_elf_section_already_linked): Handle g++-3.4 relocations in `.gnu.linkonce.r.*' referencing its `.gnu.linkonce.t.*'. ld/testsuite/ * ld-elf/linkoncerdiff.d, ld-elf/linkoncerdiff1.s, ld-elf/linkoncerdiff2.s: New. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index da237ce608d..477cad0938b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2009-01-11 Jan Kratochvil + + * elflink.c (_bfd_elf_section_already_linked): Handle g++-3.4 + relocations in `.gnu.linkonce.r.*' referencing its `.gnu.linkonce.t.*'. + 2009-01-07 Hans-Peter Nilsson * elf32-cris.c (cris_elf_relocate_section) diff --git a/bfd/elflink.c b/bfd/elflink.c index 987de895b26..29523c4614e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12281,6 +12281,28 @@ _bfd_elf_section_already_linked (bfd *abfd, asection *sec, } } + /* Do not complain on unresolved relocations in `.gnu.linkonce.r.F' + referencing its discarded `.gnu.linkonce.t.F' counterpart - g++-3.4 + specific as g++-4.x is using COMDAT groups (without the `.gnu.linkonce' + prefix) instead. `.gnu.linkonce.r.*' were the `.rodata' part of its + matching `.gnu.linkonce.t.*'. If `.gnu.linkonce.r.F' is not discarded + but its `.gnu.linkonce.t.F' is discarded means we chose one-only + `.gnu.linkonce.t.F' section from a different bfd not requiring any + `.gnu.linkonce.r.F'. Thus `.gnu.linkonce.r.F' should be discarded. + The reverse order cannot happen as there is never a bfd with only the + `.gnu.linkonce.r.F' section. The order of sections in a bfd does not + matter as here were are looking only for cross-bfd sections. */ + + if ((flags & SEC_GROUP) == 0 && CONST_STRNEQ (name, ".gnu.linkonce.r.")) + for (l = already_linked_list->entry; l != NULL; l = l->next) + if ((l->sec->flags & SEC_GROUP) == 0 + && CONST_STRNEQ (l->sec->name, ".gnu.linkonce.t.")) + { + if (abfd != l->sec->owner) + sec->output_section = bfd_abs_section_ptr; + break; + } + /* This is the first section with this name. Record it. */ if (! bfd_section_already_linked_table_insert (already_linked_list, sec)) info->callbacks->einfo (_("%F%P: already_linked_table: %E")); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index f0728e50d75..1c8b545660c 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-11 Jan Kratochvil + + * ld-elf/linkoncerdiff.d, ld-elf/linkoncerdiff1.s, + ld-elf/linkoncerdiff2.s: New. + 2009-01-07 Hans-Peter Nilsson * ld-cris/tls-e-20.d, ld-cris/tls-e-20a.d, ld-cris/tls-e-21.d, diff --git a/ld/testsuite/ld-elf/linkoncerdiff.d b/ld/testsuite/ld-elf/linkoncerdiff.d new file mode 100644 index 00000000000..8eec3d2ca27 --- /dev/null +++ b/ld/testsuite/ld-elf/linkoncerdiff.d @@ -0,0 +1,6 @@ +#source: linkoncerdiff1.s +#source: linkoncerdiff2.s +#ld: -r +#readelf: -r +There are no relocations in this file. +#pass diff --git a/ld/testsuite/ld-elf/linkoncerdiff1.s b/ld/testsuite/ld-elf/linkoncerdiff1.s new file mode 100644 index 00000000000..9e8e17eca14 --- /dev/null +++ b/ld/testsuite/ld-elf/linkoncerdiff1.s @@ -0,0 +1,7 @@ + .section .gnu.linkonce.t.foo, "a", %progbits + .globl symfoo +symfoo: + + .section .gnu.linkonce.t.bar, "a", %progbits + .globl symbar +symbar: diff --git a/ld/testsuite/ld-elf/linkoncerdiff2.s b/ld/testsuite/ld-elf/linkoncerdiff2.s new file mode 100644 index 00000000000..1e8c2baefd0 --- /dev/null +++ b/ld/testsuite/ld-elf/linkoncerdiff2.s @@ -0,0 +1,22 @@ + .section .gnu.linkonce.t.foo, "a", %progbits +1: + .globl symfoo +symfoo: + .long 0 + + .section .gnu.linkonce.t.bar, "a", %progbits +2: + .globl symbar +symbar: + .long 0 + + .section .gnu.linkonce.r.foo, "a", %progbits + .long 1b + .long symfoo +/* ld currently incorrectly silently discards this relocation. Just such + relocations are never produced by g++-3.4 so this suppressed error message + is not a problem: + #error: `.gnu.linkonce.t.bar' referenced in section `.gnu.linkonce.r.foo' of tmpdir/dump1.o: defined in discarded section `.gnu.linkonce.t.bar' of tmpdir/dump1.o + */ + .long 2b + .long symbar