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 "method_verifier-inl.h" 18 19 #include <iostream> 20 21 #include "android-base/stringprintf.h" 22 23 #include "art_field-inl.h" 24 #include "art_method-inl.h" 25 #include "base/enums.h" 26 #include "base/logging.h" 27 #include "base/mutex-inl.h" 28 #include "base/stl_util.h" 29 #include "base/systrace.h" 30 #include "base/time_utils.h" 31 #include "class_linker.h" 32 #include "compiler_callbacks.h" 33 #include "dex_file-inl.h" 34 #include "dex_instruction-inl.h" 35 #include "dex_instruction_utils.h" 36 #include "dex_instruction_visitor.h" 37 #include "experimental_flags.h" 38 #include "gc/accounting/card_table-inl.h" 39 #include "handle_scope-inl.h" 40 #include "indenter.h" 41 #include "intern_table.h" 42 #include "leb128.h" 43 #include "method_resolution_kind.h" 44 #include "mirror/class.h" 45 #include "mirror/class-inl.h" 46 #include "mirror/dex_cache-inl.h" 47 #include "mirror/method_handle_impl.h" 48 #include "mirror/object-inl.h" 49 #include "mirror/object_array-inl.h" 50 #include "reg_type-inl.h" 51 #include "register_line-inl.h" 52 #include "runtime.h" 53 #include "scoped_thread_state_change-inl.h" 54 #include "utils.h" 55 #include "verifier_deps.h" 56 #include "verifier_compiler_binding.h" 57 58 namespace art { 59 namespace verifier { 60 61 using android::base::StringPrintf; 62 63 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild; 64 static constexpr bool kDebugVerify = false; 65 // TODO: Add a constant to method_verifier to turn on verbose logging? 66 67 // On VLOG(verifier), should we dump the whole state when we run into a hard failure? 68 static constexpr bool kDumpRegLinesOnHardFailureIfVLOG = true; 69 70 // We print a warning blurb about "dx --no-optimize" when we find monitor-locking issues. Make 71 // sure we only print this once. 72 static bool gPrintedDxMonitorText = false; 73 74 PcToRegisterLineTable::PcToRegisterLineTable(ScopedArenaAllocator& arena) 75 : register_lines_(arena.Adapter(kArenaAllocVerifier)) {} 76 77 void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* flags, 78 uint32_t insns_size, uint16_t registers_size, 79 MethodVerifier* verifier) { 80 DCHECK_GT(insns_size, 0U); 81 register_lines_.resize(insns_size); 82 for (uint32_t i = 0; i < insns_size; i++) { 83 bool interesting = false; 84 switch (mode) { 85 case kTrackRegsAll: 86 interesting = flags[i].IsOpcode(); 87 break; 88 case kTrackCompilerInterestPoints: 89 interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget(); 90 break; 91 case kTrackRegsBranches: 92 interesting = flags[i].IsBranchTarget(); 93 break; 94 default: 95 break; 96 } 97 if (interesting) { 98 register_lines_[i].reset(RegisterLine::Create(registers_size, verifier)); 99 } 100 } 101 } 102 103 PcToRegisterLineTable::~PcToRegisterLineTable() {} 104 105 // Note: returns true on failure. 106 ALWAYS_INLINE static inline bool FailOrAbort(MethodVerifier* verifier, bool condition, 107 const char* error_msg, uint32_t work_insn_idx) { 108 if (kIsDebugBuild) { 109 // In a debug build, abort if the error condition is wrong. Only warn if 110 // we are already aborting (as this verification is likely run to print 111 // lock information). 112 if (LIKELY(gAborting == 0)) { 113 DCHECK(condition) << error_msg << work_insn_idx; 114 } else { 115 if (!condition) { 116 LOG(ERROR) << error_msg << work_insn_idx; 117 verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx; 118 return true; 119 } 120 } 121 } else { 122 // In a non-debug build, just fail the class. 123 if (!condition) { 124 verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx; 125 return true; 126 } 127 } 128 129 return false; 130 } 131 132 static void SafelyMarkAllRegistersAsConflicts(MethodVerifier* verifier, RegisterLine* reg_line) { 133 if (verifier->IsInstanceConstructor()) { 134 // Before we mark all regs as conflicts, check that we don't have an uninitialized this. 135 reg_line->CheckConstructorReturn(verifier); 136 } 137 reg_line->MarkAllRegistersAsConflicts(verifier); 138 } 139 140 FailureKind MethodVerifier::VerifyClass(Thread* self, 141 mirror::Class* klass, 142 CompilerCallbacks* callbacks, 143 bool allow_soft_failures, 144 HardFailLogMode log_level, 145 std::string* error) { 146 if (klass->IsVerified()) { 147 return FailureKind::kNoFailure; 148 } 149 bool early_failure = false; 150 std::string failure_message; 151 const DexFile& dex_file = klass->GetDexFile(); 152 const DexFile::ClassDef* class_def = klass->GetClassDef(); 153 mirror::Class* super = klass->GetSuperClass(); 154 std::string temp; 155 if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) { 156 early_failure = true; 157 failure_message = " that has no super class"; 158 } else if (super != nullptr && super->IsFinal()) { 159 early_failure = true; 160 failure_message = " that attempts to sub-class final class " + super->PrettyDescriptor(); 161 } else if (class_def == nullptr) { 162 early_failure = true; 163 failure_message = " that isn't present in dex file " + dex_file.GetLocation(); 164 } 165 if (early_failure) { 166 *error = "Verifier rejected class " + klass->PrettyDescriptor() + failure_message; 167 if (callbacks != nullptr) { 168 ClassReference ref(&dex_file, klass->GetDexClassDefIndex()); 169 callbacks->ClassRejected(ref); 170 } 171 return FailureKind::kHardFailure; 172 } 173 StackHandleScope<2> hs(self); 174 Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache())); 175 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader())); 176 return VerifyClass(self, 177 &dex_file, 178 dex_cache, 179 class_loader, 180 *class_def, 181 callbacks, 182 allow_soft_failures, 183 log_level, 184 error); 185 } 186 187 template <bool kDirect> 188 static bool HasNextMethod(ClassDataItemIterator* it) { 189 return kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod(); 190 } 191 192 static FailureKind FailureKindMax(FailureKind fk1, FailureKind fk2) { 193 static_assert(FailureKind::kNoFailure < FailureKind::kSoftFailure 194 && FailureKind::kSoftFailure < FailureKind::kHardFailure, 195 "Unexpected FailureKind order"); 196 return std::max(fk1, fk2); 197 } 198 199 void MethodVerifier::FailureData::Merge(const MethodVerifier::FailureData& fd) { 200 kind = FailureKindMax(kind, fd.kind); 201 types |= fd.types; 202 } 203 204 template <bool kDirect> 205 MethodVerifier::FailureData MethodVerifier::VerifyMethods(Thread* self, 206 ClassLinker* linker, 207 const DexFile* dex_file, 208 const DexFile::ClassDef& class_def, 209 ClassDataItemIterator* it, 210 Handle<mirror::DexCache> dex_cache, 211 Handle<mirror::ClassLoader> class_loader, 212 CompilerCallbacks* callbacks, 213 bool allow_soft_failures, 214 HardFailLogMode log_level, 215 bool need_precise_constants, 216 std::string* error_string) { 217 DCHECK(it != nullptr); 218 219 MethodVerifier::FailureData failure_data; 220 221 int64_t previous_method_idx = -1; 222 while (HasNextMethod<kDirect>(it)) { 223 self->AllowThreadSuspension(); 224 uint32_t method_idx = it->GetMemberIndex(); 225 if (method_idx == previous_method_idx) { 226 // smali can create dex files with two encoded_methods sharing the same method_idx 227 // http://code.google.com/p/smali/issues/detail?id=119 228 it->Next(); 229 continue; 230 } 231 previous_method_idx = method_idx; 232 InvokeType type = it->GetMethodInvokeType(class_def); 233 ArtMethod* method = linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>( 234 *dex_file, method_idx, dex_cache, class_loader, nullptr, type); 235 if (method == nullptr) { 236 DCHECK(self->IsExceptionPending()); 237 // We couldn't resolve the method, but continue regardless. 238 self->ClearException(); 239 } else { 240 DCHECK(method->GetDeclaringClassUnchecked() != nullptr) << type; 241 } 242 StackHandleScope<1> hs(self); 243 std::string hard_failure_msg; 244 MethodVerifier::FailureData result = VerifyMethod(self, 245 method_idx, 246 dex_file, 247 dex_cache, 248 class_loader, 249 class_def, 250 it->GetMethodCodeItem(), 251 method, 252 it->GetMethodAccessFlags(), 253 callbacks, 254 allow_soft_failures, 255 log_level, 256 need_precise_constants, 257 &hard_failure_msg); 258 if (result.kind == FailureKind::kHardFailure) { 259 if (failure_data.kind == FailureKind::kHardFailure) { 260 // If we logged an error before, we need a newline. 261 *error_string += "\n"; 262 } else { 263 // If we didn't log a hard failure before, print the header of the message. 264 *error_string += "Verifier rejected class "; 265 *error_string += PrettyDescriptor(dex_file->GetClassDescriptor(class_def)); 266 *error_string += ":"; 267 } 268 *error_string += " "; 269 *error_string += hard_failure_msg; 270 } 271 failure_data.Merge(result); 272 it->Next(); 273 } 274 275 return failure_data; 276 } 277 278 FailureKind MethodVerifier::VerifyClass(Thread* self, 279 const DexFile* dex_file, 280 Handle<mirror::DexCache> dex_cache, 281 Handle<mirror::ClassLoader> class_loader, 282 const DexFile::ClassDef& class_def, 283 CompilerCallbacks* callbacks, 284 bool allow_soft_failures, 285 HardFailLogMode log_level, 286 std::string* error) { 287 ScopedTrace trace(__FUNCTION__); 288 289 // A class must not be abstract and final. 290 if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) { 291 *error = "Verifier rejected class "; 292 *error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def)); 293 *error += ": class is abstract and final."; 294 return FailureKind::kHardFailure; 295 } 296 297 const uint8_t* class_data = dex_file->GetClassData(class_def); 298 if (class_data == nullptr) { 299 // empty class, probably a marker interface 300 return FailureKind::kNoFailure; 301 } 302 ClassDataItemIterator it(*dex_file, class_data); 303 while (it.HasNextStaticField() || it.HasNextInstanceField()) { 304 it.Next(); 305 } 306 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 307 // Direct methods. 308 MethodVerifier::FailureData data1 = VerifyMethods<true>(self, 309 linker, 310 dex_file, 311 class_def, 312 &it, 313 dex_cache, 314 class_loader, 315 callbacks, 316 allow_soft_failures, 317 log_level, 318 false /* need precise constants */, 319 error); 320 // Virtual methods. 321 MethodVerifier::FailureData data2 = VerifyMethods<false>(self, 322 linker, 323 dex_file, 324 class_def, 325 &it, 326 dex_cache, 327 class_loader, 328 callbacks, 329 allow_soft_failures, 330 log_level, 331 false /* need precise constants */, 332 error); 333 334 data1.Merge(data2); 335 336 if (data1.kind == FailureKind::kNoFailure) { 337 return FailureKind::kNoFailure; 338 } else { 339 if ((data1.types & VERIFY_ERROR_LOCKING) != 0) { 340 // Print a warning about expected slow-down. Use a string temporary to print one contiguous 341 // warning. 342 std::string tmp = 343 StringPrintf("Class %s failed lock verification and will run slower.", 344 PrettyDescriptor(dex_file->GetClassDescriptor(class_def)).c_str()); 345 if (!gPrintedDxMonitorText) { 346 tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n" 347 "and incorrect proguard optimizations."; 348 gPrintedDxMonitorText = true; 349 } 350 LOG(WARNING) << tmp; 351 } 352 return data1.kind; 353 } 354 } 355 356 static bool IsLargeMethod(const DexFile::CodeItem* const code_item) { 357 if (code_item == nullptr) { 358 return false; 359 } 360 361 uint16_t registers_size = code_item->registers_size_; 362 uint32_t insns_size = code_item->insns_size_in_code_units_; 363 364 return registers_size * insns_size > 4*1024*1024; 365 } 366 367 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, 368 uint32_t method_idx, 369 const DexFile* dex_file, 370 Handle<mirror::DexCache> dex_cache, 371 Handle<mirror::ClassLoader> class_loader, 372 const DexFile::ClassDef& class_def, 373 const DexFile::CodeItem* code_item, 374 ArtMethod* method, 375 uint32_t method_access_flags, 376 CompilerCallbacks* callbacks, 377 bool allow_soft_failures, 378 HardFailLogMode log_level, 379 bool need_precise_constants, 380 std::string* hard_failure_msg) { 381 MethodVerifier::FailureData result; 382 uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0; 383 384 MethodVerifier verifier(self, 385 dex_file, 386 dex_cache, 387 class_loader, 388 class_def, 389 code_item, 390 method_idx, 391 method, 392 method_access_flags, 393 true /* can_load_classes */, 394 allow_soft_failures, 395 need_precise_constants, 396 false /* verify to dump */, 397 true /* allow_thread_suspension */); 398 if (verifier.Verify()) { 399 // Verification completed, however failures may be pending that didn't cause the verification 400 // to hard fail. 401 CHECK(!verifier.have_pending_hard_failure_); 402 403 if (code_item != nullptr && callbacks != nullptr) { 404 // Let the interested party know that the method was verified. 405 callbacks->MethodVerified(&verifier); 406 } 407 408 if (verifier.failures_.size() != 0) { 409 if (VLOG_IS_ON(verifier)) { 410 verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in " 411 << dex_file->PrettyMethod(method_idx) << "\n"); 412 } 413 result.kind = FailureKind::kSoftFailure; 414 if (method != nullptr && 415 !CanCompilerHandleVerificationFailure(verifier.encountered_failure_types_)) { 416 method->SetDontCompile(); 417 } 418 } 419 if (method != nullptr) { 420 if (verifier.HasInstructionThatWillThrow()) { 421 method->SetDontCompile(); 422 if (Runtime::Current()->IsAotCompiler() && 423 (callbacks != nullptr) && !callbacks->IsBootImage()) { 424 // When compiling apps, make HasInstructionThatWillThrow a soft error to trigger 425 // re-verification at runtime. 426 // The dead code after the throw is not verified and might be invalid. This may cause 427 // the JIT compiler to crash since it assumes that all the code is valid. 428 // 429 // There's a strong assumption that the entire boot image is verified and all its dex 430 // code is valid (even the dead and unverified one). As such this is done only for apps. 431 // (CompilerDriver DCHECKs in VerifyClassVisitor that methods from boot image are 432 // fully verified). 433 result.kind = FailureKind::kSoftFailure; 434 } 435 } 436 if ((verifier.encountered_failure_types_ & VerifyError::VERIFY_ERROR_LOCKING) != 0) { 437 method->AddAccessFlags(kAccMustCountLocks); 438 } 439 } 440 } else { 441 // Bad method data. 442 CHECK_NE(verifier.failures_.size(), 0U); 443 444 if (UNLIKELY(verifier.have_pending_experimental_failure_)) { 445 // Failed due to being forced into interpreter. This is ok because 446 // we just want to skip verification. 447 result.kind = FailureKind::kSoftFailure; 448 } else { 449 CHECK(verifier.have_pending_hard_failure_); 450 if (VLOG_IS_ON(verifier)) { 451 log_level = std::max(HardFailLogMode::kLogVerbose, log_level); 452 } 453 if (log_level >= HardFailLogMode::kLogVerbose) { 454 LogSeverity severity; 455 switch (log_level) { 456 case HardFailLogMode::kLogVerbose: 457 severity = LogSeverity::VERBOSE; 458 break; 459 case HardFailLogMode::kLogWarning: 460 severity = LogSeverity::WARNING; 461 break; 462 case HardFailLogMode::kLogInternalFatal: 463 severity = LogSeverity::FATAL_WITHOUT_ABORT; 464 break; 465 default: 466 LOG(FATAL) << "Unsupported log-level " << static_cast<uint32_t>(log_level); 467 UNREACHABLE(); 468 } 469 verifier.DumpFailures(LOG_STREAM(severity) << "Verification error in " 470 << dex_file->PrettyMethod(method_idx) 471 << "\n"); 472 } 473 if (hard_failure_msg != nullptr) { 474 CHECK(!verifier.failure_messages_.empty()); 475 *hard_failure_msg = 476 verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str(); 477 } 478 result.kind = FailureKind::kHardFailure; 479 480 if (callbacks != nullptr) { 481 // Let the interested party know that we failed the class. 482 ClassReference ref(dex_file, dex_file->GetIndexForClassDef(class_def)); 483 callbacks->ClassRejected(ref); 484 } 485 } 486 if (VLOG_IS_ON(verifier)) { 487 std::cout << "\n" << verifier.info_messages_.str(); 488 verifier.Dump(std::cout); 489 } 490 } 491 if (kTimeVerifyMethod) { 492 uint64_t duration_ns = NanoTime() - start_ns; 493 if (duration_ns > MsToNs(100)) { 494 LOG(WARNING) << "Verification of " << dex_file->PrettyMethod(method_idx) 495 << " took " << PrettyDuration(duration_ns) 496 << (IsLargeMethod(code_item) ? " (large method)" : ""); 497 } 498 } 499 result.types = verifier.encountered_failure_types_; 500 return result; 501 } 502 503 MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self, 504 VariableIndentationOutputStream* vios, 505 uint32_t dex_method_idx, 506 const DexFile* dex_file, 507 Handle<mirror::DexCache> dex_cache, 508 Handle<mirror::ClassLoader> class_loader, 509 const DexFile::ClassDef& class_def, 510 const DexFile::CodeItem* code_item, 511 ArtMethod* method, 512 uint32_t method_access_flags) { 513 MethodVerifier* verifier = new MethodVerifier(self, 514 dex_file, 515 dex_cache, 516 class_loader, 517 class_def, 518 code_item, 519 dex_method_idx, 520 method, 521 method_access_flags, 522 true /* can_load_classes */, 523 true /* allow_soft_failures */, 524 true /* need_precise_constants */, 525 true /* verify_to_dump */, 526 true /* allow_thread_suspension */); 527 verifier->Verify(); 528 verifier->DumpFailures(vios->Stream()); 529 vios->Stream() << verifier->info_messages_.str(); 530 // Only dump and return if no hard failures. Otherwise the verifier may be not fully initialized 531 // and querying any info is dangerous/can abort. 532 if (verifier->have_pending_hard_failure_) { 533 delete verifier; 534 return nullptr; 535 } else { 536 verifier->Dump(vios); 537 return verifier; 538 } 539 } 540 541 MethodVerifier::MethodVerifier(Thread* self, 542 const DexFile* dex_file, 543 Handle<mirror::DexCache> dex_cache, 544 Handle<mirror::ClassLoader> class_loader, 545 const DexFile::ClassDef& class_def, 546 const DexFile::CodeItem* code_item, 547 uint32_t dex_method_idx, 548 ArtMethod* method, 549 uint32_t method_access_flags, 550 bool can_load_classes, 551 bool allow_soft_failures, 552 bool need_precise_constants, 553 bool verify_to_dump, 554 bool allow_thread_suspension) 555 : self_(self), 556 arena_stack_(Runtime::Current()->GetArenaPool()), 557 arena_(&arena_stack_), 558 reg_types_(can_load_classes, arena_), 559 reg_table_(arena_), 560 work_insn_idx_(DexFile::kDexNoIndex), 561 dex_method_idx_(dex_method_idx), 562 mirror_method_(method), 563 method_access_flags_(method_access_flags), 564 return_type_(nullptr), 565 dex_file_(dex_file), 566 dex_cache_(dex_cache), 567 class_loader_(class_loader), 568 class_def_(class_def), 569 code_item_(code_item), 570 declaring_class_(nullptr), 571 interesting_dex_pc_(-1), 572 monitor_enter_dex_pcs_(nullptr), 573 have_pending_hard_failure_(false), 574 have_pending_runtime_throw_failure_(false), 575 have_pending_experimental_failure_(false), 576 have_any_pending_runtime_throw_failure_(false), 577 new_instance_count_(0), 578 monitor_enter_count_(0), 579 encountered_failure_types_(0), 580 can_load_classes_(can_load_classes), 581 allow_soft_failures_(allow_soft_failures), 582 need_precise_constants_(need_precise_constants), 583 has_check_casts_(false), 584 has_virtual_or_interface_invokes_(false), 585 verify_to_dump_(verify_to_dump), 586 allow_thread_suspension_(allow_thread_suspension), 587 is_constructor_(false), 588 link_(nullptr) { 589 self->PushVerifier(this); 590 } 591 592 MethodVerifier::~MethodVerifier() { 593 Thread::Current()->PopVerifier(this); 594 STLDeleteElements(&failure_messages_); 595 } 596 597 void MethodVerifier::FindLocksAtDexPc(ArtMethod* m, uint32_t dex_pc, 598 std::vector<uint32_t>* monitor_enter_dex_pcs) { 599 StackHandleScope<2> hs(Thread::Current()); 600 Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); 601 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); 602 MethodVerifier verifier(hs.Self(), 603 m->GetDexFile(), 604 dex_cache, 605 class_loader, 606 m->GetClassDef(), 607 m->GetCodeItem(), 608 m->GetDexMethodIndex(), 609 m, 610 m->GetAccessFlags(), 611 false /* can_load_classes */, 612 true /* allow_soft_failures */, 613 false /* need_precise_constants */, 614 false /* verify_to_dump */, 615 false /* allow_thread_suspension */); 616 verifier.interesting_dex_pc_ = dex_pc; 617 verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs; 618 verifier.FindLocksAtDexPc(); 619 } 620 621 static bool HasMonitorEnterInstructions(const DexFile::CodeItem* const code_item) { 622 const Instruction* inst = Instruction::At(code_item->insns_); 623 624 uint32_t insns_size = code_item->insns_size_in_code_units_; 625 for (uint32_t dex_pc = 0; dex_pc < insns_size;) { 626 if (inst->Opcode() == Instruction::MONITOR_ENTER) { 627 return true; 628 } 629 630 dex_pc += inst->SizeInCodeUnits(); 631 inst = inst->Next(); 632 } 633 634 return false; 635 } 636 637 void MethodVerifier::FindLocksAtDexPc() { 638 CHECK(monitor_enter_dex_pcs_ != nullptr); 639 CHECK(code_item_ != nullptr); // This only makes sense for methods with code. 640 641 // Quick check whether there are any monitor_enter instructions at all. 642 if (!HasMonitorEnterInstructions(code_item_)) { 643 return; 644 } 645 646 // Strictly speaking, we ought to be able to get away with doing a subset of the full method 647 // verification. In practice, the phase we want relies on data structures set up by all the 648 // earlier passes, so we just run the full method verification and bail out early when we've 649 // got what we wanted. 650 Verify(); 651 } 652 653 ArtField* MethodVerifier::FindAccessedFieldAtDexPc(ArtMethod* m, uint32_t dex_pc) { 654 StackHandleScope<2> hs(Thread::Current()); 655 Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); 656 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); 657 MethodVerifier verifier(hs.Self(), 658 m->GetDexFile(), 659 dex_cache, 660 class_loader, 661 m->GetClassDef(), 662 m->GetCodeItem(), 663 m->GetDexMethodIndex(), 664 m, 665 m->GetAccessFlags(), 666 true /* can_load_classes */, 667 true /* allow_soft_failures */, 668 false /* need_precise_constants */, 669 false /* verify_to_dump */, 670 true /* allow_thread_suspension */); 671 return verifier.FindAccessedFieldAtDexPc(dex_pc); 672 } 673 674 ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) { 675 CHECK(code_item_ != nullptr); // This only makes sense for methods with code. 676 677 // Strictly speaking, we ought to be able to get away with doing a subset of the full method 678 // verification. In practice, the phase we want relies on data structures set up by all the 679 // earlier passes, so we just run the full method verification and bail out early when we've 680 // got what we wanted. 681 bool success = Verify(); 682 if (!success) { 683 return nullptr; 684 } 685 RegisterLine* register_line = reg_table_.GetLine(dex_pc); 686 if (register_line == nullptr) { 687 return nullptr; 688 } 689 const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc); 690 return GetQuickFieldAccess(inst, register_line); 691 } 692 693 ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(ArtMethod* m, uint32_t dex_pc) { 694 StackHandleScope<2> hs(Thread::Current()); 695 Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); 696 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); 697 MethodVerifier verifier(hs.Self(), 698 m->GetDexFile(), 699 dex_cache, 700 class_loader, 701 m->GetClassDef(), 702 m->GetCodeItem(), 703 m->GetDexMethodIndex(), 704 m, 705 m->GetAccessFlags(), 706 true /* can_load_classes */, 707 true /* allow_soft_failures */, 708 false /* need_precise_constants */, 709 false /* verify_to_dump */, 710 true /* allow_thread_suspension */); 711 return verifier.FindInvokedMethodAtDexPc(dex_pc); 712 } 713 714 ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(uint32_t dex_pc) { 715 CHECK(code_item_ != nullptr); // This only makes sense for methods with code. 716 717 // Strictly speaking, we ought to be able to get away with doing a subset of the full method 718 // verification. In practice, the phase we want relies on data structures set up by all the 719 // earlier passes, so we just run the full method verification and bail out early when we've 720 // got what we wanted. 721 bool success = Verify(); 722 if (!success) { 723 return nullptr; 724 } 725 RegisterLine* register_line = reg_table_.GetLine(dex_pc); 726 if (register_line == nullptr) { 727 return nullptr; 728 } 729 const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc); 730 const bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK); 731 return GetQuickInvokedMethod(inst, register_line, is_range, false); 732 } 733 734 bool MethodVerifier::Verify() { 735 // Some older code doesn't correctly mark constructors as such. Test for this case by looking at 736 // the name. 737 const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 738 const char* method_name = dex_file_->StringDataByIdx(method_id.name_idx_); 739 bool instance_constructor_by_name = strcmp("<init>", method_name) == 0; 740 bool static_constructor_by_name = strcmp("<clinit>", method_name) == 0; 741 bool constructor_by_name = instance_constructor_by_name || static_constructor_by_name; 742 // Check that only constructors are tagged, and check for bad code that doesn't tag constructors. 743 if ((method_access_flags_ & kAccConstructor) != 0) { 744 if (!constructor_by_name) { 745 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 746 << "method is marked as constructor, but not named accordingly"; 747 return false; 748 } 749 is_constructor_ = true; 750 } else if (constructor_by_name) { 751 LOG(WARNING) << "Method " << dex_file_->PrettyMethod(dex_method_idx_) 752 << " not marked as constructor."; 753 is_constructor_ = true; 754 } 755 // If it's a constructor, check whether IsStatic() matches the name. 756 // This should have been rejected by the dex file verifier. Only do in debug build. 757 if (kIsDebugBuild) { 758 if (IsConstructor()) { 759 if (IsStatic() ^ static_constructor_by_name) { 760 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 761 << "constructor name doesn't match static flag"; 762 return false; 763 } 764 } 765 } 766 767 // Methods may only have one of public/protected/private. 768 // This should have been rejected by the dex file verifier. Only do in debug build. 769 if (kIsDebugBuild) { 770 size_t access_mod_count = 771 (((method_access_flags_ & kAccPublic) == 0) ? 0 : 1) + 772 (((method_access_flags_ & kAccProtected) == 0) ? 0 : 1) + 773 (((method_access_flags_ & kAccPrivate) == 0) ? 0 : 1); 774 if (access_mod_count > 1) { 775 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "method has more than one of public/protected/private"; 776 return false; 777 } 778 } 779 780 // If there aren't any instructions, make sure that's expected, then exit successfully. 781 if (code_item_ == nullptr) { 782 // Only native or abstract methods may not have code. 783 if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) { 784 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method"; 785 return false; 786 } 787 788 // This should have been rejected by the dex file verifier. Only do in debug build. 789 // Note: the above will also be rejected in the dex file verifier, starting in dex version 37. 790 if (kIsDebugBuild) { 791 if ((method_access_flags_ & kAccAbstract) != 0) { 792 // Abstract methods are not allowed to have the following flags. 793 static constexpr uint32_t kForbidden = 794 kAccPrivate | 795 kAccStatic | 796 kAccFinal | 797 kAccNative | 798 kAccStrict | 799 kAccSynchronized; 800 if ((method_access_flags_ & kForbidden) != 0) { 801 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 802 << "method can't be abstract and private/static/final/native/strict/synchronized"; 803 return false; 804 } 805 } 806 if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) { 807 // Interface methods must be public and abstract (if default methods are disabled). 808 uint32_t kRequired = kAccPublic; 809 if ((method_access_flags_ & kRequired) != kRequired) { 810 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods must be public"; 811 return false; 812 } 813 // In addition to the above, interface methods must not be protected. 814 static constexpr uint32_t kForbidden = kAccProtected; 815 if ((method_access_flags_ & kForbidden) != 0) { 816 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods can't be protected"; 817 return false; 818 } 819 } 820 // We also don't allow constructors to be abstract or native. 821 if (IsConstructor()) { 822 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be abstract or native"; 823 return false; 824 } 825 } 826 return true; 827 } 828 829 // This should have been rejected by the dex file verifier. Only do in debug build. 830 if (kIsDebugBuild) { 831 // When there's code, the method must not be native or abstract. 832 if ((method_access_flags_ & (kAccNative | kAccAbstract)) != 0) { 833 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "non-zero-length code in abstract or native method"; 834 return false; 835 } 836 837 if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) { 838 // Interfaces may always have static initializers for their fields. If we are running with 839 // default methods enabled we also allow other public, static, non-final methods to have code. 840 // Otherwise that is the only type of method allowed. 841 if (!(IsConstructor() && IsStatic())) { 842 if (IsInstanceConstructor()) { 843 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-static constructor"; 844 return false; 845 } else if (method_access_flags_ & kAccFinal) { 846 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods"; 847 return false; 848 } else { 849 uint32_t access_flag_options = kAccPublic; 850 if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) { 851 access_flag_options |= kAccPrivate; 852 } 853 if (!(method_access_flags_ & access_flag_options)) { 854 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 855 << "interfaces may not have protected or package-private members"; 856 return false; 857 } 858 } 859 } 860 } 861 862 // Instance constructors must not be synchronized. 863 if (IsInstanceConstructor()) { 864 static constexpr uint32_t kForbidden = kAccSynchronized; 865 if ((method_access_flags_ & kForbidden) != 0) { 866 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be synchronized"; 867 return false; 868 } 869 } 870 } 871 872 // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers. 873 if (code_item_->ins_size_ > code_item_->registers_size_) { 874 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins=" << code_item_->ins_size_ 875 << " regs=" << code_item_->registers_size_; 876 return false; 877 } 878 879 // Allocate and initialize an array to hold instruction data. 880 insn_flags_.reset(arena_.AllocArray<InstructionFlags>(code_item_->insns_size_in_code_units_)); 881 DCHECK(insn_flags_ != nullptr); 882 std::uninitialized_fill_n(insn_flags_.get(), 883 code_item_->insns_size_in_code_units_, 884 InstructionFlags()); 885 // Run through the instructions and see if the width checks out. 886 bool result = ComputeWidthsAndCountOps(); 887 // Flag instructions guarded by a "try" block and check exception handlers. 888 result = result && ScanTryCatchBlocks(); 889 // Perform static instruction verification. 890 result = result && VerifyInstructions(); 891 // Perform code-flow analysis and return. 892 result = result && VerifyCodeFlow(); 893 894 return result; 895 } 896 897 std::ostream& MethodVerifier::Fail(VerifyError error) { 898 // Mark the error type as encountered. 899 encountered_failure_types_ |= static_cast<uint32_t>(error); 900 901 switch (error) { 902 case VERIFY_ERROR_NO_CLASS: 903 case VERIFY_ERROR_NO_FIELD: 904 case VERIFY_ERROR_NO_METHOD: 905 case VERIFY_ERROR_ACCESS_CLASS: 906 case VERIFY_ERROR_ACCESS_FIELD: 907 case VERIFY_ERROR_ACCESS_METHOD: 908 case VERIFY_ERROR_INSTANTIATION: 909 case VERIFY_ERROR_CLASS_CHANGE: 910 case VERIFY_ERROR_FORCE_INTERPRETER: 911 case VERIFY_ERROR_LOCKING: 912 if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) { 913 // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx, 914 // class change and instantiation errors into soft verification errors so that we re-verify 915 // at runtime. We may fail to find or to agree on access because of not yet available class 916 // loaders, or class loaders that will differ at runtime. In these cases, we don't want to 917 // affect the soundness of the code being compiled. Instead, the generated code runs "slow 918 // paths" that dynamically perform the verification and cause the behavior to be that akin 919 // to an interpreter. 920 error = VERIFY_ERROR_BAD_CLASS_SOFT; 921 } else { 922 // If we fail again at runtime, mark that this instruction would throw and force this 923 // method to be executed using the interpreter with checks. 924 have_pending_runtime_throw_failure_ = true; 925 926 // We need to save the work_line if the instruction wasn't throwing before. Otherwise we'll 927 // try to merge garbage. 928 // Note: this assumes that Fail is called before we do any work_line modifications. 929 // Note: this can fail before we touch any instruction, for the signature of a method. So 930 // add a check. 931 if (work_insn_idx_ < DexFile::kDexNoIndex) { 932 const uint16_t* insns = code_item_->insns_ + work_insn_idx_; 933 const Instruction* inst = Instruction::At(insns); 934 int opcode_flags = Instruction::FlagsOf(inst->Opcode()); 935 936 if ((opcode_flags & Instruction::kThrow) == 0 && CurrentInsnFlags()->IsInTry()) { 937 saved_line_->CopyFromLine(work_line_.get()); 938 } 939 } 940 } 941 break; 942 943 // Indication that verification should be retried at runtime. 944 case VERIFY_ERROR_BAD_CLASS_SOFT: 945 if (!allow_soft_failures_) { 946 have_pending_hard_failure_ = true; 947 } 948 break; 949 950 // Hard verification failures at compile time will still fail at runtime, so the class is 951 // marked as rejected to prevent it from being compiled. 952 case VERIFY_ERROR_BAD_CLASS_HARD: { 953 have_pending_hard_failure_ = true; 954 if (VLOG_IS_ON(verifier) && kDumpRegLinesOnHardFailureIfVLOG) { 955 ScopedObjectAccess soa(Thread::Current()); 956 std::ostringstream oss; 957 Dump(oss); 958 LOG(ERROR) << oss.str(); 959 } 960 break; 961 } 962 } 963 failures_.push_back(error); 964 std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(), 965 work_insn_idx_)); 966 std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate); 967 failure_messages_.push_back(failure_message); 968 return *failure_message; 969 } 970 971 std::ostream& MethodVerifier::LogVerifyInfo() { 972 return info_messages_ << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_) 973 << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : "; 974 } 975 976 void MethodVerifier::PrependToLastFailMessage(std::string prepend) { 977 size_t failure_num = failure_messages_.size(); 978 DCHECK_NE(failure_num, 0U); 979 std::ostringstream* last_fail_message = failure_messages_[failure_num - 1]; 980 prepend += last_fail_message->str(); 981 failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate); 982 delete last_fail_message; 983 } 984 985 void MethodVerifier::AppendToLastFailMessage(const std::string& append) { 986 size_t failure_num = failure_messages_.size(); 987 DCHECK_NE(failure_num, 0U); 988 std::ostringstream* last_fail_message = failure_messages_[failure_num - 1]; 989 (*last_fail_message) << append; 990 } 991 992 bool MethodVerifier::ComputeWidthsAndCountOps() { 993 const uint16_t* insns = code_item_->insns_; 994 size_t insns_size = code_item_->insns_size_in_code_units_; 995 const Instruction* inst = Instruction::At(insns); 996 size_t new_instance_count = 0; 997 size_t monitor_enter_count = 0; 998 size_t dex_pc = 0; 999 1000 while (dex_pc < insns_size) { 1001 Instruction::Code opcode = inst->Opcode(); 1002 switch (opcode) { 1003 case Instruction::APUT_OBJECT: 1004 case Instruction::CHECK_CAST: 1005 has_check_casts_ = true; 1006 break; 1007 case Instruction::INVOKE_VIRTUAL: 1008 case Instruction::INVOKE_VIRTUAL_RANGE: 1009 case Instruction::INVOKE_INTERFACE: 1010 case Instruction::INVOKE_INTERFACE_RANGE: 1011 has_virtual_or_interface_invokes_ = true; 1012 break; 1013 case Instruction::MONITOR_ENTER: 1014 monitor_enter_count++; 1015 break; 1016 case Instruction::NEW_INSTANCE: 1017 new_instance_count++; 1018 break; 1019 default: 1020 break; 1021 } 1022 size_t inst_size = inst->SizeInCodeUnits(); 1023 GetInstructionFlags(dex_pc).SetIsOpcode(); 1024 dex_pc += inst_size; 1025 inst = inst->RelativeAt(inst_size); 1026 } 1027 1028 if (dex_pc != insns_size) { 1029 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected (" 1030 << dex_pc << " vs. " << insns_size << ")"; 1031 return false; 1032 } 1033 1034 new_instance_count_ = new_instance_count; 1035 monitor_enter_count_ = monitor_enter_count; 1036 return true; 1037 } 1038 1039 bool MethodVerifier::ScanTryCatchBlocks() { 1040 uint32_t tries_size = code_item_->tries_size_; 1041 if (tries_size == 0) { 1042 return true; 1043 } 1044 uint32_t insns_size = code_item_->insns_size_in_code_units_; 1045 const DexFile::TryItem* tries = DexFile::GetTryItems(*code_item_, 0); 1046 1047 for (uint32_t idx = 0; idx < tries_size; idx++) { 1048 const DexFile::TryItem* try_item = &tries[idx]; 1049 uint32_t start = try_item->start_addr_; 1050 uint32_t end = start + try_item->insn_count_; 1051 if ((start >= end) || (start >= insns_size) || (end > insns_size)) { 1052 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start 1053 << " endAddr=" << end << " (size=" << insns_size << ")"; 1054 return false; 1055 } 1056 if (!GetInstructionFlags(start).IsOpcode()) { 1057 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1058 << "'try' block starts inside an instruction (" << start << ")"; 1059 return false; 1060 } 1061 uint32_t dex_pc = start; 1062 const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc); 1063 while (dex_pc < end) { 1064 GetInstructionFlags(dex_pc).SetInTry(); 1065 size_t insn_size = inst->SizeInCodeUnits(); 1066 dex_pc += insn_size; 1067 inst = inst->RelativeAt(insn_size); 1068 } 1069 } 1070 // Iterate over each of the handlers to verify target addresses. 1071 const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0); 1072 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 1073 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 1074 for (uint32_t idx = 0; idx < handlers_size; idx++) { 1075 CatchHandlerIterator iterator(handlers_ptr); 1076 for (; iterator.HasNext(); iterator.Next()) { 1077 uint32_t dex_pc= iterator.GetHandlerAddress(); 1078 if (!GetInstructionFlags(dex_pc).IsOpcode()) { 1079 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1080 << "exception handler starts at bad address (" << dex_pc << ")"; 1081 return false; 1082 } 1083 if (!CheckNotMoveResult(code_item_->insns_, dex_pc)) { 1084 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1085 << "exception handler begins with move-result* (" << dex_pc << ")"; 1086 return false; 1087 } 1088 GetInstructionFlags(dex_pc).SetBranchTarget(); 1089 // Ensure exception types are resolved so that they don't need resolution to be delivered, 1090 // unresolved exception types will be ignored by exception delivery 1091 if (iterator.GetHandlerTypeIndex().IsValid()) { 1092 mirror::Class* exception_type = linker->ResolveType(*dex_file_, 1093 iterator.GetHandlerTypeIndex(), 1094 dex_cache_, class_loader_); 1095 if (exception_type == nullptr) { 1096 DCHECK(self_->IsExceptionPending()); 1097 self_->ClearException(); 1098 } 1099 } 1100 } 1101 handlers_ptr = iterator.EndDataPointer(); 1102 } 1103 return true; 1104 } 1105 1106 bool MethodVerifier::VerifyInstructions() { 1107 const Instruction* inst = Instruction::At(code_item_->insns_); 1108 1109 /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */ 1110 GetInstructionFlags(0).SetBranchTarget(); 1111 GetInstructionFlags(0).SetCompileTimeInfoPoint(); 1112 1113 uint32_t insns_size = code_item_->insns_size_in_code_units_; 1114 for (uint32_t dex_pc = 0; dex_pc < insns_size;) { 1115 if (!VerifyInstruction(inst, dex_pc)) { 1116 DCHECK_NE(failures_.size(), 0U); 1117 return false; 1118 } 1119 /* Flag instructions that are garbage collection points */ 1120 // All invoke points are marked as "Throw" points already. 1121 // We are relying on this to also count all the invokes as interesting. 1122 if (inst->IsBranch()) { 1123 GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint(); 1124 // The compiler also needs safepoints for fall-through to loop heads. 1125 // Such a loop head must be a target of a branch. 1126 int32_t offset = 0; 1127 bool cond, self_ok; 1128 bool target_ok = GetBranchOffset(dex_pc, &offset, &cond, &self_ok); 1129 DCHECK(target_ok); 1130 GetInstructionFlags(dex_pc + offset).SetCompileTimeInfoPoint(); 1131 } else if (inst->IsSwitch() || inst->IsThrow()) { 1132 GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint(); 1133 } else if (inst->IsReturn()) { 1134 GetInstructionFlags(dex_pc).SetCompileTimeInfoPointAndReturn(); 1135 } 1136 dex_pc += inst->SizeInCodeUnits(); 1137 inst = inst->Next(); 1138 } 1139 return true; 1140 } 1141 1142 bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_offset) { 1143 if (UNLIKELY(inst->IsExperimental())) { 1144 // Experimental instructions don't yet have verifier support implementation. 1145 // While it is possible to use them by themselves, when we try to use stable instructions 1146 // with a virtual register that was created by an experimental instruction, 1147 // the data flow analysis will fail. 1148 Fail(VERIFY_ERROR_FORCE_INTERPRETER) 1149 << "experimental instruction is not supported by verifier; skipping verification"; 1150 have_pending_experimental_failure_ = true; 1151 return false; 1152 } 1153 1154 bool result = true; 1155 switch (inst->GetVerifyTypeArgumentA()) { 1156 case Instruction::kVerifyRegA: 1157 result = result && CheckRegisterIndex(inst->VRegA()); 1158 break; 1159 case Instruction::kVerifyRegAWide: 1160 result = result && CheckWideRegisterIndex(inst->VRegA()); 1161 break; 1162 } 1163 switch (inst->GetVerifyTypeArgumentB()) { 1164 case Instruction::kVerifyRegB: 1165 result = result && CheckRegisterIndex(inst->VRegB()); 1166 break; 1167 case Instruction::kVerifyRegBField: 1168 result = result && CheckFieldIndex(inst->VRegB()); 1169 break; 1170 case Instruction::kVerifyRegBMethod: 1171 result = result && CheckMethodIndex(inst->VRegB()); 1172 break; 1173 case Instruction::kVerifyRegBNewInstance: 1174 result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB())); 1175 break; 1176 case Instruction::kVerifyRegBString: 1177 result = result && CheckStringIndex(inst->VRegB()); 1178 break; 1179 case Instruction::kVerifyRegBType: 1180 result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB())); 1181 break; 1182 case Instruction::kVerifyRegBWide: 1183 result = result && CheckWideRegisterIndex(inst->VRegB()); 1184 break; 1185 } 1186 switch (inst->GetVerifyTypeArgumentC()) { 1187 case Instruction::kVerifyRegC: 1188 result = result && CheckRegisterIndex(inst->VRegC()); 1189 break; 1190 case Instruction::kVerifyRegCField: 1191 result = result && CheckFieldIndex(inst->VRegC()); 1192 break; 1193 case Instruction::kVerifyRegCNewArray: 1194 result = result && CheckNewArray(dex::TypeIndex(inst->VRegC())); 1195 break; 1196 case Instruction::kVerifyRegCType: 1197 result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC())); 1198 break; 1199 case Instruction::kVerifyRegCWide: 1200 result = result && CheckWideRegisterIndex(inst->VRegC()); 1201 break; 1202 } 1203 switch (inst->GetVerifyTypeArgumentH()) { 1204 case Instruction::kVerifyRegHPrototype: 1205 result = result && CheckPrototypeIndex(inst->VRegH()); 1206 break; 1207 } 1208 switch (inst->GetVerifyExtraFlags()) { 1209 case Instruction::kVerifyArrayData: 1210 result = result && CheckArrayData(code_offset); 1211 break; 1212 case Instruction::kVerifyBranchTarget: 1213 result = result && CheckBranchTarget(code_offset); 1214 break; 1215 case Instruction::kVerifySwitchTargets: 1216 result = result && CheckSwitchTargets(code_offset); 1217 break; 1218 case Instruction::kVerifyVarArgNonZero: 1219 // Fall-through. 1220 case Instruction::kVerifyVarArg: { 1221 // Instructions that can actually return a negative value shouldn't have this flag. 1222 uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA()); 1223 if ((inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && v_a == 0) || 1224 v_a > Instruction::kMaxVarArgRegs) { 1225 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << v_a << ") in " 1226 "non-range invoke"; 1227 return false; 1228 } 1229 1230 uint32_t args[Instruction::kMaxVarArgRegs]; 1231 inst->GetVarArgs(args); 1232 result = result && CheckVarArgRegs(v_a, args); 1233 break; 1234 } 1235 case Instruction::kVerifyVarArgRangeNonZero: 1236 // Fall-through. 1237 case Instruction::kVerifyVarArgRange: 1238 if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero && 1239 inst->VRegA() <= 0) { 1240 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in " 1241 "range invoke"; 1242 return false; 1243 } 1244 result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC()); 1245 break; 1246 case Instruction::kVerifyError: 1247 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name(); 1248 result = false; 1249 break; 1250 } 1251 if (inst->GetVerifyIsRuntimeOnly() && Runtime::Current()->IsAotCompiler() && !verify_to_dump_) { 1252 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name(); 1253 result = false; 1254 } 1255 return result; 1256 } 1257 1258 inline bool MethodVerifier::CheckRegisterIndex(uint32_t idx) { 1259 if (idx >= code_item_->registers_size_) { 1260 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= " 1261 << code_item_->registers_size_ << ")"; 1262 return false; 1263 } 1264 return true; 1265 } 1266 1267 inline bool MethodVerifier::CheckWideRegisterIndex(uint32_t idx) { 1268 if (idx + 1 >= code_item_->registers_size_) { 1269 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx 1270 << "+1 >= " << code_item_->registers_size_ << ")"; 1271 return false; 1272 } 1273 return true; 1274 } 1275 1276 inline bool MethodVerifier::CheckFieldIndex(uint32_t idx) { 1277 if (idx >= dex_file_->GetHeader().field_ids_size_) { 1278 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max " 1279 << dex_file_->GetHeader().field_ids_size_ << ")"; 1280 return false; 1281 } 1282 return true; 1283 } 1284 1285 inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) { 1286 if (idx >= dex_file_->GetHeader().method_ids_size_) { 1287 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max " 1288 << dex_file_->GetHeader().method_ids_size_ << ")"; 1289 return false; 1290 } 1291 return true; 1292 } 1293 1294 inline bool MethodVerifier::CheckNewInstance(dex::TypeIndex idx) { 1295 if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { 1296 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1297 << dex_file_->GetHeader().type_ids_size_ << ")"; 1298 return false; 1299 } 1300 // We don't need the actual class, just a pointer to the class name. 1301 const char* descriptor = dex_file_->StringByTypeIdx(idx); 1302 if (descriptor[0] != 'L') { 1303 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'"; 1304 return false; 1305 } else if (strcmp(descriptor, "Ljava/lang/Class;") == 0) { 1306 // An unlikely new instance on Class is not allowed. Fall back to interpreter to ensure an 1307 // exception is thrown when this statement is executed (compiled code would not do that). 1308 Fail(VERIFY_ERROR_INSTANTIATION); 1309 } 1310 return true; 1311 } 1312 1313 inline bool MethodVerifier::CheckPrototypeIndex(uint32_t idx) { 1314 if (idx >= dex_file_->GetHeader().proto_ids_size_) { 1315 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad prototype index " << idx << " (max " 1316 << dex_file_->GetHeader().proto_ids_size_ << ")"; 1317 return false; 1318 } 1319 return true; 1320 } 1321 1322 inline bool MethodVerifier::CheckStringIndex(uint32_t idx) { 1323 if (idx >= dex_file_->GetHeader().string_ids_size_) { 1324 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max " 1325 << dex_file_->GetHeader().string_ids_size_ << ")"; 1326 return false; 1327 } 1328 return true; 1329 } 1330 1331 inline bool MethodVerifier::CheckTypeIndex(dex::TypeIndex idx) { 1332 if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { 1333 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1334 << dex_file_->GetHeader().type_ids_size_ << ")"; 1335 return false; 1336 } 1337 return true; 1338 } 1339 1340 bool MethodVerifier::CheckNewArray(dex::TypeIndex idx) { 1341 if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) { 1342 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max " 1343 << dex_file_->GetHeader().type_ids_size_ << ")"; 1344 return false; 1345 } 1346 int bracket_count = 0; 1347 const char* descriptor = dex_file_->StringByTypeIdx(idx); 1348 const char* cp = descriptor; 1349 while (*cp++ == '[') { 1350 bracket_count++; 1351 } 1352 if (bracket_count == 0) { 1353 /* The given class must be an array type. */ 1354 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1355 << "can't new-array class '" << descriptor << "' (not an array)"; 1356 return false; 1357 } else if (bracket_count > 255) { 1358 /* It is illegal to create an array of more than 255 dimensions. */ 1359 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1360 << "can't new-array class '" << descriptor << "' (exceeds limit)"; 1361 return false; 1362 } 1363 return true; 1364 } 1365 1366 bool MethodVerifier::CheckArrayData(uint32_t cur_offset) { 1367 const uint32_t insn_count = code_item_->insns_size_in_code_units_; 1368 const uint16_t* insns = code_item_->insns_ + cur_offset; 1369 const uint16_t* array_data; 1370 int32_t array_data_offset; 1371 1372 DCHECK_LT(cur_offset, insn_count); 1373 /* make sure the start of the array data table is in range */ 1374 array_data_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 1375 if (static_cast<int32_t>(cur_offset) + array_data_offset < 0 || 1376 cur_offset + array_data_offset + 2 >= insn_count) { 1377 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset 1378 << ", data offset " << array_data_offset 1379 << ", count " << insn_count; 1380 return false; 1381 } 1382 /* offset to array data table is a relative branch-style offset */ 1383 array_data = insns + array_data_offset; 1384 // Make sure the table is at an even dex pc, that is, 32-bit aligned. 1385 if (!IsAligned<4>(array_data)) { 1386 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset 1387 << ", data offset " << array_data_offset; 1388 return false; 1389 } 1390 // Make sure the array-data is marked as an opcode. This ensures that it was reached when 1391 // traversing the code item linearly. It is an approximation for a by-spec padding value. 1392 if (!GetInstructionFlags(cur_offset + array_data_offset).IsOpcode()) { 1393 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array data table at " << cur_offset 1394 << ", data offset " << array_data_offset 1395 << " not correctly visited, probably bad padding."; 1396 return false; 1397 } 1398 1399 uint32_t value_width = array_data[1]; 1400 uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]); 1401 uint32_t table_size = 4 + (value_width * value_count + 1) / 2; 1402 /* make sure the end of the switch is in range */ 1403 if (cur_offset + array_data_offset + table_size > insn_count) { 1404 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset 1405 << ", data offset " << array_data_offset << ", end " 1406 << cur_offset + array_data_offset + table_size 1407 << ", count " << insn_count; 1408 return false; 1409 } 1410 return true; 1411 } 1412 1413 bool MethodVerifier::CheckBranchTarget(uint32_t cur_offset) { 1414 int32_t offset; 1415 bool isConditional, selfOkay; 1416 if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) { 1417 return false; 1418 } 1419 if (!selfOkay && offset == 0) { 1420 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at" 1421 << reinterpret_cast<void*>(cur_offset); 1422 return false; 1423 } 1424 // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime 1425 // to have identical "wrap-around" behavior, but it's unwise to depend on that. 1426 if (((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset)) { 1427 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow " 1428 << reinterpret_cast<void*>(cur_offset) << " +" << offset; 1429 return false; 1430 } 1431 const uint32_t insn_count = code_item_->insns_size_in_code_units_; 1432 int32_t abs_offset = cur_offset + offset; 1433 if (abs_offset < 0 || 1434 (uint32_t) abs_offset >= insn_count || 1435 !GetInstructionFlags(abs_offset).IsOpcode()) { 1436 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> " 1437 << reinterpret_cast<void*>(abs_offset) << ") at " 1438 << reinterpret_cast<void*>(cur_offset); 1439 return false; 1440 } 1441 GetInstructionFlags(abs_offset).SetBranchTarget(); 1442 return true; 1443 } 1444 1445 bool MethodVerifier::GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional, 1446 bool* selfOkay) { 1447 const uint16_t* insns = code_item_->insns_ + cur_offset; 1448 *pConditional = false; 1449 *selfOkay = false; 1450 switch (*insns & 0xff) { 1451 case Instruction::GOTO: 1452 *pOffset = ((int16_t) *insns) >> 8; 1453 break; 1454 case Instruction::GOTO_32: 1455 *pOffset = insns[1] | (((uint32_t) insns[2]) << 16); 1456 *selfOkay = true; 1457 break; 1458 case Instruction::GOTO_16: 1459 *pOffset = (int16_t) insns[1]; 1460 break; 1461 case Instruction::IF_EQ: 1462 case Instruction::IF_NE: 1463 case Instruction::IF_LT: 1464 case Instruction::IF_GE: 1465 case Instruction::IF_GT: 1466 case Instruction::IF_LE: 1467 case Instruction::IF_EQZ: 1468 case Instruction::IF_NEZ: 1469 case Instruction::IF_LTZ: 1470 case Instruction::IF_GEZ: 1471 case Instruction::IF_GTZ: 1472 case Instruction::IF_LEZ: 1473 *pOffset = (int16_t) insns[1]; 1474 *pConditional = true; 1475 break; 1476 default: 1477 return false; 1478 } 1479 return true; 1480 } 1481 1482 bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) { 1483 const uint32_t insn_count = code_item_->insns_size_in_code_units_; 1484 DCHECK_LT(cur_offset, insn_count); 1485 const uint16_t* insns = code_item_->insns_ + cur_offset; 1486 /* make sure the start of the switch is in range */ 1487 int32_t switch_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 1488 if (static_cast<int32_t>(cur_offset) + switch_offset < 0 || 1489 cur_offset + switch_offset + 2 > insn_count) { 1490 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset 1491 << ", switch offset " << switch_offset 1492 << ", count " << insn_count; 1493 return false; 1494 } 1495 /* offset to switch table is a relative branch-style offset */ 1496 const uint16_t* switch_insns = insns + switch_offset; 1497 // Make sure the table is at an even dex pc, that is, 32-bit aligned. 1498 if (!IsAligned<4>(switch_insns)) { 1499 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset 1500 << ", switch offset " << switch_offset; 1501 return false; 1502 } 1503 // Make sure the switch data is marked as an opcode. This ensures that it was reached when 1504 // traversing the code item linearly. It is an approximation for a by-spec padding value. 1505 if (!GetInstructionFlags(cur_offset + switch_offset).IsOpcode()) { 1506 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "switch table at " << cur_offset 1507 << ", switch offset " << switch_offset 1508 << " not correctly visited, probably bad padding."; 1509 return false; 1510 } 1511 1512 bool is_packed_switch = (*insns & 0xff) == Instruction::PACKED_SWITCH; 1513 1514 uint32_t switch_count = switch_insns[1]; 1515 int32_t targets_offset; 1516 uint16_t expected_signature; 1517 if (is_packed_switch) { 1518 /* 0=sig, 1=count, 2/3=firstKey */ 1519 targets_offset = 4; 1520 expected_signature = Instruction::kPackedSwitchSignature; 1521 } else { 1522 /* 0=sig, 1=count, 2..count*2 = keys */ 1523 targets_offset = 2 + 2 * switch_count; 1524 expected_signature = Instruction::kSparseSwitchSignature; 1525 } 1526 uint32_t table_size = targets_offset + switch_count * 2; 1527 if (switch_insns[0] != expected_signature) { 1528 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 1529 << StringPrintf("wrong signature for switch table (%x, wanted %x)", 1530 switch_insns[0], expected_signature); 1531 return false; 1532 } 1533 /* make sure the end of the switch is in range */ 1534 if (cur_offset + switch_offset + table_size > (uint32_t) insn_count) { 1535 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset 1536 << ", switch offset " << switch_offset 1537 << ", end " << (cur_offset + switch_offset + table_size) 1538 << ", count " << insn_count; 1539 return false; 1540 } 1541 1542 constexpr int32_t keys_offset = 2; 1543 if (switch_count > 1) { 1544 if (is_packed_switch) { 1545 /* for a packed switch, verify that keys do not overflow int32 */ 1546 int32_t first_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16); 1547 int32_t max_first_key = 1548 std::numeric_limits<int32_t>::max() - (static_cast<int32_t>(switch_count) - 1); 1549 if (first_key > max_first_key) { 1550 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: first_key=" << first_key 1551 << ", switch_count=" << switch_count; 1552 return false; 1553 } 1554 } else { 1555 /* for a sparse switch, verify the keys are in ascending order */ 1556 int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16); 1557 for (uint32_t targ = 1; targ < switch_count; targ++) { 1558 int32_t key = 1559 static_cast<int32_t>(switch_insns[keys_offset + targ * 2]) | 1560 static_cast<int32_t>(switch_insns[keys_offset + targ * 2 + 1] << 16); 1561 if (key <= last_key) { 1562 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid sparse switch: last key=" << last_key 1563 << ", this=" << key; 1564 return false; 1565 } 1566 last_key = key; 1567 } 1568 } 1569 } 1570 /* verify each switch target */ 1571 for (uint32_t targ = 0; targ < switch_count; targ++) { 1572 int32_t offset = static_cast<int32_t>(switch_insns[targets_offset + targ * 2]) | 1573 static_cast<int32_t>(switch_insns[targets_offset + targ * 2 + 1] << 16); 1574 int32_t abs_offset = cur_offset + offset; 1575 if (abs_offset < 0 || 1576 abs_offset >= static_cast<int32_t>(insn_count) || 1577 !GetInstructionFlags(abs_offset).IsOpcode()) { 1578 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset 1579 << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at " 1580 << reinterpret_cast<void*>(cur_offset) 1581 << "[" << targ << "]"; 1582 return false; 1583 } 1584 GetInstructionFlags(abs_offset).SetBranchTarget(); 1585 } 1586 return true; 1587 } 1588 1589 bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) { 1590 uint16_t registers_size = code_item_->registers_size_; 1591 for (uint32_t idx = 0; idx < vA; idx++) { 1592 if (arg[idx] >= registers_size) { 1593 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx] 1594 << ") in non-range invoke (>= " << registers_size << ")"; 1595 return false; 1596 } 1597 } 1598 1599 return true; 1600 } 1601 1602 bool MethodVerifier::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) { 1603 uint16_t registers_size = code_item_->registers_size_; 1604 // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of 1605 // integer overflow when adding them here. 1606 if (vA + vC > registers_size) { 1607 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC 1608 << " in range invoke (> " << registers_size << ")"; 1609 return false; 1610 } 1611 return true; 1612 } 1613 1614 bool MethodVerifier::VerifyCodeFlow() { 1615 uint16_t registers_size = code_item_->registers_size_; 1616 uint32_t insns_size = code_item_->insns_size_in_code_units_; 1617 1618 /* Create and initialize table holding register status */ 1619 reg_table_.Init(kTrackCompilerInterestPoints, 1620 insn_flags_.get(), 1621 insns_size, 1622 registers_size, 1623 this); 1624 1625 work_line_.reset(RegisterLine::Create(registers_size, this)); 1626 saved_line_.reset(RegisterLine::Create(registers_size, this)); 1627 1628 /* Initialize register types of method arguments. */ 1629 if (!SetTypesFromSignature()) { 1630 DCHECK_NE(failures_.size(), 0U); 1631 std::string prepend("Bad signature in "); 1632 prepend += dex_file_->PrettyMethod(dex_method_idx_); 1633 PrependToLastFailMessage(prepend); 1634 return false; 1635 } 1636 // We may have a runtime failure here, clear. 1637 have_pending_runtime_throw_failure_ = false; 1638 1639 /* Perform code flow verification. */ 1640 if (!CodeFlowVerifyMethod()) { 1641 DCHECK_NE(failures_.size(), 0U); 1642 return false; 1643 } 1644 return true; 1645 } 1646 1647 std::ostream& MethodVerifier::DumpFailures(std::ostream& os) { 1648 DCHECK_EQ(failures_.size(), failure_messages_.size()); 1649 for (size_t i = 0; i < failures_.size(); ++i) { 1650 os << failure_messages_[i]->str() << "\n"; 1651 } 1652 return os; 1653 } 1654 1655 void MethodVerifier::Dump(std::ostream& os) { 1656 VariableIndentationOutputStream vios(&os); 1657 Dump(&vios); 1658 } 1659 1660 void MethodVerifier::Dump(VariableIndentationOutputStream* vios) { 1661 if (code_item_ == nullptr) { 1662 vios->Stream() << "Native method\n"; 1663 return; 1664 } 1665 { 1666 vios->Stream() << "Register Types:\n"; 1667 ScopedIndentation indent1(vios); 1668 reg_types_.Dump(vios->Stream()); 1669 } 1670 vios->Stream() << "Dumping instructions and register lines:\n"; 1671 ScopedIndentation indent1(vios); 1672 const Instruction* inst = Instruction::At(code_item_->insns_); 1673 for (size_t dex_pc = 0; dex_pc < code_item_->insns_size_in_code_units_; 1674 dex_pc += inst->SizeInCodeUnits(), inst = inst->Next()) { 1675 RegisterLine* reg_line = reg_table_.GetLine(dex_pc); 1676 if (reg_line != nullptr) { 1677 vios->Stream() << reg_line->Dump(this) << "\n"; 1678 } 1679 vios->Stream() 1680 << StringPrintf("0x%04zx", dex_pc) << ": " << GetInstructionFlags(dex_pc).ToString() << " "; 1681 const bool kDumpHexOfInstruction = false; 1682 if (kDumpHexOfInstruction) { 1683 vios->Stream() << inst->DumpHex(5) << " "; 1684 } 1685 vios->Stream() << inst->DumpString(dex_file_) << "\n"; 1686 } 1687 } 1688 1689 static bool IsPrimitiveDescriptor(char descriptor) { 1690 switch (descriptor) { 1691 case 'I': 1692 case 'C': 1693 case 'S': 1694 case 'B': 1695 case 'Z': 1696 case 'F': 1697 case 'D': 1698 case 'J': 1699 return true; 1700 default: 1701 return false; 1702 } 1703 } 1704 1705 bool MethodVerifier::SetTypesFromSignature() { 1706 RegisterLine* reg_line = reg_table_.GetLine(0); 1707 1708 // Should have been verified earlier. 1709 DCHECK_GE(code_item_->registers_size_, code_item_->ins_size_); 1710 1711 uint32_t arg_start = code_item_->registers_size_ - code_item_->ins_size_; 1712 size_t expected_args = code_item_->ins_size_; /* long/double count as two */ 1713 1714 // Include the "this" pointer. 1715 size_t cur_arg = 0; 1716 if (!IsStatic()) { 1717 if (expected_args == 0) { 1718 // Expect at least a receiver. 1719 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected 0 args, but method is not static"; 1720 return false; 1721 } 1722 1723 // If this is a constructor for a class other than java.lang.Object, mark the first ("this") 1724 // argument as uninitialized. This restricts field access until the superclass constructor is 1725 // called. 1726 const RegType& declaring_class = GetDeclaringClass(); 1727 if (IsConstructor()) { 1728 if (declaring_class.IsJavaLangObject()) { 1729 // "this" is implicitly initialized. 1730 reg_line->SetThisInitialized(); 1731 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class); 1732 } else { 1733 reg_line->SetRegisterType<LockOp::kClear>( 1734 this, 1735 arg_start + cur_arg, 1736 reg_types_.UninitializedThisArgument(declaring_class)); 1737 } 1738 } else { 1739 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class); 1740 } 1741 cur_arg++; 1742 } 1743 1744 const DexFile::ProtoId& proto_id = 1745 dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_)); 1746 DexFileParameterIterator iterator(*dex_file_, proto_id); 1747 1748 for (; iterator.HasNext(); iterator.Next()) { 1749 const char* descriptor = iterator.GetDescriptor(); 1750 if (descriptor == nullptr) { 1751 LOG(FATAL) << "Null descriptor"; 1752 } 1753 if (cur_arg >= expected_args) { 1754 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1755 << " args, found more (" << descriptor << ")"; 1756 return false; 1757 } 1758 switch (descriptor[0]) { 1759 case 'L': 1760 case '[': 1761 // We assume that reference arguments are initialized. The only way it could be otherwise 1762 // (assuming the caller was verified) is if the current method is <init>, but in that case 1763 // it's effectively considered initialized the instant we reach here (in the sense that we 1764 // can return without doing anything or call virtual methods). 1765 { 1766 const RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx()); 1767 if (!reg_type.IsNonZeroReferenceTypes()) { 1768 DCHECK(HasFailures()); 1769 return false; 1770 } 1771 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_type); 1772 } 1773 break; 1774 case 'Z': 1775 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Boolean()); 1776 break; 1777 case 'C': 1778 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Char()); 1779 break; 1780 case 'B': 1781 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Byte()); 1782 break; 1783 case 'I': 1784 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Integer()); 1785 break; 1786 case 'S': 1787 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Short()); 1788 break; 1789 case 'F': 1790 reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Float()); 1791 break; 1792 case 'J': 1793 case 'D': { 1794 if (cur_arg + 1 >= expected_args) { 1795 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1796 << " args, found more (" << descriptor << ")"; 1797 return false; 1798 } 1799 1800 const RegType* lo_half; 1801 const RegType* hi_half; 1802 if (descriptor[0] == 'J') { 1803 lo_half = ®_types_.LongLo(); 1804 hi_half = ®_types_.LongHi(); 1805 } else { 1806 lo_half = ®_types_.DoubleLo(); 1807 hi_half = ®_types_.DoubleHi(); 1808 } 1809 reg_line->SetRegisterTypeWide(this, arg_start + cur_arg, *lo_half, *hi_half); 1810 cur_arg++; 1811 break; 1812 } 1813 default: 1814 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '" 1815 << descriptor << "'"; 1816 return false; 1817 } 1818 cur_arg++; 1819 } 1820 if (cur_arg != expected_args) { 1821 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args 1822 << " arguments, found " << cur_arg; 1823 return false; 1824 } 1825 const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id); 1826 // Validate return type. We don't do the type lookup; just want to make sure that it has the right 1827 // format. Only major difference from the method argument format is that 'V' is supported. 1828 bool result; 1829 if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') { 1830 result = descriptor[1] == '\0'; 1831 } else if (descriptor[0] == '[') { // single/multi-dimensional array of object/primitive 1832 size_t i = 0; 1833 do { 1834 i++; 1835 } while (descriptor[i] == '['); // process leading [ 1836 if (descriptor[i] == 'L') { // object array 1837 do { 1838 i++; // find closing ; 1839 } while (descriptor[i] != ';' && descriptor[i] != '\0'); 1840 result = descriptor[i] == ';'; 1841 } else { // primitive array 1842 result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0'; 1843 } 1844 } else if (descriptor[0] == 'L') { 1845 // could be more thorough here, but shouldn't be required 1846 size_t i = 0; 1847 do { 1848 i++; 1849 } while (descriptor[i] != ';' && descriptor[i] != '\0'); 1850 result = descriptor[i] == ';'; 1851 } else { 1852 result = false; 1853 } 1854 if (!result) { 1855 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '" 1856 << descriptor << "'"; 1857 } 1858 return result; 1859 } 1860 1861 bool MethodVerifier::CodeFlowVerifyMethod() { 1862 const uint16_t* insns = code_item_->insns_; 1863 const uint32_t insns_size = code_item_->insns_size_in_code_units_; 1864 1865 /* Begin by marking the first instruction as "changed". */ 1866 GetInstructionFlags(0).SetChanged(); 1867 uint32_t start_guess = 0; 1868 1869 /* Continue until no instructions are marked "changed". */ 1870 while (true) { 1871 if (allow_thread_suspension_) { 1872 self_->AllowThreadSuspension(); 1873 } 1874 // Find the first marked one. Use "start_guess" as a way to find one quickly. 1875 uint32_t insn_idx = start_guess; 1876 for (; insn_idx < insns_size; insn_idx++) { 1877 if (GetInstructionFlags(insn_idx).IsChanged()) 1878 break; 1879 } 1880 if (insn_idx == insns_size) { 1881 if (start_guess != 0) { 1882 /* try again, starting from the top */ 1883 start_guess = 0; 1884 continue; 1885 } else { 1886 /* all flags are clear */ 1887 break; 1888 } 1889 } 1890 // We carry the working set of registers from instruction to instruction. If this address can 1891 // be the target of a branch (or throw) instruction, or if we're skipping around chasing 1892 // "changed" flags, we need to load the set of registers from the table. 1893 // Because we always prefer to continue on to the next instruction, we should never have a 1894 // situation where we have a stray "changed" flag set on an instruction that isn't a branch 1895 // target. 1896 work_insn_idx_ = insn_idx; 1897 if (GetInstructionFlags(insn_idx).IsBranchTarget()) { 1898 work_line_->CopyFromLine(reg_table_.GetLine(insn_idx)); 1899 } else if (kIsDebugBuild) { 1900 /* 1901 * Sanity check: retrieve the stored register line (assuming 1902 * a full table) and make sure it actually matches. 1903 */ 1904 RegisterLine* register_line = reg_table_.GetLine(insn_idx); 1905 if (register_line != nullptr) { 1906 if (work_line_->CompareLine(register_line) != 0) { 1907 Dump(std::cout); 1908 std::cout << info_messages_.str(); 1909 LOG(FATAL) << "work_line diverged in " << dex_file_->PrettyMethod(dex_method_idx_) 1910 << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n" 1911 << " work_line=" << work_line_->Dump(this) << "\n" 1912 << " expected=" << register_line->Dump(this); 1913 } 1914 } 1915 } 1916 if (!CodeFlowVerifyInstruction(&start_guess)) { 1917 std::string prepend(dex_file_->PrettyMethod(dex_method_idx_)); 1918 prepend += " failed to verify: "; 1919 PrependToLastFailMessage(prepend); 1920 return false; 1921 } 1922 /* Clear "changed" and mark as visited. */ 1923 GetInstructionFlags(insn_idx).SetVisited(); 1924 GetInstructionFlags(insn_idx).ClearChanged(); 1925 } 1926 1927 if (kDebugVerify) { 1928 /* 1929 * Scan for dead code. There's nothing "evil" about dead code 1930 * (besides the wasted space), but it indicates a flaw somewhere 1931 * down the line, possibly in the verifier. 1932 * 1933 * If we've substituted "always throw" instructions into the stream, 1934 * we are almost certainly going to have some dead code. 1935 */ 1936 int dead_start = -1; 1937 uint32_t insn_idx = 0; 1938 for (; insn_idx < insns_size; 1939 insn_idx += Instruction::At(code_item_->insns_ + insn_idx)->SizeInCodeUnits()) { 1940 /* 1941 * Switch-statement data doesn't get "visited" by scanner. It 1942 * may or may not be preceded by a padding NOP (for alignment). 1943 */ 1944 if (insns[insn_idx] == Instruction::kPackedSwitchSignature || 1945 insns[insn_idx] == Instruction::kSparseSwitchSignature || 1946 insns[insn_idx] == Instruction::kArrayDataSignature || 1947 (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) && 1948 (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature || 1949 insns[insn_idx + 1] == Instruction::kSparseSwitchSignature || 1950 insns[insn_idx + 1] == Instruction::kArrayDataSignature))) { 1951 GetInstructionFlags(insn_idx).SetVisited(); 1952 } 1953 1954 if (!GetInstructionFlags(insn_idx).IsVisited()) { 1955 if (dead_start < 0) 1956 dead_start = insn_idx; 1957 } else if (dead_start >= 0) { 1958 LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start) 1959 << "-" << reinterpret_cast<void*>(insn_idx - 1); 1960 dead_start = -1; 1961 } 1962 } 1963 if (dead_start >= 0) { 1964 LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start) 1965 << "-" << reinterpret_cast<void*>(insn_idx - 1); 1966 } 1967 // To dump the state of the verify after a method, do something like: 1968 // if (dex_file_->PrettyMethod(dex_method_idx_) == 1969 // "boolean java.lang.String.equals(java.lang.Object)") { 1970 // LOG(INFO) << info_messages_.str(); 1971 // } 1972 } 1973 return true; 1974 } 1975 1976 // Returns the index of the first final instance field of the given class, or kDexNoIndex if there 1977 // is no such field. 1978 static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) { 1979 const DexFile::ClassDef* class_def = dex_file.FindClassDef(type_idx); 1980 DCHECK(class_def != nullptr); 1981 const uint8_t* class_data = dex_file.GetClassData(*class_def); 1982 DCHECK(class_data != nullptr); 1983 ClassDataItemIterator it(dex_file, class_data); 1984 // Skip static fields. 1985 while (it.HasNextStaticField()) { 1986 it.Next(); 1987 } 1988 while (it.HasNextInstanceField()) { 1989 if ((it.GetFieldAccessFlags() & kAccFinal) != 0) { 1990 return it.GetMemberIndex(); 1991 } 1992 it.Next(); 1993 } 1994 return DexFile::kDexNoIndex; 1995 } 1996 1997 // Setup a register line for the given return instruction. 1998 static void AdjustReturnLine(MethodVerifier* verifier, 1999 const Instruction* ret_inst, 2000 RegisterLine* line) { 2001 Instruction::Code opcode = ret_inst->Opcode(); 2002 2003 switch (opcode) { 2004 case Instruction::RETURN_VOID: 2005 case Instruction::RETURN_VOID_NO_BARRIER: 2006 SafelyMarkAllRegistersAsConflicts(verifier, line); 2007 break; 2008 2009 case Instruction::RETURN: 2010 case Instruction::RETURN_OBJECT: 2011 line->MarkAllRegistersAsConflictsExcept(verifier, ret_inst->VRegA_11x()); 2012 break; 2013 2014 case Instruction::RETURN_WIDE: 2015 line->MarkAllRegistersAsConflictsExceptWide(verifier, ret_inst->VRegA_11x()); 2016 break; 2017 2018 default: 2019 LOG(FATAL) << "Unknown return opcode " << opcode; 2020 UNREACHABLE(); 2021 } 2022 } 2023 2024 bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { 2025 // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about. 2026 // We want the state _before_ the instruction, for the case where the dex pc we're 2027 // interested in is itself a monitor-enter instruction (which is a likely place 2028 // for a thread to be suspended). 2029 if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) { 2030 monitor_enter_dex_pcs_->clear(); // The new work line is more accurate than the previous one. 2031 for (size_t i = 0; i < work_line_->GetMonitorEnterCount(); ++i) { 2032 monitor_enter_dex_pcs_->push_back(work_line_->GetMonitorEnterDexPc(i)); 2033 } 2034 } 2035 2036 /* 2037 * Once we finish decoding the instruction, we need to figure out where 2038 * we can go from here. There are three possible ways to transfer 2039 * control to another statement: 2040 * 2041 * (1) Continue to the next instruction. Applies to all but 2042 * unconditional branches, method returns, and exception throws. 2043 * (2) Branch to one or more possible locations. Applies to branches 2044 * and switch statements. 2045 * (3) Exception handlers. Applies to any instruction that can 2046 * throw an exception that is handled by an encompassing "try" 2047 * block. 2048 * 2049 * We can also return, in which case there is no successor instruction 2050 * from this point. 2051 * 2052 * The behavior can be determined from the opcode flags. 2053 */ 2054 const uint16_t* insns = code_item_->insns_ + work_insn_idx_; 2055 const Instruction* inst = Instruction::At(insns); 2056 int opcode_flags = Instruction::FlagsOf(inst->Opcode()); 2057 2058 int32_t branch_target = 0; 2059 bool just_set_result = false; 2060 if (kDebugVerify) { 2061 // Generate processing back trace to debug verifier 2062 LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n" 2063 << work_line_->Dump(this) << "\n"; 2064 } 2065 2066 /* 2067 * Make a copy of the previous register state. If the instruction 2068 * can throw an exception, we will copy/merge this into the "catch" 2069 * address rather than work_line, because we don't want the result 2070 * from the "successful" code path (e.g. a check-cast that "improves" 2071 * a type) to be visible to the exception handler. 2072 */ 2073 if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) { 2074 saved_line_->CopyFromLine(work_line_.get()); 2075 } else if (kIsDebugBuild) { 2076 saved_line_->FillWithGarbage(); 2077 } 2078 DCHECK(!have_pending_runtime_throw_failure_); // Per-instruction flag, should not be set here. 2079 2080 2081 // We need to ensure the work line is consistent while performing validation. When we spot a 2082 // peephole pattern we compute a new line for either the fallthrough instruction or the 2083 // branch target. 2084 RegisterLineArenaUniquePtr branch_line; 2085 RegisterLineArenaUniquePtr fallthrough_line; 2086 2087 switch (inst->Opcode()) { 2088 case Instruction::NOP: 2089 /* 2090 * A "pure" NOP has no effect on anything. Data tables start with 2091 * a signature that looks like a NOP; if we see one of these in 2092 * the course of executing code then we have a problem. 2093 */ 2094 if (inst->VRegA_10x() != 0) { 2095 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream"; 2096 } 2097 break; 2098 2099 case Instruction::MOVE: 2100 work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr); 2101 break; 2102 case Instruction::MOVE_FROM16: 2103 work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr); 2104 break; 2105 case Instruction::MOVE_16: 2106 work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr); 2107 break; 2108 case Instruction::MOVE_WIDE: 2109 work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x()); 2110 break; 2111 case Instruction::MOVE_WIDE_FROM16: 2112 work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x()); 2113 break; 2114 case Instruction::MOVE_WIDE_16: 2115 work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x()); 2116 break; 2117 case Instruction::MOVE_OBJECT: 2118 work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef); 2119 break; 2120 case Instruction::MOVE_OBJECT_FROM16: 2121 work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef); 2122 break; 2123 case Instruction::MOVE_OBJECT_16: 2124 work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef); 2125 break; 2126 2127 /* 2128 * The move-result instructions copy data out of a "pseudo-register" 2129 * with the results from the last method invocation. In practice we 2130 * might want to hold the result in an actual CPU register, so the 2131 * Dalvik spec requires that these only appear immediately after an 2132 * invoke or filled-new-array. 2133 * 2134 * These calls invalidate the "result" register. (This is now 2135 * redundant with the reset done below, but it can make the debug info 2136 * easier to read in some cases.) 2137 */ 2138 case Instruction::MOVE_RESULT: 2139 work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false); 2140 break; 2141 case Instruction::MOVE_RESULT_WIDE: 2142 work_line_->CopyResultRegister2(this, inst->VRegA_11x()); 2143 break; 2144 case Instruction::MOVE_RESULT_OBJECT: 2145 work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true); 2146 break; 2147 2148 case Instruction::MOVE_EXCEPTION: { 2149 // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case 2150 // where one entrypoint to the catch block is not actually an exception path. 2151 if (work_insn_idx_ == 0) { 2152 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0"; 2153 break; 2154 } 2155 /* 2156 * This statement can only appear as the first instruction in an exception handler. We verify 2157 * that as part of extracting the exception type from the catch block list. 2158 */ 2159 const RegType& res_type = GetCaughtExceptionType(); 2160 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_11x(), res_type); 2161 break; 2162 } 2163 case Instruction::RETURN_VOID: 2164 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2165 if (!GetMethodReturnType().IsConflict()) { 2166 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected"; 2167 } 2168 } 2169 break; 2170 case Instruction::RETURN: 2171 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2172 /* check the method signature */ 2173 const RegType& return_type = GetMethodReturnType(); 2174 if (!return_type.IsCategory1Types()) { 2175 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type " 2176 << return_type; 2177 } else { 2178 // Compilers may generate synthetic functions that write byte values into boolean fields. 2179 // Also, it may use integer values for boolean, byte, short, and character return types. 2180 const uint32_t vregA = inst->VRegA_11x(); 2181 const RegType& src_type = work_line_->GetRegisterType(this, vregA); 2182 bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) || 2183 ((return_type.IsBoolean() || return_type.IsByte() || 2184 return_type.IsShort() || return_type.IsChar()) && 2185 src_type.IsInteger())); 2186 /* check the register contents */ 2187 bool success = 2188 work_line_->VerifyRegisterType(this, vregA, use_src ? src_type : return_type); 2189 if (!success) { 2190 AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA)); 2191 } 2192 } 2193 } 2194 break; 2195 case Instruction::RETURN_WIDE: 2196 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2197 /* check the method signature */ 2198 const RegType& return_type = GetMethodReturnType(); 2199 if (!return_type.IsCategory2Types()) { 2200 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected"; 2201 } else { 2202 /* check the register contents */ 2203 const uint32_t vregA = inst->VRegA_11x(); 2204 bool success = work_line_->VerifyRegisterType(this, vregA, return_type); 2205 if (!success) { 2206 AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA)); 2207 } 2208 } 2209 } 2210 break; 2211 case Instruction::RETURN_OBJECT: 2212 if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) { 2213 const RegType& return_type = GetMethodReturnType(); 2214 if (!return_type.IsReferenceTypes()) { 2215 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected"; 2216 } else { 2217 /* return_type is the *expected* return type, not register value */ 2218 DCHECK(!return_type.IsZero()); 2219 DCHECK(!return_type.IsUninitializedReference()); 2220 const uint32_t vregA = inst->VRegA_11x(); 2221 const RegType& reg_type = work_line_->GetRegisterType(this, vregA); 2222 // Disallow returning undefined, conflict & uninitialized values and verify that the 2223 // reference in vAA is an instance of the "return_type." 2224 if (reg_type.IsUndefined()) { 2225 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning undefined register"; 2226 } else if (reg_type.IsConflict()) { 2227 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning register with conflict"; 2228 } else if (reg_type.IsUninitializedTypes()) { 2229 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning uninitialized object '" 2230 << reg_type << "'"; 2231 } else if (!reg_type.IsReferenceTypes()) { 2232 // We really do expect a reference here. 2233 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object returns a non-reference type " 2234 << reg_type; 2235 } else if (!return_type.IsAssignableFrom(reg_type, this)) { 2236 if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) { 2237 Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type 2238 << "' or '" << reg_type << "'"; 2239 } else { 2240 bool soft_error = false; 2241 // Check whether arrays are involved. They will show a valid class status, even 2242 // if their components are erroneous. 2243 if (reg_type.IsArrayTypes() && return_type.IsArrayTypes()) { 2244 return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this, &soft_error); 2245 if (soft_error) { 2246 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "array with erroneous component type: " 2247 << reg_type << " vs " << return_type; 2248 } 2249 } 2250 2251 if (!soft_error) { 2252 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type 2253 << "', but expected from declaration '" << return_type << "'"; 2254 } 2255 } 2256 } 2257 } 2258 } 2259 break; 2260 2261 /* could be boolean, int, float, or a null reference */ 2262 case Instruction::CONST_4: { 2263 int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28; 2264 work_line_->SetRegisterType<LockOp::kClear>( 2265 this, inst->VRegA_11n(), DetermineCat1Constant(val, need_precise_constants_)); 2266 break; 2267 } 2268 case Instruction::CONST_16: { 2269 int16_t val = static_cast<int16_t>(inst->VRegB_21s()); 2270 work_line_->SetRegisterType<LockOp::kClear>( 2271 this, inst->VRegA_21s(), DetermineCat1Constant(val, need_precise_constants_)); 2272 break; 2273 } 2274 case Instruction::CONST: { 2275 int32_t val = inst->VRegB_31i(); 2276 work_line_->SetRegisterType<LockOp::kClear>( 2277 this, inst->VRegA_31i(), DetermineCat1Constant(val, need_precise_constants_)); 2278 break; 2279 } 2280 case Instruction::CONST_HIGH16: { 2281 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16); 2282 work_line_->SetRegisterType<LockOp::kClear>( 2283 this, inst->VRegA_21h(), DetermineCat1Constant(val, need_precise_constants_)); 2284 break; 2285 } 2286 /* could be long or double; resolved upon use */ 2287 case Instruction::CONST_WIDE_16: { 2288 int64_t val = static_cast<int16_t>(inst->VRegB_21s()); 2289 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2290 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2291 work_line_->SetRegisterTypeWide(this, inst->VRegA_21s(), lo, hi); 2292 break; 2293 } 2294 case Instruction::CONST_WIDE_32: { 2295 int64_t val = static_cast<int32_t>(inst->VRegB_31i()); 2296 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2297 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2298 work_line_->SetRegisterTypeWide(this, inst->VRegA_31i(), lo, hi); 2299 break; 2300 } 2301 case Instruction::CONST_WIDE: { 2302 int64_t val = inst->VRegB_51l(); 2303 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2304 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2305 work_line_->SetRegisterTypeWide(this, inst->VRegA_51l(), lo, hi); 2306 break; 2307 } 2308 case Instruction::CONST_WIDE_HIGH16: { 2309 int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48; 2310 const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true); 2311 const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 2312 work_line_->SetRegisterTypeWide(this, inst->VRegA_21h(), lo, hi); 2313 break; 2314 } 2315 case Instruction::CONST_STRING: 2316 work_line_->SetRegisterType<LockOp::kClear>( 2317 this, inst->VRegA_21c(), reg_types_.JavaLangString()); 2318 break; 2319 case Instruction::CONST_STRING_JUMBO: 2320 work_line_->SetRegisterType<LockOp::kClear>( 2321 this, inst->VRegA_31c(), reg_types_.JavaLangString()); 2322 break; 2323 case Instruction::CONST_CLASS: { 2324 // Get type from instruction if unresolved then we need an access check 2325 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2326 const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); 2327 // Register holds class, ie its type is class, on error it will hold Conflict. 2328 work_line_->SetRegisterType<LockOp::kClear>( 2329 this, inst->VRegA_21c(), res_type.IsConflict() ? res_type 2330 : reg_types_.JavaLangClass()); 2331 break; 2332 } 2333 case Instruction::MONITOR_ENTER: 2334 work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_); 2335 // Check whether the previous instruction is a move-object with vAA as a source, creating 2336 // untracked lock aliasing. 2337 if (0 != work_insn_idx_ && !GetInstructionFlags(work_insn_idx_).IsBranchTarget()) { 2338 uint32_t prev_idx = work_insn_idx_ - 1; 2339 while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) { 2340 prev_idx--; 2341 } 2342 const Instruction* prev_inst = Instruction::At(code_item_->insns_ + prev_idx); 2343 switch (prev_inst->Opcode()) { 2344 case Instruction::MOVE_OBJECT: 2345 case Instruction::MOVE_OBJECT_16: 2346 case Instruction::MOVE_OBJECT_FROM16: 2347 if (prev_inst->VRegB() == inst->VRegA_11x()) { 2348 // Redo the copy. This won't change the register types, but update the lock status 2349 // for the aliased register. 2350 work_line_->CopyRegister1(this, 2351 prev_inst->VRegA(), 2352 prev_inst->VRegB(), 2353 kTypeCategoryRef); 2354 } 2355 break; 2356 2357 default: // Other instruction types ignored. 2358 break; 2359 } 2360 } 2361 break; 2362 case Instruction::MONITOR_EXIT: 2363 /* 2364 * monitor-exit instructions are odd. They can throw exceptions, 2365 * but when they do they act as if they succeeded and the PC is 2366 * pointing to the following instruction. (This behavior goes back 2367 * to the need to handle asynchronous exceptions, a now-deprecated 2368 * feature that Dalvik doesn't support.) 2369 * 2370 * In practice we don't need to worry about this. The only 2371 * exceptions that can be thrown from monitor-exit are for a 2372 * null reference and -exit without a matching -enter. If the 2373 * structured locking checks are working, the former would have 2374 * failed on the -enter instruction, and the latter is impossible. 2375 * 2376 * This is fortunate, because issue 3221411 prevents us from 2377 * chasing the "can throw" path when monitor verification is 2378 * enabled. If we can fully verify the locking we can ignore 2379 * some catch blocks (which will show up as "dead" code when 2380 * we skip them here); if we can't, then the code path could be 2381 * "live" so we still need to check it. 2382 */ 2383 opcode_flags &= ~Instruction::kThrow; 2384 work_line_->PopMonitor(this, inst->VRegA_11x()); 2385 break; 2386 case Instruction::CHECK_CAST: 2387 case Instruction::INSTANCE_OF: { 2388 /* 2389 * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This 2390 * could be a "upcast" -- not expected, so we don't try to address it.) 2391 * 2392 * If it fails, an exception is thrown, which we deal with later by ignoring the update to 2393 * dec_insn.vA when branching to a handler. 2394 */ 2395 const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST); 2396 const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c()); 2397 const RegType& res_type = ResolveClassAndCheckAccess(type_idx); 2398 if (res_type.IsConflict()) { 2399 // If this is a primitive type, fail HARD. 2400 ObjPtr<mirror::Class> klass = 2401 ClassLinker::LookupResolvedType(type_idx, dex_cache_.Get(), class_loader_.Get()); 2402 if (klass != nullptr && klass->IsPrimitive()) { 2403 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type " 2404 << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in " 2405 << GetDeclaringClass(); 2406 break; 2407 } 2408 2409 DCHECK_NE(failures_.size(), 0U); 2410 if (!is_checkcast) { 2411 work_line_->SetRegisterType<LockOp::kClear>(this, 2412 inst->VRegA_22c(), 2413 reg_types_.Boolean()); 2414 } 2415 break; // bad class 2416 } 2417 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2418 uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c(); 2419 const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg); 2420 if (!res_type.IsNonZeroReferenceTypes()) { 2421 if (is_checkcast) { 2422 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type; 2423 } else { 2424 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type; 2425 } 2426 } else if (!orig_type.IsReferenceTypes()) { 2427 if (is_checkcast) { 2428 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg; 2429 } else { 2430 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg; 2431 } 2432 } else if (orig_type.IsUninitializedTypes()) { 2433 if (is_checkcast) { 2434 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on uninitialized reference in v" 2435 << orig_type_reg; 2436 } else { 2437 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on uninitialized reference in v" 2438 << orig_type_reg; 2439 } 2440 } else { 2441 if (is_checkcast) { 2442 work_line_->SetRegisterType<LockOp::kKeep>(this, inst->VRegA_21c(), res_type); 2443 } else { 2444 work_line_->SetRegisterType<LockOp::kClear>(this, 2445 inst->VRegA_22c(), 2446 reg_types_.Boolean()); 2447 } 2448 } 2449 break; 2450 } 2451 case Instruction::ARRAY_LENGTH: { 2452 const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x()); 2453 if (res_type.IsReferenceTypes()) { 2454 if (!res_type.IsArrayTypes() && !res_type.IsZero()) { // ie not an array or null 2455 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type; 2456 } else { 2457 work_line_->SetRegisterType<LockOp::kClear>(this, 2458 inst->VRegA_12x(), 2459 reg_types_.Integer()); 2460 } 2461 } else { 2462 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type; 2463 } 2464 break; 2465 } 2466 case Instruction::NEW_INSTANCE: { 2467 const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c())); 2468 if (res_type.IsConflict()) { 2469 DCHECK_NE(failures_.size(), 0U); 2470 break; // bad class 2471 } 2472 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 2473 // can't create an instance of an interface or abstract class */ 2474 if (!res_type.IsInstantiableTypes()) { 2475 Fail(VERIFY_ERROR_INSTANTIATION) 2476 << "new-instance on primitive, interface or abstract class" << res_type; 2477 // Soft failure so carry on to set register type. 2478 } 2479 const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_); 2480 // Any registers holding previous allocations from this address that have not yet been 2481 // initialized must be marked invalid. 2482 work_line_->MarkUninitRefsAsInvalid(this, uninit_type); 2483 // add the new uninitialized reference to the register state 2484 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_21c(), uninit_type); 2485 break; 2486 } 2487 case Instruction::NEW_ARRAY: 2488 VerifyNewArray(inst, false, false); 2489 break; 2490 case Instruction::FILLED_NEW_ARRAY: 2491 VerifyNewArray(inst, true, false); 2492 just_set_result = true; // Filled new array sets result register 2493 break; 2494 case Instruction::FILLED_NEW_ARRAY_RANGE: 2495 VerifyNewArray(inst, true, true); 2496 just_set_result = true; // Filled new array range sets result register 2497 break; 2498 case Instruction::CMPL_FLOAT: 2499 case Instruction::CMPG_FLOAT: 2500 if (!work_line_->VerifyRegisterType(this, inst->VRegB_23x(), reg_types_.Float())) { 2501 break; 2502 } 2503 if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) { 2504 break; 2505 } 2506 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2507 break; 2508 case Instruction::CMPL_DOUBLE: 2509 case Instruction::CMPG_DOUBLE: 2510 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.DoubleLo(), 2511 reg_types_.DoubleHi())) { 2512 break; 2513 } 2514 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.DoubleLo(), 2515 reg_types_.DoubleHi())) { 2516 break; 2517 } 2518 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2519 break; 2520 case Instruction::CMP_LONG: 2521 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(), 2522 reg_types_.LongHi())) { 2523 break; 2524 } 2525 if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.LongLo(), 2526 reg_types_.LongHi())) { 2527 break; 2528 } 2529 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer()); 2530 break; 2531 case Instruction::THROW: { 2532 const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x()); 2533 if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type, this)) { 2534 if (res_type.IsUninitializedTypes()) { 2535 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown exception not initialized"; 2536 } else if (!res_type.IsReferenceTypes()) { 2537 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown value of non-reference type " << res_type; 2538 } else { 2539 Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT) 2540 << "thrown class " << res_type << " not instanceof Throwable"; 2541 } 2542 } 2543 break; 2544 } 2545 case Instruction::GOTO: 2546 case Instruction::GOTO_16: 2547 case Instruction::GOTO_32: 2548 /* no effect on or use of registers */ 2549 break; 2550 2551 case Instruction::PACKED_SWITCH: 2552 case Instruction::SPARSE_SWITCH: 2553 /* verify that vAA is an integer, or can be converted to one */ 2554 work_line_->VerifyRegisterType(this, inst->VRegA_31t(), reg_types_.Integer()); 2555 break; 2556 2557 case Instruction::FILL_ARRAY_DATA: { 2558 /* Similar to the verification done for APUT */ 2559 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t()); 2560 /* array_type can be null if the reg type is Zero */ 2561 if (!array_type.IsZero()) { 2562 if (!array_type.IsArrayTypes()) { 2563 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type " 2564 << array_type; 2565 } else if (array_type.IsUnresolvedTypes()) { 2566 // If it's an unresolved array type, it must be non-primitive. 2567 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data for array of type " 2568 << array_type; 2569 } else { 2570 const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader()); 2571 DCHECK(!component_type.IsConflict()); 2572 if (component_type.IsNonZeroReferenceTypes()) { 2573 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type " 2574 << component_type; 2575 } else { 2576 // Now verify if the element width in the table matches the element width declared in 2577 // the array 2578 const uint16_t* array_data = 2579 insns + (insns[1] | (static_cast<int32_t>(insns[2]) << 16)); 2580 if (array_data[0] != Instruction::kArrayDataSignature) { 2581 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data"; 2582 } else { 2583 size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType()); 2584 // Since we don't compress the data in Dex, expect to see equal width of data stored 2585 // in the table and expected from the array class. 2586 if (array_data[1] != elem_width) { 2587 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1] 2588 << " vs " << elem_width << ")"; 2589 } 2590 } 2591 } 2592 } 2593 } 2594 break; 2595 } 2596 case Instruction::IF_EQ: 2597 case Instruction::IF_NE: { 2598 const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t()); 2599 const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t()); 2600 bool mismatch = false; 2601 if (reg_type1.IsZero()) { // zero then integral or reference expected 2602 mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes(); 2603 } else if (reg_type1.IsReferenceTypes()) { // both references? 2604 mismatch = !reg_type2.IsReferenceTypes(); 2605 } else { // both integral? 2606 mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes(); 2607 } 2608 if (mismatch) { 2609 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << "," 2610 << reg_type2 << ") must both be references or integral"; 2611 } 2612 break; 2613 } 2614 case Instruction::IF_LT: 2615 case Instruction::IF_GE: 2616 case Instruction::IF_GT: 2617 case Instruction::IF_LE: { 2618 const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t()); 2619 const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t()); 2620 if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) { 2621 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << "," 2622 << reg_type2 << ") must be integral"; 2623 } 2624 break; 2625 } 2626 case Instruction::IF_EQZ: 2627 case Instruction::IF_NEZ: { 2628 const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t()); 2629 if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) { 2630 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type 2631 << " unexpected as arg to if-eqz/if-nez"; 2632 } 2633 2634 // Find previous instruction - its existence is a precondition to peephole optimization. 2635 uint32_t instance_of_idx = 0; 2636 if (0 != work_insn_idx_) { 2637 instance_of_idx = work_insn_idx_ - 1; 2638 while (0 != instance_of_idx && !GetInstructionFlags(instance_of_idx).IsOpcode()) { 2639 instance_of_idx--; 2640 } 2641 if (FailOrAbort(this, GetInstructionFlags(instance_of_idx).IsOpcode(), 2642 "Unable to get previous instruction of if-eqz/if-nez for work index ", 2643 work_insn_idx_)) { 2644 break; 2645 } 2646 } else { 2647 break; 2648 } 2649 2650 const Instruction* instance_of_inst = Instruction::At(code_item_->insns_ + instance_of_idx); 2651 2652 /* Check for peep-hole pattern of: 2653 * ...; 2654 * instance-of vX, vY, T; 2655 * ifXXX vX, label ; 2656 * ...; 2657 * label: 2658 * ...; 2659 * and sharpen the type of vY to be type T. 2660 * Note, this pattern can't be if: 2661 * - if there are other branches to this branch, 2662 * - when vX == vY. 2663 */ 2664 if (!CurrentInsnFlags()->IsBranchTarget() && 2665 (Instruction::INSTANCE_OF == instance_of_inst->Opcode()) && 2666 (inst->VRegA_21t() == instance_of_inst->VRegA_22c()) && 2667 (instance_of_inst->VRegA_22c() != instance_of_inst->VRegB_22c())) { 2668 // Check the type of the instance-of is different than that of registers type, as if they 2669 // are the same there is no work to be done here. Check that the conversion is not to or 2670 // from an unresolved type as type information is imprecise. If the instance-of is to an 2671 // interface then ignore the type information as interfaces can only be treated as Objects 2672 // and we don't want to disallow field and other operations on the object. If the value 2673 // being instance-of checked against is known null (zero) then allow the optimization as 2674 // we didn't have type information. If the merge of the instance-of type with the original 2675 // type is assignable to the original then allow optimization. This check is performed to 2676 // ensure that subsequent merges don't lose type information - such as becoming an 2677 // interface from a class that would lose information relevant to field checks. 2678 const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst->VRegB_22c()); 2679 const RegType& cast_type = ResolveClassAndCheckAccess( 2680 dex::TypeIndex(instance_of_inst->VRegC_22c())); 2681 2682 if (!orig_type.Equals(cast_type) && 2683 !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() && 2684 cast_type.HasClass() && // Could be conflict type, make sure it has a class. 2685 !cast_type.GetClass()->IsInterface() && 2686 (orig_type.IsZero() || 2687 orig_type.IsStrictlyAssignableFrom( 2688 cast_type.Merge(orig_type, ®_types_, this), this))) { 2689 RegisterLine* update_line = RegisterLine::Create(code_item_->registers_size_, this); 2690 if (inst->Opcode() == Instruction::IF_EQZ) { 2691 fallthrough_line.reset(update_line); 2692 } else { 2693 branch_line.reset(update_line); 2694 } 2695 update_line->CopyFromLine(work_line_.get()); 2696 update_line->SetRegisterType<LockOp::kKeep>(this, 2697 instance_of_inst->VRegB_22c(), 2698 cast_type); 2699 if (!GetInstructionFlags(instance_of_idx).IsBranchTarget() && 0 != instance_of_idx) { 2700 // See if instance-of was preceded by a move-object operation, common due to the small 2701 // register encoding space of instance-of, and propagate type information to the source 2702 // of the move-object. 2703 uint32_t move_idx = instance_of_idx - 1; 2704 while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) { 2705 move_idx--; 2706 } 2707 if (FailOrAbort(this, GetInstructionFlags(move_idx).IsOpcode(), 2708 "Unable to get previous instruction of if-eqz/if-nez for work index ", 2709 work_insn_idx_)) { 2710 break; 2711 } 2712 const Instruction* move_inst = Instruction::At(code_item_->insns_ + move_idx); 2713 switch (move_inst->Opcode()) { 2714 case Instruction::MOVE_OBJECT: 2715 if (move_inst->VRegA_12x() == instance_of_inst->VRegB_22c()) { 2716 update_line->SetRegisterType<LockOp::kKeep>(this, 2717 move_inst->VRegB_12x(), 2718 cast_type); 2719 } 2720 break; 2721 case Instruction::MOVE_OBJECT_FROM16: 2722 if (move_inst->VRegA_22x() == instance_of_inst->VRegB_22c()) { 2723 update_line->SetRegisterType<LockOp::kKeep>(this, 2724 move_inst->VRegB_22x(), 2725 cast_type); 2726 } 2727 break; 2728 case Instruction::MOVE_OBJECT_16: 2729 if (move_inst->VRegA_32x() == instance_of_inst->VRegB_22c()) { 2730 update_line->SetRegisterType<LockOp::kKeep>(this, 2731 move_inst->VRegB_32x(), 2732 cast_type); 2733 } 2734 break; 2735 default: 2736 break; 2737 } 2738 } 2739 } 2740 } 2741 2742 break; 2743 } 2744 case Instruction::IF_LTZ: 2745 case Instruction::IF_GEZ: 2746 case Instruction::IF_GTZ: 2747 case Instruction::IF_LEZ: { 2748 const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t()); 2749 if (!reg_type.IsIntegralTypes()) { 2750 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type 2751 << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez"; 2752 } 2753 break; 2754 } 2755 case Instruction::AGET_BOOLEAN: 2756 VerifyAGet(inst, reg_types_.Boolean(), true); 2757 break; 2758 case Instruction::AGET_BYTE: 2759 VerifyAGet(inst, reg_types_.Byte(), true); 2760 break; 2761 case Instruction::AGET_CHAR: 2762 VerifyAGet(inst, reg_types_.Char(), true); 2763 break; 2764 case Instruction::AGET_SHORT: 2765 VerifyAGet(inst, reg_types_.Short(), true); 2766 break; 2767 case Instruction::AGET: 2768 VerifyAGet(inst, reg_types_.Integer(), true); 2769 break; 2770 case Instruction::AGET_WIDE: 2771 VerifyAGet(inst, reg_types_.LongLo(), true); 2772 break; 2773 case Instruction::AGET_OBJECT: 2774 VerifyAGet(inst, reg_types_.JavaLangObject(false), false); 2775 break; 2776 2777 case Instruction::APUT_BOOLEAN: 2778 VerifyAPut(inst, reg_types_.Boolean(), true); 2779 break; 2780 case Instruction::APUT_BYTE: 2781 VerifyAPut(inst, reg_types_.Byte(), true); 2782 break; 2783 case Instruction::APUT_CHAR: 2784 VerifyAPut(inst, reg_types_.Char(), true); 2785 break; 2786 case Instruction::APUT_SHORT: 2787 VerifyAPut(inst, reg_types_.Short(), true); 2788 break; 2789 case Instruction::APUT: 2790 VerifyAPut(inst, reg_types_.Integer(), true); 2791 break; 2792 case Instruction::APUT_WIDE: 2793 VerifyAPut(inst, reg_types_.LongLo(), true); 2794 break; 2795 case Instruction::APUT_OBJECT: 2796 VerifyAPut(inst, reg_types_.JavaLangObject(false), false); 2797 break; 2798 2799 case Instruction::IGET_BOOLEAN: 2800 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, false); 2801 break; 2802 case Instruction::IGET_BYTE: 2803 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, false); 2804 break; 2805 case Instruction::IGET_CHAR: 2806 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, false); 2807 break; 2808 case Instruction::IGET_SHORT: 2809 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, false); 2810 break; 2811 case Instruction::IGET: 2812 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, false); 2813 break; 2814 case Instruction::IGET_WIDE: 2815 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, false); 2816 break; 2817 case Instruction::IGET_OBJECT: 2818 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false, 2819 false); 2820 break; 2821 2822 case Instruction::IPUT_BOOLEAN: 2823 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, false); 2824 break; 2825 case Instruction::IPUT_BYTE: 2826 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, false); 2827 break; 2828 case Instruction::IPUT_CHAR: 2829 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, false); 2830 break; 2831 case Instruction::IPUT_SHORT: 2832 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, false); 2833 break; 2834 case Instruction::IPUT: 2835 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, false); 2836 break; 2837 case Instruction::IPUT_WIDE: 2838 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, false); 2839 break; 2840 case Instruction::IPUT_OBJECT: 2841 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false, 2842 false); 2843 break; 2844 2845 case Instruction::SGET_BOOLEAN: 2846 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, true); 2847 break; 2848 case Instruction::SGET_BYTE: 2849 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, true); 2850 break; 2851 case Instruction::SGET_CHAR: 2852 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, true); 2853 break; 2854 case Instruction::SGET_SHORT: 2855 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, true); 2856 break; 2857 case Instruction::SGET: 2858 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, true); 2859 break; 2860 case Instruction::SGET_WIDE: 2861 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, true); 2862 break; 2863 case Instruction::SGET_OBJECT: 2864 VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false, 2865 true); 2866 break; 2867 2868 case Instruction::SPUT_BOOLEAN: 2869 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, true); 2870 break; 2871 case Instruction::SPUT_BYTE: 2872 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, true); 2873 break; 2874 case Instruction::SPUT_CHAR: 2875 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, true); 2876 break; 2877 case Instruction::SPUT_SHORT: 2878 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, true); 2879 break; 2880 case Instruction::SPUT: 2881 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, true); 2882 break; 2883 case Instruction::SPUT_WIDE: 2884 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, true); 2885 break; 2886 case Instruction::SPUT_OBJECT: 2887 VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false, 2888 true); 2889 break; 2890 2891 case Instruction::INVOKE_VIRTUAL: 2892 case Instruction::INVOKE_VIRTUAL_RANGE: 2893 case Instruction::INVOKE_SUPER: 2894 case Instruction::INVOKE_SUPER_RANGE: { 2895 bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE || 2896 inst->Opcode() == Instruction::INVOKE_SUPER_RANGE); 2897 bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER || 2898 inst->Opcode() == Instruction::INVOKE_SUPER_RANGE); 2899 MethodType type = is_super ? METHOD_SUPER : METHOD_VIRTUAL; 2900 ArtMethod* called_method = VerifyInvocationArgs(inst, type, is_range); 2901 const RegType* return_type = nullptr; 2902 if (called_method != nullptr) { 2903 mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_); 2904 if (return_type_class != nullptr) { 2905 return_type = &FromClass(called_method->GetReturnTypeDescriptor(), 2906 return_type_class, 2907 return_type_class->CannotBeAssignedFromOtherTypes()); 2908 } else { 2909 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 2910 self_->ClearException(); 2911 } 2912 } 2913 if (return_type == nullptr) { 2914 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 2915 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 2916 dex::TypeIndex return_type_idx = 2917 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 2918 const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); 2919 return_type = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); 2920 } 2921 if (!return_type->IsLowHalf()) { 2922 work_line_->SetResultRegisterType(this, *return_type); 2923 } else { 2924 work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(®_types_)); 2925 } 2926 just_set_result = true; 2927 break; 2928 } 2929 case Instruction::INVOKE_DIRECT: 2930 case Instruction::INVOKE_DIRECT_RANGE: { 2931 bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE); 2932 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, is_range); 2933 const char* return_type_descriptor; 2934 bool is_constructor; 2935 const RegType* return_type = nullptr; 2936 if (called_method == nullptr) { 2937 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 2938 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 2939 is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0; 2940 dex::TypeIndex return_type_idx = 2941 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 2942 return_type_descriptor = dex_file_->StringByTypeIdx(return_type_idx); 2943 } else { 2944 is_constructor = called_method->IsConstructor(); 2945 return_type_descriptor = called_method->GetReturnTypeDescriptor(); 2946 mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_); 2947 if (return_type_class != nullptr) { 2948 return_type = &FromClass(return_type_descriptor, 2949 return_type_class, 2950 return_type_class->CannotBeAssignedFromOtherTypes()); 2951 } else { 2952 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 2953 self_->ClearException(); 2954 } 2955 } 2956 if (is_constructor) { 2957 /* 2958 * Some additional checks when calling a constructor. We know from the invocation arg check 2959 * that the "this" argument is an instance of called_method->klass. Now we further restrict 2960 * that to require that called_method->klass is the same as this->klass or this->super, 2961 * allowing the latter only if the "this" argument is the same as the "this" argument to 2962 * this method (which implies that we're in a constructor ourselves). 2963 */ 2964 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 2965 if (this_type.IsConflict()) // failure. 2966 break; 2967 2968 /* no null refs allowed (?) */ 2969 if (this_type.IsZero()) { 2970 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref"; 2971 break; 2972 } 2973 2974 /* must be in same class or in superclass */ 2975 // const RegType& this_super_klass = this_type.GetSuperClass(®_types_); 2976 // TODO: re-enable constructor type verification 2977 // if (this_super_klass.IsConflict()) { 2978 // Unknown super class, fail so we re-check at runtime. 2979 // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'"; 2980 // break; 2981 // } 2982 2983 /* arg must be an uninitialized reference */ 2984 if (!this_type.IsUninitializedTypes()) { 2985 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference " 2986 << this_type; 2987 break; 2988 } 2989 2990 /* 2991 * Replace the uninitialized reference with an initialized one. We need to do this for all 2992 * registers that have the same object instance in them, not just the "this" register. 2993 */ 2994 work_line_->MarkRefsAsInitialized(this, this_type); 2995 } 2996 if (return_type == nullptr) { 2997 return_type = ®_types_.FromDescriptor(GetClassLoader(), return_type_descriptor, false); 2998 } 2999 if (!return_type->IsLowHalf()) { 3000 work_line_->SetResultRegisterType(this, *return_type); 3001 } else { 3002 work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(®_types_)); 3003 } 3004 just_set_result = true; 3005 break; 3006 } 3007 case Instruction::INVOKE_STATIC: 3008 case Instruction::INVOKE_STATIC_RANGE: { 3009 bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE); 3010 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_STATIC, is_range); 3011 const char* descriptor; 3012 if (called_method == nullptr) { 3013 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 3014 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 3015 dex::TypeIndex return_type_idx = 3016 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 3017 descriptor = dex_file_->StringByTypeIdx(return_type_idx); 3018 } else { 3019 descriptor = called_method->GetReturnTypeDescriptor(); 3020 } 3021 const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false); 3022 if (!return_type.IsLowHalf()) { 3023 work_line_->SetResultRegisterType(this, return_type); 3024 } else { 3025 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3026 } 3027 just_set_result = true; 3028 } 3029 break; 3030 case Instruction::INVOKE_INTERFACE: 3031 case Instruction::INVOKE_INTERFACE_RANGE: { 3032 bool is_range = (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE); 3033 ArtMethod* abs_method = VerifyInvocationArgs(inst, METHOD_INTERFACE, is_range); 3034 if (abs_method != nullptr) { 3035 mirror::Class* called_interface = abs_method->GetDeclaringClass(); 3036 if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) { 3037 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '" 3038 << abs_method->PrettyMethod() << "'"; 3039 break; 3040 } 3041 } 3042 /* Get the type of the "this" arg, which should either be a sub-interface of called 3043 * interface or Object (see comments in RegType::JoinClass). 3044 */ 3045 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 3046 if (this_type.IsZero()) { 3047 /* null pointer always passes (and always fails at runtime) */ 3048 } else { 3049 if (this_type.IsUninitializedTypes()) { 3050 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object " 3051 << this_type; 3052 break; 3053 } 3054 // In the past we have tried to assert that "called_interface" is assignable 3055 // from "this_type.GetClass()", however, as we do an imprecise Join 3056 // (RegType::JoinClass) we don't have full information on what interfaces are 3057 // implemented by "this_type". For example, two classes may implement the same 3058 // interfaces and have a common parent that doesn't implement the interface. The 3059 // join will set "this_type" to the parent class and a test that this implements 3060 // the interface will incorrectly fail. 3061 } 3062 /* 3063 * We don't have an object instance, so we can't find the concrete method. However, all of 3064 * the type information is in the abstract method, so we're good. 3065 */ 3066 const char* descriptor; 3067 if (abs_method == nullptr) { 3068 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 3069 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 3070 dex::TypeIndex return_type_idx = 3071 dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; 3072 descriptor = dex_file_->StringByTypeIdx(return_type_idx); 3073 } else { 3074 descriptor = abs_method->GetReturnTypeDescriptor(); 3075 } 3076 const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false); 3077 if (!return_type.IsLowHalf()) { 3078 work_line_->SetResultRegisterType(this, return_type); 3079 } else { 3080 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3081 } 3082 just_set_result = true; 3083 break; 3084 } 3085 case Instruction::INVOKE_POLYMORPHIC: 3086 case Instruction::INVOKE_POLYMORPHIC_RANGE: { 3087 bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE); 3088 ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_POLYMORPHIC, is_range); 3089 if (called_method == nullptr) { 3090 // Convert potential soft failures in VerifyInvocationArgs() to hard errors. 3091 if (failure_messages_.size() > 0) { 3092 std::string message = failure_messages_.back()->str(); 3093 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << message; 3094 } else { 3095 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-polymorphic verification failure."; 3096 } 3097 break; 3098 } 3099 if (!CheckSignaturePolymorphicMethod(called_method) || 3100 !CheckSignaturePolymorphicReceiver(inst)) { 3101 break; 3102 } 3103 const uint32_t proto_idx = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc(); 3104 const char* return_descriptor = 3105 dex_file_->GetReturnTypeDescriptor(dex_file_->GetProtoId(proto_idx)); 3106 const RegType& return_type = 3107 reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false); 3108 if (!return_type.IsLowHalf()) { 3109 work_line_->SetResultRegisterType(this, return_type); 3110 } else { 3111 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3112 } 3113 just_set_result = true; 3114 break; 3115 } 3116 case Instruction::INVOKE_CUSTOM: 3117 case Instruction::INVOKE_CUSTOM_RANGE: { 3118 // Verify registers based on method_type in the call site. 3119 bool is_range = (inst->Opcode() == Instruction::INVOKE_CUSTOM_RANGE); 3120 3121 // Step 1. Check the call site that produces the method handle for invocation 3122 const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); 3123 if (!CheckCallSite(call_site_idx)) { 3124 DCHECK(HasFailures()); 3125 break; 3126 } 3127 3128 // Step 2. Check the register arguments correspond to the expected arguments for the 3129 // method handle produced by step 1. The dex file verifier has checked ranges for 3130 // the first three arguments and CheckCallSite has checked the method handle type. 3131 CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx)); 3132 it.Next(); // Skip to name. 3133 it.Next(); // Skip to method type of the method handle 3134 const uint32_t proto_idx = static_cast<uint32_t>(it.GetJavaValue().i); 3135 const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(proto_idx); 3136 DexFileParameterIterator param_it(*dex_file_, proto_id); 3137 // Treat method as static as it has yet to be determined. 3138 VerifyInvocationArgsFromIterator(¶m_it, inst, METHOD_STATIC, is_range, nullptr); 3139 const char* return_descriptor = dex_file_->GetReturnTypeDescriptor(proto_id); 3140 3141 // Step 3. Propagate return type information 3142 const RegType& return_type = 3143 reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false); 3144 if (!return_type.IsLowHalf()) { 3145 work_line_->SetResultRegisterType(this, return_type); 3146 } else { 3147 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3148 } 3149 just_set_result = true; 3150 // TODO: Add compiler support for invoke-custom (b/35337872). 3151 Fail(VERIFY_ERROR_FORCE_INTERPRETER); 3152 break; 3153 } 3154 case Instruction::NEG_INT: 3155 case Instruction::NOT_INT: 3156 work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer()); 3157 break; 3158 case Instruction::NEG_LONG: 3159 case Instruction::NOT_LONG: 3160 work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3161 reg_types_.LongLo(), reg_types_.LongHi()); 3162 break; 3163 case Instruction::NEG_FLOAT: 3164 work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Float()); 3165 break; 3166 case Instruction::NEG_DOUBLE: 3167 work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3168 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3169 break; 3170 case Instruction::INT_TO_LONG: 3171 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3172 reg_types_.Integer()); 3173 break; 3174 case Instruction::INT_TO_FLOAT: 3175 work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Integer()); 3176 break; 3177 case Instruction::INT_TO_DOUBLE: 3178 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3179 reg_types_.Integer()); 3180 break; 3181 case Instruction::LONG_TO_INT: 3182 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(), 3183 reg_types_.LongLo(), reg_types_.LongHi()); 3184 break; 3185 case Instruction::LONG_TO_FLOAT: 3186 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(), 3187 reg_types_.LongLo(), reg_types_.LongHi()); 3188 break; 3189 case Instruction::LONG_TO_DOUBLE: 3190 work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3191 reg_types_.LongLo(), reg_types_.LongHi()); 3192 break; 3193 case Instruction::FLOAT_TO_INT: 3194 work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Float()); 3195 break; 3196 case Instruction::FLOAT_TO_LONG: 3197 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3198 reg_types_.Float()); 3199 break; 3200 case Instruction::FLOAT_TO_DOUBLE: 3201 work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3202 reg_types_.Float()); 3203 break; 3204 case Instruction::DOUBLE_TO_INT: 3205 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(), 3206 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3207 break; 3208 case Instruction::DOUBLE_TO_LONG: 3209 work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3210 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3211 break; 3212 case Instruction::DOUBLE_TO_FLOAT: 3213 work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(), 3214 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3215 break; 3216 case Instruction::INT_TO_BYTE: 3217 work_line_->CheckUnaryOp(this, inst, reg_types_.Byte(), reg_types_.Integer()); 3218 break; 3219 case Instruction::INT_TO_CHAR: 3220 work_line_->CheckUnaryOp(this, inst, reg_types_.Char(), reg_types_.Integer()); 3221 break; 3222 case Instruction::INT_TO_SHORT: 3223 work_line_->CheckUnaryOp(this, inst, reg_types_.Short(), reg_types_.Integer()); 3224 break; 3225 3226 case Instruction::ADD_INT: 3227 case Instruction::SUB_INT: 3228 case Instruction::MUL_INT: 3229 case Instruction::REM_INT: 3230 case Instruction::DIV_INT: 3231 case Instruction::SHL_INT: 3232 case Instruction::SHR_INT: 3233 case Instruction::USHR_INT: 3234 work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3235 reg_types_.Integer(), false); 3236 break; 3237 case Instruction::AND_INT: 3238 case Instruction::OR_INT: 3239 case Instruction::XOR_INT: 3240 work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3241 reg_types_.Integer(), true); 3242 break; 3243 case Instruction::ADD_LONG: 3244 case Instruction::SUB_LONG: 3245 case Instruction::MUL_LONG: 3246 case Instruction::DIV_LONG: 3247 case Instruction::REM_LONG: 3248 case Instruction::AND_LONG: 3249 case Instruction::OR_LONG: 3250 case Instruction::XOR_LONG: 3251 work_line_->CheckBinaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3252 reg_types_.LongLo(), reg_types_.LongHi(), 3253 reg_types_.LongLo(), reg_types_.LongHi()); 3254 break; 3255 case Instruction::SHL_LONG: 3256 case Instruction::SHR_LONG: 3257 case Instruction::USHR_LONG: 3258 /* shift distance is Int, making these different from other binary operations */ 3259 work_line_->CheckBinaryOpWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3260 reg_types_.Integer()); 3261 break; 3262 case Instruction::ADD_FLOAT: 3263 case Instruction::SUB_FLOAT: 3264 case Instruction::MUL_FLOAT: 3265 case Instruction::DIV_FLOAT: 3266 case Instruction::REM_FLOAT: 3267 work_line_->CheckBinaryOp(this, inst, reg_types_.Float(), reg_types_.Float(), 3268 reg_types_.Float(), false); 3269 break; 3270 case Instruction::ADD_DOUBLE: 3271 case Instruction::SUB_DOUBLE: 3272 case Instruction::MUL_DOUBLE: 3273 case Instruction::DIV_DOUBLE: 3274 case Instruction::REM_DOUBLE: 3275 work_line_->CheckBinaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3276 reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3277 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3278 break; 3279 case Instruction::ADD_INT_2ADDR: 3280 case Instruction::SUB_INT_2ADDR: 3281 case Instruction::MUL_INT_2ADDR: 3282 case Instruction::REM_INT_2ADDR: 3283 case Instruction::SHL_INT_2ADDR: 3284 case Instruction::SHR_INT_2ADDR: 3285 case Instruction::USHR_INT_2ADDR: 3286 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3287 reg_types_.Integer(), false); 3288 break; 3289 case Instruction::AND_INT_2ADDR: 3290 case Instruction::OR_INT_2ADDR: 3291 case Instruction::XOR_INT_2ADDR: 3292 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3293 reg_types_.Integer(), true); 3294 break; 3295 case Instruction::DIV_INT_2ADDR: 3296 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(), 3297 reg_types_.Integer(), false); 3298 break; 3299 case Instruction::ADD_LONG_2ADDR: 3300 case Instruction::SUB_LONG_2ADDR: 3301 case Instruction::MUL_LONG_2ADDR: 3302 case Instruction::DIV_LONG_2ADDR: 3303 case Instruction::REM_LONG_2ADDR: 3304 case Instruction::AND_LONG_2ADDR: 3305 case Instruction::OR_LONG_2ADDR: 3306 case Instruction::XOR_LONG_2ADDR: 3307 work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3308 reg_types_.LongLo(), reg_types_.LongHi(), 3309 reg_types_.LongLo(), reg_types_.LongHi()); 3310 break; 3311 case Instruction::SHL_LONG_2ADDR: 3312 case Instruction::SHR_LONG_2ADDR: 3313 case Instruction::USHR_LONG_2ADDR: 3314 work_line_->CheckBinaryOp2addrWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(), 3315 reg_types_.Integer()); 3316 break; 3317 case Instruction::ADD_FLOAT_2ADDR: 3318 case Instruction::SUB_FLOAT_2ADDR: 3319 case Instruction::MUL_FLOAT_2ADDR: 3320 case Instruction::DIV_FLOAT_2ADDR: 3321 case Instruction::REM_FLOAT_2ADDR: 3322 work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Float(), reg_types_.Float(), 3323 reg_types_.Float(), false); 3324 break; 3325 case Instruction::ADD_DOUBLE_2ADDR: 3326 case Instruction::SUB_DOUBLE_2ADDR: 3327 case Instruction::MUL_DOUBLE_2ADDR: 3328 case Instruction::DIV_DOUBLE_2ADDR: 3329 case Instruction::REM_DOUBLE_2ADDR: 3330 work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3331 reg_types_.DoubleLo(), reg_types_.DoubleHi(), 3332 reg_types_.DoubleLo(), reg_types_.DoubleHi()); 3333 break; 3334 case Instruction::ADD_INT_LIT16: 3335 case Instruction::RSUB_INT_LIT16: 3336 case Instruction::MUL_INT_LIT16: 3337 case Instruction::DIV_INT_LIT16: 3338 case Instruction::REM_INT_LIT16: 3339 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false, 3340 true); 3341 break; 3342 case Instruction::AND_INT_LIT16: 3343 case Instruction::OR_INT_LIT16: 3344 case Instruction::XOR_INT_LIT16: 3345 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true, 3346 true); 3347 break; 3348 case Instruction::ADD_INT_LIT8: 3349 case Instruction::RSUB_INT_LIT8: 3350 case Instruction::MUL_INT_LIT8: 3351 case Instruction::DIV_INT_LIT8: 3352 case Instruction::REM_INT_LIT8: 3353 case Instruction::SHL_INT_LIT8: 3354 case Instruction::SHR_INT_LIT8: 3355 case Instruction::USHR_INT_LIT8: 3356 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false, 3357 false); 3358 break; 3359 case Instruction::AND_INT_LIT8: 3360 case Instruction::OR_INT_LIT8: 3361 case Instruction::XOR_INT_LIT8: 3362 work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true, 3363 false); 3364 break; 3365 3366 // Special instructions. 3367 case Instruction::RETURN_VOID_NO_BARRIER: 3368 if (IsConstructor() && !IsStatic()) { 3369 auto& declaring_class = GetDeclaringClass(); 3370 if (declaring_class.IsUnresolvedReference()) { 3371 // We must iterate over the fields, even if we cannot use mirror classes to do so. Do it 3372 // manually over the underlying dex file. 3373 uint32_t first_index = GetFirstFinalInstanceFieldIndex(*dex_file_, 3374 dex_file_->GetMethodId(dex_method_idx_).class_idx_); 3375 if (first_index != DexFile::kDexNoIndex) { 3376 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for field " 3377 << first_index; 3378 } 3379 break; 3380 } 3381 auto* klass = declaring_class.GetClass(); 3382 for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) { 3383 if (klass->GetInstanceField(i)->IsFinal()) { 3384 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for " 3385 << klass->GetInstanceField(i)->PrettyField(); 3386 break; 3387 } 3388 } 3389 } 3390 // Handle this like a RETURN_VOID now. Code is duplicated to separate standard from 3391 // quickened opcodes (otherwise this could be a fall-through). 3392 if (!IsConstructor()) { 3393 if (!GetMethodReturnType().IsConflict()) { 3394 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected"; 3395 } 3396 } 3397 break; 3398 // Note: the following instructions encode offsets derived from class linking. 3399 // As such they use Class*/Field*/Executable* as these offsets only have 3400 // meaning if the class linking and resolution were successful. 3401 case Instruction::IGET_QUICK: 3402 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true); 3403 break; 3404 case Instruction::IGET_WIDE_QUICK: 3405 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true); 3406 break; 3407 case Instruction::IGET_OBJECT_QUICK: 3408 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false); 3409 break; 3410 case Instruction::IGET_BOOLEAN_QUICK: 3411 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true); 3412 break; 3413 case Instruction::IGET_BYTE_QUICK: 3414 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true); 3415 break; 3416 case Instruction::IGET_CHAR_QUICK: 3417 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true); 3418 break; 3419 case Instruction::IGET_SHORT_QUICK: 3420 VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true); 3421 break; 3422 case Instruction::IPUT_QUICK: 3423 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true); 3424 break; 3425 case Instruction::IPUT_BOOLEAN_QUICK: 3426 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true); 3427 break; 3428 case Instruction::IPUT_BYTE_QUICK: 3429 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true); 3430 break; 3431 case Instruction::IPUT_CHAR_QUICK: 3432 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true); 3433 break; 3434 case Instruction::IPUT_SHORT_QUICK: 3435 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true); 3436 break; 3437 case Instruction::IPUT_WIDE_QUICK: 3438 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true); 3439 break; 3440 case Instruction::IPUT_OBJECT_QUICK: 3441 VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false); 3442 break; 3443 case Instruction::INVOKE_VIRTUAL_QUICK: 3444 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 3445 bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK); 3446 ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range); 3447 if (called_method != nullptr) { 3448 const char* descriptor = called_method->GetReturnTypeDescriptor(); 3449 const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false); 3450 if (!return_type.IsLowHalf()) { 3451 work_line_->SetResultRegisterType(this, return_type); 3452 } else { 3453 work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); 3454 } 3455 just_set_result = true; 3456 } 3457 break; 3458 } 3459 3460 /* These should never appear during verification. */ 3461 case Instruction::UNUSED_3E ... Instruction::UNUSED_43: 3462 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9: 3463 case Instruction::UNUSED_FE ... Instruction::UNUSED_FF: 3464 case Instruction::UNUSED_79: 3465 case Instruction::UNUSED_7A: 3466 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_); 3467 break; 3468 3469 /* 3470 * DO NOT add a "default" clause here. Without it the compiler will 3471 * complain if an instruction is missing (which is desirable). 3472 */ 3473 } // end - switch (dec_insn.opcode) 3474 3475 if (have_pending_hard_failure_) { 3476 if (Runtime::Current()->IsAotCompiler()) { 3477 /* When AOT compiling, check that the last failure is a hard failure */ 3478 if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) { 3479 LOG(ERROR) << "Pending failures:"; 3480 for (auto& error : failures_) { 3481 LOG(ERROR) << error; 3482 } 3483 for (auto& error_msg : failure_messages_) { 3484 LOG(ERROR) << error_msg->str(); 3485 } 3486 LOG(FATAL) << "Pending hard failure, but last failure not hard."; 3487 } 3488 } 3489 /* immediate failure, reject class */ 3490 info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_); 3491 return false; 3492 } else if (have_pending_runtime_throw_failure_) { 3493 /* checking interpreter will throw, mark following code as unreachable */ 3494 opcode_flags = Instruction::kThrow; 3495 // Note: the flag must be reset as it is only global to decouple Fail and is semantically per 3496 // instruction. However, RETURN checking may throw LOCKING errors, so we clear at the 3497 // very end. 3498 } 3499 /* 3500 * If we didn't just set the result register, clear it out. This ensures that you can only use 3501 * "move-result" immediately after the result is set. (We could check this statically, but it's 3502 * not expensive and it makes our debugging output cleaner.) 3503 */ 3504 if (!just_set_result) { 3505 work_line_->SetResultTypeToUnknown(this); 3506 } 3507 3508 /* 3509 * Handle "branch". Tag the branch target. 3510 * 3511 * NOTE: instructions like Instruction::EQZ provide information about the 3512 * state of the register when the branch is taken or not taken. For example, 3513 * somebody could get a reference field, check it for zero, and if the 3514 * branch is taken immediately store that register in a boolean field 3515 * since the value is known to be zero. We do not currently account for 3516 * that, and will reject the code. 3517 * 3518 * TODO: avoid re-fetching the branch target 3519 */ 3520 if ((opcode_flags & Instruction::kBranch) != 0) { 3521 bool isConditional, selfOkay; 3522 if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) { 3523 /* should never happen after static verification */ 3524 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch"; 3525 return false; 3526 } 3527 DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0); 3528 if (!CheckNotMoveExceptionOrMoveResult(code_item_->insns_, work_insn_idx_ + branch_target)) { 3529 return false; 3530 } 3531 /* update branch target, set "changed" if appropriate */ 3532 if (nullptr != branch_line) { 3533 if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) { 3534 return false; 3535 } 3536 } else { 3537 if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) { 3538 return false; 3539 } 3540 } 3541 } 3542 3543 /* 3544 * Handle "switch". Tag all possible branch targets. 3545 * 3546 * We've already verified that the table is structurally sound, so we 3547 * just need to walk through and tag the targets. 3548 */ 3549 if ((opcode_flags & Instruction::kSwitch) != 0) { 3550 int offset_to_switch = insns[1] | (static_cast<int32_t>(insns[2]) << 16); 3551 const uint16_t* switch_insns = insns + offset_to_switch; 3552 int switch_count = switch_insns[1]; 3553 int offset_to_targets, targ; 3554 3555 if ((*insns & 0xff) == Instruction::PACKED_SWITCH) { 3556 /* 0 = sig, 1 = count, 2/3 = first key */ 3557 offset_to_targets = 4; 3558 } else { 3559 /* 0 = sig, 1 = count, 2..count * 2 = keys */ 3560 DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH); 3561 offset_to_targets = 2 + 2 * switch_count; 3562 } 3563 3564 /* verify each switch target */ 3565 for (targ = 0; targ < switch_count; targ++) { 3566 int offset; 3567 uint32_t abs_offset; 3568 3569 /* offsets are 32-bit, and only partly endian-swapped */ 3570 offset = switch_insns[offset_to_targets + targ * 2] | 3571 (static_cast<int32_t>(switch_insns[offset_to_targets + targ * 2 + 1]) << 16); 3572 abs_offset = work_insn_idx_ + offset; 3573 DCHECK_LT(abs_offset, code_item_->insns_size_in_code_units_); 3574 if (!CheckNotMoveExceptionOrMoveResult(code_item_->insns_, abs_offset)) { 3575 return false; 3576 } 3577 if (!UpdateRegisters(abs_offset, work_line_.get(), false)) { 3578 return false; 3579 } 3580 } 3581 } 3582 3583 /* 3584 * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a 3585 * "try" block when they throw, control transfers out of the method.) 3586 */ 3587 if ((opcode_flags & Instruction::kThrow) != 0 && GetInstructionFlags(work_insn_idx_).IsInTry()) { 3588 bool has_catch_all_handler = false; 3589 CatchHandlerIterator iterator(*code_item_, work_insn_idx_); 3590 3591 // Need the linker to try and resolve the handled class to check if it's Throwable. 3592 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3593 3594 for (; iterator.HasNext(); iterator.Next()) { 3595 dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex(); 3596 if (!handler_type_idx.IsValid()) { 3597 has_catch_all_handler = true; 3598 } else { 3599 // It is also a catch-all if it is java.lang.Throwable. 3600 mirror::Class* klass = linker->ResolveType(*dex_file_, handler_type_idx, dex_cache_, 3601 class_loader_); 3602 if (klass != nullptr) { 3603 if (klass == mirror::Throwable::GetJavaLangThrowable()) { 3604 has_catch_all_handler = true; 3605 } 3606 } else { 3607 // Clear exception. 3608 DCHECK(self_->IsExceptionPending()); 3609 self_->ClearException(); 3610 } 3611 } 3612 /* 3613 * Merge registers into the "catch" block. We want to use the "savedRegs" rather than 3614 * "work_regs", because at runtime the exception will be thrown before the instruction 3615 * modifies any registers. 3616 */ 3617 if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) { 3618 return false; 3619 } 3620 } 3621 3622 /* 3623 * If the monitor stack depth is nonzero, there must be a "catch all" handler for this 3624 * instruction. This does apply to monitor-exit because of async exception handling. 3625 */ 3626 if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) { 3627 /* 3628 * The state in work_line reflects the post-execution state. If the current instruction is a 3629 * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws, 3630 * it will do so before grabbing the lock). 3631 */ 3632 if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) { 3633 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 3634 << "expected to be within a catch-all for an instruction where a monitor is held"; 3635 return false; 3636 } 3637 } 3638 } 3639 3640 /* Handle "continue". Tag the next consecutive instruction. 3641 * Note: Keep the code handling "continue" case below the "branch" and "switch" cases, 3642 * because it changes work_line_ when performing peephole optimization 3643 * and this change should not be used in those cases. 3644 */ 3645 if ((opcode_flags & Instruction::kContinue) != 0) { 3646 DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst); 3647 uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits(); 3648 if (next_insn_idx >= code_item_->insns_size_in_code_units_) { 3649 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area"; 3650 return false; 3651 } 3652 // The only way to get to a move-exception instruction is to get thrown there. Make sure the 3653 // next instruction isn't one. 3654 if (!CheckNotMoveException(code_item_->insns_, next_insn_idx)) { 3655 return false; 3656 } 3657 if (nullptr != fallthrough_line) { 3658 // Make workline consistent with fallthrough computed from peephole optimization. 3659 work_line_->CopyFromLine(fallthrough_line.get()); 3660 } 3661 if (GetInstructionFlags(next_insn_idx).IsReturn()) { 3662 // For returns we only care about the operand to the return, all other registers are dead. 3663 const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn_idx); 3664 AdjustReturnLine(this, ret_inst, work_line_.get()); 3665 } 3666 RegisterLine* next_line = reg_table_.GetLine(next_insn_idx); 3667 if (next_line != nullptr) { 3668 // Merge registers into what we have for the next instruction, and set the "changed" flag if 3669 // needed. If the merge changes the state of the registers then the work line will be 3670 // updated. 3671 if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) { 3672 return false; 3673 } 3674 } else { 3675 /* 3676 * We're not recording register data for the next instruction, so we don't know what the 3677 * prior state was. We have to assume that something has changed and re-evaluate it. 3678 */ 3679 GetInstructionFlags(next_insn_idx).SetChanged(); 3680 } 3681 } 3682 3683 /* If we're returning from the method, make sure monitor stack is empty. */ 3684 if ((opcode_flags & Instruction::kReturn) != 0) { 3685 work_line_->VerifyMonitorStackEmpty(this); 3686 } 3687 3688 /* 3689 * Update start_guess. Advance to the next instruction of that's 3690 * possible, otherwise use the branch target if one was found. If 3691 * neither of those exists we're in a return or throw; leave start_guess 3692 * alone and let the caller sort it out. 3693 */ 3694 if ((opcode_flags & Instruction::kContinue) != 0) { 3695 DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst); 3696 *start_guess = work_insn_idx_ + inst->SizeInCodeUnits(); 3697 } else if ((opcode_flags & Instruction::kBranch) != 0) { 3698 /* we're still okay if branch_target is zero */ 3699 *start_guess = work_insn_idx_ + branch_target; 3700 } 3701 3702 DCHECK_LT(*start_guess, code_item_->insns_size_in_code_units_); 3703 DCHECK(GetInstructionFlags(*start_guess).IsOpcode()); 3704 3705 if (have_pending_runtime_throw_failure_) { 3706 have_any_pending_runtime_throw_failure_ = true; 3707 // Reset the pending_runtime_throw flag now. 3708 have_pending_runtime_throw_failure_ = false; 3709 } 3710 3711 return true; 3712 } // NOLINT(readability/fn_size) 3713 3714 void MethodVerifier::UninstantiableError(const char* descriptor) { 3715 Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for " 3716 << "non-instantiable klass " << descriptor; 3717 } 3718 3719 inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) { 3720 return klass->IsInstantiable() || klass->IsPrimitive(); 3721 } 3722 3723 const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_idx) { 3724 mirror::Class* klass = can_load_classes_ 3725 ? Runtime::Current()->GetClassLinker()->ResolveType( 3726 *dex_file_, class_idx, dex_cache_, class_loader_) 3727 : ClassLinker::LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()).Ptr(); 3728 if (can_load_classes_ && klass == nullptr) { 3729 DCHECK(self_->IsExceptionPending()); 3730 self_->ClearException(); 3731 } 3732 const RegType* result = nullptr; 3733 if (klass != nullptr) { 3734 bool precise = klass->CannotBeAssignedFromOtherTypes(); 3735 if (precise && !IsInstantiableOrPrimitive(klass)) { 3736 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3737 UninstantiableError(descriptor); 3738 precise = false; 3739 } 3740 result = reg_types_.FindClass(klass, precise); 3741 if (result == nullptr) { 3742 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3743 result = reg_types_.InsertClass(descriptor, klass, precise); 3744 } 3745 } else { 3746 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3747 result = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); 3748 } 3749 DCHECK(result != nullptr); 3750 if (result->IsConflict()) { 3751 const char* descriptor = dex_file_->StringByTypeIdx(class_idx); 3752 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor 3753 << "' in " << GetDeclaringClass(); 3754 return *result; 3755 } 3756 3757 // Record result of class resolution attempt. 3758 VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass); 3759 3760 // Check if access is allowed. Unresolved types use xxxWithAccessCheck to 3761 // check at runtime if access is allowed and so pass here. If result is 3762 // primitive, skip the access check. 3763 if (result->IsNonZeroReferenceTypes() && !result->IsUnresolvedTypes()) { 3764 const RegType& referrer = GetDeclaringClass(); 3765 if (!referrer.IsUnresolvedTypes() && !referrer.CanAccess(*result)) { 3766 Fail(VERIFY_ERROR_ACCESS_CLASS) << "illegal class access: '" 3767 << referrer << "' -> '" << *result << "'"; 3768 } 3769 } 3770 return *result; 3771 } 3772 3773 const RegType& MethodVerifier::GetCaughtExceptionType() { 3774 const RegType* common_super = nullptr; 3775 if (code_item_->tries_size_ != 0) { 3776 const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0); 3777 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 3778 for (uint32_t i = 0; i < handlers_size; i++) { 3779 CatchHandlerIterator iterator(handlers_ptr); 3780 for (; iterator.HasNext(); iterator.Next()) { 3781 if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) { 3782 if (!iterator.GetHandlerTypeIndex().IsValid()) { 3783 common_super = ®_types_.JavaLangThrowable(false); 3784 } else { 3785 const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex()); 3786 if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception, this)) { 3787 DCHECK(!exception.IsUninitializedTypes()); // Comes from dex, shouldn't be uninit. 3788 if (exception.IsUnresolvedTypes()) { 3789 // We don't know enough about the type. Fail here and let runtime handle it. 3790 Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception; 3791 return exception; 3792 } else { 3793 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception; 3794 return reg_types_.Conflict(); 3795 } 3796 } else if (common_super == nullptr) { 3797 common_super = &exception; 3798 } else if (common_super->Equals(exception)) { 3799 // odd case, but nothing to do 3800 } else { 3801 common_super = &common_super->Merge(exception, ®_types_, this); 3802 if (FailOrAbort(this, 3803 reg_types_.JavaLangThrowable(false).IsAssignableFrom( 3804 *common_super, this), 3805 "java.lang.Throwable is not assignable-from common_super at ", 3806 work_insn_idx_)) { 3807 break; 3808 } 3809 } 3810 } 3811 } 3812 } 3813 handlers_ptr = iterator.EndDataPointer(); 3814 } 3815 } 3816 if (common_super == nullptr) { 3817 /* no catch blocks, or no catches with classes we can find */ 3818 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler"; 3819 return reg_types_.Conflict(); 3820 } 3821 return *common_super; 3822 } 3823 3824 inline static MethodResolutionKind GetMethodResolutionKind( 3825 MethodType method_type, bool is_interface) { 3826 if (method_type == METHOD_DIRECT || method_type == METHOD_STATIC) { 3827 return kDirectMethodResolution; 3828 } else if (method_type == METHOD_INTERFACE) { 3829 return kInterfaceMethodResolution; 3830 } else if (method_type == METHOD_SUPER && is_interface) { 3831 return kInterfaceMethodResolution; 3832 } else { 3833 DCHECK(method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER 3834 || method_type == METHOD_POLYMORPHIC); 3835 return kVirtualMethodResolution; 3836 } 3837 } 3838 3839 ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess( 3840 uint32_t dex_method_idx, MethodType method_type) { 3841 const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx); 3842 const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_); 3843 if (klass_type.IsConflict()) { 3844 std::string append(" in attempt to access method "); 3845 append += dex_file_->GetMethodName(method_id); 3846 AppendToLastFailMessage(append); 3847 return nullptr; 3848 } 3849 if (klass_type.IsUnresolvedTypes()) { 3850 return nullptr; // Can't resolve Class so no more to do here 3851 } 3852 mirror::Class* klass = klass_type.GetClass(); 3853 const RegType& referrer = GetDeclaringClass(); 3854 auto* cl = Runtime::Current()->GetClassLinker(); 3855 auto pointer_size = cl->GetImagePointerSize(); 3856 MethodResolutionKind res_kind = GetMethodResolutionKind(method_type, klass->IsInterface()); 3857 3858 ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx, pointer_size); 3859 bool stash_method = false; 3860 if (res_method == nullptr) { 3861 const char* name = dex_file_->GetMethodName(method_id); 3862 const Signature signature = dex_file_->GetMethodSignature(method_id); 3863 3864 if (res_kind == kDirectMethodResolution) { 3865 res_method = klass->FindDirectMethod(name, signature, pointer_size); 3866 } else if (res_kind == kVirtualMethodResolution) { 3867 res_method = klass->FindVirtualMethod(name, signature, pointer_size); 3868 } else { 3869 DCHECK_EQ(res_kind, kInterfaceMethodResolution); 3870 res_method = klass->FindInterfaceMethod(name, signature, pointer_size); 3871 } 3872 3873 if (res_method != nullptr) { 3874 stash_method = true; 3875 } else { 3876 // If a virtual or interface method wasn't found with the expected type, look in 3877 // the direct methods. This can happen when the wrong invoke type is used or when 3878 // a class has changed, and will be flagged as an error in later checks. 3879 // Note that in this case, we do not put the resolved method in the Dex cache 3880 // because it was not discovered using the expected type of method resolution. 3881 if (res_kind != kDirectMethodResolution) { 3882 // Record result of the initial resolution attempt. 3883 VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_kind, nullptr); 3884 // Change resolution type to 'direct' and try to resolve again. 3885 res_kind = kDirectMethodResolution; 3886 res_method = klass->FindDirectMethod(name, signature, pointer_size); 3887 } 3888 } 3889 } 3890 3891 // Record result of method resolution attempt. 3892 VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_kind, res_method); 3893 3894 if (res_method == nullptr) { 3895 Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method " 3896 << klass->PrettyDescriptor() << "." 3897 << dex_file_->GetMethodName(method_id) << " " 3898 << dex_file_->GetMethodSignature(method_id); 3899 return nullptr; 3900 } 3901 3902 // Make sure calls to constructors are "direct". There are additional restrictions but we don't 3903 // enforce them here. 3904 if (res_method->IsConstructor() && method_type != METHOD_DIRECT) { 3905 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor " 3906 << res_method->PrettyMethod(); 3907 return nullptr; 3908 } 3909 // Disallow any calls to class initializers. 3910 if (res_method->IsClassInitializer()) { 3911 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer " 3912 << res_method->PrettyMethod(); 3913 return nullptr; 3914 } 3915 3916 // Check that interface methods are static or match interface classes. 3917 // We only allow statics if we don't have default methods enabled. 3918 // 3919 // Note: this check must be after the initializer check, as those are required to fail a class, 3920 // while this check implies an IncompatibleClassChangeError. 3921 if (klass->IsInterface()) { 3922 // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if 3923 // dex file version is 37 or greater), or invoke-static. 3924 if (method_type != METHOD_INTERFACE && 3925 method_type != METHOD_STATIC && 3926 ((dex_file_->GetVersion() < DexFile::kDefaultMethodsVersion) || 3927 method_type != METHOD_DIRECT) && 3928 method_type != METHOD_SUPER) { 3929 Fail(VERIFY_ERROR_CLASS_CHANGE) 3930 << "non-interface method " << dex_file_->PrettyMethod(dex_method_idx) 3931 << " is in an interface class " << klass->PrettyClass(); 3932 return nullptr; 3933 } 3934 } else { 3935 if (method_type == METHOD_INTERFACE) { 3936 Fail(VERIFY_ERROR_CLASS_CHANGE) 3937 << "interface method " << dex_file_->PrettyMethod(dex_method_idx) 3938 << " is in a non-interface class " << klass->PrettyClass(); 3939 return nullptr; 3940 } 3941 } 3942 3943 // Only stash after the above passed. Otherwise the method wasn't guaranteed to be correct. 3944 if (stash_method) { 3945 dex_cache_->SetResolvedMethod(dex_method_idx, res_method, pointer_size); 3946 } 3947 3948 // Check if access is allowed. 3949 if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) { 3950 Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call " 3951 << res_method->PrettyMethod() 3952 << " from " << referrer << ")"; 3953 return res_method; 3954 } 3955 // Check that invoke-virtual and invoke-super are not used on private methods of the same class. 3956 if (res_method->IsPrivate() && (method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER)) { 3957 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method " 3958 << res_method->PrettyMethod(); 3959 return nullptr; 3960 } 3961 // See if the method type implied by the invoke instruction matches the access flags for the 3962 // target method. The flags for METHOD_POLYMORPHIC are based on there being precisely two 3963 // signature polymorphic methods supported by the run-time which are native methods with variable 3964 // arguments. 3965 if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) || 3966 (method_type == METHOD_STATIC && !res_method->IsStatic()) || 3967 ((method_type == METHOD_SUPER || 3968 method_type == METHOD_VIRTUAL || 3969 method_type == METHOD_INTERFACE) && res_method->IsDirect()) || 3970 ((method_type == METHOD_POLYMORPHIC) && 3971 (!res_method->IsNative() || !res_method->IsVarargs()))) { 3972 Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method " 3973 "type of " << res_method->PrettyMethod(); 3974 return nullptr; 3975 } 3976 return res_method; 3977 } 3978 3979 template <class T> 3980 ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator( 3981 T* it, const Instruction* inst, MethodType method_type, bool is_range, ArtMethod* res_method) { 3982 // We use vAA as our expected arg count, rather than res_method->insSize, because we need to 3983 // match the call to the signature. Also, we might be calling through an abstract method 3984 // definition (which doesn't have register count values). 3985 const size_t expected_args = inst->VRegA(); 3986 /* caught by static verifier */ 3987 DCHECK(is_range || expected_args <= 5); 3988 3989 // TODO(oth): Enable this path for invoke-polymorphic when b/33099829 is resolved. 3990 if (method_type != METHOD_POLYMORPHIC) { 3991 if (expected_args > code_item_->outs_size_) { 3992 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args 3993 << ") exceeds outsSize (" << code_item_->outs_size_ << ")"; 3994 return nullptr; 3995 } 3996 } 3997 3998 /* 3999 * Check the "this" argument, which must be an instance of the class that declared the method. 4000 * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a 4001 * rigorous check here (which is okay since we have to do it at runtime). 4002 */ 4003 if (method_type != METHOD_STATIC) { 4004 const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst); 4005 if (actual_arg_type.IsConflict()) { // GetInvocationThis failed. 4006 CHECK(have_pending_hard_failure_); 4007 return nullptr; 4008 } 4009 bool is_init = false; 4010 if (actual_arg_type.IsUninitializedTypes()) { 4011 if (res_method) { 4012 if (!res_method->IsConstructor()) { 4013 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized"; 4014 return nullptr; 4015 } 4016 } else { 4017 // Check whether the name of the called method is "<init>" 4018 const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 4019 if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) { 4020 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized"; 4021 return nullptr; 4022 } 4023 } 4024 is_init = true; 4025 } 4026 const RegType& adjusted_type = is_init 4027 ? GetRegTypeCache()->FromUninitialized(actual_arg_type) 4028 : actual_arg_type; 4029 if (method_type != METHOD_INTERFACE && !adjusted_type.IsZero()) { 4030 const RegType* res_method_class; 4031 // Miranda methods have the declaring interface as their declaring class, not the abstract 4032 // class. It would be wrong to use this for the type check (interface type checks are 4033 // postponed to runtime). 4034 if (res_method != nullptr && !res_method->IsMiranda()) { 4035 mirror::Class* klass = res_method->GetDeclaringClass(); 4036 std::string temp; 4037 res_method_class = &FromClass(klass->GetDescriptor(&temp), klass, 4038 klass->CannotBeAssignedFromOtherTypes()); 4039 } else { 4040 const uint32_t method_idx = inst->VRegB(); 4041 const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; 4042 res_method_class = ®_types_.FromDescriptor( 4043 GetClassLoader(), 4044 dex_file_->StringByTypeIdx(class_idx), 4045 false); 4046 } 4047 if (!res_method_class->IsAssignableFrom(adjusted_type, this)) { 4048 Fail(adjusted_type.IsUnresolvedTypes() 4049 ? VERIFY_ERROR_NO_CLASS 4050 : VERIFY_ERROR_BAD_CLASS_SOFT) 4051 << "'this' argument '" << actual_arg_type << "' not instance of '" 4052 << *res_method_class << "'"; 4053 // Continue on soft failures. We need to find possible hard failures to avoid problems in 4054 // the compiler. 4055 if (have_pending_hard_failure_) { 4056 return nullptr; 4057 } 4058 } 4059 } 4060 } 4061 4062 uint32_t arg[5]; 4063 if (!is_range) { 4064 inst->GetVarArgs(arg); 4065 } 4066 uint32_t sig_registers = (method_type == METHOD_STATIC) ? 0 : 1; 4067 for ( ; it->HasNext(); it->Next()) { 4068 if (sig_registers >= expected_args) { 4069 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() << 4070 " argument registers, method signature has " << sig_registers + 1 << " or more"; 4071 return nullptr; 4072 } 4073 4074 const char* param_descriptor = it->GetDescriptor(); 4075 4076 if (param_descriptor == nullptr) { 4077 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature " 4078 "component"; 4079 return nullptr; 4080 } 4081 4082 const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false); 4083 uint32_t get_reg = is_range ? inst->VRegC() + static_cast<uint32_t>(sig_registers) : 4084 arg[sig_registers]; 4085 if (reg_type.IsIntegralTypes()) { 4086 const RegType& src_type = work_line_->GetRegisterType(this, get_reg); 4087 if (!src_type.IsIntegralTypes()) { 4088 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type 4089 << " but expected " << reg_type; 4090 return nullptr; 4091 } 4092 } else { 4093 if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) { 4094 // Continue on soft failures. We need to find possible hard failures to avoid problems in 4095 // the compiler. 4096 if (have_pending_hard_failure_) { 4097 return nullptr; 4098 } 4099 } else if (reg_type.IsLongOrDoubleTypes()) { 4100 // Check that registers are consecutive (for non-range invokes). Invokes are the only 4101 // instructions not specifying register pairs by the first component, but require them 4102 // nonetheless. Only check when there's an actual register in the parameters. If there's 4103 // none, this will fail below. 4104 if (!is_range && sig_registers + 1 < expected_args) { 4105 uint32_t second_reg = arg[sig_registers + 1]; 4106 if (second_reg != get_reg + 1) { 4107 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, long or double parameter " 4108 "at index " << sig_registers << " is not a pair: " << get_reg << " + " 4109 << second_reg << "."; 4110 return nullptr; 4111 } 4112 } 4113 } 4114 } 4115 sig_registers += reg_type.IsLongOrDoubleTypes() ? 2 : 1; 4116 } 4117 if (expected_args != sig_registers) { 4118 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args << 4119 " argument registers, method signature has " << sig_registers; 4120 return nullptr; 4121 } 4122 return res_method; 4123 } 4124 4125 void MethodVerifier::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst, 4126 MethodType method_type, 4127 bool is_range) { 4128 // As the method may not have been resolved, make this static check against what we expect. 4129 // The main reason for this code block is to fail hard when we find an illegal use, e.g., 4130 // wrong number of arguments or wrong primitive types, even if the method could not be resolved. 4131 const uint32_t method_idx = inst->VRegB(); 4132 DexFileParameterIterator it(*dex_file_, 4133 dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_)); 4134 VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, nullptr); 4135 } 4136 4137 bool MethodVerifier::CheckCallSite(uint32_t call_site_idx) { 4138 if (call_site_idx >= dex_file_->NumCallSiteIds()) { 4139 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Bad call site id #" << call_site_idx 4140 << " >= " << dex_file_->NumCallSiteIds(); 4141 return false; 4142 } 4143 4144 CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx)); 4145 // Check essential arguments are provided. The dex file verifier has verified indicies of the 4146 // main values (method handle, name, method_type). 4147 if (it.Size() < 3) { 4148 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4149 << " has too few arguments: " 4150 << it.Size() << "< 3"; 4151 return false; 4152 } 4153 4154 // Get and check the first argument: the method handle (index range 4155 // checked by the dex file verifier). 4156 uint32_t method_handle_idx = static_cast<uint32_t>(it.GetJavaValue().i); 4157 it.Next(); 4158 4159 const DexFile::MethodHandleItem& mh = dex_file_->GetMethodHandle(method_handle_idx); 4160 if (mh.method_handle_type_ != static_cast<uint16_t>(DexFile::MethodHandleType::kInvokeStatic)) { 4161 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4162 << " argument 0 method handle type is not InvokeStatic"; 4163 return false; 4164 } 4165 4166 // Skip the second argument, the name to resolve, as checked by the 4167 // dex file verifier. 4168 it.Next(); 4169 4170 // Skip the third argument, the method type expected, as checked by 4171 // the dex file verifier. 4172 it.Next(); 4173 4174 // Check the bootstrap method handle and remaining arguments. 4175 const DexFile::MethodId& method_id = dex_file_->GetMethodId(mh.field_or_method_idx_); 4176 uint32_t length; 4177 const char* shorty = dex_file_->GetMethodShorty(method_id, &length); 4178 4179 if (it.Size() < length - 1) { 4180 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4181 << " too few arguments for bootstrap method: " 4182 << it.Size() << " < " << (length - 1); 4183 return false; 4184 } 4185 4186 // Check the return type and first 3 arguments are references 4187 // (CallSite, Lookup, String, MethodType). If they are not of the 4188 // expected types (or subtypes), it will trigger a 4189 // WrongMethodTypeException during execution. 4190 if (shorty[0] != 'L') { 4191 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4192 << " bootstrap return type is not a reference"; 4193 return false; 4194 } 4195 4196 for (uint32_t i = 1; i < 4; ++i) { 4197 if (shorty[i] != 'L') { 4198 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4199 << " bootstrap method argument " << (i - 1) 4200 << " is not a reference"; 4201 return false; 4202 } 4203 } 4204 4205 // Check the optional arguments. 4206 for (uint32_t i = 4; i < length; ++i, it.Next()) { 4207 bool match = false; 4208 switch (it.GetValueType()) { 4209 case EncodedArrayValueIterator::ValueType::kBoolean: 4210 case EncodedArrayValueIterator::ValueType::kByte: 4211 case EncodedArrayValueIterator::ValueType::kShort: 4212 case EncodedArrayValueIterator::ValueType::kChar: 4213 case EncodedArrayValueIterator::ValueType::kInt: 4214 // These all fit within one register and encoders do not seem 4215 // too exacting on the encoding type they use (ie using 4216 // integer for all of these). 4217 match = (strchr("ZBCSI", shorty[i]) != nullptr); 4218 break; 4219 case EncodedArrayValueIterator::ValueType::kLong: 4220 match = ('J' == shorty[i]); 4221 break; 4222 case EncodedArrayValueIterator::ValueType::kFloat: 4223 match = ('F' == shorty[i]); 4224 break; 4225 case EncodedArrayValueIterator::ValueType::kDouble: 4226 match = ('D' == shorty[i]); 4227 break; 4228 case EncodedArrayValueIterator::ValueType::kMethodType: 4229 case EncodedArrayValueIterator::ValueType::kMethodHandle: 4230 case EncodedArrayValueIterator::ValueType::kString: 4231 case EncodedArrayValueIterator::ValueType::kType: 4232 case EncodedArrayValueIterator::ValueType::kNull: 4233 match = ('L' == shorty[i]); 4234 break; 4235 case EncodedArrayValueIterator::ValueType::kField: 4236 case EncodedArrayValueIterator::ValueType::kMethod: 4237 case EncodedArrayValueIterator::ValueType::kEnum: 4238 case EncodedArrayValueIterator::ValueType::kArray: 4239 case EncodedArrayValueIterator::ValueType::kAnnotation: 4240 // Unreachable based on current EncodedArrayValueIterator::Next(). 4241 UNREACHABLE(); 4242 } 4243 4244 if (!match) { 4245 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx 4246 << " bootstrap method argument " << (i - 1) 4247 << " expected " << shorty[i] 4248 << " got value type: " << it.GetValueType(); 4249 return false; 4250 } 4251 } 4252 return true; 4253 } 4254 4255 class MethodParamListDescriptorIterator { 4256 public: 4257 explicit MethodParamListDescriptorIterator(ArtMethod* res_method) : 4258 res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()), 4259 params_size_(params_ == nullptr ? 0 : params_->Size()) { 4260 } 4261 4262 bool HasNext() { 4263 return pos_ < params_size_; 4264 } 4265 4266 void Next() { 4267 ++pos_; 4268 } 4269 4270 const char* GetDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) { 4271 return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_); 4272 } 4273 4274 private: 4275 ArtMethod* res_method_; 4276 size_t pos_; 4277 const DexFile::TypeList* params_; 4278 const size_t params_size_; 4279 }; 4280 4281 ArtMethod* MethodVerifier::VerifyInvocationArgs( 4282 const Instruction* inst, MethodType method_type, bool is_range) { 4283 // Resolve the method. This could be an abstract or concrete method depending on what sort of call 4284 // we're making. 4285 const uint32_t method_idx = inst->VRegB(); 4286 ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type); 4287 if (res_method == nullptr) { // error or class is unresolved 4288 // Check what we can statically. 4289 if (!have_pending_hard_failure_) { 4290 VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range); 4291 } 4292 return nullptr; 4293 } 4294 4295 // If we're using invoke-super(method), make sure that the executing method's class' superclass 4296 // has a vtable entry for the target method. Or the target is on a interface. 4297 if (method_type == METHOD_SUPER) { 4298 dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_; 4299 const RegType& reference_type = reg_types_.FromDescriptor( 4300 GetClassLoader(), 4301 dex_file_->StringByTypeIdx(class_idx), 4302 false); 4303 if (reference_type.IsUnresolvedTypes()) { 4304 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Unable to find referenced class from invoke-super"; 4305 return nullptr; 4306 } 4307 if (reference_type.GetClass()->IsInterface()) { 4308 // TODO Can we verify anything else. 4309 if (class_idx == class_def_.class_idx_) { 4310 Fail(VERIFY_ERROR_CLASS_CHANGE) << "Cannot invoke-super on self as interface"; 4311 return nullptr; 4312 } 4313 // TODO Revisit whether we want to allow invoke-super on direct interfaces only like the JLS 4314 // does. 4315 if (!GetDeclaringClass().HasClass()) { 4316 Fail(VERIFY_ERROR_NO_CLASS) << "Unable to resolve the full class of 'this' used in an" 4317 << "interface invoke-super"; 4318 return nullptr; 4319 } else if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this)) { 4320 Fail(VERIFY_ERROR_CLASS_CHANGE) 4321 << "invoke-super in " << mirror::Class::PrettyClass(GetDeclaringClass().GetClass()) 4322 << " in method " 4323 << dex_file_->PrettyMethod(dex_method_idx_) << " to method " 4324 << dex_file_->PrettyMethod(method_idx) << " references " 4325 << "non-super-interface type " << mirror::Class::PrettyClass(reference_type.GetClass()); 4326 return nullptr; 4327 } 4328 } else { 4329 const RegType& super = GetDeclaringClass().GetSuperClass(®_types_); 4330 if (super.IsUnresolvedTypes()) { 4331 Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from " 4332 << dex_file_->PrettyMethod(dex_method_idx_) 4333 << " to super " << res_method->PrettyMethod(); 4334 return nullptr; 4335 } 4336 if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this) || 4337 (res_method->GetMethodIndex() >= super.GetClass()->GetVTableLength())) { 4338 Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from " 4339 << dex_file_->PrettyMethod(dex_method_idx_) 4340 << " to super " << super 4341 << "." << res_method->GetName() 4342 << res_method->GetSignature(); 4343 return nullptr; 4344 } 4345 } 4346 } 4347 4348 if (method_type == METHOD_POLYMORPHIC) { 4349 // Process the signature of the calling site that is invoking the method handle. 4350 DexFileParameterIterator it(*dex_file_, dex_file_->GetProtoId(inst->VRegH())); 4351 return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method); 4352 } else { 4353 // Process the target method's signature. 4354 MethodParamListDescriptorIterator it(res_method); 4355 return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method); 4356 } 4357 } 4358 4359 bool MethodVerifier::CheckSignaturePolymorphicMethod(ArtMethod* method) { 4360 mirror::Class* klass = method->GetDeclaringClass(); 4361 if (klass != mirror::MethodHandle::StaticClass()) { 4362 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4363 << "Signature polymorphic method must be declared in java.lang.invoke.MethodClass"; 4364 return false; 4365 } 4366 4367 const char* method_name = method->GetName(); 4368 if (strcmp(method_name, "invoke") != 0 && strcmp(method_name, "invokeExact") != 0) { 4369 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4370 << "Signature polymorphic method name invalid: " << method_name; 4371 return false; 4372 } 4373 4374 const DexFile::TypeList* types = method->GetParameterTypeList(); 4375 if (types->Size() != 1) { 4376 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4377 << "Signature polymorphic method has too many arguments " << types->Size() << " != 1"; 4378 return false; 4379 } 4380 4381 const dex::TypeIndex argument_type_index = types->GetTypeItem(0).type_idx_; 4382 const char* argument_descriptor = method->GetTypeDescriptorFromTypeIdx(argument_type_index); 4383 if (strcmp(argument_descriptor, "[Ljava/lang/Object;") != 0) { 4384 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4385 << "Signature polymorphic method has unexpected argument type: " << argument_descriptor; 4386 return false; 4387 } 4388 4389 const char* return_descriptor = method->GetReturnTypeDescriptor(); 4390 if (strcmp(return_descriptor, "Ljava/lang/Object;") != 0) { 4391 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4392 << "Signature polymorphic method has unexpected return type: " << return_descriptor; 4393 return false; 4394 } 4395 4396 return true; 4397 } 4398 4399 bool MethodVerifier::CheckSignaturePolymorphicReceiver(const Instruction* inst) { 4400 const RegType& this_type = work_line_->GetInvocationThis(this, inst); 4401 if (this_type.IsZero()) { 4402 /* null pointer always passes (and always fails at run time) */ 4403 return true; 4404 } else if (!this_type.IsNonZeroReferenceTypes()) { 4405 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4406 << "invoke-polymorphic receiver is not a reference: " 4407 << this_type; 4408 return false; 4409 } else if (this_type.IsUninitializedReference()) { 4410 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4411 << "invoke-polymorphic receiver is uninitialized: " 4412 << this_type; 4413 return false; 4414 } else if (!this_type.HasClass()) { 4415 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4416 << "invoke-polymorphic receiver has no class: " 4417 << this_type; 4418 return false; 4419 } else if (!this_type.GetClass()->IsSubClass(mirror::MethodHandle::StaticClass())) { 4420 Fail(VERIFY_ERROR_BAD_CLASS_HARD) 4421 << "invoke-polymorphic receiver is not a subclass of MethodHandle: " 4422 << this_type; 4423 return false; 4424 } 4425 return true; 4426 } 4427 4428 ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst, RegisterLine* reg_line, 4429 bool is_range, bool allow_failure) { 4430 if (is_range) { 4431 DCHECK_EQ(inst->Opcode(), Instruction::INVOKE_VIRTUAL_RANGE_QUICK); 4432 } else { 4433 DCHECK_EQ(inst->Opcode(), Instruction::INVOKE_VIRTUAL_QUICK); 4434 } 4435 const RegType& actual_arg_type = reg_line->GetInvocationThis(this, inst, allow_failure); 4436 if (!actual_arg_type.HasClass()) { 4437 VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'"; 4438 return nullptr; 4439 } 4440 mirror::Class* klass = actual_arg_type.GetClass(); 4441 mirror::Class* dispatch_class; 4442 if (klass->IsInterface()) { 4443 // Derive Object.class from Class.class.getSuperclass(). 4444 mirror::Class* object_klass = klass->GetClass()->GetSuperClass(); 4445 if (FailOrAbort(this, object_klass->IsObjectClass(), 4446 "Failed to find Object class in quickened invoke receiver", work_insn_idx_)) { 4447 return nullptr; 4448 } 4449 dispatch_class = object_klass; 4450 } else { 4451 dispatch_class = klass; 4452 } 4453 if (!dispatch_class->HasVTable()) { 4454 FailOrAbort(this, allow_failure, "Receiver class has no vtable for quickened invoke at ", 4455 work_insn_idx_); 4456 return nullptr; 4457 } 4458 uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); 4459 auto* cl = Runtime::Current()->GetClassLinker(); 4460 auto pointer_size = cl->GetImagePointerSize(); 4461 if (static_cast<int32_t>(vtable_index) >= dispatch_class->GetVTableLength()) { 4462 FailOrAbort(this, allow_failure, 4463 "Receiver class has not enough vtable slots for quickened invoke at ", 4464 work_insn_idx_); 4465 return nullptr; 4466 } 4467 ArtMethod* res_method = dispatch_class->GetVTableEntry(vtable_index, pointer_size); 4468 if (self_->IsExceptionPending()) { 4469 FailOrAbort(this, allow_failure, "Unexpected exception pending for quickened invoke at ", 4470 work_insn_idx_); 4471 return nullptr; 4472 } 4473 return res_method; 4474 } 4475 4476 ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst, bool is_range) { 4477 DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_) 4478 << dex_file_->PrettyMethod(dex_method_idx_, true) << "@" << work_insn_idx_; 4479 4480 ArtMethod* res_method = GetQuickInvokedMethod(inst, work_line_.get(), is_range, false); 4481 if (res_method == nullptr) { 4482 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer method from " << inst->Name(); 4483 return nullptr; 4484 } 4485 if (FailOrAbort(this, !res_method->IsDirect(), "Quick-invoked method is direct at ", 4486 work_insn_idx_)) { 4487 return nullptr; 4488 } 4489 if (FailOrAbort(this, !res_method->IsStatic(), "Quick-invoked method is static at ", 4490 work_insn_idx_)) { 4491 return nullptr; 4492 } 4493 4494 // We use vAA as our expected arg count, rather than res_method->insSize, because we need to 4495 // match the call to the signature. Also, we might be calling through an abstract method 4496 // definition (which doesn't have register count values). 4497 const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst); 4498 if (actual_arg_type.IsConflict()) { // GetInvocationThis failed. 4499 return nullptr; 4500 } 4501 const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c(); 4502 /* caught by static verifier */ 4503 DCHECK(is_range || expected_args <= 5); 4504 if (expected_args > code_item_->outs_size_) { 4505 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args 4506 << ") exceeds outsSize (" << code_item_->outs_size_ << ")"; 4507 return nullptr; 4508 } 4509 4510 /* 4511 * Check the "this" argument, which must be an instance of the class that declared the method. 4512 * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a 4513 * rigorous check here (which is okay since we have to do it at runtime). 4514 */ 4515 // Note: given an uninitialized type, this should always fail. Constructors aren't virtual. 4516 if (actual_arg_type.IsUninitializedTypes() && !res_method->IsConstructor()) { 4517 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized"; 4518 return nullptr; 4519 } 4520 if (!actual_arg_type.IsZero()) { 4521 mirror::Class* klass = res_method->GetDeclaringClass(); 4522 std::string temp; 4523 const RegType& res_method_class = 4524 FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes()); 4525 if (!res_method_class.IsAssignableFrom(actual_arg_type, this)) { 4526 Fail(actual_arg_type.IsUninitializedTypes() // Just overcautious - should have never 4527 ? VERIFY_ERROR_BAD_CLASS_HARD // quickened this. 4528 : actual_arg_type.IsUnresolvedTypes() 4529 ? VERIFY_ERROR_NO_CLASS 4530 : VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type 4531 << "' not instance of '" << res_method_class << "'"; 4532 return nullptr; 4533 } 4534 } 4535 /* 4536 * Process the target method's signature. This signature may or may not 4537 * have been verified, so we can't assume it's properly formed. 4538 */ 4539 const DexFile::TypeList* params = res_method->GetParameterTypeList(); 4540 size_t params_size = params == nullptr ? 0 : params->Size(); 4541 uint32_t arg[5]; 4542 if (!is_range) { 4543 inst->GetVarArgs(arg); 4544 } 4545 size_t actual_args = 1; 4546 for (size_t param_index = 0; param_index < params_size; param_index++) { 4547 if (actual_args >= expected_args) { 4548 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invalid call to '" 4549 << res_method->PrettyMethod() 4550 << "'. Expected " << expected_args 4551 << " arguments, processing argument " << actual_args 4552 << " (where longs/doubles count twice)."; 4553 return nullptr; 4554 } 4555 const char* descriptor = 4556 res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_); 4557 if (descriptor == nullptr) { 4558 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " 4559 << res_method->PrettyMethod() 4560 << " missing signature component"; 4561 return nullptr; 4562 } 4563 const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false); 4564 uint32_t get_reg = is_range ? inst->VRegC_3rc() + actual_args : arg[actual_args]; 4565 if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) { 4566 return res_method; 4567 } 4568 actual_args = reg_type.IsLongOrDoubleTypes() ? actual_args + 2 : actual_args + 1; 4569 } 4570 if (actual_args != expected_args) { 4571 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " 4572 << res_method->PrettyMethod() << " expected " 4573 << expected_args << " arguments, found " << actual_args; 4574 return nullptr; 4575 } else { 4576 return res_method; 4577 } 4578 } 4579 4580 void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) { 4581 dex::TypeIndex type_idx; 4582 if (!is_filled) { 4583 DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY); 4584 type_idx = dex::TypeIndex(inst->VRegC_22c()); 4585 } else if (!is_range) { 4586 DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY); 4587 type_idx = dex::TypeIndex(inst->VRegB_35c()); 4588 } else { 4589 DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE); 4590 type_idx = dex::TypeIndex(inst->VRegB_3rc()); 4591 } 4592 const RegType& res_type = ResolveClassAndCheckAccess(type_idx); 4593 if (res_type.IsConflict()) { // bad class 4594 DCHECK_NE(failures_.size(), 0U); 4595 } else { 4596 // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved 4597 if (!res_type.IsArrayTypes()) { 4598 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type; 4599 } else if (!is_filled) { 4600 /* make sure "size" register is valid type */ 4601 work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer()); 4602 /* set register type to array class */ 4603 const RegType& precise_type = reg_types_.FromUninitialized(res_type); 4604 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_22c(), precise_type); 4605 } else { 4606 DCHECK(!res_type.IsUnresolvedMergedReference()); 4607 // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of 4608 // the list and fail. It's legal, if silly, for arg_count to be zero. 4609 const RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader()); 4610 uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c(); 4611 uint32_t arg[5]; 4612 if (!is_range) { 4613 inst->GetVarArgs(arg); 4614 } 4615 for (size_t ui = 0; ui < arg_count; ui++) { 4616 uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui]; 4617 if (!work_line_->VerifyRegisterType(this, get_reg, expected_type)) { 4618 work_line_->SetResultRegisterType(this, reg_types_.Conflict()); 4619 return; 4620 } 4621 } 4622 // filled-array result goes into "result" register 4623 const RegType& precise_type = reg_types_.FromUninitialized(res_type); 4624 work_line_->SetResultRegisterType(this, precise_type); 4625 } 4626 } 4627 } 4628 4629 void MethodVerifier::VerifyAGet(const Instruction* inst, 4630 const RegType& insn_type, bool is_primitive) { 4631 const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x()); 4632 if (!index_type.IsArrayIndexTypes()) { 4633 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")"; 4634 } else { 4635 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x()); 4636 if (array_type.IsZero()) { 4637 have_pending_runtime_throw_failure_ = true; 4638 // Null array class; this code path will fail at runtime. Infer a merge-able type from the 4639 // instruction type. TODO: have a proper notion of bottom here. 4640 if (!is_primitive || insn_type.IsCategory1Types()) { 4641 // Reference or category 1 4642 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Zero()); 4643 } else { 4644 // Category 2 4645 work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), 4646 reg_types_.FromCat2ConstLo(0, false), 4647 reg_types_.FromCat2ConstHi(0, false)); 4648 } 4649 } else if (!array_type.IsArrayTypes()) { 4650 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget"; 4651 } else if (array_type.IsUnresolvedMergedReference()) { 4652 // Unresolved array types must be reference array types. 4653 if (is_primitive) { 4654 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type 4655 << " source for category 1 aget"; 4656 } else { 4657 Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aget for " << array_type 4658 << " because of missing class"; 4659 // Approximate with java.lang.Object[]. 4660 work_line_->SetRegisterType<LockOp::kClear>(this, 4661 inst->VRegA_23x(), 4662 reg_types_.JavaLangObject(false)); 4663 } 4664 } else { 4665 /* verify the class */ 4666 const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader()); 4667 if (!component_type.IsReferenceTypes() && !is_primitive) { 4668 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type 4669 << " source for aget-object"; 4670 } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) { 4671 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type 4672 << " source for category 1 aget"; 4673 } else if (is_primitive && !insn_type.Equals(component_type) && 4674 !((insn_type.IsInteger() && component_type.IsFloat()) || 4675 (insn_type.IsLong() && component_type.IsDouble()))) { 4676 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type 4677 << " incompatible with aget of type " << insn_type; 4678 } else { 4679 // Use knowledge of the field type which is stronger than the type inferred from the 4680 // instruction, which can't differentiate object types and ints from floats, longs from 4681 // doubles. 4682 if (!component_type.IsLowHalf()) { 4683 work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), component_type); 4684 } else { 4685 work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type, 4686 component_type.HighHalf(®_types_)); 4687 } 4688 } 4689 } 4690 } 4691 } 4692 4693 void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type, 4694 const uint32_t vregA) { 4695 // Primitive assignability rules are weaker than regular assignability rules. 4696 bool instruction_compatible; 4697 bool value_compatible; 4698 const RegType& value_type = work_line_->GetRegisterType(this, vregA); 4699 if (target_type.IsIntegralTypes()) { 4700 instruction_compatible = target_type.Equals(insn_type); 4701 value_compatible = value_type.IsIntegralTypes(); 4702 } else if (target_type.IsFloat()) { 4703 instruction_compatible = insn_type.IsInteger(); // no put-float, so expect put-int 4704 value_compatible = value_type.IsFloatTypes(); 4705 } else if (target_type.IsLong()) { 4706 instruction_compatible = insn_type.IsLong(); 4707 // Additional register check: this is not checked statically (as part of VerifyInstructions), 4708 // as target_type depends on the resolved type of the field. 4709 if (instruction_compatible && work_line_->NumRegs() > vregA + 1) { 4710 const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1); 4711 value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi); 4712 } else { 4713 value_compatible = false; 4714 } 4715 } else if (target_type.IsDouble()) { 4716 instruction_compatible = insn_type.IsLong(); // no put-double, so expect put-long 4717 // Additional register check: this is not checked statically (as part of VerifyInstructions), 4718 // as target_type depends on the resolved type of the field. 4719 if (instruction_compatible && work_line_->NumRegs() > vregA + 1) { 4720 const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1); 4721 value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi); 4722 } else { 4723 value_compatible = false; 4724 } 4725 } else { 4726 instruction_compatible = false; // reference with primitive store 4727 value_compatible = false; // unused 4728 } 4729 if (!instruction_compatible) { 4730 // This is a global failure rather than a class change failure as the instructions and 4731 // the descriptors for the type should have been consistent within the same file at 4732 // compile time. 4733 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type 4734 << "' but expected type '" << target_type << "'"; 4735 return; 4736 } 4737 if (!value_compatible) { 4738 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA 4739 << " of type " << value_type << " but expected " << target_type << " for put"; 4740 return; 4741 } 4742 } 4743 4744 void MethodVerifier::VerifyAPut(const Instruction* inst, 4745 const RegType& insn_type, bool is_primitive) { 4746 const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x()); 4747 if (!index_type.IsArrayIndexTypes()) { 4748 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")"; 4749 } else { 4750 const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x()); 4751 if (array_type.IsZero()) { 4752 // Null array type; this code path will fail at runtime. 4753 // Still check that the given value matches the instruction's type. 4754 // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed 4755 // and fits multiple register types. 4756 const RegType* modified_reg_type = &insn_type; 4757 if ((modified_reg_type == ®_types_.Integer()) || 4758 (modified_reg_type == ®_types_.LongLo())) { 4759 // May be integer or float | long or double. Overwrite insn_type accordingly. 4760 const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x()); 4761 if (modified_reg_type == ®_types_.Integer()) { 4762 if (&value_type == ®_types_.Float()) { 4763 modified_reg_type = &value_type; 4764 } 4765 } else { 4766 if (&value_type == ®_types_.DoubleLo()) { 4767 modified_reg_type = &value_type; 4768 } 4769 } 4770 } 4771 work_line_->VerifyRegisterType(this, inst->VRegA_23x(), *modified_reg_type); 4772 } else if (!array_type.IsArrayTypes()) { 4773 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput"; 4774 } else if (array_type.IsUnresolvedMergedReference()) { 4775 // Unresolved array types must be reference array types. 4776 if (is_primitive) { 4777 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type 4778 << "' but unresolved type '" << array_type << "'"; 4779 } else { 4780 Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aput for " << array_type 4781 << " because of missing class"; 4782 } 4783 } else { 4784 const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader()); 4785 const uint32_t vregA = inst->VRegA_23x(); 4786 if (is_primitive) { 4787 VerifyPrimitivePut(component_type, insn_type, vregA); 4788 } else { 4789 if (!component_type.IsReferenceTypes()) { 4790 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type 4791 << " source for aput-object"; 4792 } else { 4793 // The instruction agrees with the type of array, confirm the value to be stored does too 4794 // Note: we use the instruction type (rather than the component type) for aput-object as 4795 // incompatible classes will be caught at runtime as an array store exception 4796 work_line_->VerifyRegisterType(this, vregA, insn_type); 4797 } 4798 } 4799 } 4800 } 4801 } 4802 4803 ArtField* MethodVerifier::GetStaticField(int field_idx) { 4804 const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4805 // Check access to class 4806 const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_); 4807 if (klass_type.IsConflict()) { // bad class 4808 AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s", 4809 field_idx, dex_file_->GetFieldName(field_id), 4810 dex_file_->GetFieldDeclaringClassDescriptor(field_id))); 4811 return nullptr; 4812 } 4813 if (klass_type.IsUnresolvedTypes()) { 4814 return nullptr; // Can't resolve Class so no more to do here, will do checking at runtime. 4815 } 4816 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 4817 ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_, class_loader_); 4818 4819 // Record result of the field resolution attempt. 4820 VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field); 4821 4822 if (field == nullptr) { 4823 VLOG(verifier) << "Unable to resolve static field " << field_idx << " (" 4824 << dex_file_->GetFieldName(field_id) << ") in " 4825 << dex_file_->GetFieldDeclaringClassDescriptor(field_id); 4826 DCHECK(self_->IsExceptionPending()); 4827 self_->ClearException(); 4828 return nullptr; 4829 } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(), 4830 field->GetAccessFlags())) { 4831 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << field->PrettyField() 4832 << " from " << GetDeclaringClass(); 4833 return nullptr; 4834 } else if (!field->IsStatic()) { 4835 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() << " to be static"; 4836 return nullptr; 4837 } 4838 return field; 4839 } 4840 4841 ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) { 4842 const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4843 // Check access to class. 4844 const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_); 4845 if (klass_type.IsConflict()) { 4846 AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s", 4847 field_idx, dex_file_->GetFieldName(field_id), 4848 dex_file_->GetFieldDeclaringClassDescriptor(field_id))); 4849 return nullptr; 4850 } 4851 if (klass_type.IsUnresolvedTypes()) { 4852 return nullptr; // Can't resolve Class so no more to do here 4853 } 4854 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 4855 ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_, class_loader_); 4856 4857 // Record result of the field resolution attempt. 4858 VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field); 4859 4860 if (field == nullptr) { 4861 VLOG(verifier) << "Unable to resolve instance field " << field_idx << " (" 4862 << dex_file_->GetFieldName(field_id) << ") in " 4863 << dex_file_->GetFieldDeclaringClassDescriptor(field_id); 4864 DCHECK(self_->IsExceptionPending()); 4865 self_->ClearException(); 4866 return nullptr; 4867 } else if (obj_type.IsZero()) { 4868 // Cannot infer and check type, however, access will cause null pointer exception. 4869 // Fall through into a few last soft failure checks below. 4870 } else if (!obj_type.IsReferenceTypes()) { 4871 // Trying to read a field from something that isn't a reference. 4872 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has " 4873 << "non-reference type " << obj_type; 4874 return nullptr; 4875 } else { 4876 std::string temp; 4877 ObjPtr<mirror::Class> klass = field->GetDeclaringClass(); 4878 const RegType& field_klass = 4879 FromClass(klass->GetDescriptor(&temp), 4880 klass.Ptr(), 4881 klass->CannotBeAssignedFromOtherTypes()); 4882 if (obj_type.IsUninitializedTypes()) { 4883 // Field accesses through uninitialized references are only allowable for constructors where 4884 // the field is declared in this class. 4885 // Note: this IsConstructor check is technically redundant, as UninitializedThis should only 4886 // appear in constructors. 4887 if (!obj_type.IsUninitializedThisReference() || 4888 !IsConstructor() || 4889 !field_klass.Equals(GetDeclaringClass())) { 4890 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << field->PrettyField() 4891 << " of a not fully initialized object within the context" 4892 << " of " << dex_file_->PrettyMethod(dex_method_idx_); 4893 return nullptr; 4894 } 4895 } else if (!field_klass.IsAssignableFrom(obj_type, this)) { 4896 // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class 4897 // of C1. For resolution to occur the declared class of the field must be compatible with 4898 // obj_type, we've discovered this wasn't so, so report the field didn't exist. 4899 VerifyError type; 4900 bool is_aot = Runtime::Current()->IsAotCompiler(); 4901 if (is_aot && (field_klass.IsUnresolvedTypes() || obj_type.IsUnresolvedTypes())) { 4902 // Compiler & unresolved types involved, retry at runtime. 4903 type = VerifyError::VERIFY_ERROR_NO_CLASS; 4904 } else { 4905 // Classes known (resolved; and thus assignability check is precise), or we are at runtime 4906 // and still missing classes. This is a hard failure. 4907 type = VerifyError::VERIFY_ERROR_BAD_CLASS_HARD; 4908 } 4909 Fail(type) << "cannot access instance field " << field->PrettyField() 4910 << " from object of type " << obj_type; 4911 return nullptr; 4912 } 4913 } 4914 4915 // Few last soft failure checks. 4916 if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(), 4917 field->GetAccessFlags())) { 4918 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << field->PrettyField() 4919 << " from " << GetDeclaringClass(); 4920 return nullptr; 4921 } else if (field->IsStatic()) { 4922 Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() 4923 << " to not be static"; 4924 return nullptr; 4925 } 4926 4927 return field; 4928 } 4929 4930 template <MethodVerifier::FieldAccessType kAccType> 4931 void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& insn_type, 4932 bool is_primitive, bool is_static) { 4933 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 4934 ArtField* field; 4935 if (is_static) { 4936 field = GetStaticField(field_idx); 4937 } else { 4938 const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c()); 4939 4940 // One is not allowed to access fields on uninitialized references, except to write to 4941 // fields in the constructor (before calling another constructor). 4942 // GetInstanceField does an assignability check which will fail for uninitialized types. 4943 // We thus modify the type if the uninitialized reference is a "this" reference (this also 4944 // checks at the same time that we're verifying a constructor). 4945 bool should_adjust = (kAccType == FieldAccessType::kAccPut) && 4946 object_type.IsUninitializedThisReference(); 4947 const RegType& adjusted_type = should_adjust 4948 ? GetRegTypeCache()->FromUninitialized(object_type) 4949 : object_type; 4950 field = GetInstanceField(adjusted_type, field_idx); 4951 if (UNLIKELY(have_pending_hard_failure_)) { 4952 return; 4953 } 4954 if (should_adjust) { 4955 if (field == nullptr) { 4956 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Might be accessing a superclass instance field prior " 4957 << "to the superclass being initialized in " 4958 << dex_file_->PrettyMethod(dex_method_idx_); 4959 } else if (field->GetDeclaringClass() != GetDeclaringClass().GetClass()) { 4960 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access superclass instance field " 4961 << field->PrettyField() << " of a not fully initialized " 4962 << "object within the context of " 4963 << dex_file_->PrettyMethod(dex_method_idx_); 4964 return; 4965 } 4966 } 4967 } 4968 const RegType* field_type = nullptr; 4969 if (field != nullptr) { 4970 if (kAccType == FieldAccessType::kAccPut) { 4971 if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) { 4972 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField() 4973 << " from other class " << GetDeclaringClass(); 4974 // Keep hunting for possible hard fails. 4975 } 4976 } 4977 4978 ObjPtr<mirror::Class> field_type_class = 4979 can_load_classes_ ? field->GetType<true>() : field->GetType<false>(); 4980 if (field_type_class != nullptr) { 4981 field_type = &FromClass(field->GetTypeDescriptor(), 4982 field_type_class.Ptr(), 4983 field_type_class->CannotBeAssignedFromOtherTypes()); 4984 } else { 4985 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 4986 self_->ClearException(); 4987 } 4988 } 4989 if (field_type == nullptr) { 4990 const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx); 4991 const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id); 4992 field_type = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); 4993 } 4994 DCHECK(field_type != nullptr); 4995 const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c(); 4996 static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet, 4997 "Unexpected third access type"); 4998 if (kAccType == FieldAccessType::kAccPut) { 4999 // sput or iput. 5000 if (is_primitive) { 5001 VerifyPrimitivePut(*field_type, insn_type, vregA); 5002 } else { 5003 if (!insn_type.IsAssignableFrom(*field_type, this)) { 5004 // If the field type is not a reference, this is a global failure rather than 5005 // a class change failure as the instructions and the descriptors for the type 5006 // should have been consistent within the same file at compile time. 5007 VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT 5008 : VERIFY_ERROR_BAD_CLASS_HARD; 5009 Fail(error) << "expected field " << ArtField::PrettyField(field) 5010 << " to be compatible with type '" << insn_type 5011 << "' but found type '" << *field_type 5012 << "' in put-object"; 5013 return; 5014 } 5015 work_line_->VerifyRegisterType(this, vregA, *field_type); 5016 } 5017 } else if (kAccType == FieldAccessType::kAccGet) { 5018 // sget or iget. 5019 if (is_primitive) { 5020 if (field_type->Equals(insn_type) || 5021 (field_type->IsFloat() && insn_type.IsInteger()) || 5022 (field_type->IsDouble() && insn_type.IsLong())) { 5023 // expected that read is of the correct primitive type or that int reads are reading 5024 // floats or long reads are reading doubles 5025 } else { 5026 // This is a global failure rather than a class change failure as the instructions and 5027 // the descriptors for the type should have been consistent within the same file at 5028 // compile time 5029 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field) 5030 << " to be of type '" << insn_type 5031 << "' but found type '" << *field_type << "' in get"; 5032 return; 5033 } 5034 } else { 5035 if (!insn_type.IsAssignableFrom(*field_type, this)) { 5036 // If the field type is not a reference, this is a global failure rather than 5037 // a class change failure as the instructions and the descriptors for the type 5038 // should have been consistent within the same file at compile time. 5039 VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT 5040 : VERIFY_ERROR_BAD_CLASS_HARD; 5041 Fail(error) << "expected field " << ArtField::PrettyField(field) 5042 << " to be compatible with type '" << insn_type 5043 << "' but found type '" << *field_type 5044 << "' in get-object"; 5045 if (error != VERIFY_ERROR_BAD_CLASS_HARD) { 5046 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict()); 5047 } 5048 return; 5049 } 5050 } 5051 if (!field_type->IsLowHalf()) { 5052 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type); 5053 } else { 5054 work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(®_types_)); 5055 } 5056 } else { 5057 LOG(FATAL) << "Unexpected case."; 5058 } 5059 } 5060 5061 ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, 5062 RegisterLine* reg_line) { 5063 DCHECK(IsInstructionIGetQuickOrIPutQuick(inst->Opcode())) << inst->Opcode(); 5064 const RegType& object_type = reg_line->GetRegisterType(this, inst->VRegB_22c()); 5065 if (!object_type.HasClass()) { 5066 VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'"; 5067 return nullptr; 5068 } 5069 uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c()); 5070 ArtField* const f = ArtField::FindInstanceFieldWithOffset(object_type.GetClass(), field_offset); 5071 DCHECK_EQ(f->GetOffset().Uint32Value(), field_offset); 5072 if (f == nullptr) { 5073 VLOG(verifier) << "Failed to find instance field at offset '" << field_offset 5074 << "' from '" << mirror::Class::PrettyDescriptor(object_type.GetClass()) << "'"; 5075 } 5076 return f; 5077 } 5078 5079 template <MethodVerifier::FieldAccessType kAccType> 5080 void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, const RegType& insn_type, 5081 bool is_primitive) { 5082 DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_); 5083 5084 ArtField* field = GetQuickFieldAccess(inst, work_line_.get()); 5085 if (field == nullptr) { 5086 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name(); 5087 return; 5088 } 5089 5090 // For an IPUT_QUICK, we now test for final flag of the field. 5091 if (kAccType == FieldAccessType::kAccPut) { 5092 if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) { 5093 Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField() 5094 << " from other class " << GetDeclaringClass(); 5095 return; 5096 } 5097 } 5098 5099 // Get the field type. 5100 const RegType* field_type; 5101 { 5102 ObjPtr<mirror::Class> field_type_class = can_load_classes_ ? field->GetType<true>() : 5103 field->GetType<false>(); 5104 5105 if (field_type_class != nullptr) { 5106 field_type = &FromClass(field->GetTypeDescriptor(), 5107 field_type_class.Ptr(), 5108 field_type_class->CannotBeAssignedFromOtherTypes()); 5109 } else { 5110 Thread* self = Thread::Current(); 5111 DCHECK(!can_load_classes_ || self->IsExceptionPending()); 5112 self->ClearException(); 5113 field_type = ®_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(), 5114 field->GetTypeDescriptor(), 5115 false); 5116 } 5117 if (field_type == nullptr) { 5118 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field type from " << inst->Name(); 5119 return; 5120 } 5121 } 5122 5123 const uint32_t vregA = inst->VRegA_22c(); 5124 static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet, 5125 "Unexpected third access type"); 5126 if (kAccType == FieldAccessType::kAccPut) { 5127 if (is_primitive) { 5128 // Primitive field assignability rules are weaker than regular assignability rules 5129 bool instruction_compatible; 5130 bool value_compatible; 5131 const RegType& value_type = work_line_->GetRegisterType(this, vregA); 5132 if (field_type->IsIntegralTypes()) { 5133 instruction_compatible = insn_type.IsIntegralTypes(); 5134 value_compatible = value_type.IsIntegralTypes(); 5135 } else if (field_type->IsFloat()) { 5136 instruction_compatible = insn_type.IsInteger(); // no [is]put-float, so expect [is]put-int 5137 value_compatible = value_type.IsFloatTypes(); 5138 } else if (field_type->IsLong()) { 5139 instruction_compatible = insn_type.IsLong(); 5140 value_compatible = value_type.IsLongTypes(); 5141 } else if (field_type->IsDouble()) { 5142 instruction_compatible = insn_type.IsLong(); // no [is]put-double, so expect [is]put-long 5143 value_compatible = value_type.IsDoubleTypes(); 5144 } else { 5145 instruction_compatible = false; // reference field with primitive store 5146 value_compatible = false; // unused 5147 } 5148 if (!instruction_compatible) { 5149 // This is a global failure rather than a class change failure as the instructions and 5150 // the descriptors for the type should have been consistent within the same file at 5151 // compile time 5152 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field) 5153 << " to be of type '" << insn_type 5154 << "' but found type '" << *field_type 5155 << "' in put"; 5156 return; 5157 } 5158 if (!value_compatible) { 5159 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA 5160 << " of type " << value_type 5161 << " but expected " << *field_type 5162 << " for store to " << ArtField::PrettyField(field) << " in put"; 5163 return; 5164 } 5165 } else { 5166 if (!insn_type.IsAssignableFrom(*field_type, this)) { 5167 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << ArtField::PrettyField(field) 5168 << " to be compatible with type '" << insn_type 5169 << "' but found type '" << *field_type 5170 << "' in put-object"; 5171 return; 5172 } 5173 work_line_->VerifyRegisterType(this, vregA, *field_type); 5174 } 5175 } else if (kAccType == FieldAccessType::kAccGet) { 5176 if (is_primitive) { 5177 if (field_type->Equals(insn_type) || 5178 (field_type->IsFloat() && insn_type.IsIntegralTypes()) || 5179 (field_type->IsDouble() && insn_type.IsLongTypes())) { 5180 // expected that read is of the correct primitive type or that int reads are reading 5181 // floats or long reads are reading doubles 5182 } else { 5183 // This is a global failure rather than a class change failure as the instructions and 5184 // the descriptors for the type should have been consistent within the same file at 5185 // compile time 5186 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field) 5187 << " to be of type '" << insn_type 5188 << "' but found type '" << *field_type << "' in Get"; 5189 return; 5190 } 5191 } else { 5192 if (!insn_type.IsAssignableFrom(*field_type, this)) { 5193 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << ArtField::PrettyField(field) 5194 << " to be compatible with type '" << insn_type 5195 << "' but found type '" << *field_type 5196 << "' in get-object"; 5197 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict()); 5198 return; 5199 } 5200 } 5201 if (!field_type->IsLowHalf()) { 5202 work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type); 5203 } else { 5204 work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(®_types_)); 5205 } 5206 } else { 5207 LOG(FATAL) << "Unexpected case."; 5208 } 5209 } 5210 5211 bool MethodVerifier::CheckNotMoveException(const uint16_t* insns, int insn_idx) { 5212 if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) { 5213 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception"; 5214 return false; 5215 } 5216 return true; 5217 } 5218 5219 bool MethodVerifier::CheckNotMoveResult(const uint16_t* insns, int insn_idx) { 5220 if (((insns[insn_idx] & 0xff) >= Instruction::MOVE_RESULT) && 5221 ((insns[insn_idx] & 0xff) <= Instruction::MOVE_RESULT_OBJECT)) { 5222 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-result*"; 5223 return false; 5224 } 5225 return true; 5226 } 5227 5228 bool MethodVerifier::CheckNotMoveExceptionOrMoveResult(const uint16_t* insns, int insn_idx) { 5229 return (CheckNotMoveException(insns, insn_idx) && CheckNotMoveResult(insns, insn_idx)); 5230 } 5231 5232 bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line, 5233 bool update_merge_line) { 5234 bool changed = true; 5235 RegisterLine* target_line = reg_table_.GetLine(next_insn); 5236 if (!GetInstructionFlags(next_insn).IsVisitedOrChanged()) { 5237 /* 5238 * We haven't processed this instruction before, and we haven't touched the registers here, so 5239 * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the 5240 * only way a register can transition out of "unknown", so this is not just an optimization.) 5241 */ 5242 target_line->CopyFromLine(merge_line); 5243 if (GetInstructionFlags(next_insn).IsReturn()) { 5244 // Verify that the monitor stack is empty on return. 5245 merge_line->VerifyMonitorStackEmpty(this); 5246 5247 // For returns we only care about the operand to the return, all other registers are dead. 5248 // Initialize them as conflicts so they don't add to GC and deoptimization information. 5249 const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn); 5250 AdjustReturnLine(this, ret_inst, target_line); 5251 // Directly bail if a hard failure was found. 5252 if (have_pending_hard_failure_) { 5253 return false; 5254 } 5255 } 5256 } else { 5257 RegisterLineArenaUniquePtr copy; 5258 if (kDebugVerify) { 5259 copy.reset(RegisterLine::Create(target_line->NumRegs(), this)); 5260 copy->CopyFromLine(target_line); 5261 } 5262 changed = target_line->MergeRegisters(this, merge_line); 5263 if (have_pending_hard_failure_) { 5264 return false; 5265 } 5266 if (kDebugVerify && changed) { 5267 LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]" 5268 << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n" 5269 << copy->Dump(this) << " MERGE\n" 5270 << merge_line->Dump(this) << " ==\n" 5271 << target_line->Dump(this) << "\n"; 5272 } 5273 if (update_merge_line && changed) { 5274 merge_line->CopyFromLine(target_line); 5275 } 5276 } 5277 if (changed) { 5278 GetInstructionFlags(next_insn).SetChanged(); 5279 } 5280 return true; 5281 } 5282 5283 InstructionFlags* MethodVerifier::CurrentInsnFlags() { 5284 return &GetInstructionFlags(work_insn_idx_); 5285 } 5286 5287 const RegType& MethodVerifier::GetMethodReturnType() { 5288 if (return_type_ == nullptr) { 5289 if (mirror_method_ != nullptr) { 5290 mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_); 5291 if (return_type_class != nullptr) { 5292 return_type_ = &FromClass(mirror_method_->GetReturnTypeDescriptor(), 5293 return_type_class, 5294 return_type_class->CannotBeAssignedFromOtherTypes()); 5295 } else { 5296 DCHECK(!can_load_classes_ || self_->IsExceptionPending()); 5297 self_->ClearException(); 5298 } 5299 } 5300 if (return_type_ == nullptr) { 5301 const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 5302 const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id); 5303 dex::TypeIndex return_type_idx = proto_id.return_type_idx_; 5304 const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx)); 5305 return_type_ = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); 5306 } 5307 } 5308 return *return_type_; 5309 } 5310 5311 const RegType& MethodVerifier::GetDeclaringClass() { 5312 if (declaring_class_ == nullptr) { 5313 const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); 5314 const char* descriptor 5315 = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_)); 5316 if (mirror_method_ != nullptr) { 5317 mirror::Class* klass = mirror_method_->GetDeclaringClass(); 5318 declaring_class_ = &FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()); 5319 } else { 5320 declaring_class_ = ®_types_.FromDescriptor(GetClassLoader(), descriptor, false); 5321 } 5322 } 5323 return *declaring_class_; 5324 } 5325 5326 std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) { 5327 RegisterLine* line = reg_table_.GetLine(dex_pc); 5328 DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc); 5329 std::vector<int32_t> result; 5330 for (size_t i = 0; i < line->NumRegs(); ++i) { 5331 const RegType& type = line->GetRegisterType(this, i); 5332 if (type.IsConstant()) { 5333 result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant); 5334 const ConstantType* const_val = down_cast<const ConstantType*>(&type); 5335 result.push_back(const_val->ConstantValue()); 5336 } else if (type.IsConstantLo()) { 5337 result.push_back(type.IsPreciseConstantLo() ? kConstant : kImpreciseConstant); 5338 const ConstantType* const_val = down_cast<const ConstantType*>(&type); 5339 result.push_back(const_val->ConstantValueLo()); 5340 } else if (type.IsConstantHi()) { 5341 result.push_back(type.IsPreciseConstantHi() ? kConstant : kImpreciseConstant); 5342 const ConstantType* const_val = down_cast<const ConstantType*>(&type); 5343 result.push_back(const_val->ConstantValueHi()); 5344 } else if (type.IsIntegralTypes()) { 5345 result.push_back(kIntVReg); 5346 result.push_back(0); 5347 } else if (type.IsFloat()) { 5348 result.push_back(kFloatVReg); 5349 result.push_back(0); 5350 } else if (type.IsLong()) { 5351 result.push_back(kLongLoVReg); 5352 result.push_back(0); 5353 result.push_back(kLongHiVReg); 5354 result.push_back(0); 5355 ++i; 5356 } else if (type.IsDouble()) { 5357 result.push_back(kDoubleLoVReg); 5358 result.push_back(0); 5359 result.push_back(kDoubleHiVReg); 5360 result.push_back(0); 5361 ++i; 5362 } else if (type.IsUndefined() || type.IsConflict() || type.IsHighHalf()) { 5363 result.push_back(kUndefined); 5364 result.push_back(0); 5365 } else { 5366 CHECK(type.IsNonZeroReferenceTypes()); 5367 result.push_back(kReferenceVReg); 5368 result.push_back(0); 5369 } 5370 } 5371 return result; 5372 } 5373 5374 const RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) { 5375 if (precise) { 5376 // Precise constant type. 5377 return reg_types_.FromCat1Const(value, true); 5378 } else { 5379 // Imprecise constant type. 5380 if (value < -32768) { 5381 return reg_types_.IntConstant(); 5382 } else if (value < -128) { 5383 return reg_types_.ShortConstant(); 5384 } else if (value < 0) { 5385 return reg_types_.ByteConstant(); 5386 } else if (value == 0) { 5387 return reg_types_.Zero(); 5388 } else if (value == 1) { 5389 return reg_types_.One(); 5390 } else if (value < 128) { 5391 return reg_types_.PosByteConstant(); 5392 } else if (value < 32768) { 5393 return reg_types_.PosShortConstant(); 5394 } else if (value < 65536) { 5395 return reg_types_.CharConstant(); 5396 } else { 5397 return reg_types_.IntConstant(); 5398 } 5399 } 5400 } 5401 5402 void MethodVerifier::Init() { 5403 art::verifier::RegTypeCache::Init(); 5404 } 5405 5406 void MethodVerifier::Shutdown() { 5407 verifier::RegTypeCache::ShutDown(); 5408 } 5409 5410 void MethodVerifier::VisitStaticRoots(RootVisitor* visitor) { 5411 RegTypeCache::VisitStaticRoots(visitor); 5412 } 5413 5414 void MethodVerifier::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) { 5415 reg_types_.VisitRoots(visitor, root_info); 5416 } 5417 5418 const RegType& MethodVerifier::FromClass(const char* descriptor, 5419 mirror::Class* klass, 5420 bool precise) { 5421 DCHECK(klass != nullptr); 5422 if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) { 5423 Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for " 5424 << "non-instantiable klass " << descriptor; 5425 precise = false; 5426 } 5427 return reg_types_.FromClass(descriptor, klass, precise); 5428 } 5429 5430 } // namespace verifier 5431 } // namespace art 5432