Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "verifier_deps.h"
     18 
     19 #include <cstring>
     20 #include <sstream>
     21 
     22 #include "art_field-inl.h"
     23 #include "art_method-inl.h"
     24 #include "base/indenter.h"
     25 #include "base/leb128.h"
     26 #include "base/mutex-inl.h"
     27 #include "compiler_callbacks.h"
     28 #include "dex/class_accessor-inl.h"
     29 #include "dex/dex_file-inl.h"
     30 #include "mirror/class-inl.h"
     31 #include "mirror/class_loader.h"
     32 #include "oat_file.h"
     33 #include "obj_ptr-inl.h"
     34 #include "runtime.h"
     35 
     36 namespace art {
     37 namespace verifier {
     38 
     39 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only)
     40     : output_only_(output_only) {
     41   for (const DexFile* dex_file : dex_files) {
     42     DCHECK(GetDexFileDeps(*dex_file) == nullptr);
     43     std::unique_ptr<DexFileDeps> deps(new DexFileDeps(dex_file->NumClassDefs()));
     44     dex_deps_.emplace(dex_file, std::move(deps));
     45   }
     46 }
     47 
     48 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files)
     49     : VerifierDeps(dex_files, /*output_only=*/ true) {}
     50 
     51 // Perform logical OR on two bit vectors and assign back to LHS, i.e. `to_update |= other`.
     52 // Size of the two vectors must be equal.
     53 // Size of `other` must be equal to size of `to_update`.
     54 static inline void BitVectorOr(std::vector<bool>& to_update, const std::vector<bool>& other) {
     55   DCHECK_EQ(to_update.size(), other.size());
     56   std::transform(other.begin(),
     57                  other.end(),
     58                  to_update.begin(),
     59                  to_update.begin(),
     60                  std::logical_or<bool>());
     61 }
     62 
     63 void VerifierDeps::MergeWith(std::unique_ptr<VerifierDeps> other,
     64                              const std::vector<const DexFile*>& dex_files) {
     65   DCHECK(other != nullptr);
     66   DCHECK_EQ(dex_deps_.size(), other->dex_deps_.size());
     67   for (const DexFile* dex_file : dex_files) {
     68     DexFileDeps* my_deps = GetDexFileDeps(*dex_file);
     69     DexFileDeps& other_deps = *other->GetDexFileDeps(*dex_file);
     70     // We currently collect extra strings only on the main `VerifierDeps`,
     71     // which should be the one passed as `this` in this method.
     72     DCHECK(other_deps.strings_.empty());
     73     my_deps->assignable_types_.merge(other_deps.assignable_types_);
     74     my_deps->unassignable_types_.merge(other_deps.unassignable_types_);
     75     my_deps->classes_.merge(other_deps.classes_);
     76     my_deps->fields_.merge(other_deps.fields_);
     77     my_deps->methods_.merge(other_deps.methods_);
     78     BitVectorOr(my_deps->verified_classes_, other_deps.verified_classes_);
     79     BitVectorOr(my_deps->redefined_classes_, other_deps.redefined_classes_);
     80   }
     81 }
     82 
     83 VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) {
     84   auto it = dex_deps_.find(&dex_file);
     85   return (it == dex_deps_.end()) ? nullptr : it->second.get();
     86 }
     87 
     88 const VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const {
     89   auto it = dex_deps_.find(&dex_file);
     90   return (it == dex_deps_.end()) ? nullptr : it->second.get();
     91 }
     92 
     93 // Access flags that impact vdex verification.
     94 static constexpr uint32_t kAccVdexAccessFlags =
     95     kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface;
     96 
     97 template <typename Ptr>
     98 uint16_t VerifierDeps::GetAccessFlags(Ptr element) {
     99   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
    100   if (element == nullptr) {
    101     return VerifierDeps::kUnresolvedMarker;
    102   } else {
    103     uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags;
    104     CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
    105     return access_flags;
    106   }
    107 }
    108 
    109 dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
    110                                                           ObjPtr<mirror::Class> klass) {
    111   DCHECK(klass != nullptr);
    112   ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
    113   // Array and proxy classes do not have a dex cache.
    114   if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
    115     DCHECK(dex_cache != nullptr) << klass->PrettyClass();
    116     if (dex_cache->GetDexFile() == &dex_file) {
    117       // FindStringId is slow, try to go through the class def if we have one.
    118       const dex::ClassDef* class_def = klass->GetClassDef();
    119       DCHECK(class_def != nullptr) << klass->PrettyClass();
    120       const dex::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
    121       if (kIsDebugBuild) {
    122         std::string temp;
    123         CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
    124       }
    125       return type_id.descriptor_idx_;
    126     }
    127   }
    128   std::string temp;
    129   return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
    130 }
    131 
    132 // Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
    133 static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
    134                                                       dex::TypeIndex type_idx,
    135                                                       ObjPtr<mirror::Class> klass)
    136     REQUIRES_SHARED(Locks::mutator_lock_) {
    137   if (!klass->IsArrayClass()) {
    138     const dex::TypeId& type_id = dex_file.GetTypeId(type_idx);
    139     const DexFile& klass_dex = klass->GetDexFile();
    140     const dex::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
    141     if (strcmp(dex_file.GetTypeDescriptor(type_id),
    142                klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
    143       return type_id.descriptor_idx_;
    144     }
    145   }
    146   return dex::StringIndex::Invalid();
    147 }
    148 
    149 dex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
    150                                                                uint32_t dex_method_index,
    151                                                                ArtMethod* method) {
    152   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
    153   if (method == nullptr) {
    154     return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
    155   }
    156   const dex::StringIndex string_id = TryGetClassDescriptorStringId(
    157       dex_file,
    158       dex_file.GetMethodId(dex_method_index).class_idx_,
    159       method->GetDeclaringClass());
    160   if (string_id.IsValid()) {
    161     // Got lucky using the original dex file, return based on the input dex file.
    162     DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
    163     return string_id;
    164   }
    165   return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
    166 }
    167 
    168 dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
    169                                                               uint32_t dex_field_idx,
    170                                                               ArtField* field) {
    171   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
    172   if (field == nullptr) {
    173     return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
    174   }
    175   const dex::StringIndex string_id = TryGetClassDescriptorStringId(
    176       dex_file,
    177       dex_file.GetFieldId(dex_field_idx).class_idx_,
    178       field->GetDeclaringClass());
    179   if (string_id.IsValid()) {
    180     // Got lucky using the original dex file, return based on the input dex file.
    181     DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
    182     return string_id;
    183   }
    184   return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
    185 }
    186 
    187 static inline VerifierDeps* GetMainVerifierDeps() {
    188   // The main VerifierDeps is the one set in the compiler callbacks, which at the
    189   // end of verification will have all the per-thread VerifierDeps merged into it.
    190   CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
    191   if (callbacks == nullptr) {
    192     return nullptr;
    193   }
    194   return callbacks->GetVerifierDeps();
    195 }
    196 
    197 static inline VerifierDeps* GetThreadLocalVerifierDeps() {
    198   // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
    199   // of full verification, these VerifierDeps will be merged into the main one.
    200   if (!Runtime::Current()->IsAotCompiler()) {
    201     return nullptr;
    202   }
    203   return Thread::Current()->GetVerifierDeps();
    204 }
    205 
    206 static bool FindExistingStringId(const std::vector<std::string>& strings,
    207                                  const std::string& str,
    208                                  uint32_t* found_id) {
    209   uint32_t num_extra_ids = strings.size();
    210   for (size_t i = 0; i < num_extra_ids; ++i) {
    211     if (strings[i] == str) {
    212       *found_id = i;
    213       return true;
    214     }
    215   }
    216   return false;
    217 }
    218 
    219 dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
    220   const dex::StringId* string_id = dex_file.FindStringId(str.c_str());
    221   if (string_id != nullptr) {
    222     // String is in the DEX file. Return its ID.
    223     return dex_file.GetIndexForStringId(*string_id);
    224   }
    225 
    226   // String is not in the DEX file. Assign a new ID to it which is higher than
    227   // the number of strings in the DEX file.
    228 
    229   // We use the main `VerifierDeps` for adding new strings to simplify
    230   // synchronization/merging of these entries between threads.
    231   VerifierDeps* singleton = GetMainVerifierDeps();
    232   DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
    233   DCHECK(deps != nullptr);
    234 
    235   uint32_t num_ids_in_dex = dex_file.NumStringIds();
    236   uint32_t found_id;
    237 
    238   {
    239     ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
    240     if (FindExistingStringId(deps->strings_, str, &found_id)) {
    241       return dex::StringIndex(num_ids_in_dex + found_id);
    242     }
    243   }
    244   {
    245     WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
    246     if (FindExistingStringId(deps->strings_, str, &found_id)) {
    247       return dex::StringIndex(num_ids_in_dex + found_id);
    248     }
    249     deps->strings_.push_back(str);
    250     dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
    251     CHECK_GE(new_id.index_, num_ids_in_dex);  // check for overflows
    252     DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
    253     return new_id;
    254   }
    255 }
    256 
    257 std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
    258     const {
    259   uint32_t num_ids_in_dex = dex_file.NumStringIds();
    260   if (string_id.index_ < num_ids_in_dex) {
    261     return std::string(dex_file.StringDataByIdx(string_id));
    262   } else {
    263     const DexFileDeps* deps = GetDexFileDeps(dex_file);
    264     DCHECK(deps != nullptr);
    265     string_id.index_ -= num_ids_in_dex;
    266     CHECK_LT(string_id.index_, deps->strings_.size());
    267     return deps->strings_[string_id.index_];
    268   }
    269 }
    270 
    271 bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
    272   DCHECK(klass != nullptr);
    273 
    274   // For array types, we return whether the non-array component type
    275   // is in the classpath.
    276   while (klass->IsArrayClass()) {
    277     klass = klass->GetComponentType();
    278   }
    279 
    280   if (klass->IsPrimitive()) {
    281     return true;
    282   }
    283 
    284   ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
    285   DCHECK(dex_cache != nullptr);
    286   const DexFile* dex_file = dex_cache->GetDexFile();
    287   DCHECK(dex_file != nullptr);
    288 
    289   // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
    290   // file was not registered as being compiled and we assume `klass` is in the
    291   // classpath.
    292   return (GetDexFileDeps(*dex_file) == nullptr);
    293 }
    294 
    295 void VerifierDeps::AddClassResolution(const DexFile& dex_file,
    296                                       dex::TypeIndex type_idx,
    297                                       ObjPtr<mirror::Class> klass) {
    298   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    299   if (dex_deps == nullptr) {
    300     // This invocation is from verification of a dex file which is not being compiled.
    301     return;
    302   }
    303 
    304   if (klass != nullptr && !IsInClassPath(klass)) {
    305     // Class resolved into one of the DEX files which are being compiled.
    306     // This is not a classpath dependency.
    307     return;
    308   }
    309 
    310   dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
    311 }
    312 
    313 void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
    314                                       uint32_t field_idx,
    315                                       ArtField* field) {
    316   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    317   if (dex_deps == nullptr) {
    318     // This invocation is from verification of a dex file which is not being compiled.
    319     return;
    320   }
    321 
    322   if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
    323     // Field resolved into one of the DEX files which are being compiled.
    324     // This is not a classpath dependency.
    325     return;
    326   }
    327 
    328   dex_deps->fields_.emplace(FieldResolution(field_idx,
    329                                             GetAccessFlags(field),
    330                                             GetFieldDeclaringClassStringId(dex_file,
    331                                                                            field_idx,
    332                                                                            field)));
    333 }
    334 
    335 void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
    336                                        uint32_t method_idx,
    337                                        ArtMethod* method) {
    338   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    339   if (dex_deps == nullptr) {
    340     // This invocation is from verification of a dex file which is not being compiled.
    341     return;
    342   }
    343 
    344   if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
    345     // Method resolved into one of the DEX files which are being compiled.
    346     // This is not a classpath dependency.
    347     return;
    348   }
    349 
    350   MethodResolution method_tuple(method_idx,
    351                                 GetAccessFlags(method),
    352                                 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
    353   dex_deps->methods_.insert(method_tuple);
    354 }
    355 
    356 ObjPtr<mirror::Class> VerifierDeps::FindOneClassPathBoundaryForInterface(
    357     ObjPtr<mirror::Class> destination,
    358     ObjPtr<mirror::Class> source) const {
    359   DCHECK(destination->IsInterface());
    360   DCHECK(IsInClassPath(destination));
    361   Thread* thread = Thread::Current();
    362   ObjPtr<mirror::Class> current = source;
    363   // Record the classes that are at the boundary between the compiled DEX files and
    364   // the classpath. We will check those classes later to find one class that inherits
    365   // `destination`.
    366   std::vector<ObjPtr<mirror::Class>> boundaries;
    367   // If the destination is a direct interface of a class defined in the DEX files being
    368   // compiled, no need to record it.
    369   while (!IsInClassPath(current)) {
    370     for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
    371       ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
    372       if (direct == destination) {
    373         return nullptr;
    374       } else if (IsInClassPath(direct)) {
    375         boundaries.push_back(direct);
    376       }
    377     }
    378     current = current->GetSuperClass();
    379   }
    380   DCHECK(current != nullptr);
    381   boundaries.push_back(current);
    382 
    383   // Check if we have an interface defined in the DEX files being compiled, direclty
    384   // inheriting `destination`.
    385   int32_t iftable_count = source->GetIfTableCount();
    386   ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
    387   for (int32_t i = 0; i < iftable_count; ++i) {
    388     ObjPtr<mirror::Class> itf = iftable->GetInterface(i);
    389     if (!IsInClassPath(itf)) {
    390       for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
    391         ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
    392         if (direct == destination) {
    393           return nullptr;
    394         } else if (IsInClassPath(direct)) {
    395           boundaries.push_back(direct);
    396         }
    397       }
    398     }
    399   }
    400 
    401   // Find a boundary making `source` inherit from `destination`. We must find one.
    402   for (const ObjPtr<mirror::Class>& boundary : boundaries) {
    403     if (destination->IsAssignableFrom(boundary)) {
    404       return boundary;
    405     }
    406   }
    407   LOG(FATAL) << "Should have found a classpath boundary";
    408   UNREACHABLE();
    409 }
    410 
    411 void VerifierDeps::AddAssignability(const DexFile& dex_file,
    412                                     ObjPtr<mirror::Class> destination,
    413                                     ObjPtr<mirror::Class> source,
    414                                     bool is_strict,
    415                                     bool is_assignable) {
    416   // Test that the method is only called on reference types.
    417   // Note that concurrent verification of `destination` and `source` may have
    418   // set their status to erroneous. However, the tests performed below rely
    419   // merely on no issues with linking (valid access flags, superclass and
    420   // implemented interfaces). If the class at any point reached the IsResolved
    421   // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
    422   DCHECK(destination != nullptr);
    423   DCHECK(source != nullptr);
    424 
    425   if (destination->IsPrimitive() || source->IsPrimitive()) {
    426     // Primitive types are trivially non-assignable to anything else.
    427     // We do not need to record trivial assignability, as it will
    428     // not change across releases.
    429     return;
    430   }
    431 
    432   if (source->IsObjectClass() && !is_assignable) {
    433     // j.l.Object is trivially non-assignable to other types, don't
    434     // record it.
    435     return;
    436   }
    437 
    438   if (destination == source ||
    439       destination->IsObjectClass() ||
    440       (!is_strict && destination->IsInterface())) {
    441     // Cases when `destination` is trivially assignable from `source`.
    442     DCHECK(is_assignable);
    443     return;
    444   }
    445 
    446   if (destination->IsArrayClass() && source->IsArrayClass()) {
    447     // Both types are arrays. Break down to component types and add recursively.
    448     // This helps filter out destinations from compiled DEX files (see below)
    449     // and deduplicate entries with the same canonical component type.
    450     ObjPtr<mirror::Class> destination_component = destination->GetComponentType();
    451     ObjPtr<mirror::Class> source_component = source->GetComponentType();
    452 
    453     // Only perform the optimization if both types are resolved which guarantees
    454     // that they linked successfully, as required at the top of this method.
    455     if (destination_component->IsResolved() && source_component->IsResolved()) {
    456       AddAssignability(dex_file,
    457                        destination_component,
    458                        source_component,
    459                        /* is_strict= */ true,
    460                        is_assignable);
    461       return;
    462     }
    463   } else {
    464     // We only do this check for non-array types, as arrays might have erroneous
    465     // component types which makes the IsAssignableFrom check unreliable.
    466     DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
    467   }
    468 
    469   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    470   if (dex_deps == nullptr) {
    471     // This invocation is from verification of a DEX file which is not being compiled.
    472     return;
    473   }
    474 
    475   if (!IsInClassPath(destination) && !IsInClassPath(source)) {
    476     // Both `destination` and `source` are defined in the compiled DEX files.
    477     // No need to record a dependency.
    478     return;
    479   }
    480 
    481   if (!IsInClassPath(source)) {
    482     if (!destination->IsInterface() && !source->IsInterface()) {
    483       // Find the super class at the classpath boundary. Only that class
    484       // can change the assignability.
    485       do {
    486         source = source->GetSuperClass();
    487       } while (!IsInClassPath(source));
    488 
    489       // If that class is the actual destination, no need to record it.
    490       if (source == destination) {
    491         return;
    492       }
    493     } else if (is_assignable) {
    494       source = FindOneClassPathBoundaryForInterface(destination, source);
    495       if (source == nullptr) {
    496         // There was no classpath boundary, no need to record.
    497         return;
    498       }
    499       DCHECK(IsInClassPath(source));
    500     }
    501   }
    502 
    503 
    504   // Get string IDs for both descriptors and store in the appropriate set.
    505   dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
    506   dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
    507 
    508   if (is_assignable) {
    509     dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
    510   } else {
    511     dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
    512   }
    513 }
    514 
    515 void VerifierDeps::MaybeRecordClassRedefinition(const DexFile& dex_file,
    516                                                 const dex::ClassDef& class_def) {
    517   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    518   if (thread_deps != nullptr) {
    519     DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
    520     DCHECK_EQ(dex_deps->redefined_classes_.size(), dex_file.NumClassDefs());
    521     dex_deps->redefined_classes_[dex_file.GetIndexForClassDef(class_def)] = true;
    522   }
    523 }
    524 
    525 void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
    526                                                  const dex::ClassDef& class_def,
    527                                                  FailureKind failure_kind) {
    528   // The `verified_classes_` bit vector is initialized to `false`.
    529   // Only continue if we are about to write `true`.
    530   if (failure_kind == FailureKind::kNoFailure) {
    531     VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    532     if (thread_deps != nullptr) {
    533       thread_deps->RecordClassVerified(dex_file, class_def);
    534     }
    535   }
    536 }
    537 
    538 void VerifierDeps::RecordClassVerified(const DexFile& dex_file, const dex::ClassDef& class_def) {
    539   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    540   DCHECK_EQ(dex_deps->verified_classes_.size(), dex_file.NumClassDefs());
    541   dex_deps->verified_classes_[dex_file.GetIndexForClassDef(class_def)] = true;
    542 }
    543 
    544 void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
    545                                               dex::TypeIndex type_idx,
    546                                               ObjPtr<mirror::Class> klass) {
    547   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    548   if (thread_deps != nullptr) {
    549     thread_deps->AddClassResolution(dex_file, type_idx, klass);
    550   }
    551 }
    552 
    553 void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
    554                                               uint32_t field_idx,
    555                                               ArtField* field) {
    556   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    557   if (thread_deps != nullptr) {
    558     thread_deps->AddFieldResolution(dex_file, field_idx, field);
    559   }
    560 }
    561 
    562 void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
    563                                                uint32_t method_idx,
    564                                                ArtMethod* method) {
    565   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    566   if (thread_deps != nullptr) {
    567     thread_deps->AddMethodResolution(dex_file, method_idx, method);
    568   }
    569 }
    570 
    571 void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
    572                                             ObjPtr<mirror::Class> destination,
    573                                             ObjPtr<mirror::Class> source,
    574                                             bool is_strict,
    575                                             bool is_assignable) {
    576   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    577   if (thread_deps != nullptr) {
    578     thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
    579   }
    580 }
    581 
    582 namespace {
    583 
    584 static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
    585   CHECK_LT(*in, end);
    586   return DecodeUnsignedLeb128(in);
    587 }
    588 
    589 template<typename T> inline uint32_t Encode(T in);
    590 
    591 template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
    592   return in;
    593 }
    594 template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
    595   return in;
    596 }
    597 template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
    598   return in.index_;
    599 }
    600 template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
    601   return in.index_;
    602 }
    603 
    604 template<typename T> inline T Decode(uint32_t in);
    605 
    606 template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
    607   return dchecked_integral_cast<uint16_t>(in);
    608 }
    609 template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
    610   return in;
    611 }
    612 template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
    613   return dex::TypeIndex(in);
    614 }
    615 template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
    616   return dex::StringIndex(in);
    617 }
    618 
    619 template<typename T1, typename T2>
    620 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
    621   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
    622   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
    623 }
    624 
    625 template<typename T1, typename T2>
    626 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
    627   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
    628   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
    629   *t = std::make_tuple(v1, v2);
    630 }
    631 
    632 template<typename T1, typename T2, typename T3>
    633 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
    634   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
    635   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
    636   EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
    637 }
    638 
    639 template<typename T1, typename T2, typename T3>
    640 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
    641   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
    642   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
    643   T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
    644   *t = std::make_tuple(v1, v2, v3);
    645 }
    646 
    647 template<typename T>
    648 static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
    649   EncodeUnsignedLeb128(out, set.size());
    650   for (const T& entry : set) {
    651     EncodeTuple(out, entry);
    652   }
    653 }
    654 
    655 template<typename T>
    656 static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
    657   DCHECK(set->empty());
    658   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
    659   for (size_t i = 0; i < num_entries; ++i) {
    660     T tuple;
    661     DecodeTuple(in, end, &tuple);
    662     set->emplace(tuple);
    663   }
    664 }
    665 
    666 static inline void EncodeUint16SparseBitVector(std::vector<uint8_t>* out,
    667                                                const std::vector<bool>& vector,
    668                                                bool sparse_value) {
    669   DCHECK(IsUint<16>(vector.size()));
    670   EncodeUnsignedLeb128(out, std::count(vector.begin(), vector.end(), sparse_value));
    671   for (uint16_t idx = 0; idx < vector.size(); ++idx) {
    672     if (vector[idx] == sparse_value) {
    673       EncodeUnsignedLeb128(out, Encode(idx));
    674     }
    675   }
    676 }
    677 
    678 static inline void DecodeUint16SparseBitVector(const uint8_t** in,
    679                                                const uint8_t* end,
    680                                                std::vector<bool>* vector,
    681                                                bool sparse_value) {
    682   DCHECK(IsUint<16>(vector->size()));
    683   std::fill(vector->begin(), vector->end(), !sparse_value);
    684   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
    685   for (size_t i = 0; i < num_entries; ++i) {
    686     uint16_t idx = Decode<uint16_t>(DecodeUint32WithOverflowCheck(in, end));
    687     DCHECK_LT(idx, vector->size());
    688     (*vector)[idx] = sparse_value;
    689   }
    690 }
    691 
    692 static inline void EncodeStringVector(std::vector<uint8_t>* out,
    693                                       const std::vector<std::string>& strings) {
    694   EncodeUnsignedLeb128(out, strings.size());
    695   for (const std::string& str : strings) {
    696     const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
    697     size_t length = str.length() + 1;
    698     out->insert(out->end(), data, data + length);
    699     DCHECK_EQ(0u, out->back());
    700   }
    701 }
    702 
    703 static inline void DecodeStringVector(const uint8_t** in,
    704                                       const uint8_t* end,
    705                                       std::vector<std::string>* strings) {
    706   DCHECK(strings->empty());
    707   size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
    708   strings->reserve(num_strings);
    709   for (size_t i = 0; i < num_strings; ++i) {
    710     CHECK_LT(*in, end);
    711     const char* string_start = reinterpret_cast<const char*>(*in);
    712     strings->emplace_back(std::string(string_start));
    713     *in += strings->back().length() + 1;
    714   }
    715 }
    716 
    717 static inline std::string ToHex(uint32_t value) {
    718   std::stringstream ss;
    719   ss << std::hex << value << std::dec;
    720   return ss.str();
    721 }
    722 
    723 }  // namespace
    724 
    725 void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
    726                           std::vector<uint8_t>* buffer) const {
    727   for (const DexFile* dex_file : dex_files) {
    728     const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
    729     EncodeStringVector(buffer, deps.strings_);
    730     EncodeSet(buffer, deps.assignable_types_);
    731     EncodeSet(buffer, deps.unassignable_types_);
    732     EncodeSet(buffer, deps.classes_);
    733     EncodeSet(buffer, deps.fields_);
    734     EncodeSet(buffer, deps.methods_);
    735     EncodeUint16SparseBitVector(buffer, deps.verified_classes_, /* sparse_value= */ false);
    736     EncodeUint16SparseBitVector(buffer, deps.redefined_classes_, /* sparse_value= */ true);
    737   }
    738 }
    739 
    740 void VerifierDeps::DecodeDexFileDeps(DexFileDeps& deps,
    741                                      const uint8_t** data_start,
    742                                      const uint8_t* data_end) {
    743   DecodeStringVector(data_start, data_end, &deps.strings_);
    744   DecodeSet(data_start, data_end, &deps.assignable_types_);
    745   DecodeSet(data_start, data_end, &deps.unassignable_types_);
    746   DecodeSet(data_start, data_end, &deps.classes_);
    747   DecodeSet(data_start, data_end, &deps.fields_);
    748   DecodeSet(data_start, data_end, &deps.methods_);
    749   DecodeUint16SparseBitVector(data_start,
    750                               data_end,
    751                               &deps.verified_classes_,
    752                               /* sparse_value= */ false);
    753   DecodeUint16SparseBitVector(data_start,
    754                               data_end,
    755                               &deps.redefined_classes_,
    756                               /* sparse_value= */ true);
    757 }
    758 
    759 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
    760                            ArrayRef<const uint8_t> data)
    761     : VerifierDeps(dex_files, /*output_only=*/ false) {
    762   if (data.empty()) {
    763     // Return eagerly, as the first thing we expect from VerifierDeps data is
    764     // the number of created strings, even if there is no dependency.
    765     // Currently, only the boot image does not have any VerifierDeps data.
    766     return;
    767   }
    768   const uint8_t* data_start = data.data();
    769   const uint8_t* data_end = data_start + data.size();
    770   for (const DexFile* dex_file : dex_files) {
    771     DexFileDeps* deps = GetDexFileDeps(*dex_file);
    772     DecodeDexFileDeps(*deps, &data_start, data_end);
    773   }
    774   CHECK_LE(data_start, data_end);
    775 }
    776 
    777 std::vector<std::vector<bool>> VerifierDeps::ParseVerifiedClasses(
    778     const std::vector<const DexFile*>& dex_files,
    779     ArrayRef<const uint8_t> data) {
    780   DCHECK(!data.empty());
    781   DCHECK(!dex_files.empty());
    782 
    783   std::vector<std::vector<bool>> verified_classes_per_dex;
    784   verified_classes_per_dex.reserve(dex_files.size());
    785 
    786   const uint8_t* data_start = data.data();
    787   const uint8_t* data_end = data_start + data.size();
    788   for (const DexFile* dex_file : dex_files) {
    789     DexFileDeps deps(dex_file->NumClassDefs());
    790     DecodeDexFileDeps(deps, &data_start, data_end);
    791     verified_classes_per_dex.push_back(std::move(deps.verified_classes_));
    792   }
    793   return verified_classes_per_dex;
    794 }
    795 
    796 bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
    797   if (dex_deps_.size() != rhs.dex_deps_.size()) {
    798     return false;
    799   }
    800 
    801   auto lhs_it = dex_deps_.begin();
    802   auto rhs_it = rhs.dex_deps_.begin();
    803 
    804   for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
    805     const DexFile* lhs_dex_file = lhs_it->first;
    806     const DexFile* rhs_dex_file = rhs_it->first;
    807     if (lhs_dex_file != rhs_dex_file) {
    808       return false;
    809     }
    810 
    811     DexFileDeps* lhs_deps = lhs_it->second.get();
    812     DexFileDeps* rhs_deps = rhs_it->second.get();
    813     if (!lhs_deps->Equals(*rhs_deps)) {
    814       return false;
    815     }
    816   }
    817 
    818   DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
    819   return true;
    820 }
    821 
    822 bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
    823   return (strings_ == rhs.strings_) &&
    824          (assignable_types_ == rhs.assignable_types_) &&
    825          (unassignable_types_ == rhs.unassignable_types_) &&
    826          (classes_ == rhs.classes_) &&
    827          (fields_ == rhs.fields_) &&
    828          (methods_ == rhs.methods_) &&
    829          (verified_classes_ == rhs.verified_classes_);
    830 }
    831 
    832 void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
    833   for (const auto& dep : dex_deps_) {
    834     const DexFile& dex_file = *dep.first;
    835     vios->Stream()
    836         << "Dependencies of "
    837         << dex_file.GetLocation()
    838         << ":\n";
    839 
    840     ScopedIndentation indent(vios);
    841 
    842     for (const std::string& str : dep.second->strings_) {
    843       vios->Stream() << "Extra string: " << str << "\n";
    844     }
    845 
    846     for (const TypeAssignability& entry : dep.second->assignable_types_) {
    847       vios->Stream()
    848         << GetStringFromId(dex_file, entry.GetSource())
    849         << " must be assignable to "
    850         << GetStringFromId(dex_file, entry.GetDestination())
    851         << "\n";
    852     }
    853 
    854     for (const TypeAssignability& entry : dep.second->unassignable_types_) {
    855       vios->Stream()
    856         << GetStringFromId(dex_file, entry.GetSource())
    857         << " must not be assignable to "
    858         << GetStringFromId(dex_file, entry.GetDestination())
    859         << "\n";
    860     }
    861 
    862     for (const ClassResolution& entry : dep.second->classes_) {
    863       vios->Stream()
    864           << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
    865           << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
    866           << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
    867           << "\n";
    868     }
    869 
    870     for (const FieldResolution& entry : dep.second->fields_) {
    871       const dex::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
    872       vios->Stream()
    873           << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
    874           << dex_file.GetFieldName(field_id) << ":"
    875           << dex_file.GetFieldTypeDescriptor(field_id)
    876           << " is expected to be ";
    877       if (!entry.IsResolved()) {
    878         vios->Stream() << "unresolved\n";
    879       } else {
    880         vios->Stream()
    881           << "in class "
    882           << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
    883           << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
    884           << "\n";
    885       }
    886     }
    887 
    888     for (const MethodResolution& method : dep.second->methods_) {
    889       const dex::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
    890       vios->Stream()
    891           << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
    892           << dex_file.GetMethodName(method_id)
    893           << dex_file.GetMethodSignature(method_id).ToString()
    894           << " is expected to be ";
    895       if (!method.IsResolved()) {
    896         vios->Stream() << "unresolved\n";
    897       } else {
    898         vios->Stream()
    899           << "in class "
    900           << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
    901           << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
    902           << "\n";
    903       }
    904     }
    905 
    906     for (size_t idx = 0; idx < dep.second->verified_classes_.size(); idx++) {
    907       if (!dep.second->verified_classes_[idx]) {
    908         vios->Stream()
    909             << dex_file.GetClassDescriptor(dex_file.GetClassDef(idx))
    910             << " will be verified at runtime\n";
    911       }
    912     }
    913   }
    914 }
    915 
    916 bool VerifierDeps::ValidateDependencies(Thread* self,
    917                                         Handle<mirror::ClassLoader> class_loader,
    918                                         const std::vector<const DexFile*>& classpath,
    919                                         /* out */ std::string* error_msg) const {
    920   for (const auto& entry : dex_deps_) {
    921     if (!VerifyDexFile(class_loader, *entry.first, *entry.second, classpath, self, error_msg)) {
    922       return false;
    923     }
    924   }
    925   return true;
    926 }
    927 
    928 // TODO: share that helper with other parts of the compiler that have
    929 // the same lookup pattern.
    930 static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker,
    931                                                         Thread* self,
    932                                                         const std::string& name,
    933                                                         Handle<mirror::ClassLoader> class_loader)
    934     REQUIRES_SHARED(Locks::mutator_lock_) {
    935   ObjPtr<mirror::Class> result = class_linker->FindClass(self, name.c_str(), class_loader);
    936   if (result == nullptr) {
    937     DCHECK(self->IsExceptionPending());
    938     self->ClearException();
    939   }
    940   return result;
    941 }
    942 
    943 bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
    944                                        const DexFile& dex_file,
    945                                        const std::set<TypeAssignability>& assignables,
    946                                        bool expected_assignability,
    947                                        Thread* self,
    948                                        /* out */ std::string* error_msg) const {
    949   StackHandleScope<2> hs(self);
    950   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    951   MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
    952   MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
    953 
    954   for (const auto& entry : assignables) {
    955     const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
    956     destination.Assign(
    957         FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
    958     const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
    959     source.Assign(
    960         FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
    961 
    962     if (destination == nullptr) {
    963       *error_msg = "Could not resolve class " + destination_desc;
    964       return false;
    965     }
    966 
    967     if (source == nullptr) {
    968       *error_msg = "Could not resolve class " + source_desc;
    969       return false;
    970     }
    971 
    972     DCHECK(destination->IsResolved() && source->IsResolved());
    973     if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
    974       *error_msg = "Class " + destination_desc + (expected_assignability ? " not " : " ") +
    975           "assignable from " + source_desc;
    976       return false;
    977     }
    978   }
    979   return true;
    980 }
    981 
    982 bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
    983                                  const DexFile& dex_file,
    984                                  const std::set<ClassResolution>& classes,
    985                                  Thread* self,
    986                                  /* out */ std::string* error_msg) const {
    987   StackHandleScope<1> hs(self);
    988   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    989   MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
    990   for (const auto& entry : classes) {
    991     std::string descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
    992     cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
    993 
    994     if (entry.IsResolved()) {
    995       if (cls == nullptr) {
    996         *error_msg = "Could not resolve class " + descriptor;
    997         return false;
    998       } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
    999         *error_msg = "Unexpected access flags on class " + descriptor
   1000             + " (expected=" + ToHex(entry.GetAccessFlags())
   1001             + ", actual=" + ToHex(GetAccessFlags(cls.Get())) + ")";
   1002         return false;
   1003       }
   1004     } else if (cls != nullptr) {
   1005       *error_msg = "Unexpected successful resolution of class " + descriptor;
   1006       return false;
   1007     }
   1008   }
   1009   return true;
   1010 }
   1011 
   1012 static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
   1013   const dex::FieldId& field_id = dex_file.GetFieldId(index);
   1014   return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
   1015       + "->"
   1016       + dex_file.GetFieldName(field_id)
   1017       + ":"
   1018       + dex_file.GetFieldTypeDescriptor(field_id);
   1019 }
   1020 
   1021 bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
   1022                                 const DexFile& dex_file,
   1023                                 const std::set<FieldResolution>& fields,
   1024                                 Thread* self,
   1025                                 /* out */ std::string* error_msg) const {
   1026   // Check recorded fields are resolved the same way, have the same recorded class,
   1027   // and have the same recorded flags.
   1028   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   1029   for (const auto& entry : fields) {
   1030     const dex::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
   1031     std::string_view name(dex_file.StringDataByIdx(field_id.name_idx_));
   1032     std::string_view type(
   1033         dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
   1034     // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
   1035     // Otherwise, we might end up resolving an application class, which is expensive.
   1036     std::string expected_decl_klass = entry.IsResolved()
   1037         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
   1038         : dex_file.StringByTypeIdx(field_id.class_idx_);
   1039     ObjPtr<mirror::Class> cls = FindClassAndClearException(
   1040         class_linker, self, expected_decl_klass.c_str(), class_loader);
   1041     if (cls == nullptr) {
   1042       *error_msg = "Could not resolve class " + expected_decl_klass;
   1043       return false;
   1044     }
   1045     DCHECK(cls->IsResolved());
   1046 
   1047     ArtField* field = mirror::Class::FindField(self, cls, name, type);
   1048     if (entry.IsResolved()) {
   1049       std::string temp;
   1050       if (field == nullptr) {
   1051         *error_msg = "Could not resolve field " +
   1052             GetFieldDescription(dex_file, entry.GetDexFieldIndex());
   1053         return false;
   1054       } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
   1055         *error_msg = "Unexpected declaring class for field resolution "
   1056             + GetFieldDescription(dex_file, entry.GetDexFieldIndex())
   1057             + " (expected=" + expected_decl_klass
   1058             + ", actual=" + field->GetDeclaringClass()->GetDescriptor(&temp) + ")";
   1059         return false;
   1060       } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
   1061         *error_msg = "Unexpected access flags for resolved field "
   1062             + GetFieldDescription(dex_file, entry.GetDexFieldIndex())
   1063             + " (expected=" + ToHex(entry.GetAccessFlags())
   1064             + ", actual=" + ToHex(GetAccessFlags(field)) + ")";
   1065         return false;
   1066       }
   1067     } else if (field != nullptr) {
   1068       *error_msg = "Unexpected successful resolution of field "
   1069           + GetFieldDescription(dex_file, entry.GetDexFieldIndex());
   1070       return false;
   1071     }
   1072   }
   1073   return true;
   1074 }
   1075 
   1076 static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
   1077   const dex::MethodId& method_id = dex_file.GetMethodId(index);
   1078   return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
   1079       + "->"
   1080       + dex_file.GetMethodName(method_id)
   1081       + dex_file.GetMethodSignature(method_id).ToString();
   1082 }
   1083 
   1084 bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
   1085                                  const DexFile& dex_file,
   1086                                  const std::set<MethodResolution>& methods,
   1087                                  Thread* self,
   1088                                  /* out */ std::string* error_msg) const {
   1089   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   1090   PointerSize pointer_size = class_linker->GetImagePointerSize();
   1091 
   1092   for (const auto& entry : methods) {
   1093     const dex::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
   1094 
   1095     const char* name = dex_file.GetMethodName(method_id);
   1096     const Signature signature = dex_file.GetMethodSignature(method_id);
   1097     // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
   1098     // Otherwise, we might end up resolving an application class, which is expensive.
   1099     std::string expected_decl_klass = entry.IsResolved()
   1100         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
   1101         : dex_file.StringByTypeIdx(method_id.class_idx_);
   1102 
   1103     ObjPtr<mirror::Class> cls = FindClassAndClearException(
   1104         class_linker, self, expected_decl_klass.c_str(), class_loader);
   1105     if (cls == nullptr) {
   1106       *error_msg = "Could not resolve class " + expected_decl_klass;
   1107       return false;
   1108     }
   1109     DCHECK(cls->IsResolved());
   1110     ArtMethod* method = nullptr;
   1111     if (cls->IsInterface()) {
   1112       method = cls->FindInterfaceMethod(name, signature, pointer_size);
   1113     } else {
   1114       method = cls->FindClassMethod(name, signature, pointer_size);
   1115     }
   1116 
   1117     if (entry.IsResolved()) {
   1118       std::string temp;
   1119       if (method == nullptr) {
   1120         *error_msg = "Could not resolve method "
   1121             + GetMethodDescription(dex_file, entry.GetDexMethodIndex());
   1122         return false;
   1123       } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
   1124         *error_msg = "Unexpected declaring class for method resolution "
   1125             + GetMethodDescription(dex_file, entry.GetDexMethodIndex())
   1126             + " (expected=" + expected_decl_klass
   1127             + ", actual=" + method->GetDeclaringClass()->GetDescriptor(&temp) + ")";
   1128         return false;
   1129       } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
   1130         *error_msg = "Unexpected access flags for resolved method resolution "
   1131             + GetMethodDescription(dex_file, entry.GetDexMethodIndex())
   1132             + " (expected=" + ToHex(entry.GetAccessFlags())
   1133             + ", actual=" + ToHex(GetAccessFlags(method)) + ")";
   1134         return false;
   1135       }
   1136     } else if (method != nullptr) {
   1137       *error_msg = "Unexpected successful resolution of method "
   1138           + GetMethodDescription(dex_file, entry.GetDexMethodIndex());
   1139       return false;
   1140     }
   1141   }
   1142   return true;
   1143 }
   1144 
   1145 bool VerifierDeps::IsInDexFiles(const char* descriptor,
   1146                                 size_t hash,
   1147                                 const std::vector<const DexFile*>& dex_files,
   1148                                 /* out */ const DexFile** out_dex_file) const {
   1149   for (const DexFile* dex_file : dex_files) {
   1150     if (OatDexFile::FindClassDef(*dex_file, descriptor, hash) != nullptr) {
   1151       *out_dex_file = dex_file;
   1152       return true;
   1153     }
   1154   }
   1155   return false;
   1156 }
   1157 
   1158 bool VerifierDeps::VerifyInternalClasses(const DexFile& dex_file,
   1159                                          const std::vector<const DexFile*>& classpath,
   1160                                          const std::vector<bool>& verified_classes,
   1161                                          const std::vector<bool>& redefined_classes,
   1162                                          /* out */ std::string* error_msg) const {
   1163   const std::vector<const DexFile*>& boot_classpath =
   1164       Runtime::Current()->GetClassLinker()->GetBootClassPath();
   1165 
   1166   for (ClassAccessor accessor : dex_file.GetClasses()) {
   1167     const char* descriptor = accessor.GetDescriptor();
   1168 
   1169     const uint16_t class_def_index = accessor.GetClassDefIndex();
   1170     if (redefined_classes[class_def_index]) {
   1171       if (verified_classes[class_def_index]) {
   1172         *error_msg = std::string("Class ") + descriptor + " marked both verified and redefined";
   1173         return false;
   1174       }
   1175 
   1176       // Class was not verified under these dependencies. No need to check it further.
   1177       continue;
   1178     }
   1179 
   1180     // Check that the class resolved into the same dex file. Otherwise there is
   1181     // a different class with the same descriptor somewhere in one of the parent
   1182     // class loaders.
   1183     const size_t hash = ComputeModifiedUtf8Hash(descriptor);
   1184     const DexFile* cp_dex_file = nullptr;
   1185     if (IsInDexFiles(descriptor, hash, boot_classpath, &cp_dex_file) ||
   1186         IsInDexFiles(descriptor, hash, classpath, &cp_dex_file)) {
   1187       *error_msg = std::string("Class ") + descriptor
   1188           + " redefines a class in the classpath "
   1189           + "(dexFile expected=" + dex_file.GetLocation()
   1190           + ", actual=" + cp_dex_file->GetLocation() + ")";
   1191       return false;
   1192     }
   1193   }
   1194 
   1195   return true;
   1196 }
   1197 
   1198 bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
   1199                                  const DexFile& dex_file,
   1200                                  const DexFileDeps& deps,
   1201                                  const std::vector<const DexFile*>& classpath,
   1202                                  Thread* self,
   1203                                  /* out */ std::string* error_msg) const {
   1204   return VerifyInternalClasses(dex_file,
   1205                                classpath,
   1206                                deps.verified_classes_,
   1207                                deps.redefined_classes_,
   1208                                error_msg) &&
   1209          VerifyAssignability(class_loader,
   1210                              dex_file,
   1211                              deps.assignable_types_,
   1212                              /* expected_assignability= */ true,
   1213                              self,
   1214                              error_msg) &&
   1215          VerifyAssignability(class_loader,
   1216                              dex_file,
   1217                              deps.unassignable_types_,
   1218                              /* expected_assignability= */ false,
   1219                              self,
   1220                              error_msg) &&
   1221          VerifyClasses(class_loader, dex_file, deps.classes_, self, error_msg) &&
   1222          VerifyFields(class_loader, dex_file, deps.fields_, self, error_msg) &&
   1223          VerifyMethods(class_loader, dex_file, deps.methods_, self, error_msg);
   1224 }
   1225 
   1226 }  // namespace verifier
   1227 }  // namespace art
   1228