Chromium Code Reviews| 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 |
| 11 // renderer process. | 11 // renderer process. |
| 12 | 12 |
| 13 // This source code *cannot* depend on anything from base/ or the C++ | 13 // This source code *cannot* depend on anything from base/ or the C++ |
| 14 // STL, to keep the final library small, and avoid ugly dependency issues. | 14 // STL, to keep the final library small, and avoid ugly dependency issues. |
| 15 | 15 |
| 16 #include <android/log.h> | 16 #include <android/log.h> |
| 17 #include <crazy_linker.h> | 17 #include <crazy_linker.h> |
| 18 #include <errno.h> | |
| 19 #include <fcntl.h> | |
| 18 #include <jni.h> | 20 #include <jni.h> |
| 21 #include <limits.h> | |
| 19 #include <stdlib.h> | 22 #include <stdlib.h> |
| 20 #include <sys/mman.h> | 23 #include <sys/mman.h> |
| 21 #include <unistd.h> | 24 #include <unistd.h> |
| 22 | 25 |
| 23 // Set this to 1 to enable debug traces to the Android log. | 26 // Set this to 1 to enable debug traces to the Android log. |
| 24 // Note that LOG() from "base/logging.h" cannot be used, since it is | 27 // Note that LOG() from "base/logging.h" cannot be used, since it is |
| 25 // in base/ which hasn't been loaded yet. | 28 // in base/ which hasn't been loaded yet. |
| 26 #define DEBUG 0 | 29 #define DEBUG 0 |
| 27 | 30 |
| 28 #define TAG "chromium_android_linker" | 31 #define TAG "chromium_android_linker" |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 mmap(NULL, bytes, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 570 mmap(NULL, bytes, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
| 568 if (address == MAP_FAILED) { | 571 if (address == MAP_FAILED) { |
| 569 LOG_INFO("%s: Random base load address not determinable\n", __FUNCTION__); | 572 LOG_INFO("%s: Random base load address not determinable\n", __FUNCTION__); |
| 570 return 0; | 573 return 0; |
| 571 } | 574 } |
| 572 munmap(address, bytes); | 575 munmap(address, bytes); |
| 573 LOG_INFO("%s: Random base load address is %p\n", __FUNCTION__, address); | 576 LOG_INFO("%s: Random base load address is %p\n", __FUNCTION__, address); |
| 574 return static_cast<jlong>(reinterpret_cast<uintptr_t>(address)); | 577 return static_cast<jlong>(reinterpret_cast<uintptr_t>(address)); |
| 575 } | 578 } |
| 576 | 579 |
| 580 // Check whether the device supports memory mapping APK files with executable | |
| 581 // permissions. | |
| 582 // | |
| 583 // |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.
| |
| 584 // |clazz| is the static class handle for org.chromium.base.Linker, | |
| 585 // 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.
| |
| 586 // |apkfile_name| is the filename of the APK. | |
| 587 // Returns true if supported. | |
| 588 jboolean CheckApkMemoryMappingSupport(JNIEnv* env, jclass clazz, | |
| 589 jstring apkfile_name) { | |
| 590 String apkfile_name_str(env, apkfile_name); | |
| 591 const char* apkfile_name_c_str = apkfile_name_str.c_str(); | |
| 592 | |
| 593 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.
| |
| 594 if (fd == -1) { | |
| 595 LOG_ERROR("%s: Failed to open %s\n", __FUNCTION__, apkfile_name_c_str); | |
| 596 return 0; | |
| 597 } | |
| 598 | |
| 599 LOG_INFO("%s: Memory mapping the first page of %s\n", __FUNCTION__, | |
| 600 apkfile_name_c_str); | |
| 601 void* address = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, fd, 0); | |
| 602 | |
| 603 jboolean success; | |
| 604 if (address == MAP_FAILED) { | |
| 605 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.
| |
| 606 } else { | |
| 607 success = 1; | |
| 608 munmap(address, PAGE_SIZE); | |
| 609 } | |
| 610 | |
| 611 TEMP_FAILURE_RETRY(close(fd)); | |
|
rmcilroy
2014/10/10 16:26:08
ditto
petrcermak
2014/10/10 17:13:24
Done.
| |
| 612 | |
| 613 LOG_INFO(" %ssupported\n", success ? "" : "NOT "); | |
| 614 return success; | |
| 615 | |
| 616 } | |
| 617 | |
| 577 const JNINativeMethod kNativeMethods[] = { | 618 const JNINativeMethod kNativeMethods[] = { |
| 578 {"nativeLoadLibrary", | 619 {"nativeLoadLibrary", |
| 579 "(" | 620 "(" |
| 580 "Ljava/lang/String;" | 621 "Ljava/lang/String;" |
| 581 "J" | 622 "J" |
| 582 "Lorg/chromium/base/library_loader/Linker$LibInfo;" | 623 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
| 583 ")" | 624 ")" |
| 584 "Z", | 625 "Z", |
| 585 reinterpret_cast<void*>(&LoadLibrary)}, | 626 reinterpret_cast<void*>(&LoadLibrary)}, |
| 586 {"nativeLoadLibraryInZipFile", | 627 {"nativeLoadLibraryInZipFile", |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 616 {"nativeCanUseSharedRelro", | 657 {"nativeCanUseSharedRelro", |
| 617 "(" | 658 "(" |
| 618 ")" | 659 ")" |
| 619 "Z", | 660 "Z", |
| 620 reinterpret_cast<void*>(&CanUseSharedRelro)}, | 661 reinterpret_cast<void*>(&CanUseSharedRelro)}, |
| 621 {"nativeGetRandomBaseLoadAddress", | 662 {"nativeGetRandomBaseLoadAddress", |
| 622 "(" | 663 "(" |
| 623 "J" | 664 "J" |
| 624 ")" | 665 ")" |
| 625 "J", | 666 "J", |
| 626 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, }; | 667 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, |
| 668 {"nativeCheckApkMemoryMappingSupport", | |
| 669 "(" | |
| 670 "Ljava/lang/String;" | |
| 671 ")" | |
| 672 "Z", | |
| 673 reinterpret_cast<void*>(&CheckApkMemoryMappingSupport)}, }; | |
| 627 | 674 |
| 628 } // namespace | 675 } // namespace |
| 629 | 676 |
| 630 // JNI_OnLoad() hook called when the linker library is loaded through | 677 // JNI_OnLoad() hook called when the linker library is loaded through |
| 631 // the regular System.LoadLibrary) API. This shall save the Java VM | 678 // the regular System.LoadLibrary) API. This shall save the Java VM |
| 632 // handle and initialize LibInfo fields. | 679 // handle and initialize LibInfo fields. |
| 633 jint JNI_OnLoad(JavaVM* vm, void* reserved) { | 680 jint JNI_OnLoad(JavaVM* vm, void* reserved) { |
| 634 LOG_INFO("%s: Entering", __FUNCTION__); | 681 LOG_INFO("%s: Entering", __FUNCTION__); |
| 635 // Get new JNIEnv | 682 // Get new JNIEnv |
| 636 JNIEnv* env; | 683 JNIEnv* env; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 667 crazy_context_t* context = GetCrazyContext(); | 714 crazy_context_t* context = GetCrazyContext(); |
| 668 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); | 715 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); |
| 669 | 716 |
| 670 // Register the function that the crazy linker can call to post code | 717 // Register the function that the crazy linker can call to post code |
| 671 // for later execution. | 718 // for later execution. |
| 672 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); | 719 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); |
| 673 | 720 |
| 674 LOG_INFO("%s: Done", __FUNCTION__); | 721 LOG_INFO("%s: Done", __FUNCTION__); |
| 675 return JNI_VERSION_1_4; | 722 return JNI_VERSION_1_4; |
| 676 } | 723 } |
| OLD | NEW |