method_verifier.h revision ea46f950e7a51585db293cd7f047de190a482414
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 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 19776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 20776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <set> 21776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include <vector> 22776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 231aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/casts.h" 24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 251aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 2651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "class_reference.h" 27776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "dex_file.h" 28776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "dex_instruction.h" 297b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers#include "instruction_flags.h" 3051c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "method_reference.h" 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object.h" 32776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type.h" 3351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include "reg_type_cache-inl.h" 34776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "register_line.h" 35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "safe_map.h" 36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "UniquePtr.h" 37776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 38776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art { 39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstruct ReferenceMap2Visitor; 41776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 42776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier { 43776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 44776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass MethodVerifier; 4546c6bb2f52cef82660b9be7576b49f83845df93aIan Rogersclass DexPcToReferenceMap; 46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 48776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "Direct" and "virtual" methods are stored independently. The type of call used to invoke the 49776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * method determines which list we search, and whether we travel up into superclasses. 50776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 51776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (<clinit>, <init>, and methods declared "private" or "static" are stored in the "direct" list. 52776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * All others are stored in the "virtual" list.) 53776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 54776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum MethodType { 55776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_UNKNOWN = 0, 56776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_DIRECT, // <init>, private 57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_STATIC, // static 58776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_VIRTUAL, // virtual, super 59776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers METHOD_INTERFACE // interface 60776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 612fc1427ee9c534ed44d72184ad6d74ea65f3d5b3Ian Rogersstd::ostream& operator<<(std::ostream& os, const MethodType& rhs); 62776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 63776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 64776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * An enumeration of problems that can turn up during verification. 65776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Both VERIFY_ERROR_BAD_CLASS_SOFT and VERIFY_ERROR_BAD_CLASS_HARD denote failures that cause 66776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the entire class to be rejected. However, VERIFY_ERROR_BAD_CLASS_SOFT denotes a soft failure 67776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * that can potentially be corrected, and the verifier will try again at runtime. 68776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * VERIFY_ERROR_BAD_CLASS_HARD denotes a hard failure that can't be corrected, and will cause 69776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the class to remain uncompiled. Other errors denote verification errors that cause bytecode 70776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * to be rewritten to fail at runtime. 71776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 72776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum VerifyError { 737934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_BAD_CLASS_HARD, // VerifyError; hard error that skips compilation. 747934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_BAD_CLASS_SOFT, // VerifyError; soft error that verifies again at runtime. 75776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 767934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_NO_CLASS, // NoClassDefFoundError. 777934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_NO_FIELD, // NoSuchFieldError. 787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_NO_METHOD, // NoSuchMethodError. 797934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_ACCESS_CLASS, // IllegalAccessError. 807934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_ACCESS_FIELD, // IllegalAccessError. 817934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_ACCESS_METHOD, // IllegalAccessError. 827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_CLASS_CHANGE, // IncompatibleClassChangeError. 837934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom VERIFY_ERROR_INSTANTIATION, // InstantiationError. 84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstd::ostream& operator<<(std::ostream& os, const VerifyError& rhs); 86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/* 88776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Identifies the type of reference in the instruction that generated the verify error 89776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (e.g. VERIFY_ERROR_ACCESS_CLASS could come from a method, field, or class reference). 90776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 91776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This must fit in two bits. 92776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 93776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum VerifyErrorRefType { 94776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_CLASS = 0, 95776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_FIELD = 1, 96776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers VERIFY_ERROR_REF_METHOD = 2, 97776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 98776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst int kVerifyErrorRefTypeShift = 6; 99776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 100776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// We don't need to store the register data for many instructions, because we either only need 101776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// it at branch points (for verification) or GC points and branches (for verification + 102776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// type-precise register analysis). 103776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersenum RegisterTrackingMode { 104776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kTrackRegsBranches, 10502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal kTrackCompilerInterestPoints, 106776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kTrackRegsAll, 107776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 108776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 1092bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers// A mapping from a dex pc to the register line statuses as they are immediately prior to the 1102bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers// execution of that instruction. 111776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass PcToRegisterLineTable { 112776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers public: 113776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers PcToRegisterLineTable() {} 114776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers ~PcToRegisterLineTable() { 115776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers STLDeleteValues(&pc_to_register_line_); 116776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 117776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 118776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Initialize the RegisterTable. Every instruction address can have a different set of information 119776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // about what's in which register, but for verification purposes we only need to store it at 120776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // branch target addresses (because we merge into that). 1217b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers void Init(RegisterTrackingMode mode, InstructionFlags* flags, uint32_t insns_size, 122776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint16_t registers_size, MethodVerifier* verifier); 123776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 124776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegisterLine* GetLine(size_t idx) { 125776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers Table::iterator result = pc_to_register_line_.find(idx); // TODO: C++0x auto 126776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (result == pc_to_register_line_.end()) { 127776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return NULL; 128776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 129776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return result->second; 130776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 131776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 132776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 133776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers private: 134776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers typedef SafeMap<int32_t, RegisterLine*> Table; 135776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers Table pc_to_register_line_; 136776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 137776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 138776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers// The verifier 139776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersclass MethodVerifier { 140776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers public: 141f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao enum FailureKind { 142f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kNoFailure, 143f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kSoftFailure, 144f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao kHardFailure, 145f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao }; 146f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao 147f1e6b7c8cd78c02f4eb36574f0e417c4edc2b91ejeffhao /* Verify a class. Returns "kNoFailure" on success. */ 148ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao static FailureKind VerifyClass(const mirror::Class* klass, std::string& error, 149ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao bool allow_soft_failures) 150b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache, 1522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader, uint32_t class_def_idx, 153ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao std::string& error, bool allow_soft_failures) 154b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 155776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 1562bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file, 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader, 1582bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers uint32_t class_def_idx, const DexFile::CodeItem* code_item, 159ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, uint32_t method_access_flags) 1602bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1612bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers 162776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint8_t EncodePcToReferenceMapData() const; 163776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 164776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint32_t DexFileVersion() const { 165776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return dex_file_->GetVersion(); 166776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 167776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 168776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegTypeCache* GetRegTypeCache() { 169776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return ®_types_; 170776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 171776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 172ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Log a verification failure. 173776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostream& Fail(VerifyError error); 174776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 175ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Log for verification information. 176776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostream& LogVerifyInfo() { 1772bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers return info_messages_ << "VFY: " << PrettyMethod(dex_method_idx_, *dex_file_) 178776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : "; 179776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 180776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 181ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Dump the failures encountered by the verifier. 182ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::ostream& DumpFailures(std::ostream& os); 183ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 184776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Dump the state of the verifier, namely each instruction, what flags are set on it, register 185776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // information 186b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 187776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 18851c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static const std::vector<uint8_t>* GetDexGcMap(MethodReference ref) 1890c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers LOCKS_EXCLUDED(dex_gc_maps_lock_); 1900a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes 19151c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static const MethodReference* GetDevirtMap(const MethodReference& ref, uint32_t dex_pc) 19202c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal LOCKS_EXCLUDED(devirt_maps_lock_); 19302c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal 194980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea // Returns true if the cast can statically be verified to be redundant 195980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea // by using the check-cast elision peephole optimization in the verifier 19651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static bool IsSafeCast(MethodReference ref, uint32_t pc) LOCKS_EXCLUDED(safecast_map_lock_); 197980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea 19808fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding 1992d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // to the locks held at 'dex_pc' in method 'm'. 200ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom static void FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc, 20100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::vector<uint32_t>& monitor_enter_dex_pcs) 202b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 20308fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 2042d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Returns the accessed field corresponding to the quick instruction's field 2052d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // offset at 'dex_pc' in method 'm'. 206ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom static mirror::ArtField* FindAccessedFieldAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) 2072d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2082d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 2092d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Returns the invoked method corresponding to the quick instruction's vtable 2102d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // index at 'dex_pc' in method 'm'. 211ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom static mirror::ArtMethod* FindInvokedMethodAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) 2122d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2132d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 21451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2150a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes static void Shutdown(); 216776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 21751c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static bool IsClassRejected(ClassReference ref) 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(rejected_classes_lock_); 219776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 2204993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes bool CanLoadClasses() const { 2214993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes return can_load_classes_; 2224993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes } 2234993bbc8eda377804e585efd918f8ab9d9eab7d4Elliott Hughes 2247b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache, 2257b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers mirror::ClassLoader* class_loader, uint32_t class_def_idx, 2267b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers const DexFile::CodeItem* code_item, 227ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom uint32_t method_idx, mirror::ArtMethod* method, 228ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao uint32_t access_flags, bool can_load_classes, bool allow_soft_failures) 229b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 230ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 23133691abbc43850fd2b2951256c4b6bbc9733ccc8Sebastien Hertz ~MethodVerifier() { 23233691abbc43850fd2b2951256c4b6bbc9733ccc8Sebastien Hertz STLDeleteElements(&failure_messages_); 23333691abbc43850fd2b2951256c4b6bbc9733ccc8Sebastien Hertz } 23433691abbc43850fd2b2951256c4b6bbc9733ccc8Sebastien Hertz 2357b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers // Run verification on the method. Returns true if verification completes and false if the input 2367b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers // has an irrecoverable corruption. 2377b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers bool Verify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2387b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers 2397b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers // Describe VRegs at the given dex pc. 2407b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers std::vector<int32_t> DescribeVRegs(uint32_t dex_pc); 2417b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers 2424d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz static bool IsCandidateForCompilation(const DexFile::CodeItem* code_item, 2434d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz const uint32_t access_flags); 2444d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz 2457b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers private: 246ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Adds the given string to the beginning of the last failure message. 247ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers void PrependToLastFailMessage(std::string); 248ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 249ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Adds the given string to the end of the last failure message. 250ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers void AppendToLastFailMessage(std::string); 251776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 252776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 253776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform verification on a single method. 254776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 255776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * We do this in three passes: 256776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (1) Walk through all code units, determining instruction locations, 257776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * widths, and other characteristics. 258776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (2) Walk through all code units, performing static checks on 259776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * operands. 260776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (3) Iterate through the method, checking type safety and looking 261776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * for code flow problems. 262e1758feb293c7ff67d6fe59dbc31af0811863ce5Ian Rogers */ 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file, 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache, 2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader, uint32_t class_def_idx, 2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const DexFile::CodeItem* code_item, 267ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, uint32_t method_access_flags, 268ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao bool allow_soft_failures) 269b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 270e1758feb293c7ff67d6fe59dbc31af0811863ce5Ian Rogers 271b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void FindLocksAtDexPc() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 27208fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 273ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* FindAccessedFieldAtDexPc(uint32_t dex_pc) 274c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2752d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 276ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* FindInvokedMethodAtDexPc(uint32_t dex_pc) 277c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2782d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 279776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 280776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Compute the width of the instruction at each address in the instruction stream, and store it in 281776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * insn_flags_. Addresses that are in the middle of an instruction, or that are part of switch 282776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * table data, are not touched (so the caller should probably initialize "insn_flags" to zero). 283776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 284776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The "new_instance_count_" and "monitor_enter_count_" fields in vdata are also set. 285776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 286776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Performs some static checks, notably: 287776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - opcode of first instruction begins at index 0 288776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - only documented instructions may appear 289776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - each instruction follows the last 290776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - last byte of last instruction is at (code_length-1) 291776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 292776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Logs an error and returns "false" on failure. 293776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 294776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool ComputeWidthsAndCountOps(); 295776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 296776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 297776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Set the "in try" flags for all instructions protected by "try" statements. Also sets the 298776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "branch target" flags for exception handlers. 299776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 300776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Call this after widths have been set in "insn_flags". 301776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 302776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "false" if something in the exception table looks fishy, but we're expecting the 303776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception table to be somewhat sane. 304776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 305b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool ScanTryCatchBlocks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 306776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 307776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 308776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform static verification on all instructions in a method. 309776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 310776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Walks through instructions in a method calling VerifyInstruction on each. 311776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 312776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool VerifyInstructions(); 313776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 314776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 315776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform static verification on an instruction. 316776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 317776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * As a side effect, this sets the "branch target" flags in InsnFlags. 318776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 319776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * "(CF)" items are handled during code-flow analysis. 320776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 321776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.10.1 322776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - target of each jump and branch instruction must be valid 323776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - targets of switch statements must be valid 324776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operands referencing constant pool entries must be valid 325776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid 326776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) operands of method invocation instructions must be valid 327776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) only invoke-direct can call a method starting with '<' 328776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (CF) <clinit> must never be called explicitly 329776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operands of instanceof, checkcast, new (and variants) must be valid 330776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - new-array[-type] limited to 255 dimensions 331776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - can't use "new" on an array class 332776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (?) limit dimensions in multi-array creation 333776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - local variable load/store register values must be in valid range 334776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 335776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.2 336776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - branches must be within the bounds of the code array 337776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - targets of all control-flow instructions are the start of an instruction 338776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - register accesses fall within range of allocated registers 339776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (N/A) access to constant pool must be of appropriate type 340776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - code does not end in the middle of an instruction 341776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - execution cannot fall off the end of the code 342776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (earlier) for each exception handler, the "try" area must begin and 343776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * end at the start of an instruction (end can be at the end of the code) 344776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (earlier) for each exception handler, the handler must start at a valid 345776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction 346776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 347776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool VerifyInstruction(const Instruction* inst, uint32_t code_offset); 348776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 349776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the register index is valid for this code item. */ 350776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckRegisterIndex(uint32_t idx); 351776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 352776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the wide register index is valid for this code item. */ 353776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckWideRegisterIndex(uint32_t idx); 354776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 355776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a field get or set instruction. All we do here is ensure that the 356776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // field index is in the valid range. 357776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckFieldIndex(uint32_t idx); 358776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 359776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a method invocation instruction. All we do here is ensure that the 360776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // method index is in the valid range. 361776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckMethodIndex(uint32_t idx); 362776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 363776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a "new-instance" instruction. Specifically, make sure the class 364776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // reference isn't for an array class. 365776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNewInstance(uint32_t idx); 366776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 367776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Ensure that the string index is in the valid range. */ 368776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckStringIndex(uint32_t idx); 369776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 370776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on an instruction that takes a class constant. Ensure that the class 371776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // index is in the valid range. 372776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckTypeIndex(uint32_t idx); 373776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 374776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform static checks on a "new-array" instruction. Specifically, make sure they aren't 375776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // creating an array of arrays that causes the number of dimensions to exceed 255. 376776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNewArray(uint32_t idx); 377776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 378776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify an array data table. "cur_offset" is the offset of the fill-array-data instruction. 379776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckArrayData(uint32_t cur_offset); 380776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 381776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify that the target of a branch instruction is valid. We don't expect code to jump directly 382776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // into an exception handler, but it's valid to do so as long as the target isn't a 383776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // "move-exception" instruction. We verify that in a later stage. 384776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The dex format forbids certain instructions from branching to themselves. 38524edeb5f13c2fe67344cab01cb248b8f94e6faf9Elliott Hughes // Updates "insn_flags_", setting the "branch target" flag. 386776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckBranchTarget(uint32_t cur_offset); 387776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 388776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify a switch table. "cur_offset" is the offset of the switch instruction. 38924edeb5f13c2fe67344cab01cb248b8f94e6faf9Elliott Hughes // Updates "insn_flags_", setting the "branch target" flag. 390776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckSwitchTargets(uint32_t cur_offset); 391776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 392776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Check the register indices used in a "vararg" instruction, such as invoke-virtual or 393776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // filled-new-array. 394776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // - vA holds word count (0-5), args[] have values. 395776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // There are some tests we don't do here, e.g. we don't try to verify that invoking a method that 396776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // takes a double is done with consecutive registers. This requires parsing the target method 397776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // signature, which we will be doing later on during the code flow analysis. 398776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckVarArgRegs(uint32_t vA, uint32_t arg[]); 399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 400776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Check the register indices used in a "vararg/range" instruction, such as invoke-virtual/range 401776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // or filled-new-array/range. 402776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // - vA holds word count, vC holds index of first reg. 403776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckVarArgRangeRegs(uint32_t vA, uint32_t vC); 404776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 405776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Extract the relative offset from a branch instruction. 406776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Returns "false" on failure (e.g. this isn't a branch instruction). 407776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional, 408776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool* selfOkay); 409776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 410776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* Perform detailed code-flow analysis on a single method. */ 411b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool VerifyCodeFlow() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 412776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 413776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Set the register types for the first instruction in the method based on the method signature. 414776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // This has the side-effect of validating the signature. 415b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool SetTypesFromSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 416776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 417776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 418776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform code flow on a method. 419776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 420776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit on the first 421776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction, process it (setting additional "changed" bits), and repeat until there are no 422776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * more. 423776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 424776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.1 425776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - (N/A) operand stack is always the same size 426776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - operand stack [registers] contain the correct types of values 427776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - local variables [registers] contain the correct types of values 428776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - methods are invoked with the appropriate arguments 429776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - fields are assigned using values of appropriate types 430776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - opcodes have the correct type values in operand registers 431776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - there is never an uninitialized class instance in a local variable in code protected by an 432776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception handler (operand stack is okay, because the operand stack is discarded when an 433776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception is thrown) [can't know what's a local var w/o the debug info -- should fall out of 434776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * register typing] 435776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 436776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * v3 4.11.1.2 437776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * - execution cannot fall off the end of the code 438776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 439776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * (We also do many of the items described in the "static checks" sections, because it's easier to 440776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * do them here.) 441776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 442776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * We need an array of RegType values, one per register, for every instruction. If the method uses 443776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * monitor-enter, we need extra data for every register, and a stack for every "interesting" 444776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * instruction. In theory this could become quite large -- up to several megabytes for a monster 445776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * function. 446776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 447776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * NOTE: 448776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The spec forbids backward branches when there's an uninitialized reference in a register. The 449776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * idea is to prevent something like this: 450776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * loop: 451776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * move r1, r0 452776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * new-instance r0, MyClass 453776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * ... 454776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * if-eq rN, loop // once 455776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * initialize r0 456776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 457776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This leaves us with two different instances, both allocated by the same instruction, but only 458776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * one is initialized. The scheme outlined in v3 4.11.1.4 wouldn't catch this, so they work around 459776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * it by preventing backward branches. We achieve identical results without restricting code 460776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * reordering by specifying that you can't execute the new-instance instruction if a register 461776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * contains an uninitialized instance created by that same instruction. 462776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 463b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool CodeFlowVerifyMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 464776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 465776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 466776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Perform verification for a single instruction. 467776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 468776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * This requires fully decoding the instruction to determine the effect it has on registers. 469776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 470776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Finds zero or more following instructions and sets the "changed" flag if execution at that 471776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * point needs to be (re-)evaluated. Register changes are merged into "reg_types_" at the target 472776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * addresses. Does not set or clear any other flags in "insn_flags_". 473776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 47400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool CodeFlowVerifyInstruction(uint32_t* start_guess) 475b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 476776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 477776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of a new array instruction 4785243e912875026f99428088db7e80cb11651d64eSebastien Hertz void VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) 479b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 480776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 481fe1f7c84369abbf5a0121557aa0c6c58e9477710Jeff Hao // Helper to perform verification on puts of primitive type. 482fe1f7c84369abbf5a0121557aa0c6c58e9477710Jeff Hao void VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type, 483fe1f7c84369abbf5a0121557aa0c6c58e9477710Jeff Hao const uint32_t vregA) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 484fe1f7c84369abbf5a0121557aa0c6c58e9477710Jeff Hao 485776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an aget instruction. The destination register's type will be set to 486776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // be that of component type of the array unless the array type is unknown, in which case a 487776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // bottom type inferred from the type of instruction is used. is_primitive is false for an 488776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // aget-object. 4895243e912875026f99428088db7e80cb11651d64eSebastien Hertz void VerifyAGet(const Instruction* inst, const RegType& insn_type, 490b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 491776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 492776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an aput instruction. 4935243e912875026f99428088db7e80cb11651d64eSebastien Hertz void VerifyAPut(const Instruction* inst, const RegType& insn_type, 494b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 495776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 496776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Lookup instance field and fail for resolution violations 497ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* GetInstanceField(const RegType& obj_type, int field_idx) 498b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 499776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 500776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Lookup static field and fail for resolution violations 501ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 502776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 503776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an iget or sget instruction. 5045243e912875026f99428088db7e80cb11651d64eSebastien Hertz void VerifyISGet(const Instruction* inst, const RegType& insn_type, 50500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive, bool is_static) 506b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 507776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 508776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Perform verification of an iput or sput instruction. 5095243e912875026f99428088db7e80cb11651d64eSebastien Hertz void VerifyISPut(const Instruction* inst, const RegType& insn_type, 51000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool is_primitive, bool is_static) 511b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 512776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 513c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz // Returns the access field of a quick field access (iget/iput-quick) or NULL 514c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz // if it cannot be found. 515ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtField* GetQuickFieldAccess(const Instruction* inst, RegisterLine* reg_line) 516c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 517c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz 5182d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Perform verification of an iget-quick instruction. 5192d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz void VerifyIGetQuick(const Instruction* inst, const RegType& insn_type, 5202d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz bool is_primitive) 5212d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5222d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 5232d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz // Perform verification of an iput-quick instruction. 5242d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz void VerifyIPutQuick(const Instruction* inst, const RegType& insn_type, 5252d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz bool is_primitive) 5262d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5272d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 528776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Resolves a class based on an index and performs access checks to ensure the referrer can 529776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // access the resolved class. 53000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& ResolveClassAndCheckAccess(uint32_t class_idx) 531b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 532776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 533776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 534776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * For the "move-exception" instruction at "work_insn_idx_", which must be at an exception handler 535776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * address, determine the Join of all exceptions that can land here. Fails if no matching 536776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * exception handler can be found or if the Join of exception types fails. 537776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 53800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const RegType& GetCaughtExceptionType() 539b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 540776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 541776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 542776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Resolves a method based on an index and performs access checks to ensure 543776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * the referrer can access the resolved method. 544776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Does not throw exceptions. 545776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 546ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type) 547b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 548776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 549776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 550776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Verify the arguments to a method. We're executing in "method", making 551776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * a call to the method reference in vB. 552776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 553776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * If this is a "direct" invoke, we allow calls to <init>. For calls to 554776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * <init>, the first argument may be an uninitialized reference. Otherwise, 555776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * calls to anything starting with '<' will be rejected, as will any 556776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * uninitialized reference arguments. 557776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 558776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * For non-static method calls, this will verify that the method call is 559776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * appropriate for the "this" argument. 560776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 561776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * The method reference is in vBBBB. The "is_range" parameter determines 562776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * whether we use 0-4 "args" values or a range of registers defined by 563776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * vAA and vCCCC. 564776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 565776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Widening conversions on integers and references are allowed, but 566776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * narrowing conversions are not. 567776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * 568776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns the resolved method on success, NULL on failure (with *failure 569776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * set appropriately). 570776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 571ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* VerifyInvocationArgs(const Instruction* inst, 572ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom MethodType method_type, 573ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom bool is_range, bool is_super) 574b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 575776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 576ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* GetQuickInvokedMethod(const Instruction* inst, 577ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom RegisterLine* reg_line, 578ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom bool is_range) 579c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 580c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz 581ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* VerifyInvokeVirtualQuickArgs(const Instruction* inst, bool is_range) 5822d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5832d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz 584776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 585776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Verify that the target instruction is not "move-exception". It's important that the only way 586776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * to execute a move-exception is as the first instruction of an exception handler. 587776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "true" if all is well, "false" if the target instruction is move-exception. 588776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 589776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers bool CheckNotMoveException(const uint16_t* insns, int insn_idx); 590776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 591776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 592776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Control can transfer to "next_insn". Merge the registers from merge_line into the table at 593776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * next_insn, and set the changed flag on the target address if any of the registers were changed. 594776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns "false" if an error is encountered. 595776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 59600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool UpdateRegisters(uint32_t next_insn, const RegisterLine* merge_line) 597b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 598776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 599ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is the method being verified a constructor? 600ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool IsConstructor() const { 601ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return (method_access_flags_ & kAccConstructor) != 0; 602ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 603ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 604ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is the method verified static? 605ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool IsStatic() const { 606ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return (method_access_flags_ & kAccStatic) != 0; 607ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 608ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 609ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Return the register type for the method. 610b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers const RegType& GetMethodReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 611ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 612ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Get a type representing the declaring class of the method. 613b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers const RegType& GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 614ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers 615776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers /* 616776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of 617776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * verification). For type-precise determination we have all the data we need, so we just need to 618776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * encode it in some clever fashion. 619776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure. 620776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */ 621776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers const std::vector<uint8_t>* GenerateGcMap(); 622776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 623776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Verify that the GC map associated with method_ is well formed 624776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void VerifyGcMap(const std::vector<uint8_t>& data); 625776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 626776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Compute sizes for GC map data 627776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers void ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc); 628776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 6297b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers InstructionFlags* CurrentInsnFlags(); 630776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 631776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // All the GC maps that the verifier has created 63251c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom typedef SafeMap<const MethodReference, const std::vector<uint8_t>*, 63351c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReferenceComparator> DexGcMapTable; 634637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers static ReaderWriterMutex* dex_gc_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 6350c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers static DexGcMapTable* dex_gc_maps_ GUARDED_BY(dex_gc_maps_lock_); 63651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static void SetDexGcMap(MethodReference ref, const std::vector<uint8_t>& dex_gc_map) 6370c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers LOCKS_EXCLUDED(dex_gc_maps_lock_); 638776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 63902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal 640980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea // Cast elision types. 641980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea typedef std::set<uint32_t> MethodSafeCastSet; 64251c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom typedef SafeMap<const MethodReference, const MethodSafeCastSet*, 64351c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReferenceComparator> SafeCastMap; 644980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea MethodVerifier::MethodSafeCastSet* GenerateSafeCastSet() 645980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static void SetSafeCastMap(MethodReference ref, const MethodSafeCastSet* mscs); 647980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea LOCKS_EXCLUDED(safecast_map_lock_); 648b9c37fb5746cc240e86677e56cb0d74d829e3504Sebastien Hertz static ReaderWriterMutex* safecast_map_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 649980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea static SafeCastMap* safecast_map_ GUARDED_BY(safecast_map_lock_); 650980d16b81f3dd78eb491b80bed9cd184016878c6Dragos Sbirlea 65102c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal // Devirtualization map. 65251c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom typedef SafeMap<const uint32_t, MethodReference> PcToConcreteMethodMap; 65351c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom typedef SafeMap<const MethodReference, const PcToConcreteMethodMap*, 65451c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReferenceComparator> DevirtualizationMapTable; 655d0583802482a7b2f54749edc4faa00303459f9a8Ian Rogers MethodVerifier::PcToConcreteMethodMap* GenerateDevirtMap() 65633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 65702c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal 658637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers static ReaderWriterMutex* devirt_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 65902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal static DevirtualizationMapTable* devirt_maps_ GUARDED_BY(devirt_maps_lock_); 66051c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static void SetDevirtMap(MethodReference ref, 661d0583802482a7b2f54749edc4faa00303459f9a8Ian Rogers const PcToConcreteMethodMap* pc_method_map) 66202c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal LOCKS_EXCLUDED(devirt_maps_lock_); 66351c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom typedef std::set<ClassReference> RejectedClassesTable; 66400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 6654d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz static RejectedClassesTable* rejected_classes_ GUARDED_BY(rejected_classes_lock_); 6660a1038b0a30a52dff1a449a989825e808a83df80Elliott Hughes 66751c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom static void AddRejectedClass(ClassReference ref) 66800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(rejected_classes_lock_); 669776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 670776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegTypeCache reg_types_; 671776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 672776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers PcToRegisterLineTable reg_table_; 673776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 674776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Storage for the register status we're currently working on. 675776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UniquePtr<RegisterLine> work_line_; 676776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 677776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The address of the instruction we're currently working on, note that this is in 2 byte 678776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // quantities 679776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers uint32_t work_insn_idx_; 680776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 681776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Storage for the register status we're saving for later. 682776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers UniquePtr<RegisterLine> saved_line_; 683776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 684637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const uint32_t dex_method_idx_; // The method we're working on. 68500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Its object representation if known. 686ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* mirror_method_ GUARDED_BY(Locks::mutator_lock_); 687637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const uint32_t method_access_flags_; // Method's access flags. 688637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const DexFile* const dex_file_; // The dex file containing the method. 68900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The dex_cache for the declaring class of the method. 6902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_); 69100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The class loader for the declaring class of the method. 6922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_); 693637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const uint32_t class_def_idx_; // The class def index of the declaring class of the method. 694637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const DexFile::CodeItem* const code_item_; // The code item containing the code for the method. 695637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class. 6967b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers // Instruction widths and flags, one entry per code unit. 6977b3ddd27c223fcce784314f78fda7f67dcb37730Ian Rogers UniquePtr<InstructionFlags[]> insn_flags_; 698c15853b8b5da9dd8fb28e2adbbd61af34555e4c2Sebastien Hertz // The dex PC of a FindLocksAtDexPc request, -1 otherwise. 69908fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes uint32_t interesting_dex_pc_; 70008fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // The container into which FindLocksAtDexPc should write the registers containing held locks, 70108fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes // NULL if we're not doing FindLocksAtDexPc. 70208fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes std::vector<uint32_t>* monitor_enter_dex_pcs_; 70308fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 704ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // The types of any error that occurs. 705ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::vector<VerifyError> failures_; 706ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Error messages associated with failures. 707ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers std::vector<std::ostringstream*> failure_messages_; 708ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Is there a pending hard failure? 709ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers bool have_pending_hard_failure_; 710faf459e5decdfcf6dd7844947898beefe31e6435jeffhao // Is there a pending runtime throw failure? A runtime throw failure is when an instruction 711faf459e5decdfcf6dd7844947898beefe31e6435jeffhao // would fail at runtime throwing an exception. Such an instruction causes the following code 712faf459e5decdfcf6dd7844947898beefe31e6435jeffhao // to be unreachable. This is set by Fail and used to ensure we don't process unreachable 713faf459e5decdfcf6dd7844947898beefe31e6435jeffhao // instructions that would hard fail the verification. 714faf459e5decdfcf6dd7844947898beefe31e6435jeffhao bool have_pending_runtime_throw_failure_; 715776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 716ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // Info message log use primarily for verifier diagnostics. 717776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::ostringstream info_messages_; 718776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 719776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The number of occurrences of specific opcodes. 720776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers size_t new_instance_count_; 721776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers size_t monitor_enter_count_; 72280537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes 72380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes const bool can_load_classes_; 724ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao 725ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao // Converts soft failures to hard failures when false. Only false when the compiler isn't 726ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao // running and the verifier is called from the class linker. 727ee9889502a34a08741a6f8ecc02917202de9d773Jeff Hao const bool allow_soft_failures_; 7284d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz 7294d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz // Indicates if the method being verified contains at least one check-cast instruction. 7304d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz bool has_check_casts_; 7314d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz 7324d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz // Indicates if the method being verified contains at least one invoke-virtual/range 7334d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz // or invoke-interface/range. 7344d4adb1dae07bb7421e863732ab789413a3b43f0Sebastien Hertz bool has_virtual_or_interface_invokes_; 735776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}; 736e4f0b2ab4abd8e942a099e9b9b4682fbdd9eb21cjeffhaostd::ostream& operator<<(std::ostream& os, const MethodVerifier::FailureKind& rhs); 737776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 738776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} // namespace verifier 739776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} // namespace art 740776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 741fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 742