]> 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)
elf/dl-load.c
include/link.h

index e49d0862f9ccfc8c41e2c5f5c32030d8cb93f25b..b6c4aa8da025368844094a8d5dfaf1598181a683 100644 (file)
@@ -840,7 +840,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, off_t of
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
-    if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id))
+    if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id)
+        && l->l_off == offset)
       {
        /* The object is already loaded.
           Just bump its reference count and return it.  */
@@ -947,8 +948,25 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, off_t of
   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 (__glibc_unlikely (l == NULL))
     {
 #ifdef SHARED
@@ -1320,6 +1338,8 @@ cannot enable executable stack as shared object requires");
   assert (origname == NULL);
 #endif
 
+  l->l_off = offset;
+
   /* When we profile the SONAME might be needed for something else but
      loading.  Add it right away.  */
   if (__glibc_unlikely (GLRO(dl_profile) != NULL)
index 5924594548e7ef820595217e7714f7994c533ec1..22c3eec73d0fb6cda5731db6a376e923bfe7537e 100644 (file)
@@ -246,6 +246,12 @@ struct link_map
        object is the same as one already loaded.  */
     struct r_file_id l_file_id;
 
+    /* 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;