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