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