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