blob: ff466c0d960b5f43fc46dc1c57fedbd7ba433009 [file] [log] [blame]
Calin Juravle87e2cb62017-06-13 21:48:45 -07001/*
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
Andreas Gampe72527382017-09-02 16:53:03 -070017#include "class_loader_context.h"
18
Calin Juravle87e2cb62017-06-13 21:48:45 -070019#include <gtest/gtest.h>
20
Andreas Gampe72527382017-09-02 16:53:03 -070021#include "android-base/strings.h"
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +000022#include "art_field-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070023#include "base/dchecked_vector.h"
24#include "base/stl_util.h"
25#include "class_linker.h"
Vladimir Marko5868ada2020-05-12 11:50:34 +010026#include "class_root-inl.h"
Calin Juravle821a2592017-08-11 14:33:38 -070027#include "common_runtime_test.h"
David Sehr9e734c72018-01-04 17:56:19 -080028#include "dex/dex_file.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070029#include "handle_scope-inl.h"
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +000030#include "jni/jni_internal.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070031#include "mirror/class.h"
Vladimir Markobdc93b42019-03-29 16:12:04 +000032#include "mirror/class_loader-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070033#include "mirror/object-inl.h"
Nicolas Geoffraye1672732018-11-30 01:09:49 +000034#include "mirror/object_array-alloc-inl.h"
Calin Juravle87e2cb62017-06-13 21:48:45 -070035#include "oat_file_assistant.h"
36#include "runtime.h"
37#include "scoped_thread_state_change-inl.h"
38#include "thread.h"
39#include "well_known_classes.h"
40
41namespace art {
42
43class ClassLoaderContextTest : public CommonRuntimeTest {
44 public:
45 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) {
46 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000047 ASSERT_EQ(expected_size, context->GetParentChainSize());
Calin Juravle87e2cb62017-06-13 21:48:45 -070048 }
49
50 void VerifyClassLoaderPCL(ClassLoaderContext* context,
51 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070052 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070053 VerifyClassLoaderInfo(
54 context, index, ClassLoaderContext::kPathClassLoader, classpath);
55 }
56
57 void VerifyClassLoaderDLC(ClassLoaderContext* context,
58 size_t index,
Calin Juravle57d0acc2017-07-11 17:41:30 -070059 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -070060 VerifyClassLoaderInfo(
61 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath);
62 }
63
David Brazdil1a9ac532019-03-05 11:57:13 +000064 void VerifyClassLoaderIMC(ClassLoaderContext* context,
65 size_t index,
66 const std::string& classpath) {
67 VerifyClassLoaderInfo(
68 context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath);
69 }
70
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000071 void VerifyClassLoaderSharedLibraryPCL(ClassLoaderContext* context,
72 size_t loader_index,
73 size_t shared_library_index,
74 const std::string& classpath) {
75 VerifyClassLoaderInfoSL(
76 context, loader_index, shared_library_index, ClassLoaderContext::kPathClassLoader,
77 classpath);
78 }
79
David Brazdil1a9ac532019-03-05 11:57:13 +000080 void VerifyClassLoaderSharedLibraryIMC(ClassLoaderContext* context,
81 size_t loader_index,
82 size_t shared_library_index,
83 const std::string& classpath) {
84 VerifyClassLoaderInfoSL(
85 context, loader_index, shared_library_index, ClassLoaderContext::kInMemoryDexClassLoader,
86 classpath);
87 }
88
Nicolas Geoffray06af3b42018-10-29 10:39:04 +000089 void VerifySharedLibrariesSize(ClassLoaderContext* context,
90 size_t loader_index,
91 size_t expected_size) {
92 ASSERT_TRUE(context != nullptr);
93 ASSERT_GT(context->GetParentChainSize(), loader_index);
94 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
95 ASSERT_EQ(info.shared_libraries.size(), expected_size);
96 }
97
98 void VerifyClassLoaderSharedLibraryDLC(ClassLoaderContext* context,
99 size_t loader_index,
100 size_t shared_library_index,
101 const std::string& classpath) {
102 VerifyClassLoaderInfoSL(
103 context, loader_index, shared_library_index, ClassLoaderContext::kDelegateLastClassLoader,
104 classpath);
105 }
106
Calin Juravle57d0acc2017-07-11 17:41:30 -0700107 void VerifyClassLoaderPCLFromTestDex(ClassLoaderContext* context,
108 size_t index,
109 const std::string& test_name) {
110 VerifyClassLoaderFromTestDex(
111 context, index, ClassLoaderContext::kPathClassLoader, test_name);
112 }
113
114 void VerifyClassLoaderDLCFromTestDex(ClassLoaderContext* context,
115 size_t index,
116 const std::string& test_name) {
117 VerifyClassLoaderFromTestDex(
118 context, index, ClassLoaderContext::kDelegateLastClassLoader, test_name);
119 }
120
David Brazdil1a9ac532019-03-05 11:57:13 +0000121 void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context,
122 size_t index,
123 const std::string& test_name) {
124 VerifyClassLoaderFromTestDex(
David Brazdil93d339d2019-03-27 09:56:45 +0000125 context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +0000126 }
127
Andreas Gampe72527382017-09-02 16:53:03 -0700128 enum class LocationCheck {
129 kEquals,
130 kEndsWith
131 };
132 enum class BaseLocationCheck {
133 kEquals,
134 kEndsWith
135 };
136
Calin Juravle92003fe2017-09-06 02:22:57 +0000137 static bool IsAbsoluteLocation(const std::string& location) {
138 return !location.empty() && location[0] == '/';
139 }
140
Calin Juravle87e2cb62017-06-13 21:48:45 -0700141 void VerifyOpenDexFiles(
142 ClassLoaderContext* context,
143 size_t index,
David Brazdil93d339d2019-03-27 09:56:45 +0000144 std::vector<std::unique_ptr<const DexFile>>* all_dex_files,
145 bool classpath_matches_dex_location = true) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700146 ASSERT_TRUE(context != nullptr);
147 ASSERT_TRUE(context->dex_files_open_attempted_);
148 ASSERT_TRUE(context->dex_files_open_result_);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000149 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700150 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
151 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700152 size_t cur_open_dex_index = 0;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700153 for (size_t k = 0; k < all_dex_files->size(); k++) {
154 std::unique_ptr<const DexFile>& opened_dex_file =
Calin Juravle87e2cb62017-06-13 21:48:45 -0700155 info.opened_dex_files[cur_open_dex_index++];
Calin Juravlec5b215f2017-09-12 14:49:37 -0700156 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle87e2cb62017-06-13 21:48:45 -0700157
Calin Juravle92003fe2017-09-06 02:22:57 +0000158 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700159
Calin Juravle92003fe2017-09-06 02:22:57 +0000160 const std::string& opened_location = opened_dex_file->GetLocation();
161 if (!IsAbsoluteLocation(opened_location)) {
162 // If the opened location is relative (it was open from a relative path without a
163 // classpath_dir) it might not match the expected location which is absolute in tests).
164 // So we compare the endings (the checksum will validate it's actually the same file).
165 ASSERT_EQ(0, expected_location.compare(
166 expected_location.length() - opened_location.length(),
167 opened_location.length(),
168 opened_location));
169 } else {
170 ASSERT_EQ(expected_location, opened_location);
171 }
Calin Juravlec5b215f2017-09-12 14:49:37 -0700172 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
David Brazdil93d339d2019-03-27 09:56:45 +0000173 if (classpath_matches_dex_location) {
174 ASSERT_EQ(info.classpath[k], opened_location);
175 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700176 }
177 }
178
Calin Juravle57d0acc2017-07-11 17:41:30 -0700179 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
180 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
181 }
182
Calin Juravle3f918642017-07-11 19:04:20 -0700183 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
184 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700185 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700186 return nullptr;
187 }
188 return context;
189 }
190
Calin Juravle57d0acc2017-07-11 17:41:30 -0700191 void VerifyContextForClassLoader(ClassLoaderContext* context) {
192 ASSERT_TRUE(context != nullptr);
193 ASSERT_TRUE(context->dex_files_open_attempted_);
194 ASSERT_TRUE(context->dex_files_open_result_);
195 ASSERT_FALSE(context->owns_the_dex_files_);
196 ASSERT_FALSE(context->special_shared_library_);
197 }
198
Calin Juravlec79470d2017-07-12 17:37:42 -0700199 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
200 Handle<mirror::ClassLoader> class_loader,
201 jclass type,
202 std::vector<const DexFile*>& expected_dex_files)
203 REQUIRES_SHARED(Locks::mutator_lock_) {
204 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
205
206 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
207 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
208
209 for (size_t i = 0; i < expected_dex_files.size(); i++) {
210 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
211 class_loader_dex_files[i]->GetLocation());
212 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
213 class_loader_dex_files[i]->GetLocationChecksum());
214 }
215 }
216
Calin Juravlec5b215f2017-09-12 14:49:37 -0700217 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
218 context->dex_files_open_attempted_ = true;
219 context->dex_files_open_result_ = true;
220 }
221
Calin Juravle87e2cb62017-06-13 21:48:45 -0700222 private:
223 void VerifyClassLoaderInfo(ClassLoaderContext* context,
224 size_t index,
225 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700226 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700227 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000228 ASSERT_GT(context->GetParentChainSize(), index);
229 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700230 ASSERT_EQ(type, info.type);
231 std::vector<std::string> expected_classpath;
232 Split(classpath, ':', &expected_classpath);
233 ASSERT_EQ(expected_classpath, info.classpath);
234 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700235
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000236 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
237 size_t loader_index,
238 size_t shared_library_index,
239 ClassLoaderContext::ClassLoaderType type,
240 const std::string& classpath) {
241 ASSERT_TRUE(context != nullptr);
242 ASSERT_GT(context->GetParentChainSize(), loader_index);
243 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
244 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
245 const ClassLoaderContext::ClassLoaderInfo& sl =
246 *info.shared_libraries[shared_library_index].get();
247 ASSERT_EQ(type, info.type);
248 std::vector<std::string> expected_classpath;
249 Split(classpath, ':', &expected_classpath);
250 ASSERT_EQ(expected_classpath, sl.classpath);
251 }
252
Calin Juravle57d0acc2017-07-11 17:41:30 -0700253 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
254 size_t index,
255 ClassLoaderContext::ClassLoaderType type,
David Brazdil93d339d2019-03-27 09:56:45 +0000256 const std::string& test_name,
257 const std::string& classpath = "") {
Calin Juravle57d0acc2017-07-11 17:41:30 -0700258 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700259
David Brazdil93d339d2019-03-27 09:56:45 +0000260 // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath.
261 // Otherwise assume it is equal to dex location (here test dex file name).
262 VerifyClassLoaderInfo(context,
263 index,
264 type,
265 classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath);
266 VerifyOpenDexFiles(context,
267 index,
268 &dex_files,
269 /* classpath_matches_dex_location= */ classpath.empty());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700270 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700271};
272
Calin Juravle1a509c82017-07-24 16:51:21 -0700273TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
274 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
275 // An empty context should create a single empty PathClassLoader.
276 VerifyContextSize(context.get(), 1);
277 VerifyClassLoaderPCL(context.get(), 0, "");
278}
279
280TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) {
281 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
282 // An shared library context should have no class loader in the chain.
283 VerifyContextSize(context.get(), 0);
284}
285
Calin Juravle87e2cb62017-06-13 21:48:45 -0700286TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000287 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700288 VerifyContextSize(context.get(), 1);
289 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
290}
291
292TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000293 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700294 VerifyContextSize(context.get(), 1);
295 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
296}
297
David Brazdil93d339d2019-03-27 09:56:45 +0000298TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
299 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
300 ASSERT_FALSE(context == nullptr);
301}
302
303TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000304 // IMC is treated as an unknown class loader unless a checksum is provided.
305 // This is because the dex location is always bogus.
David Brazdil93d339d2019-03-27 09:56:45 +0000306 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
307 ASSERT_TRUE(context == nullptr);
308}
309
310TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
311 // IMC does not support arbitrary dex location. A magic marker must be used
312 // otherwise the spec should be rejected.
313 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000314 ASSERT_TRUE(context == nullptr);
315}
316
Calin Juravle87e2cb62017-06-13 21:48:45 -0700317TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
318 std::unique_ptr<ClassLoaderContext> context =
319 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
320 VerifyContextSize(context.get(), 3);
321 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
322 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
323 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
324}
325
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000326TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
327 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
328 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
329 VerifyContextSize(context.get(), 2);
330 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
331 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
332 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
333 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
334}
335
336TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
337 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
338 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
339 VerifyContextSize(context.get(), 1);
340 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
341}
342
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000343TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
344 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
345 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
346 VerifyContextSize(context.get(), 1);
347 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
348}
349
350TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
351 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
352 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
353 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
354 VerifyContextSize(context.get(), 1);
355 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
356 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
357 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
358 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
359 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
360}
361
Calin Juravle87e2cb62017-06-13 21:48:45 -0700362TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
363 std::unique_ptr<ClassLoaderContext> context =
364 ClassLoaderContext::Create("DLC[]");
365 VerifyContextSize(context.get(), 1);
366 VerifyClassLoaderDLC(context.get(), 0, "");
367}
368
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000369TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
370 std::unique_ptr<ClassLoaderContext> context =
371 ClassLoaderContext::Create("DLC[]{}");
372 VerifyContextSize(context.get(), 1);
373 VerifySharedLibrariesSize(context.get(), 0, 0);
374}
375
Calin Juravle87e2cb62017-06-13 21:48:45 -0700376TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
377 std::unique_ptr<ClassLoaderContext> context =
378 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
379 VerifyContextSize(context.get(), 0);
380}
381
382TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
383 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
384 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
385 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
386 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
387 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
388 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000389 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
390 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
391 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
392 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
393 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000394 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
395 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
396 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
397 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700398}
399
400TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
401 std::unique_ptr<ClassLoaderContext> context =
402 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
403 VerifyContextSize(context.get(), 1);
404 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
405}
406
407TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
408 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700409 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700410 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700411
Calin Juravle92003fe2017-09-06 02:22:57 +0000412
Calin Juravle87e2cb62017-06-13 21:48:45 -0700413 std::unique_ptr<ClassLoaderContext> context =
414 ClassLoaderContext::Create(
415 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
416 "DLC[" + dex_name + "]");
417
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700418 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700419
420 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700421
Calin Juravlec5b215f2017-09-12 14:49:37 -0700422 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
423 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
424 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
425 all_dex_files0.emplace_back(myclass_dex_files[i].release());
426 }
427 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
428
429 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
430 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700431}
432
Alex Light77ef93b2018-01-12 11:18:31 -0800433// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
434// TODO We should somehow support this in all situations. b/72042237.
435static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100436 int cwd_len = strlen(cwd);
437 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800438 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700439 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100440 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
441 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800442 *out = in.substr(start_position);
443 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700444}
445
446TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
447 char cwd_buf[4096];
448 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
449 PLOG(FATAL) << "Could not get working directory";
450 }
Alex Light77ef93b2018-01-12 11:18:31 -0800451 std::string multidex_name;
452 std::string myclass_dex_name;
453 std::string dex_name;
454 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
455 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
456 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
457 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
458 << "relative path.";
459 SUCCEED();
460 return;
461 }
Andreas Gampe72527382017-09-02 16:53:03 -0700462
Andreas Gampe72527382017-09-02 16:53:03 -0700463 std::unique_ptr<ClassLoaderContext> context =
464 ClassLoaderContext::Create(
465 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
466 "DLC[" + dex_name + "]");
467
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700468 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700469
Calin Juravlec5b215f2017-09-12 14:49:37 -0700470 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
471 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
472 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
473 all_dex_files0.emplace_back(myclass_dex_files[i].release());
474 }
475 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700476
Calin Juravlec5b215f2017-09-12 14:49:37 -0700477 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
478 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700479}
480
481TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
482 char cwd_buf[4096];
483 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
484 PLOG(FATAL) << "Could not get working directory";
485 }
Alex Light77ef93b2018-01-12 11:18:31 -0800486 std::string multidex_name;
487 std::string myclass_dex_name;
488 std::string dex_name;
489 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
490 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
491 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
492 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
493 << "no relative path.";
494 SUCCEED();
495 return;
496 }
Andreas Gampe72527382017-09-02 16:53:03 -0700497 std::unique_ptr<ClassLoaderContext> context =
498 ClassLoaderContext::Create(
499 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
500 "DLC[" + dex_name + "]");
501
502 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
503
504 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700505 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
506 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
507 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
508 all_dex_files0.emplace_back(myclass_dex_files[i].release());
509 }
510 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700511
Calin Juravlec5b215f2017-09-12 14:49:37 -0700512 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
513 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700514}
515
Calin Juravle87e2cb62017-06-13 21:48:45 -0700516TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
517 std::string dex_name = GetTestDexFileName("Main");
518 std::unique_ptr<ClassLoaderContext> context =
519 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
520 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
521}
522
David Brazdil1a9ac532019-03-05 11:57:13 +0000523TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
524 std::unique_ptr<ClassLoaderContext> context;
525 std::string dex_name = GetTestDexFileName("Main");
526
David Brazdil93d339d2019-03-27 09:56:45 +0000527 context = ParseContextWithChecksums("IMC[<unknown>*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000528 VerifyContextSize(context.get(), 1);
529 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
530}
531
Calin Juravle87e2cb62017-06-13 21:48:45 -0700532TEST_F(ClassLoaderContextTest, CreateClassLoader) {
533 std::string dex_name = GetTestDexFileName("Main");
534 std::unique_ptr<ClassLoaderContext> context =
535 ClassLoaderContext::Create("PCL[" + dex_name + "]");
536 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
537
538 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
539 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
540
541 std::vector<const DexFile*> compilation_sources_raw =
542 MakeNonOwningPointerVector(compilation_sources);
543 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
544 ASSERT_TRUE(jclass_loader != nullptr);
545
546 ScopedObjectAccess soa(Thread::Current());
547
Calin Juravlec79470d2017-07-12 17:37:42 -0700548 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700549 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
550 soa.Decode<mirror::ClassLoader>(jclass_loader));
551
552 ASSERT_TRUE(class_loader->GetClass() ==
553 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
554 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
555 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
556
Calin Juravlec79470d2017-07-12 17:37:42 -0700557 // For the first class loader the class path dex files must come first and then the
558 // compilation sources.
559 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
560 for (auto& dex : compilation_sources_raw) {
561 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700562 }
563
Calin Juravlec79470d2017-07-12 17:37:42 -0700564 VerifyClassLoaderDexFiles(soa,
565 class_loader,
566 WellKnownClasses::dalvik_system_PathClassLoader,
567 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700568}
569
Calin Juravle7b0648a2017-07-07 18:40:50 -0700570TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
571 std::unique_ptr<ClassLoaderContext> context =
572 ClassLoaderContext::Create("");
573 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
574
575 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
576
577 std::vector<const DexFile*> compilation_sources_raw =
578 MakeNonOwningPointerVector(compilation_sources);
579 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
580 ASSERT_TRUE(jclass_loader != nullptr);
581
582 ScopedObjectAccess soa(Thread::Current());
583
Calin Juravlec79470d2017-07-12 17:37:42 -0700584 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700585 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
586 soa.Decode<mirror::ClassLoader>(jclass_loader));
587
Calin Juravlec79470d2017-07-12 17:37:42 -0700588 // An empty context should create a single PathClassLoader with only the compilation sources.
589 VerifyClassLoaderDexFiles(soa,
590 class_loader,
591 WellKnownClasses::dalvik_system_PathClassLoader,
592 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700593 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
594 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700595}
596
Calin Juravle1a509c82017-07-24 16:51:21 -0700597TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
598 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
599
600 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
601
602 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
603
604 std::vector<const DexFile*> compilation_sources_raw =
605 MakeNonOwningPointerVector(compilation_sources);
606 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
607 ASSERT_TRUE(jclass_loader != nullptr);
608
609 ScopedObjectAccess soa(Thread::Current());
610
611 StackHandleScope<1> hs(soa.Self());
612 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
613 soa.Decode<mirror::ClassLoader>(jclass_loader));
614
615 // A shared library context should create a single PathClassLoader with only the compilation
616 // sources.
617 VerifyClassLoaderDexFiles(soa,
618 class_loader,
619 WellKnownClasses::dalvik_system_PathClassLoader,
620 compilation_sources_raw);
621 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
622 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
623}
624
Calin Juravlec79470d2017-07-12 17:37:42 -0700625TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
626 // Setup the context.
627 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
628 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
629 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
630 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
631
632 std::string context_spec =
633 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
634 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
635 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
636
637 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
638 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
639
640 // Setup the compilation sources.
641 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
642 std::vector<const DexFile*> compilation_sources_raw =
643 MakeNonOwningPointerVector(compilation_sources);
644
645 // Create the class loader.
646 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
647 ASSERT_TRUE(jclass_loader != nullptr);
648
649 // Verify the class loader.
650 ScopedObjectAccess soa(Thread::Current());
651
652 StackHandleScope<3> hs(soa.Self());
653 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
654 soa.Decode<mirror::ClassLoader>(jclass_loader));
655
656 // Verify the first class loader
657
658 // For the first class loader the class path dex files must come first and then the
659 // compilation sources.
660 std::vector<const DexFile*> class_loader_1_dex_files =
661 MakeNonOwningPointerVector(classpath_dex_a);
662 for (auto& dex : classpath_dex_b) {
663 class_loader_1_dex_files.push_back(dex.get());
664 }
665 for (auto& dex : compilation_sources_raw) {
666 class_loader_1_dex_files.push_back(dex);
667 }
668 VerifyClassLoaderDexFiles(soa,
669 class_loader_1,
670 WellKnownClasses::dalvik_system_PathClassLoader,
671 class_loader_1_dex_files);
672
673 // Verify the second class loader
674 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
675 std::vector<const DexFile*> class_loader_2_dex_files =
676 MakeNonOwningPointerVector(classpath_dex_c);
677 VerifyClassLoaderDexFiles(soa,
678 class_loader_2,
679 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
680 class_loader_2_dex_files);
681
682 // Verify the third class loader
683 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
684 std::vector<const DexFile*> class_loader_3_dex_files =
685 MakeNonOwningPointerVector(classpath_dex_d);
686 VerifyClassLoaderDexFiles(soa,
687 class_loader_3,
688 WellKnownClasses::dalvik_system_PathClassLoader,
689 class_loader_3_dex_files);
690 // The last class loader should have the BootClassLoader as a parent.
691 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
692 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
693}
694
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000695TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
696 // Setup the context.
697 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
698 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
699 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
700 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
701
702 std::string context_spec =
703 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
704 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
705 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
706
707 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
708 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
709
710 // Setup the compilation sources.
711 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
712 std::vector<const DexFile*> compilation_sources_raw =
713 MakeNonOwningPointerVector(compilation_sources);
714
715 // Create the class loader.
716 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
717 ASSERT_TRUE(jclass_loader != nullptr);
718
719 // Verify the class loader.
720 ScopedObjectAccess soa(Thread::Current());
721
722 StackHandleScope<4> hs(soa.Self());
723 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
724 soa.Decode<mirror::ClassLoader>(jclass_loader));
725
726 // For the first class loader the class path dex files must come first and then the
727 // compilation sources.
728 std::vector<const DexFile*> class_loader_1_dex_files =
729 MakeNonOwningPointerVector(classpath_dex_a);
730 for (auto& dex : classpath_dex_b) {
731 class_loader_1_dex_files.push_back(dex.get());
732 }
733 for (auto& dex : compilation_sources_raw) {
734 class_loader_1_dex_files.push_back(dex);
735 }
736 VerifyClassLoaderDexFiles(soa,
737 class_loader_1,
738 WellKnownClasses::dalvik_system_PathClassLoader,
739 class_loader_1_dex_files);
740
741 // Verify the shared libraries.
742 ArtField* field =
743 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
744 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
745 ASSERT_TRUE(raw_shared_libraries != nullptr);
746
747 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
748 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
749 ASSERT_EQ(shared_libraries->GetLength(), 2);
750
751 // Verify the first shared library.
752 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
753 std::vector<const DexFile*> class_loader_2_dex_files =
754 MakeNonOwningPointerVector(classpath_dex_c);
755 VerifyClassLoaderDexFiles(soa,
756 class_loader_2,
757 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
758 class_loader_2_dex_files);
759 raw_shared_libraries = field->GetObject(class_loader_2.Get());
760 ASSERT_TRUE(raw_shared_libraries == nullptr);
761
762 // Verify the second shared library.
763 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
764 std::vector<const DexFile*> class_loader_3_dex_files =
765 MakeNonOwningPointerVector(classpath_dex_d);
766 VerifyClassLoaderDexFiles(soa,
767 class_loader_3,
768 WellKnownClasses::dalvik_system_PathClassLoader,
769 class_loader_3_dex_files);
770 raw_shared_libraries = field->GetObject(class_loader_3.Get());
771 ASSERT_TRUE(raw_shared_libraries == nullptr);
772
773 // All class loaders should have the BootClassLoader as a parent.
774 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
775 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
776 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
777 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
778 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
779 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
780}
781
782TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
783 // Setup the context.
784 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
785 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
786 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
787 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
788
789 std::string context_spec =
790 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
791 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
792 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
793 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
794
795 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
796 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
797
798 // Setup the compilation sources.
799 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
800 std::vector<const DexFile*> compilation_sources_raw =
801 MakeNonOwningPointerVector(compilation_sources);
802
803 // Create the class loader.
804 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
805 ASSERT_TRUE(jclass_loader != nullptr);
806
807 // Verify the class loader.
808 ScopedObjectAccess soa(Thread::Current());
809
810 StackHandleScope<6> hs(soa.Self());
811 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
812 soa.Decode<mirror::ClassLoader>(jclass_loader));
813
814 // For the first class loader the class path dex files must come first and then the
815 // compilation sources.
816 std::vector<const DexFile*> class_loader_1_dex_files =
817 MakeNonOwningPointerVector(classpath_dex_a);
818 for (auto& dex : compilation_sources_raw) {
819 class_loader_1_dex_files.push_back(dex);
820 }
821 VerifyClassLoaderDexFiles(soa,
822 class_loader_1,
823 WellKnownClasses::dalvik_system_PathClassLoader,
824 class_loader_1_dex_files);
825
826 // Verify its shared library.
827 ArtField* field =
828 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
829 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
830 ASSERT_TRUE(raw_shared_libraries != nullptr);
831
832 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
833 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
834 ASSERT_EQ(shared_libraries->GetLength(), 1);
835
836 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
837 std::vector<const DexFile*> class_loader_2_dex_files =
838 MakeNonOwningPointerVector(classpath_dex_b);
839 VerifyClassLoaderDexFiles(soa,
840 class_loader_2,
841 WellKnownClasses::dalvik_system_PathClassLoader,
842 class_loader_2_dex_files);
843 raw_shared_libraries = field->GetObject(class_loader_2.Get());
844 ASSERT_TRUE(raw_shared_libraries == nullptr);
845
846 // Verify the parent.
847 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
848 std::vector<const DexFile*> class_loader_3_dex_files =
849 MakeNonOwningPointerVector(classpath_dex_c);
850 VerifyClassLoaderDexFiles(soa,
851 class_loader_3,
852 WellKnownClasses::dalvik_system_PathClassLoader,
853 class_loader_3_dex_files);
854
855 // Verify its shared library.
856 raw_shared_libraries = field->GetObject(class_loader_3.Get());
857 ASSERT_TRUE(raw_shared_libraries != nullptr);
858
859 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
860 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
861 ASSERT_EQ(shared_libraries->GetLength(), 1);
862
863 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
864 std::vector<const DexFile*> class_loader_4_dex_files =
865 MakeNonOwningPointerVector(classpath_dex_d);
866 VerifyClassLoaderDexFiles(soa,
867 class_loader_4,
868 WellKnownClasses::dalvik_system_PathClassLoader,
869 class_loader_4_dex_files);
870 raw_shared_libraries = field->GetObject(class_loader_4.Get());
871 ASSERT_TRUE(raw_shared_libraries == nullptr);
872
873 // Class loaders should have the BootClassLoader as a parent.
874 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
875 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
876 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
877 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
878 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
879 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
880}
881
882TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
883 // Setup the context.
884 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
885 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
886 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
887 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
888
889 std::string context_spec =
890 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
891 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
892 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
893 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
894
895 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
896 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
897
898 // Setup the compilation sources.
899 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
900 std::vector<const DexFile*> compilation_sources_raw =
901 MakeNonOwningPointerVector(compilation_sources);
902
903 // Create the class loader.
904 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
905 ASSERT_TRUE(jclass_loader != nullptr);
906
907 // Verify the class loader.
908 ScopedObjectAccess soa(Thread::Current());
909
910 StackHandleScope<6> hs(soa.Self());
911 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
912 soa.Decode<mirror::ClassLoader>(jclass_loader));
913
914 // For the first class loader the class path dex files must come first and then the
915 // compilation sources.
916 std::vector<const DexFile*> class_loader_1_dex_files =
917 MakeNonOwningPointerVector(classpath_dex_a);
918 for (auto& dex : compilation_sources_raw) {
919 class_loader_1_dex_files.push_back(dex);
920 }
921 VerifyClassLoaderDexFiles(soa,
922 class_loader_1,
923 WellKnownClasses::dalvik_system_PathClassLoader,
924 class_loader_1_dex_files);
925
926 // Verify its shared library.
927 ArtField* field =
928 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
929 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
930 ASSERT_TRUE(raw_shared_libraries != nullptr);
931
932 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
933 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
934 ASSERT_EQ(shared_libraries->GetLength(), 1);
935
936 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
937 std::vector<const DexFile*> class_loader_2_dex_files =
938 MakeNonOwningPointerVector(classpath_dex_b);
939 VerifyClassLoaderDexFiles(soa,
940 class_loader_2,
941 WellKnownClasses::dalvik_system_PathClassLoader,
942 class_loader_2_dex_files);
943
944 // Verify the shared library dependency of the shared library.
945 raw_shared_libraries = field->GetObject(class_loader_2.Get());
946 ASSERT_TRUE(raw_shared_libraries != nullptr);
947
948 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
949 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
950 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
951
952 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
953 std::vector<const DexFile*> class_loader_3_dex_files =
954 MakeNonOwningPointerVector(classpath_dex_c);
955 VerifyClassLoaderDexFiles(soa,
956 class_loader_3,
957 WellKnownClasses::dalvik_system_PathClassLoader,
958 class_loader_3_dex_files);
959 raw_shared_libraries = field->GetObject(class_loader_3.Get());
960 ASSERT_TRUE(raw_shared_libraries == nullptr);
961
962 // Verify the parent.
963 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
964 std::vector<const DexFile*> class_loader_4_dex_files =
965 MakeNonOwningPointerVector(classpath_dex_d);
966 VerifyClassLoaderDexFiles(soa,
967 class_loader_4,
968 WellKnownClasses::dalvik_system_PathClassLoader,
969 class_loader_4_dex_files);
970 raw_shared_libraries = field->GetObject(class_loader_4.Get());
971 ASSERT_TRUE(raw_shared_libraries == nullptr);
972
973 // Class loaders should have the BootClassLoader as a parent.
974 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
975 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
976 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
977 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
978 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
979 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
980}
Calin Juravlec79470d2017-07-12 17:37:42 -0700981
Calin Juravle87e2cb62017-06-13 21:48:45 -0700982TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
983 std::unique_ptr<ClassLoaderContext> context =
984 ClassLoaderContext::Create("PCL[a.dex]");
985 dchecked_vector<std::string> classpath_dex;
986 classpath_dex.push_back("a.dex");
987 dchecked_vector<std::string> compilation_sources;
988 compilation_sources.push_back("src.dex");
989
990 // Nothing should be removed.
991 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
992 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
993 // Classes should be removed.
994 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
995 VerifyClassLoaderPCL(context.get(), 0, "");
996}
997
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +0000998TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
999 // Setup the context.
1000 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
1001 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
1002 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
1003
1004 std::string context_spec =
1005 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
1006 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
1007 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
1008 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
1009
1010 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
1011 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1012
1013 // Setup the compilation sources.
1014 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1015 std::vector<const DexFile*> compilation_sources_raw =
1016 MakeNonOwningPointerVector(compilation_sources);
1017
1018 // Create the class loader.
1019 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1020 ASSERT_TRUE(jclass_loader != nullptr);
1021
1022 // Verify the class loader.
1023 ScopedObjectAccess soa(Thread::Current());
1024
1025 StackHandleScope<6> hs(soa.Self());
1026 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1027 soa.Decode<mirror::ClassLoader>(jclass_loader));
1028
1029 // For the first class loader the class path dex files must come first and then the
1030 // compilation sources.
1031 std::vector<const DexFile*> class_loader_1_dex_files =
1032 MakeNonOwningPointerVector(classpath_dex_a);
1033 for (auto& dex : compilation_sources_raw) {
1034 class_loader_1_dex_files.push_back(dex);
1035 }
1036 VerifyClassLoaderDexFiles(soa,
1037 class_loader_1,
1038 WellKnownClasses::dalvik_system_PathClassLoader,
1039 class_loader_1_dex_files);
1040
1041 // Verify its shared library.
1042 ArtField* field =
1043 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1044 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1045 ASSERT_TRUE(raw_shared_libraries != nullptr);
1046
1047 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1048 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1049 ASSERT_EQ(shared_libraries->GetLength(), 1);
1050
1051 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1052 std::vector<const DexFile*> class_loader_2_dex_files =
1053 MakeNonOwningPointerVector(classpath_dex_b);
1054 VerifyClassLoaderDexFiles(soa,
1055 class_loader_2,
1056 WellKnownClasses::dalvik_system_PathClassLoader,
1057 class_loader_2_dex_files);
1058
1059 // Verify the parent.
1060 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1061 std::vector<const DexFile*> class_loader_3_dex_files =
1062 MakeNonOwningPointerVector(classpath_dex_c);
1063 VerifyClassLoaderDexFiles(soa,
1064 class_loader_3,
1065 WellKnownClasses::dalvik_system_PathClassLoader,
1066 class_loader_3_dex_files);
1067
1068 // Verify its shared library is the same as the child.
1069 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1070 ASSERT_TRUE(raw_shared_libraries != nullptr);
1071 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1072 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1073 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
Vladimir Marko423bebb2019-03-26 15:17:21 +00001074 ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +00001075
1076 // Class loaders should have the BootClassLoader as a parent.
1077 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1078 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1079 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1080 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1081}
1082
Calin Juravle87e2cb62017-06-13 21:48:45 -07001083TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1084 std::string dex1_name = GetTestDexFileName("Main");
1085 std::string dex2_name = GetTestDexFileName("MyClass");
1086 std::unique_ptr<ClassLoaderContext> context =
1087 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1088 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1089
1090 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1091 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1092 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001093 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1094 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001095 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1096}
1097
David Brazdil93d339d2019-03-27 09:56:45 +00001098TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) {
1099 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1100 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1101
1102 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1103 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1104
1105 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1106 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1107 ASSERT_EQ(dex2.size(), 1u);
1108
1109 std::string encoding = context->EncodeContextForOatFile("");
1110 std::string expected_encoding = "IMC[<unknown>*" + std::to_string(dex2[0]->GetLocationChecksum())
1111 + "];PCL[" + CreateClassPathWithChecksums(dex1) + "]";
1112 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1113}
1114
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001115TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1116 std::string dex1_name = GetTestDexFileName("Main");
1117 std::string dex2_name = GetTestDexFileName("MultiDex");
1118 std::unique_ptr<ClassLoaderContext> context =
1119 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1120 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1121
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001122 std::string encoding = context->EncodeContextForDex2oat("");
1123 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1124 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1125}
1126
David Brazdil93d339d2019-03-27 09:56:45 +00001127TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) {
1128 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1129 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1130
1131 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1132 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1133
1134 std::string encoding = context->EncodeContextForDex2oat("");
1135 std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]";
1136 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1137}
1138
Dan Zimmermanb682ea42019-12-23 06:59:06 -08001139TEST_F(ClassLoaderContextTest, EncodeContextsSinglePath) {
1140 jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1141 std::unique_ptr<ClassLoaderContext> context =
1142 CreateContextForClassLoader(class_loader);
1143
1144 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1145 ASSERT_EQ(1u, encodings.size());
1146 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1147}
1148
1149TEST_F(ClassLoaderContextTest, EncodeContextsMultiDex) {
1150 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1151 std::unique_ptr<ClassLoaderContext> context =
1152 CreateContextForClassLoader(class_loader);
1153
1154 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1155 ASSERT_EQ(1u, encodings.size());
1156 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("MultiDex")));
1157}
1158
1159TEST_F(ClassLoaderContextTest, EncodeContextsRepeatedMultiDex) {
1160 jobject top_class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1161 jobject middle_class_loader =
1162 LoadDexInPathClassLoader("Main", top_class_loader);
1163 jobject bottom_class_loader =
1164 LoadDexInPathClassLoader("MultiDex", middle_class_loader);
1165 std::unique_ptr<ClassLoaderContext> context =
1166 CreateContextForClassLoader(bottom_class_loader);
1167
1168 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1169 ASSERT_EQ(1u, encodings.size());
1170
1171 std::string main_dex_name = GetTestDexFileName("Main");
1172 std::string multidex_dex_name = GetTestDexFileName("MultiDex");
1173 ASSERT_EQ(
1174 "PCL[];PCL[" + main_dex_name + "];PCL[" + multidex_dex_name + "]",
1175 encodings.at(multidex_dex_name));
1176}
1177
1178TEST_F(ClassLoaderContextTest, EncodeContextsSinglePathWithShared) {
1179 jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1180
1181 ScopedObjectAccess soa(Thread::Current());
1182 StackHandleScope<1> hs(soa.Self());
1183 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1184 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1185 soa.Self(),
1186 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1187 1));
1188 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1189
1190 jobject class_loader_b = LoadDexInPathClassLoader(
1191 "Main", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1192
1193 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1194
1195 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1196 ASSERT_EQ(1u, encodings.size());
1197 ASSERT_EQ(
1198 "PCL[]{PCL[" + GetTestDexFileName("MyClass") + "]}",
1199 encodings.at(GetTestDexFileName("Main")));
1200}
1201
1202TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePaths) {
1203 jobject class_loader = LoadDexInPathClassLoader(
1204 std::vector<std::string>{ "Main", "MultiDex"}, nullptr);
1205
1206 std::unique_ptr<ClassLoaderContext> context =
1207 CreateContextForClassLoader(class_loader);
1208
1209 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1210 ASSERT_EQ(2u, encodings.size());
1211 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1212 ASSERT_EQ(
1213 "PCL[" + GetTestDexFileName("Main") + "]", encodings.at(GetTestDexFileName("MultiDex")));
1214}
1215
1216TEST_F(ClassLoaderContextTest, EncodeContextsMultiplePathsWithShared) {
1217 jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
1218
1219 ScopedObjectAccess soa(Thread::Current());
1220 StackHandleScope<1> hs(soa.Self());
1221 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1222 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1223 soa.Self(),
1224 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1225 1));
1226 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1227
1228 jobject class_loader_b = LoadDexInPathClassLoader(
1229 std::vector<std::string> { "Main", "MultiDex" },
1230 nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1231
1232 std::unique_ptr<ClassLoaderContext> context =
1233 CreateContextForClassLoader(class_loader_b);
1234
1235 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1236 ASSERT_EQ(2u, encodings.size());
1237 const std::string context_suffix =
1238 "{PCL[" + GetTestDexFileName("MyClass") + "]}";
1239 ASSERT_EQ("PCL[]" + context_suffix, encodings.at(GetTestDexFileName("Main")));
1240 ASSERT_EQ(
1241 "PCL[" + GetTestDexFileName("Main") + "]" + context_suffix,
1242 encodings.at(GetTestDexFileName("MultiDex")));
1243}
1244
1245TEST_F(ClassLoaderContextTest, EncodeContextsIMC) {
1246 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1247 jobject class_loader_b =
1248 LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1249
1250 std::unique_ptr<ClassLoaderContext> context =
1251 CreateContextForClassLoader(class_loader_b);
1252
1253 std::map<std::string, std::string> encodings = context->EncodeClassPathContexts("");
1254 ASSERT_EQ(1u, encodings.size());
1255 ASSERT_EQ(
1256 "IMC[];PCL[" + GetTestDexFileName("Main") + "]",
1257 encodings.at("<unknown>"));
1258}
1259
1260TEST_F(ClassLoaderContextTest, EncodeContextsForSingleDex) {
1261 jobject class_loader = LoadDexInPathClassLoader("Main", nullptr);
1262 std::map<std::string, std::string> encodings =
1263 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1264 ASSERT_EQ(1u, encodings.size());
1265 ASSERT_EQ("PCL[]", encodings.at(GetTestDexFileName("Main")));
1266}
1267
1268static jobject CreateForeignClassLoader() {
1269 ScopedObjectAccess soa(Thread::Current());
1270 JNIEnv* env = soa.Env();
1271
1272 // We cannot instantiate a ClassLoader directly, so instead we allocate an Object to represent
1273 // our foreign ClassLoader (this works because the runtime does proper instanceof checks before
1274 // operating on this object.
1275 jmethodID ctor = env->GetMethodID(WellKnownClasses::java_lang_Object, "<init>", "()V");
1276 return env->NewObject(WellKnownClasses::java_lang_Object, ctor);
1277}
1278
1279TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedBase) {
1280 std::map<std::string, std::string> empty;
1281 ASSERT_EQ(
1282 empty, ClassLoaderContext::EncodeClassPathContextsForClassLoader(CreateForeignClassLoader()));
1283}
1284
1285TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChain) {
1286 jobject class_loader = LoadDexInPathClassLoader("Main", CreateForeignClassLoader());
1287 std::map<std::string, std::string> encodings =
1288 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1289 ASSERT_EQ(1u, encodings.size());
1290 ASSERT_EQ(
1291 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1292 encodings.at(GetTestDexFileName("Main")));
1293}
1294
1295TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiPath) {
1296 jobject class_loader = LoadDexInPathClassLoader(std::vector<std::string> { "Main", "MyClass" },
1297 CreateForeignClassLoader());
1298 std::map<std::string, std::string> encodings =
1299 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1300 ASSERT_EQ(2u, encodings.size());
1301 ASSERT_EQ(
1302 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1303 encodings.at(GetTestDexFileName("Main")));
1304 ASSERT_EQ(
1305 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1306 encodings.at(GetTestDexFileName("MyClass")));
1307}
1308
1309TEST_F(ClassLoaderContextTest, EncodeContextsForUnsupportedChainMultiDex) {
1310 jobject class_loader = LoadDexInPathClassLoader("MultiDex", CreateForeignClassLoader());
1311 std::map<std::string, std::string> encodings =
1312 ClassLoaderContext::EncodeClassPathContextsForClassLoader(class_loader);
1313 ASSERT_EQ(1u, encodings.size());
1314 ASSERT_EQ(
1315 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding,
1316 encodings.at(GetTestDexFileName("MultiDex")));
1317}
1318
Dan Zimmermanc9fa7702020-01-31 13:35:12 -08001319TEST_F(ClassLoaderContextTest, IsValidEncoding) {
1320 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[]"));
1321 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex]"));
1322 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("PCL[foo.dex];PCL[bar.dex]"));
1323 ASSERT_TRUE(ClassLoaderContext::IsValidEncoding("DLC[];PCL[bar.dex]"));
1324 ASSERT_TRUE(
1325 ClassLoaderContext::IsValidEncoding(
1326 ClassLoaderContext::kUnsupportedClassLoaderContextEncoding));
1327 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("not_valid"));
1328 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("[]"));
1329 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("FCL[]"));
1330 ASSERT_FALSE(ClassLoaderContext::IsValidEncoding("foo.dex:bar.dex"));
1331}
1332
Calin Juravle57d0acc2017-07-11 17:41:30 -07001333// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1334TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1335 // The chain is
1336 // ClassLoaderA (PathClassLoader)
1337 // ^
1338 // |
1339 // ClassLoaderB (DelegateLastClassLoader)
1340 // ^
1341 // |
1342 // ClassLoaderC (PathClassLoader)
1343 // ^
1344 // |
1345 // ClassLoaderD (DelegateLastClassLoader)
1346
1347 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1348 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1349 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1350 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1351
1352 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1353
1354 VerifyContextForClassLoader(context.get());
1355 VerifyContextSize(context.get(), 4);
1356
1357 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1358 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1359 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1360 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1361}
1362
David Brazdil1a9ac532019-03-05 11:57:13 +00001363TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1364 // The chain is
1365 // ClassLoaderA (PathClassLoader)
1366 // ^
1367 // |
1368 // ClassLoaderB (InMemoryDexClassLoader)
1369 // ^
1370 // |
1371 // ClassLoaderC (InMemoryDexClassLoader)
1372 // ^
1373 // |
1374 // ClassLoaderD (DelegateLastClassLoader)
1375
1376 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1377 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1378 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1379 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1380
1381 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1382
1383 VerifyContextForClassLoader(context.get());
1384 VerifyContextSize(context.get(), 4);
1385
1386 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1387 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1388 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1389 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1390}
Mathieu Chartieradc90862018-05-11 13:03:06 -07001391
1392TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1393 std::string context_spec = "PCL[]";
1394 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1395 ASSERT_TRUE(context != nullptr);
1396 PretendContextOpenedDexFiles(context.get());
1397 // Ensure that the special shared library marks as verified for the first thing in the class path.
1398 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1399 ClassLoaderContext::VerificationResult::kVerifies);
1400}
1401
Calin Juravle3f918642017-07-11 19:04:20 -07001402TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1403 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1404 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001405 // Pretend that we successfully open the dex files to pass the DCHECKS.
1406 // (as it's much easier to test all the corner cases without relying on actual dex files).
1407 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001408
1409 VerifyContextSize(context.get(), 2);
1410 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1411 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1412
Mathieu Chartieradc90862018-05-11 13:03:06 -07001413 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1414 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001415
1416 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001417 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1418 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001419
1420 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001421 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1422 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001423
1424 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001425 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1426 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001427
1428 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001429 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1430 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001431
1432 std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001433 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1434 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001435
1436 std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001437 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1438 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001439
1440 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001441 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1442 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001443}
1444
David Brazdil1a9ac532019-03-05 11:57:13 +00001445TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
David Brazdil93d339d2019-03-27 09:56:45 +00001446 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001447 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1448 // Pretend that we successfully open the dex files to pass the DCHECKS.
1449 // (as it's much easier to test all the corner cases without relying on actual dex files).
1450 PretendContextOpenedDexFiles(context.get());
1451
1452 VerifyContextSize(context.get(), 3);
1453 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1454 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001455 VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001456
1457 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1458 ClassLoaderContext::VerificationResult::kVerifies);
1459}
1460
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001461TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1462 std::string context_spec = "&";
1463 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1464 // Pretend that we successfully open the dex files to pass the DCHECKS.
1465 // (as it's much easier to test all the corner cases without relying on actual dex files).
1466 PretendContextOpenedDexFiles(context.get());
1467
1468 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1469 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1470}
1471
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001472TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1473 std::string context_spec =
1474 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1475 ";DLC[c.dex*890]";
1476 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1477 // Pretend that we successfully open the dex files to pass the DCHECKS.
1478 // (as it's much easier to test all the corner cases without relying on actual dex files).
1479 PretendContextOpenedDexFiles(context.get());
1480
1481 VerifyContextSize(context.get(), 2);
1482 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1483 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1484 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1485 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1486
1487 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1488 ClassLoaderContext::VerificationResult::kVerifies);
1489
1490 std::string wrong_class_loader_type =
1491 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1492 ";DLC[c.dex*890]";
1493 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1494 ClassLoaderContext::VerificationResult::kMismatch);
1495
1496 std::string wrong_class_loader_order =
1497 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1498 ";DLC[c.dex*890]";
1499 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1500 ClassLoaderContext::VerificationResult::kMismatch);
1501
1502 std::string wrong_classpath_order =
1503 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1504 ";DLC[c.dex*890]";
1505 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1506 ClassLoaderContext::VerificationResult::kMismatch);
1507
1508 std::string wrong_checksum =
1509 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1510 ";DLC[c.dex*890]";
1511 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1512 ClassLoaderContext::VerificationResult::kMismatch);
1513
1514 std::string wrong_extra_class_loader =
1515 "PCL[a.dex*123:b.dex*456]"
1516 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1517 ";DLC[c.dex*890]";
1518 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1519 ClassLoaderContext::VerificationResult::kMismatch);
1520
1521 std::string wrong_extra_classpath =
1522 "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]}"
1523 ";DLC[c.dex*890]";
1524 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1525 ClassLoaderContext::VerificationResult::kMismatch);
1526}
1527
David Brazdil1a9ac532019-03-05 11:57:13 +00001528TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1529 std::string context_spec =
David Brazdil93d339d2019-03-27 09:56:45 +00001530 "IMC[<unknown>*123:<unknown>*456]"
1531 "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1532 "DLC[c.dex*890]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001533 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1534 // Pretend that we successfully open the dex files to pass the DCHECKS.
1535 // (as it's much easier to test all the corner cases without relying on actual dex files).
1536 PretendContextOpenedDexFiles(context.get());
1537
1538 VerifyContextSize(context.get(), 2);
David Brazdil93d339d2019-03-27 09:56:45 +00001539 VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001540 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001541 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1542 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001543
1544 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1545 ClassLoaderContext::VerificationResult::kVerifies);
1546}
1547
Calin Juravle3f918642017-07-11 19:04:20 -07001548TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1549 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1550 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1551 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1552 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1553
1554 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1555
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001556 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001557 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1558 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001559
1560 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1561 size_t pos = dex_location.rfind('/');
1562 ASSERT_NE(std::string::npos, pos);
1563 std::string parent = dex_location.substr(0, pos);
1564
1565 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1566 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001567 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1568 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001569}
1570
David Brazdil1a9ac532019-03-05 11:57:13 +00001571TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1572 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1573 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1574 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1575 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1576
1577 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1578
1579 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1580 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1581 ClassLoaderContext::VerificationResult::kVerifies);
1582
1583 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1584 size_t pos = dex_location.rfind('/');
1585 ASSERT_NE(std::string::npos, pos);
1586 std::string parent = dex_location.substr(0, pos);
1587
1588 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1589 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1590 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1591 ClassLoaderContext::VerificationResult::kVerifies);
1592}
1593
Calin Juravlea308a322017-07-18 16:51:51 -07001594TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1595 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1596
1597 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1598
Vladimir Marko36ec5982019-11-28 10:55:16 +00001599 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1600 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1601 ClassLoaderContext::VerificationResult::kVerifies);
1602
1603 std::string dex_location = GetTestDexFileName("MultiDex");
1604 size_t pos = dex_location.rfind('/');
1605 ASSERT_NE(std::string::npos, pos);
1606 std::string parent = dex_location.substr(0, pos);
1607
1608 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1609 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1610 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
Mathieu Chartieradc90862018-05-11 13:03:06 -07001611 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001612}
1613
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001614TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1615 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1616
1617 ScopedObjectAccess soa(Thread::Current());
1618 StackHandleScope<1> hs(soa.Self());
1619 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1620 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1621 soa.Self(),
1622 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1623 1));
1624 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1625
1626 jobject class_loader_b = LoadDexInPathClassLoader(
1627 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1628
1629 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1630 ASSERT_TRUE(context != nullptr);
1631 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1632 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1633 dex_files = OpenTestDexFiles("ForClassLoaderA");
1634 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1635
1636 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1637 ClassLoaderContext::VerificationResult::kVerifies);
1638}
1639
Calin Juravleb495e7f2020-04-06 19:29:45 -07001640TEST_F(ClassLoaderContextTest, CheckForDuplicateDexFiles) {
1641 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr);
1642 jobject class_loader_b =
1643 LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a);
1644
1645 std::unique_ptr<ClassLoaderContext> context =
1646 CreateContextForClassLoader(class_loader_b);
1647
1648 std::vector<const DexFile*> result = context->CheckForDuplicateDexFiles(
1649 std::vector<const DexFile*>());
1650 ASSERT_EQ(0u, result.size());
1651
1652 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1653 std::vector<const DexFile*> dex1_raw = MakeNonOwningPointerVector(dex1);
1654 result = context->CheckForDuplicateDexFiles(dex1_raw);
1655 ASSERT_EQ(1u, result.size());
1656 ASSERT_EQ(dex1_raw[0], result[0]);
1657}
1658
Calin Juravle87e2cb62017-06-13 21:48:45 -07001659} // namespace art