about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-08-26 10:50:26 +0000
committerUlrich Drepper <drepper@redhat.com>2001-08-26 10:50:26 +0000
commit680254fe22215c1f41f247d085c5cac5783b73f5 (patch)
treeb91211374166ef246d63137e39f7e1968cfb53c8 /elf
parenta711b01d34ca5de9857ca5d19235812674fccee6 (diff)
downloadglibc-680254fe22215c1f41f247d085c5cac5783b73f5.tar.gz
glibc-680254fe22215c1f41f247d085c5cac5783b73f5.tar.xz
glibc-680254fe22215c1f41f247d085c5cac5783b73f5.zip
Update.
	* include/link.h (struct link_map): Add l_lookup_cache element.
	* elf/dl-reloc.c (RESOLVE): Add symbol caching here.
	(RESOLVE_MAP): Likewise.
	(_dl_relocate_object): Remove cache initialization.
	* elf/dl-lookup.c: Rip out cache handling code.
	* sysdeps/generic/ldsodefs.h: Remove lookup_cache struct and variable
	declarations.

	* elf/dl-lookup.c (_dl_lookup_symbol): Reorder some conditions and
	remove some __builtin_expect.
	(_dl_lookup_versioned_symbol): Likewise.

	R_386_RELATIVE handling for ld.so startup.  Reduce RTLD_BOOTSTRAP
	case to almost no code.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-lookup.c82
-rw-r--r--elf/dl-reloc.c55
2 files changed, 49 insertions, 88 deletions
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 047ce4be9f..71dda25aff 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -60,7 +60,6 @@ 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
@@ -185,8 +184,6 @@ _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.  */
@@ -197,29 +194,15 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
 		   const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
 		   int reloc_type, int explicit)
 {
-  unsigned long int hash;
-  struct sym_val current_value;
+  unsigned long int hash = _dl_elf_hash (undef_name);
+  struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
   int protected;
   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;
 
-  hash = _dl_elf_hash (undef_name);
-  current_value = ((struct sym_val) { NULL, NULL });
-
   /* Search the relevant loaded objects for a definition.  */
   for (scope = symbol_scope; *scope; ++scope)
     if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
@@ -229,13 +212,12 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
 	   in the global scope which was dynamically loaded.  In this case
 	   we have to prevent the latter from being unloaded unless the
 	   UNDEF_MAP object is also unloaded.  */
-	if (__builtin_expect (current_value.m->l_global, 0)
-	    && (__builtin_expect (current_value.m->l_type, lt_library)
-		== lt_loaded)
+	if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
+	    && current_value.m->l_global
 	    && undef_map != current_value.m
 	    /* Don't do this for explicit lookups as opposed to implicit
 	       runtime lookups.  */
-	    && __builtin_expect (! explicit, 1)
+	    && ! explicit
 	    /* Add UNDEF_MAP to the dependencies.  */
 	    && add_dependency (undef_map, current_value.m) < 0)
 	  /* Something went wrong.  Perhaps the object we tried to reference
@@ -246,11 +228,6 @@ _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))
     {
       const char *reference_name = undef_map ? undef_map->l_name : NULL;
@@ -262,8 +239,6 @@ _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;
     }
@@ -284,8 +259,6 @@ _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);
     }
@@ -302,13 +275,9 @@ _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);
     }
@@ -407,30 +376,15 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 			     const struct r_found_version *version,
 			     int reloc_type, int explicit)
 {
-  unsigned long int hash;
-  struct sym_val current_value;
+  unsigned long int hash = _dl_elf_hash (undef_name);
+  struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
   int protected;
   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;
 
-  hash = _dl_elf_hash (undef_name);
-  current_value = ((struct sym_val) { NULL, NULL });
-
   /* Search the relevant loaded objects for a definition.  */
   for (scope = symbol_scope; *scope; ++scope)
     {
@@ -442,13 +396,12 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 	     in the global scope which was dynamically loaded.  In this case
 	     we have to prevent the latter from being unloaded unless the
 	     UNDEF_MAP object is also unloaded.  */
-	  if (__builtin_expect (current_value.m->l_global, 0)
-	      && (__builtin_expect (current_value.m->l_type, lt_library)
-		  == lt_loaded)
+	  if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
+	      && current_value.m->l_global
 	      && undef_map != current_value.m
 	      /* Don't do this for explicit lookups as opposed to implicit
 		 runtime lookups.  */
-	      && __builtin_expect (! explicit, 1)
+	      && ! explicit
 	      /* Add UNDEF_MAP to the dependencies.  */
 	      && add_dependency (undef_map, current_value.m) < 0)
 	    /* Something went wrong.  Perhaps the object we tried to reference
@@ -482,12 +435,6 @@ _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)
@@ -503,9 +450,6 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 					  ", version ",
 					  version->name ?: NULL));
 	}
-
-      _dl_lookup_cache_versioned.ret = NULL;
-      _dl_lookup_cache_versioned.value = 0;
       *ref = NULL;
       return 0;
     }
@@ -527,8 +471,6 @@ _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);
     }
@@ -545,14 +487,10 @@ _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);
     }
 }
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 99cb18962d..276aea094b 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -27,6 +27,9 @@
 #include <sys/types.h>
 #include "dynamic-link.h"
 
+/* Statistics function.  */
+unsigned long int _dl_num_cache_relocations;
+
 
 void
 _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
@@ -74,31 +77,51 @@ cannot make segment writable for relocation"));
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 #define RESOLVE_MAP(ref, version, flags) \
     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
-     ? ((version) != NULL && (version)->hash != 0			      \
-	? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref),    \
-				       scope, (version), (flags), 0)	      \
-	: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope,	      \
-			     (flags), 0))				      \
+     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
+	 && elf_machine_lookup_noexec_p (flags) == l->l_lookup_cache.noexec   \
+	 && elf_machine_lookup_noplt_p (flags) == l->l_lookup_cache.noplt)    \
+	? (++_dl_num_cache_relocations,					      \
+	   (*ref) = l->l_lookup_cache.ret,				      \
+	   l->l_lookup_cache.value)					      \
+	: ({ lookup_t _lr;						      \
+	     l->l_lookup_cache.sym = (*ref);				      \
+	     l->l_lookup_cache.noexec = elf_machine_lookup_noexec_p (flags);  \
+	     l->l_lookup_cache.noplt = elf_machine_lookup_noplt_p (flags);    \
+	     _lr = ((version) != NULL && (version)->hash != 0		      \
+		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \
+						   l, (ref), scope,	      \
+						   (version), (flags), 0)     \
+		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \
+					 scope, (flags), 0));		      \
+	     l->l_lookup_cache.ret = (*ref);				      \
+	     l->l_lookup_cache.value = _lr; }))				      \
      : l)
 #define RESOLVE(ref, version, flags) \
     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
-     ? ((version) != NULL && (version)->hash != 0			      \
-	? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref),    \
-				       scope, (version), (flags), 0)	      \
-	: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope,	      \
-			     (flags), 0))				      \
+     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
+	 && elf_machine_lookup_noexec_p (flags) == l->l_lookup_cache.noexec   \
+	 && elf_machine_lookup_noplt_p (flags) == l->l_lookup_cache.noplt)    \
+	? (++_dl_num_cache_relocations,					      \
+	   (*ref) = l->l_lookup_cache.ret,				      \
+	   l->l_lookup_cache.value)					      \
+	: ({ lookup_t _lr;						      \
+	     l->l_lookup_cache.sym = (*ref);				      \
+	     l->l_lookup_cache.noexec = elf_machine_lookup_noexec_p (flags);  \
+	     l->l_lookup_cache.noplt = elf_machine_lookup_noplt_p (flags);    \
+	     _lr = ((version) != NULL && (version)->hash != 0		      \
+		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \
+						   l, (ref), scope,	      \
+						   (version), (flags), 0)     \
+		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \
+					 scope, (flags), 0));		      \
+	     l->l_lookup_cache.ret = (*ref);				      \
+	     l->l_lookup_cache.value = _lr; }))				      \
      : 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