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