about summary refs log tree commit diff
path: root/src/thread/i386
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-05-23 15:45:41 -0400
committerRich Felker <dalias@aerifal.cx>2012-05-23 15:45:41 -0400
commit4da268f74b90696563db4f5d9d2b8e1c1351bdc6 (patch)
tree6248d447902f2a011c70e2b207e600718bed77a4 /src/thread/i386
parentcfd892fde9454e014d9b291a56ce5740d8bc4a78 (diff)
downloadmusl-4da268f74b90696563db4f5d9d2b8e1c1351bdc6.tar.gz
musl-4da268f74b90696563db4f5d9d2b8e1c1351bdc6.tar.xz
musl-4da268f74b90696563db4f5d9d2b8e1c1351bdc6.zip
fix issue with longjmp out of signal handlers and cancellation
stale state information indicating that a thread was possibly blocked
at a cancellation point could get left behind if longjmp was used to
exit a signal handler that interrupted a cancellation point.

to fix the issue, we throw away the state information entirely and
simply compare the saved instruction pointer to a range of code
addresses in the __syscall_cp_asm function. all the ugly PIC work
(which becomes minimal anyway with this approach) is defered to
cancellation time instead of happening at every syscall, which should
improve performance too.

this commit also fixes cancellation on arm, which was mildly broken
(race condition, not checking cancellation flag once inside the
cancellation point zone). apparently i forgot to implement that. the
new arm code is untested, but appears correct; i'll test and fix it
later if there are problems.
Diffstat (limited to 'src/thread/i386')
-rw-r--r--src/thread/i386/syscall_cp.s36
1 files changed, 15 insertions, 21 deletions
diff --git a/src/thread/i386/syscall_cp.s b/src/thread/i386/syscall_cp.s
index 05e867a1..3bf52c1f 100644
--- a/src/thread/i386/syscall_cp.s
+++ b/src/thread/i386/syscall_cp.s
@@ -2,34 +2,28 @@
 .global __syscall_cp_asm
 .type   __syscall_cp_asm,@function
 __syscall_cp_asm:
+	mov 4(%esp),%ecx
 	pushl %ebx
 	pushl %esi
 	pushl %edi
 	pushl %ebp
-	leal 20(%esp),%ebp
-	call 1f
-1:	popl %eax
-	movl (%ebp),%ecx
-	addl $[1f-1b],%eax
-	movl %eax,4(%ecx)
-	movl %esp,(%ecx)
-	movl 8(%ecx),%eax
+.global __cp_begin
+__cp_begin:
+	movl (%ecx),%eax
 	testl %eax,%eax
-	jnz 2f
-	movl 4(%ebp),%eax
-	movl 8(%ebp),%ebx
-	movl 12(%ebp),%ecx
-	movl 16(%ebp),%edx
-	movl 20(%ebp),%esi
-	movl 24(%ebp),%edi
-	movl 28(%ebp),%ebp
-1:	int $128
+	jnz __cancel
+	movl 24(%esp),%eax
+	movl 28(%esp),%ebx
+	movl 32(%esp),%ecx
+	movl 36(%esp),%edx
+	movl 40(%esp),%esi
+	movl 44(%esp),%edi
+	movl 48(%esp),%ebp
+	int $128
+.global __cp_end
+__cp_end:
 	popl %ebp
 	popl %edi
 	popl %esi
 	popl %ebx
-	xorl %edx,%edx
-	movl 4(%esp),%ecx
-	movl %edx,(%ecx)
 	ret
-2:	call __cancel