about summary refs log tree commit diff
path: root/elf/dl-deps.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-30 12:31:25 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-30 12:31:25 -0400
commit6b1e7d1992cd89032df431c0e0d1418b97e57cd8 (patch)
tree708eff9b7d7318adf26082ca2df86c71899c1255 /elf/dl-deps.c
parent4997db742946d08be4378cf91221f558f928bc73 (diff)
downloadglibc-6b1e7d1992cd89032df431c0e0d1418b97e57cd8.tar.gz
glibc-6b1e7d1992cd89032df431c0e0d1418b97e57cd8.tar.xz
glibc-6b1e7d1992cd89032df431c0e0d1418b97e57cd8.zip
Handle DSOs without any dependency in ld.so
Diffstat (limited to 'elf/dl-deps.c')
-rw-r--r--elf/dl-deps.c93
1 files changed, 48 insertions, 45 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index d3c27f14cc..0b03b903fe 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -617,61 +617,64 @@ Filters not supported with LD_TRACE_PRELINKING"));
 	map->l_searchlist.r_list[i]->l_reserved = 0;
     }
 
-  /* Now determine the order in which the initialization has to happen.  */
+  /* Sort the initializer list to take dependencies into account.  The binary
+     itself will always be initialize last.  */
   memcpy (l_initfini, map->l_searchlist.r_list,
 	  nlist * sizeof (struct link_map *));
-
-  /* We can skip looking for the binary itself which is at the front
-     of the search list.  */
-  assert (nlist > 1);
-  i = 1;
-  bool seen[nlist];
-  memset (seen, false, nlist * sizeof (seen[0]));
-  while (1)
+  if (__builtin_expect (nlist > 1, 1))
     {
-      /* Keep track of which object we looked at this round.  */
-      seen[i] = true;
-      struct link_map *thisp = l_initfini[i];
-
-      /* Find the last object in the list for which the current one is
-	 a dependency and move the current object behind the object
-	 with the dependency.  */
-      unsigned int k = nlist - 1;
-      while (k > i)
+      /* We can skip looking for the binary itself which is at the front
+	 of the search list.  */
+      i = 1;
+      bool seen[nlist];
+      memset (seen, false, nlist * sizeof (seen[0]));
+      while (1)
 	{
-	  struct link_map **runp = l_initfini[k]->l_initfini;
-	  if (runp != NULL)
-	    /* Look through the dependencies of the object.  */
-	    while (*runp != NULL)
-	      if (__builtin_expect (*runp++ == thisp, 0))
-		{
-		  /* Move the current object to the back past the last
-		     object with it as the dependency.  */
-		  memmove (&l_initfini[i], &l_initfini[i + 1],
-			   (k - i) * sizeof (l_initfini[0]));
-		  l_initfini[k] = thisp;
-
-		  if (seen[i + 1])
+	  /* Keep track of which object we looked at this round.  */
+	  seen[i] = true;
+	  struct link_map *thisp = l_initfini[i];
+
+	  /* Find the last object in the list for which the current one is
+	     a dependency and move the current object behind the object
+	     with the dependency.  */
+	  unsigned int k = nlist - 1;
+	  while (k > i)
+	    {
+	      struct link_map **runp = l_initfini[k]->l_initfini;
+	      if (runp != NULL)
+		/* Look through the dependencies of the object.  */
+		while (*runp != NULL)
+		  if (__builtin_expect (*runp++ == thisp, 0))
 		    {
-		      ++i;
-		      goto next_clear;
+		      /* Move the current object to the back past the last
+			 object with it as the dependency.  */
+		      memmove (&l_initfini[i], &l_initfini[i + 1],
+			       (k - i) * sizeof (l_initfini[0]));
+		      l_initfini[k] = thisp;
+
+		      if (seen[i + 1])
+			{
+			  ++i;
+			  goto next_clear;
+			}
+
+		      memmove (&seen[i], &seen[i + 1],
+			       (k - i) * sizeof (seen[0]));
+		      seen[k] = true;
+
+		      goto next;
 		    }
 
-		  memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0]));
-		  seen[k] = true;
+	      --k;
+	    }
 
-		  goto next;
-		}
+	  if (++i == nlist)
+	    break;
+	next_clear:
+	  memset (&seen[i], false, (nlist - i) * sizeof (seen[0]));
 
-	  --k;
+	next:;
 	}
-
-      if (++i == nlist)
-	break;
-    next_clear:
-      memset (&seen[i], false, (nlist - i) * sizeof (seen[0]));
-
-    next:;
     }
 
   /* Terminate the list of dependencies.  */