diff --git a/libc/Android.mk b/libc/Android.mk index 49c87314e..410f2428e 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -353,6 +353,7 @@ libc_common_src_files += \ arch-arm/bionic/kill.S \ arch-arm/bionic/libgcc_compat.c \ arch-arm/bionic/tkill.S \ + arch-arm/bionic/tgkill.S \ arch-arm/bionic/memcmp.S \ arch-arm/bionic/memcmp16.S \ arch-arm/bionic/memcpy.S \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 46e7b1f72..fa02edc9f 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -63,6 +63,7 @@ void* __brk:brk(void*) 45 # see comments in arch-arm/bionic/kill.S to understand why we don't generate an ARM stub for kill/tkill int kill(pid_t, int) -1,37 int tkill(pid_t tid, int sig) -1,238 +int tgkill(pid_t tgid, pid_t tid, int sig) -1,270 int __ptrace:ptrace(int request, int pid, void* addr, void* data) 26 int __set_thread_area:set_thread_area(void* user_desc) -1,243 int __getpriority:getpriority(int, int) 96 diff --git a/libc/arch-arm/bionic/tgkill.S b/libc/arch-arm/bionic/tgkill.S new file mode 100644 index 000000000..da5c0af7e --- /dev/null +++ b/libc/arch-arm/bionic/tgkill.S @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* unlike our auto-generated syscall stubs, this code saves lr + on the stack, as well as a few other registers. this makes + our stack unwinder happy, when we generate debug stack + traces after the C library or other parts of the system + abort due to a fatal runtime error (e.g. detection + of a corrupted malloc heap). +*/ + +#include +#include + +#ifndef __NR_tgkill +#define __NR_tgkill 268 +#endif + +ENTRY(tgkill) + stmfd sp!, {r4-r7, ip, lr} + ldr r7, =__NR_tgkill + swi #0 + ldmfd sp!, {r4-r7, ip, lr} + movs r0, r0 + bxpl lr + b __set_syscall_errno +END(tgkill) diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk index 1d8760087..d4e45834d 100644 --- a/libc/arch-sh/syscalls.mk +++ b/libc/arch-sh/syscalls.mk @@ -26,6 +26,7 @@ syscall_src += arch-sh/syscalls/setresgid.S syscall_src += arch-sh/syscalls/__brk.S syscall_src += arch-sh/syscalls/kill.S syscall_src += arch-sh/syscalls/tkill.S +syscall_src += arch-sh/syscalls/tgkill.S syscall_src += arch-sh/syscalls/__ptrace.S syscall_src += arch-sh/syscalls/__set_thread_area.S syscall_src += arch-sh/syscalls/__getpriority.S diff --git a/libc/arch-sh/syscalls/tgkill.S b/libc/arch-sh/syscalls/tgkill.S new file mode 100644 index 000000000..222f83683 --- /dev/null +++ b/libc/arch-sh/syscalls/tgkill.S @@ -0,0 +1,32 @@ +/* autogenerated by gensyscalls.py */ +#include + + .text + .type tgkill, @function + .globl tgkill + .align 4 + +tgkill: + + /* invoke trap */ + mov.l 0f, r3 /* trap num */ + trapa #(3 + 0x10) + + /* check return value */ + cmp/pz r0 + bt __NR_tgkill_end + + /* keep error number */ + sts.l pr, @-r15 + mov.l 1f, r1 + jsr @r1 + mov r0, r4 + lds.l @r15+, pr + +__NR_tgkill_end: + rts + nop + + .align 2 +0: .long __NR_tgkill +1: .long __set_syscall_errno diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 3b85025dd..13edeb0df 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -26,6 +26,7 @@ syscall_src += arch-x86/syscalls/setresgid.S syscall_src += arch-x86/syscalls/__brk.S syscall_src += arch-x86/syscalls/kill.S syscall_src += arch-x86/syscalls/tkill.S +syscall_src += arch-x86/syscalls/tgkill.S syscall_src += arch-x86/syscalls/__ptrace.S syscall_src += arch-x86/syscalls/__set_thread_area.S syscall_src += arch-x86/syscalls/__getpriority.S diff --git a/libc/arch-x86/syscalls/tgkill.S b/libc/arch-x86/syscalls/tgkill.S new file mode 100644 index 000000000..99af74079 --- /dev/null +++ b/libc/arch-x86/syscalls/tgkill.S @@ -0,0 +1,29 @@ +/* autogenerated by gensyscalls.py */ +#include + + .text + .type tgkill, @function + .globl tgkill + .align 4 + +tgkill: + pushl %ebx + pushl %ecx + pushl %edx + mov 16(%esp), %ebx + mov 20(%esp), %ecx + mov 24(%esp), %edx + movl $__NR_tgkill, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax +1: + popl %edx + popl %ecx + popl %ebx + ret diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index b893a124f..10fb7b5d6 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -1839,7 +1839,7 @@ static void pthread_key_clean_all(void) } // man says this should be in , but it isn't -extern int tkill(int tid, int sig); +extern int tgkill(int tgid, int tid, int sig); int pthread_kill(pthread_t tid, int sig) { @@ -1847,7 +1847,7 @@ int pthread_kill(pthread_t tid, int sig) int old_errno = errno; pthread_internal_t * thread = (pthread_internal_t *)tid; - ret = tkill(thread->kernel_id, sig); + ret = tgkill(getpid(), thread->kernel_id, sig); if (ret < 0) { ret = errno; errno = old_errno; diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h index 7b74a4b82..930508a25 100644 --- a/libc/include/sys/linux-syscalls.h +++ b/libc/include/sys/linux-syscalls.h @@ -198,6 +198,7 @@ #define __NR_waitid (__NR_SYSCALL_BASE + 284) #define __NR_kill (__NR_SYSCALL_BASE + 37) #define __NR_tkill (__NR_SYSCALL_BASE + 238) +#define __NR_tgkill (__NR_SYSCALL_BASE + 270) #define __NR_set_thread_area (__NR_SYSCALL_BASE + 243) #define __NR_openat (__NR_SYSCALL_BASE + 295) #define __NR_madvise (__NR_SYSCALL_BASE + 219) @@ -242,6 +243,7 @@ #define __NR_waitid (__NR_SYSCALL_BASE + 284) #define __NR_kill (__NR_SYSCALL_BASE + 37) #define __NR_tkill (__NR_SYSCALL_BASE + 238) +#define __NR_tgkill (__NR_SYSCALL_BASE + 270) #define __NR_set_thread_area (__NR_SYSCALL_BASE + 243) #define __NR_vfork (__NR_SYSCALL_BASE + 190) #define __NR_openat (__NR_SYSCALL_BASE + 295) diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h index ae9077ffb..f463127b5 100644 --- a/libc/include/sys/linux-unistd.h +++ b/libc/include/sys/linux-unistd.h @@ -32,6 +32,7 @@ int setresgid (gid_t, gid_t, gid_t); void* __brk (void*); int kill (pid_t, int); int tkill (pid_t tid, int sig); +int tgkill (pid_t tgid, pid_t tid, int sig); int __ptrace (int request, int pid, void* addr, void* data); int __set_thread_area (void* user_desc); int __getpriority (int, int);