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 |