OLD | NEW |
---|---|
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> |
(...skipping 10 matching lines...) Expand all Loading... | |
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_macros.h" | 29 #include "native_client/src/include/nacl_macros.h" |
30 #include "native_client/src/public/irt_core.h" | 30 #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" | 31 #include "native_client/src/trusted/service_runtime/include/machine/_types.h" |
33 #include "native_client/src/trusted/service_runtime/include/sys/mman.h" | 32 #include "native_client/src/trusted/service_runtime/include/sys/mman.h" |
34 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" | 33 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" |
35 #include "native_client/src/trusted/service_runtime/include/sys/time.h" | 34 #include "native_client/src/trusted/service_runtime/include/sys/time.h" |
36 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" | 35 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" |
37 #include "native_client/src/untrusted/irt/irt.h" | 36 #include "native_client/src/untrusted/irt/irt.h" |
38 #include "native_client/src/untrusted/irt/irt_dev.h" | 37 #include "native_client/src/untrusted/irt/irt_dev.h" |
39 #include "native_client/src/untrusted/irt/irt_interfaces.h" | 38 #include "native_client/src/untrusted/irt/irt_interfaces.h" |
40 #include "native_client/src/untrusted/nacl/nacl_random.h" | 39 #include "native_client/src/untrusted/nacl/nacl_random.h" |
41 | 40 |
42 #if defined(__native_client__) && defined(__arm__) | 41 #if defined(__native_client__) && defined(__arm__) |
43 #include "native_client/src/nonsfi/irt/irt_icache.h" | 42 #include "native_client/src/nonsfi/irt/irt_icache.h" |
44 #endif | 43 #endif |
45 | 44 |
46 #if defined(__native_client__) | 45 #if defined(__native_client__) |
46 # include "native_client/src/nonsfi/linux/irt_signal_handling.h" | |
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" | |
Mark Seaborn
2015/08/12 01:43:06
This one is not needed, I think?
Luis Héctor Chávez
2015/08/12 22:14:26
Done.
| |
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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 }; | 350 }; |
350 | 351 |
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 void *thread_ptr) { | |
361 #if defined(__native_client__) | 360 #if defined(__native_client__) |
361 static int thread_create_nonsfi(void (*start_func)(void), void *stack, | |
362 void *thread_ptr, nacl_irt_tid_t *child_tid) { | |
Mark Seaborn
2015/08/12 01:43:07
Nit: align indentation
Luis Héctor Chávez
2015/08/12 22:14:26
Done.
| |
362 struct thread_args *args = malloc(sizeof(struct thread_args)); | 363 struct thread_args *args = malloc(sizeof(struct thread_args)); |
363 if (args == NULL) { | 364 if (args == NULL) { |
364 return ENOMEM; | 365 return ENOMEM; |
365 } | 366 } |
366 args->start_func = start_func; | 367 args->start_func = start_func; |
367 args->thread_ptr = thread_ptr; | 368 args->thread_ptr = thread_ptr; |
368 /* In Linux, it is possible to use the provided stack directly. */ | 369 /* In Linux, it is possible to use the provided stack directly. */ |
369 int error = nacl_user_thread_create(start_thread, stack, args); | 370 int error = nacl_user_thread_create(start_thread, stack, args, child_tid); |
370 if (error != 0) | 371 if (error != 0) |
371 free(args); | 372 free(args); |
372 return error; | 373 return error; |
374 } | |
375 | |
376 static void thread_exit_nonsfi(int32_t *stack_flag) { | |
377 nacl_user_thread_exit(stack_flag); | |
378 } | |
379 #endif | |
380 | |
381 static int thread_create(void (*start_func)(void), void *stack, | |
382 void *thread_ptr) { | |
383 #if defined(__native_client__) | |
384 /* | |
385 * When available, use the nonsfi version that does allow the |stack| to be | |
386 * set in the new thread. | |
387 */ | |
388 return thread_create_nonsfi(start_func, stack, thread_ptr, NULL); | |
373 #else | 389 #else |
374 /* | 390 /* |
375 * For now, we ignore the stack that user code provides and just use | 391 * For now, we ignore the stack that user code provides and just use |
376 * the stack that the host libpthread allocates. | 392 * the stack that the host libpthread allocates. |
377 */ | 393 */ |
378 pthread_attr_t attr; | 394 pthread_attr_t attr; |
379 int error = pthread_attr_init(&attr); | 395 int error = pthread_attr_init(&attr); |
380 if (error != 0) | 396 if (error != 0) |
381 return error; | 397 return error; |
382 error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 398 error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
(...skipping 11 matching lines...) Expand all Loading... | |
394 if (error != 0) | 410 if (error != 0) |
395 free(args); | 411 free(args); |
396 cleanup: | 412 cleanup: |
397 pthread_attr_destroy(&attr); | 413 pthread_attr_destroy(&attr); |
398 return error; | 414 return error; |
399 #endif | 415 #endif |
400 } | 416 } |
401 | 417 |
402 static void thread_exit(int32_t *stack_flag) { | 418 static void thread_exit(int32_t *stack_flag) { |
403 #if defined(__native_client__) | 419 #if defined(__native_client__) |
404 nacl_user_thread_exit(stack_flag); | 420 /* |
421 * Since we used the nonsfi version of thread_create, we must also call the | |
422 * nonsfi version of thread_exit to correctly clean it up. | |
423 */ | |
424 thread_exit_nonsfi(stack_flag); | |
405 #else | 425 #else |
406 *stack_flag = 0; /* Indicate that the user code's stack can be freed. */ | 426 *stack_flag = 0; /* Indicate that the user code's stack can be freed. */ |
407 pthread_exit(NULL); | 427 pthread_exit(NULL); |
408 #endif | 428 #endif |
409 } | 429 } |
410 | 430 |
411 static int thread_nice(const int nice) { | 431 static int thread_nice(const int nice) { |
412 return 0; | 432 return 0; |
413 } | 433 } |
414 | 434 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 tls_init, | 625 tls_init, |
606 tls_get, | 626 tls_get, |
607 }; | 627 }; |
608 | 628 |
609 const struct nacl_irt_thread nacl_irt_thread = { | 629 const struct nacl_irt_thread nacl_irt_thread = { |
610 thread_create, | 630 thread_create, |
611 thread_exit, | 631 thread_exit, |
612 thread_nice, | 632 thread_nice, |
613 }; | 633 }; |
614 | 634 |
635 #if defined(__native_client__) | |
636 const struct nacl_irt_thread_v0_2 nacl_irt_thread_v0_2 = { | |
637 thread_create_nonsfi, | |
638 thread_exit_nonsfi, | |
639 thread_nice, | |
640 }; | |
641 #endif | |
642 | |
615 #if defined(__linux__) | 643 #if defined(__linux__) |
616 const struct nacl_irt_futex nacl_irt_futex = { | 644 const struct nacl_irt_futex nacl_irt_futex = { |
617 futex_wait_abs, | 645 futex_wait_abs, |
618 futex_wake, | 646 futex_wake, |
619 }; | 647 }; |
620 #elif !defined(__native_client__) | 648 #elif !defined(__native_client__) |
621 DEFINE_STUB(futex_wait_abs) | 649 DEFINE_STUB(futex_wait_abs) |
622 DEFINE_STUB(futex_wake) | 650 DEFINE_STUB(futex_wake) |
623 const struct nacl_irt_futex nacl_irt_futex = { | 651 const struct nacl_irt_futex nacl_irt_futex = { |
624 USE_STUB(nacl_irt_futex, futex_wait_abs), | 652 USE_STUB(nacl_irt_futex, futex_wait_abs), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 * The following condition is true when building for Non-SFI Mode, | 693 * The following condition is true when building for Non-SFI Mode, |
666 * when we're calling Linux syscalls directly. (Counter-intuitively, | 694 * when we're calling Linux syscalls directly. (Counter-intuitively, |
667 * "__linux__" is not #defined in this case.) | 695 * "__linux__" is not #defined in this case.) |
668 */ | 696 */ |
669 #if defined(__native_client__) | 697 #if defined(__native_client__) |
670 const struct nacl_irt_exception_handling nacl_irt_exception_handling = { | 698 const struct nacl_irt_exception_handling nacl_irt_exception_handling = { |
671 nacl_exception_get_and_set_handler, | 699 nacl_exception_get_and_set_handler, |
672 nacl_exception_set_stack, | 700 nacl_exception_set_stack, |
673 nacl_exception_clear_flag, | 701 nacl_exception_clear_flag, |
674 }; | 702 }; |
703 | |
704 const struct nacl_irt_async_signal_handling nacl_irt_async_signal_handling = { | |
705 nacl_signal_set_handler, | |
706 nacl_signal_send_async_signal, | |
707 }; | |
675 #endif | 708 #endif |
676 | 709 |
677 #if defined(__native_client__) && defined(__arm__) | 710 #if defined(__native_client__) && defined(__arm__) |
678 const struct nacl_irt_icache nacl_irt_icache = { | 711 const struct nacl_irt_icache nacl_irt_icache = { |
679 irt_clear_cache, | 712 irt_clear_cache, |
680 }; | 713 }; |
681 #endif | 714 #endif |
682 | 715 |
683 static int g_allow_dev_interfaces = 0; | 716 static int g_allow_dev_interfaces = 0; |
684 | 717 |
685 void nacl_irt_nonsfi_allow_dev_interfaces() { | 718 void nacl_irt_nonsfi_allow_dev_interfaces() { |
686 g_allow_dev_interfaces = 1; | 719 g_allow_dev_interfaces = 1; |
687 } | 720 } |
688 | 721 |
689 static int irt_dev_filter(void) { | 722 static int irt_dev_filter(void) { |
690 return g_allow_dev_interfaces; | 723 return g_allow_dev_interfaces; |
691 } | 724 } |
692 | 725 |
693 static const struct nacl_irt_interface irt_interfaces[] = { | 726 static const struct nacl_irt_interface irt_interfaces[] = { |
694 { NACL_IRT_BASIC_v0_1, &nacl_irt_basic, sizeof(nacl_irt_basic), NULL }, | 727 { 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 }, | 728 { 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 }, | 729 { 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 }, | 730 { 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 }, | 731 { NACL_IRT_THREAD_v0_1, &nacl_irt_thread, sizeof(nacl_irt_thread), NULL }, |
732 #if defined(__native_client__) | |
733 { NACL_IRT_THREAD_v0_2, &nacl_irt_thread_v0_2, | |
734 sizeof(nacl_irt_thread_v0_2), NULL }, | |
735 #endif | |
699 { NACL_IRT_FUTEX_v0_1, &nacl_irt_futex, sizeof(nacl_irt_futex), NULL }, | 736 { 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 }, | 737 { NACL_IRT_RANDOM_v0_1, &nacl_irt_random, sizeof(nacl_irt_random), NULL }, |
701 #if defined(__linux__) || defined(__native_client__) | 738 #if defined(__linux__) || defined(__native_client__) |
702 { NACL_IRT_CLOCK_v0_1, &nacl_irt_clock, sizeof(nacl_irt_clock), NULL }, | 739 { NACL_IRT_CLOCK_v0_1, &nacl_irt_clock, sizeof(nacl_irt_clock), NULL }, |
703 #endif | 740 #endif |
704 { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename, | 741 { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename, |
705 sizeof(nacl_irt_dev_filename), irt_dev_filter }, | 742 sizeof(nacl_irt_dev_filename), irt_dev_filter }, |
706 { NACL_IRT_DEV_GETPID_v0_1, &nacl_irt_dev_getpid, | 743 { NACL_IRT_DEV_GETPID_v0_1, &nacl_irt_dev_getpid, |
707 sizeof(nacl_irt_dev_getpid), irt_dev_filter }, | 744 sizeof(nacl_irt_dev_getpid), irt_dev_filter }, |
708 #if defined(__native_client__) | 745 #if defined(__native_client__) |
709 { NACL_IRT_EXCEPTION_HANDLING_v0_1, &nacl_irt_exception_handling, | 746 { NACL_IRT_EXCEPTION_HANDLING_v0_1, &nacl_irt_exception_handling, |
710 sizeof(nacl_irt_exception_handling), NULL }, | 747 sizeof(nacl_irt_exception_handling), NULL }, |
748 { NACL_IRT_ASYNC_SIGNAL_HANDLING_v0_1, &nacl_irt_async_signal_handling, | |
749 sizeof(nacl_irt_async_signal_handling), NULL }, | |
711 #endif | 750 #endif |
712 #if defined(__native_client__) && defined(__arm__) | 751 #if defined(__native_client__) && defined(__arm__) |
713 { NACL_IRT_ICACHE_v0_1, &nacl_irt_icache, sizeof(nacl_irt_icache), NULL }, | 752 { NACL_IRT_ICACHE_v0_1, &nacl_irt_icache, sizeof(nacl_irt_icache), NULL }, |
714 #endif | 753 #endif |
715 }; | 754 }; |
716 | 755 |
717 size_t nacl_irt_query_core(const char *interface_ident, | 756 size_t nacl_irt_query_core(const char *interface_ident, |
718 void *table, size_t tablesize) { | 757 void *table, size_t tablesize) { |
719 return nacl_irt_query_list(interface_ident, table, tablesize, | 758 return nacl_irt_query_list(interface_ident, table, tablesize, |
720 irt_interfaces, sizeof(irt_interfaces)); | 759 irt_interfaces, sizeof(irt_interfaces)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 nacl_entry_func_t entry_func = | 814 nacl_entry_func_t entry_func = |
776 #if defined(__APPLE__) | 815 #if defined(__APPLE__) |
777 _start; | 816 _start; |
778 #else | 817 #else |
779 _user_start; | 818 _user_start; |
780 #endif | 819 #endif |
781 | 820 |
782 return nacl_irt_nonsfi_entry(argc, argv, environ, entry_func); | 821 return nacl_irt_nonsfi_entry(argc, argv, environ, entry_func); |
783 } | 822 } |
784 #endif | 823 #endif |
OLD | NEW |