1ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil/*
2ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Copyright (C) 2016 The Android Open Source Project
3ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil *
4ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Licensed under the Apache License, Version 2.0 (the "License");
5ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * you may not use this file except in compliance with the License.
6ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * You may obtain a copy of the License at
7ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil *
8ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil *      http://www.apache.org/licenses/LICENSE-2.0
9ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil *
10ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Unless required by applicable law or agreed to in writing, software
11ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * distributed under the License is distributed on an "AS IS" BASIS,
12ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * See the License for the specific language governing permissions and
14ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * limitations under the License.
15ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil */
16ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
17ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#ifndef ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_
18ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#define ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_
19ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
20ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include <map>
21ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include <set>
22ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include <vector>
23ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
246f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil#include "base/array_ref.h"
25ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "base/mutex.h"
269e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_file_types.h"
276d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe#include "handle.h"
283398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier#include "obj_ptr.h"
296d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe#include "thread.h"
306d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe#include "verifier_enums.h"  // For MethodVerifier::FailureKind.
31ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
32ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace art {
336d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe
346d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass ArtField;
356d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass ArtMethod;
366d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass DexFile;
376d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass VariableIndentationOutputStream;
386d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe
396d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampenamespace mirror {
406d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass Class;
416d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampeclass ClassLoader;
42deae7db5864fa50c5a1cd6c232a17aeb986b36e1Andreas Gampe}  // namespace mirror
436d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe
44ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace verifier {
45ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
46ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// Verification dependencies collector class used by the MethodVerifier to record
47ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// resolution outcomes and type assignability tests of classes/methods/fields
48ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// not present in the set of compiled DEX files, that is classes/methods/fields
49ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// defined in the classpath.
50ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// The compilation driver initializes the class and registers all DEX files
51ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// which are being compiled. Classes defined in DEX files outside of this set
52ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// (or synthesized classes without associated DEX files) are considered being
53ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil// in the classpath.
54340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray// During code-flow verification, the MethodVerifier informs VerifierDeps
55340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray// about the outcome of every resolution and assignability test, and
56340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray// the VerifierDeps object records them if their outcome may change with
57340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray// changes in the classpath.
58ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilclass VerifierDeps {
59ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil public:
60340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  explicit VerifierDeps(const std::vector<const DexFile*>& dex_files);
61ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
62340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps(const std::vector<const DexFile*>& dex_files, ArrayRef<const uint8_t> data);
63340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray
64340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // Merge `other` into this `VerifierDeps`'. `other` and `this` must be for the
65340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // same set of dex files.
66340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  void MergeWith(const VerifierDeps& other, const std::vector<const DexFile*>& dex_files);
67e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray
680802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  // Record the verification status of the class at `type_idx`.
690802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  static void MaybeRecordVerificationStatus(const DexFile& dex_file,
70a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                            dex::TypeIndex type_idx,
716d7abbd2324f544c6b6da42bb6b9b531df0ce3cdAndreas Gampe                                            FailureKind failure_kind)
720802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray      REQUIRES(!Locks::verifier_deps_lock_);
730802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
74ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Record the outcome `klass` of resolving type `type_idx` from `dex_file`.
75ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // If `klass` is null, the class is assumed unresolved.
76ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static void MaybeRecordClassResolution(const DexFile& dex_file,
77a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                         dex::TypeIndex type_idx,
78ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                         mirror::Class* klass)
79ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
80ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
81ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
82ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Record the outcome `field` of resolving field `field_idx` from `dex_file`.
83ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // If `field` is null, the field is assumed unresolved.
84ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static void MaybeRecordFieldResolution(const DexFile& dex_file,
85ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                         uint32_t field_idx,
86ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                         ArtField* field)
87ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
88ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
89ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
90ba118827465d12177f3996e50133960087b1c916Vladimir Marko  // Record the outcome `method` of resolving method `method_idx` from `dex_file`.
91ba118827465d12177f3996e50133960087b1c916Vladimir Marko  // If `method` is null, the method is assumed unresolved.
92ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static void MaybeRecordMethodResolution(const DexFile& dex_file,
93ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                          uint32_t method_idx,
94ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                          ArtMethod* method)
95ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
96ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
97ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
98ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Record the outcome `is_assignable` of type assignability test from `source`
99ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // to `destination` as defined by RegType::AssignableFrom. `dex_file` is the
100ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // owner of the method for which MethodVerifier performed the assignability test.
101ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static void MaybeRecordAssignability(const DexFile& dex_file,
102ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       mirror::Class* destination,
103ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       mirror::Class* source,
104ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       bool is_strict,
105ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       bool is_assignable)
106ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
107ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
108ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1096f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  // Serialize the recorded dependencies and store the data into `buffer`.
110d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  // `dex_files` provides the order of the dex files in which the dependencies
111d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  // should be emitted.
112340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  void Encode(const std::vector<const DexFile*>& dex_files, std::vector<uint8_t>* buffer) const;
1136f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
114340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  void Dump(VariableIndentationOutputStream* vios) const;
115d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
1166bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray  // Verify the encoded dependencies of this `VerifierDeps` are still valid.
1176bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray  bool ValidateDependencies(Handle<mirror::ClassLoader> class_loader, Thread* self) const
118340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
1198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
120bf755fefbfcfbb2677a519c12efe7890f3879854Mathieu Chartier  const std::set<dex::TypeIndex>& GetUnverifiedClasses(const DexFile& dex_file) const {
1216bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray    return GetDexFileDeps(dex_file)->unverified_classes_;
1226bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray  }
1236bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray
12472041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier  bool OutputOnly() const {
12572041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier    return output_only_;
12672041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier  }
12772041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier
128ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil private:
129ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1);
130ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
131a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  using ClassResolutionBase = std::tuple<dex::TypeIndex, uint16_t>;
132ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  struct ClassResolution : public ClassResolutionBase {
1336f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    ClassResolution() = default;
1346f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    ClassResolution(const ClassResolution&) = default;
135a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    ClassResolution(dex::TypeIndex type_idx, uint16_t access_flags)
136ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil        : ClassResolutionBase(type_idx, access_flags) {}
137ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
138ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
139a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    dex::TypeIndex GetDexTypeIndex() const { return std::get<0>(*this); }
140ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    uint16_t GetAccessFlags() const { return std::get<1>(*this); }
141ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  };
142ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  using FieldResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
144ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  struct FieldResolution : public FieldResolutionBase {
1456f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    FieldResolution() = default;
1466f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    FieldResolution(const FieldResolution&) = default;
1478a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    FieldResolution(uint32_t field_idx, uint16_t access_flags, dex::StringIndex declaring_class_idx)
148ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil        : FieldResolutionBase(field_idx, access_flags, declaring_class_idx) {}
149ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
150ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
151ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    uint32_t GetDexFieldIndex() const { return std::get<0>(*this); }
152ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    uint16_t GetAccessFlags() const { return std::get<1>(*this); }
1538a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
154ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  };
155ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1568a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  using MethodResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
157ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  struct MethodResolution : public MethodResolutionBase {
1586f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    MethodResolution() = default;
1596f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    MethodResolution(const MethodResolution&) = default;
1608a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    MethodResolution(uint32_t method_idx,
1618a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                     uint16_t access_flags,
1628a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                     dex::StringIndex declaring_class_idx)
163ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil        : MethodResolutionBase(method_idx, access_flags, declaring_class_idx) {}
164ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
165ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
166ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    uint32_t GetDexMethodIndex() const { return std::get<0>(*this); }
167ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    uint16_t GetAccessFlags() const { return std::get<1>(*this); }
1688a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
169ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  };
170ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1718a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  using TypeAssignabilityBase = std::tuple<dex::StringIndex, dex::StringIndex>;
1720802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  struct TypeAssignability : public TypeAssignabilityBase {
1736f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    TypeAssignability() = default;
1746f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    TypeAssignability(const TypeAssignability&) = default;
1758a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    TypeAssignability(dex::StringIndex destination_idx, dex::StringIndex source_idx)
176ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil        : TypeAssignabilityBase(destination_idx, source_idx) {}
177ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1788a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    dex::StringIndex GetDestination() const { return std::get<0>(*this); }
1798a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    dex::StringIndex GetSource() const { return std::get<1>(*this); }
180ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  };
181ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
182ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Data structure representing dependencies collected during verification of
183ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // methods inside one DexFile.
184ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  struct DexFileDeps {
185ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Vector of strings which are not present in the corresponding DEX file.
186ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // These are referred to with ids starting with `NumStringIds()` of that DexFile.
187ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::vector<std::string> strings_;
188ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
189ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Set of class pairs recording the outcome of assignability test from one
190ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // of the two types to the other.
191ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::set<TypeAssignability> assignable_types_;
192ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::set<TypeAssignability> unassignable_types_;
193ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
194ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Sets of recorded class/field/method resolutions.
195ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::set<ClassResolution> classes_;
196ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::set<FieldResolution> fields_;
197ba118827465d12177f3996e50133960087b1c916Vladimir Marko    std::set<MethodResolution> methods_;
1986f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
1990802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray    // List of classes that were not fully verified in that dex file.
200bf755fefbfcfbb2677a519c12efe7890f3879854Mathieu Chartier    std::set<dex::TypeIndex> unverified_classes_;
2010802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
2026f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    bool Equals(const DexFileDeps& rhs) const;
203ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  };
204ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
20572041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier  VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only);
20672041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier
207ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Finds the DexFileDep instance associated with `dex_file`, or nullptr if
208ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // `dex_file` is not reported as being compiled.
209340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  DexFileDeps* GetDexFileDeps(const DexFile& dex_file);
210ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
211340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  const DexFileDeps* GetDexFileDeps(const DexFile& dex_file) const;
212d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
213ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Returns true if `klass` is null or not defined in any of dex files which
214ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // were reported as being compiled.
215d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  bool IsInClassPath(ObjPtr<mirror::Class> klass) const
216ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_);
217ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
2180e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // Finds the class in the classpath that makes `source` inherit` from `destination`.
2190e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // Returns null if a class defined in the compiled DEX files, and assignable to
2200e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // `source`, direclty inherits from `destination`.
2210e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  mirror::Class* FindOneClassPathBoundaryForInterface(mirror::Class* destination,
2220e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray                                                      mirror::Class* source) const
2230e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
2240e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray
225ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Returns the index of `str`. If it is defined in `dex_file_`, this is the dex
226ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // string ID. If not, an ID is assigned to the string and cached in `strings_`
227ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // of the corresponding DexFileDeps structure (either provided or inferred from
228ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // `dex_file`).
2298a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex GetIdFromString(const DexFile& dex_file, const std::string& str)
230340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES(!Locks::verifier_deps_lock_);
231ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
232ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Returns the string represented by `id`.
2338a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  std::string GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) const;
234ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
235ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Returns the bytecode access flags of `element` (bottom 16 bits), or
236ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // `kUnresolvedMarker` if `element` is null.
237ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  template <typename T>
238d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  static uint16_t GetAccessFlags(T* element)
239ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_);
240ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
241ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Returns a string ID of the descriptor of the declaring class of `element`,
242ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // or `kUnresolvedMarker` if `element` is null.
2438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex GetMethodDeclaringClassStringId(const DexFile& dex_file,
2448a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                   uint32_t dex_method_idx,
2458a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                   ArtMethod* method)
246340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
2478a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex GetFieldDeclaringClassStringId(const DexFile& dex_file,
2488a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                  uint32_t dex_field_idx,
2498a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                  ArtField* field)
250340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
25132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier
25232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  // Returns a string ID of the descriptor of the class.
2538a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
254ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
255340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES(!Locks::verifier_deps_lock_);
256ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
257ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  void AddClassResolution(const DexFile& dex_file,
258a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                          dex::TypeIndex type_idx,
259ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                          mirror::Class* klass)
260ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
261ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
262ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
263ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  void AddFieldResolution(const DexFile& dex_file,
264ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                          uint32_t field_idx,
265ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                          ArtField* field)
266ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
267ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
268ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
269ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  void AddMethodResolution(const DexFile& dex_file,
270ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                           uint32_t method_idx,
271ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                           ArtMethod* method)
272ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES_SHARED(Locks::mutator_lock_)
273ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      REQUIRES(!Locks::verifier_deps_lock_);
274ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
275ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  void AddAssignability(const DexFile& dex_file,
276ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                        mirror::Class* destination,
277ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                        mirror::Class* source,
278ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                        bool is_strict,
279ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                        bool is_assignable)
280340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
281ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
282340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  bool Equals(const VerifierDeps& rhs) const;
2836f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
2848904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // Verify `dex_file` according to the `deps`, that is going over each
2858904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // `DexFileDeps` field, and checking that the recorded information still
2868904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // holds.
2878904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
2888904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const DexFile& dex_file,
2898904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const DexFileDeps& deps,
2908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     Thread* self) const
291340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
2928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
2938904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
2948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                           const DexFile& dex_file,
2958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                           const std::set<TypeAssignability>& assignables,
2968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                           bool expected_assignability,
2978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                           Thread* self) const
298340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
2998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
3008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // Verify that the set of resolved classes at the point of creation
3018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // of this `VerifierDeps` is still the same.
3028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool VerifyClasses(Handle<mirror::ClassLoader> class_loader,
3038904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const DexFile& dex_file,
3048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const std::set<ClassResolution>& classes,
3058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     Thread* self) const
306340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
3078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
3088904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // Verify that the set of resolved fields at the point of creation
3098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // of this `VerifierDeps` is still the same, and each field resolves to the
3108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // same field holder and access flags.
3118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool VerifyFields(Handle<mirror::ClassLoader> class_loader,
3128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                    const DexFile& dex_file,
3138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                    const std::set<FieldResolution>& classes,
3148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                    Thread* self) const
3158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_)
316340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES(!Locks::verifier_deps_lock_);
3178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
3188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // Verify that the set of resolved methods at the point of creation
3198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // of this `VerifierDeps` is still the same, and each method resolves to the
3208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // same method holder, access flags, and invocation kind.
3218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool VerifyMethods(Handle<mirror::ClassLoader> class_loader,
3228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const DexFile& dex_file,
3238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     const std::set<MethodResolution>& methods,
3248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                     Thread* self) const
325340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      REQUIRES_SHARED(Locks::mutator_lock_);
3268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
327ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Map from DexFiles into dependencies collected from verification of their methods.
328340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  std::map<const DexFile*, std::unique_ptr<DexFileDeps>> dex_deps_;
329ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
33072041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier  // Output only signifies if we are using the verifier deps to verify or just to generate them.
33172041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier  const bool output_only_;
33272041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier
333ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  friend class VerifierDepsTest;
334ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  ART_FRIEND_TEST(VerifierDepsTest, StringToId);
3356f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  ART_FRIEND_TEST(VerifierDepsTest, EncodeDecode);
336d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  ART_FRIEND_TEST(VerifierDepsTest, EncodeDecodeMulti);
3378904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  ART_FRIEND_TEST(VerifierDepsTest, VerifyDeps);
3386bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray  ART_FRIEND_TEST(VerifierDepsTest, CompilerDriver);
339ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil};
340ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
341ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}  // namespace verifier
342ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}  // namespace art
343ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
344ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#endif  // ART_RUNTIME_VERIFIER_VERIFIER_DEPS_H_
345