Linker hacking:

    + dl-open.c (dl_open_worker):
	-> dl-reloc.c (_dl_relocate_object)
	   -> dynamic-link.h etc.
#0  _dl_lookup_symbol_x (undef_name=Variable "undef_name" is not available.
) at dl-lookup.c:233
#1  0x4000a3e4 in _dl_relocate_object (l=0x81a7e20, scope=0x81a7fc0, lazy=1, consider_profiling=0) at dl-machine.h:426
#2  0x413ff8b7 in dl_open_worker (a=0xbfffc690) at dl-open.c:322
    ie. lazy == 1 - but still doing lots of symbol lookups (?)
	[ debug relocs ]

	dl-machine.h uses the 'RESOLVE*' macros to do lookups,
	from (inlined) elf_machine_rel* function.

	ELF_DYNAMIC_RELOCATE(...)
	    -> elf_machine_runtime_setup() ...
	    -> ELF_DYNAMIC_DO_REL()	   \ must do lots of chewing
	    -> ELF_DYNAMIC_DOR_RELA()	   /

	do-rel.h (elf_dynamic_do_rel)
	    + does most of the work ...

Doing a 'full' make - it seems big chunks are included in libc:
      dl-open.c etc.

       make -C .. objdir=`pwd` -C elf subdir_lib

    include/link.h: linker structures.

struct link_map
    - describes a loaded shared object;
    has lots of struct r_scope_elem 

core:
    do-lookup.h (do_lookup_x)
	+ looks through a single scope (list of link maps
	  / libraries) for a symbol.

    dl-lookup.c (_dl_lookup_symbol_x)
	+ passed a NULL terminated array of
	  scopes (4th arg)

    callers:
	dl-reloc.c (RESOLVE, RESOLVE_MAP)
	dl-rtld.c
	    + (dl_main): debugging code
	    + (struct: .dl_lookup_symbol_x) - hook
	dl-runtime.c
	    + (profile_fixup) - profiling only
	    + (fixup) - the real entry point
		        called per PLT entry via.
			the trampoline.
	dl-open.c
	    + _dl_open_worker - _Loads_ of OO.o linkage calls from here.


	dl-deps.c (_dl_map_object_deps)
	    + builds the dep list we want into l_searchlist
		+ only seems to work for dlopened' stuff.
		    ( & deps )
	    + called from:
		+ rtld _dl_map_object_deps vtable
    
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
	+ our local symbol info:

elf/elf.h:

typedef struct
{
  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
  Elf32_Addr	st_value;		/* Symbol value */
  Elf32_Word	st_size;		/* Symbol size */
  unsigned char	st_info;		/* Symbol type and binding */
  unsigned char	st_other;		/* Symbol visibility */
  Elf32_Section	st_shndx;		/* Section index */
} Elf32_Sym;


st_info: 

/* Legal values for ST_BIND subfield of st_info (symbol binding).  */

#define STB_LOCAL	0		/* Local symbol */
#define STB_GLOBAL	1		/* Global symbol */
#define STB_WEAK	2		/* Weak symbol */
#define	STB_NUM		3		/* Number of defined types.  */
#define STB_LOOS	10		/* Start of OS-specific */
#define STB_HIOS	12		/* End of OS-specific */
#define STB_LOPROC	13		/* Start of processor-specific */
#define STB_HIPROC	15		/* End of processor-specific */
    
#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)

if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)

_dl_lookup_symbol_skip (...)
	+ only looks at objects loaded after
	  the described object - pretty pants, but better.


fixup:
    passed 'link_map' l -> scope
    Have Sym *symtab; & local sym; ie. can:

    if (ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
       ... do something fast ...

    switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) {
	   is or is not versioned ...
	      [ versioned symbols can be dog slow too ]
    }

    Passes l->l_scope for _both_ methods.
	+ l_searchlist (?) - DT_NEEDED dependencies & their deps in order :-)
	    + ... looks ideal ... [ dependency order ? ]


LD_DEBUG=<anything but reloc> stops 'fixup' being called;
    + also stops things working nastily.