]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements
authorUlrich Drepper <drepper@redhat.com>
Tue, 19 Jun 2007 22:59:48 +0000 (22:59 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 19 Jun 2007 22:59:48 +0000 (22:59 +0000)
to fill in holes
(rtld_global_ro): Likewise.

2007-06-18  Jakub Jelinek  <jakub@redhat.com>

* elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous.
Move PT_LOAD checking to...
(_dl_addr_inside_object): ... here, new function.
* elf/dl-sym.c (do_sym): If not l_contiguous,
call _dl_addr_inside_object.
* elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise.
* dlfcn/dlinfo.c (dlinfo_doit): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise.
(_dl_addr_inside_object): New function if IS_IN_rtld.
* elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no
holes are present or are PROT_NONE protected.
* include/link.h (struct link_map): Add l_contiguous field.
* sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype.

ChangeLog
dlfcn/dlinfo.c
elf/dl-addr.c
elf/dl-iteratephdr.c
elf/dl-load.c
elf/dl-open.c
elf/dl-sym.c
include/link.h
sysdeps/generic/ldsodefs.h

index e75170e75ac67e31137636cd7eeb7799b17185c3..444973335f36f3087f8ccac78afe755f44b14787 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2007-06-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements
+       to fill in holes
+       (rtld_global_ro): Likewise.
+
+2007-06-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous.
+       Move PT_LOAD checking to...
+       (_dl_addr_inside_object): ... here, new function.
+       * elf/dl-sym.c (do_sym): If not l_contiguous,
+       call _dl_addr_inside_object.
+       * elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise.
+       * dlfcn/dlinfo.c (dlinfo_doit): Likewise.
+       * elf/dl-open.c (dl_open_worker): Likewise.
+       (_dl_addr_inside_object): New function if IS_IN_rtld.
+       * elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no
+       holes are present or are PROT_NONE protected.
+       * include/link.h (struct link_map): Add l_contiguous field.
+       * sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype.
+
 2007-06-18  Jakub Jelinek  <jakub@redhat.com>
             Tomas Janousek  <tjanouse@redhat.com>
             Ulrich Drepper  <drepper@redhat.com>
index 923127cbf3d2c91827bc75b14ec817bab3dac563..b3a3e13899f07983d8cd9736c9ef02e75ea8480a 100644 (file)
@@ -1,5 +1,5 @@
 /* dlinfo -- Get information from the dynamic linker.
-   Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2006, 2007 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
@@ -56,9 +56,8 @@ dlinfo_doit (void *argsblock)
       /* Find the highest-addressed object that CALLER is not below.  */
       for (nsid = 0; nsid < DL_NNS; ++nsid)
        for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
-         if (caller >= l->l_map_start && caller < l->l_map_end)
-           /* There must be exactly one DSO for the range of the virtual
-              memory.  Otherwise something is really broken.  */
+         if (caller >= l->l_map_start && caller < l->l_map_end
+             && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
            break;
 
       if (l == NULL)
index e13105572e1d7532fa2330ba200bf05dacd00a86..17745b55b07c9bb86b7c2cb0670d0c9dcd512539 100644 (file)
@@ -134,22 +134,12 @@ _dl_addr (const void *address, Dl_info *info,
   /* Find the highest-addressed object that ADDRESS is not below.  */
   for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
     for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
-      if (addr >= l->l_map_start && addr < l->l_map_end)
+      if (addr >= l->l_map_start && addr < l->l_map_end
+         && (l->l_contiguous || _dl_addr_inside_object (l, addr)))
        {
-         /* Make sure it lies within one of L's segments.  */
-         int n = l->l_phnum;
-         const ElfW(Addr) reladdr = addr - l->l_addr;
-         while (--n >= 0)
-           if (l->l_phdr[n].p_type == PT_LOAD)
-             {
-               if (reladdr - l->l_phdr[n].p_vaddr >= 0
-                   && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
-                 {
-                   determine_info (addr, l, info, mapp, symbolp);
-                   result = 1;
-                   goto out;
-                 }
-             }
+         determine_info (addr, l, info, mapp, symbolp);
+         result = 1;
+         goto out;
        }
 
  out:
@@ -158,3 +148,19 @@ _dl_addr (const void *address, Dl_info *info,
   return result;
 }
 libc_hidden_def (_dl_addr)
+
+/* Return non-zero if ADDR lies within one of L's segments.  */
+int
+internal_function
+_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
+{
+  int n = l->l_phnum;
+  const ElfW(Addr) reladdr = addr - l->l_addr;
+
+  while (--n >= 0)
+    if (l->l_phdr[n].p_type == PT_LOAD
+       && reladdr - l->l_phdr[n].p_vaddr >= 0
+       && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
+      return 1;
+  return 0;
+}
index d03d8b6daf1d128549aea5e6727db6f9c9ec88bb..55cf10852e4f6b7796e23714eda9a2969f142590 100644 (file)
@@ -1,5 +1,5 @@
 /* Get loaded objects program headers.
-   Copyright (C) 2001,2002,2003,2004,2006 Free Software Foundation, Inc.
+   Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
 
@@ -54,9 +54,9 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
        nloaded += GL(dl_ns)[cnt]._ns_nloaded;
 
        if (caller >= (const void *) l->l_map_start
-           && caller < (const void *) l->l_map_end)
-         /* There must be exactly one DSO for the range of the virtual
-            memory.  Otherwise something is really broken.  */
+           && caller < (const void *) l->l_map_end
+           && (l->l_contiguous
+               || _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
          ns = cnt;
       }
 
index 1650ef953a7a04712b14af7c9c7e7eaf77187cc3..025b9fd86b600eefa40db3f40d731f7009f49673 100644 (file)
@@ -1,5 +1,5 @@
 /* Map in a shared object's segments from the file.
-   Copyright (C) 1995-2005, 2006  Free Software Foundation, Inc.
+   Copyright (C) 1995-2005, 2006, 2007  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
@@ -1223,6 +1223,8 @@ cannot allocate TLS data structures for initial thread");
                      loadcmds[nloadcmds - 1].mapstart - c->mapend,
                      PROT_NONE);
 
+       l->l_contiguous = 1;
+
        goto postmap;
       }
 
@@ -1242,6 +1244,7 @@ cannot allocate TLS data structures for initial thread");
     /* Remember which part of the address space this object uses.  */
     l->l_map_start = c->mapstart + l->l_addr;
     l->l_map_end = l->l_map_start + maplength;
+    l->l_contiguous = !has_holes;
 
     while (c < &loadcmds[nloadcmds])
       {
index a043cf61b6e6b899366509c50297dab0ea79e38b..2000f580c3fbee1c88335ac4dca8e9f94d873158 100644 (file)
@@ -201,10 +201,10 @@ dl_open_worker (void *a)
       for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
        for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
          if (caller_dlopen >= (const void *) l->l_map_start
-             && caller_dlopen < (const void *) l->l_map_end)
+             && caller_dlopen < (const void *) l->l_map_end
+             && (l->l_contiguous
+                 || _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen)))
            {
-             /* There must be exactly one DSO for the range of the virtual
-                memory.  Otherwise something is really broken.  */
              assert (ns == l->l_ns);
              call_map = l;
              goto found_caller;
@@ -662,3 +662,21 @@ show_scope (struct link_map *new)
     }
 }
 #endif
+
+#ifdef IS_IN_rtld
+/* Return non-zero if ADDR lies within one of L's segments.  */
+int
+internal_function
+_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
+{
+  int n = l->l_phnum;
+  const ElfW(Addr) reladdr = addr - l->l_addr;
+
+  while (--n >= 0)
+    if (l->l_phdr[n].p_type == PT_LOAD
+       && reladdr - l->l_phdr[n].p_vaddr >= 0
+       && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
+      return 1;
+  return 0;
+}
+#endif
index 1c3ab5c877a29e9d9d019688a77927d613181aad..0e1b258b5a0fbfa3638f00885aabff0971bffe18 100644 (file)
@@ -98,10 +98,9 @@ do_sym (void *handle, const char *name, void *who,
   for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
     for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
         l = l->l_next)
-      if (caller >= l->l_map_start && caller < l->l_map_end)
+      if (caller >= l->l_map_start && caller < l->l_map_end
+         && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
        {
-         /* There must be exactly one DSO for the range of the virtual
-            memory.  Otherwise something is really broken.  */
          match = l;
          break;
        }
index 67d70470d1c430486ad7985b3fc77525fbdb97a1..56764a916425a19ac8c082ee092101b7d2a965f9 100644 (file)
@@ -187,6 +187,9 @@ struct link_map
                                       is interested in the PLT interception.*/
     unsigned int l_removed:1;  /* Nozero if the object cannot be used anymore
                                   since it is removed.  */
+    unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
+                                   mprotected or if no holes are present at
+                                   all.  */
 
     /* Collected information about own RPATH directories.  */
     struct r_search_path_struct l_rpath_dirs;
index 5205c414938b111eecb661b9286352617828614d..c910ed59c4e26ca3cb8c0408496ef85c5220ca4b 100644 (file)
@@ -439,18 +439,18 @@ struct rtld_global
   EXTERN void (*_dl_rtld_unlock_recursive) (void *);
 #endif
 
-  /* Prevailing state of the stack, PF_X indicating it's executable.  */
-  EXTERN ElfW(Word) _dl_stack_flags;
-
   /* If loading a shared object requires that we make the stack executable
      when it was not, we do it by calling this function.
      It returns an errno code or zero on success.  */
   EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
 
-  /* Highest dtv index currently needed.  */
-  EXTERN size_t _dl_tls_max_dtv_idx;
+  /* Prevailing state of the stack, PF_X indicating it's executable.  */
+  EXTERN ElfW(Word) _dl_stack_flags;
+
   /* Flag signalling whether there are gaps in the module ID allocation.  */
   EXTERN bool _dl_tls_dtv_gaps;
+  /* Highest dtv index currently needed.  */
+  EXTERN size_t _dl_tls_max_dtv_idx;
   /* Information about the dtv slots.  */
   EXTERN struct dtv_slotinfo_list
   {
@@ -534,15 +534,15 @@ struct rtld_global_ro
 #define DL_DEBUG_HELP       (1 << 9)
 #define DL_DEBUG_PRELINK    (1 << 10)
 
-  /* Cached value of `getpagesize ()'.  */
-  EXTERN size_t _dl_pagesize;
-
   /* OS version.  */
   EXTERN unsigned int _dl_osversion;
   /* Platform name.  */
   EXTERN const char *_dl_platform;
   EXTERN size_t _dl_platformlen;
 
+  /* Cached value of `getpagesize ()'.  */
+  EXTERN size_t _dl_pagesize;
+
   /* Copy of the content of `_dl_main_searchlist' at startup time.  */
   EXTERN struct r_scope_elem _dl_initial_searchlist;
 
@@ -571,9 +571,6 @@ struct rtld_global_ro
   /* Expected cache ID.  */
   EXTERN int _dl_correct_cache_id;
 
-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
-  EXTERN int _dl_pointer_guard;
-
   /* Mask for hardware capabilities that are available.  */
   EXTERN uint64_t _dl_hwcap;
 
@@ -657,6 +654,9 @@ struct rtld_global_ro
   /* List of auditing interfaces.  */
   struct audit_ifaces *_dl_audit;
   unsigned int _dl_naudit;
+
+  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
+  EXTERN int _dl_pointer_guard;
 };
 # define __rtld_global_attribute__
 # ifdef IS_IN_rtld
@@ -1061,6 +1061,8 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid);
    but never touch anything.  Return null if it's not allocated yet.  */
 extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function;
 
+extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
+     internal_function attribute_hidden;
 
 __END_DECLS