Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: src/nonsfi/linux/linux_sys_private.c

Issue 1212613002: Non-SFI mode: Add Linux asynchronous signal support (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: Disabled the async signal test for glibc Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * This file defines various POSIX-like functions directly using Linux 8 * This file defines various POSIX-like functions directly using Linux
9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which 9 * syscalls. This is analogous to src/untrusted/nacl/sys_private.c, which
10 * defines functions using NaCl syscalls directly. 10 * defines functions using NaCl syscalls directly.
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 603
604 int linux_sigprocmask(int how, 604 int linux_sigprocmask(int how,
605 const linux_sigset_t *set, 605 const linux_sigset_t *set,
606 linux_sigset_t *oset) { 606 linux_sigset_t *oset) {
607 return errno_value_call( 607 return errno_value_call(
608 linux_syscall4(__NR_rt_sigprocmask, how, 608 linux_syscall4(__NR_rt_sigprocmask, how,
609 (uintptr_t) set, (uintptr_t) oset, 609 (uintptr_t) set, (uintptr_t) oset,
610 sizeof(*set))); 610 sizeof(*set)));
611 } 611 }
612 612
613 int linux_tgkill(int tgid, int tid, int sig) {
614 return errno_value_call(
615 linux_syscall3(__NR_tgkill, tgid, tid, sig));
616 }
617
613 /* 618 /*
614 * Obtain Linux signal number from portable signal number. 619 * Obtain Linux signal number from portable signal number.
615 */ 620 */
616 static int nacl_signum_to_linux_signum(int signum) { 621 static int nacl_signum_to_linux_signum(int signum) {
617 /* SIGSTKFLT is not defined in newlib, hence no mapping. */ 622 /* SIGSTKFLT is not defined in newlib, hence no mapping. */
618 #define HANDLE_SIGNUM(SIGNUM) case SIGNUM: return LINUX_##SIGNUM; 623 #define HANDLE_SIGNUM(SIGNUM) case SIGNUM: return LINUX_##SIGNUM;
619 switch(signum) { 624 switch(signum) {
620 HANDLE_SIGNUM(SIGHUP); 625 HANDLE_SIGNUM(SIGHUP);
621 HANDLE_SIGNUM(SIGINT); 626 HANDLE_SIGNUM(SIGINT);
622 HANDLE_SIGNUM(SIGQUIT); 627 HANDLE_SIGNUM(SIGQUIT);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 /* 743 /*
739 * This function is called only from clone() below or 744 * This function is called only from clone() below or
740 * nacl_irt_thread_create() defined in linux_pthread_private.c. 745 * nacl_irt_thread_create() defined in linux_pthread_private.c.
741 * In both cases, |child_stack| will never be NULL, although it is allowed 746 * In both cases, |child_stack| will never be NULL, although it is allowed
742 * for direct clone() syscall. So, we skip that case's implementation for 747 * for direct clone() syscall. So, we skip that case's implementation for
743 * simplicity here. 748 * simplicity here.
744 * 749 *
745 * Here we reserve 6 * 4 bytes for three purposes described below: 750 * Here we reserve 6 * 4 bytes for three purposes described below:
746 * 1) At the beginning of the child process, we call fn(arg). To pass 751 * 1) At the beginning of the child process, we call fn(arg). To pass
747 * the function pointer and arguments, we use |stack| for |arg|, 752 * the function pointer and arguments, we use |stack| for |arg|,
748 * |stack - 4| for |fn|. Here, we need 4-byte extra memory on top of 753 * |stack + 4| for |fn|.
749 * stack for |arg|.
750 * 2) Our syscall() implementation reads six 4-byte arguments regardless 754 * 2) Our syscall() implementation reads six 4-byte arguments regardless
751 * of its actual arguments. 755 * of its actual arguments.
752 * 3) Similar to 2), our clone() implementation reads three 4-byte arguments 756 * 3) Similar to 2), our clone() implementation reads three 4-byte arguments
753 * regardless of its actual arguments. 757 * regardless of its actual arguments.
754 * So, here we need max size of those three cases (= 6 * 4 bytes) on top of 758 * So, here we need max size of those three cases (= 6 * 4 bytes) on top of
755 * the stack, with 16-byte alignment. 759 * the stack, with 16-byte alignment.
756 */ 760 */
757 static const int kStackAlignmentMask = ~15; 761 static const int kStackAlignmentMask = ~15;
758 void *stack = (void *) (((uintptr_t) child_stack - sizeof(uintptr_t) * 6) & 762 void *stack = (void *) (((uintptr_t) child_stack - sizeof(uintptr_t) * 6) &
759 kStackAlignmentMask); 763 kStackAlignmentMask);
760 /* Put |fn| and |arg| on child process's stack. */ 764 /* Put |fn| and |arg| on child process's stack. */
761 ((uintptr_t *) stack)[-1] = fn;
762 ((uintptr_t *) stack)[0] = arg; 765 ((uintptr_t *) stack)[0] = arg;
766 ((uintptr_t *) stack)[1] = fn;
763 767
764 #if defined(__i386__) 768 #if defined(__i386__)
765 uint32_t result; 769 uint32_t result;
766 __asm__ __volatile__("int $0x80\n" 770 __asm__ __volatile__("int $0x80\n"
767 /* 771 /*
768 * If the return value of clone is non-zero, we are 772 * If the return value of clone is non-zero, we are
769 * in the parent thread of clone. 773 * in the parent thread of clone.
770 */ 774 */
771 "cmp $0, %%eax\n" 775 "cmp $0, %%eax\n"
772 "jne 0f\n" 776 "jne 0f\n"
773 /* 777 /*
774 * In child thread. Clear the frame pointer to 778 * In child thread. Clear the frame pointer to
775 * prevent debuggers from unwinding beyond this. 779 * prevent debuggers from unwinding beyond this.
776 */ 780 */
777 "mov $0, %%ebp\n" 781 "mov $0, %%ebp\n"
778 /* 782 /*
779 * Call fn(arg). Note that |arg| is already ready on top 783 * Call fn(arg). Note that |arg| is already ready on top
780 * of the stack, here. 784 * of the stack, here.
781 */ 785 */
782 "call *-4(%%esp)\n" 786 "call *4(%%esp)\n"
783 /* Then call _exit(2) with the return value. */ 787 /* Then call _exit(2) with the return value. */
784 "mov %%eax, %%ebx\n" 788 "mov %%eax, %%ebx\n"
785 "mov %[exit_sysno], %%eax\n" 789 "mov %[exit_sysno], %%eax\n"
786 "int $0x80\n" 790 "int $0x80\n"
787 /* _exit(2) will never return. */ 791 /* _exit(2) will never return. */
788 "hlt\n" 792 "hlt\n"
789 "0:\n" 793 "0:\n"
790 : "=a"(result) 794 : "=a"(result)
791 : "a"(__NR_clone), "b"(flags), "c"(stack), 795 : "a"(__NR_clone), "b"(flags), "c"(stack),
792 "d"(ptid), "S"(&desc), "D"(ctid), 796 "d"(ptid), "S"(&desc), "D"(ctid),
(...skipping 15 matching lines...) Expand all
808 "cmp r0, #0\n" 812 "cmp r0, #0\n"
809 "bne 0f\n" 813 "bne 0f\n"
810 /* 814 /*
811 * In child thread. Clear the frame pointer to 815 * In child thread. Clear the frame pointer to
812 * prevent debuggers from unwinding beyond this, 816 * prevent debuggers from unwinding beyond this,
813 * load start_func from the stack and call it. 817 * load start_func from the stack and call it.
814 */ 818 */
815 "mov fp, #0\n" 819 "mov fp, #0\n"
816 /* Load |arg| to r0 register, then call |fn|. */ 820 /* Load |arg| to r0 register, then call |fn|. */
817 "ldr r0, [sp]\n" 821 "ldr r0, [sp]\n"
818 "ldr r1, [sp, #-4]\n" 822 "ldr r1, [sp, #4]\n"
819 "blx r1\n" 823 "blx r1\n"
820 /* 824 /*
821 * Then, call _exit(2) with the returned value. 825 * Then, call _exit(2) with the returned value.
822 * r0 keeps the return value of |fn(arg)|. 826 * r0 keeps the return value of |fn(arg)|.
823 */ 827 */
824 "mov r7, %[exit_sysno]\n" 828 "mov r7, %[exit_sysno]\n"
825 "svc #0\n" 829 "svc #0\n"
826 /* _exit(2) will never return. */ 830 /* _exit(2) will never return. */
827 "bkpt #0\n" 831 "bkpt #0\n"
828 "0:\n" 832 "0:\n"
(...skipping 22 matching lines...) Expand all
851 va_list ap; 855 va_list ap;
852 va_start(ap, arg); 856 va_start(ap, arg);
853 void *ptid = va_arg(ap, void *); 857 void *ptid = va_arg(ap, void *);
854 void *tls = va_arg(ap, void *); 858 void *tls = va_arg(ap, void *);
855 void *ctid = va_arg(ap, void *); 859 void *ctid = va_arg(ap, void *);
856 va_end(ap); 860 va_end(ap);
857 861
858 return errno_value_call(linux_clone_wrapper( 862 return errno_value_call(linux_clone_wrapper(
859 (uintptr_t) fn, (uintptr_t) arg, flags, child_stack, ptid, tls, ctid)); 863 (uintptr_t) fn, (uintptr_t) arg, flags, child_stack, ptid, tls, ctid));
860 } 864 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698