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)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
MergeWith(const VerifierDeps & other,const std::vector<const DexFile * > & dex_files)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
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,MethodResolutionKind resolution_kind,ArtMethod * method)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
FindOneClassPathBoundaryForInterface(mirror::Class * destination,mirror::Class * source) const347 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
AddAssignability(const DexFile & dex_file,mirror::Class * destination,mirror::Class * source,bool is_strict,bool is_assignable)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
MaybeRecordVerificationStatus(const DexFile & dex_file,dex::TypeIndex type_idx,FailureKind failure_kind)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
MaybeRecordClassResolution(const DexFile & dex_file,dex::TypeIndex type_idx,mirror::Class * klass)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
MaybeRecordFieldResolution(const DexFile & dex_file,uint32_t field_idx,ArtField * field)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
MaybeRecordMethodResolution(const DexFile & dex_file,uint32_t method_idx,MethodResolutionKind resolution_kind,ArtMethod * method)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
MaybeRecordAssignability(const DexFile & dex_file,mirror::Class * destination,mirror::Class * source,bool is_strict,bool is_assignable)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
DecodeUint32WithOverflowCheck(const uint8_t ** in,const uint8_t * end)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
Encode(uint16_t in)568 template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
569 return in;
570 }
Encode(uint32_t in)571 template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
572 return in;
573 }
Encode(dex::TypeIndex in)574 template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
575 return in.index_;
576 }
Encode(dex::StringIndex in)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
Decode(uint32_t in)583 template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
584 return dchecked_integral_cast<uint16_t>(in);
585 }
Decode(uint32_t in)586 template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
587 return in;
588 }
Decode(uint32_t in)589 template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
590 return dex::TypeIndex(in);
591 }
Decode(uint32_t in)592 template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
593 return dex::StringIndex(in);
594 }
595
596 template<typename T1, typename T2>
EncodeTuple(std::vector<uint8_t> * out,const std::tuple<T1,T2> & t)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>
DecodeTuple(const uint8_t ** in,const uint8_t * end,std::tuple<T1,T2> * t)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>
EncodeTuple(std::vector<uint8_t> * out,const std::tuple<T1,T2,T3> & t)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>
DecodeTuple(const uint8_t ** in,const uint8_t * end,std::tuple<T1,T2,T3> * t)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>
EncodeSet(std::vector<uint8_t> * out,const std::set<T> & set)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>
EncodeUint16Vector(std::vector<uint8_t> * out,const std::vector<T> & vector)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>
DecodeSet(const uint8_t ** in,const uint8_t * end,std::set<T> * set)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>
DecodeUint16Vector(const uint8_t ** in,const uint8_t * end,std::vector<T> * vector)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
EncodeStringVector(std::vector<uint8_t> * out,const std::vector<std::string> & strings)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
DecodeStringVector(const uint8_t ** in,const uint8_t * end,std::vector<std::string> * strings)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
Encode(const std::vector<const DexFile * > & dex_files,std::vector<uint8_t> * buffer) const692 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
VerifierDeps(const std::vector<const DexFile * > & dex_files,ArrayRef<const uint8_t> data)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
Equals(const VerifierDeps & rhs) const734 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
Equals(const VerifierDeps::DexFileDeps & rhs) const760 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
Dump(VariableIndentationOutputStream * vios) const772 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
ValidateDependencies(Handle<mirror::ClassLoader> class_loader,Thread * self) const860 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.
FindClassAndClearException(ClassLinker * class_linker,Thread * self,const char * name,Handle<mirror::ClassLoader> class_loader)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
VerifyAssignability(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<TypeAssignability> & assignables,bool expected_assignability,Thread * self) const885 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
VerifyClasses(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<ClassResolution> & classes,Thread * self) const926 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
GetFieldDescription(const DexFile & dex_file,uint32_t index)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
VerifyFields(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<FieldResolution> & fields,Thread * self) const969 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
GetMethodDescription(const DexFile & dex_file,uint32_t index)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
VerifyMethods(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const std::set<MethodResolution> & methods,MethodResolutionKind kind,Thread * self) const1030 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
VerifyDexFile(Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const DexFileDeps & deps,Thread * self) const1109 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