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