Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 26 Aug 2001 10:50:26 +0000 (10:50 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 26 Aug 2001 10:50:26 +0000 (10:50 +0000)
* 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.

ChangeLog
elf/dl-lookup.c
elf/dl-reloc.c
include/link.h
sysdeps/generic/ldsodefs.h
sysdeps/i386/dl-machine.h

index efa4644..7ba5e66 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,24 @@
 2001-08-26  Ulrich Drepper  <drepper@redhat.com>
 
+       * 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.
+
        * config.h.in: Add HAVE_Z_COMBRELOC.
        * configure.in: Add test for -z combreloc.
 
        * sysdeps/i386/dl-machine.h (elf_machine_rel): Minor cleanups and
        optimizations.  Use HAVE_Z_COMBRELOC to avoid generaton of
-       R_386_RELATIVE handling for ld.so startup.
+       R_386_RELATIVE handling for ld.so startup.  Reduce RTLD_BOOTSTRAP
+       case to almost no code.
 
 2001-08-25  Ulrich Drepper  <drepper@redhat.com>
 
index 047ce4b..71dda25 100644 (file)
@@ -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);
     }
 }
index 99cb189..276aea0 100644 (file)
@@ -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
index 9345c92..5aba874 100644 (file)
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995-1999, 2000, 2001 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
@@ -34,6 +34,7 @@
 
 #include <bits/elfclass.h>             /* Defines __ELF_NATIVE_CLASS.  */
 #include <bits/link.h>
+#include <dl-lookupcfg.h>
 
 /* Rendezvous structure used by the run-time dynamic linker to communicate
    details of shared object loading to the debugger.  If the executable's
@@ -231,6 +232,19 @@ struct link_map
     unsigned int l_idx;
 
     struct link_map_machine l_mach;
+
+    struct
+    {
+      const ElfW(Sym) *sym;
+      int noexec;
+      int noplt;
+#ifdef DL_LOOKUP_RETURNS_MAP
+      struct link_map *value;
+#else
+      ElfW(Addr) value;
+#endif
+      const ElfW(Sym) *ret;
+    } l_lookup_cache;
   };
 
 struct dl_phdr_info
index 5e093fc..6d196c7 100644 (file)
@@ -327,21 +327,6 @@ extern void _dl_map_object_deps (struct link_map *map,
 /* Cache the locations of MAP's hash table.  */
 extern void _dl_setup_hash (struct link_map *map) internal_function;
 
-/* This holds symbol lookup cache.  */
-struct lookup_cache
-  {
-    const ElfW(Sym) *sym;
-    struct link_map *map;
-    const struct r_found_version *version;
-    int noexec;
-    int noplt;
-    lookup_t value;
-    const ElfW(Sym) *ret;
-  };
-
-extern struct lookup_cache _dl_lookup_cache;
-extern struct lookup_cache _dl_lookup_cache_versioned;
-
 
 /* Search loaded objects' symbol tables for a definition of the symbol
    referred to by UNDEF.  *SYM is the symbol table entry containing the
index 53d8022..e7a1b10 100644 (file)
@@ -334,13 +334,16 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
       if (sym)
        value += sym->st_value;
 
+#ifdef RTLD_BOOTSTRAP
+      assert (r_type == R_386_GLOB_DAT || r_type == R_386_JMP_SLOT);
+      *reloc_addr = value;
+#else
       switch (r_type)
        {
        case R_386_GLOB_DAT:
        case R_386_JMP_SLOT:
          *reloc_addr = value;
          break;
-#ifndef RTLD_BOOTSTRAP
        case R_386_32:
          *reloc_addr += value;
          break;
@@ -372,8 +375,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
             if we are still debugging.  */
          _dl_reloc_bad_type (map, r_type, 0);
          break;
-#endif
        }
+#endif
     }
 }