blob: 8e4c1664929f0460fc6b662dc010f3584ead9fa9 [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
Nicolas Geoffray6e54f782017-03-08 15:27:09 +000071// Access flags that impact vdex verification.
72static constexpr uint32_t kAccVdexAccessFlags =
73 kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface;
74
David Brazdilca3c8c32016-09-06 14:04:48 +010075template <typename T>
76uint16_t VerifierDeps::GetAccessFlags(T* element) {
77 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
78 if (element == nullptr) {
79 return VerifierDeps::kUnresolvedMarker;
80 } else {
Nicolas Geoffray6e54f782017-03-08 15:27:09 +000081 uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags;
David Brazdilca3c8c32016-09-06 14:04:48 +010082 CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
83 return access_flags;
84 }
85}
86
Andreas Gampe8a0128a2016-11-28 07:38:35 -080087dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
88 ObjPtr<mirror::Class> klass) {
Mathieu Chartier32b50302016-11-17 13:08:35 -080089 DCHECK(klass != nullptr);
90 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
Mathieu Chartierfc2dd612016-11-21 15:05:23 -080091 // Array and proxy classes do not have a dex cache.
Mathieu Chartier32b50302016-11-17 13:08:35 -080092 if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
93 DCHECK(dex_cache != nullptr) << klass->PrettyClass();
94 if (dex_cache->GetDexFile() == &dex_file) {
95 // FindStringId is slow, try to go through the class def if we have one.
96 const DexFile::ClassDef* class_def = klass->GetClassDef();
97 DCHECK(class_def != nullptr) << klass->PrettyClass();
Mathieu Chartier32b50302016-11-17 13:08:35 -080098 const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
Mathieu Chartierfc2dd612016-11-21 15:05:23 -080099 if (kIsDebugBuild) {
100 std::string temp;
101 CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
102 }
Mathieu Chartier32b50302016-11-17 13:08:35 -0800103 return type_id.descriptor_idx_;
104 }
105 }
106 std::string temp;
107 return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
108}
109
110// 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 -0800111static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
112 dex::TypeIndex type_idx,
113 ObjPtr<mirror::Class> klass)
Mathieu Chartier32b50302016-11-17 13:08:35 -0800114 REQUIRES_SHARED(Locks::mutator_lock_) {
115 if (!klass->IsArrayClass()) {
116 const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
117 const DexFile& klass_dex = klass->GetDexFile();
118 const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
119 if (strcmp(dex_file.GetTypeDescriptor(type_id),
120 klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
121 return type_id.descriptor_idx_;
122 }
123 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800124 return dex::StringIndex::Invalid();
Mathieu Chartier32b50302016-11-17 13:08:35 -0800125}
126
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800127dex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
128 uint32_t dex_method_index,
129 ArtMethod* method) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100130 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
Mathieu Chartier32b50302016-11-17 13:08:35 -0800131 if (method == nullptr) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800132 return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
Mathieu Chartier32b50302016-11-17 13:08:35 -0800133 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800134 const dex::StringIndex string_id = TryGetClassDescriptorStringId(
Mathieu Chartier32b50302016-11-17 13:08:35 -0800135 dex_file,
136 dex_file.GetMethodId(dex_method_index).class_idx_,
137 method->GetDeclaringClass());
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800138 if (string_id.IsValid()) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800139 // Got lucky using the original dex file, return based on the input dex file.
140 DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
David Brazdilca3c8c32016-09-06 14:04:48 +0100141 return string_id;
142 }
Mathieu Chartier32b50302016-11-17 13:08:35 -0800143 return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
144}
145
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800146dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
147 uint32_t dex_field_idx,
148 ArtField* field) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800149 static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
150 if (field == nullptr) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800151 return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
Mathieu Chartier32b50302016-11-17 13:08:35 -0800152 }
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800153 const dex::StringIndex string_id = TryGetClassDescriptorStringId(
Mathieu Chartier32b50302016-11-17 13:08:35 -0800154 dex_file,
155 dex_file.GetFieldId(dex_field_idx).class_idx_,
156 field->GetDeclaringClass());
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800157 if (string_id.IsValid()) {
Mathieu Chartier32b50302016-11-17 13:08:35 -0800158 // Got lucky using the original dex file, return based on the input dex file.
159 DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
160 return string_id;
161 }
162 return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
David Brazdilca3c8c32016-09-06 14:04:48 +0100163}
164
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000165static inline VerifierDeps* GetMainVerifierDeps() {
166 // The main VerifierDeps is the one set in the compiler callbacks, which at the
167 // end of verification will have all the per-thread VerifierDeps merged into it.
168 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
169 if (callbacks == nullptr) {
170 return nullptr;
171 }
172 return callbacks->GetVerifierDeps();
173}
174
175static inline VerifierDeps* GetThreadLocalVerifierDeps() {
176 // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
177 // of full verification, these VerifierDeps will be merged into the main one.
178 if (!Runtime::Current()->IsAotCompiler()) {
179 return nullptr;
180 }
181 return Thread::Current()->GetVerifierDeps();
182}
183
184static bool FindExistingStringId(const std::vector<std::string>& strings,
185 const std::string& str,
186 uint32_t* found_id) {
187 uint32_t num_extra_ids = strings.size();
188 for (size_t i = 0; i < num_extra_ids; ++i) {
189 if (strings[i] == str) {
190 *found_id = i;
191 return true;
192 }
193 }
194 return false;
195}
196
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800197dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100198 const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
199 if (string_id != nullptr) {
200 // String is in the DEX file. Return its ID.
201 return dex_file.GetIndexForStringId(*string_id);
202 }
203
204 // String is not in the DEX file. Assign a new ID to it which is higher than
205 // the number of strings in the DEX file.
206
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000207 // We use the main `VerifierDeps` for adding new strings to simplify
208 // synchronization/merging of these entries between threads.
209 VerifierDeps* singleton = GetMainVerifierDeps();
210 DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100211 DCHECK(deps != nullptr);
212
213 uint32_t num_ids_in_dex = dex_file.NumStringIds();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000214 uint32_t found_id;
David Brazdilca3c8c32016-09-06 14:04:48 +0100215
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000216 {
217 ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
218 if (FindExistingStringId(deps->strings_, str, &found_id)) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800219 return dex::StringIndex(num_ids_in_dex + found_id);
David Brazdilca3c8c32016-09-06 14:04:48 +0100220 }
221 }
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000222 {
223 WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
224 if (FindExistingStringId(deps->strings_, str, &found_id)) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800225 return dex::StringIndex(num_ids_in_dex + found_id);
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000226 }
227 deps->strings_.push_back(str);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800228 dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
229 CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000230 DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
231 return new_id;
232 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100233}
234
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800235std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
236 const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100237 uint32_t num_ids_in_dex = dex_file.NumStringIds();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800238 if (string_id.index_ < num_ids_in_dex) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100239 return std::string(dex_file.StringDataByIdx(string_id));
240 } else {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100241 const DexFileDeps* deps = GetDexFileDeps(dex_file);
David Brazdilca3c8c32016-09-06 14:04:48 +0100242 DCHECK(deps != nullptr);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800243 string_id.index_ -= num_ids_in_dex;
244 CHECK_LT(string_id.index_, deps->strings_.size());
245 return deps->strings_[string_id.index_];
David Brazdilca3c8c32016-09-06 14:04:48 +0100246 }
247}
248
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100249bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100250 DCHECK(klass != nullptr);
251
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000252 // For array types, we return whether the non-array component type
253 // is in the classpath.
254 while (klass->IsArrayClass()) {
255 klass = klass->GetComponentType();
David Brazdilca3c8c32016-09-06 14:04:48 +0100256 }
257
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000258 if (klass->IsPrimitive()) {
259 return true;
260 }
261
262 ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
263 DCHECK(dex_cache != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100264 const DexFile* dex_file = dex_cache->GetDexFile();
265 DCHECK(dex_file != nullptr);
266
267 // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
268 // file was not registered as being compiled and we assume `klass` is in the
269 // classpath.
270 return (GetDexFileDeps(*dex_file) == nullptr);
271}
272
273void VerifierDeps::AddClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800274 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100275 mirror::Class* klass) {
276 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
277 if (dex_deps == nullptr) {
278 // This invocation is from verification of a dex file which is not being compiled.
279 return;
280 }
281
282 if (klass != nullptr && !IsInClassPath(klass)) {
283 // Class resolved into one of the DEX files which are being compiled.
284 // This is not a classpath dependency.
285 return;
286 }
287
David Brazdilca3c8c32016-09-06 14:04:48 +0100288 dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
289}
290
291void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
292 uint32_t field_idx,
293 ArtField* field) {
294 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
295 if (dex_deps == nullptr) {
296 // This invocation is from verification of a dex file which is not being compiled.
297 return;
298 }
299
300 if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
301 // Field resolved into one of the DEX files which are being compiled.
302 // This is not a classpath dependency.
303 return;
304 }
305
Mathieu Chartier32b50302016-11-17 13:08:35 -0800306 dex_deps->fields_.emplace(FieldResolution(field_idx,
307 GetAccessFlags(field),
308 GetFieldDeclaringClassStringId(dex_file,
309 field_idx,
310 field)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100311}
312
313void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
314 uint32_t method_idx,
315 MethodResolutionKind resolution_kind,
316 ArtMethod* method) {
317 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
318 if (dex_deps == nullptr) {
319 // This invocation is from verification of a dex file which is not being compiled.
320 return;
321 }
322
323 if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
324 // Method resolved into one of the DEX files which are being compiled.
325 // This is not a classpath dependency.
326 return;
327 }
328
David Brazdilca3c8c32016-09-06 14:04:48 +0100329 MethodResolution method_tuple(method_idx,
330 GetAccessFlags(method),
Mathieu Chartier32b50302016-11-17 13:08:35 -0800331 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
David Brazdilca3c8c32016-09-06 14:04:48 +0100332 if (resolution_kind == kDirectMethodResolution) {
333 dex_deps->direct_methods_.emplace(method_tuple);
334 } else if (resolution_kind == kVirtualMethodResolution) {
335 dex_deps->virtual_methods_.emplace(method_tuple);
336 } else {
337 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
338 dex_deps->interface_methods_.emplace(method_tuple);
339 }
340}
341
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000342mirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
343 mirror::Class* source) const {
344 DCHECK(destination->IsInterface());
345 DCHECK(IsInClassPath(destination));
346 Thread* thread = Thread::Current();
347 mirror::Class* current = source;
348 // Record the classes that are at the boundary between the compiled DEX files and
349 // the classpath. We will check those classes later to find one class that inherits
350 // `destination`.
351 std::vector<ObjPtr<mirror::Class>> boundaries;
352 // If the destination is a direct interface of a class defined in the DEX files being
353 // compiled, no need to record it.
354 while (!IsInClassPath(current)) {
355 for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
356 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
357 if (direct == destination) {
358 return nullptr;
359 } else if (IsInClassPath(direct)) {
360 boundaries.push_back(direct);
361 }
362 }
363 current = current->GetSuperClass();
364 }
365 DCHECK(current != nullptr);
366 boundaries.push_back(current);
367
368 // Check if we have an interface defined in the DEX files being compiled, direclty
369 // inheriting `destination`.
370 int32_t iftable_count = source->GetIfTableCount();
371 ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
372 for (int32_t i = 0; i < iftable_count; ++i) {
373 mirror::Class* itf = iftable->GetInterface(i);
374 if (!IsInClassPath(itf)) {
375 for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
376 ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
377 if (direct == destination) {
378 return nullptr;
379 } else if (IsInClassPath(direct)) {
380 boundaries.push_back(direct);
381 }
382 }
383 }
384 }
385
386 // Find a boundary making `source` inherit from `destination`. We must find one.
387 for (const ObjPtr<mirror::Class>& boundary : boundaries) {
388 if (destination->IsAssignableFrom(boundary)) {
389 return boundary.Ptr();
390 }
391 }
392 LOG(FATAL) << "Should have found a classpath boundary";
393 UNREACHABLE();
394}
395
David Brazdilca3c8c32016-09-06 14:04:48 +0100396void VerifierDeps::AddAssignability(const DexFile& dex_file,
397 mirror::Class* destination,
398 mirror::Class* source,
399 bool is_strict,
400 bool is_assignable) {
401 // Test that the method is only called on reference types.
402 // Note that concurrent verification of `destination` and `source` may have
403 // set their status to erroneous. However, the tests performed below rely
404 // merely on no issues with linking (valid access flags, superclass and
405 // implemented interfaces). If the class at any point reached the IsResolved
406 // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
Nicolas Geoffrayd1665a02016-12-12 13:07:07 +0000407 DCHECK(destination != nullptr);
408 DCHECK(source != nullptr);
409
410 if (destination->IsPrimitive() || source->IsPrimitive()) {
411 // Primitive types are trivially non-assignable to anything else.
412 // We do not need to record trivial assignability, as it will
413 // not change across releases.
414 return;
415 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100416
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000417 if (source->IsObjectClass() && !is_assignable) {
418 // j.l.Object is trivially non-assignable to other types, don't
419 // record it.
420 return;
421 }
422
David Brazdilca3c8c32016-09-06 14:04:48 +0100423 if (destination == source ||
424 destination->IsObjectClass() ||
425 (!is_strict && destination->IsInterface())) {
426 // Cases when `destination` is trivially assignable from `source`.
427 DCHECK(is_assignable);
428 return;
429 }
430
431 DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
432
433 if (destination->IsArrayClass() && source->IsArrayClass()) {
434 // Both types are arrays. Break down to component types and add recursively.
435 // This helps filter out destinations from compiled DEX files (see below)
436 // and deduplicate entries with the same canonical component type.
437 mirror::Class* destination_component = destination->GetComponentType();
438 mirror::Class* source_component = source->GetComponentType();
439
440 // Only perform the optimization if both types are resolved which guarantees
441 // that they linked successfully, as required at the top of this method.
442 if (destination_component->IsResolved() && source_component->IsResolved()) {
443 AddAssignability(dex_file,
444 destination_component,
445 source_component,
446 /* is_strict */ true,
447 is_assignable);
448 return;
449 }
450 }
451
452 DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
453 if (dex_deps == nullptr) {
454 // This invocation is from verification of a DEX file which is not being compiled.
455 return;
456 }
457
458 if (!IsInClassPath(destination) && !IsInClassPath(source)) {
459 // Both `destination` and `source` are defined in the compiled DEX files.
460 // No need to record a dependency.
461 return;
462 }
463
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000464 if (!IsInClassPath(source)) {
Nicolas Geoffrayfc38e912017-03-16 16:51:59 +0000465 if (!destination->IsInterface() && !source->IsInterface()) {
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000466 // Find the super class at the classpath boundary. Only that class
467 // can change the assignability.
468 do {
469 source = source->GetSuperClass();
470 } while (!IsInClassPath(source));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000471
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000472 // If that class is the actual destination, no need to record it.
473 if (source == destination) {
474 return;
475 }
476 } else if (is_assignable) {
477 source = FindOneClassPathBoundaryForInterface(destination, source);
478 if (source == nullptr) {
479 // There was no classpath boundary, no need to record.
480 return;
481 }
482 DCHECK(IsInClassPath(source));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000483 }
484 }
485
486
David Brazdilca3c8c32016-09-06 14:04:48 +0100487 // Get string IDs for both descriptors and store in the appropriate set.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800488 dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
489 dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
David Brazdilca3c8c32016-09-06 14:04:48 +0100490
491 if (is_assignable) {
492 dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
493 } else {
494 dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
495 }
496}
497
Nicolas Geoffray08025182016-10-25 17:20:18 +0100498void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800499 dex::TypeIndex type_idx,
Nicolas Geoffray08025182016-10-25 17:20:18 +0100500 MethodVerifier::FailureKind failure_kind) {
501 if (failure_kind == MethodVerifier::kNoFailure) {
502 // We only record classes that did not fully verify at compile time.
503 return;
504 }
505
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000506 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
507 if (thread_deps != nullptr) {
508 DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100509 dex_deps->unverified_classes_.push_back(type_idx);
510 }
511}
512
David Brazdilca3c8c32016-09-06 14:04:48 +0100513void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800514 dex::TypeIndex type_idx,
David Brazdilca3c8c32016-09-06 14:04:48 +0100515 mirror::Class* klass) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000516 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
517 if (thread_deps != nullptr) {
518 thread_deps->AddClassResolution(dex_file, type_idx, klass);
David Brazdilca3c8c32016-09-06 14:04:48 +0100519 }
520}
521
522void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
523 uint32_t field_idx,
524 ArtField* field) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000525 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
526 if (thread_deps != nullptr) {
527 thread_deps->AddFieldResolution(dex_file, field_idx, field);
David Brazdilca3c8c32016-09-06 14:04:48 +0100528 }
529}
530
531void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
532 uint32_t method_idx,
533 MethodResolutionKind resolution_kind,
534 ArtMethod* method) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000535 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
536 if (thread_deps != nullptr) {
537 thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method);
David Brazdilca3c8c32016-09-06 14:04:48 +0100538 }
539}
540
541void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
542 mirror::Class* destination,
543 mirror::Class* source,
544 bool is_strict,
545 bool is_assignable) {
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000546 VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
547 if (thread_deps != nullptr) {
548 thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
David Brazdilca3c8c32016-09-06 14:04:48 +0100549 }
550}
551
Andreas Gampea5b09a62016-11-17 15:21:22 -0800552namespace {
553
David Brazdil6f82fbd2016-09-14 11:55:26 +0100554static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
555 CHECK_LT(*in, end);
556 return DecodeUnsignedLeb128(in);
557}
558
Andreas Gampea5b09a62016-11-17 15:21:22 -0800559template<typename T> inline uint32_t Encode(T in);
560
561template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
562 return in;
563}
564template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
565 return in;
566}
567template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
568 return in.index_;
569}
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800570template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
571 return in.index_;
572}
Andreas Gampea5b09a62016-11-17 15:21:22 -0800573
574template<typename T> inline T Decode(uint32_t in);
575
576template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
577 return dchecked_integral_cast<uint16_t>(in);
578}
579template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
580 return in;
581}
582template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
583 return dex::TypeIndex(in);
584}
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800585template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
586 return dex::StringIndex(in);
587}
Andreas Gampea5b09a62016-11-17 15:21:22 -0800588
David Brazdil6f82fbd2016-09-14 11:55:26 +0100589template<typename T1, typename T2>
590static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800591 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
592 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100593}
594
595template<typename T1, typename T2>
596static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800597 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
598 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100599 *t = std::make_tuple(v1, v2);
600}
601
602template<typename T1, typename T2, typename T3>
603static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800604 EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
605 EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
606 EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100607}
608
609template<typename T1, typename T2, typename T3>
610static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800611 T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
612 T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800613 T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
David Brazdil6f82fbd2016-09-14 11:55:26 +0100614 *t = std::make_tuple(v1, v2, v3);
615}
616
617template<typename T>
618static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
619 EncodeUnsignedLeb128(out, set.size());
620 for (const T& entry : set) {
621 EncodeTuple(out, entry);
622 }
623}
624
Andreas Gampea5b09a62016-11-17 15:21:22 -0800625template <typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100626static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800627 const std::vector<T>& vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100628 EncodeUnsignedLeb128(out, vector.size());
Andreas Gampea5b09a62016-11-17 15:21:22 -0800629 for (const T& entry : vector) {
630 EncodeUnsignedLeb128(out, Encode(entry));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100631 }
632}
633
David Brazdil6f82fbd2016-09-14 11:55:26 +0100634template<typename T>
635static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
636 DCHECK(set->empty());
637 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
638 for (size_t i = 0; i < num_entries; ++i) {
639 T tuple;
640 DecodeTuple(in, end, &tuple);
641 set->emplace(tuple);
642 }
643}
644
Andreas Gampea5b09a62016-11-17 15:21:22 -0800645template<typename T>
Nicolas Geoffray08025182016-10-25 17:20:18 +0100646static inline void DecodeUint16Vector(const uint8_t** in,
647 const uint8_t* end,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800648 std::vector<T>* vector) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100649 DCHECK(vector->empty());
650 size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
651 vector->reserve(num_entries);
652 for (size_t i = 0; i < num_entries; ++i) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800653 vector->push_back(
654 Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100655 }
656}
657
David Brazdil6f82fbd2016-09-14 11:55:26 +0100658static inline void EncodeStringVector(std::vector<uint8_t>* out,
659 const std::vector<std::string>& strings) {
660 EncodeUnsignedLeb128(out, strings.size());
661 for (const std::string& str : strings) {
662 const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
663 size_t length = str.length() + 1;
664 out->insert(out->end(), data, data + length);
665 DCHECK_EQ(0u, out->back());
666 }
667}
668
669static inline void DecodeStringVector(const uint8_t** in,
670 const uint8_t* end,
671 std::vector<std::string>* strings) {
672 DCHECK(strings->empty());
673 size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
674 strings->reserve(num_strings);
675 for (size_t i = 0; i < num_strings; ++i) {
676 CHECK_LT(*in, end);
677 const char* string_start = reinterpret_cast<const char*>(*in);
678 strings->emplace_back(std::string(string_start));
679 *in += strings->back().length() + 1;
680 }
681}
682
Andreas Gampea5b09a62016-11-17 15:21:22 -0800683} // namespace
684
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100685void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
686 std::vector<uint8_t>* buffer) const {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100687 for (const DexFile* dex_file : dex_files) {
688 const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
689 EncodeStringVector(buffer, deps.strings_);
690 EncodeSet(buffer, deps.assignable_types_);
691 EncodeSet(buffer, deps.unassignable_types_);
692 EncodeSet(buffer, deps.classes_);
693 EncodeSet(buffer, deps.fields_);
694 EncodeSet(buffer, deps.direct_methods_);
695 EncodeSet(buffer, deps.virtual_methods_);
696 EncodeSet(buffer, deps.interface_methods_);
697 EncodeUint16Vector(buffer, deps.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100698 }
699}
700
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000701VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
702 ArrayRef<const uint8_t> data)
David Brazdil6f82fbd2016-09-14 11:55:26 +0100703 : VerifierDeps(dex_files) {
Nicolas Geoffraye70dd562016-10-30 21:03:35 +0000704 if (data.empty()) {
705 // Return eagerly, as the first thing we expect from VerifierDeps data is
706 // the number of created strings, even if there is no dependency.
707 // Currently, only the boot image does not have any VerifierDeps data.
708 return;
709 }
David Brazdil6f82fbd2016-09-14 11:55:26 +0100710 const uint8_t* data_start = data.data();
711 const uint8_t* data_end = data_start + data.size();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100712 for (const DexFile* dex_file : dex_files) {
713 DexFileDeps* deps = GetDexFileDeps(*dex_file);
714 DecodeStringVector(&data_start, data_end, &deps->strings_);
715 DecodeSet(&data_start, data_end, &deps->assignable_types_);
716 DecodeSet(&data_start, data_end, &deps->unassignable_types_);
717 DecodeSet(&data_start, data_end, &deps->classes_);
718 DecodeSet(&data_start, data_end, &deps->fields_);
719 DecodeSet(&data_start, data_end, &deps->direct_methods_);
720 DecodeSet(&data_start, data_end, &deps->virtual_methods_);
721 DecodeSet(&data_start, data_end, &deps->interface_methods_);
722 DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100723 }
724 CHECK_LE(data_start, data_end);
725}
726
727bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100728 if (dex_deps_.size() != rhs.dex_deps_.size()) {
729 return false;
730 }
731
732 auto lhs_it = dex_deps_.begin();
733 auto rhs_it = rhs.dex_deps_.begin();
734
735 for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
736 const DexFile* lhs_dex_file = lhs_it->first;
737 const DexFile* rhs_dex_file = rhs_it->first;
738 if (lhs_dex_file != rhs_dex_file) {
739 return false;
740 }
741
742 DexFileDeps* lhs_deps = lhs_it->second.get();
743 DexFileDeps* rhs_deps = rhs_it->second.get();
744 if (!lhs_deps->Equals(*rhs_deps)) {
745 return false;
746 }
747 }
748
749 DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
750 return true;
751}
752
753bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
754 return (strings_ == rhs.strings_) &&
755 (assignable_types_ == rhs.assignable_types_) &&
756 (unassignable_types_ == rhs.unassignable_types_) &&
757 (classes_ == rhs.classes_) &&
758 (fields_ == rhs.fields_) &&
759 (direct_methods_ == rhs.direct_methods_) &&
760 (virtual_methods_ == rhs.virtual_methods_) &&
Nicolas Geoffray08025182016-10-25 17:20:18 +0100761 (interface_methods_ == rhs.interface_methods_) &&
762 (unverified_classes_ == rhs.unverified_classes_);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100763}
764
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100765void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
766 for (const auto& dep : dex_deps_) {
767 const DexFile& dex_file = *dep.first;
768 vios->Stream()
769 << "Dependencies of "
770 << dex_file.GetLocation()
771 << ":\n";
772
773 ScopedIndentation indent(vios);
774
775 for (const std::string& str : dep.second->strings_) {
776 vios->Stream() << "Extra string: " << str << "\n";
777 }
778
779 for (const TypeAssignability& entry : dep.second->assignable_types_) {
780 vios->Stream()
781 << GetStringFromId(dex_file, entry.GetSource())
782 << " must be assignable to "
783 << GetStringFromId(dex_file, entry.GetDestination())
784 << "\n";
785 }
786
787 for (const TypeAssignability& entry : dep.second->unassignable_types_) {
788 vios->Stream()
789 << GetStringFromId(dex_file, entry.GetSource())
790 << " must not be assignable to "
791 << GetStringFromId(dex_file, entry.GetDestination())
792 << "\n";
793 }
794
795 for (const ClassResolution& entry : dep.second->classes_) {
796 vios->Stream()
797 << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
798 << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
799 << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
800 << "\n";
801 }
802
803 for (const FieldResolution& entry : dep.second->fields_) {
804 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
805 vios->Stream()
806 << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
807 << dex_file.GetFieldName(field_id) << ":"
808 << dex_file.GetFieldTypeDescriptor(field_id)
809 << " is expected to be ";
810 if (!entry.IsResolved()) {
811 vios->Stream() << "unresolved\n";
812 } else {
813 vios->Stream()
814 << "in class "
815 << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
816 << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
817 << "\n";
818 }
819 }
820
821 for (const auto& entry :
822 { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_),
823 std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_),
824 std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) {
825 for (const MethodResolution& method : entry.second) {
826 const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
827 vios->Stream()
828 << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
829 << dex_file.GetMethodName(method_id)
830 << dex_file.GetMethodSignature(method_id).ToString()
831 << " is expected to be ";
832 if (!method.IsResolved()) {
833 vios->Stream() << "unresolved\n";
834 } else {
835 vios->Stream()
836 << "in class "
837 << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
838 << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
839 << ", and be of kind " << entry.first
840 << "\n";
841 }
842 }
843 }
844
Andreas Gampea5b09a62016-11-17 15:21:22 -0800845 for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100846 vios->Stream()
847 << dex_file.StringByTypeIdx(type_index)
848 << " is expected to be verified at runtime\n";
849 }
850 }
851}
852
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000853bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
854 Thread* self) const {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100855 for (const auto& entry : dex_deps_) {
856 if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
857 return false;
858 }
859 }
860 return true;
861}
862
863// TODO: share that helper with other parts of the compiler that have
864// the same lookup pattern.
865static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
866 Thread* self,
867 const char* name,
868 Handle<mirror::ClassLoader> class_loader)
869 REQUIRES_SHARED(Locks::mutator_lock_) {
870 mirror::Class* result = class_linker->FindClass(self, name, class_loader);
871 if (result == nullptr) {
872 DCHECK(self->IsExceptionPending());
873 self->ClearException();
874 }
875 return result;
876}
877
878bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
879 const DexFile& dex_file,
880 const std::set<TypeAssignability>& assignables,
881 bool expected_assignability,
882 Thread* self) const {
883 StackHandleScope<2> hs(self);
884 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
885 MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
886 MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
887
888 for (const auto& entry : assignables) {
889 const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
890 destination.Assign(
891 FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
892 const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
893 source.Assign(
894 FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
895
Andreas Gampefa4333d2017-02-14 11:10:34 -0800896 if (destination == nullptr) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100897 LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
898 return false;
899 }
900
Andreas Gampefa4333d2017-02-14 11:10:34 -0800901 if (source == nullptr) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100902 LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
903 return false;
904 }
905
906 DCHECK(destination->IsResolved() && source->IsResolved());
907 if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
908 LOG(INFO) << "VerifierDeps: Class "
909 << destination_desc
910 << (expected_assignability ? " not " : " ")
911 << "assignable from "
912 << source_desc;
913 return false;
914 }
915 }
916 return true;
917}
918
919bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
920 const DexFile& dex_file,
921 const std::set<ClassResolution>& classes,
922 Thread* self) const {
923 StackHandleScope<1> hs(self);
924 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
925 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
926 for (const auto& entry : classes) {
927 const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
928 cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
929
930 if (entry.IsResolved()) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800931 if (cls == nullptr) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100932 LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
933 return false;
934 } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
935 LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
936 << descriptor
937 << std::hex
938 << " (expected="
939 << entry.GetAccessFlags()
940 << ", actual="
941 << GetAccessFlags(cls.Get()) << ")"
942 << std::dec;
943 return false;
944 }
Andreas Gampefa4333d2017-02-14 11:10:34 -0800945 } else if (cls != nullptr) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100946 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
947 return false;
948 }
949 }
950 return true;
951}
952
953static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
954 const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
955 return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
956 + "->"
957 + dex_file.GetFieldName(field_id)
958 + ":"
959 + dex_file.GetFieldTypeDescriptor(field_id);
960}
961
962bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
963 const DexFile& dex_file,
964 const std::set<FieldResolution>& fields,
965 Thread* self) const {
966 // Check recorded fields are resolved the same way, have the same recorded class,
967 // and have the same recorded flags.
968 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100969 for (const auto& entry : fields) {
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000970 const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
971 StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
972 StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
973 // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
974 // Otherwise, we might end up resolving an application class, which is expensive.
975 std::string expected_decl_klass = entry.IsResolved()
976 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
977 : dex_file.StringByTypeIdx(field_id.class_idx_);
978 mirror::Class* cls = FindClassAndClearException(
979 class_linker, self, expected_decl_klass.c_str(), class_loader);
980 if (cls == nullptr) {
981 LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
982 return false;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100983 }
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000984 DCHECK(cls->IsResolved());
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100985
Nicolas Geoffray865cf902017-01-18 14:34:48 +0000986 ArtField* field = mirror::Class::FindField(self, cls, name, type);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100987 if (entry.IsResolved()) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100988 std::string temp;
989 if (field == nullptr) {
990 LOG(INFO) << "VerifierDeps: Could not resolve field "
991 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
992 return false;
993 } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
994 LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
995 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
996 << " (expected=" << expected_decl_klass
997 << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
998 return false;
999 } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
1000 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
1001 << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
1002 << std::hex << " (expected=" << entry.GetAccessFlags()
1003 << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
1004 return false;
1005 }
1006 } else if (field != nullptr) {
1007 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
1008 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
1009 return false;
1010 }
1011 }
1012 return true;
1013}
1014
1015static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
1016 const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
1017 return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
1018 + "->"
1019 + dex_file.GetMethodName(method_id)
1020 + dex_file.GetMethodSignature(method_id).ToString();
1021}
1022
1023bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
1024 const DexFile& dex_file,
1025 const std::set<MethodResolution>& methods,
1026 MethodResolutionKind kind,
1027 Thread* self) const {
1028 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1029 PointerSize pointer_size = class_linker->GetImagePointerSize();
1030
1031 for (const auto& entry : methods) {
1032 const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
1033
1034 const char* name = dex_file.GetMethodName(method_id);
1035 const Signature signature = dex_file.GetMethodSignature(method_id);
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001036 // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
1037 // Otherwise, we might end up resolving an application class, which is expensive.
1038 std::string expected_decl_klass = entry.IsResolved()
1039 ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
1040 : dex_file.StringByTypeIdx(method_id.class_idx_);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001041
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001042 mirror::Class* cls = FindClassAndClearException(
1043 class_linker, self, expected_decl_klass.c_str(), class_loader);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001044 if (cls == nullptr) {
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001045 LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001046 return false;
1047 }
1048 DCHECK(cls->IsResolved());
1049 ArtMethod* method = nullptr;
1050 if (kind == kDirectMethodResolution) {
1051 method = cls->FindDirectMethod(name, signature, pointer_size);
1052 } else if (kind == kVirtualMethodResolution) {
1053 method = cls->FindVirtualMethod(name, signature, pointer_size);
1054 } else {
1055 DCHECK_EQ(kind, kInterfaceMethodResolution);
1056 method = cls->FindInterfaceMethod(name, signature, pointer_size);
1057 }
1058
1059 if (entry.IsResolved()) {
1060 std::string temp;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001061 if (method == nullptr) {
1062 LOG(INFO) << "VerifierDeps: Could not resolve "
1063 << kind
1064 << " method "
1065 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1066 return false;
1067 } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
1068 LOG(INFO) << "VerifierDeps: Unexpected declaring class for "
1069 << kind
1070 << " method resolution "
1071 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1072 << " (expected="
1073 << expected_decl_klass
1074 << ", actual="
1075 << method->GetDeclaringClass()->GetDescriptor(&temp)
1076 << ")";
1077 return false;
1078 } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
1079 LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved "
1080 << kind
1081 << " method resolution "
1082 << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
1083 << std::hex
1084 << " (expected="
1085 << entry.GetAccessFlags()
1086 << ", actual="
1087 << GetAccessFlags(method) << ")"
1088 << std::dec;
1089 return false;
1090 }
1091 } else if (method != nullptr) {
1092 LOG(INFO) << "VerifierDeps: Unexpected successful resolution of "
1093 << kind
1094 << " method "
1095 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
1096 return false;
1097 }
1098 }
1099 return true;
1100}
1101
1102bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
1103 const DexFile& dex_file,
1104 const DexFileDeps& deps,
1105 Thread* self) const {
1106 bool result = VerifyAssignability(
1107 class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
1108 result = result && VerifyAssignability(
1109 class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
1110
1111 result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
1112 result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
1113
1114 result = result && VerifyMethods(
1115 class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self);
1116 result = result && VerifyMethods(
1117 class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self);
1118 result = result && VerifyMethods(
1119 class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self);
1120
1121 return result;
1122}
1123
David Brazdilca3c8c32016-09-06 14:04:48 +01001124} // namespace verifier
1125} // namespace art