| 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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 } | 577 } |
| 578 | 578 |
| 579 // Check whether the device supports loading a library directly from the APK | 579 // Check whether the device supports loading a library directly from the APK |
| 580 // file. | 580 // file. |
| 581 // | 581 // |
| 582 // |env| is the current JNI environment handle. | 582 // |env| is the current JNI environment handle. |
| 583 // |clazz| is the static class handle which is not used here. | 583 // |clazz| is the static class handle which is not used here. |
| 584 // |apkfile_name| is the filename of the APK. | 584 // |apkfile_name| is the filename of the APK. |
| 585 // Returns true if supported. | 585 // Returns true if supported. |
| 586 jboolean CheckLibraryLoadFromApkSupport(JNIEnv* env, jclass clazz, | 586 jboolean CheckLibraryLoadFromApkSupport(JNIEnv* env, jclass clazz, |
| 587 jstring apkfile_name) { | 587 jstring apkfile_name) { |
| 588 String apkfile_name_str(env, apkfile_name); | 588 String apkfile_name_str(env, apkfile_name); |
| 589 const char* apkfile_name_c_str = apkfile_name_str.c_str(); | 589 const char* apkfile_name_c_str = apkfile_name_str.c_str(); |
| 590 | 590 |
| 591 int fd = open(apkfile_name_c_str, O_RDONLY); | 591 int fd = open(apkfile_name_c_str, O_RDONLY); |
| 592 if (fd == -1) { | 592 if (fd == -1) { |
| 593 LOG_ERROR("%s: Failed to open %s\n", __FUNCTION__, apkfile_name_c_str); | 593 LOG_ERROR("%s: Failed to open %s\n", __FUNCTION__, apkfile_name_c_str); |
| 594 return false; | 594 return false; |
| 595 } | 595 } |
| 596 | 596 |
| 597 LOG_INFO( | 597 LOG_INFO( |
| 598 "%s: Memory mapping the first page of %s with executable permissions\n", | 598 "%s: Memory mapping the first page of %s with executable permissions\n", |
| 599 __FUNCTION__, apkfile_name_c_str); | 599 __FUNCTION__, apkfile_name_c_str); |
| 600 void* address = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, fd, 0); | 600 void* address = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_PRIVATE, fd, 0); |
| 601 | 601 |
| 602 jboolean status; | 602 jboolean status; |
| 603 if (address == MAP_FAILED) { | 603 if (address == MAP_FAILED) { |
| 604 status = false; | 604 status = false; |
| 605 } else { | 605 } else { |
| 606 status = true; | 606 status = true; |
| 607 munmap(address, PAGE_SIZE); | 607 munmap(address, PAGE_SIZE); |
| 608 } | 608 } |
| 609 | 609 |
| 610 close(fd); | 610 close(fd); |
| 611 | 611 |
| 612 LOG_INFO("%s: %s\n", __FUNCTION__, status ? "Supported" : "NOT supported"); | 612 LOG_INFO("%s: %s\n", __FUNCTION__, status ? "Supported" : "NOT supported"); |
| 613 return status; | 613 return status; |
| 614 } | 614 } |
| 615 | 615 |
| 616 // Check whether a library is page aligned in the APK file. |
| 617 // |
| 618 // |env| is the current JNI environment handle. |
| 619 // |clazz| is the static class handle which is not used here. |
| 620 // |apkfile_name| is the filename of the APK. |
| 621 // |library_name| is the library base name. |
| 622 // Returns true if page aligned. |
| 623 jboolean CheckLibraryAlignedInApk(JNIEnv* env, jclass clazz, |
| 624 jstring apkfile_name, jstring library_name) { |
| 625 String apkfile_name_str(env, apkfile_name); |
| 626 const char* apkfile_name_c_str = apkfile_name_str.c_str(); |
| 627 String library_name_str(env, library_name); |
| 628 const char* library_name_c_str = library_name_str.c_str(); |
| 629 |
| 630 LOG_INFO("%s: Checking if %s is page-aligned in %s\n", __FUNCTION__, |
| 631 library_name_c_str, apkfile_name_c_str); |
| 632 jboolean aligned = crazy_linker_check_library_aligned_in_zip_file( |
| 633 apkfile_name_c_str, library_name_c_str) == CRAZY_STATUS_SUCCESS; |
| 634 LOG_INFO("%s: %s\n", __FUNCTION__, aligned ? "Aligned" : "NOT aligned"); |
| 635 |
| 636 return aligned; |
| 637 } |
| 638 |
| 616 const JNINativeMethod kNativeMethods[] = { | 639 const JNINativeMethod kNativeMethods[] = { |
| 617 {"nativeLoadLibrary", | 640 {"nativeLoadLibrary", |
| 618 "(" | 641 "(" |
| 619 "Ljava/lang/String;" | 642 "Ljava/lang/String;" |
| 620 "J" | 643 "J" |
| 621 "Lorg/chromium/base/library_loader/Linker$LibInfo;" | 644 "Lorg/chromium/base/library_loader/Linker$LibInfo;" |
| 622 ")" | 645 ")" |
| 623 "Z", | 646 "Z", |
| 624 reinterpret_cast<void*>(&LoadLibrary)}, | 647 reinterpret_cast<void*>(&LoadLibrary)}, |
| 625 {"nativeLoadLibraryInZipFile", | 648 {"nativeLoadLibraryInZipFile", |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 "(" | 684 "(" |
| 662 "J" | 685 "J" |
| 663 ")" | 686 ")" |
| 664 "J", | 687 "J", |
| 665 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, | 688 reinterpret_cast<void*>(&GetRandomBaseLoadAddress)}, |
| 666 {"nativeCheckLibraryLoadFromApkSupport", | 689 {"nativeCheckLibraryLoadFromApkSupport", |
| 667 "(" | 690 "(" |
| 668 "Ljava/lang/String;" | 691 "Ljava/lang/String;" |
| 669 ")" | 692 ")" |
| 670 "Z", | 693 "Z", |
| 671 reinterpret_cast<void*>(&CheckLibraryLoadFromApkSupport)}, }; | 694 reinterpret_cast<void*>(&CheckLibraryLoadFromApkSupport)}, |
| 695 {"nativeCheckLibraryAlignedInApk", |
| 696 "(" |
| 697 "Ljava/lang/String;" |
| 698 "Ljava/lang/String;" |
| 699 ")" |
| 700 "Z", |
| 701 reinterpret_cast<void*>(&CheckLibraryAlignedInApk)}, }; |
| 672 | 702 |
| 673 } // namespace | 703 } // namespace |
| 674 | 704 |
| 675 // JNI_OnLoad() hook called when the linker library is loaded through | 705 // JNI_OnLoad() hook called when the linker library is loaded through |
| 676 // the regular System.LoadLibrary) API. This shall save the Java VM | 706 // the regular System.LoadLibrary) API. This shall save the Java VM |
| 677 // handle and initialize LibInfo fields. | 707 // handle and initialize LibInfo fields. |
| 678 jint JNI_OnLoad(JavaVM* vm, void* reserved) { | 708 jint JNI_OnLoad(JavaVM* vm, void* reserved) { |
| 679 LOG_INFO("%s: Entering", __FUNCTION__); | 709 LOG_INFO("%s: Entering", __FUNCTION__); |
| 680 // Get new JNIEnv | 710 // Get new JNIEnv |
| 681 JNIEnv* env; | 711 JNIEnv* env; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 712 crazy_context_t* context = GetCrazyContext(); | 742 crazy_context_t* context = GetCrazyContext(); |
| 713 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); | 743 crazy_context_set_java_vm(context, vm, JNI_VERSION_1_4); |
| 714 | 744 |
| 715 // Register the function that the crazy linker can call to post code | 745 // Register the function that the crazy linker can call to post code |
| 716 // for later execution. | 746 // for later execution. |
| 717 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); | 747 crazy_context_set_callback_poster(context, &PostForLaterExecution, NULL); |
| 718 | 748 |
| 719 LOG_INFO("%s: Done", __FUNCTION__); | 749 LOG_INFO("%s: Done", __FUNCTION__); |
| 720 return JNI_VERSION_1_4; | 750 return JNI_VERSION_1_4; |
| 721 } | 751 } |
| OLD | NEW |