blob: 01af5ec00ab5bb71e8eff759d96269451490adcb [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();
Mathieu Chartierfc2dd612016-11-21 15:05:23 -080087 // Array and proxy classes do not have a dex cache.
Mathieu Chartier32b50302016-11-17 13:08:35 -080088 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();
Mathieu Chartier32b50302016-11-17 13:08:35 -080094 const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
Mathieu Chartierfc2dd612016-11-21 15:05:23 -080095 if (kIsDebugBuild) {
96 std::string temp;
97 CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
98 }
Mathieu Chartier32b50302016-11-17 13:08:35 -080099 return type_id.descriptor_idx_;
100 }
101 }
102 std::string temp;
103 return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
104}
105
106// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
107static uint32_t TryGetClassDescriptorStringId(const DexFile& dex_file,
108 dex::TypeIndex type_idx,
109 ObjPtr<mirror::Class> klass)
110 REQUIRES_SHARED(Locks::mutator_lock_) {
111 if (!klass->IsArrayClass()) {
112 const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
113 const DexFile& klass_dex = klass->GetDexFile();
114 const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
115 if (strcmp(dex_file.GetTypeDescriptor(type_id),
116 klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
117 return type_id.descriptor_idx_;
118 }
119 }
120 return DexFile::kDexNoIndex;
121}
122
123uint32_t VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
124 uint32_t dex_method_index,
125 ArtMethod* method) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100126 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
Mathieu Chartier32b50302016-11-17 13:08:35 -0800127 if (method == nullptr) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100128 return VerifierDeps::kUnresolvedMarker;
Mathieu Chartier32b50302016-11-17 13:08:35 -0800129 }
130 const uint32_t string_id = TryGetClassDescriptorStringId(
131 dex_file,
132 dex_file.GetMethodId(dex_method_index).class_idx_,
133 method->GetDeclaringClass());
134 if (string_id != DexFile::kDexNoIndex) {
135 // Got lucky using the original dex file, return based on the input dex file.
136 DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
David Brazdilca3c8c32016-09-06 14:04:48 +0100137 return string_id;
138 }
Mathieu Chartier32b50302016-11-17 13:08:35 -0800139 return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
140}
141
142uint32_t VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
143 uint32_t dex_field_idx,
144 ArtField* field) {
145 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
146 if (field == nullptr) {
147 return VerifierDeps::kUnresolvedMarker;
148 }
149 const uint32_t string_id = TryGetClassDescriptorStringId(
150 dex_file,
151 dex_file.GetFieldId(dex_field_idx).class_idx_,
152 field->GetDeclaringClass());
153 if (string_id != DexFile::kDexNoIndex) {
154 // Got lucky using the original dex file, return based on the input dex file.
155 DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
156 return string_id;
157 }
158 return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
David Brazdilca3c8c32016-09-06 14:04:48 +0100159}
160
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000161static inline VerifierDeps* GetMainVerifierDeps() {
162 // The main VerifierDeps is the one set in the compiler callbacks, which at the
163 // end of verification will have all the per-thread VerifierDeps merged into it.
164 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
165 if (callbacks == nullptr) {
166 return nullptr;
167 }
168 return callbacks->GetVerifierDeps();
169}
170
171static inline VerifierDeps* GetThreadLocalVerifierDeps() {
172 // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
173 // of full verification, these VerifierDeps will be merged into the main one.
174 if (!Runtime::Current()->IsAotCompiler()) {
175 return nullptr;
176 }
177 return Thread::Current()->GetVerifierDeps();
178}
179
180static bool FindExistingStringId(const std::vector<std::string>& strings,
181 const std::string& str,
182 uint32_t* found_id) {
183 uint32_t num_extra_ids = strings.size();
184 for (size_t i = 0; i < num_extra_ids; ++i) {
185 if (strings[i] == str) {
186 *found_id = i;
187 return true;
188 }
189 }
190 return false;
191}
192
David Brazdilca3c8c32016-09-06 14:04:48 +0100193uint32_t VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
194 const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
195 if (string_id != nullptr) {
196 // String is in the DEX file. Return its ID.
197 return dex_file.GetIndexForStringId(*string_id);
198 }
199
200 // String is not in the DEX file. Assign a new ID to it which is higher than
201 // the number of strings in the DEX file.
202
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000203 // We use the main `VerifierDeps` for adding new strings to simplify
204 // synchronization/merging of these entries between threads.
205 VerifierDeps* singleton = GetMainVerifierDeps();
206 DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100207 DCHECK(deps != nullptr);
208
209 uint32_t num_ids_in_dex = dex_file.NumStringIds();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000210 uint32_t found_id;
David Brazdilca3c8c32016-09-06 14:04:48 +0100211
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000212 {
213 ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
214 if (FindExistingStringId(deps->strings_, str, &found_id)) {
215 return num_ids_in_dex + found_id;
David Brazdilca3c8c32016-09-06 14:04:48 +0100216 }
217 }
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000218 {
219 WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
220 if (FindExistingStringId(deps->strings_, str, &found_id)) {
221 return num_ids_in_dex + found_id;
222 }
223 deps->strings_.push_back(str);
224 uint32_t new_id = num_ids_in_dex + deps->strings_.size() - 1;
225 CHECK_GE(new_id, num_ids_in_dex); // check for overflows
226 DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
227 return new_id;
228 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100229}
230
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100231std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, uint32_t string_id) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100232 uint32_t num_ids_in_dex = dex_file.NumStringIds();
233 if (string_id < num_ids_in_dex) {
234 return std::string(dex_file.StringDataByIdx(string_id));
235 } else {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100236 const DexFileDeps* deps = GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100237 DCHECK(deps != nullptr);
238 string_id -= num_ids_in_dex;
239 CHECK_LT(string_id, deps->strings_.size());
240 return deps->strings_[string_id];
241 }
242}
243
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100244bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100245 DCHECK(klass != nullptr);
246
Mathieu Chartier3398c782016-09-30 10:27:43 -0700247 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
David Brazdilca3c8c32016-09-06 14:04:48 +0100248 if (dex_cache == nullptr) {
249 // This is a synthesized class, in this case always an array. They are not
250 // defined in the compiled DEX files and therefore are part of the classpath.
251 // We could avoid recording dependencies on arrays with component types in
252 // the compiled DEX files but we choose to record them anyway so as to
253 // record the access flags VM sets for array classes.
David Sehr709b0702016-10-13 09:12:37 -0700254 DCHECK(klass->IsArrayClass()) << klass->PrettyDescriptor();
David Brazdilca3c8c32016-09-06 14:04:48 +0100255 return true;
256 }
257
258 const DexFile* dex_file = dex_cache->GetDexFile();
259 DCHECK(dex_file != nullptr);
260
261 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
262 // file was not registered as being compiled and we assume `klass` is in the
263 // classpath.
264 return (GetDexFileDeps(*dex_file) == nullptr);
265}
266
267void VerifierDeps::AddClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800268 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100269 mirror::Class* klass) {
270 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
271 if (dex_deps == nullptr) {
272 // This invocation is from verification of a dex file which is not being compiled.
273 return;
274 }
275
276 if (klass != nullptr && !IsInClassPath(klass)) {
277 // Class resolved into one of the DEX files which are being compiled.
278 // This is not a classpath dependency.
279 return;
280 }
281
David Brazdilca3c8c32016-09-06 14:04:48 +0100282 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
283}
284
285void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
286 uint32_t field_idx,
287 ArtField* field) {
288 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
289 if (dex_deps == nullptr) {
290 // This invocation is from verification of a dex file which is not being compiled.
291 return;
292 }
293
294 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
295 // Field resolved into one of the DEX files which are being compiled.
296 // This is not a classpath dependency.
297 return;
298 }
299
Mathieu Chartier32b50302016-11-17 13:08:35 -0800300 dex_deps->fields_.emplace(FieldResolution(field_idx,
301 GetAccessFlags(field),
302 GetFieldDeclaringClassStringId(dex_file,
303 field_idx,
304 field)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100305}
306
307void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
308 uint32_t method_idx,
309 MethodResolutionKind resolution_kind,
310 ArtMethod* method) {
311 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
312 if (dex_deps == nullptr) {
313 // This invocation is from verification of a dex file which is not being compiled.
314 return;
315 }
316
317 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
318 // Method resolved into one of the DEX files which are being compiled.
319 // This is not a classpath dependency.
320 return;
321 }
322
David Brazdilca3c8c32016-09-06 14:04:48 +0100323 MethodResolution method_tuple(method_idx,
324 GetAccessFlags(method),
Mathieu Chartier32b50302016-11-17 13:08:35 -0800325 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
David Brazdilca3c8c32016-09-06 14:04:48 +0100326 if (resolution_kind == kDirectMethodResolution) {
327 dex_deps->direct_methods_.emplace(method_tuple);
328 } else if (resolution_kind == kVirtualMethodResolution) {
329 dex_deps->virtual_methods_.emplace(method_tuple);
330 } else {
331 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
332 dex_deps->interface_methods_.emplace(method_tuple);
333 }
334}
335
336void VerifierDeps::AddAssignability(const DexFile& dex_file,
337 mirror::Class* destination,
338 mirror::Class* source,
339 bool is_strict,
340 bool is_assignable) {
341 // Test that the method is only called on reference types.
342 // Note that concurrent verification of `destination` and `source` may have
343 // set their status to erroneous. However, the tests performed below rely
344 // merely on no issues with linking (valid access flags, superclass and
345 // implemented interfaces). If the class at any point reached the IsResolved
346 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
347 DCHECK(destination != nullptr && !destination->IsPrimitive());
348 DCHECK(source != nullptr && !source->IsPrimitive());
349
350 if (destination == source ||
351 destination->IsObjectClass() ||
352 (!is_strict && destination->IsInterface())) {
353 // Cases when `destination` is trivially assignable from `source`.
354 DCHECK(is_assignable);
355 return;
356 }
357
358 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
359
360 if (destination->IsArrayClass() && source->IsArrayClass()) {
361 // Both types are arrays. Break down to component types and add recursively.
362 // This helps filter out destinations from compiled DEX files (see below)
363 // and deduplicate entries with the same canonical component type.
364 mirror::Class* destination_component = destination->GetComponentType();
365 mirror::Class* source_component = source->GetComponentType();
366
367 // Only perform the optimization if both types are resolved which guarantees
368 // that they linked successfully, as required at the top of this method.
369 if (destination_component->IsResolved() && source_component->IsResolved()) {
370 AddAssignability(dex_file,
371 destination_component,
372 source_component,
373 /* is_strict */ true,
374 is_assignable);
375 return;
376 }
377 }
378
379 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
380 if (dex_deps == nullptr) {
381 // This invocation is from verification of a DEX file which is not being compiled.
382 return;
383 }
384
385 if (!IsInClassPath(destination) && !IsInClassPath(source)) {
386 // Both `destination` and `source` are defined in the compiled DEX files.
387 // No need to record a dependency.
388 return;
389 }
390
David Brazdilca3c8c32016-09-06 14:04:48 +0100391 // Get string IDs for both descriptors and store in the appropriate set.
Mathieu Chartier32b50302016-11-17 13:08:35 -0800392 uint32_t destination_id = GetClassDescriptorStringId(dex_file, destination);
393 uint32_t source_id = GetClassDescriptorStringId(dex_file, source);
David Brazdilca3c8c32016-09-06 14:04:48 +0100394
395 if (is_assignable) {
396 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
397 } else {
398 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
399 }
400}
401
Nicolas Geoffray08025182016-10-25 17:20:18 +0100402void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800403 dex::TypeIndex type_idx,
Nicolas Geoffray08025182016-10-25 17:20:18 +0100404 MethodVerifier::FailureKind failure_kind) {
405 if (failure_kind == MethodVerifier::kNoFailure) {
406 // We only record classes that did not fully verify at compile time.
407 return;
408 }
409
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000410 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
411 if (thread_deps != nullptr) {
412 DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100413 dex_deps->unverified_classes_.push_back(type_idx);
414 }
415}
416
David Brazdilca3c8c32016-09-06 14:04:48 +0100417void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800418 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100419 mirror::Class* klass) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000420 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
421 if (thread_deps != nullptr) {
422 thread_deps->AddClassResolution(dex_file, type_idx, klass);
David Brazdilca3c8c32016-09-06 14:04:48 +0100423 }
424}
425
426void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
427 uint32_t field_idx,
428 ArtField* field) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000429 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
430 if (thread_deps != nullptr) {
431 thread_deps->AddFieldResolution(dex_file, field_idx, field);
David Brazdilca3c8c32016-09-06 14:04:48 +0100432 }
433}
434
435void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
436 uint32_t method_idx,
437 MethodResolutionKind resolution_kind,
438 ArtMethod* method) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000439 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
440 if (thread_deps != nullptr) {
441 thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
David Brazdilca3c8c32016-09-06 14:04:48 +0100442 }
443}
444
445void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
446 mirror::Class* destination,
447 mirror::Class* source,
448 bool is_strict,
449 bool is_assignable) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000450 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
451 if (thread_deps != nullptr) {
452 thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
David Brazdilca3c8c32016-09-06 14:04:48 +0100453 }
454}
455
Andreas Gampea5b09a62016-11-17 15:21:22 -0800456namespace {
457
David Brazdil6f82fbd2016-09-14 11:55:26 +0100458static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
459 CHECK_LT(*in, end);
460 return DecodeUnsignedLeb128(in);
461}
462
Andreas Gampea5b09a62016-11-17 15:21:22 -0800463template<typename T> inline uint32_t Encode(T in);
464
465template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
466 return in;
467}
468template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
469 return in;
470}
471template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
472 return in.index_;
473}
474
475template<typename T> inline T Decode(uint32_t in);
476
477template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
478 return dchecked_integral_cast<uint16_t>(in);
479}
480template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
481 return in;
482}
483template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
484 return dex::TypeIndex(in);
485}
486
David Brazdil6f82fbd2016-09-14 11:55:26 +0100487template<typename T1, typename T2>
488static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800489 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
490 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100491}
492
493template<typename T1, typename T2>
494static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800495 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
496 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100497 *t = std::make_tuple(v1, v2);
498}
499
500template<typename T1, typename T2, typename T3>
501static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800502 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
503 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
504 EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100505}
506
507template<typename T1, typename T2, typename T3>
508static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800509 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
510 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
511 T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100512 *t = std::make_tuple(v1, v2, v3);
513}
514
515template<typename T>
516static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
517 EncodeUnsignedLeb128(out, set.size());
518 for (const T& entry : set) {
519 EncodeTuple(out, entry);
520 }
521}
522
Andreas Gampea5b09a62016-11-17 15:21:22 -0800523template <typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100524static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800525 const std::vector<T>& vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100526 EncodeUnsignedLeb128(out, vector.size());
Andreas Gampea5b09a62016-11-17 15:21:22 -0800527 for (const T& entry : vector) {
528 EncodeUnsignedLeb128(out, Encode(entry));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100529 }
530}
531
David Brazdil6f82fbd2016-09-14 11:55:26 +0100532template<typename T>
533static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
534 DCHECK(set->empty());
535 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
536 for (size_t i = 0; i < num_entries; ++i) {
537 T tuple;
538 DecodeTuple(in, end, &tuple);
539 set->emplace(tuple);
540 }
541}
542
Andreas Gampea5b09a62016-11-17 15:21:22 -0800543template<typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100544static inline void DecodeUint16Vector(const uint8_t** in,
545 const uint8_t* end,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800546 std::vector<T>* vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100547 DCHECK(vector->empty());
548 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
549 vector->reserve(num_entries);
550 for (size_t i = 0; i < num_entries; ++i) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800551 vector->push_back(
552 Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100553 }
554}
555
David Brazdil6f82fbd2016-09-14 11:55:26 +0100556static inline void EncodeStringVector(std::vector<uint8_t>* out,
557 const std::vector<std::string>& strings) {
558 EncodeUnsignedLeb128(out, strings.size());
559 for (const std::string& str : strings) {
560 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
561 size_t length = str.length() + 1;
562 out->insert(out->end(), data, data + length);
563 DCHECK_EQ(0u, out->back());
564 }
565}
566
567static inline void DecodeStringVector(const uint8_t** in,
568 const uint8_t* end,
569 std::vector<std::string>* strings) {
570 DCHECK(strings->empty());
571 size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
572 strings->reserve(num_strings);
573 for (size_t i = 0; i < num_strings; ++i) {
574 CHECK_LT(*in, end);
575 const char* string_start = reinterpret_cast<const char*>(*in);
576 strings->emplace_back(std::string(string_start));
577 *in += strings->back().length() + 1;
578 }
579}
580
Andreas Gampea5b09a62016-11-17 15:21:22 -0800581} // namespace
582
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100583void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
584 std::vector<uint8_t>* buffer) const {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100585 for (const DexFile* dex_file : dex_files) {
586 const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
587 EncodeStringVector(buffer, deps.strings_);
588 EncodeSet(buffer, deps.assignable_types_);
589 EncodeSet(buffer, deps.unassignable_types_);
590 EncodeSet(buffer, deps.classes_);
591 EncodeSet(buffer, deps.fields_);
592 EncodeSet(buffer, deps.direct_methods_);
593 EncodeSet(buffer, deps.virtual_methods_);
594 EncodeSet(buffer, deps.interface_methods_);
595 EncodeUint16Vector(buffer, deps.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100596 }
597}
598
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000599VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
600 ArrayRef<const uint8_t> data)
David Brazdil6f82fbd2016-09-14 11:55:26 +0100601 : VerifierDeps(dex_files) {
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000602 if (data.empty()) {
603 // Return eagerly, as the first thing we expect from VerifierDeps data is
604 // the number of created strings, even if there is no dependency.
605 // Currently, only the boot image does not have any VerifierDeps data.
606 return;
607 }
David Brazdil6f82fbd2016-09-14 11:55:26 +0100608 const uint8_t* data_start = data.data();
609 const uint8_t* data_end = data_start + data.size();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100610 for (const DexFile* dex_file : dex_files) {
611 DexFileDeps* deps = GetDexFileDeps(*dex_file);
612 DecodeStringVector(&data_start, data_end, &deps->strings_);
613 DecodeSet(&data_start, data_end, &deps->assignable_types_);
614 DecodeSet(&data_start, data_end, &deps->unassignable_types_);
615 DecodeSet(&data_start, data_end, &deps->classes_);
616 DecodeSet(&data_start, data_end, &deps->fields_);
617 DecodeSet(&data_start, data_end, &deps->direct_methods_);
618 DecodeSet(&data_start, data_end, &deps->virtual_methods_);
619 DecodeSet(&data_start, data_end, &deps->interface_methods_);
620 DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100621 }
622 CHECK_LE(data_start, data_end);
623}
624
625bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100626 if (dex_deps_.size() != rhs.dex_deps_.size()) {
627 return false;
628 }
629
630 auto lhs_it = dex_deps_.begin();
631 auto rhs_it = rhs.dex_deps_.begin();
632
633 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
634 const DexFile* lhs_dex_file = lhs_it->first;
635 const DexFile* rhs_dex_file = rhs_it->first;
636 if (lhs_dex_file != rhs_dex_file) {
637 return false;
638 }
639
640 DexFileDeps* lhs_deps = lhs_it->second.get();
641 DexFileDeps* rhs_deps = rhs_it->second.get();
642 if (!lhs_deps->Equals(*rhs_deps)) {
643 return false;
644 }
645 }
646
647 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
648 return true;
649}
650
651bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
652 return (strings_ == rhs.strings_) &&
653 (assignable_types_ == rhs.assignable_types_) &&
654 (unassignable_types_ == rhs.unassignable_types_) &&
655 (classes_ == rhs.classes_) &&
656 (fields_ == rhs.fields_) &&
657 (direct_methods_ == rhs.direct_methods_) &&
658 (virtual_methods_ == rhs.virtual_methods_) &&
Nicolas Geoffray08025182016-10-25 17:20:18 +0100659 (interface_methods_ == rhs.interface_methods_) &&
660 (unverified_classes_ == rhs.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100661}
662
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100663void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
664 for (const auto& dep : dex_deps_) {
665 const DexFile& dex_file = *dep.first;
666 vios->Stream()
667 << "Dependencies of "
668 << dex_file.GetLocation()
669 << ":\n";
670
671 ScopedIndentation indent(vios);
672
673 for (const std::string& str : dep.second->strings_) {
674 vios->Stream() << "Extra string: " << str << "\n";
675 }
676
677 for (const TypeAssignability& entry : dep.second->assignable_types_) {
678 vios->Stream()
679 << GetStringFromId(dex_file, entry.GetSource())
680 << " must be assignable to "
681 << GetStringFromId(dex_file, entry.GetDestination())
682 << "\n";
683 }
684
685 for (const TypeAssignability& entry : dep.second->unassignable_types_) {
686 vios->Stream()
687 << GetStringFromId(dex_file, entry.GetSource())
688 << " must not be assignable to "
689 << GetStringFromId(dex_file, entry.GetDestination())
690 << "\n";
691 }
692
693 for (const ClassResolution& entry : dep.second->classes_) {
694 vios->Stream()
695 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
696 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
697 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
698 << "\n";
699 }
700
701 for (const FieldResolution& entry : dep.second->fields_) {
702 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
703 vios->Stream()
704 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
705 << dex_file.GetFieldName(field_id) << ":"
706 << dex_file.GetFieldTypeDescriptor(field_id)
707 << " is expected to be ";
708 if (!entry.IsResolved()) {
709 vios->Stream() << "unresolved\n";
710 } else {
711 vios->Stream()
712 << "in class "
713 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
714 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
715 << "\n";
716 }
717 }
718
719 for (const auto& entry :
720 { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
721 std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
722 std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
723 for (const MethodResolution& method : entry.second) {
724 const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
725 vios->Stream()
726 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
727 << dex_file.GetMethodName(method_id)
728 << dex_file.GetMethodSignature(method_id).ToString()
729 << " is expected to be ";
730 if (!method.IsResolved()) {
731 vios->Stream() << "unresolved\n";
732 } else {
733 vios->Stream()
734 << "in class "
735 << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
736 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
737 << ", and be of kind " << entry.first
738 << "\n";
739 }
740 }
741 }
742
Andreas Gampea5b09a62016-11-17 15:21:22 -0800743 for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100744 vios->Stream()
745 << dex_file.StringByTypeIdx(type_index)
746 << " is expected to be verified at runtime\n";
747 }
748 }
749}
750
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000751bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
752 Thread* self) const {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100753 for (const auto& entry : dex_deps_) {
754 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
755 return false;
756 }
757 }
758 return true;
759}
760
761// TODO: share that helper with other parts of the compiler that have
762// the same lookup pattern.
763static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
764 Thread* self,
765 const char* name,
766 Handle<mirror::ClassLoader> class_loader)
767 REQUIRES_SHARED(Locks::mutator_lock_) {
768 mirror::Class* result = class_linker->FindClass(self, name, class_loader);
769 if (result == nullptr) {
770 DCHECK(self->IsExceptionPending());
771 self->ClearException();
772 }
773 return result;
774}
775
776bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
777 const DexFile& dex_file,
778 const std::set<TypeAssignability>& assignables,
779 bool expected_assignability,
780 Thread* self) const {
781 StackHandleScope<2> hs(self);
782 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
783 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
784 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
785
786 for (const auto& entry : assignables) {
787 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
788 destination.Assign(
789 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
790 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
791 source.Assign(
792 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
793
794 if (destination.Get() == nullptr) {
795 LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
796 return false;
797 }
798
799 if (source.Get() == nullptr) {
800 LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
801 return false;
802 }
803
804 DCHECK(destination->IsResolved() && source->IsResolved());
805 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
806 LOG(INFO) << "VerifierDeps: Class "
807 << destination_desc
808 << (expected_assignability ? " not " : " ")
809 << "assignable from "
810 << source_desc;
811 return false;
812 }
813 }
814 return true;
815}
816
817bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
818 const DexFile& dex_file,
819 const std::set<ClassResolution>& classes,
820 Thread* self) const {
821 StackHandleScope<1> hs(self);
822 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
823 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
824 for (const auto& entry : classes) {
825 const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
826 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
827
828 if (entry.IsResolved()) {
829 if (cls.Get() == nullptr) {
830 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
831 return false;
832 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
833 LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
834 << descriptor
835 << std::hex
836 << " (expected="
837 << entry.GetAccessFlags()
838 << ", actual="
839 << GetAccessFlags(cls.Get()) << ")"
840 << std::dec;
841 return false;
842 }
843 } else if (cls.Get() != nullptr) {
844 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
845 return false;
846 }
847 }
848 return true;
849}
850
851static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
852 const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
853 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
854 + "->"
855 + dex_file.GetFieldName(field_id)
856 + ":"
857 + dex_file.GetFieldTypeDescriptor(field_id);
858}
859
860bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
861 const DexFile& dex_file,
862 const std::set<FieldResolution>& fields,
863 Thread* self) const {
864 // Check recorded fields are resolved the same way, have the same recorded class,
865 // and have the same recorded flags.
866 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
867 StackHandleScope<1> hs(self);
868 Handle<mirror::DexCache> dex_cache(
869 hs.NewHandle(class_linker->FindDexCache(self, dex_file, /* allow_failure */ false)));
870 for (const auto& entry : fields) {
871 ArtField* field = class_linker->ResolveFieldJLS(
872 dex_file, entry.GetDexFieldIndex(), dex_cache, class_loader);
873
874 if (field == nullptr) {
875 DCHECK(self->IsExceptionPending());
876 self->ClearException();
877 }
878
879 if (entry.IsResolved()) {
880 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
881 std::string temp;
882 if (field == nullptr) {
883 LOG(INFO) << "VerifierDeps: Could not resolve field "
884 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
885 return false;
886 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
887 LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
888 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
889 << " (expected=" << expected_decl_klass
890 << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
891 return false;
892 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
893 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
894 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
895 << std::hex << " (expected=" << entry.GetAccessFlags()
896 << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
897 return false;
898 }
899 } else if (field != nullptr) {
900 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
901 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
902 return false;
903 }
904 }
905 return true;
906}
907
908static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
909 const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
910 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
911 + "->"
912 + dex_file.GetMethodName(method_id)
913 + dex_file.GetMethodSignature(method_id).ToString();
914}
915
916bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
917 const DexFile& dex_file,
918 const std::set<MethodResolution>& methods,
919 MethodResolutionKind kind,
920 Thread* self) const {
921 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
922 PointerSize pointer_size = class_linker->GetImagePointerSize();
923
924 for (const auto& entry : methods) {
925 const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
926
927 const char* name = dex_file.GetMethodName(method_id);
928 const Signature signature = dex_file.GetMethodSignature(method_id);
929 const char* descriptor = dex_file.GetMethodDeclaringClassDescriptor(method_id);
930
931 mirror::Class* cls = FindClassAndClearException(class_linker, self, descriptor, class_loader);
932 if (cls == nullptr) {
933 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
934 return false;
935 }
936 DCHECK(cls->IsResolved());
937 ArtMethod* method = nullptr;
938 if (kind == kDirectMethodResolution) {
939 method = cls->FindDirectMethod(name, signature, pointer_size);
940 } else if (kind == kVirtualMethodResolution) {
941 method = cls->FindVirtualMethod(name, signature, pointer_size);
942 } else {
943 DCHECK_EQ(kind, kInterfaceMethodResolution);
944 method = cls->FindInterfaceMethod(name, signature, pointer_size);
945 }
946
947 if (entry.IsResolved()) {
948 std::string temp;
949 std::string expected_decl_klass = GetStringFromId(dex_file, entry.GetDeclaringClassIndex());
950 if (method == nullptr) {
951 LOG(INFO) << "VerifierDeps: Could not resolve "
952 << kind
953 << " method "
954 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
955 return false;
956 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
957 LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
958 << kind
959 << " method resolution "
960 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
961 << " (expected="
962 << expected_decl_klass
963 << ", actual="
964 << method->GetDeclaringClass()->GetDescriptor(&temp)
965 << ")";
966 return false;
967 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
968 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
969 << kind
970 << " method resolution "
971 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
972 << std::hex
973 << " (expected="
974 << entry.GetAccessFlags()
975 << ", actual="
976 << GetAccessFlags(method) << ")"
977 << std::dec;
978 return false;
979 }
980 } else if (method != nullptr) {
981 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
982 << kind
983 << " method "
984 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
985 return false;
986 }
987 }
988 return true;
989}
990
991bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
992 const DexFile& dex_file,
993 const DexFileDeps& deps,
994 Thread* self) const {
995 bool result = VerifyAssignability(
996 class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
997 result = result && VerifyAssignability(
998 class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
999
1000 result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
1001 result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
1002
1003 result = result && VerifyMethods(
1004 class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
1005 result = result && VerifyMethods(
1006 class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
1007 result = result && VerifyMethods(
1008 class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
1009
1010 return result;
1011}
1012
David Brazdilca3c8c32016-09-06 14:04:48 +01001013} // namespace verifier
1014} // namespace art