OO.o / ld / -Bsymbolic patch ...
michael meeks
michael.meeks@novell.com
Tue Jul 5 14:34:00 GMT 2005
More information about the Binutils mailing list
Tue Jul 5 14:34:00 GMT 2005
- Previous message (by thread): [RFC] Providing init_fini_syms earlier?
- Next message (by thread): OO.o / ld / -Bsymbolic patch ...
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message (by thread): [RFC] Providing init_fini_syms earlier?
- Next message (by thread): OO.o / ld / -Bsymbolic patch ...
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list