More linking acceleration work (with visibility attribute)

* potential fixes:
	+ static linking / aggregation & altering library deps etc.
	    + potentially factor of 10 improvement
	    + aggregate all non-components used during startup
	      into 1 monster library:
		+ ensure this is the 1st entry in the link deps.
		+ unfortately the largest libraries: libsvx, libsfx
		  are also components themselves ...
	    + post-aggregate these (somehow?) & re-link 'desktop'
		+ how can we re-link that stuff ?

	+ Adding markup: may remove: 5000 more relocations == ~6%

	+ Doing internal compiler fixups - may remove: 20k+ == ~25% speedup

	+ removing libraries from link time
	    + potential 1/20th improvement per library
	    + plus - wastefulness: why was it there ?
	    + should do for audio pieces in vcl
		- 350K of unused code - force/paged into memory




** Latest worst-offender library results: (preloc):

libvos3gcc3.so : used 31 internal(withsym) 406 total 437
libsc680li.so : used 1937 internal(withsym) 409 total 2346
i18npool.uno.so : used 64 internal(withsym) 420 total 484
libicuuc.so : used 109 internal(withsym) 429 total 538
libucbhelper3gcc3.so : used 165 internal(withsym) 487 total 652
libcppcanvas680li.so : used 29 internal(withsym) 490 total 519
libgo680li.so : used 104 internal(withsym) 500 total 604
libxsec_xmlsec.so : used 70 internal(withsym) 545 total 615
libfwe680li.so : used 324 internal(withsym) 546 total 870
libcomphelp4gcc3.so : used 486 internal(withsym) 566 total 1052
libsfx680li.so : used 1259 internal(withsym) 622 total 1881
libxcr680li.so : used 118 internal(withsym) 652 total 770
libdbu680li.so : used 1649 internal(withsym) 656 total 2305
libfile680li.so : used 1173 internal(withsym) 742 total 1915
libfrm680li.so : used 935 internal(withsym) 743 total 1678
configmgr2.uno.so : used 263 internal(withsym) 764 total 1027
liblng680li.so : used 256 internal(withsym) 792 total 1048
slideshow.uno.so : used 72 internal(withsym) 961 total 1033
libstlport_gcc.so : used 40 internal(withsym) 973 total 1013
libstdc++.so : used 37 internal(withsym) 1002 total 1039
libsw680li.so : used 2691 internal(withsym) 1035 total 3726

libicui18n.so : used 103 internal(withsym) 1091 total 1194  - no vis markup
libso680li.so : used 347 internal(withsym) 1197 total 1544  - no vis markup
libvcl680li.so : used 631 internal(withsym) 1403 total 2034 - marked up[!]
libsb680li.so : used 297 internal(withsym) 1455 total 1752  - no vis markup

libsvt680li.so : used 2489 internal(withsym) 2277 total 4766  - marked up[!]
libsvx680li.so : used 3960 internal(withsym) 5926 total 9886  - marked up[!]
Total relocs: 92477

was [ Total relocs: 183315 ]



** Interesting:

#0  osl_psz_loadModule (pszModuleName=0xbfffccb0 "libdtransX11680li.so", nRtldMode=257) at module.c:253
#1  0x408e3298 in osl_loadModule (ustrModuleName=0x44f5bab0, nRtldMode=257) at module.c:152
#2  0x408874a3 in cppu::loadSharedLibComponentFactory () from /opt/OOInstall/program/libuno_cppuhelpergcc3.so.3
#3  0x42054fbd in component_getFactory () from /opt/OOInstall/program/shlibloader.uno.so
#4  0x408807c4 in cppu::createFactoryProxy () from /opt/OOInstall/program/libuno_cppuhelpergcc3.so.3
#5  0x40880957 in cppu::createFactoryProxy () from /opt/OOInstall/program/libuno_cppuhelpergcc3.so.3
#6  0x4203e4a2 in component_getFactory () from /opt/OOInstall/program/servicemgr.uno.so
#7  0x4203de64 in component_getFactory () from /opt/OOInstall/program/servicemgr.uno.so
#8  0x401d5a8d in Window::GetDragSource () from /opt/OOInstall/program/libvcl680li.so
#9  0x401d010b in Window::GetDropTarget () from /opt/OOInstall/program/libvcl680li.so
#10 0x40b20e34 in non-virtual thunk to VCLXMenu::execute(com::sun::star::uno::Reference<com::sun::star::awt::XWindowPeer> const&, com::sun::star::awt::Rectangle const&, short) () from /opt/OOInstall/program/libtk680li.so
#11 0x43c44ec4 in ?? () from /opt/OOInstall/program/libfwk680li.so
#12 0x43c45753 in ?? () from /opt/OOInstall/program/libfwk680li.so
#13 0x43c668d0 in component_getFactory () from /opt/OOInstall/program/libfwk680li.so
#14 0x43c66b73 in component_getFactory () from /opt/OOInstall/program/libfwk680li.so
#15 0x43c2a73f in ?? () from /opt/OOInstall/program/libfwk680li.so
#16 0x43cd6672 in component_getFactory () from /opt/OOInstall/program/libfwk680li.so
#17 0x43cd6c5d in component_getFactory () from /opt/OOInstall/program/libfwk680li.so
#18 0x43cd6d16 in component_getFactory () from /opt/OOInstall/program/libfwk680li.so
#19 0x43c2aa99 in ?? () from /opt/OOInstall/program/libfwk680li.so
#20 0x080739d3 in desktop::DispatchWatcher::executeDispatchRequests ()
#21 0x0806d6bb in desktop::OfficeIPCThread::ExecuteCmdLineRequests ()
#22 0x0806234f in desktop::Desktop::OpenDefault ()
#23 0x08065dc1 in desktop::Desktop::OpenClients ()
#24 0x08067b23 in desktop::Desktop::OpenClients_Impl ()
#25 0x400921de in Help::ShowTip () from /opt/OOInstall/program/libvcl680li.so
#26 0x401e5fb7 in Window::DrawNativeControl () from /opt/OOInstall/program/libvcl680li.so
#27 0x41c7b72c in X11SalFrame::GetWindowState () from /opt/OOInstall/program/libvclplug_gen680li.so
#28 0x41c9eef1 in SalDisplay::DispatchInternalEvent () from /opt/OOInstall/program/libvclplug_gen680li.so
#29 0x41778873 in ?? () from /opt/OOInstall/program/libvclplug_gtk680li.so
#30 0x40c3c5a0 in ?? ()
#31 0x40c3c5a0 in ?? ()
#32 0x40c3b260 in ?? ()
#33 0x41c58578 in __JCR_LIST__ () from /opt/gnome/lib/libglib-2.0.so.0
#34 0x00000000 in ?? ()
#35 0x080f4470 in ?? ()
#36 0xbfffeaac in ?? ()
#37 0x41bfc221 in g_idle_dispatch () from /opt/gnome/lib/libglib-2.0.so.0
Previous frame identical to this frame (corrupt stack?)



Helper libraries: glup into 1 ?:

helper: ./libavmedia680li.so
helper: ./libbasegfx680li.so
helper: ./libfwe680li.so
helper: ./libfwi680li.so
helper: ./libgcc3_uno.so
helper: ./libi18nutilgcc3.so
helper: ./libicudata.so.26
helper: ./libicui18n.so.26
helper: ./libicule.so.26
helper: ./libicuuc.so.26
helper: ./libj680li_g.so
helper: ./libjvmaccessgcc3.so.3
helper: ./libjvmfwk.so.3
helper: ./liblocaledata_en.so
helper: ./libportaudio.so.0
helper: ./libpsp680li.so
helper: ./libreg.so.3
helper: ./libsb680li.so
helper: ./libsndfile.so.1
helper: ./libstlport_gcc.so
helper: ./libstore.so.3
helper: ./libsvl680li.so
helper: ./libtl680li.so
helper: ./libucbhelper3gcc3.so
helper: ./libuno_cppu.so.3
helper: ./libuno_salhelpergcc3.so.3
helper: ./libuno_sal.so.3
helper: ./libvclplug_gen680li.so
helper: ./libvclplug_gtk680li.so
helper: ./libvos3gcc3.so

Components:
component: ./behelper.uno.so
component: ./configmgr2.uno.so
component: ./fsstorage.uno.so
component: ./gconfbe1.uno.so
component: ./i18npool.uno.so
component: ./ldapbe2.uno.so
component: ./libcomphelp4gcc3.so
component: ./libdbtools680li.so
component: ./libdtransX11680li.so
component: ./libfileacc.so
component: ./libfilterconfig1.so
component: ./libfwk680li.so
component: ./libfwl680li.so
component: ./libgo680li.so
component: ./liblng680li.so
component: ./libmcnttype.so
component: ./libpackage2.so
component: ./libsfx680li.so
component: ./libsot680li.so
component: ./libspl680li.so
component: ./libsvt680li.so
component: ./libsvx680li.so
component: ./libsw680li.so
component: ./libtk680li.so [!]
component: ./libucb1.so
component: ./libucpfile1.so
component: ./libuno_cppuhelpergcc3.so.3
component: ./libutl680li.so
component: ./libuui680li.so
component: ./libvcl680li.so
component: ./libxcr680li.so
component: ./libxo680li.so
component: ./libxstor.so
component: ./localebe1.uno.so
component: ./sax.uno.so
component: ./streams.uno.so
component: ./sysmgr1.uno.so
component: ./typeconverter.uno.so
component: ./ucpgvfs1.uno.so
component: ./uriproc.uno.so
component: implreg.uno.so
component: nestedreg.uno.so
component: regtypeprov.uno.so
component: security.uno.so
component: servicemgr.uno.so
component: shlibloader.uno.so
component: simplereg.uno.so
component: typemgr.uno.so


Gcc 4 research:
    + ld -Bsymbolic breaks stuff; - should avoid weak symbols (?)

    + before: (objdump -R)
000019f0 R_386_GLOB_DAT    _ZTV9BaseClass
00001a2c R_386_32          _ZTS9BaseClass
00001a34 R_386_32          _ZTI9BaseClass
00001a38 R_386_32          _ZN9BaseClass5doFooEv
00001a40 R_386_32          _ZTS11MyException

    + after:
000019fc R_386_RELATIVE    *ABS*
00001a04 R_386_RELATIVE    *ABS*
00001a08 R_386_RELATIVE    *ABS*
00001a10 R_386_RELATIVE    *ABS*
00001a18 R_386_RELATIVE    *ABS*

    + Of these symbols:
class BaseClass {
public:
	BaseClass();
	virtual void doFoo() throw (MyException);
	int inlineFoo() { return 1; }
};
    + we should be able to -Bsymbolic the local symbols: surely [!?]
0000079c g    DF .text  00000056  Base        _ZN9BaseClassC2Ev
00000746 g    DF .text  00000056  Base        _ZN9BaseClassC1Ev
000007fb  w   DO .rodata        0000000b  Base        _ZTS9BaseClass
00001a28  w   DO .data  00000008  Base        _ZTI9BaseClass
000006ee g    DF .text  00000057  Base        _ZN9BaseClass5doFooEv
00001a30  w   DO .data  0000000c  Base        _ZTV9BaseClass

    + On that basis we should keep all but the doFooEv

    + libsvx - grep '_ZN...' - 14k symbols,

    + Fix 'ld -Bsymbolic' to use weakness too...
    + get a nice run-time test of that ...
	+ bfd/elf32-i386.c '->symbolic' usage
	    + this is just an incidental usage - not the filtering

'w' == (bfd/syms.c:) (type & BSF_WEAK) ? 'w' : ' ', on an 'asymbol'

We need to hack elflink.c: 
   _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
   + Unfortunately 'h' points to the relocation itself seemingly
	+ all of STT_OBJECT
	+ => need to de-ref the symbol name to get the real data ...

   + This function called from SYMBOL_REFERENCES_LOCAL
        ... potentially has:
	    + input_bfd, output_bfd, bfd_link_info *info,
	    + input_section, contents, relocs, local_syms,
	    + local_sections
Called from:
    elf_i386_relocate_section ...


** How the (correct)BSF_WEAK flag gets set:

elfcode.h (elf_slurp_symbol_table):
  Elf_Internal_Sym *isym;
  isym = bfd_elf_get_elf_syms
	  switch (ELF_ST_BIND (isym->st_info))
	    case STB_WEAK:
	      sym->symbol.flags |= BSF_WEAK;

   isym from:
   -> elf.c (bfd_elf_get_elf_syms): read/convert symbols to internal format
	-> read with elfcode.h (elf_swap_symbol_in)
	


static bfd_boolean
elf_i386_relocate_section (bfd *output_bfd,
			   struct bfd_link_info *info,
			   bfd *input_bfd,
			   asection *input_section,
			   bfd_byte *contents,
			   Elf_Internal_Rela *relocs,
			   Elf_Internal_Sym *local_syms,
			   asection **local_sections)

called from: elflink.c (elf_link_input_bfd)


  /* The RELOCATE_SECTION function is called by the ELF backend linker
     to handle the relocations for a section.

     The relocs are always passed as Rela structures; if the section
     actually uses Rel structures, the r_addend field will always be
     zero.

     This function is responsible for adjust the section contents as
     necessary, and (if using Rela relocs and generating a
     relocatable output file) adjusting the reloc addend as
     necessary.

     This function does not have to worry about setting the reloc
     address or the reloc symbol index.

     LOCAL_SYMS is a pointer to the swapped in local symbols.

     LOCAL_SECTIONS is an array giving the section in the input file
     corresponding to the st_shndx field of each local symbol.

     The global hash table entry for the global symbols can be found
     via elf_sym_hashes (input_bfd).

     When generating relocatable output, this function must handle
     STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
     going to be the section symbol corresponding to the output
     section, which means that the addend must be adjusted
     accordingly.  */

Dumping the contents of LOCAL_SYMS - we get:

fprintf( stderr, "Process reloc %2d 0x%2x 0x%2x '%s'\n",
	 rel - relocs, 
	 sym->st_info, sym->st_other,
	 h->root.root.string );

Process reloc  1 0x 3 0x 0 'typeinfo name for SubClass'
Process reloc  2 0x 3 0x 0 'typeinfo for BaseClass'
Process reloc  0 0x 0 0x 0 'typeinfo for SubClass'
Process reloc  1 0x 3 0x 0 'SubClass::doFoo()'
Process reloc  0 0x 3 0x 0 '__i686.get_pc_thunk.bx'
Process reloc  1 0x 3 0x 0 '_GLOBAL_OFFSET_TABLE_'
Process reloc  2 0x 3 0x 0 'BaseClass::BaseClass()'
Process reloc  3 0x 3 0x 0 'vtable for SubClass'
Process reloc  0 0x 3 0x 0 'DW.ref._ZTI11MyException'
Process reloc  1 0x 3 0x 0 'DW.ref._ZTI11MyException'
Process reloc  0 0x 3 0x 0 'vtable for __cxxabiv1::__class_type_info'
Process reloc  1 0x 3 0x 0 'typeinfo name for MyException'
Process reloc  0 0x 3 0x 0 'DW.ref.__gxx_personality_v0'
Process reloc  0 0x 3 0x 0 '__gxx_personality_v0'
Process reloc  0 0x 3 0x 0 'typeinfo for MyException'
Process reloc  0 0x 4 0x 0 '__i686.get_pc_thunk.bx'
Process reloc  1 0x 3 0x 0 '_GLOBAL_OFFSET_TABLE_'
Process reloc  2 0x 3 0x 0 '__fini_array_end'
Process reloc  3 0x 3 0x 0 '__fini_array_start'
Process reloc  4 0x 3 0x 0 '_fini'
Process reloc  5 0x 3 0x 0 '_fini'
Process reloc  6 0x 4 0x 0 '__i686.get_pc_thunk.bx'
Process reloc  7 0x 3 0x 0 '_GLOBAL_OFFSET_TABLE_'
Process reloc  8 0x 3 0x 0 '_init'
Process reloc  9 0x 3 0x 0 '__init_array_end'
Process reloc 10 0x 3 0x 0 '__init_array_start'

#define ELF_ST_INFO(bind,type)		(((bind) << 4) + ((type) & 0xF))
an st_info of 3 means: 
STB_LOCAL |
#define STT_SECTION	3		/* Symbol associated with a section */
#define STT_FILE	4		/* Symbol gives a file name */

	Looks pretty broken [!]


elflink.c (elf_link_input_bfd):
    the 'symbols' data here - is just section names /
    data for them. ie. irrelevant nonsense.

	+ the bfd_elf_get_elf_syms seems to split the syms into
	  finfo->internal_syms / external_syms / locsym_shndx etc.

** In the .o file - each function is in a separate section

Very odd oddness: adding debug:

** bfd_elf_get_elf_syms ** 1 syms from file 'lib.o' section '.symtab'
Symbol typeinfo for BaseClass(0x21, 0x 0)
** bfd_elf_get_elf_syms ** 1 syms from file 'lib.o' section '.symtab'
Symbol typeinfo name for BaseClass(0x21, 0x 0)
** bfd_elf_get_elf_syms ** 1 syms from file 'lib.o' section '.symtab'
Symbol vtable for BaseClass(0x21, 0x 0)
** bfd_elf_get_elf_syms ** 1 syms from file 'lib.o' section '.symtab'
Symbol typeinfo for MyException(0x21, 0x 0)

followed by:

** bfd_elf_get_elf_syms ** 20 syms from file 'lib.o' section '.symtab'
Symbol typeinfo for BaseClass(0x21, 0x 0)
Symbol vtable for __cxxabiv1::__class_type_info(0x10, 0x 0)
Symbol typeinfo name for BaseClass(0x21, 0x 0)
Symbol vtable for BaseClass(0x21, 0x 0)
Symbol BaseClass::doFoo()    (0x12, 0x 0)
Symbol typeinfo for MyException(0x21, 0x 0)
Symbol typeinfo name for MyException(0x21, 0x 0)
Symbol BaseClass::BaseClass()(0x12, 0x 0)
Symbol __i686.get_pc_thunk.cx (0x12, 0x 2)
Symbol _GLOBAL_OFFSET_TABLE_ (0x10, 0x 0)
Symbol BaseClass::BaseClass()(0x12, 0x 0)
Symbol MyException::MyException()(0x12, 0x 0)
Symbol __i686.get_pc_thunk.bx (0x12, 0x 2)
Symbol stderr (0x10, 0x 0)
Symbol fprintf (0x10, 0x 0)

Very odd - same file, same 'section' - but reading
very different stuff; some different hdr type or somesuch ?

subsequently we have:

** bfd_elf_get_elf_syms ** 33 syms from file 'lib.o' section '.symtab'
Symbol  (0x 0, 0x 0)
Symbol lib.cxx (0x 4, 0x 0)
Symbol .text (0x 3, 0x 0)
Symbol .data (0x 3, 0x 0)
Symbol .bss (0x 3, 0x 0)
Symbol .debug_abbrev (0x 3, 0x 0)
Symbol .debug_info (0x 3, 0x 0)
Symbol .debug_line (0x 3, 0x 0)
Symbol .gnu.linkonce.d._ZTI9BaseClass (0x 3, 0x 0)
Symbol .gnu.linkonce.r._ZTS9BaseClass (0x 3, 0x 0)
Symbol .gnu.linkonce.d._ZTV9BaseClass (0x 3, 0x 0)
Symbol .gnu.linkonce.d._ZTI11MyException (0x 3, 0x 0)
Symbol .gnu.linkonce.r._ZTS11MyException (0x 3, 0x 0)

- ie. completely broken symbol / flags again (or at least per-section flags).

TODO: dump the 'sh_offset' file offset data as well [!?]
      + start printing 'dynindx' and 'indx' to get 'real' symbol offsets ?
	    + look those up to get real weak/strong foo ?

The dynindx looks valuable & relevant:

-Bsymbolic (new) tag for this binding 'MyException::MyException()' (16) ? 
-Bsymbolic (new) tag for this binding 'typeinfo name for MyException' (13) ? 
-Bsymbolic (new) tag for this binding 'typeinfo name for BaseClass' (9) ? 
-Bsymbolic (new) tag for this binding 'typeinfo for BaseClass' (7) ? 
-Bsymbolic (new) tag for this binding 'BaseClass::doFoo()' (11) ? 

How do we lookup the symbol at that index though ?

  elf_link_hash_traverse (elf_hash_table (info),
			  elf_link_renumber_local_hash_table_dynsyms,
			  &dynsymcount);

  that sort of thing interesting ?

  /* Hash table handled by BFD.  */
  struct bfd_link_hash_table *hash;

elf-bfd.h:424:#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash))

Traversing the dynlocal entries - just nothing in that table [!]

linker.c (elf_link_hash_traverse)  -> bfd_hash_traverse (table->table)
    + traversing the list.

** DOH ! - need to be looking in bfd_link_hash_entry structure
for type etc. [!?]
		   h->root.type == bfd_link_hash_defweak || h->root.type == bfd_link_hash_undefweak

- old debugging cruft: -

static bfd_boolean
foo_dump_entry (struct elf_link_hash_entry *h, void *data)
{
	fprintf( stderr, ">entry: '%s' (%d) root type 0x%x size 0x%x weak: %d\n",
		 h->root.root.string, h->dynindx,
		 h->root.type, (int)h->size, h->dynamic_weak );
	return TRUE;
}

#if 0
	  elf_link_hash_traverse (elf_hash_table (info),
				  foo_dump_entry, NULL);
#endif
#if 0
 {
	  struct elf_link_local_dynamic_entry *entry;
	  for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) {
	  //		  if (entry->dynindx == h->dynindx) {
			  sym = &entry->isym;
			  fprintf( stderr, "real symbol (%d) 0x%x 0x%x bind 0x%x\n",
				   entry->dynindx,
				   sym ? sym->st_info : -1 , sym ? sym->st_other : -1 ,
				   sym ? ELF_ST_BIND(sym->st_info) : -1
				   );
			  //		  }
	  }
 }
#endif
#if 0
 {
	  struct elf_link_local_dynamic_entry *entry;
	  for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) {
	  //		  if (entry->dynindx == h->dynindx) {
			  sym = &entry->isym;
			  fprintf( stderr, "real symbol (%d) 0x%x 0x%x bind 0x%x\n",
				   entry->dynindx,
				   sym ? sym->st_info : -1 , sym ? sym->st_other : -1 ,
				   sym ? ELF_ST_BIND(sym->st_info) : -1
				   );
			  //		  }
	  }
 }
#endif
	  
	   /*	   "real symbol 0x%x 0x%x bind 0x%x"
	   sym ? sym->st_info : -1 , sym ? sym->st_other : -1 ,
	   sym ? ELF_ST_BIND(sym->st_info) : -1 */

/*	   h->type, h->other,

	   h->ref_regular, h->def_regular,
	   h->ref_dynamic, h->def_dynamic,
	   h->ref_regular_nonweak, h->dynamic_adjusted,
	   h->needs_copy, h->needs_plt,
	   h->dynamic_def, h->dynamic_weak,
	   h->hidden, h->forced_local*/

Before:
2:
00001b50 R_386_RELATIVE    *ABS*
00001b54 R_386_RELATIVE    *ABS*
6:
00001b14 R_386_GLOB_DAT    stderr
00001b18 R_386_GLOB_DAT    _ZTI11MyException
00001b1c R_386_GLOB_DAT    __cxa_finalize
00001b20 R_386_GLOB_DAT    _ZTV9BaseClass
00001b24 R_386_GLOB_DAT    _Jv_RegisterClasses
00001b28 R_386_GLOB_DAT    __gmon_start__
7:
00001b58 R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b6c R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b5c R_386_32          _ZTS9BaseClass
00001b64 R_386_32          _ZTI9BaseClass
00001b68 R_386_32          _ZN9BaseClass5doFooEv
00001b70 R_386_32          _ZTS11MyException
00001b74 R_386_32          __gxx_personality_v0

Broken:

OFFSET   TYPE              VALUE 
00001b40 R_386_RELATIVE    *ABS*
00001b44 R_386_RELATIVE    *ABS*
00001b4c R_386_RELATIVE    *ABS*
00001b54 R_386_RELATIVE    *ABS*
00001b58 R_386_RELATIVE    *ABS*
00001b60 R_386_RELATIVE    *ABS*

00001b0c R_386_GLOB_DAT    stderr
00001b10 R_386_GLOB_DAT    _ZTI11MyException
00001b14 R_386_GLOB_DAT    __cxa_finalize
00001b18 R_386_GLOB_DAT    _ZTV9BaseClass
00001b1c R_386_GLOB_DAT    _Jv_RegisterClasses
00001b20 R_386_GLOB_DAT    __gmon_start__

00001b48 R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b5c R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b64 R_386_32          __gxx_personality_v0
00001b30 R_386_JUMP_SLOT   fprintf
00001b34 R_386_JUMP_SLOT   __cxa_allocate_exception
00001b38 R_386_JUMP_SLOT   __cxa_finalize
00001b3c R_386_JUMP_SLOT   __cxa_throw

After:

OFFSET   TYPE              VALUE 
00001b40 R_386_RELATIVE    *ABS*
00001b44 R_386_RELATIVE    *ABS*
00001b58 R_386_RELATIVE    *ABS*
00001b0c R_386_GLOB_DAT    stderr
00001b10 R_386_GLOB_DAT    _ZTI11MyException
00001b14 R_386_GLOB_DAT    __cxa_finalize
00001b18 R_386_GLOB_DAT    _ZTV9BaseClass
00001b1c R_386_GLOB_DAT    _Jv_RegisterClasses
00001b20 R_386_GLOB_DAT    __gmon_start__
00001b48 R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b5c R_386_32          _ZTVN10__cxxabiv117__class_type_infoE
00001b4c R_386_32          _ZTS9BaseClass
00001b54 R_386_32          _ZTI9BaseClass
00001b60 R_386_32          _ZTS11MyException
00001b64 R_386_32          __gxx_personality_v0
00001b30 R_386_JUMP_SLOT   fprintf
00001b34 R_386_JUMP_SLOT   __cxa_allocate_exception
00001b38 R_386_JUMP_SLOT   __cxa_finalize
00001b3c R_386_JUMP_SLOT   __cxa_throw

Next problem:

* diff of objdump -x output:
    +  SYMBOLIC    0x0

* Linker is using this to:

ie. direct (-Bsymbolic) lookup:
     25599:	symbol=_ZTI11MyException;  lookup in file=./liblib.so
     25599:	binding file ./liblib.so to ./liblib.so: normal symbol `_ZTI11MyException'
should be:
     25694:	symbol=_ZTI11MyException;  lookup in file=./app
     25694:	binding file ./liblib.so to ./app: normal symbol `_ZTI11MyException'

ie. don't set SYMBOLIC flag in output ...
    (elflink.c _bfd_elf_add_dynamic_entry ... DT_SYMBOLIC )


Solution:

--- 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;
 	}
 
+#if 0
+      fprintf (stderr, "Not setting DT_SYMBOLIC\n");
       if (info->symbolic)
 	{
 	  if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
 	    return FALSE;
 	  info->flags |= DF_SYMBOLIC;
 	}
+#endif
 
       if (rpath != NULL)
 	{


** So ...

    + using 'protected' attribute on *every* method works just
      as well as the -Bsymbolic fix - not realistic to think we
      can get that up-stream though.

    + using 'protected' per-class instead of 'default' appears
      to work - until we hit the dynamic linker ... - at which
      point we fail to link correctly:

     22100:	symbol=_ZTS11MyException;  lookup in file=./app
     22100:	symbol=_ZTS11MyException;  lookup in file=./app
     22100:	binding file ./liblib.so to ./liblib.so: protected symbol `_ZTS11MyException'

    + the 'visibility' attribute just gets pushed through gcc
      to the assembler - trivially.

    + -fno-rtti seems to do little wrt. not exporting _ZTI
      symbols etc. -fexceptions seems to have no effect.
      -fno-rtti does shrink the output though.


    + !STB_GLOBAL && !STB_LOCAL ... -> 
	== STB_WEAK ...

** Researching COMDAT **

    + -ffunction-sections separate functions for the linker (COMDAT)
        + sounds like you put this data into separate sections
	+ cf. MAKE_DECL_ONE_ONLY: "extra copies in multiple
	  translation units will be discarded by the linker. Define
	  this macro if your object file format provides support for
	  this concept, such as the 'COMDAT' section flags in the
	  MS Windows PE/COFF format, and this support requires changes
	  to decl, such as putting it in a separate section.


    + hppa: The C++ ABI has changed incompatibly in GCC 4.0. COMDAT
	  subspaces are used for one-only code and data. This resolves
	  many of the previous problems in using C++ on this
	  target. However, the ABI is not compatible with the one
	  implemented under HP-UX 11 using secondary definitions.

    + 4.0 - COMDAT support re-enabled ...
    +   This patch stops entities with vague linkage from being
	declared as ELF weak symbols when HAVE_GAS_COMDAT_GROUP is
	true. This is mainly cosmetic, but could lead to subtle
	interoperability problems.
	Tested with cross to arm-none-eabi.
	OK to apply?

* Tackle this lower down:
    + hacked up version of g++ ...
    + -fvtable-thunk - more efficient ? - output more relocs ?
  