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