about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Pluzhnikov <ppluzhnikov@google.com>2011-10-31 16:27:54 -0700
committerRoland McGrath <roland@hack.frob.com>2011-10-31 16:27:54 -0700
commit02f9c6cfe286ebd1f39106ae77245c5514ec6919 (patch)
treeea1864301d110e31163f7c91e5dc9b2f99514639
parentf4ec483382e167469def497422dbb30fee5f5f32 (diff)
downloadglibc-02f9c6cfe286ebd1f39106ae77245c5514ec6919.tar.gz
glibc-02f9c6cfe286ebd1f39106ae77245c5514ec6919.tar.xz
glibc-02f9c6cfe286ebd1f39106ae77245c5514ec6919.zip
Use extend_alloca in _dl_map_object_deps.
-rw-r--r--ChangeLog5
-rw-r--r--elf/dl-deps.c19
2 files changed, 22 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 83a64e8358..6e247ec445 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-10-31  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	* elf/dl-deps.c (_dl_map_object_deps): Reuse alloca space to reduce
+	stack usage.
+
 2011-10-31  Ulrich Drepper  <drepper@gmail.com>
 
 	[BZ #13367]
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 95b1088f22..a1ba3d1d32 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -188,6 +188,10 @@ _dl_map_object_deps (struct link_map *map,
   /* Pointer to last unique object.  */
   tail = &known[nlist - 1];
 
+  /* No alloca'd space yet.  */
+  struct link_map **needed_space = NULL;
+  size_t needed_space_bytes = 0;
+
   /* Process each element of the search list, loading each of its
      auxiliary objects and immediate dependencies.  Auxiliary objects
      will be added in the list before the object itself and
@@ -216,8 +220,19 @@ _dl_map_object_deps (struct link_map *map,
 	 dependencies of this object.  */
       if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL
 	  && l != map && l->l_ldnum > 0)
-	needed = (struct link_map **) alloca (l->l_ldnum
-					      * sizeof (struct link_map *));
+	{
+	  /* 16-align so extend_alloca has a chance to re-use the space.
+	     Note that extend_alloca is broken for recent versions of GCC
+	     on x86: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50938  */
+	  size_t new_size
+            = (l->l_ldnum * sizeof (struct link_map *) + 15) & ~15;
+
+	  if (new_size > needed_space_bytes)
+	    needed_space
+              = extend_alloca (needed_space, needed_space_bytes, new_size);
+
+	  needed = needed_space;
+	}
 
       if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])
 	{