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