xref: /aosp_15_r20/art/runtime/verifier/method_verifier.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "method_verifier-inl.h"
18 
19 #include <ostream>
20 
21 #include "android-base/stringprintf.h"
22 
23 #include "art_field-inl.h"
24 #include "art_method-inl.h"
25 #include "base/aborting.h"
26 #include "base/leb128.h"
27 #include "base/indenter.h"
28 #include "base/logging.h"  // For VLOG.
29 #include "base/mutex-inl.h"
30 #include "base/pointer_size.h"
31 #include "base/sdk_version.h"
32 #include "base/stl_util.h"
33 #include "base/systrace.h"
34 #include "base/time_utils.h"
35 #include "base/utils.h"
36 #include "class_linker.h"
37 #include "class_root-inl.h"
38 #include "dex/class_accessor-inl.h"
39 #include "dex/descriptors_names.h"
40 #include "dex/dex_file-inl.h"
41 #include "dex/dex_file_exception_helpers.h"
42 #include "dex/dex_instruction-inl.h"
43 #include "dex/dex_instruction_list.h"
44 #include "dex/dex_instruction_utils.h"
45 #include "experimental_flags.h"
46 #include "gc/accounting/card_table-inl.h"
47 #include "handle_scope-inl.h"
48 #include "intern_table.h"
49 #include "mirror/class-inl.h"
50 #include "mirror/class.h"
51 #include "mirror/class_loader.h"
52 #include "mirror/dex_cache-inl.h"
53 #include "mirror/method_handle_impl.h"
54 #include "mirror/method_type.h"
55 #include "mirror/object-inl.h"
56 #include "mirror/object_array-inl.h"
57 #include "mirror/var_handle.h"
58 #include "obj_ptr-inl.h"
59 #include "reg_type-inl.h"
60 #include "reg_type_cache.h"
61 #include "register_line-inl.h"
62 #include "runtime.h"
63 #include "scoped_newline.h"
64 #include "scoped_thread_state_change-inl.h"
65 #include "stack.h"
66 #include "vdex_file.h"
67 #include "verifier/method_verifier.h"
68 #include "verifier_deps.h"
69 
70 namespace art HIDDEN {
71 namespace verifier {
72 
73 using android::base::StringPrintf;
74 
75 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
76 
PcToRegisterLineTable(ArenaAllocator & allocator)77 PcToRegisterLineTable::PcToRegisterLineTable(ArenaAllocator& allocator)
78     : register_lines_(allocator.Adapter(kArenaAllocVerifier)) {}
79 
Init(InstructionFlags * flags,uint32_t insns_size,uint16_t registers_size,ArenaAllocator & allocator,RegTypeCache * reg_types,uint32_t interesting_dex_pc)80 void PcToRegisterLineTable::Init(InstructionFlags* flags,
81                                  uint32_t insns_size,
82                                  uint16_t registers_size,
83                                  ArenaAllocator& allocator,
84                                  RegTypeCache* reg_types,
85                                  uint32_t interesting_dex_pc) {
86   DCHECK_GT(insns_size, 0U);
87   register_lines_.resize(insns_size);
88   for (uint32_t i = 0; i < insns_size; i++) {
89     if ((i == interesting_dex_pc) || flags[i].IsBranchTarget()) {
90       register_lines_[i].reset(RegisterLine::Create(registers_size, allocator, reg_types));
91     }
92   }
93 }
94 
~PcToRegisterLineTable()95 PcToRegisterLineTable::~PcToRegisterLineTable() {}
96 
97 namespace impl {
98 namespace {
99 
100 enum class CheckAccess {
101   kNo,
102   kOnResolvedClass,
103   kYes,
104 };
105 
106 enum class FieldAccessType {
107   kAccGet,
108   kAccPut
109 };
110 
111 // Instruction types that are not marked as throwing (because they normally would not), but for
112 // historical reasons may do so. These instructions cannot be marked kThrow as that would introduce
113 // a general flow that is unwanted.
114 //
115 // Note: Not implemented as Instruction::Flags value as that set is full and we'd need to increase
116 //       the struct size (making it a non-power-of-two) for a single element.
117 //
118 // Note: This should eventually be removed.
IsCompatThrow(Instruction::Code opcode)119 constexpr bool IsCompatThrow(Instruction::Code opcode) {
120   return opcode == Instruction::Code::RETURN_OBJECT || opcode == Instruction::Code::MOVE_EXCEPTION;
121 }
122 
123 template <bool kVerifierDebug>
124 class MethodVerifier final : public ::art::verifier::MethodVerifier {
125  public:
IsInstanceConstructor() const126   bool IsInstanceConstructor() const {
127     return IsConstructor() && !IsStatic();
128   }
129 
130   void FindLocksAtDexPc() REQUIRES_SHARED(Locks::mutator_lock_);
131 
132  private:
MethodVerifier(Thread * self,ArenaPool * arena_pool,RegTypeCache * reg_types,VerifierDeps * verifier_deps,const dex::CodeItem * code_item,uint32_t method_idx,bool aot_mode,Handle<mirror::DexCache> dex_cache,const dex::ClassDef & class_def,uint32_t access_flags,bool verify_to_dump,uint32_t api_level)133   MethodVerifier(Thread* self,
134                  ArenaPool* arena_pool,
135                  RegTypeCache* reg_types,
136                  VerifierDeps* verifier_deps,
137                  const dex::CodeItem* code_item,
138                  uint32_t method_idx,
139                  bool aot_mode,
140                  Handle<mirror::DexCache> dex_cache,
141                  const dex::ClassDef& class_def,
142                  uint32_t access_flags,
143                  bool verify_to_dump,
144                  uint32_t api_level) REQUIRES_SHARED(Locks::mutator_lock_)
145      : art::verifier::MethodVerifier(self,
146                                      arena_pool,
147                                      reg_types,
148                                      verifier_deps,
149                                      class_def,
150                                      code_item,
151                                      method_idx,
152                                      aot_mode),
153        method_access_flags_(access_flags),
154        return_type_(nullptr),
155        dex_cache_(dex_cache),
156        class_loader_(reg_types->GetClassLoader()),
157        declaring_class_(nullptr),
158        interesting_dex_pc_(-1),
159        monitor_enter_dex_pcs_(nullptr),
160        verify_to_dump_(verify_to_dump),
161        allow_thread_suspension_(reg_types->CanSuspend()),
162        is_constructor_(false),
163        api_level_(api_level == 0 ? std::numeric_limits<uint32_t>::max() : api_level) {
164     DCHECK_EQ(dex_cache->GetDexFile(), reg_types->GetDexFile())
165         << dex_cache->GetDexFile()->GetLocation() << " / "
166         << reg_types->GetDexFile()->GetLocation();
167   }
168 
FinalAbstractClassError(ObjPtr<mirror::Class> klass)169   void FinalAbstractClassError(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
170     // Note: We reuse NO_CLASS as the instruction we're checking shall throw an exception at
171     // runtime if executed. A final abstract class shall fail verification, so no instances can
172     // be created and therefore instance field or method access can be reached only for a null
173     // reference and throw NPE. All other instructions where we check for final abstract class
174     // shall throw `VerifyError`. (But we can also hit OOME/SOE while creating the exception.)
175     std::string temp;
176     const char* descriptor = klass->GetDescriptor(&temp);
177     Fail(VerifyError::VERIFY_ERROR_NO_CLASS)
178         << "Final abstract class used in a context that requires a verified class: " << descriptor;
179   }
180 
CheckForFinalAbstractClass(ObjPtr<mirror::Class> klass)181   void CheckForFinalAbstractClass(ObjPtr<mirror::Class> klass)
182       REQUIRES_SHARED(Locks::mutator_lock_) {
183     if (UNLIKELY(klass->IsFinal() &&
184                  klass->IsAbstract() &&
185                  !klass->IsInterface() &&
186                  !klass->IsPrimitive() &&
187                  !klass->IsArrayClass())) {
188       FinalAbstractClassError(klass);
189     }
190   }
191 
192   // Is the method being verified a constructor? See the comment on the field.
IsConstructor() const193   bool IsConstructor() const {
194     return is_constructor_;
195   }
196 
197   // Is the method verified static?
IsStatic() const198   bool IsStatic() const {
199     return (method_access_flags_ & kAccStatic) != 0;
200   }
201 
202   // Adds the given string to the beginning of the last failure message.
PrependToLastFailMessage(std::string prepend)203   void PrependToLastFailMessage(std::string prepend) {
204     size_t failure_num = failure_messages_.size();
205     DCHECK_NE(failure_num, 0U);
206     std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
207     prepend += last_fail_message->str();
208     failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate);
209     delete last_fail_message;
210   }
211 
212   // Adds the given string to the end of the last failure message.
AppendToLastFailMessage(const std::string & append)213   void AppendToLastFailMessage(const std::string& append) {
214     size_t failure_num = failure_messages_.size();
215     DCHECK_NE(failure_num, 0U);
216     std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
217     (*last_fail_message) << append;
218   }
219 
220   /*
221    * Compute the width of the instruction at each address in the instruction stream, and store it in
222    * insn_flags_. Addresses that are in the middle of an instruction, or that are part of switch
223    * table data, are not touched (so the caller should probably initialize "insn_flags" to zero).
224    *
225    * The "new_instance_count_" and "monitor_enter_count_" fields in vdata are also set.
226    *
227    * Performs some static checks, notably:
228    * - opcode of first instruction begins at index 0
229    * - only documented instructions may appear
230    * - each instruction follows the last
231    * - last byte of last instruction is at (code_length-1)
232    *
233    * Logs an error and returns "false" on failure.
234    */
235   bool ComputeWidthsAndCountOps();
236 
237   /*
238    * Set the "in try" flags for all instructions protected by "try" statements. Also sets the
239    * "branch target" flags for exception handlers.
240    *
241    * Call this after widths have been set in "insn_flags".
242    *
243    * Returns "false" if something in the exception table looks fishy, but we're expecting the
244    * exception table to be valid.
245    */
246   bool ScanTryCatchBlocks() REQUIRES_SHARED(Locks::mutator_lock_);
247 
248   /*
249    * Perform static verification on all instructions in a method.
250    *
251    * Walks through instructions in a method calling VerifyInstruction on each.
252    */
253   bool VerifyInstructions();
254 
255   /*
256    * Perform static verification on an instruction.
257    *
258    * As a side effect, this sets the "branch target" flags in InsnFlags.
259    *
260    * "(CF)" items are handled during code-flow analysis.
261    *
262    * v3 4.10.1
263    * - target of each jump and branch instruction must be valid
264    * - targets of switch statements must be valid
265    * - operands referencing constant pool entries must be valid
266    * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid
267    * - (CF) operands of method invocation instructions must be valid
268    * - (CF) only invoke-direct can call a method starting with '<'
269    * - (CF) <clinit> must never be called explicitly
270    * - operands of instanceof, checkcast, new (and variants) must be valid
271    * - new-array[-type] limited to 255 dimensions
272    * - can't use "new" on an array class
273    * - (?) limit dimensions in multi-array creation
274    * - local variable load/store register values must be in valid range
275    *
276    * v3 4.11.1.2
277    * - branches must be within the bounds of the code array
278    * - targets of all control-flow instructions are the start of an instruction
279    * - register accesses fall within range of allocated registers
280    * - (N/A) access to constant pool must be of appropriate type
281    * - code does not end in the middle of an instruction
282    * - execution cannot fall off the end of the code
283    * - (earlier) for each exception handler, the "try" area must begin and
284    *   end at the start of an instruction (end can be at the end of the code)
285    * - (earlier) for each exception handler, the handler must start at a valid
286    *   instruction
287    */
288   template <Instruction::Code kDispatchOpcode>
289   ALWAYS_INLINE bool VerifyInstruction(const Instruction* inst,
290                                        uint32_t code_offset,
291                                        uint16_t inst_data);
292 
293   /* Ensure that the register index is valid for this code item. */
CheckRegisterIndex(uint32_t idx)294   bool CheckRegisterIndex(uint32_t idx) {
295     if (UNLIKELY(idx >= code_item_accessor_.RegistersSize())) {
296       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= "
297                                         << code_item_accessor_.RegistersSize() << ")";
298       return false;
299     }
300     return true;
301   }
302 
303   /* Ensure that the wide register index is valid for this code item. */
CheckWideRegisterIndex(uint32_t idx)304   bool CheckWideRegisterIndex(uint32_t idx) {
305     if (UNLIKELY(idx + 1 >= code_item_accessor_.RegistersSize())) {
306       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx
307                                         << "+1 >= " << code_item_accessor_.RegistersSize() << ")";
308       return false;
309     }
310     return true;
311   }
312 
313   // Perform static checks on an instruction referencing a CallSite. All we do here is ensure that
314   // the call site index is in the valid range.
CheckCallSiteIndex(uint32_t idx)315   bool CheckCallSiteIndex(uint32_t idx) {
316     uint32_t limit = dex_file_->NumCallSiteIds();
317     if (UNLIKELY(idx >= limit)) {
318       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad call site index " << idx << " (max "
319                                         << limit << ")";
320       return false;
321     }
322     return true;
323   }
324 
325   // Perform static checks on a field Get or set instruction. We ensure that the field index
326   // is in the valid range and we check that the field descriptor matches the instruction.
CheckFieldIndex(const Instruction * inst,uint16_t inst_data,uint32_t field_idx)327   ALWAYS_INLINE bool CheckFieldIndex(const Instruction* inst,
328                                      uint16_t inst_data,
329                                      uint32_t field_idx) {
330     if (UNLIKELY(field_idx >= dex_file_->NumFieldIds())) {
331       FailBadFieldIndex(field_idx);
332       return false;
333     }
334 
335     // Prepare a table with permitted descriptors, evaluated at compile time.
336     static constexpr uint32_t kVerifyFieldIndexFlags =
337         Instruction::kVerifyRegBField | Instruction::kVerifyRegCField;
338     static constexpr uint32_t kMinFieldAccessOpcode = []() constexpr {
339       for (uint32_t opcode = 0u; opcode != 256u; ++opcode) {
340         uint32_t verify_flags = Instruction::VerifyFlagsOf(enum_cast<Instruction::Code>(opcode));
341         if ((verify_flags & kVerifyFieldIndexFlags) != 0u) {
342           return opcode;
343         }
344       }
345       LOG(FATAL) << "Compile time error if we reach this.";
346       return 0u;
347     }();
348     static constexpr uint32_t kMaxFieldAccessOpcode = []() constexpr {
349       for (uint32_t opcode = 256u; opcode != 0u; ) {
350         --opcode;
351         uint32_t verify_flags = Instruction::VerifyFlagsOf(enum_cast<Instruction::Code>(opcode));
352         if ((verify_flags & kVerifyFieldIndexFlags) != 0u) {
353           return opcode;
354         }
355       }
356       LOG(FATAL) << "Compile time error if we reach this.";
357       return 0u;
358     }();
359     static constexpr uint32_t kArraySize = kMaxFieldAccessOpcode + 1u - kMinFieldAccessOpcode;
360     using PermittedDescriptorArray = std::array<std::pair<char, char>, kArraySize>;
361     static constexpr PermittedDescriptorArray kPermittedDescriptors = []() constexpr {
362       PermittedDescriptorArray result;
363       for (uint32_t index = 0u; index != kArraySize; ++index) {
364         Instruction::Code opcode = enum_cast<Instruction::Code>(index + kMinFieldAccessOpcode);
365         DexMemAccessType access_type;
366         if (IsInstructionIGet(opcode) || IsInstructionIPut(opcode)) {
367           access_type = IGetOrIPutMemAccessType(opcode);
368         } else {
369           // `iget*`, `iput*`, `sget*` and `sput*` instructions form a contiguous range.
370           CHECK(IsInstructionSGet(opcode) || IsInstructionSPut(opcode));
371           access_type = SGetOrSPutMemAccessType(opcode);
372         }
373         switch (access_type) {
374           case DexMemAccessType::kDexMemAccessWord:
375             result[index] = { 'I', 'F' };
376             break;
377           case DexMemAccessType::kDexMemAccessWide:
378             result[index] = { 'J', 'D' };
379             break;
380           case DexMemAccessType::kDexMemAccessObject:
381             result[index] = { 'L', '[' };
382             break;
383           case DexMemAccessType::kDexMemAccessBoolean:
384             result[index] = { 'Z', 'Z' };  // Only one character is permitted.
385             break;
386           case DexMemAccessType::kDexMemAccessByte:
387             result[index] = { 'B', 'B' };  // Only one character is permitted.
388             break;
389           case DexMemAccessType::kDexMemAccessChar:
390             result[index] = { 'C', 'C' };  // Only one character is permitted.
391             break;
392           case DexMemAccessType::kDexMemAccessShort:
393             result[index] = { 'S', 'S' };  // Only one character is permitted.
394             break;
395           default:
396             LOG(FATAL) << "Compile time error if we reach this.";
397             break;
398         }
399       }
400       return result;
401     }();
402 
403     // Check the first character of the field type descriptor.
404     Instruction::Code opcode = inst->Opcode(inst_data);
405     DCHECK_GE(opcode, kMinFieldAccessOpcode);
406     DCHECK_LE(opcode, kMaxFieldAccessOpcode);
407     std::pair<char, char> permitted = kPermittedDescriptors[opcode - kMinFieldAccessOpcode];
408     const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_idx);
409     if (UNLIKELY(descriptor[0] != permitted.first && descriptor[0] != permitted.second)) {
410       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
411           << "expected field " << dex_file_->PrettyField(field_idx)
412           << " to have type descritor starting with '" << permitted.first
413           << (permitted.second != permitted.first ? std::string("' or '") + permitted.second : "")
414           << "' but found '" << descriptor[0] << "' in " << opcode;
415       return false;
416     }
417     return true;
418   }
419 
420   // Perform static checks on a method invocation instruction. All we do here is ensure that the
421   // method index is in the valid range.
CheckMethodIndex(uint32_t method_idx)422   ALWAYS_INLINE bool CheckMethodIndex(uint32_t method_idx) {
423     if (UNLIKELY(method_idx >= dex_file_->NumMethodIds())) {
424       FailBadMethodIndex(method_idx);
425       return false;
426     }
427     return true;
428   }
429 
430   // Perform static checks on an instruction referencing a constant method handle. All we do here
431   // is ensure that the method index is in the valid range.
CheckMethodHandleIndex(uint32_t idx)432   bool CheckMethodHandleIndex(uint32_t idx) {
433     uint32_t limit = dex_file_->NumMethodHandles();
434     if (UNLIKELY(idx >= limit)) {
435       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method handle index " << idx << " (max "
436                                         << limit << ")";
437       return false;
438     }
439     return true;
440   }
441 
442   // Perform static checks on a "new-instance" instruction. Specifically, make sure the class
443   // reference isn't for an array class.
444   bool CheckNewInstance(dex::TypeIndex idx);
445 
446   // Perform static checks on a prototype indexing instruction. All we do here is ensure that the
447   // prototype index is in the valid range.
CheckPrototypeIndex(uint32_t idx)448   bool CheckPrototypeIndex(uint32_t idx) {
449     if (UNLIKELY(idx >= dex_file_->GetHeader().proto_ids_size_)) {
450       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad prototype index " << idx << " (max "
451                                         << dex_file_->GetHeader().proto_ids_size_ << ")";
452       return false;
453     }
454     return true;
455   }
456 
457   /* Ensure that the string index is in the valid range. */
CheckStringIndex(uint32_t idx)458   bool CheckStringIndex(uint32_t idx) {
459     if (UNLIKELY(idx >= dex_file_->GetHeader().string_ids_size_)) {
460       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max "
461                                         << dex_file_->GetHeader().string_ids_size_ << ")";
462       return false;
463     }
464     return true;
465   }
466 
467   // Perform static checks on an instruction that takes a class constant. Ensure that the class
468   // index is in the valid range.
CheckTypeIndex(dex::TypeIndex idx)469   bool CheckTypeIndex(dex::TypeIndex idx) {
470     if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
471       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
472                                         << dex_file_->GetHeader().type_ids_size_ << ")";
473       return false;
474     }
475     return true;
476   }
477 
478   // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't
479   // creating an array of arrays that causes the number of dimensions to exceed 255.
480   bool CheckNewArray(dex::TypeIndex idx);
481 
482   // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction.
483   bool CheckArrayData(uint32_t cur_offset);
484 
485   // Verify that the target of a branch instruction is valid. We don't expect code to jump directly
486   // into an exception handler, but it's valid to do so as long as the target isn't a
487   // "move-exception" instruction. We verify that in a later stage.
488   // The dex format forbids certain instructions from branching to themselves.
489   // Updates "insn_flags_", setting the "branch target" flag.
490   bool CheckBranchTarget(uint32_t cur_offset);
491 
492   // Verify a switch table. "cur_offset" is the offset of the switch instruction.
493   // Updates "insn_flags_", setting the "branch target" flag.
494   bool CheckSwitchTargets(uint32_t cur_offset);
495 
496   // Check the register indices used in a "vararg" instruction, such as invoke-virtual or
497   // filled-new-array.
498   // - inst is the instruction from which we retrieve the arguments
499   // - vA holds the argument count (0-5)
500   // There are some tests we don't do here, e.g. we don't try to verify that invoking a method that
501   // takes a double is done with consecutive registers. This requires parsing the target method
502   // signature, which we will be doing later on during the code flow analysis.
CheckVarArgRegs(const Instruction * inst,uint32_t vA)503   bool CheckVarArgRegs(const Instruction* inst, uint32_t vA) {
504     uint16_t registers_size = code_item_accessor_.RegistersSize();
505     // All args are 4-bit and therefore under 16. We do not need to check args for
506     // `registers_size >= 16u` but let's check them anyway in debug builds.
507     if (registers_size < 16u || kIsDebugBuild) {
508       uint32_t args[Instruction::kMaxVarArgRegs];
509       inst->GetVarArgs(args);
510       for (uint32_t idx = 0; idx < vA; idx++) {
511         DCHECK_LT(args[idx], 16u);
512         if (UNLIKELY(args[idx] >= registers_size)) {
513           DCHECK_LT(registers_size, 16u);
514           Fail(VERIFY_ERROR_BAD_CLASS_HARD)
515               << "invalid reg index (" << args[idx]
516               << ") in non-range invoke (>= " << registers_size << ")";
517           return false;
518         }
519       }
520     }
521     return true;
522   }
523 
524   // Check the register indices used in a "vararg/range" instruction, such as invoke-virtual/range
525   // or filled-new-array/range.
526   // - vA holds word count, vC holds index of first reg.
CheckVarArgRangeRegs(uint32_t vA,uint32_t vC)527   bool CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) {
528     uint16_t registers_size = code_item_accessor_.RegistersSize();
529     // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of
530     // integer overflow when adding them here.
531     if (UNLIKELY(vA + vC > registers_size)) {
532       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC
533                                         << " in range invoke (> " << registers_size << ")";
534       return false;
535     }
536     return true;
537   }
538 
539   // Checks the method matches the expectations required to be signature polymorphic.
540   bool CheckSignaturePolymorphicMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
541 
542   // Checks the invoked receiver matches the expectations for signature polymorphic methods.
543   bool CheckSignaturePolymorphicReceiver(const Instruction* inst) REQUIRES_SHARED(Locks::mutator_lock_);
544 
545   // Extract the relative offset from a branch instruction.
546   // Returns "false" on failure (e.g. this isn't a branch instruction).
547   bool GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional,
548                        bool* selfOkay);
549 
550   /* Perform detailed code-flow analysis on a single method. */
551   bool VerifyCodeFlow() REQUIRES_SHARED(Locks::mutator_lock_);
552 
553   // Set the register types for the first instruction in the method based on the method signature.
554   // This has the side-effect of validating the signature.
555   bool SetTypesFromSignature() REQUIRES_SHARED(Locks::mutator_lock_);
556 
557   /*
558    * Perform code flow on a method.
559    *
560    * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit on the first
561    * instruction, process it (setting additional "changed" bits), and repeat until there are no
562    * more.
563    *
564    * v3 4.11.1.1
565    * - (N/A) operand stack is always the same size
566    * - operand stack [registers] contain the correct types of values
567    * - local variables [registers] contain the correct types of values
568    * - methods are invoked with the appropriate arguments
569    * - fields are assigned using values of appropriate types
570    * - opcodes have the correct type values in operand registers
571    * - there is never an uninitialized class instance in a local variable in code protected by an
572    *   exception handler (operand stack is okay, because the operand stack is discarded when an
573    *   exception is thrown) [can't know what's a local var w/o the debug info -- should fall out of
574    *   register typing]
575    *
576    * v3 4.11.1.2
577    * - execution cannot fall off the end of the code
578    *
579    * (We also do many of the items described in the "static checks" sections, because it's easier to
580    * do them here.)
581    *
582    * We need an array of RegType values, one per register, for every instruction. If the method uses
583    * monitor-enter, we need extra data for every register, and a stack for every "interesting"
584    * instruction. In theory this could become quite large -- up to several megabytes for a monster
585    * function.
586    *
587    * NOTE:
588    * The spec forbids backward branches when there's an uninitialized reference in a register. The
589    * idea is to prevent something like this:
590    *   loop:
591    *     move r1, r0
592    *     new-instance r0, MyClass
593    *     ...
594    *     if-eq rN, loop  // once
595    *   initialize r0
596    *
597    * This leaves us with two different instances, both allocated by the same instruction, but only
598    * one is initialized. The scheme outlined in v3 4.11.1.4 wouldn't catch this, so they work around
599    * it by preventing backward branches. We achieve identical results without restricting code
600    * reordering by specifying that you can't execute the new-instance instruction if a register
601    * contains an uninitialized instance created by that same instruction.
602    */
603   template <bool kMonitorDexPCs>
604   bool CodeFlowVerifyMethod() REQUIRES_SHARED(Locks::mutator_lock_);
605 
606   /*
607    * Perform verification for a single instruction.
608    *
609    * This requires fully decoding the instruction to determine the effect it has on registers.
610    *
611    * Finds zero or more following instructions and sets the "changed" flag if execution at that
612    * point needs to be (re-)evaluated. Register changes are merged into "reg_types_" at the target
613    * addresses. Does not set or clear any other flags in "insn_flags_".
614    */
615   bool CodeFlowVerifyInstruction(uint32_t* start_guess)
616       REQUIRES_SHARED(Locks::mutator_lock_);
617 
618   // Perform verification of a new array instruction
619   void VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range)
620       REQUIRES_SHARED(Locks::mutator_lock_);
621 
622   // Helper to perform verification on puts of primitive type.
623   void VerifyPrimitivePut(const RegType& target_type, uint32_t vregA)
624       REQUIRES_SHARED(Locks::mutator_lock_);
625 
626   // Perform verification of an aget instruction. The destination register's type will be set to
627   // be that of component type of the array unless the array type is unknown, in which case a
628   // bottom type inferred from the type of instruction is used. is_primitive is false for an
629   // aget-object.
630   void VerifyAGet(const Instruction* inst, const RegType& insn_type,
631                   bool is_primitive) REQUIRES_SHARED(Locks::mutator_lock_);
632 
633   // Perform verification of an aput instruction.
634   void VerifyAPut(const Instruction* inst, const RegType& insn_type,
635                   bool is_primitive) REQUIRES_SHARED(Locks::mutator_lock_);
636 
637   // Lookup instance field and fail for resolution violations
638   ArtField* GetInstanceField(uint32_t vregB, uint32_t field_idx, bool is_put)
639       REQUIRES_SHARED(Locks::mutator_lock_);
640 
641   // Lookup static field and fail for resolution violations
642   ArtField* GetStaticField(uint32_t field_idx, bool is_put) REQUIRES_SHARED(Locks::mutator_lock_);
643 
644   // Common checks for `GetInstanceField()` and `GetStaticField()`.
645   ArtField* GetISFieldCommon(ArtField* field, bool is_put) REQUIRES_SHARED(Locks::mutator_lock_);
646 
647   // Perform verification of an iget/sget/iput/sput instruction.
648   template <FieldAccessType kAccType>
649   void VerifyISFieldAccess(const Instruction* inst, bool is_primitive, bool is_static)
650       REQUIRES_SHARED(Locks::mutator_lock_);
651 
652   // Resolves a class based on an index and, if C is kYes, performs access checks to ensure
653   // the referrer can access the resolved class.
654   template <CheckAccess C>
655   const RegType& ResolveClass(dex::TypeIndex class_idx)
656       REQUIRES_SHARED(Locks::mutator_lock_);
657 
658   /*
659    * For the "move-exception" instruction at "work_insn_idx_", which must be at an exception handler
660    * address, determine the Join of all exceptions that can land here. Fails if no matching
661    * exception handler can be found or if the Join of exception types fails.
662    */
663   const RegType& GetCaughtExceptionType()
664       REQUIRES_SHARED(Locks::mutator_lock_);
665 
666   /*
667    * Resolves a method based on an index and performs access checks to ensure
668    * the referrer can access the resolved method.
669    * Does not throw exceptions.
670    */
671   ArtMethod* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type)
672       REQUIRES_SHARED(Locks::mutator_lock_);
673 
674   /*
675    * Verify the arguments to a method. We're executing in "method", making
676    * a call to the method reference in vB.
677    *
678    * If this is a "direct" invoke, we allow calls to <init>. For calls to
679    * <init>, the first argument may be an uninitialized reference. Otherwise,
680    * calls to anything starting with '<' will be rejected, as will any
681    * uninitialized reference arguments.
682    *
683    * For non-static method calls, this will verify that the method call is
684    * appropriate for the "this" argument.
685    *
686    * The method reference is in vBBBB. The "is_range" parameter determines
687    * whether we use 0-4 "args" values or a range of registers defined by
688    * vAA and vCCCC.
689    *
690    * Widening conversions on integers and references are allowed, but
691    * narrowing conversions are not.
692    *
693    * Returns the resolved method on success, null on failure (with *failure
694    * set appropriately).
695    */
696   ArtMethod* VerifyInvocationArgs(const Instruction* inst, MethodType method_type, bool is_range)
697       REQUIRES_SHARED(Locks::mutator_lock_);
698 
699   // Similar checks to the above, but on the proto. Will be used when the method cannot be
700   // resolved.
701   void VerifyInvocationArgsUnresolvedMethod(const Instruction* inst, MethodType method_type,
702                                             bool is_range)
703       REQUIRES_SHARED(Locks::mutator_lock_);
704 
705   template <class T>
706   ArtMethod* VerifyInvocationArgsFromIterator(T* it, const Instruction* inst,
707                                                       MethodType method_type, bool is_range,
708                                                       ArtMethod* res_method)
709       REQUIRES_SHARED(Locks::mutator_lock_);
710 
711   /*
712    * Verify the arguments present for a call site. Returns "true" if all is well, "false" otherwise.
713    */
714   bool CheckCallSite(uint32_t call_site_idx);
715 
716   /*
717    * Verify that the target instruction is not "move-exception". It's important that the only way
718    * to execute a move-exception is as the first instruction of an exception handler.
719    * Returns "true" if all is well, "false" if the target instruction is move-exception.
720    */
CheckNotMoveException(const uint16_t * insns,int insn_idx)721   bool CheckNotMoveException(const uint16_t* insns, int insn_idx) {
722     if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
723       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception";
724       return false;
725     }
726     return true;
727   }
728 
729   /*
730    * Verify that the target instruction is not "move-result". It is important that we cannot
731    * branch to move-result instructions, but we have to make this a distinct check instead of
732    * adding it to CheckNotMoveException, because it is legal to continue into "move-result"
733    * instructions - as long as the previous instruction was an invoke, which is checked elsewhere.
734    */
CheckNotMoveResult(const uint16_t * insns,int insn_idx)735   bool CheckNotMoveResult(const uint16_t* insns, int insn_idx) {
736     if (((insns[insn_idx] & 0xff) >= Instruction::MOVE_RESULT) &&
737         ((insns[insn_idx] & 0xff) <= Instruction::MOVE_RESULT_OBJECT)) {
738       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-result*";
739       return false;
740     }
741     return true;
742   }
743 
744   /*
745    * Verify that the target instruction is not "move-result" or "move-exception". This is to
746    * be used when checking branch and switch instructions, but not instructions that can
747    * continue.
748    */
CheckNotMoveExceptionOrMoveResult(const uint16_t * insns,int insn_idx)749   bool CheckNotMoveExceptionOrMoveResult(const uint16_t* insns, int insn_idx) {
750     return (CheckNotMoveException(insns, insn_idx) && CheckNotMoveResult(insns, insn_idx));
751   }
752 
753   /*
754   * Control can transfer to "next_insn". Merge the registers from merge_line into the table at
755   * next_insn, and set the changed flag on the target address if any of the registers were changed.
756   * In the case of fall-through, update the merge line on a change as its the working line for the
757   * next instruction.
758   * Returns "false" if an error is encountered.
759   */
760   bool UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line, bool update_merge_line)
761       REQUIRES_SHARED(Locks::mutator_lock_);
762 
763   // Return the register type for the method.
764   const RegType& GetMethodReturnType() REQUIRES_SHARED(Locks::mutator_lock_);
765 
766   // Get a type representing the declaring class of the method.
GetDeclaringClass()767   const RegType& GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_) {
768     if (declaring_class_ == nullptr) {
769       const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
770       declaring_class_ = &reg_types_.FromTypeIndex(method_id.class_idx_);
771     }
772     return *declaring_class_;
773   }
774 
GetRegTypeClass(const RegType & reg_type)775   ObjPtr<mirror::Class> GetRegTypeClass(const RegType& reg_type)
776       REQUIRES_SHARED(Locks::mutator_lock_) {
777     DCHECK(reg_type.IsJavaLangObject() || reg_type.IsReference()) << reg_type;
778     return reg_type.IsJavaLangObject() ? GetClassRoot<mirror::Object>(GetClassLinker())
779                                        : reg_type.GetClass();
780   }
781 
CanAccess(const RegType & other)782   bool CanAccess(const RegType& other) REQUIRES_SHARED(Locks::mutator_lock_) {
783     DCHECK(other.IsJavaLangObject() || other.IsReference() || other.IsUnresolvedReference());
784     const RegType& declaring_class = GetDeclaringClass();
785     if (declaring_class.Equals(other)) {
786       return true;  // Trivial accessibility.
787     } else if (other.IsUnresolvedReference()) {
788       return false;  // More complicated test not possible on unresolved types, be conservative.
789     } else if (declaring_class.IsUnresolvedReference()) {
790       // Be conservative, only allow if `other` is public.
791       return other.IsJavaLangObject() || (other.IsReference() && other.GetClass()->IsPublic());
792     } else {
793       return GetRegTypeClass(declaring_class)->CanAccess(GetRegTypeClass(other));
794     }
795   }
796 
CanAccessMember(ObjPtr<mirror::Class> klass,uint32_t access_flags)797   bool CanAccessMember(ObjPtr<mirror::Class> klass, uint32_t access_flags)
798       REQUIRES_SHARED(Locks::mutator_lock_) {
799     const RegType& declaring_class = GetDeclaringClass();
800     if (declaring_class.IsUnresolvedReference()) {
801       return false;  // More complicated test not possible on unresolved types, be conservative.
802     } else {
803       return GetRegTypeClass(declaring_class)->CanAccessMember(klass, access_flags);
804     }
805   }
806 
FailInvalidArgCount(const Instruction * inst,uint32_t arg_count)807   NO_INLINE void FailInvalidArgCount(const Instruction* inst, uint32_t arg_count) {
808     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
809         << "invalid arg count (" << arg_count << ") in " << inst->Name();
810   }
811 
FailUnexpectedOpcode(const Instruction * inst)812   NO_INLINE void FailUnexpectedOpcode(const Instruction* inst) {
813     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name();
814   }
815 
FailBadFieldIndex(uint32_t field_idx)816   NO_INLINE void FailBadFieldIndex(uint32_t field_idx) {
817     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
818         << "bad field index " << field_idx << " (max " << dex_file_->NumFieldIds() << ")";
819   }
820 
FailBadMethodIndex(uint32_t method_idx)821   NO_INLINE void FailBadMethodIndex(uint32_t method_idx) {
822     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
823         << "bad method index " << method_idx << " (max " << dex_file_->NumMethodIds() << ")";
824   }
825 
FailForRegisterType(uint32_t vsrc,const RegType & check_type,const RegType & src_type,VerifyError fail_type=VERIFY_ERROR_BAD_CLASS_HARD)826   NO_INLINE void FailForRegisterType(uint32_t vsrc,
827                                      const RegType& check_type,
828                                      const RegType& src_type,
829                                      VerifyError fail_type = VERIFY_ERROR_BAD_CLASS_HARD)
830       REQUIRES_SHARED(Locks::mutator_lock_) {
831     Fail(fail_type)
832         << "register v" << vsrc << " has type " << src_type << " but expected " << check_type;
833   }
834 
FailForRegisterType(uint32_t vsrc,RegType::Kind check_kind,uint16_t src_type_id)835   NO_INLINE void FailForRegisterType(uint32_t vsrc,
836                                      RegType::Kind check_kind,
837                                      uint16_t src_type_id)
838       REQUIRES_SHARED(Locks::mutator_lock_) {
839     FailForRegisterType(
840         vsrc, reg_types_.GetFromRegKind(check_kind), reg_types_.GetFromId(src_type_id));
841   }
842 
FailForRegisterTypeWide(uint32_t vsrc,const RegType & src_type,const RegType & src_type_h)843   NO_INLINE void FailForRegisterTypeWide(uint32_t vsrc,
844                                          const RegType& src_type,
845                                          const RegType& src_type_h)
846       REQUIRES_SHARED(Locks::mutator_lock_) {
847     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
848         << "wide register v" << vsrc << " has type " << src_type << "/" << src_type_h;
849   }
850 
FailForRegisterTypeWide(uint32_t vsrc,uint16_t src_type_id,uint16_t src_type_id_h)851   NO_INLINE void FailForRegisterTypeWide(uint32_t vsrc,
852                                          uint16_t src_type_id,
853                                          uint16_t src_type_id_h)
854       REQUIRES_SHARED(Locks::mutator_lock_) {
855     FailForRegisterTypeWide(
856         vsrc, reg_types_.GetFromId(src_type_id), reg_types_.GetFromId(src_type_id_h));
857   }
858 
VerifyRegisterType(uint32_t vsrc,const RegType & check_type)859   ALWAYS_INLINE inline bool VerifyRegisterType(uint32_t vsrc, const RegType& check_type)
860       REQUIRES_SHARED(Locks::mutator_lock_) {
861     // Verify the src register type against the check type refining the type of the register
862     const RegType& src_type = work_line_->GetRegisterType(this, vsrc);
863     if (UNLIKELY(!IsAssignableFrom(check_type, src_type))) {
864       enum VerifyError fail_type;
865       if (!check_type.IsNonZeroReferenceTypes() || !src_type.IsNonZeroReferenceTypes()) {
866         // Hard fail if one of the types is primitive, since they are concretely known.
867         fail_type = VERIFY_ERROR_BAD_CLASS_HARD;
868       } else if (check_type.IsUninitializedTypes() || src_type.IsUninitializedTypes()) {
869         // Hard fail for uninitialized types, which don't match anything but themselves.
870         fail_type = VERIFY_ERROR_BAD_CLASS_HARD;
871       } else if (check_type.IsUnresolvedTypes() || src_type.IsUnresolvedTypes()) {
872         fail_type = VERIFY_ERROR_UNRESOLVED_TYPE_CHECK;
873       } else {
874         fail_type = VERIFY_ERROR_BAD_CLASS_HARD;
875       }
876       FailForRegisterType(vsrc, check_type, src_type, fail_type);
877       return false;
878     }
879     if (check_type.IsLowHalf()) {
880       const RegType& src_type_h = work_line_->GetRegisterType(this, vsrc + 1);
881       if (UNLIKELY(!src_type.CheckWidePair(src_type_h))) {
882         FailForRegisterTypeWide(vsrc, src_type, src_type_h);
883         return false;
884       }
885     }
886     // The register at vsrc has a defined type, we know the lower-upper-bound, but this is less
887     // precise than the subtype in vsrc so leave it for reference types. For primitive types if
888     // they are a defined type then they are as precise as we can get, however, for constant types
889     // we may wish to refine them. Unfortunately constant propagation has rendered this useless.
890     return true;
891   }
892 
VerifyRegisterType(uint32_t vsrc,RegType::Kind check_kind)893   ALWAYS_INLINE inline bool VerifyRegisterType(uint32_t vsrc, RegType::Kind check_kind)
894       REQUIRES_SHARED(Locks::mutator_lock_) {
895     DCHECK(check_kind == RegType::Kind::kInteger || check_kind == RegType::Kind::kFloat);
896     // Verify the src register type against the check type refining the type of the register
897     uint16_t src_type_id = work_line_->GetRegisterTypeId(vsrc);
898     if (UNLIKELY(src_type_id >= RegTypeCache::NumberOfRegKindCacheIds()) ||
899         UNLIKELY(RegType::AssignabilityFrom(check_kind, RegTypeCache::RegKindForId(src_type_id)) !=
900                      RegType::Assignability::kAssignable)) {
901       // Integer or float assignability is never a `kNarrowingConversion` or `kReference`.
902       DCHECK_EQ(
903           RegType::AssignabilityFrom(check_kind, reg_types_.GetFromId(src_type_id).GetKind()),
904           RegType::Assignability::kNotAssignable);
905       FailForRegisterType(vsrc, check_kind, src_type_id);
906       return false;
907     }
908     return true;
909   }
910 
VerifyRegisterTypeWide(uint32_t vsrc,RegType::Kind check_kind)911   bool VerifyRegisterTypeWide(uint32_t vsrc, RegType::Kind check_kind)
912       REQUIRES_SHARED(Locks::mutator_lock_) {
913     DCHECK(check_kind == RegType::Kind::kLongLo || check_kind == RegType::Kind::kDoubleLo);
914     // Verify the src register type against the check type refining the type of the register
915     uint16_t src_type_id = work_line_->GetRegisterTypeId(vsrc);
916     if (UNLIKELY(src_type_id >= RegTypeCache::NumberOfRegKindCacheIds()) ||
917         UNLIKELY(RegType::AssignabilityFrom(check_kind, RegTypeCache::RegKindForId(src_type_id)) !=
918                      RegType::Assignability::kAssignable)) {
919       // Wide assignability is never a `kNarrowingConversion` or `kReference`.
920       DCHECK_EQ(
921           RegType::AssignabilityFrom(check_kind, reg_types_.GetFromId(src_type_id).GetKind()),
922           RegType::Assignability::kNotAssignable);
923       FailForRegisterType(vsrc, check_kind, src_type_id);
924       return false;
925     }
926     uint16_t src_type_id_h = work_line_->GetRegisterTypeId(vsrc + 1);
927     uint16_t expected_src_type_id_h =
928         RegTypeCache::IdForRegKind(RegType::ToHighHalf(RegTypeCache::RegKindForId(src_type_id)));
929     DCHECK_EQ(src_type_id_h == expected_src_type_id_h,
930               reg_types_.GetFromId(src_type_id).CheckWidePair(reg_types_.GetFromId(src_type_id_h)));
931     if (UNLIKELY(src_type_id_h != expected_src_type_id_h)) {
932       FailForRegisterTypeWide(vsrc, src_type_id, src_type_id_h);
933       return false;
934     }
935     // The register at vsrc has a defined type, we know the lower-upper-bound, but this is less
936     // precise than the subtype in vsrc so leave it for reference types. For primitive types if
937     // they are a defined type then they are as precise as we can get, however, for constant types
938     // we may wish to refine them. Unfortunately constant propagation has rendered this useless.
939     return true;
940   }
941 
942   /*
943    * Verify types for a simple two-register instruction (e.g. "neg-int").
944    * "dst_type" is stored into vA, and "src_type" is verified against vB.
945    */
CheckUnaryOp(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind)946   void CheckUnaryOp(const Instruction* inst, RegType::Kind dst_kind, RegType::Kind src_kind)
947       REQUIRES_SHARED(Locks::mutator_lock_) {
948     if (VerifyRegisterType(inst->VRegB_12x(), src_kind)) {
949       work_line_->SetRegisterType(inst->VRegA_12x(), dst_kind);
950     }
951   }
952 
CheckUnaryOpWide(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind)953   void CheckUnaryOpWide(const Instruction* inst,
954                         RegType::Kind dst_kind,
955                         RegType::Kind src_kind)
956       REQUIRES_SHARED(Locks::mutator_lock_) {
957     if (VerifyRegisterTypeWide(inst->VRegB_12x(), src_kind)) {
958       work_line_->SetRegisterTypeWide(inst->VRegA_12x(), dst_kind, RegType::ToHighHalf(dst_kind));
959     }
960   }
961 
CheckUnaryOpToWide(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind)962   void CheckUnaryOpToWide(const Instruction* inst,
963                           RegType::Kind dst_kind,
964                           RegType::Kind src_kind)
965       REQUIRES_SHARED(Locks::mutator_lock_) {
966     if (VerifyRegisterType(inst->VRegB_12x(), src_kind)) {
967       work_line_->SetRegisterTypeWide(inst->VRegA_12x(), dst_kind, RegType::ToHighHalf(dst_kind));
968     }
969   }
970 
CheckUnaryOpFromWide(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind)971   void CheckUnaryOpFromWide(const Instruction* inst,
972                             RegType::Kind dst_kind,
973                             RegType::Kind src_kind)
974       REQUIRES_SHARED(Locks::mutator_lock_) {
975     if (VerifyRegisterTypeWide(inst->VRegB_12x(), src_kind)) {
976       work_line_->SetRegisterType(inst->VRegA_12x(), dst_kind);
977     }
978   }
979 
980   /*
981    * Verify types for a simple three-register instruction (e.g. "add-int").
982    * "dst_type" is stored into vA, and "src_type1"/"src_type2" are verified
983    * against vB/vC.
984    */
CheckBinaryOp(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind1,RegType::Kind src_kind2,bool check_boolean_op)985   void CheckBinaryOp(const Instruction* inst,
986                      RegType::Kind dst_kind,
987                      RegType::Kind src_kind1,
988                      RegType::Kind src_kind2,
989                      bool check_boolean_op)
990       REQUIRES_SHARED(Locks::mutator_lock_) {
991     const uint32_t vregA = inst->VRegA_23x();
992     const uint32_t vregB = inst->VRegB_23x();
993     const uint32_t vregC = inst->VRegC_23x();
994     if (VerifyRegisterType(vregB, src_kind1) &&
995         VerifyRegisterType(vregC, src_kind2)) {
996       if (check_boolean_op) {
997         DCHECK_EQ(dst_kind, RegType::Kind::kInteger);
998         if (RegType::IsBooleanTypes(
999                 RegTypeCache::RegKindForId(work_line_->GetRegisterTypeId(vregB))) &&
1000             RegType::IsBooleanTypes(
1001                 RegTypeCache::RegKindForId(work_line_->GetRegisterTypeId(vregC)))) {
1002           work_line_->SetRegisterType(vregA, RegType::Kind::kBoolean);
1003           return;
1004         }
1005       }
1006       work_line_->SetRegisterType(vregA, dst_kind);
1007     }
1008   }
1009 
CheckBinaryOpWide(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind1,RegType::Kind src_kind2)1010   void CheckBinaryOpWide(const Instruction* inst,
1011                          RegType::Kind dst_kind,
1012                          RegType::Kind src_kind1,
1013                          RegType::Kind src_kind2)
1014       REQUIRES_SHARED(Locks::mutator_lock_) {
1015     if (VerifyRegisterTypeWide(inst->VRegB_23x(), src_kind1) &&
1016         VerifyRegisterTypeWide(inst->VRegC_23x(), src_kind2)) {
1017       work_line_->SetRegisterTypeWide(inst->VRegA_23x(), dst_kind, RegType::ToHighHalf(dst_kind));
1018     }
1019   }
1020 
CheckBinaryOpWideCmp(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind1,RegType::Kind src_kind2)1021   void CheckBinaryOpWideCmp(const Instruction* inst,
1022                             RegType::Kind dst_kind,
1023                             RegType::Kind src_kind1,
1024                             RegType::Kind src_kind2)
1025       REQUIRES_SHARED(Locks::mutator_lock_) {
1026     if (VerifyRegisterTypeWide(inst->VRegB_23x(), src_kind1) &&
1027         VerifyRegisterTypeWide(inst->VRegC_23x(), src_kind2)) {
1028       work_line_->SetRegisterType(inst->VRegA_23x(), dst_kind);
1029     }
1030   }
1031 
CheckBinaryOpWideShift(const Instruction * inst,RegType::Kind long_lo_kind,RegType::Kind int_kind)1032   void CheckBinaryOpWideShift(const Instruction* inst,
1033                               RegType::Kind long_lo_kind,
1034                               RegType::Kind int_kind)
1035       REQUIRES_SHARED(Locks::mutator_lock_) {
1036     if (VerifyRegisterTypeWide(inst->VRegB_23x(), long_lo_kind) &&
1037         VerifyRegisterType(inst->VRegC_23x(), int_kind)) {
1038       RegType::Kind long_hi_kind = RegType::ToHighHalf(long_lo_kind);
1039       work_line_->SetRegisterTypeWide(inst->VRegA_23x(), long_lo_kind, long_hi_kind);
1040     }
1041   }
1042 
1043   /*
1044    * Verify types for a binary "2addr" operation. "src_type1"/"src_type2"
1045    * are verified against vA/vB, then "dst_type" is stored into vA.
1046    */
CheckBinaryOp2addr(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind1,RegType::Kind src_kind2,bool check_boolean_op)1047   void CheckBinaryOp2addr(const Instruction* inst,
1048                           RegType::Kind dst_kind,
1049                           RegType::Kind src_kind1,
1050                           RegType::Kind src_kind2,
1051                           bool check_boolean_op)
1052       REQUIRES_SHARED(Locks::mutator_lock_) {
1053     const uint32_t vregA = inst->VRegA_12x();
1054     const uint32_t vregB = inst->VRegB_12x();
1055     if (VerifyRegisterType(vregA, src_kind1) &&
1056         VerifyRegisterType(vregB, src_kind2)) {
1057       if (check_boolean_op) {
1058         DCHECK_EQ(dst_kind, RegType::Kind::kInteger);
1059         if (RegType::IsBooleanTypes(
1060                 RegTypeCache::RegKindForId(work_line_->GetRegisterTypeId(vregA))) &&
1061             RegType::IsBooleanTypes(
1062                 RegTypeCache::RegKindForId(work_line_->GetRegisterTypeId(vregB)))) {
1063           work_line_->SetRegisterType(vregA, RegType::Kind::kBoolean);
1064           return;
1065         }
1066       }
1067       work_line_->SetRegisterType(vregA, dst_kind);
1068     }
1069   }
1070 
CheckBinaryOp2addrWide(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind1,RegType::Kind src_kind2)1071   void CheckBinaryOp2addrWide(const Instruction* inst,
1072                               RegType::Kind dst_kind,
1073                               RegType::Kind src_kind1,
1074                               RegType::Kind src_kind2)
1075       REQUIRES_SHARED(Locks::mutator_lock_) {
1076     const uint32_t vregA = inst->VRegA_12x();
1077     const uint32_t vregB = inst->VRegB_12x();
1078     if (VerifyRegisterTypeWide(vregA, src_kind1) &&
1079         VerifyRegisterTypeWide(vregB, src_kind2)) {
1080       work_line_->SetRegisterTypeWide(vregA, dst_kind, RegType::ToHighHalf(dst_kind));
1081     }
1082   }
1083 
CheckBinaryOp2addrWideShift(const Instruction * inst,RegType::Kind long_lo_kind,RegType::Kind int_kind)1084   void CheckBinaryOp2addrWideShift(const Instruction* inst,
1085                                    RegType::Kind long_lo_kind,
1086                                    RegType::Kind int_kind)
1087       REQUIRES_SHARED(Locks::mutator_lock_) {
1088     const uint32_t vregA = inst->VRegA_12x();
1089     const uint32_t vregB = inst->VRegB_12x();
1090     if (VerifyRegisterTypeWide(vregA, long_lo_kind) &&
1091         VerifyRegisterType(vregB, int_kind)) {
1092       RegType::Kind long_hi_kind = RegType::ToHighHalf(long_lo_kind);
1093       work_line_->SetRegisterTypeWide(vregA, long_lo_kind, long_hi_kind);
1094     }
1095   }
1096 
1097   /*
1098    * Verify types for A two-register instruction with a literal constant (e.g. "add-int/lit8").
1099    * "dst_type" is stored into vA, and "src_type" is verified against vB.
1100    *
1101    * If "check_boolean_op" is set, we use the constant value in vC.
1102    */
CheckLiteralOp(const Instruction * inst,RegType::Kind dst_kind,RegType::Kind src_kind,bool check_boolean_op,bool is_lit16)1103   void CheckLiteralOp(const Instruction* inst,
1104                       RegType::Kind dst_kind,
1105                       RegType::Kind src_kind,
1106                       bool check_boolean_op,
1107                       bool is_lit16)
1108       REQUIRES_SHARED(Locks::mutator_lock_) {
1109     const uint32_t vregA = is_lit16 ? inst->VRegA_22s() : inst->VRegA_22b();
1110     const uint32_t vregB = is_lit16 ? inst->VRegB_22s() : inst->VRegB_22b();
1111     if (VerifyRegisterType(vregB, src_kind)) {
1112       if (check_boolean_op) {
1113         DCHECK_EQ(dst_kind, RegType::Kind::kInteger);
1114         /* check vB with the call, then check the constant manually */
1115         const uint32_t val = is_lit16 ? inst->VRegC_22s() : inst->VRegC_22b();
1116         if (work_line_->GetRegisterType(this, vregB).IsBooleanTypes() && (val == 0 || val == 1)) {
1117           work_line_->SetRegisterType(vregA, RegType::Kind::kBoolean);
1118           return;
1119         }
1120       }
1121       work_line_->SetRegisterType(vregA, dst_kind);
1122     }
1123   }
1124 
CurrentInsnFlags()1125   InstructionFlags* CurrentInsnFlags() {
1126     return &GetModifiableInstructionFlags(work_insn_idx_);
1127   }
1128 
1129   RegType::Kind DetermineCat1Constant(int32_t value)
1130       REQUIRES_SHARED(Locks::mutator_lock_);
1131 
1132   ALWAYS_INLINE bool FailOrAbort(bool condition, const char* error_msg, uint32_t work_insn_idx);
1133 
GetModifiableInstructionFlags(size_t index)1134   ALWAYS_INLINE InstructionFlags& GetModifiableInstructionFlags(size_t index) {
1135     return insn_flags_[index];
1136   }
1137 
1138   // Returns the method index of an invoke instruction.
GetMethodIdxOfInvoke(const Instruction * inst)1139   static uint16_t GetMethodIdxOfInvoke(const Instruction* inst)
1140       REQUIRES_SHARED(Locks::mutator_lock_) {
1141     // Note: This is compiled to a single load in release mode.
1142     Instruction::Code opcode = inst->Opcode();
1143     if (opcode == Instruction::INVOKE_VIRTUAL ||
1144         opcode == Instruction::INVOKE_SUPER ||
1145         opcode == Instruction::INVOKE_DIRECT ||
1146         opcode == Instruction::INVOKE_STATIC ||
1147         opcode == Instruction::INVOKE_INTERFACE ||
1148         opcode == Instruction::INVOKE_CUSTOM) {
1149       return inst->VRegB_35c();
1150     } else if (opcode == Instruction::INVOKE_VIRTUAL_RANGE ||
1151                opcode == Instruction::INVOKE_SUPER_RANGE ||
1152                opcode == Instruction::INVOKE_DIRECT_RANGE ||
1153                opcode == Instruction::INVOKE_STATIC_RANGE ||
1154                opcode == Instruction::INVOKE_INTERFACE_RANGE ||
1155                opcode == Instruction::INVOKE_CUSTOM_RANGE) {
1156       return inst->VRegB_3rc();
1157     } else if (opcode == Instruction::INVOKE_POLYMORPHIC) {
1158       return inst->VRegB_45cc();
1159     } else {
1160       DCHECK_EQ(opcode, Instruction::INVOKE_POLYMORPHIC_RANGE);
1161       return inst->VRegB_4rcc();
1162     }
1163   }
1164   // Returns the field index of a field access instruction.
GetFieldIdxOfFieldAccess(const Instruction * inst,bool is_static)1165   uint16_t GetFieldIdxOfFieldAccess(const Instruction* inst, bool is_static)
1166       REQUIRES_SHARED(Locks::mutator_lock_) {
1167     if (is_static) {
1168       return inst->VRegB_21c();
1169     } else {
1170       return inst->VRegC_22c();
1171     }
1172   }
1173 
1174   // Run verification on the method. Returns true if verification completes and false if the input
1175   // has an irrecoverable corruption.
1176   bool Verify() override REQUIRES_SHARED(Locks::mutator_lock_);
1177 
1178   // For app-compatibility, code after a runtime throw is treated as dead code
1179   // for apps targeting <= S.
1180   // Returns whether the current instruction was marked as throwing.
1181   bool PotentiallyMarkRuntimeThrow() override;
1182 
1183   // Dump the failures encountered by the verifier.
DumpFailures(std::ostream & os)1184   std::ostream& DumpFailures(std::ostream& os) {
1185     DCHECK_EQ(failures_.size(), failure_messages_.size());
1186     for (const auto* stream : failure_messages_) {
1187         os << stream->str() << "\n";
1188     }
1189     return os;
1190   }
1191 
1192   // Dump the state of the verifier, namely each instruction, what flags are set on it, register
1193   // information
Dump(std::ostream & os)1194   void Dump(std::ostream& os) REQUIRES_SHARED(Locks::mutator_lock_) {
1195     VariableIndentationOutputStream vios(&os);
1196     Dump(&vios);
1197   }
1198   void Dump(VariableIndentationOutputStream* vios) REQUIRES_SHARED(Locks::mutator_lock_);
1199 
1200   bool HandleMoveException(const Instruction* inst) REQUIRES_SHARED(Locks::mutator_lock_);
1201 
1202   const uint32_t method_access_flags_;  // Method's access flags.
1203   const RegType* return_type_;  // Lazily computed return type of the method.
1204   // The dex_cache for the declaring class of the method.
1205   Handle<mirror::DexCache> dex_cache_ GUARDED_BY(Locks::mutator_lock_);
1206   // The class loader for the declaring class of the method.
1207   Handle<mirror::ClassLoader> class_loader_ GUARDED_BY(Locks::mutator_lock_);
1208   const RegType* declaring_class_;  // Lazily computed reg type of the method's declaring class.
1209 
1210   // The dex PC of a FindLocksAtDexPc request, -1 otherwise.
1211   uint32_t interesting_dex_pc_;
1212   // The container into which FindLocksAtDexPc should write the registers containing held locks,
1213   // null if we're not doing FindLocksAtDexPc.
1214   std::vector<DexLockInfo>* monitor_enter_dex_pcs_;
1215 
1216   // Indicates whether we verify to dump the info. In that case we accept quickened instructions
1217   // even though we might detect to be a compiler. Should only be set when running
1218   // VerifyMethodAndDump.
1219   const bool verify_to_dump_;
1220 
1221   // Whether or not we call AllowThreadSuspension periodically, we want a way to disable this for
1222   // thread dumping checkpoints since we may get thread suspension at an inopportune time due to
1223   // FindLocksAtDexPC, resulting in deadlocks.
1224   const bool allow_thread_suspension_;
1225 
1226   // Whether the method seems to be a constructor. Note that this field exists as we can't trust
1227   // the flags in the dex file. Some older code does not mark methods named "<init>" and "<clinit>"
1228   // correctly.
1229   //
1230   // Note: this flag is only valid once Verify() has started.
1231   bool is_constructor_;
1232 
1233   // API level, for dependent checks. Note: we do not use '0' for unset here, to simplify checks.
1234   // Instead, unset level should correspond to max().
1235   const uint32_t api_level_;
1236 
1237   friend class ::art::verifier::MethodVerifier;
1238 
1239   DISALLOW_COPY_AND_ASSIGN(MethodVerifier);
1240 };
1241 
1242 // Note: returns true on failure.
1243 template <bool kVerifierDebug>
FailOrAbort(bool condition,const char * error_msg,uint32_t work_insn_idx)1244 inline bool MethodVerifier<kVerifierDebug>::FailOrAbort(bool condition,
1245                                                         const char* error_msg,
1246                                                         uint32_t work_insn_idx) {
1247   if (kIsDebugBuild) {
1248     // In a debug build, abort if the error condition is wrong. Only warn if
1249     // we are already aborting (as this verification is likely run to print
1250     // lock information).
1251     if (LIKELY(gAborting == 0)) {
1252       DCHECK(condition) << error_msg << work_insn_idx << " "
1253                         << dex_file_->PrettyMethod(dex_method_idx_);
1254     } else {
1255       if (!condition) {
1256         LOG(ERROR) << error_msg << work_insn_idx;
1257         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
1258         return true;
1259       }
1260     }
1261   } else {
1262     // In a non-debug build, just fail the class.
1263     if (!condition) {
1264       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
1265       return true;
1266     }
1267   }
1268 
1269   return false;
1270 }
1271 
IsLargeMethod(const CodeItemDataAccessor & accessor)1272 static bool IsLargeMethod(const CodeItemDataAccessor& accessor) {
1273   if (!accessor.HasCodeItem()) {
1274     return false;
1275   }
1276 
1277   uint16_t registers_size = accessor.RegistersSize();
1278   uint32_t insns_size = accessor.InsnsSizeInCodeUnits();
1279 
1280   return registers_size * insns_size > 4*1024*1024;
1281 }
1282 
1283 template <bool kVerifierDebug>
FindLocksAtDexPc()1284 void MethodVerifier<kVerifierDebug>::FindLocksAtDexPc() {
1285   CHECK(monitor_enter_dex_pcs_ != nullptr);
1286   CHECK(code_item_accessor_.HasCodeItem());  // This only makes sense for methods with code.
1287 
1288   // Quick check whether there are any monitor_enter instructions before verifying.
1289   for (const DexInstructionPcPair& inst : code_item_accessor_) {
1290     if (inst->Opcode() == Instruction::MONITOR_ENTER) {
1291       // Strictly speaking, we ought to be able to get away with doing a subset of the full method
1292       // verification. In practice, the phase we want relies on data structures set up by all the
1293       // earlier passes, so we just run the full method verification and bail out early when we've
1294       // got what we wanted.
1295       Verify();
1296       return;
1297     }
1298   }
1299 }
1300 
1301 template <bool kVerifierDebug>
Verify()1302 bool MethodVerifier<kVerifierDebug>::Verify() {
1303   // Some older code doesn't correctly mark constructors as such, so we need look
1304   // at the name if the constructor flag is not present.
1305   if ((method_access_flags_ & kAccConstructor) != 0) {
1306     // `DexFileVerifier` rejects methods with the constructor flag without a constructor name.
1307     DCHECK(dex_file_->GetMethodNameView(dex_method_idx_) == "<init>" ||
1308            dex_file_->GetMethodNameView(dex_method_idx_) == "<clinit>");
1309     is_constructor_ = true;
1310   } else if (dex_file_->GetMethodName(dex_method_idx_)[0] == '<') {
1311     // `DexFileVerifier` rejects method names starting with '<' other than constructors.
1312     DCHECK(dex_file_->GetMethodNameView(dex_method_idx_) == "<init>" ||
1313            dex_file_->GetMethodNameView(dex_method_idx_) == "<clinit>");
1314     LOG(WARNING) << "Method " << dex_file_->PrettyMethod(dex_method_idx_)
1315                  << " not marked as constructor.";
1316     is_constructor_ = true;
1317   }
1318   // If it's a constructor, check whether IsStatic() matches the name for newer dex files.
1319   // This should be rejected by the `DexFileVerifier` but it's  accepted for older dex files.
1320   if (kIsDebugBuild && IsConstructor() && dex_file_->SupportsDefaultMethods()) {
1321     CHECK_EQ(IsStatic(), dex_file_->GetMethodNameView(dex_method_idx_) == "<clinit>");
1322   }
1323 
1324   // Methods may only have one of public/protected/private.
1325   // This should have been rejected by the dex file verifier. Only do in debug build.
1326   constexpr uint32_t kAccPublicProtectedPrivate = kAccPublic | kAccProtected | kAccPrivate;
1327   DCHECK_IMPLIES((method_access_flags_ & kAccPublicProtectedPrivate) != 0u,
1328                  IsPowerOfTwo(method_access_flags_ & kAccPublicProtectedPrivate));
1329 
1330   // If there aren't any instructions, make sure that's expected, then exit successfully.
1331   if (!code_item_accessor_.HasCodeItem()) {
1332     // Only native or abstract methods may not have code.
1333     if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) {
1334       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method";
1335       return false;
1336     }
1337 
1338     // Test FastNative and CriticalNative annotations. We do this in the
1339     // verifier for convenience.
1340     if ((method_access_flags_ & kAccNative) != 0) {
1341       // Fetch the flags from the annotations: the class linker hasn't processed
1342       // them yet.
1343       uint32_t native_access_flags = annotations::GetNativeMethodAnnotationAccessFlags(
1344           *dex_file_, class_def_, dex_method_idx_);
1345       if ((native_access_flags & kAccFastNative) != 0) {
1346         if ((method_access_flags_ & kAccSynchronized) != 0) {
1347           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "fast native methods cannot be synchronized";
1348           return false;
1349         }
1350       }
1351       if ((native_access_flags & kAccCriticalNative) != 0) {
1352         if ((method_access_flags_ & kAccSynchronized) != 0) {
1353           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "critical native methods cannot be synchronized";
1354           return false;
1355         }
1356         if ((method_access_flags_ & kAccStatic) == 0) {
1357           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "critical native methods must be static";
1358           return false;
1359         }
1360         const char* shorty = dex_file_->GetMethodShorty(dex_method_idx_);
1361         for (size_t i = 0, len = strlen(shorty); i < len; ++i) {
1362           if (Primitive::GetType(shorty[i]) == Primitive::kPrimNot) {
1363             Fail(VERIFY_ERROR_BAD_CLASS_HARD) <<
1364                 "critical native methods must not have references as arguments or return type";
1365             return false;
1366           }
1367         }
1368       }
1369     }
1370 
1371     // This should have been rejected by the dex file verifier. Only do in debug build.
1372     // Note: the above will also be rejected in the dex file verifier, starting in dex version 37.
1373     if (kIsDebugBuild) {
1374       if ((method_access_flags_ & kAccAbstract) != 0) {
1375         // Abstract methods are not allowed to have the following flags.
1376         static constexpr uint32_t kForbidden =
1377             kAccPrivate |
1378             kAccStatic |
1379             kAccFinal |
1380             kAccNative |
1381             kAccStrict |
1382             kAccSynchronized;
1383         if ((method_access_flags_ & kForbidden) != 0) {
1384           Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1385                 << "method can't be abstract and private/static/final/native/strict/synchronized";
1386           return false;
1387         }
1388       }
1389       if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
1390         // Interface methods must be public and abstract (if default methods are disabled).
1391         uint32_t kRequired = kAccPublic;
1392         if ((method_access_flags_ & kRequired) != kRequired) {
1393           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods must be public";
1394           return false;
1395         }
1396         // In addition to the above, interface methods must not be protected.
1397         static constexpr uint32_t kForbidden = kAccProtected;
1398         if ((method_access_flags_ & kForbidden) != 0) {
1399           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods can't be protected";
1400           return false;
1401         }
1402       }
1403       // We also don't allow constructors to be abstract or native.
1404       if (IsConstructor()) {
1405         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be abstract or native";
1406         return false;
1407       }
1408     }
1409     return true;
1410   }
1411 
1412   // This should have been rejected by the dex file verifier. Only do in debug build.
1413   if (kIsDebugBuild) {
1414     // When there's code, the method must not be native or abstract.
1415     if ((method_access_flags_ & (kAccNative | kAccAbstract)) != 0) {
1416       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "non-zero-length code in abstract or native method";
1417       return false;
1418     }
1419 
1420     if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
1421       // Interfaces may always have static initializers for their fields. If we are running with
1422       // default methods enabled we also allow other public, static, non-final methods to have code.
1423       // Otherwise that is the only type of method allowed.
1424       if (!(IsConstructor() && IsStatic())) {
1425         if (IsInstanceConstructor()) {
1426           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-static constructor";
1427           return false;
1428         } else if (method_access_flags_ & kAccFinal) {
1429           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods";
1430           return false;
1431         } else {
1432           uint32_t access_flag_options = kAccPublic;
1433           if (dex_file_->SupportsDefaultMethods()) {
1434             access_flag_options |= kAccPrivate;
1435           }
1436           if (!(method_access_flags_ & access_flag_options)) {
1437             Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1438                 << "interfaces may not have protected or package-private members";
1439             return false;
1440           }
1441         }
1442       }
1443     }
1444 
1445     // Instance constructors must not be synchronized.
1446     if (IsInstanceConstructor()) {
1447       static constexpr uint32_t kForbidden = kAccSynchronized;
1448       if ((method_access_flags_ & kForbidden) != 0) {
1449         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be synchronized";
1450         return false;
1451       }
1452     }
1453   }
1454 
1455   // Consistency-check of the register counts.
1456   // ins + locals = registers, so make sure that ins <= registers.
1457   if (code_item_accessor_.InsSize() > code_item_accessor_.RegistersSize()) {
1458     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins="
1459                                       << code_item_accessor_.InsSize()
1460                                       << " regs=" << code_item_accessor_.RegistersSize();
1461     return false;
1462   }
1463 
1464   // Allocate and initialize an array to hold instruction data.
1465   insn_flags_.reset(allocator_.AllocArray<InstructionFlags>(
1466       code_item_accessor_.InsnsSizeInCodeUnits()));
1467   DCHECK(insn_flags_ != nullptr);
1468   // `ArenaAllocator` guarantees zero-initialization.
1469   static_assert(std::is_same_v<decltype(allocator_), ArenaAllocator>);
1470   DCHECK(std::all_of(
1471       insn_flags_.get(),
1472       insn_flags_.get() + code_item_accessor_.InsnsSizeInCodeUnits(),
1473       [](const InstructionFlags& flags) { return flags.Equals(InstructionFlags()); }));
1474   // Run through the instructions and see if the width checks out.
1475   bool result = ComputeWidthsAndCountOps();
1476   // Flag instructions guarded by a "try" block and check exception handlers.
1477   result = result && ScanTryCatchBlocks();
1478   // Perform static instruction verification.
1479   result = result && VerifyInstructions();
1480   // Perform code-flow analysis and return.
1481   result = result && VerifyCodeFlow();
1482 
1483   return result;
1484 }
1485 
1486 template <bool kVerifierDebug>
ComputeWidthsAndCountOps()1487 bool MethodVerifier<kVerifierDebug>::ComputeWidthsAndCountOps() {
1488   // We can't assume the instruction is well formed, handle the case where calculating the size
1489   // goes past the end of the code item.
1490   SafeDexInstructionIterator it(code_item_accessor_.begin(), code_item_accessor_.end());
1491   if (it == code_item_accessor_.end()) {
1492     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code item has no opcode";
1493     return false;
1494   }
1495   for ( ; !it.IsErrorState() && it < code_item_accessor_.end(); ++it) {
1496     // In case the instruction goes past the end of the code item, make sure to not process it.
1497     SafeDexInstructionIterator next = it;
1498     ++next;
1499     if (next.IsErrorState()) {
1500       break;
1501     }
1502     GetModifiableInstructionFlags(it.DexPc()).SetIsOpcode();
1503   }
1504 
1505   if (it != code_item_accessor_.end()) {
1506     const size_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
1507     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected ("
1508                                       << it.DexPc() << " vs. " << insns_size << ")";
1509     return false;
1510   }
1511   DCHECK(GetInstructionFlags(0).IsOpcode());
1512 
1513   return true;
1514 }
1515 
1516 template <bool kVerifierDebug>
ScanTryCatchBlocks()1517 bool MethodVerifier<kVerifierDebug>::ScanTryCatchBlocks() {
1518   const uint32_t tries_size = code_item_accessor_.TriesSize();
1519   if (tries_size == 0) {
1520     return true;
1521   }
1522   const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
1523   for (const dex::TryItem& try_item : code_item_accessor_.TryItems()) {
1524     const uint32_t start = try_item.start_addr_;
1525     const uint32_t end = start + try_item.insn_count_;
1526     if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
1527       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start
1528                                         << " endAddr=" << end << " (size=" << insns_size << ")";
1529       return false;
1530     }
1531     if (!GetInstructionFlags(start).IsOpcode()) {
1532       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1533           << "'try' block starts inside an instruction (" << start << ")";
1534       return false;
1535     }
1536     DexInstructionIterator end_it(code_item_accessor_.Insns(), end);
1537     for (DexInstructionIterator it(code_item_accessor_.Insns(), start); it < end_it; ++it) {
1538       GetModifiableInstructionFlags(it.DexPc()).SetInTry();
1539     }
1540   }
1541   // Iterate over each of the handlers to verify target addresses.
1542   const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
1543   const uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
1544   ClassLinker* linker = GetClassLinker();
1545   for (uint32_t idx = 0; idx < handlers_size; idx++) {
1546     CatchHandlerIterator iterator(handlers_ptr);
1547     for (; iterator.HasNext(); iterator.Next()) {
1548       uint32_t dex_pc = iterator.GetHandlerAddress();
1549       if (!GetInstructionFlags(dex_pc).IsOpcode()) {
1550         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1551             << "exception handler starts at bad address (" << dex_pc << ")";
1552         return false;
1553       }
1554       if (!CheckNotMoveResult(code_item_accessor_.Insns(), dex_pc)) {
1555         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1556             << "exception handler begins with move-result* (" << dex_pc << ")";
1557         return false;
1558       }
1559       GetModifiableInstructionFlags(dex_pc).SetBranchTarget();
1560       // Ensure exception types are resolved so that they don't need resolution to be delivered,
1561       // unresolved exception types will be ignored by exception delivery
1562       if (iterator.GetHandlerTypeIndex().IsValid()) {
1563         ObjPtr<mirror::Class> exception_type =
1564             linker->ResolveType(iterator.GetHandlerTypeIndex(), dex_cache_, class_loader_);
1565         if (exception_type == nullptr) {
1566           DCHECK(self_->IsExceptionPending());
1567           self_->ClearException();
1568         }
1569       }
1570     }
1571     handlers_ptr = iterator.EndDataPointer();
1572   }
1573   return true;
1574 }
1575 
1576 template <bool kVerifierDebug>
VerifyInstructions()1577 bool MethodVerifier<kVerifierDebug>::VerifyInstructions() {
1578   // Flag the start of the method as a branch target.
1579   GetModifiableInstructionFlags(0).SetBranchTarget();
1580   const Instruction* inst = Instruction::At(code_item_accessor_.Insns());
1581   uint32_t dex_pc = 0u;
1582   const uint32_t end_dex_pc = code_item_accessor_.InsnsSizeInCodeUnits();
1583   while (dex_pc != end_dex_pc) {
1584     auto find_dispatch_opcode = [](Instruction::Code opcode) constexpr {
1585       // NOP needs its own dipatch because it needs special code for instruction size.
1586       if (opcode == Instruction::NOP) {
1587         return opcode;
1588       }
1589       DCHECK_GT(Instruction::SizeInCodeUnits(Instruction::FormatOf(opcode)), 0u);
1590       for (uint32_t raw_other = 0; raw_other != opcode; ++raw_other) {
1591         Instruction::Code other = enum_cast<Instruction::Code>(raw_other);
1592         if (other == Instruction::NOP) {
1593           continue;
1594         }
1595         // We dispatch to `VerifyInstruction()` based on the format and verify flags but
1596         // we also treat return instructions separately to update instruction flags.
1597         if (Instruction::FormatOf(opcode) == Instruction::FormatOf(other) &&
1598             Instruction::VerifyFlagsOf(opcode) == Instruction::VerifyFlagsOf(other) &&
1599             Instruction::IsReturn(opcode) == Instruction::IsReturn(other)) {
1600           return other;
1601         }
1602       }
1603       return opcode;
1604     };
1605 
1606     uint16_t inst_data = inst->Fetch16(0);
1607     Instruction::Code dispatch_opcode = Instruction::NOP;
1608     switch (inst->Opcode(inst_data)) {
1609 #define DEFINE_CASE(opcode, c, p, format, index, flags, eflags, vflags) \
1610       case opcode: {                                                    \
1611         /* Enforce compile-time evaluation. */                          \
1612         constexpr Instruction::Code kDispatchOpcode =                   \
1613             find_dispatch_opcode(enum_cast<Instruction::Code>(opcode)); \
1614         dispatch_opcode = kDispatchOpcode;                              \
1615         break;                                                          \
1616       }
1617       DEX_INSTRUCTION_LIST(DEFINE_CASE)
1618 #undef DEFINE_CASE
1619     }
1620     bool is_return = false;
1621     uint32_t instruction_size = 0u;
1622     switch (dispatch_opcode) {
1623 #define DEFINE_CASE(opcode, c, p, format, index, flags, eflags, vflags)             \
1624       case opcode: {                                                                \
1625         constexpr Instruction::Code kOpcode = enum_cast<Instruction::Code>(opcode); \
1626         if (!VerifyInstruction<kOpcode>(inst, dex_pc, inst_data)) {                 \
1627           DCHECK_NE(failures_.size(), 0U);                                          \
1628           return false;                                                             \
1629         }                                                                           \
1630         is_return = Instruction::IsReturn(kOpcode);                                 \
1631         instruction_size = (opcode == Instruction::NOP)                             \
1632             ? inst->SizeInCodeUnitsComplexOpcode()                                  \
1633             : Instruction::SizeInCodeUnits(Instruction::FormatOf(kOpcode));         \
1634         DCHECK_EQ(instruction_size, inst->SizeInCodeUnits());                       \
1635         break;                                                                      \
1636       }
1637       DEX_INSTRUCTION_LIST(DEFINE_CASE)
1638 #undef DEFINE_CASE
1639     }
1640     // Flag some interesting instructions.
1641     if (is_return) {
1642       GetModifiableInstructionFlags(dex_pc).SetReturn();
1643     }
1644     DCHECK_NE(instruction_size, 0u);
1645     DCHECK_LE(instruction_size, end_dex_pc - dex_pc);
1646     dex_pc += instruction_size;
1647     inst = inst->RelativeAt(instruction_size);
1648   }
1649   return true;
1650 }
1651 
1652 template <bool kVerifierDebug>
1653 template <Instruction::Code kDispatchOpcode>
VerifyInstruction(const Instruction * inst,uint32_t code_offset,uint16_t inst_data)1654 inline bool MethodVerifier<kVerifierDebug>::VerifyInstruction(const Instruction* inst,
1655                                                               uint32_t code_offset,
1656                                                               uint16_t inst_data) {
1657   // The `kDispatchOpcode` may differ from the actual opcode but it shall have the
1658   // same verification flags and format. We explicitly `DCHECK` these below and
1659   // the format is also `DCHECK`ed in VReg getters that take it as an argument.
1660   constexpr Instruction::Format kFormat = Instruction::FormatOf(kDispatchOpcode);
1661   DCHECK_EQ(kFormat, Instruction::FormatOf(inst->Opcode()));
1662 
1663   bool result = true;
1664   constexpr uint32_t kVerifyA = Instruction::GetVerifyTypeArgumentAOf(kDispatchOpcode);
1665   DCHECK_EQ(kVerifyA, inst->GetVerifyTypeArgumentA());
1666   switch (kVerifyA) {
1667     case Instruction::kVerifyRegA:
1668       result = result && CheckRegisterIndex(inst->VRegA(kFormat, inst_data));
1669       break;
1670     case Instruction::kVerifyRegAWide:
1671       result = result && CheckWideRegisterIndex(inst->VRegA(kFormat, inst_data));
1672       break;
1673     case Instruction::kVerifyNothing:
1674       break;
1675   }
1676   constexpr uint32_t kVerifyB = Instruction::GetVerifyTypeArgumentBOf(kDispatchOpcode);
1677   DCHECK_EQ(kVerifyB, inst->GetVerifyTypeArgumentB());
1678   switch (kVerifyB) {
1679     case Instruction::kVerifyRegB:
1680       result = result && CheckRegisterIndex(inst->VRegB(kFormat, inst_data));
1681       break;
1682     case Instruction::kVerifyRegBField:
1683       result = result && CheckFieldIndex(inst, inst_data, inst->VRegB(kFormat, inst_data));
1684       break;
1685     case Instruction::kVerifyRegBMethod:
1686       result = result && CheckMethodIndex(inst->VRegB(kFormat, inst_data));
1687       break;
1688     case Instruction::kVerifyRegBNewInstance:
1689       result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB(kFormat, inst_data)));
1690       break;
1691     case Instruction::kVerifyRegBString:
1692       result = result && CheckStringIndex(inst->VRegB(kFormat, inst_data));
1693       break;
1694     case Instruction::kVerifyRegBType:
1695       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB(kFormat, inst_data)));
1696       break;
1697     case Instruction::kVerifyRegBWide:
1698       result = result && CheckWideRegisterIndex(inst->VRegB(kFormat, inst_data));
1699       break;
1700     case Instruction::kVerifyRegBCallSite:
1701       result = result && CheckCallSiteIndex(inst->VRegB(kFormat, inst_data));
1702       break;
1703     case Instruction::kVerifyRegBMethodHandle:
1704       result = result && CheckMethodHandleIndex(inst->VRegB(kFormat, inst_data));
1705       break;
1706     case Instruction::kVerifyRegBPrototype:
1707       result = result && CheckPrototypeIndex(inst->VRegB(kFormat, inst_data));
1708       break;
1709     case Instruction::kVerifyNothing:
1710       break;
1711   }
1712   constexpr uint32_t kVerifyC = Instruction::GetVerifyTypeArgumentCOf(kDispatchOpcode);
1713   DCHECK_EQ(kVerifyC, inst->GetVerifyTypeArgumentC());
1714   switch (kVerifyC) {
1715     case Instruction::kVerifyRegC:
1716       result = result && CheckRegisterIndex(inst->VRegC(kFormat));
1717       break;
1718     case Instruction::kVerifyRegCField:
1719       result = result && CheckFieldIndex(inst, inst_data, inst->VRegC(kFormat));
1720       break;
1721     case Instruction::kVerifyRegCNewArray:
1722       result = result && CheckNewArray(dex::TypeIndex(inst->VRegC(kFormat)));
1723       break;
1724     case Instruction::kVerifyRegCType:
1725       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC(kFormat)));
1726       break;
1727     case Instruction::kVerifyRegCWide:
1728       result = result && CheckWideRegisterIndex(inst->VRegC(kFormat));
1729       break;
1730     case Instruction::kVerifyNothing:
1731       break;
1732   }
1733   constexpr uint32_t kVerifyH = Instruction::GetVerifyTypeArgumentHOf(kDispatchOpcode);
1734   DCHECK_EQ(kVerifyH, inst->GetVerifyTypeArgumentH());
1735   switch (kVerifyH) {
1736     case Instruction::kVerifyRegHPrototype:
1737       result = result && CheckPrototypeIndex(inst->VRegH(kFormat));
1738       break;
1739     case Instruction::kVerifyNothing:
1740       break;
1741   }
1742   constexpr uint32_t kVerifyExtra = Instruction::GetVerifyExtraFlagsOf(kDispatchOpcode);
1743   DCHECK_EQ(kVerifyExtra, inst->GetVerifyExtraFlags());
1744   switch (kVerifyExtra) {
1745     case Instruction::kVerifyArrayData:
1746       result = result && CheckArrayData(code_offset);
1747       break;
1748     case Instruction::kVerifyBranchTarget:
1749       result = result && CheckBranchTarget(code_offset);
1750       break;
1751     case Instruction::kVerifySwitchTargets:
1752       result = result && CheckSwitchTargets(code_offset);
1753       break;
1754     case Instruction::kVerifyVarArgNonZero:
1755       // Fall-through.
1756     case Instruction::kVerifyVarArg: {
1757       // Instructions that can actually return a negative value shouldn't have this flag.
1758       uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA(kFormat, inst_data));
1759       if ((kVerifyExtra == Instruction::kVerifyVarArgNonZero && v_a == 0) ||
1760           v_a > Instruction::kMaxVarArgRegs) {
1761         FailInvalidArgCount(inst, v_a);
1762         return false;
1763       }
1764 
1765       result = result && CheckVarArgRegs(inst, v_a);
1766       break;
1767     }
1768     case Instruction::kVerifyVarArgRangeNonZero:
1769       // Fall-through.
1770     case Instruction::kVerifyVarArgRange: {
1771       uint32_t v_a = inst->VRegA(kFormat, inst_data);
1772       if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero && v_a == 0) {
1773         FailInvalidArgCount(inst, v_a);
1774         return false;
1775       }
1776       result = result && CheckVarArgRangeRegs(v_a, inst->VRegC(kFormat));
1777       break;
1778     }
1779     case Instruction::kVerifyError:
1780       FailUnexpectedOpcode(inst);
1781       result = false;
1782       break;
1783     case Instruction::kVerifyNothing:
1784       break;
1785   }
1786   return result;
1787 }
1788 
1789 template <bool kVerifierDebug>
CheckNewInstance(dex::TypeIndex idx)1790 inline bool MethodVerifier<kVerifierDebug>::CheckNewInstance(dex::TypeIndex idx) {
1791   if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
1792     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
1793                                       << dex_file_->GetHeader().type_ids_size_ << ")";
1794     return false;
1795   }
1796   // We don't need the actual class, just a pointer to the class name.
1797   const std::string_view descriptor = dex_file_->GetTypeDescriptorView(idx);
1798   if (UNLIKELY(descriptor[0] != 'L')) {
1799     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'";
1800     return false;
1801   } else if (UNLIKELY(descriptor == "Ljava/lang/Class;")) {
1802     // An unlikely new instance on Class is not allowed. Fall back to interpreter to ensure an
1803     // exception is thrown when this statement is executed (compiled code would not do that).
1804     Fail(VERIFY_ERROR_INSTANTIATION);
1805   }
1806   return true;
1807 }
1808 
1809 template <bool kVerifierDebug>
CheckNewArray(dex::TypeIndex idx)1810 bool MethodVerifier<kVerifierDebug>::CheckNewArray(dex::TypeIndex idx) {
1811   if (UNLIKELY(idx.index_ >= dex_file_->GetHeader().type_ids_size_)) {
1812     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
1813                                       << dex_file_->GetHeader().type_ids_size_ << ")";
1814     return false;
1815   }
1816   int bracket_count = 0;
1817   const char* descriptor = dex_file_->GetTypeDescriptor(idx);
1818   const char* cp = descriptor;
1819   while (*cp++ == '[') {
1820     bracket_count++;
1821   }
1822   if (UNLIKELY(bracket_count == 0)) {
1823     /* The given class must be an array type. */
1824     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1825         << "can't new-array class '" << descriptor << "' (not an array)";
1826     return false;
1827   } else if (UNLIKELY(bracket_count > 255)) {
1828     /* It is illegal to create an array of more than 255 dimensions. */
1829     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
1830         << "can't new-array class '" << descriptor << "' (exceeds limit)";
1831     return false;
1832   }
1833   return true;
1834 }
1835 
1836 template <bool kVerifierDebug>
CheckArrayData(uint32_t cur_offset)1837 bool MethodVerifier<kVerifierDebug>::CheckArrayData(uint32_t cur_offset) {
1838   const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits();
1839   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
1840   const uint16_t* array_data;
1841   int32_t array_data_offset;
1842 
1843   DCHECK_LT(cur_offset, insn_count);
1844   /* make sure the start of the array data table is in range */
1845   array_data_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
1846   if (UNLIKELY(static_cast<int32_t>(cur_offset) + array_data_offset < 0 ||
1847                cur_offset + array_data_offset + 2 >= insn_count)) {
1848     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset
1849                                       << ", data offset " << array_data_offset
1850                                       << ", count " << insn_count;
1851     return false;
1852   }
1853   /* offset to array data table is a relative branch-style offset */
1854   array_data = insns + array_data_offset;
1855   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
1856   if (UNLIKELY(!IsAligned<4>(array_data))) {
1857     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset
1858                                       << ", data offset " << array_data_offset;
1859     return false;
1860   }
1861   // Make sure the array-data is marked as an opcode. This ensures that it was reached when
1862   // traversing the code item linearly. It is an approximation for a by-spec padding value.
1863   if (UNLIKELY(!GetInstructionFlags(cur_offset + array_data_offset).IsOpcode())) {
1864     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array data table at " << cur_offset
1865                                       << ", data offset " << array_data_offset
1866                                       << " not correctly visited, probably bad padding.";
1867     return false;
1868   }
1869 
1870   uint32_t value_width = array_data[1];
1871   uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]);
1872   uint32_t table_size = 4 + (value_width * value_count + 1) / 2;
1873   /* make sure the end of the switch is in range */
1874   if (UNLIKELY(cur_offset + array_data_offset + table_size > insn_count)) {
1875     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset
1876                                       << ", data offset " << array_data_offset << ", end "
1877                                       << cur_offset + array_data_offset + table_size
1878                                       << ", count " << insn_count;
1879     return false;
1880   }
1881   return true;
1882 }
1883 
1884 template <bool kVerifierDebug>
CheckBranchTarget(uint32_t cur_offset)1885 bool MethodVerifier<kVerifierDebug>::CheckBranchTarget(uint32_t cur_offset) {
1886   int32_t offset;
1887   bool isConditional, selfOkay;
1888   if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) {
1889     return false;
1890   }
1891   if (UNLIKELY(!selfOkay && offset == 0)) {
1892     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at"
1893                                       << reinterpret_cast<void*>(cur_offset);
1894     return false;
1895   }
1896   // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime
1897   // to have identical "wrap-around" behavior, but it's unwise to depend on that.
1898   if (UNLIKELY(((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset))) {
1899     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow "
1900                                       << reinterpret_cast<void*>(cur_offset) << " +" << offset;
1901     return false;
1902   }
1903   int32_t abs_offset = cur_offset + offset;
1904   if (UNLIKELY(abs_offset < 0 ||
1905                (uint32_t) abs_offset >= code_item_accessor_.InsnsSizeInCodeUnits()  ||
1906                !GetInstructionFlags(abs_offset).IsOpcode())) {
1907     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> "
1908                                       << reinterpret_cast<void*>(abs_offset) << ") at "
1909                                       << reinterpret_cast<void*>(cur_offset);
1910     return false;
1911   }
1912   GetModifiableInstructionFlags(abs_offset).SetBranchTarget();
1913   return true;
1914 }
1915 
1916 template <bool kVerifierDebug>
GetBranchOffset(uint32_t cur_offset,int32_t * pOffset,bool * pConditional,bool * selfOkay)1917 bool MethodVerifier<kVerifierDebug>::GetBranchOffset(uint32_t cur_offset,
1918                                                      int32_t* pOffset,
1919                                                      bool* pConditional,
1920                                                      bool* selfOkay) {
1921   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
1922   *pConditional = false;
1923   *selfOkay = false;
1924   switch (*insns & 0xff) {
1925     case Instruction::GOTO:
1926       *pOffset = ((int16_t) *insns) >> 8;
1927       break;
1928     case Instruction::GOTO_32:
1929       *pOffset = insns[1] | (((uint32_t) insns[2]) << 16);
1930       *selfOkay = true;
1931       break;
1932     case Instruction::GOTO_16:
1933       *pOffset = (int16_t) insns[1];
1934       break;
1935     case Instruction::IF_EQ:
1936     case Instruction::IF_NE:
1937     case Instruction::IF_LT:
1938     case Instruction::IF_GE:
1939     case Instruction::IF_GT:
1940     case Instruction::IF_LE:
1941     case Instruction::IF_EQZ:
1942     case Instruction::IF_NEZ:
1943     case Instruction::IF_LTZ:
1944     case Instruction::IF_GEZ:
1945     case Instruction::IF_GTZ:
1946     case Instruction::IF_LEZ:
1947       *pOffset = (int16_t) insns[1];
1948       *pConditional = true;
1949       break;
1950     default:
1951       return false;
1952   }
1953   return true;
1954 }
1955 
1956 template <bool kVerifierDebug>
CheckSwitchTargets(uint32_t cur_offset)1957 bool MethodVerifier<kVerifierDebug>::CheckSwitchTargets(uint32_t cur_offset) {
1958   const uint32_t insn_count = code_item_accessor_.InsnsSizeInCodeUnits();
1959   DCHECK_LT(cur_offset, insn_count);
1960   const uint16_t* insns = code_item_accessor_.Insns() + cur_offset;
1961   /* make sure the start of the switch is in range */
1962   int32_t switch_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
1963   if (UNLIKELY(static_cast<int32_t>(cur_offset) + switch_offset < 0 ||
1964                cur_offset + switch_offset + 2 > insn_count)) {
1965     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset
1966                                       << ", switch offset " << switch_offset
1967                                       << ", count " << insn_count;
1968     return false;
1969   }
1970   /* offset to switch table is a relative branch-style offset */
1971   const uint16_t* switch_insns = insns + switch_offset;
1972   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
1973   if (UNLIKELY(!IsAligned<4>(switch_insns))) {
1974     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset
1975                                       << ", switch offset " << switch_offset;
1976     return false;
1977   }
1978   // Make sure the switch data is marked as an opcode. This ensures that it was reached when
1979   // traversing the code item linearly. It is an approximation for a by-spec padding value.
1980   if (UNLIKELY(!GetInstructionFlags(cur_offset + switch_offset).IsOpcode())) {
1981     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "switch table at " << cur_offset
1982                                       << ", switch offset " << switch_offset
1983                                       << " not correctly visited, probably bad padding.";
1984     return false;
1985   }
1986 
1987   bool is_packed_switch = (*insns & 0xff) == Instruction::PACKED_SWITCH;
1988 
1989   uint32_t switch_count = switch_insns[1];
1990   int32_t targets_offset;
1991   uint16_t expected_signature;
1992   if (is_packed_switch) {
1993     /* 0=sig, 1=count, 2/3=firstKey */
1994     targets_offset = 4;
1995     expected_signature = Instruction::kPackedSwitchSignature;
1996   } else {
1997     /* 0=sig, 1=count, 2..count*2 = keys */
1998     targets_offset = 2 + 2 * switch_count;
1999     expected_signature = Instruction::kSparseSwitchSignature;
2000   }
2001   uint32_t table_size = targets_offset + switch_count * 2;
2002   if (UNLIKELY(switch_insns[0] != expected_signature)) {
2003     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
2004         << StringPrintf("wrong signature for switch table (%x, wanted %x)",
2005                         switch_insns[0], expected_signature);
2006     return false;
2007   }
2008   /* make sure the end of the switch is in range */
2009   if (UNLIKELY(cur_offset + switch_offset + table_size > (uint32_t) insn_count)) {
2010     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset
2011                                       << ", switch offset " << switch_offset
2012                                       << ", end " << (cur_offset + switch_offset + table_size)
2013                                       << ", count " << insn_count;
2014     return false;
2015   }
2016 
2017   constexpr int32_t keys_offset = 2;
2018   if (switch_count > 1) {
2019     if (is_packed_switch) {
2020       /* for a packed switch, verify that keys do not overflow int32 */
2021       int32_t first_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
2022       int32_t max_first_key =
2023           std::numeric_limits<int32_t>::max() - (static_cast<int32_t>(switch_count) - 1);
2024       if (UNLIKELY(first_key > max_first_key)) {
2025         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: first_key=" << first_key
2026                                           << ", switch_count=" << switch_count;
2027         return false;
2028       }
2029     } else {
2030       /* for a sparse switch, verify the keys are in ascending order */
2031       int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
2032       for (uint32_t targ = 1; targ < switch_count; targ++) {
2033         int32_t key =
2034             static_cast<int32_t>(switch_insns[keys_offset + targ * 2]) |
2035             static_cast<int32_t>(switch_insns[keys_offset + targ * 2 + 1] << 16);
2036         if (UNLIKELY(key <= last_key)) {
2037           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid sparse switch: last key=" << last_key
2038                                             << ", this=" << key;
2039           return false;
2040         }
2041         last_key = key;
2042       }
2043     }
2044   }
2045   /* verify each switch target */
2046   for (uint32_t targ = 0; targ < switch_count; targ++) {
2047     int32_t offset = static_cast<int32_t>(switch_insns[targets_offset + targ * 2]) |
2048                      static_cast<int32_t>(switch_insns[targets_offset + targ * 2 + 1] << 16);
2049     int32_t abs_offset = cur_offset + offset;
2050     if (UNLIKELY(abs_offset < 0 ||
2051                  abs_offset >= static_cast<int32_t>(insn_count) ||
2052                  !GetInstructionFlags(abs_offset).IsOpcode())) {
2053       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset
2054                                         << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at "
2055                                         << reinterpret_cast<void*>(cur_offset)
2056                                         << "[" << targ << "]";
2057       return false;
2058     }
2059     GetModifiableInstructionFlags(abs_offset).SetBranchTarget();
2060   }
2061   return true;
2062 }
2063 
2064 template <bool kVerifierDebug>
VerifyCodeFlow()2065 bool MethodVerifier<kVerifierDebug>::VerifyCodeFlow() {
2066   const uint16_t registers_size = code_item_accessor_.RegistersSize();
2067 
2068   /* Create and initialize table holding register status */
2069   reg_table_.Init(insn_flags_.get(),
2070                   code_item_accessor_.InsnsSizeInCodeUnits(),
2071                   registers_size,
2072                   allocator_,
2073                   GetRegTypeCache(),
2074                   interesting_dex_pc_);
2075 
2076   work_line_.reset(RegisterLine::Create(registers_size, allocator_, GetRegTypeCache()));
2077   saved_line_.reset(RegisterLine::Create(registers_size, allocator_, GetRegTypeCache()));
2078 
2079   /* Initialize register types of method arguments. */
2080   if (!SetTypesFromSignature()) {
2081     DCHECK_NE(failures_.size(), 0U);
2082     std::string prepend("Bad signature in ");
2083     prepend += dex_file_->PrettyMethod(dex_method_idx_);
2084     PrependToLastFailMessage(prepend);
2085     return false;
2086   }
2087   // We may have a runtime failure here, clear.
2088   flags_.have_pending_runtime_throw_failure_ = false;
2089 
2090   /* Perform code flow verification. */
2091   bool res = LIKELY(monitor_enter_dex_pcs_ == nullptr)
2092                  ? CodeFlowVerifyMethod</*kMonitorDexPCs=*/ false>()
2093                  : CodeFlowVerifyMethod</*kMonitorDexPCs=*/ true>();
2094   if (UNLIKELY(!res)) {
2095     DCHECK_NE(failures_.size(), 0U);
2096     return false;
2097   }
2098   return true;
2099 }
2100 
2101 template <bool kVerifierDebug>
Dump(VariableIndentationOutputStream * vios)2102 void MethodVerifier<kVerifierDebug>::Dump(VariableIndentationOutputStream* vios) {
2103   if (!code_item_accessor_.HasCodeItem()) {
2104     vios->Stream() << "Native method\n";
2105     return;
2106   }
2107   {
2108     vios->Stream() << "Register Types:\n";
2109     ScopedIndentation indent1(vios);
2110     reg_types_.Dump(vios->Stream());
2111   }
2112   vios->Stream() << "Dumping instructions and register lines:\n";
2113   ScopedIndentation indent1(vios);
2114 
2115   for (const DexInstructionPcPair& inst : code_item_accessor_) {
2116     const size_t dex_pc = inst.DexPc();
2117 
2118     // Might be asked to dump before the table is initialized.
2119     if (reg_table_.IsInitialized()) {
2120       RegisterLine* reg_line = reg_table_.GetLine(dex_pc);
2121       if (reg_line != nullptr) {
2122         vios->Stream() << reg_line->Dump(this) << "\n";
2123       }
2124     }
2125 
2126     vios->Stream()
2127         << StringPrintf("0x%04zx", dex_pc) << ": " << GetInstructionFlags(dex_pc).ToString() << " ";
2128     const bool kDumpHexOfInstruction = false;
2129     if (kDumpHexOfInstruction) {
2130       vios->Stream() << inst->DumpHex(5) << " ";
2131     }
2132     vios->Stream() << inst->DumpString(dex_file_) << "\n";
2133   }
2134 }
2135 
2136 template <bool kVerifierDebug>
SetTypesFromSignature()2137 bool MethodVerifier<kVerifierDebug>::SetTypesFromSignature() {
2138   RegisterLine* reg_line = reg_table_.GetLine(0);
2139 
2140   // Should have been verified earlier.
2141   DCHECK_GE(code_item_accessor_.RegistersSize(), code_item_accessor_.InsSize());
2142 
2143   uint32_t arg_start = code_item_accessor_.RegistersSize() - code_item_accessor_.InsSize();
2144   size_t expected_args = code_item_accessor_.InsSize();   /* long/double count as two */
2145 
2146   // Include the "this" pointer.
2147   size_t cur_arg = 0;
2148   if (!IsStatic()) {
2149     if (expected_args == 0) {
2150       // Expect at least a receiver.
2151       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected 0 args, but method is not static";
2152       return false;
2153     }
2154 
2155     // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
2156     // argument as uninitialized. This restricts field access until the superclass constructor is
2157     // called.
2158     const RegType& declaring_class = GetDeclaringClass();
2159     if (IsConstructor()) {
2160       if (declaring_class.IsJavaLangObject()) {
2161         // "this" is implicitly initialized.
2162         reg_line->SetThisInitialized();
2163         reg_line->SetRegisterType<LockOp::kClear>(arg_start + cur_arg, declaring_class);
2164       } else {
2165         reg_line->SetRegisterType<LockOp::kClear>(
2166             arg_start + cur_arg,
2167             reg_types_.UninitializedThisArgument(declaring_class));
2168       }
2169     } else {
2170       reg_line->SetRegisterType<LockOp::kClear>(arg_start + cur_arg, declaring_class);
2171     }
2172     cur_arg++;
2173   }
2174 
2175   const dex::ProtoId& proto_id =
2176       dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
2177   DexFileParameterIterator iterator(*dex_file_, proto_id);
2178 
2179   for (; iterator.HasNext(); iterator.Next()) {
2180     const char* descriptor = iterator.GetDescriptor();
2181     if (descriptor == nullptr) {
2182       LOG(FATAL) << "Null descriptor";
2183     }
2184     if (cur_arg >= expected_args) {
2185       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
2186                                         << " args, found more (" << descriptor << ")";
2187       return false;
2188     }
2189     switch (descriptor[0]) {
2190       case 'L':
2191       case '[':
2192         // We assume that reference arguments are initialized. The only way it could be otherwise
2193         // (assuming the caller was verified) is if the current method is <init>, but in that case
2194         // it's effectively considered initialized the instant we reach here (in the sense that we
2195         // can return without doing anything or call virtual methods).
2196         {
2197           // Note: don't check access. No error would be thrown for declaring or passing an
2198           //       inaccessible class. Only actual accesses to fields or methods will.
2199           const RegType& reg_type = ResolveClass<CheckAccess::kNo>(iterator.GetTypeIdx());
2200           if (!reg_type.IsNonZeroReferenceTypes()) {
2201             DCHECK(HasFailures());
2202             return false;
2203           }
2204           reg_line->SetRegisterType<LockOp::kClear>(arg_start + cur_arg, reg_type);
2205         }
2206         break;
2207       case 'Z':
2208         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kBoolean);
2209         break;
2210       case 'C':
2211         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kChar);
2212         break;
2213       case 'B':
2214         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kByte);
2215         break;
2216       case 'I':
2217         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kInteger);
2218         break;
2219       case 'S':
2220         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kShort);
2221         break;
2222       case 'F':
2223         reg_line->SetRegisterType(arg_start + cur_arg, RegType::Kind::kFloat);
2224         break;
2225       case 'J':
2226       case 'D': {
2227         if (cur_arg + 1 >= expected_args) {
2228           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
2229               << " args, found more (" << descriptor << ")";
2230           return false;
2231         }
2232 
2233         const RegType* lo_half;
2234         const RegType* hi_half;
2235         if (descriptor[0] == 'J') {
2236           lo_half = &reg_types_.LongLo();
2237           hi_half = &reg_types_.LongHi();
2238         } else {
2239           lo_half = &reg_types_.DoubleLo();
2240           hi_half = &reg_types_.DoubleHi();
2241         }
2242         reg_line->SetRegisterTypeWide(arg_start + cur_arg, *lo_half, *hi_half);
2243         cur_arg++;
2244         break;
2245       }
2246       default:
2247         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '"
2248                                           << descriptor << "'";
2249         return false;
2250     }
2251     cur_arg++;
2252   }
2253   if (cur_arg != expected_args) {
2254     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
2255                                       << " arguments, found " << cur_arg;
2256     return false;
2257   }
2258   // Dex file verifier ensures that all valid type indexes reference valid descriptors.
2259   DCHECK(IsValidDescriptor(dex_file_->GetReturnTypeDescriptor(proto_id)));
2260   return true;
2261 }
2262 
2263 COLD_ATTR
HandleMonitorDexPcsWorkLine(std::vector<::art::verifier::MethodVerifier::DexLockInfo> * monitor_enter_dex_pcs,RegisterLine * work_line)2264 void HandleMonitorDexPcsWorkLine(
2265     std::vector<::art::verifier::MethodVerifier::DexLockInfo>* monitor_enter_dex_pcs,
2266     RegisterLine* work_line) {
2267   monitor_enter_dex_pcs->clear();  // The new work line is more accurate than the previous one.
2268 
2269   std::map<uint32_t, ::art::verifier::MethodVerifier::DexLockInfo> depth_to_lock_info;
2270   auto collector = [&](uint32_t dex_reg, uint32_t depth) {
2271     auto insert_pair = depth_to_lock_info.emplace(
2272         depth, ::art::verifier::MethodVerifier::DexLockInfo(depth));
2273     auto it = insert_pair.first;
2274     auto set_insert_pair = it->second.dex_registers.insert(dex_reg);
2275     DCHECK(set_insert_pair.second);
2276   };
2277   work_line->IterateRegToLockDepths(collector);
2278   for (auto& pair : depth_to_lock_info) {
2279     monitor_enter_dex_pcs->push_back(pair.second);
2280     // Map depth to dex PC.
2281     monitor_enter_dex_pcs->back().dex_pc = work_line->GetMonitorEnterDexPc(pair.second.dex_pc);
2282   }
2283 }
2284 
2285 template <bool kVerifierDebug>
2286 template <bool kMonitorDexPCs>
CodeFlowVerifyMethod()2287 bool MethodVerifier<kVerifierDebug>::CodeFlowVerifyMethod() {
2288   const uint16_t* insns = code_item_accessor_.Insns();
2289   const uint32_t insns_size = code_item_accessor_.InsnsSizeInCodeUnits();
2290 
2291   /* Begin by marking the first instruction as "changed". */
2292   GetModifiableInstructionFlags(0).SetChanged();
2293   uint32_t start_guess = 0;
2294 
2295   /* Continue until no instructions are marked "changed". */
2296   while (true) {
2297     if (allow_thread_suspension_) {
2298       self_->AllowThreadSuspension();
2299     }
2300     // Find the first marked one. Use "start_guess" as a way to find one quickly.
2301     uint32_t insn_idx = start_guess;
2302     for (; insn_idx < insns_size; insn_idx++) {
2303       if (GetInstructionFlags(insn_idx).IsChanged())
2304         break;
2305     }
2306     if (insn_idx == insns_size) {
2307       if (start_guess != 0) {
2308         /* try again, starting from the top */
2309         start_guess = 0;
2310         continue;
2311       } else {
2312         /* all flags are clear */
2313         break;
2314       }
2315     }
2316     // We carry the working set of registers from instruction to instruction. If this address can
2317     // be the target of a branch (or throw) instruction, or if we're skipping around chasing
2318     // "changed" flags, we need to load the set of registers from the table.
2319     // Because we always prefer to continue on to the next instruction, we should never have a
2320     // situation where we have a stray "changed" flag set on an instruction that isn't a branch
2321     // target.
2322     work_insn_idx_ = insn_idx;
2323     if (GetInstructionFlags(insn_idx).IsBranchTarget()) {
2324       work_line_->CopyFromLine(reg_table_.GetLine(insn_idx));
2325     } else if (kIsDebugBuild) {
2326       /*
2327        * Consistency check: retrieve the stored register line (assuming
2328        * a full table) and make sure it actually matches.
2329        */
2330       RegisterLine* register_line = reg_table_.GetLine(insn_idx);
2331       if (register_line != nullptr) {
2332         if (work_line_->CompareLine(register_line) != 0) {
2333           Dump(LOG_STREAM(FATAL_WITHOUT_ABORT));
2334           LOG(FATAL_WITHOUT_ABORT) << InfoMessages().str();
2335           LOG(FATAL) << "work_line diverged in " << dex_file_->PrettyMethod(dex_method_idx_)
2336                      << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n"
2337                      << " work_line=" << work_line_->Dump(this) << "\n"
2338                      << "  expected=" << register_line->Dump(this);
2339         }
2340       }
2341     }
2342 
2343     // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about.
2344     // We want the state _before_ the instruction, for the case where the dex pc we're
2345     // interested in is itself a monitor-enter instruction (which is a likely place
2346     // for a thread to be suspended).
2347     if (kMonitorDexPCs && UNLIKELY(work_insn_idx_ == interesting_dex_pc_)) {
2348       HandleMonitorDexPcsWorkLine(monitor_enter_dex_pcs_, work_line_.get());
2349     }
2350 
2351     if (!CodeFlowVerifyInstruction(&start_guess)) {
2352       std::string prepend(dex_file_->PrettyMethod(dex_method_idx_));
2353       prepend += " failed to verify: ";
2354       PrependToLastFailMessage(prepend);
2355       return false;
2356     }
2357     /* Clear "changed" and mark as visited. */
2358     GetModifiableInstructionFlags(insn_idx).SetVisited();
2359     GetModifiableInstructionFlags(insn_idx).ClearChanged();
2360   }
2361 
2362   if (kVerifierDebug) {
2363     /*
2364      * Scan for dead code. There's nothing "evil" about dead code
2365      * (besides the wasted space), but it indicates a flaw somewhere
2366      * down the line, possibly in the verifier.
2367      *
2368      * If we've substituted "always throw" instructions into the stream,
2369      * we are almost certainly going to have some dead code.
2370      */
2371     int dead_start = -1;
2372 
2373     for (const DexInstructionPcPair& inst : code_item_accessor_) {
2374       const uint32_t insn_idx = inst.DexPc();
2375       /*
2376        * Switch-statement data doesn't get "visited" by scanner. It
2377        * may or may not be preceded by a padding NOP (for alignment).
2378        */
2379       if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
2380           insns[insn_idx] == Instruction::kSparseSwitchSignature ||
2381           insns[insn_idx] == Instruction::kArrayDataSignature ||
2382           (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) &&
2383            (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
2384             insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
2385             insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
2386         GetModifiableInstructionFlags(insn_idx).SetVisited();
2387       }
2388 
2389       if (!GetInstructionFlags(insn_idx).IsVisited()) {
2390         if (dead_start < 0) {
2391           dead_start = insn_idx;
2392         }
2393       } else if (dead_start >= 0) {
2394         LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
2395                         << "-" << reinterpret_cast<void*>(insn_idx - 1);
2396         dead_start = -1;
2397       }
2398     }
2399     if (dead_start >= 0) {
2400       LogVerifyInfo()
2401           << "dead code " << reinterpret_cast<void*>(dead_start)
2402           << "-" << reinterpret_cast<void*>(code_item_accessor_.InsnsSizeInCodeUnits() - 1);
2403     }
2404     // To dump the state of the verify after a method, do something like:
2405     // if (dex_file_->PrettyMethod(dex_method_idx_) ==
2406     //     "boolean java.lang.String.equals(java.lang.Object)") {
2407     //   LOG(INFO) << InfoMessages().str();
2408     // }
2409   }
2410   return true;
2411 }
2412 
2413 // Setup a register line for the given return instruction.
2414 template <bool kVerifierDebug>
AdjustReturnLine(MethodVerifier<kVerifierDebug> * verifier,const Instruction * ret_inst,RegisterLine * line)2415 static void AdjustReturnLine(MethodVerifier<kVerifierDebug>* verifier,
2416                              const Instruction* ret_inst,
2417                              RegisterLine* line) {
2418   Instruction::Code opcode = ret_inst->Opcode();
2419 
2420   switch (opcode) {
2421     case Instruction::RETURN_VOID:
2422       if (verifier->IsInstanceConstructor()) {
2423         // Before we mark all regs as conflicts, check that we don't have an uninitialized this.
2424         line->CheckConstructorReturn(verifier);
2425       }
2426       line->MarkAllRegistersAsConflicts(verifier);
2427       break;
2428 
2429     case Instruction::RETURN:
2430     case Instruction::RETURN_OBJECT:
2431       line->MarkAllRegistersAsConflictsExcept(verifier, ret_inst->VRegA_11x());
2432       break;
2433 
2434     case Instruction::RETURN_WIDE:
2435       line->MarkAllRegistersAsConflictsExceptWide(verifier, ret_inst->VRegA_11x());
2436       break;
2437 
2438     default:
2439       LOG(FATAL) << "Unknown return opcode " << opcode;
2440       UNREACHABLE();
2441   }
2442 }
2443 
2444 template <bool kVerifierDebug>
CodeFlowVerifyInstruction(uint32_t * start_guess)2445 bool MethodVerifier<kVerifierDebug>::CodeFlowVerifyInstruction(uint32_t* start_guess) {
2446   /*
2447    * Once we finish decoding the instruction, we need to figure out where
2448    * we can go from here. There are three possible ways to transfer
2449    * control to another statement:
2450    *
2451    * (1) Continue to the next instruction. Applies to all but
2452    *     unconditional branches, method returns, and exception throws.
2453    * (2) Branch to one or more possible locations. Applies to branches
2454    *     and switch statements.
2455    * (3) Exception handlers. Applies to any instruction that can
2456    *     throw an exception that is handled by an encompassing "try"
2457    *     block.
2458    *
2459    * We can also return, in which case there is no successor instruction
2460    * from this point.
2461    *
2462    * The behavior can be determined from the opcode flags.
2463    */
2464   const uint16_t* insns = code_item_accessor_.Insns() + work_insn_idx_;
2465   const Instruction* inst = Instruction::At(insns);
2466   int opcode_flags = Instruction::FlagsOf(inst->Opcode());
2467 
2468   int32_t branch_target = 0;
2469   bool just_set_result = false;
2470   if (kVerifierDebug) {
2471     // Generate processing back trace to debug verifier
2472     LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << std::endl
2473                     << work_line_->Dump(this);
2474   }
2475 
2476   /*
2477    * Make a copy of the previous register state. If the instruction
2478    * can throw an exception, we will copy/merge this into the "catch"
2479    * address rather than work_line, because we don't want the result
2480    * from the "successful" code path (e.g. a check-cast that "improves"
2481    * a type) to be visible to the exception handler.
2482    */
2483   if (((opcode_flags & Instruction::kThrow) != 0 || IsCompatThrow(inst->Opcode())) &&
2484       CurrentInsnFlags()->IsInTry()) {
2485     saved_line_->CopyFromLine(work_line_.get());
2486   } else if (kIsDebugBuild) {
2487     saved_line_->FillWithGarbage();
2488   }
2489   // Per-instruction flag, should not be set here.
2490   DCHECK(!flags_.have_pending_runtime_throw_failure_);
2491   bool exc_handler_unreachable = false;
2492 
2493 
2494   // We need to ensure the work line is consistent while performing validation. When we spot a
2495   // peephole pattern we compute a new line for either the fallthrough instruction or the
2496   // branch target.
2497   RegisterLineArenaUniquePtr branch_line;
2498   RegisterLineArenaUniquePtr fallthrough_line;
2499 
2500   using enum RegType::Kind;
2501   switch (inst->Opcode()) {
2502     case Instruction::NOP:
2503       /*
2504        * A "pure" NOP has no effect on anything. Data tables start with
2505        * a signature that looks like a NOP; if we see one of these in
2506        * the course of executing code then we have a problem.
2507        */
2508       if (inst->VRegA_10x() != 0) {
2509         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream";
2510       }
2511       break;
2512 
2513     case Instruction::MOVE:
2514       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr);
2515       break;
2516     case Instruction::MOVE_FROM16:
2517       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr);
2518       break;
2519     case Instruction::MOVE_16:
2520       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr);
2521       break;
2522     case Instruction::MOVE_WIDE:
2523       work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x());
2524       break;
2525     case Instruction::MOVE_WIDE_FROM16:
2526       work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x());
2527       break;
2528     case Instruction::MOVE_WIDE_16:
2529       work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x());
2530       break;
2531     case Instruction::MOVE_OBJECT:
2532       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef);
2533       break;
2534     case Instruction::MOVE_OBJECT_FROM16:
2535       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef);
2536       break;
2537     case Instruction::MOVE_OBJECT_16:
2538       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef);
2539       break;
2540 
2541     /*
2542      * The move-result instructions copy data out of a "pseudo-register"
2543      * with the results from the last method invocation. In practice we
2544      * might want to hold the result in an actual CPU register, so the
2545      * Dalvik spec requires that these only appear immediately after an
2546      * invoke or filled-new-array.
2547      *
2548      * These calls invalidate the "result" register. (This is now
2549      * redundant with the reset done below, but it can make the debug info
2550      * easier to read in some cases.)
2551      */
2552     case Instruction::MOVE_RESULT:
2553       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false);
2554       break;
2555     case Instruction::MOVE_RESULT_WIDE:
2556       work_line_->CopyResultRegister2(this, inst->VRegA_11x());
2557       break;
2558     case Instruction::MOVE_RESULT_OBJECT:
2559       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true);
2560       break;
2561 
2562     case Instruction::MOVE_EXCEPTION:
2563       if (!HandleMoveException(inst)) {
2564         exc_handler_unreachable = true;
2565       }
2566       break;
2567 
2568     case Instruction::RETURN_VOID:
2569       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
2570         if (!GetMethodReturnType().IsConflict()) {
2571           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
2572         }
2573       }
2574       break;
2575     case Instruction::RETURN:
2576       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
2577         /* check the method signature */
2578         const RegType& return_type = GetMethodReturnType();
2579         if (!return_type.IsCategory1Types()) {
2580           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
2581                                             << return_type;
2582         } else {
2583           // Compilers may generate synthetic functions that write byte values into boolean fields.
2584           // Also, it may use integer values for boolean, byte, short, and character return types.
2585           const uint32_t vregA = inst->VRegA_11x();
2586           const RegType& src_type = work_line_->GetRegisterType(this, vregA);
2587           bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
2588                           ((return_type.IsBoolean() || return_type.IsByte() ||
2589                            return_type.IsShort() || return_type.IsChar()) &&
2590                            src_type.IsInteger()));
2591           /* check the register contents */
2592           bool success = VerifyRegisterType(vregA, use_src ? src_type : return_type);
2593           if (!success) {
2594             AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA));
2595           }
2596         }
2597       }
2598       break;
2599     case Instruction::RETURN_WIDE:
2600       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
2601         /* check the method signature */
2602         const RegType& return_type = GetMethodReturnType();
2603         if (!return_type.IsCategory2Types()) {
2604           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
2605         } else {
2606           /* check the register contents */
2607           const uint32_t vregA = inst->VRegA_11x();
2608           bool success = VerifyRegisterTypeWide(vregA, return_type.GetKind());
2609           if (!success) {
2610             AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA));
2611           }
2612         }
2613       }
2614       break;
2615     case Instruction::RETURN_OBJECT:
2616       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
2617         const RegType& return_type = GetMethodReturnType();
2618         if (!return_type.IsReferenceTypes()) {
2619           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
2620         } else {
2621           /* return_type is the *expected* return type, not register value */
2622           DCHECK(!return_type.IsZeroOrNull());
2623           DCHECK(!return_type.IsUninitializedReference());
2624           const uint32_t vregA = inst->VRegA_11x();
2625           const RegType& reg_type = work_line_->GetRegisterType(this, vregA);
2626           // Disallow returning undefined, conflict & uninitialized values and verify that the
2627           // reference in vAA is an instance of the "return_type."
2628           if (reg_type.IsUndefined()) {
2629             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning undefined register";
2630           } else if (reg_type.IsConflict()) {
2631             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning register with conflict";
2632           } else if (reg_type.IsUninitializedTypes()) {
2633             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning uninitialized object '"
2634                                               << reg_type << "'";
2635           } else if (!reg_type.IsReferenceTypes()) {
2636             // We really do expect a reference here.
2637             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object returns a non-reference type "
2638                                               << reg_type;
2639           } else if (!IsAssignableFrom(return_type, reg_type)) {
2640             if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) {
2641               Fail(VERIFY_ERROR_UNRESOLVED_TYPE_CHECK)
2642                   << " can't resolve returned type '" << return_type << "' or '" << reg_type << "'";
2643             } else {
2644               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
2645                   << "', but expected from declaration '" << return_type << "'";
2646             }
2647           }
2648         }
2649       }
2650       break;
2651 
2652       /* could be boolean, int, float, or a null reference */
2653     case Instruction::CONST_4: {
2654       int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
2655       work_line_->SetRegisterType(inst->VRegA_11n(), DetermineCat1Constant(val));
2656       break;
2657     }
2658     case Instruction::CONST_16: {
2659       int16_t val = static_cast<int16_t>(inst->VRegB_21s());
2660       work_line_->SetRegisterType(inst->VRegA_21s(), DetermineCat1Constant(val));
2661       break;
2662     }
2663     case Instruction::CONST: {
2664       int32_t val = inst->VRegB_31i();
2665       work_line_->SetRegisterType(inst->VRegA_31i(), DetermineCat1Constant(val));
2666       break;
2667     }
2668     case Instruction::CONST_HIGH16: {
2669       int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
2670       work_line_->SetRegisterType(inst->VRegA_21h(), DetermineCat1Constant(val));
2671       break;
2672     }
2673       /* could be long or double; resolved upon use */
2674     case Instruction::CONST_WIDE_16: {
2675       int64_t val = static_cast<int16_t>(inst->VRegB_21s());
2676       const RegType& lo = reg_types_.ConstantLo();
2677       const RegType& hi = reg_types_.ConstantHi();
2678       work_line_->SetRegisterTypeWide(inst->VRegA_21s(), lo, hi);
2679       break;
2680     }
2681     case Instruction::CONST_WIDE_32: {
2682       int64_t val = static_cast<int32_t>(inst->VRegB_31i());
2683       const RegType& lo = reg_types_.ConstantLo();
2684       const RegType& hi = reg_types_.ConstantHi();
2685       work_line_->SetRegisterTypeWide(inst->VRegA_31i(), lo, hi);
2686       break;
2687     }
2688     case Instruction::CONST_WIDE: {
2689       int64_t val = inst->VRegB_51l();
2690       const RegType& lo = reg_types_.ConstantLo();
2691       const RegType& hi = reg_types_.ConstantHi();
2692       work_line_->SetRegisterTypeWide(inst->VRegA_51l(), lo, hi);
2693       break;
2694     }
2695     case Instruction::CONST_WIDE_HIGH16: {
2696       int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
2697       const RegType& lo = reg_types_.ConstantLo();
2698       const RegType& hi = reg_types_.ConstantHi();
2699       work_line_->SetRegisterTypeWide(inst->VRegA_21h(), lo, hi);
2700       break;
2701     }
2702     case Instruction::CONST_STRING:
2703       work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_21c(), reg_types_.JavaLangString());
2704       break;
2705     case Instruction::CONST_STRING_JUMBO:
2706       work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_31c(), reg_types_.JavaLangString());
2707       break;
2708     case Instruction::CONST_CLASS: {
2709       // Get type from instruction if unresolved then we need an access check
2710       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
2711       const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c()));
2712       // Register holds class, ie its type is class, on error it will hold Conflict.
2713       work_line_->SetRegisterType<LockOp::kClear>(
2714           inst->VRegA_21c(),
2715           res_type.IsConflict() ? res_type : reg_types_.JavaLangClass());
2716       break;
2717     }
2718     case Instruction::CONST_METHOD_HANDLE:
2719       work_line_->SetRegisterType<LockOp::kClear>(
2720           inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodHandle());
2721       break;
2722     case Instruction::CONST_METHOD_TYPE:
2723       work_line_->SetRegisterType<LockOp::kClear>(
2724           inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodType());
2725       break;
2726     case Instruction::MONITOR_ENTER:
2727       work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_);
2728       // Check whether the previous instruction is a move-object with vAA as a source, creating
2729       // untracked lock aliasing.
2730       if (0 != work_insn_idx_ && !GetInstructionFlags(work_insn_idx_).IsBranchTarget()) {
2731         uint32_t prev_idx = work_insn_idx_ - 1;
2732         while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) {
2733           prev_idx--;
2734         }
2735         const Instruction& prev_inst = code_item_accessor_.InstructionAt(prev_idx);
2736         switch (prev_inst.Opcode()) {
2737           case Instruction::MOVE_OBJECT:
2738           case Instruction::MOVE_OBJECT_16:
2739           case Instruction::MOVE_OBJECT_FROM16:
2740             if (prev_inst.VRegB() == inst->VRegA_11x()) {
2741               // Redo the copy. This won't change the register types, but update the lock status
2742               // for the aliased register.
2743               work_line_->CopyRegister1(this,
2744                                         prev_inst.VRegA(),
2745                                         prev_inst.VRegB(),
2746                                         kTypeCategoryRef);
2747             }
2748             break;
2749 
2750           // Catch a case of register aliasing when two registers are linked to the same
2751           // java.lang.Class object via two consequent const-class instructions immediately
2752           // preceding monitor-enter called on one of those registers.
2753           case Instruction::CONST_CLASS: {
2754             // Get the second previous instruction.
2755             if (prev_idx == 0 || GetInstructionFlags(prev_idx).IsBranchTarget()) {
2756               break;
2757             }
2758             prev_idx--;
2759             while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) {
2760               prev_idx--;
2761             }
2762             const Instruction& prev2_inst = code_item_accessor_.InstructionAt(prev_idx);
2763 
2764             // Match the pattern "const-class; const-class; monitor-enter;"
2765             if (prev2_inst.Opcode() != Instruction::CONST_CLASS) {
2766               break;
2767             }
2768 
2769             // Ensure both const-classes are called for the same type_idx.
2770             if (prev_inst.VRegB_21c() != prev2_inst.VRegB_21c()) {
2771               break;
2772             }
2773 
2774             // Update the lock status for the aliased register.
2775             if (prev_inst.VRegA() == inst->VRegA_11x()) {
2776               work_line_->CopyRegister1(this,
2777                                         prev2_inst.VRegA(),
2778                                         inst->VRegA_11x(),
2779                                         kTypeCategoryRef);
2780             } else if (prev2_inst.VRegA() == inst->VRegA_11x()) {
2781               work_line_->CopyRegister1(this,
2782                                         prev_inst.VRegA(),
2783                                         inst->VRegA_11x(),
2784                                         kTypeCategoryRef);
2785             }
2786             break;
2787           }
2788 
2789           default:  // Other instruction types ignored.
2790             break;
2791         }
2792       }
2793       break;
2794     case Instruction::MONITOR_EXIT:
2795       /*
2796        * monitor-exit instructions are odd. They can throw exceptions,
2797        * but when they do they act as if they succeeded and the PC is
2798        * pointing to the following instruction. (This behavior goes back
2799        * to the need to handle asynchronous exceptions, a now-deprecated
2800        * feature that Dalvik doesn't support.)
2801        *
2802        * In practice we don't need to worry about this. The only
2803        * exceptions that can be thrown from monitor-exit are for a
2804        * null reference and -exit without a matching -enter. If the
2805        * structured locking checks are working, the former would have
2806        * failed on the -enter instruction, and the latter is impossible.
2807        *
2808        * This is fortunate, because issue 3221411 prevents us from
2809        * chasing the "can throw" path when monitor verification is
2810        * enabled. If we can fully verify the locking we can ignore
2811        * some catch blocks (which will show up as "dead" code when
2812        * we skip them here); if we can't, then the code path could be
2813        * "live" so we still need to check it.
2814        */
2815       opcode_flags &= ~Instruction::kThrow;
2816       work_line_->PopMonitor(this, inst->VRegA_11x());
2817       break;
2818     case Instruction::CHECK_CAST:
2819     case Instruction::INSTANCE_OF: {
2820       /*
2821        * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This
2822        * could be a "upcast" -- not expected, so we don't try to address it.)
2823        *
2824        * If it fails, an exception is thrown, which we deal with later by ignoring the update to
2825        * dec_insn.vA when branching to a handler.
2826        */
2827       const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
2828       const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c());
2829       const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx);
2830       if (res_type.IsConflict()) {
2831         // If this is a primitive type, fail HARD.
2832         ObjPtr<mirror::Class> klass = GetClassLinker()->LookupResolvedType(
2833             type_idx, dex_cache_.Get(), class_loader_.Get());
2834         if (klass != nullptr && klass->IsPrimitive()) {
2835           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type "
2836               << dex_file_->GetTypeDescriptorView(type_idx) << " in instanceof in "
2837               << GetDeclaringClass();
2838           break;
2839         }
2840 
2841         DCHECK_NE(failures_.size(), 0U);
2842         if (!is_checkcast) {
2843           work_line_->SetRegisterType(inst->VRegA_22c(), kBoolean);
2844         }
2845         break;  // bad class
2846       }
2847       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
2848       uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
2849       const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg);
2850       if (!res_type.IsNonZeroReferenceTypes()) {
2851         if (is_checkcast) {
2852           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
2853         } else {
2854           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type;
2855         }
2856       } else if (!orig_type.IsReferenceTypes()) {
2857         if (is_checkcast) {
2858           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg;
2859         } else {
2860           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg;
2861         }
2862       } else if (orig_type.IsUninitializedTypes()) {
2863         if (is_checkcast) {
2864           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on uninitialized reference in v"
2865                                             << orig_type_reg;
2866         } else {
2867           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on uninitialized reference in v"
2868                                             << orig_type_reg;
2869         }
2870       } else {
2871         if (is_checkcast) {
2872           work_line_->SetRegisterType<LockOp::kKeep>(inst->VRegA_21c(), res_type);
2873         } else {
2874           work_line_->SetRegisterType(inst->VRegA_22c(), kBoolean);
2875         }
2876       }
2877       break;
2878     }
2879     case Instruction::ARRAY_LENGTH: {
2880       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x());
2881       if (res_type.IsReferenceTypes()) {
2882         if (!res_type.IsArrayTypes() && !res_type.IsZeroOrNull()) {
2883           // ie not an array or null
2884           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
2885         } else {
2886           work_line_->SetRegisterType(inst->VRegA_12x(), kInteger);
2887         }
2888       } else {
2889         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
2890       }
2891       break;
2892     }
2893     case Instruction::NEW_INSTANCE: {
2894       const RegType& res_type = ResolveClass<CheckAccess::kYes>(dex::TypeIndex(inst->VRegB_21c()));
2895       // Dex file verifier ensures that all valid type indexes reference valid descriptors and the
2896       // `CheckNewInstance()` ensures that the descriptor starts with an `L` before we get to the
2897       // code flow verification. So, we should not see a conflict (void) or a primitive type here.
2898       DCHECK(res_type.IsJavaLangObject() ||
2899              res_type.IsReference() ||
2900              res_type.IsUnresolvedReference()) << res_type;
2901       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
2902       // can't create an instance of an interface or abstract class */
2903       if (!res_type.IsInstantiableTypes()) {
2904         Fail(VERIFY_ERROR_INSTANTIATION)
2905             << "new-instance on primitive, interface or abstract class" << res_type;
2906         // Soft failure so carry on to set register type.
2907       }
2908       const RegType& uninit_type = reg_types_.Uninitialized(res_type);
2909       // Add the new uninitialized reference to the register state and record the allocation dex pc.
2910       uint32_t vA = inst->VRegA_21c();
2911       work_line_->DCheckUniqueNewInstanceDexPc(this, work_insn_idx_);
2912       work_line_->SetRegisterTypeForNewInstance(vA, uninit_type, work_insn_idx_);
2913       break;
2914     }
2915     case Instruction::NEW_ARRAY:
2916       VerifyNewArray(inst, false, false);
2917       break;
2918     case Instruction::FILLED_NEW_ARRAY:
2919       VerifyNewArray(inst, true, false);
2920       just_set_result = true;  // Filled new array sets result register
2921       break;
2922     case Instruction::FILLED_NEW_ARRAY_RANGE:
2923       VerifyNewArray(inst, true, true);
2924       just_set_result = true;  // Filled new array range sets result register
2925       break;
2926     case Instruction::CMPL_FLOAT:
2927     case Instruction::CMPG_FLOAT:
2928       CheckBinaryOp(inst, kInteger, kFloat, kFloat, /*check_boolean_op=*/ false);
2929       break;
2930     case Instruction::CMPL_DOUBLE:
2931     case Instruction::CMPG_DOUBLE:
2932       CheckBinaryOpWideCmp(inst, kInteger, kDoubleLo, kDoubleLo);
2933       break;
2934     case Instruction::CMP_LONG:
2935       CheckBinaryOpWideCmp(inst, kInteger, kLongLo, kLongLo);
2936       break;
2937     case Instruction::THROW: {
2938       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x());
2939       if (!IsAssignableFrom(reg_types_.JavaLangThrowable(), res_type)) {
2940         if (res_type.IsUninitializedTypes()) {
2941           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown exception not initialized";
2942         } else if (!res_type.IsReferenceTypes()) {
2943           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown value of non-reference type " << res_type;
2944         } else {
2945           Fail(res_type.IsUnresolvedTypes()
2946                   ? VERIFY_ERROR_UNRESOLVED_TYPE_CHECK : VERIFY_ERROR_BAD_CLASS_HARD)
2947                 << "thrown class " << res_type << " not instanceof Throwable";
2948         }
2949       }
2950       break;
2951     }
2952     case Instruction::GOTO:
2953     case Instruction::GOTO_16:
2954     case Instruction::GOTO_32:
2955       /* no effect on or use of registers */
2956       break;
2957 
2958     case Instruction::PACKED_SWITCH:
2959     case Instruction::SPARSE_SWITCH:
2960       /* verify that vAA is an integer, or can be converted to one */
2961       VerifyRegisterType(inst->VRegA_31t(), kInteger);
2962       break;
2963 
2964     case Instruction::FILL_ARRAY_DATA: {
2965       /* Similar to the verification done for APUT */
2966       const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t());
2967       /* array_type can be null if the reg type is Zero */
2968       if (!array_type.IsZeroOrNull()) {
2969         if (!array_type.IsArrayTypes()) {
2970           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
2971                                             << array_type;
2972         } else if (array_type.IsUnresolvedTypes()) {
2973           // If it's an unresolved array type, it must be non-primitive.
2974           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data for array of type "
2975                                             << array_type;
2976         } else {
2977           const RegType& component_type = reg_types_.GetComponentType(array_type);
2978           DCHECK(!component_type.IsConflict());
2979           if (component_type.IsNonZeroReferenceTypes()) {
2980             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
2981                                               << component_type;
2982           } else {
2983             // Now verify if the element width in the table matches the element width declared in
2984             // the array
2985             const uint16_t* array_data =
2986                 insns + (insns[1] | (static_cast<int32_t>(insns[2]) << 16));
2987             if (array_data[0] != Instruction::kArrayDataSignature) {
2988               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data";
2989             } else {
2990               size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
2991               // Since we don't compress the data in Dex, expect to see equal width of data stored
2992               // in the table and expected from the array class.
2993               if (array_data[1] != elem_width) {
2994                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1]
2995                                                   << " vs " << elem_width << ")";
2996               }
2997             }
2998           }
2999         }
3000       }
3001       break;
3002     }
3003     case Instruction::IF_EQ:
3004     case Instruction::IF_NE: {
3005       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
3006       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
3007       bool mismatch = false;
3008       if (reg_type1.IsZeroOrNull()) {  // zero then integral or reference expected
3009         mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
3010       } else if (reg_type1.IsReferenceTypes()) {  // both references?
3011         mismatch = !reg_type2.IsReferenceTypes();
3012       } else {  // both integral?
3013         mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes();
3014       }
3015       if (mismatch) {
3016         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << ","
3017                                           << reg_type2 << ") must both be references or integral";
3018       }
3019       break;
3020     }
3021     case Instruction::IF_LT:
3022     case Instruction::IF_GE:
3023     case Instruction::IF_GT:
3024     case Instruction::IF_LE: {
3025       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
3026       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
3027       if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
3028         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
3029                                           << reg_type2 << ") must be integral";
3030       }
3031       break;
3032     }
3033     case Instruction::IF_EQZ:
3034     case Instruction::IF_NEZ: {
3035       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
3036       if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
3037         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
3038                                           << " unexpected as arg to if-eqz/if-nez";
3039       }
3040 
3041       // Find previous instruction - its existence is a precondition to peephole optimization.
3042       if (UNLIKELY(0 == work_insn_idx_)) {
3043         break;
3044       }
3045       uint32_t instance_of_idx = work_insn_idx_ - 1;
3046       while (0 != instance_of_idx && !GetInstructionFlags(instance_of_idx).IsOpcode()) {
3047         instance_of_idx--;
3048       }
3049       // Dex index 0 must be an opcode.
3050       DCHECK(GetInstructionFlags(instance_of_idx).IsOpcode());
3051 
3052       const Instruction& instance_of_inst = code_item_accessor_.InstructionAt(instance_of_idx);
3053 
3054       /* Check for peep-hole pattern of:
3055        *    ...;
3056        *    instance-of vX, vY, T;
3057        *    ifXXX vX, label ;
3058        *    ...;
3059        * label:
3060        *    ...;
3061        * and sharpen the type of vY to be type T.
3062        * Note, this pattern can't be if:
3063        *  - if there are other branches to this branch,
3064        *  - when vX == vY.
3065        */
3066       if (!CurrentInsnFlags()->IsBranchTarget() &&
3067           (Instruction::INSTANCE_OF == instance_of_inst.Opcode()) &&
3068           (inst->VRegA_21t() == instance_of_inst.VRegA_22c()) &&
3069           (instance_of_inst.VRegA_22c() != instance_of_inst.VRegB_22c())) {
3070         // Check the type of the instance-of is different than that of registers type, as if they
3071         // are the same there is no work to be done here. Check that the conversion is not to or
3072         // from an unresolved type as type information is imprecise. If the instance-of is to an
3073         // interface then ignore the type information as interfaces can only be treated as Objects
3074         // and we don't want to disallow field and other operations on the object. If the value
3075         // being instance-of checked against is known null (zero) then allow the optimization as
3076         // we didn't have type information. If the merge of the instance-of type with the original
3077         // type is assignable to the original then allow optimization. This check is performed to
3078         // ensure that subsequent merges don't lose type information - such as becoming an
3079         // interface from a class that would lose information relevant to field checks.
3080         //
3081         // Note: do not do an access check. This may mark this with a runtime throw that actually
3082         //       happens at the instanceof, not the branch (and branches aren't flagged to throw).
3083         const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst.VRegB_22c());
3084         const RegType& cast_type = ResolveClass<CheckAccess::kNo>(
3085             dex::TypeIndex(instance_of_inst.VRegC_22c()));
3086 
3087         if (!orig_type.Equals(cast_type) &&
3088             !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
3089             cast_type.HasClass() &&             // Could be conflict type, make sure it has a class.
3090             !cast_type.GetClass()->IsInterface() &&
3091             !orig_type.IsZeroOrNull() &&
3092             IsStrictlyAssignableFrom(orig_type, cast_type.Merge(orig_type, &reg_types_, this))) {
3093           RegisterLine* update_line = RegisterLine::Create(code_item_accessor_.RegistersSize(),
3094                                                            allocator_,
3095                                                            GetRegTypeCache());
3096           if (inst->Opcode() == Instruction::IF_EQZ) {
3097             fallthrough_line.reset(update_line);
3098           } else {
3099             branch_line.reset(update_line);
3100           }
3101           update_line->CopyFromLine(work_line_.get());
3102           update_line->SetRegisterType<LockOp::kKeep>(instance_of_inst.VRegB_22c(), cast_type);
3103           if (!GetInstructionFlags(instance_of_idx).IsBranchTarget() && 0 != instance_of_idx) {
3104             // See if instance-of was preceded by a move-object operation, common due to the small
3105             // register encoding space of instance-of, and propagate type information to the source
3106             // of the move-object.
3107             // Note: this is only valid if the move source was not clobbered.
3108             uint32_t move_idx = instance_of_idx - 1;
3109             while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) {
3110               move_idx--;
3111             }
3112             DCHECK(GetInstructionFlags(move_idx).IsOpcode());
3113             auto maybe_update_fn = [&instance_of_inst, update_line, &cast_type](
3114                 uint16_t move_src,
3115                 uint16_t move_trg)
3116                 REQUIRES_SHARED(Locks::mutator_lock_) {
3117               if (move_trg == instance_of_inst.VRegB_22c() &&
3118                   move_src != instance_of_inst.VRegA_22c()) {
3119                 update_line->SetRegisterType<LockOp::kKeep>(move_src, cast_type);
3120               }
3121             };
3122             const Instruction& move_inst = code_item_accessor_.InstructionAt(move_idx);
3123             switch (move_inst.Opcode()) {
3124               case Instruction::MOVE_OBJECT:
3125                 maybe_update_fn(move_inst.VRegB_12x(), move_inst.VRegA_12x());
3126                 break;
3127               case Instruction::MOVE_OBJECT_FROM16:
3128                 maybe_update_fn(move_inst.VRegB_22x(), move_inst.VRegA_22x());
3129                 break;
3130               case Instruction::MOVE_OBJECT_16:
3131                 maybe_update_fn(move_inst.VRegB_32x(), move_inst.VRegA_32x());
3132                 break;
3133               default:
3134                 break;
3135             }
3136           }
3137         }
3138       }
3139 
3140       break;
3141     }
3142     case Instruction::IF_LTZ:
3143     case Instruction::IF_GEZ:
3144     case Instruction::IF_GTZ:
3145     case Instruction::IF_LEZ: {
3146       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
3147       if (!reg_type.IsIntegralTypes()) {
3148         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
3149                                           << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
3150       }
3151       break;
3152     }
3153     case Instruction::AGET_BOOLEAN:
3154       VerifyAGet(inst, reg_types_.Boolean(), true);
3155       break;
3156     case Instruction::AGET_BYTE:
3157       VerifyAGet(inst, reg_types_.Byte(), true);
3158       break;
3159     case Instruction::AGET_CHAR:
3160       VerifyAGet(inst, reg_types_.Char(), true);
3161       break;
3162     case Instruction::AGET_SHORT:
3163       VerifyAGet(inst, reg_types_.Short(), true);
3164       break;
3165     case Instruction::AGET:
3166       VerifyAGet(inst, reg_types_.Integer(), true);
3167       break;
3168     case Instruction::AGET_WIDE:
3169       VerifyAGet(inst, reg_types_.LongLo(), true);
3170       break;
3171     case Instruction::AGET_OBJECT:
3172       VerifyAGet(inst, reg_types_.JavaLangObject(), false);
3173       break;
3174 
3175     case Instruction::APUT_BOOLEAN:
3176       VerifyAPut(inst, reg_types_.Boolean(), true);
3177       break;
3178     case Instruction::APUT_BYTE:
3179       VerifyAPut(inst, reg_types_.Byte(), true);
3180       break;
3181     case Instruction::APUT_CHAR:
3182       VerifyAPut(inst, reg_types_.Char(), true);
3183       break;
3184     case Instruction::APUT_SHORT:
3185       VerifyAPut(inst, reg_types_.Short(), true);
3186       break;
3187     case Instruction::APUT:
3188       VerifyAPut(inst, reg_types_.Integer(), true);
3189       break;
3190     case Instruction::APUT_WIDE:
3191       VerifyAPut(inst, reg_types_.LongLo(), true);
3192       break;
3193     case Instruction::APUT_OBJECT:
3194       VerifyAPut(inst, reg_types_.JavaLangObject(), false);
3195       break;
3196 
3197     case Instruction::IGET_BOOLEAN:
3198       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3199       break;
3200     case Instruction::IGET_BYTE:
3201       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3202       break;
3203     case Instruction::IGET_CHAR:
3204       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3205       break;
3206     case Instruction::IGET_SHORT:
3207       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3208       break;
3209     case Instruction::IGET:
3210       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3211       break;
3212     case Instruction::IGET_WIDE:
3213       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, false);
3214       break;
3215     case Instruction::IGET_OBJECT:
3216       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, false, false);
3217       break;
3218 
3219     case Instruction::IPUT_BOOLEAN:
3220       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3221       break;
3222     case Instruction::IPUT_BYTE:
3223       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3224       break;
3225     case Instruction::IPUT_CHAR:
3226       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3227       break;
3228     case Instruction::IPUT_SHORT:
3229       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3230       break;
3231     case Instruction::IPUT:
3232       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3233       break;
3234     case Instruction::IPUT_WIDE:
3235       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, false);
3236       break;
3237     case Instruction::IPUT_OBJECT:
3238       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, false, false);
3239       break;
3240 
3241     case Instruction::SGET_BOOLEAN:
3242       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3243       break;
3244     case Instruction::SGET_BYTE:
3245       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3246       break;
3247     case Instruction::SGET_CHAR:
3248       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3249       break;
3250     case Instruction::SGET_SHORT:
3251       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3252       break;
3253     case Instruction::SGET:
3254       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3255       break;
3256     case Instruction::SGET_WIDE:
3257       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, true, true);
3258       break;
3259     case Instruction::SGET_OBJECT:
3260       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, false, true);
3261       break;
3262 
3263     case Instruction::SPUT_BOOLEAN:
3264       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3265       break;
3266     case Instruction::SPUT_BYTE:
3267       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3268       break;
3269     case Instruction::SPUT_CHAR:
3270       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3271       break;
3272     case Instruction::SPUT_SHORT:
3273       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3274       break;
3275     case Instruction::SPUT:
3276       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3277       break;
3278     case Instruction::SPUT_WIDE:
3279       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, true, true);
3280       break;
3281     case Instruction::SPUT_OBJECT:
3282       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, false, true);
3283       break;
3284 
3285     case Instruction::INVOKE_VIRTUAL:
3286     case Instruction::INVOKE_VIRTUAL_RANGE:
3287     case Instruction::INVOKE_SUPER:
3288     case Instruction::INVOKE_SUPER_RANGE: {
3289       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
3290                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
3291       bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
3292                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
3293       MethodType type = is_super ? METHOD_SUPER : METHOD_VIRTUAL;
3294       ArtMethod* called_method = VerifyInvocationArgs(inst, type, is_range);
3295       uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3296       const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx);
3297       dex::TypeIndex return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
3298       DCHECK_IMPLIES(called_method != nullptr,
3299                      called_method->GetReturnTypeDescriptorView() ==
3300                          dex_file_->GetTypeDescriptorView(return_type_idx));
3301       const RegType& return_type = reg_types_.FromTypeIndex(return_type_idx);
3302       if (!return_type.IsLowHalf()) {
3303         work_line_->SetResultRegisterType(this, return_type);
3304       } else {
3305         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3306       }
3307       just_set_result = true;
3308       break;
3309     }
3310     case Instruction::INVOKE_DIRECT:
3311     case Instruction::INVOKE_DIRECT_RANGE: {
3312       bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
3313       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, is_range);
3314       uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3315       const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx);
3316       dex::TypeIndex return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
3317       DCHECK_IMPLIES(called_method != nullptr,
3318                      called_method->GetReturnTypeDescriptorView() ==
3319                          dex_file_->GetTypeDescriptorView(return_type_idx));
3320       bool is_constructor = (called_method != nullptr)
3321           ? called_method->IsConstructor()
3322           : dex_file_->GetStringView(method_id.name_idx_) == "<init>";
3323       if (is_constructor) {
3324         /*
3325          * Some additional checks when calling a constructor. We know from the invocation arg check
3326          * that the "this" argument is an instance of called_method->klass. Now we further restrict
3327          * that to require that called_method->klass is the same as this->klass or this->super,
3328          * allowing the latter only if the "this" argument is the same as the "this" argument to
3329          * this method (which implies that we're in a constructor ourselves).
3330          */
3331         const RegType& this_type = GetInvocationThis(inst);
3332         if (this_type.IsConflict())  // failure.
3333           break;
3334 
3335         /* no null refs allowed (?) */
3336         if (this_type.IsZeroOrNull()) {
3337           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref";
3338           break;
3339         }
3340 
3341         /* arg must be an uninitialized reference */
3342         if (!this_type.IsUninitializedTypes()) {
3343           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference "
3344               << this_type;
3345           break;
3346         }
3347 
3348         // Note: According to JLS, constructors are never inherited. Therefore the target
3349         // constructor should be defined exactly by the `this_type`, or by the direct
3350         // superclass in the case of a constructor calling the superclass constructor.
3351         // However, ART had this check commented out for a very long time and this has
3352         // allowed bytecode optimizers such as R8 to inline constructors, often calling
3353         // `j.l.Object.<init>` directly without any intermediate constructor. Since this
3354         // optimization allows eliminating constructor methods, this often results in a
3355         // significant dex size reduction. Therefore it is undesirable to reinstate this
3356         // check and ART deliberately remains permissive here and diverges from the RI.
3357 
3358         /*
3359          * Replace the uninitialized reference with an initialized one. We need to do this for all
3360          * registers that have the same object instance in them, not just the "this" register.
3361          */
3362         work_line_->MarkRefsAsInitialized(this, inst->VRegC());
3363       }
3364       const RegType& return_type = reg_types_.FromTypeIndex(return_type_idx);
3365       if (!return_type.IsLowHalf()) {
3366         work_line_->SetResultRegisterType(this, return_type);
3367       } else {
3368         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3369       }
3370       just_set_result = true;
3371       break;
3372     }
3373     case Instruction::INVOKE_STATIC:
3374     case Instruction::INVOKE_STATIC_RANGE: {
3375       bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
3376       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_STATIC, is_range);
3377       uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3378       const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx);
3379       dex::TypeIndex return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
3380       DCHECK_IMPLIES(called_method != nullptr,
3381                      called_method->GetReturnTypeDescriptorView() ==
3382                          dex_file_->GetTypeDescriptorView(return_type_idx));
3383       const RegType& return_type = reg_types_.FromTypeIndex(return_type_idx);
3384       if (!return_type.IsLowHalf()) {
3385         work_line_->SetResultRegisterType(this, return_type);
3386       } else {
3387         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3388       }
3389       just_set_result = true;
3390       break;
3391     }
3392     case Instruction::INVOKE_INTERFACE:
3393     case Instruction::INVOKE_INTERFACE_RANGE: {
3394       bool is_range =  (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
3395       ArtMethod* abs_method = VerifyInvocationArgs(inst, METHOD_INTERFACE, is_range);
3396       if (abs_method != nullptr) {
3397         ObjPtr<mirror::Class> called_interface = abs_method->GetDeclaringClass();
3398         if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
3399           Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
3400               << abs_method->PrettyMethod() << "'";
3401           break;
3402         }
3403       }
3404       /* Get the type of the "this" arg, which should either be a sub-interface of called
3405        * interface or Object (see comments in RegType::JoinClass).
3406        */
3407       const RegType& this_type = GetInvocationThis(inst);
3408       if (this_type.IsZeroOrNull()) {
3409         /* null pointer always passes (and always fails at runtime) */
3410       } else {
3411         if (this_type.IsUninitializedTypes()) {
3412           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object "
3413               << this_type;
3414           break;
3415         }
3416         // In the past we have tried to assert that "called_interface" is assignable
3417         // from "this_type.GetClass()", however, as we do an imprecise Join
3418         // (RegType::JoinClass) we don't have full information on what interfaces are
3419         // implemented by "this_type". For example, two classes may implement the same
3420         // interfaces and have a common parent that doesn't implement the interface. The
3421         // join will set "this_type" to the parent class and a test that this implements
3422         // the interface will incorrectly fail.
3423       }
3424       /*
3425        * We don't have an object instance, so we can't find the concrete method. However, all of
3426        * the type information is in the abstract method, so we're good.
3427        */
3428       uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
3429       const dex::MethodId& method_id = dex_file_->GetMethodId(method_idx);
3430       dex::TypeIndex return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
3431       DCHECK_IMPLIES(abs_method != nullptr,
3432                      abs_method->GetReturnTypeDescriptorView() ==
3433                          dex_file_->GetTypeDescriptorView(return_type_idx));
3434       const RegType& return_type = reg_types_.FromTypeIndex(return_type_idx);
3435       if (!return_type.IsLowHalf()) {
3436         work_line_->SetResultRegisterType(this, return_type);
3437       } else {
3438         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3439       }
3440       just_set_result = true;
3441       break;
3442     }
3443     case Instruction::INVOKE_POLYMORPHIC:
3444     case Instruction::INVOKE_POLYMORPHIC_RANGE: {
3445       bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE);
3446       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_POLYMORPHIC, is_range);
3447       if (called_method == nullptr) {
3448         // Convert potential soft failures in VerifyInvocationArgs() to hard errors.
3449         if (failure_messages_.size() > 0) {
3450           std::string message = failure_messages_.back()->str();
3451           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << message;
3452         } else {
3453           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-polymorphic verification failure.";
3454         }
3455         break;
3456       }
3457       if (!CheckSignaturePolymorphicMethod(called_method) ||
3458           !CheckSignaturePolymorphicReceiver(inst)) {
3459         DCHECK(HasFailures());
3460         break;
3461       }
3462       const dex::ProtoIndex proto_idx((is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc());
3463       const RegType& return_type =
3464           reg_types_.FromTypeIndex(dex_file_->GetProtoId(proto_idx).return_type_idx_);
3465       if (!return_type.IsLowHalf()) {
3466         work_line_->SetResultRegisterType(this, return_type);
3467       } else {
3468         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3469       }
3470       just_set_result = true;
3471       break;
3472     }
3473     case Instruction::INVOKE_CUSTOM:
3474     case Instruction::INVOKE_CUSTOM_RANGE: {
3475       // Verify registers based on method_type in the call site.
3476       bool is_range = (inst->Opcode() == Instruction::INVOKE_CUSTOM_RANGE);
3477 
3478       // Step 1. Check the call site that produces the method handle for invocation
3479       const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
3480       if (!CheckCallSite(call_site_idx)) {
3481         DCHECK(HasFailures());
3482         break;
3483       }
3484 
3485       // Step 2. Check the register arguments correspond to the expected arguments for the
3486       // method handle produced by step 1. The dex file verifier has checked ranges for
3487       // the first three arguments and CheckCallSite has checked the method handle type.
3488       const dex::ProtoIndex proto_idx = dex_file_->GetProtoIndexForCallSite(call_site_idx);
3489       const dex::ProtoId& proto_id = dex_file_->GetProtoId(proto_idx);
3490       DexFileParameterIterator param_it(*dex_file_, proto_id);
3491       // Treat method as static as it has yet to be determined.
3492       VerifyInvocationArgsFromIterator(&param_it, inst, METHOD_STATIC, is_range, nullptr);
3493 
3494       // Step 3. Propagate return type information
3495       const RegType& return_type = reg_types_.FromTypeIndex(proto_id.return_type_idx_);
3496       if (!return_type.IsLowHalf()) {
3497         work_line_->SetResultRegisterType(this, return_type);
3498       } else {
3499         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
3500       }
3501       just_set_result = true;
3502       break;
3503     }
3504     case Instruction::NEG_INT:
3505     case Instruction::NOT_INT:
3506       CheckUnaryOp(inst, kInteger, kInteger);
3507       break;
3508     case Instruction::NEG_LONG:
3509     case Instruction::NOT_LONG:
3510       CheckUnaryOpWide(inst, kLongLo, kLongLo);
3511       break;
3512     case Instruction::NEG_FLOAT:
3513       CheckUnaryOp(inst, kFloat, kFloat);
3514       break;
3515     case Instruction::NEG_DOUBLE:
3516       CheckUnaryOpWide(inst, kDoubleLo, kDoubleLo);
3517       break;
3518     case Instruction::INT_TO_LONG:
3519       CheckUnaryOpToWide(inst, kLongLo, kInteger);
3520       break;
3521     case Instruction::INT_TO_FLOAT:
3522       CheckUnaryOp(inst, kFloat, kInteger);
3523       break;
3524     case Instruction::INT_TO_DOUBLE:
3525       CheckUnaryOpToWide(inst, kDoubleLo, kInteger);
3526       break;
3527     case Instruction::LONG_TO_INT:
3528       CheckUnaryOpFromWide(inst, kInteger, kLongLo);
3529       break;
3530     case Instruction::LONG_TO_FLOAT:
3531       CheckUnaryOpFromWide(inst, kFloat, kLongLo);
3532       break;
3533     case Instruction::LONG_TO_DOUBLE:
3534       CheckUnaryOpWide(inst, kDoubleLo, kLongLo);
3535       break;
3536     case Instruction::FLOAT_TO_INT:
3537       CheckUnaryOp(inst, kInteger, kFloat);
3538       break;
3539     case Instruction::FLOAT_TO_LONG:
3540       CheckUnaryOpToWide(inst, kLongLo, kFloat);
3541       break;
3542     case Instruction::FLOAT_TO_DOUBLE:
3543       CheckUnaryOpToWide(inst, kDoubleLo, kFloat);
3544       break;
3545     case Instruction::DOUBLE_TO_INT:
3546       CheckUnaryOpFromWide(inst, kInteger, kDoubleLo);
3547       break;
3548     case Instruction::DOUBLE_TO_LONG:
3549       CheckUnaryOpWide(inst, kLongLo, kDoubleLo);
3550       break;
3551     case Instruction::DOUBLE_TO_FLOAT:
3552       CheckUnaryOpFromWide(inst, kFloat, kDoubleLo);
3553       break;
3554     case Instruction::INT_TO_BYTE:
3555       CheckUnaryOp(inst, kByte, kInteger);
3556       break;
3557     case Instruction::INT_TO_CHAR:
3558       CheckUnaryOp(inst, kChar, kInteger);
3559       break;
3560     case Instruction::INT_TO_SHORT:
3561       CheckUnaryOp(inst, kShort, kInteger);
3562       break;
3563 
3564     case Instruction::ADD_INT:
3565     case Instruction::SUB_INT:
3566     case Instruction::MUL_INT:
3567     case Instruction::REM_INT:
3568     case Instruction::DIV_INT:
3569     case Instruction::SHL_INT:
3570     case Instruction::SHR_INT:
3571     case Instruction::USHR_INT:
3572       CheckBinaryOp(inst, kInteger, kInteger, kInteger, /*check_boolean_op=*/ false);
3573       break;
3574     case Instruction::AND_INT:
3575     case Instruction::OR_INT:
3576     case Instruction::XOR_INT:
3577       CheckBinaryOp(inst, kInteger, kInteger, kInteger, /*check_boolean_op=*/ true);
3578       break;
3579     case Instruction::ADD_LONG:
3580     case Instruction::SUB_LONG:
3581     case Instruction::MUL_LONG:
3582     case Instruction::DIV_LONG:
3583     case Instruction::REM_LONG:
3584     case Instruction::AND_LONG:
3585     case Instruction::OR_LONG:
3586     case Instruction::XOR_LONG:
3587       CheckBinaryOpWide(inst, kLongLo, kLongLo, kLongLo);
3588       break;
3589     case Instruction::SHL_LONG:
3590     case Instruction::SHR_LONG:
3591     case Instruction::USHR_LONG:
3592       /* shift distance is Int, making these different from other binary operations */
3593       CheckBinaryOpWideShift(inst, kLongLo, kInteger);
3594       break;
3595     case Instruction::ADD_FLOAT:
3596     case Instruction::SUB_FLOAT:
3597     case Instruction::MUL_FLOAT:
3598     case Instruction::DIV_FLOAT:
3599     case Instruction::REM_FLOAT:
3600       CheckBinaryOp(inst, kFloat, kFloat, kFloat, /*check_boolean_op=*/ false);
3601       break;
3602     case Instruction::ADD_DOUBLE:
3603     case Instruction::SUB_DOUBLE:
3604     case Instruction::MUL_DOUBLE:
3605     case Instruction::DIV_DOUBLE:
3606     case Instruction::REM_DOUBLE:
3607       CheckBinaryOpWide(inst, kDoubleLo, kDoubleLo, kDoubleLo);
3608       break;
3609     case Instruction::ADD_INT_2ADDR:
3610     case Instruction::SUB_INT_2ADDR:
3611     case Instruction::MUL_INT_2ADDR:
3612     case Instruction::REM_INT_2ADDR:
3613     case Instruction::SHL_INT_2ADDR:
3614     case Instruction::SHR_INT_2ADDR:
3615     case Instruction::USHR_INT_2ADDR:
3616       CheckBinaryOp2addr(inst, kInteger, kInteger, kInteger, /*check_boolean_op=*/ false);
3617       break;
3618     case Instruction::AND_INT_2ADDR:
3619     case Instruction::OR_INT_2ADDR:
3620     case Instruction::XOR_INT_2ADDR:
3621       CheckBinaryOp2addr(inst, kInteger, kInteger, kInteger, /*check_boolean_op=*/ true);
3622       break;
3623     case Instruction::DIV_INT_2ADDR:
3624       CheckBinaryOp2addr(inst, kInteger, kInteger, kInteger, /*check_boolean_op=*/ false);
3625       break;
3626     case Instruction::ADD_LONG_2ADDR:
3627     case Instruction::SUB_LONG_2ADDR:
3628     case Instruction::MUL_LONG_2ADDR:
3629     case Instruction::DIV_LONG_2ADDR:
3630     case Instruction::REM_LONG_2ADDR:
3631     case Instruction::AND_LONG_2ADDR:
3632     case Instruction::OR_LONG_2ADDR:
3633     case Instruction::XOR_LONG_2ADDR:
3634       CheckBinaryOp2addrWide(inst, kLongLo, kLongLo, kLongLo);
3635       break;
3636     case Instruction::SHL_LONG_2ADDR:
3637     case Instruction::SHR_LONG_2ADDR:
3638     case Instruction::USHR_LONG_2ADDR:
3639       CheckBinaryOp2addrWideShift(inst, kLongLo, kInteger);
3640       break;
3641     case Instruction::ADD_FLOAT_2ADDR:
3642     case Instruction::SUB_FLOAT_2ADDR:
3643     case Instruction::MUL_FLOAT_2ADDR:
3644     case Instruction::DIV_FLOAT_2ADDR:
3645     case Instruction::REM_FLOAT_2ADDR:
3646       CheckBinaryOp2addr(inst, kFloat, kFloat, kFloat, /*check_boolean_op=*/ false);
3647       break;
3648     case Instruction::ADD_DOUBLE_2ADDR:
3649     case Instruction::SUB_DOUBLE_2ADDR:
3650     case Instruction::MUL_DOUBLE_2ADDR:
3651     case Instruction::DIV_DOUBLE_2ADDR:
3652     case Instruction::REM_DOUBLE_2ADDR:
3653       CheckBinaryOp2addrWide(inst, kDoubleLo, kDoubleLo, kDoubleLo);
3654       break;
3655     case Instruction::ADD_INT_LIT16:
3656     case Instruction::RSUB_INT_LIT16:
3657     case Instruction::MUL_INT_LIT16:
3658     case Instruction::DIV_INT_LIT16:
3659     case Instruction::REM_INT_LIT16:
3660       CheckLiteralOp(inst, kInteger, kInteger, /*check_boolean_op=*/ false, /*is_lit16=*/ true);
3661       break;
3662     case Instruction::AND_INT_LIT16:
3663     case Instruction::OR_INT_LIT16:
3664     case Instruction::XOR_INT_LIT16:
3665       CheckLiteralOp(inst, kInteger, kInteger, /*check_boolean_op=*/ true, /*is_lit16=*/ true);
3666       break;
3667     case Instruction::ADD_INT_LIT8:
3668     case Instruction::RSUB_INT_LIT8:
3669     case Instruction::MUL_INT_LIT8:
3670     case Instruction::DIV_INT_LIT8:
3671     case Instruction::REM_INT_LIT8:
3672     case Instruction::SHL_INT_LIT8:
3673     case Instruction::SHR_INT_LIT8:
3674     case Instruction::USHR_INT_LIT8:
3675       CheckLiteralOp(inst, kInteger, kInteger, /*check_boolean_op=*/ false, /*is_lit16=*/ false);
3676       break;
3677     case Instruction::AND_INT_LIT8:
3678     case Instruction::OR_INT_LIT8:
3679     case Instruction::XOR_INT_LIT8:
3680       CheckLiteralOp(inst, kInteger, kInteger, /*check_boolean_op=*/ true, /*is_lit16=*/ false);
3681       break;
3682 
3683     /* These should never appear during verification. */
3684     case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
3685     case Instruction::UNUSED_E3 ... Instruction::UNUSED_F9:
3686     case Instruction::UNUSED_73:
3687     case Instruction::UNUSED_79:
3688     case Instruction::UNUSED_7A:
3689       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_);
3690       break;
3691 
3692     /*
3693      * DO NOT add a "default" clause here. Without it the compiler will
3694      * complain if an instruction is missing (which is desirable).
3695      */
3696   }  // end - switch (dec_insn.opcode)
3697 
3698   if (flags_.have_pending_hard_failure_) {
3699     if (IsAotMode()) {
3700       /* When AOT compiling, check that the last failure is a hard failure */
3701       if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) {
3702         LOG(ERROR) << "Pending failures:";
3703         for (auto& error : failures_) {
3704           LOG(ERROR) << error;
3705         }
3706         for (auto& error_msg : failure_messages_) {
3707           LOG(ERROR) << error_msg->str();
3708         }
3709         LOG(FATAL) << "Pending hard failure, but last failure not hard.";
3710       }
3711     }
3712     /* immediate failure, reject class */
3713     InfoMessages() << "Rejecting opcode " << inst->DumpString(dex_file_);
3714     return false;
3715   } else if (flags_.have_pending_runtime_throw_failure_) {
3716     LogVerifyInfo() << "Elevating opcode flags from " << opcode_flags << " to Throw";
3717     /* checking interpreter will throw, mark following code as unreachable */
3718     opcode_flags = Instruction::kThrow;
3719     // Note: the flag must be reset as it is only global to decouple Fail and is semantically per
3720     //       instruction. However, RETURN checking may throw LOCKING errors, so we clear at the
3721     //       very end.
3722   }
3723   /*
3724    * If we didn't just set the result register, clear it out. This ensures that you can only use
3725    * "move-result" immediately after the result is set. (We could check this statically, but it's
3726    * not expensive and it makes our debugging output cleaner.)
3727    */
3728   if (!just_set_result) {
3729     work_line_->SetResultTypeToUnknown(GetRegTypeCache());
3730   }
3731 
3732   /*
3733    * Handle "branch". Tag the branch target.
3734    *
3735    * NOTE: instructions like Instruction::EQZ provide information about the
3736    * state of the register when the branch is taken or not taken. For example,
3737    * somebody could get a reference field, check it for zero, and if the
3738    * branch is taken immediately store that register in a boolean field
3739    * since the value is known to be zero. We do not currently account for
3740    * that, and will reject the code.
3741    *
3742    * TODO: avoid re-fetching the branch target
3743    */
3744   if ((opcode_flags & Instruction::kBranch) != 0) {
3745     bool isConditional, selfOkay;
3746     if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) {
3747       /* should never happen after static verification */
3748       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch";
3749       return false;
3750     }
3751     DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0);
3752     if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(),
3753                                            work_insn_idx_ + branch_target)) {
3754       return false;
3755     }
3756     /* update branch target, set "changed" if appropriate */
3757     if (nullptr != branch_line) {
3758       if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) {
3759         return false;
3760       }
3761     } else {
3762       if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) {
3763         return false;
3764       }
3765     }
3766   }
3767 
3768   /*
3769    * Handle "switch". Tag all possible branch targets.
3770    *
3771    * We've already verified that the table is structurally sound, so we
3772    * just need to walk through and tag the targets.
3773    */
3774   if ((opcode_flags & Instruction::kSwitch) != 0) {
3775     int offset_to_switch = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
3776     const uint16_t* switch_insns = insns + offset_to_switch;
3777     int switch_count = switch_insns[1];
3778     int offset_to_targets, targ;
3779 
3780     if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
3781       /* 0 = sig, 1 = count, 2/3 = first key */
3782       offset_to_targets = 4;
3783     } else {
3784       /* 0 = sig, 1 = count, 2..count * 2 = keys */
3785       DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH);
3786       offset_to_targets = 2 + 2 * switch_count;
3787     }
3788 
3789     /* verify each switch target */
3790     for (targ = 0; targ < switch_count; targ++) {
3791       int offset;
3792       uint32_t abs_offset;
3793 
3794       /* offsets are 32-bit, and only partly endian-swapped */
3795       offset = switch_insns[offset_to_targets + targ * 2] |
3796          (static_cast<int32_t>(switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
3797       abs_offset = work_insn_idx_ + offset;
3798       DCHECK_LT(abs_offset, code_item_accessor_.InsnsSizeInCodeUnits());
3799       if (!CheckNotMoveExceptionOrMoveResult(code_item_accessor_.Insns(), abs_offset)) {
3800         return false;
3801       }
3802       if (!UpdateRegisters(abs_offset, work_line_.get(), false)) {
3803         return false;
3804       }
3805     }
3806   }
3807 
3808   /*
3809    * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a
3810    * "try" block when they throw, control transfers out of the method.)
3811    */
3812   if ((opcode_flags & Instruction::kThrow) != 0 && GetInstructionFlags(work_insn_idx_).IsInTry()) {
3813     bool has_catch_all_handler = false;
3814     const dex::TryItem* try_item = code_item_accessor_.FindTryItem(work_insn_idx_);
3815     CHECK(try_item != nullptr);
3816     CatchHandlerIterator iterator(code_item_accessor_, *try_item);
3817 
3818     // Need the linker to try and resolve the handled class to check if it's Throwable.
3819     ClassLinker* linker = GetClassLinker();
3820 
3821     for (; iterator.HasNext(); iterator.Next()) {
3822       dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex();
3823       if (!handler_type_idx.IsValid()) {
3824         has_catch_all_handler = true;
3825       } else {
3826         // It is also a catch-all if it is java.lang.Throwable.
3827         ObjPtr<mirror::Class> klass =
3828             linker->ResolveType(handler_type_idx, dex_cache_, class_loader_);
3829         if (klass != nullptr) {
3830           if (klass == GetClassRoot<mirror::Throwable>()) {
3831             has_catch_all_handler = true;
3832           }
3833         } else {
3834           // Clear exception.
3835           DCHECK(self_->IsExceptionPending());
3836           self_->ClearException();
3837         }
3838       }
3839       /*
3840        * Merge registers into the "catch" block. We want to use the "savedRegs" rather than
3841        * "work_regs", because at runtime the exception will be thrown before the instruction
3842        * modifies any registers.
3843        */
3844       if (kVerifierDebug) {
3845         LogVerifyInfo() << "Updating exception handler 0x"
3846                         << std::hex << iterator.GetHandlerAddress();
3847       }
3848       if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) {
3849         return false;
3850       }
3851     }
3852 
3853     /*
3854      * If the monitor stack depth is nonzero, there must be a "catch all" handler for this
3855      * instruction. This does apply to monitor-exit because of async exception handling.
3856      */
3857     if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) {
3858       /*
3859        * The state in work_line reflects the post-execution state. If the current instruction is a
3860        * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws,
3861        * it will do so before grabbing the lock).
3862        */
3863       if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) {
3864         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
3865             << "expected to be within a catch-all for an instruction where a monitor is held";
3866         return false;
3867       }
3868     }
3869   }
3870 
3871   /* Handle "continue". Tag the next consecutive instruction.
3872    *  Note: Keep the code handling "continue" case below the "branch" and "switch" cases,
3873    *        because it changes work_line_ when performing peephole optimization
3874    *        and this change should not be used in those cases.
3875    */
3876   if ((opcode_flags & Instruction::kContinue) != 0 && !exc_handler_unreachable) {
3877     DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst);
3878     uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits();
3879     if (next_insn_idx >= code_item_accessor_.InsnsSizeInCodeUnits()) {
3880       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area";
3881       return false;
3882     }
3883     // The only way to get to a move-exception instruction is to get thrown there. Make sure the
3884     // next instruction isn't one.
3885     if (!CheckNotMoveException(code_item_accessor_.Insns(), next_insn_idx)) {
3886       return false;
3887     }
3888     if (nullptr != fallthrough_line) {
3889       // Make workline consistent with fallthrough computed from peephole optimization.
3890       work_line_->CopyFromLine(fallthrough_line.get());
3891     }
3892     if (GetInstructionFlags(next_insn_idx).IsReturn()) {
3893       // For returns we only care about the operand to the return, all other registers are dead.
3894       const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn_idx);
3895       AdjustReturnLine(this, ret_inst, work_line_.get());
3896     }
3897     RegisterLine* next_line = reg_table_.GetLine(next_insn_idx);
3898     if (next_line != nullptr) {
3899       // Merge registers into what we have for the next instruction, and set the "changed" flag if
3900       // needed. If the merge changes the state of the registers then the work line will be
3901       // updated.
3902       if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) {
3903         return false;
3904       }
3905     } else {
3906       /*
3907        * We're not recording register data for the next instruction, so we don't know what the
3908        * prior state was. We have to assume that something has changed and re-evaluate it.
3909        */
3910       GetModifiableInstructionFlags(next_insn_idx).SetChanged();
3911     }
3912   }
3913 
3914   /* If we're returning from the method, make sure monitor stack is empty. */
3915   if ((opcode_flags & Instruction::kReturn) != 0) {
3916     work_line_->VerifyMonitorStackEmpty(this);
3917   }
3918 
3919   /*
3920    * Update start_guess. Advance to the next instruction of that's
3921    * possible, otherwise use the branch target if one was found. If
3922    * neither of those exists we're in a return or throw; leave start_guess
3923    * alone and let the caller sort it out.
3924    */
3925   if ((opcode_flags & Instruction::kContinue) != 0) {
3926     DCHECK_EQ(&code_item_accessor_.InstructionAt(work_insn_idx_), inst);
3927     *start_guess = work_insn_idx_ + inst->SizeInCodeUnits();
3928   } else if ((opcode_flags & Instruction::kBranch) != 0) {
3929     /* we're still okay if branch_target is zero */
3930     *start_guess = work_insn_idx_ + branch_target;
3931   }
3932 
3933   DCHECK_LT(*start_guess, code_item_accessor_.InsnsSizeInCodeUnits());
3934   DCHECK(GetInstructionFlags(*start_guess).IsOpcode());
3935 
3936   if (flags_.have_pending_runtime_throw_failure_) {
3937     Fail(VERIFY_ERROR_RUNTIME_THROW, /* pending_exc= */ false);
3938     // Reset the pending_runtime_throw flag now.
3939     flags_.have_pending_runtime_throw_failure_ = false;
3940   }
3941 
3942   return true;
3943 }  // NOLINT(readability/fn_size)
3944 
3945 template <bool kVerifierDebug>
3946 template <CheckAccess C>
ResolveClass(dex::TypeIndex class_idx)3947 const RegType& MethodVerifier<kVerifierDebug>::ResolveClass(dex::TypeIndex class_idx) {
3948   // FIXME: `RegTypeCache` can currently return a few fundamental classes such as j.l.Object
3949   // or j.l.Class without resolving them using the current class loader and recording them
3950   // in the corresponding `ClassTable`. The subsequent method and field lookup by callers of
3951   // `ResolveClass<>()` can then put their methods and fields to the `DexCache` which should
3952   // not be done for classes that are not in the `ClassTable`, potentially leading to crashes.
3953   // For now, we force the class resolution here to avoid the inconsistency.
3954   // Note that there's nothing we can do if we cannot load classes. (The only code path that
3955   // does not allow loading classes is `FindLocksAtDexPc()` which should really need only to
3956   // distinguish between reference and non-reference types and track locking. All the other
3957   // work, including class lookup, is unnecessary as the class has already been verified.)
3958   if (CanLoadClasses()) {
3959     ClassLinker* linker = GetClassLinker();
3960     ObjPtr<mirror::Class> klass =  linker->ResolveType(class_idx, dex_cache_, class_loader_);
3961     if (klass == nullptr) {
3962       DCHECK(self_->IsExceptionPending());
3963       self_->ClearException();
3964     }
3965   }
3966 
3967   const RegType& result = reg_types_.FromTypeIndex(class_idx);
3968   if (result.IsConflict()) {
3969     const char* descriptor = dex_file_->GetTypeDescriptor(class_idx);
3970     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "accessing broken descriptor '" << descriptor
3971         << "' in " << GetDeclaringClass();
3972     return result;
3973   }
3974 
3975   // If requested, check if access is allowed. Unresolved types are included in this check, as the
3976   // interpreter only tests whether access is allowed when a class is not pre-verified and runs in
3977   // the access-checks interpreter. If result is primitive, skip the access check.
3978   //
3979   // Note: we do this for unresolved classes to trigger re-verification at runtime.
3980   if (C != CheckAccess::kNo &&
3981       result.IsNonZeroReferenceTypes() &&
3982       ((C == CheckAccess::kYes && IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP))
3983           || !result.IsUnresolvedTypes())) {
3984     const RegType& referrer = GetDeclaringClass();
3985     if ((IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP) || !referrer.IsUnresolvedTypes()) &&
3986         !CanAccess(result)) {
3987       if (IsAotMode()) {
3988         Fail(VERIFY_ERROR_ACCESS_CLASS);
3989         VLOG(verifier)
3990             << "(possibly) illegal class access: '" << referrer << "' -> '" << result << "'";
3991       } else {
3992         Fail(VERIFY_ERROR_ACCESS_CLASS)
3993             << "(possibly) illegal class access: '" << referrer << "' -> '" << result << "'";
3994       }
3995     }
3996   }
3997   return result;
3998 }
3999 
4000 template <bool kVerifierDebug>
HandleMoveException(const Instruction * inst)4001 bool MethodVerifier<kVerifierDebug>::HandleMoveException(const Instruction* inst)  {
4002   // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case
4003   // where one entrypoint to the catch block is not actually an exception path.
4004   if (work_insn_idx_ == 0) {
4005     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0";
4006     return true;
4007   }
4008   /*
4009    * This statement can only appear as the first instruction in an exception handler. We verify
4010    * that as part of extracting the exception type from the catch block list.
4011    */
4012   auto caught_exc_type_fn = [&]() REQUIRES_SHARED(Locks::mutator_lock_) ->
4013       std::pair<bool, const RegType*> {
4014     const RegType* common_super = nullptr;
4015     if (code_item_accessor_.TriesSize() != 0) {
4016       const uint8_t* handlers_ptr = code_item_accessor_.GetCatchHandlerData();
4017       uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
4018       const RegType* unresolved = nullptr;
4019       for (uint32_t i = 0; i < handlers_size; i++) {
4020         CatchHandlerIterator iterator(handlers_ptr);
4021         for (; iterator.HasNext(); iterator.Next()) {
4022           if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) {
4023             if (!iterator.GetHandlerTypeIndex().IsValid()) {
4024               common_super = &reg_types_.JavaLangThrowable();
4025             } else {
4026               // Do access checks only on resolved exception classes.
4027               const RegType& exception =
4028                   ResolveClass<CheckAccess::kOnResolvedClass>(iterator.GetHandlerTypeIndex());
4029               if (!IsAssignableFrom(reg_types_.JavaLangThrowable(), exception)) {
4030                 DCHECK(!exception.IsUninitializedTypes());  // Comes from dex, shouldn't be uninit.
4031                 if (exception.IsUnresolvedTypes()) {
4032                   if (unresolved == nullptr) {
4033                     unresolved = &exception;
4034                   } else {
4035                     unresolved = &unresolved->SafeMerge(exception, &reg_types_, this);
4036                   }
4037                 } else {
4038                   Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-throwable class "
4039                                                     << exception;
4040                   return std::make_pair(true, &reg_types_.Conflict());
4041                 }
4042               } else if (common_super == nullptr) {
4043                 common_super = &exception;
4044               } else if (common_super->Equals(exception)) {
4045                 // odd case, but nothing to do
4046               } else {
4047                 common_super = &common_super->Merge(exception, &reg_types_, this);
4048                 if (FailOrAbort(IsAssignableFrom(reg_types_.JavaLangThrowable(), *common_super),
4049                                 "java.lang.Throwable is not assignable-from common_super at ",
4050                                 work_insn_idx_)) {
4051                   break;
4052                 }
4053               }
4054             }
4055           }
4056         }
4057         handlers_ptr = iterator.EndDataPointer();
4058       }
4059       if (unresolved != nullptr) {
4060         // Soft-fail, but do not handle this with a synthetic throw.
4061         Fail(VERIFY_ERROR_UNRESOLVED_TYPE_CHECK, /*pending_exc=*/ false)
4062             << "Unresolved catch handler";
4063         bool should_continue = true;
4064         if (common_super != nullptr) {
4065           unresolved = &unresolved->Merge(*common_super, &reg_types_, this);
4066         } else {
4067           should_continue = !PotentiallyMarkRuntimeThrow();
4068         }
4069         return std::make_pair(should_continue, unresolved);
4070       }
4071     }
4072     if (common_super == nullptr) {
4073       /* No catch block */
4074       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to find exception handler";
4075       return std::make_pair(true, &reg_types_.Conflict());
4076     }
4077     DCHECK(common_super->HasClass());
4078     CheckForFinalAbstractClass(common_super->GetClass());
4079     return std::make_pair(true, common_super);
4080   };
4081   auto result = caught_exc_type_fn();
4082   work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_11x(), *result.second);
4083   return result.first;
4084 }
4085 
4086 template <bool kVerifierDebug>
ResolveMethodAndCheckAccess(uint32_t dex_method_idx,MethodType method_type)4087 ArtMethod* MethodVerifier<kVerifierDebug>::ResolveMethodAndCheckAccess(
4088     uint32_t dex_method_idx, MethodType method_type) {
4089   const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
4090   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(method_id.class_idx_);
4091   if (klass_type.IsConflict()) {
4092     std::string append(" in attempt to access method ");
4093     append += dex_file_->GetMethodName(method_id);
4094     AppendToLastFailMessage(append);
4095     return nullptr;
4096   }
4097   if (klass_type.IsUnresolvedTypes()) {
4098     return nullptr;  // Can't resolve Class so no more to do here
4099   }
4100   ClassLinker* class_linker = GetClassLinker();
4101   ObjPtr<mirror::Class> klass = GetRegTypeClass(klass_type);
4102 
4103   ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
4104   if (res_method == nullptr) {
4105     res_method = class_linker->FindResolvedMethod(
4106         klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx);
4107   }
4108 
4109   bool must_fail = false;
4110   // This is traditional and helps with screwy bytecode. It will tell you that, yes, a method
4111   // exists, but that it's called incorrectly. This significantly helps debugging, as locally it's
4112   // hard to see the differences.
4113   // If we don't have res_method here we must fail. Just use this bool to make sure of that with a
4114   // DCHECK.
4115   if (res_method == nullptr) {
4116     must_fail = true;
4117     // Try to find the method also with the other type for better error reporting below
4118     // but do not store such bogus lookup result in the DexCache or VerifierDeps.
4119     res_method = class_linker->FindIncompatibleMethod(
4120         klass, dex_cache_.Get(), class_loader_.Get(), dex_method_idx);
4121   }
4122 
4123   if (res_method == nullptr) {
4124     Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method "
4125                                  << klass->PrettyDescriptor() << "."
4126                                  << dex_file_->GetMethodName(method_id) << " "
4127                                  << dex_file_->GetMethodSignature(method_id);
4128     return nullptr;
4129   }
4130 
4131   // Make sure calls to constructors are "direct". There are additional restrictions but we don't
4132   // enforce them here.
4133   if (res_method->IsConstructor() && method_type != METHOD_DIRECT) {
4134     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor "
4135                                       << res_method->PrettyMethod();
4136     return nullptr;
4137   }
4138   // Disallow any calls to class initializers.
4139   if (res_method->IsClassInitializer()) {
4140     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
4141                                       << res_method->PrettyMethod();
4142     return nullptr;
4143   }
4144 
4145   // Check that interface methods are static or match interface classes.
4146   // We only allow statics if we don't have default methods enabled.
4147   //
4148   // Note: this check must be after the initializer check, as those are required to fail a class,
4149   //       while this check implies an IncompatibleClassChangeError.
4150   if (klass->IsInterface()) {
4151     // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if
4152     // default methods are supported for the dex file), or invoke-static.
4153     if (method_type != METHOD_INTERFACE &&
4154         method_type != METHOD_STATIC &&
4155         (!dex_file_->SupportsDefaultMethods() ||
4156          method_type != METHOD_DIRECT) &&
4157         method_type != METHOD_SUPER) {
4158       Fail(VERIFY_ERROR_CLASS_CHANGE)
4159           << "non-interface method " << dex_file_->PrettyMethod(dex_method_idx)
4160           << " is in an interface class " << klass->PrettyClass();
4161       return nullptr;
4162     }
4163   } else {
4164     if (method_type == METHOD_INTERFACE) {
4165       Fail(VERIFY_ERROR_CLASS_CHANGE)
4166           << "interface method " << dex_file_->PrettyMethod(dex_method_idx)
4167           << " is in a non-interface class " << klass->PrettyClass();
4168       return nullptr;
4169     }
4170   }
4171 
4172   // Check specifically for non-public object methods being provided for interface dispatch. This
4173   // can occur if we failed to find a method with FindInterfaceMethod but later find one with
4174   // FindClassMethod for error message use.
4175   if (method_type == METHOD_INTERFACE &&
4176       res_method->GetDeclaringClass()->IsObjectClass() &&
4177       !res_method->IsPublic()) {
4178     Fail(VERIFY_ERROR_NO_METHOD) << "invoke-interface " << klass->PrettyDescriptor() << "."
4179                                  << dex_file_->GetMethodName(method_id) << " "
4180                                  << dex_file_->GetMethodSignature(method_id) << " resolved to "
4181                                  << "non-public object method " << res_method->PrettyMethod() << " "
4182                                  << "but non-public Object methods are excluded from interface "
4183                                  << "method resolution.";
4184     return nullptr;
4185   }
4186   // Check if access is allowed.
4187   if (!CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
4188     Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call "
4189                                      << res_method->PrettyMethod()
4190                                      << " from " << GetDeclaringClass() << ")";
4191     return res_method;
4192   }
4193   // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
4194   if (res_method->IsPrivate() && (method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER)) {
4195     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method "
4196                                       << res_method->PrettyMethod();
4197     return nullptr;
4198   }
4199   // See if the method type implied by the invoke instruction matches the access flags for the
4200   // target method. The flags for METHOD_POLYMORPHIC are based on there being precisely two
4201   // signature polymorphic methods supported by the run-time which are native methods with variable
4202   // arguments.
4203   if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) ||
4204       (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
4205       ((method_type == METHOD_SUPER ||
4206         method_type == METHOD_VIRTUAL ||
4207         method_type == METHOD_INTERFACE) && res_method->IsDirect()) ||
4208       ((method_type == METHOD_POLYMORPHIC) &&
4209        (!res_method->IsNative() || !res_method->IsVarargs()))) {
4210     Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method "
4211                                        "type of " << res_method->PrettyMethod();
4212     return nullptr;
4213   }
4214   // Make sure we weren't expecting to fail.
4215   DCHECK(!must_fail) << "invoke type (" << method_type << ")"
4216                      << klass->PrettyDescriptor() << "."
4217                      << dex_file_->GetMethodName(method_id) << " "
4218                      << dex_file_->GetMethodSignature(method_id) << " unexpectedly resolved to "
4219                      << res_method->PrettyMethod() << " without error. Initially this method was "
4220                      << "not found so we were expecting to fail for some reason.";
4221   return res_method;
4222 }
4223 
4224 template <bool kVerifierDebug>
4225 template <class T>
VerifyInvocationArgsFromIterator(T * it,const Instruction * inst,MethodType method_type,bool is_range,ArtMethod * res_method)4226 ArtMethod* MethodVerifier<kVerifierDebug>::VerifyInvocationArgsFromIterator(
4227     T* it, const Instruction* inst, MethodType method_type, bool is_range, ArtMethod* res_method) {
4228   DCHECK_EQ(!is_range, inst->HasVarArgs());
4229 
4230   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
4231   // match the call to the signature. Also, we might be calling through an abstract method
4232   // definition (which doesn't have register count values).
4233   const size_t expected_args = inst->VRegA();
4234   /* caught by static verifier */
4235   DCHECK(is_range || expected_args <= 5);
4236 
4237   if (expected_args > code_item_accessor_.OutsSize()) {
4238     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
4239                                       << ") exceeds outsSize ("
4240                                       << code_item_accessor_.OutsSize() << ")";
4241     return nullptr;
4242   }
4243 
4244   /*
4245    * Check the "this" argument, which must be an instance of the class that declared the method.
4246    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
4247    * rigorous check here (which is okay since we have to do it at runtime).
4248    */
4249   if (method_type != METHOD_STATIC) {
4250     const RegType& actual_arg_type = GetInvocationThis(inst);
4251     if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
4252       CHECK(flags_.have_pending_hard_failure_);
4253       return nullptr;
4254     }
4255     bool is_init = false;
4256     if (actual_arg_type.IsUninitializedTypes()) {
4257       if (res_method != nullptr) {
4258         if (!res_method->IsConstructor()) {
4259           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
4260           return nullptr;
4261         }
4262       } else {
4263         // Check whether the name of the called method is "<init>"
4264         const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
4265         if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) {
4266           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
4267           return nullptr;
4268         }
4269       }
4270       is_init = true;
4271     }
4272     const RegType& adjusted_type = is_init
4273                                        ? GetRegTypeCache()->FromUninitialized(actual_arg_type)
4274                                        : actual_arg_type;
4275     if (method_type != METHOD_INTERFACE && !adjusted_type.IsZeroOrNull()) {
4276       // Get the referenced class first. This is fast because it's already cached by the type
4277       // index due to method resolution. It is usually the resolved method's declaring class.
4278       const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
4279       const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
4280       const RegType* res_method_class = &reg_types_.FromTypeIndex(class_idx);
4281       DCHECK_IMPLIES(res_method != nullptr,
4282                      res_method_class->IsJavaLangObject() || res_method_class->IsReference());
4283       DCHECK_IMPLIES(res_method != nullptr && res_method_class->IsJavaLangObject(),
4284                      res_method->GetDeclaringClass()->IsObjectClass());
4285       // Miranda methods have the declaring interface as their declaring class, not the abstract
4286       // class. It would be wrong to use this for the type check (interface type checks are
4287       // postponed to runtime).
4288       if (res_method != nullptr && res_method_class->IsReference() && !res_method->IsMiranda()) {
4289         ObjPtr<mirror::Class> klass = res_method->GetDeclaringClass();
4290         if (res_method_class->GetClass() != klass) {
4291           // The resolved method is in a superclass, not directly in the referenced class.
4292           res_method_class = &reg_types_.FromClass(klass);
4293         }
4294       }
4295       if (!IsAssignableFrom(*res_method_class, adjusted_type)) {
4296         Fail(adjusted_type.IsUnresolvedTypes()
4297                  ? VERIFY_ERROR_UNRESOLVED_TYPE_CHECK
4298                  : VERIFY_ERROR_BAD_CLASS_HARD)
4299             << "'this' argument '" << actual_arg_type << "' not instance of '"
4300             << *res_method_class << "'";
4301         // Continue on soft failures. We need to find possible hard failures to avoid problems in
4302         // the compiler.
4303         if (flags_.have_pending_hard_failure_) {
4304           return nullptr;
4305         }
4306       }
4307     }
4308   }
4309 
4310   uint32_t arg[5];
4311   if (!is_range) {
4312     inst->GetVarArgs(arg);
4313   }
4314   uint32_t sig_registers = (method_type == METHOD_STATIC) ? 0 : 1;
4315   for ( ; it->HasNext(); it->Next()) {
4316     if (sig_registers >= expected_args) {
4317       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() <<
4318           " argument registers, method signature has " << sig_registers + 1 << " or more";
4319       return nullptr;
4320     }
4321 
4322     const RegType& reg_type = reg_types_.FromTypeIndex(it->GetTypeIdx());
4323     uint32_t get_reg = is_range ? inst->VRegC() + static_cast<uint32_t>(sig_registers) :
4324         arg[sig_registers];
4325     if (reg_type.IsIntegralTypes()) {
4326       const RegType& src_type = work_line_->GetRegisterType(this, get_reg);
4327       if (!src_type.IsIntegralTypes()) {
4328         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
4329             << " but expected " << reg_type;
4330         return nullptr;
4331       }
4332     } else {
4333       if (!VerifyRegisterType(get_reg, reg_type)) {
4334         // Continue on soft failures. We need to find possible hard failures to avoid problems in
4335         // the compiler.
4336         if (flags_.have_pending_hard_failure_) {
4337           return nullptr;
4338         }
4339       } else if (reg_type.IsLongOrDoubleTypes()) {
4340         // Check that registers are consecutive (for non-range invokes). Invokes are the only
4341         // instructions not specifying register pairs by the first component, but require them
4342         // nonetheless. Only check when there's an actual register in the parameters. If there's
4343         // none, this will fail below.
4344         if (!is_range && sig_registers + 1 < expected_args) {
4345           uint32_t second_reg = arg[sig_registers + 1];
4346           if (second_reg != get_reg + 1) {
4347             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, long or double parameter "
4348                 "at index " << sig_registers << " is not a pair: " << get_reg << " + "
4349                 << second_reg << ".";
4350             return nullptr;
4351           }
4352         }
4353       }
4354     }
4355     sig_registers += reg_type.IsLongOrDoubleTypes() ?  2 : 1;
4356   }
4357   if (expected_args != sig_registers) {
4358     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args <<
4359         " argument registers, method signature has " << sig_registers;
4360     return nullptr;
4361   }
4362   return res_method;
4363 }
4364 
4365 template <bool kVerifierDebug>
VerifyInvocationArgsUnresolvedMethod(const Instruction * inst,MethodType method_type,bool is_range)4366 void MethodVerifier<kVerifierDebug>::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst,
4367                                                                           MethodType method_type,
4368                                                                           bool is_range) {
4369   // As the method may not have been resolved, make this static check against what we expect.
4370   // The main reason for this code block is to fail hard when we find an illegal use, e.g.,
4371   // wrong number of arguments or wrong primitive types, even if the method could not be resolved.
4372   const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
4373   DexFileParameterIterator it(*dex_file_,
4374                               dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_));
4375   VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, nullptr);
4376 }
4377 
4378 template <bool kVerifierDebug>
CheckCallSite(uint32_t call_site_idx)4379 bool MethodVerifier<kVerifierDebug>::CheckCallSite(uint32_t call_site_idx) {
4380   if (call_site_idx >= dex_file_->NumCallSiteIds()) {
4381     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Bad call site id #" << call_site_idx
4382                                       << " >= " << dex_file_->NumCallSiteIds();
4383     return false;
4384   }
4385 
4386   CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx));
4387   // Check essential arguments are provided. The dex file verifier has verified indices of the
4388   // main values (method handle, name, method_type).
4389   static const size_t kRequiredArguments = 3;
4390   if (it.Size() < kRequiredArguments) {
4391     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
4392                                       << " has too few arguments: "
4393                                       << it.Size() << " < " << kRequiredArguments;
4394     return false;
4395   }
4396 
4397   std::pair<const EncodedArrayValueIterator::ValueType, size_t> type_and_max[kRequiredArguments] =
4398       { { EncodedArrayValueIterator::ValueType::kMethodHandle, dex_file_->NumMethodHandles() },
4399         { EncodedArrayValueIterator::ValueType::kString, dex_file_->NumStringIds() },
4400         { EncodedArrayValueIterator::ValueType::kMethodType, dex_file_->NumProtoIds() }
4401       };
4402   uint32_t index[kRequiredArguments];
4403 
4404   // Check arguments have expected types and are within permitted ranges.
4405   for (size_t i = 0; i < kRequiredArguments; ++i) {
4406     if (it.GetValueType() != type_and_max[i].first) {
4407       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site id #" << call_site_idx
4408                                         << " argument " << i << " has wrong type "
4409                                         << it.GetValueType() << "!=" << type_and_max[i].first;
4410       return false;
4411     }
4412     index[i] = static_cast<uint32_t>(it.GetJavaValue().i);
4413     if (index[i] >= type_and_max[i].second) {
4414       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site id #" << call_site_idx
4415                                         << " argument " << i << " bad index "
4416                                         << index[i] << " >= " << type_and_max[i].second;
4417       return false;
4418     }
4419     it.Next();
4420   }
4421 
4422   // Check method handle kind is valid.
4423   const dex::MethodHandleItem& mh = dex_file_->GetMethodHandle(index[0]);
4424   if (mh.method_handle_type_ != static_cast<uint16_t>(DexFile::MethodHandleType::kInvokeStatic)) {
4425     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
4426                                       << " argument 0 method handle type is not InvokeStatic: "
4427                                       << mh.method_handle_type_;
4428     return false;
4429   }
4430   return true;
4431 }
4432 
4433 template <bool kVerifierDebug>
VerifyInvocationArgs(const Instruction * inst,MethodType method_type,bool is_range)4434 ArtMethod* MethodVerifier<kVerifierDebug>::VerifyInvocationArgs(
4435     const Instruction* inst, MethodType method_type, bool is_range) {
4436   // Resolve the method. This could be an abstract or concrete method depending on what sort of call
4437   // we're making.
4438   const uint32_t method_idx = GetMethodIdxOfInvoke(inst);
4439   ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type);
4440   if (res_method == nullptr) {  // error or class is unresolved
4441     // Check what we can statically.
4442     if (!flags_.have_pending_hard_failure_) {
4443       VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4444     }
4445     return nullptr;
4446   }
4447 
4448   // If we're using invoke-super(method), make sure that the executing method's class' superclass
4449   // has a vtable entry for the target method. Or the target is on a interface.
4450   if (method_type == METHOD_SUPER) {
4451     dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
4452     const RegType& reference_type = reg_types_.FromTypeIndex(class_idx);
4453     if (reference_type.IsUnresolvedTypes()) {
4454       // We cannot differentiate on whether this is a class change error or just
4455       // a missing method. This will be handled at runtime.
4456       Fail(VERIFY_ERROR_NO_METHOD) << "Unable to find referenced class from invoke-super";
4457       VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4458       return nullptr;
4459     }
4460     DCHECK(reference_type.IsJavaLangObject() || reference_type.IsReference());
4461     if (reference_type.IsReference() && reference_type.GetClass()->IsInterface()) {
4462       if (!GetDeclaringClass().HasClass()) {
4463         Fail(VERIFY_ERROR_NO_CLASS) << "Unable to resolve the full class of 'this' used in an"
4464                                     << "interface invoke-super";
4465         VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4466         return nullptr;
4467       } else if (!IsStrictlyAssignableFrom(reference_type, GetDeclaringClass())) {
4468         Fail(VERIFY_ERROR_CLASS_CHANGE)
4469             << "invoke-super in " << mirror::Class::PrettyClass(GetDeclaringClass().GetClass())
4470             << " in method "
4471             << dex_file_->PrettyMethod(dex_method_idx_) << " to method "
4472             << dex_file_->PrettyMethod(method_idx) << " references "
4473             << "non-super-interface type " << mirror::Class::PrettyClass(reference_type.GetClass());
4474         VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4475         return nullptr;
4476       }
4477     } else {
4478       if (UNLIKELY(!class_def_.superclass_idx_.IsValid())) {
4479         // Verification error in `j.l.Object` leads to a hang while trying to verify
4480         // the exception class. It is better to crash directly.
4481         LOG(FATAL) << "No superclass for invoke-super from "
4482                    << dex_file_->PrettyMethod(dex_method_idx_)
4483                    << " to super " << res_method->PrettyMethod() << ".";
4484         UNREACHABLE();
4485       }
4486       const RegType& super = reg_types_.FromTypeIndex(class_def_.superclass_idx_);
4487       if (super.IsUnresolvedTypes()) {
4488         Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
4489                                     << dex_file_->PrettyMethod(dex_method_idx_)
4490                                     << " to super " << res_method->PrettyMethod();
4491         VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4492         return nullptr;
4493       }
4494       if (!IsStrictlyAssignableFrom(reference_type, GetDeclaringClass()) ||
4495           (res_method->GetMethodIndex() >= GetRegTypeClass(super)->GetVTableLength())) {
4496         Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
4497                                     << dex_file_->PrettyMethod(dex_method_idx_)
4498                                     << " to super " << super
4499                                     << "." << res_method->GetName()
4500                                     << res_method->GetSignature();
4501         VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
4502         return nullptr;
4503       }
4504     }
4505   }
4506 
4507   dex::ProtoIndex proto_idx;
4508   if (UNLIKELY(method_type == METHOD_POLYMORPHIC)) {
4509     // Process the signature of the calling site that is invoking the method handle.
4510     proto_idx = dex::ProtoIndex(inst->VRegH());
4511   } else {
4512     // Process the target method's signature.
4513     proto_idx = dex_file_->GetMethodId(method_idx).proto_idx_;
4514   }
4515   DexFileParameterIterator it(*dex_file_, dex_file_->GetProtoId(proto_idx));
4516   ArtMethod* verified_method =
4517       VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method);
4518 
4519   if (verified_method != nullptr && !verified_method->GetDeclaringClass()->IsInterface()) {
4520     CheckForFinalAbstractClass(res_method->GetDeclaringClass());
4521   }
4522 
4523   return verified_method;
4524 }
4525 
4526 template <bool kVerifierDebug>
CheckSignaturePolymorphicMethod(ArtMethod * method)4527 bool MethodVerifier<kVerifierDebug>::CheckSignaturePolymorphicMethod(ArtMethod* method) {
4528   ObjPtr<mirror::Class> klass = method->GetDeclaringClass();
4529   const char* method_name = method->GetName();
4530 
4531   const char* expected_return_descriptor;
4532   ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = GetClassLinker()->GetClassRoots();
4533   if (klass == GetClassRoot<mirror::MethodHandle>(class_roots)) {
4534     expected_return_descriptor = mirror::MethodHandle::GetReturnTypeDescriptor(method_name);
4535   } else if (klass == GetClassRoot<mirror::VarHandle>(class_roots)) {
4536     expected_return_descriptor = mirror::VarHandle::GetReturnTypeDescriptor(method_name);
4537   } else {
4538     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4539         << "Signature polymorphic method in unsuppported class: " << klass->PrettyDescriptor();
4540     return false;
4541   }
4542 
4543   if (expected_return_descriptor == nullptr) {
4544     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4545         << "Signature polymorphic method name invalid: " << method_name;
4546     return false;
4547   }
4548 
4549   const dex::TypeList* types = method->GetParameterTypeList();
4550   if (types->Size() != 1) {
4551     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4552         << "Signature polymorphic method has too many arguments " << types->Size() << " != 1";
4553     return false;
4554   }
4555 
4556   const dex::TypeIndex argument_type_index = types->GetTypeItem(0).type_idx_;
4557   const char* argument_descriptor = method->GetTypeDescriptorFromTypeIdx(argument_type_index);
4558   if (strcmp(argument_descriptor, "[Ljava/lang/Object;") != 0) {
4559     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4560         << "Signature polymorphic method has unexpected argument type: " << argument_descriptor;
4561     return false;
4562   }
4563 
4564   const char* return_descriptor = method->GetReturnTypeDescriptor();
4565   if (strcmp(return_descriptor, expected_return_descriptor) != 0) {
4566     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4567         << "Signature polymorphic method has unexpected return type: " << return_descriptor
4568         << " != " << expected_return_descriptor;
4569     return false;
4570   }
4571 
4572   return true;
4573 }
4574 
4575 template <bool kVerifierDebug>
CheckSignaturePolymorphicReceiver(const Instruction * inst)4576 bool MethodVerifier<kVerifierDebug>::CheckSignaturePolymorphicReceiver(const Instruction* inst) {
4577   const RegType& this_type = GetInvocationThis(inst);
4578   if (this_type.IsZeroOrNull()) {
4579     /* null pointer always passes (and always fails at run time) */
4580     return true;
4581   } else if (!this_type.IsNonZeroReferenceTypes()) {
4582     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4583         << "invoke-polymorphic receiver is not a reference: "
4584         << this_type;
4585     return false;
4586   } else if (this_type.IsUninitializedReference()) {
4587     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4588         << "invoke-polymorphic receiver is uninitialized: "
4589         << this_type;
4590     return false;
4591   } else if (!this_type.HasClass()) {
4592     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4593         << "invoke-polymorphic receiver has no class: "
4594         << this_type;
4595     return false;
4596   } else {
4597     ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots = GetClassLinker()->GetClassRoots();
4598     if (!this_type.GetClass()->IsSubClass(GetClassRoot<mirror::MethodHandle>(class_roots)) &&
4599         !this_type.GetClass()->IsSubClass(GetClassRoot<mirror::VarHandle>(class_roots))) {
4600       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4601           << "invoke-polymorphic receiver is not a subclass of MethodHandle or VarHandle: "
4602           << this_type;
4603       return false;
4604     }
4605   }
4606   return true;
4607 }
4608 
4609 template <bool kVerifierDebug>
VerifyNewArray(const Instruction * inst,bool is_filled,bool is_range)4610 void MethodVerifier<kVerifierDebug>::VerifyNewArray(const Instruction* inst,
4611                                                     bool is_filled,
4612                                                     bool is_range) {
4613   dex::TypeIndex type_idx;
4614   if (!is_filled) {
4615     DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY);
4616     type_idx = dex::TypeIndex(inst->VRegC_22c());
4617   } else if (!is_range) {
4618     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY);
4619     type_idx = dex::TypeIndex(inst->VRegB_35c());
4620   } else {
4621     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
4622     type_idx = dex::TypeIndex(inst->VRegB_3rc());
4623   }
4624   const RegType& res_type = ResolveClass<CheckAccess::kYes>(type_idx);
4625   if (res_type.IsConflict()) {  // bad class
4626     DCHECK_NE(failures_.size(), 0U);
4627   } else {
4628     // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
4629     if (!res_type.IsArrayTypes()) {
4630       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type;
4631     } else if (!is_filled) {
4632       /* make sure "size" register is valid type */
4633       VerifyRegisterType(inst->VRegB_22c(), RegType::Kind::kInteger);
4634       /* set register type to array class */
4635       work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_22c(), res_type);
4636     } else {
4637       DCHECK(!res_type.IsUnresolvedMergedReference());
4638       // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
4639       // the list and fail. It's legal, if silly, for arg_count to be zero.
4640       const RegType& expected_type = reg_types_.GetComponentType(res_type);
4641       uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
4642       uint32_t arg[5];
4643       if (!is_range) {
4644         inst->GetVarArgs(arg);
4645       }
4646       for (size_t ui = 0; ui < arg_count; ui++) {
4647         uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui];
4648         VerifyRegisterType(get_reg, expected_type);
4649         if (flags_.have_pending_hard_failure_) {
4650           // Don't continue on hard failures.
4651           return;
4652         }
4653       }
4654       // filled-array result goes into "result" register
4655       work_line_->SetResultRegisterType(this, res_type);
4656     }
4657   }
4658 }
4659 
4660 template <bool kVerifierDebug>
VerifyAGet(const Instruction * inst,const RegType & insn_type,bool is_primitive)4661 void MethodVerifier<kVerifierDebug>::VerifyAGet(const Instruction* inst,
4662                                                 const RegType& insn_type,
4663                                                 bool is_primitive) {
4664   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
4665   if (!index_type.IsArrayIndexTypes()) {
4666     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
4667   } else {
4668     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
4669     if (array_type.IsZeroOrNull()) {
4670       // Null array class; this code path will fail at runtime. Infer a merge-able type from the
4671       // instruction type.
4672       if (!is_primitive) {
4673         work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_23x(), reg_types_.Null());
4674       } else if (insn_type.IsInteger()) {
4675         // Pick a non-zero constant (to distinguish with null) that can fit in any primitive.
4676         // We cannot use 'insn_type' as it could be a float array or an int array.
4677         work_line_->SetRegisterType(inst->VRegA_23x(), DetermineCat1Constant(1));
4678       } else if (insn_type.IsCategory1Types()) {
4679         // Category 1
4680         // The 'insn_type' is exactly the type we need.
4681         work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_23x(), insn_type);
4682       } else {
4683         // Category 2
4684         work_line_->SetRegisterTypeWide(inst->VRegA_23x(),
4685                                         reg_types_.ConstantLo(),
4686                                         reg_types_.ConstantHi());
4687       }
4688     } else if (!array_type.IsArrayTypes()) {
4689       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
4690     } else if (array_type.IsUnresolvedMergedReference()) {
4691       // Unresolved array types must be reference array types.
4692       if (is_primitive) {
4693         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
4694                     << " source for category 1 aget";
4695       } else {
4696         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aget for " << array_type
4697             << " because of missing class";
4698         // Approximate with java.lang.Object[].
4699         work_line_->SetRegisterType(inst->VRegA_23x(), RegType::Kind::kJavaLangObject);
4700       }
4701     } else {
4702       /* verify the class */
4703       const RegType& component_type = reg_types_.GetComponentType(array_type);
4704       if (!component_type.IsReferenceTypes() && !is_primitive) {
4705         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
4706             << " source for aget-object";
4707       } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) {
4708         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
4709             << " source for category 1 aget";
4710       } else if (is_primitive && !insn_type.Equals(component_type) &&
4711                  !((insn_type.IsInteger() && component_type.IsFloat()) ||
4712                  (insn_type.IsLongLo() && component_type.IsDoubleLo()))) {
4713         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type
4714             << " incompatible with aget of type " << insn_type;
4715       } else {
4716         // Use knowledge of the field type which is stronger than the type inferred from the
4717         // instruction, which can't differentiate object types and ints from floats, longs from
4718         // doubles.
4719         if (!component_type.IsLowHalf()) {
4720           work_line_->SetRegisterType<LockOp::kClear>(inst->VRegA_23x(), component_type);
4721         } else {
4722           work_line_->SetRegisterTypeWide(inst->VRegA_23x(), component_type,
4723                                           component_type.HighHalf(&reg_types_));
4724         }
4725       }
4726     }
4727   }
4728 }
4729 
4730 template <bool kVerifierDebug>
VerifyPrimitivePut(const RegType & target_type,uint32_t vregA)4731 void MethodVerifier<kVerifierDebug>::VerifyPrimitivePut(const RegType& target_type,
4732                                                         uint32_t vregA) {
4733   // Primitive assignability rules are weaker than regular assignability rules.
4734   bool value_compatible;
4735   const RegType& value_type = work_line_->GetRegisterType(this, vregA);
4736   if (target_type.IsIntegralTypes()) {
4737     value_compatible = value_type.IsIntegralTypes();
4738   } else if (target_type.IsFloat()) {
4739     value_compatible = value_type.IsFloatTypes();
4740   } else if (target_type.IsLongLo()) {
4741     DCHECK_LT(vregA + 1, work_line_->NumRegs());
4742     const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
4743     value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
4744   } else if (target_type.IsDoubleLo()) {
4745     DCHECK_LT(vregA + 1, work_line_->NumRegs());
4746     const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
4747     value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
4748   } else {
4749     value_compatible = false;  // unused
4750   }
4751   if (!value_compatible) {
4752     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
4753         << " of type " << value_type << " but expected " << target_type << " for put";
4754     return;
4755   }
4756 }
4757 
4758 template <bool kVerifierDebug>
VerifyAPut(const Instruction * inst,const RegType & insn_type,bool is_primitive)4759 void MethodVerifier<kVerifierDebug>::VerifyAPut(const Instruction* inst,
4760                                                 const RegType& insn_type,
4761                                                 bool is_primitive) {
4762   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
4763   if (!index_type.IsArrayIndexTypes()) {
4764     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
4765   } else {
4766     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
4767     if (array_type.IsZeroOrNull()) {
4768       // Null array type; this code path will fail at runtime.
4769       // Still check that the given value matches the instruction's type.
4770       // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed
4771       //       and fits multiple register types.
4772       const RegType* modified_reg_type = &insn_type;
4773       if ((modified_reg_type == &reg_types_.Integer()) ||
4774           (modified_reg_type == &reg_types_.LongLo())) {
4775         // May be integer or float | long or double. Overwrite insn_type accordingly.
4776         const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x());
4777         if (modified_reg_type == &reg_types_.Integer()) {
4778           if (&value_type == &reg_types_.Float()) {
4779             modified_reg_type = &value_type;
4780           }
4781         } else {
4782           if (&value_type == &reg_types_.DoubleLo()) {
4783             modified_reg_type = &value_type;
4784           }
4785         }
4786       }
4787       VerifyRegisterType(inst->VRegA_23x(), *modified_reg_type);
4788     } else if (!array_type.IsArrayTypes()) {
4789       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
4790     } else if (array_type.IsUnresolvedMergedReference()) {
4791       // Unresolved array types must be reference array types.
4792       if (is_primitive) {
4793         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "aput insn has type '" << insn_type
4794                                           << "' but unresolved type '" << array_type << "'";
4795       } else {
4796         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aput for " << array_type
4797                                     << " because of missing class";
4798       }
4799     } else {
4800       const RegType& component_type = reg_types_.GetComponentType(array_type);
4801       const uint32_t vregA = inst->VRegA_23x();
4802       if (is_primitive) {
4803         bool instruction_compatible;
4804         if (component_type.IsIntegralTypes()) {
4805           instruction_compatible = component_type.Equals(insn_type);
4806         } else if (component_type.IsFloat()) {
4807           instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
4808         } else if (component_type.IsLongLo()) {
4809           instruction_compatible = insn_type.IsLongLo();
4810         } else if (component_type.IsDoubleLo()) {
4811           instruction_compatible = insn_type.IsLongLo();  // no put-double, so expect put-long
4812         } else {
4813           instruction_compatible = false;  // reference with primitive store
4814         }
4815         if (!instruction_compatible) {
4816           // This is a global failure rather than a class change failure as the instructions and
4817           // the descriptors for the type should have been consistent within the same file at
4818           // compile time.
4819           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "aput insn has type '" << insn_type
4820               << "' but expected type '" << component_type << "'";
4821           return;
4822         }
4823         VerifyPrimitivePut(component_type, vregA);
4824       } else {
4825         if (!component_type.IsReferenceTypes()) {
4826           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
4827               << " source for aput-object";
4828         } else {
4829           // The instruction agrees with the type of array, confirm the value to be stored does too
4830           // Note: we use the instruction type (rather than the component type) for aput-object as
4831           // incompatible classes will be caught at runtime as an array store exception
4832           VerifyRegisterType(vregA, insn_type);
4833         }
4834       }
4835     }
4836   }
4837 }
4838 
4839 template <bool kVerifierDebug>
GetStaticField(uint32_t field_idx,bool is_put)4840 ArtField* MethodVerifier<kVerifierDebug>::GetStaticField(uint32_t field_idx, bool is_put) {
4841   const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx);
4842   // Check access to class
4843   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
4844   // Dex file verifier ensures that field ids reference valid descriptors starting with `L`.
4845   DCHECK(klass_type.IsJavaLangObject() ||
4846          klass_type.IsReference() ||
4847          klass_type.IsUnresolvedReference());
4848   if (klass_type.IsUnresolvedReference()) {
4849     // Accessibility checks depend on resolved fields.
4850     DCHECK(klass_type.Equals(GetDeclaringClass()) ||
4851            !failures_.empty() ||
4852            IsSdkVersionSetAndLessThan(api_level_, SdkVersion::kP));
4853     return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
4854   }
4855   ClassLinker* class_linker = GetClassLinker();
4856   ArtField* field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_);
4857   if (field == nullptr) {
4858     VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
4859               << dex_file_->GetFieldName(field_id) << ") in "
4860               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
4861     DCHECK(self_->IsExceptionPending());
4862     self_->ClearException();
4863     Fail(VERIFY_ERROR_NO_FIELD)
4864         << "field " << dex_file_->PrettyField(field_idx)
4865         << " not found in the resolved type " << klass_type;
4866     return nullptr;
4867   } else if (!field->IsStatic()) {
4868     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() << " to be static";
4869     return nullptr;
4870   }
4871 
4872   return GetISFieldCommon(field, is_put);
4873 }
4874 
4875 template <bool kVerifierDebug>
GetInstanceField(uint32_t vregB,uint32_t field_idx,bool is_put)4876 ArtField* MethodVerifier<kVerifierDebug>::GetInstanceField(uint32_t vregB,
4877                                                            uint32_t field_idx,
4878                                                            bool is_put) {
4879   const RegType& obj_type = work_line_->GetRegisterType(this, vregB);
4880   if (!obj_type.IsReferenceTypes()) {
4881     // Trying to read a field from something that isn't a reference.
4882     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4883         << "instance field access on object that has non-reference type " << obj_type;
4884     return nullptr;
4885   }
4886   const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx);
4887   // Check access to class.
4888   const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
4889   // Dex file verifier ensures that field ids reference valid descriptors starting with `L`.
4890   DCHECK(klass_type.IsJavaLangObject() ||
4891          klass_type.IsReference() ||
4892          klass_type.IsUnresolvedReference());
4893   ArtField* field = nullptr;
4894   if (!klass_type.IsUnresolvedReference()) {
4895     ClassLinker* class_linker = GetClassLinker();
4896     field = class_linker->ResolveFieldJLS(field_idx, dex_cache_, class_loader_);
4897     if (field == nullptr) {
4898       VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
4899                      << dex_file_->GetFieldName(field_id) << ") in "
4900                      << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
4901       DCHECK(self_->IsExceptionPending());
4902       self_->ClearException();
4903     }
4904   }
4905 
4906   if (obj_type.IsUninitializedTypes()) {
4907     // One is not allowed to access fields on uninitialized references, except to write to
4908     // fields in the constructor (before calling another constructor). We strictly check
4909     // that the field id references the class directly instead of some subclass.
4910     if (is_put && field_id.class_idx_ == GetClassDef().class_idx_) {
4911       if (obj_type.IsUnresolvedUninitializedThisReference()) {
4912         DCHECK(GetDeclaringClass().IsUnresolvedReference());
4913         DCHECK(GetDeclaringClass().Equals(reg_types_.FromUninitialized(obj_type)));
4914         ClassAccessor accessor(*dex_file_, GetClassDef());
4915         auto it = std::find_if(
4916             accessor.GetInstanceFields().begin(),
4917             accessor.GetInstanceFields().end(),
4918             [field_idx] (const ClassAccessor::Field& f) { return f.GetIndex() == field_idx; });
4919         if (it != accessor.GetInstanceFields().end()) {
4920           // There are no soft failures to report anymore, other than the class being unresolved.
4921           return nullptr;
4922         }
4923       } else if (obj_type.IsUninitializedThisReference()) {
4924         DCHECK(GetDeclaringClass().IsJavaLangObject() || GetDeclaringClass().IsReference());
4925         DCHECK(GetDeclaringClass().Equals(reg_types_.FromUninitialized(obj_type)));
4926         if (field != nullptr &&
4927             field->GetDeclaringClass() == GetDeclaringClass().GetClass() &&
4928             !field->IsStatic()) {
4929           // The field is now fully verified against the `obj_type`.
4930           return field;
4931         }
4932       }
4933     }
4934     // Allow `iget` on resolved uninitialized `this` for app compatibility.
4935     // This is rejected by the RI but there are Android apps that actually have such `iget`s.
4936     // TODO: Should we start rejecting such bytecode based on the SDK level?
4937     if (!is_put &&
4938         obj_type.IsUninitializedThisReference() &&
4939         field != nullptr &&
4940         field->GetDeclaringClass() == GetDeclaringClass().GetClass()) {
4941       return field;
4942     }
4943     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
4944         << "cannot access instance field " << dex_file_->PrettyField(field_idx)
4945         << " of a not fully initialized object within the context of "
4946         << dex_file_->PrettyMethod(dex_method_idx_);
4947     return nullptr;
4948   }
4949 
4950   if (klass_type.IsUnresolvedReference()) {
4951     // Accessibility checks depend on resolved fields.
4952     DCHECK(klass_type.Equals(GetDeclaringClass()) ||
4953            !failures_.empty() ||
4954            IsSdkVersionSetAndLessThan(api_level_, SdkVersion::kP));
4955     return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
4956   } else if (field == nullptr) {
4957     Fail(VERIFY_ERROR_NO_FIELD)
4958         << "field " << dex_file_->PrettyField(field_idx)
4959         << " not found in the resolved type " << klass_type;
4960     return nullptr;
4961   } else if (obj_type.IsZeroOrNull()) {
4962     // Cannot infer and check type, however, access will cause null pointer exception.
4963     // Fall through into a few last soft failure checks below.
4964   } else {
4965     ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
4966     DCHECK_IMPLIES(klass_type.IsJavaLangObject(), klass->IsObjectClass());
4967     const RegType& field_klass =
4968         LIKELY(klass_type.IsJavaLangObject() || klass_type.GetClass() == klass)
4969             ? klass_type
4970             : reg_types_.FromClass(klass);
4971     DCHECK(!obj_type.IsUninitializedTypes());
4972     if (!IsAssignableFrom(field_klass, obj_type)) {
4973       // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class
4974       // of C1. For resolution to occur the declared class of the field must be compatible with
4975       // obj_type, we've discovered this wasn't so, so report the field didn't exist.
4976       DCHECK(!field_klass.IsUnresolvedTypes());
4977       Fail(obj_type.IsUnresolvedTypes()
4978                  ? VERIFY_ERROR_UNRESOLVED_TYPE_CHECK
4979                  : VERIFY_ERROR_BAD_CLASS_HARD)
4980           << "cannot access instance field " << field->PrettyField()
4981           << " from object of type " << obj_type;
4982       return nullptr;
4983     }
4984   }
4985 
4986   // Few last soft failure checks.
4987   if (field->IsStatic()) {
4988     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField()
4989                                     << " to not be static";
4990     return nullptr;
4991   }
4992 
4993   return GetISFieldCommon(field, is_put);
4994 }
4995 
4996 template <bool kVerifierDebug>
GetISFieldCommon(ArtField * field,bool is_put)4997 ArtField* MethodVerifier<kVerifierDebug>::GetISFieldCommon(ArtField* field, bool is_put) {
4998   DCHECK(field != nullptr);
4999   if (!CanAccessMember(field->GetDeclaringClass(), field->GetAccessFlags())) {
5000     Fail(VERIFY_ERROR_ACCESS_FIELD)
5001         << "cannot access " << (field->IsStatic() ? "static" : "instance") << " field "
5002         << field->PrettyField() << " from " << GetDeclaringClass();
5003     return nullptr;
5004   }
5005   if (is_put && field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
5006     Fail(VERIFY_ERROR_ACCESS_FIELD)
5007         << "cannot modify final field " << field->PrettyField()
5008         << " from other class " << GetDeclaringClass();
5009     return nullptr;
5010   }
5011   CheckForFinalAbstractClass(field->GetDeclaringClass());
5012   return field;
5013 }
5014 
5015 template <bool kVerifierDebug>
5016 template <FieldAccessType kAccType>
VerifyISFieldAccess(const Instruction * inst,bool is_primitive,bool is_static)5017 void MethodVerifier<kVerifierDebug>::VerifyISFieldAccess(const Instruction* inst,
5018                                                          bool is_primitive,
5019                                                          bool is_static) {
5020   uint32_t field_idx = GetFieldIdxOfFieldAccess(inst, is_static);
5021   DCHECK(!flags_.have_pending_hard_failure_);
5022   ArtField* field;
5023   if (is_static) {
5024     field = GetStaticField(field_idx, kAccType == FieldAccessType::kAccPut);
5025   } else {
5026     field = GetInstanceField(inst->VRegB_22c(), field_idx, kAccType == FieldAccessType::kAccPut);
5027     if (UNLIKELY(flags_.have_pending_hard_failure_)) {
5028       return;
5029     }
5030   }
5031   DCHECK(!flags_.have_pending_hard_failure_);
5032   const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx);
5033   DCHECK_IMPLIES(field == nullptr && IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kP),
5034                  field_id.class_idx_ == class_def_.class_idx_ || !failures_.empty());
5035   const RegType& field_type = reg_types_.FromTypeIndex(field_id.type_idx_);
5036   const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
5037   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
5038                 "Unexpected third access type");
5039   if (kAccType == FieldAccessType::kAccPut) {
5040     // sput or iput.
5041     if (is_primitive) {
5042       VerifyPrimitivePut(field_type, vregA);
5043     } else {
5044       VerifyRegisterType(vregA, field_type);
5045     }
5046   } else if (kAccType == FieldAccessType::kAccGet) {
5047     // sget or iget.
5048     if (!field_type.IsLowHalf()) {
5049       work_line_->SetRegisterType<LockOp::kClear>(vregA, field_type);
5050     } else {
5051       work_line_->SetRegisterTypeWide(vregA, field_type, field_type.HighHalf(&reg_types_));
5052     }
5053   } else {
5054     LOG(FATAL) << "Unexpected case.";
5055   }
5056 }
5057 
5058 template <bool kVerifierDebug>
UpdateRegisters(uint32_t next_insn,RegisterLine * merge_line,bool update_merge_line)5059 bool MethodVerifier<kVerifierDebug>::UpdateRegisters(uint32_t next_insn,
5060                                                      RegisterLine* merge_line,
5061                                                      bool update_merge_line) {
5062   bool changed = true;
5063   RegisterLine* target_line = reg_table_.GetLine(next_insn);
5064   if (!GetInstructionFlags(next_insn).IsVisitedOrChanged()) {
5065     /*
5066      * We haven't processed this instruction before, and we haven't touched the registers here, so
5067      * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the
5068      * only way a register can transition out of "unknown", so this is not just an optimization.)
5069      */
5070     target_line->CopyFromLine(merge_line);
5071     if (GetInstructionFlags(next_insn).IsReturn()) {
5072       // Verify that the monitor stack is empty on return.
5073       merge_line->VerifyMonitorStackEmpty(this);
5074 
5075       // For returns we only care about the operand to the return, all other registers are dead.
5076       // Initialize them as conflicts so they don't add to GC and deoptimization information.
5077       const Instruction* ret_inst = &code_item_accessor_.InstructionAt(next_insn);
5078       AdjustReturnLine(this, ret_inst, target_line);
5079       // Directly bail if a hard failure was found.
5080       if (flags_.have_pending_hard_failure_) {
5081         return false;
5082       }
5083     }
5084   } else {
5085     RegisterLineArenaUniquePtr copy;
5086     if (kVerifierDebug) {
5087       copy.reset(RegisterLine::Create(target_line->NumRegs(), allocator_, GetRegTypeCache()));
5088       copy->CopyFromLine(target_line);
5089     }
5090     changed = target_line->MergeRegisters(this, merge_line);
5091     if (flags_.have_pending_hard_failure_) {
5092       return false;
5093     }
5094     if (kVerifierDebug && changed) {
5095       LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]"
5096                       << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
5097                       << copy->Dump(this) << "  MERGE\n"
5098                       << merge_line->Dump(this) << "  ==\n"
5099                       << target_line->Dump(this);
5100     }
5101     if (update_merge_line && changed) {
5102       merge_line->CopyFromLine(target_line);
5103     }
5104   }
5105   if (changed) {
5106     GetModifiableInstructionFlags(next_insn).SetChanged();
5107   }
5108   return true;
5109 }
5110 
5111 template <bool kVerifierDebug>
GetMethodReturnType()5112 const RegType& MethodVerifier<kVerifierDebug>::GetMethodReturnType() {
5113   if (return_type_ == nullptr) {
5114     const dex::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
5115     const dex::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id);
5116     return_type_ = &reg_types_.FromTypeIndex(proto_id.return_type_idx_);
5117   }
5118   return *return_type_;
5119 }
5120 
5121 template <bool kVerifierDebug>
DetermineCat1Constant(int32_t value)5122 RegType::Kind MethodVerifier<kVerifierDebug>::DetermineCat1Constant(int32_t value) {
5123   // Imprecise constant type.
5124   if (value < -32768) {
5125     return RegType::Kind::kIntegerConstant;
5126   } else if (value < -128) {
5127     return RegType::Kind::kShortConstant;
5128   } else if (value < 0) {
5129     return RegType::Kind::kByteConstant;
5130   } else if (value == 0) {
5131     return RegType::Kind::kZero;
5132   } else if (value == 1) {
5133     return RegType::Kind::kBooleanConstant;
5134   } else if (value < 128) {
5135     return RegType::Kind::kPositiveByteConstant;
5136   } else if (value < 32768) {
5137     return RegType::Kind::kPositiveShortConstant;
5138   } else if (value < 65536) {
5139     return RegType::Kind::kCharConstant;
5140   } else {
5141     return RegType::Kind::kIntegerConstant;
5142   }
5143 }
5144 
5145 template <bool kVerifierDebug>
PotentiallyMarkRuntimeThrow()5146 bool MethodVerifier<kVerifierDebug>::PotentiallyMarkRuntimeThrow() {
5147   if (IsAotMode() || IsSdkVersionSetAndAtLeast(api_level_, SdkVersion::kS_V2)) {
5148     return false;
5149   }
5150   // Compatibility mode: we treat the following code unreachable and the verifier
5151   // will not analyze it.
5152   // The verifier may fail before we touch any instruction, for the signature of a method. So
5153   // add a check.
5154   if (work_insn_idx_ < dex::kDexNoIndex) {
5155     const Instruction& inst = code_item_accessor_.InstructionAt(work_insn_idx_);
5156     Instruction::Code opcode = inst.Opcode();
5157     if (opcode == Instruction::MOVE_EXCEPTION) {
5158       // This is an unreachable handler. The instruction doesn't throw, but we
5159       // mark the method as having a pending runtime throw failure so that
5160       // the compiler does not try to compile it.
5161       Fail(VERIFY_ERROR_RUNTIME_THROW, /* pending_exc= */ false);
5162       return true;
5163     }
5164     // How to handle runtime failures for instructions that are not flagged kThrow.
5165     if ((Instruction::FlagsOf(opcode) & Instruction::kThrow) == 0 &&
5166         !impl::IsCompatThrow(opcode) &&
5167         GetInstructionFlags(work_insn_idx_).IsInTry()) {
5168       if (Runtime::Current()->IsVerifierMissingKThrowFatal()) {
5169         LOG(FATAL) << "Unexpected throw: " << std::hex << work_insn_idx_ << " " << opcode;
5170         UNREACHABLE();
5171       }
5172       // We need to save the work_line if the instruction wasn't throwing before. Otherwise
5173       // we'll try to merge garbage.
5174       // Note: this assumes that Fail is called before we do any work_line modifications.
5175       saved_line_->CopyFromLine(work_line_.get());
5176     }
5177   }
5178   flags_.have_pending_runtime_throw_failure_ = true;
5179   return true;
5180 }
5181 
5182 }  // namespace
5183 }  // namespace impl
5184 
GetClassLinker() const5185 inline ClassLinker* MethodVerifier::GetClassLinker() const {
5186   return reg_types_.GetClassLinker();
5187 }
5188 
MethodVerifier(Thread * self,ArenaPool * arena_pool,RegTypeCache * reg_types,VerifierDeps * verifier_deps,const dex::ClassDef & class_def,const dex::CodeItem * code_item,uint32_t dex_method_idx,bool aot_mode)5189 MethodVerifier::MethodVerifier(Thread* self,
5190                                ArenaPool* arena_pool,
5191                                RegTypeCache* reg_types,
5192                                VerifierDeps* verifier_deps,
5193                                const dex::ClassDef& class_def,
5194                                const dex::CodeItem* code_item,
5195                                uint32_t dex_method_idx,
5196                                bool aot_mode)
5197     : self_(self),
5198       allocator_(arena_pool),
5199       reg_types_(*reg_types),
5200       reg_table_(allocator_),
5201       work_insn_idx_(dex::kDexNoIndex),
5202       dex_method_idx_(dex_method_idx),
5203       dex_file_(reg_types->GetDexFile()),
5204       class_def_(class_def),
5205       code_item_accessor_(*dex_file_, code_item),
5206       flags_{ .have_pending_hard_failure_ = false, .have_pending_runtime_throw_failure_ = false },
5207       const_flags_{ .aot_mode_ = aot_mode, .can_load_classes_ = reg_types->CanLoadClasses() },
5208       encountered_failure_types_(0),
5209       info_messages_(std::nullopt),
5210       verifier_deps_(verifier_deps),
5211       link_(nullptr) {
5212 }
5213 
~MethodVerifier()5214 MethodVerifier::~MethodVerifier() {
5215   STLDeleteElements(&failure_messages_);
5216 }
5217 
VerifyMethod(Thread * self,ArenaPool * arena_pool,RegTypeCache * reg_types,VerifierDeps * verifier_deps,uint32_t method_idx,Handle<mirror::DexCache> dex_cache,const dex::ClassDef & class_def,const dex::CodeItem * code_item,uint32_t method_access_flags,HardFailLogMode log_level,uint32_t api_level,bool aot_mode,std::string * hard_failure_msg)5218 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
5219                                                          ArenaPool* arena_pool,
5220                                                          RegTypeCache* reg_types,
5221                                                          VerifierDeps* verifier_deps,
5222                                                          uint32_t method_idx,
5223                                                          Handle<mirror::DexCache> dex_cache,
5224                                                          const dex::ClassDef& class_def,
5225                                                          const dex::CodeItem* code_item,
5226                                                          uint32_t method_access_flags,
5227                                                          HardFailLogMode log_level,
5228                                                          uint32_t api_level,
5229                                                          bool aot_mode,
5230                                                          std::string* hard_failure_msg) {
5231   if (VLOG_IS_ON(verifier_debug)) {
5232     return VerifyMethod<true>(self,
5233                               arena_pool,
5234                               reg_types,
5235                               verifier_deps,
5236                               method_idx,
5237                               dex_cache,
5238                               class_def,
5239                               code_item,
5240                               method_access_flags,
5241                               log_level,
5242                               api_level,
5243                               aot_mode,
5244                               hard_failure_msg);
5245   } else {
5246     return VerifyMethod<false>(self,
5247                                arena_pool,
5248                                reg_types,
5249                                verifier_deps,
5250                                method_idx,
5251                                dex_cache,
5252                                class_def,
5253                                code_item,
5254                                method_access_flags,
5255                                log_level,
5256                                api_level,
5257                                aot_mode,
5258                                hard_failure_msg);
5259   }
5260 }
5261 
5262 // Return whether the runtime knows how to execute a method without needing to
5263 // re-verify it at runtime (and therefore save on first use of the class).
5264 // The AOT/JIT compiled code is not affected.
CanRuntimeHandleVerificationFailure(uint32_t encountered_failure_types)5265 static inline bool CanRuntimeHandleVerificationFailure(uint32_t encountered_failure_types) {
5266   constexpr uint32_t unresolved_mask =
5267       verifier::VerifyError::VERIFY_ERROR_UNRESOLVED_TYPE_CHECK |
5268       verifier::VerifyError::VERIFY_ERROR_NO_CLASS |
5269       verifier::VerifyError::VERIFY_ERROR_CLASS_CHANGE |
5270       verifier::VerifyError::VERIFY_ERROR_INSTANTIATION |
5271       verifier::VerifyError::VERIFY_ERROR_ACCESS_CLASS |
5272       verifier::VerifyError::VERIFY_ERROR_ACCESS_FIELD |
5273       verifier::VerifyError::VERIFY_ERROR_NO_METHOD |
5274       verifier::VerifyError::VERIFY_ERROR_NO_FIELD |
5275       verifier::VerifyError::VERIFY_ERROR_ACCESS_METHOD |
5276       verifier::VerifyError::VERIFY_ERROR_RUNTIME_THROW;
5277   return (encountered_failure_types & (~unresolved_mask)) == 0;
5278 }
5279 
5280 template <bool kVerifierDebug>
VerifyMethod(Thread * self,ArenaPool * arena_pool,RegTypeCache * reg_types,VerifierDeps * verifier_deps,uint32_t method_idx,Handle<mirror::DexCache> dex_cache,const dex::ClassDef & class_def,const dex::CodeItem * code_item,uint32_t method_access_flags,HardFailLogMode log_level,uint32_t api_level,bool aot_mode,std::string * hard_failure_msg)5281 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
5282                                                          ArenaPool* arena_pool,
5283                                                          RegTypeCache* reg_types,
5284                                                          VerifierDeps* verifier_deps,
5285                                                          uint32_t method_idx,
5286                                                          Handle<mirror::DexCache> dex_cache,
5287                                                          const dex::ClassDef& class_def,
5288                                                          const dex::CodeItem* code_item,
5289                                                          uint32_t method_access_flags,
5290                                                          HardFailLogMode log_level,
5291                                                          uint32_t api_level,
5292                                                          bool aot_mode,
5293                                                          std::string* hard_failure_msg) {
5294   MethodVerifier::FailureData result;
5295   uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
5296 
5297   impl::MethodVerifier<kVerifierDebug> verifier(self,
5298                                                 arena_pool,
5299                                                 reg_types,
5300                                                 verifier_deps,
5301                                                 code_item,
5302                                                 method_idx,
5303                                                 aot_mode,
5304                                                 dex_cache,
5305                                                 class_def,
5306                                                 method_access_flags,
5307                                                 /* verify_to_dump= */ false,
5308                                                 api_level);
5309   if (verifier.Verify()) {
5310     // Verification completed, however failures may be pending that didn't cause the verification
5311     // to hard fail.
5312     CHECK(!verifier.flags_.have_pending_hard_failure_);
5313 
5314     if (verifier.failures_.size() != 0) {
5315       if (VLOG_IS_ON(verifier)) {
5316         verifier.DumpFailures(VLOG_STREAM(verifier)
5317             << "Soft verification failures in "
5318             << reg_types->GetDexFile()->PrettyMethod(method_idx) << "\n");
5319       }
5320       if (kVerifierDebug) {
5321         LOG(INFO) << verifier.InfoMessages().str();
5322         verifier.Dump(LOG_STREAM(INFO));
5323       }
5324       if (CanRuntimeHandleVerificationFailure(verifier.encountered_failure_types_)) {
5325         if (verifier.encountered_failure_types_ & VERIFY_ERROR_UNRESOLVED_TYPE_CHECK) {
5326           result.kind = FailureKind::kTypeChecksFailure;
5327         } else {
5328           result.kind = FailureKind::kAccessChecksFailure;
5329         }
5330       } else {
5331         result.kind = FailureKind::kSoftFailure;
5332       }
5333     }
5334   } else {
5335     // Bad method data.
5336     CHECK_NE(verifier.failures_.size(), 0U);
5337     CHECK(verifier.flags_.have_pending_hard_failure_);
5338     if (VLOG_IS_ON(verifier)) {
5339       log_level = std::max(HardFailLogMode::kLogVerbose, log_level);
5340     }
5341     if (log_level >= HardFailLogMode::kLogVerbose) {
5342       LogSeverity severity;
5343       switch (log_level) {
5344         case HardFailLogMode::kLogVerbose:
5345           severity = LogSeverity::VERBOSE;
5346           break;
5347         case HardFailLogMode::kLogWarning:
5348           severity = LogSeverity::WARNING;
5349           break;
5350         case HardFailLogMode::kLogInternalFatal:
5351           severity = LogSeverity::FATAL_WITHOUT_ABORT;
5352           break;
5353         default:
5354           LOG(FATAL) << "Unsupported log-level " << static_cast<uint32_t>(log_level);
5355           UNREACHABLE();
5356       }
5357       verifier.DumpFailures(LOG_STREAM(severity)
5358           << "Verification error in "
5359           << reg_types->GetDexFile()->PrettyMethod(method_idx) << "\n");
5360     }
5361     if (hard_failure_msg != nullptr) {
5362       CHECK(!verifier.failure_messages_.empty());
5363       *hard_failure_msg =
5364           verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str();
5365     }
5366     result.kind = FailureKind::kHardFailure;
5367 
5368     if (kVerifierDebug || VLOG_IS_ON(verifier)) {
5369       LOG(ERROR) << verifier.InfoMessages().str();
5370       verifier.Dump(LOG_STREAM(ERROR));
5371     }
5372     // Under verifier-debug, dump the complete log into the error message.
5373     if (kVerifierDebug && hard_failure_msg != nullptr) {
5374       hard_failure_msg->append("\n");
5375       hard_failure_msg->append(verifier.InfoMessages().str());
5376       hard_failure_msg->append("\n");
5377       std::ostringstream oss;
5378       verifier.Dump(oss);
5379       hard_failure_msg->append(oss.str());
5380     }
5381   }
5382   if (kTimeVerifyMethod) {
5383     uint64_t duration_ns = NanoTime() - start_ns;
5384     if (duration_ns > MsToNs(Runtime::Current()->GetVerifierLoggingThresholdMs())) {
5385       double bytecodes_per_second =
5386           verifier.code_item_accessor_.InsnsSizeInCodeUnits() / (duration_ns * 1e-9);
5387       LOG(WARNING) << "Verification of " << reg_types->GetDexFile()->PrettyMethod(method_idx)
5388                    << " took " << PrettyDuration(duration_ns)
5389                    << (impl::IsLargeMethod(verifier.CodeItem()) ? " (large method)" : "")
5390                    << " (" << StringPrintf("%.2f", bytecodes_per_second) << " bytecodes/s)"
5391                    << " (" << verifier.allocator_.BytesAllocated() << "B arena alloc)";
5392     }
5393   }
5394   result.types = verifier.encountered_failure_types_;
5395   return result;
5396 }
5397 
CalculateVerificationInfo(Thread * self,RegTypeCache * reg_types,ArtMethod * method,Handle<mirror::DexCache> dex_cache,uint32_t dex_pc)5398 MethodVerifier* MethodVerifier::CalculateVerificationInfo(
5399       Thread* self,
5400       RegTypeCache* reg_types,
5401       ArtMethod* method,
5402       Handle<mirror::DexCache> dex_cache,
5403       uint32_t dex_pc) {
5404   Runtime* runtime = Runtime::Current();
5405   std::unique_ptr<impl::MethodVerifier<false>> verifier(
5406       new impl::MethodVerifier<false>(self,
5407                                       runtime->GetArenaPool(),
5408                                       reg_types,
5409                                       /* verifier_deps= */ nullptr,
5410                                       method->GetCodeItem(),
5411                                       method->GetDexMethodIndex(),
5412                                       runtime->IsAotCompiler(),
5413                                       dex_cache,
5414                                       *method->GetDeclaringClass()->GetClassDef(),
5415                                       method->GetAccessFlags(),
5416                                       /* verify_to_dump= */ false,
5417                                       // Just use the verifier at the current skd-version.
5418                                       // This might affect what soft-verifier errors are reported.
5419                                       // Callers can then filter out relevant errors if needed.
5420                                       runtime->GetTargetSdkVersion()));
5421   verifier->interesting_dex_pc_ = dex_pc;
5422   verifier->Verify();
5423   if (VLOG_IS_ON(verifier)) {
5424     verifier->DumpFailures(VLOG_STREAM(verifier));
5425     VLOG(verifier) << verifier->InfoMessages().str();
5426     verifier->Dump(VLOG_STREAM(verifier));
5427   }
5428   if (verifier->flags_.have_pending_hard_failure_) {
5429     return nullptr;
5430   } else {
5431     return verifier.release();
5432   }
5433 }
5434 
VerifyMethodAndDump(Thread * self,VariableIndentationOutputStream * vios,uint32_t dex_method_idx,const DexFile * dex_file,Handle<mirror::DexCache> dex_cache,Handle<mirror::ClassLoader> class_loader,const dex::ClassDef & class_def,const dex::CodeItem * code_item,uint32_t method_access_flags,uint32_t api_level)5435 void MethodVerifier::VerifyMethodAndDump(Thread* self,
5436                                          VariableIndentationOutputStream* vios,
5437                                          uint32_t dex_method_idx,
5438                                          const DexFile* dex_file,
5439                                          Handle<mirror::DexCache> dex_cache,
5440                                          Handle<mirror::ClassLoader> class_loader,
5441                                          const dex::ClassDef& class_def,
5442                                          const dex::CodeItem* code_item,
5443                                          uint32_t method_access_flags,
5444                                          uint32_t api_level) {
5445   Runtime* runtime = Runtime::Current();
5446   ClassLinker* class_linker = runtime->GetClassLinker();
5447   ArenaPool* arena_pool = runtime->GetArenaPool();
5448   RegTypeCache reg_types(self, class_linker, arena_pool, class_loader, dex_file);
5449   impl::MethodVerifier<false> verifier(
5450       self,
5451       arena_pool,
5452       &reg_types,
5453       /* verifier_deps= */ nullptr,
5454       code_item,
5455       dex_method_idx,
5456       runtime->IsAotCompiler(),
5457       dex_cache,
5458       class_def,
5459       method_access_flags,
5460       /* verify_to_dump= */ true,
5461       api_level);
5462   verifier.Verify();
5463   verifier.DumpFailures(vios->Stream());
5464   vios->Stream() << verifier.InfoMessages().str();
5465   // Only dump if no hard failures. Otherwise the verifier may be not fully initialized
5466   // and querying any info is dangerous/can abort.
5467   if (!verifier.flags_.have_pending_hard_failure_) {
5468     verifier.Dump(vios);
5469   }
5470 }
5471 
FindLocksAtDexPc(ArtMethod * m,uint32_t dex_pc,std::vector<MethodVerifier::DexLockInfo> * monitor_enter_dex_pcs,uint32_t api_level)5472 void MethodVerifier::FindLocksAtDexPc(
5473     ArtMethod* m,
5474     uint32_t dex_pc,
5475     std::vector<MethodVerifier::DexLockInfo>* monitor_enter_dex_pcs,
5476     uint32_t api_level) {
5477   Thread* self = Thread::Current();
5478   StackHandleScope<2> hs(self);
5479   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
5480   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
5481   Runtime* runtime = Runtime::Current();
5482   ClassLinker* class_linker = runtime->GetClassLinker();
5483   ArenaPool* arena_pool = runtime->GetArenaPool();
5484   RegTypeCache reg_types(self,
5485                          class_linker,
5486                          arena_pool,
5487                          class_loader,
5488                          dex_cache->GetDexFile(),
5489                          /* can_load_classes= */ false,
5490                          /* can_suspend= */ false);
5491   impl::MethodVerifier<false> verifier(self,
5492                                        arena_pool,
5493                                        &reg_types,
5494                                        /* verifier_deps= */ nullptr,
5495                                        m->GetCodeItem(),
5496                                        m->GetDexMethodIndex(),
5497                                        runtime->IsAotCompiler(),
5498                                        dex_cache,
5499                                        m->GetClassDef(),
5500                                        m->GetAccessFlags(),
5501                                        /* verify_to_dump= */ false,
5502                                        api_level);
5503   verifier.interesting_dex_pc_ = dex_pc;
5504   verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
5505   verifier.FindLocksAtDexPc();
5506 }
5507 
CreateVerifier(Thread * self,RegTypeCache * reg_types,VerifierDeps * verifier_deps,Handle<mirror::DexCache> dex_cache,const dex::ClassDef & class_def,const dex::CodeItem * code_item,uint32_t method_idx,uint32_t access_flags,bool verify_to_dump,uint32_t api_level)5508 MethodVerifier* MethodVerifier::CreateVerifier(Thread* self,
5509                                                RegTypeCache* reg_types,
5510                                                VerifierDeps* verifier_deps,
5511                                                Handle<mirror::DexCache> dex_cache,
5512                                                const dex::ClassDef& class_def,
5513                                                const dex::CodeItem* code_item,
5514                                                uint32_t method_idx,
5515                                                uint32_t access_flags,
5516                                                bool verify_to_dump,
5517                                                uint32_t api_level) {
5518   return new impl::MethodVerifier<false>(self,
5519                                          Runtime::Current()->GetArenaPool(),
5520                                          reg_types,
5521                                          verifier_deps,
5522                                          code_item,
5523                                          method_idx,
5524                                          Runtime::Current()->IsAotCompiler(),
5525                                          dex_cache,
5526                                          class_def,
5527                                          access_flags,
5528                                          verify_to_dump,
5529                                          api_level);
5530 }
5531 
Fail(VerifyError error,bool pending_exc)5532 std::ostream& MethodVerifier::Fail(VerifyError error, bool pending_exc) {
5533   // Mark the error type as encountered.
5534   encountered_failure_types_ |= static_cast<uint32_t>(error);
5535 
5536   if (pending_exc) {
5537     switch (error) {
5538       case VERIFY_ERROR_NO_CLASS:
5539       case VERIFY_ERROR_UNRESOLVED_TYPE_CHECK:
5540       case VERIFY_ERROR_NO_METHOD:
5541       case VERIFY_ERROR_NO_FIELD:
5542       case VERIFY_ERROR_ACCESS_CLASS:
5543       case VERIFY_ERROR_ACCESS_FIELD:
5544       case VERIFY_ERROR_ACCESS_METHOD:
5545       case VERIFY_ERROR_INSTANTIATION:
5546       case VERIFY_ERROR_CLASS_CHANGE: {
5547         PotentiallyMarkRuntimeThrow();
5548         break;
5549       }
5550 
5551       case VERIFY_ERROR_LOCKING:
5552         PotentiallyMarkRuntimeThrow();
5553         // This will be reported to the runtime as a soft failure.
5554         break;
5555 
5556       // Hard verification failures at compile time will still fail at runtime, so the class is
5557       // marked as rejected to prevent it from being compiled.
5558       case VERIFY_ERROR_BAD_CLASS_HARD: {
5559         flags_.have_pending_hard_failure_ = true;
5560         break;
5561       }
5562 
5563       case VERIFY_ERROR_RUNTIME_THROW: {
5564         LOG(FATAL) << "UNREACHABLE";
5565       }
5566     }
5567   } else if (kIsDebugBuild) {
5568     CHECK_NE(error, VERIFY_ERROR_BAD_CLASS_HARD);
5569   }
5570 
5571   failures_.push_back(error);
5572   std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(),
5573                                     work_insn_idx_));
5574   std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate);
5575   failure_messages_.push_back(failure_message);
5576   return *failure_message;
5577 }
5578 
LogVerifyInfo()5579 ScopedNewLine MethodVerifier::LogVerifyInfo() {
5580   ScopedNewLine ret{InfoMessages()};
5581   ret << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_)
5582       << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
5583   return ret;
5584 }
5585 
FailureKindMax(FailureKind fk1,FailureKind fk2)5586 static FailureKind FailureKindMax(FailureKind fk1, FailureKind fk2) {
5587   static_assert(FailureKind::kNoFailure < FailureKind::kSoftFailure
5588                     && FailureKind::kSoftFailure < FailureKind::kHardFailure,
5589                 "Unexpected FailureKind order");
5590   return std::max(fk1, fk2);
5591 }
5592 
Merge(const MethodVerifier::FailureData & fd)5593 void MethodVerifier::FailureData::Merge(const MethodVerifier::FailureData& fd) {
5594   kind = FailureKindMax(kind, fd.kind);
5595   types |= fd.types;
5596 }
5597 
GetInvocationThis(const Instruction * inst)5598 const RegType& MethodVerifier::GetInvocationThis(const Instruction* inst) {
5599   DCHECK(inst->IsInvoke());
5600   const size_t args_count = inst->VRegA();
5601   if (args_count < 1) {
5602     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke lacks 'this'";
5603     return reg_types_.Conflict();
5604   }
5605   const uint32_t this_reg = inst->VRegC();
5606   const RegType& this_type = work_line_->GetRegisterType(this, this_reg);
5607   if (!this_type.IsReferenceTypes()) {
5608     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
5609         << "tried to get class from non-reference register v" << this_reg
5610         << " (type=" << this_type << ")";
5611     return reg_types_.Conflict();
5612   }
5613   return this_type;
5614 }
5615 
AssignableFrom(const RegType & lhs,const RegType & rhs,bool strict) const5616 bool MethodVerifier::AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) const {
5617   if (lhs.Equals(rhs)) {
5618     return true;
5619   }
5620 
5621   RegType::Assignability assignable = RegType::AssignabilityFrom(lhs.GetKind(), rhs.GetKind());
5622   DCHECK(assignable != RegType::Assignability::kInvalid)
5623       << "Unexpected register type in IsAssignableFrom: '" << lhs << "' := '" << rhs << "'";
5624   if (assignable == RegType::Assignability::kAssignable) {
5625     return true;
5626   } else if (assignable == RegType::Assignability::kNotAssignable) {
5627     return false;
5628   } else if (assignable == RegType::Assignability::kNarrowingConversion) {
5629     // FIXME: The `MethodVerifier` is mostly doing a category check and avoiding
5630     // assignability checks that would expose narrowing conversions. However, for
5631     // the `return` instruction, it explicitly allows certain narrowing conversions
5632     // and prohibits others by doing a modified assignability check. Without strict
5633     // enforcement in all cases, this can compromise compiler optimizations that
5634     // rely on knowing the range of the values. Bug: 270660613
5635     return false;
5636   } else {
5637     DCHECK(assignable == RegType::Assignability::kReference);
5638     DCHECK(lhs.IsNonZeroReferenceTypes());
5639     DCHECK(rhs.IsNonZeroReferenceTypes());
5640     DCHECK(!lhs.IsUninitializedTypes());
5641     DCHECK(!rhs.IsUninitializedTypes());
5642     DCHECK(!lhs.IsJavaLangObject());
5643     if (!strict && !lhs.IsUnresolvedTypes() && lhs.GetClass()->IsInterface()) {
5644       // If we're not strict allow assignment to any interface, see comment in ClassJoin.
5645       return true;
5646     } else if (lhs.IsJavaLangObjectArray()) {
5647       return rhs.IsObjectArrayTypes();  // All reference arrays may be assigned to Object[]
5648     } else if (lhs.HasClass() && rhs.IsJavaLangObject()) {
5649       return false;  // Note: Non-strict check for interface `lhs` is handled above.
5650     } else if (lhs.HasClass() && rhs.HasClass()) {
5651       // Test assignability from the Class point-of-view.
5652       bool result = lhs.GetClass()->IsAssignableFrom(rhs.GetClass());
5653       // Record assignability dependency. The `verifier` is null during unit tests and
5654       // VerifiedMethod::GenerateSafeCastSet.
5655       if (result) {
5656         VerifierDeps::MaybeRecordAssignability(GetVerifierDeps(),
5657                                                GetDexFile(),
5658                                                GetClassDef(),
5659                                                lhs.GetClass(),
5660                                                rhs.GetClass());
5661       }
5662       return result;
5663     } else {
5664       // For unresolved types, we don't know if they are assignable, and the
5665       // verifier will continue assuming they are. We need to record that.
5666       //
5667       // Note that if `rhs` is an interface type, `lhs` may be j.l.Object
5668       // and if the assignability check is not strict, then this should be
5669       // OK. However we don't encode strictness in the verifier deps, and
5670       // such a situation will force a full verification.
5671       VerifierDeps::MaybeRecordAssignability(GetVerifierDeps(),
5672                                              GetDexFile(),
5673                                              GetClassDef(),
5674                                              lhs,
5675                                              rhs);
5676       // Unresolved types are only assignable for null and equality.
5677       // Null cannot be the left-hand side.
5678       return false;
5679     }
5680   }
5681 }
5682 
IsAssignableFrom(const RegType & lhs,const RegType & rhs) const5683 inline bool MethodVerifier::IsAssignableFrom(const RegType& lhs, const RegType& rhs) const {
5684   return AssignableFrom(lhs, rhs, false);
5685 }
5686 
IsStrictlyAssignableFrom(const RegType & lhs,const RegType & rhs) const5687 inline bool MethodVerifier::IsStrictlyAssignableFrom(const RegType& lhs, const RegType& rhs) const {
5688   return AssignableFrom(lhs, rhs, true);
5689 }
5690 
5691 }  // namespace verifier
5692 }  // namespace art
5693