1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 18 #define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 19 20 #include <memory> 21 #include <sstream> 22 #include <vector> 23 24 #include <android-base/logging.h> 25 26 #include "base/arena_allocator.h" 27 #include "base/macros.h" 28 #include "base/scoped_arena_containers.h" 29 #include "base/value_object.h" 30 #include "dex/code_item_accessors.h" 31 #include "dex/dex_file_types.h" 32 #include "dex/method_reference.h" 33 #include "handle.h" 34 #include "instruction_flags.h" 35 #include "reg_type_cache.h" 36 #include "register_line.h" 37 #include "verifier_enums.h" 38 39 namespace art { 40 41 class ClassLinker; 42 class CompilerCallbacks; 43 class DexFile; 44 class Instruction; 45 struct ReferenceMap2Visitor; 46 class Thread; 47 class VariableIndentationOutputStream; 48 49 namespace dex { 50 struct ClassDef; 51 struct CodeItem; 52 } // namespace dex 53 54 namespace mirror { 55 class DexCache; 56 } // namespace mirror 57 58 namespace verifier { 59 60 class MethodVerifier; 61 class RegisterLine; 62 using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>; 63 class RegType; 64 struct ScopedNewLine; 65 66 // We don't need to store the register data for many instructions, because we either only need 67 // it at branch points (for verification) or GC points and branches (for verification + 68 // type-precise register analysis). 69 enum RegisterTrackingMode { 70 kTrackRegsBranches, 71 kTrackCompilerInterestPoints, 72 kTrackRegsAll, 73 }; 74 75 // A mapping from a dex pc to the register line statuses as they are immediately prior to the 76 // execution of that instruction. 77 class PcToRegisterLineTable { 78 public: 79 explicit PcToRegisterLineTable(ScopedArenaAllocator& allocator); 80 ~PcToRegisterLineTable(); 81 82 // Initialize the RegisterTable. Every instruction address can have a different set of information 83 // about what's in which register, but for verification purposes we only need to store it at 84 // branch target addresses (because we merge into that). 85 void Init(RegisterTrackingMode mode, 86 InstructionFlags* flags, 87 uint32_t insns_size, 88 uint16_t registers_size, 89 ScopedArenaAllocator& allocator, 90 RegTypeCache* reg_types); 91 IsInitialized()92 bool IsInitialized() const { 93 return !register_lines_.empty(); 94 } 95 GetLine(size_t idx)96 RegisterLine* GetLine(size_t idx) const { 97 return register_lines_[idx].get(); 98 } 99 100 private: 101 ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_; 102 103 DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable); 104 }; 105 106 // The verifier 107 class MethodVerifier { 108 public: 109 static MethodVerifier* VerifyMethodAndDump(Thread* self, 110 VariableIndentationOutputStream* vios, 111 uint32_t method_idx, 112 const DexFile* dex_file, 113 Handle<mirror::DexCache> dex_cache, 114 Handle<mirror::ClassLoader> class_loader, 115 const dex::ClassDef& class_def, 116 const dex::CodeItem* code_item, ArtMethod* method, 117 uint32_t method_access_flags, 118 uint32_t api_level) 119 REQUIRES_SHARED(Locks::mutator_lock_); 120 GetDexFile()121 const DexFile& GetDexFile() const { 122 DCHECK(dex_file_ != nullptr); 123 return *dex_file_; 124 } 125 GetRegTypeCache()126 RegTypeCache* GetRegTypeCache() { 127 return ®_types_; 128 } 129 130 // Log a verification failure. 131 std::ostream& Fail(VerifyError error); 132 133 // Log for verification information. 134 ScopedNewLine LogVerifyInfo(); 135 136 // Information structure for a lock held at a certain point in time. 137 struct DexLockInfo { 138 // The registers aliasing the lock. 139 std::set<uint32_t> dex_registers; 140 // The dex PC of the monitor-enter instruction. 141 uint32_t dex_pc; 142 DexLockInfoDexLockInfo143 explicit DexLockInfo(uint32_t dex_pc_in) { 144 dex_pc = dex_pc_in; 145 } 146 }; 147 // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding 148 // to the locks held at 'dex_pc' in method 'm'. 149 // Note: this is the only situation where the verifier will visit quickened instructions. 150 static void FindLocksAtDexPc(ArtMethod* m, 151 uint32_t dex_pc, 152 std::vector<DexLockInfo>* monitor_enter_dex_pcs, 153 uint32_t api_level) 154 REQUIRES_SHARED(Locks::mutator_lock_); 155 156 static void Init() REQUIRES_SHARED(Locks::mutator_lock_); 157 static void Shutdown(); 158 159 virtual ~MethodVerifier(); 160 161 static void VisitStaticRoots(RootVisitor* visitor) 162 REQUIRES_SHARED(Locks::mutator_lock_); 163 void VisitRoots(RootVisitor* visitor, const RootInfo& roots) 164 REQUIRES_SHARED(Locks::mutator_lock_); 165 166 // Accessors used by the compiler via CompilerCallback CodeItem()167 const CodeItemDataAccessor& CodeItem() const { 168 return code_item_accessor_; 169 } 170 RegisterLine* GetRegLine(uint32_t dex_pc); 171 ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const; 172 173 MethodReference GetMethodReference() const; 174 bool HasCheckCasts() const; 175 bool HasFailures() const; HasInstructionThatWillThrow()176 bool HasInstructionThatWillThrow() const { 177 return have_any_pending_runtime_throw_failure_; 178 } 179 180 virtual const RegType& ResolveCheckedClass(dex::TypeIndex class_idx) 181 REQUIRES_SHARED(Locks::mutator_lock_) = 0; 182 GetEncounteredFailureTypes()183 uint32_t GetEncounteredFailureTypes() { 184 return encountered_failure_types_; 185 } 186 187 protected: 188 MethodVerifier(Thread* self, 189 const DexFile* dex_file, 190 const dex::CodeItem* code_item, 191 uint32_t dex_method_idx, 192 bool can_load_classes, 193 bool allow_thread_suspension, 194 bool allow_soft_failures) 195 REQUIRES_SHARED(Locks::mutator_lock_); 196 197 // Verification result for method(s). Includes a (maximum) failure kind, and (the union of) 198 // all failure types. 199 struct FailureData : ValueObject { 200 FailureKind kind = FailureKind::kNoFailure; 201 uint32_t types = 0U; 202 203 // Merge src into this. Uses the most severe failure kind, and the union of types. 204 void Merge(const FailureData& src); 205 }; 206 207 /* 208 * Perform verification on a single method. 209 * 210 * We do this in three passes: 211 * (1) Walk through all code units, determining instruction locations, 212 * widths, and other characteristics. 213 * (2) Walk through all code units, performing static checks on 214 * operands. 215 * (3) Iterate through the method, checking type safety and looking 216 * for code flow problems. 217 */ 218 static FailureData VerifyMethod(Thread* self, 219 uint32_t method_idx, 220 const DexFile* dex_file, 221 Handle<mirror::DexCache> dex_cache, 222 Handle<mirror::ClassLoader> class_loader, 223 const dex::ClassDef& class_def_idx, 224 const dex::CodeItem* code_item, 225 ArtMethod* method, 226 uint32_t method_access_flags, 227 CompilerCallbacks* callbacks, 228 bool allow_soft_failures, 229 HardFailLogMode log_level, 230 bool need_precise_constants, 231 uint32_t api_level, 232 std::string* hard_failure_msg) 233 REQUIRES_SHARED(Locks::mutator_lock_); 234 235 template <bool kVerifierDebug> 236 static FailureData VerifyMethod(Thread* self, 237 uint32_t method_idx, 238 const DexFile* dex_file, 239 Handle<mirror::DexCache> dex_cache, 240 Handle<mirror::ClassLoader> class_loader, 241 const dex::ClassDef& class_def_idx, 242 const dex::CodeItem* code_item, 243 ArtMethod* method, 244 uint32_t method_access_flags, 245 CompilerCallbacks* callbacks, 246 bool allow_soft_failures, 247 HardFailLogMode log_level, 248 bool need_precise_constants, 249 uint32_t api_level, 250 std::string* hard_failure_msg) 251 REQUIRES_SHARED(Locks::mutator_lock_); 252 253 // For VerifierDepsTest. TODO: Refactor. 254 255 // Run verification on the method. Returns true if verification completes and false if the input 256 // has an irrecoverable corruption. 257 virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0; 258 static MethodVerifier* CreateVerifier(Thread* self, 259 const DexFile* dex_file, 260 Handle<mirror::DexCache> dex_cache, 261 Handle<mirror::ClassLoader> class_loader, 262 const dex::ClassDef& class_def, 263 const dex::CodeItem* code_item, 264 uint32_t method_idx, 265 ArtMethod* method, 266 uint32_t access_flags, 267 bool can_load_classes, 268 bool allow_soft_failures, 269 bool need_precise_constants, 270 bool verify_to_dump, 271 bool allow_thread_suspension, 272 uint32_t api_level) 273 REQUIRES_SHARED(Locks::mutator_lock_); 274 275 // The thread we're verifying on. 276 Thread* const self_; 277 278 // Arena allocator. 279 ArenaStack arena_stack_; 280 ScopedArenaAllocator allocator_; 281 282 RegTypeCache reg_types_; 283 284 PcToRegisterLineTable reg_table_; 285 286 // Storage for the register status we're currently working on. 287 RegisterLineArenaUniquePtr work_line_; 288 289 // The address of the instruction we're currently working on, note that this is in 2 byte 290 // quantities 291 uint32_t work_insn_idx_; 292 293 // Storage for the register status we're saving for later. 294 RegisterLineArenaUniquePtr saved_line_; 295 296 const uint32_t dex_method_idx_; // The method we're working on. 297 const DexFile* const dex_file_; // The dex file containing the method. 298 const CodeItemDataAccessor code_item_accessor_; 299 300 // Instruction widths and flags, one entry per code unit. 301 // Owned, but not unique_ptr since insn_flags_ are allocated in arenas. 302 ArenaUniquePtr<InstructionFlags[]> insn_flags_; 303 304 // The types of any error that occurs. 305 std::vector<VerifyError> failures_; 306 // Error messages associated with failures. 307 std::vector<std::ostringstream*> failure_messages_; 308 // Is there a pending hard failure? 309 bool have_pending_hard_failure_; 310 // Is there a pending runtime throw failure? A runtime throw failure is when an instruction 311 // would fail at runtime throwing an exception. Such an instruction causes the following code 312 // to be unreachable. This is set by Fail and used to ensure we don't process unreachable 313 // instructions that would hard fail the verification. 314 // Note: this flag is reset after processing each instruction. 315 bool have_pending_runtime_throw_failure_; 316 // Is there a pending experimental failure? 317 bool have_pending_experimental_failure_; 318 319 // A version of the above that is not reset and thus captures if there were *any* throw failures. 320 bool have_any_pending_runtime_throw_failure_; 321 322 // Info message log use primarily for verifier diagnostics. 323 std::ostringstream info_messages_; 324 325 // Bitset of the encountered failure types. Bits are according to the values in VerifyError. 326 uint32_t encountered_failure_types_; 327 328 const bool can_load_classes_; 329 330 // Converts soft failures to hard failures when false. Only false when the compiler isn't 331 // running and the verifier is called from the class linker. 332 const bool allow_soft_failures_; 333 334 // Indicates the method being verified contains at least one check-cast or aput-object 335 // instruction. Aput-object operations implicitly check for array-store exceptions, similar to 336 // check-cast. 337 bool has_check_casts_; 338 339 // Link, for the method verifier root linked list. 340 MethodVerifier* link_; 341 342 friend class art::Thread; 343 friend class ClassVerifier; 344 friend class VerifierDepsTest; 345 346 DISALLOW_COPY_AND_ASSIGN(MethodVerifier); 347 }; 348 349 } // namespace verifier 350 } // namespace art 351 352 #endif // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_ 353