This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Restore .gnu.linkonce.r. g++-3.4 linking


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]