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

Side by Side Diff: src/trusted/service_runtime/sel_ldr_standard.c

Issue 7276050: Change startup ABI for untrusted code to be C-compatible (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 9 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 | Annotate | Revision Log
« no previous file with comments | « src/trusted/service_runtime/nacl_config.h ('k') | src/untrusted/irt/elf_restart_arm.S » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2011 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 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 char const *const *envv) { 648 char const *const *envv) {
649 /* 649 /*
650 * Compute size of string tables for argv and envv 650 * Compute size of string tables for argv and envv
651 */ 651 */
652 int retval; 652 int retval;
653 int envc; 653 int envc;
654 size_t size; 654 size_t size;
655 int auxv_entries; 655 int auxv_entries;
656 size_t ptr_tbl_size; 656 size_t ptr_tbl_size;
657 int i; 657 int i;
658 char *p; 658 uint32_t *p;
659 char *strp; 659 char *strp;
660 size_t *argv_len; 660 size_t *argv_len;
661 size_t *envv_len; 661 size_t *envv_len;
662 struct NaClAppThread *natp; 662 struct NaClAppThread *natp;
663 uintptr_t stack_ptr; 663 uintptr_t stack_ptr;
664 664
665 retval = 0; /* fail */ 665 retval = 0; /* fail */
666 CHECK(argc > 0); 666 CHECK(argc > 0);
667 CHECK(NULL != argv); 667 CHECK(NULL != argv);
668 668
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 } 713 }
714 for (i = 0; i < envc; ++i) { 714 for (i = 0; i < envc; ++i) {
715 envv_len[i] = strlen(envv[i]) + 1; 715 envv_len[i] = strlen(envv[i]) + 1;
716 size += envv_len[i]; 716 size += envv_len[i];
717 } 717 }
718 718
719 /* 719 /*
720 * NaCl modules are ILP32, so the argv, envv pointers, as well as 720 * NaCl modules are ILP32, so the argv, envv pointers, as well as
721 * the terminating NULL pointers at the end of the argv/envv tables, 721 * the terminating NULL pointers at the end of the argv/envv tables,
722 * are 32-bit values. We also have the auxv to take into account. 722 * are 32-bit values. We also have the auxv to take into account.
723 * Note that on nacl64, argc is popped, and is an 8-byte value!
724 * 723 *
725 * The argv and envv pointer tables came from trusted code and is 724 * The argv and envv pointer tables came from trusted code and is
726 * part of memory. Thus, by the same argument above, adding in 725 * part of memory. Thus, by the same argument above, adding in
727 * "ptr_tbl_size" cannot possibly overflow the "size" variable since 726 * "ptr_tbl_size" cannot possibly overflow the "size" variable since
728 * it is a size_t object. However, the extra pointers for auxv and 727 * it is a size_t object. However, the extra pointers for auxv and
729 * the space for argv could cause an overflow. The fact that we 728 * the space for argv could cause an overflow. The fact that we
730 * used stack to get here etc means that ptr_tbl_size could not have 729 * used stack to get here etc means that ptr_tbl_size could not have
731 * overflowed. 730 * overflowed.
732 * 731 *
733 * NB: the underlying OS would have limited the amount of space used 732 * NB: the underlying OS would have limited the amount of space used
734 * for argv and envv -- on linux, it is ARG_MAX, or 128KB -- and 733 * for argv and envv -- on linux, it is ARG_MAX, or 128KB -- and
735 * hence the overflow check is for obvious auditability rather than 734 * hence the overflow check is for obvious auditability rather than
736 * for correctness. 735 * for correctness.
737 */ 736 */
738 auxv_entries = 1; 737 auxv_entries = 1;
739 if (0 != nap->user_entry_pt) { 738 if (0 != nap->user_entry_pt) {
740 auxv_entries++; 739 auxv_entries++;
741 } 740 }
742 ptr_tbl_size = (argc + envc + 2 + auxv_entries * 2) * sizeof(uint32_t) 741 ptr_tbl_size = (((NACL_STACK_GETS_ARG ? 1 : 0) +
743 + sizeof(nacl_reg_t); 742 (3 + argc + 1 + envc + 1 + auxv_entries * 2)) *
743 sizeof(uint32_t));
744 744
745 if (SIZE_T_MAX - size < ptr_tbl_size) { 745 if (SIZE_T_MAX - size < ptr_tbl_size) {
746 NaClLog(LOG_WARNING, 746 NaClLog(LOG_WARNING,
747 "NaClCreateMainThread: ptr_tbl_size cause size of" 747 "NaClCreateMainThread: ptr_tbl_size cause size of"
748 " argv / environment copy to overflow!?!\n"); 748 " argv / environment copy to overflow!?!\n");
749 retval = 0; 749 retval = 0;
750 goto cleanup; 750 goto cleanup;
751 } 751 }
752 size += ptr_tbl_size; 752 size += ptr_tbl_size;
753 753
754 size = (size + NACL_STACK_ALIGN_MASK) & ~NACL_STACK_ALIGN_MASK; 754 size = (size + NACL_STACK_ALIGN_MASK) & ~NACL_STACK_ALIGN_MASK;
755 755
756 if (size > nap->stack_size) { 756 if (size > nap->stack_size) {
757 retval = 0; 757 retval = 0;
758 goto cleanup; 758 goto cleanup;
759 } 759 }
760 760
761 /* write strings and char * arrays to stack */ 761 /* write strings and char * arrays to stack */
762 stack_ptr = (nap->mem_start + ((uintptr_t) 1U << nap->addr_bits) - size); 762 stack_ptr = (nap->mem_start + ((uintptr_t) 1U << nap->addr_bits) - size);
763 763
764 NaClLog(2, "setting stack to : %016"NACL_PRIxPTR"\n", stack_ptr); 764 NaClLog(2, "setting stack to : %016"NACL_PRIxPTR"\n", stack_ptr);
765 765
766 VCHECK(0 == (stack_ptr & NACL_STACK_ALIGN_MASK), 766 VCHECK(0 == (stack_ptr & NACL_STACK_ALIGN_MASK),
767 ("stack_ptr not aligned: %016"NACL_PRIxPTR"\n", stack_ptr)); 767 ("stack_ptr not aligned: %016"NACL_PRIxPTR"\n", stack_ptr));
768 768
769 p = (char *) stack_ptr; 769 p = (uint32_t *) stack_ptr;
770 strp = p + ptr_tbl_size; 770 strp = (char *) stack_ptr + ptr_tbl_size;
771 771
772 #define BLAT(t, v) do { \ 772 /*
773 *(t *) p = (t) v; p += sizeof(t); \ 773 * For x86-32, we push an initial argument that is the address of
774 } while (0); 774 * the main argument block. For other machines, this is passed
775 * in a register and that's set in NaClStartThreadInApp.
776 */
777 if (NACL_STACK_GETS_ARG) {
778 uint32_t *argloc = p++;
779 *argloc = NaClSysToUser(nap, (uintptr_t) p);
780 }
775 781
776 BLAT(nacl_reg_t, argc); 782 *p++ = 0; /* Cleanup function pointer, always NULL. */
783 *p++ = envc;
784 *p++ = argc;
777 785
778 for (i = 0; i < argc; ++i) { 786 for (i = 0; i < argc; ++i) {
779 BLAT(uint32_t, NaClSysToUser(nap, (uintptr_t) strp)); 787 *p++ = NaClSysToUser(nap, (uintptr_t) strp);
780 NaClLog(2, "copying arg %d %p -> %p\n", 788 NaClLog(2, "copying arg %d %p -> %p\n",
781 i, argv[i], strp); 789 i, argv[i], strp);
782 strcpy(strp, argv[i]); 790 strcpy(strp, argv[i]);
783 strp += argv_len[i]; 791 strp += argv_len[i];
784 } 792 }
785 BLAT(uint32_t, 0); 793 *p++ = 0; /* argv[argc] is NULL. */
786 794
787 for (i = 0; i < envc; ++i) { 795 for (i = 0; i < envc; ++i) {
788 BLAT(uint32_t, NaClSysToUser(nap, (uintptr_t) strp)); 796 *p++ = NaClSysToUser(nap, (uintptr_t) strp);
789 NaClLog(2, "copying env %d %p -> %p\n", 797 NaClLog(2, "copying env %d %p -> %p\n",
790 i, envv[i], strp); 798 i, envv[i], strp);
791 strcpy(strp, envv[i]); 799 strcpy(strp, envv[i]);
792 strp += envv_len[i]; 800 strp += envv_len[i];
793 } 801 }
794 BLAT(uint32_t, 0); 802 *p++ = 0; /* envp[envc] is NULL. */
803
795 /* Push an auxv */ 804 /* Push an auxv */
796 if (0 != nap->user_entry_pt) { 805 if (0 != nap->user_entry_pt) {
797 BLAT(uint32_t, AT_ENTRY); 806 *p++ = AT_ENTRY;
798 BLAT(uint32_t, nap->user_entry_pt); 807 *p++ = nap->user_entry_pt;
799 } 808 }
800 BLAT(uint32_t, AT_NULL); 809 *p++ = AT_NULL;
801 BLAT(uint32_t, 0); 810 *p++ = 0;
802 #undef BLAT 811
803 CHECK(p == (char *) stack_ptr + ptr_tbl_size); 812 CHECK((char *) p == (char *) stack_ptr + ptr_tbl_size);
804 813
805 /* now actually spawn the thread */ 814 /* now actually spawn the thread */
806 natp = malloc(sizeof *natp); 815 natp = malloc(sizeof *natp);
807 if (!natp) { 816 if (!natp) {
808 goto cleanup; 817 goto cleanup;
809 } 818 }
810 819
811 /* We are ready to distinguish crashes in trusted and untrusted code. */ 820 /* We are ready to distinguish crashes in trusted and untrusted code. */
812 NaClSignalRegisterApp(nap); 821 NaClSignalRegisterApp(nap);
813 822
814 /* NaClApp initialization is completed, call OOP debugger hook. */ 823 /* NaClApp initialization is completed, call OOP debugger hook. */
815 NaClOopDebuggerAppCreateHook(nap); 824 NaClOopDebuggerAppCreateHook(nap);
816 825
817 NaClXMutexLock(&nap->mu); 826 NaClXMutexLock(&nap->mu);
818 nap->running = 1; 827 nap->running = 1;
819 NaClXMutexUnlock(&nap->mu); 828 NaClXMutexUnlock(&nap->mu);
820 829
821 NaClVmHoleWaitToStartThread(nap); 830 NaClVmHoleWaitToStartThread(nap);
822 831
832 /*
833 * For x86, we adjust the stack pointer down to push a dummy return
834 * address. This happens after the stack pointer alignment.
835 */
836 if (NACL_STACK_PAD_BELOW_ALIGN != 0) {
bsy 2011/06/29 18:23:07 if NACL_STACK_PAD_BELOW_ALIGN is zero, i bet the c
837 stack_ptr -= NACL_STACK_PAD_BELOW_ALIGN;
838 memset((void *) stack_ptr, 0, NACL_STACK_PAD_BELOW_ALIGN);
839 }
840
823 NaClLog(2, "system stack ptr : %016"NACL_PRIxPTR"\n", stack_ptr); 841 NaClLog(2, "system stack ptr : %016"NACL_PRIxPTR"\n", stack_ptr);
824 NaClLog(2, " user stack ptr : %016"NACL_PRIxPTR"\n", 842 NaClLog(2, " user stack ptr : %016"NACL_PRIxPTR"\n",
825 NaClSysToUserStackAddr(nap, stack_ptr)); 843 NaClSysToUserStackAddr(nap, stack_ptr));
826 844
827 /* e_entry is user addr */ 845 /* e_entry is user addr */
828 if (!NaClAppThreadAllocSegCtor(natp, 846 if (!NaClAppThreadAllocSegCtor(natp,
829 nap, 847 nap,
830 nap->initial_entry_pt, 848 nap->initial_entry_pt,
831 NaClSysToUserStackAddr(nap, stack_ptr), 849 NaClSysToUserStackAddr(nap, stack_ptr),
832 NaClUserToSys(nap, nap->break_addr))) { 850 NaClUserToSys(nap, nap->break_addr))) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 stack_ptr, 928 stack_ptr,
911 sys_tls)) { 929 sys_tls)) {
912 NaClLog(LOG_WARNING, 930 NaClLog(LOG_WARNING,
913 ("NaClCreateAdditionalThread: could not allocate thread index." 931 ("NaClCreateAdditionalThread: could not allocate thread index."
914 " Returning EAGAIN per POSIX specs.\n")); 932 " Returning EAGAIN per POSIX specs.\n"));
915 free(natp); 933 free(natp);
916 return -NACL_ABI_EAGAIN; 934 return -NACL_ABI_EAGAIN;
917 } 935 }
918 return 0; 936 return 0;
919 } 937 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/nacl_config.h ('k') | src/untrusted/irt/elf_restart_arm.S » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698