Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2017 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 "class_loader_context.h"
     18 
     19 #include <android-base/parseint.h>
     20 #include <android-base/strings.h>
     21 
     22 #include "art_field-inl.h"
     23 #include "base/casts.h"
     24 #include "base/dchecked_vector.h"
     25 #include "base/stl_util.h"
     26 #include "class_linker.h"
     27 #include "class_loader_utils.h"
     28 #include "class_root.h"
     29 #include "dex/art_dex_file_loader.h"
     30 #include "dex/dex_file.h"
     31 #include "dex/dex_file_loader.h"
     32 #include "handle_scope-inl.h"
     33 #include "jni/jni_internal.h"
     34 #include "mirror/class_loader-inl.h"
     35 #include "mirror/object_array-alloc-inl.h"
     36 #include "nativehelper/scoped_local_ref.h"
     37 #include "oat_file_assistant.h"
     38 #include "obj_ptr-inl.h"
     39 #include "runtime.h"
     40 #include "scoped_thread_state_change-inl.h"
     41 #include "thread.h"
     42 #include "well_known_classes.h"
     43 
     44 namespace art {
     45 
     46 static constexpr char kPathClassLoaderString[] = "PCL";
     47 static constexpr char kDelegateLastClassLoaderString[] = "DLC";
     48 static constexpr char kInMemoryDexClassLoaderString[] = "IMC";
     49 static constexpr char kClassLoaderOpeningMark = '[';
     50 static constexpr char kClassLoaderClosingMark = ']';
     51 static constexpr char kClassLoaderSharedLibraryOpeningMark = '{';
     52 static constexpr char kClassLoaderSharedLibraryClosingMark = '}';
     53 static constexpr char kClassLoaderSharedLibrarySeparator = '#';
     54 static constexpr char kClassLoaderSeparator = ';';
     55 static constexpr char kClasspathSeparator = ':';
     56 static constexpr char kDexFileChecksumSeparator = '*';
     57 static constexpr char kInMemoryDexClassLoaderDexLocationMagic[] = "<unknown>";
     58 
     59 ClassLoaderContext::ClassLoaderContext()
     60     : special_shared_library_(false),
     61       dex_files_open_attempted_(false),
     62       dex_files_open_result_(false),
     63       owns_the_dex_files_(true) {}
     64 
     65 ClassLoaderContext::ClassLoaderContext(bool owns_the_dex_files)
     66     : special_shared_library_(false),
     67       dex_files_open_attempted_(true),
     68       dex_files_open_result_(true),
     69       owns_the_dex_files_(owns_the_dex_files) {}
     70 
     71 // Utility method to add parent and shared libraries of `info` into
     72 // the `work_list`.
     73 static void AddToWorkList(
     74     ClassLoaderContext::ClassLoaderInfo* info,
     75     std::vector<ClassLoaderContext::ClassLoaderInfo*>& work_list) {
     76   if (info->parent != nullptr) {
     77     work_list.push_back(info->parent.get());
     78   }
     79   for (size_t i = 0; i < info->shared_libraries.size(); ++i) {
     80     work_list.push_back(info->shared_libraries[i].get());
     81   }
     82 }
     83 
     84 ClassLoaderContext::~ClassLoaderContext() {
     85   if (!owns_the_dex_files_ && class_loader_chain_ != nullptr) {
     86     // If the context does not own the dex/oat files release the unique pointers to
     87     // make sure we do not de-allocate them.
     88     std::vector<ClassLoaderInfo*> work_list;
     89     work_list.push_back(class_loader_chain_.get());
     90     while (!work_list.empty()) {
     91       ClassLoaderInfo* info = work_list.back();
     92       work_list.pop_back();
     93       for (std::unique_ptr<OatFile>& oat_file : info->opened_oat_files) {
     94         oat_file.release();  // NOLINT b/117926937
     95       }
     96       for (std::unique_ptr<const DexFile>& dex_file : info->opened_dex_files) {
     97         dex_file.release();  // NOLINT b/117926937
     98       }
     99       AddToWorkList(info, work_list);
    100     }
    101   }
    102 }
    103 
    104 std::unique_ptr<ClassLoaderContext> ClassLoaderContext::Default() {
    105   return Create("");
    106 }
    107 
    108 std::unique_ptr<ClassLoaderContext> ClassLoaderContext::Create(const std::string& spec) {
    109   std::unique_ptr<ClassLoaderContext> result(new ClassLoaderContext());
    110   if (result->Parse(spec)) {
    111     return result;
    112   } else {
    113     return nullptr;
    114   }
    115 }
    116 
    117 static size_t FindMatchingSharedLibraryCloseMarker(const std::string& spec,
    118                                                    size_t shared_library_open_index) {
    119   // Counter of opened shared library marker we've encountered so far.
    120   uint32_t counter = 1;
    121   // The index at which we're operating in the loop.
    122   uint32_t string_index = shared_library_open_index + 1;
    123   size_t shared_library_close = std::string::npos;
    124   while (counter != 0) {
    125     shared_library_close =
    126         spec.find_first_of(kClassLoaderSharedLibraryClosingMark, string_index);
    127     size_t shared_library_open =
    128         spec.find_first_of(kClassLoaderSharedLibraryOpeningMark, string_index);
    129     if (shared_library_close == std::string::npos) {
    130       // No matching closing marker. Return an error.
    131       break;
    132     }
    133 
    134     if ((shared_library_open == std::string::npos) ||
    135         (shared_library_close < shared_library_open)) {
    136       // We have seen a closing marker. Decrement the counter.
    137       --counter;
    138       // Move the search index forward.
    139       string_index = shared_library_close + 1;
    140     } else {
    141       // New nested opening marker. Increment the counter and move the search
    142       // index after the marker.
    143       ++counter;
    144       string_index = shared_library_open + 1;
    145     }
    146   }
    147   return shared_library_close;
    148 }
    149 
    150 // The expected format is:
    151 // "ClassLoaderType1[ClasspathElem1*Checksum1:ClasspathElem2*Checksum2...]{ClassLoaderType2[...]}".
    152 // The checksum part of the format is expected only if parse_cheksums is true.
    153 std::unique_ptr<ClassLoaderContext::ClassLoaderInfo> ClassLoaderContext::ParseClassLoaderSpec(
    154     const std::string& class_loader_spec,
    155     bool parse_checksums) {
    156   ClassLoaderType class_loader_type = ExtractClassLoaderType(class_loader_spec);
    157   if (class_loader_type == kInvalidClassLoader) {
    158     return nullptr;
    159   }
    160 
    161   // InMemoryDexClassLoader's dex location is always bogus. Special-case it.
    162   if (class_loader_type == kInMemoryDexClassLoader) {
    163     if (parse_checksums) {
    164       // Make sure that OpenDexFiles() will never be attempted on this context
    165       // because the dex locations of IMC do not correspond to real files.
    166       CHECK(!dex_files_open_attempted_ || !dex_files_open_result_)
    167           << "Parsing spec not supported when context created from a ClassLoader object";
    168       dex_files_open_attempted_ = true;
    169       dex_files_open_result_ = false;
    170     } else {
    171       // Checksums are not provided and dex locations themselves have no meaning
    172       // (although we keep them in the spec to simplify parsing). Treat this as
    173       // an unknown class loader.
    174       // We can hit this case if dex2oat is invoked with a spec containing IMC.
    175       // Because the dex file data is only available at runtime, we cannot proceed.
    176       return nullptr;
    177     }
    178   }
    179 
    180   const char* class_loader_type_str = GetClassLoaderTypeName(class_loader_type);
    181   size_t type_str_size = strlen(class_loader_type_str);
    182 
    183   CHECK_EQ(0, class_loader_spec.compare(0, type_str_size, class_loader_type_str));
    184 
    185   // Check the opening and closing markers.
    186   if (class_loader_spec[type_str_size] != kClassLoaderOpeningMark) {
    187     return nullptr;
    188   }
    189   if ((class_loader_spec[class_loader_spec.length() - 1] != kClassLoaderClosingMark) &&
    190       (class_loader_spec[class_loader_spec.length() - 1] != kClassLoaderSharedLibraryClosingMark)) {
    191     return nullptr;
    192   }
    193 
    194   size_t closing_index = class_loader_spec.find_first_of(kClassLoaderClosingMark);
    195 
    196   // At this point we know the format is ok; continue and extract the classpath.
    197   // Note that class loaders with an empty class path are allowed.
    198   std::string classpath = class_loader_spec.substr(type_str_size + 1,
    199                                                    closing_index - type_str_size - 1);
    200 
    201   std::unique_ptr<ClassLoaderInfo> info(new ClassLoaderInfo(class_loader_type));
    202 
    203   if (!parse_checksums) {
    204     DCHECK(class_loader_type != kInMemoryDexClassLoader);
    205     Split(classpath, kClasspathSeparator, &info->classpath);
    206   } else {
    207     std::vector<std::string> classpath_elements;
    208     Split(classpath, kClasspathSeparator, &classpath_elements);
    209     for (const std::string& element : classpath_elements) {
    210       std::vector<std::string> dex_file_with_checksum;
    211       Split(element, kDexFileChecksumSeparator, &dex_file_with_checksum);
    212       if (dex_file_with_checksum.size() != 2) {
    213         return nullptr;
    214       }
    215       uint32_t checksum = 0;
    216       if (!android::base::ParseUint(dex_file_with_checksum[1].c_str(), &checksum)) {
    217         return nullptr;
    218       }
    219       if ((class_loader_type == kInMemoryDexClassLoader) &&
    220           (dex_file_with_checksum[0] != kInMemoryDexClassLoaderDexLocationMagic)) {
    221         return nullptr;
    222       }
    223 
    224       info->classpath.push_back(dex_file_with_checksum[0]);
    225       info->checksums.push_back(checksum);
    226     }
    227   }
    228 
    229   if ((class_loader_spec[class_loader_spec.length() - 1] == kClassLoaderSharedLibraryClosingMark) &&
    230       (class_loader_spec[class_loader_spec.length() - 2] != kClassLoaderSharedLibraryOpeningMark)) {
    231     // Non-empty list of shared libraries.
    232     size_t start_index = class_loader_spec.find_first_of(kClassLoaderSharedLibraryOpeningMark);
    233     if (start_index == std::string::npos) {
    234       return nullptr;
    235     }
    236     std::string shared_libraries_spec =
    237         class_loader_spec.substr(start_index + 1, class_loader_spec.length() - start_index - 2);
    238     std::vector<std::string> shared_libraries;
    239     size_t cursor = 0;
    240     while (cursor != shared_libraries_spec.length()) {
    241       size_t shared_library_separator =
    242           shared_libraries_spec.find_first_of(kClassLoaderSharedLibrarySeparator, cursor);
    243       size_t shared_library_open =
    244           shared_libraries_spec.find_first_of(kClassLoaderSharedLibraryOpeningMark, cursor);
    245       std::string shared_library_spec;
    246       if (shared_library_separator == std::string::npos) {
    247         // Only one shared library, for example:
    248         // PCL[...]
    249         shared_library_spec =
    250             shared_libraries_spec.substr(cursor, shared_libraries_spec.length() - cursor);
    251         cursor = shared_libraries_spec.length();
    252       } else if ((shared_library_open == std::string::npos) ||
    253                  (shared_library_open > shared_library_separator)) {
    254         // We found a shared library without nested shared libraries, for example:
    255         // PCL[...]#PCL[...]{...}
    256         shared_library_spec =
    257             shared_libraries_spec.substr(cursor, shared_library_separator - cursor);
    258         cursor = shared_library_separator + 1;
    259       } else {
    260         // The shared library contains nested shared libraries. Find the matching closing shared
    261         // marker for it.
    262         size_t closing_marker =
    263             FindMatchingSharedLibraryCloseMarker(shared_libraries_spec, shared_library_open);
    264         if (closing_marker == std::string::npos) {
    265           // No matching closing marker, return an error.
    266           return nullptr;
    267         }
    268         shared_library_spec = shared_libraries_spec.substr(cursor, closing_marker + 1 - cursor);
    269         cursor = closing_marker + 1;
    270         if (cursor != shared_libraries_spec.length() &&
    271             shared_libraries_spec[cursor] == kClassLoaderSharedLibrarySeparator) {
    272           // Pass the shared library separator marker.
    273           ++cursor;
    274         }
    275       }
    276       std::unique_ptr<ClassLoaderInfo> shared_library(
    277           ParseInternal(shared_library_spec, parse_checksums));
    278       if (shared_library == nullptr) {
    279         return nullptr;
    280       }
    281       info->shared_libraries.push_back(std::move(shared_library));
    282     }
    283   }
    284 
    285   return info;
    286 }
    287 
    288 // Extracts the class loader type from the given spec.
    289 // Return ClassLoaderContext::kInvalidClassLoader if the class loader type is not
    290 // recognized.
    291 ClassLoaderContext::ClassLoaderType
    292 ClassLoaderContext::ExtractClassLoaderType(const std::string& class_loader_spec) {
    293   const ClassLoaderType kValidTypes[] = { kPathClassLoader,
    294                                           kDelegateLastClassLoader,
    295                                           kInMemoryDexClassLoader };
    296   for (const ClassLoaderType& type : kValidTypes) {
    297     const char* type_str = GetClassLoaderTypeName(type);
    298     if (class_loader_spec.compare(0, strlen(type_str), type_str) == 0) {
    299       return type;
    300     }
    301   }
    302   return kInvalidClassLoader;
    303 }
    304 
    305 // The format: ClassLoaderType1[ClasspathElem1:ClasspathElem2...];ClassLoaderType2[...]...
    306 // ClassLoaderType is either "PCL" (PathClassLoader) or "DLC" (DelegateLastClassLoader).
    307 // ClasspathElem is the path of dex/jar/apk file.
    308 bool ClassLoaderContext::Parse(const std::string& spec, bool parse_checksums) {
    309   if (spec.empty()) {
    310     // By default we load the dex files in a PathClassLoader.
    311     // So an empty spec is equivalent to an empty PathClassLoader (this happens when running
    312     // tests)
    313     class_loader_chain_.reset(new ClassLoaderInfo(kPathClassLoader));
    314     return true;
    315   }
    316 
    317   // Stop early if we detect the special shared library, which may be passed as the classpath
    318   // for dex2oat when we want to skip the shared libraries check.
    319   if (spec == OatFile::kSpecialSharedLibrary) {
    320     LOG(INFO) << "The ClassLoaderContext is a special shared library.";
    321     special_shared_library_ = true;
    322     return true;
    323   }
    324 
    325   CHECK(class_loader_chain_ == nullptr);
    326   class_loader_chain_.reset(ParseInternal(spec, parse_checksums));
    327   return class_loader_chain_ != nullptr;
    328 }
    329 
    330 ClassLoaderContext::ClassLoaderInfo* ClassLoaderContext::ParseInternal(
    331     const std::string& spec, bool parse_checksums) {
    332   CHECK(!spec.empty());
    333   CHECK_NE(spec, OatFile::kSpecialSharedLibrary);
    334   std::string remaining = spec;
    335   std::unique_ptr<ClassLoaderInfo> first(nullptr);
    336   ClassLoaderInfo* previous_iteration = nullptr;
    337   while (!remaining.empty()) {
    338     std::string class_loader_spec;
    339     size_t first_class_loader_separator = remaining.find_first_of(kClassLoaderSeparator);
    340     size_t first_shared_library_open =
    341         remaining.find_first_of(kClassLoaderSharedLibraryOpeningMark);
    342     if (first_class_loader_separator == std::string::npos) {
    343       // Only one class loader, for example:
    344       // PCL[...]
    345       class_loader_spec = remaining;
    346       remaining = "";
    347     } else if ((first_shared_library_open == std::string::npos) ||
    348                (first_shared_library_open > first_class_loader_separator)) {
    349       // We found a class loader spec without shared libraries, for example:
    350       // PCL[...];PCL[...]{...}
    351       class_loader_spec = remaining.substr(0, first_class_loader_separator);
    352       remaining = remaining.substr(first_class_loader_separator + 1,
    353                                    remaining.size() - first_class_loader_separator - 1);
    354     } else {
    355       // The class loader spec contains shared libraries. Find the matching closing
    356       // shared library marker for it.
    357 
    358       uint32_t shared_library_close =
    359           FindMatchingSharedLibraryCloseMarker(remaining, first_shared_library_open);
    360       if (shared_library_close == std::string::npos) {
    361         LOG(ERROR) << "Invalid class loader spec: " << class_loader_spec;
    362         return nullptr;
    363       }
    364       class_loader_spec = remaining.substr(0, shared_library_close + 1);
    365 
    366       // Compute the remaining string to analyze.
    367       if (remaining.size() == shared_library_close + 1) {
    368         remaining = "";
    369       } else if ((remaining.size() == shared_library_close + 2) ||
    370                  (remaining.at(shared_library_close + 1) != kClassLoaderSeparator)) {
    371         LOG(ERROR) << "Invalid class loader spec: " << class_loader_spec;
    372         return nullptr;
    373       } else {
    374         remaining = remaining.substr(shared_library_close + 2,
    375                                      remaining.size() - shared_library_close - 2);
    376       }
    377     }
    378 
    379     std::unique_ptr<ClassLoaderInfo> info =
    380         ParseClassLoaderSpec(class_loader_spec, parse_checksums);
    381     if (info == nullptr) {
    382       LOG(ERROR) << "Invalid class loader spec: " << class_loader_spec;
    383       return nullptr;
    384     }
    385     if (first == nullptr) {
    386       first = std::move(info);
    387       previous_iteration = first.get();
    388     } else {
    389       CHECK(previous_iteration != nullptr);
    390       previous_iteration->parent = std::move(info);
    391       previous_iteration = previous_iteration->parent.get();
    392     }
    393   }
    394   return first.release();
    395 }
    396 
    397 // Opens requested class path files and appends them to opened_dex_files. If the dex files have
    398 // been stripped, this opens them from their oat files (which get added to opened_oat_files).
    399 bool ClassLoaderContext::OpenDexFiles(InstructionSet isa,
    400                                       const std::string& classpath_dir,
    401                                       const std::vector<int>& fds) {
    402   if (dex_files_open_attempted_) {
    403     // Do not attempt to re-open the files if we already tried.
    404     return dex_files_open_result_;
    405   }
    406 
    407   dex_files_open_attempted_ = true;
    408   // Assume we can open all dex files. If not, we will set this to false as we go.
    409   dex_files_open_result_ = true;
    410 
    411   if (special_shared_library_) {
    412     // Nothing to open if the context is a special shared library.
    413     return true;
    414   }
    415 
    416   // Note that we try to open all dex files even if some fail.
    417   // We may get resource-only apks which we cannot load.
    418   // TODO(calin): Refine the dex opening interface to be able to tell if an archive contains
    419   // no dex files. So that we can distinguish the real failures...
    420   const ArtDexFileLoader dex_file_loader;
    421   std::vector<ClassLoaderInfo*> work_list;
    422   CHECK(class_loader_chain_ != nullptr);
    423   work_list.push_back(class_loader_chain_.get());
    424   size_t dex_file_index = 0;
    425   while (!work_list.empty()) {
    426     ClassLoaderInfo* info = work_list.back();
    427     work_list.pop_back();
    428     DCHECK(info->type != kInMemoryDexClassLoader) << __FUNCTION__ << " not supported for IMC";
    429 
    430     size_t opened_dex_files_index = info->opened_dex_files.size();
    431     for (const std::string& cp_elem : info->classpath) {
    432       // If path is relative, append it to the provided base directory.
    433       std::string location = cp_elem;
    434       if (location[0] != '/' && !classpath_dir.empty()) {
    435         location = classpath_dir + (classpath_dir.back() == '/' ? "" : "/") + location;
    436       }
    437 
    438       // If file descriptors were provided for the class loader context dex paths,
    439       // get the descriptor which correponds to this dex path. We assume the `fds`
    440       // vector follows the same order as a flattened class loader context.
    441       int fd = -1;
    442       if (!fds.empty()) {
    443         if (dex_file_index >= fds.size()) {
    444           LOG(WARNING) << "Number of FDs is smaller than number of dex files in the context";
    445           dex_files_open_result_ = false;
    446           return false;
    447         }
    448 
    449         fd = fds[dex_file_index++];
    450         DCHECK_GE(fd, 0);
    451       }
    452 
    453       std::string error_msg;
    454       // When opening the dex files from the context we expect their checksum to match their
    455       // contents. So pass true to verify_checksum.
    456       if (fd < 0) {
    457         if (!dex_file_loader.Open(location.c_str(),
    458                                   location.c_str(),
    459                                   Runtime::Current()->IsVerificationEnabled(),
    460                                   /*verify_checksum=*/ true,
    461                                   &error_msg,
    462                                   &info->opened_dex_files)) {
    463           // If we fail to open the dex file because it's been stripped, try to
    464           // open the dex file from its corresponding oat file.
    465           // This could happen when we need to recompile a pre-build whose dex
    466           // code has been stripped (for example, if the pre-build is only
    467           // quicken and we want to re-compile it speed-profile).
    468           // TODO(calin): Use the vdex directly instead of going through the oat file.
    469           OatFileAssistant oat_file_assistant(location.c_str(), isa, false);
    470           std::unique_ptr<OatFile> oat_file(oat_file_assistant.GetBestOatFile());
    471           std::vector<std::unique_ptr<const DexFile>> oat_dex_files;
    472           if (oat_file != nullptr &&
    473               OatFileAssistant::LoadDexFiles(*oat_file, location, &oat_dex_files)) {
    474             info->opened_oat_files.push_back(std::move(oat_file));
    475             info->opened_dex_files.insert(info->opened_dex_files.end(),
    476                                           std::make_move_iterator(oat_dex_files.begin()),
    477                                           std::make_move_iterator(oat_dex_files.end()));
    478           } else {
    479             LOG(WARNING) << "Could not open dex files from location: " << location;
    480             dex_files_open_result_ = false;
    481           }
    482         }
    483       } else if (!dex_file_loader.Open(fd,
    484                                        location.c_str(),
    485                                        Runtime::Current()->IsVerificationEnabled(),
    486                                        /*verify_checksum=*/ true,
    487                                        &error_msg,
    488                                        &info->opened_dex_files)) {
    489         LOG(WARNING) << "Could not open dex files from fd " << fd << " for location: " << location;
    490         dex_files_open_result_ = false;
    491       }
    492     }
    493 
    494     // We finished opening the dex files from the classpath.
    495     // Now update the classpath and the checksum with the locations of the dex files.
    496     //
    497     // We do this because initially the classpath contains the paths of the dex files; and
    498     // some of them might be multi-dexes. So in order to have a consistent view we replace all the
    499     // file paths with the actual dex locations being loaded.
    500     // This will allow the context to VerifyClassLoaderContextMatch which expects or multidex
    501     // location in the class paths.
    502     // Note that this will also remove the paths that could not be opened.
    503     info->original_classpath = std::move(info->classpath);
    504     info->classpath.clear();
    505     info->checksums.clear();
    506     for (size_t k = opened_dex_files_index; k < info->opened_dex_files.size(); k++) {
    507       std::unique_ptr<const DexFile>& dex = info->opened_dex_files[k];
    508       info->classpath.push_back(dex->GetLocation());
    509       info->checksums.push_back(dex->GetLocationChecksum());
    510     }
    511     AddToWorkList(info, work_list);
    512   }
    513 
    514   // Check that if file descriptors were provided, there were exactly as many
    515   // as we have encountered while iterating over this class loader context.
    516   if (dex_file_index != fds.size()) {
    517     LOG(WARNING) << fds.size() << " FDs provided but only " << dex_file_index
    518         << " dex files are in the class loader context";
    519     dex_files_open_result_ = false;
    520   }
    521 
    522   return dex_files_open_result_;
    523 }
    524 
    525 bool ClassLoaderContext::RemoveLocationsFromClassPaths(
    526     const dchecked_vector<std::string>& locations) {
    527   CHECK(!dex_files_open_attempted_)
    528       << "RemoveLocationsFromClasspaths cannot be call after OpenDexFiles";
    529 
    530   if (class_loader_chain_ == nullptr) {
    531     return false;
    532   }
    533 
    534   std::set<std::string> canonical_locations;
    535   for (const std::string& location : locations) {
    536     canonical_locations.insert(DexFileLoader::GetDexCanonicalLocation(location.c_str()));
    537   }
    538   bool removed_locations = false;
    539   std::vector<ClassLoaderInfo*> work_list;
    540   work_list.push_back(class_loader_chain_.get());
    541   while (!work_list.empty()) {
    542     ClassLoaderInfo* info = work_list.back();
    543     work_list.pop_back();
    544     size_t initial_size = info->classpath.size();
    545     auto kept_it = std::remove_if(
    546         info->classpath.begin(),
    547         info->classpath.end(),
    548         [canonical_locations](const std::string& location) {
    549             return ContainsElement(canonical_locations,
    550                                    DexFileLoader::GetDexCanonicalLocation(location.c_str()));
    551         });
    552     info->classpath.erase(kept_it, info->classpath.end());
    553     if (initial_size != info->classpath.size()) {
    554       removed_locations = true;
    555     }
    556     AddToWorkList(info, work_list);
    557   }
    558   return removed_locations;
    559 }
    560 
    561 std::string ClassLoaderContext::EncodeContextForDex2oat(const std::string& base_dir) const {
    562   return EncodeContext(base_dir, /*for_dex2oat=*/ true, /*stored_context=*/ nullptr);
    563 }
    564 
    565 std::string ClassLoaderContext::EncodeContextForOatFile(const std::string& base_dir,
    566                                                         ClassLoaderContext* stored_context) const {
    567   return EncodeContext(base_dir, /*for_dex2oat=*/ false, stored_context);
    568 }
    569 
    570 std::string ClassLoaderContext::EncodeContext(const std::string& base_dir,
    571                                               bool for_dex2oat,
    572                                               ClassLoaderContext* stored_context) const {
    573   CheckDexFilesOpened("EncodeContextForOatFile");
    574   if (special_shared_library_) {
    575     return OatFile::kSpecialSharedLibrary;
    576   }
    577 
    578   if (stored_context != nullptr) {
    579     DCHECK_EQ(GetParentChainSize(), stored_context->GetParentChainSize());
    580   }
    581 
    582   std::ostringstream out;
    583   if (class_loader_chain_ == nullptr) {
    584     // We can get in this situation if the context was created with a class path containing the
    585     // source dex files which were later removed (happens during run-tests).
    586     out << GetClassLoaderTypeName(kPathClassLoader)
    587         << kClassLoaderOpeningMark
    588         << kClassLoaderClosingMark;
    589     return out.str();
    590   }
    591 
    592   EncodeContextInternal(
    593       *class_loader_chain_,
    594       base_dir,
    595       for_dex2oat,
    596       (stored_context == nullptr ? nullptr : stored_context->class_loader_chain_.get()),
    597       out);
    598   return out.str();
    599 }
    600 
    601 void ClassLoaderContext::EncodeContextInternal(const ClassLoaderInfo& info,
    602                                                const std::string& base_dir,
    603                                                bool for_dex2oat,
    604                                                ClassLoaderInfo* stored_info,
    605                                                std::ostringstream& out) const {
    606   out << GetClassLoaderTypeName(info.type);
    607   out << kClassLoaderOpeningMark;
    608   std::set<std::string> seen_locations;
    609   SafeMap<std::string, std::string> remap;
    610   if (stored_info != nullptr) {
    611     for (size_t k = 0; k < info.original_classpath.size(); ++k) {
    612       // Note that we don't care if the same name appears twice.
    613       remap.Put(info.original_classpath[k], stored_info->classpath[k]);
    614     }
    615   }
    616   for (size_t k = 0; k < info.opened_dex_files.size(); k++) {
    617     const std::unique_ptr<const DexFile>& dex_file = info.opened_dex_files[k];
    618     if (for_dex2oat) {
    619       // dex2oat only needs the base location. It cannot accept multidex locations.
    620       // So ensure we only add each file once.
    621       bool new_insert = seen_locations.insert(
    622           DexFileLoader::GetBaseLocation(dex_file->GetLocation())).second;
    623       if (!new_insert) {
    624         continue;
    625       }
    626     }
    627     std::string location = dex_file->GetLocation();
    628     // If there is a stored class loader remap, fix up the multidex strings.
    629     if (!remap.empty()) {
    630       std::string base_dex_location = DexFileLoader::GetBaseLocation(location);
    631       auto it = remap.find(base_dex_location);
    632       CHECK(it != remap.end()) << base_dex_location;
    633       location = it->second + DexFileLoader::GetMultiDexSuffix(location);
    634     }
    635     if (k > 0) {
    636       out << kClasspathSeparator;
    637     }
    638     if (info.type == kInMemoryDexClassLoader) {
    639       out << kInMemoryDexClassLoaderDexLocationMagic;
    640     } else if (!base_dir.empty() && location.substr(0, base_dir.length()) == base_dir) {
    641       // Find paths that were relative and convert them back from absolute.
    642       out << location.substr(base_dir.length() + 1).c_str();
    643     } else {
    644       out << location.c_str();
    645     }
    646     // dex2oat does not need the checksums.
    647     if (!for_dex2oat) {
    648       out << kDexFileChecksumSeparator;
    649       out << dex_file->GetLocationChecksum();
    650     }
    651   }
    652   out << kClassLoaderClosingMark;
    653 
    654   if (!info.shared_libraries.empty()) {
    655     out << kClassLoaderSharedLibraryOpeningMark;
    656     for (uint32_t i = 0; i < info.shared_libraries.size(); ++i) {
    657       if (i > 0) {
    658         out << kClassLoaderSharedLibrarySeparator;
    659       }
    660       EncodeContextInternal(
    661           *info.shared_libraries[i].get(),
    662           base_dir,
    663           for_dex2oat,
    664           (stored_info == nullptr ? nullptr : stored_info->shared_libraries[i].get()),
    665           out);
    666     }
    667     out << kClassLoaderSharedLibraryClosingMark;
    668   }
    669   if (info.parent != nullptr) {
    670     out << kClassLoaderSeparator;
    671     EncodeContextInternal(
    672         *info.parent.get(),
    673         base_dir,
    674         for_dex2oat,
    675         (stored_info == nullptr ? nullptr : stored_info->parent.get()),
    676         out);
    677   }
    678 }
    679 
    680 // Returns the WellKnownClass for the given class loader type.
    681 static jclass GetClassLoaderClass(ClassLoaderContext::ClassLoaderType type) {
    682   switch (type) {
    683     case ClassLoaderContext::kPathClassLoader:
    684       return WellKnownClasses::dalvik_system_PathClassLoader;
    685     case ClassLoaderContext::kDelegateLastClassLoader:
    686       return WellKnownClasses::dalvik_system_DelegateLastClassLoader;
    687     case ClassLoaderContext::kInMemoryDexClassLoader:
    688       return WellKnownClasses::dalvik_system_InMemoryDexClassLoader;
    689     case ClassLoaderContext::kInvalidClassLoader: break;  // will fail after the switch.
    690   }
    691   LOG(FATAL) << "Invalid class loader type " << type;
    692   UNREACHABLE();
    693 }
    694 
    695 static std::string FlattenClasspath(const std::vector<std::string>& classpath) {
    696   return android::base::Join(classpath, ':');
    697 }
    698 
    699 static ObjPtr<mirror::ClassLoader> CreateClassLoaderInternal(
    700     Thread* self,
    701     ScopedObjectAccess& soa,
    702     const ClassLoaderContext::ClassLoaderInfo& info,
    703     bool for_shared_library,
    704     VariableSizedHandleScope& map_scope,
    705     std::map<std::string, Handle<mirror::ClassLoader>>& canonicalized_libraries,
    706     bool add_compilation_sources,
    707     const std::vector<const DexFile*>& compilation_sources)
    708       REQUIRES_SHARED(Locks::mutator_lock_) {
    709   if (for_shared_library) {
    710     // Check if the shared library has already been created.
    711     auto search = canonicalized_libraries.find(FlattenClasspath(info.classpath));
    712     if (search != canonicalized_libraries.end()) {
    713       return search->second.Get();
    714     }
    715   }
    716 
    717   StackHandleScope<3> hs(self);
    718   MutableHandle<mirror::ObjectArray<mirror::ClassLoader>> libraries(
    719       hs.NewHandle<mirror::ObjectArray<mirror::ClassLoader>>(nullptr));
    720 
    721   if (!info.shared_libraries.empty()) {
    722     libraries.Assign(mirror::ObjectArray<mirror::ClassLoader>::Alloc(
    723         self,
    724         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
    725         info.shared_libraries.size()));
    726     for (uint32_t i = 0; i < info.shared_libraries.size(); ++i) {
    727       // We should only add the compilation sources to the first class loader.
    728       libraries->Set(i,
    729                      CreateClassLoaderInternal(
    730                          self,
    731                          soa,
    732                          *info.shared_libraries[i].get(),
    733                          /* for_shared_library= */ true,
    734                          map_scope,
    735                          canonicalized_libraries,
    736                          /* add_compilation_sources= */ false,
    737                          compilation_sources));
    738     }
    739   }
    740 
    741   MutableHandle<mirror::ClassLoader> parent = hs.NewHandle<mirror::ClassLoader>(nullptr);
    742   if (info.parent != nullptr) {
    743     // We should only add the compilation sources to the first class loader.
    744     parent.Assign(CreateClassLoaderInternal(
    745         self,
    746         soa,
    747         *info.parent.get(),
    748         /* for_shared_library= */ false,
    749         map_scope,
    750         canonicalized_libraries,
    751         /* add_compilation_sources= */ false,
    752         compilation_sources));
    753   }
    754   std::vector<const DexFile*> class_path_files = MakeNonOwningPointerVector(
    755       info.opened_dex_files);
    756   if (add_compilation_sources) {
    757     // For the first class loader, its classpath comes first, followed by compilation sources.
    758     // This ensures that whenever we need to resolve classes from it the classpath elements
    759     // come first.
    760     class_path_files.insert(class_path_files.end(),
    761                             compilation_sources.begin(),
    762                             compilation_sources.end());
    763   }
    764   Handle<mirror::Class> loader_class = hs.NewHandle<mirror::Class>(
    765       soa.Decode<mirror::Class>(GetClassLoaderClass(info.type)));
    766   ObjPtr<mirror::ClassLoader> loader =
    767       Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
    768           self,
    769           class_path_files,
    770           loader_class,
    771           parent,
    772           libraries);
    773   if (for_shared_library) {
    774     canonicalized_libraries[FlattenClasspath(info.classpath)] =
    775         map_scope.NewHandle<mirror::ClassLoader>(loader);
    776   }
    777   return loader;
    778 }
    779 
    780 jobject ClassLoaderContext::CreateClassLoader(
    781     const std::vector<const DexFile*>& compilation_sources) const {
    782   CheckDexFilesOpened("CreateClassLoader");
    783 
    784   Thread* self = Thread::Current();
    785   ScopedObjectAccess soa(self);
    786 
    787   ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
    788 
    789   if (class_loader_chain_ == nullptr) {
    790     CHECK(special_shared_library_);
    791     return class_linker->CreatePathClassLoader(self, compilation_sources);
    792   }
    793 
    794   // Create a map of canonicalized shared libraries. As we're holding objects,
    795   // we're creating a variable size handle scope to put handles in the map.
    796   VariableSizedHandleScope map_scope(self);
    797   std::map<std::string, Handle<mirror::ClassLoader>> canonicalized_libraries;
    798 
    799   // Create the class loader.
    800   ObjPtr<mirror::ClassLoader> loader =
    801       CreateClassLoaderInternal(self,
    802                                 soa,
    803                                 *class_loader_chain_.get(),
    804                                 /* for_shared_library= */ false,
    805                                 map_scope,
    806                                 canonicalized_libraries,
    807                                 /* add_compilation_sources= */ true,
    808                                 compilation_sources);
    809   // Make it a global ref and return.
    810   ScopedLocalRef<jobject> local_ref(
    811       soa.Env(), soa.Env()->AddLocalReference<jobject>(loader));
    812   return soa.Env()->NewGlobalRef(local_ref.get());
    813 }
    814 
    815 std::vector<const DexFile*> ClassLoaderContext::FlattenOpenedDexFiles() const {
    816   CheckDexFilesOpened("FlattenOpenedDexFiles");
    817 
    818   std::vector<const DexFile*> result;
    819   if (class_loader_chain_ == nullptr) {
    820     return result;
    821   }
    822   std::vector<ClassLoaderInfo*> work_list;
    823   work_list.push_back(class_loader_chain_.get());
    824   while (!work_list.empty()) {
    825     ClassLoaderInfo* info = work_list.back();
    826     work_list.pop_back();
    827     for (const std::unique_ptr<const DexFile>& dex_file : info->opened_dex_files) {
    828       result.push_back(dex_file.get());
    829     }
    830     AddToWorkList(info, work_list);
    831   }
    832   return result;
    833 }
    834 
    835 std::string ClassLoaderContext::FlattenDexPaths() const {
    836   if (class_loader_chain_ == nullptr) {
    837     return "";
    838   }
    839 
    840   std::vector<std::string> result;
    841   std::vector<ClassLoaderInfo*> work_list;
    842   work_list.push_back(class_loader_chain_.get());
    843   while (!work_list.empty()) {
    844     ClassLoaderInfo* info = work_list.back();
    845     work_list.pop_back();
    846     for (const std::string& dex_path : info->classpath) {
    847       result.push_back(dex_path);
    848     }
    849     AddToWorkList(info, work_list);
    850   }
    851   return FlattenClasspath(result);
    852 }
    853 
    854 const char* ClassLoaderContext::GetClassLoaderTypeName(ClassLoaderType type) {
    855   switch (type) {
    856     case kPathClassLoader: return kPathClassLoaderString;
    857     case kDelegateLastClassLoader: return kDelegateLastClassLoaderString;
    858     case kInMemoryDexClassLoader: return kInMemoryDexClassLoaderString;
    859     default:
    860       LOG(FATAL) << "Invalid class loader type " << type;
    861       UNREACHABLE();
    862   }
    863 }
    864 
    865 void ClassLoaderContext::CheckDexFilesOpened(const std::string& calling_method) const {
    866   CHECK(dex_files_open_attempted_)
    867       << "Dex files were not successfully opened before the call to " << calling_method
    868       << "attempt=" << dex_files_open_attempted_ << ", result=" << dex_files_open_result_;
    869 }
    870 
    871 // Collects the dex files from the give Java dex_file object. Only the dex files with
    872 // at least 1 class are collected. If a null java_dex_file is passed this method does nothing.
    873 static bool CollectDexFilesFromJavaDexFile(ObjPtr<mirror::Object> java_dex_file,
    874                                            ArtField* const cookie_field,
    875                                            std::vector<const DexFile*>* out_dex_files)
    876       REQUIRES_SHARED(Locks::mutator_lock_) {
    877   if (java_dex_file == nullptr) {
    878     return true;
    879   }
    880   // On the Java side, the dex files are stored in the cookie field.
    881   ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(java_dex_file)->AsLongArray();
    882   if (long_array == nullptr) {
    883     // This should never happen so log a warning.
    884     LOG(ERROR) << "Unexpected null cookie";
    885     return false;
    886   }
    887   int32_t long_array_size = long_array->GetLength();
    888   // Index 0 from the long array stores the oat file. The dex files start at index 1.
    889   for (int32_t j = 1; j < long_array_size; ++j) {
    890     const DexFile* cp_dex_file =
    891         reinterpret_cast64<const DexFile*>(long_array->GetWithoutChecks(j));
    892     if (cp_dex_file != nullptr && cp_dex_file->NumClassDefs() > 0) {
    893       // TODO(calin): It's unclear why the dex files with no classes are skipped here and when
    894       // cp_dex_file can be null.
    895       out_dex_files->push_back(cp_dex_file);
    896     }
    897   }
    898   return true;
    899 }
    900 
    901 // Collects all the dex files loaded by the given class loader.
    902 // Returns true for success or false if an unexpected state is discovered (e.g. a null dex cookie,
    903 // a null list of dex elements or a null dex element).
    904 static bool CollectDexFilesFromSupportedClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
    905                                                     Handle<mirror::ClassLoader> class_loader,
    906                                                     std::vector<const DexFile*>* out_dex_files)
    907       REQUIRES_SHARED(Locks::mutator_lock_) {
    908   CHECK(IsPathOrDexClassLoader(soa, class_loader) ||
    909         IsDelegateLastClassLoader(soa, class_loader) ||
    910         IsInMemoryDexClassLoader(soa, class_loader));
    911 
    912   // All supported class loaders inherit from BaseDexClassLoader.
    913   // We need to get the DexPathList and loop through it.
    914   ArtField* const cookie_field =
    915       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
    916   ArtField* const dex_file_field =
    917       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
    918   ObjPtr<mirror::Object> dex_path_list =
    919       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
    920           GetObject(class_loader.Get());
    921   CHECK(cookie_field != nullptr);
    922   CHECK(dex_file_field != nullptr);
    923   if (dex_path_list == nullptr) {
    924     // This may be null if the current class loader is under construction and it does not
    925     // have its fields setup yet.
    926     return true;
    927   }
    928   // DexPathList has an array dexElements of Elements[] which each contain a dex file.
    929   ObjPtr<mirror::Object> dex_elements_obj =
    930       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
    931           GetObject(dex_path_list);
    932   // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
    933   // at the mCookie which is a DexFile vector.
    934   if (dex_elements_obj == nullptr) {
    935     // TODO(calin): It's unclear if we should just assert here. For now be prepared for the worse
    936     // and assume we have no elements.
    937     return true;
    938   } else {
    939     StackHandleScope<1> hs(soa.Self());
    940     Handle<mirror::ObjectArray<mirror::Object>> dex_elements(
    941         hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>()));
    942     for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
    943       ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
    944       if (element == nullptr) {
    945         // Should never happen, log an error and break.
    946         // TODO(calin): It's unclear if we should just assert here.
    947         // This code was propagated to oat_file_manager from the class linker where it would
    948         // throw a NPE. For now, return false which will mark this class loader as unsupported.
    949         LOG(ERROR) << "Unexpected null in the dex element list";
    950         return false;
    951       }
    952       ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
    953       if (!CollectDexFilesFromJavaDexFile(dex_file, cookie_field, out_dex_files)) {
    954         return false;
    955       }
    956     }
    957   }
    958 
    959   return true;
    960 }
    961 
    962 static bool GetDexFilesFromDexElementsArray(
    963     ScopedObjectAccessAlreadyRunnable& soa,
    964     Handle<mirror::ObjectArray<mirror::Object>> dex_elements,
    965     std::vector<const DexFile*>* out_dex_files) REQUIRES_SHARED(Locks::mutator_lock_) {
    966   DCHECK(dex_elements != nullptr);
    967 
    968   ArtField* const cookie_field =
    969       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
    970   ArtField* const dex_file_field =
    971       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
    972   const ObjPtr<mirror::Class> element_class = soa.Decode<mirror::Class>(
    973       WellKnownClasses::dalvik_system_DexPathList__Element);
    974   const ObjPtr<mirror::Class> dexfile_class = soa.Decode<mirror::Class>(
    975       WellKnownClasses::dalvik_system_DexFile);
    976 
    977   for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
    978     ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
    979     // We can hit a null element here because this is invoked with a partially filled dex_elements
    980     // array from DexPathList. DexPathList will open each dex sequentially, each time passing the
    981     // list of dex files which were opened before.
    982     if (element == nullptr) {
    983       continue;
    984     }
    985 
    986     // We support this being dalvik.system.DexPathList$Element and dalvik.system.DexFile.
    987     // TODO(calin): Code caried over oat_file_manager: supporting both classes seem to be
    988     // a historical glitch. All the java code opens dex files using an array of Elements.
    989     ObjPtr<mirror::Object> dex_file;
    990     if (element_class == element->GetClass()) {
    991       dex_file = dex_file_field->GetObject(element);
    992     } else if (dexfile_class == element->GetClass()) {
    993       dex_file = element;
    994     } else {
    995       LOG(ERROR) << "Unsupported element in dex_elements: "
    996                  << mirror::Class::PrettyClass(element->GetClass());
    997       return false;
    998     }
    999 
   1000     if (!CollectDexFilesFromJavaDexFile(dex_file, cookie_field, out_dex_files)) {
   1001       return false;
   1002     }
   1003   }
   1004   return true;
   1005 }
   1006 
   1007 // Adds the `class_loader` info to the `context`.
   1008 // The dex file present in `dex_elements` array (if not null) will be added at the end of
   1009 // the classpath.
   1010 // This method is recursive (w.r.t. the class loader parent) and will stop once it reaches the
   1011 // BootClassLoader. Note that the class loader chain is expected to be short.
   1012 bool ClassLoaderContext::CreateInfoFromClassLoader(
   1013       ScopedObjectAccessAlreadyRunnable& soa,
   1014       Handle<mirror::ClassLoader> class_loader,
   1015       Handle<mirror::ObjectArray<mirror::Object>> dex_elements,
   1016       ClassLoaderInfo* child_info,
   1017       bool is_shared_library)
   1018     REQUIRES_SHARED(Locks::mutator_lock_) {
   1019   if (ClassLinker::IsBootClassLoader(soa, class_loader.Get())) {
   1020     // Nothing to do for the boot class loader as we don't add its dex files to the context.
   1021     return true;
   1022   }
   1023 
   1024   ClassLoaderContext::ClassLoaderType type;
   1025   if (IsPathOrDexClassLoader(soa, class_loader)) {
   1026     type = kPathClassLoader;
   1027   } else if (IsDelegateLastClassLoader(soa, class_loader)) {
   1028     type = kDelegateLastClassLoader;
   1029   } else if (IsInMemoryDexClassLoader(soa, class_loader)) {
   1030     type = kInMemoryDexClassLoader;
   1031   } else {
   1032     LOG(WARNING) << "Unsupported class loader";
   1033     return false;
   1034   }
   1035 
   1036   // Inspect the class loader for its dex files.
   1037   std::vector<const DexFile*> dex_files_loaded;
   1038   CollectDexFilesFromSupportedClassLoader(soa, class_loader, &dex_files_loaded);
   1039 
   1040   // If we have a dex_elements array extract its dex elements now.
   1041   // This is used in two situations:
   1042   //   1) when a new ClassLoader is created DexPathList will open each dex file sequentially
   1043   //      passing the list of already open dex files each time. This ensures that we see the
   1044   //      correct context even if the ClassLoader under construction is not fully build.
   1045   //   2) when apk splits are loaded on the fly, the framework will load their dex files by
   1046   //      appending them to the current class loader. When the new code paths are loaded in
   1047   //      BaseDexClassLoader, the paths already present in the class loader will be passed
   1048   //      in the dex_elements array.
   1049   if (dex_elements != nullptr) {
   1050     GetDexFilesFromDexElementsArray(soa, dex_elements, &dex_files_loaded);
   1051   }
   1052 
   1053   ClassLoaderInfo* info = new ClassLoaderContext::ClassLoaderInfo(type);
   1054   // Attach the `ClassLoaderInfo` now, before populating dex files, as only the
   1055   // `ClassLoaderContext` knows whether these dex files should be deleted or not.
   1056   if (child_info == nullptr) {
   1057     class_loader_chain_.reset(info);
   1058   } else if (is_shared_library) {
   1059     child_info->shared_libraries.push_back(std::unique_ptr<ClassLoaderInfo>(info));
   1060   } else {
   1061     child_info->parent.reset(info);
   1062   }
   1063 
   1064   // Now that `info` is in the chain, populate dex files.
   1065   for (const DexFile* dex_file : dex_files_loaded) {
   1066     // Dex location of dex files loaded with InMemoryDexClassLoader is always bogus.
   1067     // Use a magic value for the classpath instead.
   1068     info->classpath.push_back((type == kInMemoryDexClassLoader)
   1069         ? kInMemoryDexClassLoaderDexLocationMagic
   1070         : dex_file->GetLocation());
   1071     info->checksums.push_back(dex_file->GetLocationChecksum());
   1072     info->opened_dex_files.emplace_back(dex_file);
   1073   }
   1074 
   1075   // Note that dex_elements array is null here. The elements are considered to be part of the
   1076   // current class loader and are not passed to the parents.
   1077   ScopedNullHandle<mirror::ObjectArray<mirror::Object>> null_dex_elements;
   1078 
   1079   // Add the shared libraries.
   1080   StackHandleScope<3> hs(Thread::Current());
   1081   ArtField* field =
   1082       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
   1083   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader.Get());
   1084   if (raw_shared_libraries != nullptr) {
   1085     Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries =
   1086         hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>());
   1087     MutableHandle<mirror::ClassLoader> temp_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
   1088     for (int32_t i = 0; i < shared_libraries->GetLength(); ++i) {
   1089       temp_loader.Assign(shared_libraries->Get(i));
   1090       if (!CreateInfoFromClassLoader(
   1091               soa, temp_loader, null_dex_elements, info, /*is_shared_library=*/ true)) {
   1092         return false;
   1093       }
   1094     }
   1095   }
   1096 
   1097   // We created the ClassLoaderInfo for the current loader. Move on to its parent.
   1098   Handle<mirror::ClassLoader> parent = hs.NewHandle(class_loader->GetParent());
   1099   if (!CreateInfoFromClassLoader(
   1100           soa, parent, null_dex_elements, info, /*is_shared_library=*/ false)) {
   1101     return false;
   1102   }
   1103   return true;
   1104 }
   1105 
   1106 std::unique_ptr<ClassLoaderContext> ClassLoaderContext::CreateContextForClassLoader(
   1107     jobject class_loader,
   1108     jobjectArray dex_elements) {
   1109   CHECK(class_loader != nullptr);
   1110 
   1111   ScopedObjectAccess soa(Thread::Current());
   1112   StackHandleScope<2> hs(soa.Self());
   1113   Handle<mirror::ClassLoader> h_class_loader =
   1114       hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader));
   1115   Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements =
   1116       hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements));
   1117   std::unique_ptr<ClassLoaderContext> result(new ClassLoaderContext(/*owns_the_dex_files=*/ false));
   1118   if (!result->CreateInfoFromClassLoader(
   1119           soa, h_class_loader, h_dex_elements, nullptr, /*is_shared_library=*/ false)) {
   1120     return nullptr;
   1121   }
   1122   return result;
   1123 }
   1124 
   1125 ClassLoaderContext::VerificationResult ClassLoaderContext::VerifyClassLoaderContextMatch(
   1126     const std::string& context_spec,
   1127     bool verify_names,
   1128     bool verify_checksums) const {
   1129   if (verify_names || verify_checksums) {
   1130     DCHECK(dex_files_open_attempted_);
   1131     DCHECK(dex_files_open_result_);
   1132   }
   1133 
   1134   ClassLoaderContext expected_context;
   1135   if (!expected_context.Parse(context_spec, verify_checksums)) {
   1136     LOG(WARNING) << "Invalid class loader context: " << context_spec;
   1137     return VerificationResult::kMismatch;
   1138   }
   1139 
   1140   // Special shared library contexts always match. They essentially instruct the runtime
   1141   // to ignore the class path check because the oat file is known to be loaded in different
   1142   // contexts. OatFileManager will further verify if the oat file can be loaded based on the
   1143   // collision check.
   1144   if (expected_context.special_shared_library_) {
   1145     // Special case where we are the only entry in the class path.
   1146     if (class_loader_chain_ != nullptr &&
   1147         class_loader_chain_->parent == nullptr &&
   1148         class_loader_chain_->classpath.size() == 0) {
   1149       return VerificationResult::kVerifies;
   1150     }
   1151     return VerificationResult::kForcedToSkipChecks;
   1152   } else if (special_shared_library_) {
   1153     return VerificationResult::kForcedToSkipChecks;
   1154   }
   1155 
   1156   ClassLoaderInfo* info = class_loader_chain_.get();
   1157   ClassLoaderInfo* expected = expected_context.class_loader_chain_.get();
   1158   CHECK(info != nullptr);
   1159   CHECK(expected != nullptr);
   1160   if (!ClassLoaderInfoMatch(*info, *expected, context_spec, verify_names, verify_checksums)) {
   1161     return VerificationResult::kMismatch;
   1162   }
   1163   return VerificationResult::kVerifies;
   1164 }
   1165 
   1166 bool ClassLoaderContext::ClassLoaderInfoMatch(
   1167     const ClassLoaderInfo& info,
   1168     const ClassLoaderInfo& expected_info,
   1169     const std::string& context_spec,
   1170     bool verify_names,
   1171     bool verify_checksums) const {
   1172   if (info.type != expected_info.type) {
   1173     LOG(WARNING) << "ClassLoaderContext type mismatch"
   1174         << ". expected=" << GetClassLoaderTypeName(expected_info.type)
   1175         << ", found=" << GetClassLoaderTypeName(info.type)
   1176         << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1177     return false;
   1178   }
   1179   if (info.classpath.size() != expected_info.classpath.size()) {
   1180     LOG(WARNING) << "ClassLoaderContext classpath size mismatch"
   1181           << ". expected=" << expected_info.classpath.size()
   1182           << ", found=" << info.classpath.size()
   1183           << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1184     return false;
   1185   }
   1186 
   1187   if (verify_checksums) {
   1188     DCHECK_EQ(info.classpath.size(), info.checksums.size());
   1189     DCHECK_EQ(expected_info.classpath.size(), expected_info.checksums.size());
   1190   }
   1191 
   1192   if (verify_names) {
   1193     for (size_t k = 0; k < info.classpath.size(); k++) {
   1194       // Compute the dex location that must be compared.
   1195       // We shouldn't do a naive comparison `info.classpath[k] == expected_info.classpath[k]`
   1196       // because even if they refer to the same file, one could be encoded as a relative location
   1197       // and the other as an absolute one.
   1198       bool is_dex_name_absolute = IsAbsoluteLocation(info.classpath[k]);
   1199       bool is_expected_dex_name_absolute = IsAbsoluteLocation(expected_info.classpath[k]);
   1200       std::string dex_name;
   1201       std::string expected_dex_name;
   1202 
   1203       if (is_dex_name_absolute == is_expected_dex_name_absolute) {
   1204         // If both locations are absolute or relative then compare them as they are.
   1205         // This is usually the case for: shared libraries and secondary dex files.
   1206         dex_name = info.classpath[k];
   1207         expected_dex_name = expected_info.classpath[k];
   1208       } else if (is_dex_name_absolute) {
   1209         // The runtime name is absolute but the compiled name (the expected one) is relative.
   1210         // This is the case for split apks which depend on base or on other splits.
   1211         dex_name = info.classpath[k];
   1212         OatFile::ResolveRelativeEncodedDexLocation(info.classpath[k].c_str(),
   1213                                                    expected_info.classpath[k],
   1214                                                    &expected_dex_name);
   1215       } else if (is_expected_dex_name_absolute) {
   1216         // The runtime name is relative but the compiled name is absolute.
   1217         // There is no expected use case that would end up here as dex files are always loaded
   1218         // with their absolute location. However, be tolerant and do the best effort (in case
   1219         // there are unexpected new use case...).
   1220         OatFile::ResolveRelativeEncodedDexLocation(expected_info.classpath[k].c_str(),
   1221                                                    info.classpath[k],
   1222                                                    &dex_name);
   1223         expected_dex_name = expected_info.classpath[k];
   1224       } else {
   1225         // Both locations are relative. In this case there's not much we can be sure about
   1226         // except that the names are the same. The checksum will ensure that the files are
   1227         // are same. This should not happen outside testing and manual invocations.
   1228         dex_name = info.classpath[k];
   1229         expected_dex_name = expected_info.classpath[k];
   1230       }
   1231 
   1232       // Compare the locations.
   1233       if (dex_name != expected_dex_name) {
   1234         LOG(WARNING) << "ClassLoaderContext classpath element mismatch"
   1235             << ". expected=" << expected_info.classpath[k]
   1236             << ", found=" << info.classpath[k]
   1237             << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1238         return false;
   1239       }
   1240 
   1241       // Compare the checksums.
   1242       if (info.checksums[k] != expected_info.checksums[k]) {
   1243         LOG(WARNING) << "ClassLoaderContext classpath element checksum mismatch"
   1244                      << ". expected=" << expected_info.checksums[k]
   1245                      << ", found=" << info.checksums[k]
   1246                      << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1247         return false;
   1248       }
   1249     }
   1250   }
   1251 
   1252   if (info.shared_libraries.size() != expected_info.shared_libraries.size()) {
   1253     LOG(WARNING) << "ClassLoaderContext shared library size mismatch. "
   1254           << "Expected=" << expected_info.shared_libraries.size()
   1255           << ", found=" << info.shared_libraries.size()
   1256           << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1257     return false;
   1258   }
   1259   for (size_t i = 0; i < info.shared_libraries.size(); ++i) {
   1260     if (!ClassLoaderInfoMatch(*info.shared_libraries[i].get(),
   1261                               *expected_info.shared_libraries[i].get(),
   1262                               context_spec,
   1263                               verify_names,
   1264                               verify_checksums)) {
   1265       return false;
   1266     }
   1267   }
   1268   if (info.parent.get() == nullptr) {
   1269     if (expected_info.parent.get() != nullptr) {
   1270       LOG(WARNING) << "ClassLoaderContext parent mismatch. "
   1271             << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1272       return false;
   1273     }
   1274     return true;
   1275   } else if (expected_info.parent.get() == nullptr) {
   1276     LOG(WARNING) << "ClassLoaderContext parent mismatch. "
   1277           << " (" << context_spec << " | " << EncodeContextForOatFile("") << ")";
   1278     return false;
   1279   } else {
   1280     return ClassLoaderInfoMatch(*info.parent.get(),
   1281                                 *expected_info.parent.get(),
   1282                                 context_spec,
   1283                                 verify_names,
   1284                                 verify_checksums);
   1285   }
   1286 }
   1287 
   1288 }  // namespace art
   1289