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 package org.chromium.base.library_loader; | 5 package org.chromium.base.library_loader; |
6 | 6 |
7 import android.os.Bundle; | 7 import android.os.Bundle; |
8 import android.os.Parcel; | 8 import android.os.Parcel; |
9 import android.os.ParcelFileDescriptor; | 9 import android.os.ParcelFileDescriptor; |
10 import android.os.Parcelable; | 10 import android.os.Parcelable; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 * useSharedRelros() from another thread. | 151 * useSharedRelros() from another thread. |
152 * | 152 * |
153 * This method also ensures the process uses the shared RELROs. | 153 * This method also ensures the process uses the shared RELROs. |
154 */ | 154 */ |
155 public class Linker { | 155 public class Linker { |
156 | 156 |
157 // Log tag for this class. This must match the name of the linker's native l ibrary. | 157 // Log tag for this class. This must match the name of the linker's native l ibrary. |
158 private static final String TAG = "chromium_android_linker"; | 158 private static final String TAG = "chromium_android_linker"; |
159 | 159 |
160 // Set to true to enable debug logs. | 160 // Set to true to enable debug logs. |
161 private static final boolean DEBUG = false; | 161 public static final boolean DEBUG = false; |
162 | 162 |
163 // Constants used to control the behaviour of the browser process with | 163 // Constants used to control the behaviour of the browser process with |
164 // regards to the shared RELRO section. | 164 // regards to the shared RELRO section. |
165 // NEVER -> The browser never uses it itself. | 165 // NEVER -> The browser never uses it itself. |
166 // LOW_RAM_ONLY -> It is only used on devices with low RAM. | 166 // LOW_RAM_ONLY -> It is only used on devices with low RAM. |
167 // ALWAYS -> It is always used. | 167 // ALWAYS -> It is always used. |
168 // NOTE: These names are known and expected by the Linker test scripts. | 168 // NOTE: These names are known and expected by the Linker test scripts. |
169 public static final int BROWSER_SHARED_RELRO_CONFIG_NEVER = 0; | 169 public static final int BROWSER_SHARED_RELRO_CONFIG_NEVER = 0; |
170 public static final int BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY = 1; | 170 public static final int BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY = 1; |
171 public static final int BROWSER_SHARED_RELRO_CONFIG_ALWAYS = 2; | 171 public static final int BROWSER_SHARED_RELRO_CONFIG_ALWAYS = 2; |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 if (!sInBrowserProcess) | 695 if (!sInBrowserProcess) |
696 closeLibInfoMap(relroMap); | 696 closeLibInfoMap(relroMap); |
697 | 697 |
698 if (DEBUG) Log.i(TAG, "Linker.useSharedRelrosLocked() exiting"); | 698 if (DEBUG) Log.i(TAG, "Linker.useSharedRelrosLocked() exiting"); |
699 } | 699 } |
700 | 700 |
701 /** | 701 /** |
702 * Load a native shared library with the Chromium linker. | 702 * Load a native shared library with the Chromium linker. |
703 * The shared library is uncompressed and page aligned inside the zipfile. | 703 * The shared library is uncompressed and page aligned inside the zipfile. |
704 * Note the crazy linker treats libraries and files as equivalent, | 704 * Note the crazy linker treats libraries and files as equivalent, |
705 * so you can only open one library in a given zip file. | 705 * so you can only open one library in a given zip file. The library must |
706 * not be the Chromium linker library. | |
706 * | 707 * |
707 * @param zipfile The filename of the zipfile contain the library. | 708 * @param zipfile The filename of the zipfile contain the library. |
708 * @param library The library's base name. | 709 * @param library The library's base name. |
709 */ | 710 */ |
710 public static void loadLibraryInZipFile(String zipfile, String library) { | 711 public static void loadLibraryInZipFile(String zipfile, String library) { |
711 loadLibraryMaybeInZipFile(zipfile, library); | 712 loadLibraryMaybeInZipFile(zipfile, library); |
712 } | 713 } |
713 | 714 |
714 /** | 715 /** |
715 * Load a native shared library with the Chromium linker. | 716 * Load a native shared library with the Chromium linker. The library must |
717 * not be the Chromium linker library. | |
716 * | 718 * |
717 * @param library The library's base name. | 719 * @param library The library's base name. |
718 */ | 720 */ |
719 public static void loadLibrary(String library) { | 721 public static void loadLibrary(String library) { |
720 loadLibraryMaybeInZipFile(null, library); | 722 loadLibraryMaybeInZipFile(null, library); |
721 } | 723 } |
722 | 724 |
723 private static void loadLibraryMaybeInZipFile( | 725 private static void loadLibraryMaybeInZipFile( |
724 @Nullable String zipFile, String library) { | 726 @Nullable String zipFile, String library) { |
725 if (DEBUG) Log.i(TAG, "loadLibrary: " + library); | 727 if (DEBUG) Log.i(TAG, "loadLibrary: " + library); |
726 | 728 assert !isLinkerLibrary(library); |
727 // Don't self-load the linker. This is because the build system is | |
728 // not clever enough to understand that all the libraries packaged | |
729 // in the final .apk don't need to be explicitly loaded. | |
730 // Also deal with the component build that adds a .cr suffix to the name . | |
731 if (library.equals(TAG) || library.equals(TAG + ".cr")) { | |
732 if (DEBUG) Log.i(TAG, "ignoring self-linker load"); | |
733 return; | |
734 } | |
735 | 729 |
736 synchronized (Linker.class) { | 730 synchronized (Linker.class) { |
737 ensureInitializedLocked(); | 731 ensureInitializedLocked(); |
738 | 732 |
739 // Security: Ensure prepareLibraryLoad() was called before. | 733 // Security: Ensure prepareLibraryLoad() was called before. |
740 // In theory, this can be done lazily here, but it's more consistent | 734 // In theory, this can be done lazily here, but it's more consistent |
741 // to use a pair of functions (i.e. prepareLibraryLoad() + finishLib raryLoad()) | 735 // to use a pair of functions (i.e. prepareLibraryLoad() + finishLib raryLoad()) |
742 // that wrap all calls to loadLibrary() in the library loader. | 736 // that wrap all calls to loadLibrary() in the library loader. |
743 assert sPrepareLibraryLoadCalled; | 737 assert sPrepareLibraryLoadCalled; |
744 | 738 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 // only. | 808 // only. |
815 sCurrentLoadAddress = libInfo.mLoadAddress + libInfo.mLoadSize; | 809 sCurrentLoadAddress = libInfo.mLoadAddress + libInfo.mLoadSize; |
816 } | 810 } |
817 | 811 |
818 sLoadedLibraries.put(sharedRelRoName, libInfo); | 812 sLoadedLibraries.put(sharedRelRoName, libInfo); |
819 if (DEBUG) Log.i(TAG, "Library details " + libInfo.toString()); | 813 if (DEBUG) Log.i(TAG, "Library details " + libInfo.toString()); |
820 } | 814 } |
821 } | 815 } |
822 | 816 |
823 /** | 817 /** |
818 * Determine whether a library is the linker library. Also deal with the | |
819 * component build that adds a .cr suffix to the name. | |
820 */ | |
821 public static boolean isLinkerLibrary(String library) { | |
rmcilroy
2014/10/28 13:07:15
nit - isChromiumLinkerLibrary
petrcermak
2014/10/28 13:48:15
Done.
| |
822 return library.equals(TAG) || library.equals(TAG + ".cr"); | |
823 } | |
824 | |
825 /** | |
824 * Check whether the device supports loading a library directly from the APK file. | 826 * Check whether the device supports loading a library directly from the APK file. |
825 * | 827 * |
826 * @param apkFile Filename of the APK. | 828 * @param apkFile Filename of the APK. |
827 * @return true if supported. | 829 * @return true if supported. |
828 */ | 830 */ |
829 public static boolean checkLibraryLoadFromApkSupport(String apkFile) { | 831 public static boolean checkLibraryLoadFromApkSupport(String apkFile) { |
830 assert apkFile != null; | 832 assert apkFile != null; |
831 synchronized (Linker.class) { | 833 synchronized (Linker.class) { |
832 ensureInitializedLocked(); | 834 ensureInitializedLocked(); |
833 | 835 |
834 if (DEBUG) Log.i(TAG, "checkLibraryLoadFromApkSupported: " + apkFile ); | 836 if (DEBUG) Log.i(TAG, "checkLibraryLoadFromApkSupported: " + apkFile ); |
835 boolean supported = nativeCheckLibraryLoadFromApkSupport(apkFile); | 837 boolean supported = nativeCheckLibraryLoadFromApkSupport(apkFile); |
836 if (DEBUG) Log.i(TAG, "Loading a library directly from the APK file " + | 838 if (DEBUG) Log.i(TAG, "Loading a library directly from the APK file " + |
837 (supported ? "" : "NOT ") + "supported"); | 839 (supported ? "" : "NOT ") + "supported"); |
838 return supported; | 840 return supported; |
839 } | 841 } |
840 } | 842 } |
841 | 843 |
842 /** | 844 /** |
845 * Check whether a library is page aligned in the APK file. | |
846 * | |
847 * @param apkFile Filename of the APK. | |
848 * @param library The library's base name. | |
849 * @return true if page aligned. | |
850 */ | |
851 public static boolean checkLibraryAlignedInApk(String apkFile, String librar y) { | |
852 synchronized (Linker.class) { | |
853 ensureInitializedLocked(); | |
854 | |
855 if (DEBUG) Log.i(TAG, "checkLibraryAlignedInApk: " + apkFile + ", " + library); | |
856 boolean aligned = nativeCheckLibraryAlignedInApk(apkFile, library); | |
857 if (DEBUG) Log.i(TAG, library + " is " + (aligned ? "" : "NOT ") + | |
858 "page aligned in " + apkFile); | |
859 return aligned; | |
860 } | |
861 } | |
862 | |
863 /** | |
843 * Move activity from the native thread to the main UI thread. | 864 * Move activity from the native thread to the main UI thread. |
844 * Called from native code on its own thread. Posts a callback from | 865 * Called from native code on its own thread. Posts a callback from |
845 * the UI thread back to native code. | 866 * the UI thread back to native code. |
846 * | 867 * |
847 * @param opaque Opaque argument. | 868 * @param opaque Opaque argument. |
848 */ | 869 */ |
849 @CalledByNative | 870 @CalledByNative |
850 public static void postCallbackOnMainThread(final long opaque) { | 871 public static void postCallbackOnMainThread(final long opaque) { |
851 ThreadUtils.postOnUiThread(new Runnable() { | 872 ThreadUtils.postOnUiThread(new Runnable() { |
852 @Override | 873 @Override |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
935 * @return address to pass to future mmap, or 0 on error. | 956 * @return address to pass to future mmap, or 0 on error. |
936 */ | 957 */ |
937 private static native long nativeGetRandomBaseLoadAddress(long sizeBytes); | 958 private static native long nativeGetRandomBaseLoadAddress(long sizeBytes); |
938 | 959 |
939 /** | 960 /** |
940 * Native method which checks whether the device supports loading a library | 961 * Native method which checks whether the device supports loading a library |
941 * directly from the APK file. | 962 * directly from the APK file. |
942 * | 963 * |
943 * @param apkFile Filename of the APK. | 964 * @param apkFile Filename of the APK. |
944 * @return true if supported. | 965 * @return true if supported. |
945 * | |
946 */ | 966 */ |
947 private static native boolean nativeCheckLibraryLoadFromApkSupport(String ap kFile); | 967 private static native boolean nativeCheckLibraryLoadFromApkSupport(String ap kFile); |
948 | 968 |
949 /** | 969 /** |
970 * Native method which checks whether a library is page aligned in the APK f ile. | |
971 * | |
972 * @param apkFile Filename of the APK. | |
973 * @param library The library's base name. | |
974 * @return true if page aligned. | |
975 */ | |
976 private static native boolean nativeCheckLibraryAlignedInApk(String apkFile, String library); | |
977 | |
978 /** | |
950 * Record information for a given library. | 979 * Record information for a given library. |
951 * IMPORTANT: Native code knows about this class's fields, so | 980 * IMPORTANT: Native code knows about this class's fields, so |
952 * don't change them without modifying the corresponding C++ sources. | 981 * don't change them without modifying the corresponding C++ sources. |
953 * Also, the LibInfo instance owns the ashmem file descriptor. | 982 * Also, the LibInfo instance owns the ashmem file descriptor. |
954 */ | 983 */ |
955 public static class LibInfo implements Parcelable { | 984 public static class LibInfo implements Parcelable { |
956 | 985 |
957 public LibInfo() { | 986 public LibInfo() { |
958 mLoadAddress = 0; | 987 mLoadAddress = 0; |
959 mLoadSize = 0; | 988 mLoadSize = 0; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1074 } | 1103 } |
1075 } | 1104 } |
1076 | 1105 |
1077 // The map of libraries that are currently loaded in this process. | 1106 // The map of libraries that are currently loaded in this process. |
1078 private static HashMap<String, LibInfo> sLoadedLibraries = null; | 1107 private static HashMap<String, LibInfo> sLoadedLibraries = null; |
1079 | 1108 |
1080 // Used to pass the shared RELRO Bundle through Binder. | 1109 // Used to pass the shared RELRO Bundle through Binder. |
1081 public static final String EXTRA_LINKER_SHARED_RELROS = | 1110 public static final String EXTRA_LINKER_SHARED_RELROS = |
1082 "org.chromium.base.android.linker.shared_relros"; | 1111 "org.chromium.base.android.linker.shared_relros"; |
1083 } | 1112 } |
OLD | NEW |