method_verifier.h revision 2fc1427ee9c534ed44d72184ad6d74ea65f3d5b3
1776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 2776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Copyright (C) 2011 The Android Open Source Project 3776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 4776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 5776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * you may not use this file except in compliance with the License. 6776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * You may obtain a copy of the License at 7776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 8776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 9776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 10776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Unless required by applicable law or agreed to in writing, software 11776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 12776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * See the License for the specific language governing permissions and 14776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * limitations under the License. 15776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 16776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 17776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#ifndef ART_SRC_VERIFIER_METHOD_VERIFIER_H_ 18776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#define ART_SRC_VERIFIER_METHOD_VERIFIER_H_ 19776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 20776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <deque> 21776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <limits> 22776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <set> 23776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <vector> 24776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "casts.h" 26776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "compiler.h" 27776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "dex_file.h" 28776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "dex_instruction.h" 29776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "macros.h" 30776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "object.h" 31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type.h" 32776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type_cache.h" 33776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "register_line.h" 34776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "safe_map.h" 35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "stl_util.h" 36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "UniquePtr.h" 37776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 38776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art { 39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstruct ReferenceMap2Visitor; 41776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 42776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#if defined(ART_USE_LLVM_COMPILER) 43776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace compiler_llvm { 44776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers class InferredRegCategoryMap; 45776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} // namespace compiler_llvm 46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 48e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#if defined(ART_USE_GREENLAND_COMPILER) 49e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liaonamespace greenland { 50e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao class InferredRegCategoryMap; 51e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao} // namespace greenland 52e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#endif 53e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao 54776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier { 55776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 56776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass MethodVerifier; 57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass InsnFlags; 58776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass PcToReferenceMap; 59776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 60776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 61776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "Direct" and "virtual" methods are stored independently. The type of call used to invoke the 62776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * method determines which list we search, and whether we travel up into superclasses. 63776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 64776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (<clinit>, <init>, and methods declared "private" or "static" are stored in the "direct" list. 65776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * All others are stored in the "virtual" list.) 66776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 67776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum MethodType { 68776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_UNKNOWN = 0, 69776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_DIRECT, // <init>, private 70776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_STATIC, // static 71776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_VIRTUAL, // virtual, super 72776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_INTERFACE // interface 73776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 742fc1427ee9c534ed44d72184ad6d74ea65f3d5b3Ian Rogersstd::ostream& operator<<(std::ostream& os, const MethodType& rhs); 75776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 76776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * An enumeration of problems that can turn up during verification. 78776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Both VERIFY_ERROR_BAD_CLASS_SOFT and VERIFY_ERROR_BAD_CLASS_HARD denote failures that cause 79776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the entire class to be rejected. However, VERIFY_ERROR_BAD_CLASS_SOFT denotes a soft failure 80776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * that can potentially be corrected, and the verifier will try again at runtime. 81776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * VERIFY_ERROR_BAD_CLASS_HARD denotes a hard failure that can't be corrected, and will cause 82776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the class to remain uncompiled. Other errors denote verification errors that cause bytecode 83776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * to be rewritten to fail at runtime. 84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum VerifyError { 86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_BAD_CLASS_HARD, // VerifyError; hard error that skips compilation. 87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_BAD_CLASS_SOFT, // VerifyError; soft error that verifies again at runtime. 88776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 89776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_NO_CLASS, // NoClassDefFoundError. 90776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_NO_FIELD, // NoSuchFieldError. 91776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_NO_METHOD, // NoSuchMethodError. 92776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_ACCESS_CLASS, // IllegalAccessError. 93776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_ACCESS_FIELD, // IllegalAccessError. 94776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_ACCESS_METHOD, // IllegalAccessError. 95776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_CLASS_CHANGE, // IncompatibleClassChangeError. 96776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_INSTANTIATION, // InstantiationError. 97776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 98776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstd::ostream& operator<<(std::ostream& os, const VerifyError& rhs); 99776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 100776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 101776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Identifies the type of reference in the instruction that generated the verify error 102776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (e.g. VERIFY_ERROR_ACCESS_CLASS could come from a method, field, or class reference). 103776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 104776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This must fit in two bits. 105776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 106776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum VerifyErrorRefType { 107776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_CLASS = 0, 108776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_FIELD = 1, 109776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_METHOD = 2, 110776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 111776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst int kVerifyErrorRefTypeShift = 6; 112776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 113776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// We don't need to store the register data for many instructions, because we either only need 114776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// it at branch points (for verification) or GC points and branches (for verification + 115776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// type-precise register analysis). 116776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum RegisterTrackingMode { 117776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kTrackRegsBranches, 118776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kTrackRegsGcPoints, 119776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kTrackRegsAll, 120776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 121776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 122776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass PcToRegisterLineTable { 123776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers public: 124776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers PcToRegisterLineTable() {} 125776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers ~PcToRegisterLineTable() { 126776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers STLDeleteValues(&pc_to_register_line_); 127776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 128776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 129776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Initialize the RegisterTable. Every instruction address can have a different set of information 130776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // about what's in which register, but for verification purposes we only need to store it at 131776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // branch target addresses (because we merge into that). 132776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void Init(RegisterTrackingMode mode, InsnFlags* flags, uint32_t insns_size, 133776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint16_t registers_size, MethodVerifier* verifier); 134776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 135776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegisterLine* GetLine(size_t idx) { 136776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers Table::iterator result = pc_to_register_line_.find(idx); // TODO: C++0x auto 137776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (result == pc_to_register_line_.end()) { 138776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return NULL; 139776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 140776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return result->second; 141776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 142776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 143776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 144776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers private: 145776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers typedef SafeMap<int32_t, RegisterLine*> Table; 146776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Map from a dex pc to the register status associated with it 147776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers Table pc_to_register_line_; 148776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 149776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 150776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// The verifier 151776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass MethodVerifier { 152e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) 153e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao typedef compiler_llvm::InferredRegCategoryMap InferredRegCategoryMap; 154e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#elif defined(ART_USE_GREENLAND_COMPILER) 155e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao typedef greenland::InferredRegCategoryMap InferredRegCategoryMap; 156e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#endif 157a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 158776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers public: 159f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao enum FailureKind { 160f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kNoFailure, 161f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kSoftFailure, 162f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kHardFailure, 163f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao }; 164f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao 165f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao /* Verify a class. Returns "kNoFailure" on success. */ 16600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static FailureKind VerifyClass(const Class* klass, std::string& error) 16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 168f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao static FailureKind VerifyClass(const DexFile* dex_file, DexCache* dex_cache, 169365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ClassLoader* class_loader, uint32_t class_def_idx, 17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::string& error) 17100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 172776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 173776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint8_t EncodePcToReferenceMapData() const; 174776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 175776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint32_t DexFileVersion() const { 176776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return dex_file_->GetVersion(); 177776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 178776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 179776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegTypeCache* GetRegTypeCache() { 180776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return ®_types_; 181776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 182776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 183ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Log a verification failure. 184776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostream& Fail(VerifyError error); 185776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 186ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Log for verification information. 187776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostream& LogVerifyInfo() { 188ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return info_messages_ << "VFY: " << PrettyMethod(method_idx_, *dex_file_) 189776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : "; 190776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 191776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 192ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Dump the failures encountered by the verifier. 193ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::ostream& DumpFailures(std::ostream& os); 194ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 195776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Dump the state of the verifier, namely each instruction, what flags are set on it, register 196776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // information 19700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 198776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 19900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref) 20000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(gc_maps_lock_); 2010a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes 20208fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding 20308fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // to the locks held at 'dex_pc' in 'm'. 20400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void FindLocksAtDexPc(Method* m, uint32_t dex_pc, 20500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::vector<uint32_t>& monitor_enter_dex_pcs) 20600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 20708fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 2080a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes static void Init(); 2090a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes static void Shutdown(); 210776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 211e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER) 212cd05a6274782c50a2b990c18b5f8d5ae5e44d509Shih-wei Liao static const InferredRegCategoryMap* GetInferredRegCategoryMap(Compiler::MethodReference ref) 213cd05a6274782c50a2b990c18b5f8d5ae5e44d509Shih-wei Liao LOCKS_EXCLUDED(inferred_reg_category_maps_lock_); 214776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 215776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 21600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static bool IsClassRejected(Compiler::ClassReference ref) 21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(rejected_classes_lock_); 218776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 219776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers private: 220776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers explicit MethodVerifier(const DexFile* dex_file, DexCache* dex_cache, 221365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item, 22200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers uint32_t method_idx, Method* method, uint32_t access_flags) 22300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 224ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 225ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Adds the given string to the beginning of the last failure message. 226ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers void PrependToLastFailMessage(std::string); 227ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 228ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Adds the given string to the end of the last failure message. 229ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers void AppendToLastFailMessage(std::string); 230776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 231776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 232776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform verification on a single method. 233776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 234776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * We do this in three passes: 235776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (1) Walk through all code units, determining instruction locations, 236776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * widths, and other characteristics. 237776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (2) Walk through all code units, performing static checks on 238776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * operands. 239776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (3) Iterate through the method, checking type safety and looking 240776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * for code flow problems. 241e1758feb293c7ff67d6fe59dbc31af0811863ce5Ian Rogers */ 242f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file, DexCache* dex_cache, 243365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item, 24400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* method, uint32_t method_access_flags) 24500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void VerifyMethodAndDump(Method* method) 24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 248e1758feb293c7ff67d6fe59dbc31af0811863ce5Ian Rogers 249ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Run verification on the method. Returns true if verification completes and false if the input 250ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // has an irrecoverable corruption. 25100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool Verify() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 252776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 25300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void FindLocksAtDexPc() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 25408fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 255776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 256776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Compute the width of the instruction at each address in the instruction stream, and store it in 257776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * insn_flags_. Addresses that are in the middle of an instruction, or that are part of switch 258776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * table data, are not touched (so the caller should probably initialize "insn_flags" to zero). 259776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 260776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The "new_instance_count_" and "monitor_enter_count_" fields in vdata are also set. 261776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 262776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Performs some static checks, notably: 263776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - opcode of first instruction begins at index 0 264776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - only documented instructions may appear 265776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - each instruction follows the last 266776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - last byte of last instruction is at (code_length-1) 267776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 268776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Logs an error and returns "false" on failure. 269776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 270776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool ComputeWidthsAndCountOps(); 271776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 272776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 273776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Set the "in try" flags for all instructions protected by "try" statements. Also sets the 274776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "branch target" flags for exception handlers. 275776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 276776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Call this after widths have been set in "insn_flags". 277776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 278776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "false" if something in the exception table looks fishy, but we're expecting the 279776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception table to be somewhat sane. 280776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool ScanTryCatchBlocks() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 282776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 283776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 284776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform static verification on all instructions in a method. 285776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 286776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Walks through instructions in a method calling VerifyInstruction on each. 287776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 288776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool VerifyInstructions(); 289776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 290776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 291776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform static verification on an instruction. 292776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 293776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * As a side effect, this sets the "branch target" flags in InsnFlags. 294776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 295776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "(CF)" items are handled during code-flow analysis. 296776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 297776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.10.1 298776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - target of each jump and branch instruction must be valid 299776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - targets of switch statements must be valid 300776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operands referencing constant pool entries must be valid 301776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid 302776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) operands of method invocation instructions must be valid 303776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) only invoke-direct can call a method starting with '<' 304776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) <clinit> must never be called explicitly 305776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operands of instanceof, checkcast, new (and variants) must be valid 306776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - new-array[-type] limited to 255 dimensions 307776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - can't use "new" on an array class 308776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (?) limit dimensions in multi-array creation 309776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - local variable load/store register values must be in valid range 310776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 311776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.2 312776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - branches must be within the bounds of the code array 313776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - targets of all control-flow instructions are the start of an instruction 314776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - register accesses fall within range of allocated registers 315776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (N/A) access to constant pool must be of appropriate type 316776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - code does not end in the middle of an instruction 317776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - execution cannot fall off the end of the code 318776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (earlier) for each exception handler, the "try" area must begin and 319776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * end at the start of an instruction (end can be at the end of the code) 320776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (earlier) for each exception handler, the handler must start at a valid 321776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction 322776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 323776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool VerifyInstruction(const Instruction* inst, uint32_t code_offset); 324776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 325776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the register index is valid for this code item. */ 326776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckRegisterIndex(uint32_t idx); 327776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 328776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the wide register index is valid for this code item. */ 329776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckWideRegisterIndex(uint32_t idx); 330776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 331776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a field get or set instruction. All we do here is ensure that the 332776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // field index is in the valid range. 333776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckFieldIndex(uint32_t idx); 334776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 335776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a method invocation instruction. All we do here is ensure that the 336776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // method index is in the valid range. 337776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckMethodIndex(uint32_t idx); 338776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 339776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a "new-instance" instruction. Specifically, make sure the class 340776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // reference isn't for an array class. 341776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNewInstance(uint32_t idx); 342776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 343776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the string index is in the valid range. */ 344776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckStringIndex(uint32_t idx); 345776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 346776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on an instruction that takes a class constant. Ensure that the class 347776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // index is in the valid range. 348776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckTypeIndex(uint32_t idx); 349776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 350776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't 351776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // creating an array of arrays that causes the number of dimensions to exceed 255. 352776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNewArray(uint32_t idx); 353776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 354776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction. 355776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckArrayData(uint32_t cur_offset); 356776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 357776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify that the target of a branch instruction is valid. We don't expect code to jump directly 358776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // into an exception handler, but it's valid to do so as long as the target isn't a 359776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // "move-exception" instruction. We verify that in a later stage. 360776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The dex format forbids certain instructions from branching to themselves. 36124edeb5f13c2fe67344cab01cb248b8f94e6faf9Elliott Hughes // Updates "insn_flags_", setting the "branch target" flag. 362776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckBranchTarget(uint32_t cur_offset); 363776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 364776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify a switch table. "cur_offset" is the offset of the switch instruction. 36524edeb5f13c2fe67344cab01cb248b8f94e6faf9Elliott Hughes // Updates "insn_flags_", setting the "branch target" flag. 366776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckSwitchTargets(uint32_t cur_offset); 367776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 368776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Check the register indices used in a "vararg" instruction, such as invoke-virtual or 369776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // filled-new-array. 370776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // - vA holds word count (0-5), args[] have values. 371776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // There are some tests we don't do here, e.g. we don't try to verify that invoking a method that 372776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // takes a double is done with consecutive registers. This requires parsing the target method 373776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // signature, which we will be doing later on during the code flow analysis. 374776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckVarArgRegs(uint32_t vA, uint32_t arg[]); 375776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 376776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Check the register indices used in a "vararg/range" instruction, such as invoke-virtual/range 377776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // or filled-new-array/range. 378776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // - vA holds word count, vC holds index of first reg. 379776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckVarArgRangeRegs(uint32_t vA, uint32_t vC); 380776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 381776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Extract the relative offset from a branch instruction. 382776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Returns "false" on failure (e.g. this isn't a branch instruction). 383776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional, 384776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool* selfOkay); 385776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 386776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Perform detailed code-flow analysis on a single method. */ 38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool VerifyCodeFlow() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 388776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 389776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Set the register types for the first instruction in the method based on the method signature. 390776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // This has the side-effect of validating the signature. 39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool SetTypesFromSignature() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 392776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 393776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 394776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform code flow on a method. 395776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 396776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit on the first 397776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction, process it (setting additional "changed" bits), and repeat until there are no 398776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * more. 399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 400776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.1 401776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (N/A) operand stack is always the same size 402776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operand stack [registers] contain the correct types of values 403776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - local variables [registers] contain the correct types of values 404776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - methods are invoked with the appropriate arguments 405776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - fields are assigned using values of appropriate types 406776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - opcodes have the correct type values in operand registers 407776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - there is never an uninitialized class instance in a local variable in code protected by an 408776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception handler (operand stack is okay, because the operand stack is discarded when an 409776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception is thrown) [can't know what's a local var w/o the debug info -- should fall out of 410776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * register typing] 411776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 412776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.2 413776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - execution cannot fall off the end of the code 414776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 415776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (We also do many of the items described in the "static checks" sections, because it's easier to 416776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * do them here.) 417776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 418776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * We need an array of RegType values, one per register, for every instruction. If the method uses 419776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * monitor-enter, we need extra data for every register, and a stack for every "interesting" 420776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction. In theory this could become quite large -- up to several megabytes for a monster 421776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * function. 422776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 423776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * NOTE: 424776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The spec forbids backward branches when there's an uninitialized reference in a register. The 425776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * idea is to prevent something like this: 426776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * loop: 427776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * move r1, r0 428776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * new-instance r0, MyClass 429776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * ... 430776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * if-eq rN, loop // once 431776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * initialize r0 432776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 433776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This leaves us with two different instances, both allocated by the same instruction, but only 434776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * one is initialized. The scheme outlined in v3 4.11.1.4 wouldn't catch this, so they work around 435776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * it by preventing backward branches. We achieve identical results without restricting code 436776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * reordering by specifying that you can't execute the new-instance instruction if a register 437776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * contains an uninitialized instance created by that same instruction. 438776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 43900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool CodeFlowVerifyMethod() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 440776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 441776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 442776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform verification for a single instruction. 443776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 444776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This requires fully decoding the instruction to determine the effect it has on registers. 445776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 446776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Finds zero or more following instructions and sets the "changed" flag if execution at that 447776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * point needs to be (re-)evaluated. Register changes are merged into "reg_types_" at the target 448776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * addresses. Does not set or clear any other flags in "insn_flags_". 449776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 45000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool CodeFlowVerifyInstruction(uint32_t* start_guess) 45100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 452776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 453776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of a new array instruction 454776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyNewArray(const DecodedInstruction& dec_insn, bool is_filled, 45500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_range) 45600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 457776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 458776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an aget instruction. The destination register's type will be set to 459776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // be that of component type of the array unless the array type is unknown, in which case a 460776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // bottom type inferred from the type of instruction is used. is_primitive is false for an 461776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // aget-object. 462776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyAGet(const DecodedInstruction& insn, const RegType& insn_type, 46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 464776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 465776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an aput instruction. 466776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyAPut(const DecodedInstruction& insn, const RegType& insn_type, 46700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 468776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 469776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Lookup instance field and fail for resolution violations 47000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* GetInstanceField(const RegType& obj_type, int field_idx) 47100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 472776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 473776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Lookup static field and fail for resolution violations 47400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 475776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 476776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an iget or sget instruction. 477776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyISGet(const DecodedInstruction& insn, const RegType& insn_type, 47800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive, bool is_static) 47900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 480776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 481776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an iput or sput instruction. 482776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyISPut(const DecodedInstruction& insn, const RegType& insn_type, 48300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive, bool is_static) 48400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 485776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 486776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Resolves a class based on an index and performs access checks to ensure the referrer can 487776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // access the resolved class. 48800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& ResolveClassAndCheckAccess(uint32_t class_idx) 48900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 490776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 491776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 492776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * For the "move-exception" instruction at "work_insn_idx_", which must be at an exception handler 493776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * address, determine the Join of all exceptions that can land here. Fails if no matching 494776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception handler can be found or if the Join of exception types fails. 495776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 49600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& GetCaughtExceptionType() 49700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 498776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 499776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 500776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Resolves a method based on an index and performs access checks to ensure 501776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the referrer can access the resolved method. 502776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Does not throw exceptions. 503776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 50400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type) 50500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 506776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 507776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 508776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Verify the arguments to a method. We're executing in "method", making 509776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * a call to the method reference in vB. 510776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 511776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * If this is a "direct" invoke, we allow calls to <init>. For calls to 512776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * <init>, the first argument may be an uninitialized reference. Otherwise, 513776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * calls to anything starting with '<' will be rejected, as will any 514776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * uninitialized reference arguments. 515776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 516776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * For non-static method calls, this will verify that the method call is 517776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * appropriate for the "this" argument. 518776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 519776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The method reference is in vBBBB. The "is_range" parameter determines 520776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * whether we use 0-4 "args" values or a range of registers defined by 521776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * vAA and vCCCC. 522776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 523776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Widening conversions on integers and references are allowed, but 524776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * narrowing conversions are not. 525776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 526776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns the resolved method on success, NULL on failure (with *failure 527776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * set appropriately). 528776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 529776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers Method* VerifyInvocationArgs(const DecodedInstruction& dec_insn, 53000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers MethodType method_type, bool is_range, bool is_super) 53100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 532776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 533776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 534776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Verify that the target instruction is not "move-exception". It's important that the only way 535776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * to execute a move-exception is as the first instruction of an exception handler. 536776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "true" if all is well, "false" if the target instruction is move-exception. 537776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 538776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNotMoveException(const uint16_t* insns, int insn_idx); 539776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 540776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 541776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Control can transfer to "next_insn". Merge the registers from merge_line into the table at 542776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * next_insn, and set the changed flag on the target address if any of the registers were changed. 543776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "false" if an error is encountered. 544776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 54500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool UpdateRegisters(uint32_t next_insn, const RegisterLine* merge_line) 54600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 547776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 548ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is the method being verified a constructor? 549ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool IsConstructor() const { 550ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return (method_access_flags_ & kAccConstructor) != 0; 551ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 552ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 553ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is the method verified static? 554ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool IsStatic() const { 555ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return (method_access_flags_ & kAccStatic) != 0; 556ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 557ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 558ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Return the register type for the method. 55900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& GetMethodReturnType() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 560ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 561ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Get a type representing the declaring class of the method. 56200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& GetDeclaringClass() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_); 563ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 564e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER) 565776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 566776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Generate the inferred register category for LLVM-based code generator. 567776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns a pointer to a two-dimension Class array, or NULL on failure. 568776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 569e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao const InferredRegCategoryMap* GenerateInferredRegCategoryMap(); 570776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 571776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 572776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 573776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of 574776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * verification). For type-precise determination we have all the data we need, so we just need to 575776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * encode it in some clever fashion. 576776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure. 577776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 578776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers const std::vector<uint8_t>* GenerateGcMap(); 579776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 580776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify that the GC map associated with method_ is well formed 581776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyGcMap(const std::vector<uint8_t>& data); 582776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 583776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Compute sizes for GC map data 584776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc); 585776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 586776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers InsnFlags* CurrentInsnFlags(); 587776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 588776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // All the GC maps that the verifier has created 589776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers typedef SafeMap<const Compiler::MethodReference, const std::vector<uint8_t>*> GcMapTable; 59000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Mutex* gc_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 59100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static GcMapTable* gc_maps_ GUARDED_BY(gc_maps_lock_); 59200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void SetGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map) 59300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(gc_maps_lock_); 594776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 5950a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes typedef std::set<Compiler::ClassReference> RejectedClassesTable; 59600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 5970a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes static RejectedClassesTable* rejected_classes_; 5980a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes 599e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER) 6000a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes // All the inferred register category maps that the verifier has created. 601776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers typedef SafeMap<const Compiler::MethodReference, 602e94d9b23c52ec0f36c8a132914eac33bc707faffShih-wei Liao const InferredRegCategoryMap*> InferredRegCategoryMapTable; 60300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Mutex* inferred_reg_category_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 604cd05a6274782c50a2b990c18b5f8d5ae5e44d509Shih-wei Liao static InferredRegCategoryMapTable* inferred_reg_category_maps_ GUARDED_BY(inferred_reg_category_maps_lock_); 605776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers static void SetInferredRegCategoryMap(Compiler::MethodReference ref, 606cd05a6274782c50a2b990c18b5f8d5ae5e44d509Shih-wei Liao const InferredRegCategoryMap& m) 607cd05a6274782c50a2b990c18b5f8d5ae5e44d509Shih-wei Liao LOCKS_EXCLUDED(inferred_reg_category_maps_lock_); 608776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif 609776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 61000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void AddRejectedClass(Compiler::ClassReference ref) 61100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(rejected_classes_lock_); 612776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 613776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegTypeCache reg_types_; 614776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 615776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers PcToRegisterLineTable reg_table_; 616776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 617776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Storage for the register status we're currently working on. 618776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UniquePtr<RegisterLine> work_line_; 619776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 620776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The address of the instruction we're currently working on, note that this is in 2 byte 621776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // quantities 622776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint32_t work_insn_idx_; 623776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 624776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Storage for the register status we're saving for later. 625776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UniquePtr<RegisterLine> saved_line_; 626776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 627ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers uint32_t method_idx_; // The method we're working on. 62800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Its object representation if known. 62900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Method* foo_method_ GUARDED_BY(GlobalSynchronization::mutator_lock_); 630ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers uint32_t method_access_flags_; // Method's access flags. 631776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers const DexFile* dex_file_; // The dex file containing the method. 63200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The dex_cache for the declaring class of the method. 63300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DexCache* dex_cache_ GUARDED_BY(GlobalSynchronization::mutator_lock_); 63400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The class loader for the declaring class of the method. 63500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ClassLoader* class_loader_ GUARDED_BY(GlobalSynchronization::mutator_lock_); 636776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint32_t class_def_idx_; // The class def index of the declaring class of the method. 637776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers const DexFile::CodeItem* code_item_; // The code item containing the code for the method. 638776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UniquePtr<InsnFlags[]> insn_flags_; // Instruction widths and flags, one entry per code unit. 639776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 64008fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // The dex PC of a FindLocksAtDexPc request, -1 otherwise. 64108fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes uint32_t interesting_dex_pc_; 64208fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // The container into which FindLocksAtDexPc should write the registers containing held locks, 64308fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // NULL if we're not doing FindLocksAtDexPc. 64408fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes std::vector<uint32_t>* monitor_enter_dex_pcs_; 64508fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 646ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // The types of any error that occurs. 647ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::vector<VerifyError> failures_; 648ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Error messages associated with failures. 649ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::vector<std::ostringstream*> failure_messages_; 650ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is there a pending hard failure? 651ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool have_pending_hard_failure_; 652776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 653ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Info message log use primarily for verifier diagnostics. 654776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostringstream info_messages_; 655776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 656776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The number of occurrences of specific opcodes. 657776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers size_t new_instance_count_; 658776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers size_t monitor_enter_count_; 659776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 660776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers friend struct art::ReferenceMap2Visitor; // for VerifyMethodAndDump 661776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 662776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 663776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} // namespace verifier 664776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} // namespace art 665776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 666776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#endif // ART_SRC_VERIFIER_METHOD_VERIFIER_H_ 667