Home | History | Annotate | Download | only in runtime
      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