From: Rich Felker Date: Sat, 21 Feb 2015 01:25:35 +0000 (-0500) Subject: prepare cancellation syscall asm for possibility of __cancel returning X-Git-Tag: v1.1.7~44 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=f409338a9e808a09001669377c608fd2803d808d;p=oweals%2Fmusl.git prepare cancellation syscall asm for possibility of __cancel returning --- 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);