• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
VerifierDeps(const std::vector<const DexFile * > & dex_files,bool output_only)36 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only)
37     : output_only_(output_only) {
38   for (const DexFile* dex_file : dex_files) {
39     DCHECK(GetDexFileDeps(*dex_file) == nullptr);
40     std::unique_ptr<DexFileDeps> deps(new DexFileDeps());
41     dex_deps_.emplace(dex_file, std::move(deps));
42   }
43 }
44 
VerifierDeps(const std::vector<const DexFile * > & dex_files)45 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files)
46     : VerifierDeps(dex_files, /*output_only*/ true) {}
47 
MergeWith(const VerifierDeps & other,const std::vector<const DexFile * > & dex_files)48 void VerifierDeps::MergeWith(const VerifierDeps& other,
49                              const std::vector<const DexFile*>& dex_files) {
50   DCHECK(dex_deps_.size() == other.dex_deps_.size());
51   for (const DexFile* dex_file : dex_files) {
52     DexFileDeps* my_deps = GetDexFileDeps(*dex_file);
53     const DexFileDeps& other_deps = *other.GetDexFileDeps(*dex_file);
54     // We currently collect extra strings only on the main `VerifierDeps`,
55     // which should be the one passed as `this` in this method.
56     DCHECK(other_deps.strings_.empty());
57     MergeSets(my_deps->assignable_types_, other_deps.assignable_types_);
58     MergeSets(my_deps->unassignable_types_, other_deps.unassignable_types_);
59     MergeSets(my_deps->classes_, other_deps.classes_);
60     MergeSets(my_deps->fields_, other_deps.fields_);
61     MergeSets(my_deps->methods_, other_deps.methods_);
62     MergeSets(my_deps->unverified_classes_, other_deps.unverified_classes_);
63   }
64 }
65 
GetDexFileDeps(const DexFile & dex_file)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 
GetDexFileDeps(const DexFile & dex_file) const71 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>
GetAccessFlags(T * element)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 
GetClassDescriptorStringId(const DexFile & dex_file,ObjPtr<mirror::Class> klass)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.
TryGetClassDescriptorStringId(const DexFile & dex_file,dex::TypeIndex type_idx,ObjPtr<mirror::Class> klass)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 
GetMethodDeclaringClassStringId(const DexFile & dex_file,uint32_t dex_method_index,ArtMethod * method)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 
GetFieldDeclaringClassStringId(const DexFile & dex_file,uint32_t dex_field_idx,ArtField * field)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 
GetMainVerifierDeps()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 
GetThreadLocalVerifierDeps()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 
FindExistingStringId(const std::vector<std::string> & strings,const std::string & str,uint32_t * found_id)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 
GetIdFromString(const DexFile & dex_file,const std::string & str)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 
GetStringFromId(const DexFile & dex_file,dex::StringIndex string_id) const240 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 
IsInClassPath(ObjPtr<mirror::Class> klass) const254 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 
AddClassResolution(const DexFile & dex_file,dex::TypeIndex type_idx,mirror::Class * klass)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 
AddFieldResolution(const DexFile & dex_file,uint32_t field_idx,ArtField * field)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 
AddMethodResolution(const DexFile & dex_file,uint32_t method_idx,ArtMethod * method)318 void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
319                                        uint32_t method_idx,
320                                        ArtMethod* method) {
321   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
322   if (dex_deps == nullptr) {
323     // This invocation is from verification of a dex file which is not being compiled.
324     return;
325   }
326 
327   if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
328     // Method resolved into one of the DEX files which are being compiled.
329     // This is not a classpath dependency.
330     return;
331   }
332 
333   MethodResolution method_tuple(method_idx,
334                                 GetAccessFlags(method),
335                                 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
336   dex_deps->methods_.insert(method_tuple);
337 }
338 
FindOneClassPathBoundaryForInterface(mirror::Class * destination,mirror::Class * source) const339 mirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
340                                                                   mirror::Class* source) const {
341   DCHECK(destination->IsInterface());
342   DCHECK(IsInClassPath(destination));
343   Thread* thread = Thread::Current();
344   mirror::Class* current = source;
345   // Record the classes that are at the boundary between the compiled DEX files and
346   // the classpath. We will check those classes later to find one class that inherits
347   // `destination`.
348   std::vector<ObjPtr<mirror::Class>> boundaries;
349   // If the destination is a direct interface of a class defined in the DEX files being
350   // compiled, no need to record it.
351   while (!IsInClassPath(current)) {
352     for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
353       ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
354       if (direct == destination) {
355         return nullptr;
356       } else if (IsInClassPath(direct)) {
357         boundaries.push_back(direct);
358       }
359     }
360     current = current->GetSuperClass();
361   }
362   DCHECK(current != nullptr);
363   boundaries.push_back(current);
364 
365   // Check if we have an interface defined in the DEX files being compiled, direclty
366   // inheriting `destination`.
367   int32_t iftable_count = source->GetIfTableCount();
368   ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
369   for (int32_t i = 0; i < iftable_count; ++i) {
370     mirror::Class* itf = iftable->GetInterface(i);
371     if (!IsInClassPath(itf)) {
372       for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
373         ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
374         if (direct == destination) {
375           return nullptr;
376         } else if (IsInClassPath(direct)) {
377           boundaries.push_back(direct);
378         }
379       }
380     }
381   }
382 
383   // Find a boundary making `source` inherit from `destination`. We must find one.
384   for (const ObjPtr<mirror::Class>& boundary : boundaries) {
385     if (destination->IsAssignableFrom(boundary)) {
386       return boundary.Ptr();
387     }
388   }
389   LOG(FATAL) << "Should have found a classpath boundary";
390   UNREACHABLE();
391 }
392 
AddAssignability(const DexFile & dex_file,mirror::Class * destination,mirror::Class * source,bool is_strict,bool is_assignable)393 void VerifierDeps::AddAssignability(const DexFile& dex_file,
394                                     mirror::Class* destination,
395                                     mirror::Class* source,
396                                     bool is_strict,
397                                     bool is_assignable) {
398   // Test that the method is only called on reference types.
399   // Note that concurrent verification of `destination` and `source` may have
400   // set their status to erroneous. However, the tests performed below rely
401   // merely on no issues with linking (valid access flags, superclass and
402   // implemented interfaces). If the class at any point reached the IsResolved
403   // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
404   DCHECK(destination != nullptr);
405   DCHECK(source != nullptr);
406 
407   if (destination->IsPrimitive() || source->IsPrimitive()) {
408     // Primitive types are trivially non-assignable to anything else.
409     // We do not need to record trivial assignability, as it will
410     // not change across releases.
411     return;
412   }
413 
414   if (source->IsObjectClass() && !is_assignable) {
415     // j.l.Object is trivially non-assignable to other types, don't
416     // record it.
417     return;
418   }
419 
420   if (destination == source ||
421       destination->IsObjectClass() ||
422       (!is_strict && destination->IsInterface())) {
423     // Cases when `destination` is trivially assignable from `source`.
424     DCHECK(is_assignable);
425     return;
426   }
427 
428   if (destination->IsArrayClass() && source->IsArrayClass()) {
429     // Both types are arrays. Break down to component types and add recursively.
430     // This helps filter out destinations from compiled DEX files (see below)
431     // and deduplicate entries with the same canonical component type.
432     mirror::Class* destination_component = destination->GetComponentType();
433     mirror::Class* source_component = source->GetComponentType();
434 
435     // Only perform the optimization if both types are resolved which guarantees
436     // that they linked successfully, as required at the top of this method.
437     if (destination_component->IsResolved() && source_component->IsResolved()) {
438       AddAssignability(dex_file,
439                        destination_component,
440                        source_component,
441                        /* is_strict */ true,
442                        is_assignable);
443       return;
444     }
445   } else {
446     // We only do this check for non-array types, as arrays might have erroneous
447     // component types which makes the IsAssignableFrom check unreliable.
448     DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
449   }
450 
451   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
452   if (dex_deps == nullptr) {
453     // This invocation is from verification of a DEX file which is not being compiled.
454     return;
455   }
456 
457   if (!IsInClassPath(destination) && !IsInClassPath(source)) {
458     // Both `destination` and `source` are defined in the compiled DEX files.
459     // No need to record a dependency.
460     return;
461   }
462 
463   if (!IsInClassPath(source)) {
464     if (!destination->IsInterface() && !source->IsInterface()) {
465       // Find the super class at the classpath boundary. Only that class
466       // can change the assignability.
467       do {
468         source = source->GetSuperClass();
469       } while (!IsInClassPath(source));
470 
471       // If that class is the actual destination, no need to record it.
472       if (source == destination) {
473         return;
474       }
475     } else if (is_assignable) {
476       source = FindOneClassPathBoundaryForInterface(destination, source);
477       if (source == nullptr) {
478         // There was no classpath boundary, no need to record.
479         return;
480       }
481       DCHECK(IsInClassPath(source));
482     }
483   }
484 
485 
486   // Get string IDs for both descriptors and store in the appropriate set.
487   dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
488   dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
489 
490   if (is_assignable) {
491     dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
492   } else {
493     dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
494   }
495 }
496 
MaybeRecordVerificationStatus(const DexFile & dex_file,dex::TypeIndex type_idx,FailureKind failure_kind)497 void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
498                                                  dex::TypeIndex type_idx,
499                                                  FailureKind failure_kind) {
500   if (failure_kind == FailureKind::kNoFailure) {
501     // We only record classes that did not fully verify at compile time.
502     return;
503   }
504 
505   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
506   if (thread_deps != nullptr) {
507     DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
508     dex_deps->unverified_classes_.insert(type_idx);
509   }
510 }
511 
MaybeRecordClassResolution(const DexFile & dex_file,dex::TypeIndex type_idx,mirror::Class * klass)512 void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
513                                               dex::TypeIndex type_idx,
514                                               mirror::Class* klass) {
515   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
516   if (thread_deps != nullptr) {
517     thread_deps->AddClassResolution(dex_file, type_idx, klass);
518   }
519 }
520 
MaybeRecordFieldResolution(const DexFile & dex_file,uint32_t field_idx,ArtField * field)521 void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
522                                               uint32_t field_idx,
523                                               ArtField* field) {
524   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
525   if (thread_deps != nullptr) {
526     thread_deps->AddFieldResolution(dex_file, field_idx, field);
527   }
528 }
529 
MaybeRecordMethodResolution(const DexFile & dex_file,uint32_t method_idx,ArtMethod * method)530 void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
531                                                uint32_t method_idx,
532                                                ArtMethod* method) {
533   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
534   if (thread_deps != nullptr) {
535     thread_deps->AddMethodResolution(dex_file, method_idx, method);
536   }
537 }
538 
MaybeRecordAssignability(const DexFile & dex_file,mirror::Class * destination,mirror::Class * source,bool is_strict,bool is_assignable)539 void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
540                                             mirror::Class* destination,
541                                             mirror::Class* source,
542                                             bool is_strict,
543                                             bool is_assignable) {
544   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
545   if (thread_deps != nullptr) {
546     thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
547   }
548 }
549 
550 namespace {
551 
DecodeUint32WithOverflowCheck(const uint8_t ** in,const uint8_t * end)552 static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
553   CHECK_LT(*in, end);
554   return DecodeUnsignedLeb128(in);
555 }
556 
557 template<typename T> inline uint32_t Encode(T in);
558 
Encode(uint16_t in)559 template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
560   return in;
561 }
Encode(uint32_t in)562 template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
563   return in;
564 }
Encode(dex::TypeIndex in)565 template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
566   return in.index_;
567 }
Encode(dex::StringIndex in)568 template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
569   return in.index_;
570 }
571 
572 template<typename T> inline T Decode(uint32_t in);
573 
Decode(uint32_t in)574 template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
575   return dchecked_integral_cast<uint16_t>(in);
576 }
Decode(uint32_t in)577 template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
578   return in;
579 }
Decode(uint32_t in)580 template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
581   return dex::TypeIndex(in);
582 }
Decode(uint32_t in)583 template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
584   return dex::StringIndex(in);
585 }
586 
587 // TODO: Clean this up, if we use a template arg here it confuses the compiler.
EncodeTuple(std::vector<uint8_t> * out,const dex::TypeIndex & t)588 static inline void EncodeTuple(std::vector<uint8_t>* out, const dex::TypeIndex& t) {
589   EncodeUnsignedLeb128(out, Encode(t));
590 }
591 
592 // TODO: Clean this up, if we use a template arg here it confuses the compiler.
DecodeTuple(const uint8_t ** in,const uint8_t * end,dex::TypeIndex * t)593 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, dex::TypeIndex* t) {
594   *t = Decode<dex::TypeIndex>(DecodeUint32WithOverflowCheck(in, end));
595 }
596 
597 template<typename T1, typename T2>
EncodeTuple(std::vector<uint8_t> * out,const std::tuple<T1,T2> & t)598 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
599   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
600   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
601 }
602 
603 template<typename T1, typename T2>
DecodeTuple(const uint8_t ** in,const uint8_t * end,std::tuple<T1,T2> * t)604 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
605   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
606   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
607   *t = std::make_tuple(v1, v2);
608 }
609 
610 template<typename T1, typename T2, typename T3>
EncodeTuple(std::vector<uint8_t> * out,const std::tuple<T1,T2,T3> & t)611 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
612   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
613   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
614   EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
615 }
616 
617 template<typename T1, typename T2, typename T3>
DecodeTuple(const uint8_t ** in,const uint8_t * end,std::tuple<T1,T2,T3> * t)618 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
619   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
620   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
621   T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
622   *t = std::make_tuple(v1, v2, v3);
623 }
624 
625 template<typename T>
EncodeSet(std::vector<uint8_t> * out,const std::set<T> & set)626 static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
627   EncodeUnsignedLeb128(out, set.size());
628   for (const T& entry : set) {
629     EncodeTuple(out, entry);
630   }
631 }
632 
633 template <typename T>
EncodeUint16Vector(std::vector<uint8_t> * out,const std::vector<T> & vector)634 static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
635                                       const std::vector<T>& vector) {
636   EncodeUnsignedLeb128(out, vector.size());
637   for (const T& entry : vector) {
638     EncodeUnsignedLeb128(out, Encode(entry));
639   }
640 }
641 
642 template<typename T>
DecodeSet(const uint8_t ** in,const uint8_t * end,std::set<T> * set)643 static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
644   DCHECK(set->empty());
645   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
646   for (size_t i = 0; i < num_entries; ++i) {
647     T tuple;
648     DecodeTuple(in, end, &tuple);
649     set->emplace(tuple);
650   }
651 }
652 
653 template<typename T>
DecodeUint16Vector(const uint8_t ** in,const uint8_t * end,std::vector<T> * vector)654 static inline void DecodeUint16Vector(const uint8_t** in,
655                                       const uint8_t* end,
656                                       std::vector<T>* vector) {
657   DCHECK(vector->empty());
658   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
659   vector->reserve(num_entries);
660   for (size_t i = 0; i < num_entries; ++i) {
661     vector->push_back(
662         Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
663   }
664 }
665 
EncodeStringVector(std::vector<uint8_t> * out,const std::vector<std::string> & strings)666 static inline void EncodeStringVector(std::vector<uint8_t>* out,
667                                       const std::vector<std::string>& strings) {
668   EncodeUnsignedLeb128(out, strings.size());
669   for (const std::string& str : strings) {
670     const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
671     size_t length = str.length() + 1;
672     out->insert(out->end(), data, data + length);
673     DCHECK_EQ(0u, out->back());
674   }
675 }
676 
DecodeStringVector(const uint8_t ** in,const uint8_t * end,std::vector<std::string> * strings)677 static inline void DecodeStringVector(const uint8_t** in,
678                                       const uint8_t* end,
679                                       std::vector<std::string>* strings) {
680   DCHECK(strings->empty());
681   size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
682   strings->reserve(num_strings);
683   for (size_t i = 0; i < num_strings; ++i) {
684     CHECK_LT(*in, end);
685     const char* string_start = reinterpret_cast<const char*>(*in);
686     strings->emplace_back(std::string(string_start));
687     *in += strings->back().length() + 1;
688   }
689 }
690 
691 }  // namespace
692 
Encode(const std::vector<const DexFile * > & dex_files,std::vector<uint8_t> * buffer) const693 void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
694                           std::vector<uint8_t>* buffer) const {
695   for (const DexFile* dex_file : dex_files) {
696     const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
697     EncodeStringVector(buffer, deps.strings_);
698     EncodeSet(buffer, deps.assignable_types_);
699     EncodeSet(buffer, deps.unassignable_types_);
700     EncodeSet(buffer, deps.classes_);
701     EncodeSet(buffer, deps.fields_);
702     EncodeSet(buffer, deps.methods_);
703     EncodeSet(buffer, deps.unverified_classes_);
704   }
705 }
706 
VerifierDeps(const std::vector<const DexFile * > & dex_files,ArrayRef<const uint8_t> data)707 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
708                            ArrayRef<const uint8_t> data)
709     : VerifierDeps(dex_files, /*output_only*/ false) {
710   if (data.empty()) {
711     // Return eagerly, as the first thing we expect from VerifierDeps data is
712     // the number of created strings, even if there is no dependency.
713     // Currently, only the boot image does not have any VerifierDeps data.
714     return;
715   }
716   const uint8_t* data_start = data.data();
717   const uint8_t* data_end = data_start + data.size();
718   for (const DexFile* dex_file : dex_files) {
719     DexFileDeps* deps = GetDexFileDeps(*dex_file);
720     DecodeStringVector(&data_start, data_end, &deps->strings_);
721     DecodeSet(&data_start, data_end, &deps->assignable_types_);
722     DecodeSet(&data_start, data_end, &deps->unassignable_types_);
723     DecodeSet(&data_start, data_end, &deps->classes_);
724     DecodeSet(&data_start, data_end, &deps->fields_);
725     DecodeSet(&data_start, data_end, &deps->methods_);
726     DecodeSet(&data_start, data_end, &deps->unverified_classes_);
727   }
728   CHECK_LE(data_start, data_end);
729 }
730 
Equals(const VerifierDeps & rhs) const731 bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
732   if (dex_deps_.size() != rhs.dex_deps_.size()) {
733     return false;
734   }
735 
736   auto lhs_it = dex_deps_.begin();
737   auto rhs_it = rhs.dex_deps_.begin();
738 
739   for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
740     const DexFile* lhs_dex_file = lhs_it->first;
741     const DexFile* rhs_dex_file = rhs_it->first;
742     if (lhs_dex_file != rhs_dex_file) {
743       return false;
744     }
745 
746     DexFileDeps* lhs_deps = lhs_it->second.get();
747     DexFileDeps* rhs_deps = rhs_it->second.get();
748     if (!lhs_deps->Equals(*rhs_deps)) {
749       return false;
750     }
751   }
752 
753   DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
754   return true;
755 }
756 
Equals(const VerifierDeps::DexFileDeps & rhs) const757 bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
758   return (strings_ == rhs.strings_) &&
759          (assignable_types_ == rhs.assignable_types_) &&
760          (unassignable_types_ == rhs.unassignable_types_) &&
761          (classes_ == rhs.classes_) &&
762          (fields_ == rhs.fields_) &&
763          (methods_ == rhs.methods_) &&
764          (unverified_classes_ == rhs.unverified_classes_);
765 }
766 
Dump(VariableIndentationOutputStream * vios) const767 void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
768   for (const auto& dep : dex_deps_) {
769     const DexFile& dex_file = *dep.first;
770     vios->Stream()
771         << "Dependencies of "
772         << dex_file.GetLocation()
773         << ":\n";
774 
775     ScopedIndentation indent(vios);
776 
777     for (const std::string& str : dep.second->strings_) {
778       vios->Stream() << "Extra string: " << str << "\n";
779     }
780 
781     for (const TypeAssignability& entry : dep.second->assignable_types_) {
782       vios->Stream()
783         << GetStringFromId(dex_file, entry.GetSource())
784         << " must be assignable to "
785         << GetStringFromId(dex_file, entry.GetDestination())
786         << "\n";
787     }
788 
789     for (const TypeAssignability& entry : dep.second->unassignable_types_) {
790       vios->Stream()
791         << GetStringFromId(dex_file, entry.GetSource())
792         << " must not be assignable to "
793         << GetStringFromId(dex_file, entry.GetDestination())
794         << "\n";
795     }
796 
797     for (const ClassResolution& entry : dep.second->classes_) {
798       vios->Stream()
799           << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
800           << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
801           << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
802           << "\n";
803     }
804 
805     for (const FieldResolution& entry : dep.second->fields_) {
806       const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
807       vios->Stream()
808           << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
809           << dex_file.GetFieldName(field_id) << ":"
810           << dex_file.GetFieldTypeDescriptor(field_id)
811           << " is expected to be ";
812       if (!entry.IsResolved()) {
813         vios->Stream() << "unresolved\n";
814       } else {
815         vios->Stream()
816           << "in class "
817           << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
818           << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
819           << "\n";
820       }
821     }
822 
823     for (const MethodResolution& method : dep.second->methods_) {
824       const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
825       vios->Stream()
826           << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
827           << dex_file.GetMethodName(method_id)
828           << dex_file.GetMethodSignature(method_id).ToString()
829           << " is expected to be ";
830       if (!method.IsResolved()) {
831         vios->Stream() << "unresolved\n";
832       } else {
833         vios->Stream()
834           << "in class "
835           << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
836           << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
837           << "\n";
838       }
839     }
840 
841     for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
842       vios->Stream()
843           << dex_file.StringByTypeIdx(type_index)
844           << " is expected to be verified at runtime\n";
845     }
846   }
847 }
848 
ValidateDependencies(Handle<mirror::ClassLoader> class_loader,Thread * self) const849 bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
850                                         Thread* self) const {
851   for (const auto& entry : dex_deps_) {
852     if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
853       return false;
854     }
855   }
856   return true;
857 }
858 
859 // TODO: share that helper with other parts of the compiler that have
860 // the same lookup pattern.
FindClassAndClearException(ClassLinker * class_linker,Thread * self,const char * name,Handle<mirror::ClassLoader> class_loader)861 static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
862                                                  Thread* self,
863                                                  const char* name,
864                                                  Handle<mirror::ClassLoader> class_loader)
865     REQUIRES_SHARED(Locks::mutator_lock_) {
866   mirror::Class* result = class_linker->FindClass(self, name, class_loader);
867   if (result == nullptr) {
868     DCHECK(self->IsExceptionPending());
869     self->ClearException();
870   }
871   return result;
872 }
873 
VerifyAssignability(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<TypeAssignability> & assignables,bool expected_assignability,Thread * self) const874 bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
875                                        const DexFile& dex_file,
876                                        const std::set<TypeAssignability>& assignables,
877                                        bool expected_assignability,
878                                        Thread* self) const {
879   StackHandleScope<2> hs(self);
880   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
881   MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
882   MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
883 
884   for (const auto& entry : assignables) {
885     const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
886     destination.Assign(
887         FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
888     const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
889     source.Assign(
890         FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
891 
892     if (destination == nullptr) {
893       LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
894       return false;
895     }
896 
897     if (source == nullptr) {
898       LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
899       return false;
900     }
901 
902     DCHECK(destination->IsResolved() && source->IsResolved());
903     if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
904       LOG(INFO) << "VerifierDeps: Class "
905                 << destination_desc
906                 << (expected_assignability ? " not " : " ")
907                 << "assignable from "
908                 << source_desc;
909       return false;
910     }
911   }
912   return true;
913 }
914 
VerifyClasses(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<ClassResolution> & classes,Thread * self) const915 bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
916                                  const DexFile& dex_file,
917                                  const std::set<ClassResolution>& classes,
918                                  Thread* self) const {
919   StackHandleScope<1> hs(self);
920   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
921   MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
922   for (const auto& entry : classes) {
923     const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
924     cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
925 
926     if (entry.IsResolved()) {
927       if (cls == nullptr) {
928         LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
929         return false;
930       } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
931         LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
932                   << descriptor
933                   << std::hex
934                   << " (expected="
935                   << entry.GetAccessFlags()
936                   << ", actual="
937                   << GetAccessFlags(cls.Get()) << ")"
938                   << std::dec;
939         return false;
940       }
941     } else if (cls != nullptr) {
942       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
943       return false;
944     }
945   }
946   return true;
947 }
948 
GetFieldDescription(const DexFile & dex_file,uint32_t index)949 static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
950   const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
951   return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
952       + "->"
953       + dex_file.GetFieldName(field_id)
954       + ":"
955       + dex_file.GetFieldTypeDescriptor(field_id);
956 }
957 
VerifyFields(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<FieldResolution> & fields,Thread * self) const958 bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
959                                 const DexFile& dex_file,
960                                 const std::set<FieldResolution>& fields,
961                                 Thread* self) const {
962   // Check recorded fields are resolved the same way, have the same recorded class,
963   // and have the same recorded flags.
964   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
965   for (const auto& entry : fields) {
966     const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
967     StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
968     StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
969     // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
970     // Otherwise, we might end up resolving an application class, which is expensive.
971     std::string expected_decl_klass = entry.IsResolved()
972         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
973         : dex_file.StringByTypeIdx(field_id.class_idx_);
974     mirror::Class* cls = FindClassAndClearException(
975         class_linker, self, expected_decl_klass.c_str(), class_loader);
976     if (cls == nullptr) {
977       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
978       return false;
979     }
980     DCHECK(cls->IsResolved());
981 
982     ArtField* field = mirror::Class::FindField(self, cls, name, type);
983     if (entry.IsResolved()) {
984       std::string temp;
985       if (field == nullptr) {
986         LOG(INFO) << "VerifierDeps: Could not resolve field "
987                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
988         return false;
989       } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
990         LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
991                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
992                   << " (expected=" << expected_decl_klass
993                   << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
994         return false;
995       } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
996         LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
997                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
998                   << std::hex << " (expected=" << entry.GetAccessFlags()
999                   << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
1000         return false;
1001       }
1002     } else if (field != nullptr) {
1003       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
1004                 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
1005       return false;
1006     }
1007   }
1008   return true;
1009 }
1010 
GetMethodDescription(const DexFile & dex_file,uint32_t index)1011 static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
1012   const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
1013   return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
1014       + "->"
1015       + dex_file.GetMethodName(method_id)
1016       + dex_file.GetMethodSignature(method_id).ToString();
1017 }
1018 
VerifyMethods(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<MethodResolution> & methods,Thread * self) const1019 bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
1020                                  const DexFile& dex_file,
1021                                  const std::set<MethodResolution>& methods,
1022                                  Thread* self) const {
1023   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1024   PointerSize pointer_size = class_linker->GetImagePointerSize();
1025 
1026   for (const auto& entry : methods) {
1027     const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
1028 
1029     const char* name = dex_file.GetMethodName(method_id);
1030     const Signature signature = dex_file.GetMethodSignature(method_id);
1031     // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
1032     // Otherwise, we might end up resolving an application class, which is expensive.
1033     std::string expected_decl_klass = entry.IsResolved()
1034         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
1035         : dex_file.StringByTypeIdx(method_id.class_idx_);
1036 
1037     mirror::Class* cls = FindClassAndClearException(
1038         class_linker, self, expected_decl_klass.c_str(), class_loader);
1039     if (cls == nullptr) {
1040       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
1041       return false;
1042     }
1043     DCHECK(cls->IsResolved());
1044     ArtMethod* method = nullptr;
1045     if (cls->IsInterface()) {
1046       method = cls->FindInterfaceMethod(name, signature, pointer_size);
1047     } else {
1048       method = cls->FindClassMethod(name, signature, pointer_size);
1049     }
1050 
1051     if (entry.IsResolved()) {
1052       std::string temp;
1053       if (method == nullptr) {
1054         LOG(INFO) << "VerifierDeps: Could not resolve method "
1055                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1056         return false;
1057       } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
1058         LOG(INFO) << "VerifierDeps: Unexpected declaring class for method resolution "
1059                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1060                   << " (expected="
1061                   << expected_decl_klass
1062                   << ", actual="
1063                   << method->GetDeclaringClass()->GetDescriptor(&temp)
1064                   << ")";
1065         return false;
1066       } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
1067         LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved method resolution "
1068                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1069                   << std::hex
1070                   << " (expected="
1071                   << entry.GetAccessFlags()
1072                   << ", actual="
1073                   << GetAccessFlags(method) << ")"
1074                   << std::dec;
1075         return false;
1076       }
1077     } else if (method != nullptr) {
1078       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of method "
1079                 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1080       return false;
1081     }
1082   }
1083   return true;
1084 }
1085 
VerifyDexFile(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const DexFileDeps & deps,Thread * self) const1086 bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
1087                                  const DexFile& dex_file,
1088                                  const DexFileDeps& deps,
1089                                  Thread* self) const {
1090   bool result = VerifyAssignability(
1091       class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
1092   result = result && VerifyAssignability(
1093       class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
1094 
1095   result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
1096   result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
1097 
1098   result = result && VerifyMethods(class_loader, dex_file, deps.methods_, self);
1099 
1100   return result;
1101 }
1102 
1103 }  // namespace verifier
1104 }  // namespace art
1105