1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <memory> 21*795d594fSAndroid Build Coastguard Worker #include <sstream> 22*795d594fSAndroid Build Coastguard Worker #include <vector> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker #include "base/arena_allocator.h" 27*795d594fSAndroid Build Coastguard Worker #include "base/arena_containers.h" 28*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 29*795d594fSAndroid Build Coastguard Worker #include "base/value_object.h" 30*795d594fSAndroid Build Coastguard Worker #include "dex/code_item_accessors.h" 31*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h" 32*795d594fSAndroid Build Coastguard Worker #include "dex/method_reference.h" 33*795d594fSAndroid Build Coastguard Worker #include "handle.h" 34*795d594fSAndroid Build Coastguard Worker #include "instruction_flags.h" 35*795d594fSAndroid Build Coastguard Worker #include "register_line.h" 36*795d594fSAndroid Build Coastguard Worker #include "verifier_enums.h" 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker class ClassLinker; 41*795d594fSAndroid Build Coastguard Worker class DexFile; 42*795d594fSAndroid Build Coastguard Worker class Instruction; 43*795d594fSAndroid Build Coastguard Worker struct ReferenceMap2Visitor; 44*795d594fSAndroid Build Coastguard Worker class Thread; 45*795d594fSAndroid Build Coastguard Worker class VariableIndentationOutputStream; 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker namespace dex { 48*795d594fSAndroid Build Coastguard Worker struct ClassDef; 49*795d594fSAndroid Build Coastguard Worker struct CodeItem; 50*795d594fSAndroid Build Coastguard Worker } // namespace dex 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker namespace mirror { 53*795d594fSAndroid Build Coastguard Worker class ClassLoader; 54*795d594fSAndroid Build Coastguard Worker class DexCache; 55*795d594fSAndroid Build Coastguard Worker } // namespace mirror 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker namespace verifier { 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker class MethodVerifier; 60*795d594fSAndroid Build Coastguard Worker class RegType; 61*795d594fSAndroid Build Coastguard Worker class RegTypeCache; 62*795d594fSAndroid Build Coastguard Worker struct ScopedNewLine; 63*795d594fSAndroid Build Coastguard Worker class VerifierDeps; 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker // A mapping from a dex pc to the register line statuses as they are immediately prior to the 66*795d594fSAndroid Build Coastguard Worker // execution of that instruction. 67*795d594fSAndroid Build Coastguard Worker class PcToRegisterLineTable { 68*795d594fSAndroid Build Coastguard Worker public: 69*795d594fSAndroid Build Coastguard Worker explicit PcToRegisterLineTable(ArenaAllocator& allocator); 70*795d594fSAndroid Build Coastguard Worker ~PcToRegisterLineTable(); 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker // Initialize the RegisterTable. Every instruction address can have a different set of information 73*795d594fSAndroid Build Coastguard Worker // about what's in which register, but for verification purposes we only need to store it at 74*795d594fSAndroid Build Coastguard Worker // branch target addresses (because we merge into that). 75*795d594fSAndroid Build Coastguard Worker void Init(InstructionFlags* flags, 76*795d594fSAndroid Build Coastguard Worker uint32_t insns_size, 77*795d594fSAndroid Build Coastguard Worker uint16_t registers_size, 78*795d594fSAndroid Build Coastguard Worker ArenaAllocator& allocator, 79*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 80*795d594fSAndroid Build Coastguard Worker uint32_t interesting_dex_pc); 81*795d594fSAndroid Build Coastguard Worker IsInitialized()82*795d594fSAndroid Build Coastguard Worker bool IsInitialized() const { 83*795d594fSAndroid Build Coastguard Worker return !register_lines_.empty(); 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker GetLine(size_t idx)86*795d594fSAndroid Build Coastguard Worker RegisterLine* GetLine(size_t idx) const { 87*795d594fSAndroid Build Coastguard Worker return register_lines_[idx].get(); 88*795d594fSAndroid Build Coastguard Worker } 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker private: 91*795d594fSAndroid Build Coastguard Worker ArenaVector<RegisterLineArenaUniquePtr> register_lines_; 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable); 94*795d594fSAndroid Build Coastguard Worker }; 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker // The verifier 97*795d594fSAndroid Build Coastguard Worker class MethodVerifier { 98*795d594fSAndroid Build Coastguard Worker public: 99*795d594fSAndroid Build Coastguard Worker EXPORT static void VerifyMethodAndDump(Thread* self, 100*795d594fSAndroid Build Coastguard Worker VariableIndentationOutputStream* vios, 101*795d594fSAndroid Build Coastguard Worker uint32_t method_idx, 102*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file, 103*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache, 104*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> class_loader, 105*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 106*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item, 107*795d594fSAndroid Build Coastguard Worker uint32_t method_access_flags, 108*795d594fSAndroid Build Coastguard Worker uint32_t api_level) 109*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker // Calculates the type information at the given `dex_pc`. 112*795d594fSAndroid Build Coastguard Worker // No classes will be loaded. 113*795d594fSAndroid Build Coastguard Worker EXPORT static MethodVerifier* CalculateVerificationInfo(Thread* self, 114*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 115*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 116*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache, 117*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) 118*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 119*795d594fSAndroid Build Coastguard Worker GetDexFile()120*795d594fSAndroid Build Coastguard Worker const DexFile& GetDexFile() const { 121*795d594fSAndroid Build Coastguard Worker DCHECK(dex_file_ != nullptr); 122*795d594fSAndroid Build Coastguard Worker return *dex_file_; 123*795d594fSAndroid Build Coastguard Worker } 124*795d594fSAndroid Build Coastguard Worker GetClassDef()125*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& GetClassDef() const { 126*795d594fSAndroid Build Coastguard Worker return class_def_; 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker GetRegTypeCache()129*795d594fSAndroid Build Coastguard Worker RegTypeCache* GetRegTypeCache() { 130*795d594fSAndroid Build Coastguard Worker return ®_types_; 131*795d594fSAndroid Build Coastguard Worker } 132*795d594fSAndroid Build Coastguard Worker 133*795d594fSAndroid Build Coastguard Worker // Log a verification failure. 134*795d594fSAndroid Build Coastguard Worker std::ostream& Fail(VerifyError error, bool pending_exc = true); 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker // Log for verification information. 137*795d594fSAndroid Build Coastguard Worker ScopedNewLine LogVerifyInfo(); 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker // Information structure for a lock held at a certain point in time. 140*795d594fSAndroid Build Coastguard Worker struct DexLockInfo { 141*795d594fSAndroid Build Coastguard Worker // The registers aliasing the lock. 142*795d594fSAndroid Build Coastguard Worker std::set<uint32_t> dex_registers; 143*795d594fSAndroid Build Coastguard Worker // The dex PC of the monitor-enter instruction. 144*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc; 145*795d594fSAndroid Build Coastguard Worker DexLockInfoDexLockInfo146*795d594fSAndroid Build Coastguard Worker explicit DexLockInfo(uint32_t dex_pc_in) { 147*795d594fSAndroid Build Coastguard Worker dex_pc = dex_pc_in; 148*795d594fSAndroid Build Coastguard Worker } 149*795d594fSAndroid Build Coastguard Worker }; 150*795d594fSAndroid Build Coastguard Worker // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding 151*795d594fSAndroid Build Coastguard Worker // to the locks held at 'dex_pc' in method 'm'. 152*795d594fSAndroid Build Coastguard Worker // Note: this is the only situation where the verifier will visit quickened instructions. 153*795d594fSAndroid Build Coastguard Worker static void FindLocksAtDexPc(ArtMethod* m, 154*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 155*795d594fSAndroid Build Coastguard Worker std::vector<DexLockInfo>* monitor_enter_dex_pcs, 156*795d594fSAndroid Build Coastguard Worker uint32_t api_level) 157*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker virtual ~MethodVerifier(); 160*795d594fSAndroid Build Coastguard Worker CodeItem()161*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor& CodeItem() const { 162*795d594fSAndroid Build Coastguard Worker return code_item_accessor_; 163*795d594fSAndroid Build Coastguard Worker } 164*795d594fSAndroid Build Coastguard Worker RegisterLine* GetRegLine(uint32_t dex_pc); 165*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const; 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker MethodReference GetMethodReference() const; 168*795d594fSAndroid Build Coastguard Worker bool HasFailures() const; HasInstructionThatWillThrow()169*795d594fSAndroid Build Coastguard Worker bool HasInstructionThatWillThrow() const { 170*795d594fSAndroid Build Coastguard Worker return (encountered_failure_types_ & VERIFY_ERROR_RUNTIME_THROW) != 0; 171*795d594fSAndroid Build Coastguard Worker } 172*795d594fSAndroid Build Coastguard Worker GetEncounteredFailureTypes()173*795d594fSAndroid Build Coastguard Worker uint32_t GetEncounteredFailureTypes() const { 174*795d594fSAndroid Build Coastguard Worker return encountered_failure_types_; 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker 177*795d594fSAndroid Build Coastguard Worker ClassLinker* GetClassLinker() const; 178*795d594fSAndroid Build Coastguard Worker IsAotMode()179*795d594fSAndroid Build Coastguard Worker bool IsAotMode() const { 180*795d594fSAndroid Build Coastguard Worker return const_flags_.aot_mode_; 181*795d594fSAndroid Build Coastguard Worker } 182*795d594fSAndroid Build Coastguard Worker CanLoadClasses()183*795d594fSAndroid Build Coastguard Worker bool CanLoadClasses() const { 184*795d594fSAndroid Build Coastguard Worker return const_flags_.can_load_classes_; 185*795d594fSAndroid Build Coastguard Worker } 186*795d594fSAndroid Build Coastguard Worker GetVerifierDeps()187*795d594fSAndroid Build Coastguard Worker VerifierDeps* GetVerifierDeps() const { 188*795d594fSAndroid Build Coastguard Worker return verifier_deps_; 189*795d594fSAndroid Build Coastguard Worker } 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker protected: 192*795d594fSAndroid Build Coastguard Worker MethodVerifier(Thread* self, 193*795d594fSAndroid Build Coastguard Worker ArenaPool* arena_pool, 194*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 195*795d594fSAndroid Build Coastguard Worker VerifierDeps* verifier_deps, 196*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 197*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item, 198*795d594fSAndroid Build Coastguard Worker uint32_t dex_method_idx, 199*795d594fSAndroid Build Coastguard Worker bool aot_mode) 200*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker // Verification result for method(s). Includes a (maximum) failure kind, and (the union of) 203*795d594fSAndroid Build Coastguard Worker // all failure types. 204*795d594fSAndroid Build Coastguard Worker struct FailureData : ValueObject { 205*795d594fSAndroid Build Coastguard Worker FailureKind kind = FailureKind::kNoFailure; 206*795d594fSAndroid Build Coastguard Worker uint32_t types = 0U; 207*795d594fSAndroid Build Coastguard Worker 208*795d594fSAndroid Build Coastguard Worker // Merge src into this. Uses the most severe failure kind, and the union of types. 209*795d594fSAndroid Build Coastguard Worker void Merge(const FailureData& src); 210*795d594fSAndroid Build Coastguard Worker }; 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker /* 213*795d594fSAndroid Build Coastguard Worker * Perform verification on a single method. 214*795d594fSAndroid Build Coastguard Worker * 215*795d594fSAndroid Build Coastguard Worker * We do this in three passes: 216*795d594fSAndroid Build Coastguard Worker * (1) Walk through all code units, determining instruction locations, 217*795d594fSAndroid Build Coastguard Worker * widths, and other characteristics. 218*795d594fSAndroid Build Coastguard Worker * (2) Walk through all code units, performing static checks on 219*795d594fSAndroid Build Coastguard Worker * operands. 220*795d594fSAndroid Build Coastguard Worker * (3) Iterate through the method, checking type safety and looking 221*795d594fSAndroid Build Coastguard Worker * for code flow problems. 222*795d594fSAndroid Build Coastguard Worker */ 223*795d594fSAndroid Build Coastguard Worker static FailureData VerifyMethod(Thread* self, 224*795d594fSAndroid Build Coastguard Worker ArenaPool* arena_pool, 225*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 226*795d594fSAndroid Build Coastguard Worker VerifierDeps* verifier_deps, 227*795d594fSAndroid Build Coastguard Worker uint32_t method_idx, 228*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache, 229*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def_idx, 230*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item, 231*795d594fSAndroid Build Coastguard Worker uint32_t method_access_flags, 232*795d594fSAndroid Build Coastguard Worker HardFailLogMode log_level, 233*795d594fSAndroid Build Coastguard Worker uint32_t api_level, 234*795d594fSAndroid Build Coastguard Worker bool aot_mode, 235*795d594fSAndroid Build Coastguard Worker std::string* hard_failure_msg) 236*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker template <bool kVerifierDebug> 239*795d594fSAndroid Build Coastguard Worker static FailureData VerifyMethod(Thread* self, 240*795d594fSAndroid Build Coastguard Worker ArenaPool* arena_pool, 241*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 242*795d594fSAndroid Build Coastguard Worker VerifierDeps* verifier_deps, 243*795d594fSAndroid Build Coastguard Worker uint32_t method_idx, 244*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache, 245*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def_idx, 246*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item, 247*795d594fSAndroid Build Coastguard Worker uint32_t method_access_flags, 248*795d594fSAndroid Build Coastguard Worker HardFailLogMode log_level, 249*795d594fSAndroid Build Coastguard Worker uint32_t api_level, 250*795d594fSAndroid Build Coastguard Worker bool aot_mode, 251*795d594fSAndroid Build Coastguard Worker std::string* hard_failure_msg) 252*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 253*795d594fSAndroid Build Coastguard Worker 254*795d594fSAndroid Build Coastguard Worker /* 255*795d594fSAndroid Build Coastguard Worker * Get the "this" pointer from a non-static method invocation. This returns the RegType so the 256*795d594fSAndroid Build Coastguard Worker * caller can decide whether it needs the reference to be initialized or not. 257*795d594fSAndroid Build Coastguard Worker * 258*795d594fSAndroid Build Coastguard Worker * The argument count is in vA, and the first argument is in vC, for both "simple" and "range" 259*795d594fSAndroid Build Coastguard Worker * versions. We just need to make sure vA is >= 1 and then return vC. 260*795d594fSAndroid Build Coastguard Worker */ 261*795d594fSAndroid Build Coastguard Worker const RegType& GetInvocationThis(const Instruction* inst) 262*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker // Can a variable with type `lhs` be assigned a value with type `rhs`? 265*795d594fSAndroid Build Coastguard Worker // Note: Object and interface types may always be assigned to one another, see 266*795d594fSAndroid Build Coastguard Worker // comment on `ClassJoin()`. 267*795d594fSAndroid Build Coastguard Worker bool IsAssignableFrom(const RegType& lhs, const RegType& rhs) const 268*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker // Can a variable with type `lhs` be assigned a value with type `rhs`? 271*795d594fSAndroid Build Coastguard Worker // Variant of IsAssignableFrom that doesn't allow assignment to an interface from an Object. 272*795d594fSAndroid Build Coastguard Worker bool IsStrictlyAssignableFrom(const RegType& lhs, const RegType& rhs) const 273*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker // Implementation helper for `IsAssignableFrom()` and `IsStrictlyAssignableFrom()`. 276*795d594fSAndroid Build Coastguard Worker bool AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) const 277*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 278*795d594fSAndroid Build Coastguard Worker 279*795d594fSAndroid Build Coastguard Worker // For VerifierDepsTest. TODO: Refactor. 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker // Run verification on the method. Returns true if verification completes and false if the input 282*795d594fSAndroid Build Coastguard Worker // has an irrecoverable corruption. 283*795d594fSAndroid Build Coastguard Worker virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0; 284*795d594fSAndroid Build Coastguard Worker static MethodVerifier* CreateVerifier(Thread* self, 285*795d594fSAndroid Build Coastguard Worker RegTypeCache* reg_types, 286*795d594fSAndroid Build Coastguard Worker VerifierDeps* verifier_deps, 287*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache, 288*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def, 289*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item, 290*795d594fSAndroid Build Coastguard Worker uint32_t method_idx, 291*795d594fSAndroid Build Coastguard Worker uint32_t access_flags, 292*795d594fSAndroid Build Coastguard Worker bool verify_to_dump, 293*795d594fSAndroid Build Coastguard Worker uint32_t api_level) 294*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 295*795d594fSAndroid Build Coastguard Worker 296*795d594fSAndroid Build Coastguard Worker virtual bool PotentiallyMarkRuntimeThrow() = 0; 297*795d594fSAndroid Build Coastguard Worker InfoMessages()298*795d594fSAndroid Build Coastguard Worker std::ostringstream& InfoMessages() { 299*795d594fSAndroid Build Coastguard Worker if (!info_messages_.has_value()) { 300*795d594fSAndroid Build Coastguard Worker info_messages_.emplace(); 301*795d594fSAndroid Build Coastguard Worker } 302*795d594fSAndroid Build Coastguard Worker return info_messages_.value(); 303*795d594fSAndroid Build Coastguard Worker } 304*795d594fSAndroid Build Coastguard Worker 305*795d594fSAndroid Build Coastguard Worker // The thread we're verifying on. 306*795d594fSAndroid Build Coastguard Worker Thread* const self_; 307*795d594fSAndroid Build Coastguard Worker 308*795d594fSAndroid Build Coastguard Worker // Arena allocator. 309*795d594fSAndroid Build Coastguard Worker ArenaAllocator allocator_; 310*795d594fSAndroid Build Coastguard Worker 311*795d594fSAndroid Build Coastguard Worker RegTypeCache& reg_types_; // TODO: Change to a pointer in a separate CL. 312*795d594fSAndroid Build Coastguard Worker 313*795d594fSAndroid Build Coastguard Worker PcToRegisterLineTable reg_table_; 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker // Storage for the register status we're currently working on. 316*795d594fSAndroid Build Coastguard Worker RegisterLineArenaUniquePtr work_line_; 317*795d594fSAndroid Build Coastguard Worker 318*795d594fSAndroid Build Coastguard Worker // The address of the instruction we're currently working on, note that this is in 2 byte 319*795d594fSAndroid Build Coastguard Worker // quantities 320*795d594fSAndroid Build Coastguard Worker uint32_t work_insn_idx_; 321*795d594fSAndroid Build Coastguard Worker 322*795d594fSAndroid Build Coastguard Worker // Storage for the register status we're saving for later. 323*795d594fSAndroid Build Coastguard Worker RegisterLineArenaUniquePtr saved_line_; 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker const uint32_t dex_method_idx_; // The method we're working on. 326*795d594fSAndroid Build Coastguard Worker const DexFile* const dex_file_; // The dex file containing the method. 327*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def_; // The class being verified. 328*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor code_item_accessor_; 329*795d594fSAndroid Build Coastguard Worker 330*795d594fSAndroid Build Coastguard Worker // Instruction widths and flags, one entry per code unit. 331*795d594fSAndroid Build Coastguard Worker // Owned, but not unique_ptr since insn_flags_ are allocated in arenas. 332*795d594fSAndroid Build Coastguard Worker ArenaUniquePtr<InstructionFlags[]> insn_flags_; 333*795d594fSAndroid Build Coastguard Worker 334*795d594fSAndroid Build Coastguard Worker // The types of any error that occurs. 335*795d594fSAndroid Build Coastguard Worker std::vector<VerifyError> failures_; 336*795d594fSAndroid Build Coastguard Worker // Error messages associated with failures. 337*795d594fSAndroid Build Coastguard Worker std::vector<std::ostringstream*> failure_messages_; 338*795d594fSAndroid Build Coastguard Worker 339*795d594fSAndroid Build Coastguard Worker struct { 340*795d594fSAndroid Build Coastguard Worker // Is there a pending hard failure? 341*795d594fSAndroid Build Coastguard Worker bool have_pending_hard_failure_ : 1; 342*795d594fSAndroid Build Coastguard Worker 343*795d594fSAndroid Build Coastguard Worker // Is there a pending runtime throw failure? A runtime throw failure is when an instruction 344*795d594fSAndroid Build Coastguard Worker // would fail at runtime throwing an exception. Such an instruction causes the following code 345*795d594fSAndroid Build Coastguard Worker // to be unreachable. This is set by Fail and used to ensure we don't process unreachable 346*795d594fSAndroid Build Coastguard Worker // instructions that would hard fail the verification. 347*795d594fSAndroid Build Coastguard Worker // Note: this flag is reset after processing each instruction. 348*795d594fSAndroid Build Coastguard Worker bool have_pending_runtime_throw_failure_ : 1; 349*795d594fSAndroid Build Coastguard Worker } flags_; 350*795d594fSAndroid Build Coastguard Worker 351*795d594fSAndroid Build Coastguard Worker struct { 352*795d594fSAndroid Build Coastguard Worker // Verify in AoT mode? 353*795d594fSAndroid Build Coastguard Worker bool aot_mode_ : 1; 354*795d594fSAndroid Build Coastguard Worker 355*795d594fSAndroid Build Coastguard Worker // Whether the `MethodVerifer` can load classes. 356*795d594fSAndroid Build Coastguard Worker bool can_load_classes_ : 1; 357*795d594fSAndroid Build Coastguard Worker } const const_flags_; 358*795d594fSAndroid Build Coastguard Worker 359*795d594fSAndroid Build Coastguard Worker // Bitset of the encountered failure types. Bits are according to the values in VerifyError. 360*795d594fSAndroid Build Coastguard Worker uint32_t encountered_failure_types_; 361*795d594fSAndroid Build Coastguard Worker 362*795d594fSAndroid Build Coastguard Worker // Info message log use primarily for verifier diagnostics. 363*795d594fSAndroid Build Coastguard Worker std::optional<std::ostringstream> info_messages_; 364*795d594fSAndroid Build Coastguard Worker 365*795d594fSAndroid Build Coastguard Worker // The verifier deps object we are going to report type assigability 366*795d594fSAndroid Build Coastguard Worker // constraints to. Can be null for runtime verification. 367*795d594fSAndroid Build Coastguard Worker VerifierDeps* verifier_deps_; 368*795d594fSAndroid Build Coastguard Worker 369*795d594fSAndroid Build Coastguard Worker // Link, for the method verifier root linked list. 370*795d594fSAndroid Build Coastguard Worker MethodVerifier* link_; 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker friend class art::Thread; 373*795d594fSAndroid Build Coastguard Worker friend class ClassVerifier; 374*795d594fSAndroid Build Coastguard Worker friend class RegisterLineTest; 375*795d594fSAndroid Build Coastguard Worker friend class VerifierDepsTest; 376*795d594fSAndroid Build Coastguard Worker 377*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(MethodVerifier); 378*795d594fSAndroid Build Coastguard Worker }; 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker } // namespace verifier 381*795d594fSAndroid Build Coastguard Worker } // namespace art 382*795d594fSAndroid Build Coastguard Worker 383*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 384