| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 version of the Android-specific Chromium linker that uses | 5 // This is the version of the Android-specific Chromium linker that uses |
| 6 // the Android M and later system linker to load libraries. | 6 // the Android M and later system linker to load libraries. |
| 7 | 7 |
| 8 // This source code *cannot* depend on anything from base/ or the C++ | 8 // This source code *cannot* depend on anything from base/ or the C++ |
| 9 // STL, to keep the final library small, and avoid ugly dependency issues. | 9 // STL, to keep the final library small, and avoid ugly dependency issues. |
| 10 | 10 |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 // so that the Android Package Manager doesn't extract the library into | 346 // so that the Android Package Manager doesn't extract the library into |
| 347 // /data/app-lib. | 347 // /data/app-lib. |
| 348 // | 348 // |
| 349 // If |dlopen_ext_path| contains no "!/" separator then android_dlopen_ext() | 349 // If |dlopen_ext_path| contains no "!/" separator then android_dlopen_ext() |
| 350 // assumes that it is a normal path to a standalone library file. | 350 // assumes that it is a normal path to a standalone library file. |
| 351 // | 351 // |
| 352 // Loading the library will also call its JNI_OnLoad() method, which | 352 // Loading the library will also call its JNI_OnLoad() method, which |
| 353 // shall register its methods. Note that lazy native method resolution | 353 // shall register its methods. Note that lazy native method resolution |
| 354 // will _not_ work after this, because Dalvik uses the system's dlsym() | 354 // will _not_ work after this, because Dalvik uses the system's dlsym() |
| 355 // which won't see the new library, so explicit registration is mandatory. | 355 // which won't see the new library, so explicit registration is mandatory. |
| 356 // Load a library with the chromium linker. This will also call its | |
| 357 // JNI_OnLoad() method, which shall register its methods. Note that | |
| 358 // lazy native method resolution will _not_ work after this, because | |
| 359 // Dalvik uses the system's dlsym() which won't see the new library, | |
| 360 // so explicit registration is mandatory. | |
| 361 // | 356 // |
| 362 // |env| is the current JNI environment handle. | 357 // |env| is the current JNI environment handle. |
| 363 // |clazz| is the static class handle for org.chromium.base.Linker, | 358 // |clazz| is the static class handle for org.chromium.base.Linker, |
| 364 // and is ignored here. | 359 // and is ignored here. |
| 365 // |dlopen_ext_path| is the library identifier (e.g. libfoo.so). | 360 // |dlopen_ext_path| is the library identifier (e.g. libfoo.so). |
| 366 // |load_address| is an explicit load address. | 361 // |load_address| is an explicit load address. |
| 367 // |relro_path| is the path to the file into which RELRO data is held. | 362 // |relro_path| is the path to the file into which RELRO data is held. |
| 368 // |lib_info_obj| is a LibInfo handle used to communicate information | 363 // |lib_info_obj| is a LibInfo handle used to communicate information |
| 369 // with the Java side. | 364 // with the Java side. |
| 370 // Return true on success. | 365 // Return true on success. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 size_t min_vaddr = 0; | 424 size_t min_vaddr = 0; |
| 430 if (!GetLibraryLoadSize(addr, &load_size, &min_vaddr)) { | 425 if (!GetLibraryLoadSize(addr, &load_size, &min_vaddr)) { |
| 431 LOG_ERROR("Unable to find size for load at %p", addr); | 426 LOG_ERROR("Unable to find size for load at %p", addr); |
| 432 return false; | 427 return false; |
| 433 } | 428 } |
| 434 if (!ResizeReservedAddressSpace(addr, size, load_size, min_vaddr)) { | 429 if (!ResizeReservedAddressSpace(addr, size, load_size, min_vaddr)) { |
| 435 LOG_ERROR("Unable to resize reserved address mapping"); | 430 LOG_ERROR("Unable to resize reserved address mapping"); |
| 436 return false; | 431 return false; |
| 437 } | 432 } |
| 438 | 433 |
| 439 // Locate and then call the loaded library's JNI_OnLoad() function. Check | 434 // Locate and if found then call the loaded library's JNI_OnLoad() function. |
| 440 // that it returns a usable JNI version. | |
| 441 using JNI_OnLoadFunctionPtr = int (*)(void* vm, void* reserved); | 435 using JNI_OnLoadFunctionPtr = int (*)(void* vm, void* reserved); |
| 442 auto jni_onload = | 436 auto jni_onload = |
| 443 reinterpret_cast<JNI_OnLoadFunctionPtr>(dlsym(handle, "JNI_OnLoad")); | 437 reinterpret_cast<JNI_OnLoadFunctionPtr>(dlsym(handle, "JNI_OnLoad")); |
| 444 if (jni_onload == nullptr) { | 438 if (jni_onload != nullptr) { |
| 445 LOG_ERROR("dlsym: JNI_OnLoad: %s", dlerror()); | 439 // Check that JNI_OnLoad returns a usable JNI version. |
| 446 return false; | 440 int jni_version = (*jni_onload)(s_java_vm, nullptr); |
| 447 } | 441 if (jni_version < JNI_VERSION_1_4) { |
| 448 | 442 LOG_ERROR("JNI version is invalid: %d", jni_version); |
| 449 int jni_version = (*jni_onload)(s_java_vm, nullptr); | 443 return false; |
| 450 if (jni_version < JNI_VERSION_1_4) { | 444 } |
| 451 LOG_ERROR("JNI version is invalid: %d", jni_version); | |
| 452 return false; | |
| 453 } | 445 } |
| 454 | 446 |
| 455 // Release mapping before returning so that we do not unmap reserved space. | 447 // Release mapping before returning so that we do not unmap reserved space. |
| 456 mapping.Release(); | 448 mapping.Release(); |
| 457 | 449 |
| 458 // Note the load address and load size in the supplied libinfo object. | 450 // Note the load address and load size in the supplied libinfo object. |
| 459 const size_t cast_addr = reinterpret_cast<size_t>(addr); | 451 const size_t cast_addr = reinterpret_cast<size_t>(addr); |
| 460 s_lib_info_fields.SetLoadInfo(env, lib_info_obj, cast_addr, load_size); | 452 s_lib_info_fields.SetLoadInfo(env, lib_info_obj, cast_addr, load_size); |
| 461 | 453 |
| 462 LOG_INFO("Success loading library %s", dlopen_library_path.c_str()); | 454 LOG_INFO("Success loading library %s", dlopen_library_path.c_str()); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 kNativeMethods, | 603 kNativeMethods, |
| 612 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); | 604 sizeof(kNativeMethods) / sizeof(kNativeMethods[0])); |
| 613 | 605 |
| 614 // Record the Java VM handle. | 606 // Record the Java VM handle. |
| 615 s_java_vm = vm; | 607 s_java_vm = vm; |
| 616 | 608 |
| 617 return true; | 609 return true; |
| 618 } | 610 } |
| 619 | 611 |
| 620 } // namespace chromium_android_linker | 612 } // namespace chromium_android_linker |
| OLD | NEW |