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 <gtest/gtest.h>
20 
21 #include <filesystem>
22 #include <fstream>
23 #include <optional>
24 #include <vector>
25 
26 #include "android-base/stringprintf.h"
27 #include "android-base/strings.h"
28 #include "art_field-inl.h"
29 #include "art_method-alloc-inl.h"
30 #include "base/dchecked_vector.h"
31 #include "base/stl_util.h"
32 #include "class_linker.h"
33 #include "class_root-inl.h"
34 #include "common_runtime_test.h"
35 #include "dex/dex_file.h"
36 #include "handle_scope-inl.h"
37 #include "jni/jni_internal.h"
38 #include "mirror/class.h"
39 #include "mirror/class_loader-inl.h"
40 #include "mirror/object-inl.h"
41 #include "mirror/object_array-alloc-inl.h"
42 #include "oat/oat_file_assistant.h"
43 #include "runtime.h"
44 #include "scoped_thread_state_change-inl.h"
45 #include "thread.h"
46 #include "well_known_classes-inl.h"
47 
48 namespace art HIDDEN {
49 
50 class ClassLoaderContextTest : public CommonRuntimeTest {
51  public:
ClassLoaderContextTest()52   ClassLoaderContextTest() {
53     use_boot_image_ = true;  // Make the Runtime creation cheaper.
54   }
55 
SetUp()56   void SetUp() override {
57     CommonRuntimeTest::SetUp();
58     scratch_dir_ = std::make_unique<ScratchDir>();
59     scratch_path_ = scratch_dir_->GetPath();
60     // Remove the trailing '/';
61     scratch_path_.resize(scratch_path_.length() - 1);
62   }
63 
TearDown()64   void TearDown() override {
65     scratch_dir_.reset();
66     CommonRuntimeTest::TearDown();
67   }
68 
VerifyContextSize(ClassLoaderContext * context,size_t expected_size)69   void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
70     ASSERT_TRUE(context != nullptr);
71     ASSERT_EQ(expected_size, context->GetParentChainSize());
72   }
73 
VerifyClassLoaderPCL(ClassLoaderContext * context,size_t index,const std::string & classpath)74   void VerifyClassLoaderPCL(ClassLoaderContext* context,
75                             size_t index,
76                             const std::string& classpath) {
77     VerifyClassLoaderInfo(
78         context, index, ClassLoaderContext::kPathClassLoader, classpath);
79   }
80 
VerifyClassLoaderDLC(ClassLoaderContext * context,size_t index,const std::string & classpath)81   void VerifyClassLoaderDLC(ClassLoaderContext* context,
82                             size_t index,
83                             const std::string& classpath) {
84     VerifyClassLoaderInfo(
85         context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
86   }
87 
VerifyClassLoaderIMC(ClassLoaderContext * context,size_t index,const std::string & classpath)88   void VerifyClassLoaderIMC(ClassLoaderContext* context,
89                             size_t index,
90                             const std::string& classpath) {
91     VerifyClassLoaderInfo(
92         context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath);
93   }
94 
VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)95   void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
96                                          size_t loader_index,
97                                          size_t shared_library_index,
98                                          const std::string& classpath) {
99     VerifyClassLoaderInfoSL(
100         context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
101         classpath);
102   }
103 
VerifyClassLoaderSharedLibraryPCLAfter(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)104   void VerifyClassLoaderSharedLibraryPCLAfter(ClassLoaderContext* context,
105                                               size_t loader_index,
106                                               size_t shared_library_index,
107                                               const std::string& classpath) {
108     VerifyClassLoaderInfoSLAfter(
109         context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
110         classpath);
111   }
112 
VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)113   void VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext* context,
114                                          size_t loader_index,
115                                          size_t shared_library_index,
116                                          const std::string& classpath) {
117     VerifyClassLoaderInfoSL(
118         context, loader_index, shared_library_index, ClassLoaderContext::kInMemoryDexClassLoader,
119         classpath);
120   }
121 
VerifySharedLibrariesSize(ClassLoaderContext * context,size_t loader_index,size_t expected_size)122   void VerifySharedLibrariesSize(ClassLoaderContext* context,
123                                  size_t loader_index,
124                                  size_t expected_size) {
125     ASSERT_TRUE(context != nullptr);
126     ASSERT_GT(context->GetParentChainSize(), loader_index);
127     const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
128     ASSERT_EQ(info.shared_libraries.size(), expected_size);
129   }
130 
VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,const std::string & classpath)131   void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
132                                          size_t loader_index,
133                                          size_t shared_library_index,
134                                          const std::string& classpath) {
135     VerifyClassLoaderInfoSL(
136         context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
137         classpath);
138   }
139 
VerifyClassLoaderPCLFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)140   void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
141                                        size_t index,
142                                        const std::string& test_name) {
143     VerifyClassLoaderFromTestDex(
144         context, index, ClassLoaderContext::kPathClassLoader, test_name);
145   }
146 
VerifyClassLoaderDLCFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)147   void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
148                                        size_t index,
149                                        const std::string& test_name) {
150     VerifyClassLoaderFromTestDex(
151         context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
152   }
153 
VerifyClassLoaderIMCFromTestDex(ClassLoaderContext * context,size_t index,const std::string & test_name)154   void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context,
155                                        size_t index,
156                                        const std::string& test_name) {
157     VerifyClassLoaderFromTestDex(
158         context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>");
159   }
160 
161   enum class LocationCheck {
162     kEquals,
163     kEndsWith
164   };
165   enum class BaseLocationCheck {
166     kEquals,
167     kEndsWith
168   };
169 
IsAbsoluteLocation(const std::string & location)170   static bool IsAbsoluteLocation(const std::string& location) {
171     return !location.empty() && location[0] == '/';
172   }
173 
VerifyOpenDexFiles(ClassLoaderContext * context,size_t index,std::vector<std::unique_ptr<const DexFile>> * all_dex_files,bool classpath_matches_dex_location=true,bool only_read_checksums=false)174   void VerifyOpenDexFiles(
175       ClassLoaderContext* context,
176       size_t index,
177       std::vector<std::unique_ptr<const DexFile>>* all_dex_files,
178       bool classpath_matches_dex_location = true,
179       bool only_read_checksums = false) {
180     ASSERT_TRUE(context != nullptr);
181     if (only_read_checksums) {
182       ASSERT_EQ(context->dex_files_state_,
183                 ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead);
184     } else {
185       ASSERT_EQ(context->dex_files_state_,
186                 ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
187     }
188     ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
189 
190     std::vector<const DexFile*> primary_dex_files;
191     std::vector<std::optional<uint32_t>> primary_checksums;
192     for (size_t i = 0; i < all_dex_files->size();) {
193       primary_dex_files.push_back((*all_dex_files)[i].get());
194       primary_checksums.push_back(DexFileLoader::GetMultiDexChecksum(*all_dex_files, &i));
195     }
196     ASSERT_EQ(primary_dex_files.size(), info.classpath.size());
197     ASSERT_EQ(primary_dex_files.size(), info.checksums.size());
198 
199     if (only_read_checksums) {
200       ASSERT_EQ(0u, info.opened_dex_files.size());
201       for (size_t k = 0; k < primary_dex_files.size(); k++) {
202         const std::string& opened_location = info.classpath[k];
203         uint32_t opened_checksum = info.checksums[k];
204 
205         const DexFile* expected_dex_file = primary_dex_files[k];
206         std::string expected_location = expected_dex_file->GetLocation();
207 
208         if (!IsAbsoluteLocation(opened_location)) {
209           // If the opened location is relative (it was open from a relative path without a
210           // classpath_dir) it might not match the expected location which is absolute in tests).
211           // So we compare the endings (the checksum will validate it's actually the same file).
212           ASSERT_TRUE(expected_location.ends_with(opened_location))
213               << expected_location << " " << opened_location;
214         } else {
215           ASSERT_EQ(expected_location, opened_location);
216         }
217         ASSERT_EQ(primary_checksums[k], opened_checksum);
218         if (classpath_matches_dex_location) {
219           ASSERT_EQ(info.classpath[k], opened_location);
220         }
221       }
222     } else {
223       ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
224 
225       for (size_t k = 0; k < all_dex_files->size(); k++) {
226         const std::string& opened_location = info.opened_dex_files[k]->GetLocation();
227         uint32_t opened_checksum = info.opened_dex_files[k]->GetLocationChecksum();
228 
229         std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
230         std::string expected_location = expected_dex_file->GetLocation();
231 
232         if (!IsAbsoluteLocation(opened_location)) {
233           // If the opened location is relative (it was open from a relative path without a
234           // classpath_dir) it might not match the expected location which is absolute in tests).
235           // So we compare the endings (the checksum will validate it's actually the same file).
236           ASSERT_TRUE(expected_location.ends_with(opened_location))
237               << expected_location << " " << opened_location;
238         } else {
239           ASSERT_EQ(expected_location, opened_location);
240         }
241         ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_checksum);
242         if (classpath_matches_dex_location) {
243           ASSERT_EQ(info.classpath[k], opened_location);
244         }
245       }
246     }
247   }
248 
CreateContextForClassLoader(jobject class_loader)249   std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
250     return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
251   }
252 
ParseContextWithChecksums(const std::string & context_spec)253   std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
254     std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
255     if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
256       return nullptr;
257     }
258     return context;
259   }
260 
VerifyContextForClassLoader(ClassLoaderContext * context)261   void VerifyContextForClassLoader(ClassLoaderContext* context) {
262     ASSERT_TRUE(context != nullptr);
263     ASSERT_EQ(context->dex_files_state_, ClassLoaderContext::ContextDexFilesState::kDexFilesOpened);
264     ASSERT_FALSE(context->owns_the_dex_files_);
265   }
266 
VerifyClassLoaderDexFiles(Thread * self,Handle<mirror::ClassLoader> class_loader,ObjPtr<mirror::Class> type,std::vector<const DexFile * > & expected_dex_files)267   void VerifyClassLoaderDexFiles(Thread* self,
268                                  Handle<mirror::ClassLoader> class_loader,
269                                  ObjPtr<mirror::Class> type,
270                                  std::vector<const DexFile*>& expected_dex_files)
271       REQUIRES_SHARED(Locks::mutator_lock_) {
272     ASSERT_TRUE(class_loader->GetClass() == type);
273 
274     std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(self, class_loader);
275     ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
276 
277     for (size_t i = 0; i < expected_dex_files.size(); i++) {
278       ASSERT_EQ(expected_dex_files[i]->GetLocation(),
279                 class_loader_dex_files[i]->GetLocation());
280       ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
281                 class_loader_dex_files[i]->GetLocationChecksum());
282     }
283   }
284 
PretendContextOpenedDexFiles(ClassLoaderContext * context)285   void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
286     context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesOpened;
287   }
288 
PretendContextOpenedDexFilesForChecksums(ClassLoaderContext * context)289   void PretendContextOpenedDexFilesForChecksums(ClassLoaderContext* context) {
290     context->dex_files_state_ = ClassLoaderContext::ContextDexFilesState::kDexFilesChecksumsRead;
291   }
292 
TestOpenDexFiles(bool only_read_checksums)293   void TestOpenDexFiles(bool only_read_checksums) {
294     std::string multidex_name = GetTestDexFileName("MultiDex");
295     std::string myclass_dex_name = GetTestDexFileName("MyClass");
296     std::string dex_name = GetTestDexFileName("Main");
297 
298     std::unique_ptr<ClassLoaderContext> context =
299         ClassLoaderContext::Create(
300             "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
301             "DLC[" + dex_name + "]");
302 
303     ASSERT_TRUE(context->OpenDexFiles(
304         /*classpath_dir=*/ "",
305         /*context_fds=*/ std::vector<int>(),
306         only_read_checksums));
307 
308     VerifyContextSize(context.get(), 2);
309 
310     std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
311     std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
312     for (size_t i = 0; i < myclass_dex_files.size(); i++) {
313       all_dex_files0.emplace_back(myclass_dex_files[i].release());
314     }
315     VerifyOpenDexFiles(context.get(),
316                        /*index=*/ 0,
317                        &all_dex_files0,
318                        /*classpath_matches_dex_location=*/ false,
319                        only_read_checksums);
320     std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
321     VerifyOpenDexFiles(context.get(),
322                        /*index=*/ 1,
323                        &all_dex_files1,
324                        /*classpath_matches_dex_location=*/ false,
325                        only_read_checksums);
326   }
327 
TestOpenValidDexFilesRelative(bool use_classpath_dir,bool only_read_checksums)328   void TestOpenValidDexFilesRelative(bool use_classpath_dir, bool only_read_checksums) {
329     char cwd_buf[4096];
330     if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
331       PLOG(FATAL) << "Could not get working directory";
332     }
333     std::string multidex_name;
334     std::string myclass_dex_name;
335     std::string dex_name;
336     if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
337         !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
338         !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
339       LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
340                 << "relative path.";
341       SUCCEED();
342       return;
343     }
344 
345     std::unique_ptr<ClassLoaderContext> context =
346         ClassLoaderContext::Create(
347             "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
348             "DLC[" + dex_name + "]");
349 
350     ASSERT_TRUE(context->OpenDexFiles(
351         /*classpath_dir=*/ use_classpath_dir ? cwd_buf : "",
352         /*context_fds=*/ std::vector<int>(),
353         only_read_checksums));
354     VerifyContextSize(context.get(), 2);
355 
356     std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
357     std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
358     for (size_t i = 0; i < myclass_dex_files.size(); i++) {
359       all_dex_files0.emplace_back(myclass_dex_files[i].release());
360     }
361     VerifyOpenDexFiles(context.get(),
362                        /*index=*/ 0,
363                        &all_dex_files0,
364                        /*classpath_matches_dex_location=*/ false,
365                        only_read_checksums);
366 
367     std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
368     VerifyOpenDexFiles(context.get(),
369                        /*index=*/ 1,
370                        &all_dex_files1,
371                        /*classpath_matches_dex_location=*/ false,
372                        only_read_checksums);
373   }
374 
375   // Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
376   // TODO We should somehow support this in all situations. b/72042237.
CreateRelativeString(const std::string & in,const char * cwd,std::string * out)377   bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
378     int cwd_len = strlen(cwd);
379     if (!in.starts_with(cwd) || (cwd_len < 1)) {
380       return false;
381     }
382     bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
383     int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
384     *out = in.substr(start_position);
385     return true;
386   }
387 
388   std::unique_ptr<ScratchDir> scratch_dir_;
389   std::string scratch_path_;
390 
391  private:
VerifyClassLoaderInfo(ClassLoaderContext * context,size_t index,ClassLoaderContext::ClassLoaderType type,const std::string & classpath)392   void VerifyClassLoaderInfo(ClassLoaderContext* context,
393                              size_t index,
394                              ClassLoaderContext::ClassLoaderType type,
395                              const std::string& classpath) {
396     ASSERT_TRUE(context != nullptr);
397     ASSERT_GT(context->GetParentChainSize(), index);
398     ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
399     ASSERT_EQ(type, info.type);
400     std::vector<std::string> expected_classpath;
401     Split(classpath, ':', &expected_classpath);
402     ASSERT_EQ(expected_classpath, info.classpath);
403   }
404 
VerifyClassLoaderInfoSL(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,ClassLoaderContext::ClassLoaderType type,const std::string & classpath)405   void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
406                                size_t loader_index,
407                                size_t shared_library_index,
408                                ClassLoaderContext::ClassLoaderType type,
409                                const std::string& classpath) {
410     ASSERT_TRUE(context != nullptr);
411     ASSERT_GT(context->GetParentChainSize(), loader_index);
412     const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
413     ASSERT_GT(info.shared_libraries.size(), shared_library_index);
414     const ClassLoaderContext::ClassLoaderInfo& sl =
415         *info.shared_libraries[shared_library_index].get();
416     ASSERT_EQ(type, sl.type);
417     std::vector<std::string> expected_classpath;
418     Split(classpath, ':', &expected_classpath);
419     ASSERT_EQ(expected_classpath, sl.classpath);
420   }
421 
VerifyClassLoaderInfoSLAfter(ClassLoaderContext * context,size_t loader_index,size_t shared_library_index,ClassLoaderContext::ClassLoaderType type,const std::string & classpath)422   void VerifyClassLoaderInfoSLAfter(ClassLoaderContext* context,
423                                size_t loader_index,
424                                size_t shared_library_index,
425                                ClassLoaderContext::ClassLoaderType type,
426                                const std::string& classpath) {
427     ASSERT_TRUE(context != nullptr);
428     ASSERT_GT(context->GetParentChainSize(), loader_index);
429     const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
430     ASSERT_GT(info.shared_libraries_after.size(), shared_library_index);
431 
432     const ClassLoaderContext::ClassLoaderInfo& sl =
433         *info.shared_libraries_after[shared_library_index].get();
434     ASSERT_EQ(type, sl.type);
435     std::vector<std::string> expected_classpath;
436     Split(classpath, ':', &expected_classpath);
437     ASSERT_EQ(expected_classpath, sl.classpath);
438   }
439 
VerifyClassLoaderFromTestDex(ClassLoaderContext * context,size_t index,ClassLoaderContext::ClassLoaderType type,const std::string & test_name,const std::string & classpath="")440   void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
441                                     size_t index,
442                                     ClassLoaderContext::ClassLoaderType type,
443                                     const std::string& test_name,
444                                     const std::string& classpath = "") {
445     std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
446 
447     // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath.
448     // Otherwise assume it is equal to dex location (here test dex file name).
449     VerifyClassLoaderInfo(context,
450                           index,
451                           type,
452                           classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath);
453     VerifyOpenDexFiles(context,
454                        index,
455                        &dex_files,
456                        /* classpath_matches_dex_location= */ classpath.empty());
457   }
458 };
459 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContext)460 TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
461   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
462   // An empty context should create a single empty PathClassLoader.
463   VerifyContextSize(context.get(), 1);
464   VerifyClassLoaderPCL(context.get(), 0, "");
465 }
466 
TEST_F(ClassLoaderContextTest,ParseInvalidSharedLibraryContext)467 TEST_F(ClassLoaderContextTest, ParseInvalidSharedLibraryContext) {
468   // '&' used to be a special context.
469   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
470   ASSERT_TRUE(context == nullptr);
471 }
472 
TEST_F(ClassLoaderContextTest,ParseValidContextPCL)473 TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
474   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
475   VerifyContextSize(context.get(), 1);
476   VerifyClassLoaderPCL(context.get(), 0, "a.dex");
477 }
478 
TEST_F(ClassLoaderContextTest,ParseValidContextDLC)479 TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
480   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
481   VerifyContextSize(context.get(), 1);
482   VerifyClassLoaderDLC(context.get(), 0, "a.dex");
483 }
484 
TEST_F(ClassLoaderContextTest,ParseValidContextIMC)485 TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
486   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
487   ASSERT_FALSE(context == nullptr);
488 }
489 
TEST_F(ClassLoaderContextTest,ParseInvalidContextIMCNoChecksum)490 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
491   // IMC is treated as an unknown class loader unless a checksum is provided.
492   // This is because the dex location is always bogus.
493   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
494   ASSERT_TRUE(context == nullptr);
495 }
496 
TEST_F(ClassLoaderContextTest,ParseInvalidContextIMCWrongClasspathMagic)497 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
498   // IMC does not support arbitrary dex location. A magic marker must be used
499   // otherwise the spec should be rejected.
500   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
501   ASSERT_TRUE(context == nullptr);
502 }
503 
TEST_F(ClassLoaderContextTest,ParseValidContextChain)504 TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
505   std::unique_ptr<ClassLoaderContext> context =
506       ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
507   VerifyContextSize(context.get(), 3);
508   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
509   VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
510   VerifyClassLoaderPCL(context.get(), 2, "e.dex");
511 }
512 
TEST_F(ClassLoaderContextTest,ParseSharedLibraries)513 TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
514   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
515       "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]#~PCL[s5.dex]#~PCL[s6.dex:s7.dex]};"
516       "DLC[c.dex:d.dex]{DLC[s4.dex]}");
517   VerifyContextSize(context.get(), 2);
518   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
519   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
520   VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 0, "s5.dex");
521   VerifyClassLoaderSharedLibraryPCLAfter(context.get(), 0, 1, "s6.dex:s7.dex");
522   VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
523   VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
524 }
525 
TEST_F(ClassLoaderContextTest,ParseEnclosingSharedLibraries)526 TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
527   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
528       "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
529   VerifyContextSize(context.get(), 1);
530   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
531 }
532 
TEST_F(ClassLoaderContextTest,ParseComplexSharedLibraries1)533 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
534   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
535       "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
536   VerifyContextSize(context.get(), 1);
537   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
538 }
539 
TEST_F(ClassLoaderContextTest,ParseComplexSharedLibraries2)540 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
541   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
542       "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
543       "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
544   VerifyContextSize(context.get(), 1);
545   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
546   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
547   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
548   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
549   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
550 }
551 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContextDLC)552 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
553   std::unique_ptr<ClassLoaderContext> context =
554       ClassLoaderContext::Create("DLC[]");
555   VerifyContextSize(context.get(), 1);
556   VerifyClassLoaderDLC(context.get(), 0, "");
557 }
558 
TEST_F(ClassLoaderContextTest,ParseValidEmptyContextSharedLibrary)559 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
560   std::unique_ptr<ClassLoaderContext> context =
561       ClassLoaderContext::Create("DLC[]{}");
562   VerifyContextSize(context.get(), 1);
563   VerifySharedLibrariesSize(context.get(), 0, 0);
564 }
565 
TEST_F(ClassLoaderContextTest,ParseInvalidValidContexts)566 TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
567   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
568   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
569   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
570   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
571   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
572   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
573   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
574   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
575   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
576   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
577   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
578   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
579   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
580   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
581   ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
582 }
583 
TEST_F(ClassLoaderContextTest,OpenInvalidDexFiles)584 TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
585   std::unique_ptr<ClassLoaderContext> context =
586       ClassLoaderContext::Create("PCL[does_not_exist.dex]");
587   VerifyContextSize(context.get(), 1);
588   ASSERT_FALSE(context->OpenDexFiles("."));
589 }
590 
TEST_F(ClassLoaderContextTest,ReadChecksumsInvalidDexFiles)591 TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFiles) {
592   std::unique_ptr<ClassLoaderContext> context =
593       ClassLoaderContext::Create("PCL[does_not_exist.dex]");
594   VerifyContextSize(context.get(), 1);
595   ASSERT_FALSE(context->OpenDexFiles(
596         /*classpath_dir=*/ ".",
597         /*context_fds=*/ std::vector<int>(),
598         /*only_read_checksums=*/ true));
599 }
600 
TEST_F(ClassLoaderContextTest,OpenValidDexFiles)601 TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
602   TestOpenDexFiles(/*only_read_checksums=*/ false);
603 }
604 
TEST_F(ClassLoaderContextTest,ReadDexFileChecksums)605 TEST_F(ClassLoaderContextTest, ReadDexFileChecksums) {
606   TestOpenDexFiles(/*only_read_checksums=*/ true);
607 }
608 
TEST_F(ClassLoaderContextTest,OpenValidDexFilesRelative)609 TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
610   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ false);
611 }
612 
TEST_F(ClassLoaderContextTest,ReadChecksumsValidDexFilesRelative)613 TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesRelative) {
614   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ false, /*only_read_checksums=*/ true);
615 }
616 
TEST_F(ClassLoaderContextTest,OpenValidDexFilesClasspathDir)617 TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
618   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ false);
619 }
620 
TEST_F(ClassLoaderContextTest,ReadChecksumsValidDexFilesClasspathDir)621 TEST_F(ClassLoaderContextTest, ReadChecksumsValidDexFilesClasspathDir) {
622   TestOpenValidDexFilesRelative(/*use_classpath_dir=*/ true, /*only_read_checksums=*/ true);
623 }
624 
TEST_F(ClassLoaderContextTest,OpenInvalidDexFilesMix)625 TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
626   std::string dex_name = GetTestDexFileName("Main");
627   std::unique_ptr<ClassLoaderContext> context =
628       ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
629   ASSERT_FALSE(context->OpenDexFiles());
630 }
631 
TEST_F(ClassLoaderContextTest,ReadChecksumsInvalidDexFilesMix)632 TEST_F(ClassLoaderContextTest, ReadChecksumsInvalidDexFilesMix) {
633   std::string dex_name = GetTestDexFileName("Main");
634   std::unique_ptr<ClassLoaderContext> context =
635       ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
636   ASSERT_FALSE(context->OpenDexFiles(
637       /*classpath_dir=*/ "",
638       /*context_fds=*/ std::vector<int>(),
639       /*only_read_checksums=*/ true));
640 }
641 
TEST_F(ClassLoaderContextTest,OpenDexFilesForIMCFails)642 TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
643   std::unique_ptr<ClassLoaderContext> context;
644   std::string dex_name = GetTestDexFileName("Main");
645 
646   context = ParseContextWithChecksums("IMC[<unknown>*111]");
647   VerifyContextSize(context.get(), 1);
648   ASSERT_FALSE(context->OpenDexFiles("."));
649 }
650 
651 // Verify that we can fully open the dex files after only reading their checksums.
TEST_F(ClassLoaderContextTest,SubsequentOpenDexFilesOperations)652 TEST_F(ClassLoaderContextTest, SubsequentOpenDexFilesOperations) {
653   std::string dex_name = GetTestDexFileName("Main");
654   std::unique_ptr<ClassLoaderContext> context =
655       ClassLoaderContext::Create("PCL[" + dex_name + "]");
656 
657   std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("Main");
658 
659   ASSERT_TRUE(context->OpenDexFiles(
660       /*classpath_dir=*/ "",
661       /*context_fds=*/ std::vector<int>(),
662       /*only_read_checksums=*/ true));
663 
664   VerifyOpenDexFiles(
665       context.get(),
666       /*index=*/ 0,
667       &all_dex_files0,
668       /*classpath_matches_dex_location=*/ false,
669       /*only_read_checksums=*/ true);
670 
671   ASSERT_TRUE(context->OpenDexFiles(
672       /*classpath_dir=*/ "",
673       /*context_fds=*/ std::vector<int>(),
674       /*only_read_checksums=*/ false));
675 
676   VerifyOpenDexFiles(
677       context.get(),
678       /*index=*/ 0,
679       &all_dex_files0,
680       /*classpath_matches_dex_location=*/ false,
681       /*only_read_checksums=*/ false);
682 }
683 
TEST_F(ClassLoaderContextTest,CreateClassLoader)684 TEST_F(ClassLoaderContextTest, CreateClassLoader) {
685   std::string dex_name = GetTestDexFileName("Main");
686   std::unique_ptr<ClassLoaderContext> context =
687       ClassLoaderContext::Create("PCL[" + dex_name + "]");
688   ASSERT_TRUE(context->OpenDexFiles());
689 
690   std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
691   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
692 
693   std::vector<const DexFile*> compilation_sources_raw =
694       MakeNonOwningPointerVector(compilation_sources);
695   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
696   ASSERT_TRUE(jclass_loader != nullptr);
697 
698   ScopedObjectAccess soa(Thread::Current());
699 
700   StackHandleScope<1> hs(soa.Self());
701   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
702       soa.Decode<mirror::ClassLoader>(jclass_loader));
703 
704   ASSERT_TRUE(class_loader->GetClass() == WellKnownClasses::dalvik_system_PathClassLoader);
705   ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
706       WellKnownClasses::java_lang_BootClassLoader);
707 
708   // For the first class loader the class path dex files must come first and then the
709   // compilation sources.
710   std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
711   for (auto& dex : compilation_sources_raw) {
712     expected_classpath.push_back(dex);
713   }
714 
715   VerifyClassLoaderDexFiles(soa.Self(),
716                             class_loader,
717                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
718                             expected_classpath);
719 }
720 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithEmptyContext)721 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
722   std::unique_ptr<ClassLoaderContext> context =
723       ClassLoaderContext::Create("");
724   ASSERT_TRUE(context->OpenDexFiles());
725 
726   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
727 
728   std::vector<const DexFile*> compilation_sources_raw =
729       MakeNonOwningPointerVector(compilation_sources);
730   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
731   ASSERT_TRUE(jclass_loader != nullptr);
732 
733   ScopedObjectAccess soa(Thread::Current());
734 
735   StackHandleScope<1> hs(soa.Self());
736   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
737       soa.Decode<mirror::ClassLoader>(jclass_loader));
738 
739   // An empty context should create a single PathClassLoader with only the compilation sources.
740   VerifyClassLoaderDexFiles(soa.Self(),
741                             class_loader,
742                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
743                             compilation_sources_raw);
744   ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
745       WellKnownClasses::java_lang_BootClassLoader);
746 }
747 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithComplexChain)748 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
749   // Setup the context.
750   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
751   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
752   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
753   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
754 
755   std::string context_spec =
756       "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
757       "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
758       "PCL[" + CreateClassPath(classpath_dex_d) + "]";
759 
760   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
761   ASSERT_TRUE(context->OpenDexFiles());
762 
763   // Setup the compilation sources.
764   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
765   std::vector<const DexFile*> compilation_sources_raw =
766       MakeNonOwningPointerVector(compilation_sources);
767 
768   // Create the class loader.
769   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
770   ASSERT_TRUE(jclass_loader != nullptr);
771 
772   // Verify the class loader.
773   ScopedObjectAccess soa(Thread::Current());
774 
775   StackHandleScope<3> hs(soa.Self());
776   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
777       soa.Decode<mirror::ClassLoader>(jclass_loader));
778 
779   // Verify the first class loader
780 
781   // For the first class loader the class path dex files must come first and then the
782   // compilation sources.
783   std::vector<const DexFile*> class_loader_1_dex_files =
784       MakeNonOwningPointerVector(classpath_dex_a);
785   for (auto& dex : classpath_dex_b) {
786     class_loader_1_dex_files.push_back(dex.get());
787   }
788   for (auto& dex : compilation_sources_raw) {
789     class_loader_1_dex_files.push_back(dex);
790   }
791   VerifyClassLoaderDexFiles(soa.Self(),
792                             class_loader_1,
793                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
794                             class_loader_1_dex_files);
795 
796   // Verify the second class loader
797   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
798   std::vector<const DexFile*> class_loader_2_dex_files =
799       MakeNonOwningPointerVector(classpath_dex_c);
800   VerifyClassLoaderDexFiles(soa.Self(),
801                             class_loader_2,
802                             WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
803                             class_loader_2_dex_files);
804 
805   // Verify the third class loader
806   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
807   std::vector<const DexFile*> class_loader_3_dex_files =
808       MakeNonOwningPointerVector(classpath_dex_d);
809   VerifyClassLoaderDexFiles(soa.Self(),
810                             class_loader_3,
811                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
812                             class_loader_3_dex_files);
813   // The last class loader should have the BootClassLoader as a parent.
814   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
815       WellKnownClasses::java_lang_BootClassLoader);
816 }
817 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibraries)818 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
819   // Setup the context.
820   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
821   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
822   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
823   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
824 
825   std::string context_spec =
826       "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
827       "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
828       "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
829 
830   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
831   ASSERT_TRUE(context->OpenDexFiles());
832 
833   // Setup the compilation sources.
834   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
835   std::vector<const DexFile*> compilation_sources_raw =
836       MakeNonOwningPointerVector(compilation_sources);
837 
838   // Create the class loader.
839   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
840   ASSERT_TRUE(jclass_loader != nullptr);
841 
842   // Verify the class loader.
843   ScopedObjectAccess soa(Thread::Current());
844 
845   StackHandleScope<4> hs(soa.Self());
846   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
847       soa.Decode<mirror::ClassLoader>(jclass_loader));
848 
849   // For the first class loader the class path dex files must come first and then the
850   // compilation sources.
851   std::vector<const DexFile*> class_loader_1_dex_files =
852       MakeNonOwningPointerVector(classpath_dex_a);
853   for (auto& dex : classpath_dex_b) {
854     class_loader_1_dex_files.push_back(dex.get());
855   }
856   for (auto& dex : compilation_sources_raw) {
857     class_loader_1_dex_files.push_back(dex);
858   }
859   VerifyClassLoaderDexFiles(soa.Self(),
860                             class_loader_1,
861                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
862                             class_loader_1_dex_files);
863 
864   // Verify the shared libraries.
865   ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
866   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
867   ASSERT_TRUE(raw_shared_libraries != nullptr);
868 
869   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
870       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
871   ASSERT_EQ(shared_libraries->GetLength(), 2);
872 
873   // Verify the first shared library.
874   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
875   std::vector<const DexFile*> class_loader_2_dex_files =
876       MakeNonOwningPointerVector(classpath_dex_c);
877   VerifyClassLoaderDexFiles(soa.Self(),
878                             class_loader_2,
879                             WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
880                             class_loader_2_dex_files);
881   raw_shared_libraries = field->GetObject(class_loader_2.Get());
882   ASSERT_TRUE(raw_shared_libraries == nullptr);
883 
884   // Verify the second shared library.
885   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
886   std::vector<const DexFile*> class_loader_3_dex_files =
887       MakeNonOwningPointerVector(classpath_dex_d);
888   VerifyClassLoaderDexFiles(soa.Self(),
889                             class_loader_3,
890                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
891                             class_loader_3_dex_files);
892   raw_shared_libraries = field->GetObject(class_loader_3.Get());
893   ASSERT_TRUE(raw_shared_libraries == nullptr);
894 
895   // All class loaders should have the BootClassLoader as a parent.
896   ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
897       WellKnownClasses::java_lang_BootClassLoader);
898   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
899       WellKnownClasses::java_lang_BootClassLoader);
900   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
901       WellKnownClasses::java_lang_BootClassLoader);
902 }
903 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibrariesInParentToo)904 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
905   // Setup the context.
906   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
907   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
908   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
909   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
910 
911   std::string context_spec =
912       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
913       "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
914       "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
915       "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
916 
917   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
918   ASSERT_TRUE(context->OpenDexFiles());
919 
920   // Setup the compilation sources.
921   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
922   std::vector<const DexFile*> compilation_sources_raw =
923       MakeNonOwningPointerVector(compilation_sources);
924 
925   // Create the class loader.
926   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
927   ASSERT_TRUE(jclass_loader != nullptr);
928 
929   // Verify the class loader.
930   ScopedObjectAccess soa(Thread::Current());
931 
932   StackHandleScope<6> hs(soa.Self());
933   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
934       soa.Decode<mirror::ClassLoader>(jclass_loader));
935 
936   // For the first class loader the class path dex files must come first and then the
937   // compilation sources.
938   std::vector<const DexFile*> class_loader_1_dex_files =
939       MakeNonOwningPointerVector(classpath_dex_a);
940   for (auto& dex : compilation_sources_raw) {
941     class_loader_1_dex_files.push_back(dex);
942   }
943   VerifyClassLoaderDexFiles(soa.Self(),
944                             class_loader_1,
945                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
946                             class_loader_1_dex_files);
947 
948   // Verify its shared library.
949   ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
950   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
951   ASSERT_TRUE(raw_shared_libraries != nullptr);
952 
953   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
954       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
955   ASSERT_EQ(shared_libraries->GetLength(), 1);
956 
957   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
958   std::vector<const DexFile*> class_loader_2_dex_files =
959       MakeNonOwningPointerVector(classpath_dex_b);
960   VerifyClassLoaderDexFiles(soa.Self(),
961                             class_loader_2,
962                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
963                             class_loader_2_dex_files);
964   raw_shared_libraries = field->GetObject(class_loader_2.Get());
965   ASSERT_TRUE(raw_shared_libraries == nullptr);
966 
967   // Verify the parent.
968   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
969   std::vector<const DexFile*> class_loader_3_dex_files =
970       MakeNonOwningPointerVector(classpath_dex_c);
971   VerifyClassLoaderDexFiles(soa.Self(),
972                             class_loader_3,
973                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
974                             class_loader_3_dex_files);
975 
976   // Verify its shared library.
977   raw_shared_libraries = field->GetObject(class_loader_3.Get());
978   ASSERT_TRUE(raw_shared_libraries != nullptr);
979 
980   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
981       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
982   ASSERT_EQ(shared_libraries->GetLength(), 1);
983 
984   Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
985   std::vector<const DexFile*> class_loader_4_dex_files =
986       MakeNonOwningPointerVector(classpath_dex_d);
987   VerifyClassLoaderDexFiles(soa.Self(),
988                             class_loader_4,
989                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
990                             class_loader_4_dex_files);
991   raw_shared_libraries = field->GetObject(class_loader_4.Get());
992   ASSERT_TRUE(raw_shared_libraries == nullptr);
993 
994   // Class loaders should have the BootClassLoader as a parent.
995   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
996       WellKnownClasses::java_lang_BootClassLoader);
997   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
998       WellKnownClasses::java_lang_BootClassLoader);
999   ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
1000       WellKnownClasses::java_lang_BootClassLoader);
1001 }
1002 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSharedLibrariesDependencies)1003 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
1004   // Setup the context.
1005   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
1006   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
1007   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
1008   std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
1009 
1010   std::string context_spec =
1011       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
1012       "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
1013       "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
1014       "PCL[" + CreateClassPath(classpath_dex_d) + "]";
1015 
1016   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
1017   ASSERT_TRUE(context->OpenDexFiles());
1018 
1019   // Setup the compilation sources.
1020   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1021   std::vector<const DexFile*> compilation_sources_raw =
1022       MakeNonOwningPointerVector(compilation_sources);
1023 
1024   // Create the class loader.
1025   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1026   ASSERT_TRUE(jclass_loader != nullptr);
1027 
1028   // Verify the class loader.
1029   ScopedObjectAccess soa(Thread::Current());
1030 
1031   StackHandleScope<6> hs(soa.Self());
1032   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1033       soa.Decode<mirror::ClassLoader>(jclass_loader));
1034 
1035   // For the first class loader the class path dex files must come first and then the
1036   // compilation sources.
1037   std::vector<const DexFile*> class_loader_1_dex_files =
1038       MakeNonOwningPointerVector(classpath_dex_a);
1039   for (auto& dex : compilation_sources_raw) {
1040     class_loader_1_dex_files.push_back(dex);
1041   }
1042   VerifyClassLoaderDexFiles(soa.Self(),
1043                             class_loader_1,
1044                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1045                             class_loader_1_dex_files);
1046 
1047   // Verify its shared library.
1048   ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
1049   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1050   ASSERT_TRUE(raw_shared_libraries != nullptr);
1051 
1052   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1053       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1054   ASSERT_EQ(shared_libraries->GetLength(), 1);
1055 
1056   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1057   std::vector<const DexFile*> class_loader_2_dex_files =
1058       MakeNonOwningPointerVector(classpath_dex_b);
1059   VerifyClassLoaderDexFiles(soa.Self(),
1060                             class_loader_2,
1061                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1062                             class_loader_2_dex_files);
1063 
1064   // Verify the shared library dependency of the shared library.
1065   raw_shared_libraries = field->GetObject(class_loader_2.Get());
1066   ASSERT_TRUE(raw_shared_libraries != nullptr);
1067 
1068   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1069       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1070   ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1071 
1072   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
1073   std::vector<const DexFile*> class_loader_3_dex_files =
1074       MakeNonOwningPointerVector(classpath_dex_c);
1075   VerifyClassLoaderDexFiles(soa.Self(),
1076                             class_loader_3,
1077                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1078                             class_loader_3_dex_files);
1079   raw_shared_libraries = field->GetObject(class_loader_3.Get());
1080   ASSERT_TRUE(raw_shared_libraries == nullptr);
1081 
1082   // Verify the parent.
1083   Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
1084   std::vector<const DexFile*> class_loader_4_dex_files =
1085       MakeNonOwningPointerVector(classpath_dex_d);
1086   VerifyClassLoaderDexFiles(soa.Self(),
1087                             class_loader_4,
1088                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1089                             class_loader_4_dex_files);
1090   raw_shared_libraries = field->GetObject(class_loader_4.Get());
1091   ASSERT_TRUE(raw_shared_libraries == nullptr);
1092 
1093   // Class loaders should have the BootClassLoader as a parent.
1094   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1095       WellKnownClasses::java_lang_BootClassLoader);
1096   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1097       WellKnownClasses::java_lang_BootClassLoader);
1098   ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
1099       WellKnownClasses::java_lang_BootClassLoader);
1100 }
1101 
TEST_F(ClassLoaderContextTest,RemoveSourceLocations)1102 TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
1103   std::unique_ptr<ClassLoaderContext> context =
1104       ClassLoaderContext::Create("PCL[a.dex]");
1105   dchecked_vector<std::string> classpath_dex;
1106   classpath_dex.push_back("a.dex");
1107   dchecked_vector<std::string> compilation_sources;
1108   compilation_sources.push_back("src.dex");
1109 
1110   // Nothing should be removed.
1111   ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
1112   VerifyClassLoaderPCL(context.get(), 0, "a.dex");
1113   // Classes should be removed.
1114   ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
1115   VerifyClassLoaderPCL(context.get(), 0, "");
1116 }
1117 
TEST_F(ClassLoaderContextTest,CreateClassLoaderWithSameSharedLibraries)1118 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
1119   // Setup the context.
1120   std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
1121   std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
1122   std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
1123 
1124   std::string context_spec =
1125       "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
1126       "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
1127       "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
1128       "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
1129 
1130   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
1131   ASSERT_TRUE(context->OpenDexFiles());
1132 
1133   // Setup the compilation sources.
1134   std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1135   std::vector<const DexFile*> compilation_sources_raw =
1136       MakeNonOwningPointerVector(compilation_sources);
1137 
1138   // Create the class loader.
1139   jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1140   ASSERT_TRUE(jclass_loader != nullptr);
1141 
1142   // Verify the class loader.
1143   ScopedObjectAccess soa(Thread::Current());
1144 
1145   StackHandleScope<6> hs(soa.Self());
1146   Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1147       soa.Decode<mirror::ClassLoader>(jclass_loader));
1148 
1149   // For the first class loader the class path dex files must come first and then the
1150   // compilation sources.
1151   std::vector<const DexFile*> class_loader_1_dex_files =
1152       MakeNonOwningPointerVector(classpath_dex_a);
1153   for (auto& dex : compilation_sources_raw) {
1154     class_loader_1_dex_files.push_back(dex);
1155   }
1156   VerifyClassLoaderDexFiles(soa.Self(),
1157                             class_loader_1,
1158                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1159                             class_loader_1_dex_files);
1160 
1161   // Verify its shared library.
1162   ArtField* field = WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders;
1163   ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1164   ASSERT_TRUE(raw_shared_libraries != nullptr);
1165 
1166   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1167       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1168   ASSERT_EQ(shared_libraries->GetLength(), 1);
1169 
1170   Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1171   std::vector<const DexFile*> class_loader_2_dex_files =
1172       MakeNonOwningPointerVector(classpath_dex_b);
1173   VerifyClassLoaderDexFiles(soa.Self(),
1174                             class_loader_2,
1175                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1176                             class_loader_2_dex_files);
1177 
1178   // Verify the parent.
1179   Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1180   std::vector<const DexFile*> class_loader_3_dex_files =
1181       MakeNonOwningPointerVector(classpath_dex_c);
1182   VerifyClassLoaderDexFiles(soa.Self(),
1183                             class_loader_3,
1184                             WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1185                             class_loader_3_dex_files);
1186 
1187   // Verify its shared library is the same as the child.
1188   raw_shared_libraries = field->GetObject(class_loader_3.Get());
1189   ASSERT_TRUE(raw_shared_libraries != nullptr);
1190   Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1191       hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1192   ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1193   ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
1194 
1195   // Class loaders should have the BootClassLoader as a parent.
1196   ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1197       WellKnownClasses::java_lang_BootClassLoader);
1198   ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1199       WellKnownClasses::java_lang_BootClassLoader);
1200 }
1201 
TEST_F(ClassLoaderContextTest,EncodeInOatFile)1202 TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1203   std::string dex1_name = GetTestDexFileName("Main");
1204   std::string dex2_name = GetTestDexFileName("MyClass");
1205   std::unique_ptr<ClassLoaderContext> context =
1206       ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1207   ASSERT_TRUE(context->OpenDexFiles());
1208 
1209   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1210   std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1211   std::string encoding = context->EncodeContextForOatFile("");
1212   std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1213       CreateClassPathWithChecksums(dex2) + "]";
1214   ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1215 }
1216 
1217 // Same as above, but passes `only_read_checksums=true` to `OpenDexFiles`.
TEST_F(ClassLoaderContextTest,EncodeInOatFileOnlyReadChecksums)1218 TEST_F(ClassLoaderContextTest, EncodeInOatFileOnlyReadChecksums) {
1219   std::string dex1_name = GetTestDexFileName("Main");
1220   std::string dex2_name = GetTestDexFileName("MyClass");
1221   std::unique_ptr<ClassLoaderContext> context =
1222       ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1223   ASSERT_TRUE(context->OpenDexFiles(
1224       /*classpath_dir=*/"", /*context_fds=*/{}, /*only_read_checksums=*/true));
1225 
1226   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1227   std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1228   std::string encoding = context->EncodeContextForOatFile("");
1229   std::string expected_encoding =
1230       "PCL[" + CreateClassPathWithChecksums(dex1) + ":" + CreateClassPathWithChecksums(dex2) + "]";
1231   ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1232 }
1233 
TEST_F(ClassLoaderContextTest,EncodeInOatFileIMC)1234 TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) {
1235   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1236   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1237 
1238   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1239   ASSERT_TRUE(context->OpenDexFiles());
1240 
1241   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1242   std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1243   ASSERT_EQ(dex2.size(), 1u);
1244 
1245   uint32_t expected_checksum = DexFileLoader::GetMultiDexChecksum(dex2);
1246 
1247   std::string encoding = context->EncodeContextForOatFile("");
1248   std::string expected_encoding = "IMC[<unknown>*" + std::to_string(expected_checksum) + "];PCL[" +
1249                                   CreateClassPathWithChecksums(dex1) + "]";
1250   ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1251 }
1252 
TEST_F(ClassLoaderContextTest,EncodeForDex2oat)1253 TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1254   std::string dex1_name = GetTestDexFileName("Main");
1255   std::string dex2_name = GetTestDexFileName("MultiDex");
1256   std::unique_ptr<ClassLoaderContext> context =
1257       ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1258   ASSERT_TRUE(context->OpenDexFiles());
1259 
1260   std::string encoding = context->EncodeContextForDex2oat("");
1261   std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1262   ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1263 }
1264 
TEST_F(ClassLoaderContextTest,EncodeForDex2oatIMC)1265 TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) {
1266   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1267   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1268 
1269   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1270   ASSERT_TRUE(context->OpenDexFiles());
1271 
1272   std::string encoding = context->EncodeContextForDex2oat("");
1273   std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]";
1274   ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1275 }
1276 
TEST_F(ClassLoaderContextTest,EncodeForDex2oatDuplicates)1277 TEST_F(ClassLoaderContextTest, EncodeForDex2oatDuplicates) {
1278   std::string dex_name = GetTestDexFileName("Main");
1279   std::unique_ptr<ClassLoaderContext> context =
1280       ClassLoaderContext::Create("PCL[" + dex_name + ":" + dex_name + "]");
1281   ASSERT_TRUE(context->OpenDexFiles());
1282 
1283   std::string encoding = context->EncodeContextForDex2oat("");
1284   std::string expected_encoding = "PCL[" + dex_name + "]";
1285   ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1286 }
1287 
TEST_F(ClassLoaderContextTest,EncodeContextsSinglePath)1288 TEST_F(ClassLoaderContextTest, EncodeContextsSinglePath) {
1289   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1290   std::unique_ptr<ClassLoaderContext> context =
1291       CreateContextForClassLoader(class_loader);
1292 
1293   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1294   ASSERT_EQ(1u, encodings.size());
1295   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1296 }
1297 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiDex)1298 TEST_F(ClassLoaderContextTest, EncodeContextsMultiDex) {
1299   jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1300   std::unique_ptr<ClassLoaderContext> context =
1301       CreateContextForClassLoader(class_loader);
1302 
1303   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1304   ASSERT_EQ(1u, encodings.size());
1305   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("MultiDex")));
1306 }
1307 
TEST_F(ClassLoaderContextTest,EncodeContextsRepeatedMultiDex)1308 TEST_F(ClassLoaderContextTest, EncodeContextsRepeatedMultiDex) {
1309   jobject top_class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1310   jobject middle_class_loader =
1311       LoadDexInPathClassLoader("Main", top_class_loader);
1312   jobject bottom_class_loader =
1313       LoadDexInPathClassLoader("MultiDex", middle_class_loader);
1314   std::unique_ptr<ClassLoaderContext> context =
1315       CreateContextForClassLoader(bottom_class_loader);
1316 
1317   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1318   ASSERT_EQ(1u, encodings.size());
1319 
1320   std::string main_dex_name = GetTestDexFileName("Main");
1321   std::string multidex_dex_name = GetTestDexFileName("MultiDex");
1322   ASSERT_EQ(
1323       "PCL[];PCL[" + main_dex_name + "];PCL[" + multidex_dex_name + "]",
1324       encodings.at(multidex_dex_name));
1325 }
1326 
TEST_F(ClassLoaderContextTest,EncodeContextsSinglePathWithShared)1327 TEST_F(ClassLoaderContextTest, EncodeContextsSinglePathWithShared) {
1328   jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1329 
1330   ScopedObjectAccess soa(Thread::Current());
1331   StackHandleScope<1> hs(soa.Self());
1332   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1333     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1334         soa.Self(),
1335         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1336         1));
1337   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1338 
1339   jobject class_loader_b = LoadDexInPathClassLoader(
1340       "Main", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1341 
1342   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1343 
1344   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1345   ASSERT_EQ(1u, encodings.size());
1346   ASSERT_EQ(
1347       "PCL[]{PCL[" + GetTestDexFileName("MyClass") + "]}",
1348       encodings.at(GetTestDexFileName("Main")));
1349 }
1350 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiplePaths)1351 TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePaths) {
1352   jobject class_loader = LoadDexInPathClassLoader(
1353       std::vector<std::string>{ "Main", "MultiDex"}, nullptr);
1354 
1355   std::unique_ptr<ClassLoaderContext> context =
1356       CreateContextForClassLoader(class_loader);
1357 
1358   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1359   ASSERT_EQ(2u, encodings.size());
1360   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1361   ASSERT_EQ(
1362       "PCL[" + GetTestDexFileName("Main") + "]", encodings.at(GetTestDexFileName("MultiDex")));
1363 }
1364 
TEST_F(ClassLoaderContextTest,EncodeContextsMultiplePathsWithShared)1365 TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePathsWithShared) {
1366   jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1367 
1368   ScopedObjectAccess soa(Thread::Current());
1369   StackHandleScope<1> hs(soa.Self());
1370   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1371     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1372         soa.Self(),
1373         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1374         1));
1375   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1376 
1377   jobject class_loader_b = LoadDexInPathClassLoader(
1378       std::vector<std::string> { "Main", "MultiDex" },
1379       nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1380 
1381   std::unique_ptr<ClassLoaderContext> context =
1382       CreateContextForClassLoader(class_loader_b);
1383 
1384   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1385   ASSERT_EQ(2u, encodings.size());
1386   const std::string context_suffix =
1387       "{PCL[" + GetTestDexFileName("MyClass") + "]}";
1388   ASSERT_EQ("PCL[]" + context_suffix, encodings.at(GetTestDexFileName("Main")));
1389   ASSERT_EQ(
1390       "PCL[" + GetTestDexFileName("Main") + "]" + context_suffix,
1391       encodings.at(GetTestDexFileName("MultiDex")));
1392 }
1393 
TEST_F(ClassLoaderContextTest,EncodeContextsIMC)1394 TEST_F(ClassLoaderContextTest, EncodeContextsIMC) {
1395   jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1396   jobject class_loader_b =
1397       LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1398 
1399   std::unique_ptr<ClassLoaderContext> context =
1400       CreateContextForClassLoader(class_loader_b);
1401 
1402   std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1403   ASSERT_EQ(1u, encodings.size());
1404   ASSERT_EQ(
1405       "IMC[];PCL[" + GetTestDexFileName("Main") + "]",
1406       encodings.at("<unknown>"));
1407 }
1408 
TEST_F(ClassLoaderContextTest,EncodeContextsForSingleDex)1409 TEST_F(ClassLoaderContextTest, EncodeContextsForSingleDex) {
1410   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1411   std::map<std::string, std::string> encodings =
1412       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1413   ASSERT_EQ(1u, encodings.size());
1414   ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1415 }
1416 
CreateForeignClassLoader()1417 static jobject CreateForeignClassLoader() {
1418   ScopedObjectAccess soa(Thread::Current());
1419 
1420   // We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
1421   // our foreign ClassLoader (this works because the runtime does proper instanceof checks before
1422   // operating on this object.
1423   ArtMethod* ctor =
1424       GetClassRoot<mirror::Object>()->FindClassMethod("<init>", "()V", kRuntimePointerSize);
1425   CHECK(ctor != nullptr);
1426   return soa.AddLocalReference<jobject>(ctor->NewObject<>(soa.Self()));
1427 }
1428 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedBase)1429 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
1430   std::map<std::string, std::string> empty;
1431   ASSERT_EQ(
1432       empty, ClassLoaderContext::EncodeClassPathContextsForClassLoader(CreateForeignClassLoader()));
1433 }
1434 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChain)1435 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChain) {
1436   jobject class_loader = LoadDexInPathClassLoader("Main", CreateForeignClassLoader());
1437   std::map<std::string, std::string> encodings =
1438       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1439   ASSERT_EQ(1u, encodings.size());
1440   ASSERT_EQ(
1441       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1442       encodings.at(GetTestDexFileName("Main")));
1443 }
1444 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChainMultiPath)1445 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiPath) {
1446   jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "MyClass" },
1447                                                   CreateForeignClassLoader());
1448   std::map<std::string, std::string> encodings =
1449       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1450   ASSERT_EQ(2u, encodings.size());
1451   ASSERT_EQ(
1452       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1453       encodings.at(GetTestDexFileName("Main")));
1454   ASSERT_EQ(
1455       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1456       encodings.at(GetTestDexFileName("MyClass")));
1457 }
1458 
TEST_F(ClassLoaderContextTest,EncodeContextsForUnsupportedChainMultiDex)1459 TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiDex) {
1460   jobject class_loader = LoadDexInPathClassLoader("MultiDex", CreateForeignClassLoader());
1461   std::map<std::string, std::string> encodings =
1462       ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1463   ASSERT_EQ(1u, encodings.size());
1464   ASSERT_EQ(
1465       ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1466       encodings.at(GetTestDexFileName("MultiDex")));
1467 }
1468 
TEST_F(ClassLoaderContextTest,IsValidEncoding)1469 TEST_F(ClassLoaderContextTest, IsValidEncoding) {
1470   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[]"));
1471   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex]"));
1472   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex];PCL[bar.dex]"));
1473   ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("DLC[];PCL[bar.dex]"));
1474   ASSERT_TRUE(
1475       ClassLoaderContext::IsValidEncoding(
1476         ClassLoaderContext::kUnsupportedClassLoaderContextEncoding));
1477   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("not_valid"));
1478   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("[]"));
1479   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("FCL[]"));
1480   ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("foo.dex:bar.dex"));
1481 }
1482 
1483 // TODO(calin) add a test which creates the context for a class loader together with dex_elements.
TEST_F(ClassLoaderContextTest,CreateContextForClassLoader)1484 TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1485   // The chain is
1486   //    ClassLoaderA (PathClassLoader)
1487   //       ^
1488   //       |
1489   //    ClassLoaderB (DelegateLastClassLoader)
1490   //       ^
1491   //       |
1492   //    ClassLoaderC (PathClassLoader)
1493   //       ^
1494   //       |
1495   //    ClassLoaderD (DelegateLastClassLoader)
1496 
1497   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1498   jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1499   jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1500   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1501 
1502   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1503 
1504   VerifyContextForClassLoader(context.get());
1505   VerifyContextSize(context.get(), 4);
1506 
1507   VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1508   VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1509   VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1510   VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1511 }
1512 
TEST_F(ClassLoaderContextTest,CreateContextForClassLoaderIMC)1513 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1514   // The chain is
1515   //    ClassLoaderA (PathClassLoader)
1516   //       ^
1517   //       |
1518   //    ClassLoaderB (InMemoryDexClassLoader)
1519   //       ^
1520   //       |
1521   //    ClassLoaderC (InMemoryDexClassLoader)
1522   //       ^
1523   //       |
1524   //    ClassLoaderD (DelegateLastClassLoader)
1525 
1526   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1527   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1528   jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1529   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1530 
1531   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1532 
1533   VerifyContextForClassLoader(context.get());
1534   VerifyContextSize(context.get(), 4);
1535 
1536   VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1537   VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1538   VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1539   VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1540 }
1541 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatch)1542 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1543   std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1544   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1545   // Pretend that we successfully open the dex files to pass the DCHECKS.
1546   // (as it's much easier to test all the corner cases without relying on actual dex files).
1547   PretendContextOpenedDexFilesForChecksums(context.get());
1548 
1549   VerifyContextSize(context.get(), 2);
1550   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1551   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1552 
1553   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1554             ClassLoaderContext::VerificationResult::kVerifies);
1555 
1556   std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
1557   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1558             ClassLoaderContext::VerificationResult::kMismatch);
1559 
1560   std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
1561   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1562             ClassLoaderContext::VerificationResult::kMismatch);
1563 
1564   std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
1565   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1566             ClassLoaderContext::VerificationResult::kMismatch);
1567 
1568   std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
1569   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1570             ClassLoaderContext::VerificationResult::kMismatch);
1571 
1572   std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
1573   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1574             ClassLoaderContext::VerificationResult::kMismatch);
1575 
1576   std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
1577   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1578             ClassLoaderContext::VerificationResult::kMismatch);
1579 
1580   std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
1581   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1582             ClassLoaderContext::VerificationResult::kMismatch);
1583 }
1584 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextWithIMCMatch)1585 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
1586   std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]";
1587   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1588   // Pretend that we successfully open the dex files to pass the DCHECKS.
1589   // (as it's much easier to test all the corner cases without relying on actual dex files).
1590   PretendContextOpenedDexFiles(context.get());
1591 
1592   VerifyContextSize(context.get(), 3);
1593   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1594   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1595   VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
1596 
1597   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1598             ClassLoaderContext::VerificationResult::kVerifies);
1599 }
1600 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchWithSL)1601 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1602   std::string context_spec =
1603       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1604       ";DLC[c.dex*890]";
1605   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1606   // Pretend that we successfully open the dex files to pass the DCHECKS.
1607   // (as it's much easier to test all the corner cases without relying on actual dex files).
1608   PretendContextOpenedDexFiles(context.get());
1609 
1610   VerifyContextSize(context.get(), 2);
1611   VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1612   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1613   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1614   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1615 
1616   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1617             ClassLoaderContext::VerificationResult::kVerifies);
1618 
1619   std::string wrong_class_loader_type =
1620       "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1621       ";DLC[c.dex*890]";
1622   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1623             ClassLoaderContext::VerificationResult::kMismatch);
1624 
1625   std::string wrong_class_loader_order =
1626       "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1627       ";DLC[c.dex*890]";
1628   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1629             ClassLoaderContext::VerificationResult::kMismatch);
1630 
1631   std::string wrong_classpath_order =
1632       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1633       ";DLC[c.dex*890]";
1634   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1635             ClassLoaderContext::VerificationResult::kMismatch);
1636 
1637   std::string wrong_checksum =
1638       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1639       ";DLC[c.dex*890]";
1640   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1641             ClassLoaderContext::VerificationResult::kMismatch);
1642 
1643   std::string wrong_extra_class_loader =
1644       "PCL[a.dex*123:b.dex*456]"
1645       "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1646       ";DLC[c.dex*890]";
1647   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1648             ClassLoaderContext::VerificationResult::kMismatch);
1649 
1650   std::string wrong_extra_classpath =
1651       "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321:i.dex#444];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1652       ";DLC[c.dex*890]";
1653   ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1654             ClassLoaderContext::VerificationResult::kMismatch);
1655 }
1656 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchWithIMCSL)1657 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1658   std::string context_spec =
1659       "IMC[<unknown>*123:<unknown>*456]"
1660       "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1661       "DLC[c.dex*890]";
1662   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1663   // Pretend that we successfully open the dex files to pass the DCHECKS.
1664   // (as it's much easier to test all the corner cases without relying on actual dex files).
1665   PretendContextOpenedDexFiles(context.get());
1666 
1667   VerifyContextSize(context.get(), 2);
1668   VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
1669   VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1670   VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1671   VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
1672 
1673   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1674             ClassLoaderContext::VerificationResult::kVerifies);
1675 }
1676 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterResolvingSymlinks)1677 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterResolvingSymlinks) {
1678   {
1679     std::ofstream ofs(scratch_path_ + "/foo.jar");
1680     ASSERT_TRUE(ofs);
1681   }
1682   std::filesystem::create_directory_symlink(scratch_path_, scratch_path_ + "/bar");
1683 
1684   std::string context_spec =
1685       android::base::StringPrintf("PCL[%s/foo.jar*123:%s/foo.jar!classes2.dex*456]",
1686                                   scratch_path_.c_str(),
1687                                   scratch_path_.c_str());
1688   std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1689   PretendContextOpenedDexFilesForChecksums(context.get());
1690 
1691   std::string context_spec_with_symlinks =
1692       android::base::StringPrintf("PCL[%s/bar/foo.jar*123:%s/bar/foo.jar!classes2.dex*456]",
1693                                   scratch_path_.c_str(),
1694                                   scratch_path_.c_str());
1695   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec_with_symlinks),
1696             ClassLoaderContext::VerificationResult::kVerifies);
1697 }
1698 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncoding)1699 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1700   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1701   jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1702   jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1703   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1704 
1705   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1706 
1707   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1708   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1709             ClassLoaderContext::VerificationResult::kVerifies);
1710 
1711   std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1712   size_t pos = dex_location.rfind('/');
1713   ASSERT_NE(std::string::npos, pos);
1714   std::string parent = dex_location.substr(0, pos);
1715 
1716   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1717   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1718   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1719             ClassLoaderContext::VerificationResult::kVerifies);
1720 }
1721 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncodingIMC)1722 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1723   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1724   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1725   jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1726   jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1727 
1728   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1729 
1730   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1731   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1732             ClassLoaderContext::VerificationResult::kVerifies);
1733 
1734   std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1735   size_t pos = dex_location.rfind('/');
1736   ASSERT_NE(std::string::npos, pos);
1737   std::string parent = dex_location.substr(0, pos);
1738 
1739   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1740   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1741   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1742             ClassLoaderContext::VerificationResult::kVerifies);
1743 }
1744 
TEST_F(ClassLoaderContextTest,VerifyClassLoaderContextMatchAfterEncodingMultidex)1745 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1746   jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1747 
1748   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1749 
1750   std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1751   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1752             ClassLoaderContext::VerificationResult::kVerifies);
1753 
1754   std::string dex_location = GetTestDexFileName("MultiDex");
1755   size_t pos = dex_location.rfind('/');
1756   ASSERT_NE(std::string::npos, pos);
1757   std::string parent = dex_location.substr(0, pos);
1758 
1759   std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1760   ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1761   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1762             ClassLoaderContext::VerificationResult::kVerifies);
1763 }
1764 
TEST_F(ClassLoaderContextTest,CreateContextForClassLoaderWithSharedLibraries)1765 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1766   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1767 
1768   ScopedObjectAccess soa(Thread::Current());
1769   StackHandleScope<1> hs(soa.Self());
1770   Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1771     mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1772         soa.Self(),
1773         GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1774         1));
1775   libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1776 
1777   jobject class_loader_b = LoadDexInPathClassLoader(
1778       "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1779 
1780   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1781   ASSERT_TRUE(context != nullptr);
1782   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1783   VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1784   dex_files = OpenTestDexFiles("ForClassLoaderA");
1785   VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1786 
1787   ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1788             ClassLoaderContext::VerificationResult::kVerifies);
1789 }
1790 
TEST_F(ClassLoaderContextTest,CheckForDuplicateDexFilesNotFoundSingleCL)1791 TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesNotFoundSingleCL) {
1792   jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1793 
1794   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1795 
1796   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(
1797       std::vector<const DexFile*>());
1798   ASSERT_EQ(0u, result.size());
1799 
1800   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
1801   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1802   result = context->CheckForDuplicateDexFiles(dex1_raw);
1803   ASSERT_EQ(0u, result.size());
1804 }
1805 
TEST_F(ClassLoaderContextTest,CheckForDuplicateDexFilesFound)1806 TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFilesFound) {
1807   jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "Main" }, nullptr);
1808 
1809   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1810 
1811   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1812   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1813   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1814   ASSERT_EQ(1u, result.size()) << context->EncodeContextForOatFile("");
1815   ASSERT_EQ(dex1_raw[0], *(result.begin()));
1816 }
1817 
1818 
TEST_F(ClassLoaderContextTest,CheckForDuplicateCrossCLNotFound)1819 TEST_F(ClassLoaderContextTest, CheckForDuplicateCrossCLNotFound) {
1820   jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1821   jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1822 
1823   std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1824 
1825   std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("ForClassLoaderA");
1826   std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1827   std::set<const DexFile*> result = context->CheckForDuplicateDexFiles(dex1_raw);
1828   ASSERT_EQ(0u, result.size());
1829 }
1830 
1831 }  // namespace art
1832