about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-02-20 20:25:35 -0500
committerRich Felker <dalias@aerifal.cx>2015-02-20 20:25:35 -0500
commitf409338a9e808a09001669377c608fd2803d808d (patch)
tree2eb5478cc7177d8480ed252cc8004d1b102f5acf
parent6bea5dc69892cd9ff0c222474e7dd468c29dfa75 (diff)
downloadmusl-f409338a9e808a09001669377c608fd2803d808d.tar.gz
musl-f409338a9e808a09001669377c608fd2803d808d.tar.xz
musl-f409338a9e808a09001669377c608fd2803d808d.zip
prepare cancellation syscall asm for possibility of __cancel returning
-rw-r--r--src/thread/arm/syscall_cp.s6
-rw-r--r--src/thread/i386/syscall_cp.s9
-rw-r--r--src/thread/mips/syscall_cp.s20
-rw-r--r--src/thread/powerpc/syscall_cp.s1
-rw-r--r--src/thread/pthread_cancel.c7
5 files changed, 32 insertions, 11 deletions
diff --git a/src/thread/arm/syscall_cp.s b/src/thread/arm/syscall_cp.s
index 5a2d6c35..66c5ecbd 100644
--- a/src/thread/arm/syscall_cp.s
+++ b/src/thread/arm/syscall_cp.s
@@ -7,7 +7,7 @@ __syscall_cp_asm:
 __cp_begin:
 	ldr r0,[r0]
 	cmp r0,#0
-	blne __cancel
+	blne __cp_cancel
 	mov r7,r1
 	mov r0,r2
 	mov r1,r3
@@ -19,3 +19,7 @@ __cp_end:
 	tst lr,#1
 	moveq pc,lr
 	bx lr
+.global __cp_cancel
+__cp_cancel:
+	ldmfd sp!,{r4,r5,r6,r7,lr}
+	b __cancel
diff --git a/src/thread/i386/syscall_cp.s b/src/thread/i386/syscall_cp.s
index 3bf52c1f..71ce63f7 100644
--- a/src/thread/i386/syscall_cp.s
+++ b/src/thread/i386/syscall_cp.s
@@ -11,7 +11,7 @@ __syscall_cp_asm:
 __cp_begin:
 	movl (%ecx),%eax
 	testl %eax,%eax
-	jnz __cancel
+	jnz __cp_cancel
 	movl 24(%esp),%eax
 	movl 28(%esp),%ebx
 	movl 32(%esp),%ecx
@@ -27,3 +27,10 @@ __cp_end:
 	popl %esi
 	popl %ebx
 	ret
+.global __cp_cancel
+__cp_cancel:
+	popl %ebp
+	popl %edi
+	popl %esi
+	popl %ebx
+	jmp __cancel
diff --git a/src/thread/mips/syscall_cp.s b/src/thread/mips/syscall_cp.s
index b6f30ee8..d903794d 100644
--- a/src/thread/mips/syscall_cp.s
+++ b/src/thread/mips/syscall_cp.s
@@ -3,19 +3,19 @@
 .global __syscall_cp_asm
 .type   __syscall_cp_asm,@function
 __syscall_cp_asm:
+	subu    $sp, $sp, 32
 .global __cp_begin
 __cp_begin:
 	lw      $4, 0($4)
-	bne     $4, $0, 2f
+	bne     $4, $0, __cp_cancel
 	move    $2, $5
 	move    $4, $6
 	move    $5, $7
-	lw      $6, 16($sp)
-	lw      $7, 20($sp)
-	lw      $8, 24($sp)
-	lw      $9, 28($sp)
-	lw      $10,32($sp)
-	subu    $sp, $sp, 32
+	lw      $6, 48($sp)
+	lw      $7, 52($sp)
+	lw      $8, 56($sp)
+	lw      $9, 60($sp)
+	lw      $10,64($sp)
 	sw      $8, 16($sp)
 	sw      $9, 20($sp)
 	sw      $10,24($sp)
@@ -29,6 +29,10 @@ __cp_end:
 	subu    $2, $0, $2
 1:	jr      $ra
 	nop
-2:	lw      $25, %call16(__cancel)($gp)
+
+.global __cp_cancel
+__cp_cancel:
+	addu    $sp, $sp, 32
+	lw      $25, %call16(__cancel)($gp)
 	jr      $25
 	nop
diff --git a/src/thread/powerpc/syscall_cp.s b/src/thread/powerpc/syscall_cp.s
index 2c97ca04..0c7869cc 100644
--- a/src/thread/powerpc/syscall_cp.s
+++ b/src/thread/powerpc/syscall_cp.s
@@ -31,7 +31,6 @@ __cp_begin:
 	beq+ cr7, 1f #jump to label 1 if r0 was 0
 	
 	b __cancel #else call cancel 
-	# (the return address is not needed, since __cancel never returns)
 1:
 	#ok, the cancel flag was not set
 	# syscall: number goes to r0, the rest 3-8
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
index 4493931e..66e0817c 100644
--- a/src/thread/pthread_cancel.c
+++ b/src/thread/pthread_cancel.c
@@ -1,11 +1,18 @@
 #include "pthread_impl.h"
 #include "syscall.h"
+#include "libc.h"
 
 void __cancel()
 {
 	pthread_exit(PTHREAD_CANCELED);
 }
 
+/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a
+ * definition of __cp_cancel to undo those adjustments and call __cancel.
+ * Otherwise, __cancel provides a definition for __cp_cancel. */
+
+weak_alias(__cancel, __cp_cancel);
+
 long __syscall_cp_asm(volatile void *, syscall_arg_t,
                       syscall_arg_t, syscall_arg_t, syscall_arg_t,
                       syscall_arg_t, syscall_arg_t, syscall_arg_t);