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