Chromium Code Reviews| Index: base/android/linker/linker_jni.cc |
| diff --git a/base/android/linker/linker_jni.cc b/base/android/linker/linker_jni.cc |
| index 79dd20103e7add06b2b30dd0550193682cbb7d50..83cc1ada24630ecf525a340bcc588722899ad4a1 100644 |
| --- a/base/android/linker/linker_jni.cc |
| +++ b/base/android/linker/linker_jni.cc |
| @@ -15,7 +15,10 @@ |
| #include <android/log.h> |
| #include <crazy_linker.h> |
| +#include <errno.h> |
| +#include <fcntl.h> |
| #include <jni.h> |
| +#include <limits.h> |
| #include <stdlib.h> |
| #include <sys/mman.h> |
| #include <unistd.h> |
| @@ -574,6 +577,44 @@ jlong GetRandomBaseLoadAddress(JNIEnv* env, jclass clazz, jlong bytes) { |
| return static_cast<jlong>(reinterpret_cast<uintptr_t>(address)); |
| } |
| +// Check whether the device supports memory mapping APK files with executable |
| +// permissions. |
| +// |
| +// |env| is the current JNI environment handle and is ignored here. |
|
rmcilroy
2014/10/10 16:26:08
not ignored - used for string conversion
petrcermak
2014/10/10 17:13:24
Done.
|
| +// |clazz| is the static class handle for org.chromium.base.Linker, |
| +// and is ignored here. |
|
rmcilroy
2014/10/10 16:26:08
nit - I would just write "|class| is the static cl
petrcermak
2014/10/10 17:13:24
Done.
|
| +// |apkfile_name| is the filename of the APK. |
| +// Returns true if supported. |
| +jboolean CheckApkMemoryMappingSupport(JNIEnv* env, jclass clazz, |
| + jstring apkfile_name) { |
| + String apkfile_name_str(env, apkfile_name); |
| + const char* apkfile_name_c_str = apkfile_name_str.c_str(); |
| + |
| + int fd = TEMP_FAILURE_RETRY(open(apkfile_name_c_str, O_RDONLY)); |
|
rmcilroy
2014/10/10 16:26:08
I would avoid the TEMP_FAILURE_RETRY - it's not su
petrcermak
2014/10/10 17:13:24
Done.
|
| + if (fd == -1) { |
| + LOG_ERROR("%s: Failed to open %s\n", __FUNCTION__, apkfile_name_c_str); |
| + return 0; |
| + } |
| + |
| + LOG_INFO("%s: Memory mapping the first page of %s\n", __FUNCTION__, |
| + apkfile_name_c_str); |
| + void* address = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, fd, 0); |
| + |
| + jboolean success; |
| + if (address == MAP_FAILED) { |
| + success = 0; |
|
rmcilroy
2014/10/10 16:26:08
/s/0/false (and true for '1' below)
petrcermak
2014/10/10 17:13:24
Done.
|
| + } else { |
| + success = 1; |
| + munmap(address, PAGE_SIZE); |
| + } |
| + |
| + TEMP_FAILURE_RETRY(close(fd)); |
|
rmcilroy
2014/10/10 16:26:08
ditto
petrcermak
2014/10/10 17:13:24
Done.
|
| + |
| + LOG_INFO(" %ssupported\n", success ? "" : "NOT "); |
| + return success; |
| + |
| +} |
| + |
| const JNINativeMethod kNativeMethods[] = { |
| {"nativeLoadLibrary", |
| "(" |
| @@ -623,7 +664,13 @@ const JNINativeMethod kNativeMethods[] = { |
| "J" |
| ")" |
| "J", |
| - reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, }; |
| + reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, |
| + {"nativeCheckApkMemoryMappingSupport", |
| + "(" |
| + "Ljava/lang/String;" |
| + ")" |
| + "Z", |
| + reinterpret_cast<void*>(&CheckApkMemoryMappingSupport)}, }; |
| } // namespace |