blob: 708af0439054b4d0acc1bc7f1b0891c80058a03b [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:
Vladimir Marko483c41a2021-11-12 12:45:23 +000061 VerifierDepsTest() {
62 this->use_boot_image_ = true; // Make the Runtime creation cheaper.
63 }
64
Andreas Gampefa6a1b02018-09-07 08:11:55 -070065 void SetUpRuntimeOptions(RuntimeOptions* options) override {
Nicolas Geoffray08025182016-10-25 17:20:18 +010066 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010067 callbacks_.reset(new VerifierDepsCompilerCallbacks());
68 }
69
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010070 ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name)
David Brazdilca3c8c32016-09-06 14:04:48 +010071 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010072 StackHandleScope<1> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +010073 Handle<mirror::ClassLoader> class_loader_handle(
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010074 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
75 ObjPtr<mirror::Class> klass =
76 class_linker_->FindClass(soa.Self(), name.c_str(), class_loader_handle);
David Brazdil6f82fbd2016-09-14 11:55:26 +010077 if (klass == nullptr) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010078 DCHECK(soa.Self()->IsExceptionPending());
79 soa.Self()->ClearException();
David Brazdil6f82fbd2016-09-14 11:55:26 +010080 }
81 return klass;
82 }
83
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000084 void SetupCompilerDriver() {
Vladimir Marko9c4b9702018-11-14 15:09:02 +000085 compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000086 compiler_driver_->InitializeThreadPools();
87 }
88
Andreas Gampe3db70682018-12-26 15:12:03 -080089 void VerifyWithCompilerDriver(verifier::VerifierDeps* verifier_deps) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000090 TimingLogger timings("Verify", false, false);
91 // The compiler driver handles the verifier deps in the callbacks, so
92 // remove what this class did for unit testing.
Andreas Gampe3db70682018-12-26 15:12:03 -080093 if (verifier_deps == nullptr) {
Mathieu Chartier72041a02017-07-14 18:23:25 -070094 // Create some verifier deps by default if they are not already specified.
Andreas Gampe3db70682018-12-26 15:12:03 -080095 verifier_deps = new verifier::VerifierDeps(dex_files_);
96 verifier_deps_.reset(verifier_deps);
Mathieu Chartier72041a02017-07-14 18:23:25 -070097 }
Andreas Gampe3db70682018-12-26 15:12:03 -080098 callbacks_->SetVerifierDeps(verifier_deps);
Nicolas Geoffray9e050ab2021-07-14 14:59:25 +010099 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +0000100 callbacks_->SetVerifierDeps(nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000101 }
102
David Brazdil6f82fbd2016-09-14 11:55:26 +0100103 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
104 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
105 VerifierDepsCompilerCallbacks* callbacks =
106 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
107 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +0100108 }
109
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100110 void LoadDexFile(ScopedObjectAccess& soa, const char* name1, const char* name2 = nullptr)
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100111 REQUIRES_SHARED(Locks::mutator_lock_) {
112 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
113 dex_files_ = GetDexFiles(class_loader_);
114 primary_dex_file_ = dex_files_.front();
115
116 SetVerifierDeps(dex_files_);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100117 StackHandleScope<1> hs(soa.Self());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100118 Handle<mirror::ClassLoader> loader =
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100119 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100120 for (const DexFile* dex_file : dex_files_) {
121 class_linker_->RegisterDexFile(*dex_file, loader.Get());
122 }
Vladimir Marko213ee2d2018-06-22 11:56:34 +0100123 SetDexFilesForOatFile(dex_files_);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100124 }
125
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100126 void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100127 LoadDexFile(soa, "VerifierDeps");
128 CHECK_EQ(dex_files_.size(), 1u);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100129 klass_Main_ = FindClassByName(soa, "LMain;");
David Brazdilca3c8c32016-09-06 14:04:48 +0100130 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100131 }
132
133 bool VerifyMethod(const std::string& method_name) {
134 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100135 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100136
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100137 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100138 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700139 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100140 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
141
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800142 const dex::ClassDef* class_def = klass_Main_->GetClassDef();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700143 ClassAccessor accessor(*primary_dex_file_, *class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100144
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700145 bool has_failures = true;
146 bool found_method = false;
David Brazdilca3c8c32016-09-06 14:04:48 +0100147
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700148 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
Vladimir Markoba118822017-06-12 15:41:56 +0100149 ArtMethod* resolved_method =
150 class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700151 method.GetIndex(),
Vladimir Markoba118822017-06-12 15:41:56 +0100152 dex_cache_handle,
153 class_loader_handle,
Andreas Gampe3db70682018-12-26 15:12:03 -0800154 /* referrer= */ nullptr,
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700155 method.GetInvokeType(class_def->access_flags_));
David Brazdilca3c8c32016-09-06 14:04:48 +0100156 CHECK(resolved_method != nullptr);
157 if (method_name == resolved_method->GetName()) {
Andreas Gampefc25ae92019-04-19 22:22:57 -0700158 std::unique_ptr<MethodVerifier> verifier(
159 MethodVerifier::CreateVerifier(soa.Self(),
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000160 callbacks_->GetVerifierDeps(),
Andreas Gampefc25ae92019-04-19 22:22:57 -0700161 primary_dex_file_,
162 dex_cache_handle,
163 class_loader_handle,
164 *class_def,
165 method.GetCodeItem(),
166 method.GetIndex(),
Andreas Gampefc25ae92019-04-19 22:22:57 -0700167 method.GetAccessFlags(),
168 /* can_load_classes= */ true,
Andreas Gampefc25ae92019-04-19 22:22:57 -0700169 /* verify to dump */ false,
170 /* allow_thread_suspension= */ true,
171 /* api_level= */ 0));
172 verifier->Verify();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700173 soa.Self()->SetVerifierDeps(nullptr);
Andreas Gampefc25ae92019-04-19 22:22:57 -0700174 has_failures = verifier->HasFailures();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700175 found_method = true;
David Brazdilca3c8c32016-09-06 14:04:48 +0100176 }
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700177 }
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700178 CHECK(found_method) << "Expected to find method " << method_name;
179 return !has_failures;
David Brazdilca3c8c32016-09-06 14:04:48 +0100180 }
181
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100182 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100183 {
184 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100185 LoadDexFile(soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100186 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000187 SetupCompilerDriver();
Andreas Gampe3db70682018-12-26 15:12:03 -0800188 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100189 }
190
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100191 bool TestAssignabilityRecording(const std::string& dst, const std::string& src) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100192 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100193 LoadDexFile(soa);
194 StackHandleScope<1> hs(soa.Self());
195 Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100196 DCHECK(klass_dst != nullptr) << dst;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100197 ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src);
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100198 DCHECK(klass_src != nullptr) << src;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100199 verifier_deps_->AddAssignability(*primary_dex_file_,
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000200 primary_dex_file_->GetClassDef(0),
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100201 klass_dst.Get(),
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100202 klass_src);
David Brazdilca3c8c32016-09-06 14:04:48 +0100203 return true;
204 }
205
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000206 // Check that the status of classes in `class_loader_` match the
207 // expected status in `deps`.
208 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
209 ScopedObjectAccess soa(Thread::Current());
210 StackHandleScope<2> hs(soa.Self());
211 Handle<mirror::ClassLoader> class_loader_handle(
212 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
213 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
214 for (const DexFile* dex_file : dex_files_) {
David Brazdilfeb22822019-02-13 21:25:57 +0000215 const std::vector<bool>& verified_classes = deps.GetVerifiedClasses(*dex_file);
216 ASSERT_EQ(verified_classes.size(), dex_file->NumClassDefs());
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000217 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800218 const dex::ClassDef& class_def = dex_file->GetClassDef(i);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000219 const char* descriptor = dex_file->GetClassDescriptor(class_def);
220 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800221 if (cls == nullptr) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000222 CHECK(soa.Self()->IsExceptionPending());
223 soa.Self()->ClearException();
Andreas Gampebb30d5d2018-04-23 09:59:25 -0700224 } else if (&cls->GetDexFile() != dex_file) {
225 // Ignore classes from different dex files.
David Brazdilfeb22822019-02-13 21:25:57 +0000226 } else if (verified_classes[i]) {
Nicolas Geoffray6ebe40f2020-10-14 16:37:58 +0100227 ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerifiedNeedsAccessChecks);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000228 } else {
Vladimir Marko2c64a832018-01-04 11:31:56 +0000229 ASSERT_LT(cls->GetStatus(), ClassStatus::kVerified);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000230 }
231 }
232 }
233 }
234
David Brazdilfeb22822019-02-13 21:25:57 +0000235 uint16_t GetClassDefIndex(const std::string& cls, const DexFile& dex_file) {
236 const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
237 DCHECK(type_id != nullptr);
238 dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
239 const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx);
240 DCHECK(class_def != nullptr);
241 return dex_file.GetIndexForClassDef(*class_def);
242 }
243
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000244 bool HasVerifiedClass(const std::string& cls) {
245 return HasVerifiedClass(cls, *primary_dex_file_);
246 }
247
Nicolas Geoffray08025182016-10-25 17:20:18 +0100248 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000249 return !HasVerifiedClass(cls, *primary_dex_file_);
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000250 }
251
252 bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000253 return !HasVerifiedClass(cls, dex_file);
254 }
255
256 bool HasVerifiedClass(const std::string& cls, const DexFile& dex_file) {
David Brazdilfeb22822019-02-13 21:25:57 +0000257 uint16_t class_def_idx = GetClassDefIndex(cls, dex_file);
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000258 return verifier_deps_->GetVerifiedClasses(dex_file)[class_def_idx];
David Brazdilfeb22822019-02-13 21:25:57 +0000259 }
260
David Brazdilca3c8c32016-09-06 14:04:48 +0100261 // Iterates over all assignability records and tries to find an entry which
262 // matches the expected destination/source pair.
263 bool HasAssignable(const std::string& expected_destination,
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000264 const std::string& expected_source) const {
David Brazdilca3c8c32016-09-06 14:04:48 +0100265 for (auto& dex_dep : verifier_deps_->dex_deps_) {
266 const DexFile& dex_file = *dex_dep.first;
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100267 auto& storage = dex_dep.second->assignable_types_;
Nicolas Geoffray1960c422020-11-04 08:45:32 +0000268 for (auto& set : storage) {
269 for (auto& entry : set) {
270 std::string actual_destination =
271 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
272 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
273 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
274 return true;
275 }
David Brazdilca3c8c32016-09-06 14:04:48 +0100276 }
277 }
278 }
279 return false;
280 }
281
David Brazdil6f82fbd2016-09-14 11:55:26 +0100282 size_t NumberOfCompiledDexFiles() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100283 return verifier_deps_->dex_deps_.size();
284 }
285
David Brazdilfeb22822019-02-13 21:25:57 +0000286 bool HasBoolValue(const std::vector<bool>& vec, bool value) {
287 return std::count(vec.begin(), vec.end(), value) > 0;
288 }
289
Andreas Gampe654698d2018-09-20 13:34:35 -0700290 bool HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100291 bool has_strings = false;
292 bool has_assignability = false;
David Brazdilfeb22822019-02-13 21:25:57 +0000293 bool has_verified_classes = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100294 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100295
296 for (auto& entry : verifier_deps_->dex_deps_) {
297 has_strings |= !entry.second->strings_.empty();
298 has_assignability |= !entry.second->assignable_types_.empty();
David Brazdilfeb22822019-02-13 21:25:57 +0000299 has_verified_classes |= HasBoolValue(entry.second->verified_classes_, true);
300 has_unverified_classes |= HasBoolValue(entry.second->verified_classes_, false);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100301 }
302
Nicolas Geoffray08025182016-10-25 17:20:18 +0100303 return has_strings &&
304 has_assignability &&
David Brazdilfeb22822019-02-13 21:25:57 +0000305 has_verified_classes &&
Nicolas Geoffray07b62e32020-11-07 15:54:08 +0000306 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100307 }
308
David Brazdil8fd67222019-02-05 18:13:44 +0000309 // Load the dex file again with a new class loader, decode the VerifierDeps
310 // in `buffer`, allow the caller to modify the deps and then run validation.
311 template<typename Fn>
312 bool RunValidation(Fn fn, const std::vector<uint8_t>& buffer, std::string* error_msg) {
313 ScopedObjectAccess soa(Thread::Current());
314
315 jobject second_loader = LoadDex("VerifierDeps");
316 const auto& second_dex_files = GetDexFiles(second_loader);
317
Vladimir Markoc3908792020-04-06 14:52:04 +0100318 VerifierDeps decoded_deps(second_dex_files, /*output_only=*/ false);
319 bool parsed = decoded_deps.ParseStoredData(second_dex_files, ArrayRef<const uint8_t>(buffer));
320 CHECK(parsed);
David Brazdil8fd67222019-02-05 18:13:44 +0000321 VerifierDeps::DexFileDeps* decoded_dex_deps =
322 decoded_deps.GetDexFileDeps(*second_dex_files.front());
323
324 // Let the test modify the dependencies.
325 fn(*decoded_dex_deps);
326
327 StackHandleScope<1> hs(soa.Self());
328 Handle<mirror::ClassLoader> new_class_loader =
329 hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(second_loader));
David Brazdilfeb22822019-02-13 21:25:57 +0000330
331 return decoded_deps.ValidateDependencies(soa.Self(),
332 new_class_loader,
Yang Tianpinga8d998f2021-10-09 15:05:49 +0800333 second_dex_files,
David Brazdilfeb22822019-02-13 21:25:57 +0000334 error_msg);
David Brazdil8fd67222019-02-05 18:13:44 +0000335 }
336
David Brazdilca3c8c32016-09-06 14:04:48 +0100337 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100338 std::vector<const DexFile*> dex_files_;
339 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100340 jobject class_loader_;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100341 ObjPtr<mirror::Class> klass_Main_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100342};
343
344TEST_F(VerifierDepsTest, StringToId) {
345 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100346 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100347
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800348 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
349 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100350 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100351
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800352 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
353 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100354 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100355
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800356 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
357 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100358 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100359
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800360 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
361 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100362 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100363
364 ASSERT_EQ(id_Main1, id_Main2);
365 ASSERT_EQ(id_Lorem1, id_Lorem2);
366 ASSERT_NE(id_Main1, id_Lorem1);
367}
368
369TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800370 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100371 /* src= */ "Ljava/util/SimpleTimeZone;"));
372 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100373}
374
David Brazdilca3c8c32016-09-06 14:04:48 +0100375TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800376 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100377 /* src= */ "[[Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100378 // If the component types of both arrays are resolved, we optimize the list of
379 // dependencies by recording a dependency on the component types.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100380 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;"));
381 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;"));
382 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100383}
384
David Brazdilca3c8c32016-09-06 14:04:48 +0100385TEST_F(VerifierDepsTest, ReturnType_Reference) {
386 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100387 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100388}
389
390TEST_F(VerifierDepsTest, InvokeArgumentType) {
391 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100392 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100393}
394
395TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
396 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000397 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100398 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100399 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100400}
401
402TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
403 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100404 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100405 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100406 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100407}
408
409TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
410 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100411 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100412 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100413 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100414}
415
David Brazdilca3c8c32016-09-06 14:04:48 +0100416TEST_F(VerifierDepsTest, Throw) {
417 ASSERT_TRUE(VerifyMethod("Throw"));
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100418 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100419}
420
421TEST_F(VerifierDepsTest, MoveException_Resolved) {
422 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100423
424 // Testing that all exception types are assignable to Throwable.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100425 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;"));
426 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;"));
427 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100428
429 // Testing that the merge type is assignable to Throwable.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100430 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100431
432 // Merging of exception types.
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100433 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;"));
434 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100435 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100436 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100437}
438
David Brazdilca3c8c32016-09-06 14:04:48 +0100439TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
440 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100441 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000442 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100443}
444
445TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
446 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100447 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000448 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100449}
450
451TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
452 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100453 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000454 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100455}
456
David Brazdilca3c8c32016-09-06 14:04:48 +0100457TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
458 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100459 // Type dependency on `this` argument.
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000460 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100461}
462
463TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
464 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100465 // Type dependency on `this` argument.
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000466 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100467}
468
David Brazdilca3c8c32016-09-06 14:04:48 +0100469TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
470 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
Nicolas Geoffray8411c5d2020-11-06 08:30:22 +0000471 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +0000472}
473
David Brazdil6f82fbd2016-09-14 11:55:26 +0100474TEST_F(VerifierDepsTest, EncodeDecode) {
475 VerifyDexFile();
476
477 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
478 ASSERT_TRUE(HasEachKindOfRecord());
479
480 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100481 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100482 ASSERT_FALSE(buffer.empty());
483
Vladimir Markoc3908792020-04-06 14:52:04 +0100484 VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
485 bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
486 ASSERT_TRUE(parsed);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100487 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
488}
489
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100490TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
491 VerifyDexFile("MultiDex");
492
493 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
494 std::vector<uint8_t> buffer;
495 verifier_deps_->Encode(dex_files_, &buffer);
496 ASSERT_FALSE(buffer.empty());
497
498 // Create new DexFile, to mess with std::map order: the verifier deps used
499 // to iterate over the map, which doesn't guarantee insertion order. We fixed
500 // this by passing the expected order when encoding/decoding.
501 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
502 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
503 std::vector<const DexFile*> dex_files;
504 for (auto& dex_file : first_dex_files) {
505 dex_files.push_back(dex_file.get());
506 }
507 for (auto& dex_file : second_dex_files) {
508 dex_files.push_back(dex_file.get());
509 }
510
511 // Dump the new verifier deps to ensure it can properly read the data.
Vladimir Markoc3908792020-04-06 14:52:04 +0100512 VerifierDeps decoded_deps(dex_files, /*output_only=*/ false);
513 bool parsed = decoded_deps.ParseStoredData(dex_files, ArrayRef<const uint8_t>(buffer));
514 ASSERT_TRUE(parsed);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100515 std::ostringstream stream;
516 VariableIndentationOutputStream os(&stream);
517 decoded_deps.Dump(&os);
518}
519
Nicolas Geoffray08025182016-10-25 17:20:18 +0100520TEST_F(VerifierDepsTest, UnverifiedClasses) {
521 VerifyDexFile();
522 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
523 // Test that a class with a soft failure is recorded.
524 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
525 // Test that a class with hard failure is recorded.
526 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100527 // Test that a class with unresolved super and hard failure is recorded.
528 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
Nicolas Geoffrayc3c44172021-01-07 10:03:39 +0000529 // Test that a class with unresolved super can be verified.
530 ASSERT_TRUE(HasVerifiedClass("LMyClassWithNoSuper;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +0100531}
532
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700533TEST_F(VerifierDepsTest, UnverifiedOrder) {
534 ScopedObjectAccess soa(Thread::Current());
535 jobject loader = LoadDex("VerifierDeps");
536 std::vector<const DexFile*> dex_files = GetDexFiles(loader);
537 ASSERT_GT(dex_files.size(), 0u);
538 const DexFile* dex_file = dex_files[0];
539 VerifierDeps deps1(dex_files);
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(0u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700543 verifier::FailureKind::kHardFailure);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000544 deps1.MaybeRecordVerificationStatus(&deps1,
545 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000546 dex_file->GetClassDef(1u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700547 verifier::FailureKind::kHardFailure);
548 VerifierDeps deps2(dex_files);
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(1u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700552 verifier::FailureKind::kHardFailure);
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000553 deps2.MaybeRecordVerificationStatus(&deps2,
554 *dex_file,
David Brazdilfeb22822019-02-13 21:25:57 +0000555 dex_file->GetClassDef(0u),
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700556 verifier::FailureKind::kHardFailure);
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700557 std::vector<uint8_t> buffer1;
558 deps1.Encode(dex_files, &buffer1);
559 std::vector<uint8_t> buffer2;
560 deps2.Encode(dex_files, &buffer2);
561 EXPECT_EQ(buffer1, buffer2);
562}
563
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100564TEST_F(VerifierDepsTest, VerifyDeps) {
David Brazdil8fd67222019-02-05 18:13:44 +0000565 std::string error_msg;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100566
David Brazdil8fd67222019-02-05 18:13:44 +0000567 VerifyDexFile();
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100568 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
569 ASSERT_TRUE(HasEachKindOfRecord());
570
571 // When validating, we create a new class loader, as
572 // the existing `class_loader_` may contain erroneous classes,
573 // that ClassLinker::FindClass won't return.
574
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100575 std::vector<uint8_t> buffer;
576 verifier_deps_->Encode(dex_files_, &buffer);
577 ASSERT_FALSE(buffer.empty());
578
David Brazdil8fd67222019-02-05 18:13:44 +0000579 // Check that dependencies are satisfied after decoding `buffer`.
580 ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer, &error_msg))
581 << error_msg;
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000582}
583
584TEST_F(VerifierDepsTest, CompilerDriver) {
585 SetupCompilerDriver();
586
587 // Test both multi-dex and single-dex configuration.
588 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
589 // Test that the compiler driver behaves as expected when the dependencies
590 // verify and when they don't verify.
591 for (bool verify_failure : { false, true }) {
592 {
593 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100594 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000595 }
Andreas Gampe3db70682018-12-26 15:12:03 -0800596 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000597
598 std::vector<uint8_t> buffer;
599 verifier_deps_->Encode(dex_files_, &buffer);
600
601 {
602 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100603 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000604 }
Vladimir Markoc3908792020-04-06 14:52:04 +0100605 VerifierDeps decoded_deps(dex_files_, /*output_only=*/ false);
606 bool parsed = decoded_deps.ParseStoredData(dex_files_, ArrayRef<const uint8_t>(buffer));
607 ASSERT_TRUE(parsed);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000608 VerifyWithCompilerDriver(&decoded_deps);
609
610 if (verify_failure) {
611 ASSERT_FALSE(verifier_deps_ == nullptr);
612 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
613 } else {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000614 VerifyClassStatus(decoded_deps);
615 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100616 }
617 }
618}
619
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000620TEST_F(VerifierDepsTest, MultiDexVerification) {
621 VerifyDexFile("VerifierDepsMulti");
622 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
623
624 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
625 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
626 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
627
628 std::vector<uint8_t> buffer;
629 verifier_deps_->Encode(dex_files_, &buffer);
630 ASSERT_FALSE(buffer.empty());
631}
632
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100633TEST_F(VerifierDepsTest, Assignable_Arrays) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800634 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[LIface;",
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100635 /* src= */ "[LMyClassExtendingInterface;"));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100636 ASSERT_FALSE(HasAssignable(
Nicolas Geoffray5b041c02020-10-20 15:17:53 +0100637 "LIface;", "LMyClassExtendingInterface;"));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100638}
639
David Brazdilca3c8c32016-09-06 14:04:48 +0100640} // namespace verifier
641} // namespace art