blob: 41a9ad31c14627d5552c0d63d6e11d9e688d758f [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
17#include "verifier_deps.h"
18
19#include "class_linker.h"
20#include "common_runtime_test.h"
21#include "compiler_callbacks.h"
22#include "dex_file.h"
23#include "handle_scope-inl.h"
24#include "method_verifier-inl.h"
25#include "mirror/class_loader.h"
26#include "runtime.h"
27#include "thread.h"
28#include "scoped_thread_state_change.h"
29
30namespace art {
31namespace verifier {
32
33class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
34 public:
35 explicit VerifierDepsCompilerCallbacks()
36 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
37 deps_(nullptr) {}
38
39 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE {}
40 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) OVERRIDE {}
41 bool IsRelocationPossible() OVERRIDE { return false; }
42
43 verifier::VerifierDeps* GetVerifierDeps() const OVERRIDE { return deps_; }
44 void SetVerifierDeps(verifier::VerifierDeps* deps) { deps_ = deps; }
45
46 private:
47 verifier::VerifierDeps* deps_;
48};
49
50class VerifierDepsTest : public CommonRuntimeTest {
51 public:
52 void SetUpRuntimeOptions(RuntimeOptions* options) {
53 CommonRuntimeTest::SetUpRuntimeOptions(options);
54 callbacks_.reset(new VerifierDepsCompilerCallbacks());
55 }
56
57 mirror::Class* FindClassByName(const std::string& name, ScopedObjectAccess* soa)
58 REQUIRES_SHARED(Locks::mutator_lock_) {
59 StackHandleScope<1> hs(Thread::Current());
60 Handle<mirror::ClassLoader> class_loader_handle(
61 hs.NewHandle(soa->Decode<mirror::ClassLoader*>(class_loader_)));
62 mirror::Class* result = class_linker_->FindClass(Thread::Current(),
63 name.c_str(),
64 class_loader_handle);
65 DCHECK(result != nullptr) << name;
66 return result;
67 }
68
69 void LoadDexFile(ScopedObjectAccess* soa) REQUIRES_SHARED(Locks::mutator_lock_) {
70 class_loader_ = LoadDex("VerifierDeps");
71 std::vector<const DexFile*> dex_files = GetDexFiles(class_loader_);
72 CHECK_EQ(dex_files.size(), 1u);
73 dex_file_ = dex_files.front();
74
75 mirror::ClassLoader* loader = soa->Decode<mirror::ClassLoader*>(class_loader_);
76 class_linker_->RegisterDexFile(*dex_file_, loader);
77
78 klass_Main_ = FindClassByName("LMain;", soa);
79 CHECK(klass_Main_ != nullptr);
80
81 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
82 VerifierDepsCompilerCallbacks* callbacks =
83 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
84 callbacks->SetVerifierDeps(verifier_deps_.get());
85 }
86
87 bool VerifyMethod(const std::string& method_name) {
88 ScopedObjectAccess soa(Thread::Current());
89 LoadDexFile(&soa);
90
91 StackHandleScope<2> hs(Thread::Current());
92 Handle<mirror::ClassLoader> class_loader_handle(
93 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader_)));
94 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
95
96 const DexFile::ClassDef* class_def = klass_Main_->GetClassDef();
97 const uint8_t* class_data = dex_file_->GetClassData(*class_def);
98 CHECK(class_data != nullptr);
99
100 ClassDataItemIterator it(*dex_file_, class_data);
101 while (it.HasNextStaticField() || it.HasNextInstanceField()) {
102 it.Next();
103 }
104
105 ArtMethod* method = nullptr;
106 while (it.HasNextDirectMethod()) {
107 ArtMethod* resolved_method = class_linker_->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
108 *dex_file_,
109 it.GetMemberIndex(),
110 dex_cache_handle,
111 class_loader_handle,
112 nullptr,
113 it.GetMethodInvokeType(*class_def));
114 CHECK(resolved_method != nullptr);
115 if (method_name == resolved_method->GetName()) {
116 method = resolved_method;
117 break;
118 }
119 it.Next();
120 }
121 CHECK(method != nullptr);
122
123 MethodVerifier verifier(Thread::Current(),
124 dex_file_,
125 dex_cache_handle,
126 class_loader_handle,
127 *class_def,
128 it.GetMethodCodeItem(),
129 it.GetMemberIndex(),
130 method,
131 it.GetMethodAccessFlags(),
132 true /* can_load_classes */,
133 true /* allow_soft_failures */,
134 true /* need_precise_constants */,
135 false /* verify to dump */,
136 true /* allow_thread_suspension */);
137 verifier.Verify();
138 return !verifier.HasFailures();
139 }
140
141 bool TestAssignabilityRecording(const std::string& dst,
142 const std::string& src,
143 bool is_strict,
144 bool is_assignable) {
145 ScopedObjectAccess soa(Thread::Current());
146 LoadDexFile(&soa);
147 verifier_deps_->AddAssignability(*dex_file_,
148 FindClassByName(dst, &soa),
149 FindClassByName(src, &soa),
150 is_strict,
151 is_assignable);
152 return true;
153 }
154
155 // Iterates over all assignability records and tries to find an entry which
156 // matches the expected destination/source pair.
157 bool HasAssignable(const std::string& expected_destination,
158 const std::string& expected_source,
159 bool expected_is_assignable) {
160 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
161 for (auto& dex_dep : verifier_deps_->dex_deps_) {
162 const DexFile& dex_file = *dex_dep.first;
163 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
164 : dex_dep.second->unassignable_types_;
165 for (auto& entry : storage) {
166 std::string actual_destination =
167 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
168 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
169 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
170 return true;
171 }
172 }
173 }
174 return false;
175 }
176
177 // Iterates over all class resolution records, finds an entry which matches
178 // the given class descriptor and tests its properties.
179 bool HasClass(const std::string& expected_klass,
180 bool expected_resolved,
181 const std::string& expected_access_flags = "") {
182 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
183 for (auto& dex_dep : verifier_deps_->dex_deps_) {
184 for (auto& entry : dex_dep.second->classes_) {
185 if (expected_resolved != entry.IsResolved()) {
186 continue;
187 }
188
189 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
190 if (expected_klass != actual_klass) {
191 continue;
192 }
193
194 if (expected_resolved) {
195 // Test access flags. Note that PrettyJavaAccessFlags always appends
196 // a space after the modifiers. Add it to the expected access flags.
197 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
198 if (expected_access_flags + " " != actual_access_flags) {
199 continue;
200 }
201 }
202
203 return true;
204 }
205 }
206 return false;
207 }
208
209 // Iterates over all field resolution records, finds an entry which matches
210 // the given field class+name+type and tests its properties.
211 bool HasField(const std::string& expected_klass,
212 const std::string& expected_name,
213 const std::string& expected_type,
214 bool expected_resolved,
215 const std::string& expected_access_flags = "",
216 const std::string& expected_decl_klass = "") {
217 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
218 for (auto& dex_dep : verifier_deps_->dex_deps_) {
219 for (auto& entry : dex_dep.second->fields_) {
220 if (expected_resolved != entry.IsResolved()) {
221 continue;
222 }
223
224 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
225
226 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
227 if (expected_klass != actual_klass) {
228 continue;
229 }
230
231 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
232 if (expected_name != actual_name) {
233 continue;
234 }
235
236 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
237 if (expected_type != actual_type) {
238 continue;
239 }
240
241 if (expected_resolved) {
242 // Test access flags. Note that PrettyJavaAccessFlags always appends
243 // a space after the modifiers. Add it to the expected access flags.
244 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
245 if (expected_access_flags + " " != actual_access_flags) {
246 continue;
247 }
248
249 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
250 *dex_dep.first, entry.GetDeclaringClassIndex());
251 if (expected_decl_klass != actual_decl_klass) {
252 continue;
253 }
254 }
255
256 return true;
257 }
258 }
259 return false;
260 }
261
262 // Iterates over all method resolution records, finds an entry which matches
263 // the given field kind+class+name+signature and tests its properties.
264 bool HasMethod(const std::string& expected_kind,
265 const std::string& expected_klass,
266 const std::string& expected_name,
267 const std::string& expected_signature,
268 bool expected_resolved,
269 const std::string& expected_access_flags = "",
270 const std::string& expected_decl_klass = "") {
271 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
272 for (auto& dex_dep : verifier_deps_->dex_deps_) {
273 auto& storage = (expected_kind == "direct") ? dex_dep.second->direct_methods_
274 : (expected_kind == "virtual") ? dex_dep.second->virtual_methods_
275 : dex_dep.second->interface_methods_;
276 for (auto& entry : storage) {
277 if (expected_resolved != entry.IsResolved()) {
278 continue;
279 }
280
281 const DexFile::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
282
283 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_);
284 if (expected_klass != actual_klass) {
285 continue;
286 }
287
288 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_);
289 if (expected_name != actual_name) {
290 continue;
291 }
292
293 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString();
294 if (expected_signature != actual_signature) {
295 continue;
296 }
297
298 if (expected_resolved) {
299 // Test access flags. Note that PrettyJavaAccessFlags always appends
300 // a space after the modifiers. Add it to the expected access flags.
301 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
302 if (expected_access_flags + " " != actual_access_flags) {
303 continue;
304 }
305
306 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
307 *dex_dep.first, entry.GetDeclaringClassIndex());
308 if (expected_decl_klass != actual_decl_klass) {
309 continue;
310 }
311 }
312
313 return true;
314 }
315 }
316 return false;
317 }
318
319 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
320 const DexFile* dex_file_;
321 jobject class_loader_;
322 mirror::Class* klass_Main_;
323};
324
325TEST_F(VerifierDepsTest, StringToId) {
326 ScopedObjectAccess soa(Thread::Current());
327 LoadDexFile(&soa);
328
329 MutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
330
331 uint32_t id_Main1 = verifier_deps_->GetIdFromString(*dex_file_, "LMain;");
332 ASSERT_LT(id_Main1, dex_file_->NumStringIds());
333 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*dex_file_, id_Main1));
334
335 uint32_t id_Main2 = verifier_deps_->GetIdFromString(*dex_file_, "LMain;");
336 ASSERT_LT(id_Main2, dex_file_->NumStringIds());
337 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*dex_file_, id_Main2));
338
339 uint32_t id_Lorem1 = verifier_deps_->GetIdFromString(*dex_file_, "Lorem ipsum");
340 ASSERT_GE(id_Lorem1, dex_file_->NumStringIds());
341 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*dex_file_, id_Lorem1));
342
343 uint32_t id_Lorem2 = verifier_deps_->GetIdFromString(*dex_file_, "Lorem ipsum");
344 ASSERT_GE(id_Lorem2, dex_file_->NumStringIds());
345 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*dex_file_, id_Lorem2));
346
347 ASSERT_EQ(id_Main1, id_Main2);
348 ASSERT_EQ(id_Lorem1, id_Lorem2);
349 ASSERT_NE(id_Main1, id_Lorem1);
350}
351
352TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
353 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
354 /* src */ "Ljava/util/SimpleTimeZone;",
355 /* is_strict */ true,
356 /* is_assignable */ true));
357 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
358}
359
360TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
361 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
362 /* src */ "LMySSLSocket;",
363 /* is_strict */ true,
364 /* is_assignable */ true));
365 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "LMySSLSocket;", true));
366}
367
368TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
369 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
370 /* src */ "LMySimpleTimeZone;",
371 /* is_strict */ true,
372 /* is_assignable */ true));
373 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "LMySimpleTimeZone;", true));
374}
375
376TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
377 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
378 /* src */ "LMyThreadSet;",
379 /* is_strict */ true,
380 /* is_assignable */ true));
381 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "LMyThreadSet;", true));
382}
383
384TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
385 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
386 /* src */ "[[Ljava/util/SimpleTimeZone;",
387 /* is_strict */ true,
388 /* is_assignable */ true));
389 // If the component types of both arrays are resolved, we optimize the list of
390 // dependencies by recording a dependency on the component types.
391 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
392 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
393 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
394}
395
396TEST_F(VerifierDepsTest, Assignable_BothArrays_Erroneous) {
397 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
398 /* src */ "[[LMyErroneousTimeZone;",
399 /* is_strict */ true,
400 /* is_assignable */ true));
401 // If the component type of an array is erroneous, we record the dependency on
402 // the array type.
403 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[LMyErroneousTimeZone;", true));
404 ASSERT_TRUE(HasAssignable("[Ljava/util/TimeZone;", "[LMyErroneousTimeZone;", true));
405 ASSERT_FALSE(HasAssignable("Ljava/util/TimeZone;", "LMyErroneousTimeZone;", true));
406}
407
408 // We test that VerifierDeps does not try to optimize by storing assignability
409 // of the component types. This is due to the fact that the component type may
410 // be an erroneous class, even though the array type has resolved status.
411
412TEST_F(VerifierDepsTest, Assignable_ArrayToInterface1) {
413 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
414 /* src */ "[Ljava/util/TimeZone;",
415 /* is_strict */ true,
416 /* is_assignable */ true));
417 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[Ljava/util/TimeZone;", true));
418}
419
420TEST_F(VerifierDepsTest, Assignable_ArrayToInterface2) {
421 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/io/Serializable;",
422 /* src */ "[LMyThreadSet;",
423 /* is_strict */ true,
424 /* is_assignable */ true));
425 ASSERT_TRUE(HasAssignable("Ljava/io/Serializable;", "[LMyThreadSet;", true));
426}
427
428TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
429 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
430 /* src */ "Ljava/util/SimpleTimeZone;",
431 /* is_strict */ true,
432 /* is_assignable */ false));
433 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
434}
435
436TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
437 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
438 /* src */ "LMySSLSocket;",
439 /* is_strict */ true,
440 /* is_assignable */ false));
441 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySSLSocket;", false));
442}
443
444TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
445 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
446 /* src */ "LMySimpleTimeZone;",
447 /* is_strict */ true,
448 /* is_assignable */ false));
449 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySimpleTimeZone;", false));
450}
451
452TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
453 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
454 /* src */ "[Ljava/util/SimpleTimeZone;",
455 /* is_strict */ true,
456 /* is_assignable */ false));
457 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
458}
459
460TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
461 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
462 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
463}
464
465TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
466 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
467 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public final abstract"));
468}
469
470TEST_F(VerifierDepsTest, ArgumentType_ResolvedPrimitiveArray) {
471 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedPrimitiveArray"));
472 ASSERT_TRUE(HasClass("[B", true, "public final abstract"));
473}
474
475TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
476 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
477 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
478}
479
480TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
481 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
482 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
483}
484
485TEST_F(VerifierDepsTest, ReturnType_Reference) {
486 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
487 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
488}
489
490TEST_F(VerifierDepsTest, ReturnType_Array) {
491 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
492 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
493}
494
495TEST_F(VerifierDepsTest, InvokeArgumentType) {
496 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
497 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
498 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
499 ASSERT_TRUE(HasMethod("virtual",
500 "Ljava/text/SimpleDateFormat;",
501 "setTimeZone",
502 "(Ljava/util/TimeZone;)V",
503 true,
504 "public",
505 "Ljava/text/DateFormat;"));
506 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
507}
508
509TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
510 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
511 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LMySocketTimeoutException;", true));
512 ASSERT_TRUE(HasAssignable(
513 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
514}
515
516TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
517 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
518 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
519 ASSERT_TRUE(HasAssignable(
520 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
521 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
522}
523
524TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
525 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
526 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
527 ASSERT_TRUE(HasAssignable(
528 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
529}
530
531TEST_F(VerifierDepsTest, ConstClass_Resolved) {
532 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
533 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
534}
535
536TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
537 ASSERT_TRUE(VerifyMethod("ConstClass_Unresolved"));
538 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
539}
540
541TEST_F(VerifierDepsTest, CheckCast_Resolved) {
542 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
543 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
544}
545
546TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
547 ASSERT_TRUE(VerifyMethod("CheckCast_Unresolved"));
548 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
549}
550
551TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
552 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
553 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
554}
555
556TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
557 ASSERT_TRUE(VerifyMethod("InstanceOf_Unresolved"));
558 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
559}
560
561TEST_F(VerifierDepsTest, NewInstance_Resolved) {
562 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
563 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
564}
565
566TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
567 ASSERT_TRUE(VerifyMethod("NewInstance_Unresolved"));
568 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
569}
570
571TEST_F(VerifierDepsTest, NewArray_Resolved) {
572 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
573 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public final abstract"));
574}
575
576TEST_F(VerifierDepsTest, NewArray_Unresolved) {
577 ASSERT_TRUE(VerifyMethod("NewArray_Unresolved"));
578 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
579}
580
581TEST_F(VerifierDepsTest, Throw) {
582 ASSERT_TRUE(VerifyMethod("Throw"));
583 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
584}
585
586TEST_F(VerifierDepsTest, MoveException_Resolved) {
587 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
588 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
589 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
590 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
591
592 // Testing that all exception types are assignable to Throwable.
593 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
594 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
595 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
596
597 // Testing that the merge type is assignable to Throwable.
598 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
599
600 // Merging of exception types.
601 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
602 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
603 ASSERT_TRUE(HasAssignable(
604 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
605}
606
607TEST_F(VerifierDepsTest, MoveException_Unresolved) {
608 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
609 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
610}
611
612TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
613 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
614 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public final"));
615 ASSERT_TRUE(HasField("Ljava/lang/System;",
616 "out",
617 "Ljava/io/PrintStream;",
618 true,
619 "public final static",
620 "Ljava/lang/System;"));
621}
622
623TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
624 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
625 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
626 ASSERT_TRUE(HasField(
627 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public final static", "Ljava/util/TimeZone;"));
628}
629
630TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
631 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
632 ASSERT_TRUE(HasField(
633 "LMySimpleTimeZone;", "SHORT", "I", true, "public final static", "Ljava/util/TimeZone;"));
634}
635
636TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
637 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
638 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
639 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
640 "PI_ENABLE_OUTPUT_ESCAPING",
641 "Ljava/lang/String;",
642 true,
643 "public final static",
644 "Ljavax/xml/transform/Result;"));
645}
646
647TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
648 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
649 ASSERT_TRUE(HasField("LMyDOMResult;",
650 "PI_ENABLE_OUTPUT_ESCAPING",
651 "Ljava/lang/String;",
652 true,
653 "public final static",
654 "Ljavax/xml/transform/Result;"));
655}
656
657TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
658 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
659 ASSERT_TRUE(HasField("LMyResult;",
660 "PI_ENABLE_OUTPUT_ESCAPING",
661 "Ljava/lang/String;",
662 true,
663 "public final static",
664 "Ljavax/xml/transform/Result;"));
665}
666
667TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
668 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
669 ASSERT_TRUE(HasField("LMyDocument;",
670 "ELEMENT_NODE",
671 "S",
672 true,
673 "public final static",
674 "Lorg/w3c/dom/Node;"));
675}
676
677TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
678 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
679 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public abstract"));
680 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
681}
682
683TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
684 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
685 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
686}
687
688TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
689 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
690 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
691 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
692 "bytesTransferred",
693 "I",
694 true,
695 "public",
696 "Ljava/io/InterruptedIOException;"));
697 ASSERT_TRUE(HasAssignable(
698 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
699}
700
701TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
702 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
703 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
704 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
705 "bytesTransferred",
706 "I",
707 true,
708 "public",
709 "Ljava/io/InterruptedIOException;"));
710 ASSERT_TRUE(HasAssignable(
711 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
712}
713
714TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
715 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
716 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
717 "bytesTransferred",
718 "I",
719 true,
720 "public",
721 "Ljava/io/InterruptedIOException;"));
722 ASSERT_TRUE(HasAssignable(
723 "Ljava/io/InterruptedIOException;", "LMySocketTimeoutException;", true));
724}
725
726TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
727 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
728 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
729 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
730}
731
732TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
733 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
734 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
735}
736
737TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
738 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
739 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
740 ASSERT_TRUE(HasMethod("direct",
741 "Ljava/net/Socket;",
742 "setSocketImplFactory",
743 "(Ljava/net/SocketImplFactory;)V",
744 true,
745 "public static",
746 "Ljava/net/Socket;"));
747}
748
749TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
750 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
751 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
752 ASSERT_TRUE(HasMethod("direct",
753 "Ljavax/net/ssl/SSLSocket;",
754 "setSocketImplFactory",
755 "(Ljava/net/SocketImplFactory;)V",
756 true,
757 "public static",
758 "Ljava/net/Socket;"));
759}
760
761TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
762 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
763 ASSERT_TRUE(HasMethod("direct",
764 "LMySSLSocket;",
765 "setSocketImplFactory",
766 "(Ljava/net/SocketImplFactory;)V",
767 true,
768 "public static",
769 "Ljava/net/Socket;"));
770}
771
772TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
773 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
774 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public abstract interface"));
775 ASSERT_TRUE(HasMethod("direct",
776 "Ljava/util/Map$Entry;",
777 "comparingByKey",
778 "()Ljava/util/Comparator;",
779 true,
780 "public static",
781 "Ljava/util/Map$Entry;"));
782}
783
784TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
785 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
786 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
787 ASSERT_TRUE(HasMethod("direct",
788 "Ljava/util/AbstractMap$SimpleEntry;",
789 "comparingByKey",
790 "()Ljava/util/Comparator;",
791 false));
792}
793
794TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
795 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
796 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
797 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
798}
799
800TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
801 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
802 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
803}
804
805TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
806 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
807 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
808 ASSERT_TRUE(HasMethod(
809 "direct", "Ljava/net/Socket;", "<init>", "()V", true, "public", "Ljava/net/Socket;"));
810}
811
812TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
813 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
814 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
815 ASSERT_TRUE(HasMethod("direct",
816 "Ljavax/net/ssl/SSLSocket;",
817 "checkOldImpl",
818 "()V",
819 true,
820 "private",
821 "Ljava/net/Socket;"));
822}
823
824TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
825 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
826 ASSERT_TRUE(HasMethod(
827 "direct", "LMySSLSocket;", "checkOldImpl", "()V", true, "private", "Ljava/net/Socket;"));
828}
829
830TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
831 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
832 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public abstract"));
833 ASSERT_TRUE(HasMethod("direct", "Ljavax/net/ssl/SSLSocket;", "x", "()V", false));
834}
835
836TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
837 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
838 ASSERT_TRUE(HasMethod("direct", "LMySSLSocket;", "x", "()V", false));
839}
840
841TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
842 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
843 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
844 ASSERT_TRUE(HasMethod("virtual",
845 "Ljava/lang/Throwable;",
846 "getMessage",
847 "()Ljava/lang/String;",
848 true,
849 "public",
850 "Ljava/lang/Throwable;"));
851 // Type dependency on `this` argument.
852 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
853}
854
855TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
856 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
857 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
858 ASSERT_TRUE(HasMethod("virtual",
859 "Ljava/io/InterruptedIOException;",
860 "getMessage",
861 "()Ljava/lang/String;",
862 true,
863 "public",
864 "Ljava/lang/Throwable;"));
865 // Type dependency on `this` argument.
866 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "LMySocketTimeoutException;", true));
867}
868
869TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
870 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
871 ASSERT_TRUE(HasMethod("virtual",
872 "LMySocketTimeoutException;",
873 "getMessage",
874 "()Ljava/lang/String;",
875 true,
876 "public",
877 "Ljava/lang/Throwable;"));
878}
879
880TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
881 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
882 ASSERT_TRUE(HasMethod("virtual",
883 "LMyThreadSet;",
884 "size",
885 "()I",
886 true,
887 "public abstract",
888 "Ljava/util/Set;"));
889}
890
891TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
892 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
893 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
894 ASSERT_TRUE(HasMethod("virtual", "Ljava/io/InterruptedIOException;", "x", "()V", false));
895}
896
897TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
898 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
899 ASSERT_TRUE(HasMethod("virtual", "LMySocketTimeoutException;", "x", "()V", false));
900}
901
902TEST_F(VerifierDepsTest, InvokeVirtual_ActuallyDirect) {
903 ASSERT_FALSE(VerifyMethod("InvokeVirtual_ActuallyDirect"));
904 ASSERT_TRUE(HasMethod("virtual", "LMyThread;", "activeCount", "()I", false));
905 ASSERT_TRUE(HasMethod("direct",
906 "LMyThread;",
907 "activeCount",
908 "()I",
909 true,
910 "public static",
911 "Ljava/lang/Thread;"));
912}
913
914TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
915 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
916 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
917 ASSERT_TRUE(HasMethod("interface",
918 "Ljava/lang/Runnable;",
919 "run",
920 "()V",
921 true,
922 "public abstract",
923 "Ljava/lang/Runnable;"));
924}
925
926TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
927 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
928 ASSERT_TRUE(HasMethod("interface", "LMyThread;", "join", "()V", false));
929}
930
931TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
932 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
933 ASSERT_TRUE(HasMethod("interface",
934 "LMyThreadSet;",
935 "run",
936 "()V",
937 true,
938 "public abstract",
939 "Ljava/lang/Runnable;"));
940}
941
942TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
943 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
944 ASSERT_TRUE(HasMethod("interface",
945 "LMyThreadSet;",
946 "isEmpty",
947 "()Z",
948 true,
949 "public abstract",
950 "Ljava/util/Set;"));
951}
952
953TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
954 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
955 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
956 ASSERT_TRUE(HasMethod("interface", "Ljava/lang/Runnable;", "x", "()V", false));
957}
958
959TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
960 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
961 ASSERT_TRUE(HasMethod("interface", "LMyThreadSet;", "x", "()V", false));
962}
963
964TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
965 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
966 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public abstract interface"));
967 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "LMain;", true));
968 ASSERT_TRUE(HasMethod("interface",
969 "Ljava/lang/Runnable;",
970 "run",
971 "()V",
972 true,
973 "public abstract",
974 "Ljava/lang/Runnable;"));
975}
976
977TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
978 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
979 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public final"));
980 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "LMain;", false));
981 ASSERT_TRUE(HasMethod(
982 "virtual", "Ljava/lang/Integer;", "intValue", "()I", true, "public", "Ljava/lang/Integer;"));
983}
984
985} // namespace verifier
986} // namespace art