blob: fefe5a3faa8ba71baf4907bc6b4ff19b370e69e4 [file] [log] [blame]
David Brazdilca3c8c32016-09-06 14:04:48 +01001/*
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
Mathieu Chartier32b50302016-11-17 13:08:35 -080019#include <cstring>
20
Nicolas Geoffray340dafa2016-11-18 16:03:10 +000021#include "base/stl_util.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010022#include "compiler_callbacks.h"
David Brazdil6f82fbd2016-09-14 11:55:26 +010023#include "leb128.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010024#include "mirror/class-inl.h"
Mathieu Chartier3398c782016-09-30 10:27:43 -070025#include "obj_ptr-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010026#include "runtime.h"
27
28namespace art {
29namespace verifier {
30
31VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files) {
David Brazdilca3c8c32016-09-06 14:04:48 +010032 for (const DexFile* dex_file : dex_files) {
33 DCHECK(GetDexFileDeps(*dex_file) == nullptr);
34 std::unique_ptr<DexFileDeps> deps(new DexFileDeps());
35 dex_deps_.emplace(dex_file, std::move(deps));
36 }
37}
38
Nicolas Geoffray340dafa2016-11-18 16:03:10 +000039void VerifierDeps::MergeWith(const VerifierDeps& other,
40 const std::vector<const DexFile*>& dex_files) {
41 DCHECK(dex_deps_.size() == other.dex_deps_.size());
42 for (const DexFile* dex_file : dex_files) {
43 DexFileDeps* my_deps = GetDexFileDeps(*dex_file);
44 const DexFileDeps& other_deps = *other.GetDexFileDeps(*dex_file);
45 // We currently collect extra strings only on the main `VerifierDeps`,
46 // which should be the one passed as `this` in this method.
47 DCHECK(other_deps.strings_.empty());
48 MergeSets(my_deps->assignable_types_, other_deps.assignable_types_);
49 MergeSets(my_deps->unassignable_types_, other_deps.unassignable_types_);
50 MergeSets(my_deps->classes_, other_deps.classes_);
51 MergeSets(my_deps->fields_, other_deps.fields_);
52 MergeSets(my_deps->direct_methods_, other_deps.direct_methods_);
53 MergeSets(my_deps->virtual_methods_, other_deps.virtual_methods_);
54 MergeSets(my_deps->interface_methods_, other_deps.interface_methods_);
55 for (dex::TypeIndex entry : other_deps.unverified_classes_) {
56 my_deps->unverified_classes_.push_back(entry);
57 }
58 }
59}
60
David Brazdilca3c8c32016-09-06 14:04:48 +010061VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) {
62 auto it = dex_deps_.find(&dex_file);
63 return (it == dex_deps_.end()) ? nullptr : it->second.get();
64}
65
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +010066const VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const {
67 auto it = dex_deps_.find(&dex_file);
68 return (it == dex_deps_.end()) ? nullptr : it->second.get();
69}
70
David Brazdilca3c8c32016-09-06 14:04:48 +010071template <typename T>
72uint16_t VerifierDeps::GetAccessFlags(T* element) {
73 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
74 if (element == nullptr) {
75 return VerifierDeps::kUnresolvedMarker;
76 } else {
77 uint16_t access_flags = Low16Bits(element->GetAccessFlags());
78 CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
79 return access_flags;
80 }
81}
82
Mathieu Chartier32b50302016-11-17 13:08:35 -080083uint32_t VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
84 ObjPtr<mirror::Class> klass) {
85 DCHECK(klass != nullptr);
86 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
87 // Array classes do not have a dex cache.
88 if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
89 DCHECK(dex_cache != nullptr) << klass->PrettyClass();
90 if (dex_cache->GetDexFile() == &dex_file) {
91 // FindStringId is slow, try to go through the class def if we have one.
92 const DexFile::ClassDef* class_def = klass->GetClassDef();
93 DCHECK(class_def != nullptr) << klass->PrettyClass();
94 std::string temp;
95 const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
96 DCHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
97 return type_id.descriptor_idx_;
98 }
99 }
100 std::string temp;
101 return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
102}
103
104// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
105static uint32_t TryGetClassDescriptorStringId(const DexFile& dex_file,
106 dex::TypeIndex type_idx,
107 ObjPtr<mirror::Class> klass)
108 REQUIRES_SHARED(Locks::mutator_lock_) {
109 if (!klass->IsArrayClass()) {
110 const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
111 const DexFile& klass_dex = klass->GetDexFile();
112 const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
113 if (strcmp(dex_file.GetTypeDescriptor(type_id),
114 klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
115 return type_id.descriptor_idx_;
116 }
117 }
118 return DexFile::kDexNoIndex;
119}
120
121uint32_t VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
122 uint32_t dex_method_index,
123 ArtMethod* method) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100124 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
Mathieu Chartier32b50302016-11-17 13:08:35 -0800125 if (method == nullptr) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100126 return VerifierDeps::kUnresolvedMarker;
Mathieu Chartier32b50302016-11-17 13:08:35 -0800127 }
128 const uint32_t string_id = TryGetClassDescriptorStringId(
129 dex_file,
130 dex_file.GetMethodId(dex_method_index).class_idx_,
131 method->GetDeclaringClass());
132 if (string_id != DexFile::kDexNoIndex) {
133 // Got lucky using the original dex file, return based on the input dex file.
134 DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
David Brazdilca3c8c32016-09-06 14:04:48 +0100135 return string_id;
136 }
Mathieu Chartier32b50302016-11-17 13:08:35 -0800137 return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
138}
139
140uint32_t VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
141 uint32_t dex_field_idx,
142 ArtField* field) {
143 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
144 if (field == nullptr) {
145 return VerifierDeps::kUnresolvedMarker;
146 }
147 const uint32_t string_id = TryGetClassDescriptorStringId(
148 dex_file,
149 dex_file.GetFieldId(dex_field_idx).class_idx_,
150 field->GetDeclaringClass());
151 if (string_id != DexFile::kDexNoIndex) {
152 // Got lucky using the original dex file, return based on the input dex file.
153 DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
154 return string_id;
155 }
156 return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
David Brazdilca3c8c32016-09-06 14:04:48 +0100157}
158
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000159static inline VerifierDeps* GetMainVerifierDeps() {
160 // The main VerifierDeps is the one set in the compiler callbacks, which at the
161 // end of verification will have all the per-thread VerifierDeps merged into it.
162 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
163 if (callbacks == nullptr) {
164 return nullptr;
165 }
166 return callbacks->GetVerifierDeps();
167}
168
169static inline VerifierDeps* GetThreadLocalVerifierDeps() {
170 // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
171 // of full verification, these VerifierDeps will be merged into the main one.
172 if (!Runtime::Current()->IsAotCompiler()) {
173 return nullptr;
174 }
175 return Thread::Current()->GetVerifierDeps();
176}
177
178static bool FindExistingStringId(const std::vector<std::string>& strings,
179 const std::string& str,
180 uint32_t* found_id) {
181 uint32_t num_extra_ids = strings.size();
182 for (size_t i = 0; i < num_extra_ids; ++i) {
183 if (strings[i] == str) {
184 *found_id = i;
185 return true;
186 }
187 }
188 return false;
189}
190
David Brazdilca3c8c32016-09-06 14:04:48 +0100191uint32_t VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
192 const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
193 if (string_id != nullptr) {
194 // String is in the DEX file. Return its ID.
195 return dex_file.GetIndexForStringId(*string_id);
196 }
197
198 // String is not in the DEX file. Assign a new ID to it which is higher than
199 // the number of strings in the DEX file.
200
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000201 // We use the main `VerifierDeps` for adding new strings to simplify
202 // synchronization/merging of these entries between threads.
203 VerifierDeps* singleton = GetMainVerifierDeps();
204 DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100205 DCHECK(deps != nullptr);
206
207 uint32_t num_ids_in_dex = dex_file.NumStringIds();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000208 uint32_t found_id;
David Brazdilca3c8c32016-09-06 14:04:48 +0100209
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000210 {
211 ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
212 if (FindExistingStringId(deps->strings_, str, &found_id)) {
213 return num_ids_in_dex + found_id;
David Brazdilca3c8c32016-09-06 14:04:48 +0100214 }
215 }
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000216 {
217 WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
218 if (FindExistingStringId(deps->strings_, str, &found_id)) {
219 return num_ids_in_dex + found_id;
220 }
221 deps->strings_.push_back(str);
222 uint32_t new_id = num_ids_in_dex + deps->strings_.size() - 1;
223 CHECK_GE(new_id, num_ids_in_dex); // check for overflows
224 DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
225 return new_id;
226 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100227}
228
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100229std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, uint32_t string_id) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100230 uint32_t num_ids_in_dex = dex_file.NumStringIds();
231 if (string_id < num_ids_in_dex) {
232 return std::string(dex_file.StringDataByIdx(string_id));
233 } else {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100234 const DexFileDeps* deps = GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100235 DCHECK(deps != nullptr);
236 string_id -= num_ids_in_dex;
237 CHECK_LT(string_id, deps->strings_.size());
238 return deps->strings_[string_id];
239 }
240}
241
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100242bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100243 DCHECK(klass != nullptr);
244
Mathieu Chartier3398c782016-09-30 10:27:43 -0700245 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
David Brazdilca3c8c32016-09-06 14:04:48 +0100246 if (dex_cache == nullptr) {
247 // This is a synthesized class, in this case always an array. They are not
248 // defined in the compiled DEX files and therefore are part of the classpath.
249 // We could avoid recording dependencies on arrays with component types in
250 // the compiled DEX files but we choose to record them anyway so as to
251 // record the access flags VM sets for array classes.
David Sehr709b0702016-10-13 09:12:37 -0700252 DCHECK(klass->IsArrayClass()) << klass->PrettyDescriptor();
David Brazdilca3c8c32016-09-06 14:04:48 +0100253 return true;
254 }
255
256 const DexFile* dex_file = dex_cache->GetDexFile();
257 DCHECK(dex_file != nullptr);
258
259 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
260 // file was not registered as being compiled and we assume `klass` is in the
261 // classpath.
262 return (GetDexFileDeps(*dex_file) == nullptr);
263}
264
265void VerifierDeps::AddClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800266 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100267 mirror::Class* klass) {
268 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
269 if (dex_deps == nullptr) {
270 // This invocation is from verification of a dex file which is not being compiled.
271 return;
272 }
273
274 if (klass != nullptr && !IsInClassPath(klass)) {
275 // Class resolved into one of the DEX files which are being compiled.
276 // This is not a classpath dependency.
277 return;
278 }
279
David Brazdilca3c8c32016-09-06 14:04:48 +0100280 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
281}
282
283void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
284 uint32_t field_idx,
285 ArtField* field) {
286 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
287 if (dex_deps == nullptr) {
288 // This invocation is from verification of a dex file which is not being compiled.
289 return;
290 }
291
292 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
293 // Field resolved into one of the DEX files which are being compiled.
294 // This is not a classpath dependency.
295 return;
296 }
297
Mathieu Chartier32b50302016-11-17 13:08:35 -0800298 dex_deps->fields_.emplace(FieldResolution(field_idx,
299 GetAccessFlags(field),
300 GetFieldDeclaringClassStringId(dex_file,
301 field_idx,
302 field)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100303}
304
305void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
306 uint32_t method_idx,
307 MethodResolutionKind resolution_kind,
308 ArtMethod* method) {
309 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
310 if (dex_deps == nullptr) {
311 // This invocation is from verification of a dex file which is not being compiled.
312 return;
313 }
314
315 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
316 // Method resolved into one of the DEX files which are being compiled.
317 // This is not a classpath dependency.
318 return;
319 }
320
David Brazdilca3c8c32016-09-06 14:04:48 +0100321 MethodResolution method_tuple(method_idx,
322 GetAccessFlags(method),
Mathieu Chartier32b50302016-11-17 13:08:35 -0800323 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
David Brazdilca3c8c32016-09-06 14:04:48 +0100324 if (resolution_kind == kDirectMethodResolution) {
325 dex_deps->direct_methods_.emplace(method_tuple);
326 } else if (resolution_kind == kVirtualMethodResolution) {
327 dex_deps->virtual_methods_.emplace(method_tuple);
328 } else {
329 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
330 dex_deps->interface_methods_.emplace(method_tuple);
331 }
332}
333
334void VerifierDeps::AddAssignability(const DexFile& dex_file,
335 mirror::Class* destination,
336 mirror::Class* source,
337 bool is_strict,
338 bool is_assignable) {
339 // Test that the method is only called on reference types.
340 // Note that concurrent verification of `destination` and `source` may have
341 // set their status to erroneous. However, the tests performed below rely
342 // merely on no issues with linking (valid access flags, superclass and
343 // implemented interfaces). If the class at any point reached the IsResolved
344 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
345 DCHECK(destination != nullptr && !destination->IsPrimitive());
346 DCHECK(source != nullptr && !source->IsPrimitive());
347
348 if (destination == source ||
349 destination->IsObjectClass() ||
350 (!is_strict && destination->IsInterface())) {
351 // Cases when `destination` is trivially assignable from `source`.
352 DCHECK(is_assignable);
353 return;
354 }
355
356 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
357
358 if (destination->IsArrayClass() && source->IsArrayClass()) {
359 // Both types are arrays. Break down to component types and add recursively.
360 // This helps filter out destinations from compiled DEX files (see below)
361 // and deduplicate entries with the same canonical component type.
362 mirror::Class* destination_component = destination->GetComponentType();
363 mirror::Class* source_component = source->GetComponentType();
364
365 // Only perform the optimization if both types are resolved which guarantees
366 // that they linked successfully, as required at the top of this method.
367 if (destination_component->IsResolved() && source_component->IsResolved()) {
368 AddAssignability(dex_file,
369 destination_component,
370 source_component,
371 /* is_strict */ true,
372 is_assignable);
373 return;
374 }
375 }
376
377 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
378 if (dex_deps == nullptr) {
379 // This invocation is from verification of a DEX file which is not being compiled.
380 return;
381 }
382
383 if (!IsInClassPath(destination) && !IsInClassPath(source)) {
384 // Both `destination` and `source` are defined in the compiled DEX files.
385 // No need to record a dependency.
386 return;
387 }
388
David Brazdilca3c8c32016-09-06 14:04:48 +0100389 // Get string IDs for both descriptors and store in the appropriate set.
Mathieu Chartier32b50302016-11-17 13:08:35 -0800390 uint32_t destination_id = GetClassDescriptorStringId(dex_file, destination);
391 uint32_t source_id = GetClassDescriptorStringId(dex_file, source);
David Brazdilca3c8c32016-09-06 14:04:48 +0100392
393 if (is_assignable) {
394 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
395 } else {
396 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
397 }
398}
399
Nicolas Geoffray08025182016-10-25 17:20:18 +0100400void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800401 dex::TypeIndex type_idx,
Nicolas Geoffray08025182016-10-25 17:20:18 +0100402 MethodVerifier::FailureKind failure_kind) {
403 if (failure_kind == MethodVerifier::kNoFailure) {
404 // We only record classes that did not fully verify at compile time.
405 return;
406 }
407
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000408 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
409 if (thread_deps != nullptr) {
410 DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100411 dex_deps->unverified_classes_.push_back(type_idx);
412 }
413}
414
David Brazdilca3c8c32016-09-06 14:04:48 +0100415void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800416 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100417 mirror::Class* klass) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000418 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
419 if (thread_deps != nullptr) {
420 thread_deps->AddClassResolution(dex_file, type_idx, klass);
David Brazdilca3c8c32016-09-06 14:04:48 +0100421 }
422}
423
424void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
425 uint32_t field_idx,
426 ArtField* field) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000427 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
428 if (thread_deps != nullptr) {
429 thread_deps->AddFieldResolution(dex_file, field_idx, field);
David Brazdilca3c8c32016-09-06 14:04:48 +0100430 }
431}
432
433void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
434 uint32_t method_idx,
435 MethodResolutionKind resolution_kind,
436 ArtMethod* method) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000437 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
438 if (thread_deps != nullptr) {
439 thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
David Brazdilca3c8c32016-09-06 14:04:48 +0100440 }
441}
442
443void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
444 mirror::Class* destination,
445 mirror::Class* source,
446 bool is_strict,
447 bool is_assignable) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000448 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
449 if (thread_deps != nullptr) {
450 thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
David Brazdilca3c8c32016-09-06 14:04:48 +0100451 }
452}
453
Andreas Gampea5b09a62016-11-17 15:21:22 -0800454namespace {
455
David Brazdil6f82fbd2016-09-14 11:55:26 +0100456static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
457 CHECK_LT(*in, end);
458 return DecodeUnsignedLeb128(in);
459}
460
Andreas Gampea5b09a62016-11-17 15:21:22 -0800461template<typename T> inline uint32_t Encode(T in);
462
463template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
464 return in;
465}
466template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
467 return in;
468}
469template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
470 return in.index_;
471}
472
473template<typename T> inline T Decode(uint32_t in);
474
475template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
476 return dchecked_integral_cast<uint16_t>(in);
477}
478template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
479 return in;
480}
481template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
482 return dex::TypeIndex(in);
483}
484
David Brazdil6f82fbd2016-09-14 11:55:26 +0100485template<typename T1, typename T2>
486static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800487 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
488 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100489}
490
491template<typename T1, typename T2>
492static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800493 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
494 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100495 *t = std::make_tuple(v1, v2);
496}
497
498template<typename T1, typename T2, typename T3>
499static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800500 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
501 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
502 EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100503}
504
505template<typename T1, typename T2, typename T3>
506static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800507 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
508 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
509 T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100510 *t = std::make_tuple(v1, v2, v3);
511}
512
513template<typename T>
514static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
515 EncodeUnsignedLeb128(out, set.size());
516 for (const T& entry : set) {
517 EncodeTuple(out, entry);
518 }
519}
520
Andreas Gampea5b09a62016-11-17 15:21:22 -0800521template <typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100522static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800523 const std::vector<T>& vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100524 EncodeUnsignedLeb128(out, vector.size());
Andreas Gampea5b09a62016-11-17 15:21:22 -0800525 for (const T& entry : vector) {
526 EncodeUnsignedLeb128(out, Encode(entry));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100527 }
528}
529
David Brazdil6f82fbd2016-09-14 11:55:26 +0100530template<typename T>
531static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
532 DCHECK(set->empty());
533 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
534 for (size_t i = 0; i < num_entries; ++i) {
535 T tuple;
536 DecodeTuple(in, end, &tuple);
537 set->emplace(tuple);
538 }
539}
540
Andreas Gampea5b09a62016-11-17 15:21:22 -0800541template<typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100542static inline void DecodeUint16Vector(const uint8_t** in,
543 const uint8_t* end,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800544 std::vector<T>* vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100545 DCHECK(vector->empty());
546 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
547 vector->reserve(num_entries);
548 for (size_t i = 0; i < num_entries; ++i) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800549 vector->push_back(
550 Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100551 }
552}
553
David Brazdil6f82fbd2016-09-14 11:55:26 +0100554static inline void EncodeStringVector(std::vector<uint8_t>* out,
555 const std::vector<std::string>& strings) {
556 EncodeUnsignedLeb128(out, strings.size());
557 for (const std::string& str : strings) {
558 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
559 size_t length = str.length() + 1;
560 out->insert(out->end(), data, data + length);
561 DCHECK_EQ(0u, out->back());
562 }
563}
564
565static inline void DecodeStringVector(const uint8_t** in,
566 const uint8_t* end,
567 std::vector<std::string>* strings) {
568 DCHECK(strings->empty());
569 size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
570 strings->reserve(num_strings);
571 for (size_t i = 0; i < num_strings; ++i) {
572 CHECK_LT(*in, end);
573 const char* string_start = reinterpret_cast<const char*>(*in);
574 strings->emplace_back(std::string(string_start));
575 *in += strings->back().length() + 1;
576 }
577}
578
Andreas Gampea5b09a62016-11-17 15:21:22 -0800579} // namespace
580
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100581void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
582 std::vector<uint8_t>* buffer) const {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100583 for (const DexFile* dex_file : dex_files) {
584 const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
585 EncodeStringVector(buffer, deps.strings_);
586 EncodeSet(buffer, deps.assignable_types_);
587 EncodeSet(buffer, deps.unassignable_types_);
588 EncodeSet(buffer, deps.classes_);
589 EncodeSet(buffer, deps.fields_);
590 EncodeSet(buffer, deps.direct_methods_);
591 EncodeSet(buffer, deps.virtual_methods_);
592 EncodeSet(buffer, deps.interface_methods_);
593 EncodeUint16Vector(buffer, deps.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100594 }
595}
596
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000597VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
598 ArrayRef<const uint8_t> data)
David Brazdil6f82fbd2016-09-14 11:55:26 +0100599 : VerifierDeps(dex_files) {
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000600 if (data.empty()) {
601 // Return eagerly, as the first thing we expect from VerifierDeps data is
602 // the number of created strings, even if there is no dependency.
603 // Currently, only the boot image does not have any VerifierDeps data.
604 return;
605 }
David Brazdil6f82fbd2016-09-14 11:55:26 +0100606 const uint8_t* data_start = data.data();
607 const uint8_t* data_end = data_start + data.size();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100608 for (const DexFile* dex_file : dex_files) {
609 DexFileDeps* deps = GetDexFileDeps(*dex_file);
610 DecodeStringVector(&data_start, data_end, &deps->strings_);
611 DecodeSet(&data_start, data_end, &deps->assignable_types_);
612 DecodeSet(&data_start, data_end, &deps->unassignable_types_);
613 DecodeSet(&data_start, data_end, &deps->classes_);
614 DecodeSet(&data_start, data_end, &deps->fields_);
615 DecodeSet(&data_start, data_end, &deps->direct_methods_);
616 DecodeSet(&data_start, data_end, &deps->virtual_methods_);
617 DecodeSet(&data_start, data_end, &deps->interface_methods_);
618 DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100619 }
620 CHECK_LE(data_start, data_end);
621}
622
623bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100624 if (dex_deps_.size() != rhs.dex_deps_.size()) {
625 return false;
626 }
627
628 auto lhs_it = dex_deps_.begin();
629 auto rhs_it = rhs.dex_deps_.begin();
630
631 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
632 const DexFile* lhs_dex_file = lhs_it->first;
633 const DexFile* rhs_dex_file = rhs_it->first;
634 if (lhs_dex_file != rhs_dex_file) {
635 return false;
636 }
637
638 DexFileDeps* lhs_deps = lhs_it->second.get();
639 DexFileDeps* rhs_deps = rhs_it->second.get();
640 if (!lhs_deps->Equals(*rhs_deps)) {
641 return false;
642 }
643 }
644
645 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
646 return true;
647}
648
649bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
650 return (strings_ == rhs.strings_) &&
651 (assignable_types_ == rhs.assignable_types_) &&
652 (unassignable_types_ == rhs.unassignable_types_) &&
653 (classes_ == rhs.classes_) &&
654 (fields_ == rhs.fields_) &&
655 (direct_methods_ == rhs.direct_methods_) &&
656 (virtual_methods_ == rhs.virtual_methods_) &&
Nicolas Geoffray08025182016-10-25 17:20:18 +0100657 (interface_methods_ == rhs.interface_methods_) &&
658 (unverified_classes_ == rhs.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100659}
660
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100661void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
662 for (const auto& dep : dex_deps_) {
663 const DexFile& dex_file = *dep.first;
664 vios->Stream()
665 << "Dependencies of "
666 << dex_file.GetLocation()
667 << ":\n";
668
669 ScopedIndentation indent(vios);
670
671 for (const std::string& str : dep.second->strings_) {
672 vios->Stream() << "Extra string: " << str << "\n";
673 }
674
675 for (const TypeAssignability& entry : dep.second->assignable_types_) {
676 vios->Stream()
677 << GetStringFromId(dex_file, entry.GetSource())
678 << " must be assignable to "
679 << GetStringFromId(dex_file, entry.GetDestination())
680 << "\n";
681 }
682
683 for (const TypeAssignability& entry : dep.second->unassignable_types_) {
684 vios->Stream()
685 << GetStringFromId(dex_file, entry.GetSource())
686 << " must not be assignable to "
687 << GetStringFromId(dex_file, entry.GetDestination())
688 << "\n";
689 }
690
691 for (const ClassResolution& entry : dep.second->classes_) {
692 vios->Stream()
693 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
694 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
695 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
696 << "\n";
697 }
698
699 for (const FieldResolution& entry : dep.second->fields_) {
700 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
701 vios->Stream()
702 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
703 << dex_file.GetFieldName(field_id) << ":"
704 << dex_file.GetFieldTypeDescriptor(field_id)
705 << " is expected to be ";
706 if (!entry.IsResolved()) {
707 vios->Stream() << "unresolved\n";
708 } else {
709 vios->Stream()
710 << "in class "
711 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
712 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
713 << "\n";
714 }
715 }
716
717 for (const auto& entry :
718 { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
719 std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
720 std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
721 for (const MethodResolution& method : entry.second) {
722 const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
723 vios->Stream()
724 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
725 << dex_file.GetMethodName(method_id)
726 << dex_file.GetMethodSignature(method_id).ToString()
727 << " is expected to be ";
728 if (!method.IsResolved()) {
729 vios->Stream() << "unresolved\n";
730 } else {
731 vios->Stream()
732 << "in class "
733 << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
734 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
735 << ", and be of kind " << entry.first
736 << "\n";
737 }
738 }
739 }
740
Andreas Gampea5b09a62016-11-17 15:21:22 -0800741 for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100742 vios->Stream()
743 << dex_file.StringByTypeIdx(type_index)
744 << " is expected to be verified at runtime\n";
745 }
746 }
747}
748
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000749bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
750 Thread* self) const {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100751 for (const auto& entry : dex_deps_) {
752 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
753 return false;
754 }
755 }
756 return true;
757}
758
759// TODO: share that helper with other parts of the compiler that have
760// the same lookup pattern.
761static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
762 Thread* self,
763 const char* name,
764 Handle<mirror::ClassLoader> class_loader)
765 REQUIRES_SHARED(Locks::mutator_lock_) {
766 mirror::Class* result = class_linker->FindClass(self, name, class_loader);
767 if (result == nullptr) {
768 DCHECK(self->IsExceptionPending());
769 self->ClearException();
770 }
771 return result;
772}
773
774bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
775 const DexFile& dex_file,
776 const std::set<TypeAssignability>& assignables,
777 bool expected_assignability,
778 Thread* self) const {
779 StackHandleScope<2> hs(self);
780 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
781 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
782 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
783
784 for (const auto& entry : assignables) {
785 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
786 destination.Assign(
787 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
788 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
789 source.Assign(
790 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
791
792 if (destination.Get() == nullptr) {
793 LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
794 return false;
795 }
796
797 if (source.Get() == nullptr) {
798 LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
799 return false;
800 }
801
802 DCHECK(destination->IsResolved() && source->IsResolved());
803 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
804 LOG(INFO) << "VerifierDeps: Class "
805 << destination_desc
806 << (expected_assignability ? " not " : " ")
807 << "assignable from "
808 << source_desc;
809 return false;
810 }
811 }
812 return true;
813}
814
815bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
816 const DexFile& dex_file,
817 const std::set<ClassResolution>& classes,
818 Thread* self) const {
819 StackHandleScope<1> hs(self);
820 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
821 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
822 for (const auto& entry : classes) {
823 const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
824 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
825
826 if (entry.IsResolved()) {
827 if (cls.Get() == nullptr) {
828 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
829 return false;
830 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
831 LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
832 << descriptor
833 << std::hex
834 << " (expected="
835 << entry.GetAccessFlags()
836 << ", actual="
837 << GetAccessFlags(cls.Get()) << ")"
838 << std::dec;
839 return false;
840 }
841 } else if (cls.Get() != nullptr) {
842 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
843 return false;
844 }
845 }
846 return true;
847}
848
849static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
850 const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
851 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
852 + "->"
853 + dex_file.GetFieldName(field_id)
854 + ":"
855 + dex_file.GetFieldTypeDescriptor(field_id);
856}
857
858bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
859 const DexFile& dex_file,
860 const std::set<FieldResolution>& fields,
861 Thread* self) const {
862 // Check recorded fields are resolved the same way, have the same recorded class,
863 // and have the same recorded flags.
864 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
865 StackHandleScope<1> hs(self);
866 Handle<mirror::DexCache> dex_cache(
867 hs.NewHandle(class_linker->FindDexCache(self, dex_file, /* allow_failure */ false)));
868 for (const auto& entry : fields) {
869 ArtField* field = class_linker->ResolveFieldJLS(
870 dex_file, entry.GetDexFieldIndex(), dex_cache, class_loader);
871
872 if (field == nullptr) {
873 DCHECK(self->IsExceptionPending());
874 self->ClearException();
875 }
876
877 if (entry.IsResolved()) {
878 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
879 std::string temp;
880 if (field == nullptr) {
881 LOG(INFO) << "VerifierDeps: Could not resolve field "
882 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
883 return false;
884 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
885 LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
886 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
887 << " (expected=" << expected_decl_klass
888 << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
889 return false;
890 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
891 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
892 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
893 << std::hex << " (expected=" << entry.GetAccessFlags()
894 << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
895 return false;
896 }
897 } else if (field != nullptr) {
898 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
899 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
900 return false;
901 }
902 }
903 return true;
904}
905
906static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
907 const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
908 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
909 + "->"
910 + dex_file.GetMethodName(method_id)
911 + dex_file.GetMethodSignature(method_id).ToString();
912}
913
914bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
915 const DexFile& dex_file,
916 const std::set<MethodResolution>& methods,
917 MethodResolutionKind kind,
918 Thread* self) const {
919 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
920 PointerSize pointer_size = class_linker->GetImagePointerSize();
921
922 for (const auto& entry : methods) {
923 const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
924
925 const char* name = dex_file.GetMethodName(method_id);
926 const Signature signature = dex_file.GetMethodSignature(method_id);
927 const char* descriptor = dex_file.GetMethodDeclaringClassDescriptor(method_id);
928
929 mirror::Class* cls = FindClassAndClearException(class_linker, self, descriptor, class_loader);
930 if (cls == nullptr) {
931 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
932 return false;
933 }
934 DCHECK(cls->IsResolved());
935 ArtMethod* method = nullptr;
936 if (kind == kDirectMethodResolution) {
937 method = cls->FindDirectMethod(name, signature, pointer_size);
938 } else if (kind == kVirtualMethodResolution) {
939 method = cls->FindVirtualMethod(name, signature, pointer_size);
940 } else {
941 DCHECK_EQ(kind, kInterfaceMethodResolution);
942 method = cls->FindInterfaceMethod(name, signature, pointer_size);
943 }
944
945 if (entry.IsResolved()) {
946 std::string temp;
947 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
948 if (method == nullptr) {
949 LOG(INFO) << "VerifierDeps: Could not resolve "
950 << kind
951 << " method "
952 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
953 return false;
954 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
955 LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
956 << kind
957 << " method resolution "
958 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
959 << " (expected="
960 << expected_decl_klass
961 << ", actual="
962 << method->GetDeclaringClass()->GetDescriptor(&temp)
963 << ")";
964 return false;
965 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
966 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
967 << kind
968 << " method resolution "
969 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
970 << std::hex
971 << " (expected="
972 << entry.GetAccessFlags()
973 << ", actual="
974 << GetAccessFlags(method) << ")"
975 << std::dec;
976 return false;
977 }
978 } else if (method != nullptr) {
979 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
980 << kind
981 << " method "
982 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
983 return false;
984 }
985 }
986 return true;
987}
988
989bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
990 const DexFile& dex_file,
991 const DexFileDeps& deps,
992 Thread* self) const {
993 bool result = VerifyAssignability(
994 class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
995 result = result && VerifyAssignability(
996 class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
997
998 result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
999 result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
1000
1001 result = result && VerifyMethods(
1002 class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
1003 result = result && VerifyMethods(
1004 class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
1005 result = result && VerifyMethods(
1006 class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
1007
1008 return result;
1009}
1010
David Brazdilca3c8c32016-09-06 14:04:48 +01001011} // namespace verifier
1012} // namespace art