| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This is the Android-specific Chromium linker, a tiny shared library | 5 // This is the Android-specific Chromium linker, a tiny shared library |
| 6 // implementing a custom dynamic linker that can be used to load the | 6 // implementing a custom dynamic linker that can be used to load the |
| 7 // real Chromium libraries (e.g. libcontentshell.so). | 7 // real Chromium libraries (e.g. libcontentshell.so). |
| 8 | 8 |
| 9 // The main point of this linker is to be able to share the RELRO | 9 // The main point of this linker is to be able to share the RELRO |
| 10 // section of libcontentshell.so (or equivalent) between the browser and | 10 // section of libcontentshell.so (or equivalent) between the browser and |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 jlong load_address, | 440 jlong load_address, |
| 441 jobject lib_info_obj) { | 441 jobject lib_info_obj) { |
| 442 String zipfile_name_str(env, zipfile_name); | 442 String zipfile_name_str(env, zipfile_name); |
| 443 String lib_name(env, library_name); | 443 String lib_name(env, library_name); |
| 444 ZipLibraryOpener opener(zipfile_name_str.c_str()); | 444 ZipLibraryOpener opener(zipfile_name_str.c_str()); |
| 445 return GenericLoadLibrary( | 445 return GenericLoadLibrary( |
| 446 env, lib_name.c_str(), | 446 env, lib_name.c_str(), |
| 447 static_cast<size_t>(load_address), lib_info_obj, opener); | 447 static_cast<size_t>(load_address), lib_info_obj, opener); |
| 448 } | 448 } |
| 449 | 449 |
| 450 // Enable the fallback due to lack of support for mapping the APK file with | |
| 451 // executable permission in the crazy linker. | |
| 452 // | |
| 453 // |env| is the current JNI environment handle and is ignored here. | |
| 454 // |clazz| is the static class handle for org.chromium.base.Linker, | |
| 455 // and is ignored here. | |
| 456 void EnableNoMapExecSupportFallback(JNIEnv* env, jclass clazz) { | |
| 457 crazy_context_t* context = GetCrazyContext(); | |
| 458 crazy_context_set_no_map_exec_support_fallback_enabled(context, true); | |
| 459 } | |
| 460 | |
| 461 // Class holding the Java class and method ID for the Java side Linker | 450 // Class holding the Java class and method ID for the Java side Linker |
| 462 // postCallbackOnMainThread method. | 451 // postCallbackOnMainThread method. |
| 463 struct JavaCallbackBindings_class { | 452 struct JavaCallbackBindings_class { |
| 464 jclass clazz; | 453 jclass clazz; |
| 465 jmethodID method_id; | 454 jmethodID method_id; |
| 466 | 455 |
| 467 // Initialize an instance. | 456 // Initialize an instance. |
| 468 bool Init(JNIEnv* env, jclass linker_class) { | 457 bool Init(JNIEnv* env, jclass linker_class) { |
| 469 clazz = reinterpret_cast<jclass>(env->NewGlobalRef(linker_class)); | 458 clazz = reinterpret_cast<jclass>(env->NewGlobalRef(linker_class)); |
| 470 return InitStaticMethodId(env, | 459 return InitStaticMethodId(env, |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 char buffer[kMaxFilePathLengthInZip + 1]; | 652 char buffer[kMaxFilePathLengthInZip + 1]; |
| 664 if (crazy_library_file_path_in_zip_file( | 653 if (crazy_library_file_path_in_zip_file( |
| 665 lib_name_c_str, buffer, sizeof(buffer)) == CRAZY_STATUS_FAILURE) { | 654 lib_name_c_str, buffer, sizeof(buffer)) == CRAZY_STATUS_FAILURE) { |
| 666 LOG_ERROR("%s: Failed to get full filename for library '%s'", | 655 LOG_ERROR("%s: Failed to get full filename for library '%s'", |
| 667 __FUNCTION__, lib_name_c_str); | 656 __FUNCTION__, lib_name_c_str); |
| 668 buffer[0] = '\0'; | 657 buffer[0] = '\0'; |
| 669 } | 658 } |
| 670 return env->NewStringUTF(buffer); | 659 return env->NewStringUTF(buffer); |
| 671 } | 660 } |
| 672 | 661 |
| 673 // Check whether the device supports mapping the APK file with executable | |
| 674 // permission. | |
| 675 // | |
| 676 // |env| is the current JNI environment handle. | |
| 677 // |clazz| is the static class handle which is not used here. | |
| 678 // |apkfile_name| is the filename of the APK. | |
| 679 // Returns true if supported. | |
| 680 jboolean CheckMapExecSupport(JNIEnv* env, jclass clazz, jstring apkfile_name) { | |
| 681 String apkfile_name_str(env, apkfile_name); | |
| 682 const char* apkfile_name_c_str = apkfile_name_str.c_str(); | |
| 683 | |
| 684 int fd = open(apkfile_name_c_str, O_RDONLY); | |
| 685 if (fd == -1) { | |
| 686 LOG_ERROR("%s: Failed to open %s\n", __FUNCTION__, apkfile_name_c_str); | |
| 687 return false; | |
| 688 } | |
| 689 | |
| 690 LOG_INFO( | |
| 691 "%s: Memory mapping the first page of %s with executable permissions\n", | |
| 692 __FUNCTION__, apkfile_name_c_str); | |
| 693 void* address = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, fd, 0); | |
| 694 | |
| 695 jboolean status; | |
| 696 if (address == MAP_FAILED) { | |
| 697 status = false; | |
| 698 } else { | |
| 699 status = true; | |
| 700 munmap(address, PAGE_SIZE); | |
| 701 } | |
| 702 | |
| 703 close(fd); | |
| 704 | |
| 705 LOG_INFO("%s: %s\n", __FUNCTION__, status ? "Supported" : "NOT supported"); | |
| 706 return status; | |
| 707 } | |
| 708 | |
| 709 // Check whether a library is page aligned and uncompressed in the APK file. | 662 // Check whether a library is page aligned and uncompressed in the APK file. |
| 710 // | 663 // |
| 711 // |env| is the current JNI environment handle. | 664 // |env| is the current JNI environment handle. |
| 712 // |clazz| is the static class handle which is not used here. | 665 // |clazz| is the static class handle which is not used here. |
| 713 // |apkfile_name| is the filename of the APK. | 666 // |apkfile_name| is the filename of the APK. |
| 714 // |library_name| is the library base name. | 667 // |library_name| is the library base name. |
| 715 // Returns true if page aligned and uncompressed. | 668 // Returns true if page aligned and uncompressed. |
| 716 jboolean CheckLibraryIsMappableInApk(JNIEnv* env, jclass clazz, | 669 jboolean CheckLibraryIsMappableInApk(JNIEnv* env, jclass clazz, |
| 717 jstring apkfile_name, | 670 jstring apkfile_name, |
| 718 jstring library_name) { | 671 jstring library_name) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 741 reinterpret_cast<void*>(&LoadLibrary)}, | 694 reinterpret_cast<void*>(&LoadLibrary)}, |
| 742 {"nativeLoadLibraryInZipFile", | 695 {"nativeLoadLibraryInZipFile", |
| 743 "(" | 696 "(" |
| 744 "Ljava/lang/String;" | 697 "Ljava/lang/String;" |
| 745 "Ljava/lang/String;" | 698 "Ljava/lang/String;" |
| 746 "J" | 699 "J" |
| 747 "Lorg/chromium/base/library_loader/Linker$LibInfo;" | 700 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
| 748 ")" | 701 ")" |
| 749 "Z", | 702 "Z", |
| 750 reinterpret_cast<void*>(&LoadLibraryInZipFile)}, | 703 reinterpret_cast<void*>(&LoadLibraryInZipFile)}, |
| 751 {"nativeEnableNoMapExecSupportFallback", | |
| 752 "(" | |
| 753 ")" | |
| 754 "V", | |
| 755 reinterpret_cast<void*>(&EnableNoMapExecSupportFallback)}, | |
| 756 {"nativeRunCallbackOnUiThread", | 704 {"nativeRunCallbackOnUiThread", |
| 757 "(" | 705 "(" |
| 758 "J" | 706 "J" |
| 759 ")" | 707 ")" |
| 760 "V", | 708 "V", |
| 761 reinterpret_cast<void*>(&RunCallbackOnUiThread)}, | 709 reinterpret_cast<void*>(&RunCallbackOnUiThread)}, |
| 762 {"nativeCreateSharedRelro", | 710 {"nativeCreateSharedRelro", |
| 763 "(" | 711 "(" |
| 764 "Ljava/lang/String;" | 712 "Ljava/lang/String;" |
| 765 "J" | 713 "J" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 784 "J" | 732 "J" |
| 785 ")" | 733 ")" |
| 786 "J", | 734 "J", |
| 787 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, | 735 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, |
| 788 {"nativeGetLibraryFilePathInZipFile", | 736 {"nativeGetLibraryFilePathInZipFile", |
| 789 "(" | 737 "(" |
| 790 "Ljava/lang/String;" | 738 "Ljava/lang/String;" |
| 791 ")" | 739 ")" |
| 792 "Ljava/lang/String;", | 740 "Ljava/lang/String;", |
| 793 reinterpret_cast<void*>(&GetLibraryFilePathInZipFile)}, | 741 reinterpret_cast<void*>(&GetLibraryFilePathInZipFile)}, |
| 794 {"nativeCheckMapExecSupport", | |
| 795 "(" | |
| 796 "Ljava/lang/String;" | |
| 797 ")" | |
| 798 "Z", | |
| 799 reinterpret_cast<void*>(&CheckMapExecSupport)}, | |
| 800 {"nativeCheckLibraryIsMappableInApk", | 742 {"nativeCheckLibraryIsMappableInApk", |
| 801 "(" | 743 "(" |
| 802 "Ljava/lang/String;" | 744 "Ljava/lang/String;" |
| 803 "Ljava/lang/String;" | 745 "Ljava/lang/String;" |
| 804 ")" | 746 ")" |
| 805 "Z", | 747 "Z", |
| 806 reinterpret_cast<void*>(&CheckLibraryIsMappableInApk)}, }; | 748 reinterpret_cast<void*>(&CheckLibraryIsMappableInApk)}, }; |
| 807 | 749 |
| 808 } // namespace | 750 } // namespace |
| 809 | 751 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 crazy_context_t* context = GetCrazyContext(); | 794 crazy_context_t* context = GetCrazyContext(); |
| 853 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); | 795 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); |
| 854 | 796 |
| 855 // Register the function that the crazy linker can call to post code | 797 // Register the function that the crazy linker can call to post code |
| 856 // for later execution. | 798 // for later execution. |
| 857 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); | 799 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); |
| 858 | 800 |
| 859 LOG_INFO("%s: Done", __FUNCTION__); | 801 LOG_INFO("%s: Done", __FUNCTION__); |
| 860 return JNI_VERSION_1_4; | 802 return JNI_VERSION_1_4; |
| 861 } | 803 } |
| OLD | NEW |