]> sourceware.org Git - glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 12 Apr 2003 00:58:26 +0000 (00:58 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 12 Apr 2003 00:58:26 +0000 (00:58 +0000)
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.

22 files changed:
ChangeLog
nptl/ChangeLog
nptl/Makefile
nptl/Versions
nptl/sysdeps/pthread/bits/libc-lock.h
nptl/sysdeps/pthread/configure
nptl/sysdeps/pthread/configure.in
nptl/sysdeps/pthread/pthread-functions.h
nptl/sysdeps/pthread/pthread.h
nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
nptl/unwind.c [new file with mode: 0644]
nptl/version.c
sysdeps/alpha/bits/setjmp.h
sysdeps/generic/libc-start.c
sysdeps/generic/unwind.h
sysdeps/i386/bits/setjmp.h
sysdeps/powerpc/bits/setjmp.h
sysdeps/sh/bits/setjmp.h
sysdeps/unix/sysv/linux/i386/sysdep.h
sysdeps/unix/sysv/linux/ia64/bits/setjmp.h
sysdeps/x86_64/bits/setjmp.h

index 9f1eb446f14abedb13d114b4d0f2020b91dfb992..57be8c46bcac1e0658c2f5660819a0682bddc493 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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.
+
 2003-04-11  Roland McGrath  <roland@redhat.com>
 
        * csu/tst-empty.c: New file.
index 6ffe62314ee71f2c898f116097056841f4ad4d08..bbda8c591ee074fd60624d79f5c2d3579aa7f5c4 100644 (file)
@@ -1,3 +1,45 @@
+2003-04-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread.h: Define new data structure for cleanup buffer.  Declare
+       new cleanup handler interfaces.
+       * descr.h: Include <unwind.h> if necessary.  Define pthread_unwind_buf.
+       (struct pthread): Add cleanup_jmp_buf pointer.  Define
+       HAVE_CLEANUP_JMP_BUF and not HAVE_CANCELBUF.
+       * pthreadP.h: Declare __pthread_unwind.  Define __do_cancel to use
+       it.  Declare old cleanup handler installation functions.
+       * cleanup.c: Rewrite.  Install handler for unwind-based cleanup
+       handling.
+       * cleanup_defer.c: Likewise.
+       * cleanup_compat.c: New file.  Old cleanup code.
+       * cleanup_def_compat.c: New file.  Old cleanup code.
+       * pthread_create.c (start_thread): Initialize cleanup_jmp_buf element
+       if own thread descriptor.
+       * unwind.c: New file.
+       * forward.c: Add __pthread_unwind.
+       * init.c (pthread_functions): Add __pthread_unwind.
+       * sysdeps/pthread/pthread-functions.s (struct pthread_functions):
+       Add ptr___pthread_unwind.
+       * Versions [GLIBC_2.3.3] (libpthread): Export new cleanup handling
+       and unwind function.
+       * Makefile (libpthread-routines): Add cleanup_compat,
+       cleanup_def_compat, and unwind.  Define CFLAGS to enable unwind
+       table generation if necessary.
+       * version.c: Record whether unwind support is compiled in.
+       * sysdeps/pthread/configure.in: Add checks for unwind unterfaces.
+       * sysdeps/pthread/bits/libc-lock.h: Add prototypes of the old cleanup
+       handler interfaces.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Add quite a bit of
+       complication to generate unwind information for syscall wrappers.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Define
+       __cleanup_fct_attribute.
+
+       * Makefile: Add rules to build and run tst-cleanup0.
+       * tst-cleanup0.c: New file.
+       * tst-cleanup0.expect: New file.
+
+       * pthread_create.c (deallocate_tsd): Don't take parameter.  Adjust
+       caller.  Optimize to avoid often unecessary local variable.
+
 2003-04-11  Roland McGrath  <roland@redhat.com>
 
        * Makefile ($(objpfx)multidir.mk): New target, generated makefile that
index cd8ad98c38e433b168035f750a54c6aad38ac67e..79d28c9a3016dc44b4e2e3668f5b76fdd38f4948 100644 (file)
@@ -98,7 +98,8 @@ libpthread-routines = init events version \
                      sem_open sem_close sem_unlink \
                      sem_getvalue \
                      sem_wait sem_trywait sem_timedwait sem_post \
-                     cleanup cleanup_defer \
+                     cleanup cleanup_defer cleanup_compat \
+                     cleanup_defer_compat unwind \
                      pt-longjmp \
                      cancellation \
                      lowlevellock lowlevelmutex \
@@ -122,6 +123,10 @@ libpthread-static-only-routines = pthread_atfork
 libpthread-nonshared = pthread_atfork
 
 CFLAGS-pthread_atfork.c = -DNOT_IN_libc
+CFLAGS-init.c = -fexceptions -fasynchronous-unwind-tables
+CFLAGS-unwind.c = -fexceptions
+CFLAGS-cancellation.c = -fasynchronous-unwind-tables
+CFLAGS-libc-cancellation.c = -fasynchronous-unwind-tables
 
 # Don't generate deps for calls with no sources.  See sysdeps/unix/Makefile.
 omit-deps = $(unix-syscalls:%=ptw-%)
@@ -153,7 +158,7 @@ tests = tst-attr1 tst-attr2 \
        tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
        tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
        tst-cancel11 \
-       tst-cleanup1 tst-cleanup2 tst-cleanup3 \
+       tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \
        tst-flock1 tst-flock2 \
        tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
        tst-exec1 tst-exec2 tst-exec3 \
@@ -208,6 +213,9 @@ CFLAGS-flockfile.c = -D_IO_MTSAFE_IO
 CFLAGS-ftrylockfile.c = -D_IO_MTSAFE_IO
 CFLAGS-funlockfile.c = -D_IO_MTSAFE_IO
 
+# Ugly, ugly.  We have to link with libgcc_eh but how?
+link-libc-static := $(common-objpfx)libc.a $(gnulib) -lgcc_eh $(common-objpfx)libc.a
+
 ifeq ($(build-static),yes)
 tests-static += tst-locale1 tst-locale2
 endif
@@ -220,7 +228,6 @@ ifeq (yes,$(build-shared))
 # Make sure these things are built in the `make lib' pass so they can be used
 # to run programs during the `make others' pass.
 lib-noranlib: $(addprefix $(objpfx),$(extra-objs))
-endif
 
 # What we install as libpthread.so for programs to link against is in fact a
 # link script.  It contains references for the various libraries we need.
@@ -229,6 +236,7 @@ endif
 # We need to use absolute paths since otherwise local copies (if they exist)
 # of the files are taken by the linker.
 install: $(inst_libdir)/libpthread.so
+
 $(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
                              $(objpfx)libpthread.so$(libpthread.so-version) \
                              $(inst_libdir)/$(patsubst %,$(libtype.oS),\
@@ -245,6 +253,8 @@ $(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
        mv -f $@.new $@
 $(inst_libdir)/libpthread_nonshared.a: $(objpfx)libpthread_nonshared.a
        $(do-install)
+endif
+
 
 # 'pthread_self' is a simple memory or register load.  Setting up the
 # stack frame is more work than the actual operation.  Disable the
@@ -313,6 +323,9 @@ $(objpfx)pt-initfini.s: pt-initfini.c
        $(compile.c) -S $(CFLAGS-pt-initfini.s) -finhibit-size-directive \
                $(patsubst -f%,-fno-%,$(exceptions)) -o $@
 
+$(objpfx)tst-cleanup0.out: /dev/null $(objpfx)tst-cleanup0
+       $(make-test-out) 2>&1 | cmp - tst-cleanup0.expect >& $@
+
 # We only have one kind of startup code files.  Static binaries and
 # shared libraries are build using the PIC version.
 $(objpfx)crti.S: $(objpfx)pt-initfini.s
index 5824108426f335ba7cffa4f4efc824c97904b923..4f52eb66f3dfa5d8f7a2c8328de757163b9ba6dc 100644 (file)
@@ -211,6 +211,11 @@ libpthread {
 
     # Proposed API extensions.
     pthread_tryjoin_np; pthread_timedjoin_np;
+
+    # New cancellation cleanup handling.
+    __pthread_register_cancel; __pthread_unregister_cancel;
+    __pthread_register_cancel_defer; __pthread_unregister_cancel_restore;
+    __pthread_unwind_next;
   }
 
   GLIBC_PRIVATE {
index 3a3d3cc6d37bb4924347b2a36d178b70512d65bb..945a81cb8266fa7ccb58b0125382854bcdc77dc2 100644 (file)
@@ -345,6 +345,19 @@ typedef pthread_key_t __libc_key_t;
   } while (0)
 
 
+/* Note that for I/O cleanup handling we are using the old-style
+   cancel handling.  It does not have to be integrated with C++ snce
+   no C++ code is called in the middle.  The old-style handling is
+   faster and the support is not going away.  */
+extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
+                                   void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
+                                  int execute);
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
+                                         void (*routine) (void *), void *arg);
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
+                                          int execute);
+
 /* Start critical region with cleanup.  */
 #define __libc_cleanup_region_start(DOIT, FCT, ARG) \
   { struct _pthread_cleanup_buffer _buffer;                                  \
index 8999d37e5ab0ea011b5c05b527effa9952d6a310..50293a4f1c2792b8c763f04cf2c428ca4843efc6 100755 (executable)
@@ -5,3 +5,58 @@ if test "x$libc_cv_gcc___thread" != xyes; then
 echo "$as_me: error: compiler support for __thread is required" >&2;}
    { (exit 1); exit 1; }; }
 fi
+
+
+echo "$as_me:$LINENO: checking for forced unwind support" >&5
+echo $ECHO_N "checking for forced unwind support... $ECHO_C" >&6
+if test "${libc_cv_forced_unwind+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <unwind.h>
+int
+main ()
+{
+
+struct _Unwind_Exception exc;
+struct _Unwind_Context *context;
+_Unwind_GetCFA (context)
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  libc_cv_forced_unwind=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+libc_cv_forced_unwind=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $libc_cv_forced_unwind" >&5
+echo "${ECHO_T}$libc_cv_forced_unwind" >&6
+if test $libc_cv_forced_unwind = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FORCED_UNWIND 1
+_ACEOF
+
+fi
index 8350f86dc065c3aef4213d2bdb151831b67935c5..e4ea6830d6bd682461144bb3086f6d2847d68a92 100644 (file)
@@ -4,3 +4,16 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
 if test "x$libc_cv_gcc___thread" != xyes; then
   AC_MSG_ERROR(compiler support for __thread is required)
 fi
+
+dnl Iff <unwind.h> is available, make sure it is the right one and it
+dnl contains struct _Unwind_Exception.
+AC_CACHE_CHECK(dnl
+for forced unwind support, libc_cv_forced_unwind, [dnl
+AC_TRY_LINK([#include <unwind.h>], [
+struct _Unwind_Exception exc;
+struct _Unwind_Context *context;
+_Unwind_GetCFA (context)],
+libc_cv_forced_unwind=yes, libc_cv_forced_unwind=no)])
+if test $libc_cv_forced_unwind = yes; then
+  AC_DEFINE(HAVE_FORCED_UNWIND)
+fi
index 9f38e34053ea3b6e3b47e67b4a8098deed130a8a..93ba0899828342adfb2fcf836e928002dc0187a5 100644 (file)
@@ -85,6 +85,8 @@ struct pthread_functions
                                            int);
 #define HAVE_PTR_NTHREADS
   int *ptr_nthreads;
+  void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *)
+       __attribute ((noreturn)) __cleanup_fct_attribute;
 };
 
 /* Variable in libc.so.  */
index 72673d11a6593b7c66ccf026bb235d26cb92df4b..5373b80dcf2d47c063f5fb475a930d9e040e8874 100644 (file)
@@ -26,6 +26,7 @@
 #define __need_sigset_t
 #include <signal.h>
 #include <bits/pthreadtypes.h>
+#include <bits/setjmp.h>
 
 
 /* Detach state.  */
@@ -380,6 +381,24 @@ extern int pthread_cancel (pthread_t __th) __THROW;
 extern void pthread_testcancel (void) __THROW;
 
 
+/* Cancellation handling with integration into exception handling.  */
+
+typedef struct
+{
+  void *__pad[16];
+  struct
+  {
+    __jmp_buf __cancel_jmp_buf;
+    int __mask_was_saved;
+  } __cancel_jmp_buf[1];
+} __pthread_unwind_buf_t __attribute__ ((__aligned__));
+
+/* No special attributes by default.  */
+#ifndef __cleanup_fct_attribute
+# define __cleanup_fct_attribute
+#endif
+
+
 /* Install a cleanup handler: ROUTINE will be called with arguments ARG
    when the thread is cancelled or calls pthread_exit.  ROUTINE will also
    be called with arguments ARG when the matching pthread_cleanup_pop
@@ -387,43 +406,83 @@ extern void pthread_testcancel (void) __THROW;
 
    pthread_cleanup_push and pthread_cleanup_pop are macros and must always
    be used in matching pairs at the same nesting level of braces.  */
-#define pthread_cleanup_push(routine,arg) \
-  { struct _pthread_cleanup_buffer _buffer;                                  \
-    _pthread_cleanup_push (&_buffer, (routine), (arg));
-
-extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
-                                  void (*__routine) (void *), void *__arg)
-     __THROW;
+#define pthread_cleanup_push(routine, arg) \
+  do {                                                                       \
+    __pthread_unwind_buf_t __cancel_buf;                                     \
+    void (*__cancel_routine) (void *) = (routine);                           \
+    void *__cancel_arg = (arg);                                                      \
+    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *)               \
+                                     __cancel_buf.__cancel_jmp_buf, 0);      \
+    if (__builtin_expect (not_first_call, 0))                                \
+      {                                                                              \
+       __cancel_routine (__cancel_arg);                                      \
+       __pthread_unwind_next (&__cancel_buf);                                \
+       /* NOTREACHED */                                                      \
+      }                                                                              \
+                                                                             \
+    __pthread_register_cancel (&__cancel_buf);                               \
+    do {
+extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute;
 
 /* Remove a cleanup handler installed by the matching pthread_cleanup_push.
    If EXECUTE is non-zero, the handler function is called. */
 #define pthread_cleanup_pop(execute) \
-    _pthread_cleanup_pop (&_buffer, (execute)); }
-
-extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
-                                 int __execute) __THROW;
+    } while (0);                                                             \
+    __pthread_unregister_cancel (&__cancel_buf);                             \
+    if (execute)                                                             \
+      __cancel_routine (__cancel_arg);                                       \
+  } while (0)
+extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
+  __cleanup_fct_attribute;
 
 #ifdef __USE_GNU
 /* Install a cleanup handler as pthread_cleanup_push does, but also
    saves the current cancellation type and sets it to deferred
    cancellation.  */
-# define pthread_cleanup_push_defer_np(routine,arg) \
-  { struct _pthread_cleanup_buffer _buffer;                                  \
-    _pthread_cleanup_push_defer (&_buffer, (routine), (arg));
-
-extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
-                                        void (*__routine) (void *),
-                                        void *__arg) __THROW;
+# define pthread_cleanup_push_defer(routine, arg) \
+  do {                                                                       \
+    __pthread_unwind_buf_t __cancel_buf;                                     \
+    void (*__cancel_routine) (void *) = (routine);                           \
+    void *__cancel_arg = (arg);                                                      \
+    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *)               \
+                                     __cancel_buf.__cancel_jmp_buf, 0);      \
+    if (__builtin_expect (not_first_call, 0))                                \
+      {                                                                              \
+       __cancel_routine (__cancel_arg);                                      \
+       __pthread_unwind_next (&__cancel_buf);                                \
+       /* NOTREACHED */                                                      \
+      }                                                                              \
+                                                                             \
+    __pthread_register_cancel_defer (&__cancel_buf);                         \
+    do {
+extern void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute;
 
 /* Remove a cleanup handler as pthread_cleanup_pop does, but also
    restores the cancellation type that was in effect when the matching
    pthread_cleanup_push_defer was called.  */
-# define pthread_cleanup_pop_restore_np(execute) \
-  _pthread_cleanup_pop_restore (&_buffer, (execute)); }
+# define pthread_cleanup_pop_cleanup(execute) \
+    } while (0);                                                             \
+    __pthread_unregister_cancel_restore (&__cancel_buf);                     \
+    if (execute)                                                             \
+      __cancel_routine (__cancel_arg);                                       \
+  } while (0)
+extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
+  __cleanup_fct_attribute;
+#endif
 
-extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
-                                         int __execute) __THROW;
+/* Internal interface to initiate cleanup.  */
+extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
+     __cleanup_fct_attribute __attribute ((__noreturn__))
+#ifndef SHARED
+     __attribute ((__weak__))
 #endif
+     ;
+
+/* Function used in the macros.  */
+struct __jmp_buf_tag;
+extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROW;
 
 
 /* Mutex handling.  */
index c14f1b1ef631e894a2a35138730dec6b742e96a9..0834894c25274aabdfc50567f826f006cb67a37a 100644 (file)
@@ -149,4 +149,7 @@ typedef union
 #endif
 
 
+/* Extra attributes for the cleanup functions.  */
+#define __cleanup_fct_attribute __attribute ((regparm (1)))
+
 #endif /* bits/pthreadtypes.h */
index 35f05e1cc25e99d78c4cc15671ca5f9cfa2685ef..b7009d753fe3df5e05840510dea35d60089fecaf 100644 (file)
@@ -29,6 +29,7 @@
 # define PSEUDO(name, syscall_name, args)                                    \
   .text;                                                                     \
   ENTRY (name)                                                               \
+  L(name##START):                                                            \
     cmpl $0, %gs:MULTIPLE_THREADS_OFFSET;                                    \
     jne L(pseudo_cancel);                                                    \
     DO_CALL (syscall_name, args);                                            \
   L(pseudo_cancel):                                                          \
     CENABLE                                                                  \
     SAVE_OLDTYPE_##args                                                              \
-    PUSHARGS_##args                                                          \
+    PUSHCARGS_##args                                                         \
     DOCARGS_##args                                                           \
     movl $SYS_ify (syscall_name), %eax;                                              \
-    ENTER_KERNEL                                                             \
-    POPARGS_##args;                                                          \
-    POPCARGS_##args                                                          \
+    /* Until we can handle unwinding from the sysenter page the kernel       \
+       provides we cannot use ENTER_KERNEL here.  */                         \
+    int $0x80;                                                               \
+    POPCARGS_##args;                                                         \
+    POPSTATE_##args                                                          \
     cmpl $-4095, %eax;                                                       \
     jae SYSCALL_ERROR_LABEL;                                                 \
-  L(pseudo_end):
+  L(pseudo_end):                                                             \
+                                                                             \
+  /* Create unwinding information for the syscall wrapper.  */               \
+  .section .eh_frame,"a",@progbits;                                          \
+  L(STARTFRAME):                                                             \
+    /* Length of the CIE.  */                                                \
+    .long L(ENDCIE)-L(STARTCIE);                                             \
+  L(STARTCIE):                                                               \
+    /* CIE ID.  */                                                           \
+    .long 0;                                                                 \
+    /* Version number.  */                                                   \
+    .byte 1;                                                                 \
+    /* NUL-terminated augmentation string.  Note "z" means there is an       \
+       augmentation value later on.  */                                              \
+    .string "zR";                                                            \
+    /* Code alignment factor.  */                                            \
+    .uleb128 1;                                                                      \
+    /* Data alignment factor.  */                                            \
+    .sleb128 -4;                                                             \
+    /* Return address register column.  */                                   \
+    .byte 8;                                                                 \
+    /* Augmentation value length.  */                                        \
+    .uleb128 1;                                                                      \
+    /* Encoding: DW_EH_PE_pcrel + DW_EH_PE_sdata4.  */                       \
+    .byte 0x1b;                                                                      \
+    /* Start of the table initialization.  */                                \
+    .byte 0xc;                                                               \
+    .uleb128 4;                                                                      \
+    .uleb128 4;                                                                      \
+    .byte 0x88;                                                                      \
+    .uleb128 1;                                                                      \
+    .align 4;                                                                \
+  L(ENDCIE):                                                                 \
+    /* Length of the FDE.  */                                                \
+    .long L(ENDFDE)-L(STARTFDE);                                             \
+  L(STARTFDE):                                                               \
+    /* CIE pointer.  */                                                              \
+    .long L(STARTFDE)-L(STARTFRAME);                                         \
+    /* PC-relative start address of the code.  */                            \
+    .long L(name##START)-.;                                                  \
+    /* Length of the code.  */                                               \
+    .long L(name##END)-L(name##START);                                       \
+    /* No augmentation data.  */                                             \
+    .uleb128 0;                                                                      \
+    /* The rest of the code depends on the number of parameters the syscall   \
+       takes.  */                                                            \
+    EH_FRAME_##args(name);                                                   \
+    .align 4;                                                                \
+  L(ENDFDE):                                                                 \
+  .previous
+
+/* Callframe description for syscalls without parameters.  This is very
+   simple.  The only place the stack pointer is changed is when the old
+   cancellation state value is saved.  */
+# define EH_FRAME_0(name) \
+    .byte 4;                                                                 \
+    .long L(PUSHSTATE)-name;                                                 \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPSTATE)-L(PUSHSTATE);                                          \
+    .byte 14;                                                                \
+    .uleb128 4
+
+/* For syscalls with one and two parameters the code is the same as for
+   those which take no parameter.  */
+# define EH_FRAME_1(name) EH_FRAME_0 (name)
+# define EH_FRAME_2(name) EH_FRAME_1 (name)
+
+/* For syscalls with three parameters the stack pointer is changed
+   also to save the content of the %ebx register.  */
+# define EH_FRAME_3(name) \
+    .byte 4;                                                                 \
+    .long L(PUSHBX1)-name;                                                   \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPBX1)-L(PUSHBX1);                                                      \
+    .byte 14;                                                                \
+    .uleb128 4;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHSTATE)-L(POPBX1);                                            \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHBX2)-L(PUSHSTATE);                                           \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPBX2)-L(PUSHBX2);                                                      \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPSTATE)-L(POPBX2);                                             \
+    .byte 14;                                                                \
+    .uleb128 4
+
+/* With four parameters the syscall wrappers have to save %ebx and %esi.  */
+# define EH_FRAME_4(name) \
+    .byte 4;                                                                 \
+    .long L(PUSHSI1)-name;                                                   \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHBX1)-L(PUSHSI1);                                             \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPBX1)-L(PUSHBX1);                                                      \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPSI1)-L(POPBX1);                                               \
+    .byte 14;                                                                \
+    .uleb128 4;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHSTATE)-L(POPSI1);                                            \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHSI2)-L(PUSHSTATE);                                           \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(PUSHBX2)-L(PUSHSI2);                                             \
+    .byte 14;                                                                \
+    .uleb128 16;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPBX2)-L(PUSHBX2);                                                      \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPSI2)-L(POPBX2);                                               \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPSTATE)-L(POPSI2);                                             \
+    .byte 14;                                                                \
+    .uleb128 4
+
+/* With five parameters the syscall wrappers have to save %ebx, %esi,
+   and %edi.  */
+# define EH_FRAME_5(name) \
+    .byte 4;                                                                 \
+    .long L(PUSHDI1)-name;                                                   \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHSI1)-L(PUSHDI1);                                             \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(PUSHBX1)-L(PUSHSI1);                                             \
+    .byte 14;                                                                \
+    .uleb128 16;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPBX1)-L(PUSHBX1);                                                      \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPSI1)-L(POPBX1);                                               \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPDI1)-L(POPSI1);                                               \
+    .byte 14;                                                                \
+    .uleb128 4;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHSTATE)-L(POPDI1);                                            \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(PUSHDI2)-L(PUSHSTATE);                                           \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(PUSHSI2)-L(PUSHDI2);                                             \
+    .byte 14;                                                                \
+    .uleb128 16;                                                             \
+    .byte 4;                                                                 \
+    .long L(PUSHBX2)-L(PUSHSI2);                                             \
+    .byte 14;                                                                \
+    .uleb128 20;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPBX2)-L(PUSHBX2);                                                      \
+    .byte 14;                                                                \
+    .uleb128 16;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPSI2)-L(POPBX2);                                               \
+    .byte 14;                                                                \
+    .uleb128 12;                                                             \
+    .byte 4;                                                                 \
+    .long L(POPDI2)-L(POPSI2);                                               \
+    .byte 14;                                                                \
+    .uleb128 8;                                                                      \
+    .byte 4;                                                                 \
+    .long L(POPSTATE)-L(POPDI2);                                             \
+    .byte 14;                                                                \
+    .uleb128 4
+
+
+# undef ASM_SIZE_DIRECTIVE
+# define ASM_SIZE_DIRECTIVE(name) L(name##END): .size name,.-name;
 
 # define SAVE_OLDTYPE_0        movl %eax, %edx;
 # define SAVE_OLDTYPE_1        SAVE_OLDTYPE_0
-# define SAVE_OLDTYPE_2        pushl %eax;
+# define SAVE_OLDTYPE_2        pushl %eax; L(PUSHSTATE):
 # define SAVE_OLDTYPE_3        SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_4        SAVE_OLDTYPE_2
 # define SAVE_OLDTYPE_5        SAVE_OLDTYPE_2
 
-# define DOCARGS_0     DOARGS_0
-# define DOCARGS_1     DOARGS_1
+# define PUSHCARGS_0   /* No arguments to push.  */
+# define DOCARGS_0     /* No arguments to frob.  */
+# define POPCARGS_0    /* No arguments to pop.  */
+# define _PUSHCARGS_0  /* No arguments to push.  */
+# define _POPCARGS_0   /* No arguments to pop.  */
+
+# define PUSHCARGS_1   movl %ebx, %edx; PUSHCARGS_0
+# define DOCARGS_1     _DOARGS_1 (4)
+# define POPCARGS_1    POPCARGS_0; movl %edx, %ebx
+# define _PUSHCARGS_1  pushl %ebx; L(PUSHBX2): _PUSHCARGS_0
+# define _POPCARGS_1   _POPCARGS_0; popl %ebx; L(POPBX2):
+
+# define PUSHCARGS_2   PUSHCARGS_1
 # define DOCARGS_2     _DOARGS_2 (12)
+# define POPCARGS_2    POPCARGS_1
+# define _PUSHCARGS_2  _PUSHCARGS_1
+# define _POPCARGS_2   _POPCARGS_1
+
+# define PUSHCARGS_3   _PUSHCARGS_2
 # define DOCARGS_3     _DOARGS_3 (20)
+# define POPCARGS_3    _POPCARGS_3
+# define _PUSHCARGS_3  _PUSHCARGS_2
+# define _POPCARGS_3   _POPCARGS_2
+
+# define PUSHCARGS_4   _PUSHCARGS_4
 # define DOCARGS_4     _DOARGS_4 (28)
+# define POPCARGS_4    _POPCARGS_4
+# define _PUSHCARGS_4  pushl %esi; L(PUSHSI2): _PUSHCARGS_3
+# define _POPCARGS_4   _POPCARGS_3; popl %esi; L(POPSI2):
+
+# define PUSHCARGS_5   _PUSHCARGS_5
 # define DOCARGS_5     _DOARGS_5 (36)
+# define POPCARGS_5    _POPCARGS_5
+# define _PUSHCARGS_5  pushl %edi; L(PUSHDI2): _PUSHCARGS_4
+# define _POPCARGS_5   _POPCARGS_4; popl %edi; L(POPDI2):
 
 # ifdef IS_IN_libpthread
 #  define CENABLE      call __pthread_enable_asynccancel;
 #  define CENABLE      call __libc_enable_asynccancel;
 #  define CDISABLE     call __libc_disable_asynccancel
 # endif
-# define POPCARGS_0    pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
-# define POPCARGS_1    POPCARGS_0
-# define POPCARGS_2    xchgl (%esp), %eax; CDISABLE; popl %eax;
-# define POPCARGS_3    POPCARGS_2
-# define POPCARGS_4    POPCARGS_2
-# define POPCARGS_5    POPCARGS_2
+# define POPSTATE_0 \
+ pushl %eax; L(PUSHSTATE): movl %ecx, %eax; CDISABLE; popl %eax; L(POPSTATE):
+# define POPSTATE_1    POPSTATE_0
+# define POPSTATE_2    xchgl (%esp), %eax; CDISABLE; popl %eax; L(POPSTATE):
+# define POPSTATE_3    POPSTATE_2
+# define POPSTATE_4    POPSTATE_3
+# define POPSTATE_5    POPSTATE_4
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
diff --git a/nptl/unwind.c b/nptl/unwind.c
new file mode 100644 (file)
index 0000000..46c896d
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>
+   and Richard Henderson <rth@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "pthreadP.h"
+
+
+#ifdef HAVE_FORCED_UNWIND
+
+static _Unwind_Reason_Code
+unwind_stop (int version, _Unwind_Action actions,
+            _Unwind_Exception_Class exc_class,
+            struct _Unwind_Exception *exc_obj,
+            struct _Unwind_Context *context, void *stop_parameter)
+{
+  struct pthread_unwind_buf *buf = stop_parameter;
+
+  /* Do longjmp if we're at "end of stack", aka "end of unwind data".
+     We assume there are only C frame without unwind data in between
+     here and the jmp_buf target.  Otherwise simply note that the CFA
+     of a function is NOT within it's stack frame; it's the SP of the
+     previous frame.  */
+  if ((actions & _UA_END_OF_STACK)
+      || ! _JMPBUF_UNWINDS  (buf->cancel_jmp_buf[0].jmp_buf,
+                            _Unwind_GetCFA (context)))
+    __libc_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
+
+  return _URC_NO_REASON;
+}
+
+
+static void
+unwind_cleanup (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc)
+{
+  /* Nothing to do.  */
+}
+
+#endif /* have forced unwind */
+
+
+void
+__cleanup_fct_attribute __attribute ((noreturn))
+__pthread_unwind (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+  struct pthread *self = THREAD_SELF;
+
+  /* Handle the compatibility stuff first.  Execute all handlers
+     registered with the old method.  We don't execute them in order,
+     instead, they will run first.  */
+  struct _pthread_cleanup_buffer *oldp = ibuf->priv.data.cleanup;
+  struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
+
+  while (curp != oldp)
+    {
+      /* Pointer to the next element.  */
+      struct _pthread_cleanup_buffer *nextp = curp->__prev;
+
+      /* Call the handler.  */
+      curp->__routine (curp->__arg);
+
+      /* To the next.  */
+      curp = nextp;
+    }
+
+  /* Mark the current element as handled.  */
+  THREAD_SETMEM (self, cleanup, curp);
+
+#ifdef HAVE_FORCED_UNWIND
+  /* This is not a catchable exception, so don't provide any details about
+     the exception type.  We do need to initialize the field though.  */
+  ibuf->priv.data.exc.exception_class = 0;
+  ibuf->priv.data.exc.exception_cleanup = unwind_cleanup;
+
+  _Unwind_ForcedUnwind (&ibuf->priv.data.exc, unwind_stop, ibuf);
+#else
+  /* We simply jump to the registered setjmp buffer.  */
+  __libc_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1);
+#endif
+  /* NOTREACHED */
+
+  /* We better do not get here.  */
+  abort ();
+}
+
+
+void
+__cleanup_fct_attribute __attribute ((noreturn))
+__pthread_unwind_next (__pthread_unwind_buf_t *buf)
+{
+  struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+
+  __pthread_unwind (ibuf->priv.data.prev);
+}
index d0658bac0ccfd1b2939d25d56a5cbd074073692e..f2fd25fd6ddb2e0afd2b34ebed9b935890d252ef 100644 (file)
@@ -26,7 +26,11 @@ static const char banner[] =
 "Copyright (C) 2003 Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.\n\
 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
-PARTICULAR PURPOSE.\n";
+PARTICULAR PURPOSE.\n"
+#ifdef HAVE_FORCED_UNWIND
+"Forced unwind support included.\n"
+#endif
+;
 
 
 extern void __nptl_main (void) __attribute__ ((noreturn));
index fcd57d61d1a409a302ef7a3f8f58d68a40ce47d6..c603a355545ba6cc2c422f85ead8432124b399c8 100644 (file)
@@ -1,5 +1,5 @@
 /* Define the machine-dependent type `jmp_buf'.  Alpha version.
-   Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1997, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#ifndef _SETJMP_H
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -80,3 +83,5 @@ typedef long int __jmp_buf[17];
 #define _JMPBUF_UNWINDS(_jmpbuf, _address)                             \
      ((void *)(_address) < (void *)((_jmpbuf)[JB_SP]))
 #endif
+
+#endif  /* bits/setjmp.h */
index 351205d6360e29816602b60140d48dce97b2d45d..b98f0a2aa06df6b4df457fd28555529f28b22987 100644 (file)
@@ -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);
index ce43365a314f168a305df9dc3037450d460819e1..08d33811757951b37300310c1f9ba7be73da0d98 100644 (file)
@@ -1,26 +1,36 @@
 /* Exception handling and frame unwind runtime interface routines.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003 Free Software Foundation, Inc.
 
-   This file is part of GNU CC.
+   This file is part of GCC.
 
-   GNU CC is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
 
-   GNU CC is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GNU CC; see the file COPYING.  If not, write to
-   the Free Software Foundation, 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* As a special exception, if you include this header file into source
+   files compiled by GCC, this header file does not by itself cause
+   the resulting executable to be covered by the GNU General Public
+   License.  This exception does not however invalidate any other
+   reasons why the executable file might be covered by the GNU General
+   Public License.  */
 
 /* This is derived from the C++ ABI for IA-64.  Where we diverge
    for cross-architecture compatibility are noted with "@@@".  */
 
+#ifndef _UNWIND_H
+#define _UNWIND_H      1
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -31,7 +41,12 @@ extern "C" {
    inefficient for 32-bit and smaller machines.  */
 typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
 typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
+#if defined(__ia64__) && defined(__hpux__)
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
+#else
 typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+#endif
+typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
 
 /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
    consumer of an exception.  We'll go along with this for now even on
@@ -87,6 +102,7 @@ typedef int _Unwind_Action;
 #define _UA_CLEANUP_PHASE      2
 #define _UA_HANDLER_FRAME      4
 #define _UA_FORCE_UNWIND       8
+#define _UA_END_OF_STACK       16
 
 /* This is an opaque type used to refer to a system-specific data
    structure used by the system unwinder. This context is created and
@@ -125,6 +141,9 @@ extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
 extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
 extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
 
+/* @@@ Retrieve the CFA of the given context.  */
+extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
+
 extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
 
 extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
@@ -135,15 +154,15 @@ extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
    library and language-specific exception handling semantics.  It is
    specific to the code fragment described by an unwind info block, and
    it is always referenced via the pointer in the unwind info block, and
-   hence it has no ABI-specified name. 
+   hence it has no ABI-specified name.
 
    Note that this implies that two different C++ implementations can
    use different names, and have different contents in the language
-   specific data area.  Moreover, that the language specific data 
+   specific data area.  Moreover, that the language specific data
    area contains no version info because name of the function invoked
    provides more effective versioning by detecting at link time the
    lack of code to handle the different data format.  */
-   
+
 typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
      (int, _Unwind_Action, _Unwind_Exception_Class,
       struct _Unwind_Exception *, struct _Unwind_Context *);
@@ -186,6 +205,12 @@ extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
 extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
 #endif
 
+/* @@@ Given an address, return the entry point of the function that
+   contains it.  */
+extern void * _Unwind_FindEnclosingFunction (void *pc);
+
 #ifdef __cplusplus
 }
 #endif
+
+#endif /* unwind.h */
index e5e493bcae44a0fc554c28369adb84f878fe1863..107fe58b356d8c6698f941c6c8f5e36d4a6b4b27 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    02111-1307 USA.  */
 
 /* Define the machine-dependent type `jmp_buf'.  Intel 386 version.  */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -40,3 +42,5 @@ typedef int __jmp_buf[6];
    containing a local variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(jmpbuf, address) \
   ((void *) (address) < (void *) (jmpbuf)[JB_SP])
+
+#endif /* bits/setjmp.h */
index e17bde1351d7327b2f9fe8b7728edea60c5a1514..f849fe23ff2651e9934343c14eeb17714f945275 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    02111-1307 USA.  */
 
 /* Define the machine-dependent type `jmp_buf'.  PowerPC version.  */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -43,7 +45,7 @@
 #  define JB_CR     21 /* Condition code registers.  */
 #  define JB_FPRS   22 /* FPRs 14 through 31 are saved, 18*2 words total.  */
 #  define JB_SIZE   (58*4)
-# endif 
+# endif
 #endif
 
 #ifndef        _ASM
@@ -58,3 +60,5 @@ typedef long int __jmp_buf[58];
    containing a local variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(jmpbuf, address) \
   ((void *) (address) < (void *) (jmpbuf)[JB_GPR1])
+
+#endif  /* bits/setjmp.h */
index 55bc66549bdd0f62eee162494f0179df51b20fba..22497703afea4f5395b3558dec7fb29345ffa973 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    02111-1307 USA.  */
 
 /* Define the machine-dependent type `jmp_buf'.  SH version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -43,10 +45,12 @@ typedef struct
 #endif
 
 #if defined __USE_MISC || defined _ASM
-#define JB_SIZE                (4 * 15)
+# define JB_SIZE               (4 * 15)
 #endif
 
 /* Test if longjmp to JMPBUF would unwind the frame
    containing a local variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(jmpbuf, address) \
   ((void *) (address) < &(jmpbuf)[0].__regs[7])
+
+#endif  /* bits/setjmp.h */
index 2e660c39fcdb09242f01bca59485a9ce0b793ee4..14984b64f2a5fe897afe430208f26b7391c7a478 100644 (file)
@@ -164,7 +164,7 @@ __i686.get_pc_thunk.reg:                                                  \
 # else
 /* Store (- %eax) into errno through the GOT.  */
 #  define SYSCALL_ERROR_HANDLER                                                      \
-0:SETUP_PIC_REG(cx);                                                 \
+0:SETUP_PIC_REG(cx);                                                         \
   addl $_GLOBAL_OFFSET_TABLE_, %ecx;                                         \
   xorl %edx, %edx;                                                           \
   subl %eax, %edx;                                                           \
@@ -250,9 +250,9 @@ __i686.get_pc_thunk.reg:                                                  \
 #define PUSHARGS_1     movl %ebx, %edx; PUSHARGS_0
 #define        DOARGS_1        _DOARGS_1 (4)
 #define        POPARGS_1       POPARGS_0; movl %edx, %ebx
-#define        _PUSHARGS_1     pushl %ebx; _PUSHARGS_0
+#define        _PUSHARGS_1     pushl %ebx; L(PUSHBX1): _PUSHARGS_0
 #define _DOARGS_1(n)   movl n(%esp), %ebx; _DOARGS_0(n-4)
-#define        _POPARGS_1      _POPARGS_0; popl %ebx
+#define        _POPARGS_1      _POPARGS_0; popl %ebx; L(POPBX1):
 
 #define PUSHARGS_2     PUSHARGS_1
 #define        DOARGS_2        _DOARGS_2 (8)
@@ -271,16 +271,16 @@ __i686.get_pc_thunk.reg:                                                \
 #define PUSHARGS_4     _PUSHARGS_4
 #define DOARGS_4       _DOARGS_4 (24)
 #define POPARGS_4      _POPARGS_4
-#define _PUSHARGS_4    pushl %esi; _PUSHARGS_3
+#define _PUSHARGS_4    pushl %esi; L(PUSHSI1): _PUSHARGS_3
 #define _DOARGS_4(n)   movl n(%esp), %esi; _DOARGS_3 (n-4)
-#define _POPARGS_4     _POPARGS_3; popl %esi
+#define _POPARGS_4     _POPARGS_3; popl %esi; L(POPSI1):
 
 #define PUSHARGS_5     _PUSHARGS_5
 #define DOARGS_5       _DOARGS_5 (32)
 #define POPARGS_5      _POPARGS_5
-#define _PUSHARGS_5    pushl %edi; _PUSHARGS_4
+#define _PUSHARGS_5    pushl %edi; L(PUSHDI1): _PUSHARGS_4
 #define _DOARGS_5(n)   movl n(%esp), %edi; _DOARGS_4 (n-4)
-#define _POPARGS_5     _POPARGS_4; popl %edi
+#define _POPARGS_5     _POPARGS_4; popl %edi; L(POPDI1):
 
 #else  /* !__ASSEMBLER__ */
 
index 3ef23962501bd886c588504ff537fd31db0c4e06..76625753d959b65ed96fb703ff69f279211834df 100644 (file)
@@ -1,5 +1,5 @@
 /* Define the machine-dependent type `jmp_buf'.  Linux/IA-64 version.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
 
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#ifndef _SETJMP_H
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -33,3 +36,5 @@ typedef long __jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128
    variable at ADDRESS.  */
 #define _JMPBUF_UNWINDS(_jmpbuf, _address)             \
      ((void *)(_address) < (void *)(((long *)_jmpbuf)[0]))
+
+#endif  /* bits/setjmp.h */
index ba5dd2c112d4710606fb32537bc55bdb849e6ad8..96646efddabb7f39cca71add9c72cfe9a02e2314 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    02111-1307 USA.  */
 
 /* Define the machine-dependent type `jmp_buf'.  x86-64 version.  */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H  1
 
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
@@ -72,3 +74,5 @@ typedef int __jmp_buf[6];
   ((void *) (address) < (void *) (jmpbuf)[JB_SP])
 # endif
 #endif
+
+#endif  /* bits/setjmp.h */
This page took 0.104598 seconds and 5 git commands to generate.