aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-lookup.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-08-23 23:36:47 +0000
committerUlrich Drepper <drepper@redhat.com>2001-08-23 23:36:47 +0000
commit647eb037f3d9dee0bf6e9410c6445c4223cf832a (patch)
treefc725d27ed5ffef239f38f7aabb08227b285dfd2 /elf/dl-lookup.c
parente515fbc5fd53ff4186249a2c070f41fd73aa1c2c (diff)
downloadglibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.zip
glibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.tar.gz
glibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.tar.bz2
Update.
2001-08-23 Jakub Jelinek <jakub@redhat.com> * elf/ldconfig.c (search_dir): Remove stale symlinks. 2001-08-23 Jakub Jelinek <jakub@redhat.com> * elf/dl-lookup.c (lookup_cache, lookup_cache_versioned): New. (_dl_lookup_symbol): Lookup relocations in cache and store successfull lookups in cache. (_dl_lookup_versioned_symbol): Likewise. * elf/dl-reloc.c (_dl_relocate_object): Initialize cache for relocation lookup. * elf/rtld.c (print_statistics): Output _dl_num_cache_relocations. * sysdeps/generic/ldsodefs.h (struct lookup_cache): New definition. (lookup_cache, lookup_cache_versioned): Add declarations. 2001-08-23 Ulrich Drepper <drepper@redhat.com> * stdlib/tst-random.c (main): Swap parameters in fail call. Patch by Pete Bevin <pete@petebevin.com>. 2001-08-23 Jakub Jelinek <jakub@redhat.com> * sysdeps/generic/inttypes.h: Use __gwchar_t instead of __wchar_t. * malloc/obstack.c: Indent preprocessor directives. Patch by Jim Meyering <meyering@ascend.com>.
Diffstat (limited to 'elf/dl-lookup.c')
-rw-r--r--elf/dl-lookup.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index fe833ba..48850e6 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -60,6 +60,7 @@ struct sym_val
/* Statistics function. */
unsigned long int _dl_num_relocations;
+unsigned long int _dl_num_cache_relocations;
/* We have two different situations when looking up a simple: with or
@@ -184,6 +185,9 @@ _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
const struct r_found_version *const version,
struct link_map *skip, int noexec, int noplt);
+struct lookup_cache _dl_lookup_cache;
+struct lookup_cache _dl_lookup_cache_versioned;
+
/* Search loaded objects' symbol tables for a definition of the symbol
UNDEF_NAME. */
@@ -201,6 +205,17 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
int noexec = elf_machine_lookup_noexec_p (reloc_type);
int noplt = elf_machine_lookup_noplt_p (reloc_type);
+ /* First check if we can find it in the cache. */
+ if (__builtin_expect (*ref == _dl_lookup_cache.sym, 0)
+ && _dl_lookup_cache.map == undef_map
+ && _dl_lookup_cache.noexec == noexec
+ && _dl_lookup_cache.noplt == noplt)
+ {
+ ++_dl_num_cache_relocations;
+ *ref = _dl_lookup_cache.ret;
+ return _dl_lookup_cache.value;
+ }
+
++_dl_num_relocations;
/* Search the relevant loaded objects for a definition. */
@@ -229,6 +244,11 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
break;
}
+ /* Update common information in the cache. */
+ _dl_lookup_cache.sym = *ref;
+ _dl_lookup_cache.noexec = noexec;
+ _dl_lookup_cache.noplt = noplt;
+
if (__builtin_expect (current_value.s == NULL, 0))
{
if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
@@ -238,6 +258,8 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
? reference_name
: (_dl_argv[0] ?: "<main program>")),
make_string (undefined_msg, undef_name));
+ _dl_lookup_cache.ret = NULL;
+ _dl_lookup_cache.value = 0;
*ref = NULL;
return 0;
}
@@ -254,6 +276,8 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
if (__builtin_expect (protected == 0, 1))
{
+ _dl_lookup_cache.ret = current_value.s;
+ _dl_lookup_cache.value = LOOKUP_VALUE (current_value.m);
*ref = current_value.s;
return LOOKUP_VALUE (current_value.m);
}
@@ -270,9 +294,13 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
if (protected_value.s == NULL || protected_value.m == undef_map)
{
+ _dl_lookup_cache.ret = current_value.s;
+ _dl_lookup_cache.value = LOOKUP_VALUE (current_value.m);
*ref = current_value.s;
return LOOKUP_VALUE (current_value.m);
}
+ _dl_lookup_cache.ret = *ref;
+ _dl_lookup_cache.value = LOOKUP_VALUE (undef_map);
return LOOKUP_VALUE (undef_map);
}
@@ -379,6 +407,18 @@ _dl_lookup_versioned_symbol (const char *undef_name,
int noexec = elf_machine_lookup_noexec_p (reloc_type);
int noplt = elf_machine_lookup_noplt_p (reloc_type);
+ /* First check if we can find it in the cache. */
+ if (__builtin_expect (*ref == _dl_lookup_cache_versioned.sym, 0)
+ && _dl_lookup_cache_versioned.map == undef_map
+ && _dl_lookup_cache_versioned.noexec == noexec
+ && _dl_lookup_cache_versioned.noplt == noplt
+ && _dl_lookup_cache_versioned.version == version)
+ {
+ ++_dl_num_cache_relocations;
+ *ref = _dl_lookup_cache_versioned.ret;
+ return _dl_lookup_cache_versioned.value;
+ }
+
++_dl_num_relocations;
/* Search the relevant loaded objects for a definition. */
@@ -430,6 +470,12 @@ _dl_lookup_versioned_symbol (const char *undef_name,
}
}
+ /* Update common information in the cache. */
+ _dl_lookup_cache_versioned.sym = *ref;
+ _dl_lookup_cache_versioned.noexec = noexec;
+ _dl_lookup_cache_versioned.noplt = noplt;
+ _dl_lookup_cache_versioned.version = version;
+
if (__builtin_expect (current_value.s == NULL, 0))
{
if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
@@ -440,6 +486,8 @@ _dl_lookup_versioned_symbol (const char *undef_name,
: (_dl_argv[0] ?: "<main program>")),
make_string (undefined_msg, undef_name,
", version ", version->name ?: NULL));
+ _dl_lookup_cache_versioned.ret = NULL;
+ _dl_lookup_cache_versioned.value = 0;
*ref = NULL;
return 0;
}
@@ -457,6 +505,8 @@ _dl_lookup_versioned_symbol (const char *undef_name,
if (__builtin_expect (protected == 0, 1))
{
+ _dl_lookup_cache_versioned.ret = current_value.s;
+ _dl_lookup_cache_versioned.value = LOOKUP_VALUE (current_value.m);
*ref = current_value.s;
return LOOKUP_VALUE (current_value.m);
}
@@ -473,10 +523,14 @@ _dl_lookup_versioned_symbol (const char *undef_name,
if (protected_value.s == NULL || protected_value.m == undef_map)
{
+ _dl_lookup_cache_versioned.ret = current_value.s;
+ _dl_lookup_cache_versioned.value = LOOKUP_VALUE (current_value.m);
*ref = current_value.s;
return LOOKUP_VALUE (current_value.m);
}
+ _dl_lookup_cache_versioned.ret = *ref;
+ _dl_lookup_cache_versioned.value = LOOKUP_VALUE (undef_map);
return LOOKUP_VALUE (undef_map);
}
}
@@ -605,7 +659,7 @@ _dl_do_lookup (const char *undef_name, unsigned long int hash,
struct link_map *skip, int noexec, int noplt)
{
return do_lookup (undef_name, hash, ref, result, scope, i, skip, noexec,
- noplt);
+ noplt);
}
static int