• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "java_vm_ext-inl.h"
18 
19 #include <dlfcn.h>
20 #include <string_view>
21 
22 #include "android-base/stringprintf.h"
23 
24 #include "art_method-inl.h"
25 #include "base/dumpable.h"
26 #include "base/mutex-inl.h"
27 #include "base/sdk_version.h"
28 #include "base/stl_util.h"
29 #include "base/string_view_cpp20.h"
30 #include "base/systrace.h"
31 #include "check_jni.h"
32 #include "dex/dex_file-inl.h"
33 #include "entrypoints/entrypoint_utils-inl.h"
34 #include "fault_handler.h"
35 #include "gc/allocation_record.h"
36 #include "gc/heap.h"
37 #include "gc_root-inl.h"
38 #include "indirect_reference_table-inl.h"
39 #include "jni_internal.h"
40 #include "mirror/class-inl.h"
41 #include "mirror/class_loader.h"
42 #include "mirror/dex_cache-inl.h"
43 #include "nativebridge/native_bridge.h"
44 #include "nativehelper/scoped_local_ref.h"
45 #include "nativehelper/scoped_utf_chars.h"
46 #include "nativeloader/native_loader.h"
47 #include "object_callbacks.h"
48 #include "parsed_options.h"
49 #include "runtime-inl.h"
50 #include "runtime_options.h"
51 #include "scoped_thread_state_change-inl.h"
52 #include "sigchain.h"
53 #include "thread-inl.h"
54 #include "thread_list.h"
55 #include "ti/agent.h"
56 #include "well_known_classes.h"
57 
58 namespace art {
59 
60 using android::base::StringAppendF;
61 using android::base::StringAppendV;
62 
63 // Maximum number of global references (must fit in 16 bits).
64 static constexpr size_t kGlobalsMax = 51200;
65 
66 // Maximum number of weak global references (must fit in 16 bits).
67 static constexpr size_t kWeakGlobalsMax = 51200;
68 
IsBadJniVersion(int version)69 bool JavaVMExt::IsBadJniVersion(int version) {
70   // We don't support JNI_VERSION_1_1. These are the only other valid versions.
71   return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
72 }
73 
74 class SharedLibrary {
75  public:
SharedLibrary(JNIEnv * env,Thread * self,const std::string & path,void * handle,bool needs_native_bridge,jobject class_loader,void * class_loader_allocator)76   SharedLibrary(JNIEnv* env, Thread* self, const std::string& path, void* handle,
77                 bool needs_native_bridge, jobject class_loader, void* class_loader_allocator)
78       : path_(path),
79         handle_(handle),
80         needs_native_bridge_(needs_native_bridge),
81         class_loader_(env->NewWeakGlobalRef(class_loader)),
82         class_loader_allocator_(class_loader_allocator),
83         jni_on_load_lock_("JNI_OnLoad lock"),
84         jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
85         jni_on_load_thread_id_(self->GetThreadId()),
86         jni_on_load_result_(kPending) {
87     CHECK(class_loader_allocator_ != nullptr);
88   }
89 
~SharedLibrary()90   ~SharedLibrary() {
91     Thread* self = Thread::Current();
92     if (self != nullptr) {
93       self->GetJniEnv()->DeleteWeakGlobalRef(class_loader_);
94     }
95 
96     char* error_msg = nullptr;
97     if (!android::CloseNativeLibrary(handle_, needs_native_bridge_, &error_msg)) {
98       LOG(WARNING) << "Error while unloading native library \"" << path_ << "\": " << error_msg;
99       android::NativeLoaderFreeErrorMessage(error_msg);
100     }
101   }
102 
GetClassLoader() const103   jweak GetClassLoader() const {
104     return class_loader_;
105   }
106 
GetClassLoaderAllocator() const107   const void* GetClassLoaderAllocator() const {
108     return class_loader_allocator_;
109   }
110 
GetPath() const111   const std::string& GetPath() const {
112     return path_;
113   }
114 
115   /*
116    * Check the result of an earlier call to JNI_OnLoad on this library.
117    * If the call has not yet finished in another thread, wait for it.
118    */
CheckOnLoadResult()119   bool CheckOnLoadResult()
120       REQUIRES(!jni_on_load_lock_) {
121     Thread* self = Thread::Current();
122     bool okay;
123     {
124       MutexLock mu(self, jni_on_load_lock_);
125 
126       if (jni_on_load_thread_id_ == self->GetThreadId()) {
127         // Check this so we don't end up waiting for ourselves.  We need to return "true" so the
128         // caller can continue.
129         LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
130         okay = true;
131       } else {
132         while (jni_on_load_result_ == kPending) {
133           VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
134           jni_on_load_cond_.Wait(self);
135         }
136 
137         okay = (jni_on_load_result_ == kOkay);
138         VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
139             << (okay ? "succeeded" : "failed") << "]";
140       }
141     }
142     return okay;
143   }
144 
SetResult(bool result)145   void SetResult(bool result) REQUIRES(!jni_on_load_lock_) {
146     Thread* self = Thread::Current();
147     MutexLock mu(self, jni_on_load_lock_);
148 
149     jni_on_load_result_ = result ? kOkay : kFailed;
150     jni_on_load_thread_id_ = 0;
151 
152     // Broadcast a wakeup to anybody sleeping on the condition variable.
153     jni_on_load_cond_.Broadcast(self);
154   }
155 
SetNeedsNativeBridge(bool needs)156   void SetNeedsNativeBridge(bool needs) {
157     needs_native_bridge_ = needs;
158   }
159 
NeedsNativeBridge() const160   bool NeedsNativeBridge() const {
161     return needs_native_bridge_;
162   }
163 
164   // No mutator lock since dlsym may block for a while if another thread is doing dlopen.
FindSymbol(const std::string & symbol_name,const char * shorty=nullptr)165   void* FindSymbol(const std::string& symbol_name, const char* shorty = nullptr)
166       REQUIRES(!Locks::mutator_lock_) {
167     return NeedsNativeBridge()
168         ? FindSymbolWithNativeBridge(symbol_name, shorty)
169         : FindSymbolWithoutNativeBridge(symbol_name);
170   }
171 
172   // No mutator lock since dlsym may block for a while if another thread is doing dlopen.
FindSymbolWithoutNativeBridge(const std::string & symbol_name)173   void* FindSymbolWithoutNativeBridge(const std::string& symbol_name)
174       REQUIRES(!Locks::mutator_lock_) {
175     CHECK(!NeedsNativeBridge());
176 
177     return dlsym(handle_, symbol_name.c_str());
178   }
179 
FindSymbolWithNativeBridge(const std::string & symbol_name,const char * shorty)180   void* FindSymbolWithNativeBridge(const std::string& symbol_name, const char* shorty)
181       REQUIRES(!Locks::mutator_lock_) {
182     CHECK(NeedsNativeBridge());
183 
184     uint32_t len = 0;
185     return android::NativeBridgeGetTrampoline(handle_, symbol_name.c_str(), shorty, len);
186   }
187 
188  private:
189   enum JNI_OnLoadState {
190     kPending,
191     kFailed,
192     kOkay,
193   };
194 
195   // Path to library "/system/lib/libjni.so".
196   const std::string path_;
197 
198   // The void* returned by dlopen(3).
199   void* const handle_;
200 
201   // True if a native bridge is required.
202   bool needs_native_bridge_;
203 
204   // The ClassLoader this library is associated with, a weak global JNI reference that is
205   // created/deleted with the scope of the library.
206   const jweak class_loader_;
207   // Used to do equality check on class loaders so we can avoid decoding the weak root and read
208   // barriers that mess with class unloading.
209   const void* class_loader_allocator_;
210 
211   // Guards remaining items.
212   Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
213   // Wait for JNI_OnLoad in other thread.
214   ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
215   // Recursive invocation guard.
216   uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
217   // Result of earlier JNI_OnLoad call.
218   JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
219 };
220 
221 // This exists mainly to keep implementation details out of the header file.
222 class Libraries {
223  public:
Libraries()224   Libraries() {
225   }
226 
~Libraries()227   ~Libraries() {
228     STLDeleteValues(&libraries_);
229   }
230 
231   // NO_THREAD_SAFETY_ANALYSIS as this is during runtime shutdown, and we have
232   // no thread to lock this with.
UnloadBootNativeLibraries(JavaVM * vm) const233   void UnloadBootNativeLibraries(JavaVM* vm) const NO_THREAD_SAFETY_ANALYSIS {
234     CHECK(Thread::Current() == nullptr);
235     std::vector<SharedLibrary*> unload_libraries;
236     for (auto it = libraries_.begin(); it != libraries_.end(); ++it) {
237       SharedLibrary* const library = it->second;
238       if (library->GetClassLoader() == nullptr) {
239         unload_libraries.push_back(library);
240       }
241     }
242     UnloadLibraries(vm, unload_libraries);
243   }
244 
245   // NO_THREAD_SAFETY_ANALYSIS since this may be called from Dumpable. Dumpable can't be annotated
246   // properly due to the template. The caller should be holding the jni_libraries_lock_.
Dump(std::ostream & os) const247   void Dump(std::ostream& os) const NO_THREAD_SAFETY_ANALYSIS {
248     Locks::jni_libraries_lock_->AssertHeld(Thread::Current());
249     bool first = true;
250     for (const auto& library : libraries_) {
251       if (!first) {
252         os << ' ';
253       }
254       first = false;
255       os << library.first;
256     }
257   }
258 
size() const259   size_t size() const REQUIRES(Locks::jni_libraries_lock_) {
260     return libraries_.size();
261   }
262 
Get(const std::string & path)263   SharedLibrary* Get(const std::string& path) REQUIRES(Locks::jni_libraries_lock_) {
264     auto it = libraries_.find(path);
265     return (it == libraries_.end()) ? nullptr : it->second;
266   }
267 
Put(const std::string & path,SharedLibrary * library)268   void Put(const std::string& path, SharedLibrary* library)
269       REQUIRES(Locks::jni_libraries_lock_) {
270     libraries_.Put(path, library);
271   }
272 
273   // See section 11.3 "Linking Native Methods" of the JNI spec.
FindNativeMethod(Thread * self,ArtMethod * m,std::string * detail,bool can_suspend)274   void* FindNativeMethod(Thread* self, ArtMethod* m, std::string* detail, bool can_suspend)
275       REQUIRES(!Locks::jni_libraries_lock_)
276       REQUIRES_SHARED(Locks::mutator_lock_) {
277     std::string jni_short_name(m->JniShortName());
278     std::string jni_long_name(m->JniLongName());
279     const ObjPtr<mirror::ClassLoader> declaring_class_loader =
280         m->GetDeclaringClass()->GetClassLoader();
281     void* const declaring_class_loader_allocator =
282         Runtime::Current()->GetClassLinker()->GetAllocatorForClassLoader(declaring_class_loader);
283     CHECK(declaring_class_loader_allocator != nullptr);
284     // TODO: Avoid calling GetShorty here to prevent dirtying dex pages?
285     const char* shorty = m->GetShorty();
286     void* native_code = nullptr;
287     if (can_suspend) {
288       // Go to suspended since dlsym may block for a long time if other threads are using dlopen.
289       ScopedThreadSuspension sts(self, ThreadState::kNative);
290       native_code = FindNativeMethodInternal(self,
291                                              declaring_class_loader_allocator,
292                                              shorty,
293                                              jni_short_name,
294                                              jni_long_name);
295     } else {
296       native_code = FindNativeMethodInternal(self,
297                                              declaring_class_loader_allocator,
298                                              shorty,
299                                              jni_short_name,
300                                              jni_long_name);
301     }
302     if (native_code != nullptr) {
303       return native_code;
304     }
305     if (detail != nullptr) {
306       *detail += "No implementation found for ";
307       *detail += m->PrettyMethod();
308       *detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
309     }
310     return nullptr;
311   }
312 
FindNativeMethodInternal(Thread * self,void * declaring_class_loader_allocator,const char * shorty,const std::string & jni_short_name,const std::string & jni_long_name)313   void* FindNativeMethodInternal(Thread* self,
314                                  void* declaring_class_loader_allocator,
315                                  const char* shorty,
316                                  const std::string& jni_short_name,
317                                  const std::string& jni_long_name)
318       REQUIRES(!Locks::jni_libraries_lock_) {
319     MutexLock mu(self, *Locks::jni_libraries_lock_);
320     for (const auto& lib : libraries_) {
321       SharedLibrary* const library = lib.second;
322       // Use the allocator address for class loader equality to avoid unnecessary weak root decode.
323       if (library->GetClassLoaderAllocator() != declaring_class_loader_allocator) {
324         // We only search libraries loaded by the appropriate ClassLoader.
325         continue;
326       }
327       // Try the short name then the long name...
328       const char* arg_shorty = library->NeedsNativeBridge() ? shorty : nullptr;
329       void* fn = library->FindSymbol(jni_short_name, arg_shorty);
330       if (fn == nullptr) {
331         fn = library->FindSymbol(jni_long_name, arg_shorty);
332       }
333       if (fn != nullptr) {
334         VLOG(jni) << "[Found native code for " << jni_long_name
335                   << " in \"" << library->GetPath() << "\"]";
336         return fn;
337       }
338     }
339     return nullptr;
340   }
341 
342   // Unload native libraries with cleared class loaders.
UnloadNativeLibraries()343   void UnloadNativeLibraries()
344       REQUIRES(!Locks::jni_libraries_lock_)
345       REQUIRES_SHARED(Locks::mutator_lock_) {
346     Thread* const self = Thread::Current();
347     std::vector<SharedLibrary*> unload_libraries;
348     {
349       MutexLock mu(self, *Locks::jni_libraries_lock_);
350       for (auto it = libraries_.begin(); it != libraries_.end(); ) {
351         SharedLibrary* const library = it->second;
352         // If class loader is null then it was unloaded, call JNI_OnUnload.
353         const jweak class_loader = library->GetClassLoader();
354         // If class_loader is a null jobject then it is the boot class loader. We should not unload
355         // the native libraries of the boot class loader.
356         if (class_loader != nullptr && self->IsJWeakCleared(class_loader)) {
357           unload_libraries.push_back(library);
358           it = libraries_.erase(it);
359         } else {
360           ++it;
361         }
362       }
363     }
364     ScopedThreadSuspension sts(self, ThreadState::kNative);
365     // Do this without holding the jni libraries lock to prevent possible deadlocks.
366     UnloadLibraries(self->GetJniEnv()->GetVm(), unload_libraries);
367     for (auto library : unload_libraries) {
368       delete library;
369     }
370   }
371 
UnloadLibraries(JavaVM * vm,const std::vector<SharedLibrary * > & libraries)372   static void UnloadLibraries(JavaVM* vm, const std::vector<SharedLibrary*>& libraries) {
373     using JNI_OnUnloadFn = void(*)(JavaVM*, void*);
374     for (SharedLibrary* library : libraries) {
375       void* const sym = library->FindSymbol("JNI_OnUnload", nullptr);
376       if (sym == nullptr) {
377         VLOG(jni) << "[No JNI_OnUnload found in \"" << library->GetPath() << "\"]";
378       } else {
379         VLOG(jni) << "[JNI_OnUnload found for \"" << library->GetPath() << "\"]: Calling...";
380         JNI_OnUnloadFn jni_on_unload = reinterpret_cast<JNI_OnUnloadFn>(sym);
381         jni_on_unload(vm, nullptr);
382       }
383     }
384   }
385 
386  private:
387   AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibraries> libraries_
388       GUARDED_BY(Locks::jni_libraries_lock_);
389 };
390 
391 class JII {
392  public:
DestroyJavaVM(JavaVM * vm)393   static jint DestroyJavaVM(JavaVM* vm) {
394     if (vm == nullptr) {
395       return JNI_ERR;
396     }
397     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
398 
399     // Wait for all non-dameon threads to terminate before we start destroying
400     // bits of the runtime. Thread list deletion will repeat this in case more
401     // threads are created by daemons in the meantime.
402     raw_vm->GetRuntime()->GetThreadList()
403           ->WaitForOtherNonDaemonThreadsToExit(/*check_no_birth=*/ false);
404 
405     delete raw_vm->GetRuntime();
406     android::ResetNativeLoader();
407     return JNI_OK;
408   }
409 
AttachCurrentThread(JavaVM * vm,JNIEnv ** p_env,void * thr_args)410   static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
411     return AttachCurrentThreadInternal(vm, p_env, thr_args, false);
412   }
413 
AttachCurrentThreadAsDaemon(JavaVM * vm,JNIEnv ** p_env,void * thr_args)414   static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
415     return AttachCurrentThreadInternal(vm, p_env, thr_args, true);
416   }
417 
DetachCurrentThread(JavaVM * vm)418   static jint DetachCurrentThread(JavaVM* vm) {
419     if (vm == nullptr || Thread::Current() == nullptr) {
420       return JNI_ERR;
421     }
422     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
423     Runtime* runtime = raw_vm->GetRuntime();
424     runtime->DetachCurrentThread();
425     return JNI_OK;
426   }
427 
GetEnv(JavaVM * vm,void ** env,jint version)428   static jint GetEnv(JavaVM* vm, void** env, jint version) {
429     if (vm == nullptr || env == nullptr) {
430       return JNI_ERR;
431     }
432     Thread* thread = Thread::Current();
433     if (thread == nullptr) {
434       *env = nullptr;
435       return JNI_EDETACHED;
436     }
437     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
438     return raw_vm->HandleGetEnv(env, version);
439   }
440 
441  private:
AttachCurrentThreadInternal(JavaVM * vm,JNIEnv ** p_env,void * raw_args,bool as_daemon)442   static jint AttachCurrentThreadInternal(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
443     if (vm == nullptr || p_env == nullptr) {
444       return JNI_ERR;
445     }
446 
447     // Return immediately if we're already attached.
448     Thread* self = Thread::Current();
449     if (self != nullptr) {
450       *p_env = self->GetJniEnv();
451       return JNI_OK;
452     }
453 
454     Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->GetRuntime();
455 
456     // No threads allowed in zygote mode.
457     if (runtime->IsZygote()) {
458       LOG(ERROR) << "Attempt to attach a thread in the zygote";
459       return JNI_ERR;
460     }
461 
462     JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
463     const char* thread_name = nullptr;
464     jobject thread_group = nullptr;
465     if (args != nullptr) {
466       if (JavaVMExt::IsBadJniVersion(args->version)) {
467         LOG(ERROR) << "Bad JNI version passed to "
468                    << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
469                    << args->version;
470         return JNI_EVERSION;
471       }
472       thread_name = args->name;
473       thread_group = args->group;
474     }
475 
476     if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group,
477                                       !runtime->IsAotCompiler())) {
478       *p_env = nullptr;
479       return JNI_ERR;
480     } else {
481       *p_env = Thread::Current()->GetJniEnv();
482       return JNI_OK;
483     }
484   }
485 };
486 
487 const JNIInvokeInterface gJniInvokeInterface = {
488   nullptr,  // reserved0
489   nullptr,  // reserved1
490   nullptr,  // reserved2
491   JII::DestroyJavaVM,
492   JII::AttachCurrentThread,
493   JII::DetachCurrentThread,
494   JII::GetEnv,
495   JII::AttachCurrentThreadAsDaemon
496 };
497 
JavaVMExt(Runtime * runtime,const RuntimeArgumentMap & runtime_options,std::string * error_msg)498 JavaVMExt::JavaVMExt(Runtime* runtime,
499                      const RuntimeArgumentMap& runtime_options,
500                      std::string* error_msg)
501     : runtime_(runtime),
502       check_jni_abort_hook_(nullptr),
503       check_jni_abort_hook_data_(nullptr),
504       check_jni_(false),  // Initialized properly in the constructor body below.
505       force_copy_(runtime_options.Exists(RuntimeArgumentMap::JniOptsForceCopy)),
506       tracing_enabled_(runtime_options.Exists(RuntimeArgumentMap::JniTrace)
507                        || VLOG_IS_ON(third_party_jni)),
508       trace_(runtime_options.GetOrDefault(RuntimeArgumentMap::JniTrace)),
509       globals_(kGlobalsMax, kGlobal, IndirectReferenceTable::ResizableCapacity::kNo, error_msg),
510       libraries_(new Libraries),
511       unchecked_functions_(&gJniInvokeInterface),
512       weak_globals_(kWeakGlobalsMax,
513                     kWeakGlobal,
514                     IndirectReferenceTable::ResizableCapacity::kNo,
515                     error_msg),
516       allow_accessing_weak_globals_(true),
517       weak_globals_add_condition_("weak globals add condition",
518                                   (CHECK(Locks::jni_weak_globals_lock_ != nullptr),
519                                    *Locks::jni_weak_globals_lock_)),
520       env_hooks_lock_("environment hooks lock", art::kGenericBottomLock),
521       env_hooks_(),
522       enable_allocation_tracking_delta_(
523           runtime_options.GetOrDefault(RuntimeArgumentMap::GlobalRefAllocStackTraceLimit)),
524       allocation_tracking_enabled_(false),
525       old_allocation_tracking_state_(false) {
526   functions = unchecked_functions_;
527   SetCheckJniEnabled(runtime_options.Exists(RuntimeArgumentMap::CheckJni) || kIsDebugBuild);
528 }
529 
~JavaVMExt()530 JavaVMExt::~JavaVMExt() {
531   UnloadBootNativeLibraries();
532 }
533 
534 // Checking "globals" and "weak_globals" usually requires locks, but we
535 // don't need the locks to check for validity when constructing the
536 // object. Use NO_THREAD_SAFETY_ANALYSIS for this.
Create(Runtime * runtime,const RuntimeArgumentMap & runtime_options,std::string * error_msg)537 std::unique_ptr<JavaVMExt> JavaVMExt::Create(Runtime* runtime,
538                                              const RuntimeArgumentMap& runtime_options,
539                                              std::string* error_msg) NO_THREAD_SAFETY_ANALYSIS {
540   std::unique_ptr<JavaVMExt> java_vm(new JavaVMExt(runtime, runtime_options, error_msg));
541   if (java_vm && java_vm->globals_.IsValid() && java_vm->weak_globals_.IsValid()) {
542     return java_vm;
543   }
544   return nullptr;
545 }
546 
HandleGetEnv(void ** env,jint version)547 jint JavaVMExt::HandleGetEnv(/*out*/void** env, jint version) {
548   std::vector<GetEnvHook> env_hooks;
549   {
550     ReaderMutexLock rmu(Thread::Current(), env_hooks_lock_);
551     env_hooks.assign(env_hooks_.begin(), env_hooks_.end());
552   }
553   for (GetEnvHook hook : env_hooks) {
554     jint res = hook(this, env, version);
555     if (res == JNI_OK) {
556       return JNI_OK;
557     } else if (res != JNI_EVERSION) {
558       LOG(ERROR) << "Error returned from a plugin GetEnv handler! " << res;
559       return res;
560     }
561   }
562   LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
563   return JNI_EVERSION;
564 }
565 
566 // Add a hook to handle getting environments from the GetEnv call.
AddEnvironmentHook(GetEnvHook hook)567 void JavaVMExt::AddEnvironmentHook(GetEnvHook hook) {
568   CHECK(hook != nullptr) << "environment hooks shouldn't be null!";
569   WriterMutexLock wmu(Thread::Current(), env_hooks_lock_);
570   env_hooks_.push_back(hook);
571 }
572 
JniAbort(const char * jni_function_name,const char * msg)573 void JavaVMExt::JniAbort(const char* jni_function_name, const char* msg) {
574   Thread* self = Thread::Current();
575   ScopedObjectAccess soa(self);
576   ArtMethod* current_method = self->GetCurrentMethod(nullptr);
577 
578   std::ostringstream os;
579   os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
580 
581   if (jni_function_name != nullptr) {
582     os << "\n    in call to " << jni_function_name;
583   }
584   // TODO: is this useful given that we're about to dump the calling thread's stack?
585   if (current_method != nullptr) {
586     os << "\n    from " << current_method->PrettyMethod();
587   }
588 
589   if (check_jni_abort_hook_ != nullptr) {
590     check_jni_abort_hook_(check_jni_abort_hook_data_, os.str());
591   } else {
592     // Ensure that we get a native stack trace for this thread.
593     ScopedThreadSuspension sts(self, ThreadState::kNative);
594     LOG(FATAL) << os.str();
595     UNREACHABLE();
596   }
597 }
598 
JniAbortV(const char * jni_function_name,const char * fmt,va_list ap)599 void JavaVMExt::JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) {
600   std::string msg;
601   StringAppendV(&msg, fmt, ap);
602   JniAbort(jni_function_name, msg.c_str());
603 }
604 
JniAbortF(const char * jni_function_name,const char * fmt,...)605 void JavaVMExt::JniAbortF(const char* jni_function_name, const char* fmt, ...) {
606   va_list args;
607   va_start(args, fmt);
608   JniAbortV(jni_function_name, fmt, args);
609   va_end(args);
610 }
611 
ShouldTrace(ArtMethod * method)612 bool JavaVMExt::ShouldTrace(ArtMethod* method) {
613   // Fast where no tracing is enabled.
614   if (trace_.empty() && !VLOG_IS_ON(third_party_jni)) {
615     return false;
616   }
617   // Perform checks based on class name.
618   std::string_view class_name(method->GetDeclaringClassDescriptor());
619   if (!trace_.empty() && class_name.find(trace_) != std::string_view::npos) {
620     return true;
621   }
622   if (!VLOG_IS_ON(third_party_jni)) {
623     return false;
624   }
625   // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look
626   // like part of Android.
627   static const char* const gBuiltInPrefixes[] = {
628       "Landroid/",
629       "Lcom/android/",
630       "Lcom/google/android/",
631       "Ldalvik/",
632       "Ljava/",
633       "Ljavax/",
634       "Llibcore/",
635       "Lorg/apache/harmony/",
636   };
637   for (size_t i = 0; i < arraysize(gBuiltInPrefixes); ++i) {
638     if (StartsWith(class_name, gBuiltInPrefixes[i])) {
639       return false;
640     }
641   }
642   return true;
643 }
644 
CheckGlobalRefAllocationTracking()645 void JavaVMExt::CheckGlobalRefAllocationTracking() {
646   if (LIKELY(enable_allocation_tracking_delta_ == 0)) {
647     return;
648   }
649   size_t simple_free_capacity = globals_.FreeCapacity();
650   if (UNLIKELY(simple_free_capacity <= enable_allocation_tracking_delta_)) {
651     if (!allocation_tracking_enabled_) {
652       LOG(WARNING) << "Global reference storage appears close to exhaustion, program termination "
653                    << "may be imminent. Enabling allocation tracking to improve abort diagnostics. "
654                    << "This will result in program slow-down.";
655 
656       old_allocation_tracking_state_ = runtime_->GetHeap()->IsAllocTrackingEnabled();
657       if (!old_allocation_tracking_state_) {
658         // Need to be guaranteed suspended.
659         ScopedObjectAccess soa(Thread::Current());
660         ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
661         gc::AllocRecordObjectMap::SetAllocTrackingEnabled(true);
662       }
663       allocation_tracking_enabled_ = true;
664     }
665   } else {
666     if (UNLIKELY(allocation_tracking_enabled_)) {
667       if (!old_allocation_tracking_state_) {
668         // Need to be guaranteed suspended.
669         ScopedObjectAccess soa(Thread::Current());
670         ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
671         gc::AllocRecordObjectMap::SetAllocTrackingEnabled(false);
672       }
673       allocation_tracking_enabled_ = false;
674     }
675   }
676 }
677 
MaybeTraceGlobals()678 void JavaVMExt::MaybeTraceGlobals() {
679   if (global_ref_report_counter_++ == kGlobalRefReportInterval) {
680     global_ref_report_counter_ = 1;
681     ATraceIntegerValue("JNI Global Refs", globals_.NEntriesForGlobal());
682   }
683 }
684 
MaybeTraceWeakGlobals()685 void JavaVMExt::MaybeTraceWeakGlobals() {
686   if (weak_global_ref_report_counter_++ == kGlobalRefReportInterval) {
687     weak_global_ref_report_counter_ = 1;
688     ATraceIntegerValue("JNI Weak Global Refs", weak_globals_.NEntriesForGlobal());
689   }
690 }
691 
AddGlobalRef(Thread * self,ObjPtr<mirror::Object> obj)692 jobject JavaVMExt::AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) {
693   // Check for null after decoding the object to handle cleared weak globals.
694   if (obj == nullptr) {
695     return nullptr;
696   }
697   IndirectRef ref;
698   std::string error_msg;
699   {
700     WriterMutexLock mu(self, *Locks::jni_globals_lock_);
701     ref = globals_.Add(kIRTFirstSegment, obj, &error_msg);
702     MaybeTraceGlobals();
703   }
704   if (UNLIKELY(ref == nullptr)) {
705     LOG(FATAL) << error_msg;
706     UNREACHABLE();
707   }
708   CheckGlobalRefAllocationTracking();
709   return reinterpret_cast<jobject>(ref);
710 }
711 
WaitForWeakGlobalsAccess(Thread * self)712 void JavaVMExt::WaitForWeakGlobalsAccess(Thread* self) {
713   if (UNLIKELY(!MayAccessWeakGlobals(self))) {
714     ATraceBegin("Blocking on WeakGlobal access");
715     do {
716       // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
717       // presence of threads blocking for weak ref access.
718       self->CheckEmptyCheckpointFromWeakRefAccess(Locks::jni_weak_globals_lock_);
719       weak_globals_add_condition_.WaitHoldingLocks(self);
720     } while (!MayAccessWeakGlobals(self));
721     ATraceEnd();
722   }
723 }
724 
AddWeakGlobalRef(Thread * self,ObjPtr<mirror::Object> obj)725 jweak JavaVMExt::AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) {
726   if (obj == nullptr) {
727     return nullptr;
728   }
729   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
730   // CMS needs this to block for concurrent reference processing because an object allocated during
731   // the GC won't be marked and concurrent reference processing would incorrectly clear the JNI weak
732   // ref. But CC (kUseReadBarrier == true) doesn't because of the to-space invariant.
733   if (!kUseReadBarrier) {
734     WaitForWeakGlobalsAccess(self);
735   }
736   std::string error_msg;
737   IndirectRef ref = weak_globals_.Add(kIRTFirstSegment, obj, &error_msg);
738   MaybeTraceWeakGlobals();
739   if (UNLIKELY(ref == nullptr)) {
740     LOG(FATAL) << error_msg;
741     UNREACHABLE();
742   }
743   return reinterpret_cast<jweak>(ref);
744 }
745 
DeleteGlobalRef(Thread * self,jobject obj)746 void JavaVMExt::DeleteGlobalRef(Thread* self, jobject obj) {
747   if (obj == nullptr) {
748     return;
749   }
750   {
751     WriterMutexLock mu(self, *Locks::jni_globals_lock_);
752     if (!globals_.Remove(kIRTFirstSegment, obj)) {
753       LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
754                    << "failed to find entry";
755     }
756     MaybeTraceGlobals();
757   }
758   CheckGlobalRefAllocationTracking();
759 }
760 
DeleteWeakGlobalRef(Thread * self,jweak obj)761 void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
762   if (obj == nullptr) {
763     return;
764   }
765   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
766   if (!weak_globals_.Remove(kIRTFirstSegment, obj)) {
767     LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
768                  << "failed to find entry";
769   }
770   MaybeTraceWeakGlobals();
771 }
772 
ThreadEnableCheckJni(Thread * thread,void * arg)773 static void ThreadEnableCheckJni(Thread* thread, void* arg) {
774   bool* check_jni = reinterpret_cast<bool*>(arg);
775   thread->GetJniEnv()->SetCheckJniEnabled(*check_jni);
776 }
777 
SetCheckJniEnabled(bool enabled)778 bool JavaVMExt::SetCheckJniEnabled(bool enabled) {
779   bool old_check_jni = check_jni_;
780   check_jni_ = enabled;
781   functions = enabled ? GetCheckJniInvokeInterface() : unchecked_functions_;
782   MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
783   runtime_->GetThreadList()->ForEach(ThreadEnableCheckJni, &check_jni_);
784   return old_check_jni;
785 }
786 
DumpForSigQuit(std::ostream & os)787 void JavaVMExt::DumpForSigQuit(std::ostream& os) {
788   os << "JNI: CheckJNI is " << (check_jni_ ? "on" : "off");
789   if (force_copy_) {
790     os << " (with forcecopy)";
791   }
792   Thread* self = Thread::Current();
793   {
794     ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
795     os << "; globals=" << globals_.Capacity();
796   }
797   {
798     MutexLock mu(self, *Locks::jni_weak_globals_lock_);
799     if (weak_globals_.Capacity() > 0) {
800       os << " (plus " << weak_globals_.Capacity() << " weak)";
801     }
802   }
803   os << '\n';
804 
805   {
806     MutexLock mu(self, *Locks::jni_libraries_lock_);
807     os << "Libraries: " << Dumpable<Libraries>(*libraries_) << " (" << libraries_->size() << ")\n";
808   }
809 }
810 
DisallowNewWeakGlobals()811 void JavaVMExt::DisallowNewWeakGlobals() {
812   CHECK(!kUseReadBarrier);
813   Thread* const self = Thread::Current();
814   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
815   // DisallowNewWeakGlobals is only called by CMS during the pause. It is required to have the
816   // mutator lock exclusively held so that we don't have any threads in the middle of
817   // DecodeWeakGlobal.
818   Locks::mutator_lock_->AssertExclusiveHeld(self);
819   allow_accessing_weak_globals_.store(false, std::memory_order_seq_cst);
820 }
821 
AllowNewWeakGlobals()822 void JavaVMExt::AllowNewWeakGlobals() {
823   CHECK(!kUseReadBarrier);
824   Thread* self = Thread::Current();
825   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
826   allow_accessing_weak_globals_.store(true, std::memory_order_seq_cst);
827   weak_globals_add_condition_.Broadcast(self);
828 }
829 
BroadcastForNewWeakGlobals()830 void JavaVMExt::BroadcastForNewWeakGlobals() {
831   Thread* self = Thread::Current();
832   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
833   weak_globals_add_condition_.Broadcast(self);
834 }
835 
DecodeGlobal(IndirectRef ref)836 ObjPtr<mirror::Object> JavaVMExt::DecodeGlobal(IndirectRef ref) {
837   return globals_.SynchronizedGet(ref);
838 }
839 
UpdateGlobal(Thread * self,IndirectRef ref,ObjPtr<mirror::Object> result)840 void JavaVMExt::UpdateGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result) {
841   WriterMutexLock mu(self, *Locks::jni_globals_lock_);
842   globals_.Update(ref, result);
843 }
844 
DecodeWeakGlobal(Thread * self,IndirectRef ref)845 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
846   // It is safe to access GetWeakRefAccessEnabled without the lock since CC uses checkpoints to call
847   // SetWeakRefAccessEnabled, and the other collectors only modify allow_accessing_weak_globals_
848   // when the mutators are paused.
849   // This only applies in the case where MayAccessWeakGlobals goes from false to true. In the other
850   // case, it may be racy, this is benign since DecodeWeakGlobalLocked does the correct behavior
851   // if MayAccessWeakGlobals is false.
852   DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
853   if (LIKELY(MayAccessWeakGlobals(self))) {
854     return weak_globals_.SynchronizedGet(ref);
855   }
856   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
857   return DecodeWeakGlobalLocked(self, ref);
858 }
859 
DecodeWeakGlobalLocked(Thread * self,IndirectRef ref)860 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobalLocked(Thread* self, IndirectRef ref) {
861   if (kDebugLocking) {
862     Locks::jni_weak_globals_lock_->AssertHeld(self);
863   }
864   // TODO: Handle the already null case without waiting.
865   // TODO: Otherwise we should just wait for kInitMarkingDone, and track which weak globals were
866   // marked at that point. We would only need one mark bit per entry in the weak_globals_ table,
867   // and a quick pass over that early on during reference processing.
868   WaitForWeakGlobalsAccess(self);
869   return weak_globals_.Get(ref);
870 }
871 
DecodeWeakGlobalDuringShutdown(Thread * self,IndirectRef ref)872 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref) {
873   DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
874   DCHECK(Runtime::Current()->IsShuttingDown(self));
875   if (self != nullptr) {
876     return DecodeWeakGlobal(self, ref);
877   }
878   // self can be null during a runtime shutdown. ~Runtime()->~ClassLinker()->DecodeWeakGlobal().
879   if (!kUseReadBarrier) {
880     DCHECK(allow_accessing_weak_globals_.load(std::memory_order_seq_cst));
881   }
882   return weak_globals_.SynchronizedGet(ref);
883 }
884 
IsWeakGlobalCleared(Thread * self,IndirectRef ref)885 bool JavaVMExt::IsWeakGlobalCleared(Thread* self, IndirectRef ref) {
886   DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
887   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
888   WaitForWeakGlobalsAccess(self);
889   // When just checking a weak ref has been cleared, avoid triggering the read barrier in decode
890   // (DecodeWeakGlobal) so that we won't accidentally mark the object alive. Since the cleared
891   // sentinel is a non-moving object, we can compare the ref to it without the read barrier and
892   // decide if it's cleared.
893   return Runtime::Current()->IsClearedJniWeakGlobal(weak_globals_.Get<kWithoutReadBarrier>(ref));
894 }
895 
UpdateWeakGlobal(Thread * self,IndirectRef ref,ObjPtr<mirror::Object> result)896 void JavaVMExt::UpdateWeakGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result) {
897   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
898   weak_globals_.Update(ref, result);
899 }
900 
DumpReferenceTables(std::ostream & os)901 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
902   Thread* self = Thread::Current();
903   {
904     ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
905     globals_.Dump(os);
906   }
907   {
908     MutexLock mu(self, *Locks::jni_weak_globals_lock_);
909     weak_globals_.Dump(os);
910   }
911 }
912 
UnloadNativeLibraries()913 void JavaVMExt::UnloadNativeLibraries() {
914   libraries_.get()->UnloadNativeLibraries();
915 }
916 
UnloadBootNativeLibraries()917 void JavaVMExt::UnloadBootNativeLibraries() {
918   libraries_.get()->UnloadBootNativeLibraries(this);
919 }
920 
LoadNativeLibrary(JNIEnv * env,const std::string & path,jobject class_loader,jclass caller_class,std::string * error_msg)921 bool JavaVMExt::LoadNativeLibrary(JNIEnv* env,
922                                   const std::string& path,
923                                   jobject class_loader,
924                                   jclass caller_class,
925                                   std::string* error_msg) {
926   error_msg->clear();
927 
928   // See if we've already loaded this library.  If we have, and the class loader
929   // matches, return successfully without doing anything.
930   // TODO: for better results we should canonicalize the pathname (or even compare
931   // inodes). This implementation is fine if everybody is using System.loadLibrary.
932   SharedLibrary* library;
933   Thread* self = Thread::Current();
934   {
935     // TODO: move the locking (and more of this logic) into Libraries.
936     MutexLock mu(self, *Locks::jni_libraries_lock_);
937     library = libraries_->Get(path);
938   }
939   void* class_loader_allocator = nullptr;
940   std::string caller_location;
941   {
942     ScopedObjectAccess soa(env);
943     // As the incoming class loader is reachable/alive during the call of this function,
944     // it's okay to decode it without worrying about unexpectedly marking it alive.
945     ObjPtr<mirror::ClassLoader> loader = soa.Decode<mirror::ClassLoader>(class_loader);
946 
947     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
948     if (class_linker->IsBootClassLoader(soa, loader.Ptr())) {
949       loader = nullptr;
950       class_loader = nullptr;
951       if (caller_class != nullptr) {
952         ObjPtr<mirror::Class> caller = soa.Decode<mirror::Class>(caller_class);
953         ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
954         if (dex_cache != nullptr) {
955           caller_location = dex_cache->GetLocation()->ToModifiedUtf8();
956         }
957       }
958     }
959 
960     class_loader_allocator = class_linker->GetAllocatorForClassLoader(loader.Ptr());
961     CHECK(class_loader_allocator != nullptr);
962   }
963   if (library != nullptr) {
964     // Use the allocator pointers for class loader equality to avoid unnecessary weak root decode.
965     if (library->GetClassLoaderAllocator() != class_loader_allocator) {
966       // The library will be associated with class_loader. The JNI
967       // spec says we can't load the same library into more than one
968       // class loader.
969       //
970       // This isn't very common. So spend some time to get a readable message.
971       auto call_to_string = [&](jobject obj) -> std::string {
972         if (obj == nullptr) {
973           return "null";
974         }
975         // Handle jweaks. Ignore double local-ref.
976         ScopedLocalRef<jobject> local_ref(env, env->NewLocalRef(obj));
977         if (local_ref != nullptr) {
978           ScopedLocalRef<jclass> local_class(env, env->GetObjectClass(local_ref.get()));
979           jmethodID to_string = env->GetMethodID(local_class.get(),
980                                                  "toString",
981                                                  "()Ljava/lang/String;");
982           DCHECK(to_string != nullptr);
983           ScopedLocalRef<jobject> local_string(env,
984                                                env->CallObjectMethod(local_ref.get(), to_string));
985           if (local_string != nullptr) {
986             ScopedUtfChars utf(env, reinterpret_cast<jstring>(local_string.get()));
987             if (utf.c_str() != nullptr) {
988               return utf.c_str();
989             }
990           }
991           if (env->ExceptionCheck()) {
992             // We can't do much better logging, really. So leave it with a Describe.
993             env->ExceptionDescribe();
994             env->ExceptionClear();
995           }
996           return "(Error calling toString)";
997         }
998         return "null";
999       };
1000       std::string old_class_loader = call_to_string(library->GetClassLoader());
1001       std::string new_class_loader = call_to_string(class_loader);
1002       StringAppendF(error_msg, "Shared library \"%s\" already opened by "
1003           "ClassLoader %p(%s); can't open in ClassLoader %p(%s)",
1004           path.c_str(),
1005           library->GetClassLoader(),
1006           old_class_loader.c_str(),
1007           class_loader,
1008           new_class_loader.c_str());
1009       LOG(WARNING) << *error_msg;
1010       return false;
1011     }
1012     VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
1013               << " ClassLoader " << class_loader << "]";
1014     if (!library->CheckOnLoadResult()) {
1015       StringAppendF(error_msg, "JNI_OnLoad failed on a previous attempt "
1016           "to load \"%s\"", path.c_str());
1017       return false;
1018     }
1019     return true;
1020   }
1021 
1022   // Open the shared library.  Because we're using a full path, the system
1023   // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
1024   // resolve this library's dependencies though.)
1025 
1026   // Failures here are expected when java.library.path has several entries
1027   // and we have to hunt for the lib.
1028 
1029   // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
1030   // class unloading. Libraries will only be unloaded when the reference count (incremented by
1031   // dlopen) becomes zero from dlclose.
1032 
1033   // Retrieve the library path from the classloader, if necessary.
1034   ScopedLocalRef<jstring> library_path(env, GetLibrarySearchPath(env, class_loader));
1035 
1036   Locks::mutator_lock_->AssertNotHeld(self);
1037   const char* path_str = path.empty() ? nullptr : path.c_str();
1038   bool needs_native_bridge = false;
1039   char* nativeloader_error_msg = nullptr;
1040   void* handle = android::OpenNativeLibrary(
1041       env,
1042       runtime_->GetTargetSdkVersion(),
1043       path_str,
1044       class_loader,
1045       (caller_location.empty() ? nullptr : caller_location.c_str()),
1046       library_path.get(),
1047       &needs_native_bridge,
1048       &nativeloader_error_msg);
1049   VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_NOW) returned " << handle << "]";
1050 
1051   if (handle == nullptr) {
1052     *error_msg = nativeloader_error_msg;
1053     android::NativeLoaderFreeErrorMessage(nativeloader_error_msg);
1054     VLOG(jni) << "dlopen(\"" << path << "\", RTLD_NOW) failed: " << *error_msg;
1055     return false;
1056   }
1057 
1058   if (env->ExceptionCheck() == JNI_TRUE) {
1059     LOG(ERROR) << "Unexpected exception:";
1060     env->ExceptionDescribe();
1061     env->ExceptionClear();
1062   }
1063   // Create a new entry.
1064   // TODO: move the locking (and more of this logic) into Libraries.
1065   bool created_library = false;
1066   {
1067     // Create SharedLibrary ahead of taking the libraries lock to maintain lock ordering.
1068     std::unique_ptr<SharedLibrary> new_library(
1069         new SharedLibrary(env,
1070                           self,
1071                           path,
1072                           handle,
1073                           needs_native_bridge,
1074                           class_loader,
1075                           class_loader_allocator));
1076 
1077     MutexLock mu(self, *Locks::jni_libraries_lock_);
1078     library = libraries_->Get(path);
1079     if (library == nullptr) {  // We won race to get libraries_lock.
1080       library = new_library.release();
1081       libraries_->Put(path, library);
1082       created_library = true;
1083     }
1084   }
1085   if (!created_library) {
1086     LOG(INFO) << "WOW: we lost a race to add shared library: "
1087         << "\"" << path << "\" ClassLoader=" << class_loader;
1088     return library->CheckOnLoadResult();
1089   }
1090   VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
1091 
1092   bool was_successful = false;
1093   void* sym = library->FindSymbol("JNI_OnLoad", nullptr);
1094   if (sym == nullptr) {
1095     VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
1096     was_successful = true;
1097   } else {
1098     // Call JNI_OnLoad.  We have to override the current class
1099     // loader, which will always be "null" since the stuff at the
1100     // top of the stack is around Runtime.loadLibrary().  (See
1101     // the comments in the JNI FindClass function.)
1102     ScopedLocalRef<jobject> old_class_loader(env, env->NewLocalRef(self->GetClassLoaderOverride()));
1103     self->SetClassLoaderOverride(class_loader);
1104 
1105     VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
1106     using JNI_OnLoadFn = int(*)(JavaVM*, void*);
1107     JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
1108     int version = (*jni_on_load)(this, nullptr);
1109 
1110     if (IsSdkVersionSetAndAtMost(runtime_->GetTargetSdkVersion(), SdkVersion::kL)) {
1111       // Make sure that sigchain owns SIGSEGV.
1112       EnsureFrontOfChain(SIGSEGV);
1113     }
1114 
1115     self->SetClassLoaderOverride(old_class_loader.get());
1116 
1117     if (version == JNI_ERR) {
1118       StringAppendF(error_msg, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
1119     } else if (JavaVMExt::IsBadJniVersion(version)) {
1120       StringAppendF(error_msg, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
1121                     path.c_str(), version);
1122       // It's unwise to call dlclose() here, but we can mark it
1123       // as bad and ensure that future load attempts will fail.
1124       // We don't know how far JNI_OnLoad got, so there could
1125       // be some partially-initialized stuff accessible through
1126       // newly-registered native method calls.  We could try to
1127       // unregister them, but that doesn't seem worthwhile.
1128     } else {
1129       was_successful = true;
1130     }
1131     VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
1132               << " from JNI_OnLoad in \"" << path << "\"]";
1133   }
1134 
1135   library->SetResult(was_successful);
1136   return was_successful;
1137 }
1138 
FindCodeForNativeMethodInAgents(ArtMethod * m)1139 static void* FindCodeForNativeMethodInAgents(ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_) {
1140   std::string jni_short_name(m->JniShortName());
1141   std::string jni_long_name(m->JniLongName());
1142   for (const std::unique_ptr<ti::Agent>& agent : Runtime::Current()->GetAgents()) {
1143     void* fn = agent->FindSymbol(jni_short_name);
1144     if (fn != nullptr) {
1145       VLOG(jni) << "Found implementation for " << m->PrettyMethod()
1146                 << " (symbol: " << jni_short_name << ") in " << *agent;
1147       return fn;
1148     }
1149     fn = agent->FindSymbol(jni_long_name);
1150     if (fn != nullptr) {
1151       VLOG(jni) << "Found implementation for " << m->PrettyMethod()
1152                 << " (symbol: " << jni_long_name << ") in " << *agent;
1153       return fn;
1154     }
1155   }
1156   return nullptr;
1157 }
1158 
FindCodeForNativeMethod(ArtMethod * m,std::string * error_msg,bool can_suspend)1159 void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m, std::string* error_msg, bool can_suspend) {
1160   CHECK(m->IsNative());
1161   ObjPtr<mirror::Class> c = m->GetDeclaringClass();
1162   // If this is a static method, it could be called before the class has been initialized.
1163   CHECK(c->IsInitializing() || !NeedsClinitCheckBeforeCall(m))
1164       << c->GetStatus() << " " << m->PrettyMethod();
1165   Thread* const self = Thread::Current();
1166   void* native_method = libraries_->FindNativeMethod(self, m, error_msg, can_suspend);
1167   if (native_method == nullptr && can_suspend) {
1168     // Lookup JNI native methods from native TI Agent libraries. See runtime/ti/agent.h for more
1169     // information. Agent libraries are searched for native methods after all jni libraries.
1170     native_method = FindCodeForNativeMethodInAgents(m);
1171   }
1172   return native_method;
1173 }
1174 
SweepJniWeakGlobals(IsMarkedVisitor * visitor)1175 void JavaVMExt::SweepJniWeakGlobals(IsMarkedVisitor* visitor) {
1176   MutexLock mu(Thread::Current(), *Locks::jni_weak_globals_lock_);
1177   Runtime* const runtime = Runtime::Current();
1178   for (auto* entry : weak_globals_) {
1179     // Need to skip null here to distinguish between null entries and cleared weak ref entries.
1180     if (!entry->IsNull()) {
1181       // Since this is called by the GC, we don't need a read barrier.
1182       mirror::Object* obj = entry->Read<kWithoutReadBarrier>();
1183       mirror::Object* new_obj = visitor->IsMarked(obj);
1184       if (new_obj == nullptr) {
1185         new_obj = runtime->GetClearedJniWeakGlobal();
1186       }
1187       *entry = GcRoot<mirror::Object>(new_obj);
1188     }
1189   }
1190 }
1191 
TrimGlobals()1192 void JavaVMExt::TrimGlobals() {
1193   WriterMutexLock mu(Thread::Current(), *Locks::jni_globals_lock_);
1194   globals_.Trim();
1195 }
1196 
VisitRoots(RootVisitor * visitor)1197 void JavaVMExt::VisitRoots(RootVisitor* visitor) {
1198   Thread* self = Thread::Current();
1199   ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
1200   globals_.VisitRoots(visitor, RootInfo(kRootJNIGlobal));
1201   // The weak_globals table is visited by the GC itself (because it mutates the table).
1202 }
1203 
GetLibrarySearchPath(JNIEnv * env,jobject class_loader)1204 jstring JavaVMExt::GetLibrarySearchPath(JNIEnv* env, jobject class_loader) {
1205   if (class_loader == nullptr) {
1206     return nullptr;
1207   }
1208   if (!env->IsInstanceOf(class_loader, WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
1209     return nullptr;
1210   }
1211   return reinterpret_cast<jstring>(env->CallObjectMethod(
1212       class_loader,
1213       WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath));
1214 }
1215 
1216 // JNI Invocation interface.
1217 
JNI_CreateJavaVM(JavaVM ** p_vm,JNIEnv ** p_env,void * vm_args)1218 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
1219   ScopedTrace trace(__FUNCTION__);
1220   const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
1221   if (JavaVMExt::IsBadJniVersion(args->version)) {
1222     LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
1223     return JNI_EVERSION;
1224   }
1225   RuntimeOptions options;
1226   for (int i = 0; i < args->nOptions; ++i) {
1227     JavaVMOption* option = &args->options[i];
1228     options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
1229   }
1230   bool ignore_unrecognized = args->ignoreUnrecognized;
1231   if (!Runtime::Create(options, ignore_unrecognized)) {
1232     return JNI_ERR;
1233   }
1234 
1235   // When `ART_CRASH_RUNTIME_DELIBERATELY` is defined (which happens only in the
1236   // case of a test APEX), we crash the runtime here on purpose, to test the
1237   // behavior of rollbacks following a failed ART Mainline Module update.
1238 #ifdef ART_CRASH_RUNTIME_DELIBERATELY
1239   LOG(FATAL) << "Runtime crashing deliberately for testing purposes.";
1240 #endif
1241 
1242   // Initialize native loader. This step makes sure we have
1243   // everything set up before we start using JNI.
1244   android::InitializeNativeLoader();
1245 
1246   Runtime* runtime = Runtime::Current();
1247   bool started = runtime->Start();
1248   if (!started) {
1249     delete Thread::Current()->GetJniEnv();
1250     delete runtime->GetJavaVM();
1251     LOG(WARNING) << "CreateJavaVM failed";
1252     return JNI_ERR;
1253   }
1254 
1255   *p_env = Thread::Current()->GetJniEnv();
1256   *p_vm = runtime->GetJavaVM();
1257   return JNI_OK;
1258 }
1259 
JNI_GetCreatedJavaVMs(JavaVM ** vms_buf,jsize buf_len,jsize * vm_count)1260 extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms_buf, jsize buf_len, jsize* vm_count) {
1261   Runtime* runtime = Runtime::Current();
1262   if (runtime == nullptr || buf_len == 0) {
1263     *vm_count = 0;
1264   } else {
1265     *vm_count = 1;
1266     vms_buf[0] = runtime->GetJavaVM();
1267   }
1268   return JNI_OK;
1269 }
1270 
1271 // Historically unsupported.
JNI_GetDefaultJavaVMInitArgs(void *)1272 extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
1273   return JNI_ERR;
1274 }
1275 
1276 }  // namespace art
1277