| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * be found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "native_client/src/include/concurrency_ops.h" | 9 #include "native_client/src/include/concurrency_ops.h" |
| 10 #include "native_client/src/include/portability.h" | 10 #include "native_client/src/include/portability.h" |
| 11 #include "native_client/src/shared/platform/nacl_check.h" | 11 #include "native_client/src/shared/platform/nacl_check.h" |
| 12 #include "native_client/src/shared/platform/nacl_log.h" | 12 #include "native_client/src/shared/platform/nacl_log.h" |
| 13 #include "native_client/src/shared/platform/nacl_sync.h" |
| 14 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 13 #include "native_client/src/trusted/desc/nacl_desc_base.h" | 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" |
| 14 #include "native_client/src/trusted/desc/nacl_desc_effector.h" | 16 #include "native_client/src/trusted/desc/nacl_desc_effector.h" |
| 15 #include "native_client/src/trusted/desc/nacl_desc_effector.h" | 17 #include "native_client/src/trusted/desc/nacl_desc_effector.h" |
| 16 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h" | 18 #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h" |
| 17 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" | 19 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" |
| 18 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" | 20 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" |
| 19 #include "native_client/src/trusted/service_runtime/include/sys/mman.h" | 21 #include "native_client/src/trusted/service_runtime/include/sys/mman.h" |
| 20 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" | 22 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" |
| 21 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | 23 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" |
| 22 #include "native_client/src/trusted/service_runtime/nacl_text.h" | 24 #include "native_client/src/trusted/service_runtime/nacl_text.h" |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 } | 379 } |
| 378 } | 380 } |
| 379 | 381 |
| 380 | 382 |
| 381 void NaClSetThreadGeneration(struct NaClAppThread *natp, int generation) { | 383 void NaClSetThreadGeneration(struct NaClAppThread *natp, int generation) { |
| 382 /* | 384 /* |
| 383 * outer check handles fast case (no change) | 385 * outer check handles fast case (no change) |
| 384 * since threads only set their own generation it is safe | 386 * since threads only set their own generation it is safe |
| 385 */ | 387 */ |
| 386 if (natp->dynamic_delete_generation != generation) { | 388 if (natp->dynamic_delete_generation != generation) { |
| 387 NaClMutexLock(&natp->mu); | 389 NaClXMutexLock(&natp->mu); |
| 388 CHECK(natp->dynamic_delete_generation <= generation); | 390 CHECK(natp->dynamic_delete_generation <= generation); |
| 389 natp->dynamic_delete_generation = generation; | 391 natp->dynamic_delete_generation = generation; |
| 390 NaClMutexUnlock(&natp->mu); | 392 NaClXMutexUnlock(&natp->mu); |
| 391 } | 393 } |
| 392 } | 394 } |
| 393 | 395 |
| 394 int NaClMinimumThreadGeneration(struct NaClApp *nap) { | 396 int NaClMinimumThreadGeneration(struct NaClApp *nap) { |
| 395 int i, rv = 0; | 397 int i, rv = 0; |
| 396 NaClMutexLock(&nap->threads_mu); | 398 NaClXMutexLock(&nap->threads_mu); |
| 397 for (i = 0; i < nap->num_threads; ++i) { | 399 for (i = 0; i < nap->num_threads; ++i) { |
| 398 struct NaClAppThread *thread = NaClGetThreadMu(nap, i); | 400 struct NaClAppThread *thread = NaClGetThreadMu(nap, i); |
| 399 NaClMutexLock(&thread->mu); | 401 NaClXMutexLock(&thread->mu); |
| 400 if (i == 0 || rv > thread->dynamic_delete_generation) { | 402 if (i == 0 || rv > thread->dynamic_delete_generation) { |
| 401 rv = thread->dynamic_delete_generation; | 403 rv = thread->dynamic_delete_generation; |
| 402 } | 404 } |
| 403 NaClMutexUnlock(&thread->mu); | 405 NaClXMutexUnlock(&thread->mu); |
| 404 } | 406 } |
| 405 NaClMutexUnlock(&nap->threads_mu); | 407 NaClXMutexUnlock(&nap->threads_mu); |
| 406 return rv; | 408 return rv; |
| 407 } | 409 } |
| 408 | 410 |
| 409 static void CopyBundleTails(uint8_t *dest, | 411 static void CopyBundleTails(uint8_t *dest, |
| 410 uint8_t *src, | 412 uint8_t *src, |
| 411 int32_t size, | 413 int32_t size, |
| 412 int bundle_size) { | 414 int bundle_size) { |
| 413 /* | 415 /* |
| 414 * The order in which these locations are written does not matter: | 416 * The order in which these locations are written does not matter: |
| 415 * none of the locations will be reachable, because the bundle heads | 417 * none of the locations will be reachable, because the bundle heads |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 */ | 672 */ |
| 671 if (dest + size > nap->dynamic_text_end - NACL_HALT_SLED_SIZE) { | 673 if (dest + size > nap->dynamic_text_end - NACL_HALT_SLED_SIZE) { |
| 672 NaClLog(1, "NaClTextSysDyncode_Copy: Above dynamic code area\n"); | 674 NaClLog(1, "NaClTextSysDyncode_Copy: Above dynamic code area\n"); |
| 673 return -NACL_ABI_EFAULT; | 675 return -NACL_ABI_EFAULT; |
| 674 } | 676 } |
| 675 if (0 == size) { | 677 if (0 == size) { |
| 676 /* Nothing to load. Succeed trivially. */ | 678 /* Nothing to load. Succeed trivially. */ |
| 677 return 0; | 679 return 0; |
| 678 } | 680 } |
| 679 | 681 |
| 680 NaClMutexLock(&nap->dynamic_load_mutex); | 682 NaClXMutexLock(&nap->dynamic_load_mutex); |
| 681 | 683 |
| 682 if (NaClDynamicRegionCreate(nap, dest_addr, size) == 1) { | 684 if (NaClDynamicRegionCreate(nap, dest_addr, size) == 1) { |
| 683 /* target memory region is free */ | 685 /* target memory region is free */ |
| 684 validator_result = NaClValidateCode(nap, dest, code_copy, size); | 686 validator_result = NaClValidateCode(nap, dest, code_copy, size); |
| 685 } else { | 687 } else { |
| 686 /* target addr is in use */ | 688 /* target addr is in use */ |
| 687 NaClLog(1, "NaClTextSysDyncode_Copy: Code range already allocated\n"); | 689 NaClLog(1, "NaClTextSysDyncode_Copy: Code range already allocated\n"); |
| 688 retval = -NACL_ABI_EINVAL; | 690 retval = -NACL_ABI_EINVAL; |
| 689 goto cleanup_unlock; | 691 goto cleanup_unlock; |
| 690 } | 692 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 707 retval = -NACL_ABI_ENOMEM; | 709 retval = -NACL_ABI_ENOMEM; |
| 708 goto cleanup_unlock; | 710 goto cleanup_unlock; |
| 709 } | 711 } |
| 710 | 712 |
| 711 CopyCodeSafelyInitial(mapped_addr, code_copy, size, nap->bundle_size); | 713 CopyCodeSafelyInitial(mapped_addr, code_copy, size, nap->bundle_size); |
| 712 retval = 0; | 714 retval = 0; |
| 713 | 715 |
| 714 NaclTextMapClearCacheIfNeeded(nap, dest, size); | 716 NaclTextMapClearCacheIfNeeded(nap, dest, size); |
| 715 | 717 |
| 716 cleanup_unlock: | 718 cleanup_unlock: |
| 717 NaClMutexUnlock(&nap->dynamic_load_mutex); | 719 NaClXMutexUnlock(&nap->dynamic_load_mutex); |
| 718 | 720 |
| 719 return retval; | 721 return retval; |
| 720 } | 722 } |
| 721 | 723 |
| 722 int32_t NaClTextSysDyncode_Create(struct NaClAppThread *natp, | 724 int32_t NaClTextSysDyncode_Create(struct NaClAppThread *natp, |
| 723 uint32_t dest, | 725 uint32_t dest, |
| 724 uint32_t src, | 726 uint32_t src, |
| 725 uint32_t size) { | 727 uint32_t size) { |
| 726 struct NaClApp *nap = natp->nap; | 728 struct NaClApp *nap = natp->nap; |
| 727 uintptr_t src_addr; | 729 uintptr_t src_addr; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 return 0; | 779 return 0; |
| 778 } | 780 } |
| 779 | 781 |
| 780 dest_addr = NaClUserToSysAddrRange(nap, dest, size); | 782 dest_addr = NaClUserToSysAddrRange(nap, dest, size); |
| 781 src_addr = NaClUserToSysAddrRange(nap, src, size); | 783 src_addr = NaClUserToSysAddrRange(nap, src, size); |
| 782 if (kNaClBadAddress == src_addr || kNaClBadAddress == dest_addr) { | 784 if (kNaClBadAddress == src_addr || kNaClBadAddress == dest_addr) { |
| 783 NaClLog(1, "NaClTextSysDyncode_Modify: Address out of range\n"); | 785 NaClLog(1, "NaClTextSysDyncode_Modify: Address out of range\n"); |
| 784 return -NACL_ABI_EFAULT; | 786 return -NACL_ABI_EFAULT; |
| 785 } | 787 } |
| 786 | 788 |
| 787 NaClMutexLock(&nap->dynamic_load_mutex); | 789 NaClXMutexLock(&nap->dynamic_load_mutex); |
| 788 | 790 |
| 789 region = NaClDynamicRegionFind(nap, dest_addr, size); | 791 region = NaClDynamicRegionFind(nap, dest_addr, size); |
| 790 if (NULL == region || region->start > dest_addr | 792 if (NULL == region || region->start > dest_addr |
| 791 || region->start + region->size < dest_addr + size) { | 793 || region->start + region->size < dest_addr + size) { |
| 792 /* target not a subregion of region or region is null */ | 794 /* target not a subregion of region or region is null */ |
| 793 NaClLog(1, "NaClTextSysDyncode_Modify: Can't find region to modify\n"); | 795 NaClLog(1, "NaClTextSysDyncode_Modify: Can't find region to modify\n"); |
| 794 retval = -NACL_ABI_EFAULT; | 796 retval = -NACL_ABI_EFAULT; |
| 795 goto cleanup_unlock; | 797 goto cleanup_unlock; |
| 796 } | 798 } |
| 797 | 799 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 NaClLog(1, "NaClTextSysDyncode_Modify " | 859 NaClLog(1, "NaClTextSysDyncode_Modify " |
| 858 "Copying of replacement code failed\n"); | 860 "Copying of replacement code failed\n"); |
| 859 retval = -NACL_ABI_EINVAL; | 861 retval = -NACL_ABI_EINVAL; |
| 860 goto cleanup_unlock; | 862 goto cleanup_unlock; |
| 861 } | 863 } |
| 862 retval = 0; | 864 retval = 0; |
| 863 | 865 |
| 864 NaclTextMapClearCacheIfNeeded(nap, dest, size); | 866 NaclTextMapClearCacheIfNeeded(nap, dest, size); |
| 865 | 867 |
| 866 cleanup_unlock: | 868 cleanup_unlock: |
| 867 NaClMutexUnlock(&nap->dynamic_load_mutex); | 869 NaClXMutexUnlock(&nap->dynamic_load_mutex); |
| 868 | 870 |
| 869 if (code_copy != code_copy_buf) { | 871 if (code_copy != code_copy_buf) { |
| 870 free(code_copy); | 872 free(code_copy); |
| 871 } | 873 } |
| 872 | 874 |
| 873 return retval; | 875 return retval; |
| 874 } | 876 } |
| 875 | 877 |
| 876 int32_t NaClTextSysDyncode_Delete(struct NaClAppThread *natp, | 878 int32_t NaClTextSysDyncode_Delete(struct NaClAppThread *natp, |
| 877 uint32_t dest, | 879 uint32_t dest, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 890 dest_addr = NaClUserToSysAddrRange(nap, dest, size); | 892 dest_addr = NaClUserToSysAddrRange(nap, dest, size); |
| 891 if (kNaClBadAddress == dest_addr) { | 893 if (kNaClBadAddress == dest_addr) { |
| 892 NaClLog(1, "NaClTextSysDyncode_Delete: Address out of range\n"); | 894 NaClLog(1, "NaClTextSysDyncode_Delete: Address out of range\n"); |
| 893 return -NACL_ABI_EFAULT; | 895 return -NACL_ABI_EFAULT; |
| 894 } | 896 } |
| 895 | 897 |
| 896 if (0 == size) { | 898 if (0 == size) { |
| 897 /* Nothing to delete. Just update our generation. */ | 899 /* Nothing to delete. Just update our generation. */ |
| 898 int gen; | 900 int gen; |
| 899 /* fetch current generation */ | 901 /* fetch current generation */ |
| 900 NaClMutexLock(&nap->dynamic_load_mutex); | 902 NaClXMutexLock(&nap->dynamic_load_mutex); |
| 901 gen = nap->dynamic_delete_generation; | 903 gen = nap->dynamic_delete_generation; |
| 902 NaClMutexUnlock(&nap->dynamic_load_mutex); | 904 NaClXMutexUnlock(&nap->dynamic_load_mutex); |
| 903 /* set our generation */ | 905 /* set our generation */ |
| 904 NaClSetThreadGeneration(natp, gen); | 906 NaClSetThreadGeneration(natp, gen); |
| 905 return 0; | 907 return 0; |
| 906 } | 908 } |
| 907 | 909 |
| 908 NaClMutexLock(&nap->dynamic_load_mutex); | 910 NaClXMutexLock(&nap->dynamic_load_mutex); |
| 909 | 911 |
| 910 /* | 912 /* |
| 911 * this check ensures the to-be-deleted region is identical to a | 913 * this check ensures the to-be-deleted region is identical to a |
| 912 * previously inserted region, so no need to check for alignment/bounds/etc | 914 * previously inserted region, so no need to check for alignment/bounds/etc |
| 913 */ | 915 */ |
| 914 region = NaClDynamicRegionFind(nap, dest_addr, size); | 916 region = NaClDynamicRegionFind(nap, dest_addr, size); |
| 915 if (NULL == region || region->start != dest_addr || region->size != size) { | 917 if (NULL == region || region->start != dest_addr || region->size != size) { |
| 916 NaClLog(1, "NaClTextSysDyncode_Delete: Can't find region to delete\n"); | 918 NaClLog(1, "NaClTextSysDyncode_Delete: Can't find region to delete\n"); |
| 917 retval = -NACL_ABI_EFAULT; | 919 retval = -NACL_ABI_EFAULT; |
| 918 goto cleanup_unlock; | 920 goto cleanup_unlock; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 NaClDynamicRegionDelete(nap, region); | 959 NaClDynamicRegionDelete(nap, region); |
| 958 retval = 0; | 960 retval = 0; |
| 959 } else { | 961 } else { |
| 960 /* | 962 /* |
| 961 * Still waiting for some threads to report in... | 963 * Still waiting for some threads to report in... |
| 962 */ | 964 */ |
| 963 retval = -NACL_ABI_EAGAIN; | 965 retval = -NACL_ABI_EAGAIN; |
| 964 } | 966 } |
| 965 | 967 |
| 966 cleanup_unlock: | 968 cleanup_unlock: |
| 967 NaClMutexUnlock(&nap->dynamic_load_mutex); | 969 NaClXMutexUnlock(&nap->dynamic_load_mutex); |
| 968 return retval; | 970 return retval; |
| 969 } | 971 } |
| OLD | NEW |