Blame SOURCES/glibc-rh646954.patch

b9ba6d
2010-10-26  Ulrich Drepper  <drepper@gmail.com>
b9ba6d
b9ba6d
	* elf/rtld.c (dl_main): Move assertion after the point where rtld map
b9ba6d
	is added to the list.
b9ba6d
b9ba6d
2010-10-20  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
b9ba6d
	    Ulrich Drepper  <drepper@gmail.com>
b9ba6d
b9ba6d
	* elf/dl-object.c (_dl_new_object): Don't append the new object to
b9ba6d
	the global list here.  Move code to...
b9ba6d
	(_dl_add_to_namespace_list): ...here.  New function.
b9ba6d
	* elf/rtld.c (dl_main): Invoke _dl_add_to_namespace_list.
b9ba6d
	* sysdeps/generic/ldsodefs.h (_dl_add_to_namespace_list): Declare.
b9ba6d
	* elf/dl-load.c (lose): Don't remove the element from the list.
b9ba6d
	(_dl_map_object_from_fd): Invoke _dl_add_to_namespace_list.
b9ba6d
	(_dl_map_object): Likewise.
b9ba6d
b9ba6d
Index: glibc-2.12-2-gc4ccff1/elf/dl-load.c
b9ba6d
===================================================================
b9ba6d
--- glibc-2.12-2-gc4ccff1.orig/elf/dl-load.c
b9ba6d
+++ glibc-2.12-2-gc4ccff1/elf/dl-load.c
b9ba6d
@@ -797,22 +797,7 @@ lose (int code, int fd, const char *name
b9ba6d
   /* The file might already be closed.  */
b9ba6d
   if (fd != -1)
b9ba6d
     (void) __close (fd);
b9ba6d
-  if (l != NULL)
b9ba6d
-    {
b9ba6d
-      /* We modify the list of loaded objects.  */
b9ba6d
-      __rtld_lock_lock_recursive (GL(dl_load_write_lock));
b9ba6d
-      /* Remove the stillborn object from the list and free it.  */
b9ba6d
-      assert (l->l_next == NULL);
b9ba6d
-      if (l->l_prev == NULL)
b9ba6d
-	/* No other module loaded. This happens only in the static library,
b9ba6d
-	   or in rtld under --verify.  */
b9ba6d
-	GL(dl_ns)[l->l_ns]._ns_loaded = NULL;
b9ba6d
-      else
b9ba6d
-	l->l_prev->l_next = NULL;
b9ba6d
-      --GL(dl_ns)[l->l_ns]._ns_nloaded;
b9ba6d
-      free (l);
b9ba6d
-      __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
b9ba6d
-    }
b9ba6d
+  free (l);
b9ba6d
   free (realname);
b9ba6d
 
b9ba6d
   if (r != NULL)
b9ba6d
@@ -897,6 +882,9 @@ _dl_map_object_from_fd (const char *name
b9ba6d
 	 never be unloaded.  */
b9ba6d
       __close (fd);
b9ba6d
 
b9ba6d
+      /* Add the map for the mirrored object to the object list.  */
b9ba6d
+      _dl_add_to_namespace_list (l, nsid);
b9ba6d
+
b9ba6d
       return l;
b9ba6d
     }
b9ba6d
 #endif
b9ba6d
@@ -1491,6 +1479,9 @@ cannot enable executable stack as shared
b9ba6d
     add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
b9ba6d
 			    + l->l_info[DT_SONAME]->d_un.d_val));
b9ba6d
 
b9ba6d
+  /* Now that the object is fully initialized add it to the object list.  */
b9ba6d
+  _dl_add_to_namespace_list (l, nsid);
b9ba6d
+
b9ba6d
 #ifdef SHARED
b9ba6d
   /* Auditing checkpoint: we have a new object.  */
b9ba6d
   if (__builtin_expect (GLRO(dl_naudit) > 0, 0)
b9ba6d
@@ -2215,7 +2206,7 @@ _dl_map_object (struct link_map *loader,
b9ba6d
 	     have.  */
b9ba6d
 	  static const Elf_Symndx dummy_bucket = STN_UNDEF;
b9ba6d
 
b9ba6d
-	  /* Enter the new object in the list of loaded objects.  */
b9ba6d
+	  /* Allocate a new object map.  */
b9ba6d
 	  if ((name_copy = local_strdup (name)) == NULL
b9ba6d
 	      || (l = _dl_new_object (name_copy, name, type, loader,
b9ba6d
 				      mode, nsid)) == NULL)
b9ba6d
@@ -2233,6 +2224,9 @@ _dl_map_object (struct link_map *loader,
b9ba6d
 	  l->l_nbuckets = 1;
b9ba6d
 	  l->l_relocated = 1;
b9ba6d
 
b9ba6d
+	  /* Enter the object in the object list.  */
b9ba6d
+	  _dl_add_to_namespace_list (l, nsid);
b9ba6d
+
b9ba6d
 	  return l;
b9ba6d
 	}
b9ba6d
       else if (found_other_class)
b9ba6d
Index: glibc-2.12-2-gc4ccff1/elf/dl-object.c
b9ba6d
===================================================================
b9ba6d
--- glibc-2.12-2-gc4ccff1.orig/elf/dl-object.c
b9ba6d
+++ glibc-2.12-2-gc4ccff1/elf/dl-object.c
b9ba6d
@@ -26,16 +26,41 @@
b9ba6d
 #include <assert.h>
b9ba6d
 
b9ba6d
 
b9ba6d
+/* Add the new link_map NEW to the end of the namespace list.  */
b9ba6d
+void
b9ba6d
+internal_function
b9ba6d
+_dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
b9ba6d
+{
b9ba6d
+  /* We modify the list of loaded objects.  */
b9ba6d
+  __rtld_lock_lock_recursive (GL(dl_load_write_lock));
b9ba6d
+
b9ba6d
+  if (GL(dl_ns)[nsid]._ns_loaded != NULL)
b9ba6d
+    {
b9ba6d
+      struct link_map *l = GL(dl_ns)[nsid]._ns_loaded;
b9ba6d
+      while (l->l_next != NULL)
b9ba6d
+	l = l->l_next;
b9ba6d
+      new->l_prev = l;
b9ba6d
+      /* new->l_next = NULL;   Would be necessary but we use calloc.  */
b9ba6d
+      l->l_next = new;
b9ba6d
+    }
b9ba6d
+  else
b9ba6d
+    GL(dl_ns)[nsid]._ns_loaded = new;
b9ba6d
+  ++GL(dl_ns)[nsid]._ns_nloaded;
b9ba6d
+  new->l_serial = GL(dl_load_adds);
b9ba6d
+  ++GL(dl_load_adds);
b9ba6d
+
b9ba6d
+  __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
b9ba6d
+}
b9ba6d
+
b9ba6d
+
b9ba6d
 /* Allocate a `struct link_map' for a new object being loaded,
b9ba6d
    and enter it into the _dl_loaded list.  */
b9ba6d
-
b9ba6d
 struct link_map *
b9ba6d
 internal_function
b9ba6d
 _dl_new_object (char *realname, const char *libname, int type,
b9ba6d
 		struct link_map *loader, int mode, Lmid_t nsid)
b9ba6d
 {
b9ba6d
   struct link_map *l;
b9ba6d
-  int idx;
b9ba6d
   size_t libname_len = strlen (libname) + 1;
b9ba6d
   struct link_map *new;
b9ba6d
   struct libname_list *newname;
b9ba6d
@@ -93,31 +118,12 @@ _dl_new_object (char *realname, const ch
b9ba6d
   new->l_scope = new->l_scope_mem;
b9ba6d
   new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
b9ba6d
 
b9ba6d
-  /* We modify the list of loaded objects.  */
b9ba6d
-  __rtld_lock_lock_recursive (GL(dl_load_write_lock));
b9ba6d
-
b9ba6d
   /* Counter for the scopes we have to handle.  */
b9ba6d
-  idx = 0;
b9ba6d
+  int idx = 0;
b9ba6d
 
b9ba6d
   if (GL(dl_ns)[nsid]._ns_loaded != NULL)
b9ba6d
-    {
b9ba6d
-      l = GL(dl_ns)[nsid]._ns_loaded;
b9ba6d
-      while (l->l_next != NULL)
b9ba6d
-	l = l->l_next;
b9ba6d
-      new->l_prev = l;
b9ba6d
-      /* new->l_next = NULL;	Would be necessary but we use calloc.  */
b9ba6d
-      l->l_next = new;
b9ba6d
-
b9ba6d
-      /* Add the global scope.  */
b9ba6d
-      new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
b9ba6d
-    }
b9ba6d
-  else
b9ba6d
-    GL(dl_ns)[nsid]._ns_loaded = new;
b9ba6d
-  ++GL(dl_ns)[nsid]._ns_nloaded;
b9ba6d
-  new->l_serial = GL(dl_load_adds);
b9ba6d
-  ++GL(dl_load_adds);
b9ba6d
-
b9ba6d
-  __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
b9ba6d
+    /* Add the global scope.  */
b9ba6d
+    new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
b9ba6d
 
b9ba6d
   /* If we have no loader the new object acts as it.  */
b9ba6d
   if (loader == NULL)
b9ba6d
Index: glibc-2.12-2-gc4ccff1/elf/rtld.c
b9ba6d
===================================================================
b9ba6d
--- glibc-2.12-2-gc4ccff1.orig/elf/rtld.c
b9ba6d
+++ glibc-2.12-2-gc4ccff1/elf/rtld.c
b9ba6d
@@ -1108,11 +1108,15 @@ of this helper program; chances are you 
b9ba6d
       main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
b9ba6d
 				 __RTLD_OPENEXEC, LM_ID_BASE);
b9ba6d
       assert (main_map != NULL);
b9ba6d
-      assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
b9ba6d
       main_map->l_phdr = phdr;
b9ba6d
       main_map->l_phnum = phnum;
b9ba6d
       main_map->l_entry = *user_entry;
b9ba6d
 
b9ba6d
+      /* Even though the link map is not yet fully initialized we can add
b9ba6d
+	 it to the map list since there are no possible users running yet.  */
b9ba6d
+      _dl_add_to_namespace_list (main_map, LM_ID_BASE);
b9ba6d
+      assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
b9ba6d
+
b9ba6d
       /* At this point we are in a bit of trouble.  We would have to
b9ba6d
 	 fill in the values for l_dev and l_ino.  But in general we
b9ba6d
 	 do not know where the file is.  We also do not handle AT_EXECFD
b9ba6d
@@ -1380,6 +1384,9 @@ of this helper program; chances are you 
b9ba6d
 	      l->l_libname->name = memcpy (copy, dsoname, len);
b9ba6d
 	    }
b9ba6d
 
b9ba6d
+	  /* Add the vDSO to the object list.  */
b9ba6d
+	  _dl_add_to_namespace_list (l, LM_ID_BASE);
b9ba6d
+
b9ba6d
 	  /* Rearrange the list so this DSO appears after rtld_map.  */
b9ba6d
 	  assert (l->l_next == NULL);
b9ba6d
 	  assert (l->l_prev == main_map);
b9ba6d
Index: glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
b9ba6d
===================================================================
b9ba6d
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h
b9ba6d
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
b9ba6d
@@ -891,8 +891,11 @@ extern lookup_t _dl_lookup_symbol_x (con
b9ba6d
 extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name)
b9ba6d
      internal_function;
b9ba6d
 
b9ba6d
-/* Allocate a `struct link_map' for a new object being loaded,
b9ba6d
-   and enter it into the _dl_main_map list.  */
b9ba6d
+/* Add the new link_map NEW to the end of the namespace list.  */
b9ba6d
+extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
b9ba6d
+     internal_function attribute_hidden;
b9ba6d
+
b9ba6d
+/* Allocate a `struct link_map' for a new object being loaded.  */
b9ba6d
 extern struct link_map *_dl_new_object (char *realname, const char *libname,
b9ba6d
 					int type, struct link_map *loader,
b9ba6d
 					int mode, Lmid_t nsid)