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