about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/thread/arm/syscall_cp.s18
-rw-r--r--src/thread/cancel_impl.c15
-rw-r--r--src/thread/i386/syscall_cp.s36
-rw-r--r--src/thread/x86_64/syscall_cp.s18
4 files changed, 35 insertions, 52 deletions
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index 59924fc5..0cc23b1f 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -3,20 +3,18 @@
 __syscall_cp_asm:
 	mov ip,sp
 	stmfd sp!,{r4,r5,r6,r7,lr}
-	stmfd sp!,{r0}
-	bl 1f
-1:	mov r4,#(1f-.)
-	add r4,r4,lr
-	str r4,[r0,#4]
-	str sp,[r0]
+.global __cp_begin
+__cp_begin:
+	ld r0,[r0]
+	cmp r0,#0
+	blne __cancel
 	mov r7,r1
 	mov r0,r2
 	mov r1,r3
 	ldmfd ip,{r2,r3,r4,r5,r6}
-1:	svc 0
-	ldmfd sp!,{r1}
-	mov r2,#0
-	str r2,[r1]
+	svc 0
+.global __cp_end
+__cp_end:
 	ldmfd sp!,{r4,r5,r6,r7,lr}
 	tst lr,#1
 	moveq pc,lr
diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c
index 7652a7c9..3bf1e392 100644
--- a/src/thread/cancel_impl.c
+++ b/src/thread/cancel_impl.c
@@ -14,19 +14,12 @@ long __syscall_cp_asm(volatile void *, long, long, long, long, long, long, long)
 long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z)
 {
 	pthread_t self;
-	uintptr_t old_sp, old_ip;
 	long r;
 
 	if (!libc.main_thread || (self = __pthread_self())->canceldisable)
 		return __syscall(nr, u, v, w, x, y, z);
 
-	old_sp = self->cp_sp;
-	old_ip = self->cp_ip;
-	self->cp_sp = 0;
-	self->cp_ip = 0;
-	r = __syscall_cp_asm(&self->cp_sp, nr, u, v, w, x, y, z);
-	self->cp_ip = old_ip;
-	self->cp_sp = old_sp;
+	r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
 	if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable)
 		__cancel();
 	return r;
@@ -42,14 +35,14 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx)
 {
 	pthread_t self = __pthread_self();
 	ucontext_t *uc = ctx;
-	uintptr_t sp = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_SP];
-	uintptr_t ip = ((uintptr_t *)&uc->uc_mcontext)[CANCEL_REG_IP];
+	const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP];
+	extern const char __cp_begin[1], __cp_end[1];
 
 	if (!self->cancel || self->canceldisable) return;
 
 	_sigaddset(&uc->uc_sigmask, SIGCANCEL);
 
-	if (self->cancelasync || sp == self->cp_sp && ip <= self->cp_ip) {
+	if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
 		self->canceldisable = 1;
 		pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
 		__cancel();
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
diff --git a/src/thread/x86_64/syscall_cp.s b/src/thread/x86_64/syscall_cp.s
index b0363547..788c53cc 100644
--- a/src/thread/x86_64/syscall_cp.s
+++ b/src/thread/x86_64/syscall_cp.s
@@ -2,12 +2,12 @@
 .global __syscall_cp_asm
 .type   __syscall_cp_asm,@function
 __syscall_cp_asm:
-	lea 1f(%rip),%rax
-	mov %rax,8(%rdi)
-	mov %rsp,(%rdi)
-	mov 16(%rdi),%eax
+
+.global __cp_begin
+__cp_begin:
+	mov (%rdi),%eax
 	test %eax,%eax
-	jnz 2f
+	jnz __cancel
 	mov %rdi,%r11
 	mov %rsi,%rax
 	mov %rdx,%rdi
@@ -17,9 +17,7 @@ __syscall_cp_asm:
 	mov 8(%rsp),%r8
 	mov 16(%rsp),%r9
 	mov %r11,8(%rsp)
-1:	syscall
-	xor %ecx,%ecx
-	mov 8(%rsp),%rdi
-	mov %rcx,(%rdi)
+	syscall
+.global __cp_end
+__cp_end:
 	ret
-2:	call __cancel