Home | History | Annotate | Download | only in verifier
      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