-Bdirect linking:

+ need to elide 'vague linkage' stuff [ re-use regexp map logic ? ]

+ behaves like an optimial -Bsymbolic in-library +
+ stores library index [1 per symbol ?] for the dynamic sym table
	[ sol seems to do somewhat better than that ]

+ elflink.c:

	bfd_boolean
	bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
					    struct elf_link_hash_entry *h)

	+ calls _bfd_elf_strtab_add (...)
	+ sets (elf_link_hash_entry) h->dynstr_index to that ...
		+ of course - string table can contain anything (?)
		+ we want a symbol-table index (?)

		.dynsym <symbol data> .dynstr <string data>
		+ Precisely 1 entry in '.direct' for every entry
		  in .dynsym
			+ elf_hash_table(info)->dynsymcount ...

	+ bfd_elf_size_dynamic_sections:
		+ working nicely

	+ Need the list of external libraries (section?)
		+ what is that ?
		+ DT_NEEDED ?
			+ lots of NEEDED libs
			+ get a clear order ?
		+ [ elf_add_dt_needed_tag ]:
			+ goes through '.dynamic' section
			+ pages in all Elf_Internal_Dyn records
				+ sub-sets on DT_NEEDED
				+ etc. ...
			+ slow but reliable ;-)
		+ *Should*
			+ count index of existing DT_NEEDEDs
				+ copy elf_dt_name (bfd)
***				& assign elf_dt_index (bfd)
			+ then just use elsewhere ...

	+ elf_link_output_extsym ...
		+ build .direct here ...
		+ use the 'bfd_link_hash_entry'
			+ switch on type
			+ for 'def'
				+ asection *section [ symbol section ]
			+ [ what it resolves to ? ]
				+ is this the post link data ?
				+ [ what about weak / multiple hits !? ]
			+ section->owner == bfd ...
				+ bfd.h:3942 
					+ const char *filename
			+ elf_dt_name (bfd) = soname ...
				(const char *)
			+ so we can get that easily.

	+ grok for -Bsymbolic foo ...
		+ Carefully examine the -Bsymbolic
		  platform-dependent piece ..
		+ looks like an optimisation with
		  copy relocs
* notes:
	+ bfd_link_hash_entry: include/bfdlink.h
	+ elf_link_hash_entry: bfd/eld-bfd.h
	+ asection - bfd_section ? (bfd-in2.h)


* FIXME:
	+ executables - also require this data ...
		[ check code paths etc. ... ]
	+ do we need a new SHT_DIRECT section header ?

* Need to nail objdump:

  % elfdump -y prog

    Syminfo Section:  .SUNW_syminfo
	 index  flgs         bound to           symbol
	  ...
	  [15]  DBL      [1] ./foo.so           foo
	  [19]  DBL      [3] ./bar.so           bar


bfd_set_section_contents (?)
	+ end of elf_link_input_bfd:
	+ end of bfd_elf_final_link ... etc.
	+ default ... o->flags & SEC_EXCLUDE (?)


** Runtime linker ...
    + cf. doc/link.txt:

    + include/link.h: (struct link_map):
	+ l_searchlist - array of DT_NEEDED deps.
	    + [ in what order ? ]
	+ what is l_reldeps ?

    + dl-lookup.c (_dl_lookup_symbol_x): hack here ...

    + run /opt/gcc/bin/ld-linux.so <file> explicitely ?
    + work out how to re-build & install elf quickly ... [!?]

libfixup.so - 31 symbols
    + 16bytes per sym - in .dynsym

  Elf32_Word	st_name;	- 4b
  Elf32_Addr	st_value;	- 4b
  Elf32_Word	st_size;	- 4b
  unsigned char	st_info;	- 1
  unsigned char	st_other;	- 1
  Elf32_Section	st_shndx;	- 2

    + ie 16bytes overall.

    + ie. _dl_lookup_symbol_x gets an Elf32_Sym **ref,
    + but we want an index instead ...
	+ symbol versioning ? / hash ?

    + -Bdirect - foo...

    + relocations ...
	+ rel.dyn - <addr> <r_info> - symbol index ...

    + cf. do-rel.h (elf_dynamic_do_rel):
	+ calls -> elf_machine_rel
	    + passing &symtab[ELFW(R_SYM) (r->r_info)]


+ where is elf_machine_rel defined (!?)
    + sysdeps/i386/dl-machine.h

+ can we see if the sym reference is inside:
      const ElfW(Sym) *const symtab =
	(const void *) D_PTR (map, l_info[DT_SYMTAB]);

    + could it ever be inside anything else ? if not why
      have that hard-coded ?
	+ the elf_dynamic_do_rel - passes several sets of
	    + relocation types to elf_dynamic_do_##reloc

    + Ergo - everything (so far) looked up in
	   DT_SYMTAB (.dynsym)

** test harness
   + app was crashing since linked with -shared ;-)

** Linker test framework:
   + '~/bin/run'
	prefix=/opt/gcc
	sysroot=
	ulimit -c unlimited
	export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$prefix/lib:$sysroot/lib:$sysroot/usr/X11R6/lib:$sysroot/usr/lib:$sysroot/usr/local/lib:$sysroot/usr/openwin/lib:$sysroot/opt/kde3/lib:$sysroot/opt/gnome/lib:$sysroot/opt/gnome2/lib:$sysroot/opt/mozilla/lib"
	$prefix/lib/ld-linux.so.2 $@
   + use it to test the generated binaries ...


** Glibc build bits
   + setup kernel headers
   + symlink asm-i386 -> asm
   + add to glibc/version.h:
	#define CVSDATE "cvsdate"
	#define CONFHOST "i586-suse-linux"
   + hack sysd-sorted: move 'elf' to the front

+ binutils
	+ readelf ...
		+ 0xffff - unknown
		+ 0xfffe - vague
		+ 0 - self ...


+ Bit count for DT_NEEDED index:
	ls /opt/*/lib/*.so /usr/lib/*.so /usr/X11/lib/*.so /lib/*.so | wc -l
	533
	+ But we link to -very- few normally
		* need DT_NEEDED * stats ...

	+ LD_PRELOAD (etc.)
		+ add 'preloads' to head of dt_needed - add an offset ?
		+ have a global 'preload' scope (?)
			+ [what about a preload's recursive deps ?]


** Ultimate numbers:
	+ Before new glibc:
		+ 3968, 3978, 3983 Avg: 3980
	+ With new glibc [ no other changes ]
		+ 4224, 4238, 4250 Avg: 4240
		+ ie. 280ms slower [urgh ...]
	+ With <many> libraries -Bdirected
		+ 2378, 2387, 2389 Avg: 2385
	+ 40% faster (warm) startup
		+ measure time over dlopen ...
	+ With dlopen top/tail gettimeofdays:
		+ no -Bdirect: 2.693, 2.721, 2.714
		+ with it: 0.970, 0.968, 0.956

** Remaining issues:

        * How are new elf sections allocated ? and/or typically named
          I know DT_DIRECT / '.direct' are prolly beyond the pale

        * How should I handle LD_PRELOADs in the direct dl-lookup.c
          case ? - we should still do them clearly. Perhaps it'd
	  be possible to use the first N entries of the existing
	  searchlist (?)

        * Is there a better way to achieve what I do in dl-deps.c ?
	  the umpteen-string compares are clearly evil.

        * In binutils - what is the best way to filter out the
          important 'Vague Linkage' symbols ? clearly we don't want to
          bind any of them - the current approach is clearly a gross
	  hack.
		+ should we propagate this information from target
		  libraries ? ie. libc can advertise 'foo_baa' as not
		  to be direct linked against ?
		+ should the compiler generate / markup the vague
		  linkage pieces to avoid yet-another link map type
		  thing ?

        * If we fail to find the symbol in the direct scope should we
          check the dependants of that library - to allow some limited
          re-factoring later ? or just fallback to the global scope ?

        * Should we compress the .direct table more ? I can't envisage
          more than 12bits (4096) of DT_NEEDED libraries ever - prolly
          we should mask / save that space for future expansion
	  along with a few special values perhaps ?


    + Do we need to add an 'index' to 
	+ _bfd_generic_link_add_one_symbol (?)
	    sym -> value -> etc. ?
	    [ a section & and offset ]
	    * bfd_asymbol_value = base + value (?)
	+ [ Can we cram 1 bit into there ? 
	    we really want a 'is-vague' marker ]
	+ can be generated earlier ...
	+ is-vague, unknown, is-concrete tristate ?
    + seems to be 1 hash table ...
	+ linear load of symbols into it ...
	+ _bfd_elf_merge_symbol (?!)
	    + we return a new 'h' in *sym_hash ...
	    + need to setup foo on it ...
	+ 'elf_link_add_object_symbols'
	    + here !? ...

** You have to export LD_BIND_DIRECT=1

* TODO:
    + add 'direct' section in *applications*
	+ only use .direct if it is enabled in the app (etc.)
	+ make sure the app has a *sane* .direct section
	    + odd things seem to happen here ...
	+ (?!)


+ Without -Bdirect:
    28% of startup == do_lookup_x

+ [Foo!]
    + baa ...

    + for a in *.so; do readelf -r -W $a | grep '_ZThn' | cut -c 53-256 | sort | uniq; done | wc -l
 15661
    + for a in *.so; do readelf -r -W $a | grep -v '_ZThn' | cut -c 53-256 | sort | uniq; done | wc -l
164475
    + perhaps an extra 10% of relocations ...
	+ but are these plt or rel32 ? - grok again ?


* New patch:
    + Way better ...
    + works really nicely
    + for a in *.so; do if /opt/gcc/bin/objdump -x $a | grep DIRECT >& /dev/null; then echo "$a: direct"; else echo "$a: no direct"; fi;  done | grep 'no direct'
	libdb-4.2.so: no direct
	libdb_java-4.2.so: no direct
	libxmlsec1-nss.so: no direct
	libxmlsec1.so: no direct


A diff of LD_DEBUG=bindings
    + LD_DEBUG=bindings xml2cmp -types stdout ../../../unxlngi6.pro/misc/vbaobj.xml >& /tmp/indirect

michael@linux:/opt/OpenOffice/src680-m140/sc/source/ui/vba> diff /tmp/direct.2nd /tmp/indirect.2nd 
1135c1135
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL4cerrE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL4cerrE'

	This is (apparently) a static variable [ tagged extern in the header ]
	    cf. STLport-4.5/lib/obj/GCC/ReleaseD/iostream.o:
		    000002a0 g     O .bss   00000064 _ZN4_STL4cerrE
		STLport-4.5/src/iostream.cpp: _STLP_DECLSPEC ostream cerr(0);
	    cf. Every instance in xml2cmp/unxlngi6.pro/obj/*:
		00000000         *UND*  00000000 _ZN4_STL4cerrE
	    Do we link with 2 copies - 1 static, 1 dynamic ?

	    g++ -Wl,-z,combreloc -Wl,-z,defs -Wl,-rpath,'$ORIGIN' -Wl,-Bdirect -Wl,-export-dynamic -Wl,--noinhibit-exec -L../unxlngi6.pro/lib -L../lib -L/opt/OpenOffice/src680-m140/solenv/unxlngi6/lib -L/opt/OpenOffice/src680-m140/solver/680/unxlngi6.pro/lib -L/opt/OpenOffice/src680-m140/solenv/unxlngi6/lib -L/usr/lib/jvm/java/lib -L/usr/lib/jvm/java/jre/lib/i386 -L/usr/lib/jvm/java/jre/lib/i386/client -L/usr/lib/jvm/java/jre/lib/i386/native_threads -L/usr/X11R6/lib -L/opt/mozilla/lib \
	    ../unxlngi6.pro/obj/main.o \
	    ../unxlngi6.pro/obj/cr_html.o \
	    ../unxlngi6.pro/obj/cr_index.o \
	    ../unxlngi6.pro/obj/cr_metho.o \
	    ../unxlngi6.pro/obj/filebuff.o \
	    ../unxlngi6.pro/obj/parse.o \
	    ../unxlngi6.pro/obj/xmlelem.o \
	    ../unxlngi6.pro/obj/xmltree.o \
	     \
	     ../unxlngi6.pro/obj/cmdline.o \
	     ../unxlngi6.pro/obj/heap.o \
	     ../unxlngi6.pro/obj/sistr.o \
	     ../unxlngi6.pro/obj/syshelp.o \
	     ../unxlngi6.pro/obj/badcast.o \
	     -ldl -lpthread -lm -Wl,-Bdynamic -lstlport_gcc -o ../unxlngi6.pro/bin/xml2cmp
	     -rwxr-xr-x  1 michael users 152248 2005-11-30 12:20 ../unxlngi6.pro/bin/xml2cmp
	     -------------
	     michael@linux:/opt/OpenOffice/src680-m140/xml2cmp/util> objdump -T ../unxlngi6.pro/bin/xml2cmp | grep cerr
	     08061960 g    DO .bss   00000064              _ZN4_STL4cerrE

	+ Wow - it deliberately creates this duplicate DO .bss symbol [!?] why !?

1158c1158
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL13_Filebuf_base12_M_page_sizeE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL13_Filebuf_base12_M_page_sizeE'
	+ symbol: _STL::_Filebuf_base::_M_page_size
	    + again undefined in xml2cmp's *.o

 
1160c1160
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base6badbitE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL8ios_base6badbitE'
1286c1286
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8numpunctIcE2idE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL8numpunctIcE2idE'
1294c1294
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL7codecvtIcc15__stl_mbstate_tE2idE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL7codecvtIcc15__stl_mbstate_tE2idE'
1301c1301
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL4coutE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL4coutE'
1347c1347
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base7goodbitE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL8ios_base7goodbitE'

	symbol: _STL::ios_base::goodbit

1360c1360
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL5ctypeIcE2idE'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL5ctypeIcE2idE'
1440c1440
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE6xsgetnEPci'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE6xsgetnEPci'
1442c1442
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE5uflowEv'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE5uflowEv'
1444,1445c1444,1445
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE6xsputnEPKci'
<       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE10_M_xsputncEci'
---
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE6xsputnEPKci'
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE10_M_xsputncEci'
2334a2335,2380
>       7507:   binding file xml2cmp to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEE6xsputnEPKci'
>       7507:   binding file /libstlport_gcc.so to /lib/tls/libc.so.6: normal symbol `putc' [GLIBC_2.0]
>       7507:   binding file xml2cmp to /usr/lib/libstdc++.so.6: normal symbol `_ZdlPv' [GLIBCXX_3.4]
>       7507:   binding file xml2cmp to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base4InitD1Ev'
>       7507:   binding file xml2cmp to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base9_Loc_initD1Ev'
>       7507:   binding file /lib/tls/libc.so.6 to /lib/tls/libc.so.6: normal symbol `free' [GLIBC_2.0]
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base15_S_uninitializeEv'
>       7507:   binding file /libstlport_gcc.so to xml2cmp: normal symbol `_ZN4_STL9basic_iosIcNS_11char_traitsIcEEE5rdbufEPNS_15basic_streambufIcS2_EE'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_SgI20stdio_streambuf_baseD2Ev'
>       7507:   binding file /libstlport_gcc.so to /lib/tls/libc.so.6: normal symbol `fflush' [GLIBC_2.0]
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIcNS_11char_traitsIcEEED2Ev'
>       7507:   binding file /libstlport_gcc.so to /usr/lib/libstdc++.so.6: normal symbol `_ZdlPv' [GLIBCXX_3.4]
>  com.sun.star.uno.XComponentContext      7507:        binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL13basic_filebufIwNS_11char_traitsIwEEE5closeEv'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL13_Filebuf_base8_M_closeEv'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL13basic_filebufIwNS_11char_traitsIwEEE21_M_deallocate_buffersEv'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL15basic_streambufIwNS_11char_traitsIwEEED2Ev'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_baseD2Ev'
>       7507:
>       7507:   calling fini: /lib/libdl.so.2 [0]
>       7507:
>       7507:   binding file /lib/libdl.so.2 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:
>       7507:   calling fini: /lib/tls/libpthread.so.0 [0]
>       7507:
>       7507:   binding file /lib/tls/libpthread.so.0 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:
>       7507:   calling fini: /libstlport_gcc.so [0]
>       7507:
>       7507:   binding file /libstlport_gcc.so to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL8ios_base9_Loc_initD1Ev'
>       7507:   binding file /libstlport_gcc.so to /libstlport_gcc.so: normal symbol `_ZN4_STL6locale15_S_uninitializeEv'
>       7507:
>       7507:   calling fini: /usr/lib/libstdc++.so.6 [0]
>       7507:
>       7507:   binding file /usr/lib/libstdc++.so.6 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:
>       7507:   calling fini: /lib/tls/libm.so.6 [0]
>       7507:
>       7507:   binding file /lib/tls/libm.so.6 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:
>       7507:   calling fini: /lib/libgcc_s.so.1 [0]
>       7507:
>       7507:   binding file /lib/libgcc_s.so.1 to /lib/tls/libc.so.6: normal symbol `__cxa_finalize' [GLIBC_2.1.3]
>       7507:
>       7507:   calling fini: /lib/tls/libc.so.6 [0]
>       7507:



$ objdump -T `which xml2cmp` | grep '_ZN4_STL4cerrE'
08061960 g    DO .bss   00000064              _ZN4_STL4cerrE
$ objdump -T /opt/OpenOffice/src680-m140/solver/680/unxlngi6.pro/lib/libstlport_gcc.so | grep 'STL4cerr'
000c5200 g    DO .bss   00000064  Base        _ZN4_STL4cerrE

	 URK !? - why !? - what is the linker thinking ?

    + bfd: syms.c:
	    'DO' == BSF_OBJECT && BSF_DYNAMIC

elf.c:
      else if ((flags & BSF_OBJECT) != 0)
	type = STT_OBJECT;


<micha> That should be the COPY relocs, right?
<micha> Accessing global data from shared apps needs to produce a COPY
reloc in the app and of course the associated space (of the size of
the symbol) in .bss
<michael_> quite possibly,
<michael_> it's something I didn't understand,
* michael_ needs to learn about COPY relocs,
* michael_ has no real idea why it is necessary to have a COPY reloc,
<micha> Ah, I can explain that ;)
<michael_> but - what I do see, is that eg. libstlport's -Bdirect
links directly to it's copy of 'cerr' and the main app to it's ;-)
<michael_> => seriously bad things happen,
<micha> That shouldn't happen, right.  Every reference to such symbol
needs to refer to the copy of the app.
<michael_> right;
<michael_> but - presumably this also wastes a ton of space ?
* michael_ wonders how much .bss bloat gets caused by this,
<michael_> all vtables are 'DO' it seems
<michael_> I guess it's only for things referred to in the main app
though; so ...
<micha> Hmm, wait, I can't explain it fully if I think about it.  It's
a i386 ABI only thingy, and applies only to apps which themself are
not compiled PIC, i.e. refer to the symbol in question directly,
instead of using the GOT.

    + Can we elide potential COPY_RELOCs - by skipping
	+ 'D' symbols in dl-lookup.c ? yes - is this slow though ?

    + How many 'D' symbols are we talking about ?
	+ how many relocs point to them ?
	+ more relocstat maths ?


** LD_PRELOAD investigation ...

*** An LD_PRELOAD has the following effect:

michael@linux:/opt/gcc/src/test> LD_LIBRARY_PATH=. LD_DEBUG=direct LD_PRELOAD=/opt/gnome/lib/libgtk-x11-2.0.so:/opt/gnome/lib/libORBit-2.so:/opt/gnome/lib/libglib-2.0.so ./ld-linux.so.2 ./app 2>&1 | grep Append
     25334:     Append object 0 ''
     25334:     Append object 1 '/opt/gnome/lib/libgtk-x11-2.0.so'
     25334:     Append object 2 '/opt/gnome/lib/libORBit-2.so'
     25334:     Append object 3 '/opt/gnome/lib/libglib-2.0.so'

    + Hence by storing map->npreloads
	- we can foo the baa ?
	+ just by taking 1->npreloads from l_searchlist.r_list ...x

    + What happens for the other libraries though ?
	+ 'openaux' - calling into libc ...

     25334:     Append object 4 './liblib.so'
     25334:     Append object 5 './libfixup.so'
     25334:     Append object 6 './libb.so'
     25334:     Append object 7 './liba.so'
     25334:     Append object 8 '/usr/lib/libstdc++.so.6'
     25334:     Append object 9 '/lib/tls/libm.so.6'
     25334:     Append object 10 '/lib/libgcc_s.so.1'
     25334:     Append object 11 '/lib/tls/libc.so.6'
     25334:     Append object 12 '/opt/gnome/lib/libgdk_pixbuf-2.0.so.0'
     25334:     Append object 13 '/opt/gnome/lib/libgdk-x11-2.0.so.0'
     25334:     Append object 14 '/opt/gnome/lib/libpangocairo-1.0.so.0'
     25334:     Append object 15 '/opt/gnome/lib/libpango-1.0.so.0'
     25334:     Append object 16 '/opt/gnome/lib/libatk-1.0.so.0'
     25334:     Append object 17 '/opt/gnome/lib/libgobject-2.0.so.0'
     25334:     Append object 18 '/opt/gnome/lib/libgmodule-2.0.so.0'
     25334:     Append object 19 '/lib/libdl.so.2'
     25334:     Append object 20 '/usr/lib/libcairo.so.2'
     25334:     Append object 21 '/usr/lib/libfreetype.so.6'
     25334:     Append object 22 '/usr/lib/libfontconfig.so.1'
     25334:     Append object 23 '/usr/X11R6/lib/libXrender.so.1'
     25334:     Append object 24 '/usr/X11R6/lib/libX11.so.6'
     25334:     Append object 25 '/usr/X11R6/lib/libXext.so.6'
     25334:     Append object 26 '/usr/lib/libpng12.so.0'
     25334:     Append object 27 '/lib/libz.so.1'
     25334:     Append object 28 '/usr/lib/libglitz.so.1'
     25334:     Append object 29 '/usr/lib/libpopt.so.0'
     25334:     Append object 30 '/opt/gnome/lib/libgthread-2.0.so.0'
     25334:     Append object 31 '/lib/tls/libpthread.so.0'
     25334:     Append object 32 './ld-linux.so.2'
     25334:     Append object 33 '/usr/X11R6/lib/libXrandr.so.2'
     25334:     Append object 34 '/usr/X11R6/lib/libXi.so.6'
     25334:     Append object 35 '/usr/X11R6/lib/libXinerama.so.1'
     25334:     Append object 36 '/usr/X11R6/lib/libXcursor.so.1'
     25334:     Append object 37 '/usr/X11R6/lib/libXfixes.so.3'
     25334:     Append object 38 '/opt/gnome/lib/libpangoft2-1.0.so.0'
     25334:     Append object 39 '/usr/lib/libexpat.so.0'

Fixme:
    map->l_faked (?!)
	+ affects order of l_searchlist ...
	+ 'preloads' - local to 'dl_main'
		+ do_preload called a lot.
	+ discarded after use ...

    + how does the recursive load of sub-libraries work ?
	+ do they get preloads ?
	+ openaux - calling into libc itself ?
	    + => no debug (?)
		+ openaux
		    -> (dl-load.c): _dl_map_object
		    -> always passes '0' for preloaded.
			-> [ a boolean anyway ]
		    -> _dl_new_object
	+ how do dependant libs get their
	  l_searchpath setup ?, or even their
	  direct section ?
	+ 'dl_open_worker'
	    + calls dl_map_object_deps ...

    + Where does the searchlist come from !?



*** No reliable timing is possible on SL 10.0 ...
    + the thing is impossible ...
        + use the 'gettimeofday' patch ?

New numbers:

LD_BIND_DIRECT - no redirect:

003250 1 } PERFORMANCE - DesktopOpenClients_Impl()
003732 1 } PERFORMANCE - DesktopOpenClients_Impl()
003243 1 } PERFORMANCE - DesktopOpenClients_Impl()
003666 1 } PERFORMANCE - DesktopOpenClients_Impl()



LD_BIND_DIRECT & after 'redirect'

005086 1 } PERFORMANCE - DesktopOpenClients_Impl()
004942 1 } PERFORMANCE - DesktopOpenClients_Impl()
004747 1 } PERFORMANCE - DesktopOpenClients_Impl()
004755 1 } PERFORMANCE - DesktopOpenClients_Impl()

005086 004942 004747 004755 + + + p 4 / p
Avg: 4882ms


** (re-install) package **

rpm -U --replacefiles --replacepkgs ...


no LD_BIND_DIRECT:
006361 1 } PERFORMANCE - DesktopOpenClients_Impl()
005964 1 } PERFORMANCE - DesktopOpenClients_Impl()
006172 1 } PERFORMANCE - DesktopOpenClients_Impl()
006324 1 } PERFORMANCE - DesktopOpenClients_Impl()

006361 005964 006172 006324 + + + p 4 / p

Avg: 6205ms

Saving: 1325ms

With a heavily instrumented, consistent glibc RPM:
I get:

    7414:     _dl_map_object_deps ''
      7414:     Append object 0 ''
      7414:     Append object 1 '/opt/gnome/lib/libglib.so'
      7414:     Append object 2 '/lib/tls/librt.so.1'
      7414:     Append object 3 '/lib/libacl.so.1'
      7414:     Append object 4 '/lib/libselinux.so.1'
      7414:     Append object 5 '/lib/tls/libc.so.6'
      7414:     Append object 6 '/lib/tls/libpthread.so.0'
      7414:     Append object 7 '/lib/ld-linux.so.2'
      7414:     Append object 8 '/lib/libattr.so.1'
      7414:      no dl_direct set 0
      7414:     
      7414:     calling init: /lib/tls/libpthread.so.0
      7414:     
      7414:     
      7414:     calling init: /lib/tls/libc.so.6
      7414:     
      7414:     
      7414:     calling init: /lib/libattr.so.1
      7414:     
      7414:     
      7414:     calling init: /lib/libselinux.so.1
      7414:     
      7414:     
      7414:     calling init: /lib/libacl.so.1
      7414:     
      7414:     
      7414:     calling init: /lib/tls/librt.so.1
      7414:     
      7414:     
      7414:     calling init: /opt/gnome/lib/libglib.so
      7414:     
      7414:     
      7414:     initialize program: /bin/ls
      7414:     
      7414:     
      7414:     transferring control: /bin/ls
      7414:     
      7414:     _dl_map_object_deps '/lib/libnss_compat.so.2'
      7414:     Append object 0 '/lib/libnss_compat.so.2'
      7414:     Append object 1 '/lib/libnsl.so.1'
      7414:     Append object 2 '/lib/tls/libc.so.6'
      7414:     Append object 3 '/lib/ld-linux.so.2'
      7414:      no dl_direct set 0
      7414:     
      7414:     calling init: /lib/libnsl.so.1
      7414:     
      7414:     
      7414:     calling init: /lib/libnss_compat.so.2
      7414:     
      7414:     _dl_map_object_deps '/lib/libnss_nis.so.2'
      7414:     Append object 0 '/lib/libnss_nis.so.2'
      7414:     Append object 1 '/lib/libnsl.so.1'
      7414:     Append object 2 '/lib/libnss_files.so.2'
      7414:     Append object 3 '/lib/tls/libc.so.6'
      7414:     Append object 4 '/lib/ld-linux.so.2'
      7414:      no dl_direct set 0
      7414:     
      7414:     calling init: /lib/libnss_files.so.2
      7414:     
      7414:     
      7414:     calling init: /lib/libnss_nis.so.2
      7414:     
/dev/null

	ie. _dl_map_object_deps is not called for most objects ...
	+ however - it is clearly called for all dlopened' ones.
		=> how is l_searchlist constructed per map ?
		+ Only 'main' objects have non-NULL l_searchlists ... (clearly)
		+ => can't be used for 'ld_preload' ?
			+ can't we have a 'global' preload list though ?
			+ hence '-z interpose' ?
		+ simplify the code (?) - perhaps not ...
			- preload deps of course



** The salcpprt problem:

	+ salcpprt.lib - 'operators'
	+ we link 'libsalcpprt.so'
	+ [ AH ! ... for solaris - no -Bdirect for this ]
		+ '-z interpose'

	+ On Linux: a static library:
		+ linked into ~everything.

objdump -t ../unxlngi6.pro/lib/libsalcpprt.a  | grep -v '\*UND\*'
In archive ../unxlngi6.pro/lib/libsalcpprt.a:

operators_new_delete.o:     file format elf32-i386

SYMBOL TABLE:
00000020 g     F .text  0000002a _ZdlPv
0000010a g     F .text  0000002a _ZdaPv
00000134 g     F .text  0000002a _Znaj
0000015e g     F .text  0000002a _ZdaPvRKSt9nothrow_t
00000188 g     F .text  0000002e _ZnajRKSt9nothrow_t
000001b6 g     F .text  0000002a _Znwj
000001e0 g     F .text  0000002a _ZdlPvRKSt9nothrow_t
0000020a g     F .text  0000002e _ZnwjRKSt9nothrow_t
00000000 l     F .text  0000001f _Z10deallocatePvRKN105_GLOBAL__N__opt_OpenOffice_ooo_build_build_oob680_m1_sal_cpprt_operators_new_delete.cxx_00000000_3241DF7B15AllocatorTraitsE
0000004a l     F .text  0000008e _Z8allocatejRKN105_GLOBAL__N__opt_OpenOffice_ooo_build_build_oob680_m1_sal_cpprt_operators_new_delete.cxx_00000000_3241DF7B15AllocatorTraitsE
00000238 l     F .text  00000034 _Z15default_handlerv
000000d8 l     F .text  00000032 _Z8allocatejRKN105_GLOBAL__N__opt_OpenOffice_ooo_build_build_oob680_m1_sal_cpprt_operators_new_delete.cxx_00000000_3241DF7B15AllocatorTraitsERKSt9nothrow_t
00000008 g     O .rodata        00000008 _ZN105_GLOBAL__N__opt_OpenOffice_ooo_build_build_oob680_m1_sal_cpprt_operators_new_delete.cxx_00000000_3241DF7B12ScalarTraits11g_signatureE
00000000 g     O .rodata        00000008 _ZN105_GLOBAL__N__opt_OpenOffice_ooo_build_build_oob680_m1_sal_cpprt_operators_new_delete.cxx_00000000_3241DF7B12VectorTraits11g_signatureE
00000000  w    O .data.DW.ref.__gxx_personality_v0      00000004 .hidden DW.ref.__gxx_personality_v0
00000000 l    d  DW.ref.__gxx_personality_v0    00000000 .group
00000000 l    d  DW.ref._ZTISt9bad_alloc        00000000 .group
00000000 l    d  .data.DW.ref.__gxx_personality_v0      00000000 .data.DW.ref.__gxx_personality_v0
00000000 l    d  .data.DW.ref._ZTISt9bad_alloc  00000000 .data.DW.ref._ZTISt9bad_alloc
00000000  w    O .data.DW.ref._ZTISt9bad_alloc  00000004 .hidden DW.ref._ZTISt9bad_alloc
