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 |