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 |