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