mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
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.
This commit is contained in:
parent
877e51b20f
commit
09d65ff393
15
ChangeLog
15
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>
|
2003-04-11 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
* csu/tst-empty.c: New file.
|
* csu/tst-empty.c: New 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>
|
2003-04-11 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
* Makefile ($(objpfx)multidir.mk): New target, generated makefile that
|
* Makefile ($(objpfx)multidir.mk): New target, generated makefile that
|
||||||
|
@ -98,7 +98,8 @@ libpthread-routines = init events version \
|
|||||||
sem_open sem_close sem_unlink \
|
sem_open sem_close sem_unlink \
|
||||||
sem_getvalue \
|
sem_getvalue \
|
||||||
sem_wait sem_trywait sem_timedwait sem_post \
|
sem_wait sem_trywait sem_timedwait sem_post \
|
||||||
cleanup cleanup_defer \
|
cleanup cleanup_defer cleanup_compat \
|
||||||
|
cleanup_defer_compat unwind \
|
||||||
pt-longjmp \
|
pt-longjmp \
|
||||||
cancellation \
|
cancellation \
|
||||||
lowlevellock lowlevelmutex \
|
lowlevellock lowlevelmutex \
|
||||||
@ -122,6 +123,10 @@ libpthread-static-only-routines = pthread_atfork
|
|||||||
libpthread-nonshared = pthread_atfork
|
libpthread-nonshared = pthread_atfork
|
||||||
|
|
||||||
CFLAGS-pthread_atfork.c = -DNOT_IN_libc
|
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.
|
# Don't generate deps for calls with no sources. See sysdeps/unix/Makefile.
|
||||||
omit-deps = $(unix-syscalls:%=ptw-%)
|
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-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
|
||||||
tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
|
tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
|
||||||
tst-cancel11 \
|
tst-cancel11 \
|
||||||
tst-cleanup1 tst-cleanup2 tst-cleanup3 \
|
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \
|
||||||
tst-flock1 tst-flock2 \
|
tst-flock1 tst-flock2 \
|
||||||
tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
|
tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
|
||||||
tst-exec1 tst-exec2 tst-exec3 \
|
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-ftrylockfile.c = -D_IO_MTSAFE_IO
|
||||||
CFLAGS-funlockfile.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)
|
ifeq ($(build-static),yes)
|
||||||
tests-static += tst-locale1 tst-locale2
|
tests-static += tst-locale1 tst-locale2
|
||||||
endif
|
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
|
# Make sure these things are built in the `make lib' pass so they can be used
|
||||||
# to run programs during the `make others' pass.
|
# to run programs during the `make others' pass.
|
||||||
lib-noranlib: $(addprefix $(objpfx),$(extra-objs))
|
lib-noranlib: $(addprefix $(objpfx),$(extra-objs))
|
||||||
endif
|
|
||||||
|
|
||||||
# What we install as libpthread.so for programs to link against is in fact a
|
# 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.
|
# 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)
|
# We need to use absolute paths since otherwise local copies (if they exist)
|
||||||
# of the files are taken by the linker.
|
# of the files are taken by the linker.
|
||||||
install: $(inst_libdir)/libpthread.so
|
install: $(inst_libdir)/libpthread.so
|
||||||
|
|
||||||
$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
|
$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
|
||||||
$(objpfx)libpthread.so$(libpthread.so-version) \
|
$(objpfx)libpthread.so$(libpthread.so-version) \
|
||||||
$(inst_libdir)/$(patsubst %,$(libtype.oS),\
|
$(inst_libdir)/$(patsubst %,$(libtype.oS),\
|
||||||
@ -245,6 +253,8 @@ $(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
|
|||||||
mv -f $@.new $@
|
mv -f $@.new $@
|
||||||
$(inst_libdir)/libpthread_nonshared.a: $(objpfx)libpthread_nonshared.a
|
$(inst_libdir)/libpthread_nonshared.a: $(objpfx)libpthread_nonshared.a
|
||||||
$(do-install)
|
$(do-install)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# 'pthread_self' is a simple memory or register load. Setting up the
|
# 'pthread_self' is a simple memory or register load. Setting up the
|
||||||
# stack frame is more work than the actual operation. Disable 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 \
|
$(compile.c) -S $(CFLAGS-pt-initfini.s) -finhibit-size-directive \
|
||||||
$(patsubst -f%,-fno-%,$(exceptions)) -o $@
|
$(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
|
# We only have one kind of startup code files. Static binaries and
|
||||||
# shared libraries are build using the PIC version.
|
# shared libraries are build using the PIC version.
|
||||||
$(objpfx)crti.S: $(objpfx)pt-initfini.s
|
$(objpfx)crti.S: $(objpfx)pt-initfini.s
|
||||||
|
@ -211,6 +211,11 @@ libpthread {
|
|||||||
|
|
||||||
# Proposed API extensions.
|
# Proposed API extensions.
|
||||||
pthread_tryjoin_np; pthread_timedjoin_np;
|
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 {
|
GLIBC_PRIVATE {
|
||||||
|
@ -345,6 +345,19 @@ typedef pthread_key_t __libc_key_t;
|
|||||||
} while (0)
|
} 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. */
|
/* Start critical region with cleanup. */
|
||||||
#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
|
#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
|
||||||
{ struct _pthread_cleanup_buffer _buffer; \
|
{ struct _pthread_cleanup_buffer _buffer; \
|
||||||
|
55
nptl/sysdeps/pthread/configure
vendored
55
nptl/sysdeps/pthread/configure
vendored
@ -5,3 +5,58 @@ if test "x$libc_cv_gcc___thread" != xyes; then
|
|||||||
echo "$as_me: error: compiler support for __thread is required" >&2;}
|
echo "$as_me: error: compiler support for __thread is required" >&2;}
|
||||||
{ (exit 1); exit 1; }; }
|
{ (exit 1); exit 1; }; }
|
||||||
fi
|
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
|
||||||
|
@ -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
|
if test "x$libc_cv_gcc___thread" != xyes; then
|
||||||
AC_MSG_ERROR(compiler support for __thread is required)
|
AC_MSG_ERROR(compiler support for __thread is required)
|
||||||
fi
|
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
|
||||||
|
@ -85,6 +85,8 @@ struct pthread_functions
|
|||||||
int);
|
int);
|
||||||
#define HAVE_PTR_NTHREADS
|
#define HAVE_PTR_NTHREADS
|
||||||
int *ptr_nthreads;
|
int *ptr_nthreads;
|
||||||
|
void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *)
|
||||||
|
__attribute ((noreturn)) __cleanup_fct_attribute;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Variable in libc.so. */
|
/* Variable in libc.so. */
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define __need_sigset_t
|
#define __need_sigset_t
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <bits/pthreadtypes.h>
|
#include <bits/pthreadtypes.h>
|
||||||
|
#include <bits/setjmp.h>
|
||||||
|
|
||||||
|
|
||||||
/* Detach state. */
|
/* Detach state. */
|
||||||
@ -380,6 +381,24 @@ extern int pthread_cancel (pthread_t __th) __THROW;
|
|||||||
extern void pthread_testcancel (void) __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
|
/* Install a cleanup handler: ROUTINE will be called with arguments ARG
|
||||||
when the thread is cancelled or calls pthread_exit. ROUTINE will also
|
when the thread is cancelled or calls pthread_exit. ROUTINE will also
|
||||||
be called with arguments ARG when the matching pthread_cleanup_pop
|
be called with arguments ARG when the matching pthread_cleanup_pop
|
||||||
@ -387,44 +406,84 @@ extern void pthread_testcancel (void) __THROW;
|
|||||||
|
|
||||||
pthread_cleanup_push and pthread_cleanup_pop are macros and must always
|
pthread_cleanup_push and pthread_cleanup_pop are macros and must always
|
||||||
be used in matching pairs at the same nesting level of braces. */
|
be used in matching pairs at the same nesting level of braces. */
|
||||||
#define pthread_cleanup_push(routine,arg) \
|
#define pthread_cleanup_push(routine, arg) \
|
||||||
{ struct _pthread_cleanup_buffer _buffer; \
|
do { \
|
||||||
_pthread_cleanup_push (&_buffer, (routine), (arg));
|
__pthread_unwind_buf_t __cancel_buf; \
|
||||||
|
void (*__cancel_routine) (void *) = (routine); \
|
||||||
extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
|
void *__cancel_arg = (arg); \
|
||||||
void (*__routine) (void *), void *__arg)
|
int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) \
|
||||||
__THROW;
|
__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.
|
/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
|
||||||
If EXECUTE is non-zero, the handler function is called. */
|
If EXECUTE is non-zero, the handler function is called. */
|
||||||
#define pthread_cleanup_pop(execute) \
|
#define pthread_cleanup_pop(execute) \
|
||||||
_pthread_cleanup_pop (&_buffer, (execute)); }
|
} while (0); \
|
||||||
|
__pthread_unregister_cancel (&__cancel_buf); \
|
||||||
extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
|
if (execute) \
|
||||||
int __execute) __THROW;
|
__cancel_routine (__cancel_arg); \
|
||||||
|
} while (0)
|
||||||
|
extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
|
||||||
|
__cleanup_fct_attribute;
|
||||||
|
|
||||||
#ifdef __USE_GNU
|
#ifdef __USE_GNU
|
||||||
/* Install a cleanup handler as pthread_cleanup_push does, but also
|
/* Install a cleanup handler as pthread_cleanup_push does, but also
|
||||||
saves the current cancellation type and sets it to deferred
|
saves the current cancellation type and sets it to deferred
|
||||||
cancellation. */
|
cancellation. */
|
||||||
# define pthread_cleanup_push_defer_np(routine,arg) \
|
# define pthread_cleanup_push_defer(routine, arg) \
|
||||||
{ struct _pthread_cleanup_buffer _buffer; \
|
do { \
|
||||||
_pthread_cleanup_push_defer (&_buffer, (routine), (arg));
|
__pthread_unwind_buf_t __cancel_buf; \
|
||||||
|
void (*__cancel_routine) (void *) = (routine); \
|
||||||
extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
|
void *__cancel_arg = (arg); \
|
||||||
void (*__routine) (void *),
|
int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) \
|
||||||
void *__arg) __THROW;
|
__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
|
/* Remove a cleanup handler as pthread_cleanup_pop does, but also
|
||||||
restores the cancellation type that was in effect when the matching
|
restores the cancellation type that was in effect when the matching
|
||||||
pthread_cleanup_push_defer was called. */
|
pthread_cleanup_push_defer was called. */
|
||||||
# define pthread_cleanup_pop_restore_np(execute) \
|
# define pthread_cleanup_pop_cleanup(execute) \
|
||||||
_pthread_cleanup_pop_restore (&_buffer, (execute)); }
|
} while (0); \
|
||||||
|
__pthread_unregister_cancel_restore (&__cancel_buf); \
|
||||||
extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
|
if (execute) \
|
||||||
int __execute) __THROW;
|
__cancel_routine (__cancel_arg); \
|
||||||
|
} while (0)
|
||||||
|
extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
|
||||||
|
__cleanup_fct_attribute;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 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. */
|
/* Mutex handling. */
|
||||||
|
|
||||||
|
@ -149,4 +149,7 @@ typedef union
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Extra attributes for the cleanup functions. */
|
||||||
|
#define __cleanup_fct_attribute __attribute ((regparm (1)))
|
||||||
|
|
||||||
#endif /* bits/pthreadtypes.h */
|
#endif /* bits/pthreadtypes.h */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
# define PSEUDO(name, syscall_name, args) \
|
# define PSEUDO(name, syscall_name, args) \
|
||||||
.text; \
|
.text; \
|
||||||
ENTRY (name) \
|
ENTRY (name) \
|
||||||
|
L(name##START): \
|
||||||
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
|
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
|
||||||
jne L(pseudo_cancel); \
|
jne L(pseudo_cancel); \
|
||||||
DO_CALL (syscall_name, args); \
|
DO_CALL (syscall_name, args); \
|
||||||
@ -38,29 +39,262 @@
|
|||||||
L(pseudo_cancel): \
|
L(pseudo_cancel): \
|
||||||
CENABLE \
|
CENABLE \
|
||||||
SAVE_OLDTYPE_##args \
|
SAVE_OLDTYPE_##args \
|
||||||
PUSHARGS_##args \
|
PUSHCARGS_##args \
|
||||||
DOCARGS_##args \
|
DOCARGS_##args \
|
||||||
movl $SYS_ify (syscall_name), %eax; \
|
movl $SYS_ify (syscall_name), %eax; \
|
||||||
ENTER_KERNEL \
|
/* Until we can handle unwinding from the sysenter page the kernel \
|
||||||
POPARGS_##args; \
|
provides we cannot use ENTER_KERNEL here. */ \
|
||||||
POPCARGS_##args \
|
int $0x80; \
|
||||||
|
POPCARGS_##args; \
|
||||||
|
POPSTATE_##args \
|
||||||
cmpl $-4095, %eax; \
|
cmpl $-4095, %eax; \
|
||||||
jae SYSCALL_ERROR_LABEL; \
|
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_0 movl %eax, %edx;
|
||||||
# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
|
# 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_3 SAVE_OLDTYPE_2
|
||||||
# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
|
# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
|
||||||
# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
|
# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
|
||||||
|
|
||||||
# define DOCARGS_0 DOARGS_0
|
# define PUSHCARGS_0 /* No arguments to push. */
|
||||||
# define DOCARGS_1 DOARGS_1
|
# 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 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 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 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 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
|
# ifdef IS_IN_libpthread
|
||||||
# define CENABLE call __pthread_enable_asynccancel;
|
# define CENABLE call __pthread_enable_asynccancel;
|
||||||
@ -69,12 +303,13 @@
|
|||||||
# define CENABLE call __libc_enable_asynccancel;
|
# define CENABLE call __libc_enable_asynccancel;
|
||||||
# define CDISABLE call __libc_disable_asynccancel
|
# define CDISABLE call __libc_disable_asynccancel
|
||||||
# endif
|
# endif
|
||||||
# define POPCARGS_0 pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
|
# define POPSTATE_0 \
|
||||||
# define POPCARGS_1 POPCARGS_0
|
pushl %eax; L(PUSHSTATE): movl %ecx, %eax; CDISABLE; popl %eax; L(POPSTATE):
|
||||||
# define POPCARGS_2 xchgl (%esp), %eax; CDISABLE; popl %eax;
|
# define POPSTATE_1 POPSTATE_0
|
||||||
# define POPCARGS_3 POPCARGS_2
|
# define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; L(POPSTATE):
|
||||||
# define POPCARGS_4 POPCARGS_2
|
# define POPSTATE_3 POPSTATE_2
|
||||||
# define POPCARGS_5 POPCARGS_2
|
# define POPSTATE_4 POPSTATE_3
|
||||||
|
# define POPSTATE_5 POPSTATE_4
|
||||||
|
|
||||||
# ifndef __ASSEMBLER__
|
# ifndef __ASSEMBLER__
|
||||||
# define SINGLE_THREAD_P \
|
# define SINGLE_THREAD_P \
|
||||||
|
112
nptl/unwind.c
Normal file
112
nptl/unwind.c
Normal file
@ -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);
|
||||||
|
}
|
@ -26,7 +26,11 @@ static const char banner[] =
|
|||||||
"Copyright (C) 2003 Free Software Foundation, Inc.\n\
|
"Copyright (C) 2003 Free Software Foundation, Inc.\n\
|
||||||
This is free software; see the source for copying conditions.\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\
|
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));
|
extern void __nptl_main (void) __attribute__ ((noreturn));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Define the machine-dependent type `jmp_buf'. Alpha version.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -17,7 +17,10 @@
|
|||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
02111-1307 USA. */
|
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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -80,3 +83,5 @@ typedef long int __jmp_buf[17];
|
|||||||
#define _JMPBUF_UNWINDS(_jmpbuf, _address) \
|
#define _JMPBUF_UNWINDS(_jmpbuf, _address) \
|
||||||
((void *)(_address) < (void *)((_jmpbuf)[JB_SP]))
|
((void *)(_address) < (void *)((_jmpbuf)[JB_SP]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
@ -51,12 +51,17 @@ extern void __pthread_initialize_minimal (void)
|
|||||||
# define LIBC_START_MAIN BP_SYM (__libc_start_main)
|
# define LIBC_START_MAIN BP_SYM (__libc_start_main)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
|
|
||||||
#ifdef MAIN_AUXVEC_ARG
|
#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
|
#endif
|
||||||
|
|
||||||
),
|
STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
|
||||||
|
MAIN_AUXVEC_DECL),
|
||||||
int argc,
|
int argc,
|
||||||
char *__unbounded *__unbounded ubp_av,
|
char *__unbounded *__unbounded ubp_av,
|
||||||
#ifdef LIBC_START_MAIN_AUXVEC_ARG
|
#ifdef LIBC_START_MAIN_AUXVEC_ARG
|
||||||
@ -73,11 +78,7 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
|
|||||||
__attribute__ ((noreturn));
|
__attribute__ ((noreturn));
|
||||||
|
|
||||||
STATIC int
|
STATIC int
|
||||||
LIBC_START_MAIN (int (*main) (int, char **, char **
|
LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||||
#ifdef MAIN_AUXVEC_ARG
|
|
||||||
, void *
|
|
||||||
#endif
|
|
||||||
),
|
|
||||||
int argc, char *__unbounded *__unbounded ubp_av,
|
int argc, char *__unbounded *__unbounded ubp_av,
|
||||||
#ifdef LIBC_START_MAIN_AUXVEC_ARG
|
#ifdef LIBC_START_MAIN_AUXVEC_ARG
|
||||||
ElfW(auxv_t) *__unbounded auxvec,
|
ElfW(auxv_t) *__unbounded auxvec,
|
||||||
@ -172,10 +173,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char **
|
|||||||
if (init)
|
if (init)
|
||||||
(*init) (
|
(*init) (
|
||||||
#ifdef INIT_MAIN_ARGS
|
#ifdef INIT_MAIN_ARGS
|
||||||
argc, argv, __environ
|
argc, argv, __environ MAIN_AUXVEC_PARAM
|
||||||
# ifdef MAIN_AUXVEC_ARG
|
|
||||||
, auxvec
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -184,38 +182,45 @@ LIBC_START_MAIN (int (*main) (int, char **, char **
|
|||||||
_dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
|
_dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CANCELBUF
|
#ifdef HAVE_CLEANUP_JMP_BUF
|
||||||
if (setjmp (THREAD_SELF->cancelbuf) == 0)
|
/* Memory for the cancellation buffer. */
|
||||||
#endif
|
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
|
/* Store old info. */
|
||||||
#ifdef MAIN_AUXVEC_ARG
|
unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
|
||||||
, auxvec
|
unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
|
||||||
#endif
|
|
||||||
|
|
||||||
);
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
# ifdef HAVE_PTR_NTHREADS
|
|
||||||
/* One less thread. Decrement the counter. If it is zero we
|
/* One less thread. Decrement the counter. If it is zero we
|
||||||
terminate the entire process. */
|
terminate the entire process. */
|
||||||
result = 0;
|
result = 0;
|
||||||
# ifdef SHARED
|
# ifdef SHARED
|
||||||
int *const ptr = __libc_pthread_functions.ptr_nthreads;
|
int *const ptr = __libc_pthread_functions.ptr_nthreads;
|
||||||
# else
|
# else
|
||||||
extern int __nptl_nthreads __attribute ((weak));
|
extern int __nptl_nthreads __attribute ((weak));
|
||||||
int *const ptr = &__nptl_nthreads;
|
int *const ptr = &__nptl_nthreads;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (! atomic_decrement_and_test (ptr))
|
if (! atomic_decrement_and_test (ptr))
|
||||||
# endif
|
|
||||||
/* Not much left to do but to exit the thread, not the process. */
|
/* Not much left to do but to exit the thread, not the process. */
|
||||||
__exit_thread (0);
|
__exit_thread (0);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* Nothing fancy, just call the function. */
|
||||||
|
result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
exit (result);
|
exit (result);
|
||||||
|
@ -1,26 +1,36 @@
|
|||||||
/* Exception handling and frame unwind runtime interface routines.
|
/* 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
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
any later version.
|
any later version.
|
||||||
|
|
||||||
GNU CC is distributed in the hope that it will be useful,
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
GNU General Public License for more details.
|
License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with GNU CC; see the file COPYING. If not, write to
|
along with GCC; see the file COPYING. If not, write to the Free
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
Boston, MA 02111-1307, USA. */
|
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
|
/* This is derived from the C++ ABI for IA-64. Where we diverge
|
||||||
for cross-architecture compatibility are noted with "@@@". */
|
for cross-architecture compatibility are noted with "@@@". */
|
||||||
|
|
||||||
|
#ifndef _UNWIND_H
|
||||||
|
#define _UNWIND_H 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -31,7 +41,12 @@ extern "C" {
|
|||||||
inefficient for 32-bit and smaller machines. */
|
inefficient for 32-bit and smaller machines. */
|
||||||
typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
|
typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
|
||||||
typedef signed _Unwind_Sword __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__)));
|
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
|
/* @@@ 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
|
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_CLEANUP_PHASE 2
|
||||||
#define _UA_HANDLER_FRAME 4
|
#define _UA_HANDLER_FRAME 4
|
||||||
#define _UA_FORCE_UNWIND 8
|
#define _UA_FORCE_UNWIND 8
|
||||||
|
#define _UA_END_OF_STACK 16
|
||||||
|
|
||||||
/* This is an opaque type used to refer to a system-specific data
|
/* This is an opaque type used to refer to a system-specific data
|
||||||
structure used by the system unwinder. This context is created and
|
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 _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
|
||||||
extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
|
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 void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
|
||||||
|
|
||||||
extern _Unwind_Ptr _Unwind_GetRegionStart (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
|
library and language-specific exception handling semantics. It is
|
||||||
specific to the code fragment described by an unwind info block, and
|
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
|
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
|
Note that this implies that two different C++ implementations can
|
||||||
use different names, and have different contents in the language
|
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
|
area contains no version info because name of the function invoked
|
||||||
provides more effective versioning by detecting at link time the
|
provides more effective versioning by detecting at link time the
|
||||||
lack of code to handle the different data format. */
|
lack of code to handle the different data format. */
|
||||||
|
|
||||||
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
|
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
|
||||||
(int, _Unwind_Action, _Unwind_Exception_Class,
|
(int, _Unwind_Action, _Unwind_Exception_Class,
|
||||||
struct _Unwind_Exception *, struct _Unwind_Context *);
|
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 *);
|
extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* @@@ Given an address, return the entry point of the function that
|
||||||
|
contains it. */
|
||||||
|
extern void * _Unwind_FindEnclosingFunction (void *pc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* unwind.h */
|
||||||
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -17,8 +17,10 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
/* Define the machine-dependent type `jmp_buf'. Intel 386 version. */
|
/* 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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -40,3 +42,5 @@ typedef int __jmp_buf[6];
|
|||||||
containing a local variable at ADDRESS. */
|
containing a local variable at ADDRESS. */
|
||||||
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
||||||
((void *) (address) < (void *) (jmpbuf)[JB_SP])
|
((void *) (address) < (void *) (jmpbuf)[JB_SP])
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -17,8 +17,10 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
/* Define the machine-dependent type `jmp_buf'. PowerPC version. */
|
/* 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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -43,7 +45,7 @@
|
|||||||
# define JB_CR 21 /* Condition code registers. */
|
# define JB_CR 21 /* Condition code registers. */
|
||||||
# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
|
# define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */
|
||||||
# define JB_SIZE (58*4)
|
# define JB_SIZE (58*4)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ASM
|
#ifndef _ASM
|
||||||
@ -58,3 +60,5 @@ typedef long int __jmp_buf[58];
|
|||||||
containing a local variable at ADDRESS. */
|
containing a local variable at ADDRESS. */
|
||||||
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
||||||
((void *) (address) < (void *) (jmpbuf)[JB_GPR1])
|
((void *) (address) < (void *) (jmpbuf)[JB_GPR1])
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -17,8 +17,10 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
/* Define the machine-dependent type `jmp_buf'. SH version. */
|
/* 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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -43,10 +45,12 @@ typedef struct
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __USE_MISC || defined _ASM
|
#if defined __USE_MISC || defined _ASM
|
||||||
#define JB_SIZE (4 * 15)
|
# define JB_SIZE (4 * 15)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Test if longjmp to JMPBUF would unwind the frame
|
/* Test if longjmp to JMPBUF would unwind the frame
|
||||||
containing a local variable at ADDRESS. */
|
containing a local variable at ADDRESS. */
|
||||||
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
||||||
((void *) (address) < &(jmpbuf)[0].__regs[7])
|
((void *) (address) < &(jmpbuf)[0].__regs[7])
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
@ -164,7 +164,7 @@ __i686.get_pc_thunk.reg: \
|
|||||||
# else
|
# else
|
||||||
/* Store (- %eax) into errno through the GOT. */
|
/* Store (- %eax) into errno through the GOT. */
|
||||||
# define SYSCALL_ERROR_HANDLER \
|
# define SYSCALL_ERROR_HANDLER \
|
||||||
0:SETUP_PIC_REG(cx); \
|
0:SETUP_PIC_REG(cx); \
|
||||||
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
|
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
|
||||||
xorl %edx, %edx; \
|
xorl %edx, %edx; \
|
||||||
subl %eax, %edx; \
|
subl %eax, %edx; \
|
||||||
@ -250,9 +250,9 @@ __i686.get_pc_thunk.reg: \
|
|||||||
#define PUSHARGS_1 movl %ebx, %edx; PUSHARGS_0
|
#define PUSHARGS_1 movl %ebx, %edx; PUSHARGS_0
|
||||||
#define DOARGS_1 _DOARGS_1 (4)
|
#define DOARGS_1 _DOARGS_1 (4)
|
||||||
#define POPARGS_1 POPARGS_0; movl %edx, %ebx
|
#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 _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 PUSHARGS_2 PUSHARGS_1
|
||||||
#define DOARGS_2 _DOARGS_2 (8)
|
#define DOARGS_2 _DOARGS_2 (8)
|
||||||
@ -271,16 +271,16 @@ __i686.get_pc_thunk.reg: \
|
|||||||
#define PUSHARGS_4 _PUSHARGS_4
|
#define PUSHARGS_4 _PUSHARGS_4
|
||||||
#define DOARGS_4 _DOARGS_4 (24)
|
#define DOARGS_4 _DOARGS_4 (24)
|
||||||
#define POPARGS_4 _POPARGS_4
|
#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 _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 PUSHARGS_5 _PUSHARGS_5
|
||||||
#define DOARGS_5 _DOARGS_5 (32)
|
#define DOARGS_5 _DOARGS_5 (32)
|
||||||
#define POPARGS_5 _POPARGS_5
|
#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 _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__ */
|
#else /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version.
|
/* 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.
|
This file is part of the GNU C Library.
|
||||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
||||||
|
|
||||||
@ -18,7 +18,10 @@
|
|||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
02111-1307 USA. */
|
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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -33,3 +36,5 @@ typedef long __jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128
|
|||||||
variable at ADDRESS. */
|
variable at ADDRESS. */
|
||||||
#define _JMPBUF_UNWINDS(_jmpbuf, _address) \
|
#define _JMPBUF_UNWINDS(_jmpbuf, _address) \
|
||||||
((void *)(_address) < (void *)(((long *)_jmpbuf)[0]))
|
((void *)(_address) < (void *)(((long *)_jmpbuf)[0]))
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
@ -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.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -17,8 +17,10 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
/* Define the machine-dependent type `jmp_buf'. x86-64 version. */
|
/* 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."
|
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -72,3 +74,5 @@ typedef int __jmp_buf[6];
|
|||||||
((void *) (address) < (void *) (jmpbuf)[JB_SP])
|
((void *) (address) < (void *) (jmpbuf)[JB_SP])
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* bits/setjmp.h */
|
||||||
|
Loading…
Reference in New Issue
Block a user