• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dex_file_types.h"
27 #include "handle.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 }  // namespace mirror
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   // If `method` is null, the method is assumed unresolved.
92   static void MaybeRecordMethodResolution(const DexFile& dex_file,
93                                           uint32_t method_idx,
94                                           ArtMethod* method)
95       REQUIRES_SHARED(Locks::mutator_lock_)
96       REQUIRES(!Locks::verifier_deps_lock_);
97 
98   // Record the outcome `is_assignable` of type assignability test from `source`
99   // to `destination` as defined by RegType::AssignableFrom. `dex_file` is the
100   // owner of the method for which MethodVerifier performed the assignability test.
101   static void MaybeRecordAssignability(const DexFile& dex_file,
102                                        mirror::Class* destination,
103                                        mirror::Class* source,
104                                        bool is_strict,
105                                        bool is_assignable)
106       REQUIRES_SHARED(Locks::mutator_lock_)
107       REQUIRES(!Locks::verifier_deps_lock_);
108 
109   // Serialize the recorded dependencies and store the data into `buffer`.
110   // `dex_files` provides the order of the dex files in which the dependencies
111   // should be emitted.
112   void Encode(const std::vector<const DexFile*>& dex_files, std::vector<uint8_t>* buffer) const;
113 
114   void Dump(VariableIndentationOutputStream* vios) const;
115 
116   // Verify the encoded dependencies of this `VerifierDeps` are still valid.
117   bool ValidateDependencies(Handle<mirror::ClassLoader> class_loader, Thread* self) const
118       REQUIRES_SHARED(Locks::mutator_lock_);
119 
GetUnverifiedClasses(const DexFile & dex_file)120   const std::set<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const {
121     return GetDexFileDeps(dex_file)->unverified_classes_;
122   }
123 
OutputOnly()124   bool OutputOnly() const {
125     return output_only_;
126   }
127 
128  private:
129   static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1);
130 
131   using ClassResolutionBase = std::tuple<dex::TypeIndex, uint16_t>;
132   struct ClassResolution : public ClassResolutionBase {
133     ClassResolution() = default;
134     ClassResolution(const ClassResolution&) = default;
ClassResolutionClassResolution135     ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags)
136         : ClassResolutionBase(type_idx, access_flags) {}
137 
IsResolvedClassResolution138     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
GetDexTypeIndexClassResolution139     dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); }
GetAccessFlagsClassResolution140     uint16_t GetAccessFlags() const { return std::get<1>(*this); }
141   };
142 
143   using FieldResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
144   struct FieldResolution : public FieldResolutionBase {
145     FieldResolution() = default;
146     FieldResolution(const FieldResolution&) = default;
FieldResolutionFieldResolution147     FieldResolution(uint32_t field_idx, uint16_t access_flags, dex::StringIndex declaring_class_idx)
148         : FieldResolutionBase(field_idx, access_flags, declaring_class_idx) {}
149 
IsResolvedFieldResolution150     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
GetDexFieldIndexFieldResolution151     uint32_t GetDexFieldIndex() const { return std::get<0>(*this); }
GetAccessFlagsFieldResolution152     uint16_t GetAccessFlags() const { return std::get<1>(*this); }
GetDeclaringClassIndexFieldResolution153     dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
154   };
155 
156   using MethodResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
157   struct MethodResolution : public MethodResolutionBase {
158     MethodResolution() = default;
159     MethodResolution(const MethodResolution&) = default;
MethodResolutionMethodResolution160     MethodResolution(uint32_t method_idx,
161                      uint16_t access_flags,
162                      dex::StringIndex declaring_class_idx)
163         : MethodResolutionBase(method_idx, access_flags, declaring_class_idx) {}
164 
IsResolvedMethodResolution165     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
GetDexMethodIndexMethodResolution166     uint32_t GetDexMethodIndex() const { return std::get<0>(*this); }
GetAccessFlagsMethodResolution167     uint16_t GetAccessFlags() const { return std::get<1>(*this); }
GetDeclaringClassIndexMethodResolution168     dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
169   };
170 
171   using TypeAssignabilityBase = std::tuple<dex::StringIndex, dex::StringIndex>;
172   struct TypeAssignability : public TypeAssignabilityBase {
173     TypeAssignability() = default;
174     TypeAssignability(const TypeAssignability&) = default;
TypeAssignabilityTypeAssignability175     TypeAssignability(dex::StringIndex destination_idx, dex::StringIndex source_idx)
176         : TypeAssignabilityBase(destination_idx, source_idx) {}
177 
GetDestinationTypeAssignability178     dex::StringIndex GetDestination() const { return std::get<0>(*this); }
GetSourceTypeAssignability179     dex::StringIndex GetSource() const { return std::get<1>(*this); }
180   };
181 
182   // Data structure representing dependencies collected during verification of
183   // methods inside one DexFile.
184   struct DexFileDeps {
185     // Vector of strings which are not present in the corresponding DEX file.
186     // These are referred to with ids starting with `NumStringIds()` of that DexFile.
187     std::vector<std::string> strings_;
188 
189     // Set of class pairs recording the outcome of assignability test from one
190     // of the two types to the other.
191     std::set<TypeAssignability> assignable_types_;
192     std::set<TypeAssignability> unassignable_types_;
193 
194     // Sets of recorded class/field/method resolutions.
195     std::set<ClassResolution> classes_;
196     std::set<FieldResolution> fields_;
197     std::set<MethodResolution> methods_;
198 
199     // List of classes that were not fully verified in that dex file.
200     std::set<dex::TypeIndex> unverified_classes_;
201 
202     bool Equals(const DexFileDeps& rhs) const;
203   };
204 
205   VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only);
206 
207   // Finds the DexFileDep instance associated with `dex_file`, or nullptr if
208   // `dex_file` is not reported as being compiled.
209   DexFileDeps* GetDexFileDeps(const DexFile& dex_file);
210 
211   const DexFileDeps* GetDexFileDeps(const DexFile& dex_file) const;
212 
213   // Returns true if `klass` is null or not defined in any of dex files which
214   // were reported as being compiled.
215   bool IsInClassPath(ObjPtr<mirror::Class> klass) const
216       REQUIRES_SHARED(Locks::mutator_lock_);
217 
218   // Finds the class in the classpath that makes `source` inherit` from `destination`.
219   // Returns null if a class defined in the compiled DEX files, and assignable to
220   // `source`, direclty inherits from `destination`.
221   mirror::Class* FindOneClassPathBoundaryForInterface(mirror::Class* destination,
222                                                       mirror::Class* source) const
223       REQUIRES_SHARED(Locks::mutator_lock_);
224 
225   // Returns the index of `str`. If it is defined in `dex_file_`, this is the dex
226   // string ID. If not, an ID is assigned to the string and cached in `strings_`
227   // of the corresponding DexFileDeps structure (either provided or inferred from
228   // `dex_file`).
229   dex::StringIndex GetIdFromString(const DexFile& dex_file, const std::string& str)
230       REQUIRES(!Locks::verifier_deps_lock_);
231 
232   // Returns the string represented by `id`.
233   std::string GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) const;
234 
235   // Returns the bytecode access flags of `element` (bottom 16 bits), or
236   // `kUnresolvedMarker` if `element` is null.
237   template <typename T>
238   static uint16_t GetAccessFlags(T* element)
239       REQUIRES_SHARED(Locks::mutator_lock_);
240 
241   // Returns a string ID of the descriptor of the declaring class of `element`,
242   // or `kUnresolvedMarker` if `element` is null.
243   dex::StringIndex GetMethodDeclaringClassStringId(const DexFile& dex_file,
244                                                    uint32_t dex_method_idx,
245                                                    ArtMethod* method)
246       REQUIRES_SHARED(Locks::mutator_lock_);
247   dex::StringIndex GetFieldDeclaringClassStringId(const DexFile& dex_file,
248                                                   uint32_t dex_field_idx,
249                                                   ArtField* field)
250       REQUIRES_SHARED(Locks::mutator_lock_);
251 
252   // Returns a string ID of the descriptor of the class.
253   dex::StringIndex GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
254       REQUIRES_SHARED(Locks::mutator_lock_)
255       REQUIRES(!Locks::verifier_deps_lock_);
256 
257   void AddClassResolution(const DexFile& dex_file,
258                           dex::TypeIndex type_idx,
259                           mirror::Class* klass)
260       REQUIRES_SHARED(Locks::mutator_lock_)
261       REQUIRES(!Locks::verifier_deps_lock_);
262 
263   void AddFieldResolution(const DexFile& dex_file,
264                           uint32_t field_idx,
265                           ArtField* field)
266       REQUIRES_SHARED(Locks::mutator_lock_)
267       REQUIRES(!Locks::verifier_deps_lock_);
268 
269   void AddMethodResolution(const DexFile& dex_file,
270                            uint32_t method_idx,
271                            ArtMethod* method)
272       REQUIRES_SHARED(Locks::mutator_lock_)
273       REQUIRES(!Locks::verifier_deps_lock_);
274 
275   void AddAssignability(const DexFile& dex_file,
276                         mirror::Class* destination,
277                         mirror::Class* source,
278                         bool is_strict,
279                         bool is_assignable)
280       REQUIRES_SHARED(Locks::mutator_lock_);
281 
282   bool Equals(const VerifierDeps& rhs) const;
283 
284   // Verify `dex_file` according to the `deps`, that is going over each
285   // `DexFileDeps` field, and checking that the recorded information still
286   // holds.
287   bool VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
288                      const DexFile& dex_file,
289                      const DexFileDeps& deps,
290                      Thread* self) const
291       REQUIRES_SHARED(Locks::mutator_lock_);
292 
293   bool VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
294                            const DexFile& dex_file,
295                            const std::set<TypeAssignability>& assignables,
296                            bool expected_assignability,
297                            Thread* self) const
298       REQUIRES_SHARED(Locks::mutator_lock_);
299 
300   // Verify that the set of resolved classes at the point of creation
301   // of this `VerifierDeps` is still the same.
302   bool VerifyClasses(Handle<mirror::ClassLoader> class_loader,
303                      const DexFile& dex_file,
304                      const std::set<ClassResolution>& classes,
305                      Thread* self) const
306       REQUIRES_SHARED(Locks::mutator_lock_);
307 
308   // Verify that the set of resolved fields at the point of creation
309   // of this `VerifierDeps` is still the same, and each field resolves to the
310   // same field holder and access flags.
311   bool VerifyFields(Handle<mirror::ClassLoader> class_loader,
312                     const DexFile& dex_file,
313                     const std::set<FieldResolution>& classes,
314                     Thread* self) const
315       REQUIRES_SHARED(Locks::mutator_lock_)
316       REQUIRES(!Locks::verifier_deps_lock_);
317 
318   // Verify that the set of resolved methods at the point of creation
319   // of this `VerifierDeps` is still the same, and each method resolves to the
320   // same method holder, access flags, and invocation kind.
321   bool VerifyMethods(Handle<mirror::ClassLoader> class_loader,
322                      const DexFile& dex_file,
323                      const std::set<MethodResolution>& methods,
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   // Output only signifies if we are using the verifier deps to verify or just to generate them.
331   const bool output_only_;
332 
333   friend class VerifierDepsTest;
334   ART_FRIEND_TEST(VerifierDepsTest, StringToId);
335   ART_FRIEND_TEST(VerifierDepsTest, EncodeDecode);
336   ART_FRIEND_TEST(VerifierDepsTest, EncodeDecodeMulti);
337   ART_FRIEND_TEST(VerifierDepsTest, VerifyDeps);
338   ART_FRIEND_TEST(VerifierDepsTest, CompilerDriver);
339 };
340 
341 }  // namespace verifier
342 }  // namespace art
343 
344 #endif  // ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_
345