• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "jni_internal.h"
18 
19 #include <sys/mman.h>
20 #include <zlib.h>
21 
22 #include "base/logging.h"
23 #include "class_linker.h"
24 #include "class_linker-inl.h"
25 #include "dex_file-inl.h"
26 #include "field_helper.h"
27 #include "gc/space/space.h"
28 #include "mirror/art_field-inl.h"
29 #include "mirror/art_method-inl.h"
30 #include "mirror/class-inl.h"
31 #include "mirror/object-inl.h"
32 #include "mirror/object_array-inl.h"
33 #include "mirror/string-inl.h"
34 #include "mirror/throwable.h"
35 #include "runtime.h"
36 #include "scoped_thread_state_change.h"
37 #include "thread.h"
38 
39 namespace art {
40 
JniAbort(const char * jni_function_name,const char * msg)41 static void JniAbort(const char* jni_function_name, const char* msg) {
42   Thread* self = Thread::Current();
43   ScopedObjectAccess soa(self);
44   mirror::ArtMethod* current_method = self->GetCurrentMethod(nullptr);
45 
46   std::ostringstream os;
47   os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
48 
49   if (jni_function_name != nullptr) {
50     os << "\n    in call to " << jni_function_name;
51   }
52   // TODO: is this useful given that we're about to dump the calling thread's stack?
53   if (current_method != nullptr) {
54     os << "\n    from " << PrettyMethod(current_method);
55   }
56   os << "\n";
57   self->Dump(os);
58 
59   JavaVMExt* vm = Runtime::Current()->GetJavaVM();
60   if (vm->check_jni_abort_hook != nullptr) {
61     vm->check_jni_abort_hook(vm->check_jni_abort_hook_data, os.str());
62   } else {
63     // Ensure that we get a native stack trace for this thread.
64     self->TransitionFromRunnableToSuspended(kNative);
65     LOG(FATAL) << os.str();
66     self->TransitionFromSuspendedToRunnable();  // Unreachable, keep annotalysis happy.
67   }
68 }
69 
JniAbortV(const char * jni_function_name,const char * fmt,va_list ap)70 static void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) {
71   std::string msg;
72   StringAppendV(&msg, fmt, ap);
73   JniAbort(jni_function_name, msg.c_str());
74 }
75 
JniAbortF(const char * jni_function_name,const char * fmt,...)76 void JniAbortF(const char* jni_function_name, const char* fmt, ...) {
77   va_list args;
78   va_start(args, fmt);
79   JniAbortV(jni_function_name, fmt, args);
80   va_end(args);
81 }
82 
83 /*
84  * ===========================================================================
85  *      JNI function helpers
86  * ===========================================================================
87  */
88 
IsHandleScopeLocalRef(JNIEnv * env,jobject localRef)89 static bool IsHandleScopeLocalRef(JNIEnv* env, jobject localRef) {
90   return GetIndirectRefKind(localRef) == kHandleScopeOrInvalid &&
91       reinterpret_cast<JNIEnvExt*>(env)->self->HandleScopeContains(localRef);
92 }
93 
94 // Flags passed into ScopedCheck.
95 #define kFlag_Default       0x0000
96 
97 #define kFlag_CritBad       0x0000      // Calling while in critical is not allowed.
98 #define kFlag_CritOkay      0x0001      // Calling while in critical is allowed.
99 #define kFlag_CritGet       0x0002      // This is a critical "get".
100 #define kFlag_CritRelease   0x0003      // This is a critical "release".
101 #define kFlag_CritMask      0x0003      // Bit mask to get "crit" value.
102 
103 #define kFlag_ExcepBad      0x0000      // Raised exceptions are not allowed.
104 #define kFlag_ExcepOkay     0x0004      // Raised exceptions are allowed.
105 
106 #define kFlag_Release       0x0010      // Are we in a non-critical release function?
107 #define kFlag_NullableUtf   0x0020      // Are our UTF parameters nullable?
108 
109 #define kFlag_Invocation    0x8000      // Part of the invocation interface (JavaVM*).
110 
111 #define kFlag_ForceTrace    0x80000000  // Add this to a JNI function's flags if you want to trace every call.
112 
113 static const char* gBuiltInPrefixes[] = {
114   "Landroid/",
115   "Lcom/android/",
116   "Lcom/google/android/",
117   "Ldalvik/",
118   "Ljava/",
119   "Ljavax/",
120   "Llibcore/",
121   "Lorg/apache/harmony/",
122   nullptr
123 };
124 
ShouldTrace(JavaVMExt * vm,mirror::ArtMethod * method)125 static bool ShouldTrace(JavaVMExt* vm, mirror::ArtMethod* method)
126     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
127   // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
128   // when a native method that matches the -Xjnitrace argument calls a JNI function
129   // such as NewByteArray.
130   // If -verbose:third-party-jni is on, we want to log any JNI function calls
131   // made by a third-party native method.
132   std::string class_name(method->GetDeclaringClassDescriptor());
133   if (!vm->trace.empty() && class_name.find(vm->trace) != std::string::npos) {
134     return true;
135   }
136   if (VLOG_IS_ON(third_party_jni)) {
137     // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look
138     // like part of Android.
139     for (size_t i = 0; gBuiltInPrefixes[i] != nullptr; ++i) {
140       if (StartsWith(class_name, gBuiltInPrefixes[i])) {
141         return false;
142       }
143     }
144     return true;
145   }
146   return false;
147 }
148 
149 class ScopedCheck {
150  public:
151   // For JNIEnv* functions.
ScopedCheck(JNIEnv * env,int flags,const char * functionName)152   explicit ScopedCheck(JNIEnv* env, int flags, const char* functionName)
153       SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
154       : soa_(env) {
155     Init(flags, functionName, true);
156     CheckThread(flags);
157   }
158 
159   // For JavaVM* functions.
160   // TODO: it's not correct that this is a lock function, but making it so aids annotalysis.
ScopedCheck(JavaVM * vm,bool has_method,const char * functionName)161   explicit ScopedCheck(JavaVM* vm, bool has_method, const char* functionName)
162       SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
163       : soa_(vm) {
164     Init(kFlag_Invocation, functionName, has_method);
165   }
166 
UNLOCK_FUNCTION(Locks::mutator_lock_)167   ~ScopedCheck() UNLOCK_FUNCTION(Locks::mutator_lock_) {}
168 
soa()169   const ScopedObjectAccess& soa() {
170     return soa_;
171   }
172 
ForceCopy()173   bool ForceCopy() {
174     return Runtime::Current()->GetJavaVM()->force_copy;
175   }
176 
177   // Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread"
178   // or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of
179   // times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some
180   // circumstances, but this is incorrect.
CheckClassName(const char * class_name)181   void CheckClassName(const char* class_name) {
182     if ((class_name == nullptr) || !IsValidJniClassName(class_name)) {
183       JniAbortF(function_name_,
184                 "illegal class name '%s'\n"
185                 "    (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')",
186                 class_name);
187     }
188   }
189 
190   /*
191    * Verify that the field is of the appropriate type.  If the field has an
192    * object type, "java_object" is the object we're trying to assign into it.
193    *
194    * Works for both static and instance fields.
195    */
CheckFieldType(jvalue value,jfieldID fid,char prim,bool isStatic)196   void CheckFieldType(jvalue value, jfieldID fid, char prim, bool isStatic)
197       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
198     StackHandleScope<1> hs(Thread::Current());
199     Handle<mirror::ArtField> f(hs.NewHandle(CheckFieldID(fid)));
200     if (f.Get() == nullptr) {
201       return;
202     }
203     mirror::Class* field_type = FieldHelper(f).GetType();
204     if (!field_type->IsPrimitive()) {
205       jobject java_object = value.l;
206       if (java_object != nullptr) {
207         mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
208         // If java_object is a weak global ref whose referent has been cleared,
209         // obj will be NULL.  Otherwise, obj should always be non-NULL
210         // and valid.
211         if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) {
212           Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
213           JniAbortF(function_name_, "field operation on invalid %s: %p",
214                     ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
215           return;
216         } else {
217           if (!obj->InstanceOf(field_type)) {
218             JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %s",
219                       PrettyField(f.Get()).c_str(), PrettyTypeOf(obj).c_str());
220             return;
221           }
222         }
223       }
224     } else if (field_type != Runtime::Current()->GetClassLinker()->FindPrimitiveClass(prim)) {
225       JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %c",
226                 PrettyField(f.Get()).c_str(), prim);
227       return;
228     }
229 
230     if (isStatic != f.Get()->IsStatic()) {
231       if (isStatic) {
232         JniAbortF(function_name_, "accessing non-static field %s as static",
233                   PrettyField(f.Get()).c_str());
234       } else {
235         JniAbortF(function_name_, "accessing static field %s as non-static",
236                   PrettyField(f.Get()).c_str());
237       }
238       return;
239     }
240   }
241 
242   /*
243    * Verify that this instance field ID is valid for this object.
244    *
245    * Assumes "jobj" has already been validated.
246    */
CheckInstanceFieldID(jobject java_object,jfieldID fid)247   void CheckInstanceFieldID(jobject java_object, jfieldID fid)
248       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
249     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
250     if (o == nullptr || !Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
251       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
252       JniAbortF(function_name_, "field operation on invalid %s: %p",
253                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
254       return;
255     }
256 
257     mirror::ArtField* f = CheckFieldID(fid);
258     if (f == nullptr) {
259       return;
260     }
261     mirror::Class* c = o->GetClass();
262     if (c->FindInstanceField(f->GetName(), f->GetTypeDescriptor()) == nullptr) {
263       JniAbortF(function_name_, "jfieldID %s not valid for an object of class %s",
264                 PrettyField(f).c_str(), PrettyTypeOf(o).c_str());
265     }
266   }
267 
268   /*
269    * Verify that the pointer value is non-NULL.
270    */
CheckNonNull(const void * ptr)271   void CheckNonNull(const void* ptr) {
272     if (ptr == nullptr) {
273       JniAbortF(function_name_, "non-nullable argument was NULL");
274     }
275   }
276 
277   /*
278    * Verify that the method's return type matches the type of call.
279    * 'expectedType' will be "L" for all objects, including arrays.
280    */
CheckSig(jmethodID mid,const char * expectedType,bool isStatic)281   void CheckSig(jmethodID mid, const char* expectedType, bool isStatic)
282       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
283     mirror::ArtMethod* m = CheckMethodID(mid);
284     if (m == nullptr) {
285       return;
286     }
287     if (*expectedType != m->GetShorty()[0]) {
288       JniAbortF(function_name_, "the return type of %s does not match %s",
289                 function_name_, PrettyMethod(m).c_str());
290     }
291     if (isStatic != m->IsStatic()) {
292       if (isStatic) {
293         JniAbortF(function_name_, "calling non-static method %s with %s",
294                   PrettyMethod(m).c_str(), function_name_);
295       } else {
296         JniAbortF(function_name_, "calling static method %s with %s",
297                   PrettyMethod(m).c_str(), function_name_);
298       }
299     }
300   }
301 
302   /*
303    * Verify that this static field ID is valid for this class.
304    *
305    * Assumes "java_class" has already been validated.
306    */
CheckStaticFieldID(jclass java_class,jfieldID fid)307   void CheckStaticFieldID(jclass java_class, jfieldID fid)
308       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
309     mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
310     mirror::ArtField* f = CheckFieldID(fid);
311     if (f == nullptr) {
312       return;
313     }
314     if (f->GetDeclaringClass() != c) {
315       JniAbortF(function_name_, "static jfieldID %p not valid for class %s",
316                 fid, PrettyClass(c).c_str());
317     }
318   }
319 
320   /*
321    * Verify that "mid" is appropriate for "java_class".
322    *
323    * A mismatch isn't dangerous, because the jmethodID defines the class.  In
324    * fact, java_class is unused in the implementation.  It's best if we don't
325    * allow bad code in the system though.
326    *
327    * Instances of "java_class" must be instances of the method's declaring class.
328    */
CheckStaticMethod(jclass java_class,jmethodID mid)329   void CheckStaticMethod(jclass java_class, jmethodID mid)
330       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
331     mirror::ArtMethod* m = CheckMethodID(mid);
332     if (m == nullptr) {
333       return;
334     }
335     mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
336     if (!m->GetDeclaringClass()->IsAssignableFrom(c)) {
337       JniAbortF(function_name_, "can't call static %s on class %s",
338                 PrettyMethod(m).c_str(), PrettyClass(c).c_str());
339     }
340   }
341 
342   /*
343    * Verify that "mid" is appropriate for "jobj".
344    *
345    * Make sure the object is an instance of the method's declaring class.
346    * (Note the mid might point to a declaration in an interface; this
347    * will be handled automatically by the instanceof check.)
348    */
CheckVirtualMethod(jobject java_object,jmethodID mid)349   void CheckVirtualMethod(jobject java_object, jmethodID mid)
350       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
351     mirror::ArtMethod* m = CheckMethodID(mid);
352     if (m == nullptr) {
353       return;
354     }
355     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
356     if (o == nullptr) {
357       JniAbortF(function_name_, "can't call %s on null object", PrettyMethod(m).c_str());
358     } else if (!o->InstanceOf(m->GetDeclaringClass())) {
359       JniAbortF(function_name_, "can't call %s on instance of %s",
360                 PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
361     }
362   }
363 
364   /**
365    * The format string is a sequence of the following characters,
366    * and must be followed by arguments of the corresponding types
367    * in the same order.
368    *
369    * Java primitive types:
370    * B - jbyte
371    * C - jchar
372    * D - jdouble
373    * F - jfloat
374    * I - jint
375    * J - jlong
376    * S - jshort
377    * Z - jboolean (shown as true and false)
378    * V - void
379    *
380    * Java reference types:
381    * L - jobject
382    * a - jarray
383    * c - jclass
384    * s - jstring
385    *
386    * JNI types:
387    * b - jboolean (shown as JNI_TRUE and JNI_FALSE)
388    * f - jfieldID
389    * m - jmethodID
390    * p - void*
391    * r - jint (for release mode arguments)
392    * u - const char* (Modified UTF-8)
393    * z - jsize (for lengths; use i if negative values are okay)
394    * v - JavaVM*
395    * E - JNIEnv*
396    * . - no argument; just print "..." (used for varargs JNI calls)
397    *
398    * Use the kFlag_NullableUtf flag where 'u' field(s) are nullable.
399    */
Check(bool entry,const char * fmt0,...)400   void Check(bool entry, const char* fmt0, ...) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
401     va_list ap;
402 
403     mirror::ArtMethod* traceMethod = nullptr;
404     if (has_method_ && (!soa_.Vm()->trace.empty() || VLOG_IS_ON(third_party_jni))) {
405       // We need to guard some of the invocation interface's calls: a bad caller might
406       // use DetachCurrentThread or GetEnv on a thread that's not yet attached.
407       Thread* self = Thread::Current();
408       if ((flags_ & kFlag_Invocation) == 0 || self != nullptr) {
409         traceMethod = self->GetCurrentMethod(nullptr);
410       }
411     }
412 
413     if (((flags_ & kFlag_ForceTrace) != 0) ||
414         (traceMethod != nullptr && ShouldTrace(soa_.Vm(), traceMethod))) {
415       va_start(ap, fmt0);
416       std::string msg;
417       for (const char* fmt = fmt0; *fmt;) {
418         char ch = *fmt++;
419         if (ch == 'B') {  // jbyte
420           jbyte b = va_arg(ap, int);
421           if (b >= 0 && b < 10) {
422             StringAppendF(&msg, "%d", b);
423           } else {
424             StringAppendF(&msg, "%#x (%d)", b, b);
425           }
426         } else if (ch == 'C') {  // jchar
427           jchar c = va_arg(ap, int);
428           if (c < 0x7f && c >= ' ') {
429             StringAppendF(&msg, "U+%x ('%c')", c, c);
430           } else {
431             StringAppendF(&msg, "U+%x", c);
432           }
433         } else if (ch == 'F' || ch == 'D') {  // jfloat, jdouble
434           StringAppendF(&msg, "%g", va_arg(ap, double));
435         } else if (ch == 'I' || ch == 'S') {  // jint, jshort
436           StringAppendF(&msg, "%d", va_arg(ap, int));
437         } else if (ch == 'J') {  // jlong
438           StringAppendF(&msg, "%" PRId64, va_arg(ap, jlong));
439         } else if (ch == 'Z') {  // jboolean
440           StringAppendF(&msg, "%s", va_arg(ap, int) ? "true" : "false");
441         } else if (ch == 'V') {  // void
442           msg += "void";
443         } else if (ch == 'v') {  // JavaVM*
444           JavaVM* vm = va_arg(ap, JavaVM*);
445           StringAppendF(&msg, "(JavaVM*)%p", vm);
446         } else if (ch == 'E') {  // JNIEnv*
447           JNIEnv* env = va_arg(ap, JNIEnv*);
448           StringAppendF(&msg, "(JNIEnv*)%p", env);
449         } else if (ch == 'L' || ch == 'a' || ch == 's') {  // jobject, jarray, jstring
450           // For logging purposes, these are identical.
451           jobject o = va_arg(ap, jobject);
452           if (o == nullptr) {
453             msg += "NULL";
454           } else {
455             StringAppendF(&msg, "%p", o);
456           }
457         } else if (ch == 'b') {  // jboolean (JNI-style)
458           jboolean b = va_arg(ap, int);
459           msg += (b ? "JNI_TRUE" : "JNI_FALSE");
460         } else if (ch == 'c') {  // jclass
461           jclass jc = va_arg(ap, jclass);
462           mirror::Class* c = reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(jc));
463           if (c == nullptr) {
464             msg += "NULL";
465           } else if (c == kInvalidIndirectRefObject ||
466               !Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) {
467             StringAppendF(&msg, "INVALID POINTER:%p", jc);
468           } else if (!c->IsClass()) {
469             msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c);
470           } else {
471             msg += PrettyClass(c);
472             if (!entry) {
473               StringAppendF(&msg, " (%p)", jc);
474             }
475           }
476         } else if (ch == 'f') {  // jfieldID
477           jfieldID fid = va_arg(ap, jfieldID);
478           mirror::ArtField* f = reinterpret_cast<mirror::ArtField*>(fid);
479           msg += PrettyField(f);
480           if (!entry) {
481             StringAppendF(&msg, " (%p)", fid);
482           }
483         } else if (ch == 'z') {  // non-negative jsize
484           // You might expect jsize to be size_t, but it's not; it's the same as jint.
485           // We only treat this specially so we can do the non-negative check.
486           // TODO: maybe this wasn't worth it?
487           jint i = va_arg(ap, jint);
488           StringAppendF(&msg, "%d", i);
489         } else if (ch == 'm') {  // jmethodID
490           jmethodID mid = va_arg(ap, jmethodID);
491           mirror::ArtMethod* m = reinterpret_cast<mirror::ArtMethod*>(mid);
492           msg += PrettyMethod(m);
493           if (!entry) {
494             StringAppendF(&msg, " (%p)", mid);
495           }
496         } else if (ch == 'p') {  // void* ("pointer")
497           void* p = va_arg(ap, void*);
498           if (p == nullptr) {
499             msg += "NULL";
500           } else {
501             StringAppendF(&msg, "(void*) %p", p);
502           }
503         } else if (ch == 'r') {  // jint (release mode)
504           jint releaseMode = va_arg(ap, jint);
505           if (releaseMode == 0) {
506             msg += "0";
507           } else if (releaseMode == JNI_ABORT) {
508             msg += "JNI_ABORT";
509           } else if (releaseMode == JNI_COMMIT) {
510             msg += "JNI_COMMIT";
511           } else {
512             StringAppendF(&msg, "invalid release mode %d", releaseMode);
513           }
514         } else if (ch == 'u') {  // const char* (Modified UTF-8)
515           const char* utf = va_arg(ap, const char*);
516           if (utf == nullptr) {
517             msg += "NULL";
518           } else {
519             StringAppendF(&msg, "\"%s\"", utf);
520           }
521         } else if (ch == '.') {
522           msg += "...";
523         } else {
524           JniAbortF(function_name_, "unknown trace format specifier: %c", ch);
525           return;
526         }
527         if (*fmt) {
528           StringAppendF(&msg, ", ");
529         }
530       }
531       va_end(ap);
532 
533       if ((flags_ & kFlag_ForceTrace) != 0) {
534         LOG(INFO) << "JNI: call to " << function_name_ << "(" << msg << ")";
535       } else if (entry) {
536         if (has_method_) {
537           std::string methodName(PrettyMethod(traceMethod, false));
538           LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")";
539           indent_ = methodName.size() + 1;
540         } else {
541           LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")";
542           indent_ = 0;
543         }
544       } else {
545         LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str());
546       }
547     }
548 
549     // We always do the thorough checks on entry, and never on exit...
550     if (entry) {
551       va_start(ap, fmt0);
552       for (const char* fmt = fmt0; *fmt; ++fmt) {
553         char ch = *fmt;
554         if (ch == 'a') {
555           CheckArray(va_arg(ap, jarray));
556         } else if (ch == 'c') {
557           CheckInstance(kClass, va_arg(ap, jclass));
558         } else if (ch == 'L') {
559           CheckObject(va_arg(ap, jobject));
560         } else if (ch == 'r') {
561           CheckReleaseMode(va_arg(ap, jint));
562         } else if (ch == 's') {
563           CheckInstance(kString, va_arg(ap, jstring));
564         } else if (ch == 'u') {
565           if ((flags_ & kFlag_Release) != 0) {
566             CheckNonNull(va_arg(ap, const char*));
567           } else {
568             bool nullable = ((flags_ & kFlag_NullableUtf) != 0);
569             CheckUtfString(va_arg(ap, const char*), nullable);
570           }
571         } else if (ch == 'z') {
572           CheckLengthPositive(va_arg(ap, jsize));
573         } else if (strchr("BCISZbfmpEv", ch) != nullptr) {
574           va_arg(ap, uint32_t);  // Skip this argument.
575         } else if (ch == 'D' || ch == 'F') {
576           va_arg(ap, double);  // Skip this argument.
577         } else if (ch == 'J') {
578           va_arg(ap, uint64_t);  // Skip this argument.
579         } else if (ch == '.') {
580         } else {
581           LOG(FATAL) << "Unknown check format specifier: " << ch;
582         }
583       }
584       va_end(ap);
585     }
586   }
587 
588   enum InstanceKind {
589     kClass,
590     kDirectByteBuffer,
591     kObject,
592     kString,
593     kThrowable,
594   };
595 
596   /*
597    * Verify that "jobj" is a valid non-NULL object reference, and points to
598    * an instance of expectedClass.
599    *
600    * Because we're looking at an object on the GC heap, we have to switch
601    * to "running" mode before doing the checks.
602    */
CheckInstance(InstanceKind kind,jobject java_object)603   bool CheckInstance(InstanceKind kind, jobject java_object)
604       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
605     const char* what = nullptr;
606     switch (kind) {
607     case kClass:
608       what = "jclass";
609       break;
610     case kDirectByteBuffer:
611       what = "direct ByteBuffer";
612       break;
613     case kObject:
614       what = "jobject";
615       break;
616     case kString:
617       what = "jstring";
618       break;
619     case kThrowable:
620       what = "jthrowable";
621       break;
622     default:
623       LOG(FATAL) << "Unknown kind " << static_cast<int>(kind);
624     }
625 
626     if (java_object == nullptr) {
627       JniAbortF(function_name_, "%s received null %s", function_name_, what);
628       return false;
629     }
630 
631     mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
632     if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) {
633       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
634       JniAbortF(function_name_, "%s is an invalid %s: %p (%p)",
635                 what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object, obj);
636       return false;
637     }
638 
639     bool okay = true;
640     switch (kind) {
641     case kClass:
642       okay = obj->IsClass();
643       break;
644     case kDirectByteBuffer:
645       UNIMPLEMENTED(FATAL);
646       break;
647     case kString:
648       okay = obj->GetClass()->IsStringClass();
649       break;
650     case kThrowable:
651       okay = obj->GetClass()->IsThrowableClass();
652       break;
653     case kObject:
654       break;
655     }
656     if (!okay) {
657       JniAbortF(function_name_, "%s has wrong type: %s", what, PrettyTypeOf(obj).c_str());
658       return false;
659     }
660 
661     return true;
662   }
663 
664  private:
665   // Set "has_method" to true if we have a valid thread with a method pointer.
666   // We won't have one before attaching a thread, after detaching a thread, or
667   // when shutting down the runtime.
Init(int flags,const char * functionName,bool has_method)668   void Init(int flags, const char* functionName, bool has_method) {
669     flags_ = flags;
670     function_name_ = functionName;
671     has_method_ = has_method;
672   }
673 
674   /*
675    * Verify that "array" is non-NULL and points to an Array object.
676    *
677    * Since we're dealing with objects, switch to "running" mode.
678    */
CheckArray(jarray java_array)679   void CheckArray(jarray java_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
680     if (java_array == nullptr) {
681       JniAbortF(function_name_, "jarray was NULL");
682       return;
683     }
684 
685     mirror::Array* a = soa_.Decode<mirror::Array*>(java_array);
686     if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(a)) {
687       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
688       JniAbortF(function_name_, "jarray is an invalid %s: %p (%p)",
689                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(), java_array, a);
690     } else if (!a->IsArrayInstance()) {
691       JniAbortF(function_name_, "jarray argument has non-array type: %s", PrettyTypeOf(a).c_str());
692     }
693   }
694 
CheckLengthPositive(jsize length)695   void CheckLengthPositive(jsize length) {
696     if (length < 0) {
697       JniAbortF(function_name_, "negative jsize: %d", length);
698     }
699   }
700 
CheckFieldID(jfieldID fid)701   mirror::ArtField* CheckFieldID(jfieldID fid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
702     if (fid == nullptr) {
703       JniAbortF(function_name_, "jfieldID was NULL");
704       return nullptr;
705     }
706     mirror::ArtField* f = soa_.DecodeField(fid);
707     if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(f) || !f->IsArtField()) {
708       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
709       JniAbortF(function_name_, "invalid jfieldID: %p", fid);
710       return nullptr;
711     }
712     return f;
713   }
714 
CheckMethodID(jmethodID mid)715   mirror::ArtMethod* CheckMethodID(jmethodID mid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
716     if (mid == nullptr) {
717       JniAbortF(function_name_, "jmethodID was NULL");
718       return nullptr;
719     }
720     mirror::ArtMethod* m = soa_.DecodeMethod(mid);
721     if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(m) || !m->IsArtMethod()) {
722       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
723       JniAbortF(function_name_, "invalid jmethodID: %p", mid);
724       return nullptr;
725     }
726     return m;
727   }
728 
729   /*
730    * Verify that "jobj" is a valid object, and that it's an object that JNI
731    * is allowed to know about.  We allow NULL references.
732    *
733    * Switches to "running" mode before performing checks.
734    */
CheckObject(jobject java_object)735   void CheckObject(jobject java_object)
736       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
737     if (java_object == nullptr) {
738       return;
739     }
740 
741     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
742     if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
743       Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
744       // TODO: when we remove work_around_app_jni_bugs, this should be impossible.
745       JniAbortF(function_name_, "native code passing in reference to invalid %s: %p",
746                 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
747     }
748   }
749 
750   /*
751    * Verify that the "mode" argument passed to a primitive array Release
752    * function is one of the valid values.
753    */
CheckReleaseMode(jint mode)754   void CheckReleaseMode(jint mode) {
755     if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
756       JniAbortF(function_name_, "unknown value for release mode: %d", mode);
757     }
758   }
759 
CheckThread(int flags)760   void CheckThread(int flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
761     Thread* self = Thread::Current();
762     if (self == nullptr) {
763       JniAbortF(function_name_, "a thread (tid %d) is making JNI calls without being attached", GetTid());
764       return;
765     }
766 
767     // Get the *correct* JNIEnv by going through our TLS pointer.
768     JNIEnvExt* threadEnv = self->GetJniEnv();
769 
770     // Verify that the current thread is (a) attached and (b) associated with
771     // this particular instance of JNIEnv.
772     if (soa_.Env() != threadEnv) {
773       JniAbortF(function_name_, "thread %s using JNIEnv* from thread %s",
774                 ToStr<Thread>(*self).c_str(), ToStr<Thread>(*soa_.Self()).c_str());
775       return;
776     }
777 
778     // Verify that, if this thread previously made a critical "get" call, we
779     // do the corresponding "release" call before we try anything else.
780     switch (flags & kFlag_CritMask) {
781     case kFlag_CritOkay:    // okay to call this method
782       break;
783     case kFlag_CritBad:     // not okay to call
784       if (threadEnv->critical) {
785         JniAbortF(function_name_, "thread %s using JNI after critical get", ToStr<Thread>(*self).c_str());
786         return;
787       }
788       break;
789     case kFlag_CritGet:     // this is a "get" call
790       // Don't check here; we allow nested gets.
791       threadEnv->critical++;
792       break;
793     case kFlag_CritRelease:  // this is a "release" call
794       threadEnv->critical--;
795       if (threadEnv->critical < 0) {
796         JniAbortF(function_name_, "thread %s called too many critical releases", ToStr<Thread>(*self).c_str());
797         return;
798       }
799       break;
800     default:
801       LOG(FATAL) << "Bad flags (internal error): " << flags;
802     }
803 
804     // Verify that, if an exception has been raised, the native code doesn't
805     // make any JNI calls other than the Exception* methods.
806     if ((flags & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) {
807       ThrowLocation throw_location;
808       mirror::Throwable* exception = self->GetException(&throw_location);
809       std::string type(PrettyTypeOf(exception));
810       JniAbortF(function_name_, "JNI %s called with pending exception '%s' thrown in %s",
811                 function_name_, type.c_str(), throw_location.Dump().c_str());
812       return;
813     }
814   }
815 
816   // Verifies that "bytes" points to valid Modified UTF-8 data.
CheckUtfString(const char * bytes,bool nullable)817   void CheckUtfString(const char* bytes, bool nullable) {
818     if (bytes == nullptr) {
819       if (!nullable) {
820         JniAbortF(function_name_, "non-nullable const char* was NULL");
821         return;
822       }
823       return;
824     }
825 
826     const char* errorKind = nullptr;
827     uint8_t utf8 = CheckUtfBytes(bytes, &errorKind);
828     if (errorKind != nullptr) {
829       JniAbortF(function_name_,
830                 "input is not valid Modified UTF-8: illegal %s byte %#x\n"
831                 "    string: '%s'", errorKind, utf8, bytes);
832       return;
833     }
834   }
835 
CheckUtfBytes(const char * bytes,const char ** errorKind)836   static uint8_t CheckUtfBytes(const char* bytes, const char** errorKind) {
837     while (*bytes != '\0') {
838       uint8_t utf8 = *(bytes++);
839       // Switch on the high four bits.
840       switch (utf8 >> 4) {
841       case 0x00:
842       case 0x01:
843       case 0x02:
844       case 0x03:
845       case 0x04:
846       case 0x05:
847       case 0x06:
848       case 0x07:
849         // Bit pattern 0xxx. No need for any extra bytes.
850         break;
851       case 0x08:
852       case 0x09:
853       case 0x0a:
854       case 0x0b:
855       case 0x0f:
856         /*
857          * Bit pattern 10xx or 1111, which are illegal start bytes.
858          * Note: 1111 is valid for normal UTF-8, but not the
859          * Modified UTF-8 used here.
860          */
861         *errorKind = "start";
862         return utf8;
863       case 0x0e:
864         // Bit pattern 1110, so there are two additional bytes.
865         utf8 = *(bytes++);
866         if ((utf8 & 0xc0) != 0x80) {
867           *errorKind = "continuation";
868           return utf8;
869         }
870         // Fall through to take care of the final byte.
871       case 0x0c:
872       case 0x0d:
873         // Bit pattern 110x, so there is one additional byte.
874         utf8 = *(bytes++);
875         if ((utf8 & 0xc0) != 0x80) {
876           *errorKind = "continuation";
877           return utf8;
878         }
879         break;
880       }
881     }
882     return 0;
883   }
884 
885   const ScopedObjectAccess soa_;
886   const char* function_name_;
887   int flags_;
888   bool has_method_;
889   int indent_;
890 
891   DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
892 };
893 
894 #define CHECK_JNI_ENTRY(flags, types, args...) \
895   ScopedCheck sc(env, flags, __FUNCTION__); \
896   sc.Check(true, types, ##args)
897 
898 #define CHECK_JNI_EXIT(type, exp) ({ \
899     auto _rc = (exp); \
900   sc.Check(false, type, _rc); \
901   _rc; })
902 #define CHECK_JNI_EXIT_VOID() \
903   sc.Check(false, "V")
904 
905 /*
906  * ===========================================================================
907  *      Guarded arrays
908  * ===========================================================================
909  */
910 
911 #define kGuardLen       512         /* must be multiple of 2 */
912 #define kGuardPattern   0xd5e3      /* uncommon values; d5e3d5e3 invalid addr */
913 #define kGuardMagic     0xffd5aa96
914 
915 /* this gets tucked in at the start of the buffer; struct size must be even */
916 struct GuardedCopy {
917   uint32_t magic;
918   uLong adler;
919   size_t original_length;
920   const void* original_ptr;
921 
922   /* find the GuardedCopy given the pointer into the "live" data */
FromDataart::GuardedCopy923   static inline const GuardedCopy* FromData(const void* dataBuf) {
924     return reinterpret_cast<const GuardedCopy*>(ActualBuffer(dataBuf));
925   }
926 
927   /*
928    * Create an over-sized buffer to hold the contents of "buf".  Copy it in,
929    * filling in the area around it with guard data.
930    *
931    * We use a 16-bit pattern to make a rogue memset less likely to elude us.
932    */
Createart::GuardedCopy933   static void* Create(const void* buf, size_t len, bool modOkay) {
934     size_t newLen = ActualLength(len);
935     uint8_t* newBuf = DebugAlloc(newLen);
936 
937     // Fill it in with a pattern.
938     uint16_t* pat = reinterpret_cast<uint16_t*>(newBuf);
939     for (size_t i = 0; i < newLen / 2; i++) {
940       *pat++ = kGuardPattern;
941     }
942 
943     // Copy the data in; note "len" could be zero.
944     memcpy(newBuf + kGuardLen / 2, buf, len);
945 
946     // If modification is not expected, grab a checksum.
947     uLong adler = 0;
948     if (!modOkay) {
949       adler = adler32(0L, Z_NULL, 0);
950       adler = adler32(adler, reinterpret_cast<const Bytef*>(buf), len);
951       *reinterpret_cast<uLong*>(newBuf) = adler;
952     }
953 
954     GuardedCopy* pExtra = reinterpret_cast<GuardedCopy*>(newBuf);
955     pExtra->magic = kGuardMagic;
956     pExtra->adler = adler;
957     pExtra->original_ptr = buf;
958     pExtra->original_length = len;
959 
960     return newBuf + kGuardLen / 2;
961   }
962 
963   /*
964    * Free up the guard buffer, scrub it, and return the original pointer.
965    */
Destroyart::GuardedCopy966   static void* Destroy(void* dataBuf) {
967     const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
968     void* original_ptr = const_cast<void*>(pExtra->original_ptr);
969     size_t len = pExtra->original_length;
970     DebugFree(dataBuf, len);
971     return original_ptr;
972   }
973 
974   /*
975    * Verify the guard area and, if "modOkay" is false, that the data itself
976    * has not been altered.
977    *
978    * The caller has already checked that "dataBuf" is non-NULL.
979    */
Checkart::GuardedCopy980   static void Check(const char* functionName, const void* dataBuf, bool modOkay) {
981     static const uint32_t kMagicCmp = kGuardMagic;
982     const uint8_t* fullBuf = ActualBuffer(dataBuf);
983     const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
984 
985     // Before we do anything with "pExtra", check the magic number.  We
986     // do the check with memcmp rather than "==" in case the pointer is
987     // unaligned.  If it points to completely bogus memory we're going
988     // to crash, but there's no easy way around that.
989     if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
990       uint8_t buf[4];
991       memcpy(buf, &pExtra->magic, 4);
992       JniAbortF(functionName,
993           "guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
994           buf[3], buf[2], buf[1], buf[0], dataBuf);  // Assumes little-endian.
995     }
996 
997     size_t len = pExtra->original_length;
998 
999     // Check bottom half of guard; skip over optional checksum storage.
1000     const uint16_t* pat = reinterpret_cast<const uint16_t*>(fullBuf);
1001     for (size_t i = sizeof(GuardedCopy) / 2; i < (kGuardLen / 2 - sizeof(GuardedCopy)) / 2; i++) {
1002       if (pat[i] != kGuardPattern) {
1003         JniAbortF(functionName, "guard pattern(1) disturbed at %p +%zd", fullBuf, i*2);
1004       }
1005     }
1006 
1007     int offset = kGuardLen / 2 + len;
1008     if (offset & 0x01) {
1009       // Odd byte; expected value depends on endian.
1010       const uint16_t patSample = kGuardPattern;
1011       uint8_t expected_byte = reinterpret_cast<const uint8_t*>(&patSample)[1];
1012       if (fullBuf[offset] != expected_byte) {
1013         JniAbortF(functionName, "guard pattern disturbed in odd byte after %p +%d 0x%02x 0x%02x",
1014                   fullBuf, offset, fullBuf[offset], expected_byte);
1015       }
1016       offset++;
1017     }
1018 
1019     // Check top half of guard.
1020     pat = reinterpret_cast<const uint16_t*>(fullBuf + offset);
1021     for (size_t i = 0; i < kGuardLen / 4; i++) {
1022       if (pat[i] != kGuardPattern) {
1023         JniAbortF(functionName, "guard pattern(2) disturbed at %p +%zd", fullBuf, offset + i*2);
1024       }
1025     }
1026 
1027     // If modification is not expected, verify checksum.  Strictly speaking
1028     // this is wrong: if we told the client that we made a copy, there's no
1029     // reason they can't alter the buffer.
1030     if (!modOkay) {
1031       uLong adler = adler32(0L, Z_NULL, 0);
1032       adler = adler32(adler, (const Bytef*)dataBuf, len);
1033       if (pExtra->adler != adler) {
1034         JniAbortF(functionName, "buffer modified (0x%08lx vs 0x%08lx) at address %p",
1035                   pExtra->adler, adler, dataBuf);
1036       }
1037     }
1038   }
1039 
1040  private:
DebugAllocart::GuardedCopy1041   static uint8_t* DebugAlloc(size_t len) {
1042     void* result = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
1043     if (result == MAP_FAILED) {
1044       PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed";
1045     }
1046     return reinterpret_cast<uint8_t*>(result);
1047   }
1048 
DebugFreeart::GuardedCopy1049   static void DebugFree(void* dataBuf, size_t len) {
1050     uint8_t* fullBuf = ActualBuffer(dataBuf);
1051     size_t totalByteCount = ActualLength(len);
1052     // TODO: we could mprotect instead, and keep the allocation around for a while.
1053     // This would be even more expensive, but it might catch more errors.
1054     // if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
1055     //     PLOG(WARNING) << "mprotect(PROT_NONE) failed";
1056     // }
1057     if (munmap(fullBuf, totalByteCount) != 0) {
1058       PLOG(FATAL) << "munmap(" << reinterpret_cast<void*>(fullBuf) << ", " << totalByteCount << ") failed";
1059     }
1060   }
1061 
ActualBufferart::GuardedCopy1062   static const uint8_t* ActualBuffer(const void* dataBuf) {
1063     return reinterpret_cast<const uint8_t*>(dataBuf) - kGuardLen / 2;
1064   }
1065 
ActualBufferart::GuardedCopy1066   static uint8_t* ActualBuffer(void* dataBuf) {
1067     return reinterpret_cast<uint8_t*>(dataBuf) - kGuardLen / 2;
1068   }
1069 
1070   // Underlying length of a user allocation of 'length' bytes.
ActualLengthart::GuardedCopy1071   static size_t ActualLength(size_t length) {
1072     return (length + kGuardLen + 1) & ~0x01;
1073   }
1074 };
1075 
1076 /*
1077  * Create a guarded copy of a primitive array.  Modifications to the copied
1078  * data are allowed.  Returns a pointer to the copied data.
1079  */
CreateGuardedPACopy(JNIEnv * env,const jarray java_array,jboolean * isCopy)1080 static void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* isCopy) {
1081   ScopedObjectAccess soa(env);
1082 
1083   mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
1084   size_t component_size = a->GetClass()->GetComponentSize();
1085   size_t byte_count = a->GetLength() * component_size;
1086   void* result = GuardedCopy::Create(a->GetRawData(component_size, 0), byte_count, true);
1087   if (isCopy != nullptr) {
1088     *isCopy = JNI_TRUE;
1089   }
1090   return result;
1091 }
1092 
1093 /*
1094  * Perform the array "release" operation, which may or may not copy data
1095  * back into the managed heap, and may or may not release the underlying storage.
1096  */
ReleaseGuardedPACopy(JNIEnv * env,jarray java_array,void * dataBuf,int mode)1097 static void ReleaseGuardedPACopy(JNIEnv* env, jarray java_array, void* dataBuf, int mode) {
1098   ScopedObjectAccess soa(env);
1099   mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
1100 
1101   GuardedCopy::Check(__FUNCTION__, dataBuf, true);
1102 
1103   if (mode != JNI_ABORT) {
1104     size_t len = GuardedCopy::FromData(dataBuf)->original_length;
1105     memcpy(a->GetRawData(a->GetClass()->GetComponentSize(), 0), dataBuf, len);
1106   }
1107   if (mode != JNI_COMMIT) {
1108     GuardedCopy::Destroy(dataBuf);
1109   }
1110 }
1111 
1112 /*
1113  * ===========================================================================
1114  *      JNI functions
1115  * ===========================================================================
1116  */
1117 
1118 class CheckJNI {
1119  public:
GetVersion(JNIEnv * env)1120   static jint GetVersion(JNIEnv* env) {
1121     CHECK_JNI_ENTRY(kFlag_Default, "E", env);
1122     return CHECK_JNI_EXIT("I", baseEnv(env)->GetVersion(env));
1123   }
1124 
DefineClass(JNIEnv * env,const char * name,jobject loader,const jbyte * buf,jsize bufLen)1125   static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, jsize bufLen) {
1126     CHECK_JNI_ENTRY(kFlag_Default, "EuLpz", env, name, loader, buf, bufLen);
1127     sc.CheckClassName(name);
1128     return CHECK_JNI_EXIT("c", baseEnv(env)->DefineClass(env, name, loader, buf, bufLen));
1129   }
1130 
FindClass(JNIEnv * env,const char * name)1131   static jclass FindClass(JNIEnv* env, const char* name) {
1132     CHECK_JNI_ENTRY(kFlag_Default, "Eu", env, name);
1133     sc.CheckClassName(name);
1134     return CHECK_JNI_EXIT("c", baseEnv(env)->FindClass(env, name));
1135   }
1136 
GetSuperclass(JNIEnv * env,jclass c)1137   static jclass GetSuperclass(JNIEnv* env, jclass c) {
1138     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1139     return CHECK_JNI_EXIT("c", baseEnv(env)->GetSuperclass(env, c));
1140   }
1141 
IsAssignableFrom(JNIEnv * env,jclass c1,jclass c2)1142   static jboolean IsAssignableFrom(JNIEnv* env, jclass c1, jclass c2) {
1143     CHECK_JNI_ENTRY(kFlag_Default, "Ecc", env, c1, c2);
1144     return CHECK_JNI_EXIT("b", baseEnv(env)->IsAssignableFrom(env, c1, c2));
1145   }
1146 
FromReflectedMethod(JNIEnv * env,jobject method)1147   static jmethodID FromReflectedMethod(JNIEnv* env, jobject method) {
1148     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, method);
1149     // TODO: check that 'field' is a java.lang.reflect.Method.
1150     return CHECK_JNI_EXIT("m", baseEnv(env)->FromReflectedMethod(env, method));
1151   }
1152 
FromReflectedField(JNIEnv * env,jobject field)1153   static jfieldID FromReflectedField(JNIEnv* env, jobject field) {
1154     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, field);
1155     // TODO: check that 'field' is a java.lang.reflect.Field.
1156     return CHECK_JNI_EXIT("f", baseEnv(env)->FromReflectedField(env, field));
1157   }
1158 
ToReflectedMethod(JNIEnv * env,jclass cls,jmethodID mid,jboolean isStatic)1159   static jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID mid, jboolean isStatic) {
1160     CHECK_JNI_ENTRY(kFlag_Default, "Ecmb", env, cls, mid, isStatic);
1161     return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedMethod(env, cls, mid, isStatic));
1162   }
1163 
ToReflectedField(JNIEnv * env,jclass cls,jfieldID fid,jboolean isStatic)1164   static jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fid, jboolean isStatic) {
1165     CHECK_JNI_ENTRY(kFlag_Default, "Ecfb", env, cls, fid, isStatic);
1166     return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedField(env, cls, fid, isStatic));
1167   }
1168 
Throw(JNIEnv * env,jthrowable obj)1169   static jint Throw(JNIEnv* env, jthrowable obj) {
1170     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1171     // TODO: check that 'obj' is a java.lang.Throwable.
1172     return CHECK_JNI_EXIT("I", baseEnv(env)->Throw(env, obj));
1173   }
1174 
ThrowNew(JNIEnv * env,jclass c,const char * message)1175   static jint ThrowNew(JNIEnv* env, jclass c, const char* message) {
1176     CHECK_JNI_ENTRY(kFlag_NullableUtf, "Ecu", env, c, message);
1177     return CHECK_JNI_EXIT("I", baseEnv(env)->ThrowNew(env, c, message));
1178   }
1179 
ExceptionOccurred(JNIEnv * env)1180   static jthrowable ExceptionOccurred(JNIEnv* env) {
1181     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1182     return CHECK_JNI_EXIT("L", baseEnv(env)->ExceptionOccurred(env));
1183   }
1184 
ExceptionDescribe(JNIEnv * env)1185   static void ExceptionDescribe(JNIEnv* env) {
1186     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1187     baseEnv(env)->ExceptionDescribe(env);
1188     CHECK_JNI_EXIT_VOID();
1189   }
1190 
ExceptionClear(JNIEnv * env)1191   static void ExceptionClear(JNIEnv* env) {
1192     CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1193     baseEnv(env)->ExceptionClear(env);
1194     CHECK_JNI_EXIT_VOID();
1195   }
1196 
FatalError(JNIEnv * env,const char * msg)1197   static void FatalError(JNIEnv* env, const char* msg) {
1198     // The JNI specification doesn't say it's okay to call FatalError with a pending exception,
1199     // but you're about to abort anyway, and it's quite likely that you have a pending exception,
1200     // and it's not unimaginable that you don't know that you do. So we allow it.
1201     CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_NullableUtf, "Eu", env, msg);
1202     baseEnv(env)->FatalError(env, msg);
1203     CHECK_JNI_EXIT_VOID();
1204   }
1205 
PushLocalFrame(JNIEnv * env,jint capacity)1206   static jint PushLocalFrame(JNIEnv* env, jint capacity) {
1207     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EI", env, capacity);
1208     return CHECK_JNI_EXIT("I", baseEnv(env)->PushLocalFrame(env, capacity));
1209   }
1210 
PopLocalFrame(JNIEnv * env,jobject res)1211   static jobject PopLocalFrame(JNIEnv* env, jobject res) {
1212     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, res);
1213     return CHECK_JNI_EXIT("L", baseEnv(env)->PopLocalFrame(env, res));
1214   }
1215 
NewGlobalRef(JNIEnv * env,jobject obj)1216   static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
1217     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1218     return CHECK_JNI_EXIT("L", baseEnv(env)->NewGlobalRef(env, obj));
1219   }
1220 
NewLocalRef(JNIEnv * env,jobject ref)1221   static jobject NewLocalRef(JNIEnv* env, jobject ref) {
1222     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, ref);
1223     return CHECK_JNI_EXIT("L", baseEnv(env)->NewLocalRef(env, ref));
1224   }
1225 
DeleteGlobalRef(JNIEnv * env,jobject globalRef)1226   static void DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
1227     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef);
1228     if (globalRef != nullptr && GetIndirectRefKind(globalRef) != kGlobal) {
1229       JniAbortF(__FUNCTION__, "DeleteGlobalRef on %s: %p",
1230                 ToStr<IndirectRefKind>(GetIndirectRefKind(globalRef)).c_str(), globalRef);
1231     } else {
1232       baseEnv(env)->DeleteGlobalRef(env, globalRef);
1233       CHECK_JNI_EXIT_VOID();
1234     }
1235   }
1236 
DeleteWeakGlobalRef(JNIEnv * env,jweak weakGlobalRef)1237   static void DeleteWeakGlobalRef(JNIEnv* env, jweak weakGlobalRef) {
1238     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, weakGlobalRef);
1239     if (weakGlobalRef != nullptr && GetIndirectRefKind(weakGlobalRef) != kWeakGlobal) {
1240       JniAbortF(__FUNCTION__, "DeleteWeakGlobalRef on %s: %p",
1241                 ToStr<IndirectRefKind>(GetIndirectRefKind(weakGlobalRef)).c_str(), weakGlobalRef);
1242     } else {
1243       baseEnv(env)->DeleteWeakGlobalRef(env, weakGlobalRef);
1244       CHECK_JNI_EXIT_VOID();
1245     }
1246   }
1247 
DeleteLocalRef(JNIEnv * env,jobject localRef)1248   static void DeleteLocalRef(JNIEnv* env, jobject localRef) {
1249     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef);
1250     if (localRef != nullptr && GetIndirectRefKind(localRef) != kLocal && !IsHandleScopeLocalRef(env, localRef)) {
1251       JniAbortF(__FUNCTION__, "DeleteLocalRef on %s: %p",
1252                 ToStr<IndirectRefKind>(GetIndirectRefKind(localRef)).c_str(), localRef);
1253     } else {
1254       baseEnv(env)->DeleteLocalRef(env, localRef);
1255       CHECK_JNI_EXIT_VOID();
1256     }
1257   }
1258 
EnsureLocalCapacity(JNIEnv * env,jint capacity)1259   static jint EnsureLocalCapacity(JNIEnv *env, jint capacity) {
1260     CHECK_JNI_ENTRY(kFlag_Default, "EI", env, capacity);
1261     return CHECK_JNI_EXIT("I", baseEnv(env)->EnsureLocalCapacity(env, capacity));
1262   }
1263 
IsSameObject(JNIEnv * env,jobject ref1,jobject ref2)1264   static jboolean IsSameObject(JNIEnv* env, jobject ref1, jobject ref2) {
1265     CHECK_JNI_ENTRY(kFlag_Default, "ELL", env, ref1, ref2);
1266     return CHECK_JNI_EXIT("b", baseEnv(env)->IsSameObject(env, ref1, ref2));
1267   }
1268 
AllocObject(JNIEnv * env,jclass c)1269   static jobject AllocObject(JNIEnv* env, jclass c) {
1270     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1271     return CHECK_JNI_EXIT("L", baseEnv(env)->AllocObject(env, c));
1272   }
1273 
NewObject(JNIEnv * env,jclass c,jmethodID mid,...)1274   static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
1275     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
1276     va_list args;
1277     va_start(args, mid);
1278     jobject result = baseEnv(env)->NewObjectV(env, c, mid, args);
1279     va_end(args);
1280     return CHECK_JNI_EXIT("L", result);
1281   }
1282 
NewObjectV(JNIEnv * env,jclass c,jmethodID mid,va_list args)1283   static jobject NewObjectV(JNIEnv* env, jclass c, jmethodID mid, va_list args) {
1284     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
1285     return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectV(env, c, mid, args));
1286   }
1287 
NewObjectA(JNIEnv * env,jclass c,jmethodID mid,jvalue * args)1288   static jobject NewObjectA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) {
1289     CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
1290     return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectA(env, c, mid, args));
1291   }
1292 
GetObjectClass(JNIEnv * env,jobject obj)1293   static jclass GetObjectClass(JNIEnv* env, jobject obj) {
1294     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1295     return CHECK_JNI_EXIT("c", baseEnv(env)->GetObjectClass(env, obj));
1296   }
1297 
IsInstanceOf(JNIEnv * env,jobject obj,jclass c)1298   static jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass c) {
1299     CHECK_JNI_ENTRY(kFlag_Default, "ELc", env, obj, c);
1300     return CHECK_JNI_EXIT("b", baseEnv(env)->IsInstanceOf(env, obj, c));
1301   }
1302 
GetMethodID(JNIEnv * env,jclass c,const char * name,const char * sig)1303   static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1304     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1305     return CHECK_JNI_EXIT("m", baseEnv(env)->GetMethodID(env, c, name, sig));
1306   }
1307 
GetFieldID(JNIEnv * env,jclass c,const char * name,const char * sig)1308   static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1309     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1310     return CHECK_JNI_EXIT("f", baseEnv(env)->GetFieldID(env, c, name, sig));
1311   }
1312 
GetStaticMethodID(JNIEnv * env,jclass c,const char * name,const char * sig)1313   static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1314     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1315     return CHECK_JNI_EXIT("m", baseEnv(env)->GetStaticMethodID(env, c, name, sig));
1316   }
1317 
GetStaticFieldID(JNIEnv * env,jclass c,const char * name,const char * sig)1318   static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1319     CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1320     return CHECK_JNI_EXIT("f", baseEnv(env)->GetStaticFieldID(env, c, name, sig));
1321   }
1322 
1323 #define FIELD_ACCESSORS(_ctype, _jname, _jvalue_type, _type) \
1324     static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid) { \
1325         CHECK_JNI_ENTRY(kFlag_Default, "Ecf", env, c, fid); \
1326         sc.CheckStaticFieldID(c, fid); \
1327         return CHECK_JNI_EXIT(_type, baseEnv(env)->GetStatic##_jname##Field(env, c, fid)); \
1328     } \
1329     static _ctype Get##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid) { \
1330         CHECK_JNI_ENTRY(kFlag_Default, "ELf", env, obj, fid); \
1331         sc.CheckInstanceFieldID(obj, fid); \
1332         return CHECK_JNI_EXIT(_type, baseEnv(env)->Get##_jname##Field(env, obj, fid)); \
1333     } \
1334     static void SetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid, _ctype value) { \
1335         CHECK_JNI_ENTRY(kFlag_Default, "Ecf" _type, env, c, fid, value); \
1336         sc.CheckStaticFieldID(c, fid); \
1337         /* "value" arg only used when type == ref */ \
1338         jvalue java_type_value; \
1339         java_type_value._jvalue_type = value; \
1340         sc.CheckFieldType(java_type_value, fid, _type[0], true); \
1341         baseEnv(env)->SetStatic##_jname##Field(env, c, fid, value); \
1342         CHECK_JNI_EXIT_VOID(); \
1343     } \
1344     static void Set##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid, _ctype value) { \
1345         CHECK_JNI_ENTRY(kFlag_Default, "ELf" _type, env, obj, fid, value); \
1346         sc.CheckInstanceFieldID(obj, fid); \
1347         /* "value" arg only used when type == ref */ \
1348         jvalue java_type_value; \
1349         java_type_value._jvalue_type = value; \
1350         sc.CheckFieldType(java_type_value, fid, _type[0], false); \
1351         baseEnv(env)->Set##_jname##Field(env, obj, fid, value); \
1352         CHECK_JNI_EXIT_VOID(); \
1353     }
1354 
1355 FIELD_ACCESSORS(jobject, Object, l, "L");
1356 FIELD_ACCESSORS(jboolean, Boolean, z, "Z");
1357 FIELD_ACCESSORS(jbyte, Byte, b, "B");
1358 FIELD_ACCESSORS(jchar, Char, c, "C");
1359 FIELD_ACCESSORS(jshort, Short, s, "S");
1360 FIELD_ACCESSORS(jint, Int, i, "I");
1361 FIELD_ACCESSORS(jlong, Long, j, "J");
1362 FIELD_ACCESSORS(jfloat, Float, f, "F");
1363 FIELD_ACCESSORS(jdouble, Double, d, "D");
1364 
1365 #define CALL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig) \
1366     /* Virtual... */ \
1367     static _ctype Call##_jname##Method(JNIEnv* env, jobject obj, \
1368         jmethodID mid, ...) \
1369     { \
1370         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
1371         sc.CheckSig(mid, _retsig, false); \
1372         sc.CheckVirtualMethod(obj, mid); \
1373         _retdecl; \
1374         va_list args; \
1375         va_start(args, mid); \
1376         _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
1377         va_end(args); \
1378         _retok; \
1379     } \
1380     static _ctype Call##_jname##MethodV(JNIEnv* env, jobject obj, \
1381         jmethodID mid, va_list args) \
1382     { \
1383         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
1384         sc.CheckSig(mid, _retsig, false); \
1385         sc.CheckVirtualMethod(obj, mid); \
1386         _retdecl; \
1387         _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
1388         _retok; \
1389     } \
1390     static _ctype Call##_jname##MethodA(JNIEnv* env, jobject obj, \
1391         jmethodID mid, jvalue* args) \
1392     { \
1393         CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
1394         sc.CheckSig(mid, _retsig, false); \
1395         sc.CheckVirtualMethod(obj, mid); \
1396         _retdecl; \
1397         _retasgn(baseEnv(env)->Call##_jname##MethodA(env, obj, mid, args)); \
1398         _retok; \
1399     } \
1400     /* Non-virtual... */ \
1401     static _ctype CallNonvirtual##_jname##Method(JNIEnv* env, \
1402         jobject obj, jclass c, jmethodID mid, ...) \
1403     { \
1404         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
1405         sc.CheckSig(mid, _retsig, false); \
1406         sc.CheckVirtualMethod(obj, mid); \
1407         _retdecl; \
1408         va_list args; \
1409         va_start(args, mid); \
1410         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
1411         va_end(args); \
1412         _retok; \
1413     } \
1414     static _ctype CallNonvirtual##_jname##MethodV(JNIEnv* env, \
1415         jobject obj, jclass c, jmethodID mid, va_list args) \
1416     { \
1417         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
1418         sc.CheckSig(mid, _retsig, false); \
1419         sc.CheckVirtualMethod(obj, mid); \
1420         _retdecl; \
1421         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
1422         _retok; \
1423     } \
1424     static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, \
1425         jobject obj, jclass c, jmethodID mid, jvalue* args) \
1426     { \
1427         CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
1428         sc.CheckSig(mid, _retsig, false); \
1429         sc.CheckVirtualMethod(obj, mid); \
1430         _retdecl; \
1431         _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodA(env, obj, c, mid, args)); \
1432         _retok; \
1433     } \
1434     /* Static... */ \
1435     static _ctype CallStatic##_jname##Method(JNIEnv* env, jclass c, jmethodID mid, ...) \
1436     { \
1437         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
1438         sc.CheckSig(mid, _retsig, true); \
1439         sc.CheckStaticMethod(c, mid); \
1440         _retdecl; \
1441         va_list args; \
1442         va_start(args, mid); \
1443         _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
1444         va_end(args); \
1445         _retok; \
1446     } \
1447     static _ctype CallStatic##_jname##MethodV(JNIEnv* env, jclass c, jmethodID mid, va_list args) \
1448     { \
1449         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
1450         sc.CheckSig(mid, _retsig, true); \
1451         sc.CheckStaticMethod(c, mid); \
1452         _retdecl; \
1453          _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
1454         _retok; \
1455     } \
1456     static _ctype CallStatic##_jname##MethodA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) \
1457     { \
1458         CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
1459         sc.CheckSig(mid, _retsig, true); \
1460         sc.CheckStaticMethod(c, mid); \
1461         _retdecl; \
1462         _retasgn(baseEnv(env)->CallStatic##_jname##MethodA(env, c, mid, args)); \
1463         _retok; \
1464     }
1465 
1466 #define NON_VOID_RETURN(_retsig, _ctype) return CHECK_JNI_EXIT(_retsig, (_ctype) result)
1467 #define VOID_RETURN CHECK_JNI_EXIT_VOID()
1468 
1469 CALL(jobject, Object, mirror::Object* result, result = reinterpret_cast<mirror::Object*>, NON_VOID_RETURN("L", jobject), "L");
1470 CALL(jboolean, Boolean, jboolean result, result =, NON_VOID_RETURN("Z", jboolean), "Z");
1471 CALL(jbyte, Byte, jbyte result, result =, NON_VOID_RETURN("B", jbyte), "B");
1472 CALL(jchar, Char, jchar result, result =, NON_VOID_RETURN("C", jchar), "C");
1473 CALL(jshort, Short, jshort result, result =, NON_VOID_RETURN("S", jshort), "S");
1474 CALL(jint, Int, jint result, result =, NON_VOID_RETURN("I", jint), "I");
1475 CALL(jlong, Long, jlong result, result =, NON_VOID_RETURN("J", jlong), "J");
1476 CALL(jfloat, Float, jfloat result, result =, NON_VOID_RETURN("F", jfloat), "F");
1477 CALL(jdouble, Double, jdouble result, result =, NON_VOID_RETURN("D", jdouble), "D");
1478 CALL(void, Void, , , VOID_RETURN, "V");
1479 
NewString(JNIEnv * env,const jchar * unicodeChars,jsize len)1480   static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) {
1481     CHECK_JNI_ENTRY(kFlag_Default, "Epz", env, unicodeChars, len);
1482     return CHECK_JNI_EXIT("s", baseEnv(env)->NewString(env, unicodeChars, len));
1483   }
1484 
GetStringLength(JNIEnv * env,jstring string)1485   static jsize GetStringLength(JNIEnv* env, jstring string) {
1486     CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
1487     return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringLength(env, string));
1488   }
1489 
GetStringChars(JNIEnv * env,jstring java_string,jboolean * isCopy)1490   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* isCopy) {
1491     CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
1492     const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
1493     if (sc.ForceCopy() && result != nullptr) {
1494       mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
1495       int byteCount = s->GetLength() * 2;
1496       result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
1497       if (isCopy != nullptr) {
1498         *isCopy = JNI_TRUE;
1499       }
1500     }
1501     return CHECK_JNI_EXIT("p", result);
1502   }
1503 
ReleaseStringChars(JNIEnv * env,jstring string,const jchar * chars)1504   static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) {
1505     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Esp", env, string, chars);
1506     sc.CheckNonNull(chars);
1507     if (sc.ForceCopy()) {
1508       GuardedCopy::Check(__FUNCTION__, chars, false);
1509       chars = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(chars)));
1510     }
1511     baseEnv(env)->ReleaseStringChars(env, string, chars);
1512     CHECK_JNI_EXIT_VOID();
1513   }
1514 
NewStringUTF(JNIEnv * env,const char * bytes)1515   static jstring NewStringUTF(JNIEnv* env, const char* bytes) {
1516     CHECK_JNI_ENTRY(kFlag_NullableUtf, "Eu", env, bytes);  // TODO: show pointer and truncate string.
1517     return CHECK_JNI_EXIT("s", baseEnv(env)->NewStringUTF(env, bytes));
1518   }
1519 
GetStringUTFLength(JNIEnv * env,jstring string)1520   static jsize GetStringUTFLength(JNIEnv* env, jstring string) {
1521     CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
1522     return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringUTFLength(env, string));
1523   }
1524 
GetStringUTFChars(JNIEnv * env,jstring string,jboolean * isCopy)1525   static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* isCopy) {
1526     CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
1527     const char* result = baseEnv(env)->GetStringUTFChars(env, string, isCopy);
1528     if (sc.ForceCopy() && result != nullptr) {
1529       result = (const char*) GuardedCopy::Create(result, strlen(result) + 1, false);
1530       if (isCopy != nullptr) {
1531         *isCopy = JNI_TRUE;
1532       }
1533     }
1534     return CHECK_JNI_EXIT("u", result);  // TODO: show pointer and truncate string.
1535   }
1536 
ReleaseStringUTFChars(JNIEnv * env,jstring string,const char * utf)1537   static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) {
1538     CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf);  // TODO: show pointer and truncate string.
1539     if (sc.ForceCopy()) {
1540       GuardedCopy::Check(__FUNCTION__, utf, false);
1541       utf = reinterpret_cast<const char*>(GuardedCopy::Destroy(const_cast<char*>(utf)));
1542     }
1543     baseEnv(env)->ReleaseStringUTFChars(env, string, utf);
1544     CHECK_JNI_EXIT_VOID();
1545   }
1546 
GetArrayLength(JNIEnv * env,jarray array)1547   static jsize GetArrayLength(JNIEnv* env, jarray array) {
1548     CHECK_JNI_ENTRY(kFlag_CritOkay, "Ea", env, array);
1549     return CHECK_JNI_EXIT("I", baseEnv(env)->GetArrayLength(env, array));
1550   }
1551 
NewObjectArray(JNIEnv * env,jsize length,jclass elementClass,jobject initialElement)1552   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass elementClass, jobject initialElement) {
1553     CHECK_JNI_ENTRY(kFlag_Default, "EzcL", env, length, elementClass, initialElement);
1554     return CHECK_JNI_EXIT("a", baseEnv(env)->NewObjectArray(env, length, elementClass, initialElement));
1555   }
1556 
GetObjectArrayElement(JNIEnv * env,jobjectArray array,jsize index)1557   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
1558     CHECK_JNI_ENTRY(kFlag_Default, "EaI", env, array, index);
1559     return CHECK_JNI_EXIT("L", baseEnv(env)->GetObjectArrayElement(env, array, index));
1560   }
1561 
SetObjectArrayElement(JNIEnv * env,jobjectArray array,jsize index,jobject value)1562   static void SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) {
1563     CHECK_JNI_ENTRY(kFlag_Default, "EaIL", env, array, index, value);
1564     baseEnv(env)->SetObjectArrayElement(env, array, index, value);
1565     CHECK_JNI_EXIT_VOID();
1566   }
1567 
1568 #define NEW_PRIMITIVE_ARRAY(_artype, _jname) \
1569     static _artype New##_jname##Array(JNIEnv* env, jsize length) { \
1570         CHECK_JNI_ENTRY(kFlag_Default, "Ez", env, length); \
1571         return CHECK_JNI_EXIT("a", baseEnv(env)->New##_jname##Array(env, length)); \
1572     }
1573 NEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
1574 NEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
1575 NEW_PRIMITIVE_ARRAY(jcharArray, Char);
1576 NEW_PRIMITIVE_ARRAY(jshortArray, Short);
1577 NEW_PRIMITIVE_ARRAY(jintArray, Int);
1578 NEW_PRIMITIVE_ARRAY(jlongArray, Long);
1579 NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
1580 NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
1581 
1582 struct ForceCopyGetChecker {
1583  public:
ForceCopyGetCheckerart::CheckJNI::ForceCopyGetChecker1584   ForceCopyGetChecker(ScopedCheck& sc, jboolean* isCopy) {
1585     force_copy = sc.ForceCopy();
1586     no_copy = 0;
1587     if (force_copy && isCopy != nullptr) {
1588       // Capture this before the base call tramples on it.
1589       no_copy = *reinterpret_cast<uint32_t*>(isCopy);
1590     }
1591   }
1592 
1593   template<typename ResultT>
Checkart::CheckJNI::ForceCopyGetChecker1594   ResultT Check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
1595     if (force_copy && result != nullptr) {
1596       result = reinterpret_cast<ResultT>(CreateGuardedPACopy(env, array, isCopy));
1597     }
1598     return result;
1599   }
1600 
1601   uint32_t no_copy;
1602   bool force_copy;
1603 };
1604 
1605 #define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
1606   static _ctype* Get##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, jboolean* isCopy) { \
1607     CHECK_JNI_ENTRY(kFlag_Default, "Eap", env, array, isCopy); \
1608     _ctype* result = ForceCopyGetChecker(sc, isCopy).Check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
1609     return CHECK_JNI_EXIT("p", result); \
1610   }
1611 
1612 #define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
1613   static void Release##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, _ctype* elems, jint mode) { \
1614     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Eapr", env, array, elems, mode); \
1615     sc.CheckNonNull(elems); \
1616     if (sc.ForceCopy()) { \
1617       ReleaseGuardedPACopy(env, array, elems, mode); \
1618     } \
1619     baseEnv(env)->Release##_jname##ArrayElements(env, array, elems, mode); \
1620     CHECK_JNI_EXIT_VOID(); \
1621   }
1622 
1623 #define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
1624     static void Get##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, _ctype* buf) { \
1625         CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
1626         baseEnv(env)->Get##_jname##ArrayRegion(env, array, start, len, buf); \
1627         CHECK_JNI_EXIT_VOID(); \
1628     }
1629 
1630 #define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
1631     static void Set##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, const _ctype* buf) { \
1632         CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
1633         baseEnv(env)->Set##_jname##ArrayRegion(env, array, start, len, buf); \
1634         CHECK_JNI_EXIT_VOID(); \
1635     }
1636 
1637 #define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar) \
1638     GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
1639     RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
1640     GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname); \
1641     SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
1642 
1643 // TODO: verify primitive array type matches call type.
1644 PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
1645 PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
1646 PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
1647 PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
1648 PRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
1649 PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
1650 PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
1651 PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
1652 
RegisterNatives(JNIEnv * env,jclass c,const JNINativeMethod * methods,jint nMethods)1653   static jint RegisterNatives(JNIEnv* env, jclass c, const JNINativeMethod* methods, jint nMethods) {
1654     CHECK_JNI_ENTRY(kFlag_Default, "EcpI", env, c, methods, nMethods);
1655     return CHECK_JNI_EXIT("I", baseEnv(env)->RegisterNatives(env, c, methods, nMethods));
1656   }
1657 
UnregisterNatives(JNIEnv * env,jclass c)1658   static jint UnregisterNatives(JNIEnv* env, jclass c) {
1659     CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1660     return CHECK_JNI_EXIT("I", baseEnv(env)->UnregisterNatives(env, c));
1661   }
1662 
MonitorEnter(JNIEnv * env,jobject obj)1663   static jint MonitorEnter(JNIEnv* env, jobject obj) {
1664     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1665     if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
1666       return JNI_ERR;  // Only for jni_internal_test. Real code will have aborted already.
1667     }
1668     return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorEnter(env, obj));
1669   }
1670 
MonitorExit(JNIEnv * env,jobject obj)1671   static jint MonitorExit(JNIEnv* env, jobject obj) {
1672     CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, obj);
1673     if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
1674       return JNI_ERR;  // Only for jni_internal_test. Real code will have aborted already.
1675     }
1676     return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorExit(env, obj));
1677   }
1678 
GetJavaVM(JNIEnv * env,JavaVM ** vm)1679   static jint GetJavaVM(JNIEnv *env, JavaVM **vm) {
1680     CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, vm);
1681     return CHECK_JNI_EXIT("I", baseEnv(env)->GetJavaVM(env, vm));
1682   }
1683 
GetStringRegion(JNIEnv * env,jstring str,jsize start,jsize len,jchar * buf)1684   static void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar* buf) {
1685     CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
1686     baseEnv(env)->GetStringRegion(env, str, start, len, buf);
1687     CHECK_JNI_EXIT_VOID();
1688   }
1689 
GetStringUTFRegion(JNIEnv * env,jstring str,jsize start,jsize len,char * buf)1690   static void GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char* buf) {
1691     CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
1692     baseEnv(env)->GetStringUTFRegion(env, str, start, len, buf);
1693     CHECK_JNI_EXIT_VOID();
1694   }
1695 
GetPrimitiveArrayCritical(JNIEnv * env,jarray array,jboolean * isCopy)1696   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* isCopy) {
1697     CHECK_JNI_ENTRY(kFlag_CritGet, "Eap", env, array, isCopy);
1698     void* result = baseEnv(env)->GetPrimitiveArrayCritical(env, array, isCopy);
1699     if (sc.ForceCopy() && result != nullptr) {
1700       result = CreateGuardedPACopy(env, array, isCopy);
1701     }
1702     return CHECK_JNI_EXIT("p", result);
1703   }
1704 
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray array,void * carray,jint mode)1705   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) {
1706     CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Eapr", env, array, carray, mode);
1707     sc.CheckNonNull(carray);
1708     if (sc.ForceCopy()) {
1709       ReleaseGuardedPACopy(env, array, carray, mode);
1710     }
1711     baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
1712     CHECK_JNI_EXIT_VOID();
1713   }
1714 
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * isCopy)1715   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* isCopy) {
1716     CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
1717     const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
1718     if (sc.ForceCopy() && result != nullptr) {
1719       mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
1720       int byteCount = s->GetLength() * 2;
1721       result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
1722       if (isCopy != nullptr) {
1723         *isCopy = JNI_TRUE;
1724       }
1725     }
1726     return CHECK_JNI_EXIT("p", result);
1727   }
1728 
ReleaseStringCritical(JNIEnv * env,jstring string,const jchar * carray)1729   static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* carray) {
1730     CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Esp", env, string, carray);
1731     sc.CheckNonNull(carray);
1732     if (sc.ForceCopy()) {
1733       GuardedCopy::Check(__FUNCTION__, carray, false);
1734       carray = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(carray)));
1735     }
1736     baseEnv(env)->ReleaseStringCritical(env, string, carray);
1737     CHECK_JNI_EXIT_VOID();
1738   }
1739 
NewWeakGlobalRef(JNIEnv * env,jobject obj)1740   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
1741     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1742     return CHECK_JNI_EXIT("L", baseEnv(env)->NewWeakGlobalRef(env, obj));
1743   }
1744 
ExceptionCheck(JNIEnv * env)1745   static jboolean ExceptionCheck(JNIEnv* env) {
1746     CHECK_JNI_ENTRY(kFlag_CritOkay | kFlag_ExcepOkay, "E", env);
1747     return CHECK_JNI_EXIT("b", baseEnv(env)->ExceptionCheck(env));
1748   }
1749 
GetObjectRefType(JNIEnv * env,jobject obj)1750   static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) {
1751     // Note: we use "Ep" rather than "EL" because this is the one JNI function
1752     // that it's okay to pass an invalid reference to.
1753     CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, obj);
1754     // TODO: proper decoding of jobjectRefType!
1755     return CHECK_JNI_EXIT("I", baseEnv(env)->GetObjectRefType(env, obj));
1756   }
1757 
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)1758   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
1759     CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
1760     if (address == nullptr) {
1761       JniAbortF(__FUNCTION__, "non-nullable address is NULL");
1762       return nullptr;
1763     }
1764     return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
1765   }
1766 
GetDirectBufferAddress(JNIEnv * env,jobject buf)1767   static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
1768     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
1769     // TODO: check that 'buf' is a java.nio.Buffer.
1770     return CHECK_JNI_EXIT("p", baseEnv(env)->GetDirectBufferAddress(env, buf));
1771   }
1772 
GetDirectBufferCapacity(JNIEnv * env,jobject buf)1773   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
1774     CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
1775     // TODO: check that 'buf' is a java.nio.Buffer.
1776     return CHECK_JNI_EXIT("J", baseEnv(env)->GetDirectBufferCapacity(env, buf));
1777   }
1778 
1779  private:
baseEnv(JNIEnv * env)1780   static inline const JNINativeInterface* baseEnv(JNIEnv* env) {
1781     return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions;
1782   }
1783 };
1784 
1785 const JNINativeInterface gCheckNativeInterface = {
1786   nullptr,  // reserved0.
1787   nullptr,  // reserved1.
1788   nullptr,  // reserved2.
1789   nullptr,  // reserved3.
1790   CheckJNI::GetVersion,
1791   CheckJNI::DefineClass,
1792   CheckJNI::FindClass,
1793   CheckJNI::FromReflectedMethod,
1794   CheckJNI::FromReflectedField,
1795   CheckJNI::ToReflectedMethod,
1796   CheckJNI::GetSuperclass,
1797   CheckJNI::IsAssignableFrom,
1798   CheckJNI::ToReflectedField,
1799   CheckJNI::Throw,
1800   CheckJNI::ThrowNew,
1801   CheckJNI::ExceptionOccurred,
1802   CheckJNI::ExceptionDescribe,
1803   CheckJNI::ExceptionClear,
1804   CheckJNI::FatalError,
1805   CheckJNI::PushLocalFrame,
1806   CheckJNI::PopLocalFrame,
1807   CheckJNI::NewGlobalRef,
1808   CheckJNI::DeleteGlobalRef,
1809   CheckJNI::DeleteLocalRef,
1810   CheckJNI::IsSameObject,
1811   CheckJNI::NewLocalRef,
1812   CheckJNI::EnsureLocalCapacity,
1813   CheckJNI::AllocObject,
1814   CheckJNI::NewObject,
1815   CheckJNI::NewObjectV,
1816   CheckJNI::NewObjectA,
1817   CheckJNI::GetObjectClass,
1818   CheckJNI::IsInstanceOf,
1819   CheckJNI::GetMethodID,
1820   CheckJNI::CallObjectMethod,
1821   CheckJNI::CallObjectMethodV,
1822   CheckJNI::CallObjectMethodA,
1823   CheckJNI::CallBooleanMethod,
1824   CheckJNI::CallBooleanMethodV,
1825   CheckJNI::CallBooleanMethodA,
1826   CheckJNI::CallByteMethod,
1827   CheckJNI::CallByteMethodV,
1828   CheckJNI::CallByteMethodA,
1829   CheckJNI::CallCharMethod,
1830   CheckJNI::CallCharMethodV,
1831   CheckJNI::CallCharMethodA,
1832   CheckJNI::CallShortMethod,
1833   CheckJNI::CallShortMethodV,
1834   CheckJNI::CallShortMethodA,
1835   CheckJNI::CallIntMethod,
1836   CheckJNI::CallIntMethodV,
1837   CheckJNI::CallIntMethodA,
1838   CheckJNI::CallLongMethod,
1839   CheckJNI::CallLongMethodV,
1840   CheckJNI::CallLongMethodA,
1841   CheckJNI::CallFloatMethod,
1842   CheckJNI::CallFloatMethodV,
1843   CheckJNI::CallFloatMethodA,
1844   CheckJNI::CallDoubleMethod,
1845   CheckJNI::CallDoubleMethodV,
1846   CheckJNI::CallDoubleMethodA,
1847   CheckJNI::CallVoidMethod,
1848   CheckJNI::CallVoidMethodV,
1849   CheckJNI::CallVoidMethodA,
1850   CheckJNI::CallNonvirtualObjectMethod,
1851   CheckJNI::CallNonvirtualObjectMethodV,
1852   CheckJNI::CallNonvirtualObjectMethodA,
1853   CheckJNI::CallNonvirtualBooleanMethod,
1854   CheckJNI::CallNonvirtualBooleanMethodV,
1855   CheckJNI::CallNonvirtualBooleanMethodA,
1856   CheckJNI::CallNonvirtualByteMethod,
1857   CheckJNI::CallNonvirtualByteMethodV,
1858   CheckJNI::CallNonvirtualByteMethodA,
1859   CheckJNI::CallNonvirtualCharMethod,
1860   CheckJNI::CallNonvirtualCharMethodV,
1861   CheckJNI::CallNonvirtualCharMethodA,
1862   CheckJNI::CallNonvirtualShortMethod,
1863   CheckJNI::CallNonvirtualShortMethodV,
1864   CheckJNI::CallNonvirtualShortMethodA,
1865   CheckJNI::CallNonvirtualIntMethod,
1866   CheckJNI::CallNonvirtualIntMethodV,
1867   CheckJNI::CallNonvirtualIntMethodA,
1868   CheckJNI::CallNonvirtualLongMethod,
1869   CheckJNI::CallNonvirtualLongMethodV,
1870   CheckJNI::CallNonvirtualLongMethodA,
1871   CheckJNI::CallNonvirtualFloatMethod,
1872   CheckJNI::CallNonvirtualFloatMethodV,
1873   CheckJNI::CallNonvirtualFloatMethodA,
1874   CheckJNI::CallNonvirtualDoubleMethod,
1875   CheckJNI::CallNonvirtualDoubleMethodV,
1876   CheckJNI::CallNonvirtualDoubleMethodA,
1877   CheckJNI::CallNonvirtualVoidMethod,
1878   CheckJNI::CallNonvirtualVoidMethodV,
1879   CheckJNI::CallNonvirtualVoidMethodA,
1880   CheckJNI::GetFieldID,
1881   CheckJNI::GetObjectField,
1882   CheckJNI::GetBooleanField,
1883   CheckJNI::GetByteField,
1884   CheckJNI::GetCharField,
1885   CheckJNI::GetShortField,
1886   CheckJNI::GetIntField,
1887   CheckJNI::GetLongField,
1888   CheckJNI::GetFloatField,
1889   CheckJNI::GetDoubleField,
1890   CheckJNI::SetObjectField,
1891   CheckJNI::SetBooleanField,
1892   CheckJNI::SetByteField,
1893   CheckJNI::SetCharField,
1894   CheckJNI::SetShortField,
1895   CheckJNI::SetIntField,
1896   CheckJNI::SetLongField,
1897   CheckJNI::SetFloatField,
1898   CheckJNI::SetDoubleField,
1899   CheckJNI::GetStaticMethodID,
1900   CheckJNI::CallStaticObjectMethod,
1901   CheckJNI::CallStaticObjectMethodV,
1902   CheckJNI::CallStaticObjectMethodA,
1903   CheckJNI::CallStaticBooleanMethod,
1904   CheckJNI::CallStaticBooleanMethodV,
1905   CheckJNI::CallStaticBooleanMethodA,
1906   CheckJNI::CallStaticByteMethod,
1907   CheckJNI::CallStaticByteMethodV,
1908   CheckJNI::CallStaticByteMethodA,
1909   CheckJNI::CallStaticCharMethod,
1910   CheckJNI::CallStaticCharMethodV,
1911   CheckJNI::CallStaticCharMethodA,
1912   CheckJNI::CallStaticShortMethod,
1913   CheckJNI::CallStaticShortMethodV,
1914   CheckJNI::CallStaticShortMethodA,
1915   CheckJNI::CallStaticIntMethod,
1916   CheckJNI::CallStaticIntMethodV,
1917   CheckJNI::CallStaticIntMethodA,
1918   CheckJNI::CallStaticLongMethod,
1919   CheckJNI::CallStaticLongMethodV,
1920   CheckJNI::CallStaticLongMethodA,
1921   CheckJNI::CallStaticFloatMethod,
1922   CheckJNI::CallStaticFloatMethodV,
1923   CheckJNI::CallStaticFloatMethodA,
1924   CheckJNI::CallStaticDoubleMethod,
1925   CheckJNI::CallStaticDoubleMethodV,
1926   CheckJNI::CallStaticDoubleMethodA,
1927   CheckJNI::CallStaticVoidMethod,
1928   CheckJNI::CallStaticVoidMethodV,
1929   CheckJNI::CallStaticVoidMethodA,
1930   CheckJNI::GetStaticFieldID,
1931   CheckJNI::GetStaticObjectField,
1932   CheckJNI::GetStaticBooleanField,
1933   CheckJNI::GetStaticByteField,
1934   CheckJNI::GetStaticCharField,
1935   CheckJNI::GetStaticShortField,
1936   CheckJNI::GetStaticIntField,
1937   CheckJNI::GetStaticLongField,
1938   CheckJNI::GetStaticFloatField,
1939   CheckJNI::GetStaticDoubleField,
1940   CheckJNI::SetStaticObjectField,
1941   CheckJNI::SetStaticBooleanField,
1942   CheckJNI::SetStaticByteField,
1943   CheckJNI::SetStaticCharField,
1944   CheckJNI::SetStaticShortField,
1945   CheckJNI::SetStaticIntField,
1946   CheckJNI::SetStaticLongField,
1947   CheckJNI::SetStaticFloatField,
1948   CheckJNI::SetStaticDoubleField,
1949   CheckJNI::NewString,
1950   CheckJNI::GetStringLength,
1951   CheckJNI::GetStringChars,
1952   CheckJNI::ReleaseStringChars,
1953   CheckJNI::NewStringUTF,
1954   CheckJNI::GetStringUTFLength,
1955   CheckJNI::GetStringUTFChars,
1956   CheckJNI::ReleaseStringUTFChars,
1957   CheckJNI::GetArrayLength,
1958   CheckJNI::NewObjectArray,
1959   CheckJNI::GetObjectArrayElement,
1960   CheckJNI::SetObjectArrayElement,
1961   CheckJNI::NewBooleanArray,
1962   CheckJNI::NewByteArray,
1963   CheckJNI::NewCharArray,
1964   CheckJNI::NewShortArray,
1965   CheckJNI::NewIntArray,
1966   CheckJNI::NewLongArray,
1967   CheckJNI::NewFloatArray,
1968   CheckJNI::NewDoubleArray,
1969   CheckJNI::GetBooleanArrayElements,
1970   CheckJNI::GetByteArrayElements,
1971   CheckJNI::GetCharArrayElements,
1972   CheckJNI::GetShortArrayElements,
1973   CheckJNI::GetIntArrayElements,
1974   CheckJNI::GetLongArrayElements,
1975   CheckJNI::GetFloatArrayElements,
1976   CheckJNI::GetDoubleArrayElements,
1977   CheckJNI::ReleaseBooleanArrayElements,
1978   CheckJNI::ReleaseByteArrayElements,
1979   CheckJNI::ReleaseCharArrayElements,
1980   CheckJNI::ReleaseShortArrayElements,
1981   CheckJNI::ReleaseIntArrayElements,
1982   CheckJNI::ReleaseLongArrayElements,
1983   CheckJNI::ReleaseFloatArrayElements,
1984   CheckJNI::ReleaseDoubleArrayElements,
1985   CheckJNI::GetBooleanArrayRegion,
1986   CheckJNI::GetByteArrayRegion,
1987   CheckJNI::GetCharArrayRegion,
1988   CheckJNI::GetShortArrayRegion,
1989   CheckJNI::GetIntArrayRegion,
1990   CheckJNI::GetLongArrayRegion,
1991   CheckJNI::GetFloatArrayRegion,
1992   CheckJNI::GetDoubleArrayRegion,
1993   CheckJNI::SetBooleanArrayRegion,
1994   CheckJNI::SetByteArrayRegion,
1995   CheckJNI::SetCharArrayRegion,
1996   CheckJNI::SetShortArrayRegion,
1997   CheckJNI::SetIntArrayRegion,
1998   CheckJNI::SetLongArrayRegion,
1999   CheckJNI::SetFloatArrayRegion,
2000   CheckJNI::SetDoubleArrayRegion,
2001   CheckJNI::RegisterNatives,
2002   CheckJNI::UnregisterNatives,
2003   CheckJNI::MonitorEnter,
2004   CheckJNI::MonitorExit,
2005   CheckJNI::GetJavaVM,
2006   CheckJNI::GetStringRegion,
2007   CheckJNI::GetStringUTFRegion,
2008   CheckJNI::GetPrimitiveArrayCritical,
2009   CheckJNI::ReleasePrimitiveArrayCritical,
2010   CheckJNI::GetStringCritical,
2011   CheckJNI::ReleaseStringCritical,
2012   CheckJNI::NewWeakGlobalRef,
2013   CheckJNI::DeleteWeakGlobalRef,
2014   CheckJNI::ExceptionCheck,
2015   CheckJNI::NewDirectByteBuffer,
2016   CheckJNI::GetDirectBufferAddress,
2017   CheckJNI::GetDirectBufferCapacity,
2018   CheckJNI::GetObjectRefType,
2019 };
2020 
GetCheckJniNativeInterface()2021 const JNINativeInterface* GetCheckJniNativeInterface() {
2022   return &gCheckNativeInterface;
2023 }
2024 
2025 class CheckJII {
2026  public:
DestroyJavaVM(JavaVM * vm)2027   static jint DestroyJavaVM(JavaVM* vm) {
2028     ScopedCheck sc(vm, false, __FUNCTION__);
2029     sc.Check(true, "v", vm);
2030     return CHECK_JNI_EXIT("I", BaseVm(vm)->DestroyJavaVM(vm));
2031   }
2032 
AttachCurrentThread(JavaVM * vm,JNIEnv ** p_env,void * thr_args)2033   static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2034     ScopedCheck sc(vm, false, __FUNCTION__);
2035     sc.Check(true, "vpp", vm, p_env, thr_args);
2036     return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
2037   }
2038 
AttachCurrentThreadAsDaemon(JavaVM * vm,JNIEnv ** p_env,void * thr_args)2039   static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2040     ScopedCheck sc(vm, false, __FUNCTION__);
2041     sc.Check(true, "vpp", vm, p_env, thr_args);
2042     return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
2043   }
2044 
DetachCurrentThread(JavaVM * vm)2045   static jint DetachCurrentThread(JavaVM* vm) {
2046     ScopedCheck sc(vm, true, __FUNCTION__);
2047     sc.Check(true, "v", vm);
2048     return CHECK_JNI_EXIT("I", BaseVm(vm)->DetachCurrentThread(vm));
2049   }
2050 
GetEnv(JavaVM * vm,void ** env,jint version)2051   static jint GetEnv(JavaVM* vm, void** env, jint version) {
2052     ScopedCheck sc(vm, true, __FUNCTION__);
2053     sc.Check(true, "vpI", vm);
2054     return CHECK_JNI_EXIT("I", BaseVm(vm)->GetEnv(vm, env, version));
2055   }
2056 
2057  private:
BaseVm(JavaVM * vm)2058   static inline const JNIInvokeInterface* BaseVm(JavaVM* vm) {
2059     return reinterpret_cast<JavaVMExt*>(vm)->unchecked_functions;
2060   }
2061 };
2062 
2063 const JNIInvokeInterface gCheckInvokeInterface = {
2064   nullptr,  // reserved0
2065   nullptr,  // reserved1
2066   nullptr,  // reserved2
2067   CheckJII::DestroyJavaVM,
2068   CheckJII::AttachCurrentThread,
2069   CheckJII::DetachCurrentThread,
2070   CheckJII::GetEnv,
2071   CheckJII::AttachCurrentThreadAsDaemon
2072 };
2073 
GetCheckJniInvokeInterface()2074 const JNIInvokeInterface* GetCheckJniInvokeInterface() {
2075   return &gCheckInvokeInterface;
2076 }
2077 
2078 }  // namespace art
2079