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