]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
For b/18243822, fix dlopen_with_offset to not reuse the same link_map entry when...
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Mon, 10 Nov 2014 18:56:25 +0000 (10:56 -0800)
committerPaul Pluzhnikov <ppluzhnikov@google.com>
Mon, 10 Nov 2014 18:56:25 +0000 (10:56 -0800)
README.google
elf/dl-load.c
include/link.h

index 6ffe14b2e16149295ed90389cd2818cfd5579ea6..a4a32aa47880eb2784ef20fa47b96e68f9b14240 100644 (file)
@@ -390,3 +390,8 @@ stdlib/secure-getenv.c
   time.
   (bmoses, google-local)
 
+elf/dl-load.c
+include/link.h
+  For b/18243822, fix dlopen_with_offset to not reuse the same link_map
+  entry when called on the same file with different offsets.
+  (ppluzhnikov, google-local)
index 4f114fdcdf6c60338969f3c6ed29284b26a11aea..8adb07fde33f45b907f152ab9afde5c104c6d0c8 100644 (file)
@@ -956,7 +956,8 @@ _dl_map_object_from_fd (const char *name, int fd, off_t offset,
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
-    if (l->l_removed == 0 && l->l_ino == st.st_ino && l->l_dev == st.st_dev)
+    if (l->l_removed == 0 && l->l_ino == st.st_ino && l->l_dev == st.st_dev
+        && l->l_off == offset)
       {
        /* The object is already loaded.
           Just bump its reference count and return it.  */
@@ -1064,8 +1065,26 @@ _dl_map_object_from_fd (const char *name, int fd, off_t offset,
   else
     assert (r->r_state == RT_ADD);
 
+  if (offset != 0)
+    {
+      /* Google-specific: to help GDB, and for b/18243822, turn realname
+         into "realname/@0x<offset>"  */
+      realname = realloc (realname, strlen(realname) + 16 + 4 /* "/@0x" */);
+      if (realname == NULL)
+       {
+         errstring = N_("unable to realloc");
+         goto call_lose_errno;
+       }
+      strcat(realname, "/@0x");
+
+      char tmp[20];
+      tmp[19] = '\0';
+      strcat(realname, _itoa(offset, &tmp[18], 16, 0));
+    }
+
   /* Enter the new object in the list of loaded objects.  */
-  l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
+  l = _dl_new_object (realname, offset ? realname : name, l_type,
+                     loader, mode, nsid);
   if (__builtin_expect (l == NULL, 0))
     {
 #ifdef SHARED
@@ -1597,6 +1616,7 @@ cannot enable executable stack as shared object requires");
   /* Finally the file information.  */
   l->l_dev = st.st_dev;
   l->l_ino = st.st_ino;
+  l->l_off = offset;
 
   /* When we profile the SONAME might be needed for something else but
      loading.  Add it right away.  */
index 670d40157bab3fab2dc63b88f6c4481587eac114..10c159da13209bd07d3b743a1747353bd8da81a3 100644 (file)
@@ -238,6 +238,12 @@ struct link_map
     dev_t l_dev;
     ino64_t l_ino;
 
+    /* Google-specific extension, intended to be part of public interface
+       to the debugger.  As such, it belongs right after l_prev... except
+       putting it there causes Google libunwind to crash due to its own
+       peeking into glibc internals (see grte_v1_glibc_link_map).  */
+    size_t l_off;  /* File offset to Elf_Ehdr.  */
+
     /* Collected information about own RUNPATH directories.  */
     struct r_search_path_struct l_runpath_dirs;