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