check_jni.cc revision 277ccbd200ea43590dfc06a93ae184a765327ad0
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 "check_jni.h" 18 19#include <sys/mman.h> 20#include <zlib.h> 21 22#include "base/logging.h" 23#include "base/to_str.h" 24#include "class_linker.h" 25#include "class_linker-inl.h" 26#include "dex_file-inl.h" 27#include "field_helper.h" 28#include "gc/space/space.h" 29#include "java_vm_ext.h" 30#include "jni_internal.h" 31#include "mirror/art_field-inl.h" 32#include "mirror/art_method-inl.h" 33#include "mirror/class-inl.h" 34#include "mirror/object-inl.h" 35#include "mirror/object_array-inl.h" 36#include "mirror/string-inl.h" 37#include "mirror/throwable.h" 38#include "runtime.h" 39#include "scoped_thread_state_change.h" 40#include "thread.h" 41#include "well_known_classes.h" 42 43namespace art { 44 45/* 46 * =========================================================================== 47 * JNI function helpers 48 * =========================================================================== 49 */ 50 51// Flags passed into ScopedCheck. 52#define kFlag_Default 0x0000 53 54#define kFlag_CritBad 0x0000 // Calling while in critical is not allowed. 55#define kFlag_CritOkay 0x0001 // Calling while in critical is allowed. 56#define kFlag_CritGet 0x0002 // This is a critical "get". 57#define kFlag_CritRelease 0x0003 // This is a critical "release". 58#define kFlag_CritMask 0x0003 // Bit mask to get "crit" value. 59 60#define kFlag_ExcepBad 0x0000 // Raised exceptions are not allowed. 61#define kFlag_ExcepOkay 0x0004 // Raised exceptions are allowed. 62 63#define kFlag_Release 0x0010 // Are we in a non-critical release function? 64#define kFlag_NullableUtf 0x0020 // Are our UTF parameters nullable? 65 66#define kFlag_Invocation 0x8000 // Part of the invocation interface (JavaVM*). 67 68#define kFlag_ForceTrace 0x80000000 // Add this to a JNI function's flags if you want to trace every call. 69/* 70 * Java primitive types: 71 * B - jbyte 72 * C - jchar 73 * D - jdouble 74 * F - jfloat 75 * I - jint 76 * J - jlong 77 * S - jshort 78 * Z - jboolean (shown as true and false) 79 * V - void 80 * 81 * Java reference types: 82 * L - jobject 83 * a - jarray 84 * c - jclass 85 * s - jstring 86 * t - jthrowable 87 * 88 * JNI types: 89 * b - jboolean (shown as JNI_TRUE and JNI_FALSE) 90 * f - jfieldID 91 * i - JNI error value (JNI_OK, JNI_ERR, JNI_EDETACHED, JNI_EVERSION) 92 * m - jmethodID 93 * p - void* 94 * r - jint (for release mode arguments) 95 * u - const char* (Modified UTF-8) 96 * z - jsize (for lengths; use i if negative values are okay) 97 * v - JavaVM* 98 * w - jobjectRefType 99 * E - JNIEnv* 100 * . - no argument; just print "..." (used for varargs JNI calls) 101 * 102 */ 103union JniValueType { 104 jarray a; 105 jboolean b; 106 jclass c; 107 jfieldID f; 108 jint i; 109 jmethodID m; 110 const void* p; // Pointer. 111 jint r; // Release mode. 112 jstring s; 113 jthrowable t; 114 const char* u; // Modified UTF-8. 115 JavaVM* v; 116 jobjectRefType w; 117 jsize z; 118 jbyte B; 119 jchar C; 120 jdouble D; 121 JNIEnv* E; 122 jfloat F; 123 jint I; 124 jlong J; 125 jobject L; 126 jshort S; 127 const void* V; // void 128 jboolean Z; 129}; 130 131class ScopedCheck { 132 public: 133 explicit ScopedCheck(int flags, const char* functionName, bool has_method = true) 134 : function_name_(functionName), flags_(flags), indent_(0), has_method_(has_method) { 135 } 136 137 ~ScopedCheck() {} 138 139 // Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread" 140 // or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of 141 // times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some 142 // circumstances, but this is incorrect. 143 bool CheckClassName(const char* class_name) { 144 if ((class_name == nullptr) || !IsValidJniClassName(class_name)) { 145 AbortF("illegal class name '%s'\n" 146 " (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')", 147 class_name); 148 return false; 149 } 150 return true; 151 } 152 153 /* 154 * Verify that this instance field ID is valid for this object. 155 * 156 * Assumes "jobj" has already been validated. 157 */ 158 bool CheckInstanceFieldID(ScopedObjectAccess& soa, jobject java_object, jfieldID fid) 159 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 160 mirror::Object* o = soa.Decode<mirror::Object*>(java_object); 161 if (o == nullptr) { 162 AbortF("field operation on NULL object: %p", java_object); 163 return false; 164 } 165 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) { 166 Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 167 AbortF("field operation on invalid %s: %p", 168 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), 169 java_object); 170 return false; 171 } 172 173 mirror::ArtField* f = CheckFieldID(soa, fid); 174 if (f == nullptr) { 175 return false; 176 } 177 mirror::Class* c = o->GetClass(); 178 if (c->FindInstanceField(f->GetName(), f->GetTypeDescriptor()) == nullptr) { 179 AbortF("jfieldID %s not valid for an object of class %s", 180 PrettyField(f).c_str(), PrettyTypeOf(o).c_str()); 181 return false; 182 } 183 return true; 184 } 185 186 /* 187 * Verify that the pointer value is non-NULL. 188 */ 189 bool CheckNonNull(const void* ptr) { 190 if (UNLIKELY(ptr == nullptr)) { 191 AbortF("non-nullable argument was NULL"); 192 return false; 193 } 194 return true; 195 } 196 197 /* 198 * Verify that the method's return type matches the type of call. 199 * 'expectedType' will be "L" for all objects, including arrays. 200 */ 201 bool CheckMethodAndSig(ScopedObjectAccess& soa, jobject jobj, jclass jc, 202 jmethodID mid, Primitive::Type type, InvokeType invoke) 203 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 204 mirror::ArtMethod* m = CheckMethodID(soa, mid); 205 if (m == nullptr) { 206 return false; 207 } 208 if (type != Primitive::GetType(m->GetShorty()[0])) { 209 AbortF("the return type of %s does not match %s", function_name_, PrettyMethod(m).c_str()); 210 return false; 211 } 212 bool is_static = (invoke == kStatic); 213 if (is_static != m->IsStatic()) { 214 if (is_static) { 215 AbortF("calling non-static method %s with %s", 216 PrettyMethod(m).c_str(), function_name_); 217 } else { 218 AbortF("calling static method %s with %s", 219 PrettyMethod(m).c_str(), function_name_); 220 } 221 return false; 222 } 223 if (invoke != kVirtual) { 224 mirror::Class* c = soa.Decode<mirror::Class*>(jc); 225 if (!m->GetDeclaringClass()->IsAssignableFrom(c)) { 226 AbortF("can't call %s %s with class %s", invoke == kStatic ? "static" : "nonvirtual", 227 PrettyMethod(m).c_str(), PrettyClass(c).c_str()); 228 return false; 229 } 230 } 231 if (invoke != kStatic) { 232 mirror::Object* o = soa.Decode<mirror::Object*>(jobj); 233 if (o == nullptr) { 234 AbortF("can't call %s on null object", PrettyMethod(m).c_str()); 235 return false; 236 } else if (!o->InstanceOf(m->GetDeclaringClass())) { 237 AbortF("can't call %s on instance of %s", PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str()); 238 return false; 239 } 240 } 241 return true; 242 } 243 244 /* 245 * Verify that this static field ID is valid for this class. 246 * 247 * Assumes "java_class" has already been validated. 248 */ 249 bool CheckStaticFieldID(ScopedObjectAccess& soa, jclass java_class, jfieldID fid) 250 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 251 mirror::Class* c = soa.Decode<mirror::Class*>(java_class); 252 mirror::ArtField* f = CheckFieldID(soa, fid); 253 if (f == nullptr) { 254 return false; 255 } 256 if (f->GetDeclaringClass() != c) { 257 AbortF("static jfieldID %p not valid for class %s", fid, PrettyClass(c).c_str()); 258 return false; 259 } 260 return true; 261 } 262 263 /* 264 * Verify that "mid" is appropriate for "java_class". 265 * 266 * A mismatch isn't dangerous, because the jmethodID defines the class. In 267 * fact, java_class is unused in the implementation. It's best if we don't 268 * allow bad code in the system though. 269 * 270 * Instances of "java_class" must be instances of the method's declaring class. 271 */ 272 bool CheckStaticMethod(ScopedObjectAccess& soa, jclass java_class, jmethodID mid) 273 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 274 mirror::ArtMethod* m = CheckMethodID(soa, mid); 275 if (m == nullptr) { 276 return false; 277 } 278 mirror::Class* c = soa.Decode<mirror::Class*>(java_class); 279 if (!m->GetDeclaringClass()->IsAssignableFrom(c)) { 280 AbortF("can't call static %s on class %s", PrettyMethod(m).c_str(), PrettyClass(c).c_str()); 281 return false; 282 } 283 return true; 284 } 285 286 /* 287 * Verify that "mid" is appropriate for "jobj". 288 * 289 * Make sure the object is an instance of the method's declaring class. 290 * (Note the mid might point to a declaration in an interface; this 291 * will be handled automatically by the instanceof check.) 292 */ 293 bool CheckVirtualMethod(ScopedObjectAccess& soa, jobject java_object, jmethodID mid) 294 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 295 mirror::ArtMethod* m = CheckMethodID(soa, mid); 296 if (m == nullptr) { 297 return false; 298 } 299 mirror::Object* o = soa.Decode<mirror::Object*>(java_object); 300 if (o == nullptr) { 301 AbortF("can't call %s on null object", PrettyMethod(m).c_str()); 302 return false; 303 } else if (!o->InstanceOf(m->GetDeclaringClass())) { 304 AbortF("can't call %s on instance of %s", PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str()); 305 return false; 306 } 307 return true; 308 } 309 310 /** 311 * The format string is a sequence of the following characters, 312 * and must be followed by arguments of the corresponding types 313 * in the same order. 314 * 315 * Java primitive types: 316 * B - jbyte 317 * C - jchar 318 * D - jdouble 319 * F - jfloat 320 * I - jint 321 * J - jlong 322 * S - jshort 323 * Z - jboolean (shown as true and false) 324 * V - void 325 * 326 * Java reference types: 327 * L - jobject 328 * a - jarray 329 * c - jclass 330 * s - jstring 331 * 332 * JNI types: 333 * b - jboolean (shown as JNI_TRUE and JNI_FALSE) 334 * f - jfieldID 335 * m - jmethodID 336 * p - void* 337 * r - jint (for release mode arguments) 338 * u - const char* (Modified UTF-8) 339 * z - jsize (for lengths; use i if negative values are okay) 340 * v - JavaVM* 341 * E - JNIEnv* 342 * . - no argument; just print "..." (used for varargs JNI calls) 343 * 344 * Use the kFlag_NullableUtf flag where 'u' field(s) are nullable. 345 */ 346 bool Check(ScopedObjectAccess& soa, bool entry, const char* fmt, JniValueType* args) 347 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 348 mirror::ArtMethod* traceMethod = nullptr; 349 if (has_method_ && soa.Vm()->IsTracingEnabled()) { 350 // We need to guard some of the invocation interface's calls: a bad caller might 351 // use DetachCurrentThread or GetEnv on a thread that's not yet attached. 352 Thread* self = Thread::Current(); 353 if ((flags_ & kFlag_Invocation) == 0 || self != nullptr) { 354 traceMethod = self->GetCurrentMethod(nullptr); 355 } 356 } 357 358 if (((flags_ & kFlag_ForceTrace) != 0) || 359 (traceMethod != nullptr && soa.Vm()->ShouldTrace(traceMethod))) { 360 std::string msg; 361 for (size_t i = 0; fmt[i] != '\0'; ++i) { 362 TracePossibleHeapValue(soa, entry, fmt[i], args[i], &msg); 363 if (fmt[i + 1] != '\0') { 364 StringAppendF(&msg, ", "); 365 } 366 } 367 368 if ((flags_ & kFlag_ForceTrace) != 0) { 369 LOG(INFO) << "JNI: call to " << function_name_ << "(" << msg << ")"; 370 } else if (entry) { 371 if (has_method_) { 372 std::string methodName(PrettyMethod(traceMethod, false)); 373 LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")"; 374 indent_ = methodName.size() + 1; 375 } else { 376 LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")"; 377 indent_ = 0; 378 } 379 } else { 380 LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str()); 381 } 382 } 383 384 // We always do the thorough checks on entry, and never on exit... 385 if (entry) { 386 for (size_t i = 0; fmt[i] != '\0'; ++i) { 387 if (!CheckPossibleHeapValue(soa, fmt[i], args[i])) { 388 return false; 389 } 390 } 391 } 392 return true; 393 } 394 395 bool CheckNonHeap(JavaVMExt* vm, bool entry, const char* fmt, JniValueType* args) { 396 bool should_trace = (flags_ & kFlag_ForceTrace) != 0; 397 if (!should_trace && vm->IsTracingEnabled()) { 398 // We need to guard some of the invocation interface's calls: a bad caller might 399 // use DetachCurrentThread or GetEnv on a thread that's not yet attached. 400 Thread* self = Thread::Current(); 401 if ((flags_ & kFlag_Invocation) == 0 || self != nullptr) { 402 ScopedObjectAccess soa(self); 403 mirror::ArtMethod* traceMethod = self->GetCurrentMethod(nullptr); 404 should_trace = (traceMethod != nullptr && vm->ShouldTrace(traceMethod)); 405 } 406 } 407 if (should_trace) { 408 std::string msg; 409 for (size_t i = 0; fmt[i] != '\0'; ++i) { 410 TraceNonHeapValue(fmt[i], args[i], &msg); 411 if (fmt[i + 1] != '\0') { 412 StringAppendF(&msg, ", "); 413 } 414 } 415 416 if ((flags_ & kFlag_ForceTrace) != 0) { 417 LOG(INFO) << "JNI: call to " << function_name_ << "(" << msg << ")"; 418 } else if (entry) { 419 if (has_method_) { 420 Thread* self = Thread::Current(); 421 ScopedObjectAccess soa(self); 422 mirror::ArtMethod* traceMethod = self->GetCurrentMethod(nullptr); 423 std::string methodName(PrettyMethod(traceMethod, false)); 424 LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")"; 425 indent_ = methodName.size() + 1; 426 } else { 427 LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")"; 428 indent_ = 0; 429 } 430 } else { 431 LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str()); 432 } 433 } 434 435 // We always do the thorough checks on entry, and never on exit... 436 if (entry) { 437 for (size_t i = 0; fmt[i] != '\0'; ++i) { 438 if (!CheckNonHeapValue(fmt[i], args[i])) { 439 return false; 440 } 441 } 442 } 443 return true; 444 } 445 446 bool CheckReflectedMethod(ScopedObjectAccess& soa, jobject jmethod) 447 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 448 mirror::Object* method = soa.Decode<mirror::Object*>(jmethod); 449 if (method == nullptr) { 450 AbortF("expected non-null method"); 451 return false; 452 } 453 mirror::Class* c = method->GetClass(); 454 if (soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Method) != c && 455 soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Constructor) != c) { 456 AbortF("expected java.lang.reflect.Method or " 457 "java.lang.reflect.Constructor but got object of type %s: %p", 458 PrettyTypeOf(method).c_str(), jmethod); 459 return false; 460 } 461 return true; 462 } 463 464 bool CheckConstructor(ScopedObjectAccess& soa, jmethodID mid) 465 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 466 mirror::ArtMethod* method = soa.DecodeMethod(mid); 467 if (method == nullptr) { 468 AbortF("expected non-null constructor"); 469 return false; 470 } 471 if (!method->IsConstructor() || method->IsStatic()) { 472 AbortF("expected a constructor but %s: %p", PrettyTypeOf(method).c_str(), mid); 473 return false; 474 } 475 return true; 476 } 477 478 bool CheckReflectedField(ScopedObjectAccess& soa, jobject jfield) 479 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 480 mirror::Object* field = soa.Decode<mirror::Object*>(jfield); 481 if (field == nullptr) { 482 AbortF("expected non-null java.lang.reflect.Field"); 483 return false; 484 } 485 mirror::Class* c = field->GetClass(); 486 if (soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Field) != c) { 487 AbortF("expected java.lang.reflect.Field but got object of type %s: %p", 488 PrettyTypeOf(field).c_str(), jfield); 489 return false; 490 } 491 return true; 492 } 493 494 bool CheckThrowable(ScopedObjectAccess& soa, jthrowable jobj) 495 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 496 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); 497 if (!obj->GetClass()->IsThrowableClass()) { 498 AbortF("expected java.lang.Throwable but got object of type " 499 "%s: %p", PrettyTypeOf(obj).c_str(), obj); 500 return false; 501 } 502 return true; 503 } 504 505 bool CheckThrowableClass(ScopedObjectAccess& soa, jclass jc) 506 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 507 mirror::Class* c = soa.Decode<mirror::Class*>(jc); 508 if (!c->IsThrowableClass()) { 509 AbortF("expected java.lang.Throwable class but got object of " 510 "type %s: %p", PrettyDescriptor(c).c_str(), c); 511 return false; 512 } 513 return true; 514 } 515 516 bool CheckReferenceKind(IndirectRefKind expected_kind, Thread* self, jobject obj) { 517 IndirectRefKind found_kind; 518 if (expected_kind == kLocal) { 519 found_kind = GetIndirectRefKind(obj); 520 if (found_kind == kHandleScopeOrInvalid && self->HandleScopeContains(obj)) { 521 found_kind = kLocal; 522 } 523 } else { 524 found_kind = GetIndirectRefKind(obj); 525 } 526 if (obj != nullptr && found_kind != expected_kind) { 527 AbortF("expected reference of kind %s but found %s: %p", 528 ToStr<IndirectRefKind>(expected_kind).c_str(), 529 ToStr<IndirectRefKind>(GetIndirectRefKind(obj)).c_str(), 530 obj); 531 return false; 532 } 533 return true; 534 } 535 536 bool CheckInstantiableNonArray(ScopedObjectAccess& soa, jclass jc) 537 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 538 mirror::Class* c = soa.Decode<mirror::Class*>(jc); 539 if (!c->IsInstantiableNonArray()) { 540 AbortF("can't make objects of type %s: %p", PrettyDescriptor(c).c_str(), c); 541 return false; 542 } 543 return true; 544 } 545 546 bool CheckPrimitiveArrayType(ScopedObjectAccess& soa, jarray array, Primitive::Type type) 547 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 548 if (!CheckArray(soa, array)) { 549 return false; 550 } 551 mirror::Array* a = soa.Decode<mirror::Array*>(array); 552 if (a->GetClass()->GetComponentType()->GetPrimitiveType() != type) { 553 AbortF("incompatible array type %s expected %s[]: %p", 554 PrettyDescriptor(a->GetClass()).c_str(), PrettyDescriptor(type).c_str(), array); 555 return false; 556 } 557 return true; 558 } 559 560 bool CheckFieldAccess(ScopedObjectAccess& soa, jobject obj, jfieldID fid, bool is_static, 561 Primitive::Type type) 562 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 563 if (is_static && !CheckStaticFieldID(soa, down_cast<jclass>(obj), fid)) { 564 return false; 565 } 566 if (!is_static && !CheckInstanceFieldID(soa, obj, fid)) { 567 return false; 568 } 569 mirror::ArtField* field = soa.DecodeField(fid); 570 DCHECK(field != nullptr); // Already checked by Check. 571 if (is_static != field->IsStatic()) { 572 AbortF("attempt to access %s field %s: %p", 573 field->IsStatic() ? "static" : "non-static", PrettyField(field).c_str(), fid); 574 return false; 575 } 576 if (type != field->GetTypeAsPrimitiveType()) { 577 AbortF("attempt to access field %s of type %s with the wrong type %s: %p", 578 PrettyField(field).c_str(), PrettyDescriptor(field->GetTypeDescriptor()).c_str(), 579 PrettyDescriptor(type).c_str(), fid); 580 return false; 581 } 582 if (is_static) { 583 mirror::Object* o = soa.Decode<mirror::Object*>(obj); 584 if (o == nullptr || !o->IsClass()) { 585 AbortF("attempt to access static field %s with a class argument of type %s: %p", 586 PrettyField(field).c_str(), PrettyTypeOf(o).c_str(), fid); 587 return false; 588 } 589 mirror::Class* c = o->AsClass(); 590 if (field->GetDeclaringClass() != c) { 591 AbortF("attempt to access static field %s with an incompatible class argument of %s: %p", 592 PrettyField(field).c_str(), PrettyDescriptor(c).c_str(), fid); 593 return false; 594 } 595 } else { 596 mirror::Object* o = soa.Decode<mirror::Object*>(obj); 597 if (o == nullptr || !field->GetDeclaringClass()->IsAssignableFrom(o->GetClass())) { 598 AbortF("attempt to access field %s from an object argument of type %s: %p", 599 PrettyField(field).c_str(), PrettyTypeOf(o).c_str(), fid); 600 return false; 601 } 602 } 603 return true; 604 } 605 606 private: 607 enum InstanceKind { 608 kClass, 609 kDirectByteBuffer, 610 kObject, 611 kString, 612 kThrowable, 613 }; 614 615 /* 616 * Verify that "jobj" is a valid non-NULL object reference, and points to 617 * an instance of expectedClass. 618 * 619 * Because we're looking at an object on the GC heap, we have to switch 620 * to "running" mode before doing the checks. 621 */ 622 bool CheckInstance(ScopedObjectAccess& soa, InstanceKind kind, jobject java_object, bool null_ok) 623 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 624 const char* what = nullptr; 625 switch (kind) { 626 case kClass: 627 what = "jclass"; 628 break; 629 case kDirectByteBuffer: 630 what = "direct ByteBuffer"; 631 break; 632 case kObject: 633 what = "jobject"; 634 break; 635 case kString: 636 what = "jstring"; 637 break; 638 case kThrowable: 639 what = "jthrowable"; 640 break; 641 default: 642 LOG(FATAL) << "Unknown kind " << static_cast<int>(kind); 643 } 644 645 if (java_object == nullptr) { 646 if (null_ok) { 647 return true; 648 } else { 649 AbortF("%s received NULL %s", function_name_, what); 650 return false; 651 } 652 } 653 654 mirror::Object* obj = soa.Decode<mirror::Object*>(java_object); 655 if (obj == nullptr) { 656 // Either java_object is invalid or is a cleared weak. 657 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object); 658 bool okay; 659 if (GetIndirectRefKind(ref) != kWeakGlobal) { 660 okay = false; 661 } else { 662 obj = soa.Vm()->DecodeWeakGlobal(soa.Self(), ref); 663 okay = Runtime::Current()->IsClearedJniWeakGlobal(obj); 664 } 665 if (!okay) { 666 AbortF("%s is an invalid %s: %p (%p)", 667 what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), 668 java_object, obj); 669 return false; 670 } 671 } 672 673 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) { 674 Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 675 AbortF("%s is an invalid %s: %p (%p)", 676 what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), 677 java_object, obj); 678 return false; 679 } 680 681 bool okay = true; 682 switch (kind) { 683 case kClass: 684 okay = obj->IsClass(); 685 break; 686 case kDirectByteBuffer: 687 UNIMPLEMENTED(FATAL); 688 break; 689 case kString: 690 okay = obj->GetClass()->IsStringClass(); 691 break; 692 case kThrowable: 693 okay = obj->GetClass()->IsThrowableClass(); 694 break; 695 case kObject: 696 break; 697 } 698 if (!okay) { 699 AbortF("%s has wrong type: %s", what, PrettyTypeOf(obj).c_str()); 700 return false; 701 } 702 703 return true; 704 } 705 706 /* 707 * Verify that the "mode" argument passed to a primitive array Release 708 * function is one of the valid values. 709 */ 710 bool CheckReleaseMode(jint mode) { 711 if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) { 712 AbortF("unknown value for release mode: %d", mode); 713 return false; 714 } 715 return true; 716 } 717 718 bool CheckPossibleHeapValue(ScopedObjectAccess& soa, char fmt, JniValueType arg) 719 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 720 switch (fmt) { 721 case 'a': // jarray 722 return CheckArray(soa, arg.a); 723 case 'c': // jclass 724 return CheckInstance(soa, kClass, arg.c, false); 725 case 'f': // jfieldID 726 return CheckFieldID(soa, arg.f) != nullptr; 727 case 'm': // jmethodID 728 return CheckMethodID(soa, arg.m) != nullptr; 729 case 'r': // release int 730 return CheckReleaseMode(arg.r); 731 case 's': // jstring 732 return CheckInstance(soa, kString, arg.s, false); 733 case 't': // jthrowable 734 return CheckInstance(soa, kThrowable, arg.t, false); 735 case 'E': // JNIEnv* 736 return CheckThread(arg.E); 737 case 'L': // jobject 738 return CheckInstance(soa, kObject, arg.L, true); 739 default: 740 return CheckNonHeapValue(fmt, arg); 741 } 742 } 743 744 bool CheckNonHeapValue(char fmt, JniValueType arg) { 745 switch (fmt) { 746 case '.': // ... 747 case 'p': // TODO: pointer - null or readable? 748 case 'v': // JavaVM* 749 case 'B': // jbyte 750 case 'C': // jchar 751 case 'D': // jdouble 752 case 'F': // jfloat 753 case 'I': // jint 754 case 'J': // jlong 755 case 'S': // jshort 756 break; // Ignored. 757 case 'b': // jboolean, why two? Fall-through. 758 case 'Z': 759 return CheckBoolean(arg.Z); 760 case 'u': // utf8 761 if ((flags_ & kFlag_Release) != 0) { 762 return CheckNonNull(arg.u); 763 } else { 764 bool nullable = ((flags_ & kFlag_NullableUtf) != 0); 765 return CheckUtfString(arg.u, nullable); 766 } 767 case 'w': // jobjectRefType 768 switch (arg.w) { 769 case JNIInvalidRefType: 770 case JNILocalRefType: 771 case JNIGlobalRefType: 772 case JNIWeakGlobalRefType: 773 break; 774 default: 775 AbortF("Unknown reference type"); 776 return false; 777 } 778 break; 779 case 'z': // jsize 780 return CheckLengthPositive(arg.z); 781 default: 782 AbortF("unknown format specifier: '%c'", fmt); 783 return false; 784 } 785 return true; 786 } 787 788 void TracePossibleHeapValue(ScopedObjectAccess& soa, bool entry, char fmt, JniValueType arg, 789 std::string* msg) 790 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 791 switch (fmt) { 792 case 'L': // jobject fall-through. 793 case 'a': // jarray fall-through. 794 case 's': // jstring fall-through. 795 case 't': // jthrowable fall-through. 796 if (arg.L == nullptr) { 797 *msg += "NULL"; 798 } else { 799 StringAppendF(msg, "%p", arg.L); 800 } 801 break; 802 case 'c': { // jclass 803 jclass jc = arg.c; 804 mirror::Class* c = soa.Decode<mirror::Class*>(jc); 805 if (c == nullptr) { 806 *msg += "NULL"; 807 } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) { 808 StringAppendF(msg, "INVALID POINTER:%p", jc); 809 } else if (!c->IsClass()) { 810 *msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c); 811 } else { 812 *msg += PrettyClass(c); 813 if (!entry) { 814 StringAppendF(msg, " (%p)", jc); 815 } 816 } 817 break; 818 } 819 case 'f': { // jfieldID 820 jfieldID fid = arg.f; 821 mirror::ArtField* f = soa.DecodeField(fid); 822 *msg += PrettyField(f); 823 if (!entry) { 824 StringAppendF(msg, " (%p)", fid); 825 } 826 break; 827 } 828 case 'm': { // jmethodID 829 jmethodID mid = arg.m; 830 mirror::ArtMethod* m = soa.DecodeMethod(mid); 831 *msg += PrettyMethod(m); 832 if (!entry) { 833 StringAppendF(msg, " (%p)", mid); 834 } 835 break; 836 } 837 default: 838 TraceNonHeapValue(fmt, arg, msg); 839 break; 840 } 841 } 842 843 void TraceNonHeapValue(char fmt, JniValueType arg, std::string* msg) { 844 switch (fmt) { 845 case 'B': // jbyte 846 if (arg.B >= 0 && arg.B < 10) { 847 StringAppendF(msg, "%d", arg.B); 848 } else { 849 StringAppendF(msg, "%#x (%d)", arg.B, arg.B); 850 } 851 break; 852 case 'C': // jchar 853 if (arg.C < 0x7f && arg.C >= ' ') { 854 StringAppendF(msg, "U+%x ('%c')", arg.C, arg.C); 855 } else { 856 StringAppendF(msg, "U+%x", arg.C); 857 } 858 break; 859 case 'F': // jfloat 860 StringAppendF(msg, "%g", arg.F); 861 break; 862 case 'D': // jdouble 863 StringAppendF(msg, "%g", arg.D); 864 break; 865 case 'S': // jshort 866 StringAppendF(msg, "%d", arg.S); 867 break; 868 case 'i': // jint - fall-through. 869 case 'I': // jint 870 StringAppendF(msg, "%d", arg.I); 871 break; 872 case 'J': // jlong 873 StringAppendF(msg, "%" PRId64, arg.J); 874 break; 875 case 'Z': // jboolean 876 case 'b': // jboolean (JNI-style) 877 *msg += arg.b == JNI_TRUE ? "true" : "false"; 878 break; 879 case 'V': // void 880 DCHECK(arg.V == nullptr); 881 *msg += "void"; 882 break; 883 case 'v': // JavaVM* 884 StringAppendF(msg, "(JavaVM*)%p", arg.v); 885 break; 886 case 'E': 887 StringAppendF(msg, "(JNIEnv*)%p", arg.E); 888 break; 889 case 'z': // non-negative jsize 890 // You might expect jsize to be size_t, but it's not; it's the same as jint. 891 // We only treat this specially so we can do the non-negative check. 892 // TODO: maybe this wasn't worth it? 893 StringAppendF(msg, "%d", arg.z); 894 break; 895 case 'p': // void* ("pointer") 896 if (arg.p == nullptr) { 897 *msg += "NULL"; 898 } else { 899 StringAppendF(msg, "(void*) %p", arg.p); 900 } 901 break; 902 case 'r': { // jint (release mode) 903 jint releaseMode = arg.r; 904 if (releaseMode == 0) { 905 *msg += "0"; 906 } else if (releaseMode == JNI_ABORT) { 907 *msg += "JNI_ABORT"; 908 } else if (releaseMode == JNI_COMMIT) { 909 *msg += "JNI_COMMIT"; 910 } else { 911 StringAppendF(msg, "invalid release mode %d", releaseMode); 912 } 913 break; 914 } 915 case 'u': // const char* (Modified UTF-8) 916 if (arg.u == nullptr) { 917 *msg += "NULL"; 918 } else { 919 StringAppendF(msg, "\"%s\"", arg.u); 920 } 921 break; 922 case 'w': // jobjectRefType 923 switch (arg.w) { 924 case JNIInvalidRefType: 925 *msg += "invalid reference type"; 926 break; 927 case JNILocalRefType: 928 *msg += "local ref type"; 929 break; 930 case JNIGlobalRefType: 931 *msg += "global ref type"; 932 break; 933 case JNIWeakGlobalRefType: 934 *msg += "weak global ref type"; 935 break; 936 default: 937 *msg += "unknown ref type"; 938 break; 939 } 940 break; 941 case '.': 942 *msg += "..."; 943 break; 944 default: 945 LOG(FATAL) << function_name_ << ": unknown trace format specifier: '" << fmt << "'"; 946 } 947 } 948 /* 949 * Verify that "array" is non-NULL and points to an Array object. 950 * 951 * Since we're dealing with objects, switch to "running" mode. 952 */ 953 bool CheckArray(ScopedObjectAccess& soa, jarray java_array) 954 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 955 if (UNLIKELY(java_array == nullptr)) { 956 AbortF("jarray was NULL"); 957 return false; 958 } 959 960 mirror::Array* a = soa.Decode<mirror::Array*>(java_array); 961 if (UNLIKELY(!Runtime::Current()->GetHeap()->IsValidObjectAddress(a))) { 962 Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 963 AbortF("jarray is an invalid %s: %p (%p)", 964 ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(), 965 java_array, a); 966 return false; 967 } else if (!a->IsArrayInstance()) { 968 AbortF("jarray argument has non-array type: %s", PrettyTypeOf(a).c_str()); 969 return false; 970 } 971 return true; 972 } 973 974 bool CheckBoolean(jboolean z) { 975 if (z != JNI_TRUE && z != JNI_FALSE) { 976 AbortF("unexpected jboolean value: %d", z); 977 return false; 978 } 979 return true; 980 } 981 982 bool CheckLengthPositive(jsize length) { 983 if (length < 0) { 984 AbortF("negative jsize: %d", length); 985 return false; 986 } 987 return true; 988 } 989 990 mirror::ArtField* CheckFieldID(ScopedObjectAccess& soa, jfieldID fid) 991 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 992 if (fid == nullptr) { 993 AbortF("jfieldID was NULL"); 994 return nullptr; 995 } 996 mirror::ArtField* f = soa.DecodeField(fid); 997 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(f) || !f->IsArtField()) { 998 Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 999 AbortF("invalid jfieldID: %p", fid); 1000 return nullptr; 1001 } 1002 return f; 1003 } 1004 1005 mirror::ArtMethod* CheckMethodID(ScopedObjectAccess& soa, jmethodID mid) 1006 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1007 if (mid == nullptr) { 1008 AbortF("jmethodID was NULL"); 1009 return nullptr; 1010 } 1011 mirror::ArtMethod* m = soa.DecodeMethod(mid); 1012 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(m) || !m->IsArtMethod()) { 1013 Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR)); 1014 AbortF("invalid jmethodID: %p", mid); 1015 return nullptr; 1016 } 1017 return m; 1018 } 1019 1020 bool CheckThread(JNIEnv* env) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1021 Thread* self = Thread::Current(); 1022 if (self == nullptr) { 1023 AbortF("a thread (tid %d) is making JNI calls without being attached", GetTid()); 1024 return false; 1025 } 1026 1027 // Get the *correct* JNIEnv by going through our TLS pointer. 1028 JNIEnvExt* threadEnv = self->GetJniEnv(); 1029 1030 // Verify that the current thread is (a) attached and (b) associated with 1031 // this particular instance of JNIEnv. 1032 if (env != threadEnv) { 1033 AbortF("thread %s using JNIEnv* from thread %s", 1034 ToStr<Thread>(*self).c_str(), ToStr<Thread>(*self).c_str()); 1035 return false; 1036 } 1037 1038 // Verify that, if this thread previously made a critical "get" call, we 1039 // do the corresponding "release" call before we try anything else. 1040 switch (flags_ & kFlag_CritMask) { 1041 case kFlag_CritOkay: // okay to call this method 1042 break; 1043 case kFlag_CritBad: // not okay to call 1044 if (threadEnv->critical) { 1045 AbortF("thread %s using JNI after critical get", 1046 ToStr<Thread>(*self).c_str()); 1047 return false; 1048 } 1049 break; 1050 case kFlag_CritGet: // this is a "get" call 1051 // Don't check here; we allow nested gets. 1052 threadEnv->critical++; 1053 break; 1054 case kFlag_CritRelease: // this is a "release" call 1055 threadEnv->critical--; 1056 if (threadEnv->critical < 0) { 1057 AbortF("thread %s called too many critical releases", 1058 ToStr<Thread>(*self).c_str()); 1059 return false; 1060 } 1061 break; 1062 default: 1063 LOG(FATAL) << "Bad flags (internal error): " << flags_; 1064 } 1065 1066 // Verify that, if an exception has been raised, the native code doesn't 1067 // make any JNI calls other than the Exception* methods. 1068 if ((flags_ & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) { 1069 ThrowLocation throw_location; 1070 mirror::Throwable* exception = self->GetException(&throw_location); 1071 std::string type(PrettyTypeOf(exception)); 1072 AbortF("JNI %s called with pending exception '%s' thrown in %s", 1073 function_name_, type.c_str(), throw_location.Dump().c_str()); 1074 return false; 1075 } 1076 return true; 1077 } 1078 1079 // Verifies that "bytes" points to valid Modified UTF-8 data. 1080 bool CheckUtfString(const char* bytes, bool nullable) { 1081 if (bytes == nullptr) { 1082 if (!nullable) { 1083 AbortF("non-nullable const char* was NULL"); 1084 return false; 1085 } 1086 return true; 1087 } 1088 1089 const char* errorKind = nullptr; 1090 uint8_t utf8 = CheckUtfBytes(bytes, &errorKind); 1091 if (errorKind != nullptr) { 1092 AbortF("input is not valid Modified UTF-8: illegal %s byte %#x\n" 1093 " string: '%s'", errorKind, utf8, bytes); 1094 return false; 1095 } 1096 return true; 1097 } 1098 1099 static uint8_t CheckUtfBytes(const char* bytes, const char** errorKind) { 1100 while (*bytes != '\0') { 1101 uint8_t utf8 = *(bytes++); 1102 // Switch on the high four bits. 1103 switch (utf8 >> 4) { 1104 case 0x00: 1105 case 0x01: 1106 case 0x02: 1107 case 0x03: 1108 case 0x04: 1109 case 0x05: 1110 case 0x06: 1111 case 0x07: 1112 // Bit pattern 0xxx. No need for any extra bytes. 1113 break; 1114 case 0x08: 1115 case 0x09: 1116 case 0x0a: 1117 case 0x0b: 1118 case 0x0f: 1119 /* 1120 * Bit pattern 10xx or 1111, which are illegal start bytes. 1121 * Note: 1111 is valid for normal UTF-8, but not the 1122 * Modified UTF-8 used here. 1123 */ 1124 *errorKind = "start"; 1125 return utf8; 1126 case 0x0e: 1127 // Bit pattern 1110, so there are two additional bytes. 1128 utf8 = *(bytes++); 1129 if ((utf8 & 0xc0) != 0x80) { 1130 *errorKind = "continuation"; 1131 return utf8; 1132 } 1133 FALLTHROUGH_INTENDED; // Fall-through to take care of the final byte. 1134 case 0x0c: 1135 case 0x0d: 1136 // Bit pattern 110x, so there is one additional byte. 1137 utf8 = *(bytes++); 1138 if ((utf8 & 0xc0) != 0x80) { 1139 *errorKind = "continuation"; 1140 return utf8; 1141 } 1142 break; 1143 } 1144 } 1145 return 0; 1146 } 1147 1148 void AbortF(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) { 1149 va_list args; 1150 va_start(args, fmt); 1151 Runtime::Current()->GetJavaVM()->JniAbortV(function_name_, fmt, args); 1152 va_end(args); 1153 } 1154 1155 // The name of the JNI function being checked. 1156 const char* const function_name_; 1157 1158 const int flags_; 1159 int indent_; 1160 1161 const bool has_method_; 1162 1163 DISALLOW_COPY_AND_ASSIGN(ScopedCheck); 1164}; 1165 1166/* 1167 * =========================================================================== 1168 * Guarded arrays 1169 * =========================================================================== 1170 */ 1171 1172/* this gets tucked in at the start of the buffer; struct size must be even */ 1173class GuardedCopy { 1174 public: 1175 /* 1176 * Create an over-sized buffer to hold the contents of "buf". Copy it in, 1177 * filling in the area around it with guard data. 1178 */ 1179 static void* Create(const void* original_buf, size_t len, bool mod_okay) { 1180 const size_t new_len = LengthIncludingRedZones(len); 1181 uint8_t* const new_buf = DebugAlloc(new_len); 1182 1183 // If modification is not expected, grab a checksum. 1184 uLong adler = 0; 1185 if (!mod_okay) { 1186 adler = adler32(adler32(0L, Z_NULL, 0), reinterpret_cast<const Bytef*>(original_buf), len); 1187 } 1188 1189 GuardedCopy* copy = new (new_buf) GuardedCopy(original_buf, len, adler); 1190 1191 // Fill begin region with canary pattern. 1192 const size_t kStartCanaryLength = (GuardedCopy::kRedZoneSize / 2) - sizeof(GuardedCopy); 1193 for (size_t i = 0, j = 0; i < kStartCanaryLength; ++i) { 1194 const_cast<char*>(copy->StartRedZone())[i] = kCanary[j]; 1195 if (kCanary[j] == '\0') { 1196 j = 0; 1197 } 1198 } 1199 1200 // Copy the data in; note "len" could be zero. 1201 memcpy(const_cast<uint8_t*>(copy->BufferWithinRedZones()), original_buf, len); 1202 1203 // Fill end region with canary pattern. 1204 for (size_t i = 0, j = 0; i < kEndCanaryLength; ++i) { 1205 const_cast<char*>(copy->EndRedZone())[i] = kCanary[j]; 1206 if (kCanary[j] == '\0') { 1207 j = 0; 1208 } 1209 } 1210 1211 return const_cast<uint8_t*>(copy->BufferWithinRedZones()); 1212 } 1213 1214 /* 1215 * Create a guarded copy of a primitive array. Modifications to the copied 1216 * data are allowed. Returns a pointer to the copied data. 1217 */ 1218 static void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* is_copy) { 1219 ScopedObjectAccess soa(env); 1220 1221 mirror::Array* a = soa.Decode<mirror::Array*>(java_array); 1222 size_t component_size = a->GetClass()->GetComponentSize(); 1223 size_t byte_count = a->GetLength() * component_size; 1224 void* result = Create(a->GetRawData(component_size, 0), byte_count, true); 1225 if (is_copy != nullptr) { 1226 *is_copy = JNI_TRUE; 1227 } 1228 return result; 1229 } 1230 1231 /* 1232 * Perform the array "release" operation, which may or may not copy data 1233 * back into the managed heap, and may or may not release the underlying storage. 1234 */ 1235 static void* ReleaseGuardedPACopy(const char* function_name, JNIEnv* env, jarray java_array, 1236 void* embedded_buf, int mode) { 1237 ScopedObjectAccess soa(env); 1238 mirror::Array* a = soa.Decode<mirror::Array*>(java_array); 1239 1240 if (!GuardedCopy::Check(function_name, embedded_buf, true)) { 1241 return nullptr; 1242 } 1243 if (mode != JNI_ABORT) { 1244 size_t len = FromEmbedded(embedded_buf)->original_length_; 1245 memcpy(a->GetRawData(a->GetClass()->GetComponentSize(), 0), embedded_buf, len); 1246 } 1247 if (mode != JNI_COMMIT) { 1248 return Destroy(embedded_buf); 1249 } 1250 return embedded_buf; 1251 } 1252 1253 1254 /* 1255 * Free up the guard buffer, scrub it, and return the original pointer. 1256 */ 1257 static void* Destroy(void* embedded_buf) { 1258 GuardedCopy* copy = FromEmbedded(embedded_buf); 1259 void* original_ptr = const_cast<void*>(copy->original_ptr_); 1260 size_t len = LengthIncludingRedZones(copy->original_length_); 1261 DebugFree(copy, len); 1262 return original_ptr; 1263 } 1264 1265 /* 1266 * Verify the guard area and, if "modOkay" is false, that the data itself 1267 * has not been altered. 1268 * 1269 * The caller has already checked that "dataBuf" is non-NULL. 1270 */ 1271 static bool Check(const char* function_name, const void* embedded_buf, bool mod_okay) { 1272 const GuardedCopy* copy = FromEmbedded(embedded_buf); 1273 return copy->CheckHeader(function_name, mod_okay) && copy->CheckRedZones(function_name); 1274 } 1275 1276 private: 1277 GuardedCopy(const void* original_buf, size_t len, uLong adler) : 1278 magic_(kGuardMagic), adler_(adler), original_ptr_(original_buf), original_length_(len) { 1279 } 1280 1281 static uint8_t* DebugAlloc(size_t len) { 1282 void* result = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); 1283 if (result == MAP_FAILED) { 1284 PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed"; 1285 } 1286 return reinterpret_cast<uint8_t*>(result); 1287 } 1288 1289 static void DebugFree(void* buf, size_t len) { 1290 if (munmap(buf, len) != 0) { 1291 PLOG(FATAL) << "munmap(" << buf << ", " << len << ") failed"; 1292 } 1293 } 1294 1295 static size_t LengthIncludingRedZones(size_t len) { 1296 return len + kRedZoneSize; 1297 } 1298 1299 // Get the GuardedCopy from the interior pointer. 1300 static GuardedCopy* FromEmbedded(void* embedded_buf) { 1301 return reinterpret_cast<GuardedCopy*>( 1302 reinterpret_cast<uint8_t*>(embedded_buf) - (kRedZoneSize / 2)); 1303 } 1304 1305 static const GuardedCopy* FromEmbedded(const void* embedded_buf) { 1306 return reinterpret_cast<const GuardedCopy*>( 1307 reinterpret_cast<const uint8_t*>(embedded_buf) - (kRedZoneSize / 2)); 1308 } 1309 1310 static void AbortF(const char* jni_function_name, const char* fmt, ...) { 1311 va_list args; 1312 va_start(args, fmt); 1313 Runtime::Current()->GetJavaVM()->JniAbortV(jni_function_name, fmt, args); 1314 va_end(args); 1315 } 1316 1317 bool CheckHeader(const char* function_name, bool mod_okay) const { 1318 static const uint32_t kMagicCmp = kGuardMagic; 1319 1320 // Before we do anything with "pExtra", check the magic number. We 1321 // do the check with memcmp rather than "==" in case the pointer is 1322 // unaligned. If it points to completely bogus memory we're going 1323 // to crash, but there's no easy way around that. 1324 if (UNLIKELY(memcmp(&magic_, &kMagicCmp, 4) != 0)) { 1325 uint8_t buf[4]; 1326 memcpy(buf, &magic_, 4); 1327 AbortF(function_name, 1328 "guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?", 1329 buf[3], buf[2], buf[1], buf[0], this); // Assumes little-endian. 1330 return false; 1331 } 1332 1333 // If modification is not expected, verify checksum. Strictly speaking this is wrong: if we 1334 // told the client that we made a copy, there's no reason they can't alter the buffer. 1335 if (!mod_okay) { 1336 uLong computed_adler = 1337 adler32(adler32(0L, Z_NULL, 0), BufferWithinRedZones(), original_length_); 1338 if (computed_adler != adler_) { 1339 AbortF(function_name, "buffer modified (0x%08lx vs 0x%08lx) at address %p", 1340 computed_adler, adler_, this); 1341 return false; 1342 } 1343 } 1344 return true; 1345 } 1346 1347 bool CheckRedZones(const char* function_name) const { 1348 // Check the begin red zone. 1349 const size_t kStartCanaryLength = (GuardedCopy::kRedZoneSize / 2) - sizeof(GuardedCopy); 1350 for (size_t i = 0, j = 0; i < kStartCanaryLength; ++i) { 1351 if (UNLIKELY(StartRedZone()[i] != kCanary[j])) { 1352 AbortF(function_name, "guard pattern before buffer disturbed at %p +%zd", this, i); 1353 return false; 1354 } 1355 if (kCanary[j] == '\0') { 1356 j = 0; 1357 } 1358 } 1359 1360 // Check end region. 1361 for (size_t i = 0, j = 0; i < kEndCanaryLength; ++i) { 1362 if (UNLIKELY(EndRedZone()[i] != kCanary[j])) { 1363 size_t offset_from_buffer_start = 1364 &(EndRedZone()[i]) - &(StartRedZone()[kStartCanaryLength]); 1365 AbortF(function_name, "guard pattern after buffer disturbed at %p +%zd", this, 1366 offset_from_buffer_start); 1367 return false; 1368 } 1369 if (kCanary[j] == '\0') { 1370 j = 0; 1371 } 1372 } 1373 return true; 1374 } 1375 1376 // Location that canary value will be written before the guarded region. 1377 const char* StartRedZone() const { 1378 const uint8_t* buf = reinterpret_cast<const uint8_t*>(this); 1379 return reinterpret_cast<const char*>(buf + sizeof(GuardedCopy)); 1380 } 1381 1382 // Return the interior embedded buffer. 1383 const uint8_t* BufferWithinRedZones() const { 1384 const uint8_t* embedded_buf = reinterpret_cast<const uint8_t*>(this) + (kRedZoneSize / 2); 1385 return embedded_buf; 1386 } 1387 1388 // Location that canary value will be written after the guarded region. 1389 const char* EndRedZone() const { 1390 const uint8_t* buf = reinterpret_cast<const uint8_t*>(this); 1391 size_t buf_len = LengthIncludingRedZones(original_length_); 1392 return reinterpret_cast<const char*>(buf + (buf_len - (kRedZoneSize / 2))); 1393 } 1394 1395 static constexpr size_t kRedZoneSize = 512; 1396 static constexpr size_t kEndCanaryLength = kRedZoneSize / 2; 1397 1398 // Value written before and after the guarded array. 1399 static const char* const kCanary; 1400 1401 static constexpr uint32_t kGuardMagic = 0xffd5aa96; 1402 1403 const uint32_t magic_; 1404 const uLong adler_; 1405 const void* const original_ptr_; 1406 const size_t original_length_; 1407}; 1408const char* const GuardedCopy::kCanary = "JNI BUFFER RED ZONE"; 1409 1410/* 1411 * =========================================================================== 1412 * JNI functions 1413 * =========================================================================== 1414 */ 1415 1416class CheckJNI { 1417 public: 1418 static jint GetVersion(JNIEnv* env) { 1419 ScopedObjectAccess soa(env); 1420 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1421 JniValueType args[1] = {{.E = env }}; 1422 if (sc.Check(soa, true, "E", args)) { 1423 JniValueType result; 1424 result.I = baseEnv(env)->GetVersion(env); 1425 if (sc.Check(soa, false, "I", &result)) { 1426 return result.I; 1427 } 1428 } 1429 return JNI_ERR; 1430 } 1431 1432 static jint GetJavaVM(JNIEnv *env, JavaVM **vm) { 1433 ScopedObjectAccess soa(env); 1434 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1435 JniValueType args[2] = {{.E = env }, {.p = vm}}; 1436 if (sc.Check(soa, true, "Ep", args)) { 1437 JniValueType result; 1438 result.i = baseEnv(env)->GetJavaVM(env, vm); 1439 if (sc.Check(soa, false, "i", &result)) { 1440 return result.i; 1441 } 1442 } 1443 return JNI_ERR; 1444 } 1445 1446 static jint RegisterNatives(JNIEnv* env, jclass c, const JNINativeMethod* methods, jint nMethods) { 1447 ScopedObjectAccess soa(env); 1448 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1449 JniValueType args[4] = {{.E = env }, {.c = c}, {.p = methods}, {.I = nMethods}}; 1450 if (sc.Check(soa, true, "EcpI", args)) { 1451 JniValueType result; 1452 result.i = baseEnv(env)->RegisterNatives(env, c, methods, nMethods); 1453 if (sc.Check(soa, false, "i", &result)) { 1454 return result.i; 1455 } 1456 } 1457 return JNI_ERR; 1458 } 1459 1460 static jint UnregisterNatives(JNIEnv* env, jclass c) { 1461 ScopedObjectAccess soa(env); 1462 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1463 JniValueType args[2] = {{.E = env }, {.c = c}}; 1464 if (sc.Check(soa, true, "Ec", args)) { 1465 JniValueType result; 1466 result.i = baseEnv(env)->UnregisterNatives(env, c); 1467 if (sc.Check(soa, false, "i", &result)) { 1468 return result.i; 1469 } 1470 } 1471 return JNI_ERR; 1472 } 1473 1474 static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) { 1475 // Note: we use "EL" here but "Ep" has been used in the past on the basis that we'd like to 1476 // know the object is invalid. The spec says that passing invalid objects or even ones that 1477 // are deleted isn't supported. 1478 ScopedObjectAccess soa(env); 1479 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1480 JniValueType args[2] = {{.E = env }, {.L = obj}}; 1481 if (sc.Check(soa, true, "EL", args)) { 1482 JniValueType result; 1483 result.w = baseEnv(env)->GetObjectRefType(env, obj); 1484 if (sc.Check(soa, false, "w", &result)) { 1485 return result.w; 1486 } 1487 } 1488 return JNIInvalidRefType; 1489 } 1490 1491 static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, 1492 jsize bufLen) { 1493 ScopedObjectAccess soa(env); 1494 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1495 JniValueType args[5] = {{.E = env}, {.u = name}, {.L = loader}, {.p = buf}, {.z = bufLen}}; 1496 if (sc.Check(soa, true, "EuLpz", args) && sc.CheckClassName(name)) { 1497 JniValueType result; 1498 result.c = baseEnv(env)->DefineClass(env, name, loader, buf, bufLen); 1499 if (sc.Check(soa, false, "c", &result)) { 1500 return result.c; 1501 } 1502 } 1503 return nullptr; 1504 } 1505 1506 static jclass FindClass(JNIEnv* env, const char* name) { 1507 ScopedObjectAccess soa(env); 1508 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1509 JniValueType args[2] = {{.E = env}, {.u = name}}; 1510 if (sc.Check(soa, true, "Eu", args) && sc.CheckClassName(name)) { 1511 JniValueType result; 1512 result.c = baseEnv(env)->FindClass(env, name); 1513 if (sc.Check(soa, false, "c", &result)) { 1514 return result.c; 1515 } 1516 } 1517 return nullptr; 1518 } 1519 1520 static jclass GetSuperclass(JNIEnv* env, jclass c) { 1521 ScopedObjectAccess soa(env); 1522 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1523 JniValueType args[2] = {{.E = env}, {.c = c}}; 1524 if (sc.Check(soa, true, "Ec", args)) { 1525 JniValueType result; 1526 result.c = baseEnv(env)->GetSuperclass(env, c); 1527 if (sc.Check(soa, false, "c", &result)) { 1528 return result.c; 1529 } 1530 } 1531 return nullptr; 1532 } 1533 1534 static jboolean IsAssignableFrom(JNIEnv* env, jclass c1, jclass c2) { 1535 ScopedObjectAccess soa(env); 1536 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1537 JniValueType args[3] = {{.E = env}, {.c = c1}, {.c = c2}}; 1538 if (sc.Check(soa, true, "Ecc", args)) { 1539 JniValueType result; 1540 result.b = baseEnv(env)->IsAssignableFrom(env, c1, c2); 1541 if (sc.Check(soa, false, "b", &result)) { 1542 return result.b; 1543 } 1544 } 1545 return JNI_FALSE; 1546 } 1547 1548 static jmethodID FromReflectedMethod(JNIEnv* env, jobject method) { 1549 ScopedObjectAccess soa(env); 1550 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1551 JniValueType args[2] = {{.E = env}, {.L = method}}; 1552 if (sc.Check(soa, true, "EL", args) && sc.CheckReflectedMethod(soa, method)) { 1553 JniValueType result; 1554 result.m = baseEnv(env)->FromReflectedMethod(env, method); 1555 if (sc.Check(soa, false, "m", &result)) { 1556 return result.m; 1557 } 1558 } 1559 return nullptr; 1560 } 1561 1562 static jfieldID FromReflectedField(JNIEnv* env, jobject field) { 1563 ScopedObjectAccess soa(env); 1564 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1565 JniValueType args[2] = {{.E = env}, {.L = field}}; 1566 if (sc.Check(soa, true, "EL", args) && sc.CheckReflectedField(soa, field)) { 1567 JniValueType result; 1568 result.f = baseEnv(env)->FromReflectedField(env, field); 1569 if (sc.Check(soa, false, "f", &result)) { 1570 return result.f; 1571 } 1572 } 1573 return nullptr; 1574 } 1575 1576 static jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID mid, jboolean isStatic) { 1577 ScopedObjectAccess soa(env); 1578 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1579 JniValueType args[4] = {{.E = env}, {.c = cls}, {.m = mid}, {.b = isStatic}}; 1580 if (sc.Check(soa, true, "Ecmb", args)) { 1581 JniValueType result; 1582 result.L = baseEnv(env)->ToReflectedMethod(env, cls, mid, isStatic); 1583 if (sc.Check(soa, false, "L", &result) && (result.L != nullptr)) { 1584 DCHECK(sc.CheckReflectedMethod(soa, result.L)); 1585 return result.L; 1586 } 1587 } 1588 return nullptr; 1589 } 1590 1591 static jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fid, jboolean isStatic) { 1592 ScopedObjectAccess soa(env); 1593 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1594 JniValueType args[4] = {{.E = env}, {.c = cls}, {.f = fid}, {.b = isStatic}}; 1595 if (sc.Check(soa, true, "Ecfb", args)) { 1596 JniValueType result; 1597 result.L = baseEnv(env)->ToReflectedField(env, cls, fid, isStatic); 1598 if (sc.Check(soa, false, "L", &result) && (result.L != nullptr)) { 1599 DCHECK(sc.CheckReflectedField(soa, result.L)); 1600 return result.L; 1601 } 1602 } 1603 return nullptr; 1604 } 1605 1606 static jint Throw(JNIEnv* env, jthrowable obj) { 1607 ScopedObjectAccess soa(env); 1608 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1609 JniValueType args[2] = {{.E = env}, {.t = obj}}; 1610 if (sc.Check(soa, true, "Et", args) && sc.CheckThrowable(soa, obj)) { 1611 JniValueType result; 1612 result.i = baseEnv(env)->Throw(env, obj); 1613 if (sc.Check(soa, false, "i", &result)) { 1614 return result.i; 1615 } 1616 } 1617 return JNI_ERR; 1618 } 1619 1620 static jint ThrowNew(JNIEnv* env, jclass c, const char* message) { 1621 ScopedObjectAccess soa(env); 1622 ScopedCheck sc(kFlag_NullableUtf, __FUNCTION__); 1623 JniValueType args[5] = {{.E = env}, {.c = c}, {.u = message}}; 1624 if (sc.Check(soa, true, "Ecu", args) && sc.CheckThrowableClass(soa, c)) { 1625 JniValueType result; 1626 result.i = baseEnv(env)->ThrowNew(env, c, message); 1627 if (sc.Check(soa, false, "i", &result)) { 1628 return result.i; 1629 } 1630 } 1631 return JNI_ERR; 1632 } 1633 1634 static jthrowable ExceptionOccurred(JNIEnv* env) { 1635 ScopedObjectAccess soa(env); 1636 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 1637 JniValueType args[1] = {{.E = env}}; 1638 if (sc.Check(soa, true, "E", args)) { 1639 JniValueType result; 1640 result.t = baseEnv(env)->ExceptionOccurred(env); 1641 if (sc.Check(soa, false, "t", &result)) { 1642 return result.t; 1643 } 1644 } 1645 return nullptr; 1646 } 1647 1648 static void ExceptionDescribe(JNIEnv* env) { 1649 ScopedObjectAccess soa(env); 1650 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 1651 JniValueType args[1] = {{.E = env}}; 1652 if (sc.Check(soa, true, "E", args)) { 1653 JniValueType result; 1654 baseEnv(env)->ExceptionDescribe(env); 1655 result.V = nullptr; 1656 sc.Check(soa, false, "V", &result); 1657 } 1658 } 1659 1660 static void ExceptionClear(JNIEnv* env) { 1661 ScopedObjectAccess soa(env); 1662 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 1663 JniValueType args[1] = {{.E = env}}; 1664 if (sc.Check(soa, true, "E", args)) { 1665 JniValueType result; 1666 baseEnv(env)->ExceptionClear(env); 1667 result.V = nullptr; 1668 sc.Check(soa, false, "V", &result); 1669 } 1670 } 1671 1672 static jboolean ExceptionCheck(JNIEnv* env) { 1673 ScopedObjectAccess soa(env); 1674 ScopedCheck sc(kFlag_CritOkay | kFlag_ExcepOkay, __FUNCTION__); 1675 JniValueType args[1] = {{.E = env}}; 1676 if (sc.Check(soa, true, "E", args)) { 1677 JniValueType result; 1678 result.b = baseEnv(env)->ExceptionCheck(env); 1679 if (sc.Check(soa, false, "b", &result)) { 1680 return result.b; 1681 } 1682 } 1683 return JNI_FALSE; 1684 } 1685 1686 static void FatalError(JNIEnv* env, const char* msg) { 1687 // The JNI specification doesn't say it's okay to call FatalError with a pending exception, 1688 // but you're about to abort anyway, and it's quite likely that you have a pending exception, 1689 // and it's not unimaginable that you don't know that you do. So we allow it. 1690 ScopedObjectAccess soa(env); 1691 ScopedCheck sc(kFlag_ExcepOkay | kFlag_NullableUtf, __FUNCTION__); 1692 JniValueType args[2] = {{.E = env}, {.u = msg}}; 1693 if (sc.Check(soa, true, "Eu", args)) { 1694 JniValueType result; 1695 baseEnv(env)->FatalError(env, msg); 1696 // Unreachable. 1697 result.V = nullptr; 1698 sc.Check(soa, false, "V", &result); 1699 } 1700 } 1701 1702 static jint PushLocalFrame(JNIEnv* env, jint capacity) { 1703 ScopedObjectAccess soa(env); 1704 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 1705 JniValueType args[2] = {{.E = env}, {.I = capacity}}; 1706 if (sc.Check(soa, true, "EI", args)) { 1707 JniValueType result; 1708 result.i = baseEnv(env)->PushLocalFrame(env, capacity); 1709 if (sc.Check(soa, false, "i", &result)) { 1710 return result.i; 1711 } 1712 } 1713 return JNI_ERR; 1714 } 1715 1716 static jobject PopLocalFrame(JNIEnv* env, jobject res) { 1717 ScopedObjectAccess soa(env); 1718 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 1719 JniValueType args[2] = {{.E = env}, {.L = res}}; 1720 if (sc.Check(soa, true, "EL", args)) { 1721 JniValueType result; 1722 result.L = baseEnv(env)->PopLocalFrame(env, res); 1723 sc.Check(soa, false, "L", &result); 1724 return result.L; 1725 } 1726 return nullptr; 1727 } 1728 1729 static jobject NewGlobalRef(JNIEnv* env, jobject obj) { 1730 return NewRef(__FUNCTION__, env, obj, kGlobal); 1731 } 1732 1733 static jobject NewLocalRef(JNIEnv* env, jobject obj) { 1734 return NewRef(__FUNCTION__, env, obj, kLocal); 1735 } 1736 1737 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) { 1738 return NewRef(__FUNCTION__, env, obj, kWeakGlobal); 1739 } 1740 1741 static void DeleteGlobalRef(JNIEnv* env, jobject obj) { 1742 DeleteRef(__FUNCTION__, env, obj, kGlobal); 1743 } 1744 1745 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) { 1746 DeleteRef(__FUNCTION__, env, obj, kWeakGlobal); 1747 } 1748 1749 static void DeleteLocalRef(JNIEnv* env, jobject obj) { 1750 DeleteRef(__FUNCTION__, env, obj, kLocal); 1751 } 1752 1753 static jint EnsureLocalCapacity(JNIEnv *env, jint capacity) { 1754 ScopedObjectAccess soa(env); 1755 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1756 JniValueType args[2] = {{.E = env}, {.I = capacity}}; 1757 if (sc.Check(soa, true, "EI", args)) { 1758 JniValueType result; 1759 result.i = baseEnv(env)->EnsureLocalCapacity(env, capacity); 1760 if (sc.Check(soa, false, "i", &result)) { 1761 return result.i; 1762 } 1763 } 1764 return JNI_ERR; 1765 } 1766 1767 static jboolean IsSameObject(JNIEnv* env, jobject ref1, jobject ref2) { 1768 ScopedObjectAccess soa(env); 1769 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1770 JniValueType args[3] = {{.E = env}, {.L = ref1}, {.L = ref2}}; 1771 if (sc.Check(soa, true, "ELL", args)) { 1772 JniValueType result; 1773 result.b = baseEnv(env)->IsSameObject(env, ref1, ref2); 1774 if (sc.Check(soa, false, "b", &result)) { 1775 return result.b; 1776 } 1777 } 1778 return JNI_FALSE; 1779 } 1780 1781 static jobject AllocObject(JNIEnv* env, jclass c) { 1782 ScopedObjectAccess soa(env); 1783 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1784 JniValueType args[2] = {{.E = env}, {.c = c}}; 1785 if (sc.Check(soa, true, "Ec", args) && sc.CheckInstantiableNonArray(soa, c)) { 1786 JniValueType result; 1787 result.L = baseEnv(env)->AllocObject(env, c); 1788 if (sc.Check(soa, false, "L", &result)) { 1789 return result.L; 1790 } 1791 } 1792 return nullptr; 1793 } 1794 1795 static jobject NewObjectV(JNIEnv* env, jclass c, jmethodID mid, va_list vargs) { 1796 ScopedObjectAccess soa(env); 1797 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1798 JniValueType args[3] = {{.E = env}, {.c = c}, {.m = mid}}; 1799 if (sc.Check(soa, true, "Ecm.", args) && sc.CheckInstantiableNonArray(soa, c) && 1800 sc.CheckConstructor(soa, mid)) { 1801 JniValueType result; 1802 result.L = baseEnv(env)->NewObjectV(env, c, mid, vargs); 1803 if (sc.Check(soa, false, "L", &result)) { 1804 return result.L; 1805 } 1806 } 1807 return nullptr; 1808 } 1809 1810 static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) { 1811 va_list args; 1812 va_start(args, mid); 1813 jobject result = NewObjectV(env, c, mid, args); 1814 va_end(args); 1815 return result; 1816 } 1817 1818 static jobject NewObjectA(JNIEnv* env, jclass c, jmethodID mid, jvalue* vargs) { 1819 ScopedObjectAccess soa(env); 1820 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1821 JniValueType args[3] = {{.E = env}, {.c = c}, {.m = mid}}; 1822 if (sc.Check(soa, true, "Ecm.", args) && sc.CheckInstantiableNonArray(soa, c) && 1823 sc.CheckConstructor(soa, mid)) { 1824 JniValueType result; 1825 result.L = baseEnv(env)->NewObjectA(env, c, mid, vargs); 1826 if (sc.Check(soa, false, "L", &result)) { 1827 return result.L; 1828 } 1829 } 1830 return nullptr; 1831 } 1832 1833 static jclass GetObjectClass(JNIEnv* env, jobject obj) { 1834 ScopedObjectAccess soa(env); 1835 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1836 JniValueType args[2] = {{.E = env}, {.L = obj}}; 1837 if (sc.Check(soa, true, "EL", args)) { 1838 JniValueType result; 1839 result.c = baseEnv(env)->GetObjectClass(env, obj); 1840 if (sc.Check(soa, false, "c", &result)) { 1841 return result.c; 1842 } 1843 } 1844 return nullptr; 1845 } 1846 1847 static jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass c) { 1848 ScopedObjectAccess soa(env); 1849 ScopedCheck sc(kFlag_Default, __FUNCTION__); 1850 JniValueType args[3] = {{.E = env}, {.L = obj}, {.c = c}}; 1851 if (sc.Check(soa, true, "ELc", args)) { 1852 JniValueType result; 1853 result.b = baseEnv(env)->IsInstanceOf(env, obj, c); 1854 if (sc.Check(soa, false, "b", &result)) { 1855 return result.b; 1856 } 1857 } 1858 return JNI_FALSE; 1859 } 1860 1861 static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) { 1862 return GetMethodIDInternal(__FUNCTION__, env, c, name, sig, false); 1863 } 1864 1865 static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) { 1866 return GetMethodIDInternal(__FUNCTION__, env, c, name, sig, true); 1867 } 1868 1869 static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) { 1870 return GetFieldIDInternal(__FUNCTION__, env, c, name, sig, false); 1871 } 1872 1873 static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) { 1874 return GetFieldIDInternal(__FUNCTION__, env, c, name, sig, true); 1875 } 1876 1877#define FIELD_ACCESSORS(jtype, name, ptype, shorty) \ 1878 static jtype GetStatic##name##Field(JNIEnv* env, jclass c, jfieldID fid) { \ 1879 return GetField(__FUNCTION__, env, c, fid, true, ptype).shorty; \ 1880 } \ 1881 \ 1882 static jtype Get##name##Field(JNIEnv* env, jobject obj, jfieldID fid) { \ 1883 return GetField(__FUNCTION__, env, obj, fid, false, ptype).shorty; \ 1884 } \ 1885 \ 1886 static void SetStatic##name##Field(JNIEnv* env, jclass c, jfieldID fid, jtype v) { \ 1887 JniValueType value; \ 1888 value.shorty = v; \ 1889 SetField(__FUNCTION__, env, c, fid, true, ptype, value); \ 1890 } \ 1891 \ 1892 static void Set##name##Field(JNIEnv* env, jobject obj, jfieldID fid, jtype v) { \ 1893 JniValueType value; \ 1894 value.shorty = v; \ 1895 SetField(__FUNCTION__, env, obj, fid, false, ptype, value); \ 1896 } 1897 1898 FIELD_ACCESSORS(jobject, Object, Primitive::kPrimNot, L) 1899 FIELD_ACCESSORS(jboolean, Boolean, Primitive::kPrimBoolean, Z) 1900 FIELD_ACCESSORS(jbyte, Byte, Primitive::kPrimByte, B) 1901 FIELD_ACCESSORS(jchar, Char, Primitive::kPrimChar, C) 1902 FIELD_ACCESSORS(jshort, Short, Primitive::kPrimShort, S) 1903 FIELD_ACCESSORS(jint, Int, Primitive::kPrimInt, I) 1904 FIELD_ACCESSORS(jlong, Long, Primitive::kPrimLong, J) 1905 FIELD_ACCESSORS(jfloat, Float, Primitive::kPrimFloat, F) 1906 FIELD_ACCESSORS(jdouble, Double, Primitive::kPrimDouble, D) 1907#undef FIELD_ACCESSORS 1908 1909 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* vargs) { 1910 CallMethodA(__FUNCTION__, env, obj, nullptr, mid, vargs, Primitive::kPrimVoid, kVirtual); 1911 } 1912 1913 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass c, jmethodID mid, 1914 jvalue* vargs) { 1915 CallMethodA(__FUNCTION__, env, obj, c, mid, vargs, Primitive::kPrimVoid, kDirect); 1916 } 1917 1918 static void CallStaticVoidMethodA(JNIEnv* env, jclass c, jmethodID mid, jvalue* vargs) { 1919 CallMethodA(__FUNCTION__, env, nullptr, c, mid, vargs, Primitive::kPrimVoid, kStatic); 1920 } 1921 1922 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list vargs) { 1923 CallMethodV(__FUNCTION__, env, obj, nullptr, mid, vargs, Primitive::kPrimVoid, kVirtual); 1924 } 1925 1926 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass c, jmethodID mid, 1927 va_list vargs) { 1928 CallMethodV(__FUNCTION__, env, obj, c, mid, vargs, Primitive::kPrimVoid, kDirect); 1929 } 1930 1931 static void CallStaticVoidMethodV(JNIEnv* env, jclass c, jmethodID mid, va_list vargs) { 1932 CallMethodV(__FUNCTION__, env, nullptr, c, mid, vargs, Primitive::kPrimVoid, kStatic); 1933 } 1934 1935 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 1936 va_list vargs; 1937 va_start(vargs, mid); 1938 CallMethodV(__FUNCTION__, env, obj, nullptr, mid, vargs, Primitive::kPrimVoid, kVirtual); 1939 va_end(vargs); 1940 } 1941 1942 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass c, jmethodID mid, ...) { 1943 va_list vargs; 1944 va_start(vargs, mid); 1945 CallMethodV(__FUNCTION__, env, obj, c, mid, vargs, Primitive::kPrimVoid, kDirect); 1946 va_end(vargs); 1947 } 1948 1949 static void CallStaticVoidMethod(JNIEnv* env, jclass c, jmethodID mid, ...) { 1950 va_list vargs; 1951 va_start(vargs, mid); 1952 CallMethodV(__FUNCTION__, env, nullptr, c, mid, vargs, Primitive::kPrimVoid, kStatic); 1953 va_end(vargs); 1954 } 1955 1956#define CALL(rtype, name, ptype, shorty) \ 1957 static rtype Call##name##MethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* vargs) { \ 1958 return CallMethodA(__FUNCTION__, env, obj, nullptr, mid, vargs, ptype, kVirtual).shorty; \ 1959 } \ 1960 \ 1961 static rtype CallNonvirtual##name##MethodA(JNIEnv* env, jobject obj, jclass c, jmethodID mid, \ 1962 jvalue* vargs) { \ 1963 return CallMethodA(__FUNCTION__, env, obj, c, mid, vargs, ptype, kDirect).shorty; \ 1964 } \ 1965 \ 1966 static rtype CallStatic##name##MethodA(JNIEnv* env, jclass c, jmethodID mid, jvalue* vargs) { \ 1967 return CallMethodA(__FUNCTION__, env, nullptr, c, mid, vargs, ptype, kStatic).shorty; \ 1968 } \ 1969 \ 1970 static rtype Call##name##MethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list vargs) { \ 1971 return CallMethodV(__FUNCTION__, env, obj, nullptr, mid, vargs, ptype, kVirtual).shorty; \ 1972 } \ 1973 \ 1974 static rtype CallNonvirtual##name##MethodV(JNIEnv* env, jobject obj, jclass c, jmethodID mid, \ 1975 va_list vargs) { \ 1976 return CallMethodV(__FUNCTION__, env, obj, c, mid, vargs, ptype, kDirect).shorty; \ 1977 } \ 1978 \ 1979 static rtype CallStatic##name##MethodV(JNIEnv* env, jclass c, jmethodID mid, va_list vargs) { \ 1980 return CallMethodV(__FUNCTION__, env, nullptr, c, mid, vargs, ptype, kStatic).shorty; \ 1981 } \ 1982 \ 1983 static rtype Call##name##Method(JNIEnv* env, jobject obj, jmethodID mid, ...) { \ 1984 va_list vargs; \ 1985 va_start(vargs, mid); \ 1986 rtype result = \ 1987 CallMethodV(__FUNCTION__, env, obj, nullptr, mid, vargs, ptype, kVirtual).shorty; \ 1988 va_end(vargs); \ 1989 return result; \ 1990 } \ 1991 \ 1992 static rtype CallNonvirtual##name##Method(JNIEnv* env, jobject obj, jclass c, jmethodID mid, \ 1993 ...) { \ 1994 va_list vargs; \ 1995 va_start(vargs, mid); \ 1996 rtype result = \ 1997 CallMethodV(__FUNCTION__, env, obj, c, mid, vargs, ptype, kDirect).shorty; \ 1998 va_end(vargs); \ 1999 return result; \ 2000 } \ 2001 \ 2002 static rtype CallStatic##name##Method(JNIEnv* env, jclass c, jmethodID mid, ...) { \ 2003 va_list vargs; \ 2004 va_start(vargs, mid); \ 2005 rtype result = \ 2006 CallMethodV(__FUNCTION__, env, nullptr, c, mid, vargs, ptype, kStatic).shorty; \ 2007 va_end(vargs); \ 2008 return result; \ 2009 } 2010 2011 CALL(jobject, Object, Primitive::kPrimNot, L) 2012 CALL(jboolean, Boolean, Primitive::kPrimBoolean, Z) 2013 CALL(jbyte, Byte, Primitive::kPrimByte, B) 2014 CALL(jchar, Char, Primitive::kPrimChar, C) 2015 CALL(jshort, Short, Primitive::kPrimShort, S) 2016 CALL(jint, Int, Primitive::kPrimInt, I) 2017 CALL(jlong, Long, Primitive::kPrimLong, J) 2018 CALL(jfloat, Float, Primitive::kPrimFloat, F) 2019 CALL(jdouble, Double, Primitive::kPrimDouble, D) 2020#undef CALL 2021 2022 static jstring NewString(JNIEnv* env, const jchar* unicode_chars, jsize len) { 2023 ScopedObjectAccess soa(env); 2024 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2025 JniValueType args[3] = {{.E = env}, {.p = unicode_chars}, {.z = len}}; 2026 if (sc.Check(soa, true, "Epz", args)) { 2027 JniValueType result; 2028 result.s = baseEnv(env)->NewString(env, unicode_chars, len); 2029 if (sc.Check(soa, false, "s", &result)) { 2030 return result.s; 2031 } 2032 } 2033 return nullptr; 2034 } 2035 2036 static jstring NewStringUTF(JNIEnv* env, const char* chars) { 2037 ScopedObjectAccess soa(env); 2038 ScopedCheck sc(kFlag_NullableUtf, __FUNCTION__); 2039 JniValueType args[2] = {{.E = env}, {.u = chars}}; 2040 if (sc.Check(soa, true, "Eu", args)) { 2041 JniValueType result; 2042 // TODO: stale? show pointer and truncate string. 2043 result.s = baseEnv(env)->NewStringUTF(env, chars); 2044 if (sc.Check(soa, false, "s", &result)) { 2045 return result.s; 2046 } 2047 } 2048 return nullptr; 2049 } 2050 2051 static jsize GetStringLength(JNIEnv* env, jstring string) { 2052 ScopedObjectAccess soa(env); 2053 ScopedCheck sc(kFlag_CritOkay, __FUNCTION__); 2054 JniValueType args[2] = {{.E = env}, {.s = string}}; 2055 if (sc.Check(soa, true, "Es", args)) { 2056 JniValueType result; 2057 result.z = baseEnv(env)->GetStringLength(env, string); 2058 if (sc.Check(soa, false, "z", &result)) { 2059 return result.z; 2060 } 2061 } 2062 return JNI_ERR; 2063 } 2064 2065 static jsize GetStringUTFLength(JNIEnv* env, jstring string) { 2066 ScopedObjectAccess soa(env); 2067 ScopedCheck sc(kFlag_CritOkay, __FUNCTION__); 2068 JniValueType args[2] = {{.E = env}, {.s = string}}; 2069 if (sc.Check(soa, true, "Es", args)) { 2070 JniValueType result; 2071 result.z = baseEnv(env)->GetStringUTFLength(env, string); 2072 if (sc.Check(soa, false, "z", &result)) { 2073 return result.z; 2074 } 2075 } 2076 return JNI_ERR; 2077 } 2078 2079 static const jchar* GetStringChars(JNIEnv* env, jstring string, jboolean* is_copy) { 2080 return reinterpret_cast<const jchar*>(GetStringCharsInternal(__FUNCTION__, env, string, 2081 is_copy, false, false)); 2082 } 2083 2084 static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* is_copy) { 2085 return reinterpret_cast<const char*>(GetStringCharsInternal(__FUNCTION__, env, string, 2086 is_copy, true, false)); 2087 } 2088 2089 static const jchar* GetStringCritical(JNIEnv* env, jstring string, jboolean* is_copy) { 2090 return reinterpret_cast<const jchar*>(GetStringCharsInternal(__FUNCTION__, env, string, 2091 is_copy, false, true)); 2092 } 2093 2094 static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) { 2095 ReleaseStringCharsInternal(__FUNCTION__, env, string, chars, false, false); 2096 } 2097 2098 static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) { 2099 ReleaseStringCharsInternal(__FUNCTION__, env, string, utf, true, false); 2100 } 2101 2102 static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* chars) { 2103 ReleaseStringCharsInternal(__FUNCTION__, env, string, chars, false, true); 2104 } 2105 2106 static void GetStringRegion(JNIEnv* env, jstring string, jsize start, jsize len, jchar* buf) { 2107 ScopedObjectAccess soa(env); 2108 ScopedCheck sc(kFlag_CritOkay, __FUNCTION__); 2109 JniValueType args[5] = {{.E = env}, {.s = string}, {.z = start}, {.z = len}, {.p = buf}}; 2110 // Note: the start and len arguments are checked as 'I' rather than 'z' as invalid indices 2111 // result in ArrayIndexOutOfBoundsExceptions in the base implementation. 2112 if (sc.Check(soa, true, "EsIIp", args)) { 2113 baseEnv(env)->GetStringRegion(env, string, start, len, buf); 2114 JniValueType result; 2115 result.V = nullptr; 2116 sc.Check(soa, false, "V", &result); 2117 } 2118 } 2119 2120 static void GetStringUTFRegion(JNIEnv* env, jstring string, jsize start, jsize len, char* buf) { 2121 ScopedObjectAccess soa(env); 2122 ScopedCheck sc(kFlag_CritOkay, __FUNCTION__); 2123 JniValueType args[5] = {{.E = env}, {.s = string}, {.z = start}, {.z = len}, {.p = buf}}; 2124 // Note: the start and len arguments are checked as 'I' rather than 'z' as invalid indices 2125 // result in ArrayIndexOutOfBoundsExceptions in the base implementation. 2126 if (sc.Check(soa, true, "EsIIp", args)) { 2127 baseEnv(env)->GetStringUTFRegion(env, string, start, len, buf); 2128 JniValueType result; 2129 result.V = nullptr; 2130 sc.Check(soa, false, "V", &result); 2131 } 2132 } 2133 2134 static jsize GetArrayLength(JNIEnv* env, jarray array) { 2135 ScopedObjectAccess soa(env); 2136 ScopedCheck sc(kFlag_CritOkay, __FUNCTION__); 2137 JniValueType args[2] = {{.E = env}, {.a = array}}; 2138 if (sc.Check(soa, true, "Ea", args)) { 2139 JniValueType result; 2140 result.z = baseEnv(env)->GetArrayLength(env, array); 2141 if (sc.Check(soa, false, "z", &result)) { 2142 return result.z; 2143 } 2144 } 2145 return JNI_ERR; 2146 } 2147 2148 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_class, 2149 jobject initial_element) { 2150 ScopedObjectAccess soa(env); 2151 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2152 JniValueType args[4] = 2153 {{.E = env}, {.z = length}, {.c = element_class}, {.L = initial_element}}; 2154 if (sc.Check(soa, true, "EzcL", args)) { 2155 JniValueType result; 2156 // Note: assignability tests of initial_element are done in the base implementation. 2157 result.a = baseEnv(env)->NewObjectArray(env, length, element_class, initial_element); 2158 if (sc.Check(soa, false, "a", &result)) { 2159 return down_cast<jobjectArray>(result.a); 2160 } 2161 } 2162 return nullptr; 2163 } 2164 2165 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) { 2166 ScopedObjectAccess soa(env); 2167 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2168 JniValueType args[3] = {{.E = env}, {.a = array}, {.z = index}}; 2169 if (sc.Check(soa, true, "Eaz", args)) { 2170 JniValueType result; 2171 result.L = baseEnv(env)->GetObjectArrayElement(env, array, index); 2172 if (sc.Check(soa, false, "L", &result)) { 2173 return result.L; 2174 } 2175 } 2176 return nullptr; 2177 } 2178 2179 static void SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) { 2180 ScopedObjectAccess soa(env); 2181 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2182 JniValueType args[4] = {{.E = env}, {.a = array}, {.z = index}, {.L = value}}; 2183 // Note: the index arguments is checked as 'I' rather than 'z' as invalid indices result in 2184 // ArrayIndexOutOfBoundsExceptions in the base implementation. Similarly invalid stores result 2185 // in ArrayStoreExceptions. 2186 if (sc.Check(soa, true, "EaIL", args)) { 2187 baseEnv(env)->SetObjectArrayElement(env, array, index, value); 2188 JniValueType result; 2189 result.V = nullptr; 2190 sc.Check(soa, false, "V", &result); 2191 } 2192 } 2193 2194 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) { 2195 return down_cast<jbooleanArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2196 Primitive::kPrimBoolean)); 2197 } 2198 2199 static jbyteArray NewByteArray(JNIEnv* env, jsize length) { 2200 return down_cast<jbyteArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2201 Primitive::kPrimByte)); 2202 } 2203 2204 static jcharArray NewCharArray(JNIEnv* env, jsize length) { 2205 return down_cast<jcharArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2206 Primitive::kPrimChar)); 2207 } 2208 2209 static jshortArray NewShortArray(JNIEnv* env, jsize length) { 2210 return down_cast<jshortArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2211 Primitive::kPrimShort)); 2212 } 2213 2214 static jintArray NewIntArray(JNIEnv* env, jsize length) { 2215 return down_cast<jintArray>(NewPrimitiveArray(__FUNCTION__, env, length, Primitive::kPrimInt)); 2216 } 2217 2218 static jlongArray NewLongArray(JNIEnv* env, jsize length) { 2219 return down_cast<jlongArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2220 Primitive::kPrimLong)); 2221 } 2222 2223 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) { 2224 return down_cast<jfloatArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2225 Primitive::kPrimFloat)); 2226 } 2227 2228 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) { 2229 return down_cast<jdoubleArray>(NewPrimitiveArray(__FUNCTION__, env, length, 2230 Primitive::kPrimDouble)); 2231 } 2232 2233#define PRIMITIVE_ARRAY_FUNCTIONS(ctype, name, ptype) \ 2234 static ctype* Get##name##ArrayElements(JNIEnv* env, ctype##Array array, jboolean* is_copy) { \ 2235 return reinterpret_cast<ctype*>( \ 2236 GetPrimitiveArrayElements(__FUNCTION__, ptype, env, array, is_copy)); \ 2237 } \ 2238 \ 2239 static void Release##name##ArrayElements(JNIEnv* env, ctype##Array array, ctype* elems, \ 2240 jint mode) { \ 2241 ReleasePrimitiveArrayElements(__FUNCTION__, ptype, env, array, elems, mode); \ 2242 } \ 2243 \ 2244 static void Get##name##ArrayRegion(JNIEnv* env, ctype##Array array, jsize start, jsize len, \ 2245 ctype* buf) { \ 2246 GetPrimitiveArrayRegion(__FUNCTION__, ptype, env, array, start, len, buf); \ 2247 } \ 2248 \ 2249 static void Set##name##ArrayRegion(JNIEnv* env, ctype##Array array, jsize start, jsize len, \ 2250 const ctype* buf) { \ 2251 SetPrimitiveArrayRegion(__FUNCTION__, ptype, env, array, start, len, buf); \ 2252 } 2253 2254 PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, Primitive::kPrimBoolean) 2255 PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, Primitive::kPrimByte) 2256 PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, Primitive::kPrimChar) 2257 PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, Primitive::kPrimShort) 2258 PRIMITIVE_ARRAY_FUNCTIONS(jint, Int, Primitive::kPrimInt) 2259 PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, Primitive::kPrimLong) 2260 PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, Primitive::kPrimFloat) 2261 PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, Primitive::kPrimDouble) 2262#undef PRIMITIVE_ARRAY_FUNCTIONS 2263 2264 static jint MonitorEnter(JNIEnv* env, jobject obj) { 2265 ScopedObjectAccess soa(env); 2266 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2267 JniValueType args[2] = {{.E = env}, {.L = obj}}; 2268 if (sc.Check(soa, true, "EL", args)) { 2269 JniValueType result; 2270 result.i = baseEnv(env)->MonitorEnter(env, obj); 2271 if (sc.Check(soa, false, "i", &result)) { 2272 return result.i; 2273 } 2274 } 2275 return JNI_ERR; 2276 } 2277 2278 static jint MonitorExit(JNIEnv* env, jobject obj) { 2279 ScopedObjectAccess soa(env); 2280 ScopedCheck sc(kFlag_ExcepOkay, __FUNCTION__); 2281 JniValueType args[2] = {{.E = env}, {.L = obj}}; 2282 if (sc.Check(soa, true, "EL", args)) { 2283 JniValueType result; 2284 result.i = baseEnv(env)->MonitorExit(env, obj); 2285 if (sc.Check(soa, false, "i", &result)) { 2286 return result.i; 2287 } 2288 } 2289 return JNI_ERR; 2290 } 2291 2292 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* is_copy) { 2293 ScopedObjectAccess soa(env); 2294 ScopedCheck sc(kFlag_CritGet, __FUNCTION__); 2295 JniValueType args[3] = {{.E = env}, {.a = array}, {.p = is_copy}}; 2296 if (sc.Check(soa, true, "Eap", args)) { 2297 JniValueType result; 2298 result.p = baseEnv(env)->GetPrimitiveArrayCritical(env, array, is_copy); 2299 if (result.p != nullptr && soa.ForceCopy()) { 2300 result.p = GuardedCopy::CreateGuardedPACopy(env, array, is_copy); 2301 } 2302 if (sc.Check(soa, false, "p", &result)) { 2303 return const_cast<void*>(result.p); 2304 } 2305 } 2306 return nullptr; 2307 } 2308 2309 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) { 2310 ScopedObjectAccess soa(env); 2311 ScopedCheck sc(kFlag_CritRelease | kFlag_ExcepOkay, __FUNCTION__); 2312 sc.CheckNonNull(carray); 2313 JniValueType args[4] = {{.E = env}, {.a = array}, {.p = carray}, {.r = mode}}; 2314 if (sc.Check(soa, true, "Eapr", args)) { 2315 if (soa.ForceCopy()) { 2316 GuardedCopy::ReleaseGuardedPACopy(__FUNCTION__, env, array, carray, mode); 2317 } 2318 baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode); 2319 JniValueType result; 2320 result.V = nullptr; 2321 sc.Check(soa, false, "V", &result); 2322 } 2323 } 2324 2325 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { 2326 ScopedObjectAccess soa(env); 2327 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2328 JniValueType args[3] = {{.E = env}, {.p = address}, {.J = capacity}}; 2329 if (sc.Check(soa, true, "EpJ", args)) { 2330 JniValueType result; 2331 // Note: the validity of address and capacity are checked in the base implementation. 2332 result.L = baseEnv(env)->NewDirectByteBuffer(env, address, capacity); 2333 if (sc.Check(soa, false, "L", &result)) { 2334 return result.L; 2335 } 2336 } 2337 return nullptr; 2338 } 2339 2340 static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) { 2341 ScopedObjectAccess soa(env); 2342 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2343 JniValueType args[2] = {{.E = env}, {.L = buf}}; 2344 if (sc.Check(soa, true, "EL", args)) { 2345 JniValueType result; 2346 // Note: this is implemented in the base environment by a GetLongField which will sanity 2347 // check the type of buf in GetLongField above. 2348 result.p = baseEnv(env)->GetDirectBufferAddress(env, buf); 2349 if (sc.Check(soa, false, "p", &result)) { 2350 return const_cast<void*>(result.p); 2351 } 2352 } 2353 return nullptr; 2354 } 2355 2356 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) { 2357 ScopedObjectAccess soa(env); 2358 ScopedCheck sc(kFlag_Default, __FUNCTION__); 2359 JniValueType args[2] = {{.E = env}, {.L = buf}}; 2360 if (sc.Check(soa, true, "EL", args)) { 2361 JniValueType result; 2362 // Note: this is implemented in the base environment by a GetIntField which will sanity 2363 // check the type of buf in GetIntField above. 2364 result.J = baseEnv(env)->GetDirectBufferCapacity(env, buf); 2365 if (sc.Check(soa, false, "J", &result)) { 2366 return result.J; 2367 } 2368 } 2369 return JNI_ERR; 2370 } 2371 2372 private: 2373 static JavaVMExt* GetJavaVMExt(JNIEnv* env) { 2374 return reinterpret_cast<JNIEnvExt*>(env)->vm; 2375 } 2376 2377 static const JNINativeInterface* baseEnv(JNIEnv* env) { 2378 return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions; 2379 } 2380 2381 static jobject NewRef(const char* function_name, JNIEnv* env, jobject obj, IndirectRefKind kind) { 2382 ScopedObjectAccess soa(env); 2383 ScopedCheck sc(kFlag_Default, function_name); 2384 JniValueType args[2] = {{.E = env}, {.L = obj}}; 2385 if (sc.Check(soa, true, "EL", args)) { 2386 JniValueType result; 2387 switch (kind) { 2388 case kGlobal: 2389 result.L = baseEnv(env)->NewGlobalRef(env, obj); 2390 break; 2391 case kLocal: 2392 result.L = baseEnv(env)->NewLocalRef(env, obj); 2393 break; 2394 case kWeakGlobal: 2395 result.L = baseEnv(env)->NewWeakGlobalRef(env, obj); 2396 break; 2397 default: 2398 LOG(FATAL) << "Unexpected reference kind: " << kind; 2399 } 2400 if (sc.Check(soa, false, "L", &result)) { 2401 DCHECK_EQ(IsSameObject(env, obj, result.L), JNI_TRUE); 2402 DCHECK(sc.CheckReferenceKind(kind, soa.Self(), result.L)); 2403 return result.L; 2404 } 2405 } 2406 return nullptr; 2407 } 2408 2409 static void DeleteRef(const char* function_name, JNIEnv* env, jobject obj, IndirectRefKind kind) { 2410 ScopedObjectAccess soa(env); 2411 ScopedCheck sc(kFlag_ExcepOkay, function_name); 2412 JniValueType args[2] = {{.E = env}, {.L = obj}}; 2413 sc.Check(soa, true, "EL", args); 2414 if (sc.CheckReferenceKind(kind, soa.Self(), obj)) { 2415 JniValueType result; 2416 switch (kind) { 2417 case kGlobal: 2418 baseEnv(env)->DeleteGlobalRef(env, obj); 2419 break; 2420 case kLocal: 2421 baseEnv(env)->DeleteLocalRef(env, obj); 2422 break; 2423 case kWeakGlobal: 2424 baseEnv(env)->DeleteWeakGlobalRef(env, obj); 2425 break; 2426 default: 2427 LOG(FATAL) << "Unexpected reference kind: " << kind; 2428 } 2429 result.V = nullptr; 2430 sc.Check(soa, false, "V", &result); 2431 } 2432 } 2433 2434 static jmethodID GetMethodIDInternal(const char* function_name, JNIEnv* env, jclass c, 2435 const char* name, const char* sig, bool is_static) { 2436 ScopedObjectAccess soa(env); 2437 ScopedCheck sc(kFlag_Default, function_name); 2438 JniValueType args[4] = {{.E = env}, {.c = c}, {.u = name}, {.u = sig}}; 2439 if (sc.Check(soa, true, "Ecuu", args)) { 2440 JniValueType result; 2441 if (is_static) { 2442 result.m = baseEnv(env)->GetStaticMethodID(env, c, name, sig); 2443 } else { 2444 result.m = baseEnv(env)->GetMethodID(env, c, name, sig); 2445 } 2446 if (sc.Check(soa, false, "m", &result)) { 2447 return result.m; 2448 } 2449 } 2450 return nullptr; 2451 } 2452 2453 static jfieldID GetFieldIDInternal(const char* function_name, JNIEnv* env, jclass c, 2454 const char* name, const char* sig, bool is_static) { 2455 ScopedObjectAccess soa(env); 2456 ScopedCheck sc(kFlag_Default, function_name); 2457 JniValueType args[4] = {{.E = env}, {.c = c}, {.u = name}, {.u = sig}}; 2458 if (sc.Check(soa, true, "Ecuu", args)) { 2459 JniValueType result; 2460 if (is_static) { 2461 result.f = baseEnv(env)->GetStaticFieldID(env, c, name, sig); 2462 } else { 2463 result.f = baseEnv(env)->GetFieldID(env, c, name, sig); 2464 } 2465 if (sc.Check(soa, false, "f", &result)) { 2466 return result.f; 2467 } 2468 } 2469 return nullptr; 2470 } 2471 2472 static JniValueType GetField(const char* function_name, JNIEnv* env, jobject obj, jfieldID fid, 2473 bool is_static, Primitive::Type type) { 2474 ScopedObjectAccess soa(env); 2475 ScopedCheck sc(kFlag_Default, function_name); 2476 JniValueType args[3] = {{.E = env}, {.L = obj}, {.f = fid}}; 2477 JniValueType result; 2478 if (sc.Check(soa, true, is_static ? "Ecf" : "ELf", args) && 2479 sc.CheckFieldAccess(soa, obj, fid, is_static, type)) { 2480 const char* result_check = nullptr; 2481 switch (type) { 2482 case Primitive::kPrimNot: 2483 if (is_static) { 2484 result.L = baseEnv(env)->GetStaticObjectField(env, down_cast<jclass>(obj), fid); 2485 } else { 2486 result.L = baseEnv(env)->GetObjectField(env, obj, fid); 2487 } 2488 result_check = "L"; 2489 break; 2490 case Primitive::kPrimBoolean: 2491 if (is_static) { 2492 result.Z = baseEnv(env)->GetStaticBooleanField(env, down_cast<jclass>(obj), fid); 2493 } else { 2494 result.Z = baseEnv(env)->GetBooleanField(env, obj, fid); 2495 } 2496 result_check = "Z"; 2497 break; 2498 case Primitive::kPrimByte: 2499 if (is_static) { 2500 result.B = baseEnv(env)->GetStaticByteField(env, down_cast<jclass>(obj), fid); 2501 } else { 2502 result.B = baseEnv(env)->GetByteField(env, obj, fid); 2503 } 2504 result_check = "B"; 2505 break; 2506 case Primitive::kPrimChar: 2507 if (is_static) { 2508 result.C = baseEnv(env)->GetStaticCharField(env, down_cast<jclass>(obj), fid); 2509 } else { 2510 result.C = baseEnv(env)->GetCharField(env, obj, fid); 2511 } 2512 result_check = "C"; 2513 break; 2514 case Primitive::kPrimShort: 2515 if (is_static) { 2516 result.S = baseEnv(env)->GetStaticShortField(env, down_cast<jclass>(obj), fid); 2517 } else { 2518 result.S = baseEnv(env)->GetShortField(env, obj, fid); 2519 } 2520 result_check = "S"; 2521 break; 2522 case Primitive::kPrimInt: 2523 if (is_static) { 2524 result.I = baseEnv(env)->GetStaticIntField(env, down_cast<jclass>(obj), fid); 2525 } else { 2526 result.I = baseEnv(env)->GetIntField(env, obj, fid); 2527 } 2528 result_check = "I"; 2529 break; 2530 case Primitive::kPrimLong: 2531 if (is_static) { 2532 result.J = baseEnv(env)->GetStaticLongField(env, down_cast<jclass>(obj), fid); 2533 } else { 2534 result.J = baseEnv(env)->GetLongField(env, obj, fid); 2535 } 2536 result_check = "J"; 2537 break; 2538 case Primitive::kPrimFloat: 2539 if (is_static) { 2540 result.F = baseEnv(env)->GetStaticFloatField(env, down_cast<jclass>(obj), fid); 2541 } else { 2542 result.F = baseEnv(env)->GetFloatField(env, obj, fid); 2543 } 2544 result_check = "F"; 2545 break; 2546 case Primitive::kPrimDouble: 2547 if (is_static) { 2548 result.D = baseEnv(env)->GetStaticDoubleField(env, down_cast<jclass>(obj), fid); 2549 } else { 2550 result.D = baseEnv(env)->GetDoubleField(env, obj, fid); 2551 } 2552 result_check = "D"; 2553 break; 2554 case Primitive::kPrimVoid: 2555 LOG(FATAL) << "Unexpected type: " << type; 2556 break; 2557 } 2558 if (sc.Check(soa, false, result_check, &result)) { 2559 return result; 2560 } 2561 } 2562 result.J = 0; 2563 return result; 2564 } 2565 2566 static void SetField(const char* function_name, JNIEnv* env, jobject obj, jfieldID fid, 2567 bool is_static, Primitive::Type type, JniValueType value) { 2568 ScopedObjectAccess soa(env); 2569 ScopedCheck sc(kFlag_Default, function_name); 2570 JniValueType args[4] = {{.E = env}, {.L = obj}, {.f = fid}, value}; 2571 char sig[5] = { 'E', is_static ? 'c' : 'L', 'f', 2572 type == Primitive::kPrimNot ? 'L' : Primitive::Descriptor(type)[0], '\0'}; 2573 if (sc.Check(soa, true, sig, args) && 2574 sc.CheckFieldAccess(soa, obj, fid, is_static, type)) { 2575 switch (type) { 2576 case Primitive::kPrimNot: 2577 if (is_static) { 2578 baseEnv(env)->SetStaticObjectField(env, down_cast<jclass>(obj), fid, value.L); 2579 } else { 2580 baseEnv(env)->SetObjectField(env, obj, fid, value.L); 2581 } 2582 break; 2583 case Primitive::kPrimBoolean: 2584 if (is_static) { 2585 baseEnv(env)->SetStaticBooleanField(env, down_cast<jclass>(obj), fid, value.Z); 2586 } else { 2587 baseEnv(env)->SetBooleanField(env, obj, fid, value.Z); 2588 } 2589 break; 2590 case Primitive::kPrimByte: 2591 if (is_static) { 2592 baseEnv(env)->SetStaticByteField(env, down_cast<jclass>(obj), fid, value.B); 2593 } else { 2594 baseEnv(env)->SetByteField(env, obj, fid, value.B); 2595 } 2596 break; 2597 case Primitive::kPrimChar: 2598 if (is_static) { 2599 baseEnv(env)->SetStaticCharField(env, down_cast<jclass>(obj), fid, value.C); 2600 } else { 2601 baseEnv(env)->SetCharField(env, obj, fid, value.C); 2602 } 2603 break; 2604 case Primitive::kPrimShort: 2605 if (is_static) { 2606 baseEnv(env)->SetStaticShortField(env, down_cast<jclass>(obj), fid, value.S); 2607 } else { 2608 baseEnv(env)->SetShortField(env, obj, fid, value.S); 2609 } 2610 break; 2611 case Primitive::kPrimInt: 2612 if (is_static) { 2613 baseEnv(env)->SetStaticIntField(env, down_cast<jclass>(obj), fid, value.I); 2614 } else { 2615 baseEnv(env)->SetIntField(env, obj, fid, value.I); 2616 } 2617 break; 2618 case Primitive::kPrimLong: 2619 if (is_static) { 2620 baseEnv(env)->SetStaticLongField(env, down_cast<jclass>(obj), fid, value.J); 2621 } else { 2622 baseEnv(env)->SetLongField(env, obj, fid, value.J); 2623 } 2624 break; 2625 case Primitive::kPrimFloat: 2626 if (is_static) { 2627 baseEnv(env)->SetStaticFloatField(env, down_cast<jclass>(obj), fid, value.F); 2628 } else { 2629 baseEnv(env)->SetFloatField(env, obj, fid, value.F); 2630 } 2631 break; 2632 case Primitive::kPrimDouble: 2633 if (is_static) { 2634 baseEnv(env)->SetStaticDoubleField(env, down_cast<jclass>(obj), fid, value.D); 2635 } else { 2636 baseEnv(env)->SetDoubleField(env, obj, fid, value.D); 2637 } 2638 break; 2639 case Primitive::kPrimVoid: 2640 LOG(FATAL) << "Unexpected type: " << type; 2641 break; 2642 } 2643 JniValueType result; 2644 result.V = nullptr; 2645 sc.Check(soa, false, "V", &result); 2646 } 2647 } 2648 2649 static bool CheckCallArgs(ScopedObjectAccess& soa, ScopedCheck& sc, JNIEnv* env, jobject obj, 2650 jclass c, jmethodID mid, InvokeType invoke) 2651 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2652 bool checked; 2653 switch (invoke) { 2654 case kVirtual: { 2655 DCHECK(c == nullptr); 2656 JniValueType args[3] = {{.E = env}, {.L = obj}, {.m = mid}}; 2657 checked = sc.Check(soa, true, "ELm.", args); 2658 break; 2659 } 2660 case kDirect: { 2661 JniValueType args[4] = {{.E = env}, {.L = obj}, {.c = c}, {.m = mid}}; 2662 checked = sc.Check(soa, true, "ELcm.", args); 2663 break; 2664 } 2665 case kStatic: { 2666 DCHECK(obj == nullptr); 2667 JniValueType args[3] = {{.E = env}, {.c = c}, {.m = mid}}; 2668 checked = sc.Check(soa, true, "Ecm.", args); 2669 break; 2670 } 2671 default: 2672 LOG(FATAL) << "Unexpected invoke: " << invoke; 2673 checked = false; 2674 break; 2675 } 2676 return checked; 2677 } 2678 2679 static JniValueType CallMethodA(const char* function_name, JNIEnv* env, jobject obj, jclass c, 2680 jmethodID mid, jvalue* vargs, Primitive::Type type, 2681 InvokeType invoke) { 2682 ScopedObjectAccess soa(env); 2683 ScopedCheck sc(kFlag_Default, function_name); 2684 JniValueType result; 2685 if (CheckCallArgs(soa, sc, env, obj, c, mid, invoke) && 2686 sc.CheckMethodAndSig(soa, obj, c, mid, type, invoke)) { 2687 const char* result_check; 2688 switch (type) { 2689 case Primitive::kPrimNot: 2690 result_check = "L"; 2691 switch (invoke) { 2692 case kVirtual: 2693 result.L = baseEnv(env)->CallObjectMethodA(env, obj, mid, vargs); 2694 break; 2695 case kDirect: 2696 result.L = baseEnv(env)->CallNonvirtualObjectMethodA(env, obj, c, mid, vargs); 2697 break; 2698 case kStatic: 2699 result.L = baseEnv(env)->CallStaticObjectMethodA(env, c, mid, vargs); 2700 break; 2701 default: 2702 break; 2703 } 2704 break; 2705 case Primitive::kPrimBoolean: 2706 result_check = "Z"; 2707 switch (invoke) { 2708 case kVirtual: 2709 result.Z = baseEnv(env)->CallBooleanMethodA(env, obj, mid, vargs); 2710 break; 2711 case kDirect: 2712 result.Z = baseEnv(env)->CallNonvirtualBooleanMethodA(env, obj, c, mid, vargs); 2713 break; 2714 case kStatic: 2715 result.Z = baseEnv(env)->CallStaticBooleanMethodA(env, c, mid, vargs); 2716 break; 2717 default: 2718 break; 2719 } 2720 break; 2721 case Primitive::kPrimByte: 2722 result_check = "B"; 2723 switch (invoke) { 2724 case kVirtual: 2725 result.B = baseEnv(env)->CallByteMethodA(env, obj, mid, vargs); 2726 break; 2727 case kDirect: 2728 result.B = baseEnv(env)->CallNonvirtualByteMethodA(env, obj, c, mid, vargs); 2729 break; 2730 case kStatic: 2731 result.B = baseEnv(env)->CallStaticByteMethodA(env, c, mid, vargs); 2732 break; 2733 default: 2734 break; 2735 } 2736 break; 2737 case Primitive::kPrimChar: 2738 result_check = "C"; 2739 switch (invoke) { 2740 case kVirtual: 2741 result.C = baseEnv(env)->CallCharMethodA(env, obj, mid, vargs); 2742 break; 2743 case kDirect: 2744 result.C = baseEnv(env)->CallNonvirtualCharMethodA(env, obj, c, mid, vargs); 2745 break; 2746 case kStatic: 2747 result.C = baseEnv(env)->CallStaticCharMethodA(env, c, mid, vargs); 2748 break; 2749 default: 2750 break; 2751 } 2752 break; 2753 case Primitive::kPrimShort: 2754 result_check = "S"; 2755 switch (invoke) { 2756 case kVirtual: 2757 result.S = baseEnv(env)->CallShortMethodA(env, obj, mid, vargs); 2758 break; 2759 case kDirect: 2760 result.S = baseEnv(env)->CallNonvirtualShortMethodA(env, obj, c, mid, vargs); 2761 break; 2762 case kStatic: 2763 result.S = baseEnv(env)->CallStaticShortMethodA(env, c, mid, vargs); 2764 break; 2765 default: 2766 break; 2767 } 2768 break; 2769 case Primitive::kPrimInt: 2770 result_check = "I"; 2771 switch (invoke) { 2772 case kVirtual: 2773 result.I = baseEnv(env)->CallIntMethodA(env, obj, mid, vargs); 2774 break; 2775 case kDirect: 2776 result.I = baseEnv(env)->CallNonvirtualIntMethodA(env, obj, c, mid, vargs); 2777 break; 2778 case kStatic: 2779 result.I = baseEnv(env)->CallStaticIntMethodA(env, c, mid, vargs); 2780 break; 2781 default: 2782 break; 2783 } 2784 break; 2785 case Primitive::kPrimLong: 2786 result_check = "J"; 2787 switch (invoke) { 2788 case kVirtual: 2789 result.J = baseEnv(env)->CallLongMethodA(env, obj, mid, vargs); 2790 break; 2791 case kDirect: 2792 result.J = baseEnv(env)->CallNonvirtualLongMethodA(env, obj, c, mid, vargs); 2793 break; 2794 case kStatic: 2795 result.J = baseEnv(env)->CallStaticLongMethodA(env, c, mid, vargs); 2796 break; 2797 default: 2798 break; 2799 } 2800 break; 2801 case Primitive::kPrimFloat: 2802 result_check = "F"; 2803 switch (invoke) { 2804 case kVirtual: 2805 result.F = baseEnv(env)->CallFloatMethodA(env, obj, mid, vargs); 2806 break; 2807 case kDirect: 2808 result.F = baseEnv(env)->CallNonvirtualFloatMethodA(env, obj, c, mid, vargs); 2809 break; 2810 case kStatic: 2811 result.F = baseEnv(env)->CallStaticFloatMethodA(env, c, mid, vargs); 2812 break; 2813 default: 2814 break; 2815 } 2816 break; 2817 case Primitive::kPrimDouble: 2818 result_check = "D"; 2819 switch (invoke) { 2820 case kVirtual: 2821 result.D = baseEnv(env)->CallDoubleMethodA(env, obj, mid, vargs); 2822 break; 2823 case kDirect: 2824 result.D = baseEnv(env)->CallNonvirtualDoubleMethodA(env, obj, c, mid, vargs); 2825 break; 2826 case kStatic: 2827 result.D = baseEnv(env)->CallStaticDoubleMethodA(env, c, mid, vargs); 2828 break; 2829 default: 2830 break; 2831 } 2832 break; 2833 case Primitive::kPrimVoid: 2834 result_check = "V"; 2835 result.V = nullptr; 2836 switch (invoke) { 2837 case kVirtual: 2838 baseEnv(env)->CallVoidMethodA(env, obj, mid, vargs); 2839 break; 2840 case kDirect: 2841 baseEnv(env)->CallNonvirtualVoidMethodA(env, obj, c, mid, vargs); 2842 break; 2843 case kStatic: 2844 baseEnv(env)->CallStaticVoidMethodA(env, c, mid, vargs); 2845 break; 2846 default: 2847 LOG(FATAL) << "Unexpected invoke: " << invoke; 2848 } 2849 break; 2850 default: 2851 LOG(FATAL) << "Unexpected return type: " << type; 2852 result_check = nullptr; 2853 } 2854 if (sc.Check(soa, false, result_check, &result)) { 2855 return result; 2856 } 2857 } 2858 result.J = 0; 2859 return result; 2860 } 2861 2862 static JniValueType CallMethodV(const char* function_name, JNIEnv* env, jobject obj, jclass c, 2863 jmethodID mid, va_list vargs, Primitive::Type type, 2864 InvokeType invoke) { 2865 ScopedObjectAccess soa(env); 2866 ScopedCheck sc(kFlag_Default, function_name); 2867 JniValueType result; 2868 if (CheckCallArgs(soa, sc, env, obj, c, mid, invoke) && 2869 sc.CheckMethodAndSig(soa, obj, c, mid, type, invoke)) { 2870 const char* result_check; 2871 switch (type) { 2872 case Primitive::kPrimNot: 2873 result_check = "L"; 2874 switch (invoke) { 2875 case kVirtual: 2876 result.L = baseEnv(env)->CallObjectMethodV(env, obj, mid, vargs); 2877 break; 2878 case kDirect: 2879 result.L = baseEnv(env)->CallNonvirtualObjectMethodV(env, obj, c, mid, vargs); 2880 break; 2881 case kStatic: 2882 result.L = baseEnv(env)->CallStaticObjectMethodV(env, c, mid, vargs); 2883 break; 2884 default: 2885 LOG(FATAL) << "Unexpected invoke: " << invoke; 2886 } 2887 break; 2888 case Primitive::kPrimBoolean: 2889 result_check = "Z"; 2890 switch (invoke) { 2891 case kVirtual: 2892 result.Z = baseEnv(env)->CallBooleanMethodV(env, obj, mid, vargs); 2893 break; 2894 case kDirect: 2895 result.Z = baseEnv(env)->CallNonvirtualBooleanMethodV(env, obj, c, mid, vargs); 2896 break; 2897 case kStatic: 2898 result.Z = baseEnv(env)->CallStaticBooleanMethodV(env, c, mid, vargs); 2899 break; 2900 default: 2901 LOG(FATAL) << "Unexpected invoke: " << invoke; 2902 } 2903 break; 2904 case Primitive::kPrimByte: 2905 result_check = "B"; 2906 switch (invoke) { 2907 case kVirtual: 2908 result.B = baseEnv(env)->CallByteMethodV(env, obj, mid, vargs); 2909 break; 2910 case kDirect: 2911 result.B = baseEnv(env)->CallNonvirtualByteMethodV(env, obj, c, mid, vargs); 2912 break; 2913 case kStatic: 2914 result.B = baseEnv(env)->CallStaticByteMethodV(env, c, mid, vargs); 2915 break; 2916 default: 2917 LOG(FATAL) << "Unexpected invoke: " << invoke; 2918 } 2919 break; 2920 case Primitive::kPrimChar: 2921 result_check = "C"; 2922 switch (invoke) { 2923 case kVirtual: 2924 result.C = baseEnv(env)->CallCharMethodV(env, obj, mid, vargs); 2925 break; 2926 case kDirect: 2927 result.C = baseEnv(env)->CallNonvirtualCharMethodV(env, obj, c, mid, vargs); 2928 break; 2929 case kStatic: 2930 result.C = baseEnv(env)->CallStaticCharMethodV(env, c, mid, vargs); 2931 break; 2932 default: 2933 LOG(FATAL) << "Unexpected invoke: " << invoke; 2934 } 2935 break; 2936 case Primitive::kPrimShort: 2937 result_check = "S"; 2938 switch (invoke) { 2939 case kVirtual: 2940 result.S = baseEnv(env)->CallShortMethodV(env, obj, mid, vargs); 2941 break; 2942 case kDirect: 2943 result.S = baseEnv(env)->CallNonvirtualShortMethodV(env, obj, c, mid, vargs); 2944 break; 2945 case kStatic: 2946 result.S = baseEnv(env)->CallStaticShortMethodV(env, c, mid, vargs); 2947 break; 2948 default: 2949 LOG(FATAL) << "Unexpected invoke: " << invoke; 2950 } 2951 break; 2952 case Primitive::kPrimInt: 2953 result_check = "I"; 2954 switch (invoke) { 2955 case kVirtual: 2956 result.I = baseEnv(env)->CallIntMethodV(env, obj, mid, vargs); 2957 break; 2958 case kDirect: 2959 result.I = baseEnv(env)->CallNonvirtualIntMethodV(env, obj, c, mid, vargs); 2960 break; 2961 case kStatic: 2962 result.I = baseEnv(env)->CallStaticIntMethodV(env, c, mid, vargs); 2963 break; 2964 default: 2965 LOG(FATAL) << "Unexpected invoke: " << invoke; 2966 } 2967 break; 2968 case Primitive::kPrimLong: 2969 result_check = "J"; 2970 switch (invoke) { 2971 case kVirtual: 2972 result.J = baseEnv(env)->CallLongMethodV(env, obj, mid, vargs); 2973 break; 2974 case kDirect: 2975 result.J = baseEnv(env)->CallNonvirtualLongMethodV(env, obj, c, mid, vargs); 2976 break; 2977 case kStatic: 2978 result.J = baseEnv(env)->CallStaticLongMethodV(env, c, mid, vargs); 2979 break; 2980 default: 2981 LOG(FATAL) << "Unexpected invoke: " << invoke; 2982 } 2983 break; 2984 case Primitive::kPrimFloat: 2985 result_check = "F"; 2986 switch (invoke) { 2987 case kVirtual: 2988 result.F = baseEnv(env)->CallFloatMethodV(env, obj, mid, vargs); 2989 break; 2990 case kDirect: 2991 result.F = baseEnv(env)->CallNonvirtualFloatMethodV(env, obj, c, mid, vargs); 2992 break; 2993 case kStatic: 2994 result.F = baseEnv(env)->CallStaticFloatMethodV(env, c, mid, vargs); 2995 break; 2996 default: 2997 LOG(FATAL) << "Unexpected invoke: " << invoke; 2998 } 2999 break; 3000 case Primitive::kPrimDouble: 3001 result_check = "D"; 3002 switch (invoke) { 3003 case kVirtual: 3004 result.D = baseEnv(env)->CallDoubleMethodV(env, obj, mid, vargs); 3005 break; 3006 case kDirect: 3007 result.D = baseEnv(env)->CallNonvirtualDoubleMethodV(env, obj, c, mid, vargs); 3008 break; 3009 case kStatic: 3010 result.D = baseEnv(env)->CallStaticDoubleMethodV(env, c, mid, vargs); 3011 break; 3012 default: 3013 LOG(FATAL) << "Unexpected invoke: " << invoke; 3014 } 3015 break; 3016 case Primitive::kPrimVoid: 3017 result_check = "V"; 3018 result.V = nullptr; 3019 switch (invoke) { 3020 case kVirtual: 3021 baseEnv(env)->CallVoidMethodV(env, obj, mid, vargs); 3022 break; 3023 case kDirect: 3024 baseEnv(env)->CallNonvirtualVoidMethodV(env, obj, c, mid, vargs); 3025 break; 3026 case kStatic: 3027 baseEnv(env)->CallStaticVoidMethodV(env, c, mid, vargs); 3028 break; 3029 default: 3030 LOG(FATAL) << "Unexpected invoke: " << invoke; 3031 } 3032 break; 3033 default: 3034 LOG(FATAL) << "Unexpected return type: " << type; 3035 result_check = nullptr; 3036 } 3037 if (sc.Check(soa, false, result_check, &result)) { 3038 return result; 3039 } 3040 } 3041 result.J = 0; 3042 return result; 3043 } 3044 3045 static const void* GetStringCharsInternal(const char* function_name, JNIEnv* env, jstring string, 3046 jboolean* is_copy, bool utf, bool critical) { 3047 ScopedObjectAccess soa(env); 3048 int flags = critical ? kFlag_CritGet : kFlag_CritOkay; 3049 ScopedCheck sc(flags, function_name); 3050 JniValueType args[3] = {{.E = env}, {.s = string}, {.p = is_copy}}; 3051 if (sc.Check(soa, true, "Esp", args)) { 3052 JniValueType result; 3053 if (utf) { 3054 CHECK(!critical); 3055 result.u = baseEnv(env)->GetStringUTFChars(env, string, is_copy); 3056 } else { 3057 if (critical) { 3058 result.p = baseEnv(env)->GetStringCritical(env, string, is_copy); 3059 } else { 3060 result.p = baseEnv(env)->GetStringChars(env, string, is_copy); 3061 } 3062 } 3063 // TODO: could we be smarter about not copying when local_is_copy? 3064 if (result.p != nullptr && soa.ForceCopy()) { 3065 if (utf) { 3066 size_t length_in_bytes = strlen(result.u) + 1; 3067 result.u = 3068 reinterpret_cast<const char*>(GuardedCopy::Create(result.u, length_in_bytes, false)); 3069 } else { 3070 size_t length_in_bytes = baseEnv(env)->GetStringLength(env, string) * 2; 3071 result.p = 3072 reinterpret_cast<const jchar*>(GuardedCopy::Create(result.p, length_in_bytes, false)); 3073 } 3074 if (is_copy != nullptr) { 3075 *is_copy = JNI_TRUE; 3076 } 3077 } 3078 if (sc.Check(soa, false, utf ? "u" : "p", &result)) { 3079 return utf ? result.u : result.p; 3080 } 3081 } 3082 return nullptr; 3083 } 3084 3085 static void ReleaseStringCharsInternal(const char* function_name, JNIEnv* env, jstring string, 3086 const void* chars, bool utf, bool critical) { 3087 ScopedObjectAccess soa(env); 3088 int flags = kFlag_ExcepOkay | kFlag_Release; 3089 if (critical) { 3090 flags |= kFlag_CritRelease; 3091 } 3092 ScopedCheck sc(flags, function_name); 3093 sc.CheckNonNull(chars); 3094 bool force_copy_ok = !soa.ForceCopy() || GuardedCopy::Check(function_name, chars, false); 3095 if (force_copy_ok && soa.ForceCopy()) { 3096 chars = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<void*>(chars))); 3097 } 3098 if (force_copy_ok) { 3099 JniValueType args[3] = {{.E = env}, {.s = string}, {.p = chars}}; 3100 if (sc.Check(soa, true, utf ? "Esu" : "Esp", args)) { 3101 if (utf) { 3102 CHECK(!critical); 3103 baseEnv(env)->ReleaseStringUTFChars(env, string, reinterpret_cast<const char*>(chars)); 3104 } else { 3105 if (critical) { 3106 baseEnv(env)->ReleaseStringCritical(env, string, reinterpret_cast<const jchar*>(chars)); 3107 } else { 3108 baseEnv(env)->ReleaseStringChars(env, string, reinterpret_cast<const jchar*>(chars)); 3109 } 3110 } 3111 JniValueType result; 3112 sc.Check(soa, false, "V", &result); 3113 } 3114 } 3115 } 3116 3117 static jarray NewPrimitiveArray(const char* function_name, JNIEnv* env, jsize length, 3118 Primitive::Type type) { 3119 ScopedObjectAccess soa(env); 3120 ScopedCheck sc(kFlag_Default, function_name); 3121 JniValueType args[2] = {{.E = env}, {.z = length}}; 3122 if (sc.Check(soa, true, "Ez", args)) { 3123 JniValueType result; 3124 switch (type) { 3125 case Primitive::kPrimBoolean: 3126 result.a = baseEnv(env)->NewBooleanArray(env, length); 3127 break; 3128 case Primitive::kPrimByte: 3129 result.a = baseEnv(env)->NewByteArray(env, length); 3130 break; 3131 case Primitive::kPrimChar: 3132 result.a = baseEnv(env)->NewCharArray(env, length); 3133 break; 3134 case Primitive::kPrimShort: 3135 result.a = baseEnv(env)->NewShortArray(env, length); 3136 break; 3137 case Primitive::kPrimInt: 3138 result.a = baseEnv(env)->NewIntArray(env, length); 3139 break; 3140 case Primitive::kPrimLong: 3141 result.a = baseEnv(env)->NewLongArray(env, length); 3142 break; 3143 case Primitive::kPrimFloat: 3144 result.a = baseEnv(env)->NewFloatArray(env, length); 3145 break; 3146 case Primitive::kPrimDouble: 3147 result.a = baseEnv(env)->NewDoubleArray(env, length); 3148 break; 3149 default: 3150 LOG(FATAL) << "Unexpected primitive type: " << type; 3151 } 3152 if (sc.Check(soa, false, "a", &result)) { 3153 return result.a; 3154 } 3155 } 3156 return nullptr; 3157 } 3158 3159 static void* GetPrimitiveArrayElements(const char* function_name, Primitive::Type type, 3160 JNIEnv* env, jarray array, jboolean* is_copy) { 3161 ScopedObjectAccess soa(env); 3162 ScopedCheck sc(kFlag_Default, function_name); 3163 JniValueType args[3] = {{.E = env}, {.a = array}, {.p = is_copy}}; 3164 if (sc.Check(soa, true, "Eap", args) && sc.CheckPrimitiveArrayType(soa, array, type)) { 3165 JniValueType result; 3166 switch (type) { 3167 case Primitive::kPrimBoolean: 3168 result.p = baseEnv(env)->GetBooleanArrayElements(env, down_cast<jbooleanArray>(array), 3169 is_copy); 3170 break; 3171 case Primitive::kPrimByte: 3172 result.p = baseEnv(env)->GetByteArrayElements(env, down_cast<jbyteArray>(array), 3173 is_copy); 3174 break; 3175 case Primitive::kPrimChar: 3176 result.p = baseEnv(env)->GetCharArrayElements(env, down_cast<jcharArray>(array), 3177 is_copy); 3178 break; 3179 case Primitive::kPrimShort: 3180 result.p = baseEnv(env)->GetShortArrayElements(env, down_cast<jshortArray>(array), 3181 is_copy); 3182 break; 3183 case Primitive::kPrimInt: 3184 result.p = baseEnv(env)->GetIntArrayElements(env, down_cast<jintArray>(array), is_copy); 3185 break; 3186 case Primitive::kPrimLong: 3187 result.p = baseEnv(env)->GetLongArrayElements(env, down_cast<jlongArray>(array), 3188 is_copy); 3189 break; 3190 case Primitive::kPrimFloat: 3191 result.p = baseEnv(env)->GetFloatArrayElements(env, down_cast<jfloatArray>(array), 3192 is_copy); 3193 break; 3194 case Primitive::kPrimDouble: 3195 result.p = baseEnv(env)->GetDoubleArrayElements(env, down_cast<jdoubleArray>(array), 3196 is_copy); 3197 break; 3198 default: 3199 LOG(FATAL) << "Unexpected primitive type: " << type; 3200 } 3201 if (result.p != nullptr && soa.ForceCopy()) { 3202 result.p = GuardedCopy::CreateGuardedPACopy(env, array, is_copy); 3203 if (is_copy != nullptr) { 3204 *is_copy = JNI_TRUE; 3205 } 3206 } 3207 if (sc.Check(soa, false, "p", &result)) { 3208 return const_cast<void*>(result.p); 3209 } 3210 } 3211 return nullptr; 3212 } 3213 3214 static void ReleasePrimitiveArrayElements(const char* function_name, Primitive::Type type, 3215 JNIEnv* env, jarray array, void* elems, jint mode) { 3216 ScopedObjectAccess soa(env); 3217 ScopedCheck sc(kFlag_ExcepOkay, function_name); 3218 if (sc.CheckNonNull(elems) && sc.CheckPrimitiveArrayType(soa, array, type)) { 3219 if (soa.ForceCopy()) { 3220 elems = GuardedCopy::ReleaseGuardedPACopy(function_name, env, array, elems, mode); 3221 } 3222 if (!soa.ForceCopy() || elems != nullptr) { 3223 JniValueType args[4] = {{.E = env}, {.a = array}, {.p = elems}, {.r = mode}}; 3224 if (sc.Check(soa, true, "Eapr", args)) { 3225 switch (type) { 3226 case Primitive::kPrimBoolean: 3227 baseEnv(env)->ReleaseBooleanArrayElements(env, down_cast<jbooleanArray>(array), 3228 reinterpret_cast<jboolean*>(elems), mode); 3229 break; 3230 case Primitive::kPrimByte: 3231 baseEnv(env)->ReleaseByteArrayElements(env, down_cast<jbyteArray>(array), 3232 reinterpret_cast<jbyte*>(elems), mode); 3233 break; 3234 case Primitive::kPrimChar: 3235 baseEnv(env)->ReleaseCharArrayElements(env, down_cast<jcharArray>(array), 3236 reinterpret_cast<jchar*>(elems), mode); 3237 break; 3238 case Primitive::kPrimShort: 3239 baseEnv(env)->ReleaseShortArrayElements(env, down_cast<jshortArray>(array), 3240 reinterpret_cast<jshort*>(elems), mode); 3241 break; 3242 case Primitive::kPrimInt: 3243 baseEnv(env)->ReleaseIntArrayElements(env, down_cast<jintArray>(array), 3244 reinterpret_cast<jint*>(elems), mode); 3245 break; 3246 case Primitive::kPrimLong: 3247 baseEnv(env)->ReleaseLongArrayElements(env, down_cast<jlongArray>(array), 3248 reinterpret_cast<jlong*>(elems), mode); 3249 break; 3250 case Primitive::kPrimFloat: 3251 baseEnv(env)->ReleaseFloatArrayElements(env, down_cast<jfloatArray>(array), 3252 reinterpret_cast<jfloat*>(elems), mode); 3253 break; 3254 case Primitive::kPrimDouble: 3255 baseEnv(env)->ReleaseDoubleArrayElements(env, down_cast<jdoubleArray>(array), 3256 reinterpret_cast<jdouble*>(elems), mode); 3257 break; 3258 default: 3259 LOG(FATAL) << "Unexpected primitive type: " << type; 3260 } 3261 JniValueType result; 3262 result.V = nullptr; 3263 sc.Check(soa, false, "V", &result); 3264 } 3265 } 3266 } 3267 } 3268 3269 static void GetPrimitiveArrayRegion(const char* function_name, Primitive::Type type, JNIEnv* env, 3270 jarray array, jsize start, jsize len, void* buf) { 3271 ScopedObjectAccess soa(env); 3272 ScopedCheck sc(kFlag_Default, function_name); 3273 JniValueType args[5] = {{.E = env}, {.a = array}, {.z = start}, {.z = len}, {.p = buf}}; 3274 // Note: the start and len arguments are checked as 'I' rather than 'z' as invalid indices 3275 // result in ArrayIndexOutOfBoundsExceptions in the base implementation. 3276 if (sc.Check(soa, true, "EaIIp", args) && sc.CheckPrimitiveArrayType(soa, array, type)) { 3277 switch (type) { 3278 case Primitive::kPrimBoolean: 3279 baseEnv(env)->GetBooleanArrayRegion(env, down_cast<jbooleanArray>(array), start, len, 3280 reinterpret_cast<jboolean*>(buf)); 3281 break; 3282 case Primitive::kPrimByte: 3283 baseEnv(env)->GetByteArrayRegion(env, down_cast<jbyteArray>(array), start, len, 3284 reinterpret_cast<jbyte*>(buf)); 3285 break; 3286 case Primitive::kPrimChar: 3287 baseEnv(env)->GetCharArrayRegion(env, down_cast<jcharArray>(array), start, len, 3288 reinterpret_cast<jchar*>(buf)); 3289 break; 3290 case Primitive::kPrimShort: 3291 baseEnv(env)->GetShortArrayRegion(env, down_cast<jshortArray>(array), start, len, 3292 reinterpret_cast<jshort*>(buf)); 3293 break; 3294 case Primitive::kPrimInt: 3295 baseEnv(env)->GetIntArrayRegion(env, down_cast<jintArray>(array), start, len, 3296 reinterpret_cast<jint*>(buf)); 3297 break; 3298 case Primitive::kPrimLong: 3299 baseEnv(env)->GetLongArrayRegion(env, down_cast<jlongArray>(array), start, len, 3300 reinterpret_cast<jlong*>(buf)); 3301 break; 3302 case Primitive::kPrimFloat: 3303 baseEnv(env)->GetFloatArrayRegion(env, down_cast<jfloatArray>(array), start, len, 3304 reinterpret_cast<jfloat*>(buf)); 3305 break; 3306 case Primitive::kPrimDouble: 3307 baseEnv(env)->GetDoubleArrayRegion(env, down_cast<jdoubleArray>(array), start, len, 3308 reinterpret_cast<jdouble*>(buf)); 3309 break; 3310 default: 3311 LOG(FATAL) << "Unexpected primitive type: " << type; 3312 } 3313 JniValueType result; 3314 result.V = nullptr; 3315 sc.Check(soa, false, "V", &result); 3316 } 3317 } 3318 3319 static void SetPrimitiveArrayRegion(const char* function_name, Primitive::Type type, JNIEnv* env, 3320 jarray array, jsize start, jsize len, const void* buf) { 3321 ScopedObjectAccess soa(env); 3322 ScopedCheck sc(kFlag_Default, function_name); 3323 JniValueType args[5] = {{.E = env}, {.a = array}, {.z = start}, {.z = len}, {.p = buf}}; 3324 // Note: the start and len arguments are checked as 'I' rather than 'z' as invalid indices 3325 // result in ArrayIndexOutOfBoundsExceptions in the base implementation. 3326 if (sc.Check(soa, true, "EaIIp", args) && sc.CheckPrimitiveArrayType(soa, array, type)) { 3327 switch (type) { 3328 case Primitive::kPrimBoolean: 3329 baseEnv(env)->SetBooleanArrayRegion(env, down_cast<jbooleanArray>(array), start, len, 3330 reinterpret_cast<const jboolean*>(buf)); 3331 break; 3332 case Primitive::kPrimByte: 3333 baseEnv(env)->SetByteArrayRegion(env, down_cast<jbyteArray>(array), start, len, 3334 reinterpret_cast<const jbyte*>(buf)); 3335 break; 3336 case Primitive::kPrimChar: 3337 baseEnv(env)->SetCharArrayRegion(env, down_cast<jcharArray>(array), start, len, 3338 reinterpret_cast<const jchar*>(buf)); 3339 break; 3340 case Primitive::kPrimShort: 3341 baseEnv(env)->SetShortArrayRegion(env, down_cast<jshortArray>(array), start, len, 3342 reinterpret_cast<const jshort*>(buf)); 3343 break; 3344 case Primitive::kPrimInt: 3345 baseEnv(env)->SetIntArrayRegion(env, down_cast<jintArray>(array), start, len, 3346 reinterpret_cast<const jint*>(buf)); 3347 break; 3348 case Primitive::kPrimLong: 3349 baseEnv(env)->SetLongArrayRegion(env, down_cast<jlongArray>(array), start, len, 3350 reinterpret_cast<const jlong*>(buf)); 3351 break; 3352 case Primitive::kPrimFloat: 3353 baseEnv(env)->SetFloatArrayRegion(env, down_cast<jfloatArray>(array), start, len, 3354 reinterpret_cast<const jfloat*>(buf)); 3355 break; 3356 case Primitive::kPrimDouble: 3357 baseEnv(env)->SetDoubleArrayRegion(env, down_cast<jdoubleArray>(array), start, len, 3358 reinterpret_cast<const jdouble*>(buf)); 3359 break; 3360 default: 3361 LOG(FATAL) << "Unexpected primitive type: " << type; 3362 } 3363 JniValueType result; 3364 result.V = nullptr; 3365 sc.Check(soa, false, "V", &result); 3366 } 3367 } 3368}; 3369 3370const JNINativeInterface gCheckNativeInterface = { 3371 nullptr, // reserved0. 3372 nullptr, // reserved1. 3373 nullptr, // reserved2. 3374 nullptr, // reserved3. 3375 CheckJNI::GetVersion, 3376 CheckJNI::DefineClass, 3377 CheckJNI::FindClass, 3378 CheckJNI::FromReflectedMethod, 3379 CheckJNI::FromReflectedField, 3380 CheckJNI::ToReflectedMethod, 3381 CheckJNI::GetSuperclass, 3382 CheckJNI::IsAssignableFrom, 3383 CheckJNI::ToReflectedField, 3384 CheckJNI::Throw, 3385 CheckJNI::ThrowNew, 3386 CheckJNI::ExceptionOccurred, 3387 CheckJNI::ExceptionDescribe, 3388 CheckJNI::ExceptionClear, 3389 CheckJNI::FatalError, 3390 CheckJNI::PushLocalFrame, 3391 CheckJNI::PopLocalFrame, 3392 CheckJNI::NewGlobalRef, 3393 CheckJNI::DeleteGlobalRef, 3394 CheckJNI::DeleteLocalRef, 3395 CheckJNI::IsSameObject, 3396 CheckJNI::NewLocalRef, 3397 CheckJNI::EnsureLocalCapacity, 3398 CheckJNI::AllocObject, 3399 CheckJNI::NewObject, 3400 CheckJNI::NewObjectV, 3401 CheckJNI::NewObjectA, 3402 CheckJNI::GetObjectClass, 3403 CheckJNI::IsInstanceOf, 3404 CheckJNI::GetMethodID, 3405 CheckJNI::CallObjectMethod, 3406 CheckJNI::CallObjectMethodV, 3407 CheckJNI::CallObjectMethodA, 3408 CheckJNI::CallBooleanMethod, 3409 CheckJNI::CallBooleanMethodV, 3410 CheckJNI::CallBooleanMethodA, 3411 CheckJNI::CallByteMethod, 3412 CheckJNI::CallByteMethodV, 3413 CheckJNI::CallByteMethodA, 3414 CheckJNI::CallCharMethod, 3415 CheckJNI::CallCharMethodV, 3416 CheckJNI::CallCharMethodA, 3417 CheckJNI::CallShortMethod, 3418 CheckJNI::CallShortMethodV, 3419 CheckJNI::CallShortMethodA, 3420 CheckJNI::CallIntMethod, 3421 CheckJNI::CallIntMethodV, 3422 CheckJNI::CallIntMethodA, 3423 CheckJNI::CallLongMethod, 3424 CheckJNI::CallLongMethodV, 3425 CheckJNI::CallLongMethodA, 3426 CheckJNI::CallFloatMethod, 3427 CheckJNI::CallFloatMethodV, 3428 CheckJNI::CallFloatMethodA, 3429 CheckJNI::CallDoubleMethod, 3430 CheckJNI::CallDoubleMethodV, 3431 CheckJNI::CallDoubleMethodA, 3432 CheckJNI::CallVoidMethod, 3433 CheckJNI::CallVoidMethodV, 3434 CheckJNI::CallVoidMethodA, 3435 CheckJNI::CallNonvirtualObjectMethod, 3436 CheckJNI::CallNonvirtualObjectMethodV, 3437 CheckJNI::CallNonvirtualObjectMethodA, 3438 CheckJNI::CallNonvirtualBooleanMethod, 3439 CheckJNI::CallNonvirtualBooleanMethodV, 3440 CheckJNI::CallNonvirtualBooleanMethodA, 3441 CheckJNI::CallNonvirtualByteMethod, 3442 CheckJNI::CallNonvirtualByteMethodV, 3443 CheckJNI::CallNonvirtualByteMethodA, 3444 CheckJNI::CallNonvirtualCharMethod, 3445 CheckJNI::CallNonvirtualCharMethodV, 3446 CheckJNI::CallNonvirtualCharMethodA, 3447 CheckJNI::CallNonvirtualShortMethod, 3448 CheckJNI::CallNonvirtualShortMethodV, 3449 CheckJNI::CallNonvirtualShortMethodA, 3450 CheckJNI::CallNonvirtualIntMethod, 3451 CheckJNI::CallNonvirtualIntMethodV, 3452 CheckJNI::CallNonvirtualIntMethodA, 3453 CheckJNI::CallNonvirtualLongMethod, 3454 CheckJNI::CallNonvirtualLongMethodV, 3455 CheckJNI::CallNonvirtualLongMethodA, 3456 CheckJNI::CallNonvirtualFloatMethod, 3457 CheckJNI::CallNonvirtualFloatMethodV, 3458 CheckJNI::CallNonvirtualFloatMethodA, 3459 CheckJNI::CallNonvirtualDoubleMethod, 3460 CheckJNI::CallNonvirtualDoubleMethodV, 3461 CheckJNI::CallNonvirtualDoubleMethodA, 3462 CheckJNI::CallNonvirtualVoidMethod, 3463 CheckJNI::CallNonvirtualVoidMethodV, 3464 CheckJNI::CallNonvirtualVoidMethodA, 3465 CheckJNI::GetFieldID, 3466 CheckJNI::GetObjectField, 3467 CheckJNI::GetBooleanField, 3468 CheckJNI::GetByteField, 3469 CheckJNI::GetCharField, 3470 CheckJNI::GetShortField, 3471 CheckJNI::GetIntField, 3472 CheckJNI::GetLongField, 3473 CheckJNI::GetFloatField, 3474 CheckJNI::GetDoubleField, 3475 CheckJNI::SetObjectField, 3476 CheckJNI::SetBooleanField, 3477 CheckJNI::SetByteField, 3478 CheckJNI::SetCharField, 3479 CheckJNI::SetShortField, 3480 CheckJNI::SetIntField, 3481 CheckJNI::SetLongField, 3482 CheckJNI::SetFloatField, 3483 CheckJNI::SetDoubleField, 3484 CheckJNI::GetStaticMethodID, 3485 CheckJNI::CallStaticObjectMethod, 3486 CheckJNI::CallStaticObjectMethodV, 3487 CheckJNI::CallStaticObjectMethodA, 3488 CheckJNI::CallStaticBooleanMethod, 3489 CheckJNI::CallStaticBooleanMethodV, 3490 CheckJNI::CallStaticBooleanMethodA, 3491 CheckJNI::CallStaticByteMethod, 3492 CheckJNI::CallStaticByteMethodV, 3493 CheckJNI::CallStaticByteMethodA, 3494 CheckJNI::CallStaticCharMethod, 3495 CheckJNI::CallStaticCharMethodV, 3496 CheckJNI::CallStaticCharMethodA, 3497 CheckJNI::CallStaticShortMethod, 3498 CheckJNI::CallStaticShortMethodV, 3499 CheckJNI::CallStaticShortMethodA, 3500 CheckJNI::CallStaticIntMethod, 3501 CheckJNI::CallStaticIntMethodV, 3502 CheckJNI::CallStaticIntMethodA, 3503 CheckJNI::CallStaticLongMethod, 3504 CheckJNI::CallStaticLongMethodV, 3505 CheckJNI::CallStaticLongMethodA, 3506 CheckJNI::CallStaticFloatMethod, 3507 CheckJNI::CallStaticFloatMethodV, 3508 CheckJNI::CallStaticFloatMethodA, 3509 CheckJNI::CallStaticDoubleMethod, 3510 CheckJNI::CallStaticDoubleMethodV, 3511 CheckJNI::CallStaticDoubleMethodA, 3512 CheckJNI::CallStaticVoidMethod, 3513 CheckJNI::CallStaticVoidMethodV, 3514 CheckJNI::CallStaticVoidMethodA, 3515 CheckJNI::GetStaticFieldID, 3516 CheckJNI::GetStaticObjectField, 3517 CheckJNI::GetStaticBooleanField, 3518 CheckJNI::GetStaticByteField, 3519 CheckJNI::GetStaticCharField, 3520 CheckJNI::GetStaticShortField, 3521 CheckJNI::GetStaticIntField, 3522 CheckJNI::GetStaticLongField, 3523 CheckJNI::GetStaticFloatField, 3524 CheckJNI::GetStaticDoubleField, 3525 CheckJNI::SetStaticObjectField, 3526 CheckJNI::SetStaticBooleanField, 3527 CheckJNI::SetStaticByteField, 3528 CheckJNI::SetStaticCharField, 3529 CheckJNI::SetStaticShortField, 3530 CheckJNI::SetStaticIntField, 3531 CheckJNI::SetStaticLongField, 3532 CheckJNI::SetStaticFloatField, 3533 CheckJNI::SetStaticDoubleField, 3534 CheckJNI::NewString, 3535 CheckJNI::GetStringLength, 3536 CheckJNI::GetStringChars, 3537 CheckJNI::ReleaseStringChars, 3538 CheckJNI::NewStringUTF, 3539 CheckJNI::GetStringUTFLength, 3540 CheckJNI::GetStringUTFChars, 3541 CheckJNI::ReleaseStringUTFChars, 3542 CheckJNI::GetArrayLength, 3543 CheckJNI::NewObjectArray, 3544 CheckJNI::GetObjectArrayElement, 3545 CheckJNI::SetObjectArrayElement, 3546 CheckJNI::NewBooleanArray, 3547 CheckJNI::NewByteArray, 3548 CheckJNI::NewCharArray, 3549 CheckJNI::NewShortArray, 3550 CheckJNI::NewIntArray, 3551 CheckJNI::NewLongArray, 3552 CheckJNI::NewFloatArray, 3553 CheckJNI::NewDoubleArray, 3554 CheckJNI::GetBooleanArrayElements, 3555 CheckJNI::GetByteArrayElements, 3556 CheckJNI::GetCharArrayElements, 3557 CheckJNI::GetShortArrayElements, 3558 CheckJNI::GetIntArrayElements, 3559 CheckJNI::GetLongArrayElements, 3560 CheckJNI::GetFloatArrayElements, 3561 CheckJNI::GetDoubleArrayElements, 3562 CheckJNI::ReleaseBooleanArrayElements, 3563 CheckJNI::ReleaseByteArrayElements, 3564 CheckJNI::ReleaseCharArrayElements, 3565 CheckJNI::ReleaseShortArrayElements, 3566 CheckJNI::ReleaseIntArrayElements, 3567 CheckJNI::ReleaseLongArrayElements, 3568 CheckJNI::ReleaseFloatArrayElements, 3569 CheckJNI::ReleaseDoubleArrayElements, 3570 CheckJNI::GetBooleanArrayRegion, 3571 CheckJNI::GetByteArrayRegion, 3572 CheckJNI::GetCharArrayRegion, 3573 CheckJNI::GetShortArrayRegion, 3574 CheckJNI::GetIntArrayRegion, 3575 CheckJNI::GetLongArrayRegion, 3576 CheckJNI::GetFloatArrayRegion, 3577 CheckJNI::GetDoubleArrayRegion, 3578 CheckJNI::SetBooleanArrayRegion, 3579 CheckJNI::SetByteArrayRegion, 3580 CheckJNI::SetCharArrayRegion, 3581 CheckJNI::SetShortArrayRegion, 3582 CheckJNI::SetIntArrayRegion, 3583 CheckJNI::SetLongArrayRegion, 3584 CheckJNI::SetFloatArrayRegion, 3585 CheckJNI::SetDoubleArrayRegion, 3586 CheckJNI::RegisterNatives, 3587 CheckJNI::UnregisterNatives, 3588 CheckJNI::MonitorEnter, 3589 CheckJNI::MonitorExit, 3590 CheckJNI::GetJavaVM, 3591 CheckJNI::GetStringRegion, 3592 CheckJNI::GetStringUTFRegion, 3593 CheckJNI::GetPrimitiveArrayCritical, 3594 CheckJNI::ReleasePrimitiveArrayCritical, 3595 CheckJNI::GetStringCritical, 3596 CheckJNI::ReleaseStringCritical, 3597 CheckJNI::NewWeakGlobalRef, 3598 CheckJNI::DeleteWeakGlobalRef, 3599 CheckJNI::ExceptionCheck, 3600 CheckJNI::NewDirectByteBuffer, 3601 CheckJNI::GetDirectBufferAddress, 3602 CheckJNI::GetDirectBufferCapacity, 3603 CheckJNI::GetObjectRefType, 3604}; 3605 3606const JNINativeInterface* GetCheckJniNativeInterface() { 3607 return &gCheckNativeInterface; 3608} 3609 3610class CheckJII { 3611 public: 3612 static jint DestroyJavaVM(JavaVM* vm) { 3613 ScopedCheck sc(kFlag_Invocation, __FUNCTION__, false); 3614 JniValueType args[1] = {{.v = vm}}; 3615 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), true, "v", args); 3616 JniValueType result; 3617 result.i = BaseVm(vm)->DestroyJavaVM(vm); 3618 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), false, "i", &result); 3619 return result.i; 3620 } 3621 3622 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 3623 ScopedCheck sc(kFlag_Invocation, __FUNCTION__); 3624 JniValueType args[3] = {{.v = vm}, {.p = p_env}, {.p = thr_args}}; 3625 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), true, "vpp", args); 3626 JniValueType result; 3627 result.i = BaseVm(vm)->AttachCurrentThread(vm, p_env, thr_args); 3628 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), false, "i", &result); 3629 return result.i; 3630 } 3631 3632 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 3633 ScopedCheck sc(kFlag_Invocation, __FUNCTION__); 3634 JniValueType args[3] = {{.v = vm}, {.p = p_env}, {.p = thr_args}}; 3635 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), true, "vpp", args); 3636 JniValueType result; 3637 result.i = BaseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args); 3638 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), false, "i", &result); 3639 return result.i; 3640 } 3641 3642 static jint DetachCurrentThread(JavaVM* vm) { 3643 ScopedCheck sc(kFlag_Invocation, __FUNCTION__); 3644 JniValueType args[1] = {{.v = vm}}; 3645 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), true, "v", args); 3646 JniValueType result; 3647 result.i = BaseVm(vm)->DetachCurrentThread(vm); 3648 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), false, "i", &result); 3649 return result.i; 3650 } 3651 3652 static jint GetEnv(JavaVM* vm, void** p_env, jint version) { 3653 ScopedCheck sc(kFlag_Invocation, __FUNCTION__); 3654 JniValueType args[3] = {{.v = vm}, {.p = p_env}, {.I = version}}; 3655 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), true, "vpI", args); 3656 JniValueType result; 3657 result.i = BaseVm(vm)->GetEnv(vm, p_env, version); 3658 sc.CheckNonHeap(reinterpret_cast<JavaVMExt*>(vm), false, "i", &result); 3659 return result.i; 3660 } 3661 3662 private: 3663 static const JNIInvokeInterface* BaseVm(JavaVM* vm) { 3664 return reinterpret_cast<JavaVMExt*>(vm)->GetUncheckedFunctions(); 3665 } 3666}; 3667 3668const JNIInvokeInterface gCheckInvokeInterface = { 3669 nullptr, // reserved0 3670 nullptr, // reserved1 3671 nullptr, // reserved2 3672 CheckJII::DestroyJavaVM, 3673 CheckJII::AttachCurrentThread, 3674 CheckJII::DetachCurrentThread, 3675 CheckJII::GetEnv, 3676 CheckJII::AttachCurrentThreadAsDaemon 3677}; 3678 3679const JNIInvokeInterface* GetCheckJniInvokeInterface() { 3680 return &gCheckInvokeInterface; 3681} 3682 3683} // namespace art 3684