Chromium Code Reviews| 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> |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |