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

Side by Side Diff: src/nonsfi/irt/irt_interfaces.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: Fixed a small window where signals could corrupt the stack 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) 2013 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2013 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 #include "native_client/src/nonsfi/irt/irt_interfaces.h" 7 #include "native_client/src/nonsfi/irt/irt_interfaces.h"
8 8
9 #include <assert.h> 9 #include <assert.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <fcntl.h> 11 #include <fcntl.h>
12 #include <limits.h> 12 #include <limits.h>
13 #include <pthread.h> 13 #include <pthread.h>
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <stdlib.h> 15 #include <stdlib.h>
16 #include <string.h> 16 #include <string.h>
17 #include <sys/mman.h> 17 #include <sys/mman.h>
18 #include <sys/stat.h> 18 #include <sys/stat.h>
19 #include <unistd.h> 19 #include <unistd.h>
20 20
21 #if defined(__linux__) 21 #if defined(__linux__)
22 # include <linux/futex.h> 22 # include <linux/futex.h>
23 # include <sys/syscall.h> 23 # include <sys/syscall.h>
24 #endif 24 #endif
25 25
26 #include "native_client/src/include/elf32.h" 26 #include "native_client/src/include/elf32.h"
27 #include "native_client/src/include/elf_auxv.h" 27 #include "native_client/src/include/elf_auxv.h"
28 #include "native_client/src/include/nacl/nacl_exception.h" 28 #include "native_client/src/include/nacl/nacl_exception.h"
29 #include "native_client/src/include/nacl/nacl_signal.h"
29 #include "native_client/src/include/nacl_macros.h" 30 #include "native_client/src/include/nacl_macros.h"
30 #include "native_client/src/public/irt_core.h" 31 #include "native_client/src/public/irt_core.h"
31 #include "native_client/src/public/nonsfi/irt_exception_handling.h"
32 #include "native_client/src/trusted/service_runtime/include/machine/_types.h" 32 #include "native_client/src/trusted/service_runtime/include/machine/_types.h"
33 #include "native_client/src/trusted/service_runtime/include/sys/mman.h" 33 #include "native_client/src/trusted/service_runtime/include/sys/mman.h"
34 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" 34 #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
35 #include "native_client/src/trusted/service_runtime/include/sys/time.h" 35 #include "native_client/src/trusted/service_runtime/include/sys/time.h"
36 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" 36 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
37 #include "native_client/src/untrusted/irt/irt.h" 37 #include "native_client/src/untrusted/irt/irt.h"
38 #include "native_client/src/untrusted/irt/irt_dev.h" 38 #include "native_client/src/untrusted/irt/irt_dev.h"
39 #include "native_client/src/untrusted/irt/irt_interfaces.h" 39 #include "native_client/src/untrusted/irt/irt_interfaces.h"
40 #include "native_client/src/untrusted/nacl/nacl_random.h" 40 #include "native_client/src/untrusted/nacl/nacl_random.h"
41 41
42 #if defined(__native_client__) && defined(__arm__) 42 #if defined(__native_client__) && defined(__arm__)
43 #include "native_client/src/nonsfi/irt/irt_icache.h" 43 #include "native_client/src/nonsfi/irt/irt_icache.h"
44 #endif 44 #endif
45 45
46 #if defined(__native_client__) 46 #if defined(__native_client__)
47 # include "native_client/src/nonsfi/linux/linux_pthread_private.h" 47 # include "native_client/src/nonsfi/linux/linux_pthread_private.h"
48 # include "native_client/src/public/nonsfi/irt_signal_handling.h"
48 #endif 49 #endif
49 50
50 /* 51 /*
51 * This is an implementation of NaCl's IRT interfaces that runs 52 * This is an implementation of NaCl's IRT interfaces that runs
52 * outside of the NaCl sandbox. 53 * outside of the NaCl sandbox.
53 * 54 *
54 * This allows PNaCl to be used as a portability layer without the 55 * This allows PNaCl to be used as a portability layer without the
55 * SFI-based sandboxing. PNaCl pexes can be translated to 56 * SFI-based sandboxing. PNaCl pexes can be translated to
56 * non-SFI-sandboxed native code and linked against this IRT 57 * non-SFI-sandboxed native code and linked against this IRT
57 * implementation. 58 * implementation.
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 static void *start_thread(void *arg) { 352 static void *start_thread(void *arg) {
352 struct thread_args args = *(struct thread_args *) arg; 353 struct thread_args args = *(struct thread_args *) arg;
353 free(arg); 354 free(arg);
354 g_tls_value = args.thread_ptr; 355 g_tls_value = args.thread_ptr;
355 args.start_func(); 356 args.start_func();
356 abort(); 357 abort();
357 } 358 }
358 359
359 static int thread_create(void (*start_func)(void), void *stack, 360 static int thread_create(void (*start_func)(void), void *stack,
360 void *thread_ptr) { 361 void *thread_ptr) {
361 #if defined(__native_client__)
Mark Seaborn 2015/07/16 23:21:16 By removing this, you're changing NACL_IRT_THREAD_
Luis Héctor Chávez 2015/07/20 18:13:47 Done.
362 struct thread_args *args = malloc(sizeof(struct thread_args));
363 if (args == NULL) {
364 return ENOMEM;
365 }
366 args->start_func = start_func;
367 args->thread_ptr = thread_ptr;
368 /* In Linux, it is possible to use the provided stack directly. */
369 int error = nacl_user_thread_create(start_thread, stack, args);
370 if (error != 0)
371 free(args);
372 return error;
373 #else
374 /* 362 /*
375 * For now, we ignore the stack that user code provides and just use 363 * For now, we ignore the stack that user code provides and just use
376 * the stack that the host libpthread allocates. 364 * the stack that the host libpthread allocates.
377 */ 365 */
378 pthread_attr_t attr; 366 pthread_attr_t attr;
379 int error = pthread_attr_init(&attr); 367 int error = pthread_attr_init(&attr);
380 if (error != 0) 368 if (error != 0)
381 return error; 369 return error;
382 error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 370 error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
383 if (error != 0) 371 if (error != 0)
384 return error; 372 return error;
385 struct thread_args *args = malloc(sizeof(struct thread_args)); 373 struct thread_args *args = malloc(sizeof(struct thread_args));
386 if (args == NULL) { 374 if (args == NULL) {
387 error = ENOMEM; 375 error = ENOMEM;
388 goto cleanup; 376 goto cleanup;
389 } 377 }
390 args->start_func = start_func; 378 args->start_func = start_func;
391 args->thread_ptr = thread_ptr; 379 args->thread_ptr = thread_ptr;
392 pthread_t tid; 380 pthread_t tid;
393 error = pthread_create(&tid, &attr, start_thread, args); 381 error = pthread_create(&tid, &attr, start_thread, args);
394 if (error != 0) 382 if (error != 0)
395 free(args); 383 free(args);
396 cleanup: 384 cleanup:
397 pthread_attr_destroy(&attr); 385 pthread_attr_destroy(&attr);
398 return error; 386 return error;
399 #endif
400 } 387 }
401 388
402 static void thread_exit(int32_t *stack_flag) { 389 static void thread_exit(int32_t *stack_flag) {
403 #if defined(__native_client__)
404 nacl_user_thread_exit(stack_flag);
405 #else
406 *stack_flag = 0; /* Indicate that the user code's stack can be freed. */ 390 *stack_flag = 0; /* Indicate that the user code's stack can be freed. */
407 pthread_exit(NULL); 391 pthread_exit(NULL);
392 }
393
394 #if defined(__native_client__)
395 static int thread_create_nonsfi(void (*start_func)(void), void *stack,
396 void *thread_ptr, nacl_irt_tid_t *child_tid) {
397 struct thread_args *args = malloc(sizeof(struct thread_args));
398 if (args == NULL) {
399 return ENOMEM;
400 }
401 args->start_func = start_func;
402 args->thread_ptr = thread_ptr;
403 /* In Linux, it is possible to use the provided stack directly. */
404 int error = nacl_user_thread_create(start_thread, stack, args, child_tid);
405 if (error != 0)
406 free(args);
407 return error;
408 }
409
410 static void thread_exit_nonsfi(int32_t *stack_flag) {
411 nacl_user_thread_exit(stack_flag);
412 }
408 #endif 413 #endif
409 }
410 414
411 static int thread_nice(const int nice) { 415 static int thread_nice(const int nice) {
412 return 0; 416 return 0;
413 } 417 }
414 418
415 /* 419 /*
416 * Mac OS X does not provide futexes or clock_gettime()/getres() natively. 420 * Mac OS X does not provide futexes or clock_gettime()/getres() natively.
417 * TODO(mseaborn): Make threads and clock_gettime() work on Mac OS X. 421 * TODO(mseaborn): Make threads and clock_gettime() work on Mac OS X.
418 */ 422 */
419 #if defined(__linux__) 423 #if defined(__linux__)
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 tls_init, 609 tls_init,
606 tls_get, 610 tls_get,
607 }; 611 };
608 612
609 const struct nacl_irt_thread nacl_irt_thread = { 613 const struct nacl_irt_thread nacl_irt_thread = {
610 thread_create, 614 thread_create,
611 thread_exit, 615 thread_exit,
612 thread_nice, 616 thread_nice,
613 }; 617 };
614 618
619 #if defined(__native_client__)
620 const struct nacl_irt_thread_v0_2 nacl_irt_thread_v0_2 = {
621 thread_create_nonsfi,
622 thread_exit_nonsfi,
623 thread_nice,
624 };
625 #endif
626
615 #if defined(__linux__) 627 #if defined(__linux__)
616 const struct nacl_irt_futex nacl_irt_futex = { 628 const struct nacl_irt_futex nacl_irt_futex = {
617 futex_wait_abs, 629 futex_wait_abs,
618 futex_wake, 630 futex_wake,
619 }; 631 };
620 #elif !defined(__native_client__) 632 #elif !defined(__native_client__)
621 DEFINE_STUB(futex_wait_abs) 633 DEFINE_STUB(futex_wait_abs)
622 DEFINE_STUB(futex_wake) 634 DEFINE_STUB(futex_wake)
623 const struct nacl_irt_futex nacl_irt_futex = { 635 const struct nacl_irt_futex nacl_irt_futex = {
624 USE_STUB(nacl_irt_futex, futex_wait_abs), 636 USE_STUB(nacl_irt_futex, futex_wait_abs),
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 * The following condition is true when building for Non-SFI Mode, 677 * The following condition is true when building for Non-SFI Mode,
666 * when we're calling Linux syscalls directly. (Counter-intuitively, 678 * when we're calling Linux syscalls directly. (Counter-intuitively,
667 * "__linux__" is not #defined in this case.) 679 * "__linux__" is not #defined in this case.)
668 */ 680 */
669 #if defined(__native_client__) 681 #if defined(__native_client__)
670 const struct nacl_irt_exception_handling nacl_irt_exception_handling = { 682 const struct nacl_irt_exception_handling nacl_irt_exception_handling = {
671 nacl_exception_get_and_set_handler, 683 nacl_exception_get_and_set_handler,
672 nacl_exception_set_stack, 684 nacl_exception_set_stack,
673 nacl_exception_clear_flag, 685 nacl_exception_clear_flag,
674 }; 686 };
687
688 const struct nacl_irt_async_signal_handling nacl_irt_async_signal_handling = {
689 nacl_signal_set_handler,
690 nacl_signal_send_async_signal,
691 };
675 #endif 692 #endif
676 693
677 #if defined(__native_client__) && defined(__arm__) 694 #if defined(__native_client__) && defined(__arm__)
678 const struct nacl_irt_icache nacl_irt_icache = { 695 const struct nacl_irt_icache nacl_irt_icache = {
679 irt_clear_cache, 696 irt_clear_cache,
680 }; 697 };
681 #endif 698 #endif
682 699
683 static int g_allow_dev_interfaces = 0; 700 static int g_allow_dev_interfaces = 0;
684 701
685 void nacl_irt_nonsfi_allow_dev_interfaces() { 702 void nacl_irt_nonsfi_allow_dev_interfaces() {
686 g_allow_dev_interfaces = 1; 703 g_allow_dev_interfaces = 1;
687 } 704 }
688 705
689 static int irt_dev_filter(void) { 706 static int irt_dev_filter(void) {
690 return g_allow_dev_interfaces; 707 return g_allow_dev_interfaces;
691 } 708 }
692 709
693 static const struct nacl_irt_interface irt_interfaces[] = { 710 static const struct nacl_irt_interface irt_interfaces[] = {
694 { NACL_IRT_BASIC_v0_1, &nacl_irt_basic, sizeof(nacl_irt_basic), NULL }, 711 { NACL_IRT_BASIC_v0_1, &nacl_irt_basic, sizeof(nacl_irt_basic), NULL },
695 { NACL_IRT_FDIO_v0_1, &nacl_irt_fdio, sizeof(nacl_irt_fdio), NULL }, 712 { NACL_IRT_FDIO_v0_1, &nacl_irt_fdio, sizeof(nacl_irt_fdio), NULL },
696 { NACL_IRT_MEMORY_v0_3, &nacl_irt_memory, sizeof(nacl_irt_memory), NULL }, 713 { NACL_IRT_MEMORY_v0_3, &nacl_irt_memory, sizeof(nacl_irt_memory), NULL },
697 { NACL_IRT_TLS_v0_1, &nacl_irt_tls, sizeof(nacl_irt_tls), NULL }, 714 { NACL_IRT_TLS_v0_1, &nacl_irt_tls, sizeof(nacl_irt_tls), NULL },
698 { NACL_IRT_THREAD_v0_1, &nacl_irt_thread, sizeof(nacl_irt_thread), NULL }, 715 { NACL_IRT_THREAD_v0_1, &nacl_irt_thread, sizeof(nacl_irt_thread), NULL },
716 #if defined(__native_client__)
717 { NACL_IRT_THREAD_v0_2, &nacl_irt_thread_v0_2,
718 sizeof(nacl_irt_thread_v0_2), NULL },
719 #endif
699 { NACL_IRT_FUTEX_v0_1, &nacl_irt_futex, sizeof(nacl_irt_futex), NULL }, 720 { NACL_IRT_FUTEX_v0_1, &nacl_irt_futex, sizeof(nacl_irt_futex), NULL },
700 { NACL_IRT_RANDOM_v0_1, &nacl_irt_random, sizeof(nacl_irt_random), NULL }, 721 { NACL_IRT_RANDOM_v0_1, &nacl_irt_random, sizeof(nacl_irt_random), NULL },
701 #if defined(__linux__) || defined(__native_client__) 722 #if defined(__linux__) || defined(__native_client__)
702 { NACL_IRT_CLOCK_v0_1, &nacl_irt_clock, sizeof(nacl_irt_clock), NULL }, 723 { NACL_IRT_CLOCK_v0_1, &nacl_irt_clock, sizeof(nacl_irt_clock), NULL },
703 #endif 724 #endif
704 { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename, 725 { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename,
705 sizeof(nacl_irt_dev_filename), irt_dev_filter }, 726 sizeof(nacl_irt_dev_filename), irt_dev_filter },
706 { NACL_IRT_DEV_GETPID_v0_1, &nacl_irt_dev_getpid, 727 { NACL_IRT_DEV_GETPID_v0_1, &nacl_irt_dev_getpid,
707 sizeof(nacl_irt_dev_getpid), irt_dev_filter }, 728 sizeof(nacl_irt_dev_getpid), irt_dev_filter },
708 #if defined(__native_client__) 729 #if defined(__native_client__)
709 { NACL_IRT_EXCEPTION_HANDLING_v0_1, &nacl_irt_exception_handling, 730 { NACL_IRT_EXCEPTION_HANDLING_v0_1, &nacl_irt_exception_handling,
710 sizeof(nacl_irt_exception_handling), NULL }, 731 sizeof(nacl_irt_exception_handling), NULL },
732 { NACL_IRT_ASYNC_SIGNAL_HANDLING_v0_1, &nacl_irt_async_signal_handling,
733 sizeof(nacl_irt_async_signal_handling), NULL },
711 #endif 734 #endif
712 #if defined(__native_client__) && defined(__arm__) 735 #if defined(__native_client__) && defined(__arm__)
713 { NACL_IRT_ICACHE_v0_1, &nacl_irt_icache, sizeof(nacl_irt_icache), NULL }, 736 { NACL_IRT_ICACHE_v0_1, &nacl_irt_icache, sizeof(nacl_irt_icache), NULL },
714 #endif 737 #endif
715 }; 738 };
716 739
717 size_t nacl_irt_query_core(const char *interface_ident, 740 size_t nacl_irt_query_core(const char *interface_ident,
718 void *table, size_t tablesize) { 741 void *table, size_t tablesize) {
719 return nacl_irt_query_list(interface_ident, table, tablesize, 742 return nacl_irt_query_list(interface_ident, table, tablesize,
720 irt_interfaces, sizeof(irt_interfaces)); 743 irt_interfaces, sizeof(irt_interfaces));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 nacl_entry_func_t entry_func = 798 nacl_entry_func_t entry_func =
776 #if defined(__APPLE__) 799 #if defined(__APPLE__)
777 _start; 800 _start;
778 #else 801 #else
779 _user_start; 802 _user_start;
780 #endif 803 #endif
781 804
782 return nacl_irt_nonsfi_entry(argc, argv, environ, entry_func); 805 return nacl_irt_nonsfi_entry(argc, argv, environ, entry_func);
783 } 806 }
784 #endif 807 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698