• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 // Test is in compiler, as it uses compiler related code.
18 #include "verifier/verifier_deps.h"
19 
20 #include "aot_class_linker.h"
21 #include "art_method-inl.h"
22 #include "base/indenter.h"
23 #include "class_linker.h"
24 #include "common_compiler_driver_test.h"
25 #include "compiler_callbacks.h"
26 #include "dex/class_accessor-inl.h"
27 #include "dex/class_iterator.h"
28 #include "dex/dex_file-inl.h"
29 #include "dex/dex_file_types.h"
30 #include "dex/verification_results.h"
31 #include "driver/compiler_driver-inl.h"
32 #include "driver/compiler_options.h"
33 #include "handle_scope-inl.h"
34 #include "mirror/class_loader.h"
35 #include "runtime.h"
36 #include "scoped_thread_state_change-inl.h"
37 #include "thread.h"
38 #include "utils/atomic_dex_ref_map-inl.h"
39 #include "verifier/method_verifier-inl.h"
40 #include "verifier/reg_type_cache.h"
41 
42 namespace art {
43 namespace verifier {
44 
45 class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
46  public:
VerifierDepsCompilerCallbacks()47   VerifierDepsCompilerCallbacks()
48       : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
49         deps_(nullptr) {}
50 
CreateAotClassLinker(InternTable * intern_table)51   ClassLinker* CreateAotClassLinker(InternTable* intern_table) override {
52     return new AotClassLinker(intern_table);
53   }
54 
AddUncompilableMethod(MethodReference ref)55   void AddUncompilableMethod([[maybe_unused]] MethodReference ref) override {}
AddUncompilableClass(ClassReference ref)56   void AddUncompilableClass([[maybe_unused]] ClassReference ref) override {}
ClassRejected(ClassReference ref)57   void ClassRejected([[maybe_unused]] ClassReference ref) override {}
IsUncompilableMethod(MethodReference ref)58   bool IsUncompilableMethod([[maybe_unused]] MethodReference ref) override { return false; }
59 
GetVerifierDeps() const60   verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; }
SetVerifierDeps(verifier::VerifierDeps * deps)61   void SetVerifierDeps(verifier::VerifierDeps* deps) override { deps_ = deps; }
62 
63  private:
64   verifier::VerifierDeps* deps_;
65 };
66 
67 class VerifierDepsTest : public CommonCompilerDriverTest {
68  public:
VerifierDepsTest()69   VerifierDepsTest() {
70     this->use_boot_image_ = true;  // Make the Runtime creation cheaper.
71   }
72 
SetUpRuntimeOptions(RuntimeOptions * options)73   void SetUpRuntimeOptions(RuntimeOptions* options) override {
74     CommonCompilerTest::SetUpRuntimeOptions(options);
75     callbacks_.reset(new VerifierDepsCompilerCallbacks());
76   }
77 
FindClassByName(ScopedObjectAccess & soa,const std::string & name)78   ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name)
79       REQUIRES_SHARED(Locks::mutator_lock_) {
80     StackHandleScope<1> hs(soa.Self());
81     Handle<mirror::ClassLoader> class_loader_handle(
82         hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
83     ObjPtr<mirror::Class> klass =
84         class_linker_->FindClass(soa.Self(), name.c_str(), name.length(), class_loader_handle);
85     if (klass == nullptr) {
86       DCHECK(soa.Self()->IsExceptionPending());
87       soa.Self()->ClearException();
88     }
89     return klass;
90   }
91 
SetupCompilerDriver()92   void SetupCompilerDriver() {
93     compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
94     compiler_driver_->InitializeThreadPools();
95   }
96 
VerifyWithCompilerDriver(verifier::VerifierDeps * verifier_deps)97   void VerifyWithCompilerDriver(verifier::VerifierDeps* verifier_deps) {
98     TimingLogger timings("Verify", false, false);
99     // The compiler driver handles the verifier deps in the callbacks, so
100     // remove what this class did for unit testing.
101     if (verifier_deps == nullptr) {
102       // Create some verifier deps by default if they are not already specified.
103       verifier_deps = new verifier::VerifierDeps(dex_files_);
104       verifier_deps_.reset(verifier_deps);
105     }
106     callbacks_->SetVerifierDeps(verifier_deps);
107     compiler_driver_->Verify(class_loader_, dex_files_, &timings);
108     callbacks_->SetVerifierDeps(nullptr);
109   }
110 
SetVerifierDeps(const std::vector<const DexFile * > & dex_files)111   void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
112     verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
113     VerifierDepsCompilerCallbacks* callbacks =
114         reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
115     callbacks->SetVerifierDeps(verifier_deps_.get());
116   }
117 
LoadDexFile(ScopedObjectAccess & soa,const char * name1,const char * name2=nullptr)118   void LoadDexFile(ScopedObjectAccess& soa, const char* name1, const char* name2 = nullptr)
119       REQUIRES_SHARED(Locks::mutator_lock_) {
120     class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
121     dex_files_ = GetDexFiles(class_loader_);
122     primary_dex_file_ = dex_files_.front();
123 
124     SetVerifierDeps(dex_files_);
125     StackHandleScope<1> hs(soa.Self());
126     Handle<mirror::ClassLoader> loader =
127         hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_));
128     for (const DexFile* dex_file : dex_files_) {
129       class_linker_->RegisterDexFile(*dex_file, loader.Get());
130     }
131     SetDexFilesForOatFile(dex_files_);
132   }
133 
LoadDexFile(ScopedObjectAccess & soa)134   void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) {
135     LoadDexFile(soa, "VerifierDeps");
136     CHECK_EQ(dex_files_.size(), 1u);
137     klass_Main_ = FindClassByName(soa, "LMain;");
138     CHECK(klass_Main_ != nullptr);
139   }
140 
VerifyMethod(const std::string & method_name)141   bool VerifyMethod(const std::string& method_name) {
142     ScopedObjectAccess soa(Thread::Current());
143     LoadDexFile(soa);
144 
145     StackHandleScope<2> hs(soa.Self());
146     Handle<mirror::ClassLoader> class_loader_handle(
147         hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
148     Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
149 
150     const dex::ClassDef* class_def = klass_Main_->GetClassDef();
151     ClassAccessor accessor(*primary_dex_file_, *class_def);
152 
153     bool has_failures = true;
154     bool found_method = false;
155 
156     for (const ClassAccessor::Method& method : accessor.GetMethods()) {
157       ArtMethod* resolved_method =
158           class_linker_->ResolveMethodId(
159               method.GetIndex(),
160               dex_cache_handle,
161               class_loader_handle);
162       CHECK(resolved_method != nullptr);
163       if (method_name == resolved_method->GetName()) {
164         ArenaPool* arena_pool = Runtime::Current()->GetArenaPool();
165         RegTypeCache reg_types(
166             soa.Self(), class_linker_, arena_pool, class_loader_handle, primary_dex_file_);
167         std::unique_ptr<MethodVerifier> verifier(
168             MethodVerifier::CreateVerifier(soa.Self(),
169                                            &reg_types,
170                                            callbacks_->GetVerifierDeps(),
171                                            dex_cache_handle,
172                                            *class_def,
173                                            method.GetCodeItem(),
174                                            method.GetIndex(),
175                                            method.GetAccessFlags(),
176                                            /* verify_to_dump= */ false,
177                                            /* api_level= */ 0));
178         verifier->Verify();
179         soa.Self()->SetVerifierDeps(nullptr);
180         has_failures = verifier->HasFailures();
181         found_method = true;
182       }
183     }
184     CHECK(found_method) << "Expected to find method " << method_name;
185     return !has_failures;
186   }
187 
VerifyDexFile(const char * multidex=nullptr)188   void VerifyDexFile(const char* multidex = nullptr) {
189     {
190       ScopedObjectAccess soa(Thread::Current());
191       LoadDexFile(soa, "VerifierDeps", multidex);
192     }
193     SetupCompilerDriver();
194     VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
195   }
196 
TestAssignabilityRecording(const std::string & dst,const std::string & src)197   bool TestAssignabilityRecording(const std::string& dst, const std::string& src) {
198     ScopedObjectAccess soa(Thread::Current());
199     LoadDexFile(soa);
200     StackHandleScope<1> hs(soa.Self());
201     Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst));
202     DCHECK(klass_dst != nullptr) << dst;
203     ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src);
204     DCHECK(klass_src != nullptr) << src;
205     verifier_deps_->AddAssignability(*primary_dex_file_,
206                                      primary_dex_file_->GetClassDef(0),
207                                      klass_dst.Get(),
208                                      klass_src);
209     return true;
210   }
211 
212   // Check that the status of classes in `class_loader_` match the
213   // expected status in `deps`.
VerifyClassStatus(const verifier::VerifierDeps & deps)214   void VerifyClassStatus(const verifier::VerifierDeps& deps) {
215     ScopedObjectAccess soa(Thread::Current());
216     StackHandleScope<2> hs(soa.Self());
217     Handle<mirror::ClassLoader> class_loader_handle(
218         hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
219     MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
220     for (const DexFile* dex_file : dex_files_) {
221       const std::vector<bool>& verified_classes = deps.GetVerifiedClasses(*dex_file);
222       ASSERT_EQ(verified_classes.size(), dex_file->NumClassDefs());
223       for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
224         cls.Assign(class_linker_->FindClass(
225             soa.Self(), *dex_file, dex_file->GetClassDef(i).class_idx_, class_loader_handle));
226         if (cls == nullptr) {
227           CHECK(soa.Self()->IsExceptionPending());
228           soa.Self()->ClearException();
229         } else if (&cls->GetDexFile() != dex_file) {
230           // Ignore classes from different dex files.
231         } else if (verified_classes[i]) {
232           ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerifiedNeedsAccessChecks);
233         } else {
234           ASSERT_LT(cls->GetStatus(), ClassStatus::kVerified);
235         }
236       }
237     }
238   }
239 
GetClassDefIndex(const std::string & cls,const DexFile & dex_file)240   uint16_t GetClassDefIndex(const std::string& cls, const DexFile& dex_file) {
241     const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
242     DCHECK(type_id != nullptr);
243     dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
244     const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx);
245     DCHECK(class_def != nullptr);
246     return dex_file.GetIndexForClassDef(*class_def);
247   }
248 
HasVerifiedClass(const std::string & cls)249   bool HasVerifiedClass(const std::string& cls) {
250     return HasVerifiedClass(cls, *primary_dex_file_);
251   }
252 
HasUnverifiedClass(const std::string & cls)253   bool HasUnverifiedClass(const std::string& cls) {
254     return !HasVerifiedClass(cls, *primary_dex_file_);
255   }
256 
HasUnverifiedClass(const std::string & cls,const DexFile & dex_file)257   bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
258     return !HasVerifiedClass(cls, dex_file);
259   }
260 
HasVerifiedClass(const std::string & cls,const DexFile & dex_file)261   bool HasVerifiedClass(const std::string& cls, const DexFile& dex_file) {
262     uint16_t class_def_idx = GetClassDefIndex(cls, dex_file);
263     return verifier_deps_->GetVerifiedClasses(dex_file)[class_def_idx];
264   }
265 
266   // Iterates over all assignability records and tries to find an entry which
267   // matches the expected destination/source pair.
HasAssignable(const std::string & expected_destination,const std::string & expected_source) const268   bool HasAssignable(const std::string& expected_destination,
269                      const std::string& expected_source) const {
270     for (auto& dex_dep : verifier_deps_->dex_deps_) {
271       const DexFile& dex_file = *dex_dep.first;
272       auto& storage = dex_dep.second->assignable_types_;
273       for (auto& set : storage) {
274         for (auto& entry : set) {
275           std::string actual_destination =
276               verifier_deps_->GetStringFromIndex(dex_file, entry.GetDestination());
277           std::string actual_source =
278               verifier_deps_->GetStringFromIndex(dex_file, entry.GetSource());
279           if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
280             return true;
281           }
282         }
283       }
284     }
285     return false;
286   }
287 
NumberOfCompiledDexFiles()288   size_t NumberOfCompiledDexFiles() {
289     return verifier_deps_->dex_deps_.size();
290   }
291 
HasBoolValue(const std::vector<bool> & vec,bool value)292   bool HasBoolValue(const std::vector<bool>& vec, bool value) {
293     return std::count(vec.begin(), vec.end(), value) > 0;
294   }
295 
HasEachKindOfRecord()296   bool HasEachKindOfRecord() {
297     bool has_strings = false;
298     bool has_assignability = false;
299     bool has_verified_classes = false;
300     bool has_unverified_classes = false;
301 
302     for (auto& entry : verifier_deps_->dex_deps_) {
303       has_strings |= !entry.second->strings_.empty();
304       has_assignability |= !entry.second->assignable_types_.empty();
305       has_verified_classes |= HasBoolValue(entry.second->verified_classes_, true);
306       has_unverified_classes |= HasBoolValue(entry.second->verified_classes_, false);
307     }
308 
309     return has_strings &&
310            has_assignability &&
311            has_verified_classes &&
312            has_unverified_classes;
313   }
314 
315   // Load the dex file again with a new class loader, decode the VerifierDeps
316   // in `buffer`, allow the caller to modify the deps and then run validation.
317   template<typename Fn>
RunValidation(Fn fn,const std::vector<uint8_t> & buffer)318   bool RunValidation(Fn fn, const std::vector<uint8_t>& buffer) {
319     ScopedObjectAccess soa(Thread::Current());
320 
321     jobject second_loader = LoadDex("VerifierDeps");
322     const auto& second_dex_files = GetDexFiles(second_loader);
323 
324     VerifierDeps decoded_deps(second_dex_files, /*output_only=*/ false);
325     bool parsed = decoded_deps.ParseStoredData(second_dex_files, ArrayRef<const uint8_t>(buffer));
326     CHECK(parsed);
327     VerifierDeps::DexFileDeps* decoded_dex_deps =
328         decoded_deps.GetDexFileDeps(*second_dex_files.front());
329 
330     // Let the test modify the dependencies.
331     fn(*decoded_dex_deps);
332 
333     StackHandleScope<1> hs(soa.Self());
334     Handle<mirror::ClassLoader> new_class_loader =
335         hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(second_loader));
336 
337     return decoded_deps.ValidateDependenciesAndUpdateStatus(soa.Self(),
338                                                             new_class_loader,
339                                                             second_dex_files);
340   }
341 
342   std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
343   std::vector<const DexFile*> dex_files_;
344   const DexFile* primary_dex_file_;
345   jobject class_loader_;
346   ObjPtr<mirror::Class> klass_Main_;
347 };
348 
TEST_F(VerifierDepsTest,StringToId)349 TEST_F(VerifierDepsTest, StringToId) {
350   ScopedObjectAccess soa(Thread::Current());
351   LoadDexFile(soa);
352 
353   dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
354   ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
355   ASSERT_STREQ("LMain;", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Main1));
356 
357   dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
358   ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
359   ASSERT_STREQ("LMain;", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Main2));
360 
361   dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
362   ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
363   ASSERT_STREQ("Lorem ipsum", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Lorem1));
364 
365   dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
366   ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
367   ASSERT_STREQ("Lorem ipsum", verifier_deps_->GetStringFromIndex(*primary_dex_file_, id_Lorem2));
368 
369   ASSERT_EQ(id_Main1, id_Main2);
370   ASSERT_EQ(id_Lorem1, id_Lorem2);
371   ASSERT_NE(id_Main1, id_Lorem1);
372 }
373 
TEST_F(VerifierDepsTest,Assignable_BothInBoot)374 TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
375   ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
376                                          /* src= */ "Ljava/util/SimpleTimeZone;"));
377   ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
378 }
379 
TEST_F(VerifierDepsTest,Assignable_BothArrays_Resolved)380 TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
381   ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;",
382                                          /* src= */ "[[Ljava/util/SimpleTimeZone;"));
383   // If the component types of both arrays are resolved, we optimize the list of
384   // dependencies by recording a dependency on the component types.
385   ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;"));
386   ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;"));
387   ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
388 }
389 
TEST_F(VerifierDepsTest,ReturnType_Reference)390 TEST_F(VerifierDepsTest, ReturnType_Reference) {
391   ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
392   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
393 }
394 
TEST_F(VerifierDepsTest,InvokeArgumentType)395 TEST_F(VerifierDepsTest, InvokeArgumentType) {
396   ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
397   ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
398 }
399 
TEST_F(VerifierDepsTest,MergeTypes_RegisterLines)400 TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
401   ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
402   ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;"));
403   ASSERT_TRUE(HasAssignable(
404       "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
405 }
406 
TEST_F(VerifierDepsTest,MergeTypes_IfInstanceOf)407 TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
408   ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
409   ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
410   ASSERT_TRUE(HasAssignable(
411       "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
412 }
413 
TEST_F(VerifierDepsTest,MergeTypes_Unresolved)414 TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
415   ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
416   ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
417   ASSERT_TRUE(HasAssignable(
418       "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
419 }
420 
TEST_F(VerifierDepsTest,Throw)421 TEST_F(VerifierDepsTest, Throw) {
422   ASSERT_TRUE(VerifyMethod("Throw"));
423   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
424 }
425 
TEST_F(VerifierDepsTest,MoveException_Resolved)426 TEST_F(VerifierDepsTest, MoveException_Resolved) {
427   ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
428 
429   // Testing that all exception types are assignable to Throwable.
430   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;"));
431   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
432   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;"));
433 
434   // Testing that the merge type is assignable to Throwable.
435   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;"));
436 
437   // Merging of exception types.
438   ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;"));
439   ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;"));
440   ASSERT_TRUE(HasAssignable(
441       "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
442 }
443 
TEST_F(VerifierDepsTest,InstanceField_Resolved_DeclaredInReferenced)444 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
445   ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
446   ASSERT_TRUE(HasAssignable(
447       "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
448 }
449 
TEST_F(VerifierDepsTest,InstanceField_Resolved_DeclaredInSuperclass1)450 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
451   ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
452   ASSERT_TRUE(HasAssignable(
453       "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
454 }
455 
TEST_F(VerifierDepsTest,InstanceField_Resolved_DeclaredInSuperclass2)456 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
457   ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
458   ASSERT_TRUE(HasAssignable(
459       "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
460 }
461 
TEST_F(VerifierDepsTest,InvokeVirtual_Resolved_DeclaredInReferenced)462 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
463   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
464   // Type dependency on `this` argument.
465   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
466 }
467 
TEST_F(VerifierDepsTest,InvokeVirtual_Resolved_DeclaredInSuperclass1)468 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
469   ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
470   // Type dependency on `this` argument.
471   ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
472 }
473 
TEST_F(VerifierDepsTest,InvokeSuper_ThisAssignable)474 TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
475   ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
476   ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;"));
477 }
478 
TEST_F(VerifierDepsTest,EncodeDecode)479 TEST_F(VerifierDepsTest, EncodeDecode) {
480   VerifyDexFile();
481 
482   ASSERT_EQ(1u, NumberOfCompiledDexFiles());
483   ASSERT_TRUE(HasEachKindOfRecord());
484 
485   std::vector<uint8_t> buffer;
486   verifier_deps_->Encode(dex_files_, &buffer);
487   ASSERT_FALSE(buffer.empty());
488 
489   VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
490   bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
491   ASSERT_TRUE(parsed);
492   ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
493 }
494 
TEST_F(VerifierDepsTest,EncodeDecodeMulti)495 TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
496   VerifyDexFile("MultiDex");
497 
498   ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
499   std::vector<uint8_t> buffer;
500   verifier_deps_->Encode(dex_files_, &buffer);
501   ASSERT_FALSE(buffer.empty());
502 
503   // Create new DexFile, to mess with std::map order: the verifier deps used
504   // to iterate over the map, which doesn't guarantee insertion order. We fixed
505   // this by passing the expected order when encoding/decoding.
506   std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
507   std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
508   std::vector<const DexFile*> dex_files;
509   dex_files.reserve(first_dex_files.size() + second_dex_files.size());
510   for (auto& dex_file : first_dex_files) {
511     dex_files.push_back(dex_file.get());
512   }
513   for (auto& dex_file : second_dex_files) {
514     dex_files.push_back(dex_file.get());
515   }
516 
517   // Dump the new verifier deps to ensure it can properly read the data.
518   VerifierDeps decoded_deps(dex_files, /*output_only=*/ false);
519   bool parsed = decoded_deps.ParseStoredData(dex_files, ArrayRef<const uint8_t>(buffer));
520   ASSERT_TRUE(parsed);
521   std::ostringstream stream;
522   VariableIndentationOutputStream os(&stream);
523   decoded_deps.Dump(&os);
524 }
525 
TEST_F(VerifierDepsTest,UnverifiedClasses)526 TEST_F(VerifierDepsTest, UnverifiedClasses) {
527   VerifyDexFile();
528   ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
529   // Test that a class with a soft failure is recorded.
530   ASSERT_TRUE(HasUnverifiedClass("LMain;"));
531   // Test that a class with hard failure is recorded.
532   ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
533   // Test that a class with unresolved super and hard failure is recorded.
534   ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
535   // Test that a class with unresolved super can be verified.
536   ASSERT_TRUE(HasVerifiedClass("LMyClassWithNoSuper;"));
537 }
538 
TEST_F(VerifierDepsTest,UnverifiedOrder)539 TEST_F(VerifierDepsTest, UnverifiedOrder) {
540   ScopedObjectAccess soa(Thread::Current());
541   jobject loader = LoadDex("VerifierDeps");
542   std::vector<const DexFile*> dex_files = GetDexFiles(loader);
543   ASSERT_GT(dex_files.size(), 0u);
544   const DexFile* dex_file = dex_files[0];
545   VerifierDeps deps1(dex_files);
546   deps1.MaybeRecordVerificationStatus(&deps1,
547                                       *dex_file,
548                                       dex_file->GetClassDef(0u),
549                                       verifier::FailureKind::kHardFailure);
550   deps1.MaybeRecordVerificationStatus(&deps1,
551                                       *dex_file,
552                                       dex_file->GetClassDef(1u),
553                                       verifier::FailureKind::kHardFailure);
554   VerifierDeps deps2(dex_files);
555   deps2.MaybeRecordVerificationStatus(&deps2,
556                                       *dex_file,
557                                       dex_file->GetClassDef(1u),
558                                       verifier::FailureKind::kHardFailure);
559   deps2.MaybeRecordVerificationStatus(&deps2,
560                                       *dex_file,
561                                       dex_file->GetClassDef(0u),
562                                       verifier::FailureKind::kHardFailure);
563   std::vector<uint8_t> buffer1;
564   deps1.Encode(dex_files, &buffer1);
565   std::vector<uint8_t> buffer2;
566   deps2.Encode(dex_files, &buffer2);
567   EXPECT_EQ(buffer1, buffer2);
568 }
569 
TEST_F(VerifierDepsTest,VerifyDeps)570 TEST_F(VerifierDepsTest, VerifyDeps) {
571   VerifyDexFile();
572   ASSERT_EQ(1u, NumberOfCompiledDexFiles());
573   ASSERT_TRUE(HasEachKindOfRecord());
574 
575   // When validating, we create a new class loader, as
576   // the existing `class_loader_` may contain erroneous classes,
577   // that ClassLinker::FindClass won't return.
578 
579   std::vector<uint8_t> buffer;
580   verifier_deps_->Encode(dex_files_, &buffer);
581   ASSERT_FALSE(buffer.empty());
582 
583   // Check that dependencies are satisfied after decoding `buffer`.
584   ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer));
585 }
586 
TEST_F(VerifierDepsTest,CompilerDriver)587 TEST_F(VerifierDepsTest, CompilerDriver) {
588   SetupCompilerDriver();
589 
590   // Test both multi-dex and single-dex configuration.
591   for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
592     // Test that the compiler driver behaves as expected when the dependencies
593     // verify and when they don't verify.
594     for (bool verify_failure : { false, true }) {
595       {
596         ScopedObjectAccess soa(Thread::Current());
597         LoadDexFile(soa, "VerifierDeps", multi);
598       }
599       VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
600 
601       std::vector<uint8_t> buffer;
602       verifier_deps_->Encode(dex_files_, &buffer);
603 
604       {
605         ScopedObjectAccess soa(Thread::Current());
606         LoadDexFile(soa, "VerifierDeps", multi);
607       }
608       VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
609       bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
610       ASSERT_TRUE(parsed);
611       VerifyWithCompilerDriver(&decoded_deps);
612 
613       if (verify_failure) {
614         ASSERT_FALSE(verifier_deps_ == nullptr);
615         ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
616       } else {
617         VerifyClassStatus(decoded_deps);
618       }
619     }
620   }
621 }
622 
TEST_F(VerifierDepsTest,MultiDexVerification)623 TEST_F(VerifierDepsTest, MultiDexVerification) {
624   VerifyDexFile("VerifierDepsMulti");
625   ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
626 
627   ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
628   ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
629   ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
630 
631   std::vector<uint8_t> buffer;
632   verifier_deps_->Encode(dex_files_, &buffer);
633   ASSERT_FALSE(buffer.empty());
634 }
635 
636 }  // namespace verifier
637 }  // namespace art
638