blob: 0c36fd42c29fb826e2c6dc9cf652463c35cad447 [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"
Nicolas Geoffraye1672732018-11-30 01:09:49 +000026#include "class_root.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
Calin Juravle57d0acc2017-07-11 17:41:30 -07001139// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1140TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1141 // The chain is
1142 // ClassLoaderA (PathClassLoader)
1143 // ^
1144 // |
1145 // ClassLoaderB (DelegateLastClassLoader)
1146 // ^
1147 // |
1148 // ClassLoaderC (PathClassLoader)
1149 // ^
1150 // |
1151 // ClassLoaderD (DelegateLastClassLoader)
1152
1153 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1154 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1155 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1156 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1157
1158 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1159
1160 VerifyContextForClassLoader(context.get());
1161 VerifyContextSize(context.get(), 4);
1162
1163 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1164 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1165 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1166 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1167}
1168
David Brazdil1a9ac532019-03-05 11:57:13 +00001169TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1170 // The chain is
1171 // ClassLoaderA (PathClassLoader)
1172 // ^
1173 // |
1174 // ClassLoaderB (InMemoryDexClassLoader)
1175 // ^
1176 // |
1177 // ClassLoaderC (InMemoryDexClassLoader)
1178 // ^
1179 // |
1180 // ClassLoaderD (DelegateLastClassLoader)
1181
1182 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1183 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1184 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1185 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1186
1187 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1188
1189 VerifyContextForClassLoader(context.get());
1190 VerifyContextSize(context.get(), 4);
1191
1192 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1193 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1194 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1195 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1196}
Mathieu Chartieradc90862018-05-11 13:03:06 -07001197
1198TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1199 std::string context_spec = "PCL[]";
1200 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1201 ASSERT_TRUE(context != nullptr);
1202 PretendContextOpenedDexFiles(context.get());
1203 // Ensure that the special shared library marks as verified for the first thing in the class path.
1204 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1205 ClassLoaderContext::VerificationResult::kVerifies);
1206}
1207
Calin Juravle3f918642017-07-11 19:04:20 -07001208TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1209 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1210 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001211 // Pretend that we successfully open the dex files to pass the DCHECKS.
1212 // (as it's much easier to test all the corner cases without relying on actual dex files).
1213 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001214
1215 VerifyContextSize(context.get(), 2);
1216 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1217 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1218
Mathieu Chartieradc90862018-05-11 13:03:06 -07001219 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1220 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001221
1222 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001223 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1224 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001225
1226 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001227 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1228 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001229
1230 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001231 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1232 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001233
1234 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001235 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1236 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001237
1238 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 -07001239 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1240 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001241
1242 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 -07001243 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1244 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001245
1246 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001247 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1248 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001249}
1250
David Brazdil1a9ac532019-03-05 11:57:13 +00001251TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
David Brazdil93d339d2019-03-27 09:56:45 +00001252 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 +00001253 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1254 // Pretend that we successfully open the dex files to pass the DCHECKS.
1255 // (as it's much easier to test all the corner cases without relying on actual dex files).
1256 PretendContextOpenedDexFiles(context.get());
1257
1258 VerifyContextSize(context.get(), 3);
1259 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1260 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001261 VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001262
1263 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1264 ClassLoaderContext::VerificationResult::kVerifies);
1265}
1266
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001267TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1268 std::string context_spec = "&";
1269 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1270 // Pretend that we successfully open the dex files to pass the DCHECKS.
1271 // (as it's much easier to test all the corner cases without relying on actual dex files).
1272 PretendContextOpenedDexFiles(context.get());
1273
1274 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1275 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1276}
1277
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001278TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1279 std::string context_spec =
1280 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1281 ";DLC[c.dex*890]";
1282 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1283 // Pretend that we successfully open the dex files to pass the DCHECKS.
1284 // (as it's much easier to test all the corner cases without relying on actual dex files).
1285 PretendContextOpenedDexFiles(context.get());
1286
1287 VerifyContextSize(context.get(), 2);
1288 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1289 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1290 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1291 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1292
1293 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1294 ClassLoaderContext::VerificationResult::kVerifies);
1295
1296 std::string wrong_class_loader_type =
1297 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1298 ";DLC[c.dex*890]";
1299 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1300 ClassLoaderContext::VerificationResult::kMismatch);
1301
1302 std::string wrong_class_loader_order =
1303 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1304 ";DLC[c.dex*890]";
1305 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1306 ClassLoaderContext::VerificationResult::kMismatch);
1307
1308 std::string wrong_classpath_order =
1309 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1310 ";DLC[c.dex*890]";
1311 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1312 ClassLoaderContext::VerificationResult::kMismatch);
1313
1314 std::string wrong_checksum =
1315 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1316 ";DLC[c.dex*890]";
1317 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1318 ClassLoaderContext::VerificationResult::kMismatch);
1319
1320 std::string wrong_extra_class_loader =
1321 "PCL[a.dex*123:b.dex*456]"
1322 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1323 ";DLC[c.dex*890]";
1324 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1325 ClassLoaderContext::VerificationResult::kMismatch);
1326
1327 std::string wrong_extra_classpath =
1328 "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]}"
1329 ";DLC[c.dex*890]";
1330 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1331 ClassLoaderContext::VerificationResult::kMismatch);
1332}
1333
David Brazdil1a9ac532019-03-05 11:57:13 +00001334TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1335 std::string context_spec =
David Brazdil93d339d2019-03-27 09:56:45 +00001336 "IMC[<unknown>*123:<unknown>*456]"
1337 "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1338 "DLC[c.dex*890]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001339 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1340 // Pretend that we successfully open the dex files to pass the DCHECKS.
1341 // (as it's much easier to test all the corner cases without relying on actual dex files).
1342 PretendContextOpenedDexFiles(context.get());
1343
1344 VerifyContextSize(context.get(), 2);
David Brazdil93d339d2019-03-27 09:56:45 +00001345 VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001346 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil93d339d2019-03-27 09:56:45 +00001347 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1348 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001349
1350 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1351 ClassLoaderContext::VerificationResult::kVerifies);
1352}
1353
Calin Juravle3f918642017-07-11 19:04:20 -07001354TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1355 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1356 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1357 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1358 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1359
1360 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1361
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001362 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001363 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1364 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001365
1366 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1367 size_t pos = dex_location.rfind('/');
1368 ASSERT_NE(std::string::npos, pos);
1369 std::string parent = dex_location.substr(0, pos);
1370
1371 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1372 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001373 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1374 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001375}
1376
David Brazdil1a9ac532019-03-05 11:57:13 +00001377TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1378 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1379 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1380 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1381 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1382
1383 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1384
1385 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1386 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1387 ClassLoaderContext::VerificationResult::kVerifies);
1388
1389 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1390 size_t pos = dex_location.rfind('/');
1391 ASSERT_NE(std::string::npos, pos);
1392 std::string parent = dex_location.substr(0, pos);
1393
1394 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1395 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1396 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1397 ClassLoaderContext::VerificationResult::kVerifies);
1398}
1399
Calin Juravlea308a322017-07-18 16:51:51 -07001400TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1401 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1402
1403 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1404
Mathieu Chartieradc90862018-05-11 13:03:06 -07001405 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1406 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001407}
1408
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001409TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1410 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1411
1412 ScopedObjectAccess soa(Thread::Current());
1413 StackHandleScope<1> hs(soa.Self());
1414 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1415 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1416 soa.Self(),
1417 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1418 1));
1419 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1420
1421 jobject class_loader_b = LoadDexInPathClassLoader(
1422 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1423
1424 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1425 ASSERT_TRUE(context != nullptr);
1426 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1427 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1428 dex_files = OpenTestDexFiles("ForClassLoaderA");
1429 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1430
1431 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1432 ClassLoaderContext::VerificationResult::kVerifies);
1433}
1434
Calin Juravle87e2cb62017-06-13 21:48:45 -07001435} // namespace art