Skip to content

Commit

Permalink
* elf/dl-lookup.c (dl_new_hash): New functions.
Browse files Browse the repository at this point in the history
	(_dl_lookup_symbol_x): Rename hash to old_hash and don't compute
	value here.  Compute new-style hash value.  Pass new hash value
	and reference to variable with the old value to do_lookup_x.
	(_dl_setup_hash): If DT_GNU_HASH is defined, use it and not
	old-style hash table.
	(_dl_debug_bindings): Pass new hash value and reference to variable
	with the old value to do_lookup_x.
	* elf/do-lookup.h (do_lookup_x): Accept additional parameter with
	new-style hash value and change old-style hash value parameter to
	be a reference.  Reoganize functions to determine whether
	new-style hash table is available.  Only fall back on old-style
	table.  If old-style hash value is needed, compute it here.
	* elf/dynamic-link.h (elf_get_dynamic_info): Relocate DT_GNU_HASH
	entry.
	* elf/elf.h: Define SHT_GNU_HASH, DT_GNU_HASH, DT_TLSDEC_PLT,
	DT_TLSDEC_GOT.  Adjust DT_ADDRNUM.
	* include/link.h (struct link_map): Add l_gnu_bitmask_idxbits,
	l_gnu_shift, l_gnu_bitmask, l_gnu_buckets and l_gnu_chain_zero.
	* Makeconfig: If linker supports --hash-style option add it to all
	linker command lines to build DSOs.
	* config.make.in: Define have-hash-style.
	* configure.in: Test whether linker supports --hash-style option.

	* elf/dl-misc.c (_dl_name_match_p): Make MAP parameter const.
	* sysdeps/generic/ldsodefs.h: Adjust prototype.
  • Loading branch information
Ulrich Drepper committed Jul 10, 2006
1 parent f3be81a commit 871b915
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 139 deletions.
29 changes: 29 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
2006-07-10 Ulrich Drepper <drepper@redhat.com>

* elf/dl-lookup.c (dl_new_hash): New functions.
(_dl_lookup_symbol_x): Rename hash to old_hash and don't compute
value here. Compute new-style hash value. Pass new hash value
and reference to variable with the old value to do_lookup_x.
(_dl_setup_hash): If DT_GNU_HASH is defined, use it and not
old-style hash table.
(_dl_debug_bindings): Pass new hash value and reference to variable
with the old value to do_lookup_x.
* elf/do-lookup.h (do_lookup_x): Accept additional parameter with
new-style hash value and change old-style hash value parameter to
be a reference. Reoganize functions to determine whether
new-style hash table is available. Only fall back on old-style
table. If old-style hash value is needed, compute it here.
* elf/dynamic-link.h (elf_get_dynamic_info): Relocate DT_GNU_HASH
entry.
* elf/elf.h: Define SHT_GNU_HASH, DT_GNU_HASH, DT_TLSDEC_PLT,
DT_TLSDEC_GOT. Adjust DT_ADDRNUM.
* include/link.h (struct link_map): Add l_gnu_bitmask_idxbits,
l_gnu_shift, l_gnu_bitmask, l_gnu_buckets and l_gnu_chain_zero.
* Makeconfig: If linker supports --hash-style option add it to all
linker command lines to build DSOs.
* config.make.in: Define have-hash-style.
* configure.in: Test whether linker supports --hash-style option.

* elf/dl-misc.c (_dl_name_match_p): Make MAP parameter const.
* sysdeps/generic/ldsodefs.h: Adjust prototype.

2006-06-27 Ulrich Drepper <drepper@redhat.com>

* elf/dl-load.c (open_path): Fix test to determine whether DSO is
Expand Down
11 changes: 10 additions & 1 deletion Makeconfig
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,20 @@ LDFLAGS.so += $(relro-LDFLAGS)
LDFLAGS-rtld += $(relro-LDFLAGS)
endif

ifeq (yes,$(have-hash-style))
# For the time being we unconditionally use 'both'. At some time we
# should declare statically linked code as 'out of luck' and compile
# with --hash-style=gnu only.
hashstyle-LDFLAGS = -Wl,--hash-style=both
LDFLAGS.so += $(hashstyle-LDFLAGS)
LDFLAGS-rtld += $(hashstyle-LDFLAGS)
endif

# Command for linking programs with the C library.
ifndef +link
+link = $(CC) -nostdlib -nostartfiles -o $@ \
$(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(addprefix $(csu-objpfx),$(start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
Expand Down
6 changes: 4 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2006-05-24
GNU C Library NEWS -- history of user-visible changes. 2006-07-10
Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
See the end for copying conditions.

Expand All @@ -13,7 +13,7 @@ Version 2.5
* Allow system admin to configure getaddrinfo with the /etc/gai.conf file.
Implemented by Ulrich Drepper.

* New Linux interfaces: splice, tee, sync_file_range, vmsplace.
* New Linux interfaces: splice, tee, sync_file_range, vmsplice.

* New iconv module for MIK. Contributed by Alexander Shopov.

Expand All @@ -31,6 +31,8 @@ Version 2.5
* The interfaces introduced in RFC 3542 have been implemented by
Ulrich Drepper.

* Support for the new ELF hash table format was added by Ulrich Drepper.


Version 2.4

Expand Down
1 change: 1 addition & 0 deletions config.make.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ have-libcap = @have_libcap@
have-cc-with-libunwind = @libc_cv_cc_with_libunwind@
fno-unit-at-a-time = @fno_unit_at_a_time@
bind-now = @bindnow@
have-hash-style = @libc_cv_hashstyle@

static-libgcc = @libc_cv_gcc_static_libgcc@

Expand Down
30 changes: 29 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"

ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_files=''

# Initialize some variables set by options.
Expand Down Expand Up @@ -5876,6 +5876,33 @@ echo "$as_me:$LINENO: result: $libc_cv_fpie" >&5
echo "${ECHO_T}$libc_cv_fpie" >&6
echo "$as_me:$LINENO: checking for --hash-style option" >&5
echo $ECHO_N "checking for --hash-style option... $ECHO_C" >&6
if test "${libc_cv_hashstyle+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
-fPIC -shared -o conftest.so conftest.c
-Wl,--hash-style=both -nostdlib 1>&5'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }
then
libc_cv_hashstyle=yes
else
libc_cv_hashstyle=no
fi
rm -f conftest*
fi
echo "$as_me:$LINENO: result: $libc_cv_hashstyle" >&5
echo "${ECHO_T}$libc_cv_hashstyle" >&6
fi
echo "$as_me:$LINENO: checking for -fno-toplevel-reorder" >&5
Expand Down Expand Up @@ -8496,6 +8523,7 @@ s,@ASFLAGS_config@,$ASFLAGS_config,;t t
s,@libc_cv_z_combreloc@,$libc_cv_z_combreloc,;t t
s,@libc_cv_z_execstack@,$libc_cv_z_execstack,;t t
s,@libc_cv_fpie@,$libc_cv_fpie,;t t
s,@libc_cv_hashstyle@,$libc_cv_hashstyle,;t t
s,@fno_unit_at_a_time@,$fno_unit_at_a_time,;t t
s,@libc_cv_ssp@,$libc_cv_ssp,;t t
s,@libc_cv_have_initfini@,$libc_cv_have_initfini,;t t
Expand Down
16 changes: 16 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,22 @@ EOF
rm -f conftest*])

AC_SUBST(libc_cv_fpie)

AC_CACHE_CHECK(for --hash-style option,
libc_cv_hashstyle, [dnl
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
-fPIC -shared -o conftest.so conftest.c
-Wl,--hash-style=both -nostdlib 1>&AS_MESSAGE_LOG_FD])
then
libc_cv_hashstyle=yes
else
libc_cv_hashstyle=no
fi
rm -f conftest*])
AC_SUBST(libc_cv_hashstyle)
fi

AC_CACHE_CHECK(for -fno-toplevel-reorder, libc_cv_fno_toplevel_reorder, [dnl
Expand Down
56 changes: 47 additions & 9 deletions elf/dl-lookup.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Look up a symbol in the loaded objects.
Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -72,6 +72,16 @@ struct sym_val
#include "do-lookup.h"


static uint_fast32_t
dl_new_hash (const char *s)
{
uint_fast32_t h = 5381;
for (unsigned char c = *s; c != '\0'; c = *++s)
h = h * 33 + c;
return h & 0xffffffff;
}


/* Add extra dependency on MAP to UNDEF_MAP. */
static int
internal_function
Expand Down Expand Up @@ -206,7 +216,8 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
const struct r_found_version *version,
int type_class, int flags, struct link_map *skip_map)
{
const unsigned long int hash = _dl_elf_hash (undef_name);
const uint_fast32_t new_hash = dl_new_hash (undef_name);
unsigned long int old_hash = 0xffffffff;
struct sym_val current_value = { NULL, NULL };
struct r_scope_elem **scope = symbol_scope;

Expand All @@ -229,8 +240,9 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
/* Search the relevant loaded objects for a definition. */
for (size_t start = i; *scope != NULL; start = 0, ++scope)
{
int res = do_lookup_x (undef_name, hash, *ref, &current_value, *scope,
start, version, flags, skip_map, type_class);
int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
&current_value, *scope, start, version, flags,
skip_map, type_class);
if (res > 0)
break;

Expand Down Expand Up @@ -301,9 +313,9 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
struct sym_val protected_value = { NULL, NULL };

for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
if (do_lookup_x (undef_name, hash, *ref, &protected_value,
*scope, i, version, flags, skip_map,
ELF_RTYPE_CLASS_PLT) != 0)
if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
&protected_value, *scope, i, version, flags,
skip_map, ELF_RTYPE_CLASS_PLT) != 0)
break;

if (protected_value.s != NULL && protected_value.m != undef_map)
Expand Down Expand Up @@ -352,6 +364,31 @@ _dl_setup_hash (struct link_map *map)
Elf_Symndx *hash;
Elf_Symndx nchain;

if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
+ DT_THISPROCNUM + DT_VERSIONTAGNUM
+ DT_EXTRANUM + DT_VALNUM] != NULL, 1))
{
Elf32_Word *hash32
= (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
+ DT_THISPROCNUM + DT_VERSIONTAGNUM
+ DT_EXTRANUM + DT_VALNUM]);
map->l_nbuckets = *hash32++;
Elf32_Word symbias = *hash32++;
Elf32_Word bitmask_nwords = *hash32++;
/* Must be a power of two. */
assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
map->l_gnu_shift = *hash32++;

map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;

map->l_gnu_buckets = hash32;
hash32 += map->l_nbuckets;
map->l_gnu_chain_zero = hash32 - symbias;
return;
}

if (!map->l_info[DT_HASH])
return;
hash = (void *) D_PTR (map, l_info[DT_HASH]);
Expand Down Expand Up @@ -399,9 +436,10 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|| GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
&& undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
{
const unsigned long int hash = _dl_elf_hash (undef_name);
const uint_fast32_t new_hash = dl_new_hash (undef_name);
unsigned long int old_hash = 0xffffffff;

do_lookup_x (undef_name, hash, *ref, &val,
do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
undef_map->l_local_scope[0], 0, version, 0, NULL,
type_class);

Expand Down
4 changes: 2 additions & 2 deletions elf/dl-misc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Miscellaneous support functions for dynamic linker
Copyright (C) 1997-2002, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 1997-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Expand Down Expand Up @@ -308,7 +308,7 @@ _dl_dprintf (int fd, const char *fmt, ...)
/* Test whether given NAME matches any of the names of the given object. */
int
internal_function
_dl_name_match_p (const char *name, struct link_map *map)
_dl_name_match_p (const char *name, const struct link_map *map)
{
if (strcmp (name, map->l_name) == 0)
return 1;
Expand Down
Loading

0 comments on commit 871b915

Please sign in to comment.