blob: d096e689128b25afb8bbcba21c94809e8cfda04e [file] [log] [blame]
David Brazdilca3c8c32016-09-06 14:04:48 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Nicolas Geoffray08025182016-10-25 17:20:18 +010017// Test is in compiler, as it uses compiler related code.
18#include "verifier/verifier_deps.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010019
Andreas Gampec6ea7d02017-02-01 16:46:28 -080020#include "art_method-inl.h"
David Sehr9c4a0152018-04-05 12:23:54 -070021#include "base/indenter.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010022#include "class_linker.h"
Vladimir Marko815d5e52019-03-04 10:18:31 +000023#include "common_compiler_driver_test.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010024#include "compiler_callbacks.h"
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070025#include "dex/class_accessor-inl.h"
26#include "dex/class_iterator.h"
David Sehr9e734c72018-01-04 17:56:19 -080027#include "dex/dex_file-inl.h"
28#include "dex/dex_file_types.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070029#include "dex/verification_results.h"
Andreas Gamped482e732017-04-24 17:59:09 -070030#include "driver/compiler_driver-inl.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070031#include "driver/compiler_options.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010032#include "handle_scope-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010033#include "mirror/class_loader.h"
34#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070035#include "scoped_thread_state_change-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070036#include "thread.h"
Mathieu Chartier93764b82017-07-17 14:51:53 -070037#include "utils/atomic_dex_ref_map-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070038#include "verifier/method_verifier-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010039
40namespace art {
41namespace verifier {
42
43class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
44 public:
Igor Murashkin2ffb7032017-11-08 13:35:21 -080045 VerifierDepsCompilerCallbacks()
David Brazdilca3c8c32016-09-06 14:04:48 +010046 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
47 deps_(nullptr) {}
48
Nicolas Geoffray9e050ab2021-07-14 14:59:25 +010049 void AddUncompilableMethod(MethodReference ref ATTRIBUTE_UNUSED) override {}
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010050 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) override {}
David Brazdilca3c8c32016-09-06 14:04:48 +010051
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010052 verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; }
Andreas Gampefa6a1b02018-09-07 08:11:55 -070053 void SetVerifierDeps(verifier::VerifierDeps* deps) override { deps_ = deps; }
David Brazdilca3c8c32016-09-06 14:04:48 +010054
55 private:
56 verifier::VerifierDeps* deps_;
57};
58
Vladimir Marko815d5e52019-03-04 10:18:31 +000059class VerifierDepsTest : public CommonCompilerDriverTest {
David Brazdilca3c8c32016-09-06 14:04:48 +010060 public:
Andreas Gampefa6a1b02018-09-07 08:11:55 -070061 void SetUpRuntimeOptions(RuntimeOptions* options) override {
Nicolas Geoffray08025182016-10-25 17:20:18 +010062 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010063 callbacks_.reset(new VerifierDepsCompilerCallbacks());
64 }
65
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010066 ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name)
David Brazdilca3c8c32016-09-06 14:04:48 +010067 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010068 StackHandleScope<1> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +010069 Handle<mirror::ClassLoader> class_loader_handle(
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010070 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
71 ObjPtr<mirror::Class> klass =
72 class_linker_->FindClass(soa.Self(), name.c_str(), class_loader_handle);
David Brazdil6f82fbd2016-09-14 11:55:26 +010073 if (klass == nullptr) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010074 DCHECK(soa.Self()->IsExceptionPending());
75 soa.Self()->ClearException();
David Brazdil6f82fbd2016-09-14 11:55:26 +010076 }
77 return klass;
78 }
79
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000080 void SetupCompilerDriver() {
Vladimir Marko9c4b9702018-11-14 15:09:02 +000081 compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000082 compiler_driver_->InitializeThreadPools();
83 }
84
Andreas Gampe3db70682018-12-26 15:12:03 -080085 void VerifyWithCompilerDriver(verifier::VerifierDeps* verifier_deps) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000086 TimingLogger timings("Verify", false, false);
87 // The compiler driver handles the verifier deps in the callbacks, so
88 // remove what this class did for unit testing.
Andreas Gampe3db70682018-12-26 15:12:03 -080089 if (verifier_deps == nullptr) {
Mathieu Chartier72041a02017-07-14 18:23:25 -070090 // Create some verifier deps by default if they are not already specified.
Andreas Gampe3db70682018-12-26 15:12:03 -080091 verifier_deps = new verifier::VerifierDeps(dex_files_);
92 verifier_deps_.reset(verifier_deps);
Mathieu Chartier72041a02017-07-14 18:23:25 -070093 }
Andreas Gampe3db70682018-12-26 15:12:03 -080094 callbacks_->SetVerifierDeps(verifier_deps);
Nicolas Geoffray9e050ab2021-07-14 14:59:25 +010095 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000096 callbacks_->SetVerifierDeps(nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000097 }
98
David Brazdil6f82fbd2016-09-14 11:55:26 +010099 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
100 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
101 VerifierDepsCompilerCallbacks* callbacks =
102 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
103 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +0100104 }
105
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100106 void LoadDexFile(ScopedObjectAccess& soa, const char* name1, const char* name2 = nullptr)
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100107 REQUIRES_SHARED(Locks::mutator_lock_) {
108 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
109 dex_files_ = GetDexFiles(class_loader_);
110 primary_dex_file_ = dex_files_.front();
111
112 SetVerifierDeps(dex_files_);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100113 StackHandleScope<1> hs(soa.Self());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100114 Handle<mirror::ClassLoader> loader =
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100115 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100116 for (const DexFile* dex_file : dex_files_) {
117 class_linker_->RegisterDexFile(*dex_file, loader.Get());
118 }
Vladimir Marko213ee2d2018-06-22 11:56:34 +0100119 SetDexFilesForOatFile(dex_files_);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100120 }
121
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100122 void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100123 LoadDexFile(soa, "VerifierDeps");
124 CHECK_EQ(dex_files_.size(), 1u);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100125 klass_Main_ = FindClassByName(soa, "LMain;");
David Brazdilca3c8c32016-09-06 14:04:48 +0100126 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100127 }
128
129 bool VerifyMethod(const std::string& method_name) {
130 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100131 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100132
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100133 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100134 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700135 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100136 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
137
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800138 const dex::ClassDef* class_def = klass_Main_->GetClassDef();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700139 ClassAccessor accessor(*primary_dex_file_, *class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100140
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700141 bool has_failures = true;
142 bool found_method = false;
David Brazdilca3c8c32016-09-06 14:04:48 +0100143
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700144 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
Vladimir Markoba118822017-06-12 15:41:56 +0100145 ArtMethod* resolved_method =
146 class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700147 method.GetIndex(),
Vladimir Markoba118822017-06-12 15:41:56 +0100148 dex_cache_handle,
149 class_loader_handle,
Andreas Gampe3db70682018-12-26 15:12:03 -0800150 /* referrer= */ nullptr,
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700151 method.GetInvokeType(class_def->access_flags_));
David Brazdilca3c8c32016-09-06 14:04:48 +0100152 CHECK(resolved_method != nullptr);
153 if (method_name == resolved_method->GetName()) {
Andreas Gampefc25ae92019-04-19 22:22:57 -0700154 std::unique_ptr<MethodVerifier> verifier(
155 MethodVerifier::CreateVerifier(soa.Self(),
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000156 callbacks_->GetVerifierDeps(),
Andreas Gampefc25ae92019-04-19 22:22:57 -0700157 primary_dex_file_,
158 dex_cache_handle,
159 class_loader_handle,
160 *class_def,
161 method.GetCodeItem(),
162 method.GetIndex(),
Andreas Gampefc25ae92019-04-19 22:22:57 -0700163 method.GetAccessFlags(),
164 /* can_load_classes= */ true,
165 /* allow_soft_failures= */ true,
Andreas Gampefc25ae92019-04-19 22:22:57 -0700166 /* verify to dump */ false,
167 /* allow_thread_suspension= */ true,
168 /* api_level= */ 0));
169 verifier->Verify();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700170 soa.Self()->SetVerifierDeps(nullptr);
Andreas Gampefc25ae92019-04-19 22:22:57 -0700171 has_failures = verifier->HasFailures();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700172 found_method = true;
David Brazdilca3c8c32016-09-06 14:04:48 +0100173 }
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700174 }
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700175 CHECK(found_method) << "Expected to find method " << method_name;
176 return !has_failures;
David Brazdilca3c8c32016-09-06 14:04:48 +0100177 }
178
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100179 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100180 {
181 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100182 LoadDexFile(soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100183 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000184 SetupCompilerDriver();
Andreas Gampe3db70682018-12-26 15:12:03 -0800185 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100186 }
187
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100188 bool TestAssignabilityRecording(const std::string& dst, const std::string& src) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100189 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100190 LoadDexFile(soa);
191 StackHandleScope<1> hs(soa.Self());
192 Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100193 DCHECK(klass_dst != nullptr) << dst;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100194 ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src);
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100195 DCHECK(klass_src != nullptr) << src;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100196 verifier_deps_->AddAssignability(*primary_dex_file_,
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000197 primary_dex_file_->GetClassDef(0),
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100198 klass_dst.Get(),
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100199 klass_src);
David Brazdilca3c8c32016-09-06 14:04:48 +0100200 return true;
201 }
202
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000203 // Check that the status of classes in `class_loader_` match the
204 // expected status in `deps`.
205 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
206 ScopedObjectAccess soa(Thread::Current());
207 StackHandleScope<2> hs(soa.Self());
208 Handle<mirror::ClassLoader> class_loader_handle(
209 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
210 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
211 for (const DexFile* dex_file : dex_files_) {
David Brazdilfeb22822019-02-13 21:25:57 +0000212 const std::vector<bool>& verified_classes = deps.GetVerifiedClasses(*dex_file);
213 ASSERT_EQ(verified_classes.size(), dex_file->NumClassDefs());
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000214 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800215 const dex::ClassDef& class_def = dex_file->GetClassDef(i);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000216 const char* descriptor = dex_file->GetClassDescriptor(class_def);
217 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800218 if (cls == nullptr) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000219 CHECK(soa.Self()->IsExceptionPending());
220 soa.Self()->ClearException();
Andreas Gampebb30d5d2018-04-23 09:59:25 -0700221 } else if (&cls->GetDexFile() != dex_file) {
222 // Ignore classes from different dex files.
David Brazdilfeb22822019-02-13 21:25:57 +0000223 } else if (verified_classes[i]) {
Nicolas Geoffray6ebe40f2020-10-14 16:37:58 +0100224 ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerifiedNeedsAccessChecks);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000225 } else {
Vladimir Marko2c64a832018-01-04 11:31:56 +0000226 ASSERT_LT(cls->GetStatus(), ClassStatus::kVerified);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000227 }
228 }
229 }
230 }
231
David Brazdilfeb22822019-02-13 21:25:57 +0000232 uint16_t GetClassDefIndex(const std::string& cls, const DexFile& dex_file) {
233 const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
234 DCHECK(type_id != nullptr);
235 dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
236 const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx);
237 DCHECK(class_def != nullptr);
238 return dex_file.GetIndexForClassDef(*class_def);
239 }
240
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000241 bool HasVerifiedClass(const std::string& cls) {
242 return HasVerifiedClass(cls, *primary_dex_file_);
243 }
244
Nicolas Geoffray08025182016-10-25 17:20:18 +0100245 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000246 return !HasVerifiedClass(cls, *primary_dex_file_);
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000247 }
248
249 bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000250 return !HasVerifiedClass(cls, dex_file);
251 }
252
253 bool HasVerifiedClass(const std::string& cls, const DexFile& dex_file) {
David Brazdilfeb22822019-02-13 21:25:57 +0000254 uint16_t class_def_idx = GetClassDefIndex(cls, dex_file);
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000255 return verifier_deps_->GetVerifiedClasses(dex_file)[class_def_idx];
David Brazdilfeb22822019-02-13 21:25:57 +0000256 }
257
David Brazdilca3c8c32016-09-06 14:04:48 +0100258 // Iterates over all assignability records and tries to find an entry which
259 // matches the expected destination/source pair.
260 bool HasAssignable(const std::string& expected_destination,
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000261 const std::string& expected_source) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100262 for (auto& dex_dep : verifier_deps_->dex_deps_) {
263 const DexFile& dex_file = *dex_dep.first;
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100264 auto& storage = dex_dep.second->assignable_types_;
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000265 for (auto& set : storage) {
266 for (auto& entry : set) {
267 std::string actual_destination =
268 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
269 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
270 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
271 return true;
272 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100273 }
274 }
275 }
276 return false;
277 }
278
David Brazdil6f82fbd2016-09-14 11:55:26 +0100279 size_t NumberOfCompiledDexFiles() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100280 return verifier_deps_->dex_deps_.size();
281 }
282
David Brazdilfeb22822019-02-13 21:25:57 +0000283 bool HasBoolValue(const std::vector<bool>& vec, bool value) {
284 return std::count(vec.begin(), vec.end(), value) > 0;
285 }
286
Andreas Gampe654698d2018-09-20 13:34:35 -0700287 bool HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100288 bool has_strings = false;
289 bool has_assignability = false;
David Brazdilfeb22822019-02-13 21:25:57 +0000290 bool has_verified_classes = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100291 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100292
293 for (auto& entry : verifier_deps_->dex_deps_) {
294 has_strings |= !entry.second->strings_.empty();
295 has_assignability |= !entry.second->assignable_types_.empty();
David Brazdilfeb22822019-02-13 21:25:57 +0000296 has_verified_classes |= HasBoolValue(entry.second->verified_classes_, true);
297 has_unverified_classes |= HasBoolValue(entry.second->verified_classes_, false);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100298 }
299
Nicolas Geoffray08025182016-10-25 17:20:18 +0100300 return has_strings &&
301 has_assignability &&
David Brazdilfeb22822019-02-13 21:25:57 +0000302 has_verified_classes &&
Nicolas Geoffray07b62e32020-11-07 15:54:08 +0000303 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100304 }
305
David Brazdil8fd67222019-02-05 18:13:44 +0000306 // Load the dex file again with a new class loader, decode the VerifierDeps
307 // in `buffer`, allow the caller to modify the deps and then run validation.
308 template<typename Fn>
309 bool RunValidation(Fn fn, const std::vector<uint8_t>& buffer, std::string* error_msg) {
310 ScopedObjectAccess soa(Thread::Current());
311
312 jobject second_loader = LoadDex("VerifierDeps");
313 const auto& second_dex_files = GetDexFiles(second_loader);
314
Vladimir Markoc3908792020-04-06 14:52:04 +0100315 VerifierDeps decoded_deps(second_dex_files, /*output_only=*/ false);
316 bool parsed = decoded_deps.ParseStoredData(second_dex_files, ArrayRef<const uint8_t>(buffer));
317 CHECK(parsed);
David Brazdil8fd67222019-02-05 18:13:44 +0000318 VerifierDeps::DexFileDeps* decoded_dex_deps =
319 decoded_deps.GetDexFileDeps(*second_dex_files.front());
320
321 // Let the test modify the dependencies.
322 fn(*decoded_dex_deps);
323
324 StackHandleScope<1> hs(soa.Self());
325 Handle<mirror::ClassLoader> new_class_loader =
326 hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(second_loader));
David Brazdilfeb22822019-02-13 21:25:57 +0000327
328 return decoded_deps.ValidateDependencies(soa.Self(),
329 new_class_loader,
David Brazdilfeb22822019-02-13 21:25:57 +0000330 error_msg);
David Brazdil8fd67222019-02-05 18:13:44 +0000331 }
332
David Brazdilca3c8c32016-09-06 14:04:48 +0100333 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100334 std::vector<const DexFile*> dex_files_;
335 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100336 jobject class_loader_;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100337 ObjPtr<mirror::Class> klass_Main_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100338};
339
340TEST_F(VerifierDepsTest, StringToId) {
341 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100342 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100343
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800344 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
345 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100346 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100347
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800348 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
349 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100350 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100351
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800352 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
353 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100354 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100355
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800356 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
357 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100358 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100359
360 ASSERT_EQ(id_Main1, id_Main2);
361 ASSERT_EQ(id_Lorem1, id_Lorem2);
362 ASSERT_NE(id_Main1, id_Lorem1);
363}
364
365TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800366 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100367 /* src= */ "Ljava/util/SimpleTimeZone;"));
368 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100369}
370
David Brazdilca3c8c32016-09-06 14:04:48 +0100371TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800372 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100373 /* src= */ "[[Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100374 // If the component types of both arrays are resolved, we optimize the list of
375 // dependencies by recording a dependency on the component types.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100376 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;"));
377 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;"));
378 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100379}
380
David Brazdilca3c8c32016-09-06 14:04:48 +0100381TEST_F(VerifierDepsTest, ReturnType_Reference) {
382 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100383 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100384}
385
386TEST_F(VerifierDepsTest, InvokeArgumentType) {
387 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100388 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100389}
390
391TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
392 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000393 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100394 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100395 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100396}
397
398TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
399 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100400 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100401 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100402 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100403}
404
405TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
406 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100407 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100408 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100409 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100410}
411
David Brazdilca3c8c32016-09-06 14:04:48 +0100412TEST_F(VerifierDepsTest, Throw) {
413 ASSERT_TRUE(VerifyMethod("Throw"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100414 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100415}
416
417TEST_F(VerifierDepsTest, MoveException_Resolved) {
418 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100419
420 // Testing that all exception types are assignable to Throwable.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100421 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;"));
422 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
423 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100424
425 // Testing that the merge type is assignable to Throwable.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100426 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100427
428 // Merging of exception types.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100429 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;"));
430 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100431 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100432 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100433}
434
David Brazdilca3c8c32016-09-06 14:04:48 +0100435TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
436 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100437 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000438 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100439}
440
441TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
442 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100443 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000444 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100445}
446
447TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
448 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100449 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000450 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100451}
452
David Brazdilca3c8c32016-09-06 14:04:48 +0100453TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
454 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100455 // Type dependency on `this` argument.
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000456 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100457}
458
459TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
460 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100461 // Type dependency on `this` argument.
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000462 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100463}
464
David Brazdilca3c8c32016-09-06 14:04:48 +0100465TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
466 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000467 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000468}
469
David Brazdil6f82fbd2016-09-14 11:55:26 +0100470TEST_F(VerifierDepsTest, EncodeDecode) {
471 VerifyDexFile();
472
473 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
474 ASSERT_TRUE(HasEachKindOfRecord());
475
476 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100477 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100478 ASSERT_FALSE(buffer.empty());
479
Vladimir Markoc3908792020-04-06 14:52:04 +0100480 VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
481 bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
482 ASSERT_TRUE(parsed);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100483 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
484}
485
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100486TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
487 VerifyDexFile("MultiDex");
488
489 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
490 std::vector<uint8_t> buffer;
491 verifier_deps_->Encode(dex_files_, &buffer);
492 ASSERT_FALSE(buffer.empty());
493
494 // Create new DexFile, to mess with std::map order: the verifier deps used
495 // to iterate over the map, which doesn't guarantee insertion order. We fixed
496 // this by passing the expected order when encoding/decoding.
497 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
498 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
499 std::vector<const DexFile*> dex_files;
500 for (auto& dex_file : first_dex_files) {
501 dex_files.push_back(dex_file.get());
502 }
503 for (auto& dex_file : second_dex_files) {
504 dex_files.push_back(dex_file.get());
505 }
506
507 // Dump the new verifier deps to ensure it can properly read the data.
Vladimir Markoc3908792020-04-06 14:52:04 +0100508 VerifierDeps decoded_deps(dex_files, /*output_only=*/ false);
509 bool parsed = decoded_deps.ParseStoredData(dex_files, ArrayRef<const uint8_t>(buffer));
510 ASSERT_TRUE(parsed);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100511 std::ostringstream stream;
512 VariableIndentationOutputStream os(&stream);
513 decoded_deps.Dump(&os);
514}
515
Nicolas Geoffray08025182016-10-25 17:20:18 +0100516TEST_F(VerifierDepsTest, UnverifiedClasses) {
517 VerifyDexFile();
518 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
519 // Test that a class with a soft failure is recorded.
520 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
521 // Test that a class with hard failure is recorded.
522 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100523 // Test that a class with unresolved super and hard failure is recorded.
524 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000525 // Test that a class with unresolved super can be verified.
526 ASSERT_TRUE(HasVerifiedClass("LMyClassWithNoSuper;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100527}
528
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700529TEST_F(VerifierDepsTest, UnverifiedOrder) {
530 ScopedObjectAccess soa(Thread::Current());
531 jobject loader = LoadDex("VerifierDeps");
532 std::vector<const DexFile*> dex_files = GetDexFiles(loader);
533 ASSERT_GT(dex_files.size(), 0u);
534 const DexFile* dex_file = dex_files[0];
535 VerifierDeps deps1(dex_files);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000536 deps1.MaybeRecordVerificationStatus(&deps1,
537 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000538 dex_file->GetClassDef(0u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700539 verifier::FailureKind::kHardFailure);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000540 deps1.MaybeRecordVerificationStatus(&deps1,
541 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000542 dex_file->GetClassDef(1u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700543 verifier::FailureKind::kHardFailure);
544 VerifierDeps deps2(dex_files);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000545 deps2.MaybeRecordVerificationStatus(&deps2,
546 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000547 dex_file->GetClassDef(1u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700548 verifier::FailureKind::kHardFailure);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000549 deps2.MaybeRecordVerificationStatus(&deps2,
550 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000551 dex_file->GetClassDef(0u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700552 verifier::FailureKind::kHardFailure);
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700553 std::vector<uint8_t> buffer1;
554 deps1.Encode(dex_files, &buffer1);
555 std::vector<uint8_t> buffer2;
556 deps2.Encode(dex_files, &buffer2);
557 EXPECT_EQ(buffer1, buffer2);
558}
559
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100560TEST_F(VerifierDepsTest, VerifyDeps) {
David Brazdil8fd67222019-02-05 18:13:44 +0000561 std::string error_msg;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100562
David Brazdil8fd67222019-02-05 18:13:44 +0000563 VerifyDexFile();
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100564 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
565 ASSERT_TRUE(HasEachKindOfRecord());
566
567 // When validating, we create a new class loader, as
568 // the existing `class_loader_` may contain erroneous classes,
569 // that ClassLinker::FindClass won't return.
570
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100571 std::vector<uint8_t> buffer;
572 verifier_deps_->Encode(dex_files_, &buffer);
573 ASSERT_FALSE(buffer.empty());
574
David Brazdil8fd67222019-02-05 18:13:44 +0000575 // Check that dependencies are satisfied after decoding `buffer`.
576 ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer, &error_msg))
577 << error_msg;
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000578}
579
580TEST_F(VerifierDepsTest, CompilerDriver) {
581 SetupCompilerDriver();
582
583 // Test both multi-dex and single-dex configuration.
584 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
585 // Test that the compiler driver behaves as expected when the dependencies
586 // verify and when they don't verify.
587 for (bool verify_failure : { false, true }) {
588 {
589 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100590 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000591 }
Andreas Gampe3db70682018-12-26 15:12:03 -0800592 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000593
594 std::vector<uint8_t> buffer;
595 verifier_deps_->Encode(dex_files_, &buffer);
596
597 {
598 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100599 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000600 }
Vladimir Markoc3908792020-04-06 14:52:04 +0100601 VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
602 bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
603 ASSERT_TRUE(parsed);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000604 VerifyWithCompilerDriver(&decoded_deps);
605
606 if (verify_failure) {
607 ASSERT_FALSE(verifier_deps_ == nullptr);
608 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
609 } else {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000610 VerifyClassStatus(decoded_deps);
611 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100612 }
613 }
614}
615
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000616TEST_F(VerifierDepsTest, MultiDexVerification) {
617 VerifyDexFile("VerifierDepsMulti");
618 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
619
620 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
621 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
622 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
623
624 std::vector<uint8_t> buffer;
625 verifier_deps_->Encode(dex_files_, &buffer);
626 ASSERT_FALSE(buffer.empty());
627}
628
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100629TEST_F(VerifierDepsTest, Assignable_Arrays) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800630 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[LIface;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100631 /* src= */ "[LMyClassExtendingInterface;"));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100632 ASSERT_FALSE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100633 "LIface;", "LMyClassExtendingInterface;"));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100634}
635
David Brazdilca3c8c32016-09-06 14:04:48 +0100636} // namespace verifier
637} // namespace art