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