1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "reflection-inl.h" 18 19 #include "art_field-inl.h" 20 #include "art_method-inl.h" 21 #include "base/enums.h" 22 #include "class_linker.h" 23 #include "common_throws.h" 24 #include "dex/dex_file-inl.h" 25 #include "indirect_reference_table-inl.h" 26 #include "jni/java_vm_ext.h" 27 #include "jni/jni_internal.h" 28 #include "jvalue-inl.h" 29 #include "mirror/class-inl.h" 30 #include "mirror/executable.h" 31 #include "mirror/object_array-inl.h" 32 #include "nativehelper/scoped_local_ref.h" 33 #include "nth_caller_visitor.h" 34 #include "scoped_thread_state_change-inl.h" 35 #include "stack_reference.h" 36 #include "thread-inl.h" 37 #include "well_known_classes.h" 38 39 namespace art { 40 namespace { 41 42 using android::base::StringPrintf; 43 44 class ArgArray { 45 public: 46 ArgArray(const char* shorty, uint32_t shorty_len) 47 : shorty_(shorty), shorty_len_(shorty_len), num_bytes_(0) { 48 size_t num_slots = shorty_len + 1; // +1 in case of receiver. 49 if (LIKELY((num_slots * 2) < kSmallArgArraySize)) { 50 // We can trivially use the small arg array. 51 arg_array_ = small_arg_array_; 52 } else { 53 // Analyze shorty to see if we need the large arg array. 54 for (size_t i = 1; i < shorty_len; ++i) { 55 char c = shorty[i]; 56 if (c == 'J' || c == 'D') { 57 num_slots++; 58 } 59 } 60 if (num_slots <= kSmallArgArraySize) { 61 arg_array_ = small_arg_array_; 62 } else { 63 large_arg_array_.reset(new uint32_t[num_slots]); 64 arg_array_ = large_arg_array_.get(); 65 } 66 } 67 } 68 69 uint32_t* GetArray() { 70 return arg_array_; 71 } 72 73 uint32_t GetNumBytes() { 74 return num_bytes_; 75 } 76 77 void Append(uint32_t value) { 78 arg_array_[num_bytes_ / 4] = value; 79 num_bytes_ += 4; 80 } 81 82 void Append(ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_) { 83 Append(StackReference<mirror::Object>::FromMirrorPtr(obj.Ptr()).AsVRegValue()); 84 } 85 86 void AppendWide(uint64_t value) { 87 arg_array_[num_bytes_ / 4] = value; 88 arg_array_[(num_bytes_ / 4) + 1] = value >> 32; 89 num_bytes_ += 8; 90 } 91 92 void AppendFloat(float value) { 93 jvalue jv; 94 jv.f = value; 95 Append(jv.i); 96 } 97 98 void AppendDouble(double value) { 99 jvalue jv; 100 jv.d = value; 101 AppendWide(jv.j); 102 } 103 104 void BuildArgArrayFromVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 105 ObjPtr<mirror::Object> receiver, 106 va_list ap) 107 REQUIRES_SHARED(Locks::mutator_lock_) { 108 // Set receiver if non-null (method is not static) 109 if (receiver != nullptr) { 110 Append(receiver); 111 } 112 for (size_t i = 1; i < shorty_len_; ++i) { 113 switch (shorty_[i]) { 114 case 'Z': 115 case 'B': 116 case 'C': 117 case 'S': 118 case 'I': 119 Append(va_arg(ap, jint)); 120 break; 121 case 'F': 122 AppendFloat(va_arg(ap, jdouble)); 123 break; 124 case 'L': 125 Append(soa.Decode<mirror::Object>(va_arg(ap, jobject))); 126 break; 127 case 'D': 128 AppendDouble(va_arg(ap, jdouble)); 129 break; 130 case 'J': 131 AppendWide(va_arg(ap, jlong)); 132 break; 133 #ifndef NDEBUG 134 default: 135 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 136 #endif 137 } 138 } 139 } 140 141 void BuildArgArrayFromJValues(const ScopedObjectAccessAlreadyRunnable& soa, 142 ObjPtr<mirror::Object> receiver, const jvalue* args) 143 REQUIRES_SHARED(Locks::mutator_lock_) { 144 // Set receiver if non-null (method is not static) 145 if (receiver != nullptr) { 146 Append(receiver); 147 } 148 for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 149 switch (shorty_[i]) { 150 case 'Z': 151 Append(args[args_offset].z); 152 break; 153 case 'B': 154 Append(args[args_offset].b); 155 break; 156 case 'C': 157 Append(args[args_offset].c); 158 break; 159 case 'S': 160 Append(args[args_offset].s); 161 break; 162 case 'I': 163 FALLTHROUGH_INTENDED; 164 case 'F': 165 Append(args[args_offset].i); 166 break; 167 case 'L': 168 Append(soa.Decode<mirror::Object>(args[args_offset].l)); 169 break; 170 case 'D': 171 FALLTHROUGH_INTENDED; 172 case 'J': 173 AppendWide(args[args_offset].j); 174 break; 175 #ifndef NDEBUG 176 default: 177 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 178 #endif 179 } 180 } 181 } 182 183 void BuildArgArrayFromFrame(ShadowFrame* shadow_frame, uint32_t arg_offset) 184 REQUIRES_SHARED(Locks::mutator_lock_) { 185 // Set receiver if non-null (method is not static) 186 size_t cur_arg = arg_offset; 187 if (!shadow_frame->GetMethod()->IsStatic()) { 188 Append(shadow_frame->GetVReg(cur_arg)); 189 cur_arg++; 190 } 191 for (size_t i = 1; i < shorty_len_; ++i) { 192 switch (shorty_[i]) { 193 case 'Z': 194 case 'B': 195 case 'C': 196 case 'S': 197 case 'I': 198 case 'F': 199 case 'L': 200 Append(shadow_frame->GetVReg(cur_arg)); 201 cur_arg++; 202 break; 203 case 'D': 204 case 'J': 205 AppendWide(shadow_frame->GetVRegLong(cur_arg)); 206 cur_arg++; 207 cur_arg++; 208 break; 209 #ifndef NDEBUG 210 default: 211 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 212 #endif 213 } 214 } 215 } 216 217 static void ThrowIllegalPrimitiveArgumentException(const char* expected, 218 const char* found_descriptor) 219 REQUIRES_SHARED(Locks::mutator_lock_) { 220 ThrowIllegalArgumentException( 221 StringPrintf("Invalid primitive conversion from %s to %s", expected, 222 PrettyDescriptor(found_descriptor).c_str()).c_str()); 223 } 224 225 bool BuildArgArrayFromObjectArray(ObjPtr<mirror::Object> receiver, 226 ObjPtr<mirror::ObjectArray<mirror::Object>> raw_args, 227 ArtMethod* m, 228 Thread* self) 229 REQUIRES_SHARED(Locks::mutator_lock_) { 230 const dex::TypeList* classes = m->GetParameterTypeList(); 231 // Set receiver if non-null (method is not static) 232 if (receiver != nullptr) { 233 Append(receiver); 234 } 235 StackHandleScope<2> hs(self); 236 MutableHandle<mirror::Object> arg(hs.NewHandle<mirror::Object>(nullptr)); 237 Handle<mirror::ObjectArray<mirror::Object>> args( 238 hs.NewHandle<mirror::ObjectArray<mirror::Object>>(raw_args)); 239 for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 240 arg.Assign(args->Get(args_offset)); 241 if (((shorty_[i] == 'L') && (arg != nullptr)) || 242 ((arg == nullptr && shorty_[i] != 'L'))) { 243 // TODO: The method's parameter's type must have been previously resolved, yet 244 // we've seen cases where it's not b/34440020. 245 ObjPtr<mirror::Class> dst_class( 246 m->ResolveClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_)); 247 if (dst_class == nullptr) { 248 CHECK(self->IsExceptionPending()); 249 return false; 250 } 251 if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) { 252 ThrowIllegalArgumentException( 253 StringPrintf("method %s argument %zd has type %s, got %s", 254 m->PrettyMethod(false).c_str(), 255 args_offset + 1, // Humans don't count from 0. 256 mirror::Class::PrettyDescriptor(dst_class).c_str(), 257 mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str()); 258 return false; 259 } 260 } 261 262 #define DO_FIRST_ARG(match_descriptor, get_fn, append) { \ 263 if (LIKELY(arg != nullptr && \ 264 arg->GetClass()->DescriptorEquals(match_descriptor))) { \ 265 ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 266 append(primitive_field-> get_fn(arg.Get())); 267 268 #define DO_ARG(match_descriptor, get_fn, append) \ 269 } else if (LIKELY(arg != nullptr && \ 270 arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ 271 ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 272 append(primitive_field-> get_fn(arg.Get())); 273 274 #define DO_FAIL(expected) \ 275 } else { \ 276 if (arg->GetClass<>()->IsPrimitive()) { \ 277 std::string temp; \ 278 ThrowIllegalPrimitiveArgumentException(expected, \ 279 arg->GetClass<>()->GetDescriptor(&temp)); \ 280 } else { \ 281 ThrowIllegalArgumentException(\ 282 StringPrintf("method %s argument %zd has type %s, got %s", \ 283 ArtMethod::PrettyMethod(m, false).c_str(), \ 284 args_offset + 1, \ 285 expected, \ 286 mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str()); \ 287 } \ 288 return false; \ 289 } } 290 291 switch (shorty_[i]) { 292 case 'L': 293 Append(arg.Get()); 294 break; 295 case 'Z': 296 DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append) 297 DO_FAIL("boolean") 298 break; 299 case 'B': 300 DO_FIRST_ARG("Ljava/lang/Byte;", GetByte, Append) 301 DO_FAIL("byte") 302 break; 303 case 'C': 304 DO_FIRST_ARG("Ljava/lang/Character;", GetChar, Append) 305 DO_FAIL("char") 306 break; 307 case 'S': 308 DO_FIRST_ARG("Ljava/lang/Short;", GetShort, Append) 309 DO_ARG("Ljava/lang/Byte;", GetByte, Append) 310 DO_FAIL("short") 311 break; 312 case 'I': 313 DO_FIRST_ARG("Ljava/lang/Integer;", GetInt, Append) 314 DO_ARG("Ljava/lang/Character;", GetChar, Append) 315 DO_ARG("Ljava/lang/Short;", GetShort, Append) 316 DO_ARG("Ljava/lang/Byte;", GetByte, Append) 317 DO_FAIL("int") 318 break; 319 case 'J': 320 DO_FIRST_ARG("Ljava/lang/Long;", GetLong, AppendWide) 321 DO_ARG("Ljava/lang/Integer;", GetInt, AppendWide) 322 DO_ARG("Ljava/lang/Character;", GetChar, AppendWide) 323 DO_ARG("Ljava/lang/Short;", GetShort, AppendWide) 324 DO_ARG("Ljava/lang/Byte;", GetByte, AppendWide) 325 DO_FAIL("long") 326 break; 327 case 'F': 328 DO_FIRST_ARG("Ljava/lang/Float;", GetFloat, AppendFloat) 329 DO_ARG("Ljava/lang/Long;", GetLong, AppendFloat) 330 DO_ARG("Ljava/lang/Integer;", GetInt, AppendFloat) 331 DO_ARG("Ljava/lang/Character;", GetChar, AppendFloat) 332 DO_ARG("Ljava/lang/Short;", GetShort, AppendFloat) 333 DO_ARG("Ljava/lang/Byte;", GetByte, AppendFloat) 334 DO_FAIL("float") 335 break; 336 case 'D': 337 DO_FIRST_ARG("Ljava/lang/Double;", GetDouble, AppendDouble) 338 DO_ARG("Ljava/lang/Float;", GetFloat, AppendDouble) 339 DO_ARG("Ljava/lang/Long;", GetLong, AppendDouble) 340 DO_ARG("Ljava/lang/Integer;", GetInt, AppendDouble) 341 DO_ARG("Ljava/lang/Character;", GetChar, AppendDouble) 342 DO_ARG("Ljava/lang/Short;", GetShort, AppendDouble) 343 DO_ARG("Ljava/lang/Byte;", GetByte, AppendDouble) 344 DO_FAIL("double") 345 break; 346 #ifndef NDEBUG 347 default: 348 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 349 UNREACHABLE(); 350 #endif 351 } 352 #undef DO_FIRST_ARG 353 #undef DO_ARG 354 #undef DO_FAIL 355 } 356 return true; 357 } 358 359 private: 360 enum { kSmallArgArraySize = 16 }; 361 const char* const shorty_; 362 const uint32_t shorty_len_; 363 uint32_t num_bytes_; 364 uint32_t* arg_array_; 365 uint32_t small_arg_array_[kSmallArgArraySize]; 366 std::unique_ptr<uint32_t[]> large_arg_array_; 367 }; 368 369 void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args) 370 REQUIRES_SHARED(Locks::mutator_lock_) { 371 const dex::TypeList* params = m->GetParameterTypeList(); 372 if (params == nullptr) { 373 return; // No arguments so nothing to check. 374 } 375 uint32_t offset = 0; 376 uint32_t num_params = params->Size(); 377 size_t error_count = 0; 378 if (!m->IsStatic()) { 379 offset = 1; 380 } 381 // TODO: If args contain object references, it may cause problems. 382 Thread* const self = Thread::Current(); 383 for (uint32_t i = 0; i < num_params; i++) { 384 dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_; 385 ObjPtr<mirror::Class> param_type(m->ResolveClassFromTypeIndex(type_idx)); 386 if (param_type == nullptr) { 387 CHECK(self->IsExceptionPending()); 388 LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " 389 << m->GetTypeDescriptorFromTypeIdx(type_idx) << "\n" 390 << self->GetException()->Dump(); 391 self->ClearException(); 392 ++error_count; 393 } else if (!param_type->IsPrimitive()) { 394 // TODO: There is a compaction bug here since GetClassFromTypeIdx can cause thread suspension, 395 // this is a hard to fix problem since the args can contain Object*, we need to save and 396 // restore them by using a visitor similar to the ones used in the trampoline entrypoints. 397 ObjPtr<mirror::Object> argument = 398 (reinterpret_cast<StackReference<mirror::Object>*>(&args[i + offset]))->AsMirrorPtr(); 399 if (argument != nullptr && !argument->InstanceOf(param_type)) { 400 LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of " 401 << argument->PrettyTypeOf() << " as argument " << (i + 1) 402 << " to " << m->PrettyMethod(); 403 ++error_count; 404 } 405 } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) { 406 offset++; 407 } else { 408 int32_t arg = static_cast<int32_t>(args[i + offset]); 409 if (param_type->IsPrimitiveBoolean()) { 410 if (arg != JNI_TRUE && arg != JNI_FALSE) { 411 LOG(ERROR) << "JNI ERROR (app bug): expected jboolean (0/1) but got value of " 412 << arg << " as argument " << (i + 1) << " to " << m->PrettyMethod(); 413 ++error_count; 414 } 415 } else if (param_type->IsPrimitiveByte()) { 416 if (arg < -128 || arg > 127) { 417 LOG(ERROR) << "JNI ERROR (app bug): expected jbyte but got value of " 418 << arg << " as argument " << (i + 1) << " to " << m->PrettyMethod(); 419 ++error_count; 420 } 421 } else if (param_type->IsPrimitiveChar()) { 422 if (args[i + offset] > 0xFFFF) { 423 LOG(ERROR) << "JNI ERROR (app bug): expected jchar but got value of " 424 << arg << " as argument " << (i + 1) << " to " << m->PrettyMethod(); 425 ++error_count; 426 } 427 } else if (param_type->IsPrimitiveShort()) { 428 if (arg < -32768 || arg > 0x7FFF) { 429 LOG(ERROR) << "JNI ERROR (app bug): expected jshort but got value of " 430 << arg << " as argument " << (i + 1) << " to " << m->PrettyMethod(); 431 ++error_count; 432 } 433 } 434 } 435 } 436 if (UNLIKELY(error_count > 0)) { 437 // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort 438 // with an argument. 439 vm->JniAbortF(nullptr, "bad arguments passed to %s (see above for details)", 440 m->PrettyMethod().c_str()); 441 } 442 } 443 444 ArtMethod* FindVirtualMethod(ObjPtr<mirror::Object> receiver, ArtMethod* method) 445 REQUIRES_SHARED(Locks::mutator_lock_) { 446 return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method, kRuntimePointerSize); 447 } 448 449 450 void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa, 451 ArtMethod* method, ArgArray* arg_array, JValue* result, 452 const char* shorty) 453 REQUIRES_SHARED(Locks::mutator_lock_) { 454 uint32_t* args = arg_array->GetArray(); 455 if (UNLIKELY(soa.Env()->IsCheckJniEnabled())) { 456 CheckMethodArguments(soa.Vm(), method->GetInterfaceMethodIfProxy(kRuntimePointerSize), args); 457 } 458 method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty); 459 } 460 461 ALWAYS_INLINE 462 bool CheckArgsForInvokeMethod(ArtMethod* np_method, 463 ObjPtr<mirror::ObjectArray<mirror::Object>> objects) 464 REQUIRES_SHARED(Locks::mutator_lock_) { 465 const dex::TypeList* classes = np_method->GetParameterTypeList(); 466 uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size(); 467 uint32_t arg_count = (objects == nullptr) ? 0 : objects->GetLength(); 468 if (UNLIKELY(arg_count != classes_size)) { 469 ThrowIllegalArgumentException(StringPrintf("Wrong number of arguments; expected %d, got %d", 470 classes_size, arg_count).c_str()); 471 return false; 472 } 473 return true; 474 } 475 476 ALWAYS_INLINE 477 bool InvokeMethodImpl(const ScopedObjectAccessAlreadyRunnable& soa, 478 ArtMethod* m, 479 ArtMethod* np_method, 480 ObjPtr<mirror::Object> receiver, 481 ObjPtr<mirror::ObjectArray<mirror::Object>> objects, 482 const char** shorty, 483 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { 484 // Invoke the method. 485 uint32_t shorty_len = 0; 486 *shorty = np_method->GetShorty(&shorty_len); 487 ArgArray arg_array(*shorty, shorty_len); 488 if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method, soa.Self())) { 489 CHECK(soa.Self()->IsExceptionPending()); 490 return false; 491 } 492 493 InvokeWithArgArray(soa, m, &arg_array, result, *shorty); 494 495 // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early. 496 if (soa.Self()->IsExceptionPending()) { 497 // If we get another exception when we are trying to wrap, then just use that instead. 498 ScopedLocalRef<jthrowable> th(soa.Env(), soa.Env()->ExceptionOccurred()); 499 soa.Self()->ClearException(); 500 jclass exception_class = soa.Env()->FindClass("java/lang/reflect/InvocationTargetException"); 501 if (exception_class == nullptr) { 502 soa.Self()->AssertPendingException(); 503 return false; 504 } 505 jmethodID mid = soa.Env()->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V"); 506 CHECK(mid != nullptr); 507 jobject exception_instance = soa.Env()->NewObject(exception_class, mid, th.get()); 508 if (exception_instance == nullptr) { 509 soa.Self()->AssertPendingException(); 510 return false; 511 } 512 soa.Env()->Throw(reinterpret_cast<jthrowable>(exception_instance)); 513 return false; 514 } 515 516 return true; 517 } 518 519 } // anonymous namespace 520 521 JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid, 522 va_list args) 523 REQUIRES_SHARED(Locks::mutator_lock_) { 524 // We want to make sure that the stack is not within a small distance from the 525 // protected region in case we are calling into a leaf function whose stack 526 // check has been elided. 527 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 528 ThrowStackOverflowError(soa.Self()); 529 return JValue(); 530 } 531 532 ArtMethod* method = jni::DecodeArtMethod(mid); 533 bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 534 if (is_string_init) { 535 // Replace calls to String.<init> with equivalent StringFactory call. 536 method = WellKnownClasses::StringInitToStringFactory(method); 537 } 538 ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object>(obj); 539 uint32_t shorty_len = 0; 540 const char* shorty = 541 method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); 542 JValue result; 543 ArgArray arg_array(shorty, shorty_len); 544 arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 545 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 546 if (is_string_init) { 547 // For string init, remap original receiver to StringFactory result. 548 UpdateReference(soa.Self(), obj, result.GetL()); 549 } 550 return result; 551 } 552 553 JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid, 554 const jvalue* args) { 555 // We want to make sure that the stack is not within a small distance from the 556 // protected region in case we are calling into a leaf function whose stack 557 // check has been elided. 558 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 559 ThrowStackOverflowError(soa.Self()); 560 return JValue(); 561 } 562 563 ArtMethod* method = jni::DecodeArtMethod(mid); 564 bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 565 if (is_string_init) { 566 // Replace calls to String.<init> with equivalent StringFactory call. 567 method = WellKnownClasses::StringInitToStringFactory(method); 568 } 569 ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object>(obj); 570 uint32_t shorty_len = 0; 571 const char* shorty = 572 method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); 573 JValue result; 574 ArgArray arg_array(shorty, shorty_len); 575 arg_array.BuildArgArrayFromJValues(soa, receiver, args); 576 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 577 if (is_string_init) { 578 // For string init, remap original receiver to StringFactory result. 579 UpdateReference(soa.Self(), obj, result.GetL()); 580 } 581 return result; 582 } 583 584 JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, 585 jobject obj, jmethodID mid, const jvalue* args) { 586 // We want to make sure that the stack is not within a small distance from the 587 // protected region in case we are calling into a leaf function whose stack 588 // check has been elided. 589 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 590 ThrowStackOverflowError(soa.Self()); 591 return JValue(); 592 } 593 594 ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object>(obj); 595 ArtMethod* method = FindVirtualMethod(receiver, jni::DecodeArtMethod(mid)); 596 bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 597 if (is_string_init) { 598 // Replace calls to String.<init> with equivalent StringFactory call. 599 method = WellKnownClasses::StringInitToStringFactory(method); 600 receiver = nullptr; 601 } 602 uint32_t shorty_len = 0; 603 const char* shorty = 604 method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); 605 JValue result; 606 ArgArray arg_array(shorty, shorty_len); 607 arg_array.BuildArgArrayFromJValues(soa, receiver, args); 608 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 609 if (is_string_init) { 610 // For string init, remap original receiver to StringFactory result. 611 UpdateReference(soa.Self(), obj, result.GetL()); 612 } 613 return result; 614 } 615 616 JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 617 jobject obj, jmethodID mid, va_list args) { 618 // We want to make sure that the stack is not within a small distance from the 619 // protected region in case we are calling into a leaf function whose stack 620 // check has been elided. 621 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 622 ThrowStackOverflowError(soa.Self()); 623 return JValue(); 624 } 625 626 ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object>(obj); 627 ArtMethod* method = FindVirtualMethod(receiver, jni::DecodeArtMethod(mid)); 628 bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 629 if (is_string_init) { 630 // Replace calls to String.<init> with equivalent StringFactory call. 631 method = WellKnownClasses::StringInitToStringFactory(method); 632 receiver = nullptr; 633 } 634 uint32_t shorty_len = 0; 635 const char* shorty = 636 method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); 637 JValue result; 638 ArgArray arg_array(shorty, shorty_len); 639 arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 640 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 641 if (is_string_init) { 642 // For string init, remap original receiver to StringFactory result. 643 UpdateReference(soa.Self(), obj, result.GetL()); 644 } 645 return result; 646 } 647 648 jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod, 649 jobject javaReceiver, jobject javaArgs, size_t num_frames) { 650 // We want to make sure that the stack is not within a small distance from the 651 // protected region in case we are calling into a leaf function whose stack 652 // check has been elided. 653 if (UNLIKELY(__builtin_frame_address(0) < 654 soa.Self()->GetStackEndForInterpreter(true))) { 655 ThrowStackOverflowError(soa.Self()); 656 return nullptr; 657 } 658 659 ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(javaMethod); 660 const bool accessible = executable->IsAccessible(); 661 ArtMethod* m = executable->GetArtMethod(); 662 663 ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass(); 664 if (UNLIKELY(!declaring_class->IsInitialized())) { 665 StackHandleScope<1> hs(soa.Self()); 666 HandleWrapperObjPtr<mirror::Class> h_class(hs.NewHandleWrapper(&declaring_class)); 667 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) { 668 return nullptr; 669 } 670 } 671 672 ObjPtr<mirror::Object> receiver; 673 if (!m->IsStatic()) { 674 // Replace calls to String.<init> with equivalent StringFactory call. 675 if (declaring_class->IsStringClass() && m->IsConstructor()) { 676 m = WellKnownClasses::StringInitToStringFactory(m); 677 CHECK(javaReceiver == nullptr); 678 } else { 679 // Check that the receiver is non-null and an instance of the field's declaring class. 680 receiver = soa.Decode<mirror::Object>(javaReceiver); 681 if (!VerifyObjectIsClass(receiver, declaring_class)) { 682 return nullptr; 683 } 684 685 // Find the actual implementation of the virtual method. 686 m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m, kRuntimePointerSize); 687 } 688 } 689 690 // Get our arrays of arguments and their types, and check they're the same size. 691 ObjPtr<mirror::ObjectArray<mirror::Object>> objects = 692 soa.Decode<mirror::ObjectArray<mirror::Object>>(javaArgs); 693 auto* np_method = m->GetInterfaceMethodIfProxy(kRuntimePointerSize); 694 if (!CheckArgsForInvokeMethod(np_method, objects)) { 695 return nullptr; 696 } 697 698 // If method is not set to be accessible, verify it can be accessed by the caller. 699 ObjPtr<mirror::Class> calling_class; 700 if (!accessible && !VerifyAccess(soa.Self(), 701 receiver, 702 declaring_class, 703 m->GetAccessFlags(), 704 &calling_class, 705 num_frames)) { 706 ThrowIllegalAccessException( 707 StringPrintf("Class %s cannot access %s method %s of class %s", 708 calling_class == nullptr ? "null" : calling_class->PrettyClass().c_str(), 709 PrettyJavaAccessFlags(m->GetAccessFlags()).c_str(), 710 m->PrettyMethod().c_str(), 711 m->GetDeclaringClass() == nullptr ? "null" : 712 m->GetDeclaringClass()->PrettyClass().c_str()).c_str()); 713 return nullptr; 714 } 715 716 // Invoke the method. 717 JValue result; 718 const char* shorty; 719 if (!InvokeMethodImpl(soa, m, np_method, receiver, objects, &shorty, &result)) { 720 return nullptr; 721 } 722 return soa.AddLocalReference<jobject>(BoxPrimitive(Primitive::GetType(shorty[0]), result)); 723 } 724 725 void InvokeConstructor(const ScopedObjectAccessAlreadyRunnable& soa, 726 ArtMethod* constructor, 727 ObjPtr<mirror::Object> receiver, 728 jobject javaArgs) { 729 // We want to make sure that the stack is not within a small distance from the 730 // protected region in case we are calling into a leaf function whose stack 731 // check has been elided. 732 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEndForInterpreter(true))) { 733 ThrowStackOverflowError(soa.Self()); 734 return; 735 } 736 737 if (kIsDebugBuild) { 738 CHECK(constructor->IsConstructor()); 739 740 ObjPtr<mirror::Class> declaring_class = constructor->GetDeclaringClass(); 741 CHECK(declaring_class->IsInitialized()); 742 743 // Calls to String.<init> should have been repplaced with with equivalent StringFactory calls. 744 CHECK(!declaring_class->IsStringClass()); 745 746 // Check that the receiver is non-null and an instance of the field's declaring class. 747 CHECK(receiver != nullptr); 748 CHECK(VerifyObjectIsClass(receiver, declaring_class)); 749 CHECK_EQ(constructor, 750 receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(constructor, 751 kRuntimePointerSize)); 752 } 753 754 // Get our arrays of arguments and their types, and check they're the same size. 755 ObjPtr<mirror::ObjectArray<mirror::Object>> objects = 756 soa.Decode<mirror::ObjectArray<mirror::Object>>(javaArgs); 757 ArtMethod* np_method = constructor->GetInterfaceMethodIfProxy(kRuntimePointerSize); 758 if (!CheckArgsForInvokeMethod(np_method, objects)) { 759 return; 760 } 761 762 // Invoke the constructor. 763 JValue result; 764 const char* shorty; 765 InvokeMethodImpl(soa, constructor, np_method, receiver, objects, &shorty, &result); 766 } 767 768 ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value) { 769 if (src_class == Primitive::kPrimNot) { 770 return value.GetL(); 771 } 772 if (src_class == Primitive::kPrimVoid) { 773 // There's no such thing as a void field, and void methods invoked via reflection return null. 774 return nullptr; 775 } 776 777 jmethodID m = nullptr; 778 const char* shorty; 779 switch (src_class) { 780 case Primitive::kPrimBoolean: 781 m = WellKnownClasses::java_lang_Boolean_valueOf; 782 shorty = "LZ"; 783 break; 784 case Primitive::kPrimByte: 785 m = WellKnownClasses::java_lang_Byte_valueOf; 786 shorty = "LB"; 787 break; 788 case Primitive::kPrimChar: 789 m = WellKnownClasses::java_lang_Character_valueOf; 790 shorty = "LC"; 791 break; 792 case Primitive::kPrimDouble: 793 m = WellKnownClasses::java_lang_Double_valueOf; 794 shorty = "LD"; 795 break; 796 case Primitive::kPrimFloat: 797 m = WellKnownClasses::java_lang_Float_valueOf; 798 shorty = "LF"; 799 break; 800 case Primitive::kPrimInt: 801 m = WellKnownClasses::java_lang_Integer_valueOf; 802 shorty = "LI"; 803 break; 804 case Primitive::kPrimLong: 805 m = WellKnownClasses::java_lang_Long_valueOf; 806 shorty = "LJ"; 807 break; 808 case Primitive::kPrimShort: 809 m = WellKnownClasses::java_lang_Short_valueOf; 810 shorty = "LS"; 811 break; 812 default: 813 LOG(FATAL) << static_cast<int>(src_class); 814 shorty = nullptr; 815 } 816 817 ScopedObjectAccessUnchecked soa(Thread::Current()); 818 DCHECK_EQ(soa.Self()->GetState(), kRunnable); 819 820 ArgArray arg_array(shorty, 2); 821 JValue result; 822 if (src_class == Primitive::kPrimDouble || src_class == Primitive::kPrimLong) { 823 arg_array.AppendWide(value.GetJ()); 824 } else { 825 arg_array.Append(value.GetI()); 826 } 827 828 jni::DecodeArtMethod(m)->Invoke(soa.Self(), 829 arg_array.GetArray(), 830 arg_array.GetNumBytes(), 831 &result, 832 shorty); 833 return result.GetL(); 834 } 835 836 static std::string UnboxingFailureKind(ArtField* f) 837 REQUIRES_SHARED(Locks::mutator_lock_) { 838 if (f != nullptr) { 839 return "field " + f->PrettyField(false); 840 } 841 return "result"; 842 } 843 844 static bool UnboxPrimitive(ObjPtr<mirror::Object> o, 845 ObjPtr<mirror::Class> dst_class, 846 ArtField* f, 847 JValue* unboxed_value) 848 REQUIRES_SHARED(Locks::mutator_lock_) { 849 bool unbox_for_result = (f == nullptr); 850 if (!dst_class->IsPrimitive()) { 851 if (UNLIKELY(o != nullptr && !o->InstanceOf(dst_class))) { 852 if (!unbox_for_result) { 853 ThrowIllegalArgumentException( 854 StringPrintf("%s has type %s, got %s", 855 UnboxingFailureKind(f).c_str(), 856 dst_class->PrettyDescriptor().c_str(), 857 o->PrettyTypeOf().c_str()).c_str()); 858 } else { 859 ThrowClassCastException( 860 StringPrintf("Couldn't convert result of type %s to %s", 861 o->PrettyTypeOf().c_str(), 862 dst_class->PrettyDescriptor().c_str()).c_str()); 863 } 864 return false; 865 } 866 unboxed_value->SetL(o); 867 return true; 868 } 869 if (UNLIKELY(dst_class->GetPrimitiveType() == Primitive::kPrimVoid)) { 870 ThrowIllegalArgumentException(StringPrintf("Can't unbox %s to void", 871 UnboxingFailureKind(f).c_str()).c_str()); 872 return false; 873 } 874 if (UNLIKELY(o == nullptr)) { 875 if (!unbox_for_result) { 876 ThrowIllegalArgumentException( 877 StringPrintf("%s has type %s, got null", 878 UnboxingFailureKind(f).c_str(), 879 dst_class->PrettyDescriptor().c_str()).c_str()); 880 } else { 881 ThrowNullPointerException( 882 StringPrintf("Expected to unbox a '%s' primitive type but was returned null", 883 dst_class->PrettyDescriptor().c_str()).c_str()); 884 } 885 return false; 886 } 887 888 JValue boxed_value; 889 ObjPtr<mirror::Class> klass = o->GetClass(); 890 Primitive::Type primitive_type; 891 ArtField* primitive_field = &klass->GetIFieldsPtr()->At(0); 892 if (klass->DescriptorEquals("Ljava/lang/Boolean;")) { 893 primitive_type = Primitive::kPrimBoolean; 894 boxed_value.SetZ(primitive_field->GetBoolean(o)); 895 } else if (klass->DescriptorEquals("Ljava/lang/Byte;")) { 896 primitive_type = Primitive::kPrimByte; 897 boxed_value.SetB(primitive_field->GetByte(o)); 898 } else if (klass->DescriptorEquals("Ljava/lang/Character;")) { 899 primitive_type = Primitive::kPrimChar; 900 boxed_value.SetC(primitive_field->GetChar(o)); 901 } else if (klass->DescriptorEquals("Ljava/lang/Float;")) { 902 primitive_type = Primitive::kPrimFloat; 903 boxed_value.SetF(primitive_field->GetFloat(o)); 904 } else if (klass->DescriptorEquals("Ljava/lang/Double;")) { 905 primitive_type = Primitive::kPrimDouble; 906 boxed_value.SetD(primitive_field->GetDouble(o)); 907 } else if (klass->DescriptorEquals("Ljava/lang/Integer;")) { 908 primitive_type = Primitive::kPrimInt; 909 boxed_value.SetI(primitive_field->GetInt(o)); 910 } else if (klass->DescriptorEquals("Ljava/lang/Long;")) { 911 primitive_type = Primitive::kPrimLong; 912 boxed_value.SetJ(primitive_field->GetLong(o)); 913 } else if (klass->DescriptorEquals("Ljava/lang/Short;")) { 914 primitive_type = Primitive::kPrimShort; 915 boxed_value.SetS(primitive_field->GetShort(o)); 916 } else { 917 std::string temp; 918 ThrowIllegalArgumentException( 919 StringPrintf("%s has type %s, got %s", UnboxingFailureKind(f).c_str(), 920 dst_class->PrettyDescriptor().c_str(), 921 PrettyDescriptor(o->GetClass()->GetDescriptor(&temp)).c_str()).c_str()); 922 return false; 923 } 924 925 return ConvertPrimitiveValue(unbox_for_result, 926 primitive_type, 927 dst_class->GetPrimitiveType(), 928 boxed_value, unboxed_value); 929 } 930 931 bool UnboxPrimitiveForField(ObjPtr<mirror::Object> o, 932 ObjPtr<mirror::Class> dst_class, 933 ArtField* f, 934 JValue* unboxed_value) { 935 DCHECK(f != nullptr); 936 return UnboxPrimitive(o, dst_class, f, unboxed_value); 937 } 938 939 bool UnboxPrimitiveForResult(ObjPtr<mirror::Object> o, 940 ObjPtr<mirror::Class> dst_class, 941 JValue* unboxed_value) { 942 return UnboxPrimitive(o, dst_class, nullptr, unboxed_value); 943 } 944 945 ObjPtr<mirror::Class> GetCallingClass(Thread* self, size_t num_frames) { 946 NthCallerVisitor visitor(self, num_frames); 947 visitor.WalkStack(); 948 return visitor.caller != nullptr ? visitor.caller->GetDeclaringClass() : nullptr; 949 } 950 951 bool VerifyAccess(Thread* self, 952 ObjPtr<mirror::Object> obj, 953 ObjPtr<mirror::Class> declaring_class, 954 uint32_t access_flags, 955 ObjPtr<mirror::Class>* calling_class, 956 size_t num_frames) { 957 if ((access_flags & kAccPublic) != 0) { 958 return true; 959 } 960 ObjPtr<mirror::Class> klass = GetCallingClass(self, num_frames); 961 if (UNLIKELY(klass == nullptr)) { 962 // The caller is an attached native thread. 963 return false; 964 } 965 *calling_class = klass; 966 return VerifyAccess(obj, declaring_class, access_flags, klass); 967 } 968 969 bool VerifyAccess(ObjPtr<mirror::Object> obj, 970 ObjPtr<mirror::Class> declaring_class, 971 uint32_t access_flags, 972 ObjPtr<mirror::Class> calling_class) { 973 if (calling_class == declaring_class) { 974 return true; 975 } 976 ScopedAssertNoThreadSuspension sants("verify-access"); 977 if ((access_flags & kAccPrivate) != 0) { 978 return false; 979 } 980 if ((access_flags & kAccProtected) != 0) { 981 if (obj != nullptr && !obj->InstanceOf(calling_class) && 982 !declaring_class->IsInSamePackage(calling_class)) { 983 return false; 984 } else if (declaring_class->IsAssignableFrom(calling_class)) { 985 return true; 986 } 987 } 988 return declaring_class->IsInSamePackage(calling_class); 989 } 990 991 void InvalidReceiverError(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) { 992 std::string expected_class_name(mirror::Class::PrettyDescriptor(c)); 993 std::string actual_class_name(mirror::Object::PrettyTypeOf(o)); 994 ThrowIllegalArgumentException(StringPrintf("Expected receiver of type %s, but got %s", 995 expected_class_name.c_str(), 996 actual_class_name.c_str()).c_str()); 997 } 998 999 // This only works if there's one reference which points to the object in obj. 1000 // Will need to be fixed if there's cases where it's not. 1001 void UpdateReference(Thread* self, jobject obj, ObjPtr<mirror::Object> result) { 1002 IndirectRef ref = reinterpret_cast<IndirectRef>(obj); 1003 IndirectRefKind kind = IndirectReferenceTable::GetIndirectRefKind(ref); 1004 if (kind == kLocal) { 1005 self->GetJniEnv()->UpdateLocal(obj, result); 1006 } else if (kind == kHandleScopeOrInvalid) { 1007 LOG(FATAL) << "Unsupported UpdateReference for kind kHandleScopeOrInvalid"; 1008 } else if (kind == kGlobal) { 1009 self->GetJniEnv()->GetVm()->UpdateGlobal(self, ref, result); 1010 } else { 1011 DCHECK_EQ(kind, kWeakGlobal); 1012 self->GetJniEnv()->GetVm()->UpdateWeakGlobal(self, ref, result); 1013 } 1014 } 1015 1016 } // namespace art 1017