diff options
author | 2020-07-06 14:04:02 +0100 | |
---|---|---|
committer | 2020-07-07 12:39:22 +0000 | |
commit | 28d0a1dd26bad8a0542d167d148a7f4c9fe66c21 (patch) | |
tree | 0b9de38c038e3968a08bd596e261c84d24550fdd /runtime/class_linker-inl.h | |
parent | bbdc301928b4525487cba325804bfc5be1ac6756 (diff) |
Workaround for b/160292234.
Resolve the type if not found before invoking CheckInvokeClassMismatch.
Test: test.py
Bug: 160292234
Bug: 73760543
Change-Id: Ia8ae4c2fff19af758b5bb7586a13b76972f50711
Diffstat (limited to 'runtime/class_linker-inl.h')
-rw-r--r-- | runtime/class_linker-inl.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 15a787b110..30e78e5663 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -368,10 +368,26 @@ inline ArtMethod* ClassLinker::ResolveMethod(Thread* self, type); } else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) { referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); + const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx); + ObjPtr<mirror::Class> cls = + LookupResolvedType(method_id.class_idx_, + referrer->GetDexCache(), + referrer->GetClassLoader()); + if (cls == nullptr) { + // The verifier breaks the invariant that a resolved method must have its + // class in the class table, so resolve the type in case we haven't found it. + // b/73760543 + StackHandleScope<2> hs(Thread::Current()); + Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache())); + Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(referrer->GetClassLoader())); + cls = ResolveType(method_id.class_idx_, h_dex_cache, h_class_loader); + if (hs.Self()->IsExceptionPending()) { + return nullptr; + } + } // Check if the invoke type matches the class type. - ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache(); - ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader(); - if (CheckInvokeClassMismatch</* kThrow= */ true>(dex_cache, type, method_idx, class_loader)) { + if (CheckInvokeClassMismatch</* kThrow= */ true>( + referrer->GetDexCache(), type, [cls]() { return cls; })) { DCHECK(Thread::Current()->IsExceptionPending()); return nullptr; } @@ -379,7 +395,7 @@ inline ArtMethod* ClassLinker::ResolveMethod(Thread* self, ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass(); if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(), resolved_method, - dex_cache, + referrer->GetDexCache(), method_idx, type)) { DCHECK(Thread::Current()->IsExceptionPending()); |