summary refs log tree commit diff
path: root/nptl/unwind.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-12-19 01:37:13 +0000
committerUlrich Drepper <drepper@redhat.com>2003-12-19 01:37:13 +0000
commit675620f74c6fd1233ab57c19a3b1c6279e782c09 (patch)
tree7e2b24adbcf086227800b7d6164cf0b15645647f /nptl/unwind.c
parent3434f152228af9fa619de254559815363f86868a (diff)
downloadglibc-675620f74c6fd1233ab57c19a3b1c6279e782c09.tar.gz
glibc-675620f74c6fd1233ab57c19a3b1c6279e782c09.tar.xz
glibc-675620f74c6fd1233ab57c19a3b1c6279e782c09.zip
Update.
2003-12-18  Ulrich Drepper  <drepper@redhat.com>

	* tst-eintr1.c: Better error messages.

	* Makefile (tests): Add tst-eintr2.
	* tst-eintr2.c: New file.

2003-12-18  Jakub Jelinek  <jakub@redhat.com>

	* 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  <jakub@redhat.com>

	* Makefile (tests): Add tst-cancel20 and tst-cancelx20.
	(CFLAGS-tst-cancelx20.c): Set.
	* tst-cancel20.c: New test.
	* tst-cancelx20.c: New test.
Diffstat (limited to 'nptl/unwind.c')
-rw-r--r--nptl/unwind.c19
1 files changed, 14 insertions, 5 deletions
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);