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