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