DT_GNU_HASH serves the same purpose as DT_HASH, however it is a distinct
and faster apprach implemented and designed in the GNU toolchain in 2006.
DT_GNU_HASH is preferred whenever available.
Original GNU benchmarks claim 50% faster dynamic linking time.
https://www.sourceware.org/ml/binutils/2006-06/msg00418.html
Code based on FreeBSD and OpenBSD, both were based on DragonFlyBSD.
Define Elf_Hash struct that contains ELF/SYSV and GNU hash checksum.
Implement _rtld_gnu_hash() for DT_GNU_HASH.
Adapt existing code to compute all Elf_Hash types, instead of only
the ELF/SYSV one.
Rename _rtld_elf_hash() to _rtld_sysv_hash() to match the GNU toolchain
terminology.
_rtld_gnu_hash() uses Dan Bernstein's string hash function posted eons ago
on comp.lang.c.
The COMBREL logic predates thread-safety of the dynamic linker and
breaks the use of shared locks for the common symbol lookup case. It is
unlikely to provide any benefit for lazy binding or PLT lookups, so
provide equivalent functionality in the non-PLT relocation handling loop
by checking if the symbol used by the current relocation is the same as
the one used during the last lookup. No inter-object cachine is done as
it is also unlikely to be benefical.
Testing with Firefox startup on AMD64 shows a small performance gain by
the new method.
vector. This can normally be found via __ps_strings, but libc is
initialised too early when linked dynamically and doesn't have access to
it yet, so provide an alternative mechanism via ld.elf_so.
Bump libc minor.
_rtld_tls_allocate and _rtld_tls_free. libpthread uses this functions to
setup the thread private area of all new threads. ld.elf_so is
responsible for setting up the private area for the initial thread.
Similar functions are called from _libc_init for static binaries, using
dl_iterate_phdr to access the ELF Program Header.
Add test cases to exercise the different TLS storage models. Test cases
are compiled and installed on all platforms, but are skipped on
platforms not marked for TLS support.
This material is based upon work partially supported by
The NetBSD Foundation under a contract with Joerg Sonnenberger.
It is inspired by the TLS support in FreeBSD by Doug Rabson and the
clean ups of the DragonFly port of the original FreeBSD modifications.
act like the other versions.
In _rtld_bind, if the result is 0, call _rtld_die.
Initialize _rtld_sym_zero.st_value to -_rtld_objself.maprelocbase. Now when
the symbol is resolved, st_value + maprelocbase will equal 0 and the above
check in _rtld_bind will fire and a call to NULL will be avoided.
_rtld_find_symdef use _rtld_symlook_default.
This reduces the code size and means that dlsym(RTLD_DEFAULT,...) has the
correct lookup order.
Reviewed by kleink. Thanks.
versions used by others in libc weak, so that we have:
name: weak
__name: weak
___name: strong
- Add __name strong aliases of the dlfcn names in ld.elf_so, so that we have:
name: strong
__name: strong
This allows ld.elf_so to self-resolve both the name and __name variants
of the dlfcn functions, the former being required for dlfcn support in
applications, the latter being required for dlfcn support in libc.
Fixes the problem described in:
http://mail-index.netbsd.org/tech-toolchain/2004/07/17/0000.html
Reviewed by Nick.
before referencing object's DAG. This makes it possible for
C++ exceptions to work across shared libraries.
Patch taken from FreeBSD: src/libexec/rtld-elf/rtld.c: 1.67 -> 1.68,
committed there by kan@FreeBSD.org.
Previously dlsym resolved to the version in crt0.o or libc which would
mean that the caller's shared object couldn't be determined correctly
using __builtin_return_address(0).
Mainly from FreeBSD, but adapted by me. Benefits of this solutions are:
- backward comptibility maintained
- existing broken binaries are fixed with a new ld.elf_so
- __mainprog_obj can be removed from crt0.o
- we do the same thing as FreeBSD
Fixes PR 22067.
OKed by Jason and Christos.