| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 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 * NaCl Simple/secure ELF loader (NaCl SEL). | 8 * NaCl Simple/secure ELF loader (NaCl SEL). |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 } | 660 } |
| 661 nap->exit_status = exit_status; | 661 nap->exit_status = exit_status; |
| 662 nap->running = 0; | 662 nap->running = 0; |
| 663 NaClXCondVarSignal(&nap->cv); | 663 NaClXCondVarSignal(&nap->cv); |
| 664 | 664 |
| 665 NaClXMutexUnlock(&nap->mu); | 665 NaClXMutexUnlock(&nap->mu); |
| 666 | 666 |
| 667 return rv; | 667 return rv; |
| 668 } | 668 } |
| 669 | 669 |
| 670 uintptr_t NaClGetInitialStackTop(struct NaClApp *nap) { |
| 671 /* |
| 672 * We keep the top of useful memory a page below the top of the |
| 673 * sandbox region so that compilers can do tricks like computing a |
| 674 * base register of sp + constant and then using a |
| 675 * register-minus-constant addressing mode, which comes up at least |
| 676 * on ARM where the compiler is trying to optimize given the limited |
| 677 * size of immediate offsets available. The maximum such negative |
| 678 * constant on ARM will be -4095, but we use page size (64k) for |
| 679 * good measure and do it on all machines just for uniformity. |
| 680 */ |
| 681 return ((uintptr_t) 1U << nap->addr_bits) - NACL_MAP_PAGESIZE; |
| 682 } |
| 683 |
| 670 /* | 684 /* |
| 671 * preconditions: | 685 * preconditions: |
| 672 * * argc is the length of the argv array | 686 * * argc is the length of the argv array |
| 673 * * envv may be NULL (this happens on MacOS/Cocoa and in tests) | 687 * * envv may be NULL (this happens on MacOS/Cocoa and in tests) |
| 674 * * if envv is non-NULL it is 'consistent', null terminated etc. | 688 * * if envv is non-NULL it is 'consistent', null terminated etc. |
| 675 */ | 689 */ |
| 676 int NaClCreateMainThread(struct NaClApp *nap, | 690 int NaClCreateMainThread(struct NaClApp *nap, |
| 677 int argc, | 691 int argc, |
| 678 char **argv, | 692 char **argv, |
| 679 char const *const *envv) { | 693 char const *const *envv) { |
| 680 /* | 694 /* |
| 681 * Compute size of string tables for argv and envv | 695 * Compute size of string tables for argv and envv |
| 682 */ | 696 */ |
| 683 int retval; | 697 int retval; |
| 684 int envc; | 698 int envc; |
| 685 size_t size; | 699 size_t size; |
| 686 int auxv_entries; | 700 int auxv_entries; |
| 687 size_t ptr_tbl_size; | 701 size_t ptr_tbl_size; |
| 688 int i; | 702 int i; |
| 689 uint32_t *p; | 703 uint32_t *p; |
| 690 char *strp; | 704 char *strp; |
| 691 size_t *argv_len; | 705 size_t *argv_len; |
| 692 size_t *envv_len; | 706 size_t *envv_len; |
| 693 struct NaClAppThread *natp; | |
| 694 uintptr_t stack_ptr; | 707 uintptr_t stack_ptr; |
| 695 | 708 |
| 696 retval = 0; /* fail */ | 709 retval = 0; /* fail */ |
| 697 CHECK(argc >= 0); | 710 CHECK(argc >= 0); |
| 698 CHECK(NULL != argv || 0 == argc); | 711 CHECK(NULL != argv || 0 == argc); |
| 699 | 712 |
| 700 envc = 0; | 713 envc = 0; |
| 701 if (NULL != envv) { | 714 if (NULL != envv) { |
| 702 char const *const *pp; | 715 char const *const *pp; |
| 703 for (pp = envv; NULL != *pp; ++pp) { | 716 for (pp = envv; NULL != *pp; ++pp) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 size += ptr_tbl_size; | 785 size += ptr_tbl_size; |
| 773 | 786 |
| 774 size = (size + NACL_STACK_ALIGN_MASK) & ~NACL_STACK_ALIGN_MASK; | 787 size = (size + NACL_STACK_ALIGN_MASK) & ~NACL_STACK_ALIGN_MASK; |
| 775 | 788 |
| 776 if (size > nap->stack_size) { | 789 if (size > nap->stack_size) { |
| 777 retval = 0; | 790 retval = 0; |
| 778 goto cleanup; | 791 goto cleanup; |
| 779 } | 792 } |
| 780 | 793 |
| 781 /* | 794 /* |
| 782 * Write strings and char * arrays to stack. We keep the top of useful | 795 * Write strings and char * arrays to stack. |
| 783 * memory a page below the top of the sandbox region so that compilers | |
| 784 * can do tricks like computing a base register of sp + constant and then | |
| 785 * using a register-minus-constant addressing mode, which comes up at | |
| 786 * least on ARM where the compiler is trying to optimize given the | |
| 787 * limited size of immediate offsets available. The maximum such | |
| 788 * negative constant on ARM will be -4095, but we use page size (64k) | |
| 789 * for good measure and do it on all machines just for uniformity. | |
| 790 */ | 796 */ |
| 791 stack_ptr = (nap->mem_start + | 797 stack_ptr = NaClUserToSysAddrRange(nap, NaClGetInitialStackTop(nap) - size, |
| 792 ((uintptr_t) 1U << nap->addr_bits) - NACL_MAP_PAGESIZE - | 798 size); |
| 793 size); | 799 if (stack_ptr == kNaClBadAddress) { |
| 800 retval = 0; |
| 801 goto cleanup; |
| 802 } |
| 794 | 803 |
| 795 NaClLog(2, "setting stack to : %016"NACL_PRIxPTR"\n", stack_ptr); | 804 NaClLog(2, "setting stack to : %016"NACL_PRIxPTR"\n", stack_ptr); |
| 796 | 805 |
| 797 VCHECK(0 == (stack_ptr & NACL_STACK_ALIGN_MASK), | 806 VCHECK(0 == (stack_ptr & NACL_STACK_ALIGN_MASK), |
| 798 ("stack_ptr not aligned: %016"NACL_PRIxPTR"\n", stack_ptr)); | 807 ("stack_ptr not aligned: %016"NACL_PRIxPTR"\n", stack_ptr)); |
| 799 | 808 |
| 800 p = (uint32_t *) stack_ptr; | 809 p = (uint32_t *) stack_ptr; |
| 801 strp = (char *) stack_ptr + ptr_tbl_size; | 810 strp = (char *) stack_ptr + ptr_tbl_size; |
| 802 | 811 |
| 803 /* | 812 /* |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 if (NACL_STACK_PAD_BELOW_ALIGN != 0) { | 867 if (NACL_STACK_PAD_BELOW_ALIGN != 0) { |
| 859 stack_ptr -= NACL_STACK_PAD_BELOW_ALIGN; | 868 stack_ptr -= NACL_STACK_PAD_BELOW_ALIGN; |
| 860 memset((void *) stack_ptr, 0, NACL_STACK_PAD_BELOW_ALIGN); | 869 memset((void *) stack_ptr, 0, NACL_STACK_PAD_BELOW_ALIGN); |
| 861 } | 870 } |
| 862 | 871 |
| 863 NaClLog(2, "system stack ptr : %016"NACL_PRIxPTR"\n", stack_ptr); | 872 NaClLog(2, "system stack ptr : %016"NACL_PRIxPTR"\n", stack_ptr); |
| 864 NaClLog(2, " user stack ptr : %016"NACL_PRIxPTR"\n", | 873 NaClLog(2, " user stack ptr : %016"NACL_PRIxPTR"\n", |
| 865 NaClSysToUserStackAddr(nap, stack_ptr)); | 874 NaClSysToUserStackAddr(nap, stack_ptr)); |
| 866 | 875 |
| 867 /* e_entry is user addr */ | 876 /* e_entry is user addr */ |
| 868 natp = NaClAppThreadMake(nap, | 877 retval = NaClAppThreadSpawn(nap, |
| 869 nap->initial_entry_pt, | 878 nap->initial_entry_pt, |
| 870 NaClSysToUserStackAddr(nap, stack_ptr), | 879 NaClSysToUserStackAddr(nap, stack_ptr), |
| 871 /* user_tls1= */ (uint32_t) nap->break_addr, | 880 /* user_tls1= */ (uint32_t) nap->break_addr, |
| 872 /* user_tls2= */ 0); | 881 /* user_tls2= */ 0); |
| 873 if (natp == NULL) { | |
| 874 retval = 0; | |
| 875 goto cleanup; | |
| 876 } | |
| 877 | 882 |
| 878 retval = 1; | |
| 879 cleanup: | 883 cleanup: |
| 880 free(argv_len); | 884 free(argv_len); |
| 881 free(envv_len); | 885 free(envv_len); |
| 882 | 886 |
| 883 return retval; | 887 return retval; |
| 884 } | 888 } |
| 885 | 889 |
| 886 int NaClWaitForMainThreadToExit(struct NaClApp *nap) { | 890 int NaClWaitForMainThreadToExit(struct NaClApp *nap) { |
| 887 NaClLog(3, "NaClWaitForMainThreadToExit: taking NaClApp lock\n"); | 891 NaClLog(3, "NaClWaitForMainThreadToExit: taking NaClApp lock\n"); |
| 888 NaClXMutexLock(&nap->mu); | 892 NaClXMutexLock(&nap->mu); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 905 } | 909 } |
| 906 | 910 |
| 907 /* | 911 /* |
| 908 * stack_ptr is from syscall, so a 32-bit address. | 912 * stack_ptr is from syscall, so a 32-bit address. |
| 909 */ | 913 */ |
| 910 int32_t NaClCreateAdditionalThread(struct NaClApp *nap, | 914 int32_t NaClCreateAdditionalThread(struct NaClApp *nap, |
| 911 uintptr_t prog_ctr, | 915 uintptr_t prog_ctr, |
| 912 uintptr_t sys_stack_ptr, | 916 uintptr_t sys_stack_ptr, |
| 913 uint32_t user_tls1, | 917 uint32_t user_tls1, |
| 914 uint32_t user_tls2) { | 918 uint32_t user_tls2) { |
| 915 struct NaClAppThread *natp; | 919 if (!NaClAppThreadSpawn(nap, |
| 916 | 920 prog_ctr, |
| 917 natp = NaClAppThreadMake(nap, | 921 NaClSysToUserStackAddr(nap, sys_stack_ptr), |
| 918 prog_ctr, | 922 user_tls1, |
| 919 NaClSysToUserStackAddr(nap, sys_stack_ptr), | 923 user_tls2)) { |
| 920 user_tls1, | |
| 921 user_tls2); | |
| 922 if (natp == NULL) { | |
| 923 NaClLog(LOG_WARNING, | 924 NaClLog(LOG_WARNING, |
| 924 ("NaClCreateAdditionalThread: could not allocate thread." | 925 ("NaClCreateAdditionalThread: could not allocate thread." |
| 925 " Returning EAGAIN per POSIX specs.\n")); | 926 " Returning EAGAIN per POSIX specs.\n")); |
| 926 return -NACL_ABI_EAGAIN; | 927 return -NACL_ABI_EAGAIN; |
| 927 } | 928 } |
| 928 return 0; | 929 return 0; |
| 929 } | 930 } |
| OLD | NEW |