about summary refs log tree commit diff
path: root/elf
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
parente515fbc5fd53ff4186249a2c070f41fd73aa1c2c (diff)
downloadglibc-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.c56
-rw-r--r--elf/dl-reloc.c7
-rw-r--r--elf/ldconfig.c4
-rw-r--r--elf/rtld.c3
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.  */