blob: 8d2a0e78606c2a01b49aae4490d18bdb602406c0 [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
20#include "class_linker.h"
Nicolas Geoffray08025182016-10-25 17:20:18 +010021#include "compiler/common_compiler_test.h"
22#include "compiler/driver/compiler_options.h"
23#include "compiler/driver/compiler_driver.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010024#include "compiler_callbacks.h"
25#include "dex_file.h"
26#include "handle_scope-inl.h"
Nicolas Geoffray08025182016-10-25 17:20:18 +010027#include "verifier/method_verifier-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010028#include "mirror/class_loader.h"
29#include "runtime.h"
30#include "thread.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010032
33namespace art {
34namespace verifier {
35
36class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
37 public:
38 explicit VerifierDepsCompilerCallbacks()
39 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
40 deps_(nullptr) {}
41
42 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE {}
43 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) OVERRIDE {}
44 bool IsRelocationPossible() OVERRIDE { return false; }
45
46 verifier::VerifierDeps* GetVerifierDeps() const OVERRIDE { return deps_; }
47 void SetVerifierDeps(verifier::VerifierDeps* deps) { deps_ = deps; }
48
49 private:
50 verifier::VerifierDeps* deps_;
51};
52
Nicolas Geoffray08025182016-10-25 17:20:18 +010053class VerifierDepsTest : public CommonCompilerTest {
David Brazdilca3c8c32016-09-06 14:04:48 +010054 public:
55 void SetUpRuntimeOptions(RuntimeOptions* options) {
Nicolas Geoffray08025182016-10-25 17:20:18 +010056 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010057 callbacks_.reset(new VerifierDepsCompilerCallbacks());
58 }
59
60 mirror::Class* FindClassByName(const std::string& name, ScopedObjectAccess* soa)
61 REQUIRES_SHARED(Locks::mutator_lock_) {
62 StackHandleScope<1> hs(Thread::Current());
63 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -070064 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_)));
David Brazdil6f82fbd2016-09-14 11:55:26 +010065 mirror::Class* klass = class_linker_->FindClass(Thread::Current(),
66 name.c_str(),
67 class_loader_handle);
68 if (klass == nullptr) {
69 DCHECK(Thread::Current()->IsExceptionPending());
70 Thread::Current()->ClearException();
71 }
72 return klass;
73 }
74
75 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
76 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
77 VerifierDepsCompilerCallbacks* callbacks =
78 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
79 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +010080 }
81
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +010082 void LoadDexFile(ScopedObjectAccess* soa, const char* name1, const char* name2 = nullptr)
83 REQUIRES_SHARED(Locks::mutator_lock_) {
84 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
85 dex_files_ = GetDexFiles(class_loader_);
86 primary_dex_file_ = dex_files_.front();
87
88 SetVerifierDeps(dex_files_);
89 StackHandleScope<1> hs(soa->Self());
90 Handle<mirror::ClassLoader> loader =
91 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_));
92 for (const DexFile* dex_file : dex_files_) {
93 class_linker_->RegisterDexFile(*dex_file, loader.Get());
94 }
95 }
96
David Brazdilca3c8c32016-09-06 14:04:48 +010097 void LoadDexFile(ScopedObjectAccess* soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +010098 LoadDexFile(soa, "VerifierDeps");
99 CHECK_EQ(dex_files_.size(), 1u);
David Brazdilca3c8c32016-09-06 14:04:48 +0100100 klass_Main_ = FindClassByName("LMain;", soa);
101 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100102 }
103
104 bool VerifyMethod(const std::string& method_name) {
105 ScopedObjectAccess soa(Thread::Current());
106 LoadDexFile(&soa);
107
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100108 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100109 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700110 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100111 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
112
113 const DexFile::ClassDef* class_def = klass_Main_->GetClassDef();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100114 const uint8_t* class_data = primary_dex_file_->GetClassData(*class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100115 CHECK(class_data != nullptr);
116
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100117 ClassDataItemIterator it(*primary_dex_file_, class_data);
David Brazdilca3c8c32016-09-06 14:04:48 +0100118 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
119 it.Next();
120 }
121
122 ArtMethod* method = nullptr;
123 while (it.HasNextDirectMethod()) {
124 ArtMethod* resolved_method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100125 *primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100126 it.GetMemberIndex(),
127 dex_cache_handle,
128 class_loader_handle,
129 nullptr,
130 it.GetMethodInvokeType(*class_def));
131 CHECK(resolved_method != nullptr);
132 if (method_name == resolved_method->GetName()) {
133 method = resolved_method;
134 break;
135 }
136 it.Next();
137 }
138 CHECK(method != nullptr);
139
140 MethodVerifier verifier(Thread::Current(),
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100141 primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100142 dex_cache_handle,
143 class_loader_handle,
144 *class_def,
145 it.GetMethodCodeItem(),
146 it.GetMemberIndex(),
147 method,
148 it.GetMethodAccessFlags(),
149 true /* can_load_classes */,
150 true /* allow_soft_failures */,
151 true /* need_precise_constants */,
152 false /* verify to dump */,
153 true /* allow_thread_suspension */);
154 verifier.Verify();
155 return !verifier.HasFailures();
156 }
157
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100158 void VerifyDexFile(const char* multidex = nullptr) {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100159 std::string error_msg;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100160 {
161 ScopedObjectAccess soa(Thread::Current());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100162 LoadDexFile(&soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100163 }
Nicolas Geoffray08025182016-10-25 17:20:18 +0100164 TimingLogger timings("Verify", false, false);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100165 compiler_options_->boot_image_ = false;
166 compiler_driver_->InitializeThreadPools();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100167 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100168 }
169
David Brazdilca3c8c32016-09-06 14:04:48 +0100170 bool TestAssignabilityRecording(const std::string& dst,
171 const std::string& src,
172 bool is_strict,
173 bool is_assignable) {
174 ScopedObjectAccess soa(Thread::Current());
175 LoadDexFile(&soa);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100176 mirror::Class* klass_dst = FindClassByName(dst, &soa);
177 DCHECK(klass_dst != nullptr);
178 mirror::Class* klass_src = FindClassByName(src, &soa);
179 DCHECK(klass_src != nullptr);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100180 verifier_deps_->AddAssignability(*primary_dex_file_,
David Brazdil6f82fbd2016-09-14 11:55:26 +0100181 klass_dst,
182 klass_src,
David Brazdilca3c8c32016-09-06 14:04:48 +0100183 is_strict,
184 is_assignable);
185 return true;
186 }
187
Nicolas Geoffray08025182016-10-25 17:20:18 +0100188 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100189 const DexFile::TypeId* type_id = primary_dex_file_->FindTypeId(cls.c_str());
Nicolas Geoffray08025182016-10-25 17:20:18 +0100190 DCHECK(type_id != nullptr);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100191 uint16_t index = primary_dex_file_->GetIndexForTypeId(*type_id);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100192 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
193 for (const auto& dex_dep : verifier_deps_->dex_deps_) {
194 for (uint16_t entry : dex_dep.second->unverified_classes_) {
195 if (index == entry) {
196 return true;
197 }
198 }
199 }
200 return false;
201 }
202
David Brazdilca3c8c32016-09-06 14:04:48 +0100203 // Iterates over all assignability records and tries to find an entry which
204 // matches the expected destination/source pair.
205 bool HasAssignable(const std::string& expected_destination,
206 const std::string& expected_source,
207 bool expected_is_assignable) {
208 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
209 for (auto& dex_dep : verifier_deps_->dex_deps_) {
210 const DexFile& dex_file = *dex_dep.first;
211 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
212 : dex_dep.second->unassignable_types_;
213 for (auto& entry : storage) {
214 std::string actual_destination =
215 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
216 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
217 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
218 return true;
219 }
220 }
221 }
222 return false;
223 }
224
225 // Iterates over all class resolution records, finds an entry which matches
226 // the given class descriptor and tests its properties.
227 bool HasClass(const std::string& expected_klass,
228 bool expected_resolved,
229 const std::string& expected_access_flags = "") {
230 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
231 for (auto& dex_dep : verifier_deps_->dex_deps_) {
232 for (auto& entry : dex_dep.second->classes_) {
233 if (expected_resolved != entry.IsResolved()) {
234 continue;
235 }
236
237 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
238 if (expected_klass != actual_klass) {
239 continue;
240 }
241
242 if (expected_resolved) {
243 // Test access flags. Note that PrettyJavaAccessFlags always appends
244 // a space after the modifiers. Add it to the expected access flags.
245 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
246 if (expected_access_flags + " " != actual_access_flags) {
247 continue;
248 }
249 }
250
251 return true;
252 }
253 }
254 return false;
255 }
256
257 // Iterates over all field resolution records, finds an entry which matches
258 // the given field class+name+type and tests its properties.
259 bool HasField(const std::string& expected_klass,
260 const std::string& expected_name,
261 const std::string& expected_type,
262 bool expected_resolved,
263 const std::string& expected_access_flags = "",
264 const std::string& expected_decl_klass = "") {
265 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
266 for (auto& dex_dep : verifier_deps_->dex_deps_) {
267 for (auto& entry : dex_dep.second->fields_) {
268 if (expected_resolved != entry.IsResolved()) {
269 continue;
270 }
271
272 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
273
274 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
275 if (expected_klass != actual_klass) {
276 continue;
277 }
278
279 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
280 if (expected_name != actual_name) {
281 continue;
282 }
283
284 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
285 if (expected_type != actual_type) {
286 continue;
287 }
288
289 if (expected_resolved) {
290 // Test access flags. Note that PrettyJavaAccessFlags always appends
291 // a space after the modifiers. Add it to the expected access flags.
292 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
293 if (expected_access_flags + " " != actual_access_flags) {
294 continue;
295 }
296
297 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
298 *dex_dep.first, entry.GetDeclaringClassIndex());
299 if (expected_decl_klass != actual_decl_klass) {
300 continue;
301 }
302 }
303
304 return true;
305 }
306 }
307 return false;
308 }
309
310 // Iterates over all method resolution records, finds an entry which matches
311 // the given field kind+class+name+signature and tests its properties.
312 bool HasMethod(const std::string& expected_kind,
313 const std::string& expected_klass,
314 const std::string& expected_name,
315 const std::string& expected_signature,
316 bool expected_resolved,
317 const std::string& expected_access_flags = "",
318 const std::string& expected_decl_klass = "") {
319 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
320 for (auto& dex_dep : verifier_deps_->dex_deps_) {
321 auto& storage = (expected_kind == "direct") ? dex_dep.second->direct_methods_
322 : (expected_kind == "virtual") ? dex_dep.second->virtual_methods_
323 : dex_dep.second->interface_methods_;
324 for (auto& entry : storage) {
325 if (expected_resolved != entry.IsResolved()) {
326 continue;
327 }
328
329 const DexFile::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
330
331 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_);
332 if (expected_klass != actual_klass) {
333 continue;
334 }
335
336 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_);
337 if (expected_name != actual_name) {
338 continue;
339 }
340
341 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString();
342 if (expected_signature != actual_signature) {
343 continue;
344 }
345
346 if (expected_resolved) {
347 // Test access flags. Note that PrettyJavaAccessFlags always appends
348 // a space after the modifiers. Add it to the expected access flags.
349 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
350 if (expected_access_flags + " " != actual_access_flags) {
351 continue;
352 }
353
354 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
355 *dex_dep.first, entry.GetDeclaringClassIndex());
356 if (expected_decl_klass != actual_decl_klass) {
357 continue;
358 }
359 }
360
361 return true;
362 }
363 }
364 return false;
365 }
366
David Brazdil6f82fbd2016-09-14 11:55:26 +0100367 size_t NumberOfCompiledDexFiles() {
368 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
369 return verifier_deps_->dex_deps_.size();
370 }
371
372 size_t HasEachKindOfRecord() {
373 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
374
375 bool has_strings = false;
376 bool has_assignability = false;
377 bool has_classes = false;
378 bool has_fields = false;
379 bool has_methods = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100380 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100381
382 for (auto& entry : verifier_deps_->dex_deps_) {
383 has_strings |= !entry.second->strings_.empty();
384 has_assignability |= !entry.second->assignable_types_.empty();
385 has_assignability |= !entry.second->unassignable_types_.empty();
386 has_classes |= !entry.second->classes_.empty();
387 has_fields |= !entry.second->fields_.empty();
388 has_methods |= !entry.second->direct_methods_.empty();
389 has_methods |= !entry.second->virtual_methods_.empty();
390 has_methods |= !entry.second->interface_methods_.empty();
Nicolas Geoffray08025182016-10-25 17:20:18 +0100391 has_unverified_classes |= !entry.second->unverified_classes_.empty();
David Brazdil6f82fbd2016-09-14 11:55:26 +0100392 }
393
Nicolas Geoffray08025182016-10-25 17:20:18 +0100394 return has_strings &&
395 has_assignability &&
396 has_classes &&
397 has_fields &&
398 has_methods &&
399 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100400 }
401
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +0100402 static std::set<VerifierDeps::MethodResolution>* GetMethods(
403 VerifierDeps::DexFileDeps* deps, MethodResolutionKind resolution_kind) {
404 if (resolution_kind == kDirectMethodResolution) {
405 return &deps->direct_methods_;
406 } else if (resolution_kind == kVirtualMethodResolution) {
407 return &deps->virtual_methods_;
408 } else {
409 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
410 return &deps->interface_methods_;
411 }
412 }
413
David Brazdilca3c8c32016-09-06 14:04:48 +0100414 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100415 std::vector<const DexFile*> dex_files_;
416 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100417 jobject class_loader_;
418 mirror::Class* klass_Main_;
419};
420
421TEST_F(VerifierDepsTest, StringToId) {
422 ScopedObjectAccess soa(Thread::Current());
423 LoadDexFile(&soa);
424
425 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
426
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100427 uint32_t id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
428 ASSERT_LT(id_Main1, primary_dex_file_->NumStringIds());
429 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100430
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100431 uint32_t id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
432 ASSERT_LT(id_Main2, primary_dex_file_->NumStringIds());
433 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100434
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100435 uint32_t id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
436 ASSERT_GE(id_Lorem1, primary_dex_file_->NumStringIds());
437 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100438
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100439 uint32_t id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
440 ASSERT_GE(id_Lorem2, primary_dex_file_->NumStringIds());
441 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100442
443 ASSERT_EQ(id_Main1, id_Main2);
444 ASSERT_EQ(id_Lorem1, id_Lorem2);
445 ASSERT_NE(id_Main1, id_Lorem1);
446}
447
448TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
449 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
450 /* src */ "Ljava/util/SimpleTimeZone;",
451 /* is_strict */ true,
452 /* is_assignable */ true));
453 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
454}
455
456TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
457 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
458 /* src */ "LMySSLSocket;",
459 /* is_strict */ true,
460 /* is_assignable */ true));
461 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "LMySSLSocket;", true));
462}
463
464TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
465 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
466 /* src */ "LMySimpleTimeZone;",
467 /* is_strict */ true,
468 /* is_assignable */ true));
469 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "LMySimpleTimeZone;", true));
470}
471
472TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
473 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
474 /* src */ "LMyThreadSet;",
475 /* is_strict */ true,
476 /* is_assignable */ true));
477 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "LMyThreadSet;", true));
478}
479
480TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
481 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
482 /* src */ "[[Ljava/util/SimpleTimeZone;",
483 /* is_strict */ true,
484 /* is_assignable */ true));
485 // If the component types of both arrays are resolved, we optimize the list of
486 // dependencies by recording a dependency on the component types.
487 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
488 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
489 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
490}
491
492TEST_F(VerifierDepsTest, Assignable_BothArrays_Erroneous) {
493 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
494 /* src */ "[[LMyErroneousTimeZone;",
495 /* is_strict */ true,
496 /* is_assignable */ true));
497 // If the component type of an array is erroneous, we record the dependency on
498 // the array type.
499 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[LMyErroneousTimeZone;", true));
500 ASSERT_TRUE(HasAssignable("[Ljava/util/TimeZone;", "[LMyErroneousTimeZone;", true));
501 ASSERT_FALSE(HasAssignable("Ljava/util/TimeZone;", "LMyErroneousTimeZone;", true));
502}
503
504 // We test that VerifierDeps does not try to optimize by storing assignability
505 // of the component types. This is due to the fact that the component type may
506 // be an erroneous class, even though the array type has resolved status.
507
508TEST_F(VerifierDepsTest, Assignable_ArrayToInterface1) {
509 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
510 /* src */ "[Ljava/util/TimeZone;",
511 /* is_strict */ true,
512 /* is_assignable */ true));
513 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[Ljava/util/TimeZone;", true));
514}
515
516TEST_F(VerifierDepsTest, Assignable_ArrayToInterface2) {
517 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
518 /* src */ "[LMyThreadSet;",
519 /* is_strict */ true,
520 /* is_assignable */ true));
521 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[LMyThreadSet;", true));
522}
523
524TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
525 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
526 /* src */ "Ljava/util/SimpleTimeZone;",
527 /* is_strict */ true,
528 /* is_assignable */ false));
529 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
530}
531
532TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
533 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
534 /* src */ "LMySSLSocket;",
535 /* is_strict */ true,
536 /* is_assignable */ false));
537 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySSLSocket;", false));
538}
539
540TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
541 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
542 /* src */ "LMySimpleTimeZone;",
543 /* is_strict */ true,
544 /* is_assignable */ false));
545 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySimpleTimeZone;", false));
546}
547
548TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
549 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
550 /* src */ "[Ljava/util/SimpleTimeZone;",
551 /* is_strict */ true,
552 /* is_assignable */ false));
553 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
554}
555
556TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
557 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
558 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
559}
560
561TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
562 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
563 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public final abstract"));
564}
565
566TEST_F(VerifierDepsTest, ArgumentType_ResolvedPrimitiveArray) {
567 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedPrimitiveArray"));
568 ASSERT_TRUE(HasClass("[B", true, "public final abstract"));
569}
570
571TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
572 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
573 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
574}
575
576TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
577 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
578 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
579}
580
581TEST_F(VerifierDepsTest, ReturnType_Reference) {
582 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
583 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
584}
585
586TEST_F(VerifierDepsTest, ReturnType_Array) {
587 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
588 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
589}
590
591TEST_F(VerifierDepsTest, InvokeArgumentType) {
592 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
593 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
594 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
595 ASSERT_TRUE(HasMethod("virtual",
596 "Ljava/text/SimpleDateFormat;",
597 "setTimeZone",
598 "(Ljava/util/TimeZone;)V",
599 true,
600 "public",
601 "Ljava/text/DateFormat;"));
602 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
603}
604
605TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
606 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
607 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;", true));
608 ASSERT_TRUE(HasAssignable(
609 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
610}
611
612TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
613 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
614 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
615 ASSERT_TRUE(HasAssignable(
616 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
617 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
618}
619
620TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
621 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
622 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
623 ASSERT_TRUE(HasAssignable(
624 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
625}
626
627TEST_F(VerifierDepsTest, ConstClass_Resolved) {
628 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
629 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
630}
631
632TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
633 ASSERT_TRUE(VerifyMethod("ConstClass_Unresolved"));
634 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
635}
636
637TEST_F(VerifierDepsTest, CheckCast_Resolved) {
638 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
639 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
640}
641
642TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
643 ASSERT_TRUE(VerifyMethod("CheckCast_Unresolved"));
644 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
645}
646
647TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
648 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
649 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
650}
651
652TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
653 ASSERT_TRUE(VerifyMethod("InstanceOf_Unresolved"));
654 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
655}
656
657TEST_F(VerifierDepsTest, NewInstance_Resolved) {
658 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
659 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
660}
661
662TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
663 ASSERT_TRUE(VerifyMethod("NewInstance_Unresolved"));
664 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
665}
666
667TEST_F(VerifierDepsTest, NewArray_Resolved) {
668 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
669 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public final abstract"));
670}
671
672TEST_F(VerifierDepsTest, NewArray_Unresolved) {
673 ASSERT_TRUE(VerifyMethod("NewArray_Unresolved"));
674 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
675}
676
677TEST_F(VerifierDepsTest, Throw) {
678 ASSERT_TRUE(VerifyMethod("Throw"));
679 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
680}
681
682TEST_F(VerifierDepsTest, MoveException_Resolved) {
683 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
684 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
685 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
686 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
687
688 // Testing that all exception types are assignable to Throwable.
689 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
690 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
691 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
692
693 // Testing that the merge type is assignable to Throwable.
694 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
695
696 // Merging of exception types.
697 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
698 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
699 ASSERT_TRUE(HasAssignable(
700 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
701}
702
703TEST_F(VerifierDepsTest, MoveException_Unresolved) {
704 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
705 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
706}
707
708TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
709 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
710 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public final"));
711 ASSERT_TRUE(HasField("Ljava/lang/System;",
712 "out",
713 "Ljava/io/PrintStream;",
714 true,
715 "public final static",
716 "Ljava/lang/System;"));
717}
718
719TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
720 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
721 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
722 ASSERT_TRUE(HasField(
723 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public final static", "Ljava/util/TimeZone;"));
724}
725
726TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
727 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
728 ASSERT_TRUE(HasField(
729 "LMySimpleTimeZone;", "SHORT", "I", true, "public final static", "Ljava/util/TimeZone;"));
730}
731
732TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
733 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
734 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
735 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
736 "PI_ENABLE_OUTPUT_ESCAPING",
737 "Ljava/lang/String;",
738 true,
739 "public final static",
740 "Ljavax/xml/transform/Result;"));
741}
742
743TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
744 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
745 ASSERT_TRUE(HasField("LMyDOMResult;",
746 "PI_ENABLE_OUTPUT_ESCAPING",
747 "Ljava/lang/String;",
748 true,
749 "public final static",
750 "Ljavax/xml/transform/Result;"));
751}
752
753TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
754 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
755 ASSERT_TRUE(HasField("LMyResult;",
756 "PI_ENABLE_OUTPUT_ESCAPING",
757 "Ljava/lang/String;",
758 true,
759 "public final static",
760 "Ljavax/xml/transform/Result;"));
761}
762
763TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
764 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
765 ASSERT_TRUE(HasField("LMyDocument;",
766 "ELEMENT_NODE",
767 "S",
768 true,
769 "public final static",
770 "Lorg/w3c/dom/Node;"));
771}
772
773TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
774 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
775 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public abstract"));
776 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
777}
778
779TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
780 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
781 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
782}
783
784TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
785 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
786 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
787 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
788 "bytesTransferred",
789 "I",
790 true,
791 "public",
792 "Ljava/io/InterruptedIOException;"));
793 ASSERT_TRUE(HasAssignable(
794 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
795}
796
797TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
798 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
799 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
800 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
801 "bytesTransferred",
802 "I",
803 true,
804 "public",
805 "Ljava/io/InterruptedIOException;"));
806 ASSERT_TRUE(HasAssignable(
807 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
808}
809
810TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
811 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
812 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
813 "bytesTransferred",
814 "I",
815 true,
816 "public",
817 "Ljava/io/InterruptedIOException;"));
818 ASSERT_TRUE(HasAssignable(
819 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
820}
821
822TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
823 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
824 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
825 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
826}
827
828TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
829 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
830 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
831}
832
833TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
834 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
835 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
836 ASSERT_TRUE(HasMethod("direct",
837 "Ljava/net/Socket;",
838 "setSocketImplFactory",
839 "(Ljava/net/SocketImplFactory;)V",
840 true,
841 "public static",
842 "Ljava/net/Socket;"));
843}
844
845TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
846 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
847 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
848 ASSERT_TRUE(HasMethod("direct",
849 "Ljavax/net/ssl/SSLSocket;",
850 "setSocketImplFactory",
851 "(Ljava/net/SocketImplFactory;)V",
852 true,
853 "public static",
854 "Ljava/net/Socket;"));
855}
856
857TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
858 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
859 ASSERT_TRUE(HasMethod("direct",
860 "LMySSLSocket;",
861 "setSocketImplFactory",
862 "(Ljava/net/SocketImplFactory;)V",
863 true,
864 "public static",
865 "Ljava/net/Socket;"));
866}
867
868TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
869 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
870 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public abstract interface"));
871 ASSERT_TRUE(HasMethod("direct",
872 "Ljava/util/Map$Entry;",
873 "comparingByKey",
874 "()Ljava/util/Comparator;",
875 true,
876 "public static",
877 "Ljava/util/Map$Entry;"));
878}
879
880TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
881 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
882 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
883 ASSERT_TRUE(HasMethod("direct",
884 "Ljava/util/AbstractMap$SimpleEntry;",
885 "comparingByKey",
886 "()Ljava/util/Comparator;",
887 false));
888}
889
890TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
891 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
892 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
893 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
894}
895
896TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
897 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
898 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
899}
900
901TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
902 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
903 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
904 ASSERT_TRUE(HasMethod(
905 "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
906}
907
908TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
909 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
910 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
911 ASSERT_TRUE(HasMethod("direct",
912 "Ljavax/net/ssl/SSLSocket;",
913 "checkOldImpl",
914 "()V",
915 true,
916 "private",
917 "Ljava/net/Socket;"));
918}
919
920TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
921 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
922 ASSERT_TRUE(HasMethod(
923 "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
924}
925
926TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
927 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
928 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
929 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
930}
931
932TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
933 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
934 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
935}
936
937TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
938 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
939 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
940 ASSERT_TRUE(HasMethod("virtual",
941 "Ljava/lang/Throwable;",
942 "getMessage",
943 "()Ljava/lang/String;",
944 true,
945 "public",
946 "Ljava/lang/Throwable;"));
947 // Type dependency on `this` argument.
948 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
949}
950
951TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
952 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
953 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
954 ASSERT_TRUE(HasMethod("virtual",
955 "Ljava/io/InterruptedIOException;",
956 "getMessage",
957 "()Ljava/lang/String;",
958 true,
959 "public",
960 "Ljava/lang/Throwable;"));
961 // Type dependency on `this` argument.
962 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
963}
964
965TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
966 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
967 ASSERT_TRUE(HasMethod("virtual",
968 "LMySocketTimeoutException;",
969 "getMessage",
970 "()Ljava/lang/String;",
971 true,
972 "public",
973 "Ljava/lang/Throwable;"));
974}
975
976TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
977 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
978 ASSERT_TRUE(HasMethod("virtual",
979 "LMyThreadSet;",
980 "size",
981 "()I",
982 true,
983 "public abstract",
984 "Ljava/util/Set;"));
985}
986
987TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
988 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
989 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
990 ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
991}
992
993TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
994 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
995 ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
996}
997
998TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
999 ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
1000 ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
1001 ASSERT_TRUE(HasMethod("direct",
1002 "LMyThread;",
1003 "activeCount",
1004 "()I",
1005 true,
1006 "public static",
1007 "Ljava/lang/Thread;"));
1008}
1009
1010TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1011 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
1012 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1013 ASSERT_TRUE(HasMethod("interface",
1014 "Ljava/lang/Runnable;",
1015 "run",
1016 "()V",
1017 true,
1018 "public abstract",
1019 "Ljava/lang/Runnable;"));
1020}
1021
1022TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1023 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
1024 ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
1025}
1026
1027TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1028 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
1029 ASSERT_TRUE(HasMethod("interface",
1030 "LMyThreadSet;",
1031 "run",
1032 "()V",
1033 true,
1034 "public abstract",
1035 "Ljava/lang/Runnable;"));
1036}
1037
1038TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1039 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
1040 ASSERT_TRUE(HasMethod("interface",
1041 "LMyThreadSet;",
1042 "isEmpty",
1043 "()Z",
1044 true,
1045 "public abstract",
1046 "Ljava/util/Set;"));
1047}
1048
1049TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1050 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
1051 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1052 ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
1053}
1054
1055TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1056 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
1057 ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
1058}
1059
1060TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1061 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
1062 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
1063 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;", true));
1064 ASSERT_TRUE(HasMethod("interface",
1065 "Ljava/lang/Runnable;",
1066 "run",
1067 "()V",
1068 true,
1069 "public abstract",
1070 "Ljava/lang/Runnable;"));
1071}
1072
1073TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1074 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
1075 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public final"));
1076 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "LMain;", false));
1077 ASSERT_TRUE(HasMethod(
1078 "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
1079}
1080
David Brazdil6f82fbd2016-09-14 11:55:26 +01001081TEST_F(VerifierDepsTest, EncodeDecode) {
1082 VerifyDexFile();
1083
1084 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1085 ASSERT_TRUE(HasEachKindOfRecord());
1086
1087 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001088 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001089 ASSERT_FALSE(buffer.empty());
1090
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001091 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001092 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1093}
1094
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001095TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1096 VerifyDexFile("MultiDex");
1097
1098 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1099 std::vector<uint8_t> buffer;
1100 verifier_deps_->Encode(dex_files_, &buffer);
1101 ASSERT_FALSE(buffer.empty());
1102
1103 // Create new DexFile, to mess with std::map order: the verifier deps used
1104 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1105 // this by passing the expected order when encoding/decoding.
1106 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1107 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1108 std::vector<const DexFile*> dex_files;
1109 for (auto& dex_file : first_dex_files) {
1110 dex_files.push_back(dex_file.get());
1111 }
1112 for (auto& dex_file : second_dex_files) {
1113 dex_files.push_back(dex_file.get());
1114 }
1115
1116 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001117 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001118 std::ostringstream stream;
1119 VariableIndentationOutputStream os(&stream);
1120 decoded_deps.Dump(&os);
1121}
1122
Nicolas Geoffray08025182016-10-25 17:20:18 +01001123TEST_F(VerifierDepsTest, UnverifiedClasses) {
1124 VerifyDexFile();
1125 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1126 // Test that a class with a soft failure is recorded.
1127 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1128 // Test that a class with hard failure is recorded.
1129 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1130 // Test that a class with unresolved super is recorded.
1131 ASSERT_FALSE(HasUnverifiedClass("LMyClassWithNoSuper;"));
1132 // Test that a class with unresolved super and hard failure is recorded.
1133 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1134}
1135
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001136// Returns the next resolution kind in the enum.
1137static MethodResolutionKind GetNextResolutionKind(MethodResolutionKind resolution_kind) {
1138 if (resolution_kind == kDirectMethodResolution) {
1139 return kVirtualMethodResolution;
1140 } else if (resolution_kind == kVirtualMethodResolution) {
1141 return kInterfaceMethodResolution;
1142 } else {
1143 DCHECK_EQ(resolution_kind, kInterfaceMethodResolution);
1144 return kDirectMethodResolution;
1145 }
1146}
1147
1148TEST_F(VerifierDepsTest, VerifyDeps) {
1149 VerifyDexFile();
1150
1151 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1152 ASSERT_TRUE(HasEachKindOfRecord());
1153
1154 // When validating, we create a new class loader, as
1155 // the existing `class_loader_` may contain erroneous classes,
1156 // that ClassLinker::FindClass won't return.
1157
1158 ScopedObjectAccess soa(Thread::Current());
1159 StackHandleScope<1> hs(soa.Self());
1160 MutableHandle<mirror::ClassLoader> new_class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
1161 {
1162 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1163 ASSERT_TRUE(verifier_deps_->Verify(new_class_loader, soa.Self()));
1164 }
1165
1166 std::vector<uint8_t> buffer;
1167 verifier_deps_->Encode(dex_files_, &buffer);
1168 ASSERT_FALSE(buffer.empty());
1169
1170 {
1171 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1172 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1173 ASSERT_TRUE(decoded_deps.Verify(new_class_loader, soa.Self()));
1174 }
1175
1176 // Fiddle with the dependencies to make sure we catch any change and fail to verify.
1177
1178 {
1179 // Mess up with the assignable_types.
1180 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1181 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1182 deps->assignable_types_.insert(*deps->unassignable_types_.begin());
1183 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1184 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1185 }
1186
1187 {
1188 // Mess up with the unassignable_types.
1189 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1190 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1191 deps->unassignable_types_.insert(*deps->assignable_types_.begin());
1192 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1193 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1194 }
1195
1196 // Mess up with classes.
1197 {
1198 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1199 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1200 bool found = false;
1201 for (const auto& entry : deps->classes_) {
1202 if (entry.IsResolved()) {
1203 deps->classes_.insert(VerifierDeps::ClassResolution(
1204 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1205 found = true;
1206 break;
1207 }
1208 }
1209 ASSERT_TRUE(found);
1210 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1211 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1212 }
1213
1214 {
1215 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1216 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1217 bool found = false;
1218 for (const auto& entry : deps->classes_) {
1219 if (!entry.IsResolved()) {
1220 deps->classes_.insert(VerifierDeps::ClassResolution(
1221 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1222 found = true;
1223 break;
1224 }
1225 }
1226 ASSERT_TRUE(found);
1227 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1228 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1229 }
1230
1231 {
1232 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1233 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1234 bool found = false;
1235 for (const auto& entry : deps->classes_) {
1236 if (entry.IsResolved()) {
1237 deps->classes_.insert(VerifierDeps::ClassResolution(
1238 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1239 found = true;
1240 break;
1241 }
1242 }
1243 ASSERT_TRUE(found);
1244 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1245 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1246 }
1247
1248 // Mess up with fields.
1249 {
1250 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1251 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1252 bool found = false;
1253 for (const auto& entry : deps->fields_) {
1254 if (entry.IsResolved()) {
1255 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1256 VerifierDeps::kUnresolvedMarker,
1257 entry.GetDeclaringClassIndex()));
1258 found = true;
1259 break;
1260 }
1261 }
1262 ASSERT_TRUE(found);
1263 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1264 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1265 }
1266
1267 {
1268 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1269 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1270 bool found = false;
1271 for (const auto& entry : deps->fields_) {
1272 if (!entry.IsResolved()) {
1273 deps->fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1274 VerifierDeps::kUnresolvedMarker - 1,
1275 0 /* we know there is a class there */));
1276 found = true;
1277 break;
1278 }
1279 }
1280 ASSERT_TRUE(found);
1281 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1282 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1283 }
1284
1285 {
1286 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1287 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1288 bool found = false;
1289 for (const auto& entry : deps->fields_) {
1290 if (entry.IsResolved()) {
1291 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1292 entry.GetAccessFlags() - 1,
1293 entry.GetDeclaringClassIndex()));
1294 found = true;
1295 break;
1296 }
1297 }
1298 ASSERT_TRUE(found);
1299 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1300 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1301 }
1302
1303 {
1304 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1305 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1306 bool found = false;
1307 for (const auto& entry : deps->fields_) {
1308 static constexpr uint32_t kNewTypeIndex = 0;
1309 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1310 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1311 entry.GetAccessFlags(),
1312 kNewTypeIndex));
1313 found = true;
1314 break;
1315 }
1316 }
1317 ASSERT_TRUE(found);
1318 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1319 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1320 }
1321
1322 // Mess up with methods.
1323 for (MethodResolutionKind resolution_kind :
1324 { kDirectMethodResolution, kVirtualMethodResolution, kInterfaceMethodResolution }) {
1325 {
1326 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1327 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1328 bool found = false;
1329 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1330 for (const auto& entry : *methods) {
1331 if (entry.IsResolved()) {
1332 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1333 VerifierDeps::kUnresolvedMarker,
1334 entry.GetDeclaringClassIndex()));
1335 found = true;
1336 break;
1337 }
1338 }
1339 ASSERT_TRUE(found);
1340 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1341 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1342 }
1343
1344 {
1345 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1346 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1347 bool found = false;
1348 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1349 for (const auto& entry : *methods) {
1350 if (!entry.IsResolved()) {
1351 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1352 VerifierDeps::kUnresolvedMarker - 1,
1353 0 /* we know there is a class there */));
1354 found = true;
1355 break;
1356 }
1357 }
1358 ASSERT_TRUE(found);
1359 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1360 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1361 }
1362
1363 {
1364 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1365 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1366 bool found = false;
1367 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1368 for (const auto& entry : *methods) {
1369 if (entry.IsResolved()) {
1370 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1371 entry.GetAccessFlags() - 1,
1372 entry.GetDeclaringClassIndex()));
1373 found = true;
1374 break;
1375 }
1376 }
1377 ASSERT_TRUE(found);
1378 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1379 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1380 }
1381
1382 {
1383 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1384 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1385 bool found = false;
1386 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1387 for (const auto& entry : *methods) {
1388 static constexpr uint32_t kNewTypeIndex = 0;
1389 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1390 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1391 entry.GetAccessFlags(),
1392 kNewTypeIndex));
1393 found = true;
1394 break;
1395 }
1396 }
1397 ASSERT_TRUE(found);
1398 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1399 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1400 }
1401
1402 {
1403 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1404 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1405 bool found = false;
1406 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1407 for (const auto& entry : *methods) {
1408 if (entry.IsResolved()) {
1409 GetMethods(deps, GetNextResolutionKind(resolution_kind))->insert(
1410 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1411 entry.GetAccessFlags(),
1412 entry.GetDeclaringClassIndex()));
1413 found = true;
1414 }
1415 }
1416 ASSERT_TRUE(found);
1417 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1418 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1419 }
1420
1421 {
1422 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1423 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1424 bool found = false;
1425 std::set<VerifierDeps::MethodResolution>* methods = GetMethods(deps, resolution_kind);
1426 for (const auto& entry : *methods) {
1427 if (entry.IsResolved()) {
1428 GetMethods(deps, GetNextResolutionKind(GetNextResolutionKind(resolution_kind)))->insert(
1429 VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1430 entry.GetAccessFlags(),
1431 entry.GetDeclaringClassIndex()));
1432 found = true;
1433 }
1434 }
1435 ASSERT_TRUE(found);
1436 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1437 ASSERT_FALSE(decoded_deps.Verify(new_class_loader, soa.Self()));
1438 }
1439 }
1440}
1441
David Brazdilca3c8c32016-09-06 14:04:48 +01001442} // namespace verifier
1443} // namespace art