blob: 01c33591e5783a020d3315831f22bb3102380880 [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));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800236 if (cls == nullptr) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000237 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 Geoffray7cc3ae52017-03-07 14:33:37 +0000249 return HasUnverifiedClass(cls, *primary_dex_file_);
250 }
251
252 bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
253 const DexFile::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
Nicolas Geoffray08025182016-10-25 17:20:18 +0100254 DCHECK(type_id != nullptr);
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000255 dex::TypeIndex index = dex_file.GetIndexForTypeId(*type_id);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100256 for (const auto& dex_dep : verifier_deps_->dex_deps_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800257 for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100258 if (index == entry) {
259 return true;
260 }
261 }
262 }
263 return false;
264 }
265
David Brazdilca3c8c32016-09-06 14:04:48 +0100266 // Iterates over all assignability records and tries to find an entry which
267 // matches the expected destination/source pair.
268 bool HasAssignable(const std::string& expected_destination,
269 const std::string& expected_source,
270 bool expected_is_assignable) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100271 for (auto& dex_dep : verifier_deps_->dex_deps_) {
272 const DexFile& dex_file = *dex_dep.first;
273 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
274 : dex_dep.second->unassignable_types_;
275 for (auto& entry : storage) {
276 std::string actual_destination =
277 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
278 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
279 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
280 return true;
281 }
282 }
283 }
284 return false;
285 }
286
287 // Iterates over all class resolution records, finds an entry which matches
288 // the given class descriptor and tests its properties.
289 bool HasClass(const std::string& expected_klass,
290 bool expected_resolved,
291 const std::string& expected_access_flags = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100292 for (auto& dex_dep : verifier_deps_->dex_deps_) {
293 for (auto& entry : dex_dep.second->classes_) {
294 if (expected_resolved != entry.IsResolved()) {
295 continue;
296 }
297
298 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
299 if (expected_klass != actual_klass) {
300 continue;
301 }
302
303 if (expected_resolved) {
304 // Test access flags. Note that PrettyJavaAccessFlags always appends
305 // a space after the modifiers. Add it to the expected access flags.
306 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
307 if (expected_access_flags + " " != actual_access_flags) {
308 continue;
309 }
310 }
311
312 return true;
313 }
314 }
315 return false;
316 }
317
318 // Iterates over all field resolution records, finds an entry which matches
319 // the given field class+name+type and tests its properties.
320 bool HasField(const std::string& expected_klass,
321 const std::string& expected_name,
322 const std::string& expected_type,
323 bool expected_resolved,
324 const std::string& expected_access_flags = "",
325 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100326 for (auto& dex_dep : verifier_deps_->dex_deps_) {
327 for (auto& entry : dex_dep.second->fields_) {
328 if (expected_resolved != entry.IsResolved()) {
329 continue;
330 }
331
332 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
333
334 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
335 if (expected_klass != actual_klass) {
336 continue;
337 }
338
339 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
340 if (expected_name != actual_name) {
341 continue;
342 }
343
344 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
345 if (expected_type != actual_type) {
346 continue;
347 }
348
349 if (expected_resolved) {
350 // Test access flags. Note that PrettyJavaAccessFlags always appends
351 // a space after the modifiers. Add it to the expected access flags.
352 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
353 if (expected_access_flags + " " != actual_access_flags) {
354 continue;
355 }
356
357 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
358 *dex_dep.first, entry.GetDeclaringClassIndex());
359 if (expected_decl_klass != actual_decl_klass) {
360 continue;
361 }
362 }
363
364 return true;
365 }
366 }
367 return false;
368 }
369
370 // Iterates over all method resolution records, finds an entry which matches
371 // the given field kind+class+name+signature and tests its properties.
372 bool HasMethod(const std::string& expected_kind,
373 const std::string& expected_klass,
374 const std::string& expected_name,
375 const std::string& expected_signature,
376 bool expected_resolved,
377 const std::string& expected_access_flags = "",
378 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100379 for (auto& dex_dep : verifier_deps_->dex_deps_) {
380 auto& storage = (expected_kind == "direct") ? dex_dep.second->direct_methods_
381 : (expected_kind == "virtual") ? dex_dep.second->virtual_methods_
382 : dex_dep.second->interface_methods_;
383 for (auto& entry : storage) {
384 if (expected_resolved != entry.IsResolved()) {
385 continue;
386 }
387
388 const DexFile::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
389
390 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_);
391 if (expected_klass != actual_klass) {
392 continue;
393 }
394
395 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_);
396 if (expected_name != actual_name) {
397 continue;
398 }
399
400 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString();
401 if (expected_signature != actual_signature) {
402 continue;
403 }
404
405 if (expected_resolved) {
406 // Test access flags. Note that PrettyJavaAccessFlags always appends
407 // a space after the modifiers. Add it to the expected access flags.
408 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
409 if (expected_access_flags + " " != actual_access_flags) {
410 continue;
411 }
412
413 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
414 *dex_dep.first, entry.GetDeclaringClassIndex());
415 if (expected_decl_klass != actual_decl_klass) {
416 continue;
417 }
418 }
419
420 return true;
421 }
422 }
423 return false;
424 }
425
David Brazdil6f82fbd2016-09-14 11:55:26 +0100426 size_t NumberOfCompiledDexFiles() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100427 return verifier_deps_->dex_deps_.size();
428 }
429
430 size_t HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100431 bool has_strings = false;
432 bool has_assignability = false;
433 bool has_classes = false;
434 bool has_fields = false;
435 bool has_methods = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100436 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100437
438 for (auto& entry : verifier_deps_->dex_deps_) {
439 has_strings |= !entry.second->strings_.empty();
440 has_assignability |= !entry.second->assignable_types_.empty();
441 has_assignability |= !entry.second->unassignable_types_.empty();
442 has_classes |= !entry.second->classes_.empty();
443 has_fields |= !entry.second->fields_.empty();
444 has_methods |= !entry.second->direct_methods_.empty();
445 has_methods |= !entry.second->virtual_methods_.empty();
446 has_methods |= !entry.second->interface_methods_.empty();
Nicolas Geoffray08025182016-10-25 17:20:18 +0100447 has_unverified_classes |= !entry.second->unverified_classes_.empty();
David Brazdil6f82fbd2016-09-14 11:55:26 +0100448 }
449
Nicolas Geoffray08025182016-10-25 17:20:18 +0100450 return has_strings &&
451 has_assignability &&
452 has_classes &&
453 has_fields &&
454 has_methods &&
455 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100456 }
457
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100458 static std::set<VerifierDeps::MethodResolution>* GetMethods(
459 VerifierDeps::DexFileDeps* deps, MethodResolutionKind resolution_kind) {
460 if (resolution_kind == kDirectMethodResolution) {
461 return &deps->direct_methods_;
462 } else if (resolution_kind == kVirtualMethodResolution) {
463 return &deps->virtual_methods_;
464 } else {
465 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
466 return &deps->interface_methods_;
467 }
468 }
469
David Brazdilca3c8c32016-09-06 14:04:48 +0100470 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100471 std::vector<const DexFile*> dex_files_;
472 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100473 jobject class_loader_;
474 mirror::Class* klass_Main_;
475};
476
477TEST_F(VerifierDepsTest, StringToId) {
478 ScopedObjectAccess soa(Thread::Current());
479 LoadDexFile(&soa);
480
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800481 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
482 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100483 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100484
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800485 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
486 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100487 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100488
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
490 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100491 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100492
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800493 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
494 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100495 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100496
497 ASSERT_EQ(id_Main1, id_Main2);
498 ASSERT_EQ(id_Lorem1, id_Lorem2);
499 ASSERT_NE(id_Main1, id_Lorem1);
500}
501
502TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
503 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
504 /* src */ "Ljava/util/SimpleTimeZone;",
505 /* is_strict */ true,
506 /* is_assignable */ true));
507 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
508}
509
510TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
511 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
512 /* src */ "LMySSLSocket;",
513 /* is_strict */ true,
514 /* is_assignable */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000515 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100516}
517
518TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
519 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
520 /* src */ "LMySimpleTimeZone;",
521 /* is_strict */ true,
522 /* is_assignable */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000523 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100524}
525
526TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
527 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
528 /* src */ "LMyThreadSet;",
529 /* is_strict */ true,
530 /* is_assignable */ true));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000531 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100532}
533
534TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
535 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
536 /* src */ "[[Ljava/util/SimpleTimeZone;",
537 /* is_strict */ true,
538 /* is_assignable */ true));
539 // If the component types of both arrays are resolved, we optimize the list of
540 // dependencies by recording a dependency on the component types.
541 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
542 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
543 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
544}
545
David Brazdilca3c8c32016-09-06 14:04:48 +0100546TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
547 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
548 /* src */ "Ljava/util/SimpleTimeZone;",
549 /* is_strict */ true,
550 /* is_assignable */ false));
551 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
552}
553
554TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
555 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
556 /* src */ "LMySSLSocket;",
557 /* is_strict */ true,
558 /* is_assignable */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000559 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljavax/net/ssl/SSLSocket;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100560}
561
562TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
563 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
564 /* src */ "LMySimpleTimeZone;",
565 /* is_strict */ true,
566 /* is_assignable */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000567 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100568}
569
570TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
571 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
572 /* src */ "[Ljava/util/SimpleTimeZone;",
573 /* is_strict */ true,
574 /* is_assignable */ false));
575 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
576}
577
578TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
579 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
580 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
581}
582
David Brazdilca3c8c32016-09-06 14:04:48 +0100583TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
584 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
585 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
586}
587
588TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
589 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
590 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
591}
592
593TEST_F(VerifierDepsTest, ReturnType_Reference) {
594 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
595 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
596}
597
598TEST_F(VerifierDepsTest, ReturnType_Array) {
599 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
600 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
601}
602
603TEST_F(VerifierDepsTest, InvokeArgumentType) {
604 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
605 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
606 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
607 ASSERT_TRUE(HasMethod("virtual",
608 "Ljava/text/SimpleDateFormat;",
609 "setTimeZone",
610 "(Ljava/util/TimeZone;)V",
611 true,
612 "public",
613 "Ljava/text/DateFormat;"));
614 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
615}
616
617TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
618 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000619 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100620 ASSERT_TRUE(HasAssignable(
621 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
622}
623
624TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
625 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
626 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
627 ASSERT_TRUE(HasAssignable(
628 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
629 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
630}
631
632TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
633 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
634 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
635 ASSERT_TRUE(HasAssignable(
636 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
637}
638
639TEST_F(VerifierDepsTest, ConstClass_Resolved) {
640 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
641 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
642}
643
644TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
645 ASSERT_TRUE(VerifyMethod("ConstClass_Unresolved"));
646 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
647}
648
649TEST_F(VerifierDepsTest, CheckCast_Resolved) {
650 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
651 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
652}
653
654TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
655 ASSERT_TRUE(VerifyMethod("CheckCast_Unresolved"));
656 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
657}
658
659TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
660 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
661 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
662}
663
664TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
665 ASSERT_TRUE(VerifyMethod("InstanceOf_Unresolved"));
666 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
667}
668
669TEST_F(VerifierDepsTest, NewInstance_Resolved) {
670 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
671 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
672}
673
674TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
675 ASSERT_TRUE(VerifyMethod("NewInstance_Unresolved"));
676 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
677}
678
David Brazdilca3c8c32016-09-06 14:04:48 +0100679TEST_F(VerifierDepsTest, NewArray_Unresolved) {
680 ASSERT_TRUE(VerifyMethod("NewArray_Unresolved"));
681 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
682}
683
684TEST_F(VerifierDepsTest, Throw) {
685 ASSERT_TRUE(VerifyMethod("Throw"));
686 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
687}
688
689TEST_F(VerifierDepsTest, MoveException_Resolved) {
690 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
691 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
692 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
693 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
694
695 // Testing that all exception types are assignable to Throwable.
696 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
697 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
698 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
699
700 // Testing that the merge type is assignable to Throwable.
701 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
702
703 // Merging of exception types.
704 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
705 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
706 ASSERT_TRUE(HasAssignable(
707 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
708}
709
710TEST_F(VerifierDepsTest, MoveException_Unresolved) {
711 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
712 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
713}
714
715TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
716 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
717 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public final"));
718 ASSERT_TRUE(HasField("Ljava/lang/System;",
719 "out",
720 "Ljava/io/PrintStream;",
721 true,
722 "public final static",
723 "Ljava/lang/System;"));
724}
725
726TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
727 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
728 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
729 ASSERT_TRUE(HasField(
730 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public final static", "Ljava/util/TimeZone;"));
731}
732
733TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
734 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
735 ASSERT_TRUE(HasField(
736 "LMySimpleTimeZone;", "SHORT", "I", true, "public final static", "Ljava/util/TimeZone;"));
737}
738
739TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
740 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
741 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
742 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
743 "PI_ENABLE_OUTPUT_ESCAPING",
744 "Ljava/lang/String;",
745 true,
746 "public final static",
747 "Ljavax/xml/transform/Result;"));
748}
749
750TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
751 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
752 ASSERT_TRUE(HasField("LMyDOMResult;",
753 "PI_ENABLE_OUTPUT_ESCAPING",
754 "Ljava/lang/String;",
755 true,
756 "public final static",
757 "Ljavax/xml/transform/Result;"));
758}
759
760TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
761 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
762 ASSERT_TRUE(HasField("LMyResult;",
763 "PI_ENABLE_OUTPUT_ESCAPING",
764 "Ljava/lang/String;",
765 true,
766 "public final static",
767 "Ljavax/xml/transform/Result;"));
768}
769
770TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
771 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
772 ASSERT_TRUE(HasField("LMyDocument;",
773 "ELEMENT_NODE",
774 "S",
775 true,
776 "public final static",
777 "Lorg/w3c/dom/Node;"));
778}
779
780TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
781 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
782 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public abstract"));
783 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
784}
785
786TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
787 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
788 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
789}
790
791TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
792 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
793 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
794 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
795 "bytesTransferred",
796 "I",
797 true,
798 "public",
799 "Ljava/io/InterruptedIOException;"));
800 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000801 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100802}
803
804TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
805 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
806 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
807 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
808 "bytesTransferred",
809 "I",
810 true,
811 "public",
812 "Ljava/io/InterruptedIOException;"));
813 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000814 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100815}
816
817TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
818 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
819 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
820 "bytesTransferred",
821 "I",
822 true,
823 "public",
824 "Ljava/io/InterruptedIOException;"));
825 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000826 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100827}
828
829TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
830 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
831 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
832 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
833}
834
835TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
836 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
837 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
838}
839
840TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
841 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
842 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
843 ASSERT_TRUE(HasMethod("direct",
844 "Ljava/net/Socket;",
845 "setSocketImplFactory",
846 "(Ljava/net/SocketImplFactory;)V",
847 true,
848 "public static",
849 "Ljava/net/Socket;"));
850}
851
852TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
853 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
854 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
855 ASSERT_TRUE(HasMethod("direct",
856 "Ljavax/net/ssl/SSLSocket;",
857 "setSocketImplFactory",
858 "(Ljava/net/SocketImplFactory;)V",
859 true,
860 "public static",
861 "Ljava/net/Socket;"));
862}
863
864TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
865 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
866 ASSERT_TRUE(HasMethod("direct",
867 "LMySSLSocket;",
868 "setSocketImplFactory",
869 "(Ljava/net/SocketImplFactory;)V",
870 true,
871 "public static",
872 "Ljava/net/Socket;"));
873}
874
875TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
876 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
877 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public abstract interface"));
878 ASSERT_TRUE(HasMethod("direct",
879 "Ljava/util/Map$Entry;",
880 "comparingByKey",
881 "()Ljava/util/Comparator;",
882 true,
883 "public static",
884 "Ljava/util/Map$Entry;"));
885}
886
887TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
888 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
889 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
890 ASSERT_TRUE(HasMethod("direct",
891 "Ljava/util/AbstractMap$SimpleEntry;",
892 "comparingByKey",
893 "()Ljava/util/Comparator;",
894 false));
895}
896
897TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
898 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
899 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
900 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
901}
902
903TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
904 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
905 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
906}
907
908TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
909 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
910 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
911 ASSERT_TRUE(HasMethod(
912 "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
913}
914
915TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
916 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
917 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
918 ASSERT_TRUE(HasMethod("direct",
919 "Ljavax/net/ssl/SSLSocket;",
920 "checkOldImpl",
921 "()V",
922 true,
923 "private",
924 "Ljava/net/Socket;"));
925}
926
927TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
928 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
929 ASSERT_TRUE(HasMethod(
930 "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
931}
932
933TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
934 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
935 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
936 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
937}
938
939TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
940 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
941 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
942}
943
944TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
945 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
946 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
947 ASSERT_TRUE(HasMethod("virtual",
948 "Ljava/lang/Throwable;",
949 "getMessage",
950 "()Ljava/lang/String;",
951 true,
952 "public",
953 "Ljava/lang/Throwable;"));
954 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000955 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100956}
957
958TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
959 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
960 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
961 ASSERT_TRUE(HasMethod("virtual",
962 "Ljava/io/InterruptedIOException;",
963 "getMessage",
964 "()Ljava/lang/String;",
965 true,
966 "public",
967 "Ljava/lang/Throwable;"));
968 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000969 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100970}
971
972TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
973 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
974 ASSERT_TRUE(HasMethod("virtual",
975 "LMySocketTimeoutException;",
976 "getMessage",
977 "()Ljava/lang/String;",
978 true,
979 "public",
980 "Ljava/lang/Throwable;"));
981}
982
983TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
984 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
985 ASSERT_TRUE(HasMethod("virtual",
986 "LMyThreadSet;",
987 "size",
988 "()I",
989 true,
990 "public abstract",
991 "Ljava/util/Set;"));
992}
993
994TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
995 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
996 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
997 ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
998}
999
1000TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
1001 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
1002 ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
1003}
1004
1005TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
1006 ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
1007 ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
1008 ASSERT_TRUE(HasMethod("direct",
1009 "LMyThread;",
1010 "activeCount",
1011 "()I",
1012 true,
1013 "public static",
1014 "Ljava/lang/Thread;"));
1015}
1016
1017TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1018 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
1019 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1020 ASSERT_TRUE(HasMethod("interface",
1021 "Ljava/lang/Runnable;",
1022 "run",
1023 "()V",
1024 true,
1025 "public abstract",
1026 "Ljava/lang/Runnable;"));
1027}
1028
1029TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1030 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
1031 ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
1032}
1033
1034TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1035 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
1036 ASSERT_TRUE(HasMethod("interface",
1037 "LMyThreadSet;",
1038 "run",
1039 "()V",
1040 true,
1041 "public abstract",
1042 "Ljava/lang/Runnable;"));
1043}
1044
1045TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1046 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
1047 ASSERT_TRUE(HasMethod("interface",
1048 "LMyThreadSet;",
1049 "isEmpty",
1050 "()Z",
1051 true,
1052 "public abstract",
1053 "Ljava/util/Set;"));
1054}
1055
1056TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1057 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
1058 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1059 ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
1060}
1061
1062TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1063 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
1064 ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
1065}
1066
1067TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1068 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
1069 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +00001070 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +01001071 ASSERT_TRUE(HasMethod("interface",
1072 "Ljava/lang/Runnable;",
1073 "run",
1074 "()V",
1075 true,
1076 "public abstract",
1077 "Ljava/lang/Runnable;"));
1078}
1079
1080TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1081 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
1082 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public final"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +00001083 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001084 ASSERT_TRUE(HasMethod(
1085 "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
1086}
1087
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001088TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
1089 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
1090 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public final abstract"));
1091}
1092
1093TEST_F(VerifierDepsTest, NewArray_Resolved) {
1094 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
1095 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public final abstract"));
1096}
1097
David Brazdil6f82fbd2016-09-14 11:55:26 +01001098TEST_F(VerifierDepsTest, EncodeDecode) {
1099 VerifyDexFile();
1100
1101 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1102 ASSERT_TRUE(HasEachKindOfRecord());
1103
1104 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001105 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001106 ASSERT_FALSE(buffer.empty());
1107
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001108 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001109 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1110}
1111
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001112TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1113 VerifyDexFile("MultiDex");
1114
1115 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1116 std::vector<uint8_t> buffer;
1117 verifier_deps_->Encode(dex_files_, &buffer);
1118 ASSERT_FALSE(buffer.empty());
1119
1120 // Create new DexFile, to mess with std::map order: the verifier deps used
1121 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1122 // this by passing the expected order when encoding/decoding.
1123 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1124 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1125 std::vector<const DexFile*> dex_files;
1126 for (auto& dex_file : first_dex_files) {
1127 dex_files.push_back(dex_file.get());
1128 }
1129 for (auto& dex_file : second_dex_files) {
1130 dex_files.push_back(dex_file.get());
1131 }
1132
1133 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001134 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001135 std::ostringstream stream;
1136 VariableIndentationOutputStream os(&stream);
1137 decoded_deps.Dump(&os);
1138}
1139
Nicolas Geoffray08025182016-10-25 17:20:18 +01001140TEST_F(VerifierDepsTest, UnverifiedClasses) {
1141 VerifyDexFile();
1142 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1143 // Test that a class with a soft failure is recorded.
1144 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1145 // Test that a class with hard failure is recorded.
1146 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1147 // Test that a class with unresolved super is recorded.
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001148 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuper;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +01001149 // Test that a class with unresolved super and hard failure is recorded.
1150 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1151}
1152
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001153// Returns the next resolution kind in the enum.
1154static MethodResolutionKind GetNextResolutionKind(MethodResolutionKind resolution_kind) {
1155 if (resolution_kind == kDirectMethodResolution) {
1156 return kVirtualMethodResolution;
1157 } else if (resolution_kind == kVirtualMethodResolution) {
1158 return kInterfaceMethodResolution;
1159 } else {
1160 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
1161 return kDirectMethodResolution;
1162 }
1163}
1164
1165TEST_F(VerifierDepsTest, VerifyDeps) {
1166 VerifyDexFile();
1167
1168 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1169 ASSERT_TRUE(HasEachKindOfRecord());
1170
1171 // When validating, we create a new class loader, as
1172 // the existing `class_loader_` may contain erroneous classes,
1173 // that ClassLinker::FindClass won't return.
1174
1175 ScopedObjectAccess soa(Thread::Current());
1176 StackHandleScope<1> hs(soa.Self());
1177 MutableHandle<mirror::ClassLoader> new_class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
1178 {
1179 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001180 ASSERT_TRUE(verifier_deps_->ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001181 }
1182
1183 std::vector<uint8_t> buffer;
1184 verifier_deps_->Encode(dex_files_, &buffer);
1185 ASSERT_FALSE(buffer.empty());
1186
1187 {
1188 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1189 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001190 ASSERT_TRUE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001191 }
1192
1193 // Fiddle with the dependencies to make sure we catch any change and fail to verify.
1194
1195 {
1196 // Mess up with the assignable_types.
1197 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1198 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1199 deps->assignable_types_.insert(*deps->unassignable_types_.begin());
1200 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001201 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001202 }
1203
1204 {
1205 // Mess up with the unassignable_types.
1206 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1207 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1208 deps->unassignable_types_.insert(*deps->assignable_types_.begin());
1209 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001210 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001211 }
1212
1213 // Mess up with classes.
1214 {
1215 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1216 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1217 bool found = false;
1218 for (const auto& entry : deps->classes_) {
1219 if (entry.IsResolved()) {
1220 deps->classes_.insert(VerifierDeps::ClassResolution(
1221 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1222 found = true;
1223 break;
1224 }
1225 }
1226 ASSERT_TRUE(found);
1227 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001228 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001229 }
1230
1231 {
1232 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1233 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1234 bool found = false;
1235 for (const auto& entry : deps->classes_) {
1236 if (!entry.IsResolved()) {
1237 deps->classes_.insert(VerifierDeps::ClassResolution(
1238 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1239 found = true;
1240 break;
1241 }
1242 }
1243 ASSERT_TRUE(found);
1244 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001245 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001246 }
1247
1248 {
1249 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1250 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1251 bool found = false;
1252 for (const auto& entry : deps->classes_) {
1253 if (entry.IsResolved()) {
1254 deps->classes_.insert(VerifierDeps::ClassResolution(
1255 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1256 found = true;
1257 break;
1258 }
1259 }
1260 ASSERT_TRUE(found);
1261 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001262 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001263 }
1264
1265 // Mess up with fields.
1266 {
1267 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1268 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1269 bool found = false;
1270 for (const auto& entry : deps->fields_) {
1271 if (entry.IsResolved()) {
1272 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1273 VerifierDeps::kUnresolvedMarker,
1274 entry.GetDeclaringClassIndex()));
1275 found = true;
1276 break;
1277 }
1278 }
1279 ASSERT_TRUE(found);
1280 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001281 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001282 }
1283
1284 {
1285 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1286 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1287 bool found = false;
1288 for (const auto& entry : deps->fields_) {
1289 if (!entry.IsResolved()) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001290 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001291 deps->fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1292 VerifierDeps::kUnresolvedMarker - 1,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001293 kStringIndexZero));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001294 found = true;
1295 break;
1296 }
1297 }
1298 ASSERT_TRUE(found);
1299 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001300 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001301 }
1302
1303 {
1304 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1305 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1306 bool found = false;
1307 for (const auto& entry : deps->fields_) {
1308 if (entry.IsResolved()) {
1309 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1310 entry.GetAccessFlags() - 1,
1311 entry.GetDeclaringClassIndex()));
1312 found = true;
1313 break;
1314 }
1315 }
1316 ASSERT_TRUE(found);
1317 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001318 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001319 }
1320
1321 {
1322 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1323 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1324 bool found = false;
1325 for (const auto& entry : deps->fields_) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001326 constexpr dex::StringIndex kNewTypeIndex(0);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001327 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1328 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1329 entry.GetAccessFlags(),
1330 kNewTypeIndex));
1331 found = true;
1332 break;
1333 }
1334 }
1335 ASSERT_TRUE(found);
1336 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001337 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001338 }
1339
1340 // Mess up with methods.
1341 for (MethodResolutionKind resolution_kind :
1342 { kDirectMethodResolution, kVirtualMethodResolution, kInterfaceMethodResolution }) {
1343 {
1344 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1345 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1346 bool found = false;
1347 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1348 for (const auto& entry : *methods) {
1349 if (entry.IsResolved()) {
1350 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1351 VerifierDeps::kUnresolvedMarker,
1352 entry.GetDeclaringClassIndex()));
1353 found = true;
1354 break;
1355 }
1356 }
1357 ASSERT_TRUE(found);
1358 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001359 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001360 }
1361
1362 {
1363 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1364 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1365 bool found = false;
1366 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1367 for (const auto& entry : *methods) {
1368 if (!entry.IsResolved()) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001369 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001370 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1371 VerifierDeps::kUnresolvedMarker - 1,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001372 kStringIndexZero));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001373 found = true;
1374 break;
1375 }
1376 }
1377 ASSERT_TRUE(found);
1378 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001379 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001380 }
1381
1382 {
1383 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1384 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1385 bool found = false;
1386 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1387 for (const auto& entry : *methods) {
1388 if (entry.IsResolved()) {
1389 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1390 entry.GetAccessFlags() - 1,
1391 entry.GetDeclaringClassIndex()));
1392 found = true;
1393 break;
1394 }
1395 }
1396 ASSERT_TRUE(found);
1397 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001398 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001399 }
1400
1401 {
1402 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1403 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1404 bool found = false;
1405 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1406 for (const auto& entry : *methods) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001407 constexpr dex::StringIndex kNewTypeIndex(0);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001408 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1409 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1410 entry.GetAccessFlags(),
1411 kNewTypeIndex));
1412 found = true;
1413 break;
1414 }
1415 }
1416 ASSERT_TRUE(found);
1417 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001418 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001419 }
1420
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001421 // The two tests below make sure that fiddling with the method kind
1422 // (static, virtual, interface) is detected by `ValidateDependencies`.
1423
1424 // An interface method lookup can succeed with a virtual method lookup on the same class.
1425 // That's OK, as we only want to make sure there is a method being defined with the right
1426 // flags. Therefore, polluting the interface methods with virtual methods does not have
1427 // to fail verification.
1428 if (resolution_kind != kVirtualMethodResolution) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001429 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1430 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1431 bool found = false;
1432 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1433 for (const auto& entry : *methods) {
1434 if (entry.IsResolved()) {
1435 GetMethods(deps, GetNextResolutionKind(resolution_kind))->insert(
1436 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1437 entry.GetAccessFlags(),
1438 entry.GetDeclaringClassIndex()));
1439 found = true;
1440 }
1441 }
1442 ASSERT_TRUE(found);
1443 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001444 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001445 }
1446
Nicolas Geoffray865cf902017-01-18 14:34:48 +00001447 // See comment above that applies the same way.
1448 if (resolution_kind != kInterfaceMethodResolution) {
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001449 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1450 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1451 bool found = false;
1452 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1453 for (const auto& entry : *methods) {
1454 if (entry.IsResolved()) {
1455 GetMethods(deps, GetNextResolutionKind(GetNextResolutionKind(resolution_kind)))->insert(
1456 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1457 entry.GetAccessFlags(),
1458 entry.GetDeclaringClassIndex()));
1459 found = true;
1460 }
1461 }
1462 ASSERT_TRUE(found);
1463 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001464 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1465 }
1466 }
1467}
1468
1469TEST_F(VerifierDepsTest, CompilerDriver) {
1470 SetupCompilerDriver();
1471
1472 // Test both multi-dex and single-dex configuration.
1473 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
1474 // Test that the compiler driver behaves as expected when the dependencies
1475 // verify and when they don't verify.
1476 for (bool verify_failure : { false, true }) {
1477 {
1478 ScopedObjectAccess soa(Thread::Current());
1479 LoadDexFile(&soa, "VerifierDeps", multi);
1480 }
1481 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
1482
1483 std::vector<uint8_t> buffer;
1484 verifier_deps_->Encode(dex_files_, &buffer);
1485
1486 {
1487 ScopedObjectAccess soa(Thread::Current());
1488 LoadDexFile(&soa, "VerifierDeps", multi);
1489 }
1490 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1491 if (verify_failure) {
1492 // Just taint the decoded VerifierDeps with one invalid entry.
1493 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1494 bool found = false;
1495 for (const auto& entry : deps->classes_) {
1496 if (entry.IsResolved()) {
1497 deps->classes_.insert(VerifierDeps::ClassResolution(
1498 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1499 found = true;
1500 break;
1501 }
1502 }
1503 ASSERT_TRUE(found);
1504 }
1505 VerifyWithCompilerDriver(&decoded_deps);
1506
1507 if (verify_failure) {
1508 ASSERT_FALSE(verifier_deps_ == nullptr);
1509 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
1510 } else {
1511 ASSERT_TRUE(verifier_deps_ == nullptr);
1512 VerifyClassStatus(decoded_deps);
1513 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001514 }
1515 }
1516}
1517
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001518TEST_F(VerifierDepsTest, MultiDexVerification) {
1519 VerifyDexFile("VerifierDepsMulti");
1520 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
1521
1522 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
1523 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
1524 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
1525
1526 std::vector<uint8_t> buffer;
1527 verifier_deps_->Encode(dex_files_, &buffer);
1528 ASSERT_FALSE(buffer.empty());
1529}
1530
David Brazdilca3c8c32016-09-06 14:04:48 +01001531} // namespace verifier
1532} // namespace art