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