From 675620f74c6fd1233ab57c19a3b1c6279e782c09 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 19 Dec 2003 01:37:13 +0000 Subject: Update. 2003-12-18 Ulrich Drepper * tst-eintr1.c: Better error messages. * Makefile (tests): Add tst-eintr2. * tst-eintr2.c: New file. 2003-12-18 Jakub Jelinek * Makefile (tests): Add tst-cancel21 and tst-cancelx21. (CFLAGS-tst-cancelx21.c): Set. * tst-cancel21.c: New test. * tst-cancelx21.c: New test. * unwind.c (FRAME_LEFT): Add adj argument. Subtract it from each comparison operand. (unwind_stop): Use _JMPBUF_CFA_UNWINDS_ADJ macro instead of _JMPBUF_CFA_UNWINDS. Adjust FRAME_LEFT invocations. * pt-longjmp.c: Include jmpbuf-unwind.h. (__pthread_cleanup_upto): Use _JMPBUF_UNWINDS_ADJ macro instead of _JMPBUF_UNWINDS. Adjust compared pointers. * init.c (__pthread_initialize_minimal_internal): Initialize pd->stackblock_size. * sysdeps/pthread/jmpbuf-unwind.h: Removed. * sysdeps/alpha/jmpbuf-unwind.h: New file. * sysdeps/i386/jmpbuf-unwind.h: New file. * sysdeps/powerpc/jmpbuf-unwind.h: New file. * sysdeps/s390/jmpbuf-unwind.h: New file. * sysdeps/sh/jmpbuf-unwind.h: New file. * sysdeps/sparc/sparc32/jmpbuf-unwind.h: New file. * sysdeps/x86_64/jmpbuf-unwind.h: New file. * sysdeps/ia64/jmpbuf-unwind.h: Include stdint.h. (_JMPBUF_CFA_UNWINDS): Remove. (_JMPBUF_CFA_UNWINDS_ADJ, _JMPBUF_UNWINDS_ADJ): Define. 2003-12-12 Jakub Jelinek * Makefile (tests): Add tst-cancel20 and tst-cancelx20. (CFLAGS-tst-cancelx20.c): Set. * tst-cancel20.c: New test. * tst-cancelx20.c: New test. --- nptl/unwind.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'nptl/unwind.c') diff --git a/nptl/unwind.c b/nptl/unwind.c index 8013b5a829..f72c33891d 100644 --- a/nptl/unwind.c +++ b/nptl/unwind.c @@ -28,9 +28,11 @@ #ifdef HAVE_FORCED_UNWIND #ifdef _STACK_GROWS_DOWN -# define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other) +# define FRAME_LEFT(frame, other, adj) \ + ((uintptr_t) frame - adj >= (uintptr_t) other - adj) #elif _STACK_GROWS_UP -# define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other) +# define FRAME_LEFT(frame, other, adj) \ + ((uintptr_t) frame - adj <= (uintptr_t) other - adj) #else # error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" #endif @@ -45,6 +47,11 @@ unwind_stop (int version, _Unwind_Action actions, struct pthread *self = THREAD_SELF; struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup); int do_longjump = 0; + + /* Adjust all pointers used in comparisons, so that top of thread's + stack is at the top of address space. Without that, things break + if stack is allocated above the main stack. */ + uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size; /* 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 @@ -52,7 +59,8 @@ unwind_stop (int version, _Unwind_Action actions, 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_CFA_UNWINDS (buf->cancel_jmp_buf[0].jmp_buf, context)) + || ! _JMPBUF_CFA_UNWINDS_ADJ (buf->cancel_jmp_buf[0].jmp_buf, context, + adj)) do_longjump = 1; if (__builtin_expect (curp != NULL, 0)) @@ -63,7 +71,7 @@ unwind_stop (int version, _Unwind_Action actions, struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup; void *cfa = (void *) _Unwind_GetCFA (context); - if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp))) + if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp, adj))) { do { @@ -76,7 +84,8 @@ unwind_stop (int version, _Unwind_Action actions, /* To the next. */ curp = nextp; } - while (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp))); + while (curp != oldp + && (do_longjump || FRAME_LEFT (cfa, curp, adj))); /* Mark the current element as handled. */ THREAD_SETMEM (self, cleanup, curp); -- cgit v1.2.3