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