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#include "verifier_deps.h"
18ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
1932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier#include <cstring>
2032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier
21a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field-inl.h"
22c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "art_method-inl.h"
23340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray#include "base/stl_util.h"
24ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "compiler_callbacks.h"
25c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "dex_file-inl.h"
2676c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe#include "indenter.h"
276f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil#include "leb128.h"
28ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "mirror/class-inl.h"
2976c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe#include "mirror/class_loader.h"
303398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier#include "obj_ptr-inl.h"
31ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "runtime.h"
32ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
33ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace art {
34ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace verifier {
35ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
36ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David BrazdilVerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files) {
37ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  for (const DexFile* dex_file : dex_files) {
38ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    DCHECK(GetDexFileDeps(*dex_file) == nullptr);
39ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    std::unique_ptr<DexFileDeps> deps(new DexFileDeps());
40ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps_.emplace(dex_file, std::move(deps));
41ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
42ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
43ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
44340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffrayvoid VerifierDeps::MergeWith(const VerifierDeps& other,
45340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray                             const std::vector<const DexFile*>& dex_files) {
46340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  DCHECK(dex_deps_.size() == other.dex_deps_.size());
47340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  for (const DexFile* dex_file : dex_files) {
48340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    DexFileDeps* my_deps = GetDexFileDeps(*dex_file);
49340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    const DexFileDeps& other_deps = *other.GetDexFileDeps(*dex_file);
50340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    // We currently collect extra strings only on the main `VerifierDeps`,
51340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    // which should be the one passed as `this` in this method.
52340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    DCHECK(other_deps.strings_.empty());
53340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->assignable_types_, other_deps.assignable_types_);
54340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->unassignable_types_, other_deps.unassignable_types_);
55340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->classes_, other_deps.classes_);
56340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->fields_, other_deps.fields_);
57340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->direct_methods_, other_deps.direct_methods_);
58340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->virtual_methods_, other_deps.virtual_methods_);
59340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    MergeSets(my_deps->interface_methods_, other_deps.interface_methods_);
60340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    for (dex::TypeIndex entry : other_deps.unverified_classes_) {
61340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      my_deps->unverified_classes_.push_back(entry);
62340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    }
63340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  }
64340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray}
65340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray
66ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David BrazdilVerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) {
67ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  auto it = dex_deps_.find(&dex_file);
68ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  return (it == dex_deps_.end()) ? nullptr : it->second.get();
69ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
70ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
71d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayconst VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const {
72d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  auto it = dex_deps_.find(&dex_file);
73d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  return (it == dex_deps_.end()) ? nullptr : it->second.get();
74d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray}
75d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
766e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray// Access flags that impact vdex verification.
776e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffraystatic constexpr uint32_t kAccVdexAccessFlags =
786e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray    kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface;
796e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray
80ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdiltemplate <typename T>
81ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdiluint16_t VerifierDeps::GetAccessFlags(T* element) {
82ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
83ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (element == nullptr) {
84ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return VerifierDeps::kUnresolvedMarker;
85ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  } else {
866e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray    uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags;
87ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
88ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return access_flags;
89ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
90ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
91ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
928a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
938a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                          ObjPtr<mirror::Class> klass) {
9432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  DCHECK(klass != nullptr);
9532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
96fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier  // Array and proxy classes do not have a dex cache.
9732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
9832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    DCHECK(dex_cache != nullptr) << klass->PrettyClass();
9932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    if (dex_cache->GetDexFile() == &dex_file) {
10032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      // FindStringId is slow, try to go through the class def if we have one.
10132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      const DexFile::ClassDef* class_def = klass->GetClassDef();
10232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      DCHECK(class_def != nullptr) << klass->PrettyClass();
10332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
104fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier      if (kIsDebugBuild) {
105fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier        std::string temp;
106fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier        CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
107fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier      }
10832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      return type_id.descriptor_idx_;
10932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    }
11032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  }
11132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  std::string temp;
11232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
11332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier}
11432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier
11532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
1168a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampestatic dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
1178a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                      dex::TypeIndex type_idx,
1188a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                      ObjPtr<mirror::Class> klass)
11932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    REQUIRES_SHARED(Locks::mutator_lock_) {
12032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  if (!klass->IsArrayClass()) {
12132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
12232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    const DexFile& klass_dex = klass->GetDexFile();
12332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
12432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    if (strcmp(dex_file.GetTypeDescriptor(type_id),
12532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier               klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
12632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      return type_id.descriptor_idx_;
12732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    }
12832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  }
1298a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  return dex::StringIndex::Invalid();
13032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier}
13132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier
1328a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
1338a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                               uint32_t dex_method_index,
1348a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                               ArtMethod* method) {
135ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
13632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  if (method == nullptr) {
1378a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
13832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  }
1398a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  const dex::StringIndex string_id = TryGetClassDescriptorStringId(
14032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      dex_file,
14132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      dex_file.GetMethodId(dex_method_index).class_idx_,
14232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      method->GetDeclaringClass());
1438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  if (string_id.IsValid()) {
14432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    // Got lucky using the original dex file, return based on the input dex file.
14532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
146ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return string_id;
147ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
14832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
14932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier}
15032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier
1518a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
1528a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                              uint32_t dex_field_idx,
1538a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe                                                              ArtField* field) {
15432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
15532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  if (field == nullptr) {
1568a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
15732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  }
1588a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  const dex::StringIndex string_id = TryGetClassDescriptorStringId(
15932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      dex_file,
16032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      dex_file.GetFieldId(dex_field_idx).class_idx_,
16132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier      field->GetDeclaringClass());
1628a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  if (string_id.IsValid()) {
16332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    // Got lucky using the original dex file, return based on the input dex file.
16432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
16532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier    return string_id;
16632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  }
16732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
168ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
169ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
170340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic inline VerifierDeps* GetMainVerifierDeps() {
171340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // The main VerifierDeps is the one set in the compiler callbacks, which at the
172340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // end of verification will have all the per-thread VerifierDeps merged into it.
173340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
174340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (callbacks == nullptr) {
175340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    return nullptr;
176340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  }
177340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  return callbacks->GetVerifierDeps();
178340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray}
179340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray
180340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic inline VerifierDeps* GetThreadLocalVerifierDeps() {
181340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
182340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // of full verification, these VerifierDeps will be merged into the main one.
183340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (!Runtime::Current()->IsAotCompiler()) {
184340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    return nullptr;
185340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  }
186340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  return Thread::Current()->GetVerifierDeps();
187340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray}
188340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray
189340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic bool FindExistingStringId(const std::vector<std::string>& strings,
190340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray                                 const std::string& str,
191340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray                                 uint32_t* found_id) {
192340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  uint32_t num_extra_ids = strings.size();
193340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  for (size_t i = 0; i < num_extra_ids; ++i) {
194340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    if (strings[i] == str) {
195340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      *found_id = i;
196340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray      return true;
197340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    }
198340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  }
199340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  return false;
200340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray}
201340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray
2028a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
203ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
204ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (string_id != nullptr) {
205ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // String is in the DEX file. Return its ID.
206ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return dex_file.GetIndexForStringId(*string_id);
207ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
208ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
209ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // String is not in the DEX file. Assign a new ID to it which is higher than
210ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // the number of strings in the DEX file.
211ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
212340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // We use the main `VerifierDeps` for adding new strings to simplify
213340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  // synchronization/merging of these entries between threads.
214340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* singleton = GetMainVerifierDeps();
215340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
216ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DCHECK(deps != nullptr);
217ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
218ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  uint32_t num_ids_in_dex = dex_file.NumStringIds();
219340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  uint32_t found_id;
220ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
221340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  {
222340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
223340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    if (FindExistingStringId(deps->strings_, str, &found_id)) {
2248a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe      return dex::StringIndex(num_ids_in_dex + found_id);
225ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    }
226ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
227340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  {
228340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
229340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    if (FindExistingStringId(deps->strings_, str, &found_id)) {
2308a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe      return dex::StringIndex(num_ids_in_dex + found_id);
231340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    }
232340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    deps->strings_.push_back(str);
2338a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
2348a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    CHECK_GE(new_id.index_, num_ids_in_dex);  // check for overflows
235340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
236340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    return new_id;
237340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  }
238ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
239ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
2408a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampestd::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
2418a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    const {
242ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  uint32_t num_ids_in_dex = dex_file.NumStringIds();
2438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  if (string_id.index_ < num_ids_in_dex) {
244ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return std::string(dex_file.StringDataByIdx(string_id));
245ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  } else {
246d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    const DexFileDeps* deps = GetDexFileDeps(dex_file);
247ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    DCHECK(deps != nullptr);
2488a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    string_id.index_ -= num_ids_in_dex;
2498a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    CHECK_LT(string_id.index_, deps->strings_.size());
2508a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe    return deps->strings_[string_id.index_];
251ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
252ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
253ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
254d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffraybool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
255ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DCHECK(klass != nullptr);
256ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
2570f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  // For array types, we return whether the non-array component type
2580f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  // is in the classpath.
2590f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  while (klass->IsArrayClass()) {
2600f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray    klass = klass->GetComponentType();
2610f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  }
2620f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray
2630f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  if (klass->IsPrimitive()) {
2640f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray    return true;
265ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
266ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
2670f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
2680f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray  DCHECK(dex_cache != nullptr);
269ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  const DexFile* dex_file = dex_cache->GetDexFile();
270ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DCHECK(dex_file != nullptr);
271ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
272ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
273ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // file was not registered as being compiled and we assume `klass` is in the
274ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // classpath.
275ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  return (GetDexFileDeps(*dex_file) == nullptr);
276ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
277ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
278ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddClassResolution(const DexFile& dex_file,
279a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                      dex::TypeIndex type_idx,
280ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                      mirror::Class* klass) {
281ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
282ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (dex_deps == nullptr) {
283ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This invocation is from verification of a dex file which is not being compiled.
284ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
285ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
286ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
287ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (klass != nullptr && !IsInClassPath(klass)) {
288ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Class resolved into one of the DEX files which are being compiled.
289ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This is not a classpath dependency.
290ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
291ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
292ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
293ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
294ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
295ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
296ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddFieldResolution(const DexFile& dex_file,
297ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                      uint32_t field_idx,
298ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                      ArtField* field) {
299ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
300ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (dex_deps == nullptr) {
301ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This invocation is from verification of a dex file which is not being compiled.
302ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
303ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
304ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
305ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
306ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Field resolved into one of the DEX files which are being compiled.
307ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This is not a classpath dependency.
308ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
309ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
310ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
31132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier  dex_deps->fields_.emplace(FieldResolution(field_idx,
31232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier                                            GetAccessFlags(field),
31332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier                                            GetFieldDeclaringClassStringId(dex_file,
31432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier                                                                           field_idx,
31532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier                                                                           field)));
316ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
317ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
318ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddMethodResolution(const DexFile& dex_file,
319ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       uint32_t method_idx,
320ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       MethodResolutionKind resolution_kind,
321ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                       ArtMethod* method) {
322ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
323ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (dex_deps == nullptr) {
324ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This invocation is from verification of a dex file which is not being compiled.
325ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
326ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
327ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
328ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
329ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Method resolved into one of the DEX files which are being compiled.
330ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This is not a classpath dependency.
331ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
332ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
333ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
334ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  MethodResolution method_tuple(method_idx,
335ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                GetAccessFlags(method),
33632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier                                GetMethodDeclaringClassStringId(dex_file, method_idx, method));
337ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (resolution_kind == kDirectMethodResolution) {
338ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps->direct_methods_.emplace(method_tuple);
339ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  } else if (resolution_kind == kVirtualMethodResolution) {
340ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps->virtual_methods_.emplace(method_tuple);
341ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  } else {
342ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
343ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps->interface_methods_.emplace(method_tuple);
344ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
345ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
346ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
3470e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffraymirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
3480e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray                                                                  mirror::Class* source) const {
3490e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  DCHECK(destination->IsInterface());
3500e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  DCHECK(IsInClassPath(destination));
3510e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  Thread* thread = Thread::Current();
3520e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  mirror::Class* current = source;
3530e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // Record the classes that are at the boundary between the compiled DEX files and
3540e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // the classpath. We will check those classes later to find one class that inherits
3550e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // `destination`.
3560e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  std::vector<ObjPtr<mirror::Class>> boundaries;
3570e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // If the destination is a direct interface of a class defined in the DEX files being
3580e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // compiled, no need to record it.
3590e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  while (!IsInClassPath(current)) {
3600e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
3610e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
3620e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      if (direct == destination) {
3630e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        return nullptr;
3640e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      } else if (IsInClassPath(direct)) {
3650e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        boundaries.push_back(direct);
3660e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      }
3670e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    }
3680e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    current = current->GetSuperClass();
3690e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  }
3700e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  DCHECK(current != nullptr);
3710e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  boundaries.push_back(current);
3720e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray
3730e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // Check if we have an interface defined in the DEX files being compiled, direclty
3740e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // inheriting `destination`.
3750e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  int32_t iftable_count = source->GetIfTableCount();
3760e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
3770e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  for (int32_t i = 0; i < iftable_count; ++i) {
3780e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    mirror::Class* itf = iftable->GetInterface(i);
3790e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    if (!IsInClassPath(itf)) {
3800e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
3810e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
3820e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        if (direct == destination) {
3830e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray          return nullptr;
3840e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        } else if (IsInClassPath(direct)) {
3850e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray          boundaries.push_back(direct);
3860e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        }
3870e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      }
3880e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    }
3890e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  }
3900e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray
3910e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  // Find a boundary making `source` inherit from `destination`. We must find one.
3920e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  for (const ObjPtr<mirror::Class>& boundary : boundaries) {
3930e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    if (destination->IsAssignableFrom(boundary)) {
3940e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      return boundary.Ptr();
3950e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    }
3960e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  }
3970e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  LOG(FATAL) << "Should have found a classpath boundary";
3980e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  UNREACHABLE();
3990e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray}
4000e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray
401ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddAssignability(const DexFile& dex_file,
402ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                    mirror::Class* destination,
403ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                    mirror::Class* source,
404ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                    bool is_strict,
405ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                    bool is_assignable) {
406ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Test that the method is only called on reference types.
407ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Note that concurrent verification of `destination` and `source` may have
408ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // set their status to erroneous. However, the tests performed below rely
409ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // merely on no issues with linking (valid access flags, superclass and
410ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // implemented interfaces). If the class at any point reached the IsResolved
411ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
412d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray  DCHECK(destination != nullptr);
413d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray  DCHECK(source != nullptr);
414d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray
415d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray  if (destination->IsPrimitive() || source->IsPrimitive()) {
416d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray    // Primitive types are trivially non-assignable to anything else.
417d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray    // We do not need to record trivial assignability, as it will
418d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray    // not change across releases.
419d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray    return;
420d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray  }
421ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
422119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray  if (source->IsObjectClass() && !is_assignable) {
423119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray    // j.l.Object is trivially non-assignable to other types, don't
424119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray    // record it.
425119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray    return;
426119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray  }
427119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray
428ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (destination == source ||
429ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      destination->IsObjectClass() ||
430ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      (!is_strict && destination->IsInterface())) {
431ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Cases when `destination` is trivially assignable from `source`.
432ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    DCHECK(is_assignable);
433ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
434ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
435ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
436ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (destination->IsArrayClass() && source->IsArrayClass()) {
437ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Both types are arrays. Break down to component types and add recursively.
438ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This helps filter out destinations from compiled DEX files (see below)
439ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // and deduplicate entries with the same canonical component type.
440ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    mirror::Class* destination_component = destination->GetComponentType();
441ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    mirror::Class* source_component = source->GetComponentType();
442ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
443ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Only perform the optimization if both types are resolved which guarantees
444ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // that they linked successfully, as required at the top of this method.
445ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    if (destination_component->IsResolved() && source_component->IsResolved()) {
446ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      AddAssignability(dex_file,
447ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                       destination_component,
448ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                       source_component,
449ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                       /* is_strict */ true,
450ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                       is_assignable);
451ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil      return;
452ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    }
453bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray  } else {
454bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray    // We only do this check for non-array types, as arrays might have erroneous
455bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray    // component types which makes the IsAssignableFrom check unreliable.
456bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray    DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
457ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
458ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
459ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
460ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (dex_deps == nullptr) {
461ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // This invocation is from verification of a DEX file which is not being compiled.
462ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
463ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
464ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
465ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (!IsInClassPath(destination) && !IsInClassPath(source)) {
466ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // Both `destination` and `source` are defined in the compiled DEX files.
467ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    // No need to record a dependency.
468ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    return;
469ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
470ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
4710e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray  if (!IsInClassPath(source)) {
472fc38e919bad23670e38a484d4728f300406415c3Nicolas Geoffray    if (!destination->IsInterface() && !source->IsInterface()) {
4730e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      // Find the super class at the classpath boundary. Only that class
4740e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      // can change the assignability.
4750e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      do {
4760e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        source = source->GetSuperClass();
4770e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      } while (!IsInClassPath(source));
478119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray
4790e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      // If that class is the actual destination, no need to record it.
4800e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      if (source == destination) {
4810e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        return;
4820e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      }
4830e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray    } else if (is_assignable) {
4840e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      source = FindOneClassPathBoundaryForInterface(destination, source);
4850e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      if (source == nullptr) {
4860e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        // There was no classpath boundary, no need to record.
4870e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray        return;
4880e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      }
4890e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray      DCHECK(IsInClassPath(source));
490119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray    }
491119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray  }
492119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray
493119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray
494ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  // Get string IDs for both descriptors and store in the appropriate set.
4958a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
4968a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
497ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
498ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  if (is_assignable) {
499ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
500ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  } else {
501ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil    dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
502ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
503ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
504ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
5050802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffrayvoid VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
506a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                                 dex::TypeIndex type_idx,
50776c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe                                                 FailureKind failure_kind) {
50876c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe  if (failure_kind == FailureKind::kNoFailure) {
5090802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray    // We only record classes that did not fully verify at compile time.
5100802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray    return;
5110802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  }
5120802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
513340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
514340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (thread_deps != nullptr) {
515340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
5160802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray    dex_deps->unverified_classes_.push_back(type_idx);
5170802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  }
5180802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray}
5190802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
520ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
521a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                              dex::TypeIndex type_idx,
522ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                              mirror::Class* klass) {
523340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
524340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (thread_deps != nullptr) {
525340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    thread_deps->AddClassResolution(dex_file, type_idx, klass);
526ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
527ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
528ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
529ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
530ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                              uint32_t field_idx,
531ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                              ArtField* field) {
532340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
533340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (thread_deps != nullptr) {
534340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    thread_deps->AddFieldResolution(dex_file, field_idx, field);
535ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
536ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
537ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
538ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
539ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                               uint32_t method_idx,
540ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                               MethodResolutionKind resolution_kind,
541ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                               ArtMethod* method) {
542340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
543340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (thread_deps != nullptr) {
544340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
545ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
546ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
547ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
548ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
549ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                            mirror::Class* destination,
550ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                            mirror::Class* source,
551ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                            bool is_strict,
552ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil                                            bool is_assignable) {
553340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
554340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray  if (thread_deps != nullptr) {
555340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray    thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
556ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil  }
557ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}
558ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil
559a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampenamespace {
560a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
5616f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
5626f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  CHECK_LT(*in, end);
5636f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  return DecodeUnsignedLeb128(in);
5646f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
5656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
566a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T> inline uint32_t Encode(T in);
567a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
568a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<uint16_t>(uint16_t in) {
569a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return in;
570a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
571a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<uint32_t>(uint32_t in) {
572a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return in;
573a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
574a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
575a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return in.index_;
576a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
5778a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampetemplate<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
5788a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  return in.index_;
5798a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe}
580a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
581a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T> inline T Decode(uint32_t in);
582a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
583a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint16_t Decode<uint16_t>(uint32_t in) {
584a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return dchecked_integral_cast<uint16_t>(in);
585a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
586a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Decode<uint32_t>(uint32_t in) {
587a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return in;
588a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
589a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
590a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  return dex::TypeIndex(in);
591a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}
5928a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampetemplate<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
5938a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  return dex::StringIndex(in);
5948a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe}
595a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
5966f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2>
5976f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
598a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
599a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
6006f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6016f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
6026f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2>
6036f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
604a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
605a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
6066f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  *t = std::make_tuple(v1, v2);
6076f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6086f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
6096f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2, typename T3>
6106f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
611a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
612a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
613a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
6146f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6156f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
6166f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2, typename T3>
6176f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
618a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
619a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
6208a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe  T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
6216f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  *t = std::make_tuple(v1, v2, v3);
6226f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6236f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
6246f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T>
6256f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
6266f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  EncodeUnsignedLeb128(out, set.size());
6276f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  for (const T& entry : set) {
6286f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    EncodeTuple(out, entry);
6296f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
6306f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6316f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
632a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate <typename T>
6330802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffraystatic inline void EncodeUint16Vector(std::vector<uint8_t>* out,
634a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                      const std::vector<T>& vector) {
6350802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  EncodeUnsignedLeb128(out, vector.size());
636a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe  for (const T& entry : vector) {
637a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    EncodeUnsignedLeb128(out, Encode(entry));
6380802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  }
6390802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray}
6400802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
6416f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T>
6426f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
6436f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  DCHECK(set->empty());
6446f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
6456f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  for (size_t i = 0; i < num_entries; ++i) {
6466f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    T tuple;
6476f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    DecodeTuple(in, end, &tuple);
6486f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    set->emplace(tuple);
6496f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
6506f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6516f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
652a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T>
6530802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffraystatic inline void DecodeUint16Vector(const uint8_t** in,
6540802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray                                      const uint8_t* end,
655a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe                                      std::vector<T>* vector) {
6560802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  DCHECK(vector->empty());
6570802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
6580802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  vector->reserve(num_entries);
6590802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  for (size_t i = 0; i < num_entries; ++i) {
660a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    vector->push_back(
661a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe        Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
6620802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray  }
6630802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray}
6640802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray
6656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeStringVector(std::vector<uint8_t>* out,
6666f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil                                      const std::vector<std::string>& strings) {
6676f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  EncodeUnsignedLeb128(out, strings.size());
6686f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  for (const std::string& str : strings) {
6696f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
6706f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    size_t length = str.length() + 1;
6716f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    out->insert(out->end(), data, data + length);
6726f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    DCHECK_EQ(0u, out->back());
6736f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
6746f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6756f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
6766f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeStringVector(const uint8_t** in,
6776f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil                                      const uint8_t* end,
6786f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil                                      std::vector<std::string>* strings) {
6796f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  DCHECK(strings->empty());
6806f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
6816f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  strings->reserve(num_strings);
6826f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  for (size_t i = 0; i < num_strings; ++i) {
6836f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    CHECK_LT(*in, end);
6846f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    const char* string_start = reinterpret_cast<const char*>(*in);
6856f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    strings->emplace_back(std::string(string_start));
6866f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    *in += strings->back().length() + 1;
6876f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
6886f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
6896f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
690a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe}  // namespace
691a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe
692d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayvoid VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
693d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray                          std::vector<uint8_t>* buffer) const {
694d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  for (const DexFile* dex_file : dex_files) {
695d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
696d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeStringVector(buffer, deps.strings_);
697d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.assignable_types_);
698d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.unassignable_types_);
699d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.classes_);
700d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.fields_);
701d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.direct_methods_);
702d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.virtual_methods_);
703d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeSet(buffer, deps.interface_methods_);
704d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    EncodeUint16Vector(buffer, deps.unverified_classes_);
7056f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
7066f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
7076f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
708e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas GeoffrayVerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
709e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray                           ArrayRef<const uint8_t> data)
7106f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    : VerifierDeps(dex_files) {
711e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray  if (data.empty()) {
712e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray    // Return eagerly, as the first thing we expect from VerifierDeps data is
713e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray    // the number of created strings, even if there is no dependency.
714e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray    // Currently, only the boot image does not have any VerifierDeps data.
715e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray    return;
716e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray  }
7176f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  const uint8_t* data_start = data.data();
7186f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  const uint8_t* data_end = data_start + data.size();
719d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  for (const DexFile* dex_file : dex_files) {
720d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DexFileDeps* deps = GetDexFileDeps(*dex_file);
721d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeStringVector(&data_start, data_end, &deps->strings_);
722d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->assignable_types_);
723d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->unassignable_types_);
724d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->classes_);
725d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->fields_);
726d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->direct_methods_);
727d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->virtual_methods_);
728d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeSet(&data_start, data_end, &deps->interface_methods_);
729d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
7306f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
7316f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  CHECK_LE(data_start, data_end);
7326f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
7336f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7346f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilbool VerifierDeps::Equals(const VerifierDeps& rhs) const {
7356f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  if (dex_deps_.size() != rhs.dex_deps_.size()) {
7366f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    return false;
7376f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
7386f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7396f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  auto lhs_it = dex_deps_.begin();
7406f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  auto rhs_it = rhs.dex_deps_.begin();
7416f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7426f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
7436f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    const DexFile* lhs_dex_file = lhs_it->first;
7446f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    const DexFile* rhs_dex_file = rhs_it->first;
7456f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    if (lhs_dex_file != rhs_dex_file) {
7466f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil      return false;
7476f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    }
7486f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7496f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    DexFileDeps* lhs_deps = lhs_it->second.get();
7506f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    DexFileDeps* rhs_deps = rhs_it->second.get();
7516f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    if (!lhs_deps->Equals(*rhs_deps)) {
7526f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil      return false;
7536f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil    }
7546f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  }
7556f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7566f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
7576f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  return true;
7586f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
7596f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
7606f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilbool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
7616f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil  return (strings_ == rhs.strings_) &&
7626f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (assignable_types_ == rhs.assignable_types_) &&
7636f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (unassignable_types_ == rhs.unassignable_types_) &&
7646f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (classes_ == rhs.classes_) &&
7656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (fields_ == rhs.fields_) &&
7666f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (direct_methods_ == rhs.direct_methods_) &&
7676f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil         (virtual_methods_ == rhs.virtual_methods_) &&
7680802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray         (interface_methods_ == rhs.interface_methods_) &&
7690802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray         (unverified_classes_ == rhs.unverified_classes_);
7706f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil}
7716f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil
772d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayvoid VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
773d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  for (const auto& dep : dex_deps_) {
774d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    const DexFile& dex_file = *dep.first;
775d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    vios->Stream()
776d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << "Dependencies of "
777d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << dex_file.GetLocation()
778d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << ":\n";
779d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
780d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    ScopedIndentation indent(vios);
781d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
782d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const std::string& str : dep.second->strings_) {
783d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream() << "Extra string: " << str << "\n";
784d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
785d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
786d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const TypeAssignability& entry : dep.second->assignable_types_) {
787d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream()
788d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << GetStringFromId(dex_file, entry.GetSource())
789d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << " must be assignable to "
790d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << GetStringFromId(dex_file, entry.GetDestination())
791d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << "\n";
792d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
793d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
794d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const TypeAssignability& entry : dep.second->unassignable_types_) {
795d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream()
796d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << GetStringFromId(dex_file, entry.GetSource())
797d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << " must not be assignable to "
798d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << GetStringFromId(dex_file, entry.GetDestination())
799d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        << "\n";
800d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
801d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
802d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const ClassResolution& entry : dep.second->classes_) {
803d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream()
804d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
805d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
806d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
807d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << "\n";
808d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
809d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
810d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const FieldResolution& entry : dep.second->fields_) {
811d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
812d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream()
813d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
814d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << dex_file.GetFieldName(field_id) << ":"
815d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << dex_file.GetFieldTypeDescriptor(field_id)
816d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << " is expected to be ";
817d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      if (!entry.IsResolved()) {
818d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        vios->Stream() << "unresolved\n";
819d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      } else {
820d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        vios->Stream()
821d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << "in class "
822d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
823d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
824d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << "\n";
825d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      }
826d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
827d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
828d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    for (const auto& entry :
829d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
830d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray              std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
831d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray              std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
832d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      for (const MethodResolution& method : entry.second) {
833d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
834d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        vios->Stream()
835d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
836d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << dex_file.GetMethodName(method_id)
837d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << dex_file.GetMethodSignature(method_id).ToString()
838d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << " is expected to be ";
839d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        if (!method.IsResolved()) {
840d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          vios->Stream() << "unresolved\n";
841d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        } else {
842d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          vios->Stream()
843d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << "in class "
844d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
845d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
846d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << ", and be of kind " << entry.first
847d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray            << "\n";
848d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray        }
849d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      }
850d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
851d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
852a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe    for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
853d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray      vios->Stream()
854d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << dex_file.StringByTypeIdx(type_index)
855d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray          << " is expected to be verified at runtime\n";
856d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray    }
857d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray  }
858d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray}
859d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray
8606bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffraybool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
8616bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray                                        Thread* self) const {
8628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  for (const auto& entry : dex_deps_) {
8638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
8648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
8658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
8668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
8678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return true;
8688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
8698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
8708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray// TODO: share that helper with other parts of the compiler that have
8718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray// the same lookup pattern.
8728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
8738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                                 Thread* self,
8748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                                 const char* name,
8758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                                 Handle<mirror::ClassLoader> class_loader)
8768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    REQUIRES_SHARED(Locks::mutator_lock_) {
8778904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  mirror::Class* result = class_linker->FindClass(self, name, class_loader);
8788904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  if (result == nullptr) {
8798904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    DCHECK(self->IsExceptionPending());
8808904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    self->ClearException();
8818904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
8828904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return result;
8838904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
8848904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
8858904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
8868904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                       const DexFile& dex_file,
8878904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                       const std::set<TypeAssignability>& assignables,
8888904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                       bool expected_assignability,
8898904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                       Thread* self) const {
8908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  StackHandleScope<2> hs(self);
8918904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
8928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
8938904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
8948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
8958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  for (const auto& entry : assignables) {
8968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
8978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    destination.Assign(
8988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
8998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
9008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    source.Assign(
9018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
9028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
903fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe    if (destination == nullptr) {
9048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
9058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
9068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
9078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
908fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe    if (source == nullptr) {
9098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
9108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
9118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
9128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
9138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    DCHECK(destination->IsResolved() && source->IsResolved());
9148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
9158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Class "
9168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << destination_desc
9178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << (expected_assignability ? " not " : " ")
9188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << "assignable from "
9198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << source_desc;
9208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
9218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
9228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
9238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return true;
9248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
9258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
9268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
9278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const DexFile& dex_file,
9288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const std::set<ClassResolution>& classes,
9298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 Thread* self) const {
9308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  StackHandleScope<1> hs(self);
9318904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
9328904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
9338904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  for (const auto& entry : classes) {
9348904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
9358904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
9368904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
9378904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (entry.IsResolved()) {
938fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe      if (cls == nullptr) {
9398904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
9408904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
9418904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
9428904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
9438904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << descriptor
9448904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << std::hex
9458904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " (expected="
9468904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << entry.GetAccessFlags()
9478904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ", actual="
9488904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetAccessFlags(cls.Get()) << ")"
9498904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << std::dec;
9508904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
9518904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      }
952fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe    } else if (cls != nullptr) {
9538904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
9548904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
9558904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
9568904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
9578904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return true;
9588904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
9598904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
9608904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
9618904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
9628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
9638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + "->"
9648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + dex_file.GetFieldName(field_id)
9658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + ":"
9668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + dex_file.GetFieldTypeDescriptor(field_id);
9678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
9688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
9698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
9708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                const DexFile& dex_file,
9718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                const std::set<FieldResolution>& fields,
9728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                Thread* self) const {
9738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // Check recorded fields are resolved the same way, have the same recorded class,
9748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  // and have the same recorded flags.
9758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
9768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  for (const auto& entry : fields) {
977865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
978865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
979865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
980865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
981865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    // Otherwise, we might end up resolving an application class, which is expensive.
982865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    std::string expected_decl_klass = entry.IsResolved()
983865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
984865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        : dex_file.StringByTypeIdx(field_id.class_idx_);
985865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    mirror::Class* cls = FindClassAndClearException(
986865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        class_linker, self, expected_decl_klass.c_str(), class_loader);
987865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    if (cls == nullptr) {
988865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
989865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray      return false;
9908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
991865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    DCHECK(cls->IsResolved());
9928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
993865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    ArtField* field = mirror::Class::FindField(self, cls, name, type);
9948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (entry.IsResolved()) {
9958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      std::string temp;
9968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      if (field == nullptr) {
9978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Could not resolve field "
9988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
9998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
10018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
10028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
10038904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " (expected=" << expected_decl_klass
10048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
10058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
10078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
10088904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
10098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << std::hex << " (expected=" << entry.GetAccessFlags()
10108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
10118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      }
10138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    } else if (field != nullptr) {
10148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
10158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
10168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
10178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
10188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
10198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return true;
10208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
10218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
10228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
10238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
10248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
10258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + "->"
10268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + dex_file.GetMethodName(method_id)
10278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      + dex_file.GetMethodSignature(method_id).ToString();
10288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
10298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
10308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
10318904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const DexFile& dex_file,
10328904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const std::set<MethodResolution>& methods,
10338904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 MethodResolutionKind kind,
10348904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 Thread* self) const {
10358904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
10368904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  PointerSize pointer_size = class_linker->GetImagePointerSize();
10378904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
10388904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  for (const auto& entry : methods) {
10398904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
10408904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
10418904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const char* name = dex_file.GetMethodName(method_id);
10428904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    const Signature signature = dex_file.GetMethodSignature(method_id);
1043865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
1044865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    // Otherwise, we might end up resolving an application class, which is expensive.
1045865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    std::string expected_decl_klass = entry.IsResolved()
1046865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
1047865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        : dex_file.StringByTypeIdx(method_id.class_idx_);
1048865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray
1049865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray    mirror::Class* cls = FindClassAndClearException(
1050865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray        class_linker, self, expected_decl_klass.c_str(), class_loader);
10518904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (cls == nullptr) {
1052865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
10538904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
10548904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
10558904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    DCHECK(cls->IsResolved());
10568904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    ArtMethod* method = nullptr;
10578904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (kind == kDirectMethodResolution) {
10588904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      method = cls->FindDirectMethod(name, signature, pointer_size);
10598904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    } else if (kind == kVirtualMethodResolution) {
10608904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      method = cls->FindVirtualMethod(name, signature, pointer_size);
10618904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    } else {
10628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      DCHECK_EQ(kind, kInterfaceMethodResolution);
10638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      method = cls->FindInterfaceMethod(name, signature, pointer_size);
10648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
10658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
10668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    if (entry.IsResolved()) {
10678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      std::string temp;
10688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      if (method == nullptr) {
10698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Could not resolve "
10708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << kind
10718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " method "
10728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
10738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
10758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
10768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << kind
10778904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " method resolution "
10788904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
10798904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " (expected="
10808904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << expected_decl_klass
10818904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ", actual="
10828904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << method->GetDeclaringClass()->GetDescriptor(&temp)
10838904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ")";
10848904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10858904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
10868904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
10878904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << kind
10888904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " method resolution "
10898904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
10908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << std::hex
10918904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << " (expected="
10928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << entry.GetAccessFlags()
10938904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << ", actual="
10948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << GetAccessFlags(method) << ")"
10958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                  << std::dec;
10968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray        return false;
10978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      }
10988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    } else if (method != nullptr) {
10998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
11008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << kind
11018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << " method "
11028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
11038904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      return false;
11048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray    }
11058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  }
11068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return true;
11078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
11088904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
11098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
11108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const DexFile& dex_file,
11118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 const DexFileDeps& deps,
11128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray                                 Thread* self) const {
11138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  bool result = VerifyAssignability(
11148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
11158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyAssignability(
11168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
11178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
11188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
11198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
11208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
11218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyMethods(
11228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
11238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyMethods(
11248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
11258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  result = result && VerifyMethods(
11268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray      class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
11278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
11288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray  return result;
11298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray}
11308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray
1131ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}  // namespace verifier
1132ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil}  // namespace art
1133