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