blob: 52765f9e73c4f8e7dedec1f91f1da84972bd0510 [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
Nicolas Geoffray08025182016-10-25 17:20:18 +010017// Test is in compiler, as it uses compiler related code.
18#include "verifier/verifier_deps.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010019
20#include "class_linker.h"
Nicolas Geoffray08025182016-10-25 17:20:18 +010021#include "compiler/common_compiler_test.h"
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +000022#include "compiler/dex/verification_results.h"
23#include "compiler/dex/verified_method.h"
Nicolas Geoffray08025182016-10-25 17:20:18 +010024#include "compiler/driver/compiler_options.h"
25#include "compiler/driver/compiler_driver.h"
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +000026#include "compiler/utils/atomic_method_ref_map-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010027#include "compiler_callbacks.h"
28#include "dex_file.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080029#include "dex_file_types.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010030#include "handle_scope-inl.h"
Nicolas Geoffray08025182016-10-25 17:20:18 +010031#include "verifier/method_verifier-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010032#include "mirror/class_loader.h"
33#include "runtime.h"
34#include "thread.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070035#include "scoped_thread_state_change-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010036
37namespace art {
38namespace verifier {
39
40class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
41 public:
42 explicit VerifierDepsCompilerCallbacks()
43 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
44 deps_(nullptr) {}
45
46 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE {}
47 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) OVERRIDE {}
48 bool IsRelocationPossible() OVERRIDE { return false; }
49
50 verifier::VerifierDeps* GetVerifierDeps() const OVERRIDE { return deps_; }
51 void SetVerifierDeps(verifier::VerifierDeps* deps) { deps_ = deps; }
52
53 private:
54 verifier::VerifierDeps* deps_;
55};
56
Nicolas Geoffray08025182016-10-25 17:20:18 +010057class VerifierDepsTest : public CommonCompilerTest {
David Brazdilca3c8c32016-09-06 14:04:48 +010058 public:
59 void SetUpRuntimeOptions(RuntimeOptions* options) {
Nicolas Geoffray08025182016-10-25 17:20:18 +010060 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010061 callbacks_.reset(new VerifierDepsCompilerCallbacks());
62 }
63
64 mirror::Class* FindClassByName(const std::string& name, ScopedObjectAccess* soa)
65 REQUIRES_SHARED(Locks::mutator_lock_) {
66 StackHandleScope<1> hs(Thread::Current());
67 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -070068 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_)));
David Brazdil6f82fbd2016-09-14 11:55:26 +010069 mirror::Class* klass = class_linker_->FindClass(Thread::Current(),
70 name.c_str(),
71 class_loader_handle);
72 if (klass == nullptr) {
73 DCHECK(Thread::Current()->IsExceptionPending());
74 Thread::Current()->ClearException();
75 }
76 return klass;
77 }
78
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000079 void SetupCompilerDriver() {
80 compiler_options_->boot_image_ = false;
81 compiler_driver_->InitializeThreadPools();
82 }
83
84 void VerifyWithCompilerDriver(verifier::VerifierDeps* deps) {
85 TimingLogger timings("Verify", false, false);
86 // The compiler driver handles the verifier deps in the callbacks, so
87 // remove what this class did for unit testing.
88 verifier_deps_.reset(nullptr);
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000089 callbacks_->SetVerifierDeps(deps);
90 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000091 // The compiler driver may have updated the VerifierDeps in the callback object.
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000092 if (callbacks_->GetVerifierDeps() != deps) {
93 verifier_deps_.reset(callbacks_->GetVerifierDeps());
94 }
95 callbacks_->SetVerifierDeps(nullptr);
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +000096 // Clear entries in the verification results to avoid hitting a DCHECK that
97 // we always succeed inserting a new entry after verifying.
98 AtomicMethodRefMap<const VerifiedMethod*>* map =
99 &compiler_driver_->GetVerificationResults()->atomic_verified_methods_;
100 map->Visit([](const MethodReference& ref ATTRIBUTE_UNUSED, const VerifiedMethod* method) {
101 delete method;
102 });
103 map->ClearEntries();
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000104 }
105
David Brazdil6f82fbd2016-09-14 11:55:26 +0100106 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
107 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
108 VerifierDepsCompilerCallbacks* callbacks =
109 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
110 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +0100111 }
112
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100113 void LoadDexFile(ScopedObjectAccess* soa, const char* name1, const char* name2 = nullptr)
114 REQUIRES_SHARED(Locks::mutator_lock_) {
115 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
116 dex_files_ = GetDexFiles(class_loader_);
117 primary_dex_file_ = dex_files_.front();
118
119 SetVerifierDeps(dex_files_);
120 StackHandleScope<1> hs(soa->Self());
121 Handle<mirror::ClassLoader> loader =
122 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_));
123 for (const DexFile* dex_file : dex_files_) {
124 class_linker_->RegisterDexFile(*dex_file, loader.Get());
125 }
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +0000126 for (const DexFile* dex_file : dex_files_) {
127 compiler_driver_->GetVerificationResults()->AddDexFile(dex_file);
128 }
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100129 }
130
David Brazdilca3c8c32016-09-06 14:04:48 +0100131 void LoadDexFile(ScopedObjectAccess* soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100132 LoadDexFile(soa, "VerifierDeps");
133 CHECK_EQ(dex_files_.size(), 1u);
David Brazdilca3c8c32016-09-06 14:04:48 +0100134 klass_Main_ = FindClassByName("LMain;", soa);
135 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100136 }
137
138 bool VerifyMethod(const std::string& method_name) {
139 ScopedObjectAccess soa(Thread::Current());
140 LoadDexFile(&soa);
141
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100142 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100143 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700144 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100145 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
146
147 const DexFile::ClassDef* class_def = klass_Main_->GetClassDef();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100148 const uint8_t* class_data = primary_dex_file_->GetClassData(*class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100149 CHECK(class_data != nullptr);
150
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100151 ClassDataItemIterator it(*primary_dex_file_, class_data);
David Brazdilca3c8c32016-09-06 14:04:48 +0100152 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
153 it.Next();
154 }
155
156 ArtMethod* method = nullptr;
157 while (it.HasNextDirectMethod()) {
158 ArtMethod* resolved_method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100159 *primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100160 it.GetMemberIndex(),
161 dex_cache_handle,
162 class_loader_handle,
163 nullptr,
164 it.GetMethodInvokeType(*class_def));
165 CHECK(resolved_method != nullptr);
166 if (method_name == resolved_method->GetName()) {
167 method = resolved_method;
168 break;
169 }
170 it.Next();
171 }
172 CHECK(method != nullptr);
173
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000174 Thread::Current()->SetVerifierDeps(callbacks_->GetVerifierDeps());
David Brazdilca3c8c32016-09-06 14:04:48 +0100175 MethodVerifier verifier(Thread::Current(),
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100176 primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100177 dex_cache_handle,
178 class_loader_handle,
179 *class_def,
180 it.GetMethodCodeItem(),
181 it.GetMemberIndex(),
182 method,
183 it.GetMethodAccessFlags(),
184 true /* can_load_classes */,
185 true /* allow_soft_failures */,
186 true /* need_precise_constants */,
187 false /* verify to dump */,
188 true /* allow_thread_suspension */);
189 verifier.Verify();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000190 Thread::Current()->SetVerifierDeps(nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100191 return !verifier.HasFailures();
192 }
193
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100194 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100195 {
196 ScopedObjectAccess soa(Thread::Current());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100197 LoadDexFile(&soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100198 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000199 SetupCompilerDriver();
200 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100201 }
202
David Brazdilca3c8c32016-09-06 14:04:48 +0100203 bool TestAssignabilityRecording(const std::string& dst,
204 const std::string& src,
205 bool is_strict,
206 bool is_assignable) {
207 ScopedObjectAccess soa(Thread::Current());
208 LoadDexFile(&soa);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100209 mirror::Class* klass_dst = FindClassByName(dst, &soa);
210 DCHECK(klass_dst != nullptr);
211 mirror::Class* klass_src = FindClassByName(src, &soa);
212 DCHECK(klass_src != nullptr);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100213 verifier_deps_->AddAssignability(*primary_dex_file_,
David Brazdil6f82fbd2016-09-14 11:55:26 +0100214 klass_dst,
215 klass_src,
David Brazdilca3c8c32016-09-06 14:04:48 +0100216 is_strict,
217 is_assignable);
218 return true;
219 }
220
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000221 // Check that the status of classes in `class_loader_` match the
222 // expected status in `deps`.
223 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
224 ScopedObjectAccess soa(Thread::Current());
225 StackHandleScope<2> hs(soa.Self());
226 Handle<mirror::ClassLoader> class_loader_handle(
227 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
228 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
229 for (const DexFile* dex_file : dex_files_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800230 const std::vector<dex::TypeIndex>& unverified_classes = deps.GetUnverifiedClasses(*dex_file);
231 std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end());
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000232 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
233 const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
234 const char* descriptor = dex_file->GetClassDescriptor(class_def);
235 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
236 if (cls.Get() == nullptr) {
237 CHECK(soa.Self()->IsExceptionPending());
238 soa.Self()->ClearException();
239 } else if (set.find(class_def.class_idx_) == set.end()) {
240 ASSERT_EQ(cls->GetStatus(), mirror::Class::kStatusVerified);
241 } else {
242 ASSERT_LT(cls->GetStatus(), mirror::Class::kStatusVerified);
243 }
244 }
245 }
246 }
247
Nicolas Geoffray08025182016-10-25 17:20:18 +0100248 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100249 const DexFile::TypeId* type_id = primary_dex_file_->FindTypeId(cls.c_str());
Nicolas Geoffray08025182016-10-25 17:20:18 +0100250 DCHECK(type_id != nullptr);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800251 dex::TypeIndex index = primary_dex_file_->GetIndexForTypeId(*type_id);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100252 for (const auto& dex_dep : verifier_deps_->dex_deps_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800253 for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100254 if (index == entry) {
255 return true;
256 }
257 }
258 }
259 return false;
260 }
261
David Brazdilca3c8c32016-09-06 14:04:48 +0100262 // Iterates over all assignability records and tries to find an entry which
263 // matches the expected destination/source pair.
264 bool HasAssignable(const std::string& expected_destination,
265 const std::string& expected_source,
266 bool expected_is_assignable) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100267 for (auto& dex_dep : verifier_deps_->dex_deps_) {
268 const DexFile& dex_file = *dex_dep.first;
269 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
270 : dex_dep.second->unassignable_types_;
271 for (auto& entry : storage) {
272 std::string actual_destination =
273 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
274 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
275 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
276 return true;
277 }
278 }
279 }
280 return false;
281 }
282
283 // Iterates over all class resolution records, finds an entry which matches
284 // the given class descriptor and tests its properties.
285 bool HasClass(const std::string& expected_klass,
286 bool expected_resolved,
287 const std::string& expected_access_flags = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100288 for (auto& dex_dep : verifier_deps_->dex_deps_) {
289 for (auto& entry : dex_dep.second->classes_) {
290 if (expected_resolved != entry.IsResolved()) {
291 continue;
292 }
293
294 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
295 if (expected_klass != actual_klass) {
296 continue;
297 }
298
299 if (expected_resolved) {
300 // Test access flags. Note that PrettyJavaAccessFlags always appends
301 // a space after the modifiers. Add it to the expected access flags.
302 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
303 if (expected_access_flags + " " != actual_access_flags) {
304 continue;
305 }
306 }
307
308 return true;
309 }
310 }
311 return false;
312 }
313
314 // Iterates over all field resolution records, finds an entry which matches
315 // the given field class+name+type and tests its properties.
316 bool HasField(const std::string& expected_klass,
317 const std::string& expected_name,
318 const std::string& expected_type,
319 bool expected_resolved,
320 const std::string& expected_access_flags = "",
321 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100322 for (auto& dex_dep : verifier_deps_->dex_deps_) {
323 for (auto& entry : dex_dep.second->fields_) {
324 if (expected_resolved != entry.IsResolved()) {
325 continue;
326 }
327
328 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
329
330 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
331 if (expected_klass != actual_klass) {
332 continue;
333 }
334
335 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
336 if (expected_name != actual_name) {
337 continue;
338 }
339
340 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
341 if (expected_type != actual_type) {
342 continue;
343 }
344
345 if (expected_resolved) {
346 // Test access flags. Note that PrettyJavaAccessFlags always appends
347 // a space after the modifiers. Add it to the expected access flags.
348 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
349 if (expected_access_flags + " " != actual_access_flags) {
350 continue;
351 }
352
353 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
354 *dex_dep.first, entry.GetDeclaringClassIndex());
355 if (expected_decl_klass != actual_decl_klass) {
356 continue;
357 }
358 }
359
360 return true;
361 }
362 }
363 return false;
364 }
365
366 // Iterates over all method resolution records, finds an entry which matches
367 // the given field kind+class+name+signature and tests its properties.
368 bool HasMethod(const std::string& expected_kind,
369 const std::string& expected_klass,
370 const std::string& expected_name,
371 const std::string& expected_signature,
372 bool expected_resolved,
373 const std::string& expected_access_flags = "",
374 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100375 for (auto& dex_dep : verifier_deps_->dex_deps_) {
376 auto& storage = (expected_kind == "direct") ? dex_dep.second->direct_methods_
377 : (expected_kind == "virtual") ? dex_dep.second->virtual_methods_
378 : dex_dep.second->interface_methods_;
379 for (auto& entry : storage) {
380 if (expected_resolved != entry.IsResolved()) {
381 continue;
382 }
383
384 const DexFile::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
385
386 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_);
387 if (expected_klass != actual_klass) {
388 continue;
389 }
390
391 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_);
392 if (expected_name != actual_name) {
393 continue;
394 }
395
396 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString();
397 if (expected_signature != actual_signature) {
398 continue;
399 }
400
401 if (expected_resolved) {
402 // Test access flags. Note that PrettyJavaAccessFlags always appends
403 // a space after the modifiers. Add it to the expected access flags.
404 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
405 if (expected_access_flags + " " != actual_access_flags) {
406 continue;
407 }
408
409 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
410 *dex_dep.first, entry.GetDeclaringClassIndex());
411 if (expected_decl_klass != actual_decl_klass) {
412 continue;
413 }
414 }
415
416 return true;
417 }
418 }
419 return false;
420 }
421
David Brazdil6f82fbd2016-09-14 11:55:26 +0100422 size_t NumberOfCompiledDexFiles() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100423 return verifier_deps_->dex_deps_.size();
424 }
425
426 size_t HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100427 bool has_strings = false;
428 bool has_assignability = false;
429 bool has_classes = false;
430 bool has_fields = false;
431 bool has_methods = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100432 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100433
434 for (auto& entry : verifier_deps_->dex_deps_) {
435 has_strings |= !entry.second->strings_.empty();
436 has_assignability |= !entry.second->assignable_types_.empty();
437 has_assignability |= !entry.second->unassignable_types_.empty();
438 has_classes |= !entry.second->classes_.empty();
439 has_fields |= !entry.second->fields_.empty();
440 has_methods |= !entry.second->direct_methods_.empty();
441 has_methods |= !entry.second->virtual_methods_.empty();
442 has_methods |= !entry.second->interface_methods_.empty();
Nicolas Geoffray08025182016-10-25 17:20:18 +0100443 has_unverified_classes |= !entry.second->unverified_classes_.empty();
David Brazdil6f82fbd2016-09-14 11:55:26 +0100444 }
445
Nicolas Geoffray08025182016-10-25 17:20:18 +0100446 return has_strings &&
447 has_assignability &&
448 has_classes &&
449 has_fields &&
450 has_methods &&
451 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100452 }
453
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100454 static std::set<VerifierDeps::MethodResolution>* GetMethods(
455 VerifierDeps::DexFileDeps* deps, MethodResolutionKind resolution_kind) {
456 if (resolution_kind == kDirectMethodResolution) {
457 return &deps->direct_methods_;
458 } else if (resolution_kind == kVirtualMethodResolution) {
459 return &deps->virtual_methods_;
460 } else {
461 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
462 return &deps->interface_methods_;
463 }
464 }
465
David Brazdilca3c8c32016-09-06 14:04:48 +0100466 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100467 std::vector<const DexFile*> dex_files_;
468 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100469 jobject class_loader_;
470 mirror::Class* klass_Main_;
471};
472
473TEST_F(VerifierDepsTest, StringToId) {
474 ScopedObjectAccess soa(Thread::Current());
475 LoadDexFile(&soa);
476
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800477 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
478 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100479 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100480
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800481 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
482 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100483 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100484
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800485 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
486 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100487 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100488
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
490 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100491 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100492
493 ASSERT_EQ(id_Main1, id_Main2);
494 ASSERT_EQ(id_Lorem1, id_Lorem2);
495 ASSERT_NE(id_Main1, id_Lorem1);
496}
497
498TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
499 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
500 /* src */ "Ljava/util/SimpleTimeZone;",
501 /* is_strict */ true,
502 /* is_assignable */ true));
503 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
504}
505
506TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
507 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
508 /* src */ "LMySSLSocket;",
509 /* is_strict */ true,
510 /* is_assignable */ true));
511 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "LMySSLSocket;", true));
512}
513
514TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
515 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
516 /* src */ "LMySimpleTimeZone;",
517 /* is_strict */ true,
518 /* is_assignable */ true));
519 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "LMySimpleTimeZone;", true));
520}
521
522TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
523 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
524 /* src */ "LMyThreadSet;",
525 /* is_strict */ true,
526 /* is_assignable */ true));
527 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "LMyThreadSet;", true));
528}
529
530TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
531 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
532 /* src */ "[[Ljava/util/SimpleTimeZone;",
533 /* is_strict */ true,
534 /* is_assignable */ true));
535 // If the component types of both arrays are resolved, we optimize the list of
536 // dependencies by recording a dependency on the component types.
537 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
538 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
539 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
540}
541
542TEST_F(VerifierDepsTest, Assignable_BothArrays_Erroneous) {
543 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
544 /* src */ "[[LMyErroneousTimeZone;",
545 /* is_strict */ true,
546 /* is_assignable */ true));
547 // If the component type of an array is erroneous, we record the dependency on
548 // the array type.
549 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[LMyErroneousTimeZone;", true));
550 ASSERT_TRUE(HasAssignable("[Ljava/util/TimeZone;", "[LMyErroneousTimeZone;", true));
551 ASSERT_FALSE(HasAssignable("Ljava/util/TimeZone;", "LMyErroneousTimeZone;", true));
552}
553
554 // We test that VerifierDeps does not try to optimize by storing assignability
555 // of the component types. This is due to the fact that the component type may
556 // be an erroneous class, even though the array type has resolved status.
557
558TEST_F(VerifierDepsTest, Assignable_ArrayToInterface1) {
559 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
560 /* src */ "[Ljava/util/TimeZone;",
561 /* is_strict */ true,
562 /* is_assignable */ true));
563 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[Ljava/util/TimeZone;", true));
564}
565
566TEST_F(VerifierDepsTest, Assignable_ArrayToInterface2) {
567 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
568 /* src */ "[LMyThreadSet;",
569 /* is_strict */ true,
570 /* is_assignable */ true));
571 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[LMyThreadSet;", true));
572}
573
574TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
575 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
576 /* src */ "Ljava/util/SimpleTimeZone;",
577 /* is_strict */ true,
578 /* is_assignable */ false));
579 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
580}
581
582TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
583 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
584 /* src */ "LMySSLSocket;",
585 /* is_strict */ true,
586 /* is_assignable */ false));
587 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySSLSocket;", false));
588}
589
590TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
591 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
592 /* src */ "LMySimpleTimeZone;",
593 /* is_strict */ true,
594 /* is_assignable */ false));
595 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySimpleTimeZone;", false));
596}
597
598TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
599 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
600 /* src */ "[Ljava/util/SimpleTimeZone;",
601 /* is_strict */ true,
602 /* is_assignable */ false));
603 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
604}
605
606TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
607 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
608 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
609}
610
611TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
612 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
613 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public final abstract"));
614}
615
616TEST_F(VerifierDepsTest, ArgumentType_ResolvedPrimitiveArray) {
617 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedPrimitiveArray"));
618 ASSERT_TRUE(HasClass("[B", true, "public final abstract"));
619}
620
621TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
622 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
623 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
624}
625
626TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
627 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
628 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
629}
630
631TEST_F(VerifierDepsTest, ReturnType_Reference) {
632 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
633 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
634}
635
636TEST_F(VerifierDepsTest, ReturnType_Array) {
637 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
638 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
639}
640
641TEST_F(VerifierDepsTest, InvokeArgumentType) {
642 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
643 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
644 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
645 ASSERT_TRUE(HasMethod("virtual",
646 "Ljava/text/SimpleDateFormat;",
647 "setTimeZone",
648 "(Ljava/util/TimeZone;)V",
649 true,
650 "public",
651 "Ljava/text/DateFormat;"));
652 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
653}
654
655TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
656 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
657 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;", true));
658 ASSERT_TRUE(HasAssignable(
659 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
660}
661
662TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
663 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
664 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
665 ASSERT_TRUE(HasAssignable(
666 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
667 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
668}
669
670TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
671 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
672 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
673 ASSERT_TRUE(HasAssignable(
674 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
675}
676
677TEST_F(VerifierDepsTest, ConstClass_Resolved) {
678 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
679 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
680}
681
682TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
683 ASSERT_TRUE(VerifyMethod("ConstClass_Unresolved"));
684 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
685}
686
687TEST_F(VerifierDepsTest, CheckCast_Resolved) {
688 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
689 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
690}
691
692TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
693 ASSERT_TRUE(VerifyMethod("CheckCast_Unresolved"));
694 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
695}
696
697TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
698 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
699 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
700}
701
702TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
703 ASSERT_TRUE(VerifyMethod("InstanceOf_Unresolved"));
704 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
705}
706
707TEST_F(VerifierDepsTest, NewInstance_Resolved) {
708 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
709 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
710}
711
712TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
713 ASSERT_TRUE(VerifyMethod("NewInstance_Unresolved"));
714 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
715}
716
717TEST_F(VerifierDepsTest, NewArray_Resolved) {
718 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
719 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public final abstract"));
720}
721
722TEST_F(VerifierDepsTest, NewArray_Unresolved) {
723 ASSERT_TRUE(VerifyMethod("NewArray_Unresolved"));
724 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
725}
726
727TEST_F(VerifierDepsTest, Throw) {
728 ASSERT_TRUE(VerifyMethod("Throw"));
729 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
730}
731
732TEST_F(VerifierDepsTest, MoveException_Resolved) {
733 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
734 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
735 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
736 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
737
738 // Testing that all exception types are assignable to Throwable.
739 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
740 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
741 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
742
743 // Testing that the merge type is assignable to Throwable.
744 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
745
746 // Merging of exception types.
747 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
748 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
749 ASSERT_TRUE(HasAssignable(
750 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
751}
752
753TEST_F(VerifierDepsTest, MoveException_Unresolved) {
754 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
755 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
756}
757
758TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
759 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
760 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public final"));
761 ASSERT_TRUE(HasField("Ljava/lang/System;",
762 "out",
763 "Ljava/io/PrintStream;",
764 true,
765 "public final static",
766 "Ljava/lang/System;"));
767}
768
769TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
770 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
771 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
772 ASSERT_TRUE(HasField(
773 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public final static", "Ljava/util/TimeZone;"));
774}
775
776TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
777 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
778 ASSERT_TRUE(HasField(
779 "LMySimpleTimeZone;", "SHORT", "I", true, "public final static", "Ljava/util/TimeZone;"));
780}
781
782TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
783 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
784 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
785 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
786 "PI_ENABLE_OUTPUT_ESCAPING",
787 "Ljava/lang/String;",
788 true,
789 "public final static",
790 "Ljavax/xml/transform/Result;"));
791}
792
793TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
794 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
795 ASSERT_TRUE(HasField("LMyDOMResult;",
796 "PI_ENABLE_OUTPUT_ESCAPING",
797 "Ljava/lang/String;",
798 true,
799 "public final static",
800 "Ljavax/xml/transform/Result;"));
801}
802
803TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
804 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
805 ASSERT_TRUE(HasField("LMyResult;",
806 "PI_ENABLE_OUTPUT_ESCAPING",
807 "Ljava/lang/String;",
808 true,
809 "public final static",
810 "Ljavax/xml/transform/Result;"));
811}
812
813TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
814 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
815 ASSERT_TRUE(HasField("LMyDocument;",
816 "ELEMENT_NODE",
817 "S",
818 true,
819 "public final static",
820 "Lorg/w3c/dom/Node;"));
821}
822
823TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
824 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
825 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public abstract"));
826 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
827}
828
829TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
830 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
831 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
832}
833
834TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
835 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
836 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
837 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
838 "bytesTransferred",
839 "I",
840 true,
841 "public",
842 "Ljava/io/InterruptedIOException;"));
843 ASSERT_TRUE(HasAssignable(
844 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
845}
846
847TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
848 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
849 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
850 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
851 "bytesTransferred",
852 "I",
853 true,
854 "public",
855 "Ljava/io/InterruptedIOException;"));
856 ASSERT_TRUE(HasAssignable(
857 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
858}
859
860TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
861 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
862 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
863 "bytesTransferred",
864 "I",
865 true,
866 "public",
867 "Ljava/io/InterruptedIOException;"));
868 ASSERT_TRUE(HasAssignable(
869 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
870}
871
872TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
873 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
874 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
875 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
876}
877
878TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
879 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
880 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
881}
882
883TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
884 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
885 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
886 ASSERT_TRUE(HasMethod("direct",
887 "Ljava/net/Socket;",
888 "setSocketImplFactory",
889 "(Ljava/net/SocketImplFactory;)V",
890 true,
891 "public static",
892 "Ljava/net/Socket;"));
893}
894
895TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
896 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
897 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
898 ASSERT_TRUE(HasMethod("direct",
899 "Ljavax/net/ssl/SSLSocket;",
900 "setSocketImplFactory",
901 "(Ljava/net/SocketImplFactory;)V",
902 true,
903 "public static",
904 "Ljava/net/Socket;"));
905}
906
907TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
908 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
909 ASSERT_TRUE(HasMethod("direct",
910 "LMySSLSocket;",
911 "setSocketImplFactory",
912 "(Ljava/net/SocketImplFactory;)V",
913 true,
914 "public static",
915 "Ljava/net/Socket;"));
916}
917
918TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
919 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
920 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public abstract interface"));
921 ASSERT_TRUE(HasMethod("direct",
922 "Ljava/util/Map$Entry;",
923 "comparingByKey",
924 "()Ljava/util/Comparator;",
925 true,
926 "public static",
927 "Ljava/util/Map$Entry;"));
928}
929
930TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
931 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
932 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
933 ASSERT_TRUE(HasMethod("direct",
934 "Ljava/util/AbstractMap$SimpleEntry;",
935 "comparingByKey",
936 "()Ljava/util/Comparator;",
937 false));
938}
939
940TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
941 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
942 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
943 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
944}
945
946TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
947 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
948 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
949}
950
951TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
952 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
953 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
954 ASSERT_TRUE(HasMethod(
955 "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
956}
957
958TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
959 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
960 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
961 ASSERT_TRUE(HasMethod("direct",
962 "Ljavax/net/ssl/SSLSocket;",
963 "checkOldImpl",
964 "()V",
965 true,
966 "private",
967 "Ljava/net/Socket;"));
968}
969
970TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
971 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
972 ASSERT_TRUE(HasMethod(
973 "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
974}
975
976TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
977 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
978 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
979 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
980}
981
982TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
983 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
984 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
985}
986
987TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
988 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
989 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
990 ASSERT_TRUE(HasMethod("virtual",
991 "Ljava/lang/Throwable;",
992 "getMessage",
993 "()Ljava/lang/String;",
994 true,
995 "public",
996 "Ljava/lang/Throwable;"));
997 // Type dependency on `this` argument.
998 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
999}
1000
1001TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
1002 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
1003 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
1004 ASSERT_TRUE(HasMethod("virtual",
1005 "Ljava/io/InterruptedIOException;",
1006 "getMessage",
1007 "()Ljava/lang/String;",
1008 true,
1009 "public",
1010 "Ljava/lang/Throwable;"));
1011 // Type dependency on `this` argument.
1012 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
1013}
1014
1015TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
1016 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
1017 ASSERT_TRUE(HasMethod("virtual",
1018 "LMySocketTimeoutException;",
1019 "getMessage",
1020 "()Ljava/lang/String;",
1021 true,
1022 "public",
1023 "Ljava/lang/Throwable;"));
1024}
1025
1026TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
1027 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
1028 ASSERT_TRUE(HasMethod("virtual",
1029 "LMyThreadSet;",
1030 "size",
1031 "()I",
1032 true,
1033 "public abstract",
1034 "Ljava/util/Set;"));
1035}
1036
1037TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
1038 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
1039 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
1040 ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
1041}
1042
1043TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
1044 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
1045 ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
1046}
1047
1048TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
1049 ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
1050 ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
1051 ASSERT_TRUE(HasMethod("direct",
1052 "LMyThread;",
1053 "activeCount",
1054 "()I",
1055 true,
1056 "public static",
1057 "Ljava/lang/Thread;"));
1058}
1059
1060TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1061 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
1062 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1063 ASSERT_TRUE(HasMethod("interface",
1064 "Ljava/lang/Runnable;",
1065 "run",
1066 "()V",
1067 true,
1068 "public abstract",
1069 "Ljava/lang/Runnable;"));
1070}
1071
1072TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1073 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
1074 ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
1075}
1076
1077TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1078 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
1079 ASSERT_TRUE(HasMethod("interface",
1080 "LMyThreadSet;",
1081 "run",
1082 "()V",
1083 true,
1084 "public abstract",
1085 "Ljava/lang/Runnable;"));
1086}
1087
1088TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1089 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
1090 ASSERT_TRUE(HasMethod("interface",
1091 "LMyThreadSet;",
1092 "isEmpty",
1093 "()Z",
1094 true,
1095 "public abstract",
1096 "Ljava/util/Set;"));
1097}
1098
1099TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1100 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
1101 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1102 ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
1103}
1104
1105TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1106 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
1107 ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
1108}
1109
1110TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1111 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
1112 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1113 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;", true));
1114 ASSERT_TRUE(HasMethod("interface",
1115 "Ljava/lang/Runnable;",
1116 "run",
1117 "()V",
1118 true,
1119 "public abstract",
1120 "Ljava/lang/Runnable;"));
1121}
1122
1123TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1124 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
1125 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public final"));
1126 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "LMain;", false));
1127 ASSERT_TRUE(HasMethod(
1128 "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
1129}
1130
David Brazdil6f82fbd2016-09-14 11:55:26 +01001131TEST_F(VerifierDepsTest, EncodeDecode) {
1132 VerifyDexFile();
1133
1134 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1135 ASSERT_TRUE(HasEachKindOfRecord());
1136
1137 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001138 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001139 ASSERT_FALSE(buffer.empty());
1140
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001141 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001142 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1143}
1144
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001145TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1146 VerifyDexFile("MultiDex");
1147
1148 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1149 std::vector<uint8_t> buffer;
1150 verifier_deps_->Encode(dex_files_, &buffer);
1151 ASSERT_FALSE(buffer.empty());
1152
1153 // Create new DexFile, to mess with std::map order: the verifier deps used
1154 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1155 // this by passing the expected order when encoding/decoding.
1156 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1157 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1158 std::vector<const DexFile*> dex_files;
1159 for (auto& dex_file : first_dex_files) {
1160 dex_files.push_back(dex_file.get());
1161 }
1162 for (auto& dex_file : second_dex_files) {
1163 dex_files.push_back(dex_file.get());
1164 }
1165
1166 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001167 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001168 std::ostringstream stream;
1169 VariableIndentationOutputStream os(&stream);
1170 decoded_deps.Dump(&os);
1171}
1172
Nicolas Geoffray08025182016-10-25 17:20:18 +01001173TEST_F(VerifierDepsTest, UnverifiedClasses) {
1174 VerifyDexFile();
1175 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1176 // Test that a class with a soft failure is recorded.
1177 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1178 // Test that a class with hard failure is recorded.
1179 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1180 // Test that a class with unresolved super is recorded.
1181 ASSERT_FALSE(HasUnverifiedClass("LMyClassWithNoSuper;"));
1182 // Test that a class with unresolved super and hard failure is recorded.
1183 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1184}
1185
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001186// Returns the next resolution kind in the enum.
1187static MethodResolutionKind GetNextResolutionKind(MethodResolutionKind resolution_kind) {
1188 if (resolution_kind == kDirectMethodResolution) {
1189 return kVirtualMethodResolution;
1190 } else if (resolution_kind == kVirtualMethodResolution) {
1191 return kInterfaceMethodResolution;
1192 } else {
1193 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
1194 return kDirectMethodResolution;
1195 }
1196}
1197
1198TEST_F(VerifierDepsTest, VerifyDeps) {
1199 VerifyDexFile();
1200
1201 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1202 ASSERT_TRUE(HasEachKindOfRecord());
1203
1204 // When validating, we create a new class loader, as
1205 // the existing `class_loader_` may contain erroneous classes,
1206 // that ClassLinker::FindClass won't return.
1207
1208 ScopedObjectAccess soa(Thread::Current());
1209 StackHandleScope<1> hs(soa.Self());
1210 MutableHandle<mirror::ClassLoader> new_class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
1211 {
1212 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001213 ASSERT_TRUE(verifier_deps_->ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001214 }
1215
1216 std::vector<uint8_t> buffer;
1217 verifier_deps_->Encode(dex_files_, &buffer);
1218 ASSERT_FALSE(buffer.empty());
1219
1220 {
1221 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1222 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001223 ASSERT_TRUE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001224 }
1225
1226 // Fiddle with the dependencies to make sure we catch any change and fail to verify.
1227
1228 {
1229 // Mess up with the assignable_types.
1230 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1231 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1232 deps->assignable_types_.insert(*deps->unassignable_types_.begin());
1233 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001234 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001235 }
1236
1237 {
1238 // Mess up with the unassignable_types.
1239 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1240 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1241 deps->unassignable_types_.insert(*deps->assignable_types_.begin());
1242 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001243 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001244 }
1245
1246 // Mess up with classes.
1247 {
1248 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1249 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1250 bool found = false;
1251 for (const auto& entry : deps->classes_) {
1252 if (entry.IsResolved()) {
1253 deps->classes_.insert(VerifierDeps::ClassResolution(
1254 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1255 found = true;
1256 break;
1257 }
1258 }
1259 ASSERT_TRUE(found);
1260 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001261 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001262 }
1263
1264 {
1265 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1266 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1267 bool found = false;
1268 for (const auto& entry : deps->classes_) {
1269 if (!entry.IsResolved()) {
1270 deps->classes_.insert(VerifierDeps::ClassResolution(
1271 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1272 found = true;
1273 break;
1274 }
1275 }
1276 ASSERT_TRUE(found);
1277 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001278 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001279 }
1280
1281 {
1282 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1283 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1284 bool found = false;
1285 for (const auto& entry : deps->classes_) {
1286 if (entry.IsResolved()) {
1287 deps->classes_.insert(VerifierDeps::ClassResolution(
1288 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1289 found = true;
1290 break;
1291 }
1292 }
1293 ASSERT_TRUE(found);
1294 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001295 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001296 }
1297
1298 // Mess up with fields.
1299 {
1300 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1301 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1302 bool found = false;
1303 for (const auto& entry : deps->fields_) {
1304 if (entry.IsResolved()) {
1305 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1306 VerifierDeps::kUnresolvedMarker,
1307 entry.GetDeclaringClassIndex()));
1308 found = true;
1309 break;
1310 }
1311 }
1312 ASSERT_TRUE(found);
1313 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001314 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001315 }
1316
1317 {
1318 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1319 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1320 bool found = false;
1321 for (const auto& entry : deps->fields_) {
1322 if (!entry.IsResolved()) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001323 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001324 deps->fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1325 VerifierDeps::kUnresolvedMarker - 1,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001326 kStringIndexZero));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001327 found = true;
1328 break;
1329 }
1330 }
1331 ASSERT_TRUE(found);
1332 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001333 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001334 }
1335
1336 {
1337 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1338 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1339 bool found = false;
1340 for (const auto& entry : deps->fields_) {
1341 if (entry.IsResolved()) {
1342 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1343 entry.GetAccessFlags() - 1,
1344 entry.GetDeclaringClassIndex()));
1345 found = true;
1346 break;
1347 }
1348 }
1349 ASSERT_TRUE(found);
1350 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001351 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001352 }
1353
1354 {
1355 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1356 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1357 bool found = false;
1358 for (const auto& entry : deps->fields_) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001359 constexpr dex::StringIndex kNewTypeIndex(0);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001360 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1361 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1362 entry.GetAccessFlags(),
1363 kNewTypeIndex));
1364 found = true;
1365 break;
1366 }
1367 }
1368 ASSERT_TRUE(found);
1369 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001370 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001371 }
1372
1373 // Mess up with methods.
1374 for (MethodResolutionKind resolution_kind :
1375 { kDirectMethodResolution, kVirtualMethodResolution, kInterfaceMethodResolution }) {
1376 {
1377 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1378 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1379 bool found = false;
1380 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1381 for (const auto& entry : *methods) {
1382 if (entry.IsResolved()) {
1383 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1384 VerifierDeps::kUnresolvedMarker,
1385 entry.GetDeclaringClassIndex()));
1386 found = true;
1387 break;
1388 }
1389 }
1390 ASSERT_TRUE(found);
1391 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001392 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001393 }
1394
1395 {
1396 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1397 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1398 bool found = false;
1399 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1400 for (const auto& entry : *methods) {
1401 if (!entry.IsResolved()) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001402 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001403 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1404 VerifierDeps::kUnresolvedMarker - 1,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001405 kStringIndexZero));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001406 found = true;
1407 break;
1408 }
1409 }
1410 ASSERT_TRUE(found);
1411 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001412 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001413 }
1414
1415 {
1416 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1417 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1418 bool found = false;
1419 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1420 for (const auto& entry : *methods) {
1421 if (entry.IsResolved()) {
1422 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1423 entry.GetAccessFlags() - 1,
1424 entry.GetDeclaringClassIndex()));
1425 found = true;
1426 break;
1427 }
1428 }
1429 ASSERT_TRUE(found);
1430 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001431 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001432 }
1433
1434 {
1435 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1436 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1437 bool found = false;
1438 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1439 for (const auto& entry : *methods) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001440 constexpr dex::StringIndex kNewTypeIndex(0);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001441 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1442 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1443 entry.GetAccessFlags(),
1444 kNewTypeIndex));
1445 found = true;
1446 break;
1447 }
1448 }
1449 ASSERT_TRUE(found);
1450 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001451 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001452 }
1453
1454 {
1455 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1456 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1457 bool found = false;
1458 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1459 for (const auto& entry : *methods) {
1460 if (entry.IsResolved()) {
1461 GetMethods(deps, GetNextResolutionKind(resolution_kind))->insert(
1462 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1463 entry.GetAccessFlags(),
1464 entry.GetDeclaringClassIndex()));
1465 found = true;
1466 }
1467 }
1468 ASSERT_TRUE(found);
1469 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001470 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001471 }
1472
1473 {
1474 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1475 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1476 bool found = false;
1477 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1478 for (const auto& entry : *methods) {
1479 if (entry.IsResolved()) {
1480 GetMethods(deps, GetNextResolutionKind(GetNextResolutionKind(resolution_kind)))->insert(
1481 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1482 entry.GetAccessFlags(),
1483 entry.GetDeclaringClassIndex()));
1484 found = true;
1485 }
1486 }
1487 ASSERT_TRUE(found);
1488 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001489 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1490 }
1491 }
1492}
1493
1494TEST_F(VerifierDepsTest, CompilerDriver) {
1495 SetupCompilerDriver();
1496
1497 // Test both multi-dex and single-dex configuration.
1498 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
1499 // Test that the compiler driver behaves as expected when the dependencies
1500 // verify and when they don't verify.
1501 for (bool verify_failure : { false, true }) {
1502 {
1503 ScopedObjectAccess soa(Thread::Current());
1504 LoadDexFile(&soa, "VerifierDeps", multi);
1505 }
1506 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
1507
1508 std::vector<uint8_t> buffer;
1509 verifier_deps_->Encode(dex_files_, &buffer);
1510
1511 {
1512 ScopedObjectAccess soa(Thread::Current());
1513 LoadDexFile(&soa, "VerifierDeps", multi);
1514 }
1515 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1516 if (verify_failure) {
1517 // Just taint the decoded VerifierDeps with one invalid entry.
1518 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1519 bool found = false;
1520 for (const auto& entry : deps->classes_) {
1521 if (entry.IsResolved()) {
1522 deps->classes_.insert(VerifierDeps::ClassResolution(
1523 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1524 found = true;
1525 break;
1526 }
1527 }
1528 ASSERT_TRUE(found);
1529 }
1530 VerifyWithCompilerDriver(&decoded_deps);
1531
1532 if (verify_failure) {
1533 ASSERT_FALSE(verifier_deps_ == nullptr);
1534 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
1535 } else {
1536 ASSERT_TRUE(verifier_deps_ == nullptr);
1537 VerifyClassStatus(decoded_deps);
1538 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001539 }
1540 }
1541}
1542
David Brazdilca3c8c32016-09-06 14:04:48 +01001543} // namespace verifier
1544} // namespace art