1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "jni_internal.h" 18 19 #define ATRACE_TAG ATRACE_TAG_DALVIK 20 #include <cutils/trace.h> 21 #include <dlfcn.h> 22 23 #include "art_method.h" 24 #include "base/dumpable.h" 25 #include "base/mutex.h" 26 #include "base/stl_util.h" 27 #include "check_jni.h" 28 #include "dex_file-inl.h" 29 #include "fault_handler.h" 30 #include "indirect_reference_table-inl.h" 31 #include "mirror/class-inl.h" 32 #include "mirror/class_loader.h" 33 #include "nativebridge/native_bridge.h" 34 #include "java_vm_ext.h" 35 #include "parsed_options.h" 36 #include "runtime-inl.h" 37 #include "runtime_options.h" 38 #include "ScopedLocalRef.h" 39 #include "scoped_thread_state_change.h" 40 #include "thread-inl.h" 41 #include "thread_list.h" 42 43 namespace art { 44 45 static size_t gGlobalsInitial = 512; // Arbitrary. 46 static size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 47 48 static const size_t kWeakGlobalsInitial = 16; // Arbitrary. 49 static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 50 51 static bool IsBadJniVersion(int version) { 52 // We don't support JNI_VERSION_1_1. These are the only other valid versions. 53 return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6; 54 } 55 56 class SharedLibrary { 57 public: 58 SharedLibrary(JNIEnv* env, Thread* self, const std::string& path, void* handle, 59 jobject class_loader) 60 : path_(path), 61 handle_(handle), 62 needs_native_bridge_(false), 63 class_loader_(env->NewGlobalRef(class_loader)), 64 jni_on_load_lock_("JNI_OnLoad lock"), 65 jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_), 66 jni_on_load_thread_id_(self->GetThreadId()), 67 jni_on_load_result_(kPending) { 68 } 69 70 ~SharedLibrary() { 71 Thread* self = Thread::Current(); 72 if (self != nullptr) { 73 self->GetJniEnv()->DeleteGlobalRef(class_loader_); 74 } 75 } 76 77 jobject GetClassLoader() const { 78 return class_loader_; 79 } 80 81 const std::string& GetPath() const { 82 return path_; 83 } 84 85 /* 86 * Check the result of an earlier call to JNI_OnLoad on this library. 87 * If the call has not yet finished in another thread, wait for it. 88 */ 89 bool CheckOnLoadResult() 90 LOCKS_EXCLUDED(jni_on_load_lock_) { 91 Thread* self = Thread::Current(); 92 bool okay; 93 { 94 MutexLock mu(self, jni_on_load_lock_); 95 96 if (jni_on_load_thread_id_ == self->GetThreadId()) { 97 // Check this so we don't end up waiting for ourselves. We need to return "true" so the 98 // caller can continue. 99 LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\""; 100 okay = true; 101 } else { 102 while (jni_on_load_result_ == kPending) { 103 VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]"; 104 jni_on_load_cond_.Wait(self); 105 } 106 107 okay = (jni_on_load_result_ == kOkay); 108 VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" " 109 << (okay ? "succeeded" : "failed") << "]"; 110 } 111 } 112 return okay; 113 } 114 115 void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) { 116 Thread* self = Thread::Current(); 117 MutexLock mu(self, jni_on_load_lock_); 118 119 jni_on_load_result_ = result ? kOkay : kFailed; 120 jni_on_load_thread_id_ = 0; 121 122 // Broadcast a wakeup to anybody sleeping on the condition variable. 123 jni_on_load_cond_.Broadcast(self); 124 } 125 126 void SetNeedsNativeBridge() { 127 needs_native_bridge_ = true; 128 } 129 130 bool NeedsNativeBridge() const { 131 return needs_native_bridge_; 132 } 133 134 void* FindSymbol(const std::string& symbol_name) { 135 CHECK(!NeedsNativeBridge()); 136 137 return dlsym(handle_, symbol_name.c_str()); 138 } 139 140 void* FindSymbolWithNativeBridge(const std::string& symbol_name, const char* shorty) { 141 CHECK(NeedsNativeBridge()); 142 143 uint32_t len = 0; 144 return android::NativeBridgeGetTrampoline(handle_, symbol_name.c_str(), shorty, len); 145 } 146 147 private: 148 enum JNI_OnLoadState { 149 kPending, 150 kFailed, 151 kOkay, 152 }; 153 154 // Path to library "/system/lib/libjni.so". 155 const std::string path_; 156 157 // The void* returned by dlopen(3). 158 void* const handle_; 159 160 // True if a native bridge is required. 161 bool needs_native_bridge_; 162 163 // The ClassLoader this library is associated with, a global JNI reference that is 164 // created/deleted with the scope of the library. 165 const jobject class_loader_; 166 167 // Guards remaining items. 168 Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 169 // Wait for JNI_OnLoad in other thread. 170 ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_); 171 // Recursive invocation guard. 172 uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_); 173 // Result of earlier JNI_OnLoad call. 174 JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_); 175 }; 176 177 // This exists mainly to keep implementation details out of the header file. 178 class Libraries { 179 public: 180 Libraries() { 181 } 182 183 ~Libraries() { 184 STLDeleteValues(&libraries_); 185 } 186 187 void Dump(std::ostream& os) const { 188 bool first = true; 189 for (const auto& library : libraries_) { 190 if (!first) { 191 os << ' '; 192 } 193 first = false; 194 os << library.first; 195 } 196 } 197 198 size_t size() const { 199 return libraries_.size(); 200 } 201 202 SharedLibrary* Get(const std::string& path) { 203 auto it = libraries_.find(path); 204 return (it == libraries_.end()) ? nullptr : it->second; 205 } 206 207 void Put(const std::string& path, SharedLibrary* library) { 208 libraries_.Put(path, library); 209 } 210 211 // See section 11.3 "Linking Native Methods" of the JNI spec. 212 void* FindNativeMethod(ArtMethod* m, std::string& detail) 213 EXCLUSIVE_LOCKS_REQUIRED(Locks::jni_libraries_lock_) 214 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 215 std::string jni_short_name(JniShortName(m)); 216 std::string jni_long_name(JniLongName(m)); 217 const mirror::ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader(); 218 ScopedObjectAccessUnchecked soa(Thread::Current()); 219 for (const auto& lib : libraries_) { 220 SharedLibrary* library = lib.second; 221 if (soa.Decode<mirror::ClassLoader*>(library->GetClassLoader()) != declaring_class_loader) { 222 // We only search libraries loaded by the appropriate ClassLoader. 223 continue; 224 } 225 // Try the short name then the long name... 226 void* fn; 227 if (library->NeedsNativeBridge()) { 228 const char* shorty = m->GetShorty(); 229 fn = library->FindSymbolWithNativeBridge(jni_short_name, shorty); 230 if (fn == nullptr) { 231 fn = library->FindSymbolWithNativeBridge(jni_long_name, shorty); 232 } 233 } else { 234 fn = library->FindSymbol(jni_short_name); 235 if (fn == nullptr) { 236 fn = library->FindSymbol(jni_long_name); 237 } 238 } 239 if (fn != nullptr) { 240 VLOG(jni) << "[Found native code for " << PrettyMethod(m) 241 << " in \"" << library->GetPath() << "\"]"; 242 return fn; 243 } 244 } 245 detail += "No implementation found for "; 246 detail += PrettyMethod(m); 247 detail += " (tried " + jni_short_name + " and " + jni_long_name + ")"; 248 LOG(ERROR) << detail; 249 return nullptr; 250 } 251 252 private: 253 AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibraries> libraries_; 254 }; 255 256 257 class JII { 258 public: 259 static jint DestroyJavaVM(JavaVM* vm) { 260 if (vm == nullptr) { 261 return JNI_ERR; 262 } 263 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 264 delete raw_vm->GetRuntime(); 265 return JNI_OK; 266 } 267 268 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 269 return AttachCurrentThreadInternal(vm, p_env, thr_args, false); 270 } 271 272 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 273 return AttachCurrentThreadInternal(vm, p_env, thr_args, true); 274 } 275 276 static jint DetachCurrentThread(JavaVM* vm) { 277 if (vm == nullptr || Thread::Current() == nullptr) { 278 return JNI_ERR; 279 } 280 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 281 Runtime* runtime = raw_vm->GetRuntime(); 282 runtime->DetachCurrentThread(); 283 return JNI_OK; 284 } 285 286 static jint GetEnv(JavaVM* vm, void** env, jint version) { 287 // GetEnv always returns a JNIEnv* for the most current supported JNI version, 288 // and unlike other calls that take a JNI version doesn't care if you supply 289 // JNI_VERSION_1_1, which we don't otherwise support. 290 if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) { 291 LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version; 292 return JNI_EVERSION; 293 } 294 if (vm == nullptr || env == nullptr) { 295 return JNI_ERR; 296 } 297 Thread* thread = Thread::Current(); 298 if (thread == nullptr) { 299 *env = nullptr; 300 return JNI_EDETACHED; 301 } 302 *env = thread->GetJniEnv(); 303 return JNI_OK; 304 } 305 306 private: 307 static jint AttachCurrentThreadInternal(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) { 308 if (vm == nullptr || p_env == nullptr) { 309 return JNI_ERR; 310 } 311 312 // Return immediately if we're already attached. 313 Thread* self = Thread::Current(); 314 if (self != nullptr) { 315 *p_env = self->GetJniEnv(); 316 return JNI_OK; 317 } 318 319 Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->GetRuntime(); 320 321 // No threads allowed in zygote mode. 322 if (runtime->IsZygote()) { 323 LOG(ERROR) << "Attempt to attach a thread in the zygote"; 324 return JNI_ERR; 325 } 326 327 JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args); 328 const char* thread_name = nullptr; 329 jobject thread_group = nullptr; 330 if (args != nullptr) { 331 if (IsBadJniVersion(args->version)) { 332 LOG(ERROR) << "Bad JNI version passed to " 333 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": " 334 << args->version; 335 return JNI_EVERSION; 336 } 337 thread_name = args->name; 338 thread_group = args->group; 339 } 340 341 if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, 342 !runtime->IsAotCompiler())) { 343 *p_env = nullptr; 344 return JNI_ERR; 345 } else { 346 *p_env = Thread::Current()->GetJniEnv(); 347 return JNI_OK; 348 } 349 } 350 }; 351 352 const JNIInvokeInterface gJniInvokeInterface = { 353 nullptr, // reserved0 354 nullptr, // reserved1 355 nullptr, // reserved2 356 JII::DestroyJavaVM, 357 JII::AttachCurrentThread, 358 JII::DetachCurrentThread, 359 JII::GetEnv, 360 JII::AttachCurrentThreadAsDaemon 361 }; 362 363 JavaVMExt::JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options) 364 : runtime_(runtime), 365 check_jni_abort_hook_(nullptr), 366 check_jni_abort_hook_data_(nullptr), 367 check_jni_(false), // Initialized properly in the constructor body below. 368 force_copy_(runtime_options.Exists(RuntimeArgumentMap::JniOptsForceCopy)), 369 tracing_enabled_(runtime_options.Exists(RuntimeArgumentMap::JniTrace) 370 || VLOG_IS_ON(third_party_jni)), 371 trace_(runtime_options.GetOrDefault(RuntimeArgumentMap::JniTrace)), 372 globals_lock_("JNI global reference table lock"), 373 globals_(gGlobalsInitial, gGlobalsMax, kGlobal), 374 libraries_(new Libraries), 375 unchecked_functions_(&gJniInvokeInterface), 376 weak_globals_lock_("JNI weak global reference table lock"), 377 weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal), 378 allow_new_weak_globals_(true), 379 weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) { 380 functions = unchecked_functions_; 381 SetCheckJniEnabled(runtime_options.Exists(RuntimeArgumentMap::CheckJni)); 382 } 383 384 JavaVMExt::~JavaVMExt() { 385 } 386 387 void JavaVMExt::JniAbort(const char* jni_function_name, const char* msg) { 388 Thread* self = Thread::Current(); 389 ScopedObjectAccess soa(self); 390 ArtMethod* current_method = self->GetCurrentMethod(nullptr); 391 392 std::ostringstream os; 393 os << "JNI DETECTED ERROR IN APPLICATION: " << msg; 394 395 if (jni_function_name != nullptr) { 396 os << "\n in call to " << jni_function_name; 397 } 398 // TODO: is this useful given that we're about to dump the calling thread's stack? 399 if (current_method != nullptr) { 400 os << "\n from " << PrettyMethod(current_method); 401 } 402 os << "\n"; 403 self->Dump(os); 404 405 if (check_jni_abort_hook_ != nullptr) { 406 check_jni_abort_hook_(check_jni_abort_hook_data_, os.str()); 407 } else { 408 // Ensure that we get a native stack trace for this thread. 409 self->TransitionFromRunnableToSuspended(kNative); 410 LOG(FATAL) << os.str(); 411 self->TransitionFromSuspendedToRunnable(); // Unreachable, keep annotalysis happy. 412 } 413 } 414 415 void JavaVMExt::JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) { 416 std::string msg; 417 StringAppendV(&msg, fmt, ap); 418 JniAbort(jni_function_name, msg.c_str()); 419 } 420 421 void JavaVMExt::JniAbortF(const char* jni_function_name, const char* fmt, ...) { 422 va_list args; 423 va_start(args, fmt); 424 JniAbortV(jni_function_name, fmt, args); 425 va_end(args); 426 } 427 428 bool JavaVMExt::ShouldTrace(ArtMethod* method) { 429 // Fast where no tracing is enabled. 430 if (trace_.empty() && !VLOG_IS_ON(third_party_jni)) { 431 return false; 432 } 433 // Perform checks based on class name. 434 StringPiece class_name(method->GetDeclaringClassDescriptor()); 435 if (!trace_.empty() && class_name.find(trace_) != std::string::npos) { 436 return true; 437 } 438 if (!VLOG_IS_ON(third_party_jni)) { 439 return false; 440 } 441 // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look 442 // like part of Android. 443 static const char* gBuiltInPrefixes[] = { 444 "Landroid/", 445 "Lcom/android/", 446 "Lcom/google/android/", 447 "Ldalvik/", 448 "Ljava/", 449 "Ljavax/", 450 "Llibcore/", 451 "Lorg/apache/harmony/", 452 }; 453 for (size_t i = 0; i < arraysize(gBuiltInPrefixes); ++i) { 454 if (class_name.starts_with(gBuiltInPrefixes[i])) { 455 return false; 456 } 457 } 458 return true; 459 } 460 461 jobject JavaVMExt::AddGlobalRef(Thread* self, mirror::Object* obj) { 462 // Check for null after decoding the object to handle cleared weak globals. 463 if (obj == nullptr) { 464 return nullptr; 465 } 466 WriterMutexLock mu(self, globals_lock_); 467 IndirectRef ref = globals_.Add(IRT_FIRST_SEGMENT, obj); 468 return reinterpret_cast<jobject>(ref); 469 } 470 471 jweak JavaVMExt::AddWeakGlobalRef(Thread* self, mirror::Object* obj) { 472 if (obj == nullptr) { 473 return nullptr; 474 } 475 MutexLock mu(self, weak_globals_lock_); 476 while (UNLIKELY(!allow_new_weak_globals_)) { 477 weak_globals_add_condition_.WaitHoldingLocks(self); 478 } 479 IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj); 480 return reinterpret_cast<jweak>(ref); 481 } 482 483 void JavaVMExt::DeleteGlobalRef(Thread* self, jobject obj) { 484 if (obj == nullptr) { 485 return; 486 } 487 WriterMutexLock mu(self, globals_lock_); 488 if (!globals_.Remove(IRT_FIRST_SEGMENT, obj)) { 489 LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") " 490 << "failed to find entry"; 491 } 492 } 493 494 void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) { 495 if (obj == nullptr) { 496 return; 497 } 498 MutexLock mu(self, weak_globals_lock_); 499 if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) { 500 LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") " 501 << "failed to find entry"; 502 } 503 } 504 505 static void ThreadEnableCheckJni(Thread* thread, void* arg) { 506 bool* check_jni = reinterpret_cast<bool*>(arg); 507 thread->GetJniEnv()->SetCheckJniEnabled(*check_jni); 508 } 509 510 bool JavaVMExt::SetCheckJniEnabled(bool enabled) { 511 bool old_check_jni = check_jni_; 512 check_jni_ = enabled; 513 functions = enabled ? GetCheckJniInvokeInterface() : unchecked_functions_; 514 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); 515 runtime_->GetThreadList()->ForEach(ThreadEnableCheckJni, &check_jni_); 516 return old_check_jni; 517 } 518 519 void JavaVMExt::DumpForSigQuit(std::ostream& os) { 520 os << "JNI: CheckJNI is " << (check_jni_ ? "on" : "off"); 521 if (force_copy_) { 522 os << " (with forcecopy)"; 523 } 524 Thread* self = Thread::Current(); 525 { 526 ReaderMutexLock mu(self, globals_lock_); 527 os << "; globals=" << globals_.Capacity(); 528 } 529 { 530 MutexLock mu(self, weak_globals_lock_); 531 if (weak_globals_.Capacity() > 0) { 532 os << " (plus " << weak_globals_.Capacity() << " weak)"; 533 } 534 } 535 os << '\n'; 536 537 { 538 MutexLock mu(self, *Locks::jni_libraries_lock_); 539 os << "Libraries: " << Dumpable<Libraries>(*libraries_) << " (" << libraries_->size() << ")\n"; 540 } 541 } 542 543 void JavaVMExt::DisallowNewWeakGlobals() { 544 MutexLock mu(Thread::Current(), weak_globals_lock_); 545 allow_new_weak_globals_ = false; 546 } 547 548 void JavaVMExt::AllowNewWeakGlobals() { 549 Thread* self = Thread::Current(); 550 MutexLock mu(self, weak_globals_lock_); 551 allow_new_weak_globals_ = true; 552 weak_globals_add_condition_.Broadcast(self); 553 } 554 555 void JavaVMExt::EnsureNewWeakGlobalsDisallowed() { 556 // Lock and unlock once to ensure that no threads are still in the 557 // middle of adding new weak globals. 558 MutexLock mu(Thread::Current(), weak_globals_lock_); 559 CHECK(!allow_new_weak_globals_); 560 } 561 562 mirror::Object* JavaVMExt::DecodeGlobal(Thread* self, IndirectRef ref) { 563 return globals_.SynchronizedGet(self, &globals_lock_, ref); 564 } 565 566 void JavaVMExt::UpdateGlobal(Thread* self, IndirectRef ref, mirror::Object* result) { 567 WriterMutexLock mu(self, globals_lock_); 568 globals_.Update(ref, result); 569 } 570 571 mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) { 572 MutexLock mu(self, weak_globals_lock_); 573 while (UNLIKELY(!allow_new_weak_globals_)) { 574 weak_globals_add_condition_.WaitHoldingLocks(self); 575 } 576 return weak_globals_.Get(ref); 577 } 578 579 void JavaVMExt::UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result) { 580 MutexLock mu(self, weak_globals_lock_); 581 weak_globals_.Update(ref, result); 582 } 583 584 void JavaVMExt::DumpReferenceTables(std::ostream& os) { 585 Thread* self = Thread::Current(); 586 { 587 ReaderMutexLock mu(self, globals_lock_); 588 globals_.Dump(os); 589 } 590 { 591 MutexLock mu(self, weak_globals_lock_); 592 weak_globals_.Dump(os); 593 } 594 } 595 596 bool JavaVMExt::LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject class_loader, 597 std::string* error_msg) { 598 error_msg->clear(); 599 600 // See if we've already loaded this library. If we have, and the class loader 601 // matches, return successfully without doing anything. 602 // TODO: for better results we should canonicalize the pathname (or even compare 603 // inodes). This implementation is fine if everybody is using System.loadLibrary. 604 SharedLibrary* library; 605 Thread* self = Thread::Current(); 606 { 607 // TODO: move the locking (and more of this logic) into Libraries. 608 MutexLock mu(self, *Locks::jni_libraries_lock_); 609 library = libraries_->Get(path); 610 } 611 if (library != nullptr) { 612 if (env->IsSameObject(library->GetClassLoader(), class_loader) == JNI_FALSE) { 613 // The library will be associated with class_loader. The JNI 614 // spec says we can't load the same library into more than one 615 // class loader. 616 StringAppendF(error_msg, "Shared library \"%s\" already opened by " 617 "ClassLoader %p; can't open in ClassLoader %p", 618 path.c_str(), library->GetClassLoader(), class_loader); 619 LOG(WARNING) << error_msg; 620 return false; 621 } 622 VLOG(jni) << "[Shared library \"" << path << "\" already loaded in " 623 << " ClassLoader " << class_loader << "]"; 624 if (!library->CheckOnLoadResult()) { 625 StringAppendF(error_msg, "JNI_OnLoad failed on a previous attempt " 626 "to load \"%s\"", path.c_str()); 627 return false; 628 } 629 return true; 630 } 631 632 // Open the shared library. Because we're using a full path, the system 633 // doesn't have to search through LD_LIBRARY_PATH. (It may do so to 634 // resolve this library's dependencies though.) 635 636 // Failures here are expected when java.library.path has several entries 637 // and we have to hunt for the lib. 638 639 // Below we dlopen but there is no paired dlclose, this would be necessary if we supported 640 // class unloading. Libraries will only be unloaded when the reference count (incremented by 641 // dlopen) becomes zero from dlclose. 642 643 Locks::mutator_lock_->AssertNotHeld(self); 644 const char* path_str = path.empty() ? nullptr : path.c_str(); 645 void* handle = dlopen(path_str, RTLD_NOW); 646 bool needs_native_bridge = false; 647 if (handle == nullptr) { 648 if (android::NativeBridgeIsSupported(path_str)) { 649 handle = android::NativeBridgeLoadLibrary(path_str, RTLD_NOW); 650 needs_native_bridge = true; 651 } 652 } 653 654 VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_NOW) returned " << handle << "]"; 655 656 if (handle == nullptr) { 657 *error_msg = dlerror(); 658 VLOG(jni) << "dlopen(\"" << path << "\", RTLD_NOW) failed: " << *error_msg; 659 return false; 660 } 661 662 if (env->ExceptionCheck() == JNI_TRUE) { 663 LOG(ERROR) << "Unexpected exception:"; 664 env->ExceptionDescribe(); 665 env->ExceptionClear(); 666 } 667 // Create a new entry. 668 // TODO: move the locking (and more of this logic) into Libraries. 669 bool created_library = false; 670 { 671 // Create SharedLibrary ahead of taking the libraries lock to maintain lock ordering. 672 std::unique_ptr<SharedLibrary> new_library( 673 new SharedLibrary(env, self, path, handle, class_loader)); 674 MutexLock mu(self, *Locks::jni_libraries_lock_); 675 library = libraries_->Get(path); 676 if (library == nullptr) { // We won race to get libraries_lock. 677 library = new_library.release(); 678 libraries_->Put(path, library); 679 created_library = true; 680 } 681 } 682 if (!created_library) { 683 LOG(INFO) << "WOW: we lost a race to add shared library: " 684 << "\"" << path << "\" ClassLoader=" << class_loader; 685 return library->CheckOnLoadResult(); 686 } 687 VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]"; 688 689 bool was_successful = false; 690 void* sym; 691 if (needs_native_bridge) { 692 library->SetNeedsNativeBridge(); 693 sym = library->FindSymbolWithNativeBridge("JNI_OnLoad", nullptr); 694 } else { 695 sym = dlsym(handle, "JNI_OnLoad"); 696 } 697 if (sym == nullptr) { 698 VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]"; 699 was_successful = true; 700 } else { 701 // Call JNI_OnLoad. We have to override the current class 702 // loader, which will always be "null" since the stuff at the 703 // top of the stack is around Runtime.loadLibrary(). (See 704 // the comments in the JNI FindClass function.) 705 ScopedLocalRef<jobject> old_class_loader(env, env->NewLocalRef(self->GetClassLoaderOverride())); 706 self->SetClassLoaderOverride(class_loader); 707 708 VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]"; 709 typedef int (*JNI_OnLoadFn)(JavaVM*, void*); 710 JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym); 711 int version = (*jni_on_load)(this, nullptr); 712 713 if (runtime_->GetTargetSdkVersion() != 0 && runtime_->GetTargetSdkVersion() <= 21) { 714 fault_manager.EnsureArtActionInFrontOfSignalChain(); 715 } 716 717 self->SetClassLoaderOverride(old_class_loader.get()); 718 719 if (version == JNI_ERR) { 720 StringAppendF(error_msg, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str()); 721 } else if (IsBadJniVersion(version)) { 722 StringAppendF(error_msg, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d", 723 path.c_str(), version); 724 // It's unwise to call dlclose() here, but we can mark it 725 // as bad and ensure that future load attempts will fail. 726 // We don't know how far JNI_OnLoad got, so there could 727 // be some partially-initialized stuff accessible through 728 // newly-registered native method calls. We could try to 729 // unregister them, but that doesn't seem worthwhile. 730 } else { 731 was_successful = true; 732 } 733 VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure") 734 << " from JNI_OnLoad in \"" << path << "\"]"; 735 } 736 737 library->SetResult(was_successful); 738 return was_successful; 739 } 740 741 void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) { 742 CHECK(m->IsNative()); 743 mirror::Class* c = m->GetDeclaringClass(); 744 // If this is a static method, it could be called before the class has been initialized. 745 CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m); 746 std::string detail; 747 void* native_method; 748 Thread* self = Thread::Current(); 749 { 750 MutexLock mu(self, *Locks::jni_libraries_lock_); 751 native_method = libraries_->FindNativeMethod(m, detail); 752 } 753 // Throwing can cause libraries_lock to be reacquired. 754 if (native_method == nullptr) { 755 self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str()); 756 } 757 return native_method; 758 } 759 760 void JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) { 761 MutexLock mu(Thread::Current(), weak_globals_lock_); 762 Runtime* const runtime = Runtime::Current(); 763 for (auto* entry : weak_globals_) { 764 // Need to skip null here to distinguish between null entries and cleared weak ref entries. 765 if (!entry->IsNull()) { 766 // Since this is called by the GC, we don't need a read barrier. 767 mirror::Object* obj = entry->Read<kWithoutReadBarrier>(); 768 mirror::Object* new_obj = callback(obj, arg); 769 if (new_obj == nullptr) { 770 new_obj = runtime->GetClearedJniWeakGlobal(); 771 } 772 *entry = GcRoot<mirror::Object>(new_obj); 773 } 774 } 775 } 776 777 void JavaVMExt::TrimGlobals() { 778 WriterMutexLock mu(Thread::Current(), globals_lock_); 779 globals_.Trim(); 780 } 781 782 void JavaVMExt::VisitRoots(RootVisitor* visitor) { 783 Thread* self = Thread::Current(); 784 ReaderMutexLock mu(self, globals_lock_); 785 globals_.VisitRoots(visitor, RootInfo(kRootJNIGlobal)); 786 // The weak_globals table is visited by the GC itself (because it mutates the table). 787 } 788 789 // JNI Invocation interface. 790 791 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { 792 ATRACE_BEGIN(__FUNCTION__); 793 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args); 794 if (IsBadJniVersion(args->version)) { 795 LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version; 796 ATRACE_END(); 797 return JNI_EVERSION; 798 } 799 RuntimeOptions options; 800 for (int i = 0; i < args->nOptions; ++i) { 801 JavaVMOption* option = &args->options[i]; 802 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo)); 803 } 804 bool ignore_unrecognized = args->ignoreUnrecognized; 805 if (!Runtime::Create(options, ignore_unrecognized)) { 806 ATRACE_END(); 807 return JNI_ERR; 808 } 809 Runtime* runtime = Runtime::Current(); 810 bool started = runtime->Start(); 811 if (!started) { 812 delete Thread::Current()->GetJniEnv(); 813 delete runtime->GetJavaVM(); 814 LOG(WARNING) << "CreateJavaVM failed"; 815 ATRACE_END(); 816 return JNI_ERR; 817 } 818 *p_env = Thread::Current()->GetJniEnv(); 819 *p_vm = runtime->GetJavaVM(); 820 ATRACE_END(); 821 return JNI_OK; 822 } 823 824 extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms_buf, jsize buf_len, jsize* vm_count) { 825 Runtime* runtime = Runtime::Current(); 826 if (runtime == nullptr || buf_len == 0) { 827 *vm_count = 0; 828 } else { 829 *vm_count = 1; 830 vms_buf[0] = runtime->GetJavaVM(); 831 } 832 return JNI_OK; 833 } 834 835 // Historically unsupported. 836 extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) { 837 return JNI_ERR; 838 } 839 840 } // namespace art 841