Home | History | Annotate | Download | only in runtime
      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 
     45 namespace art {
     46 
     47 using android::base::StringPrintf;
     48 
     49 // If true, then we attempt to load the application image if it exists.
     50 static constexpr bool kEnableAppImage = true;
     51 
     52 const 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 
     70 void 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 
     80 const 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 
     94 const 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 
    100 const 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 
    110 std::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 
    120 const 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 
    134 OatFileManager::~OatFileManager() {
    135   // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
    136   // UnRegisterOatFileLocation.
    137   oat_files_.clear();
    138 }
    139 
    140 std::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 
    149 class 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 
    186 class 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 
    241 static 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 
    257 static 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 
    265 template <typename T>
    266 static 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 
    289 template <typename T>
    290 static 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 
    327 static 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 
    372 static 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 
    423 static 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 
    462 static 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.
    539 bool 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 
    602 std::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 
    789 void 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