blob: 113160785c9986c54ccd16b3f393eb4032f37942 [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
Andreas Gampe8a0128a2016-11-28 07:38:35 -080083dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
84 ObjPtr<mirror::Class> klass) {
Mathieu Chartier32b50302016-11-17 13:08:35 -080085 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.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800107static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
108 dex::TypeIndex type_idx,
109 ObjPtr<mirror::Class> klass)
Mathieu Chartier32b50302016-11-17 13:08:35 -0800110 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 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800120 return dex::StringIndex::Invalid();
Mathieu Chartier32b50302016-11-17 13:08:35 -0800121}
122
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800123dex::StringIndex 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) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800128 return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
Mathieu Chartier32b50302016-11-17 13:08:35 -0800129 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800130 const dex::StringIndex string_id = TryGetClassDescriptorStringId(
Mathieu Chartier32b50302016-11-17 13:08:35 -0800131 dex_file,
132 dex_file.GetMethodId(dex_method_index).class_idx_,
133 method->GetDeclaringClass());
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800134 if (string_id.IsValid()) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800135 // 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
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800142dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
143 uint32_t dex_field_idx,
144 ArtField* field) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800145 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
146 if (field == nullptr) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800147 return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
Mathieu Chartier32b50302016-11-17 13:08:35 -0800148 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800149 const dex::StringIndex string_id = TryGetClassDescriptorStringId(
Mathieu Chartier32b50302016-11-17 13:08:35 -0800150 dex_file,
151 dex_file.GetFieldId(dex_field_idx).class_idx_,
152 field->GetDeclaringClass());
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800153 if (string_id.IsValid()) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800154 // 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
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800193dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100194 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)) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800215 return dex::StringIndex(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)) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800221 return dex::StringIndex(num_ids_in_dex + found_id);
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000222 }
223 deps->strings_.push_back(str);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800224 dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
225 CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000226 DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
227 return new_id;
228 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100229}
230
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800231std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
232 const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100233 uint32_t num_ids_in_dex = dex_file.NumStringIds();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800234 if (string_id.index_ < num_ids_in_dex) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100235 return std::string(dex_file.StringDataByIdx(string_id));
236 } else {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100237 const DexFileDeps* deps = GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100238 DCHECK(deps != nullptr);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800239 string_id.index_ -= num_ids_in_dex;
240 CHECK_LT(string_id.index_, deps->strings_.size());
241 return deps->strings_[string_id.index_];
David Brazdilca3c8c32016-09-06 14:04:48 +0100242 }
243}
244
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100245bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100246 DCHECK(klass != nullptr);
247
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000248 // For array types, we return whether the non-array component type
249 // is in the classpath.
250 while (klass->IsArrayClass()) {
251 klass = klass->GetComponentType();
David Brazdilca3c8c32016-09-06 14:04:48 +0100252 }
253
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000254 if (klass->IsPrimitive()) {
255 return true;
256 }
257
258 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
259 DCHECK(dex_cache != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100260 const DexFile* dex_file = dex_cache->GetDexFile();
261 DCHECK(dex_file != nullptr);
262
263 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
264 // file was not registered as being compiled and we assume `klass` is in the
265 // classpath.
266 return (GetDexFileDeps(*dex_file) == nullptr);
267}
268
269void VerifierDeps::AddClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800270 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100271 mirror::Class* klass) {
272 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
273 if (dex_deps == nullptr) {
274 // This invocation is from verification of a dex file which is not being compiled.
275 return;
276 }
277
278 if (klass != nullptr && !IsInClassPath(klass)) {
279 // Class resolved into one of the DEX files which are being compiled.
280 // This is not a classpath dependency.
281 return;
282 }
283
David Brazdilca3c8c32016-09-06 14:04:48 +0100284 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
285}
286
287void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
288 uint32_t field_idx,
289 ArtField* field) {
290 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
291 if (dex_deps == nullptr) {
292 // This invocation is from verification of a dex file which is not being compiled.
293 return;
294 }
295
296 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
297 // Field resolved into one of the DEX files which are being compiled.
298 // This is not a classpath dependency.
299 return;
300 }
301
Mathieu Chartier32b50302016-11-17 13:08:35 -0800302 dex_deps->fields_.emplace(FieldResolution(field_idx,
303 GetAccessFlags(field),
304 GetFieldDeclaringClassStringId(dex_file,
305 field_idx,
306 field)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100307}
308
309void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
310 uint32_t method_idx,
311 MethodResolutionKind resolution_kind,
312 ArtMethod* method) {
313 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
314 if (dex_deps == nullptr) {
315 // This invocation is from verification of a dex file which is not being compiled.
316 return;
317 }
318
319 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
320 // Method resolved into one of the DEX files which are being compiled.
321 // This is not a classpath dependency.
322 return;
323 }
324
David Brazdilca3c8c32016-09-06 14:04:48 +0100325 MethodResolution method_tuple(method_idx,
326 GetAccessFlags(method),
Mathieu Chartier32b50302016-11-17 13:08:35 -0800327 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
David Brazdilca3c8c32016-09-06 14:04:48 +0100328 if (resolution_kind == kDirectMethodResolution) {
329 dex_deps->direct_methods_.emplace(method_tuple);
330 } else if (resolution_kind == kVirtualMethodResolution) {
331 dex_deps->virtual_methods_.emplace(method_tuple);
332 } else {
333 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
334 dex_deps->interface_methods_.emplace(method_tuple);
335 }
336}
337
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000338mirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
339 mirror::Class* source) const {
340 DCHECK(destination->IsInterface());
341 DCHECK(IsInClassPath(destination));
342 Thread* thread = Thread::Current();
343 mirror::Class* current = source;
344 // Record the classes that are at the boundary between the compiled DEX files and
345 // the classpath. We will check those classes later to find one class that inherits
346 // `destination`.
347 std::vector<ObjPtr<mirror::Class>> boundaries;
348 // If the destination is a direct interface of a class defined in the DEX files being
349 // compiled, no need to record it.
350 while (!IsInClassPath(current)) {
351 for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
352 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
353 if (direct == destination) {
354 return nullptr;
355 } else if (IsInClassPath(direct)) {
356 boundaries.push_back(direct);
357 }
358 }
359 current = current->GetSuperClass();
360 }
361 DCHECK(current != nullptr);
362 boundaries.push_back(current);
363
364 // Check if we have an interface defined in the DEX files being compiled, direclty
365 // inheriting `destination`.
366 int32_t iftable_count = source->GetIfTableCount();
367 ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
368 for (int32_t i = 0; i < iftable_count; ++i) {
369 mirror::Class* itf = iftable->GetInterface(i);
370 if (!IsInClassPath(itf)) {
371 for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
372 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
373 if (direct == destination) {
374 return nullptr;
375 } else if (IsInClassPath(direct)) {
376 boundaries.push_back(direct);
377 }
378 }
379 }
380 }
381
382 // Find a boundary making `source` inherit from `destination`. We must find one.
383 for (const ObjPtr<mirror::Class>& boundary : boundaries) {
384 if (destination->IsAssignableFrom(boundary)) {
385 return boundary.Ptr();
386 }
387 }
388 LOG(FATAL) << "Should have found a classpath boundary";
389 UNREACHABLE();
390}
391
David Brazdilca3c8c32016-09-06 14:04:48 +0100392void VerifierDeps::AddAssignability(const DexFile& dex_file,
393 mirror::Class* destination,
394 mirror::Class* source,
395 bool is_strict,
396 bool is_assignable) {
397 // Test that the method is only called on reference types.
398 // Note that concurrent verification of `destination` and `source` may have
399 // set their status to erroneous. However, the tests performed below rely
400 // merely on no issues with linking (valid access flags, superclass and
401 // implemented interfaces). If the class at any point reached the IsResolved
402 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
Nicolas Geoffrayd1665a02016-12-12 13:07:07 +0000403 DCHECK(destination != nullptr);
404 DCHECK(source != nullptr);
405
406 if (destination->IsPrimitive() || source->IsPrimitive()) {
407 // Primitive types are trivially non-assignable to anything else.
408 // We do not need to record trivial assignability, as it will
409 // not change across releases.
410 return;
411 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100412
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000413 if (source->IsObjectClass() && !is_assignable) {
414 // j.l.Object is trivially non-assignable to other types, don't
415 // record it.
416 return;
417 }
418
David Brazdilca3c8c32016-09-06 14:04:48 +0100419 if (destination == source ||
420 destination->IsObjectClass() ||
421 (!is_strict && destination->IsInterface())) {
422 // Cases when `destination` is trivially assignable from `source`.
423 DCHECK(is_assignable);
424 return;
425 }
426
427 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
428
429 if (destination->IsArrayClass() && source->IsArrayClass()) {
430 // Both types are arrays. Break down to component types and add recursively.
431 // This helps filter out destinations from compiled DEX files (see below)
432 // and deduplicate entries with the same canonical component type.
433 mirror::Class* destination_component = destination->GetComponentType();
434 mirror::Class* source_component = source->GetComponentType();
435
436 // Only perform the optimization if both types are resolved which guarantees
437 // that they linked successfully, as required at the top of this method.
438 if (destination_component->IsResolved() && source_component->IsResolved()) {
439 AddAssignability(dex_file,
440 destination_component,
441 source_component,
442 /* is_strict */ true,
443 is_assignable);
444 return;
445 }
446 }
447
448 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
449 if (dex_deps == nullptr) {
450 // This invocation is from verification of a DEX file which is not being compiled.
451 return;
452 }
453
454 if (!IsInClassPath(destination) && !IsInClassPath(source)) {
455 // Both `destination` and `source` are defined in the compiled DEX files.
456 // No need to record a dependency.
457 return;
458 }
459
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000460 if (!IsInClassPath(source)) {
461 if (!destination->IsInterface()) {
462 DCHECK(!source->IsInterface());
463 // Find the super class at the classpath boundary. Only that class
464 // can change the assignability.
465 do {
466 source = source->GetSuperClass();
467 } while (!IsInClassPath(source));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000468
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000469 // If that class is the actual destination, no need to record it.
470 if (source == destination) {
471 return;
472 }
473 } else if (is_assignable) {
474 source = FindOneClassPathBoundaryForInterface(destination, source);
475 if (source == nullptr) {
476 // There was no classpath boundary, no need to record.
477 return;
478 }
479 DCHECK(IsInClassPath(source));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000480 }
481 }
482
483
David Brazdilca3c8c32016-09-06 14:04:48 +0100484 // Get string IDs for both descriptors and store in the appropriate set.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800485 dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
486 dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
David Brazdilca3c8c32016-09-06 14:04:48 +0100487
488 if (is_assignable) {
489 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
490 } else {
491 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
492 }
493}
494
Nicolas Geoffray08025182016-10-25 17:20:18 +0100495void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800496 dex::TypeIndex type_idx,
Nicolas Geoffray08025182016-10-25 17:20:18 +0100497 MethodVerifier::FailureKind failure_kind) {
498 if (failure_kind == MethodVerifier::kNoFailure) {
499 // We only record classes that did not fully verify at compile time.
500 return;
501 }
502
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000503 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
504 if (thread_deps != nullptr) {
505 DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100506 dex_deps->unverified_classes_.push_back(type_idx);
507 }
508}
509
David Brazdilca3c8c32016-09-06 14:04:48 +0100510void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800511 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100512 mirror::Class* klass) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000513 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
514 if (thread_deps != nullptr) {
515 thread_deps->AddClassResolution(dex_file, type_idx, klass);
David Brazdilca3c8c32016-09-06 14:04:48 +0100516 }
517}
518
519void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
520 uint32_t field_idx,
521 ArtField* field) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000522 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
523 if (thread_deps != nullptr) {
524 thread_deps->AddFieldResolution(dex_file, field_idx, field);
David Brazdilca3c8c32016-09-06 14:04:48 +0100525 }
526}
527
528void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
529 uint32_t method_idx,
530 MethodResolutionKind resolution_kind,
531 ArtMethod* method) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000532 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
533 if (thread_deps != nullptr) {
534 thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
David Brazdilca3c8c32016-09-06 14:04:48 +0100535 }
536}
537
538void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
539 mirror::Class* destination,
540 mirror::Class* source,
541 bool is_strict,
542 bool is_assignable) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000543 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
544 if (thread_deps != nullptr) {
545 thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
David Brazdilca3c8c32016-09-06 14:04:48 +0100546 }
547}
548
Andreas Gampea5b09a62016-11-17 15:21:22 -0800549namespace {
550
David Brazdil6f82fbd2016-09-14 11:55:26 +0100551static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
552 CHECK_LT(*in, end);
553 return DecodeUnsignedLeb128(in);
554}
555
Andreas Gampea5b09a62016-11-17 15:21:22 -0800556template<typename T> inline uint32_t Encode(T in);
557
558template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
559 return in;
560}
561template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
562 return in;
563}
564template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
565 return in.index_;
566}
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800567template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
568 return in.index_;
569}
Andreas Gampea5b09a62016-11-17 15:21:22 -0800570
571template<typename T> inline T Decode(uint32_t in);
572
573template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
574 return dchecked_integral_cast<uint16_t>(in);
575}
576template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
577 return in;
578}
579template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
580 return dex::TypeIndex(in);
581}
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800582template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
583 return dex::StringIndex(in);
584}
Andreas Gampea5b09a62016-11-17 15:21:22 -0800585
David Brazdil6f82fbd2016-09-14 11:55:26 +0100586template<typename T1, typename T2>
587static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800588 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
589 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100590}
591
592template<typename T1, typename T2>
593static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800594 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
595 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100596 *t = std::make_tuple(v1, v2);
597}
598
599template<typename T1, typename T2, typename T3>
600static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800601 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
602 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
603 EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100604}
605
606template<typename T1, typename T2, typename T3>
607static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800608 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
609 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800610 T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100611 *t = std::make_tuple(v1, v2, v3);
612}
613
614template<typename T>
615static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
616 EncodeUnsignedLeb128(out, set.size());
617 for (const T& entry : set) {
618 EncodeTuple(out, entry);
619 }
620}
621
Andreas Gampea5b09a62016-11-17 15:21:22 -0800622template <typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100623static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800624 const std::vector<T>& vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100625 EncodeUnsignedLeb128(out, vector.size());
Andreas Gampea5b09a62016-11-17 15:21:22 -0800626 for (const T& entry : vector) {
627 EncodeUnsignedLeb128(out, Encode(entry));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100628 }
629}
630
David Brazdil6f82fbd2016-09-14 11:55:26 +0100631template<typename T>
632static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
633 DCHECK(set->empty());
634 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
635 for (size_t i = 0; i < num_entries; ++i) {
636 T tuple;
637 DecodeTuple(in, end, &tuple);
638 set->emplace(tuple);
639 }
640}
641
Andreas Gampea5b09a62016-11-17 15:21:22 -0800642template<typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100643static inline void DecodeUint16Vector(const uint8_t** in,
644 const uint8_t* end,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800645 std::vector<T>* vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100646 DCHECK(vector->empty());
647 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
648 vector->reserve(num_entries);
649 for (size_t i = 0; i < num_entries; ++i) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800650 vector->push_back(
651 Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100652 }
653}
654
David Brazdil6f82fbd2016-09-14 11:55:26 +0100655static inline void EncodeStringVector(std::vector<uint8_t>* out,
656 const std::vector<std::string>& strings) {
657 EncodeUnsignedLeb128(out, strings.size());
658 for (const std::string& str : strings) {
659 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
660 size_t length = str.length() + 1;
661 out->insert(out->end(), data, data + length);
662 DCHECK_EQ(0u, out->back());
663 }
664}
665
666static inline void DecodeStringVector(const uint8_t** in,
667 const uint8_t* end,
668 std::vector<std::string>* strings) {
669 DCHECK(strings->empty());
670 size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
671 strings->reserve(num_strings);
672 for (size_t i = 0; i < num_strings; ++i) {
673 CHECK_LT(*in, end);
674 const char* string_start = reinterpret_cast<const char*>(*in);
675 strings->emplace_back(std::string(string_start));
676 *in += strings->back().length() + 1;
677 }
678}
679
Andreas Gampea5b09a62016-11-17 15:21:22 -0800680} // namespace
681
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100682void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
683 std::vector<uint8_t>* buffer) const {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100684 for (const DexFile* dex_file : dex_files) {
685 const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
686 EncodeStringVector(buffer, deps.strings_);
687 EncodeSet(buffer, deps.assignable_types_);
688 EncodeSet(buffer, deps.unassignable_types_);
689 EncodeSet(buffer, deps.classes_);
690 EncodeSet(buffer, deps.fields_);
691 EncodeSet(buffer, deps.direct_methods_);
692 EncodeSet(buffer, deps.virtual_methods_);
693 EncodeSet(buffer, deps.interface_methods_);
694 EncodeUint16Vector(buffer, deps.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100695 }
696}
697
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000698VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
699 ArrayRef<const uint8_t> data)
David Brazdil6f82fbd2016-09-14 11:55:26 +0100700 : VerifierDeps(dex_files) {
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000701 if (data.empty()) {
702 // Return eagerly, as the first thing we expect from VerifierDeps data is
703 // the number of created strings, even if there is no dependency.
704 // Currently, only the boot image does not have any VerifierDeps data.
705 return;
706 }
David Brazdil6f82fbd2016-09-14 11:55:26 +0100707 const uint8_t* data_start = data.data();
708 const uint8_t* data_end = data_start + data.size();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100709 for (const DexFile* dex_file : dex_files) {
710 DexFileDeps* deps = GetDexFileDeps(*dex_file);
711 DecodeStringVector(&data_start, data_end, &deps->strings_);
712 DecodeSet(&data_start, data_end, &deps->assignable_types_);
713 DecodeSet(&data_start, data_end, &deps->unassignable_types_);
714 DecodeSet(&data_start, data_end, &deps->classes_);
715 DecodeSet(&data_start, data_end, &deps->fields_);
716 DecodeSet(&data_start, data_end, &deps->direct_methods_);
717 DecodeSet(&data_start, data_end, &deps->virtual_methods_);
718 DecodeSet(&data_start, data_end, &deps->interface_methods_);
719 DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100720 }
721 CHECK_LE(data_start, data_end);
722}
723
724bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100725 if (dex_deps_.size() != rhs.dex_deps_.size()) {
726 return false;
727 }
728
729 auto lhs_it = dex_deps_.begin();
730 auto rhs_it = rhs.dex_deps_.begin();
731
732 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
733 const DexFile* lhs_dex_file = lhs_it->first;
734 const DexFile* rhs_dex_file = rhs_it->first;
735 if (lhs_dex_file != rhs_dex_file) {
736 return false;
737 }
738
739 DexFileDeps* lhs_deps = lhs_it->second.get();
740 DexFileDeps* rhs_deps = rhs_it->second.get();
741 if (!lhs_deps->Equals(*rhs_deps)) {
742 return false;
743 }
744 }
745
746 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
747 return true;
748}
749
750bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
751 return (strings_ == rhs.strings_) &&
752 (assignable_types_ == rhs.assignable_types_) &&
753 (unassignable_types_ == rhs.unassignable_types_) &&
754 (classes_ == rhs.classes_) &&
755 (fields_ == rhs.fields_) &&
756 (direct_methods_ == rhs.direct_methods_) &&
757 (virtual_methods_ == rhs.virtual_methods_) &&
Nicolas Geoffray08025182016-10-25 17:20:18 +0100758 (interface_methods_ == rhs.interface_methods_) &&
759 (unverified_classes_ == rhs.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100760}
761
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100762void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
763 for (const auto& dep : dex_deps_) {
764 const DexFile& dex_file = *dep.first;
765 vios->Stream()
766 << "Dependencies of "
767 << dex_file.GetLocation()
768 << ":\n";
769
770 ScopedIndentation indent(vios);
771
772 for (const std::string& str : dep.second->strings_) {
773 vios->Stream() << "Extra string: " << str << "\n";
774 }
775
776 for (const TypeAssignability& entry : dep.second->assignable_types_) {
777 vios->Stream()
778 << GetStringFromId(dex_file, entry.GetSource())
779 << " must be assignable to "
780 << GetStringFromId(dex_file, entry.GetDestination())
781 << "\n";
782 }
783
784 for (const TypeAssignability& entry : dep.second->unassignable_types_) {
785 vios->Stream()
786 << GetStringFromId(dex_file, entry.GetSource())
787 << " must not be assignable to "
788 << GetStringFromId(dex_file, entry.GetDestination())
789 << "\n";
790 }
791
792 for (const ClassResolution& entry : dep.second->classes_) {
793 vios->Stream()
794 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
795 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
796 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
797 << "\n";
798 }
799
800 for (const FieldResolution& entry : dep.second->fields_) {
801 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
802 vios->Stream()
803 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
804 << dex_file.GetFieldName(field_id) << ":"
805 << dex_file.GetFieldTypeDescriptor(field_id)
806 << " is expected to be ";
807 if (!entry.IsResolved()) {
808 vios->Stream() << "unresolved\n";
809 } else {
810 vios->Stream()
811 << "in class "
812 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
813 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
814 << "\n";
815 }
816 }
817
818 for (const auto& entry :
819 { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
820 std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
821 std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
822 for (const MethodResolution& method : entry.second) {
823 const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
824 vios->Stream()
825 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
826 << dex_file.GetMethodName(method_id)
827 << dex_file.GetMethodSignature(method_id).ToString()
828 << " is expected to be ";
829 if (!method.IsResolved()) {
830 vios->Stream() << "unresolved\n";
831 } else {
832 vios->Stream()
833 << "in class "
834 << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
835 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
836 << ", and be of kind " << entry.first
837 << "\n";
838 }
839 }
840 }
841
Andreas Gampea5b09a62016-11-17 15:21:22 -0800842 for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100843 vios->Stream()
844 << dex_file.StringByTypeIdx(type_index)
845 << " is expected to be verified at runtime\n";
846 }
847 }
848}
849
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000850bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
851 Thread* self) const {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100852 for (const auto& entry : dex_deps_) {
853 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
854 return false;
855 }
856 }
857 return true;
858}
859
860// TODO: share that helper with other parts of the compiler that have
861// the same lookup pattern.
862static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
863 Thread* self,
864 const char* name,
865 Handle<mirror::ClassLoader> class_loader)
866 REQUIRES_SHARED(Locks::mutator_lock_) {
867 mirror::Class* result = class_linker->FindClass(self, name, class_loader);
868 if (result == nullptr) {
869 DCHECK(self->IsExceptionPending());
870 self->ClearException();
871 }
872 return result;
873}
874
875bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
876 const DexFile& dex_file,
877 const std::set<TypeAssignability>& assignables,
878 bool expected_assignability,
879 Thread* self) const {
880 StackHandleScope<2> hs(self);
881 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
882 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
883 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
884
885 for (const auto& entry : assignables) {
886 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
887 destination.Assign(
888 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
889 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
890 source.Assign(
891 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
892
893 if (destination.Get() == nullptr) {
894 LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
895 return false;
896 }
897
898 if (source.Get() == nullptr) {
899 LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
900 return false;
901 }
902
903 DCHECK(destination->IsResolved() && source->IsResolved());
904 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
905 LOG(INFO) << "VerifierDeps: Class "
906 << destination_desc
907 << (expected_assignability ? " not " : " ")
908 << "assignable from "
909 << source_desc;
910 return false;
911 }
912 }
913 return true;
914}
915
916bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
917 const DexFile& dex_file,
918 const std::set<ClassResolution>& classes,
919 Thread* self) const {
920 StackHandleScope<1> hs(self);
921 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
922 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
923 for (const auto& entry : classes) {
924 const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
925 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
926
927 if (entry.IsResolved()) {
928 if (cls.Get() == nullptr) {
929 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
930 return false;
931 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
932 LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
933 << descriptor
934 << std::hex
935 << " (expected="
936 << entry.GetAccessFlags()
937 << ", actual="
938 << GetAccessFlags(cls.Get()) << ")"
939 << std::dec;
940 return false;
941 }
942 } else if (cls.Get() != nullptr) {
943 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
944 return false;
945 }
946 }
947 return true;
948}
949
950static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
951 const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
952 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
953 + "->"
954 + dex_file.GetFieldName(field_id)
955 + ":"
956 + dex_file.GetFieldTypeDescriptor(field_id);
957}
958
959bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
960 const DexFile& dex_file,
961 const std::set<FieldResolution>& fields,
962 Thread* self) const {
963 // Check recorded fields are resolved the same way, have the same recorded class,
964 // and have the same recorded flags.
965 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100966 for (const auto& entry : fields) {
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000967 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
968 StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
969 StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
970 // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
971 // Otherwise, we might end up resolving an application class, which is expensive.
972 std::string expected_decl_klass = entry.IsResolved()
973 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
974 : dex_file.StringByTypeIdx(field_id.class_idx_);
975 mirror::Class* cls = FindClassAndClearException(
976 class_linker, self, expected_decl_klass.c_str(), class_loader);
977 if (cls == nullptr) {
978 LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
979 return false;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100980 }
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000981 DCHECK(cls->IsResolved());
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100982
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000983 ArtField* field = mirror::Class::FindField(self, cls, name, type);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100984 if (entry.IsResolved()) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100985 std::string temp;
986 if (field == nullptr) {
987 LOG(INFO) << "VerifierDeps: Could not resolve field "
988 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
989 return false;
990 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
991 LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
992 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
993 << " (expected=" << expected_decl_klass
994 << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
995 return false;
996 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
997 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
998 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
999 << std::hex << " (expected=" << entry.GetAccessFlags()
1000 << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
1001 return false;
1002 }
1003 } else if (field != nullptr) {
1004 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
1005 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
1006 return false;
1007 }
1008 }
1009 return true;
1010}
1011
1012static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
1013 const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
1014 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
1015 + "->"
1016 + dex_file.GetMethodName(method_id)
1017 + dex_file.GetMethodSignature(method_id).ToString();
1018}
1019
1020bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
1021 const DexFile& dex_file,
1022 const std::set<MethodResolution>& methods,
1023 MethodResolutionKind kind,
1024 Thread* self) const {
1025 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1026 PointerSize pointer_size = class_linker->GetImagePointerSize();
1027
1028 for (const auto& entry : methods) {
1029 const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
1030
1031 const char* name = dex_file.GetMethodName(method_id);
1032 const Signature signature = dex_file.GetMethodSignature(method_id);
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001033 // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
1034 // Otherwise, we might end up resolving an application class, which is expensive.
1035 std::string expected_decl_klass = entry.IsResolved()
1036 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
1037 : dex_file.StringByTypeIdx(method_id.class_idx_);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001038
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001039 mirror::Class* cls = FindClassAndClearException(
1040 class_linker, self, expected_decl_klass.c_str(), class_loader);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001041 if (cls == nullptr) {
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001042 LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001043 return false;
1044 }
1045 DCHECK(cls->IsResolved());
1046 ArtMethod* method = nullptr;
1047 if (kind == kDirectMethodResolution) {
1048 method = cls->FindDirectMethod(name, signature, pointer_size);
1049 } else if (kind == kVirtualMethodResolution) {
1050 method = cls->FindVirtualMethod(name, signature, pointer_size);
1051 } else {
1052 DCHECK_EQ(kind, kInterfaceMethodResolution);
1053 method = cls->FindInterfaceMethod(name, signature, pointer_size);
1054 }
1055
1056 if (entry.IsResolved()) {
1057 std::string temp;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001058 if (method == nullptr) {
1059 LOG(INFO) << "VerifierDeps: Could not resolve "
1060 << kind
1061 << " method "
1062 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1063 return false;
1064 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
1065 LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
1066 << kind
1067 << " method resolution "
1068 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1069 << " (expected="
1070 << expected_decl_klass
1071 << ", actual="
1072 << method->GetDeclaringClass()->GetDescriptor(&temp)
1073 << ")";
1074 return false;
1075 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
1076 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
1077 << kind
1078 << " method resolution "
1079 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1080 << std::hex
1081 << " (expected="
1082 << entry.GetAccessFlags()
1083 << ", actual="
1084 << GetAccessFlags(method) << ")"
1085 << std::dec;
1086 return false;
1087 }
1088 } else if (method != nullptr) {
1089 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
1090 << kind
1091 << " method "
1092 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1093 return false;
1094 }
1095 }
1096 return true;
1097}
1098
1099bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
1100 const DexFile& dex_file,
1101 const DexFileDeps& deps,
1102 Thread* self) const {
1103 bool result = VerifyAssignability(
1104 class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
1105 result = result && VerifyAssignability(
1106 class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
1107
1108 result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
1109 result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
1110
1111 result = result && VerifyMethods(
1112 class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
1113 result = result && VerifyMethods(
1114 class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
1115 result = result && VerifyMethods(
1116 class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
1117
1118 return result;
1119}
1120
David Brazdilca3c8c32016-09-06 14:04:48 +01001121} // namespace verifier
1122} // namespace art