This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [patch] Restore .gnu.linkonce.r. g++-3.4 linking
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: binutils at sourceware dot org
- Cc: Alan Modra <amodra at bigpond dot net dot au>
- Date: Mon, 17 Nov 2008 12:36:45 +0100
- Subject: Re: [patch] Restore .gnu.linkonce.r. g++-3.4 linking
- References: <20081022235914.GA26735@host0.dyn.jankratochvil.net> <20081024065708.GA6815@bubble.grove.modra.org> <20081026165921.GA15615@host0.dyn.jankratochvil.net> <20081029061457.GB15620@bubble.grove.modra.org>
On Wed, 29 Oct 2008 07:14:57 +0100, Alan Modra wrote:
> This patch is better, but it still seems like a hack to me. How do
> you feel about implementing your "could in fact also be discarded"
> comment? It should be fairly easy. _bfd_elf_section_already_linked
> already_linked_list has already selected all .gnu.linkonce.*.F
> sections, so if you see any .gnu.linkonce.* section on the list,
> belonging to a different bfd, then you could discard.
Done, it really fits there.
Just note the patch now does not check whether the relocations in the
discarded `.gnu.linkonce.r.F' sections were all the expected ones (just to
`.gnu.linkonce.t.F'). But g++-3.4 does not produce any such unexpected
relocations and one does not code `.gnu.linkonce.r.F' sections by hand..
Thanks,
Jan
No regressions. The new testcase is (as before) not PASSing for:
hppa64-hp-hpux11.23 FAILs (local labels `1' and `2' FAIL there):
ld-elf/linkoncerdiff2.s:2: Error: junk at end of line, first unrecognized character is `1'
mmix-elf FAILs (other linkonce* also FAIL):
ld-elf/linkoncerdiff1.s:1: Error: junk at end of line, first unrecognized character is `,'
2008-11-17 Jan Kratochvil <jan.kratochvil@redhat.com>
* elflink.c (_bfd_elf_section_already_linked): Handle g++-3.4
relocations in `.gnu.linkonce.r.*' referencing its `.gnu.linkonce.t.*'.
2008-11-17 Jan Kratochvil <jan.kratochvil@redhat.com>
* ld-elf/linkoncerdiff.d, ld-elf/linkoncerdiff1.s,
ld-elf/linkoncerdiff2.s: New.
--- bfd/elflink.c 2008-10-25 15:16:04.000000000 +0200
+++ bfd/elflink.c 2008-11-15 17:31:36.000000000 +0100
@@ -12233,6 +12233,30 @@ _bfd_elf_section_already_linked (bfd *ab
}
}
+ /* 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.")
+ && strcmp (name + sizeof (".gnu.linkonce.r.") - 1,
+ l->sec->name + sizeof (".gnu.linkonce.t.") - 1) == 0)
+ {
+ 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"));
--- ld/testsuite/ld-elf/linkoncerdiff.d 1970-01-01 01:00:00.000000000 +0100
+++ ld/testsuite/ld-elf/linkoncerdiff.d 2008-11-14 21:57:27.000000000 +0100
@@ -0,0 +1,6 @@
+#source: linkoncerdiff1.s
+#source: linkoncerdiff2.s
+#ld: -r
+#readelf: -r
+There are no relocations in this file.
+#pass
--- ld/testsuite/ld-elf/linkoncerdiff1.s 1970-01-01 01:00:00.000000000 +0100
+++ ld/testsuite/ld-elf/linkoncerdiff1.s 2008-10-26 13:11:04.000000000 +0100
@@ -0,0 +1,7 @@
+ .section .gnu.linkonce.t.foo, "a", %progbits
+ .globl symfoo
+symfoo:
+
+ .section .gnu.linkonce.t.bar, "a", %progbits
+ .globl symbar
+symbar:
--- ld/testsuite/ld-elf/linkoncerdiff2.s 1970-01-01 01:00:00.000000000 +0100
+++ ld/testsuite/ld-elf/linkoncerdiff2.s 2008-11-14 21:58:43.000000000 +0100
@@ -0,0 +1,20 @@
+ .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:
+ #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