1ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil/* 2ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Copyright (C) 2016 The Android Open Source Project 3ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * 4ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Licensed under the Apache License, Version 2.0 (the "License"); 5ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * you may not use this file except in compliance with the License. 6ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * You may obtain a copy of the License at 7ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * 8ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * http://www.apache.org/licenses/LICENSE-2.0 9ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * 10ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * Unless required by applicable law or agreed to in writing, software 11ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * distributed under the License is distributed on an "AS IS" BASIS, 12ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * See the License for the specific language governing permissions and 14ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil * limitations under the License. 15ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil */ 16ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 17ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "verifier_deps.h" 18ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 1932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier#include <cstring> 2032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier 21a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field-inl.h" 22c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "art_method-inl.h" 23340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray#include "base/stl_util.h" 24ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "compiler_callbacks.h" 25c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe#include "dex_file-inl.h" 2676c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe#include "indenter.h" 276f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil#include "leb128.h" 28ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "mirror/class-inl.h" 2976c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe#include "mirror/class_loader.h" 303398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier#include "obj_ptr-inl.h" 31ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil#include "runtime.h" 32ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 33ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace art { 34ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilnamespace verifier { 35ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 36ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David BrazdilVerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files) { 37ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil for (const DexFile* dex_file : dex_files) { 38ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(GetDexFileDeps(*dex_file) == nullptr); 39ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil std::unique_ptr<DexFileDeps> deps(new DexFileDeps()); 40ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps_.emplace(dex_file, std::move(deps)); 41ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 42ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 43ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 44340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffrayvoid VerifierDeps::MergeWith(const VerifierDeps& other, 45340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray const std::vector<const DexFile*>& dex_files) { 46340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DCHECK(dex_deps_.size() == other.dex_deps_.size()); 47340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray for (const DexFile* dex_file : dex_files) { 48340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DexFileDeps* my_deps = GetDexFileDeps(*dex_file); 49340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray const DexFileDeps& other_deps = *other.GetDexFileDeps(*dex_file); 50340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // We currently collect extra strings only on the main `VerifierDeps`, 51340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // which should be the one passed as `this` in this method. 52340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DCHECK(other_deps.strings_.empty()); 53340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->assignable_types_, other_deps.assignable_types_); 54340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->unassignable_types_, other_deps.unassignable_types_); 55340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->classes_, other_deps.classes_); 56340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->fields_, other_deps.fields_); 57340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->direct_methods_, other_deps.direct_methods_); 58340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->virtual_methods_, other_deps.virtual_methods_); 59340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray MergeSets(my_deps->interface_methods_, other_deps.interface_methods_); 60340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray for (dex::TypeIndex entry : other_deps.unverified_classes_) { 61340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray my_deps->unverified_classes_.push_back(entry); 62340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 63340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 64340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray} 65340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray 66ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David BrazdilVerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) { 67ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil auto it = dex_deps_.find(&dex_file); 68ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return (it == dex_deps_.end()) ? nullptr : it->second.get(); 69ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 70ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 71d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayconst VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const { 72d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray auto it = dex_deps_.find(&dex_file); 73d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray return (it == dex_deps_.end()) ? nullptr : it->second.get(); 74d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray} 75d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 766e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray// Access flags that impact vdex verification. 776e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffraystatic constexpr uint32_t kAccVdexAccessFlags = 786e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface; 796e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray 80ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdiltemplate <typename T> 81ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdiluint16_t VerifierDeps::GetAccessFlags(T* element) { 82ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 83ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (element == nullptr) { 84ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return VerifierDeps::kUnresolvedMarker; 85ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } else { 866e54f78c7c1e01c1a91a458c6e51cca1c7d13ad4Nicolas Geoffray uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags; 87ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker); 88ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return access_flags; 89ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 90ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 91ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 928a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file, 938a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe ObjPtr<mirror::Class> klass) { 9432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier DCHECK(klass != nullptr); 9532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); 96fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier // Array and proxy classes do not have a dex cache. 9732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (!klass->IsArrayClass() && !klass->IsProxyClass()) { 9832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier DCHECK(dex_cache != nullptr) << klass->PrettyClass(); 9932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (dex_cache->GetDexFile() == &dex_file) { 10032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier // FindStringId is slow, try to go through the class def if we have one. 10132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier const DexFile::ClassDef* class_def = klass->GetClassDef(); 10232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier DCHECK(class_def != nullptr) << klass->PrettyClass(); 10332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_); 104fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier if (kIsDebugBuild) { 105fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier std::string temp; 106fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_); 107fc2dd6110c7ce5fc272836d1a7e48f3b40612c2dMathieu Chartier } 10832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return type_id.descriptor_idx_; 10932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 11032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 11132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier std::string temp; 11232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return GetIdFromString(dex_file, klass->GetDescriptor(&temp)); 11332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier} 11432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier 11532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id. 1168a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampestatic dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file, 1178a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe dex::TypeIndex type_idx, 1188a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe ObjPtr<mirror::Class> klass) 11932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_) { 12032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (!klass->IsArrayClass()) { 12132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx); 12232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier const DexFile& klass_dex = klass->GetDexFile(); 12332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_); 12432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (strcmp(dex_file.GetTypeDescriptor(type_id), 12532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier klass_dex.GetTypeDescriptor(klass_type_id)) == 0) { 12632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return type_id.descriptor_idx_; 12732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 12832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 1298a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex::Invalid(); 13032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier} 13132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier 1328a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file, 1338a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe uint32_t dex_method_index, 1348a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe ArtMethod* method) { 135ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 13632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (method == nullptr) { 1378a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex(VerifierDeps::kUnresolvedMarker); 13832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 1398a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe const dex::StringIndex string_id = TryGetClassDescriptorStringId( 14032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier dex_file, 14132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier dex_file.GetMethodId(dex_method_index).class_idx_, 14232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier method->GetDeclaringClass()); 1438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe if (string_id.IsValid()) { 14432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier // Got lucky using the original dex file, return based on the input dex file. 14532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id); 146ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return string_id; 147ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 14832b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()); 14932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier} 15032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier 1518a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file, 1528a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe uint32_t dex_field_idx, 1538a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe ArtField* field) { 15432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant"); 15532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier if (field == nullptr) { 1568a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex(VerifierDeps::kUnresolvedMarker); 15732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 1588a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe const dex::StringIndex string_id = TryGetClassDescriptorStringId( 15932b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier dex_file, 16032b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier dex_file.GetFieldId(dex_field_idx).class_idx_, 16132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier field->GetDeclaringClass()); 1628a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe if (string_id.IsValid()) { 16332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier // Got lucky using the original dex file, return based on the input dex file. 16432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id); 16532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return string_id; 16632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier } 16732b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()); 168ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 169ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 170340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic inline VerifierDeps* GetMainVerifierDeps() { 171340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // The main VerifierDeps is the one set in the compiler callbacks, which at the 172340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // end of verification will have all the per-thread VerifierDeps merged into it. 173340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks(); 174340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (callbacks == nullptr) { 175340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return nullptr; 176340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 177340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return callbacks->GetVerifierDeps(); 178340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray} 179340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray 180340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic inline VerifierDeps* GetThreadLocalVerifierDeps() { 181340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end 182340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // of full verification, these VerifierDeps will be merged into the main one. 183340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (!Runtime::Current()->IsAotCompiler()) { 184340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return nullptr; 185340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 186340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return Thread::Current()->GetVerifierDeps(); 187340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray} 188340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray 189340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffraystatic bool FindExistingStringId(const std::vector<std::string>& strings, 190340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray const std::string& str, 191340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray uint32_t* found_id) { 192340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray uint32_t num_extra_ids = strings.size(); 193340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray for (size_t i = 0; i < num_extra_ids; ++i) { 194340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (strings[i] == str) { 195340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray *found_id = i; 196340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return true; 197340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 198340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 199340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return false; 200340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray} 201340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray 2028a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampedex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) { 203ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str()); 204ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (string_id != nullptr) { 205ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // String is in the DEX file. Return its ID. 206ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return dex_file.GetIndexForStringId(*string_id); 207ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 208ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 209ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // String is not in the DEX file. Assign a new ID to it which is higher than 210ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // the number of strings in the DEX file. 211ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 212340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // We use the main `VerifierDeps` for adding new strings to simplify 213340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray // synchronization/merging of these entries between threads. 214340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* singleton = GetMainVerifierDeps(); 215340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DexFileDeps* deps = singleton->GetDexFileDeps(dex_file); 216ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(deps != nullptr); 217ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 218ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t num_ids_in_dex = dex_file.NumStringIds(); 219340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray uint32_t found_id; 220ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 221340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray { 222340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); 223340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (FindExistingStringId(deps->strings_, str, &found_id)) { 2248a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex(num_ids_in_dex + found_id); 225ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 226ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 227340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray { 228340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_); 229340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (FindExistingStringId(deps->strings_, str, &found_id)) { 2308a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex(num_ids_in_dex + found_id); 231340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 232340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray deps->strings_.push_back(str); 2338a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1); 2348a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows 235340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id)); 236340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray return new_id; 237340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray } 238ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 239ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 2408a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampestd::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) 2418a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe const { 242ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t num_ids_in_dex = dex_file.NumStringIds(); 2438a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe if (string_id.index_ < num_ids_in_dex) { 244ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return std::string(dex_file.StringDataByIdx(string_id)); 245ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } else { 246d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray const DexFileDeps* deps = GetDexFileDeps(dex_file); 247ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(deps != nullptr); 2488a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe string_id.index_ -= num_ids_in_dex; 2498a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe CHECK_LT(string_id.index_, deps->strings_.size()); 2508a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return deps->strings_[string_id.index_]; 251ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 252ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 253ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 254d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffraybool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const { 255ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(klass != nullptr); 256ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 2570f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray // For array types, we return whether the non-array component type 2580f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray // is in the classpath. 2590f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray while (klass->IsArrayClass()) { 2600f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray klass = klass->GetComponentType(); 2610f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray } 2620f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray 2630f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray if (klass->IsPrimitive()) { 2640f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray return true; 265ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 266ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 2670f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache(); 2680f1cb17d23b664b96b6966e5d0f280df5925f56fNicolas Geoffray DCHECK(dex_cache != nullptr); 269ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil const DexFile* dex_file = dex_cache->GetDexFile(); 270ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(dex_file != nullptr); 271ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 272ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex 273ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // file was not registered as being compiled and we assume `klass` is in the 274ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // classpath. 275ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return (GetDexFileDeps(*dex_file) == nullptr); 276ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 277ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 278ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddClassResolution(const DexFile& dex_file, 279a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe dex::TypeIndex type_idx, 280ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* klass) { 281ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 282ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (dex_deps == nullptr) { 283ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This invocation is from verification of a dex file which is not being compiled. 284ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 285ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 286ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 287ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (klass != nullptr && !IsInClassPath(klass)) { 288ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Class resolved into one of the DEX files which are being compiled. 289ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This is not a classpath dependency. 290ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 291ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 292ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 293ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass))); 294ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 295ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 296ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddFieldResolution(const DexFile& dex_file, 297ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t field_idx, 298ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil ArtField* field) { 299ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 300ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (dex_deps == nullptr) { 301ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This invocation is from verification of a dex file which is not being compiled. 302ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 303ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 304ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 305ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) { 306ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Field resolved into one of the DEX files which are being compiled. 307ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This is not a classpath dependency. 308ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 309ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 310ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 31132b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier dex_deps->fields_.emplace(FieldResolution(field_idx, 31232b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier GetAccessFlags(field), 31332b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier GetFieldDeclaringClassStringId(dex_file, 31432b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier field_idx, 31532b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier field))); 316ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 317ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 318ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddMethodResolution(const DexFile& dex_file, 319ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t method_idx, 320ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil MethodResolutionKind resolution_kind, 321ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil ArtMethod* method) { 322ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 323ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (dex_deps == nullptr) { 324ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This invocation is from verification of a dex file which is not being compiled. 325ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 326ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 327ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 328ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) { 329ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Method resolved into one of the DEX files which are being compiled. 330ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This is not a classpath dependency. 331ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 332ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 333ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 334ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil MethodResolution method_tuple(method_idx, 335ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil GetAccessFlags(method), 33632b50302d9826430013e008b45d5c71e6b7a2469Mathieu Chartier GetMethodDeclaringClassStringId(dex_file, method_idx, method)); 337ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (resolution_kind == kDirectMethodResolution) { 338ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->direct_methods_.emplace(method_tuple); 339ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } else if (resolution_kind == kVirtualMethodResolution) { 340ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->virtual_methods_.emplace(method_tuple); 341ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } else { 342ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK_EQ(resolution_kind, kInterfaceMethodResolution); 343ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->interface_methods_.emplace(method_tuple); 344ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 345ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 346ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 3470e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffraymirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination, 3480e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray mirror::Class* source) const { 3490e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray DCHECK(destination->IsInterface()); 3500e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray DCHECK(IsInClassPath(destination)); 3510e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray Thread* thread = Thread::Current(); 3520e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray mirror::Class* current = source; 3530e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // Record the classes that are at the boundary between the compiled DEX files and 3540e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // the classpath. We will check those classes later to find one class that inherits 3550e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // `destination`. 3560e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray std::vector<ObjPtr<mirror::Class>> boundaries; 3570e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // If the destination is a direct interface of a class defined in the DEX files being 3580e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // compiled, no need to record it. 3590e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray while (!IsInClassPath(current)) { 3600e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) { 3610e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i); 3620e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (direct == destination) { 3630e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray return nullptr; 3640e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } else if (IsInClassPath(direct)) { 3650e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray boundaries.push_back(direct); 3660e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3670e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3680e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray current = current->GetSuperClass(); 3690e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3700e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray DCHECK(current != nullptr); 3710e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray boundaries.push_back(current); 3720e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray 3730e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // Check if we have an interface defined in the DEX files being compiled, direclty 3740e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // inheriting `destination`. 3750e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray int32_t iftable_count = source->GetIfTableCount(); 3760e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray ObjPtr<mirror::IfTable> iftable = source->GetIfTable(); 3770e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray for (int32_t i = 0; i < iftable_count; ++i) { 3780e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray mirror::Class* itf = iftable->GetInterface(i); 3790e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (!IsInClassPath(itf)) { 3800e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) { 3810e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j); 3820e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (direct == destination) { 3830e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray return nullptr; 3840e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } else if (IsInClassPath(direct)) { 3850e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray boundaries.push_back(direct); 3860e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3870e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3880e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3890e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3900e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray 3910e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // Find a boundary making `source` inherit from `destination`. We must find one. 3920e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray for (const ObjPtr<mirror::Class>& boundary : boundaries) { 3930e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (destination->IsAssignableFrom(boundary)) { 3940e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray return boundary.Ptr(); 3950e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3960e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 3970e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray LOG(FATAL) << "Should have found a classpath boundary"; 3980e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray UNREACHABLE(); 3990e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray} 4000e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray 401ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::AddAssignability(const DexFile& dex_file, 402ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* destination, 403ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* source, 404ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil bool is_strict, 405ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil bool is_assignable) { 406ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Test that the method is only called on reference types. 407ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Note that concurrent verification of `destination` and `source` may have 408ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // set their status to erroneous. However, the tests performed below rely 409ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // merely on no issues with linking (valid access flags, superclass and 410ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // implemented interfaces). If the class at any point reached the IsResolved 411ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass. 412d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray DCHECK(destination != nullptr); 413d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray DCHECK(source != nullptr); 414d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray 415d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray if (destination->IsPrimitive() || source->IsPrimitive()) { 416d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray // Primitive types are trivially non-assignable to anything else. 417d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray // We do not need to record trivial assignability, as it will 418d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray // not change across releases. 419d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray return; 420d1665a03ddad0e19f71e186efd8b5d2c217f1b40Nicolas Geoffray } 421ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 422119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray if (source->IsObjectClass() && !is_assignable) { 423119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray // j.l.Object is trivially non-assignable to other types, don't 424119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray // record it. 425119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray return; 426119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray } 427119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray 428ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (destination == source || 429ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil destination->IsObjectClass() || 430ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil (!is_strict && destination->IsInterface())) { 431ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Cases when `destination` is trivially assignable from `source`. 432ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DCHECK(is_assignable); 433ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 434ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 435ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 436ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (destination->IsArrayClass() && source->IsArrayClass()) { 437ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Both types are arrays. Break down to component types and add recursively. 438ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This helps filter out destinations from compiled DEX files (see below) 439ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // and deduplicate entries with the same canonical component type. 440ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* destination_component = destination->GetComponentType(); 441ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* source_component = source->GetComponentType(); 442ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 443ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Only perform the optimization if both types are resolved which guarantees 444ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // that they linked successfully, as required at the top of this method. 445ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (destination_component->IsResolved() && source_component->IsResolved()) { 446ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil AddAssignability(dex_file, 447ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil destination_component, 448ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil source_component, 449ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil /* is_strict */ true, 450ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil is_assignable); 451ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 452ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 453bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray } else { 454bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray // We only do this check for non-array types, as arrays might have erroneous 455bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray // component types which makes the IsAssignableFrom check unreliable. 456bdb540dc8d09c48ee19cf035f418bcae0f00660eNicolas Geoffray DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source)); 457ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 458ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 459ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil DexFileDeps* dex_deps = GetDexFileDeps(dex_file); 460ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (dex_deps == nullptr) { 461ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // This invocation is from verification of a DEX file which is not being compiled. 462ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 463ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 464ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 465ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (!IsInClassPath(destination) && !IsInClassPath(source)) { 466ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Both `destination` and `source` are defined in the compiled DEX files. 467ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // No need to record a dependency. 468ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil return; 469ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 470ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 4710e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (!IsInClassPath(source)) { 472fc38e919bad23670e38a484d4728f300406415c3Nicolas Geoffray if (!destination->IsInterface() && !source->IsInterface()) { 4730e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // Find the super class at the classpath boundary. Only that class 4740e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // can change the assignability. 4750e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray do { 4760e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray source = source->GetSuperClass(); 4770e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } while (!IsInClassPath(source)); 478119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray 4790e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // If that class is the actual destination, no need to record it. 4800e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (source == destination) { 4810e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray return; 4820e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 4830e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } else if (is_assignable) { 4840e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray source = FindOneClassPathBoundaryForInterface(destination, source); 4850e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray if (source == nullptr) { 4860e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray // There was no classpath boundary, no need to record. 4870e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray return; 4880e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray } 4890e2fe0ff28a89721bcf225027093ac693d568a5cNicolas Geoffray DCHECK(IsInClassPath(source)); 490119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray } 491119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray } 492119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray 493119e846b04c7c12c5b332122e71e9365b4a462f0Nicolas Geoffray 494ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil // Get string IDs for both descriptors and store in the appropriate set. 4958a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination); 4968a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source); 497ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 498ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil if (is_assignable) { 499ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id)); 500ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } else { 501ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id)); 502ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 503ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 504ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 5050802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffrayvoid VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file, 506a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe dex::TypeIndex type_idx, 50776c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe FailureKind failure_kind) { 50876c1965179bdf34ed9d0dded046c7ad6f277de3fAndreas Gampe if (failure_kind == FailureKind::kNoFailure) { 5090802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray // We only record classes that did not fully verify at compile time. 5100802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray return; 5110802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray } 5120802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray 513340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 514340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (thread_deps != nullptr) { 515340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file); 5160802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray dex_deps->unverified_classes_.push_back(type_idx); 5170802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray } 5180802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray} 5190802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray 520ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file, 521a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe dex::TypeIndex type_idx, 522ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* klass) { 523340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 524340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (thread_deps != nullptr) { 525340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray thread_deps->AddClassResolution(dex_file, type_idx, klass); 526ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 527ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 528ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 529ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file, 530ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t field_idx, 531ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil ArtField* field) { 532340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 533340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (thread_deps != nullptr) { 534340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray thread_deps->AddFieldResolution(dex_file, field_idx, field); 535ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 536ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 537ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 538ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file, 539ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil uint32_t method_idx, 540ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil MethodResolutionKind resolution_kind, 541ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil ArtMethod* method) { 542340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 543340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (thread_deps != nullptr) { 544340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray thread_deps->AddMethodResolution(dex_file, method_idx, resolution_kind, method); 545ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 546ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 547ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 548ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdilvoid VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file, 549ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* destination, 550ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil mirror::Class* source, 551ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil bool is_strict, 552ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil bool is_assignable) { 553340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray VerifierDeps* thread_deps = GetThreadLocalVerifierDeps(); 554340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray if (thread_deps != nullptr) { 555340dafabc8e88378e395cda9027cf17726910e91Nicolas Geoffray thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable); 556ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil } 557ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} 558ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil 559a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampenamespace { 560a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 5616f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) { 5626f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil CHECK_LT(*in, end); 5636f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return DecodeUnsignedLeb128(in); 5646f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 5656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 566a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T> inline uint32_t Encode(T in); 567a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 568a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<uint16_t>(uint16_t in) { 569a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return in; 570a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 571a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<uint32_t>(uint32_t in) { 572a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return in; 573a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 574a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) { 575a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return in.index_; 576a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 5778a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampetemplate<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) { 5788a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return in.index_; 5798a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe} 580a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 581a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T> inline T Decode(uint32_t in); 582a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 583a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint16_t Decode<uint16_t>(uint32_t in) { 584a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return dchecked_integral_cast<uint16_t>(in); 585a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 586a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline uint32_t Decode<uint32_t>(uint32_t in) { 587a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return in; 588a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 589a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) { 590a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe return dex::TypeIndex(in); 591a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} 5928a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampetemplate<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) { 5938a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe return dex::StringIndex(in); 5948a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe} 595a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 5966f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2> 5976f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) { 598a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); 599a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); 6006f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6016f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 6026f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2> 6036f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) { 604a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); 605a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); 6066f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil *t = std::make_tuple(v1, v2); 6076f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6086f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 6096f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2, typename T3> 6106f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) { 611a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(std::get<0>(t))); 612a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(std::get<1>(t))); 613a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(std::get<2>(t))); 6146f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6156f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 6166f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T1, typename T2, typename T3> 6176f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) { 618a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end)); 619a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end)); 6208a0128a5ca0784f6d2b4ca27907e8967a74bc4c5Andreas Gampe T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end)); 6216f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil *t = std::make_tuple(v1, v2, v3); 6226f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6236f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 6246f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T> 6256f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) { 6266f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil EncodeUnsignedLeb128(out, set.size()); 6276f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil for (const T& entry : set) { 6286f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil EncodeTuple(out, entry); 6296f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 6306f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6316f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 632a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate <typename T> 6330802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffraystatic inline void EncodeUint16Vector(std::vector<uint8_t>* out, 634a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe const std::vector<T>& vector) { 6350802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray EncodeUnsignedLeb128(out, vector.size()); 636a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe for (const T& entry : vector) { 637a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe EncodeUnsignedLeb128(out, Encode(entry)); 6380802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray } 6390802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray} 6400802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray 6416f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdiltemplate<typename T> 6426f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) { 6436f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DCHECK(set->empty()); 6446f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil size_t num_entries = DecodeUint32WithOverflowCheck(in, end); 6456f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil for (size_t i = 0; i < num_entries; ++i) { 6466f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil T tuple; 6476f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DecodeTuple(in, end, &tuple); 6486f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil set->emplace(tuple); 6496f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 6506f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6516f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 652a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampetemplate<typename T> 6530802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffraystatic inline void DecodeUint16Vector(const uint8_t** in, 6540802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray const uint8_t* end, 655a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe std::vector<T>* vector) { 6560802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray DCHECK(vector->empty()); 6570802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray size_t num_entries = DecodeUint32WithOverflowCheck(in, end); 6580802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray vector->reserve(num_entries); 6590802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray for (size_t i = 0; i < num_entries; ++i) { 660a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe vector->push_back( 661a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end)))); 6620802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray } 6630802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray} 6640802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray 6656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void EncodeStringVector(std::vector<uint8_t>* out, 6666f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const std::vector<std::string>& strings) { 6676f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil EncodeUnsignedLeb128(out, strings.size()); 6686f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil for (const std::string& str : strings) { 6696f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str()); 6706f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil size_t length = str.length() + 1; 6716f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil out->insert(out->end(), data, data + length); 6726f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DCHECK_EQ(0u, out->back()); 6736f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 6746f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6756f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 6766f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilstatic inline void DecodeStringVector(const uint8_t** in, 6776f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const uint8_t* end, 6786f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil std::vector<std::string>* strings) { 6796f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DCHECK(strings->empty()); 6806f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil size_t num_strings = DecodeUint32WithOverflowCheck(in, end); 6816f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil strings->reserve(num_strings); 6826f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil for (size_t i = 0; i < num_strings; ++i) { 6836f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil CHECK_LT(*in, end); 6846f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const char* string_start = reinterpret_cast<const char*>(*in); 6856f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil strings->emplace_back(std::string(string_start)); 6866f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil *in += strings->back().length() + 1; 6876f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 6886f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 6896f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 690a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe} // namespace 691a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe 692d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayvoid VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files, 693d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray std::vector<uint8_t>* buffer) const { 694d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const DexFile* dex_file : dex_files) { 695d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray const DexFileDeps& deps = *GetDexFileDeps(*dex_file); 696d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeStringVector(buffer, deps.strings_); 697d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.assignable_types_); 698d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.unassignable_types_); 699d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.classes_); 700d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.fields_); 701d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.direct_methods_); 702d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.virtual_methods_); 703d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeSet(buffer, deps.interface_methods_); 704d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray EncodeUint16Vector(buffer, deps.unverified_classes_); 7056f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7066f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 7076f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 708e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas GeoffrayVerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, 709e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray ArrayRef<const uint8_t> data) 7106f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil : VerifierDeps(dex_files) { 711e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray if (data.empty()) { 712e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray // Return eagerly, as the first thing we expect from VerifierDeps data is 713e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray // the number of created strings, even if there is no dependency. 714e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray // Currently, only the boot image does not have any VerifierDeps data. 715e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray return; 716e70dd560154ea38af87ce8b783ab6e382eb49d4bNicolas Geoffray } 7176f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const uint8_t* data_start = data.data(); 7186f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const uint8_t* data_end = data_start + data.size(); 719d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const DexFile* dex_file : dex_files) { 720d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DexFileDeps* deps = GetDexFileDeps(*dex_file); 721d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeStringVector(&data_start, data_end, &deps->strings_); 722d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->assignable_types_); 723d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->unassignable_types_); 724d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->classes_); 725d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->fields_); 726d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->direct_methods_); 727d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->virtual_methods_); 728d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeSet(&data_start, data_end, &deps->interface_methods_); 729d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray DecodeUint16Vector(&data_start, data_end, &deps->unverified_classes_); 7306f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7316f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil CHECK_LE(data_start, data_end); 7326f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 7336f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7346f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilbool VerifierDeps::Equals(const VerifierDeps& rhs) const { 7356f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil if (dex_deps_.size() != rhs.dex_deps_.size()) { 7366f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return false; 7376f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7386f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7396f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil auto lhs_it = dex_deps_.begin(); 7406f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil auto rhs_it = rhs.dex_deps_.begin(); 7416f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7426f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) { 7436f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const DexFile* lhs_dex_file = lhs_it->first; 7446f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil const DexFile* rhs_dex_file = rhs_it->first; 7456f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil if (lhs_dex_file != rhs_dex_file) { 7466f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return false; 7476f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7486f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7496f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DexFileDeps* lhs_deps = lhs_it->second.get(); 7506f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DexFileDeps* rhs_deps = rhs_it->second.get(); 7516f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil if (!lhs_deps->Equals(*rhs_deps)) { 7526f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return false; 7536f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7546f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil } 7556f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7566f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end())); 7576f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return true; 7586f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 7596f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 7606f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdilbool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const { 7616f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil return (strings_ == rhs.strings_) && 7626f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (assignable_types_ == rhs.assignable_types_) && 7636f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (unassignable_types_ == rhs.unassignable_types_) && 7646f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (classes_ == rhs.classes_) && 7656f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (fields_ == rhs.fields_) && 7666f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (direct_methods_ == rhs.direct_methods_) && 7676f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil (virtual_methods_ == rhs.virtual_methods_) && 7680802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray (interface_methods_ == rhs.interface_methods_) && 7690802518a6a5af8182131eb3fe66bf58dd77f9fe2Nicolas Geoffray (unverified_classes_ == rhs.unverified_classes_); 7706f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil} 7716f82fbddf69388180e4dca9bcb5ce2e183e42bfaDavid Brazdil 772d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffrayvoid VerifierDeps::Dump(VariableIndentationOutputStream* vios) const { 773d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const auto& dep : dex_deps_) { 774d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray const DexFile& dex_file = *dep.first; 775d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 776d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "Dependencies of " 777d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetLocation() 778d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << ":\n"; 779d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 780d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray ScopedIndentation indent(vios); 781d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 782d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const std::string& str : dep.second->strings_) { 783d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() << "Extra string: " << str << "\n"; 784d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 785d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 786d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const TypeAssignability& entry : dep.second->assignable_types_) { 787d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 788d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, entry.GetSource()) 789d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " must be assignable to " 790d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, entry.GetDestination()) 791d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "\n"; 792d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 793d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 794d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const TypeAssignability& entry : dep.second->unassignable_types_) { 795d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 796d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, entry.GetSource()) 797d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " must not be assignable to " 798d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, entry.GetDestination()) 799d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "\n"; 800d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 801d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 802d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const ClassResolution& entry : dep.second->classes_) { 803d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 804d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.StringByTypeIdx(entry.GetDexTypeIndex()) 805d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << (entry.IsResolved() ? " must be resolved " : "must not be resolved ") 806d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec 807d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "\n"; 808d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 809d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 810d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const FieldResolution& entry : dep.second->fields_) { 811d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex()); 812d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 813d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->" 814d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetFieldName(field_id) << ":" 815d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetFieldTypeDescriptor(field_id) 816d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " is expected to be "; 817d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray if (!entry.IsResolved()) { 818d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() << "unresolved\n"; 819d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } else { 820d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 821d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "in class " 822d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 823d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec 824d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "\n"; 825d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 826d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 827d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 828d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const auto& entry : 829d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray { std::make_pair(kDirectMethodResolution, dep.second->direct_methods_), 830d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray std::make_pair(kVirtualMethodResolution, dep.second->virtual_methods_), 831d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray std::make_pair(kInterfaceMethodResolution, dep.second->interface_methods_) }) { 832d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray for (const MethodResolution& method : entry.second) { 833d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex()); 834d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 835d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->" 836d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetMethodName(method_id) 837d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.GetMethodSignature(method_id).ToString() 838d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " is expected to be "; 839d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray if (!method.IsResolved()) { 840d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() << "unresolved\n"; 841d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } else { 842d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 843d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "in class " 844d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << GetStringFromId(dex_file, method.GetDeclaringClassIndex()) 845d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec 846d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << ", and be of kind " << entry.first 847d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << "\n"; 848d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 849d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 850d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 851d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 852a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe for (dex::TypeIndex type_index : dep.second->unverified_classes_) { 853d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray vios->Stream() 854d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << dex_file.StringByTypeIdx(type_index) 855d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray << " is expected to be verified at runtime\n"; 856d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 857d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray } 858d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray} 859d01f60cbed4ba360b84f1310d2e0d422d6a16534Nicolas Geoffray 8606bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffraybool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader, 8616bb7f1b60f4b6b2214457d19d66d2b7b50685febNicolas Geoffray Thread* self) const { 8628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray for (const auto& entry : dex_deps_) { 8638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) { 8648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 8658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 8668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 8678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return true; 8688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 8698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 8708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray// TODO: share that helper with other parts of the compiler that have 8718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray// the same lookup pattern. 8728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic mirror::Class* FindClassAndClearException(ClassLinker* class_linker, 8738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self, 8748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const char* name, 8758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Handle<mirror::ClassLoader> class_loader) 8768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray REQUIRES_SHARED(Locks::mutator_lock_) { 8778904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray mirror::Class* result = class_linker->FindClass(self, name, class_loader); 8788904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (result == nullptr) { 8798904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray DCHECK(self->IsExceptionPending()); 8808904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray self->ClearException(); 8818904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 8828904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return result; 8838904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 8848904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 8858904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader, 8868904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile& dex_file, 8878904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::set<TypeAssignability>& assignables, 8888904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray bool expected_assignability, 8898904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self) const { 8908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray StackHandleScope<2> hs(self); 8918904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 8928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr)); 8938904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr)); 8948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 8958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray for (const auto& entry : assignables) { 8968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination()); 8978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray destination.Assign( 8988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader)); 8998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource()); 9008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray source.Assign( 9018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader)); 9028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 903fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe if (destination == nullptr) { 9048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc; 9058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 908fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe if (source == nullptr) { 9098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc; 9108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 9138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray DCHECK(destination->IsResolved() && source->IsResolved()); 9148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (destination->IsAssignableFrom(source.Get()) != expected_assignability) { 9158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Class " 9168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << destination_desc 9178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << (expected_assignability ? " not " : " ") 9188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << "assignable from " 9198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << source_desc; 9208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return true; 9248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 9258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 9268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader, 9278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile& dex_file, 9288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::set<ClassResolution>& classes, 9298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self) const { 9308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray StackHandleScope<1> hs(self); 9318904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 9328904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr)); 9338904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray for (const auto& entry : classes) { 9348904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex()); 9358904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader)); 9368904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 9378904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (entry.IsResolved()) { 938fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe if (cls == nullptr) { 9398904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor; 9408904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9418904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) { 9428904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected access flags on class " 9438904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << descriptor 9448904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << std::hex 9458904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " (expected=" 9468904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << entry.GetAccessFlags() 9478904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ", actual=" 9488904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetAccessFlags(cls.Get()) << ")" 9498904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << std::dec; 9508904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9518904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 952fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe } else if (cls != nullptr) { 9538904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor; 9548904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 9558904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9568904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 9578904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return true; 9588904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 9598904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 9608904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) { 9618904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile::FieldId& field_id = dex_file.GetFieldId(index); 9628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id)) 9638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + "->" 9648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + dex_file.GetFieldName(field_id) 9658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + ":" 9668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + dex_file.GetFieldTypeDescriptor(field_id); 9678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 9688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 9698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader, 9708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile& dex_file, 9718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::set<FieldResolution>& fields, 9728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self) const { 9738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray // Check recorded fields are resolved the same way, have the same recorded class, 9748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray // and have the same recorded flags. 9758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 9768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray for (const auto& entry : fields) { 977865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex()); 978865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_)); 979865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_)); 980865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray // Only use field_id.class_idx_ when the entry is unresolved, which is rare. 981865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray // Otherwise, we might end up resolving an application class, which is expensive. 982865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray std::string expected_decl_klass = entry.IsResolved() 983865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 984865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray : dex_file.StringByTypeIdx(field_id.class_idx_); 985865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray mirror::Class* cls = FindClassAndClearException( 986865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray class_linker, self, expected_decl_klass.c_str(), class_loader); 987865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray if (cls == nullptr) { 988865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass; 989865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray return false; 9908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 991865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray DCHECK(cls->IsResolved()); 9928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 993865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray ArtField* field = mirror::Class::FindField(self, cls, name, type); 9948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (entry.IsResolved()) { 9958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray std::string temp; 9968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (field == nullptr) { 9978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve field " 9988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetFieldDescription(dex_file, entry.GetDexFieldIndex()); 9998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) { 10018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution " 10028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetFieldDescription(dex_file, entry.GetDexFieldIndex()) 10038904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " (expected=" << expected_decl_klass 10048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")"; 10058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (entry.GetAccessFlags() != GetAccessFlags(field)) { 10078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field " 10088904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetFieldDescription(dex_file, entry.GetDexFieldIndex()) 10098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << std::hex << " (expected=" << entry.GetAccessFlags() 10108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ", actual=" << GetAccessFlags(field) << ")" << std::dec; 10118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (field != nullptr) { 10148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field " 10158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetFieldDescription(dex_file, entry.GetDexFieldIndex()); 10168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return true; 10208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 10218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 10228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraystatic std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) { 10238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile::MethodId& method_id = dex_file.GetMethodId(index); 10248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id)) 10258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + "->" 10268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + dex_file.GetMethodName(method_id) 10278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray + dex_file.GetMethodSignature(method_id).ToString(); 10288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 10298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 10308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader, 10318904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile& dex_file, 10328904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const std::set<MethodResolution>& methods, 10338904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray MethodResolutionKind kind, 10348904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self) const { 10358904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 10368904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray PointerSize pointer_size = class_linker->GetImagePointerSize(); 10378904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 10388904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray for (const auto& entry : methods) { 10398904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex()); 10408904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 10418904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const char* name = dex_file.GetMethodName(method_id); 10428904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const Signature signature = dex_file.GetMethodSignature(method_id); 1043865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray // Only use method_id.class_idx_ when the entry is unresolved, which is rare. 1044865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray // Otherwise, we might end up resolving an application class, which is expensive. 1045865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray std::string expected_decl_klass = entry.IsResolved() 1046865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex()) 1047865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray : dex_file.StringByTypeIdx(method_id.class_idx_); 1048865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray 1049865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray mirror::Class* cls = FindClassAndClearException( 1050865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray class_linker, self, expected_decl_klass.c_str(), class_loader); 10518904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (cls == nullptr) { 1052865cf901e9f16680ca3594a5ab8d8e17b0b6f9d4Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass; 10538904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10548904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10558904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray DCHECK(cls->IsResolved()); 10568904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray ArtMethod* method = nullptr; 10578904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (kind == kDirectMethodResolution) { 10588904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray method = cls->FindDirectMethod(name, signature, pointer_size); 10598904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (kind == kVirtualMethodResolution) { 10608904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray method = cls->FindVirtualMethod(name, signature, pointer_size); 10618904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else { 10628904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray DCHECK_EQ(kind, kInterfaceMethodResolution); 10638904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray method = cls->FindInterfaceMethod(name, signature, pointer_size); 10648904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10658904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 10668904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (entry.IsResolved()) { 10678904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray std::string temp; 10688904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray if (method == nullptr) { 10698904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Could not resolve " 10708904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << kind 10718904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " method " 10728904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetMethodDescription(dex_file, entry.GetDexMethodIndex()); 10738904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10748904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) { 10758904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected declaring class for " 10768904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << kind 10778904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " method resolution " 10788904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetMethodDescription(dex_file, entry.GetDexMethodIndex()) 10798904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " (expected=" 10808904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << expected_decl_klass 10818904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ", actual=" 10828904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << method->GetDeclaringClass()->GetDescriptor(&temp) 10838904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ")"; 10848904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10858904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (entry.GetAccessFlags() != GetAccessFlags(method)) { 10868904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved " 10878904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << kind 10888904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " method resolution " 10898904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetMethodDescription(dex_file, entry.GetDexMethodIndex()) 10908904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << std::hex 10918904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " (expected=" 10928904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << entry.GetAccessFlags() 10938904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << ", actual=" 10948904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetAccessFlags(method) << ")" 10958904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << std::dec; 10968904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 10978904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 10988904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } else if (method != nullptr) { 10998904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray LOG(INFO) << "VerifierDeps: Unexpected successful resolution of " 11008904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << kind 11018904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << " method " 11028904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray << GetMethodDescription(dex_file, entry.GetDexMethodIndex()); 11038904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return false; 11048904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 11058904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray } 11068904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return true; 11078904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 11088904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 11098904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffraybool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader, 11108904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFile& dex_file, 11118904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray const DexFileDeps& deps, 11128904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray Thread* self) const { 11138904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray bool result = VerifyAssignability( 11148904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self); 11158904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyAssignability( 11168904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self); 11178904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 11188904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self); 11198904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyFields(class_loader, dex_file, deps.fields_, self); 11208904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 11218904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyMethods( 11228904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray class_loader, dex_file, deps.direct_methods_, kDirectMethodResolution, self); 11238904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyMethods( 11248904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray class_loader, dex_file, deps.virtual_methods_, kVirtualMethodResolution, self); 11258904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray result = result && VerifyMethods( 11268904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray class_loader, dex_file, deps.interface_methods_, kInterfaceMethodResolution, self); 11278904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 11288904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray return result; 11298904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray} 11308904b6f0e496ab389551e960426069c9deff4101Nicolas Geoffray 1131ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} // namespace verifier 1132ca3c8c33501bf199d6fd0a5db30a27d8e010cb23David Brazdil} // namespace art 1133