Update.
authorUlrich Drepper <drepper@redhat.com>
Fri, 23 Jul 1999 22:58:50 +0000 (22:58 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 23 Jul 1999 22:58:50 +0000 (22:58 +0000)
* posix/unistd.h: Move declaration of __libc_enable_secure to...
* include/unistd.h: ...here.

* elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt.
* elf/dl-deps.c (expand_dst): Likewise.

* elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW
based on DT_FLAGS value.

* elf/do-lookup.h: Remove reference_name parameter, add undef_map.
Add test for symbols marked STV_HIDDEN.
* elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter,
add undef_map.  Compute reference_name locally.  Update call to
do_lookup.
(_dl_lookup_symbol_skip): Likewise.
(_dl_lookup_versioned_symbol): Likewise.
(_dl_lookup_versioned_symbol_skip): Likewise.
* elf/dl-libc.c: Update call to _dl_lookup_*symbol.
* elf/dl-runtime.c: Likewise.
* elf/dl-sym.c: Likewise.
* elf/dl-symbol.c: Likewise.
* elf/ldsodefs.h: Adjust prototypes.

* elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and
handle appropriately.  Add comment about DT_TEXTREL.
* elf/dl-runtime.c: Likewise.

14 files changed:
ChangeLog
elf/dl-deps.c
elf/dl-libc.c
elf/dl-lookup.c
elf/dl-open.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dl-sym.c
elf/dl-symbol.c
elf/do-lookup.h
elf/dynamic-link.h
elf/ldsodefs.h
include/unistd.h
posix/unistd.h

index a254cc0..e6995d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ.
        Add DF_ORIGIN, DF_SYMBOLIC, DF_TEXTREL, and DF_BIND_NOW.
 
+       * posix/unistd.h: Move declaration of __libc_enable_secure to...
+       * include/unistd.h: ...here.
+
+       * elf/dl-open.c (dl_open_worker): If DST is used in SUID program punt.
+       * elf/dl-deps.c (expand_dst): Likewise.
+
+       * elf/dynamic-link.h: Set DT_SYMBOLIC, DT_TEXTREL, and DT_BIND_NOW
+       based on DT_FLAGS value.
+
+       * elf/do-lookup.h: Remove reference_name parameter, add undef_map.
+       Add test for symbols marked STV_HIDDEN.
+       * elf/dl-lookup.c (_dl_lookup_symbol): Remove reference_name parameter,
+       add undef_map.  Compute reference_name locally.  Update call to
+       do_lookup.
+       (_dl_lookup_symbol_skip): Likewise.
+       (_dl_lookup_versioned_symbol): Likewise.
+       (_dl_lookup_versioned_symbol_skip): Likewise.
+       * elf/dl-libc.c: Update call to _dl_lookup_*symbol.
+       * elf/dl-runtime.c: Likewise.
+       * elf/dl-sym.c: Likewise.
+       * elf/dl-symbol.c: Likewise.
+       * elf/ldsodefs.h: Adjust prototypes.
+
+       * elf/dl-reloc.c (RESOLV): Add test for STV_PROTECTED flag set and
+       handle appropriately.  Add comment about DT_TEXTREL.
+       * elf/dl-runtime.c: Likewise.
+
 1999-07-21  Roland McGrath  <roland@baalperazim.frob.com>
 
        * elf/dl-reloc.c (_dl_reloc_bad_type): New function.
index b981d49..68e4921 100644 (file)
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/param.h>
 #include <elf/ldsodefs.h>
 
@@ -96,9 +97,15 @@ struct list
                                                                              \
     if (__cnt != 0)                                                          \
       {                                                                              \
-       char *__newp = (char *) alloca (DL_DST_REQUIRED (l, __str,            \
-                                                        strlen (__str),      \
-                                                        __cnt));             \
+       char *__newp;                                                         \
+                                                                             \
+       /* DST must not appear in SUID/SGID programs.  */                     \
+       if (__libc_enable_secure)                                             \
+         _dl_signal_error (0, __str,                                         \
+                           "DST not allowed in SUID/SGID programs");         \
+                                                                             \
+       __newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str),  \
+                                                  __cnt));                   \
                                                                              \
        __result = DL_DST_SUBSTITUTE (l, __str, __newp, 0);                   \
                                                                              \
index afb3f2d..784af27 100644 (file)
@@ -82,9 +82,8 @@ do_dlsym (void *ptr)
 {
   struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
   args->ref = NULL;
-  args->loadbase = _dl_lookup_symbol (args->name, &args->ref,
-                                     args->map->l_local_scope,
-                                     args->map->l_name, 0);
+  args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
+                                     args->map->l_local_scope, 0);
 }
 
 static void
index 16173c9..4120cb1 100644 (file)
@@ -75,11 +75,11 @@ unsigned long int _dl_num_relocations;
 
 ElfW(Addr)
 internal_function
-_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
-                  struct r_scope_elem *symbol_scope[],
-                  const char *reference_name,
+_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)
 {
+  const char *reference_name = undef_map ? undef_map->l_name : NULL;
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
@@ -88,8 +88,8 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
 
   /* 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, reference_name, NULL, reloc_type))
+    if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+                  *scope, 0, NULL, reloc_type))
       break;
 
   if (current_value.s == NULL)
@@ -125,11 +125,12 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
    SKIP_MAP is only skipped.  */
 ElfW(Addr)
 internal_function
-_dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
+_dl_lookup_symbol_skip (const char *undef_name,
+                       struct link_map *undef_map, const ElfW(Sym) **ref,
                        struct r_scope_elem *symbol_scope[],
-                       const char *reference_name,
                        struct link_map *skip_map)
 {
+  const char *reference_name = undef_map ? undef_map->l_name : NULL;
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
@@ -143,11 +144,11 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
     assert (i < (*scope)->r_nduplist);
 
   if (i >= (*scope)->r_nlist
-      || ! do_lookup (undef_name, hash, *ref, &current_value,
-                     *scope, i, reference_name, skip_map, 0))
+      || ! do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+                     *scope, i, skip_map, 0))
     while (*++scope)
-      if (do_lookup (undef_name, hash, *ref, &current_value,
-                    *scope, 0, reference_name, skip_map, 0))
+      if (do_lookup (undef_name, undef_map, hash, *ref, &current_value,
+                    *scope, 0, skip_map, 0))
        break;
 
   if (current_value.s == NULL)
@@ -177,12 +178,13 @@ _dl_lookup_symbol_skip (const char *undef_name, const ElfW(Sym) **ref,
    XXX We'll see whether we need this separate function.  */
 ElfW(Addr)
 internal_function
-_dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
+_dl_lookup_versioned_symbol (const char *undef_name,
+                            struct link_map *undef_map, const ElfW(Sym) **ref,
                             struct r_scope_elem *symbol_scope[],
-                            const char *reference_name,
                             const struct r_found_version *version,
                             int reloc_type)
 {
+  const char *reference_name = undef_map ? undef_map->l_name : NULL;
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
@@ -192,8 +194,8 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
   /* Search the relevant loaded objects for a definition.  */
   for (scope = symbol_scope; *scope; ++scope)
     {
-      int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
-                                    *scope, 0, reference_name, version, NULL,
+      int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
+                                    &current_value, *scope, 0, version, NULL,
                                     reloc_type);
       if (res > 0)
        break;
@@ -250,12 +252,13 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
 ElfW(Addr)
 internal_function
 _dl_lookup_versioned_symbol_skip (const char *undef_name,
+                                 struct link_map *undef_map,
                                  const ElfW(Sym) **ref,
                                  struct r_scope_elem *symbol_scope[],
-                                 const char *reference_name,
                                  const struct r_found_version *version,
                                  struct link_map *skip_map)
 {
+  const char *reference_name = undef_map ? undef_map->l_name : NULL;
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
@@ -269,11 +272,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
     assert (i < (*scope)->r_nduplist);
 
   if (i >= (*scope)->r_nlist
-      || ! do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
-                               i, reference_name, version, skip_map, 0))
+      || ! do_lookup_versioned (undef_name, undef_map, hash, *ref,
+                               &current_value, *scope, i, version, skip_map,
+                               0))
     while (*++scope)
-      if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
-                              0, reference_name, version, skip_map, 0))
+      if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
+                              &current_value, *scope, 0, version, skip_map,
+                              0))
        break;
 
   if (current_value.s == NULL)
index a3cd8a0..097fd37 100644 (file)
 #include <assert.h>
 #include <dlfcn.h>
 #include <errno.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <string.h>
-#include <libintl.h>
+#include <unistd.h>
 #include <sys/mman.h>          /* Check whether MAP_COPY is defined.  */
 #include <sys/param.h>
 #include <bits/libc-lock.h>
@@ -100,6 +101,12 @@ dl_open_worker (void *a)
       struct link_map *call_map;
       char *new_file;
 
+      /* DSTs must not appear in SUID/SGID programs.  */
+      if (__libc_enable_secure)
+       /* This is an error.  */
+       _dl_signal_error (0, "dlopen",
+                         "DST not allowed in SUID/SGID programs");
+
       /* We have to find out from which object the caller is calling.
         Find the highest-addressed object that ADDRESS is not below.  */
       call_map = NULL;
index 0bf39a8..a1c235a 100644 (file)
@@ -71,11 +71,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 #define RESOLVE(ref, version, flags) \
-    ((version) != NULL && (version)->hash != 0                               \
-     ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope,   \
-                                   l->l_name, (version), (flags))            \
-     : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope,            \
-                         l->l_name, (flags)))
+    (ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED                 \
+     ? ((version) != NULL && (version)->hash != 0                            \
+       ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref),    \
+                                      scope, (version), (flags))             \
+       : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope,       \
+                            (flags)))                                        \
+     : l->l_addr)
 
 #include "dynamic-link.h"
     ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
@@ -96,6 +98,9 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   /* Mark the object so we know this work has been done.  */
   l->l_relocated = 1;
 
+  /* DT_TEXTREL is now in level 2 and might phase out at some time.
+     But we rewrite the DT_FLAGS entry to make testing easier and
+     therefore it will be available at all time.  */
   if (l->l_info[DT_TEXTREL])
     {
       /* Undo the protection change we made before relocating.  */
index 9f3004e..a55fbf6 100644 (file)
@@ -66,32 +66,40 @@ fixup (
   /* Sanity check that we're really looking at a PLT relocation.  */
   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
 
-   /* Look up the target symbol.  */
-  switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+   /* Look up the target symbol.  If the symbol is marked STV_PROTEXTED
+      don't look in the global scope.  */
+  if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
     {
-    default:
-      {
-       const ElfW(Half) *vernum =
-         (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
-       ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
-       const struct r_found_version *version = &l->l_versions[ndx];
-
-       if (version->hash != 0)
+      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+       {
+       default:
          {
-           value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
-                                               &sym, l->l_scope, l->l_name,
-                                               version, ELF_MACHINE_JMP_SLOT);
-           break;
+           const ElfW(Half) *vernum =
+             (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
+           ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+           const struct r_found_version *version = &l->l_versions[ndx];
+
+           if (version->hash != 0)
+             {
+               value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l,
+                                                   &sym, l->l_scope, version,
+                                                   ELF_MACHINE_JMP_SLOT);
+               break;
+             }
          }
-      }
-    case 0:
-      value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
-                                l->l_name, ELF_MACHINE_JMP_SLOT);
-    }
+       case 0:
+         value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
+                                    l->l_scope, ELF_MACHINE_JMP_SLOT);
+       }
 
-  /* Currently value contains the base load address of the object
-     that defines sym.  Now add in the symbol offset.  */
-  value = (sym ? value + sym->st_value : 0);
+      /* Currently value contains the base load address of the object
+        that defines sym.  Now add in the symbol offset.  */
+      value = (sym ? value + sym->st_value : 0);
+    }
+  else
+    /* We already found the symbol.  The module (and therefore its load
+       address) is also known.  */
+    value = l->l_addr + sym->st_value;
 
   /* And now perhaps the relocation addend.  */
   value = elf_machine_plt_value (l, reloc, value);
@@ -141,33 +149,41 @@ profile_fixup (
       /* Sanity check that we're really looking at a PLT relocation.  */
       assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
 
-      /* Look up the target symbol.  */
-      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+      /* Look up the target symbol.  If the symbol is marked STV_PROTEXTED
+        don't look in the global scope.  */
+      if (ELFW(ST_VISIBILITY) (sym->st_other) != STV_PROTECTED)
        {
-       default:
-         {
-           const ElfW(Half) *vernum =
-             (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
-           ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
-           const struct r_found_version *version = &l->l_versions[ndx];
-
-           if (version->hash != 0)
+         switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+           {
+           default:
              {
-               value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
-                                                   &sym, l->l_scope,
-                                                   l->l_name, version,
-                                                   ELF_MACHINE_JMP_SLOT);
-               break;
+               const ElfW(Half) *vernum =
+                 (const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
+               ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+               const struct r_found_version *version = &l->l_versions[ndx];
+
+               if (version->hash != 0)
+                 {
+                   value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+                                                       l, &sym, l->l_scope,
+                                                       version,
+                                                       ELF_MACHINE_JMP_SLOT);
+                   break;
+                 }
              }
-         }
-       case 0:
-         value = _dl_lookup_symbol (strtab + sym->st_name, &sym, l->l_scope,
-                                    l->l_name, ELF_MACHINE_JMP_SLOT);
+           case 0:
+             value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
+                                        l->l_scope, ELF_MACHINE_JMP_SLOT);
+           }
+
+         /* Currently value contains the base load address of the object
+            that defines sym.  Now add in the symbol offset.  */
+         value = (sym ? value + sym->st_value : 0);
        }
-
-      /* Currently value contains the base load address of the object
-        that defines sym.  Now add in the symbol offset.  */
-      value = (sym ? value + sym->st_value : 0);
+      else
+       /* We already found the symbol.  The module (and therefore its load
+          address) is also known.  */
+       value = l->l_addr + sym->st_value;
 
       /* And now perhaps the relocation addend.  */
       value = elf_machine_plt_value (l, reloc, value);
index 441b54f..91ca127 100644 (file)
@@ -34,7 +34,7 @@ _dl_sym (void *handle, const char *name, void *who)
 
   if (handle == RTLD_DEFAULT)
     /* Search the global scope.  */
-    loadbase = _dl_lookup_symbol (name, &ref, _dl_global_scope, NULL, 0);
+    loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
   else if (handle == RTLD_NEXT)
     {
       struct link_map *l, *match;
@@ -54,15 +54,14 @@ RTLD_NEXT used in code not dynamically loaded"));
       while (l->l_loader)
        l = l->l_loader;
 
-      loadbase = _dl_lookup_symbol_skip (name, &ref, l->l_local_scope,
-                                        NULL, match);
+      loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
+                                        match);
     }
   else
     {
       /* Search the scope of the given object.  */
       struct link_map *map = handle;
-      loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope,
-                                   map->l_name, 0);
+      loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
     }
 
   if (loadbase)
@@ -88,8 +87,8 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
 
   if (handle == RTLD_DEFAULT)
     /* Search the global scope.  */
-    loadbase = _dl_lookup_versioned_symbol (name, &ref, _dl_global_scope,
-                                           NULL, &vers, 0);
+    loadbase = _dl_lookup_versioned_symbol (name, NULL, &ref, _dl_global_scope,
+                                           &vers, 0);
   else if (handle == RTLD_NEXT)
     {
       struct link_map *l, *match;
@@ -109,17 +108,16 @@ RTLD_NEXT used in code not dynamically loaded"));
       while (l->l_loader)
        l = l->l_loader;
 
-      loadbase = _dl_lookup_versioned_symbol_skip (name, &ref,
+      loadbase = _dl_lookup_versioned_symbol_skip (name, l, &ref,
                                                   l->l_local_scope,
-                                                  NULL, &vers, match);
+                                                  &vers, match);
     }
   else
     {
       /* Search the scope of the given object.  */
       struct link_map *map = handle;
-      loadbase = _dl_lookup_versioned_symbol (name, &ref,
-                                             map->l_local_scope,
-                                             map->l_name, &vers, 0);
+      loadbase = _dl_lookup_versioned_symbol (name, map, &ref,
+                                             map->l_local_scope, &vers, 0);
     }
 
   if (loadbase)
index 3ae44d6..945f544 100644 (file)
@@ -1,5 +1,5 @@
 /* Look up a symbol's run-time value in the scope of a loaded object.
-   Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1998, 1999 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
@@ -28,7 +28,6 @@ _dl_symbol_value (struct link_map *map, const char *name)
 {
   ElfW(Addr) loadbase;
   const ElfW(Sym) *ref = NULL;
-  loadbase = _dl_lookup_symbol (name, &ref, map->l_local_scope, map->l_name,
-                               0);
+  loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
   return loadbase + ref->st_value;
 }
index 147560b..f83b13c 100644 (file)
    found the symbol, the value 0 if nothing is found and < 0 if
    something bad happened.  */
 static inline int
-FCT (const char *undef_name, unsigned long int hash,
-     const ElfW(Sym) *ref, struct sym_val *result,
-     struct r_scope_elem *scope, size_t i, const char *reference_name,
-     ARG struct link_map *skip, int reloc_type)
+FCT (const char *undef_name, struct link_map *undef_map,
+     unsigned long int hash, const ElfW(Sym) *ref, struct sym_val *result,
+     struct r_scope_elem *scope, size_t i, ARG struct link_map *skip,
+     int reloc_type)
 {
   struct link_map **list = scope->r_list;
   size_t n = scope->r_nlist;
@@ -154,7 +154,12 @@ FCT (const char *undef_name, unsigned long int hash,
        sym = num_versions == 1 ? versioned_sym : NULL;
 #endif
 
-      if (sym != NULL)
+      if (sym != NULL
+         /* Don't allow binding if the symbol is hidden.  When processor
+            specific definitions for STV_INTERNAL are defined we might
+            have to extend this conditional.  */
+         && (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN
+             || map == undef_map))
        {
        found_it:
          switch (ELFW(ST_BIND) (sym->st_info))
index d322c12..59a6001 100644 (file)
@@ -93,6 +93,19 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Addr) l_addr,
     info[DT_JMPREL]->d_un.d_ptr += l_addr;
   if (info[VERSYMIDX (DT_VERSYM)] != NULL)
     info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
+  if (info[DT_FLAGS] != NULL)
+    {
+      /* Flags are used.  Translate to the old form where available.
+        Since these l_info entries are only tested for NULL pointers it
+        is ok if they point to the DT_FLAGS entry.  */
+      ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val;
+      if (flags & DF_SYMBOLIC)
+       info[DT_SYMBOLIC] = info[DT_FLAGS];
+      if (flags & DF_TEXTREL)
+       info[DT_TEXTREL] = info[DT_FLAGS];
+      if (flags & DF_BIND_NOW)
+       info[DT_BIND_NOW] = info[DT_FLAGS];
+    }
 }
 
 #ifdef RESOLVE
index 483e85b..15b7cc6 100644 (file)
@@ -260,35 +260,35 @@ extern void _dl_setup_hash (struct link_map *map) internal_function;
    the `elf_machine_lookup_*_p' macros in dl-machine.h to affect which
    symbols can be chosen.  */
 extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
+                                    struct link_map *undef_map,
                                     const ElfW(Sym) **sym,
                                     struct r_scope_elem *symbol_scope[],
-                                    const char *reference_name,
                                     int reloc_type)
      internal_function;
 
 /* Lookup versioned symbol.  */
 extern ElfW(Addr) _dl_lookup_versioned_symbol (const char *undef,
+                                              struct link_map *undef_map,
                                               const ElfW(Sym) **sym,
                                               struct r_scope_elem *symbol_scope[],
-                                              const char *reference_name,
                                               const struct r_found_version *version,
                                               int reloc_type)
      internal_function;
 
 /* For handling RTLD_NEXT we must be able to skip shared objects.  */
 extern ElfW(Addr) _dl_lookup_symbol_skip (const char *undef,
+                                         struct link_map *undef_map,
                                          const ElfW(Sym) **sym,
                                          struct r_scope_elem *symbol_scope[],
-                                         const char *reference_name,
                                          struct link_map *skip_this)
      internal_function;
 
 /* For handling RTLD_NEXT with versioned symbols we must be able to
    skip shared objects.  */
 extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
+                                                   struct link_map *undef_map,
                                                    const ElfW(Sym) **sym,
                                                    struct r_scope_elem *symbol_scope[],
-                                                   const char *reference_name,
                                                    const struct r_found_version *version,
                                                    struct link_map *skip_this)
      internal_function;
index 955637e..06fa8fb 100644 (file)
@@ -63,4 +63,13 @@ extern int __profil __P ((unsigned short int *__sample_buffer, size_t __size,
                          size_t __offset, unsigned int __scale));
 extern int __getdtablesize __P ((void));
 extern int __brk __P ((__ptr_t __addr));
+
+
+/* This variable is set nonzero at startup if the process's effective
+   IDs differ from its real IDs, or it is otherwise indicated that
+   extra security should be used.  When this is set the dynamic linker
+   and some functions contained in the C library ignore various
+   environment variables that normally affect them.  */
+extern int __libc_enable_secure;
+
 #endif
index ea1d47b..d8800b7 100644 (file)
@@ -927,16 +927,7 @@ extern int lockf64 __P ((int __fd, int __cmd, __off64_t __len));
     ({ long int __result;                                                    \
        do __result = (long int) (expression);                                \
        while (__result == -1L && errno == EINTR);                            \
-       __result; }))                                                         \
-
-
-/* This variable is set nonzero at startup if the process's effective
-   IDs differ from its real IDs, or it is otherwise indicated that
-   extra security should be used.  When this is set the dynamic linker
-   and some functions contained in the C library ignore various
-   environment variables that normally affect them.  */
-extern int __libc_enable_secure;
-
+       __result; }))
 #endif
 
 #if defined __USE_POSIX199309 || defined __USE_UNIX98