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