diff options
-rw-r--r-- | src/thread/arm/syscall_cp.s | 18 | ||||
-rw-r--r-- | src/thread/cancel_impl.c | 15 | ||||
-rw-r--r-- | src/thread/i386/syscall_cp.s | 36 | ||||
-rw-r--r-- | src/thread/x86_64/syscall_cp.s | 18 |
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 |