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

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

Issue 1293793009: Reland "Non-SFI mode: Add Linux asynchronous signal support" (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: Updated documentation Created 5 years, 4 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
« no previous file with comments | « src/nonsfi/linux/linux_sys_private.h ('k') | src/nonsfi/linux/linux_syscall_defines.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 628
629 int linux_sigprocmask(int how, 629 int linux_sigprocmask(int how,
630 const linux_sigset_t *set, 630 const linux_sigset_t *set,
631 linux_sigset_t *oset) { 631 linux_sigset_t *oset) {
632 return errno_value_call( 632 return errno_value_call(
633 linux_syscall4(__NR_rt_sigprocmask, how, 633 linux_syscall4(__NR_rt_sigprocmask, how,
634 (uintptr_t) set, (uintptr_t) oset, 634 (uintptr_t) set, (uintptr_t) oset,
635 sizeof(*set))); 635 sizeof(*set)));
636 } 636 }
637 637
638 int linux_tgkill(int tgid, int tid, int sig) {
639 return errno_value_call(
640 linux_syscall3(__NR_tgkill, tgid, tid, sig));
641 }
642
638 /* 643 /*
639 * Obtain Linux signal number from portable signal number. 644 * Obtain Linux signal number from portable signal number.
640 */ 645 */
641 static int nacl_signum_to_linux_signum(int signum) { 646 static int nacl_signum_to_linux_signum(int signum) {
642 /* SIGSTKFLT is not defined in newlib, hence no mapping. */ 647 /* SIGSTKFLT is not defined in newlib, hence no mapping. */
643 #define HANDLE_SIGNUM(SIGNUM) case SIGNUM: return LINUX_##SIGNUM; 648 #define HANDLE_SIGNUM(SIGNUM) case SIGNUM: return LINUX_##SIGNUM;
644 switch(signum) { 649 switch(signum) {
645 HANDLE_SIGNUM(SIGHUP); 650 HANDLE_SIGNUM(SIGHUP);
646 HANDLE_SIGNUM(SIGINT); 651 HANDLE_SIGNUM(SIGINT);
647 HANDLE_SIGNUM(SIGQUIT); 652 HANDLE_SIGNUM(SIGQUIT);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 /* 768 /*
764 * This function is called only from clone() below or 769 * This function is called only from clone() below or
765 * nacl_irt_thread_create() defined in linux_pthread_private.c. 770 * nacl_irt_thread_create() defined in linux_pthread_private.c.
766 * In both cases, |child_stack| will never be NULL, although it is allowed 771 * In both cases, |child_stack| will never be NULL, although it is allowed
767 * for direct clone() syscall. So, we skip that case's implementation for 772 * for direct clone() syscall. So, we skip that case's implementation for
768 * simplicity here. 773 * simplicity here.
769 * 774 *
770 * Here we reserve 6 * 4 bytes for three purposes described below: 775 * Here we reserve 6 * 4 bytes for three purposes described below:
771 * 1) At the beginning of the child process, we call fn(arg). To pass 776 * 1) At the beginning of the child process, we call fn(arg). To pass
772 * the function pointer and arguments, we use |stack| for |arg|, 777 * the function pointer and arguments, we use |stack| for |arg|,
773 * |stack - 4| for |fn|. Here, we need 4-byte extra memory on top of 778 * |stack + 4| for |fn|.
774 * stack for |arg|.
775 * 2) Our syscall() implementation reads six 4-byte arguments regardless 779 * 2) Our syscall() implementation reads six 4-byte arguments regardless
776 * of its actual arguments. 780 * of its actual arguments.
777 * 3) Similar to 2), our clone() implementation reads three 4-byte arguments 781 * 3) Similar to 2), our clone() implementation reads three 4-byte arguments
778 * regardless of its actual arguments. 782 * regardless of its actual arguments.
779 * So, here we need max size of those three cases (= 6 * 4 bytes) on top of 783 * So, here we need max size of those three cases (= 6 * 4 bytes) on top of
780 * the stack, with 16-byte alignment. 784 * the stack, with 16-byte alignment.
781 */ 785 */
782 static const int kStackAlignmentMask = ~15; 786 static const int kStackAlignmentMask = ~15;
783 void *stack = (void *) (((uintptr_t) child_stack - sizeof(uintptr_t) * 6) & 787 void *stack = (void *) (((uintptr_t) child_stack - sizeof(uintptr_t) * 6) &
784 kStackAlignmentMask); 788 kStackAlignmentMask);
785 /* Put |fn| and |arg| on child process's stack. */ 789 /* Put |fn| and |arg| on child process's stack. */
786 ((uintptr_t *) stack)[-1] = fn;
787 ((uintptr_t *) stack)[0] = arg; 790 ((uintptr_t *) stack)[0] = arg;
791 ((uintptr_t *) stack)[1] = fn;
788 792
789 #if defined(__i386__) 793 #if defined(__i386__)
790 uint32_t result; 794 uint32_t result;
791 __asm__ __volatile__("int $0x80\n" 795 __asm__ __volatile__("int $0x80\n"
792 /* 796 /*
793 * If the return value of clone is non-zero, we are 797 * If the return value of clone is non-zero, we are
794 * in the parent thread of clone. 798 * in the parent thread of clone.
795 */ 799 */
796 "cmp $0, %%eax\n" 800 "cmp $0, %%eax\n"
797 "jne 0f\n" 801 "jne 0f\n"
798 /* 802 /*
799 * In child thread. Clear the frame pointer to 803 * In child thread. Clear the frame pointer to
800 * prevent debuggers from unwinding beyond this. 804 * prevent debuggers from unwinding beyond this.
801 */ 805 */
802 "mov $0, %%ebp\n" 806 "mov $0, %%ebp\n"
803 /* 807 /*
804 * Call fn(arg). Note that |arg| is already ready on top 808 * Call fn(arg). Note that |arg| is already ready on top
805 * of the stack, here. 809 * of the stack, here.
806 */ 810 */
807 "call *-4(%%esp)\n" 811 "call *4(%%esp)\n"
808 /* Then call _exit(2) with the return value. */ 812 /* Then call _exit(2) with the return value. */
809 "mov %%eax, %%ebx\n" 813 "mov %%eax, %%ebx\n"
810 "mov %[exit_sysno], %%eax\n" 814 "mov %[exit_sysno], %%eax\n"
811 "int $0x80\n" 815 "int $0x80\n"
812 /* _exit(2) will never return. */ 816 /* _exit(2) will never return. */
813 "hlt\n" 817 "hlt\n"
814 "0:\n" 818 "0:\n"
815 : "=a"(result) 819 : "=a"(result)
816 : "a"(__NR_clone), "b"(flags), "c"(stack), 820 : "a"(__NR_clone), "b"(flags), "c"(stack),
817 "d"(ptid), "S"(&desc), "D"(ctid), 821 "d"(ptid), "S"(&desc), "D"(ctid),
(...skipping 15 matching lines...) Expand all
833 "cmp r0, #0\n" 837 "cmp r0, #0\n"
834 "bne 0f\n" 838 "bne 0f\n"
835 /* 839 /*
836 * In child thread. Clear the frame pointer to 840 * In child thread. Clear the frame pointer to
837 * prevent debuggers from unwinding beyond this, 841 * prevent debuggers from unwinding beyond this,
838 * load start_func from the stack and call it. 842 * load start_func from the stack and call it.
839 */ 843 */
840 "mov fp, #0\n" 844 "mov fp, #0\n"
841 /* Load |arg| to r0 register, then call |fn|. */ 845 /* Load |arg| to r0 register, then call |fn|. */
842 "ldr r0, [sp]\n" 846 "ldr r0, [sp]\n"
843 "ldr r1, [sp, #-4]\n" 847 "ldr r1, [sp, #4]\n"
844 "blx r1\n" 848 "blx r1\n"
845 /* 849 /*
846 * Then, call _exit(2) with the returned value. 850 * Then, call _exit(2) with the returned value.
847 * r0 keeps the return value of |fn(arg)|. 851 * r0 keeps the return value of |fn(arg)|.
848 */ 852 */
849 "mov r7, %[exit_sysno]\n" 853 "mov r7, %[exit_sysno]\n"
850 "svc #0\n" 854 "svc #0\n"
851 /* _exit(2) will never return. */ 855 /* _exit(2) will never return. */
852 "bkpt #0\n" 856 "bkpt #0\n"
853 "0:\n" 857 "0:\n"
(...skipping 22 matching lines...) Expand all
876 va_list ap; 880 va_list ap;
877 va_start(ap, arg); 881 va_start(ap, arg);
878 void *ptid = va_arg(ap, void *); 882 void *ptid = va_arg(ap, void *);
879 void *tls = va_arg(ap, void *); 883 void *tls = va_arg(ap, void *);
880 void *ctid = va_arg(ap, void *); 884 void *ctid = va_arg(ap, void *);
881 va_end(ap); 885 va_end(ap);
882 886
883 return errno_value_call(linux_clone_wrapper( 887 return errno_value_call(linux_clone_wrapper(
884 (uintptr_t) fn, (uintptr_t) arg, flags, child_stack, ptid, tls, ctid)); 888 (uintptr_t) fn, (uintptr_t) arg, flags, child_stack, ptid, tls, ctid));
885 } 889 }
OLDNEW
« no previous file with comments | « src/nonsfi/linux/linux_sys_private.h ('k') | src/nonsfi/linux/linux_syscall_defines.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698