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