about summary refs log tree commit diff
path: root/sysdeps/generic/libc-start.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-12 00:58:26 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-12 00:58:26 +0000
commit09d65ff393e9183eecba1e5cb877e95dbdd3d4a4 (patch)
treeb618ac607f17c1d683f1ea1e4d34415e4ea8e7f8 /sysdeps/generic/libc-start.c
parent877e51b20f69ce1927c4978134d0c2afbbf856ad (diff)
downloadglibc-09d65ff393e9183eecba1e5cb877e95dbdd3d4a4.tar.gz
glibc-09d65ff393e9183eecba1e5cb877e95dbdd3d4a4.tar.xz
glibc-09d65ff393e9183eecba1e5cb877e95dbdd3d4a4.zip
Update.
2003-04-11  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/generic/libc-start.c: Cleanup MAIN_AUXVEC_ARG handling.
	Remove HAVE_CANCELBUF code.  Replace with code using the new
	initializers for unwind-based cleanup handling.
	* sysdeps/generic/unwind.h: Update from latest gcc version.
	* sysdeps/unix/sysv/linux/i386/sysdep.h: Define labels in a few
	places to allow unwind data generation.
	* sysdeps/i386/bits/setjmp.h: Allow file to be included multiple times.
	* sysdeps/x86_64/bits/setjmp.h: Likewise.
	* sysdeps/sh/bits/setjmp.h: Likewise.
	* sysdeps/powerpc/bits/setjmp.h: Likewise.
	* sysdeps/unix/sysv/linux/ia64/bits/setjmp.h: Likewise.
	* sysdeps/alpha/bits/setjmp.h: Likewise.
Diffstat (limited to 'sysdeps/generic/libc-start.c')
-rw-r--r--sysdeps/generic/libc-start.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/sysdeps/generic/libc-start.c b/sysdeps/generic/libc-start.c
index 351205d636..b98f0a2aa0 100644
--- a/sysdeps/generic/libc-start.c
+++ b/sysdeps/generic/libc-start.c
@@ -51,12 +51,17 @@ extern void __pthread_initialize_minimal (void)
 # define LIBC_START_MAIN BP_SYM (__libc_start_main)
 #endif
 
-STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
 #ifdef MAIN_AUXVEC_ARG
-					 , void *
+/* main gets passed a pointer to the auxiliary.  */
+# define MAIN_AUXVEC_DECL	, void *
+# define MAIN_AUXVEC_PARAM	, auxvec
+#else
+# define MAIN_AUXVEC_DECL
+# define MAIN_AUXVEC_PARAM
 #endif
 
-					 ),
+STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
+					 MAIN_AUXVEC_DECL),
 			    int argc,
 			    char *__unbounded *__unbounded ubp_av,
 #ifdef LIBC_START_MAIN_AUXVEC_ARG
@@ -73,11 +78,7 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
      __attribute__ ((noreturn));
 
 STATIC int
-LIBC_START_MAIN (int (*main) (int, char **, char **
-#ifdef MAIN_AUXVEC_ARG
-			      , void *
-#endif
-			      ),
+LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
 		 int argc, char *__unbounded *__unbounded ubp_av,
 #ifdef LIBC_START_MAIN_AUXVEC_ARG
 		 ElfW(auxv_t) *__unbounded auxvec,
@@ -172,10 +173,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char **
   if (init)
     (*init) (
 #ifdef INIT_MAIN_ARGS
-	     argc, argv, __environ
-# ifdef MAIN_AUXVEC_ARG
-	     , auxvec
-# endif
+	     argc, argv, __environ MAIN_AUXVEC_PARAM
 #endif
 	     );
 
@@ -184,38 +182,45 @@ LIBC_START_MAIN (int (*main) (int, char **, char **
     _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
 #endif
 
-#ifdef HAVE_CANCELBUF
-  if (setjmp (THREAD_SELF->cancelbuf) == 0)
-#endif
+#ifdef HAVE_CLEANUP_JMP_BUF
+  /* Memory for the cancellation buffer.  */
+  struct pthread_unwind_buf unwind_buf;
+
+  int not_first_call;
+  not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+  if (__builtin_expect (! not_first_call, 1))
     {
-      /* XXX This is where the try/finally handling must be used.  */
+      struct pthread *self = THREAD_SELF;
 
-      result = main (argc, argv, __environ
-#ifdef MAIN_AUXVEC_ARG
-		     , auxvec
-#endif
+      /* Store old info.  */
+      unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+      unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
 
-		     );
+      /* Store the new cleanup handler info.  */
+      THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
+
+      /* Run the program.  */
+      result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
     }
-#ifdef HAVE_CANCELBUF
   else
     {
-# ifdef HAVE_PTR_NTHREADS
       /* One less thread.  Decrement the counter.  If it is zero we
 	 terminate the entire process.  */
       result = 0;
-#  ifdef SHARED
+# ifdef SHARED
       int *const ptr = __libc_pthread_functions.ptr_nthreads;
-#  else
+# else
       extern int __nptl_nthreads __attribute ((weak));
       int *const ptr = &__nptl_nthreads;
-#  endif
+# endif
 
       if (! atomic_decrement_and_test (ptr))
-# endif
 	/* Not much left to do but to exit the thread, not the process.  */
 	__exit_thread (0);
     }
+#else
+  /* Nothing fancy, just call the function.  */
+  result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
 #endif
 
   exit (result);