1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "oat_file_manager.h" 18 19#include <memory> 20#include <queue> 21#include <vector> 22 23#include "android-base/stringprintf.h" 24 25#include "art_field-inl.h" 26#include "base/bit_vector-inl.h" 27#include "base/logging.h" 28#include "base/stl_util.h" 29#include "base/systrace.h" 30#include "class_linker.h" 31#include "dex_file-inl.h" 32#include "gc/scoped_gc_critical_section.h" 33#include "gc/space/image_space.h" 34#include "handle_scope-inl.h" 35#include "jni_internal.h" 36#include "mirror/class_loader.h" 37#include "mirror/object-inl.h" 38#include "oat_file_assistant.h" 39#include "obj_ptr-inl.h" 40#include "scoped_thread_state_change-inl.h" 41#include "thread-inl.h" 42#include "thread_list.h" 43#include "well_known_classes.h" 44 45namespace art { 46 47using android::base::StringPrintf; 48 49// If true, then we attempt to load the application image if it exists. 50static constexpr bool kEnableAppImage = true; 51 52const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) { 53 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 54 DCHECK(oat_file != nullptr); 55 if (kIsDebugBuild) { 56 CHECK(oat_files_.find(oat_file) == oat_files_.end()); 57 for (const std::unique_ptr<const OatFile>& existing : oat_files_) { 58 CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation(); 59 // Check that we don't have an oat file with the same address. Copies of the same oat file 60 // should be loaded at different addresses. 61 CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location"; 62 } 63 } 64 have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic(); 65 const OatFile* ret = oat_file.get(); 66 oat_files_.insert(std::move(oat_file)); 67 return ret; 68} 69 70void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) { 71 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 72 DCHECK(oat_file != nullptr); 73 std::unique_ptr<const OatFile> compare(oat_file); 74 auto it = oat_files_.find(compare); 75 CHECK(it != oat_files_.end()); 76 oat_files_.erase(it); 77 compare.release(); 78} 79 80const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation( 81 const std::string& dex_base_location) const { 82 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 83 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 84 const std::vector<const OatDexFile*>& oat_dex_files = oat_file->GetOatDexFiles(); 85 for (const OatDexFile* oat_dex_file : oat_dex_files) { 86 if (DexFile::GetBaseLocation(oat_dex_file->GetDexFileLocation()) == dex_base_location) { 87 return oat_file.get(); 88 } 89 } 90 } 91 return nullptr; 92} 93 94const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location) 95 const { 96 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 97 return FindOpenedOatFileFromOatLocationLocked(oat_location); 98} 99 100const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked( 101 const std::string& oat_location) const { 102 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 103 if (oat_file->GetLocation() == oat_location) { 104 return oat_file.get(); 105 } 106 } 107 return nullptr; 108} 109 110std::vector<const OatFile*> OatFileManager::GetBootOatFiles() const { 111 std::vector<const OatFile*> oat_files; 112 std::vector<gc::space::ImageSpace*> image_spaces = 113 Runtime::Current()->GetHeap()->GetBootImageSpaces(); 114 for (gc::space::ImageSpace* image_space : image_spaces) { 115 oat_files.push_back(image_space->GetOatFile()); 116 } 117 return oat_files; 118} 119 120const OatFile* OatFileManager::GetPrimaryOatFile() const { 121 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 122 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles(); 123 if (!boot_oat_files.empty()) { 124 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 125 if (std::find(boot_oat_files.begin(), boot_oat_files.end(), oat_file.get()) == 126 boot_oat_files.end()) { 127 return oat_file.get(); 128 } 129 } 130 } 131 return nullptr; 132} 133 134OatFileManager::~OatFileManager() { 135 // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for 136 // UnRegisterOatFileLocation. 137 oat_files_.clear(); 138} 139 140std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles( 141 std::vector<gc::space::ImageSpace*> spaces) { 142 std::vector<const OatFile*> oat_files; 143 for (gc::space::ImageSpace* space : spaces) { 144 oat_files.push_back(RegisterOatFile(space->ReleaseOatFile())); 145 } 146 return oat_files; 147} 148 149class TypeIndexInfo { 150 public: 151 explicit TypeIndexInfo(const DexFile* dex_file) 152 : type_indexes_(GenerateTypeIndexes(dex_file)), 153 iter_(type_indexes_.Indexes().begin()), 154 end_(type_indexes_.Indexes().end()) { } 155 156 BitVector& GetTypeIndexes() { 157 return type_indexes_; 158 } 159 BitVector::IndexIterator& GetIterator() { 160 return iter_; 161 } 162 BitVector::IndexIterator& GetIteratorEnd() { 163 return end_; 164 } 165 void AdvanceIterator() { 166 iter_++; 167 } 168 169 private: 170 static BitVector GenerateTypeIndexes(const DexFile* dex_file) { 171 BitVector type_indexes(/*start_bits*/0, /*expandable*/true, Allocator::GetMallocAllocator()); 172 for (uint16_t i = 0; i < dex_file->NumClassDefs(); ++i) { 173 const DexFile::ClassDef& class_def = dex_file->GetClassDef(i); 174 uint16_t type_idx = class_def.class_idx_.index_; 175 type_indexes.SetBit(type_idx); 176 } 177 return type_indexes; 178 } 179 180 // BitVector with bits set for the type indexes of all classes in the input dex file. 181 BitVector type_indexes_; 182 BitVector::IndexIterator iter_; 183 BitVector::IndexIterator end_; 184}; 185 186class DexFileAndClassPair : ValueObject { 187 public: 188 DexFileAndClassPair(const DexFile* dex_file, TypeIndexInfo* type_info, bool from_loaded_oat) 189 : type_info_(type_info), 190 dex_file_(dex_file), 191 cached_descriptor_(dex_file_->StringByTypeIdx(dex::TypeIndex(*type_info->GetIterator()))), 192 from_loaded_oat_(from_loaded_oat) { 193 type_info_->AdvanceIterator(); 194 } 195 196 DexFileAndClassPair(const DexFileAndClassPair& rhs) = default; 197 198 DexFileAndClassPair& operator=(const DexFileAndClassPair& rhs) = default; 199 200 const char* GetCachedDescriptor() const { 201 return cached_descriptor_; 202 } 203 204 bool operator<(const DexFileAndClassPair& rhs) const { 205 const int cmp = strcmp(cached_descriptor_, rhs.cached_descriptor_); 206 if (cmp != 0) { 207 // Note that the order must be reversed. We want to iterate over the classes in dex files. 208 // They are sorted lexicographically. Thus, the priority-queue must be a min-queue. 209 return cmp > 0; 210 } 211 return dex_file_ < rhs.dex_file_; 212 } 213 214 bool DexFileHasMoreClasses() const { 215 return type_info_->GetIterator() != type_info_->GetIteratorEnd(); 216 } 217 218 void Next() { 219 cached_descriptor_ = dex_file_->StringByTypeIdx(dex::TypeIndex(*type_info_->GetIterator())); 220 type_info_->AdvanceIterator(); 221 } 222 223 bool FromLoadedOat() const { 224 return from_loaded_oat_; 225 } 226 227 const DexFile* GetDexFile() const { 228 return dex_file_; 229 } 230 231 private: 232 TypeIndexInfo* type_info_; 233 const DexFile* dex_file_; 234 const char* cached_descriptor_; 235 bool from_loaded_oat_; // We only need to compare mismatches between what we load now 236 // and what was loaded before. Any old duplicates must have been 237 // OK, and any new "internal" duplicates are as well (they must 238 // be from multidex, which resolves correctly). 239}; 240 241static void AddDexFilesFromOat( 242 const OatFile* oat_file, 243 /*out*/std::vector<const DexFile*>* dex_files, 244 std::vector<std::unique_ptr<const DexFile>>* opened_dex_files) { 245 for (const OatDexFile* oat_dex_file : oat_file->GetOatDexFiles()) { 246 std::string error; 247 std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error); 248 if (dex_file == nullptr) { 249 LOG(WARNING) << "Could not create dex file from oat file: " << error; 250 } else if (dex_file->NumClassDefs() > 0U) { 251 dex_files->push_back(dex_file.get()); 252 opened_dex_files->push_back(std::move(dex_file)); 253 } 254 } 255} 256 257static void AddNext(/*inout*/DexFileAndClassPair& original, 258 /*inout*/std::priority_queue<DexFileAndClassPair>& heap) { 259 if (original.DexFileHasMoreClasses()) { 260 original.Next(); 261 heap.push(std::move(original)); 262 } 263} 264 265template <typename T> 266static void IterateOverJavaDexFile(ObjPtr<mirror::Object> dex_file, 267 ArtField* const cookie_field, 268 const T& fn) 269 REQUIRES_SHARED(Locks::mutator_lock_) { 270 if (dex_file != nullptr) { 271 mirror::LongArray* long_array = cookie_field->GetObject(dex_file)->AsLongArray(); 272 if (long_array == nullptr) { 273 // This should never happen so log a warning. 274 LOG(WARNING) << "Null DexFile::mCookie"; 275 return; 276 } 277 int32_t long_array_size = long_array->GetLength(); 278 // Start from 1 to skip the oat file. 279 for (int32_t j = 1; j < long_array_size; ++j) { 280 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>( 281 long_array->GetWithoutChecks(j))); 282 if (!fn(cp_dex_file)) { 283 return; 284 } 285 } 286 } 287} 288 289template <typename T> 290static void IterateOverPathClassLoader( 291 Handle<mirror::ClassLoader> class_loader, 292 MutableHandle<mirror::ObjectArray<mirror::Object>> dex_elements, 293 const T& fn) REQUIRES_SHARED(Locks::mutator_lock_) { 294 // Handle this step. 295 // Handle as if this is the child PathClassLoader. 296 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader. 297 // We need to get the DexPathList and loop through it. 298 ArtField* const cookie_field = 299 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); 300 ArtField* const dex_file_field = 301 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); 302 ObjPtr<mirror::Object> dex_path_list = 303 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)-> 304 GetObject(class_loader.Get()); 305 if (dex_path_list != nullptr && dex_file_field != nullptr && cookie_field != nullptr) { 306 // DexPathList has an array dexElements of Elements[] which each contain a dex file. 307 ObjPtr<mirror::Object> dex_elements_obj = 308 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)-> 309 GetObject(dex_path_list); 310 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look 311 // at the mCookie which is a DexFile vector. 312 if (dex_elements_obj != nullptr) { 313 dex_elements.Assign(dex_elements_obj->AsObjectArray<mirror::Object>()); 314 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) { 315 mirror::Object* element = dex_elements->GetWithoutChecks(i); 316 if (element == nullptr) { 317 // Should never happen, fall back to java code to throw a NPE. 318 break; 319 } 320 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element); 321 IterateOverJavaDexFile(dex_file, cookie_field, fn); 322 } 323 } 324 } 325} 326 327static bool GetDexFilesFromClassLoader( 328 ScopedObjectAccessAlreadyRunnable& soa, 329 mirror::ClassLoader* class_loader, 330 std::vector<const DexFile*>* dex_files) 331 REQUIRES_SHARED(Locks::mutator_lock_) { 332 if (ClassLinker::IsBootClassLoader(soa, class_loader)) { 333 // The boot class loader. We don't load any of these files, as we know we compiled against 334 // them correctly. 335 return true; 336 } 337 338 // Unsupported class-loader? 339 if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader) != 340 class_loader->GetClass()) { 341 VLOG(class_linker) << "Unsupported class-loader " 342 << mirror::Class::PrettyClass(class_loader->GetClass()); 343 return false; 344 } 345 346 bool recursive_result = GetDexFilesFromClassLoader(soa, class_loader->GetParent(), dex_files); 347 if (!recursive_result) { 348 // Something wrong up the chain. 349 return false; 350 } 351 352 // Collect all the dex files. 353 auto GetDexFilesFn = [&] (const DexFile* cp_dex_file) 354 REQUIRES_SHARED(Locks::mutator_lock_) { 355 if (cp_dex_file->NumClassDefs() > 0) { 356 dex_files->push_back(cp_dex_file); 357 } 358 return true; // Continue looking. 359 }; 360 361 // Handle for dex-cache-element. 362 StackHandleScope<3> hs(soa.Self()); 363 MutableHandle<mirror::ObjectArray<mirror::Object>> dex_elements( 364 hs.NewHandle<mirror::ObjectArray<mirror::Object>>(nullptr)); 365 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader)); 366 367 IterateOverPathClassLoader(h_class_loader, dex_elements, GetDexFilesFn); 368 369 return true; 370} 371 372static void GetDexFilesFromDexElementsArray( 373 ScopedObjectAccessAlreadyRunnable& soa, 374 Handle<mirror::ObjectArray<mirror::Object>> dex_elements, 375 std::vector<const DexFile*>* dex_files) 376 REQUIRES_SHARED(Locks::mutator_lock_) { 377 if (dex_elements == nullptr) { 378 // Nothing to do. 379 return; 380 } 381 382 ArtField* const cookie_field = 383 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie); 384 ArtField* const dex_file_field = 385 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); 386 ObjPtr<mirror::Class> const element_class = soa.Decode<mirror::Class>( 387 WellKnownClasses::dalvik_system_DexPathList__Element); 388 ObjPtr<mirror::Class> const dexfile_class = soa.Decode<mirror::Class>( 389 WellKnownClasses::dalvik_system_DexFile); 390 391 // Collect all the dex files. 392 auto GetDexFilesFn = [&] (const DexFile* cp_dex_file) 393 REQUIRES_SHARED(Locks::mutator_lock_) { 394 if (cp_dex_file != nullptr && cp_dex_file->NumClassDefs() > 0) { 395 dex_files->push_back(cp_dex_file); 396 } 397 return true; // Continue looking. 398 }; 399 400 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) { 401 mirror::Object* element = dex_elements->GetWithoutChecks(i); 402 if (element == nullptr) { 403 continue; 404 } 405 406 // We support this being dalvik.system.DexPathList$Element and dalvik.system.DexFile. 407 408 ObjPtr<mirror::Object> dex_file; 409 if (element_class == element->GetClass()) { 410 dex_file = dex_file_field->GetObject(element); 411 } else if (dexfile_class == element->GetClass()) { 412 dex_file = element; 413 } else { 414 LOG(WARNING) << "Unsupported element in dex_elements: " 415 << mirror::Class::PrettyClass(element->GetClass()); 416 continue; 417 } 418 419 IterateOverJavaDexFile(dex_file, cookie_field, GetDexFilesFn); 420 } 421} 422 423static bool AreSharedLibrariesOk(const std::string& shared_libraries, 424 std::vector<const DexFile*>& dex_files) { 425 // If no shared libraries, we expect no dex files. 426 if (shared_libraries.empty()) { 427 return dex_files.empty(); 428 } 429 // If we find the special shared library, skip the shared libraries check. 430 if (shared_libraries.compare(OatFile::kSpecialSharedLibrary) == 0) { 431 return true; 432 } 433 // Shared libraries is a series of dex file paths and their checksums, each separated by '*'. 434 std::vector<std::string> shared_libraries_split; 435 Split(shared_libraries, '*', &shared_libraries_split); 436 437 // Sanity check size of dex files and split shared libraries. Should be 2x as many entries in 438 // the split shared libraries since it contains pairs of filename/checksum. 439 if (dex_files.size() * 2 != shared_libraries_split.size()) { 440 return false; 441 } 442 443 // Check that the loaded dex files have the same order and checksums as the shared libraries. 444 for (size_t i = 0; i < dex_files.size(); ++i) { 445 std::string absolute_library_path = 446 OatFile::ResolveRelativeEncodedDexLocation(dex_files[i]->GetLocation().c_str(), 447 shared_libraries_split[i * 2]); 448 if (dex_files[i]->GetLocation() != absolute_library_path) { 449 return false; 450 } 451 char* end; 452 size_t shared_lib_checksum = strtoul(shared_libraries_split[i * 2 + 1].c_str(), &end, 10); 453 uint32_t dex_checksum = dex_files[i]->GetLocationChecksum(); 454 if (*end != '\0' || dex_checksum != shared_lib_checksum) { 455 return false; 456 } 457 } 458 459 return true; 460} 461 462static bool CollisionCheck(std::vector<const DexFile*>& dex_files_loaded, 463 std::vector<const DexFile*>& dex_files_unloaded, 464 std::string* error_msg /*out*/) { 465 // Generate type index information for each dex file. 466 std::vector<TypeIndexInfo> loaded_types; 467 for (const DexFile* dex_file : dex_files_loaded) { 468 loaded_types.push_back(TypeIndexInfo(dex_file)); 469 } 470 std::vector<TypeIndexInfo> unloaded_types; 471 for (const DexFile* dex_file : dex_files_unloaded) { 472 unloaded_types.push_back(TypeIndexInfo(dex_file)); 473 } 474 475 // Populate the queue of dex file and class pairs with the loaded and unloaded dex files. 476 std::priority_queue<DexFileAndClassPair> queue; 477 for (size_t i = 0; i < dex_files_loaded.size(); ++i) { 478 if (loaded_types[i].GetIterator() != loaded_types[i].GetIteratorEnd()) { 479 queue.emplace(dex_files_loaded[i], &loaded_types[i], /*from_loaded_oat*/true); 480 } 481 } 482 for (size_t i = 0; i < dex_files_unloaded.size(); ++i) { 483 if (unloaded_types[i].GetIterator() != unloaded_types[i].GetIteratorEnd()) { 484 queue.emplace(dex_files_unloaded[i], &unloaded_types[i], /*from_loaded_oat*/false); 485 } 486 } 487 488 // Now drain the queue. 489 bool has_duplicates = false; 490 error_msg->clear(); 491 while (!queue.empty()) { 492 // Modifying the top element is only safe if we pop right after. 493 DexFileAndClassPair compare_pop(queue.top()); 494 queue.pop(); 495 496 // Compare against the following elements. 497 while (!queue.empty()) { 498 DexFileAndClassPair top(queue.top()); 499 if (strcmp(compare_pop.GetCachedDescriptor(), top.GetCachedDescriptor()) == 0) { 500 // Same descriptor. Check whether it's crossing old-oat-files to new-oat-files. 501 if (compare_pop.FromLoadedOat() != top.FromLoadedOat()) { 502 error_msg->append( 503 StringPrintf("Found duplicated class when checking oat files: '%s' in %s and %s\n", 504 compare_pop.GetCachedDescriptor(), 505 compare_pop.GetDexFile()->GetLocation().c_str(), 506 top.GetDexFile()->GetLocation().c_str())); 507 if (!VLOG_IS_ON(oat)) { 508 return true; 509 } 510 has_duplicates = true; 511 } 512 queue.pop(); 513 AddNext(top, queue); 514 } else { 515 // Something else. Done here. 516 break; 517 } 518 } 519 AddNext(compare_pop, queue); 520 } 521 522 return has_duplicates; 523} 524 525// Check for class-def collisions in dex files. 526// 527// This first walks the class loader chain, getting all the dex files from the class loader. If 528// the class loader is null or one of the class loaders in the chain is unsupported, we collect 529// dex files from all open non-boot oat files to be safe. 530// 531// This first checks whether the shared libraries are in the expected order and the oat files 532// have the expected checksums. If so, we exit early. Otherwise, we do the collision check. 533// 534// The collision check works by maintaining a heap with one class from each dex file, sorted by the 535// class descriptor. Then a dex-file/class pair is continually removed from the heap and compared 536// against the following top element. If the descriptor is the same, it is now checked whether 537// the two elements agree on whether their dex file was from an already-loaded oat-file or the 538// new oat file. Any disagreement indicates a collision. 539bool OatFileManager::HasCollisions(const OatFile* oat_file, 540 jobject class_loader, 541 jobjectArray dex_elements, 542 std::string* error_msg /*out*/) const { 543 DCHECK(oat_file != nullptr); 544 DCHECK(error_msg != nullptr); 545 546 std::vector<const DexFile*> dex_files_loaded; 547 548 // Try to get dex files from the given class loader. If the class loader is null, or we do 549 // not support one of the class loaders in the chain, we do nothing and assume the collision 550 // check has succeeded. 551 bool class_loader_ok = false; 552 { 553 ScopedObjectAccess soa(Thread::Current()); 554 StackHandleScope<2> hs(Thread::Current()); 555 Handle<mirror::ClassLoader> h_class_loader = 556 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)); 557 Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements = 558 hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements)); 559 if (h_class_loader != nullptr && 560 GetDexFilesFromClassLoader(soa, h_class_loader.Get(), &dex_files_loaded)) { 561 class_loader_ok = true; 562 563 // In this case, also take into account the dex_elements array, if given. We don't need to 564 // read it otherwise, as we'll compare against all open oat files anyways. 565 GetDexFilesFromDexElementsArray(soa, h_dex_elements, &dex_files_loaded); 566 } else if (h_class_loader != nullptr) { 567 VLOG(class_linker) << "Something unsupported with " 568 << mirror::Class::PrettyClass(h_class_loader->GetClass()); 569 570 // This is a class loader we don't recognize. Our earlier strategy would 571 // be to perform a global duplicate class check (with all loaded oat files) 572 // but that seems overly conservative - we have no way of knowing that 573 // those files are present in the same loader hierarchy. Among other 574 // things, it hurt GMS core and its filtering class loader. 575 } 576 } 577 578 // Exit if we find a class loader we don't recognize. Proceed to check shared 579 // libraries and do a full class loader check otherwise. 580 if (!class_loader_ok) { 581 LOG(WARNING) << "Skipping duplicate class check due to unrecognized classloader"; 582 return false; 583 } 584 585 // Exit if shared libraries are ok. Do a full duplicate classes check otherwise. 586 const std::string 587 shared_libraries(oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey)); 588 if (AreSharedLibrariesOk(shared_libraries, dex_files_loaded)) { 589 return false; 590 } 591 592 // Vector that holds the newly opened dex files live, this is done to prevent leaks. 593 std::vector<std::unique_ptr<const DexFile>> opened_dex_files; 594 595 ScopedTrace st("Collision check"); 596 // Add dex files from the oat file to check. 597 std::vector<const DexFile*> dex_files_unloaded; 598 AddDexFilesFromOat(oat_file, &dex_files_unloaded, &opened_dex_files); 599 return CollisionCheck(dex_files_loaded, dex_files_unloaded, error_msg); 600} 601 602std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( 603 const char* dex_location, 604 jobject class_loader, 605 jobjectArray dex_elements, 606 const OatFile** out_oat_file, 607 std::vector<std::string>* error_msgs) { 608 ScopedTrace trace(__FUNCTION__); 609 CHECK(dex_location != nullptr); 610 CHECK(error_msgs != nullptr); 611 612 // Verify we aren't holding the mutator lock, which could starve GC if we 613 // have to generate or relocate an oat file. 614 Thread* const self = Thread::Current(); 615 Locks::mutator_lock_->AssertNotHeld(self); 616 Runtime* const runtime = Runtime::Current(); 617 618 OatFileAssistant oat_file_assistant(dex_location, 619 kRuntimeISA, 620 !runtime->IsAotCompiler()); 621 622 // Lock the target oat location to avoid races generating and loading the 623 // oat file. 624 std::string error_msg; 625 if (!oat_file_assistant.Lock(/*out*/&error_msg)) { 626 // Don't worry too much if this fails. If it does fail, it's unlikely we 627 // can generate an oat file anyway. 628 VLOG(class_linker) << "OatFileAssistant::Lock: " << error_msg; 629 } 630 631 const OatFile* source_oat_file = nullptr; 632 633 if (!oat_file_assistant.IsUpToDate()) { 634 // Update the oat file on disk if we can, based on the --compiler-filter 635 // option derived from the current runtime options. 636 // This may fail, but that's okay. Best effort is all that matters here. 637 switch (oat_file_assistant.MakeUpToDate(/*profile_changed*/false, /*out*/ &error_msg)) { 638 case OatFileAssistant::kUpdateFailed: 639 LOG(WARNING) << error_msg; 640 break; 641 642 case OatFileAssistant::kUpdateNotAttempted: 643 // Avoid spamming the logs if we decided not to attempt making the oat 644 // file up to date. 645 VLOG(oat) << error_msg; 646 break; 647 648 case OatFileAssistant::kUpdateSucceeded: 649 // Nothing to do. 650 break; 651 } 652 } 653 654 // Get the oat file on disk. 655 std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release()); 656 657 if (oat_file != nullptr) { 658 // Take the file only if it has no collisions, or we must take it because of preopting. 659 bool accept_oat_file = 660 !HasCollisions(oat_file.get(), class_loader, dex_elements, /*out*/ &error_msg); 661 if (!accept_oat_file) { 662 // Failed the collision check. Print warning. 663 if (Runtime::Current()->IsDexFileFallbackEnabled()) { 664 if (!oat_file_assistant.HasOriginalDexFiles()) { 665 // We need to fallback but don't have original dex files. We have to 666 // fallback to opening the existing oat file. This is potentially 667 // unsafe so we warn about it. 668 accept_oat_file = true; 669 670 LOG(WARNING) << "Dex location " << dex_location << " does not seem to include dex file. " 671 << "Allow oat file use. This is potentially dangerous."; 672 } else { 673 // We have to fallback and found original dex files - extract them from an APK. 674 // Also warn about this operation because it's potentially wasteful. 675 LOG(WARNING) << "Found duplicate classes, falling back to extracting from APK : " 676 << dex_location; 677 LOG(WARNING) << "NOTE: This wastes RAM and hurts startup performance."; 678 } 679 } else { 680 // TODO: We should remove this. The fact that we're here implies -Xno-dex-file-fallback 681 // was set, which means that we should never fallback. If we don't have original dex 682 // files, we should just fail resolution as the flag intended. 683 if (!oat_file_assistant.HasOriginalDexFiles()) { 684 accept_oat_file = true; 685 } 686 687 LOG(WARNING) << "Found duplicate classes, dex-file-fallback disabled, will be failing to " 688 " load classes for " << dex_location; 689 } 690 691 LOG(WARNING) << error_msg; 692 } 693 694 if (accept_oat_file) { 695 VLOG(class_linker) << "Registering " << oat_file->GetLocation(); 696 source_oat_file = RegisterOatFile(std::move(oat_file)); 697 *out_oat_file = source_oat_file; 698 } 699 } 700 701 std::vector<std::unique_ptr<const DexFile>> dex_files; 702 703 // Load the dex files from the oat file. 704 if (source_oat_file != nullptr) { 705 bool added_image_space = false; 706 if (source_oat_file->IsExecutable()) { 707 std::unique_ptr<gc::space::ImageSpace> image_space = 708 kEnableAppImage ? oat_file_assistant.OpenImageSpace(source_oat_file) : nullptr; 709 if (image_space != nullptr) { 710 ScopedObjectAccess soa(self); 711 StackHandleScope<1> hs(self); 712 Handle<mirror::ClassLoader> h_loader( 713 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 714 // Can not load app image without class loader. 715 if (h_loader != nullptr) { 716 std::string temp_error_msg; 717 // Add image space has a race condition since other threads could be reading from the 718 // spaces array. 719 { 720 ScopedThreadSuspension sts(self, kSuspended); 721 gc::ScopedGCCriticalSection gcs(self, 722 gc::kGcCauseAddRemoveAppImageSpace, 723 gc::kCollectorTypeAddRemoveAppImageSpace); 724 ScopedSuspendAll ssa("Add image space"); 725 runtime->GetHeap()->AddSpace(image_space.get()); 726 } 727 { 728 ScopedTrace trace2(StringPrintf("Adding image space for location %s", dex_location)); 729 added_image_space = runtime->GetClassLinker()->AddImageSpace(image_space.get(), 730 h_loader, 731 dex_elements, 732 dex_location, 733 /*out*/&dex_files, 734 /*out*/&temp_error_msg); 735 } 736 if (added_image_space) { 737 // Successfully added image space to heap, release the map so that it does not get 738 // freed. 739 image_space.release(); 740 } else { 741 LOG(INFO) << "Failed to add image file " << temp_error_msg; 742 dex_files.clear(); 743 { 744 ScopedThreadSuspension sts(self, kSuspended); 745 gc::ScopedGCCriticalSection gcs(self, 746 gc::kGcCauseAddRemoveAppImageSpace, 747 gc::kCollectorTypeAddRemoveAppImageSpace); 748 ScopedSuspendAll ssa("Remove image space"); 749 runtime->GetHeap()->RemoveSpace(image_space.get()); 750 } 751 // Non-fatal, don't update error_msg. 752 } 753 } 754 } 755 } 756 if (!added_image_space) { 757 DCHECK(dex_files.empty()); 758 dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location); 759 } 760 if (dex_files.empty()) { 761 error_msgs->push_back("Failed to open dex files from " + source_oat_file->GetLocation()); 762 } 763 } 764 765 // Fall back to running out of the original dex file if we couldn't load any 766 // dex_files from the oat file. 767 if (dex_files.empty()) { 768 if (oat_file_assistant.HasOriginalDexFiles()) { 769 if (Runtime::Current()->IsDexFileFallbackEnabled()) { 770 static constexpr bool kVerifyChecksum = true; 771 if (!DexFile::Open( 772 dex_location, dex_location, kVerifyChecksum, /*out*/ &error_msg, &dex_files)) { 773 LOG(WARNING) << error_msg; 774 error_msgs->push_back("Failed to open dex files from " + std::string(dex_location) 775 + " because: " + error_msg); 776 } 777 } else { 778 error_msgs->push_back("Fallback mode disabled, skipping dex files."); 779 } 780 } else { 781 error_msgs->push_back("No original dex files found for dex location " 782 + std::string(dex_location)); 783 } 784 } 785 786 return dex_files; 787} 788 789void OatFileManager::DumpForSigQuit(std::ostream& os) { 790 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 791 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles(); 792 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 793 if (ContainsElement(boot_oat_files, oat_file.get())) { 794 continue; 795 } 796 os << oat_file->GetLocation() << ": " << oat_file->GetCompilerFilter() << "\n"; 797 } 798} 799 800} // namespace art 801