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 "dex/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 
    120   const std::set<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const {
    121     return GetDexFileDeps(dex_file)->unverified_classes_;
    122   }
    123 
    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;
    135     ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags)
    136         : ClassResolutionBase(type_idx, access_flags) {}
    137 
    138     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
    139     dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); }
    140     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;
    147     FieldResolution(uint32_t field_idx, uint16_t access_flags, dex::StringIndex declaring_class_idx)
    148         : FieldResolutionBase(field_idx, access_flags, declaring_class_idx) {}
    149 
    150     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
    151     uint32_t GetDexFieldIndex() const { return std::get<0>(*this); }
    152     uint16_t GetAccessFlags() const { return std::get<1>(*this); }
    153     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;
    160     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 
    165     bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
    166     uint32_t GetDexMethodIndex() const { return std::get<0>(*this); }
    167     uint16_t GetAccessFlags() const { return std::get<1>(*this); }
    168     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;
    175     TypeAssignability(dex::StringIndex destination_idx, dex::StringIndex source_idx)
    176         : TypeAssignabilityBase(destination_idx, source_idx) {}
    177 
    178     dex::StringIndex GetDestination() const { return std::get<0>(*this); }
    179     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