about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorGuy Martin <gmsoft@tuxicoman.be>2013-11-21 13:23:16 -0500
committerCarlos O'Donell <carlos@redhat.com>2013-11-21 15:52:31 -0500
commitdaf75146de07303ea0c5ad700ec5ef703ec114a1 (patch)
treeed307e39a90288cbcdf727a7c07addb9f38f65d8 /elf
parentd33cafadfe365befa4ca6e0463fa926d56144046 (diff)
downloadglibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.tar.gz
glibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.tar.xz
glibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.zip
Don't use broken DL_AUTO_FUNCTION_ADDRESS()
On hppa and ia64, the macro DL_AUTO_FUNCTION_ADDRESS() uses the
variable fptr[2] in it's own scope.

The content of fptr[] is thus undefined right after the macro exits.
Newer gcc's (>= 4.7) reuse the stack space of this variable triggering
a segmentation fault in dl-init.c:69.

To fix this we rewrite the macros to make the call directly to init
and fini without needing to pass back a constructed function pointer.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c5
-rw-r--r--elf/dl-fini.c2
-rw-r--r--elf/dl-init.c8
3 files changed, 4 insertions, 11 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index fe3014cca3..407926bade 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -274,9 +274,8 @@ _dl_close_worker (struct link_map *map)
 
 	      /* Next try the old-style destructor.  */
 	      if (imap->l_info[DT_FINI] != NULL)
-		(*(void (*) (void)) DL_DT_FINI_ADDRESS
-		 (imap, ((void *) imap->l_addr
-			 + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
+		DL_CALL_DT_FINI (imap, ((void *) imap->l_addr
+			 + imap->l_info[DT_FINI]->d_un.d_ptr));
 	    }
 
 #ifdef SHARED
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 6b245f0022..db5269c82f 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -254,7 +254,7 @@ _dl_fini (void)
 
 		  /* Next try the old-style destructor.  */
 		  if (l->l_info[DT_FINI] != NULL)
-		    ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
+		     DL_CALL_DT_FINI(l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
 		}
 
 #ifdef SHARED
diff --git a/elf/dl-init.c b/elf/dl-init.c
index a657eb6c40..40783684f2 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -61,13 +61,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
      - the others in the DT_INIT_ARRAY.
   */
   if (l->l_info[DT_INIT] != NULL)
-    {
-      init_t init = (init_t) DL_DT_INIT_ADDRESS
-	(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
-
-      /* Call the function.  */
-      init (argc, argv, env);
-    }
+    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
 
   /* Next see whether there is an array with initialization functions.  */
   ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];