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