This is the mail archive of the binutils@sources.redhat.com 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]

OO.o / ld / -Bsymbolic patch ...


Hi guys,

	This is my 1st post here; please be patient with me - no doubt I'm
horribly ill-informed; furthermore my patch is for discussion purposes &
is clearly not suitable for merging in it's current form.

	So - my problem is; OO.o startup is dog slow - everyone likes to blame
OO.o for this, but arguably it's a pure infrastructural problem; it
starts faster under Wine on the same system eg.

	Everything was better in the olden-times when one could use -Bsymbolic
on C++ [correct me if I'm wrong], but then the C++ ABI changed pwrt.
exception handling such that we had to honour weak symbols globally. We
stopped using -Bsymbolic.

	OO.o startup performance then sucked so, so badly that we spent ages
marking everything up with visiblity attributes. This improved matters
somewhat. However - we still have a huge number of relocations.
To give some idea - on warm start, we take ~4secs on my machine, and
~25% of that is processing relocations ;-) this is not good.

	So - part of the problem is that we do lots of unnecessary work wrt.
internal relocations; the attached patch reduces the total OO.o rel.plt
relocations by ~20% and the total relocation count by nearly 1/2
(rel.dyn + rel.plt[1]).

	The patch does 2 things:
		a) honours the man pages' promise to bind only -global-
		   symbols, and not weak ones.
			+ a simple objdump -R shows the current 
			  mis-behavior
		b) doesn't set DT_SYMBOLIC.

	So - a) is (hopefully) quite obvious, b) is perhaps less so. After a) I
was rather perplexed to find my simple C++ throw/catch across libraries
was still not working correctly. [ test for convenience at
http://go-oo.org/~michael/symbolic-test.tar.gz ('make test') ].

	The problem with DT_SYMBOLIC (which makes me think that perhaps the
current behavior is feature-not-bug) is to ignore symbol-weakness and
just do the lookup in the scope of the current library - which of course
breaks C++ weak symbols / exceptions really badly :-)

	So - the patch turns off that flag. Of course - ideally I'd love a
DT_SYMBOLIC (or sim.) that honoured weak symbols, and yet did a far
shorter search in the library dependants to resolve global symbols - is
such a thing possible ? [I guess this isn't the right list to ask (?)].
Rather a separate issue I suppose.

	So - question 1: is this a sensible idea ? or am I smoking crack &
following some common mis-conception ? Q.2 - if not should we add a
-Bsymbolic-foo type option to do this but not set DT_SYMBOLIC (perhaps
that exists already) ?

	Anyhow - advice much appreciated, for reference here is the
before/after LD_DEBUG=statistics output for an oowriter run:

before:
     14491:     runtime linker statistics:
     14491:                final number of relocations: 61001
     14491:     final number of relocations from cache: 119292
after:
     13540:     runtime linker statistics:
     13540:                final number of relocations: 42107
     13540:     final number of relocations from cache: 95858

	Thanks,

		Michael.

[1] - I once understood the difference & my tooling counts only rel.plt
for reasons I've subsequently forgotten.

--- binutils-2.16/bfd/elf32-i386.c
+++ binutils-2.16/bfd/elf32-i386.c
@@ -2395,7 +2429,8 @@
 		       && (r_type == R_386_PC32
 			   || !info->shared
 			   || !info->symbolic
+			   || h->root.type == bfd_link_hash_defweak
 			   || !h->def_regular))
 		outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
 	      else
 		{


--- binutils-2.16/bfd/elflink.c
+++ binutils-2.16/bfd/elflink.c
@@ -2582,9 +2616,19 @@
   /* At this point, we know the symbol is defined and dynamic.  In an
      executable it must resolve locally, likewise when building symbolic
      shared libraries.  */
-  if (info->executable || info->symbolic)
+  if (info->executable)
     return TRUE;
 
+  if (info->symbolic) {
+    if (h->root.type != bfd_link_hash_defweak)
+    {
+      if (getenv ("BSYMBOLIC_DEBUG"))
+        fprintf (stderr, "-Bsymbolic binding '%s' internally\n",
+		 h->root.root.string);
+      return TRUE;
+    }
+  }
+
   /* Now deal with defined dynamic symbols in shared libraries.  Ones
      with default visibility might not resolve locally.  */
   if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -5021,12 +5065,15 @@
 	    return FALSE;
 	}
 
+      fprintf (stderr, "Not setting DT_SYMBOLIC\n");
+#if 0
       if (info->symbolic)
 	{
 	  if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
 	    return FALSE;
 	  info->flags |= DF_SYMBOLIC;
 	}
+#endif
 
       if (rpath != NULL)
 	{


-- 
 michael.meeks@novell.com  <><, Pseudo Engineer, itinerant idiot


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