blob: 525a2ee29390c55d6429904837fda97d99f7d799 [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);
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000086 callbacks_->SetVerifierDeps(deps);
87 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000088 // The compiler driver may have updated the VerifierDeps in the callback object.
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000089 if (callbacks_->GetVerifierDeps() != deps) {
90 verifier_deps_.reset(callbacks_->GetVerifierDeps());
91 }
92 callbacks_->SetVerifierDeps(nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000093 }
94
David Brazdil6f82fbd2016-09-14 11:55:26 +010095 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
96 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
97 VerifierDepsCompilerCallbacks* callbacks =
98 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
99 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +0100100 }
101
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100102 void LoadDexFile(ScopedObjectAccess* soa, const char* name1, const char* name2 = nullptr)
103 REQUIRES_SHARED(Locks::mutator_lock_) {
104 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
105 dex_files_ = GetDexFiles(class_loader_);
106 primary_dex_file_ = dex_files_.front();
107
108 SetVerifierDeps(dex_files_);
109 StackHandleScope<1> hs(soa->Self());
110 Handle<mirror::ClassLoader> loader =
111 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_));
112 for (const DexFile* dex_file : dex_files_) {
113 class_linker_->RegisterDexFile(*dex_file, loader.Get());
114 }
115 }
116
David Brazdilca3c8c32016-09-06 14:04:48 +0100117 void LoadDexFile(ScopedObjectAccess* soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100118 LoadDexFile(soa, "VerifierDeps");
119 CHECK_EQ(dex_files_.size(), 1u);
David Brazdilca3c8c32016-09-06 14:04:48 +0100120 klass_Main_ = FindClassByName("LMain;", soa);
121 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100122 }
123
124 bool VerifyMethod(const std::string& method_name) {
125 ScopedObjectAccess soa(Thread::Current());
126 LoadDexFile(&soa);
127
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100128 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100129 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700130 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100131 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
132
133 const DexFile::ClassDef* class_def = klass_Main_->GetClassDef();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100134 const uint8_t* class_data = primary_dex_file_->GetClassData(*class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100135 CHECK(class_data != nullptr);
136
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100137 ClassDataItemIterator it(*primary_dex_file_, class_data);
David Brazdilca3c8c32016-09-06 14:04:48 +0100138 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
139 it.Next();
140 }
141
142 ArtMethod* method = nullptr;
143 while (it.HasNextDirectMethod()) {
144 ArtMethod* resolved_method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100145 *primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100146 it.GetMemberIndex(),
147 dex_cache_handle,
148 class_loader_handle,
149 nullptr,
150 it.GetMethodInvokeType(*class_def));
151 CHECK(resolved_method != nullptr);
152 if (method_name == resolved_method->GetName()) {
153 method = resolved_method;
154 break;
155 }
156 it.Next();
157 }
158 CHECK(method != nullptr);
159
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000160 Thread::Current()->SetVerifierDeps(callbacks_->GetVerifierDeps());
David Brazdilca3c8c32016-09-06 14:04:48 +0100161 MethodVerifier verifier(Thread::Current(),
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100162 primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100163 dex_cache_handle,
164 class_loader_handle,
165 *class_def,
166 it.GetMethodCodeItem(),
167 it.GetMemberIndex(),
168 method,
169 it.GetMethodAccessFlags(),
170 true /* can_load_classes */,
171 true /* allow_soft_failures */,
172 true /* need_precise_constants */,
173 false /* verify to dump */,
174 true /* allow_thread_suspension */);
175 verifier.Verify();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000176 Thread::Current()->SetVerifierDeps(nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100177 return !verifier.HasFailures();
178 }
179
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100180 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100181 {
182 ScopedObjectAccess soa(Thread::Current());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100183 LoadDexFile(&soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100184 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000185 SetupCompilerDriver();
186 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100187 }
188
David Brazdilca3c8c32016-09-06 14:04:48 +0100189 bool TestAssignabilityRecording(const std::string& dst,
190 const std::string& src,
191 bool is_strict,
192 bool is_assignable) {
193 ScopedObjectAccess soa(Thread::Current());
194 LoadDexFile(&soa);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100195 mirror::Class* klass_dst = FindClassByName(dst, &soa);
196 DCHECK(klass_dst != nullptr);
197 mirror::Class* klass_src = FindClassByName(src, &soa);
198 DCHECK(klass_src != nullptr);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100199 verifier_deps_->AddAssignability(*primary_dex_file_,
David Brazdil6f82fbd2016-09-14 11:55:26 +0100200 klass_dst,
201 klass_src,
David Brazdilca3c8c32016-09-06 14:04:48 +0100202 is_strict,
203 is_assignable);
204 return true;
205 }
206
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000207 // Check that the status of classes in `class_loader_` match the
208 // expected status in `deps`.
209 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
210 ScopedObjectAccess soa(Thread::Current());
211 StackHandleScope<2> hs(soa.Self());
212 Handle<mirror::ClassLoader> class_loader_handle(
213 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
214 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
215 for (const DexFile* dex_file : dex_files_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800216 const std::vector<dex::TypeIndex>& unverified_classes = deps.GetUnverifiedClasses(*dex_file);
217 std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end());
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000218 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
219 const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
220 const char* descriptor = dex_file->GetClassDescriptor(class_def);
221 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
222 if (cls.Get() == nullptr) {
223 CHECK(soa.Self()->IsExceptionPending());
224 soa.Self()->ClearException();
225 } else if (set.find(class_def.class_idx_) == set.end()) {
226 ASSERT_EQ(cls->GetStatus(), mirror::Class::kStatusVerified);
227 } else {
228 ASSERT_LT(cls->GetStatus(), mirror::Class::kStatusVerified);
229 }
230 }
231 }
232 }
233
Nicolas Geoffray08025182016-10-25 17:20:18 +0100234 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100235 const DexFile::TypeId* type_id = primary_dex_file_->FindTypeId(cls.c_str());
Nicolas Geoffray08025182016-10-25 17:20:18 +0100236 DCHECK(type_id != nullptr);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800237 dex::TypeIndex index = primary_dex_file_->GetIndexForTypeId(*type_id);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100238 for (const auto& dex_dep : verifier_deps_->dex_deps_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800239 for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100240 if (index == entry) {
241 return true;
242 }
243 }
244 }
245 return false;
246 }
247
David Brazdilca3c8c32016-09-06 14:04:48 +0100248 // Iterates over all assignability records and tries to find an entry which
249 // matches the expected destination/source pair.
250 bool HasAssignable(const std::string& expected_destination,
251 const std::string& expected_source,
252 bool expected_is_assignable) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100253 for (auto& dex_dep : verifier_deps_->dex_deps_) {
254 const DexFile& dex_file = *dex_dep.first;
255 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
256 : dex_dep.second->unassignable_types_;
257 for (auto& entry : storage) {
258 std::string actual_destination =
259 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
260 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
261 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
262 return true;
263 }
264 }
265 }
266 return false;
267 }
268
269 // Iterates over all class resolution records, finds an entry which matches
270 // the given class descriptor and tests its properties.
271 bool HasClass(const std::string& expected_klass,
272 bool expected_resolved,
273 const std::string& expected_access_flags = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100274 for (auto& dex_dep : verifier_deps_->dex_deps_) {
275 for (auto& entry : dex_dep.second->classes_) {
276 if (expected_resolved != entry.IsResolved()) {
277 continue;
278 }
279
280 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
281 if (expected_klass != actual_klass) {
282 continue;
283 }
284
285 if (expected_resolved) {
286 // Test access flags. Note that PrettyJavaAccessFlags always appends
287 // a space after the modifiers. Add it to the expected access flags.
288 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
289 if (expected_access_flags + " " != actual_access_flags) {
290 continue;
291 }
292 }
293
294 return true;
295 }
296 }
297 return false;
298 }
299
300 // Iterates over all field resolution records, finds an entry which matches
301 // the given field class+name+type and tests its properties.
302 bool HasField(const std::string& expected_klass,
303 const std::string& expected_name,
304 const std::string& expected_type,
305 bool expected_resolved,
306 const std::string& expected_access_flags = "",
307 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100308 for (auto& dex_dep : verifier_deps_->dex_deps_) {
309 for (auto& entry : dex_dep.second->fields_) {
310 if (expected_resolved != entry.IsResolved()) {
311 continue;
312 }
313
314 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
315
316 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
317 if (expected_klass != actual_klass) {
318 continue;
319 }
320
321 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
322 if (expected_name != actual_name) {
323 continue;
324 }
325
326 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
327 if (expected_type != actual_type) {
328 continue;
329 }
330
331 if (expected_resolved) {
332 // Test access flags. Note that PrettyJavaAccessFlags always appends
333 // a space after the modifiers. Add it to the expected access flags.
334 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
335 if (expected_access_flags + " " != actual_access_flags) {
336 continue;
337 }
338
339 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
340 *dex_dep.first, entry.GetDeclaringClassIndex());
341 if (expected_decl_klass != actual_decl_klass) {
342 continue;
343 }
344 }
345
346 return true;
347 }
348 }
349 return false;
350 }
351
352 // Iterates over all method resolution records, finds an entry which matches
353 // the given field kind+class+name+signature and tests its properties.
354 bool HasMethod(const std::string& expected_kind,
355 const std::string& expected_klass,
356 const std::string& expected_name,
357 const std::string& expected_signature,
358 bool expected_resolved,
359 const std::string& expected_access_flags = "",
360 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100361 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() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100409 return verifier_deps_->dex_deps_.size();
410 }
411
412 size_t HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100413 bool has_strings = false;
414 bool has_assignability = false;
415 bool has_classes = false;
416 bool has_fields = false;
417 bool has_methods = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100418 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100419
420 for (auto& entry : verifier_deps_->dex_deps_) {
421 has_strings |= !entry.second->strings_.empty();
422 has_assignability |= !entry.second->assignable_types_.empty();
423 has_assignability |= !entry.second->unassignable_types_.empty();
424 has_classes |= !entry.second->classes_.empty();
425 has_fields |= !entry.second->fields_.empty();
426 has_methods |= !entry.second->direct_methods_.empty();
427 has_methods |= !entry.second->virtual_methods_.empty();
428 has_methods |= !entry.second->interface_methods_.empty();
Nicolas Geoffray08025182016-10-25 17:20:18 +0100429 has_unverified_classes |= !entry.second->unverified_classes_.empty();
David Brazdil6f82fbd2016-09-14 11:55:26 +0100430 }
431
Nicolas Geoffray08025182016-10-25 17:20:18 +0100432 return has_strings &&
433 has_assignability &&
434 has_classes &&
435 has_fields &&
436 has_methods &&
437 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100438 }
439
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100440 static std::set<VerifierDeps::MethodResolution>* GetMethods(
441 VerifierDeps::DexFileDeps* deps, MethodResolutionKind resolution_kind) {
442 if (resolution_kind == kDirectMethodResolution) {
443 return &deps->direct_methods_;
444 } else if (resolution_kind == kVirtualMethodResolution) {
445 return &deps->virtual_methods_;
446 } else {
447 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
448 return &deps->interface_methods_;
449 }
450 }
451
David Brazdilca3c8c32016-09-06 14:04:48 +0100452 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100453 std::vector<const DexFile*> dex_files_;
454 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100455 jobject class_loader_;
456 mirror::Class* klass_Main_;
457};
458
459TEST_F(VerifierDepsTest, StringToId) {
460 ScopedObjectAccess soa(Thread::Current());
461 LoadDexFile(&soa);
462
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100463 uint32_t id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
464 ASSERT_LT(id_Main1, primary_dex_file_->NumStringIds());
465 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100466
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100467 uint32_t id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
468 ASSERT_LT(id_Main2, primary_dex_file_->NumStringIds());
469 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100470
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100471 uint32_t id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
472 ASSERT_GE(id_Lorem1, primary_dex_file_->NumStringIds());
473 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100474
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100475 uint32_t id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
476 ASSERT_GE(id_Lorem2, primary_dex_file_->NumStringIds());
477 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100478
479 ASSERT_EQ(id_Main1, id_Main2);
480 ASSERT_EQ(id_Lorem1, id_Lorem2);
481 ASSERT_NE(id_Main1, id_Lorem1);
482}
483
484TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
485 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
486 /* src */ "Ljava/util/SimpleTimeZone;",
487 /* is_strict */ true,
488 /* is_assignable */ true));
489 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
490}
491
492TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
493 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
494 /* src */ "LMySSLSocket;",
495 /* is_strict */ true,
496 /* is_assignable */ true));
497 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "LMySSLSocket;", true));
498}
499
500TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
501 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
502 /* src */ "LMySimpleTimeZone;",
503 /* is_strict */ true,
504 /* is_assignable */ true));
505 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "LMySimpleTimeZone;", true));
506}
507
508TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
509 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
510 /* src */ "LMyThreadSet;",
511 /* is_strict */ true,
512 /* is_assignable */ true));
513 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "LMyThreadSet;", true));
514}
515
516TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
517 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
518 /* src */ "[[Ljava/util/SimpleTimeZone;",
519 /* is_strict */ true,
520 /* is_assignable */ true));
521 // If the component types of both arrays are resolved, we optimize the list of
522 // dependencies by recording a dependency on the component types.
523 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
524 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
525 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
526}
527
528TEST_F(VerifierDepsTest, Assignable_BothArrays_Erroneous) {
529 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
530 /* src */ "[[LMyErroneousTimeZone;",
531 /* is_strict */ true,
532 /* is_assignable */ true));
533 // If the component type of an array is erroneous, we record the dependency on
534 // the array type.
535 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[LMyErroneousTimeZone;", true));
536 ASSERT_TRUE(HasAssignable("[Ljava/util/TimeZone;", "[LMyErroneousTimeZone;", true));
537 ASSERT_FALSE(HasAssignable("Ljava/util/TimeZone;", "LMyErroneousTimeZone;", true));
538}
539
540 // We test that VerifierDeps does not try to optimize by storing assignability
541 // of the component types. This is due to the fact that the component type may
542 // be an erroneous class, even though the array type has resolved status.
543
544TEST_F(VerifierDepsTest, Assignable_ArrayToInterface1) {
545 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
546 /* src */ "[Ljava/util/TimeZone;",
547 /* is_strict */ true,
548 /* is_assignable */ true));
549 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[Ljava/util/TimeZone;", true));
550}
551
552TEST_F(VerifierDepsTest, Assignable_ArrayToInterface2) {
553 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
554 /* src */ "[LMyThreadSet;",
555 /* is_strict */ true,
556 /* is_assignable */ true));
557 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[LMyThreadSet;", true));
558}
559
560TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
561 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
562 /* src */ "Ljava/util/SimpleTimeZone;",
563 /* is_strict */ true,
564 /* is_assignable */ false));
565 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
566}
567
568TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
569 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
570 /* src */ "LMySSLSocket;",
571 /* is_strict */ true,
572 /* is_assignable */ false));
573 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySSLSocket;", false));
574}
575
576TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
577 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
578 /* src */ "LMySimpleTimeZone;",
579 /* is_strict */ true,
580 /* is_assignable */ false));
581 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySimpleTimeZone;", false));
582}
583
584TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
585 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
586 /* src */ "[Ljava/util/SimpleTimeZone;",
587 /* is_strict */ true,
588 /* is_assignable */ false));
589 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
590}
591
592TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
593 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
594 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
595}
596
597TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
598 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
599 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public final abstract"));
600}
601
602TEST_F(VerifierDepsTest, ArgumentType_ResolvedPrimitiveArray) {
603 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedPrimitiveArray"));
604 ASSERT_TRUE(HasClass("[B", true, "public final abstract"));
605}
606
607TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
608 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
609 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
610}
611
612TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
613 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
614 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
615}
616
617TEST_F(VerifierDepsTest, ReturnType_Reference) {
618 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
619 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
620}
621
622TEST_F(VerifierDepsTest, ReturnType_Array) {
623 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
624 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
625}
626
627TEST_F(VerifierDepsTest, InvokeArgumentType) {
628 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
629 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
630 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
631 ASSERT_TRUE(HasMethod("virtual",
632 "Ljava/text/SimpleDateFormat;",
633 "setTimeZone",
634 "(Ljava/util/TimeZone;)V",
635 true,
636 "public",
637 "Ljava/text/DateFormat;"));
638 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
639}
640
641TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
642 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
643 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;", true));
644 ASSERT_TRUE(HasAssignable(
645 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
646}
647
648TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
649 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
650 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
651 ASSERT_TRUE(HasAssignable(
652 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
653 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
654}
655
656TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
657 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
658 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
659 ASSERT_TRUE(HasAssignable(
660 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
661}
662
663TEST_F(VerifierDepsTest, ConstClass_Resolved) {
664 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
665 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
666}
667
668TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
669 ASSERT_TRUE(VerifyMethod("ConstClass_Unresolved"));
670 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
671}
672
673TEST_F(VerifierDepsTest, CheckCast_Resolved) {
674 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
675 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
676}
677
678TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
679 ASSERT_TRUE(VerifyMethod("CheckCast_Unresolved"));
680 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
681}
682
683TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
684 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
685 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
686}
687
688TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
689 ASSERT_TRUE(VerifyMethod("InstanceOf_Unresolved"));
690 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
691}
692
693TEST_F(VerifierDepsTest, NewInstance_Resolved) {
694 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
695 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
696}
697
698TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
699 ASSERT_TRUE(VerifyMethod("NewInstance_Unresolved"));
700 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
701}
702
703TEST_F(VerifierDepsTest, NewArray_Resolved) {
704 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
705 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public final abstract"));
706}
707
708TEST_F(VerifierDepsTest, NewArray_Unresolved) {
709 ASSERT_TRUE(VerifyMethod("NewArray_Unresolved"));
710 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
711}
712
713TEST_F(VerifierDepsTest, Throw) {
714 ASSERT_TRUE(VerifyMethod("Throw"));
715 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
716}
717
718TEST_F(VerifierDepsTest, MoveException_Resolved) {
719 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
720 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
721 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
722 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
723
724 // Testing that all exception types are assignable to Throwable.
725 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
726 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
727 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
728
729 // Testing that the merge type is assignable to Throwable.
730 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
731
732 // Merging of exception types.
733 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
734 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
735 ASSERT_TRUE(HasAssignable(
736 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
737}
738
739TEST_F(VerifierDepsTest, MoveException_Unresolved) {
740 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
741 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
742}
743
744TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
745 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
746 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public final"));
747 ASSERT_TRUE(HasField("Ljava/lang/System;",
748 "out",
749 "Ljava/io/PrintStream;",
750 true,
751 "public final static",
752 "Ljava/lang/System;"));
753}
754
755TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
756 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
757 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
758 ASSERT_TRUE(HasField(
759 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public final static", "Ljava/util/TimeZone;"));
760}
761
762TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
763 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
764 ASSERT_TRUE(HasField(
765 "LMySimpleTimeZone;", "SHORT", "I", true, "public final static", "Ljava/util/TimeZone;"));
766}
767
768TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
769 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
770 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
771 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
772 "PI_ENABLE_OUTPUT_ESCAPING",
773 "Ljava/lang/String;",
774 true,
775 "public final static",
776 "Ljavax/xml/transform/Result;"));
777}
778
779TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
780 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
781 ASSERT_TRUE(HasField("LMyDOMResult;",
782 "PI_ENABLE_OUTPUT_ESCAPING",
783 "Ljava/lang/String;",
784 true,
785 "public final static",
786 "Ljavax/xml/transform/Result;"));
787}
788
789TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
790 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
791 ASSERT_TRUE(HasField("LMyResult;",
792 "PI_ENABLE_OUTPUT_ESCAPING",
793 "Ljava/lang/String;",
794 true,
795 "public final static",
796 "Ljavax/xml/transform/Result;"));
797}
798
799TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
800 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
801 ASSERT_TRUE(HasField("LMyDocument;",
802 "ELEMENT_NODE",
803 "S",
804 true,
805 "public final static",
806 "Lorg/w3c/dom/Node;"));
807}
808
809TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
810 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
811 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public abstract"));
812 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
813}
814
815TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
816 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
817 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
818}
819
820TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
821 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
822 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
823 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
824 "bytesTransferred",
825 "I",
826 true,
827 "public",
828 "Ljava/io/InterruptedIOException;"));
829 ASSERT_TRUE(HasAssignable(
830 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
831}
832
833TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
834 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
835 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
836 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
837 "bytesTransferred",
838 "I",
839 true,
840 "public",
841 "Ljava/io/InterruptedIOException;"));
842 ASSERT_TRUE(HasAssignable(
843 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
844}
845
846TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
847 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
848 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
849 "bytesTransferred",
850 "I",
851 true,
852 "public",
853 "Ljava/io/InterruptedIOException;"));
854 ASSERT_TRUE(HasAssignable(
855 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
856}
857
858TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
859 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
860 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
861 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
862}
863
864TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
865 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
866 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
867}
868
869TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
870 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
871 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
872 ASSERT_TRUE(HasMethod("direct",
873 "Ljava/net/Socket;",
874 "setSocketImplFactory",
875 "(Ljava/net/SocketImplFactory;)V",
876 true,
877 "public static",
878 "Ljava/net/Socket;"));
879}
880
881TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
882 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
883 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
884 ASSERT_TRUE(HasMethod("direct",
885 "Ljavax/net/ssl/SSLSocket;",
886 "setSocketImplFactory",
887 "(Ljava/net/SocketImplFactory;)V",
888 true,
889 "public static",
890 "Ljava/net/Socket;"));
891}
892
893TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
894 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
895 ASSERT_TRUE(HasMethod("direct",
896 "LMySSLSocket;",
897 "setSocketImplFactory",
898 "(Ljava/net/SocketImplFactory;)V",
899 true,
900 "public static",
901 "Ljava/net/Socket;"));
902}
903
904TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
905 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
906 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public abstract interface"));
907 ASSERT_TRUE(HasMethod("direct",
908 "Ljava/util/Map$Entry;",
909 "comparingByKey",
910 "()Ljava/util/Comparator;",
911 true,
912 "public static",
913 "Ljava/util/Map$Entry;"));
914}
915
916TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
917 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
918 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
919 ASSERT_TRUE(HasMethod("direct",
920 "Ljava/util/AbstractMap$SimpleEntry;",
921 "comparingByKey",
922 "()Ljava/util/Comparator;",
923 false));
924}
925
926TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
927 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
928 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
929 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
930}
931
932TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
933 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
934 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
935}
936
937TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
938 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
939 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
940 ASSERT_TRUE(HasMethod(
941 "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
942}
943
944TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
945 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
946 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
947 ASSERT_TRUE(HasMethod("direct",
948 "Ljavax/net/ssl/SSLSocket;",
949 "checkOldImpl",
950 "()V",
951 true,
952 "private",
953 "Ljava/net/Socket;"));
954}
955
956TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
957 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
958 ASSERT_TRUE(HasMethod(
959 "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
960}
961
962TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
963 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
964 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
965 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
966}
967
968TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
969 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
970 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
971}
972
973TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
974 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
975 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
976 ASSERT_TRUE(HasMethod("virtual",
977 "Ljava/lang/Throwable;",
978 "getMessage",
979 "()Ljava/lang/String;",
980 true,
981 "public",
982 "Ljava/lang/Throwable;"));
983 // Type dependency on `this` argument.
984 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
985}
986
987TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
988 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
989 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
990 ASSERT_TRUE(HasMethod("virtual",
991 "Ljava/io/InterruptedIOException;",
992 "getMessage",
993 "()Ljava/lang/String;",
994 true,
995 "public",
996 "Ljava/lang/Throwable;"));
997 // Type dependency on `this` argument.
998 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
999}
1000
1001TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
1002 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
1003 ASSERT_TRUE(HasMethod("virtual",
1004 "LMySocketTimeoutException;",
1005 "getMessage",
1006 "()Ljava/lang/String;",
1007 true,
1008 "public",
1009 "Ljava/lang/Throwable;"));
1010}
1011
1012TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
1013 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
1014 ASSERT_TRUE(HasMethod("virtual",
1015 "LMyThreadSet;",
1016 "size",
1017 "()I",
1018 true,
1019 "public abstract",
1020 "Ljava/util/Set;"));
1021}
1022
1023TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
1024 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
1025 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
1026 ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
1027}
1028
1029TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
1030 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
1031 ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
1032}
1033
1034TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
1035 ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
1036 ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
1037 ASSERT_TRUE(HasMethod("direct",
1038 "LMyThread;",
1039 "activeCount",
1040 "()I",
1041 true,
1042 "public static",
1043 "Ljava/lang/Thread;"));
1044}
1045
1046TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1047 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
1048 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1049 ASSERT_TRUE(HasMethod("interface",
1050 "Ljava/lang/Runnable;",
1051 "run",
1052 "()V",
1053 true,
1054 "public abstract",
1055 "Ljava/lang/Runnable;"));
1056}
1057
1058TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1059 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
1060 ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
1061}
1062
1063TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1064 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
1065 ASSERT_TRUE(HasMethod("interface",
1066 "LMyThreadSet;",
1067 "run",
1068 "()V",
1069 true,
1070 "public abstract",
1071 "Ljava/lang/Runnable;"));
1072}
1073
1074TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1075 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
1076 ASSERT_TRUE(HasMethod("interface",
1077 "LMyThreadSet;",
1078 "isEmpty",
1079 "()Z",
1080 true,
1081 "public abstract",
1082 "Ljava/util/Set;"));
1083}
1084
1085TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1086 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
1087 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1088 ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
1089}
1090
1091TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1092 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
1093 ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
1094}
1095
1096TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1097 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
1098 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1099 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;", true));
1100 ASSERT_TRUE(HasMethod("interface",
1101 "Ljava/lang/Runnable;",
1102 "run",
1103 "()V",
1104 true,
1105 "public abstract",
1106 "Ljava/lang/Runnable;"));
1107}
1108
1109TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1110 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
1111 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public final"));
1112 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "LMain;", false));
1113 ASSERT_TRUE(HasMethod(
1114 "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
1115}
1116
David Brazdil6f82fbd2016-09-14 11:55:26 +01001117TEST_F(VerifierDepsTest, EncodeDecode) {
1118 VerifyDexFile();
1119
1120 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1121 ASSERT_TRUE(HasEachKindOfRecord());
1122
1123 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001124 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001125 ASSERT_FALSE(buffer.empty());
1126
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001127 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001128 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1129}
1130
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001131TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1132 VerifyDexFile("MultiDex");
1133
1134 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1135 std::vector<uint8_t> buffer;
1136 verifier_deps_->Encode(dex_files_, &buffer);
1137 ASSERT_FALSE(buffer.empty());
1138
1139 // Create new DexFile, to mess with std::map order: the verifier deps used
1140 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1141 // this by passing the expected order when encoding/decoding.
1142 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1143 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1144 std::vector<const DexFile*> dex_files;
1145 for (auto& dex_file : first_dex_files) {
1146 dex_files.push_back(dex_file.get());
1147 }
1148 for (auto& dex_file : second_dex_files) {
1149 dex_files.push_back(dex_file.get());
1150 }
1151
1152 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001153 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001154 std::ostringstream stream;
1155 VariableIndentationOutputStream os(&stream);
1156 decoded_deps.Dump(&os);
1157}
1158
Nicolas Geoffray08025182016-10-25 17:20:18 +01001159TEST_F(VerifierDepsTest, UnverifiedClasses) {
1160 VerifyDexFile();
1161 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1162 // Test that a class with a soft failure is recorded.
1163 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1164 // Test that a class with hard failure is recorded.
1165 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1166 // Test that a class with unresolved super is recorded.
1167 ASSERT_FALSE(HasUnverifiedClass("LMyClassWithNoSuper;"));
1168 // Test that a class with unresolved super and hard failure is recorded.
1169 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1170}
1171
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001172// Returns the next resolution kind in the enum.
1173static MethodResolutionKind GetNextResolutionKind(MethodResolutionKind resolution_kind) {
1174 if (resolution_kind == kDirectMethodResolution) {
1175 return kVirtualMethodResolution;
1176 } else if (resolution_kind == kVirtualMethodResolution) {
1177 return kInterfaceMethodResolution;
1178 } else {
1179 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
1180 return kDirectMethodResolution;
1181 }
1182}
1183
1184TEST_F(VerifierDepsTest, VerifyDeps) {
1185 VerifyDexFile();
1186
1187 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1188 ASSERT_TRUE(HasEachKindOfRecord());
1189
1190 // When validating, we create a new class loader, as
1191 // the existing `class_loader_` may contain erroneous classes,
1192 // that ClassLinker::FindClass won't return.
1193
1194 ScopedObjectAccess soa(Thread::Current());
1195 StackHandleScope<1> hs(soa.Self());
1196 MutableHandle<mirror::ClassLoader> new_class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
1197 {
1198 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001199 ASSERT_TRUE(verifier_deps_->ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001200 }
1201
1202 std::vector<uint8_t> buffer;
1203 verifier_deps_->Encode(dex_files_, &buffer);
1204 ASSERT_FALSE(buffer.empty());
1205
1206 {
1207 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1208 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001209 ASSERT_TRUE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001210 }
1211
1212 // Fiddle with the dependencies to make sure we catch any change and fail to verify.
1213
1214 {
1215 // Mess up with the assignable_types.
1216 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1217 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1218 deps->assignable_types_.insert(*deps->unassignable_types_.begin());
1219 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001220 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001221 }
1222
1223 {
1224 // Mess up with the unassignable_types.
1225 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1226 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1227 deps->unassignable_types_.insert(*deps->assignable_types_.begin());
1228 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001229 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001230 }
1231
1232 // Mess up with classes.
1233 {
1234 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1235 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1236 bool found = false;
1237 for (const auto& entry : deps->classes_) {
1238 if (entry.IsResolved()) {
1239 deps->classes_.insert(VerifierDeps::ClassResolution(
1240 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1241 found = true;
1242 break;
1243 }
1244 }
1245 ASSERT_TRUE(found);
1246 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001247 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001248 }
1249
1250 {
1251 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1252 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1253 bool found = false;
1254 for (const auto& entry : deps->classes_) {
1255 if (!entry.IsResolved()) {
1256 deps->classes_.insert(VerifierDeps::ClassResolution(
1257 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1258 found = true;
1259 break;
1260 }
1261 }
1262 ASSERT_TRUE(found);
1263 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001264 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001265 }
1266
1267 {
1268 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1269 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1270 bool found = false;
1271 for (const auto& entry : deps->classes_) {
1272 if (entry.IsResolved()) {
1273 deps->classes_.insert(VerifierDeps::ClassResolution(
1274 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1275 found = true;
1276 break;
1277 }
1278 }
1279 ASSERT_TRUE(found);
1280 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001281 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001282 }
1283
1284 // Mess up with fields.
1285 {
1286 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1287 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1288 bool found = false;
1289 for (const auto& entry : deps->fields_) {
1290 if (entry.IsResolved()) {
1291 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1292 VerifierDeps::kUnresolvedMarker,
1293 entry.GetDeclaringClassIndex()));
1294 found = true;
1295 break;
1296 }
1297 }
1298 ASSERT_TRUE(found);
1299 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001300 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001301 }
1302
1303 {
1304 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1305 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1306 bool found = false;
1307 for (const auto& entry : deps->fields_) {
1308 if (!entry.IsResolved()) {
1309 deps->fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1310 VerifierDeps::kUnresolvedMarker - 1,
1311 0 /* we know there is a class there */));
1312 found = true;
1313 break;
1314 }
1315 }
1316 ASSERT_TRUE(found);
1317 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001318 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001319 }
1320
1321 {
1322 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1323 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1324 bool found = false;
1325 for (const auto& entry : deps->fields_) {
1326 if (entry.IsResolved()) {
1327 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1328 entry.GetAccessFlags() - 1,
1329 entry.GetDeclaringClassIndex()));
1330 found = true;
1331 break;
1332 }
1333 }
1334 ASSERT_TRUE(found);
1335 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001336 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001337 }
1338
1339 {
1340 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1341 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1342 bool found = false;
1343 for (const auto& entry : deps->fields_) {
1344 static constexpr uint32_t kNewTypeIndex = 0;
1345 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1346 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1347 entry.GetAccessFlags(),
1348 kNewTypeIndex));
1349 found = true;
1350 break;
1351 }
1352 }
1353 ASSERT_TRUE(found);
1354 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001355 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001356 }
1357
1358 // Mess up with methods.
1359 for (MethodResolutionKind resolution_kind :
1360 { kDirectMethodResolution, kVirtualMethodResolution, kInterfaceMethodResolution }) {
1361 {
1362 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1363 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1364 bool found = false;
1365 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1366 for (const auto& entry : *methods) {
1367 if (entry.IsResolved()) {
1368 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1369 VerifierDeps::kUnresolvedMarker,
1370 entry.GetDeclaringClassIndex()));
1371 found = true;
1372 break;
1373 }
1374 }
1375 ASSERT_TRUE(found);
1376 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001377 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001378 }
1379
1380 {
1381 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1382 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1383 bool found = false;
1384 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1385 for (const auto& entry : *methods) {
1386 if (!entry.IsResolved()) {
1387 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1388 VerifierDeps::kUnresolvedMarker - 1,
1389 0 /* we know there is a class there */));
1390 found = true;
1391 break;
1392 }
1393 }
1394 ASSERT_TRUE(found);
1395 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001396 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001397 }
1398
1399 {
1400 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1401 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1402 bool found = false;
1403 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1404 for (const auto& entry : *methods) {
1405 if (entry.IsResolved()) {
1406 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1407 entry.GetAccessFlags() - 1,
1408 entry.GetDeclaringClassIndex()));
1409 found = true;
1410 break;
1411 }
1412 }
1413 ASSERT_TRUE(found);
1414 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001415 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001416 }
1417
1418 {
1419 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1420 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1421 bool found = false;
1422 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1423 for (const auto& entry : *methods) {
1424 static constexpr uint32_t kNewTypeIndex = 0;
1425 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1426 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1427 entry.GetAccessFlags(),
1428 kNewTypeIndex));
1429 found = true;
1430 break;
1431 }
1432 }
1433 ASSERT_TRUE(found);
1434 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001435 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001436 }
1437
1438 {
1439 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1440 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1441 bool found = false;
1442 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1443 for (const auto& entry : *methods) {
1444 if (entry.IsResolved()) {
1445 GetMethods(deps, GetNextResolutionKind(resolution_kind))->insert(
1446 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1447 entry.GetAccessFlags(),
1448 entry.GetDeclaringClassIndex()));
1449 found = true;
1450 }
1451 }
1452 ASSERT_TRUE(found);
1453 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001454 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001455 }
1456
1457 {
1458 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1459 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1460 bool found = false;
1461 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1462 for (const auto& entry : *methods) {
1463 if (entry.IsResolved()) {
1464 GetMethods(deps, GetNextResolutionKind(GetNextResolutionKind(resolution_kind)))->insert(
1465 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1466 entry.GetAccessFlags(),
1467 entry.GetDeclaringClassIndex()));
1468 found = true;
1469 }
1470 }
1471 ASSERT_TRUE(found);
1472 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001473 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1474 }
1475 }
1476}
1477
1478TEST_F(VerifierDepsTest, CompilerDriver) {
1479 SetupCompilerDriver();
1480
1481 // Test both multi-dex and single-dex configuration.
1482 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
1483 // Test that the compiler driver behaves as expected when the dependencies
1484 // verify and when they don't verify.
1485 for (bool verify_failure : { false, true }) {
1486 {
1487 ScopedObjectAccess soa(Thread::Current());
1488 LoadDexFile(&soa, "VerifierDeps", multi);
1489 }
1490 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
1491
1492 std::vector<uint8_t> buffer;
1493 verifier_deps_->Encode(dex_files_, &buffer);
1494
1495 {
1496 ScopedObjectAccess soa(Thread::Current());
1497 LoadDexFile(&soa, "VerifierDeps", multi);
1498 }
1499 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1500 if (verify_failure) {
1501 // Just taint the decoded VerifierDeps with one invalid entry.
1502 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1503 bool found = false;
1504 for (const auto& entry : deps->classes_) {
1505 if (entry.IsResolved()) {
1506 deps->classes_.insert(VerifierDeps::ClassResolution(
1507 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1508 found = true;
1509 break;
1510 }
1511 }
1512 ASSERT_TRUE(found);
1513 }
1514 VerifyWithCompilerDriver(&decoded_deps);
1515
1516 if (verify_failure) {
1517 ASSERT_FALSE(verifier_deps_ == nullptr);
1518 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
1519 } else {
1520 ASSERT_TRUE(verifier_deps_ == nullptr);
1521 VerifyClassStatus(decoded_deps);
1522 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001523 }
1524 }
1525}
1526
David Brazdilca3c8c32016-09-06 14:04:48 +01001527} // namespace verifier
1528} // namespace art