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