diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-08-23 23:36:47 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-08-23 23:36:47 +0000 |
commit | 647eb037f3d9dee0bf6e9410c6445c4223cf832a (patch) | |
tree | fc725d27ed5ffef239f38f7aabb08227b285dfd2 /elf | |
parent | e515fbc5fd53ff4186249a2c070f41fd73aa1c2c (diff) | |
download | glibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.tar.gz glibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.tar.xz glibc-647eb037f3d9dee0bf6e9410c6445c4223cf832a.zip |
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')
-rw-r--r-- | elf/dl-lookup.c | 56 | ||||
-rw-r--r-- | elf/dl-reloc.c | 7 | ||||
-rw-r--r-- | elf/ldconfig.c | 4 | ||||
-rw-r--r-- | elf/rtld.c | 3 |
4 files changed, 69 insertions, 1 deletions
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index fe833ba22b..48850e6caa 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 diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index dbbc19c233..b46d3bcf47 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -89,8 +89,15 @@ cannot make segment writable for relocation")); : l->l_addr) #include "dynamic-link.h" + /* Start symbol lookup caching for this object. */ + _dl_lookup_cache.map = l; + _dl_lookup_cache_versioned.map = l; + ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); + _dl_lookup_cache.map = NULL; + _dl_lookup_cache_versioned.map = NULL; + if (__builtin_expect (consider_profiling, 0)) { /* Allocate the array which will contain the already found diff --git a/elf/ldconfig.c b/elf/ldconfig.c index a087da85e4..ba05c67a97 100644 --- a/elf/ldconfig.c +++ b/elf/ldconfig.c @@ -699,6 +699,10 @@ search_dir (const struct dir_entry *entry) { if (opt_verbose) error (0, errno, _("Cannot stat %s"), file_name); + + /* Remove stale symlinks. */ + if (strstr (direntry->d_name, ".so.")) + unlink (real_file_name); continue; } is_dir = S_ISDIR (stat_buf.st_mode); diff --git a/elf/rtld.c b/elf/rtld.c index b32de61888..1188880351 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -127,6 +127,7 @@ static hp_timing_t relocate_time; static hp_timing_t load_time; #endif extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */ +extern unsigned long int _dl_num_cache_relocations; /* in dl-lookup.c */ static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p, hp_timing_t start_time); @@ -1524,6 +1525,8 @@ print_statistics (void) #endif _dl_debug_printf (" number of relocations: %lu\n", _dl_num_relocations); + _dl_debug_printf (" number of relocations from cache: %lu\n", + _dl_num_cache_relocations); #ifndef HP_TIMING_NONAVAIL /* Time spend while loading the object and the dependencies. */ |