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