1 /* 2 * Copyright (C) 2016 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_VERIFIER_DEPS_H_ 18 #define ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_ 19 20 #include <map> 21 #include <set> 22 #include <vector> 23 24 #include "base/array_ref.h" 25 #include "base/mutex.h" 26 #include "handle.h" 27 #include "method_resolution_kind.h" 28 #include "obj_ptr.h" 29 #include "thread.h" 30 #include "verifier_enums.h" // For MethodVerifier::FailureKind. 31 32 namespace art { 33 34 class ArtField; 35 class ArtMethod; 36 class DexFile; 37 class VariableIndentationOutputStream; 38 39 namespace mirror { 40 class Class; 41 class ClassLoader; 42 } 43 44 namespace verifier { 45 46 // Verification dependencies collector class used by the MethodVerifier to record 47 // resolution outcomes and type assignability tests of classes/methods/fields 48 // not present in the set of compiled DEX files, that is classes/methods/fields 49 // defined in the classpath. 50 // The compilation driver initializes the class and registers all DEX files 51 // which are being compiled. Classes defined in DEX files outside of this set 52 // (or synthesized classes without associated DEX files) are considered being 53 // in the classpath. 54 // During code-flow verification, the MethodVerifier informs VerifierDeps 55 // about the outcome of every resolution and assignability test, and 56 // the VerifierDeps object records them if their outcome may change with 57 // changes in the classpath. 58 class VerifierDeps { 59 public: 60 explicit VerifierDeps(const std::vector<const DexFile*>& dex_files); 61 62 VerifierDeps(const std::vector<const DexFile*>& dex_files, ArrayRef<const uint8_t> data); 63 64 // Merge `other` into this `VerifierDeps`'. `other` and `this` must be for the 65 // same set of dex files. 66 void MergeWith(const VerifierDeps& other, const std::vector<const DexFile*>& dex_files); 67 68 // Record the verification status of the class at `type_idx`. 69 static void MaybeRecordVerificationStatus(const DexFile& dex_file, 70 dex::TypeIndex type_idx, 71 FailureKind failure_kind) 72 REQUIRES(!Locks::verifier_deps_lock_); 73 74 // Record the outcome `klass` of resolving type `type_idx` from `dex_file`. 75 // If `klass` is null, the class is assumed unresolved. 76 static void MaybeRecordClassResolution(const DexFile& dex_file, 77 dex::TypeIndex type_idx, 78 mirror::Class* klass) 79 REQUIRES_SHARED(Locks::mutator_lock_) 80 REQUIRES(!Locks::verifier_deps_lock_); 81 82 // Record the outcome `field` of resolving field `field_idx` from `dex_file`. 83 // If `field` is null, the field is assumed unresolved. 84 static void MaybeRecordFieldResolution(const DexFile& dex_file, 85 uint32_t field_idx, 86 ArtField* field) 87 REQUIRES_SHARED(Locks::mutator_lock_) 88 REQUIRES(!Locks::verifier_deps_lock_); 89 90 // Record the outcome `method` of resolving method `method_idx` from `dex_file` 91 // using `res_kind` kind of method resolution algorithm. If `method` is null, 92 // the method is assumed unresolved. 93 static void MaybeRecordMethodResolution(const DexFile& dex_file, 94 uint32_t method_idx, 95 MethodResolutionKind res_kind, 96 ArtMethod* method) 97 REQUIRES_SHARED(Locks::mutator_lock_) 98 REQUIRES(!Locks::verifier_deps_lock_); 99 100 // Record the outcome `is_assignable` of type assignability test from `source` 101 // to `destination` as defined by RegType::AssignableFrom. `dex_file` is the 102 // owner of the method for which MethodVerifier performed the assignability test. 103 static void MaybeRecordAssignability(const DexFile& dex_file, 104 mirror::Class* destination, 105 mirror::Class* source, 106 bool is_strict, 107 bool is_assignable) 108 REQUIRES_SHARED(Locks::mutator_lock_) 109 REQUIRES(!Locks::verifier_deps_lock_); 110 111 // Serialize the recorded dependencies and store the data into `buffer`. 112 // `dex_files` provides the order of the dex files in which the dependencies 113 // should be emitted. 114 void Encode(const std::vector<const DexFile*>& dex_files, std::vector<uint8_t>* buffer) const; 115 116 void Dump(VariableIndentationOutputStream* vios) const; 117 118 // Verify the encoded dependencies of this `VerifierDeps` are still valid. 119 bool ValidateDependencies(Handle<mirror::ClassLoader> class_loader, Thread* self) const 120 REQUIRES_SHARED(Locks::mutator_lock_); 121 122 const std::vector<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const { 123 return GetDexFileDeps(dex_file)->unverified_classes_; 124 } 125 126 private: 127 static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1); 128 129 using ClassResolutionBase = std::tuple<dex::TypeIndex, uint16_t>; 130 struct ClassResolution : public ClassResolutionBase { 131 ClassResolution() = default; 132 ClassResolution(const ClassResolution&) = default; 133 ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags) 134 : ClassResolutionBase(type_idx, access_flags) {} 135 136 bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; } 137 dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); } 138 uint16_t GetAccessFlags() const { return std::get<1>(*this); } 139 }; 140 141 using FieldResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>; 142 struct FieldResolution : public FieldResolutionBase { 143 FieldResolution() = default; 144 FieldResolution(const FieldResolution&) = default; 145 FieldResolution(uint32_t field_idx, uint16_t access_flags, dex::StringIndex declaring_class_idx) 146 : FieldResolutionBase(field_idx, access_flags, declaring_class_idx) {} 147 148 bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; } 149 uint32_t GetDexFieldIndex() const { return std::get<0>(*this); } 150 uint16_t GetAccessFlags() const { return std::get<1>(*this); } 151 dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); } 152 }; 153 154 using MethodResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>; 155 struct MethodResolution : public MethodResolutionBase { 156 MethodResolution() = default; 157 MethodResolution(const MethodResolution&) = default; 158 MethodResolution(uint32_t method_idx, 159 uint16_t access_flags, 160 dex::StringIndex declaring_class_idx) 161 : MethodResolutionBase(method_idx, access_flags, declaring_class_idx) {} 162 163 bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; } 164 uint32_t GetDexMethodIndex() const { return std::get<0>(*this); } 165 uint16_t GetAccessFlags() const { return std::get<1>(*this); } 166 dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); } 167 }; 168 169 using TypeAssignabilityBase = std::tuple<dex::StringIndex, dex::StringIndex>; 170 struct TypeAssignability : public TypeAssignabilityBase { 171 TypeAssignability() = default; 172 TypeAssignability(const TypeAssignability&) = default; 173 TypeAssignability(dex::StringIndex destination_idx, dex::StringIndex source_idx) 174 : TypeAssignabilityBase(destination_idx, source_idx) {} 175 176 dex::StringIndex GetDestination() const { return std::get<0>(*this); } 177 dex::StringIndex GetSource() const { return std::get<1>(*this); } 178 }; 179 180 // Data structure representing dependencies collected during verification of 181 // methods inside one DexFile. 182 struct DexFileDeps { 183 // Vector of strings which are not present in the corresponding DEX file. 184 // These are referred to with ids starting with `NumStringIds()` of that DexFile. 185 std::vector<std::string> strings_; 186 187 // Set of class pairs recording the outcome of assignability test from one 188 // of the two types to the other. 189 std::set<TypeAssignability> assignable_types_; 190 std::set<TypeAssignability> unassignable_types_; 191 192 // Sets of recorded class/field/method resolutions. 193 std::set<ClassResolution> classes_; 194 std::set<FieldResolution> fields_; 195 std::set<MethodResolution> direct_methods_; 196 std::set<MethodResolution> virtual_methods_; 197 std::set<MethodResolution> interface_methods_; 198 199 // List of classes that were not fully verified in that dex file. 200 std::vector<dex::TypeIndex> unverified_classes_; 201 202 bool Equals(const DexFileDeps& rhs) const; 203 }; 204 205 // Finds the DexFileDep instance associated with `dex_file`, or nullptr if 206 // `dex_file` is not reported as being compiled. 207 DexFileDeps* GetDexFileDeps(const DexFile& dex_file); 208 209 const DexFileDeps* GetDexFileDeps(const DexFile& dex_file) const; 210 211 // Returns true if `klass` is null or not defined in any of dex files which 212 // were reported as being compiled. 213 bool IsInClassPath(ObjPtr<mirror::Class> klass) const 214 REQUIRES_SHARED(Locks::mutator_lock_); 215 216 // Finds the class in the classpath that makes `source` inherit` from `destination`. 217 // Returns null if a class defined in the compiled DEX files, and assignable to 218 // `source`, direclty inherits from `destination`. 219 mirror::Class* FindOneClassPathBoundaryForInterface(mirror::Class* destination, 220 mirror::Class* source) const 221 REQUIRES_SHARED(Locks::mutator_lock_); 222 223 // Returns the index of `str`. If it is defined in `dex_file_`, this is the dex 224 // string ID. If not, an ID is assigned to the string and cached in `strings_` 225 // of the corresponding DexFileDeps structure (either provided or inferred from 226 // `dex_file`). 227 dex::StringIndex GetIdFromString(const DexFile& dex_file, const std::string& str) 228 REQUIRES(!Locks::verifier_deps_lock_); 229 230 // Returns the string represented by `id`. 231 std::string GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) const; 232 233 // Returns the bytecode access flags of `element` (bottom 16 bits), or 234 // `kUnresolvedMarker` if `element` is null. 235 template <typename T> 236 static uint16_t GetAccessFlags(T* element) 237 REQUIRES_SHARED(Locks::mutator_lock_); 238 239 // Returns a string ID of the descriptor of the declaring class of `element`, 240 // or `kUnresolvedMarker` if `element` is null. 241 dex::StringIndex GetMethodDeclaringClassStringId(const DexFile& dex_file, 242 uint32_t dex_method_idx, 243 ArtMethod* method) 244 REQUIRES_SHARED(Locks::mutator_lock_); 245 dex::StringIndex GetFieldDeclaringClassStringId(const DexFile& dex_file, 246 uint32_t dex_field_idx, 247 ArtField* field) 248 REQUIRES_SHARED(Locks::mutator_lock_); 249 250 // Returns a string ID of the descriptor of the class. 251 dex::StringIndex GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass) 252 REQUIRES_SHARED(Locks::mutator_lock_) 253 REQUIRES(!Locks::verifier_deps_lock_); 254 255 void AddClassResolution(const DexFile& dex_file, 256 dex::TypeIndex type_idx, 257 mirror::Class* klass) 258 REQUIRES_SHARED(Locks::mutator_lock_) 259 REQUIRES(!Locks::verifier_deps_lock_); 260 261 void AddFieldResolution(const DexFile& dex_file, 262 uint32_t field_idx, 263 ArtField* field) 264 REQUIRES_SHARED(Locks::mutator_lock_) 265 REQUIRES(!Locks::verifier_deps_lock_); 266 267 void AddMethodResolution(const DexFile& dex_file, 268 uint32_t method_idx, 269 MethodResolutionKind res_kind, 270 ArtMethod* method) 271 REQUIRES_SHARED(Locks::mutator_lock_) 272 REQUIRES(!Locks::verifier_deps_lock_); 273 274 void AddAssignability(const DexFile& dex_file, 275 mirror::Class* destination, 276 mirror::Class* source, 277 bool is_strict, 278 bool is_assignable) 279 REQUIRES_SHARED(Locks::mutator_lock_); 280 281 bool Equals(const VerifierDeps& rhs) const; 282 283 // Verify `dex_file` according to the `deps`, that is going over each 284 // `DexFileDeps` field, and checking that the recorded information still 285 // holds. 286 bool VerifyDexFile(Handle<mirror::ClassLoader> class_loader, 287 const DexFile& dex_file, 288 const DexFileDeps& deps, 289 Thread* self) const 290 REQUIRES_SHARED(Locks::mutator_lock_); 291 292 bool VerifyAssignability(Handle<mirror::ClassLoader> class_loader, 293 const DexFile& dex_file, 294 const std::set<TypeAssignability>& assignables, 295 bool expected_assignability, 296 Thread* self) const 297 REQUIRES_SHARED(Locks::mutator_lock_); 298 299 // Verify that the set of resolved classes at the point of creation 300 // of this `VerifierDeps` is still the same. 301 bool VerifyClasses(Handle<mirror::ClassLoader> class_loader, 302 const DexFile& dex_file, 303 const std::set<ClassResolution>& classes, 304 Thread* self) const 305 REQUIRES_SHARED(Locks::mutator_lock_); 306 307 // Verify that the set of resolved fields at the point of creation 308 // of this `VerifierDeps` is still the same, and each field resolves to the 309 // same field holder and access flags. 310 bool VerifyFields(Handle<mirror::ClassLoader> class_loader, 311 const DexFile& dex_file, 312 const std::set<FieldResolution>& classes, 313 Thread* self) const 314 REQUIRES_SHARED(Locks::mutator_lock_) 315 REQUIRES(!Locks::verifier_deps_lock_); 316 317 // Verify that the set of resolved methods at the point of creation 318 // of this `VerifierDeps` is still the same, and each method resolves to the 319 // same method holder, access flags, and invocation kind. 320 bool VerifyMethods(Handle<mirror::ClassLoader> class_loader, 321 const DexFile& dex_file, 322 const std::set<MethodResolution>& methods, 323 MethodResolutionKind kind, 324 Thread* self) const 325 REQUIRES_SHARED(Locks::mutator_lock_); 326 327 // Map from DexFiles into dependencies collected from verification of their methods. 328 std::map<const DexFile*, std::unique_ptr<DexFileDeps>> dex_deps_; 329 330 friend class VerifierDepsTest; 331 ART_FRIEND_TEST(VerifierDepsTest, StringToId); 332 ART_FRIEND_TEST(VerifierDepsTest, EncodeDecode); 333 ART_FRIEND_TEST(VerifierDepsTest, EncodeDecodeMulti); 334 ART_FRIEND_TEST(VerifierDepsTest, VerifyDeps); 335 ART_FRIEND_TEST(VerifierDepsTest, CompilerDriver); 336 }; 337 338 } // namespace verifier 339 } // namespace art 340 341 #endif // ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_ 342