blob: 531a69031d25b12857cc8900ed520ebbe50d748b [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"
32#include "mirror/class_loader.h"
33#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(
125 context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name);
126 }
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,
Calin Juravlec5b215f2017-09-12 14:49:37 -0700144 std::vector<std::unique_ptr<const DexFile>>* all_dex_files) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700145 ASSERT_TRUE(context != nullptr);
146 ASSERT_TRUE(context->dex_files_open_attempted_);
147 ASSERT_TRUE(context->dex_files_open_result_);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000148 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700149 ASSERT_EQ(all_dex_files->size(), info.classpath.size());
150 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700151 size_t cur_open_dex_index = 0;
Calin Juravlec5b215f2017-09-12 14:49:37 -0700152 for (size_t k = 0; k < all_dex_files->size(); k++) {
153 std::unique_ptr<const DexFile>& opened_dex_file =
Calin Juravle87e2cb62017-06-13 21:48:45 -0700154 info.opened_dex_files[cur_open_dex_index++];
Calin Juravlec5b215f2017-09-12 14:49:37 -0700155 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k];
Calin Juravle87e2cb62017-06-13 21:48:45 -0700156
Calin Juravle92003fe2017-09-06 02:22:57 +0000157 std::string expected_location = expected_dex_file->GetLocation();
Calin Juravle821a2592017-08-11 14:33:38 -0700158
Calin Juravle92003fe2017-09-06 02:22:57 +0000159 const std::string& opened_location = opened_dex_file->GetLocation();
160 if (!IsAbsoluteLocation(opened_location)) {
161 // If the opened location is relative (it was open from a relative path without a
162 // classpath_dir) it might not match the expected location which is absolute in tests).
163 // So we compare the endings (the checksum will validate it's actually the same file).
164 ASSERT_EQ(0, expected_location.compare(
165 expected_location.length() - opened_location.length(),
166 opened_location.length(),
167 opened_location));
168 } else {
169 ASSERT_EQ(expected_location, opened_location);
170 }
Calin Juravlec5b215f2017-09-12 14:49:37 -0700171 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum());
Calin Juravle92003fe2017-09-06 02:22:57 +0000172 ASSERT_EQ(info.classpath[k], opened_location);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700173 }
174 }
175
Calin Juravle57d0acc2017-07-11 17:41:30 -0700176 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) {
177 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr);
178 }
179
Calin Juravle3f918642017-07-11 19:04:20 -0700180 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) {
181 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext());
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700182 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) {
Calin Juravle3f918642017-07-11 19:04:20 -0700183 return nullptr;
184 }
185 return context;
186 }
187
Calin Juravle57d0acc2017-07-11 17:41:30 -0700188 void VerifyContextForClassLoader(ClassLoaderContext* context) {
189 ASSERT_TRUE(context != nullptr);
190 ASSERT_TRUE(context->dex_files_open_attempted_);
191 ASSERT_TRUE(context->dex_files_open_result_);
192 ASSERT_FALSE(context->owns_the_dex_files_);
193 ASSERT_FALSE(context->special_shared_library_);
194 }
195
Calin Juravlec79470d2017-07-12 17:37:42 -0700196 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa,
197 Handle<mirror::ClassLoader> class_loader,
198 jclass type,
199 std::vector<const DexFile*>& expected_dex_files)
200 REQUIRES_SHARED(Locks::mutator_lock_) {
201 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type));
202
203 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader);
204 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size());
205
206 for (size_t i = 0; i < expected_dex_files.size(); i++) {
207 ASSERT_EQ(expected_dex_files[i]->GetLocation(),
208 class_loader_dex_files[i]->GetLocation());
209 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(),
210 class_loader_dex_files[i]->GetLocationChecksum());
211 }
212 }
213
Calin Juravlec5b215f2017-09-12 14:49:37 -0700214 void PretendContextOpenedDexFiles(ClassLoaderContext* context) {
215 context->dex_files_open_attempted_ = true;
216 context->dex_files_open_result_ = true;
217 }
218
Calin Juravle87e2cb62017-06-13 21:48:45 -0700219 private:
220 void VerifyClassLoaderInfo(ClassLoaderContext* context,
221 size_t index,
222 ClassLoaderContext::ClassLoaderType type,
Calin Juravle57d0acc2017-07-11 17:41:30 -0700223 const std::string& classpath) {
Calin Juravle87e2cb62017-06-13 21:48:45 -0700224 ASSERT_TRUE(context != nullptr);
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000225 ASSERT_GT(context->GetParentChainSize(), index);
226 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700227 ASSERT_EQ(type, info.type);
228 std::vector<std::string> expected_classpath;
229 Split(classpath, ':', &expected_classpath);
230 ASSERT_EQ(expected_classpath, info.classpath);
231 }
Calin Juravle57d0acc2017-07-11 17:41:30 -0700232
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000233 void VerifyClassLoaderInfoSL(ClassLoaderContext* context,
234 size_t loader_index,
235 size_t shared_library_index,
236 ClassLoaderContext::ClassLoaderType type,
237 const std::string& classpath) {
238 ASSERT_TRUE(context != nullptr);
239 ASSERT_GT(context->GetParentChainSize(), loader_index);
240 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index);
241 ASSERT_GT(info.shared_libraries.size(), shared_library_index);
242 const ClassLoaderContext::ClassLoaderInfo& sl =
243 *info.shared_libraries[shared_library_index].get();
244 ASSERT_EQ(type, info.type);
245 std::vector<std::string> expected_classpath;
246 Split(classpath, ':', &expected_classpath);
247 ASSERT_EQ(expected_classpath, sl.classpath);
248 }
249
Calin Juravle57d0acc2017-07-11 17:41:30 -0700250 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context,
251 size_t index,
252 ClassLoaderContext::ClassLoaderType type,
253 const std::string& test_name) {
254 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str());
Calin Juravle57d0acc2017-07-11 17:41:30 -0700255
256 VerifyClassLoaderInfo(context, index, type, GetTestDexFileName(test_name.c_str()));
Calin Juravlec5b215f2017-09-12 14:49:37 -0700257 VerifyOpenDexFiles(context, index, &dex_files);
Calin Juravle57d0acc2017-07-11 17:41:30 -0700258 }
Calin Juravle87e2cb62017-06-13 21:48:45 -0700259};
260
Calin Juravle1a509c82017-07-24 16:51:21 -0700261TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) {
262 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("");
263 // An empty context should create a single empty PathClassLoader.
264 VerifyContextSize(context.get(), 1);
265 VerifyClassLoaderPCL(context.get(), 0, "");
266}
267
268TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) {
269 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
270 // An shared library context should have no class loader in the chain.
271 VerifyContextSize(context.get(), 0);
272}
273
Calin Juravle87e2cb62017-06-13 21:48:45 -0700274TEST_F(ClassLoaderContextTest, ParseValidContextPCL) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000275 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700276 VerifyContextSize(context.get(), 1);
277 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
278}
279
280TEST_F(ClassLoaderContextTest, ParseValidContextDLC) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000281 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700282 VerifyContextSize(context.get(), 1);
283 VerifyClassLoaderDLC(context.get(), 0, "a.dex");
284}
285
David Brazdil1a1398e2019-03-25 17:04:47 +0000286TEST_F(ClassLoaderContextTest, ParseValidContextIMC) {
287 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]");
288 ASSERT_FALSE(context == nullptr);
289}
290
291TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000292 // IMC is treated as an unknown class loader unless a checksum is provided.
293 // This is because the dex location is always bogus.
David Brazdil1a1398e2019-03-25 17:04:47 +0000294 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]");
295 ASSERT_TRUE(context == nullptr);
296}
297
298TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) {
299 // IMC does not support arbitrary dex location. A magic marker must be used
300 // otherwise the spec should be rejected.
301 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000302 ASSERT_TRUE(context == nullptr);
303}
304
Calin Juravle87e2cb62017-06-13 21:48:45 -0700305TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
306 std::unique_ptr<ClassLoaderContext> context =
307 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
308 VerifyContextSize(context.get(), 3);
309 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
310 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
311 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
312}
313
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000314TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
315 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
316 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
317 VerifyContextSize(context.get(), 2);
318 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
319 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
320 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
321 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
322}
323
324TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
325 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
326 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
327 VerifyContextSize(context.get(), 1);
328 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
329}
330
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000331TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
332 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
333 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
334 VerifyContextSize(context.get(), 1);
335 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
336}
337
338TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
339 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
340 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
341 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
342 VerifyContextSize(context.get(), 1);
343 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
344 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
345 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
346 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
347 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
348}
349
Calin Juravle87e2cb62017-06-13 21:48:45 -0700350TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
351 std::unique_ptr<ClassLoaderContext> context =
352 ClassLoaderContext::Create("DLC[]");
353 VerifyContextSize(context.get(), 1);
354 VerifyClassLoaderDLC(context.get(), 0, "");
355}
356
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000357TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
358 std::unique_ptr<ClassLoaderContext> context =
359 ClassLoaderContext::Create("DLC[]{}");
360 VerifyContextSize(context.get(), 1);
361 VerifySharedLibrariesSize(context.get(), 0, 0);
362}
363
Calin Juravle87e2cb62017-06-13 21:48:45 -0700364TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
365 std::unique_ptr<ClassLoaderContext> context =
366 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
367 VerifyContextSize(context.get(), 0);
368}
369
370TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
371 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
372 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
373 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
374 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
375 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
376 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000377 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
378 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
379 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
380 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
381 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000382 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
383 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
384 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
385 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700386}
387
388TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
389 std::unique_ptr<ClassLoaderContext> context =
390 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
391 VerifyContextSize(context.get(), 1);
392 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
393}
394
395TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
396 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700397 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700398 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700399
Calin Juravle92003fe2017-09-06 02:22:57 +0000400
Calin Juravle87e2cb62017-06-13 21:48:45 -0700401 std::unique_ptr<ClassLoaderContext> context =
402 ClassLoaderContext::Create(
403 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
404 "DLC[" + dex_name + "]");
405
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700406 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700407
408 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700409
Calin Juravlec5b215f2017-09-12 14:49:37 -0700410 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
411 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
412 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
413 all_dex_files0.emplace_back(myclass_dex_files[i].release());
414 }
415 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
416
417 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
418 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700419}
420
Alex Light77ef93b2018-01-12 11:18:31 -0800421// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
422// TODO We should somehow support this in all situations. b/72042237.
423static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100424 int cwd_len = strlen(cwd);
425 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800426 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700427 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100428 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
429 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800430 *out = in.substr(start_position);
431 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700432}
433
434TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
435 char cwd_buf[4096];
436 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
437 PLOG(FATAL) << "Could not get working directory";
438 }
Alex Light77ef93b2018-01-12 11:18:31 -0800439 std::string multidex_name;
440 std::string myclass_dex_name;
441 std::string dex_name;
442 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
443 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
444 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
445 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
446 << "relative path.";
447 SUCCEED();
448 return;
449 }
Andreas Gampe72527382017-09-02 16:53:03 -0700450
Andreas Gampe72527382017-09-02 16:53:03 -0700451 std::unique_ptr<ClassLoaderContext> context =
452 ClassLoaderContext::Create(
453 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
454 "DLC[" + dex_name + "]");
455
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700456 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700457
Calin Juravlec5b215f2017-09-12 14:49:37 -0700458 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
459 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
460 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
461 all_dex_files0.emplace_back(myclass_dex_files[i].release());
462 }
463 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700464
Calin Juravlec5b215f2017-09-12 14:49:37 -0700465 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
466 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700467}
468
469TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
470 char cwd_buf[4096];
471 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
472 PLOG(FATAL) << "Could not get working directory";
473 }
Alex Light77ef93b2018-01-12 11:18:31 -0800474 std::string multidex_name;
475 std::string myclass_dex_name;
476 std::string dex_name;
477 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
478 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
479 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
480 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
481 << "no relative path.";
482 SUCCEED();
483 return;
484 }
Andreas Gampe72527382017-09-02 16:53:03 -0700485 std::unique_ptr<ClassLoaderContext> context =
486 ClassLoaderContext::Create(
487 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
488 "DLC[" + dex_name + "]");
489
490 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
491
492 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700493 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
494 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
495 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
496 all_dex_files0.emplace_back(myclass_dex_files[i].release());
497 }
498 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700499
Calin Juravlec5b215f2017-09-12 14:49:37 -0700500 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
501 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700502}
503
Calin Juravle87e2cb62017-06-13 21:48:45 -0700504TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
505 std::string dex_name = GetTestDexFileName("Main");
506 std::unique_ptr<ClassLoaderContext> context =
507 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
508 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
509}
510
David Brazdil1a9ac532019-03-05 11:57:13 +0000511TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
512 std::unique_ptr<ClassLoaderContext> context;
513 std::string dex_name = GetTestDexFileName("Main");
514
David Brazdil1a1398e2019-03-25 17:04:47 +0000515 context = ParseContextWithChecksums("IMC[<unknown>*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000516 VerifyContextSize(context.get(), 1);
517 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
518}
519
Calin Juravle87e2cb62017-06-13 21:48:45 -0700520TEST_F(ClassLoaderContextTest, CreateClassLoader) {
521 std::string dex_name = GetTestDexFileName("Main");
522 std::unique_ptr<ClassLoaderContext> context =
523 ClassLoaderContext::Create("PCL[" + dex_name + "]");
524 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
525
526 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
527 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
528
529 std::vector<const DexFile*> compilation_sources_raw =
530 MakeNonOwningPointerVector(compilation_sources);
531 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
532 ASSERT_TRUE(jclass_loader != nullptr);
533
534 ScopedObjectAccess soa(Thread::Current());
535
Calin Juravlec79470d2017-07-12 17:37:42 -0700536 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700537 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
538 soa.Decode<mirror::ClassLoader>(jclass_loader));
539
540 ASSERT_TRUE(class_loader->GetClass() ==
541 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
542 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
543 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
544
Calin Juravlec79470d2017-07-12 17:37:42 -0700545 // For the first class loader the class path dex files must come first and then the
546 // compilation sources.
547 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
548 for (auto& dex : compilation_sources_raw) {
549 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700550 }
551
Calin Juravlec79470d2017-07-12 17:37:42 -0700552 VerifyClassLoaderDexFiles(soa,
553 class_loader,
554 WellKnownClasses::dalvik_system_PathClassLoader,
555 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700556}
557
Calin Juravle7b0648a2017-07-07 18:40:50 -0700558TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
559 std::unique_ptr<ClassLoaderContext> context =
560 ClassLoaderContext::Create("");
561 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
562
563 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
564
565 std::vector<const DexFile*> compilation_sources_raw =
566 MakeNonOwningPointerVector(compilation_sources);
567 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
568 ASSERT_TRUE(jclass_loader != nullptr);
569
570 ScopedObjectAccess soa(Thread::Current());
571
Calin Juravlec79470d2017-07-12 17:37:42 -0700572 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700573 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
574 soa.Decode<mirror::ClassLoader>(jclass_loader));
575
Calin Juravlec79470d2017-07-12 17:37:42 -0700576 // An empty context should create a single PathClassLoader with only the compilation sources.
577 VerifyClassLoaderDexFiles(soa,
578 class_loader,
579 WellKnownClasses::dalvik_system_PathClassLoader,
580 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700581 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
582 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700583}
584
Calin Juravle1a509c82017-07-24 16:51:21 -0700585TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
586 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
587
588 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
589
590 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
591
592 std::vector<const DexFile*> compilation_sources_raw =
593 MakeNonOwningPointerVector(compilation_sources);
594 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
595 ASSERT_TRUE(jclass_loader != nullptr);
596
597 ScopedObjectAccess soa(Thread::Current());
598
599 StackHandleScope<1> hs(soa.Self());
600 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
601 soa.Decode<mirror::ClassLoader>(jclass_loader));
602
603 // A shared library context should create a single PathClassLoader with only the compilation
604 // sources.
605 VerifyClassLoaderDexFiles(soa,
606 class_loader,
607 WellKnownClasses::dalvik_system_PathClassLoader,
608 compilation_sources_raw);
609 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
610 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
611}
612
Calin Juravlec79470d2017-07-12 17:37:42 -0700613TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
614 // Setup the context.
615 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
616 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
617 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
618 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
619
620 std::string context_spec =
621 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
622 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
623 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
624
625 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
626 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
627
628 // Setup the compilation sources.
629 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
630 std::vector<const DexFile*> compilation_sources_raw =
631 MakeNonOwningPointerVector(compilation_sources);
632
633 // Create the class loader.
634 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
635 ASSERT_TRUE(jclass_loader != nullptr);
636
637 // Verify the class loader.
638 ScopedObjectAccess soa(Thread::Current());
639
640 StackHandleScope<3> hs(soa.Self());
641 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
642 soa.Decode<mirror::ClassLoader>(jclass_loader));
643
644 // Verify the first class loader
645
646 // For the first class loader the class path dex files must come first and then the
647 // compilation sources.
648 std::vector<const DexFile*> class_loader_1_dex_files =
649 MakeNonOwningPointerVector(classpath_dex_a);
650 for (auto& dex : classpath_dex_b) {
651 class_loader_1_dex_files.push_back(dex.get());
652 }
653 for (auto& dex : compilation_sources_raw) {
654 class_loader_1_dex_files.push_back(dex);
655 }
656 VerifyClassLoaderDexFiles(soa,
657 class_loader_1,
658 WellKnownClasses::dalvik_system_PathClassLoader,
659 class_loader_1_dex_files);
660
661 // Verify the second class loader
662 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
663 std::vector<const DexFile*> class_loader_2_dex_files =
664 MakeNonOwningPointerVector(classpath_dex_c);
665 VerifyClassLoaderDexFiles(soa,
666 class_loader_2,
667 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
668 class_loader_2_dex_files);
669
670 // Verify the third class loader
671 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
672 std::vector<const DexFile*> class_loader_3_dex_files =
673 MakeNonOwningPointerVector(classpath_dex_d);
674 VerifyClassLoaderDexFiles(soa,
675 class_loader_3,
676 WellKnownClasses::dalvik_system_PathClassLoader,
677 class_loader_3_dex_files);
678 // The last class loader should have the BootClassLoader as a parent.
679 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
680 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
681}
682
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000683TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
684 // Setup the context.
685 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
686 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
687 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
688 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
689
690 std::string context_spec =
691 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
692 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
693 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
694
695 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
696 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
697
698 // Setup the compilation sources.
699 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
700 std::vector<const DexFile*> compilation_sources_raw =
701 MakeNonOwningPointerVector(compilation_sources);
702
703 // Create the class loader.
704 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
705 ASSERT_TRUE(jclass_loader != nullptr);
706
707 // Verify the class loader.
708 ScopedObjectAccess soa(Thread::Current());
709
710 StackHandleScope<4> hs(soa.Self());
711 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
712 soa.Decode<mirror::ClassLoader>(jclass_loader));
713
714 // For the first class loader the class path dex files must come first and then the
715 // compilation sources.
716 std::vector<const DexFile*> class_loader_1_dex_files =
717 MakeNonOwningPointerVector(classpath_dex_a);
718 for (auto& dex : classpath_dex_b) {
719 class_loader_1_dex_files.push_back(dex.get());
720 }
721 for (auto& dex : compilation_sources_raw) {
722 class_loader_1_dex_files.push_back(dex);
723 }
724 VerifyClassLoaderDexFiles(soa,
725 class_loader_1,
726 WellKnownClasses::dalvik_system_PathClassLoader,
727 class_loader_1_dex_files);
728
729 // Verify the shared libraries.
730 ArtField* field =
731 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
732 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
733 ASSERT_TRUE(raw_shared_libraries != nullptr);
734
735 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
736 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
737 ASSERT_EQ(shared_libraries->GetLength(), 2);
738
739 // Verify the first shared library.
740 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
741 std::vector<const DexFile*> class_loader_2_dex_files =
742 MakeNonOwningPointerVector(classpath_dex_c);
743 VerifyClassLoaderDexFiles(soa,
744 class_loader_2,
745 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
746 class_loader_2_dex_files);
747 raw_shared_libraries = field->GetObject(class_loader_2.Get());
748 ASSERT_TRUE(raw_shared_libraries == nullptr);
749
750 // Verify the second shared library.
751 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
752 std::vector<const DexFile*> class_loader_3_dex_files =
753 MakeNonOwningPointerVector(classpath_dex_d);
754 VerifyClassLoaderDexFiles(soa,
755 class_loader_3,
756 WellKnownClasses::dalvik_system_PathClassLoader,
757 class_loader_3_dex_files);
758 raw_shared_libraries = field->GetObject(class_loader_3.Get());
759 ASSERT_TRUE(raw_shared_libraries == nullptr);
760
761 // All class loaders should have the BootClassLoader as a parent.
762 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
763 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
764 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
765 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
766 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
767 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
768}
769
770TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
771 // Setup the context.
772 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
773 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
774 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
775 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
776
777 std::string context_spec =
778 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
779 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
780 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
781 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
782
783 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
784 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
785
786 // Setup the compilation sources.
787 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
788 std::vector<const DexFile*> compilation_sources_raw =
789 MakeNonOwningPointerVector(compilation_sources);
790
791 // Create the class loader.
792 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
793 ASSERT_TRUE(jclass_loader != nullptr);
794
795 // Verify the class loader.
796 ScopedObjectAccess soa(Thread::Current());
797
798 StackHandleScope<6> hs(soa.Self());
799 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
800 soa.Decode<mirror::ClassLoader>(jclass_loader));
801
802 // For the first class loader the class path dex files must come first and then the
803 // compilation sources.
804 std::vector<const DexFile*> class_loader_1_dex_files =
805 MakeNonOwningPointerVector(classpath_dex_a);
806 for (auto& dex : compilation_sources_raw) {
807 class_loader_1_dex_files.push_back(dex);
808 }
809 VerifyClassLoaderDexFiles(soa,
810 class_loader_1,
811 WellKnownClasses::dalvik_system_PathClassLoader,
812 class_loader_1_dex_files);
813
814 // Verify its shared library.
815 ArtField* field =
816 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
817 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
818 ASSERT_TRUE(raw_shared_libraries != nullptr);
819
820 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
821 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
822 ASSERT_EQ(shared_libraries->GetLength(), 1);
823
824 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
825 std::vector<const DexFile*> class_loader_2_dex_files =
826 MakeNonOwningPointerVector(classpath_dex_b);
827 VerifyClassLoaderDexFiles(soa,
828 class_loader_2,
829 WellKnownClasses::dalvik_system_PathClassLoader,
830 class_loader_2_dex_files);
831 raw_shared_libraries = field->GetObject(class_loader_2.Get());
832 ASSERT_TRUE(raw_shared_libraries == nullptr);
833
834 // Verify the parent.
835 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
836 std::vector<const DexFile*> class_loader_3_dex_files =
837 MakeNonOwningPointerVector(classpath_dex_c);
838 VerifyClassLoaderDexFiles(soa,
839 class_loader_3,
840 WellKnownClasses::dalvik_system_PathClassLoader,
841 class_loader_3_dex_files);
842
843 // Verify its shared library.
844 raw_shared_libraries = field->GetObject(class_loader_3.Get());
845 ASSERT_TRUE(raw_shared_libraries != nullptr);
846
847 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
848 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
849 ASSERT_EQ(shared_libraries->GetLength(), 1);
850
851 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
852 std::vector<const DexFile*> class_loader_4_dex_files =
853 MakeNonOwningPointerVector(classpath_dex_d);
854 VerifyClassLoaderDexFiles(soa,
855 class_loader_4,
856 WellKnownClasses::dalvik_system_PathClassLoader,
857 class_loader_4_dex_files);
858 raw_shared_libraries = field->GetObject(class_loader_4.Get());
859 ASSERT_TRUE(raw_shared_libraries == nullptr);
860
861 // Class loaders should have the BootClassLoader as a parent.
862 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
863 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
864 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
865 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
866 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
867 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
868}
869
870TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
871 // Setup the context.
872 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
873 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
874 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
875 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
876
877 std::string context_spec =
878 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
879 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
880 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
881 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
882
883 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
884 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
885
886 // Setup the compilation sources.
887 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
888 std::vector<const DexFile*> compilation_sources_raw =
889 MakeNonOwningPointerVector(compilation_sources);
890
891 // Create the class loader.
892 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
893 ASSERT_TRUE(jclass_loader != nullptr);
894
895 // Verify the class loader.
896 ScopedObjectAccess soa(Thread::Current());
897
898 StackHandleScope<6> hs(soa.Self());
899 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
900 soa.Decode<mirror::ClassLoader>(jclass_loader));
901
902 // For the first class loader the class path dex files must come first and then the
903 // compilation sources.
904 std::vector<const DexFile*> class_loader_1_dex_files =
905 MakeNonOwningPointerVector(classpath_dex_a);
906 for (auto& dex : compilation_sources_raw) {
907 class_loader_1_dex_files.push_back(dex);
908 }
909 VerifyClassLoaderDexFiles(soa,
910 class_loader_1,
911 WellKnownClasses::dalvik_system_PathClassLoader,
912 class_loader_1_dex_files);
913
914 // Verify its shared library.
915 ArtField* field =
916 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
917 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
918 ASSERT_TRUE(raw_shared_libraries != nullptr);
919
920 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
921 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
922 ASSERT_EQ(shared_libraries->GetLength(), 1);
923
924 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
925 std::vector<const DexFile*> class_loader_2_dex_files =
926 MakeNonOwningPointerVector(classpath_dex_b);
927 VerifyClassLoaderDexFiles(soa,
928 class_loader_2,
929 WellKnownClasses::dalvik_system_PathClassLoader,
930 class_loader_2_dex_files);
931
932 // Verify the shared library dependency of the shared library.
933 raw_shared_libraries = field->GetObject(class_loader_2.Get());
934 ASSERT_TRUE(raw_shared_libraries != nullptr);
935
936 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
937 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
938 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
939
940 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
941 std::vector<const DexFile*> class_loader_3_dex_files =
942 MakeNonOwningPointerVector(classpath_dex_c);
943 VerifyClassLoaderDexFiles(soa,
944 class_loader_3,
945 WellKnownClasses::dalvik_system_PathClassLoader,
946 class_loader_3_dex_files);
947 raw_shared_libraries = field->GetObject(class_loader_3.Get());
948 ASSERT_TRUE(raw_shared_libraries == nullptr);
949
950 // Verify the parent.
951 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
952 std::vector<const DexFile*> class_loader_4_dex_files =
953 MakeNonOwningPointerVector(classpath_dex_d);
954 VerifyClassLoaderDexFiles(soa,
955 class_loader_4,
956 WellKnownClasses::dalvik_system_PathClassLoader,
957 class_loader_4_dex_files);
958 raw_shared_libraries = field->GetObject(class_loader_4.Get());
959 ASSERT_TRUE(raw_shared_libraries == nullptr);
960
961 // Class loaders should have the BootClassLoader as a parent.
962 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
963 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
964 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
965 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
966 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
967 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
968}
Calin Juravlec79470d2017-07-12 17:37:42 -0700969
Calin Juravle87e2cb62017-06-13 21:48:45 -0700970TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
971 std::unique_ptr<ClassLoaderContext> context =
972 ClassLoaderContext::Create("PCL[a.dex]");
973 dchecked_vector<std::string> classpath_dex;
974 classpath_dex.push_back("a.dex");
975 dchecked_vector<std::string> compilation_sources;
976 compilation_sources.push_back("src.dex");
977
978 // Nothing should be removed.
979 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
980 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
981 // Classes should be removed.
982 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
983 VerifyClassLoaderPCL(context.get(), 0, "");
984}
985
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +0000986TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
987 // Setup the context.
988 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
989 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
990 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
991
992 std::string context_spec =
993 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
994 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
995 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
996 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
997
998 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
999 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1000
1001 // Setup the compilation sources.
1002 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
1003 std::vector<const DexFile*> compilation_sources_raw =
1004 MakeNonOwningPointerVector(compilation_sources);
1005
1006 // Create the class loader.
1007 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1008 ASSERT_TRUE(jclass_loader != nullptr);
1009
1010 // Verify the class loader.
1011 ScopedObjectAccess soa(Thread::Current());
1012
1013 StackHandleScope<6> hs(soa.Self());
1014 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1015 soa.Decode<mirror::ClassLoader>(jclass_loader));
1016
1017 // For the first class loader the class path dex files must come first and then the
1018 // compilation sources.
1019 std::vector<const DexFile*> class_loader_1_dex_files =
1020 MakeNonOwningPointerVector(classpath_dex_a);
1021 for (auto& dex : compilation_sources_raw) {
1022 class_loader_1_dex_files.push_back(dex);
1023 }
1024 VerifyClassLoaderDexFiles(soa,
1025 class_loader_1,
1026 WellKnownClasses::dalvik_system_PathClassLoader,
1027 class_loader_1_dex_files);
1028
1029 // Verify its shared library.
1030 ArtField* field =
1031 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1032 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1033 ASSERT_TRUE(raw_shared_libraries != nullptr);
1034
1035 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1036 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1037 ASSERT_EQ(shared_libraries->GetLength(), 1);
1038
1039 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1040 std::vector<const DexFile*> class_loader_2_dex_files =
1041 MakeNonOwningPointerVector(classpath_dex_b);
1042 VerifyClassLoaderDexFiles(soa,
1043 class_loader_2,
1044 WellKnownClasses::dalvik_system_PathClassLoader,
1045 class_loader_2_dex_files);
1046
1047 // Verify the parent.
1048 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1049 std::vector<const DexFile*> class_loader_3_dex_files =
1050 MakeNonOwningPointerVector(classpath_dex_c);
1051 VerifyClassLoaderDexFiles(soa,
1052 class_loader_3,
1053 WellKnownClasses::dalvik_system_PathClassLoader,
1054 class_loader_3_dex_files);
1055
1056 // Verify its shared library is the same as the child.
1057 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1058 ASSERT_TRUE(raw_shared_libraries != nullptr);
1059 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1060 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1061 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
1062 ASSERT_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
1063
1064 // Class loaders should have the BootClassLoader as a parent.
1065 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1066 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1067 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1068 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1069}
1070
Calin Juravle87e2cb62017-06-13 21:48:45 -07001071TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1072 std::string dex1_name = GetTestDexFileName("Main");
1073 std::string dex2_name = GetTestDexFileName("MyClass");
1074 std::unique_ptr<ClassLoaderContext> context =
1075 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1076 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1077
1078 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1079 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1080 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001081 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1082 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001083 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1084}
1085
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001086TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1087 std::string dex1_name = GetTestDexFileName("Main");
1088 std::string dex2_name = GetTestDexFileName("MultiDex");
1089 std::unique_ptr<ClassLoaderContext> context =
1090 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1091 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1092
1093 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1094 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
1095 std::string encoding = context->EncodeContextForDex2oat("");
1096 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1097 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1098}
1099
Calin Juravle57d0acc2017-07-11 17:41:30 -07001100// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1101TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1102 // The chain is
1103 // ClassLoaderA (PathClassLoader)
1104 // ^
1105 // |
1106 // ClassLoaderB (DelegateLastClassLoader)
1107 // ^
1108 // |
1109 // ClassLoaderC (PathClassLoader)
1110 // ^
1111 // |
1112 // ClassLoaderD (DelegateLastClassLoader)
1113
1114 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1115 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1116 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1117 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1118
1119 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1120
1121 VerifyContextForClassLoader(context.get());
1122 VerifyContextSize(context.get(), 4);
1123
1124 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1125 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1126 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1127 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1128}
1129
David Brazdil1a9ac532019-03-05 11:57:13 +00001130TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1131 // The chain is
1132 // ClassLoaderA (PathClassLoader)
1133 // ^
1134 // |
1135 // ClassLoaderB (InMemoryDexClassLoader)
1136 // ^
1137 // |
1138 // ClassLoaderC (InMemoryDexClassLoader)
1139 // ^
1140 // |
1141 // ClassLoaderD (DelegateLastClassLoader)
1142
1143 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1144 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1145 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1146 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1147
1148 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1149
1150 VerifyContextForClassLoader(context.get());
1151 VerifyContextSize(context.get(), 4);
1152
1153 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1154 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1155 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1156 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1157}
Mathieu Chartieradc90862018-05-11 13:03:06 -07001158
1159TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1160 std::string context_spec = "PCL[]";
1161 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1162 ASSERT_TRUE(context != nullptr);
1163 PretendContextOpenedDexFiles(context.get());
1164 // Ensure that the special shared library marks as verified for the first thing in the class path.
1165 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1166 ClassLoaderContext::VerificationResult::kVerifies);
1167}
1168
Calin Juravle3f918642017-07-11 19:04:20 -07001169TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1170 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1171 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001172 // Pretend that we successfully open the dex files to pass the DCHECKS.
1173 // (as it's much easier to test all the corner cases without relying on actual dex files).
1174 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001175
1176 VerifyContextSize(context.get(), 2);
1177 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1178 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1179
Mathieu Chartieradc90862018-05-11 13:03:06 -07001180 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1181 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001182
1183 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001184 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1185 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001186
1187 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001188 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1189 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001190
1191 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001192 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1193 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001194
1195 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001196 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1197 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001198
1199 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 -07001200 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1201 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001202
1203 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 -07001204 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1205 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001206
1207 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001208 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1209 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001210}
1211
David Brazdil1a9ac532019-03-05 11:57:13 +00001212TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
David Brazdil1a1398e2019-03-25 17:04:47 +00001213 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 +00001214 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1215 // Pretend that we successfully open the dex files to pass the DCHECKS.
1216 // (as it's much easier to test all the corner cases without relying on actual dex files).
1217 PretendContextOpenedDexFiles(context.get());
1218
1219 VerifyContextSize(context.get(), 3);
1220 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1221 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil1a1398e2019-03-25 17:04:47 +00001222 VerifyClassLoaderIMC(context.get(), 2, "<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001223
1224 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1225 ClassLoaderContext::VerificationResult::kVerifies);
1226}
1227
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001228TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1229 std::string context_spec = "&";
1230 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1231 // Pretend that we successfully open the dex files to pass the DCHECKS.
1232 // (as it's much easier to test all the corner cases without relying on actual dex files).
1233 PretendContextOpenedDexFiles(context.get());
1234
1235 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1236 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1237}
1238
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001239TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1240 std::string context_spec =
1241 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1242 ";DLC[c.dex*890]";
1243 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1244 // Pretend that we successfully open the dex files to pass the DCHECKS.
1245 // (as it's much easier to test all the corner cases without relying on actual dex files).
1246 PretendContextOpenedDexFiles(context.get());
1247
1248 VerifyContextSize(context.get(), 2);
1249 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1250 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1251 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1252 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1253
1254 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1255 ClassLoaderContext::VerificationResult::kVerifies);
1256
1257 std::string wrong_class_loader_type =
1258 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1259 ";DLC[c.dex*890]";
1260 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1261 ClassLoaderContext::VerificationResult::kMismatch);
1262
1263 std::string wrong_class_loader_order =
1264 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1265 ";DLC[c.dex*890]";
1266 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1267 ClassLoaderContext::VerificationResult::kMismatch);
1268
1269 std::string wrong_classpath_order =
1270 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1271 ";DLC[c.dex*890]";
1272 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1273 ClassLoaderContext::VerificationResult::kMismatch);
1274
1275 std::string wrong_checksum =
1276 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1277 ";DLC[c.dex*890]";
1278 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1279 ClassLoaderContext::VerificationResult::kMismatch);
1280
1281 std::string wrong_extra_class_loader =
1282 "PCL[a.dex*123:b.dex*456]"
1283 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1284 ";DLC[c.dex*890]";
1285 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1286 ClassLoaderContext::VerificationResult::kMismatch);
1287
1288 std::string wrong_extra_classpath =
1289 "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]}"
1290 ";DLC[c.dex*890]";
1291 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1292 ClassLoaderContext::VerificationResult::kMismatch);
1293}
1294
David Brazdil1a9ac532019-03-05 11:57:13 +00001295TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1296 std::string context_spec =
David Brazdil1a1398e2019-03-25 17:04:47 +00001297 "IMC[<unknown>*123:<unknown>*456]"
1298 "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};"
1299 "DLC[c.dex*890]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001300 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1301 // Pretend that we successfully open the dex files to pass the DCHECKS.
1302 // (as it's much easier to test all the corner cases without relying on actual dex files).
1303 PretendContextOpenedDexFiles(context.get());
1304
1305 VerifyContextSize(context.get(), 2);
David Brazdil1a1398e2019-03-25 17:04:47 +00001306 VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001307 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
David Brazdil1a1398e2019-03-25 17:04:47 +00001308 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>");
1309 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>");
David Brazdil1a9ac532019-03-05 11:57:13 +00001310
1311 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1312 ClassLoaderContext::VerificationResult::kVerifies);
1313}
1314
Calin Juravle3f918642017-07-11 19:04:20 -07001315TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1316 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1317 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1318 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1319 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1320
1321 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1322
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001323 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001324 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1325 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001326
1327 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1328 size_t pos = dex_location.rfind('/');
1329 ASSERT_NE(std::string::npos, pos);
1330 std::string parent = dex_location.substr(0, pos);
1331
1332 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1333 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001334 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1335 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001336}
1337
David Brazdil1a9ac532019-03-05 11:57:13 +00001338TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1339 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1340 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1341 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1342 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1343
1344 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1345
1346 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1347 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1348 ClassLoaderContext::VerificationResult::kVerifies);
1349
1350 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1351 size_t pos = dex_location.rfind('/');
1352 ASSERT_NE(std::string::npos, pos);
1353 std::string parent = dex_location.substr(0, pos);
1354
1355 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1356 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1357 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1358 ClassLoaderContext::VerificationResult::kVerifies);
1359}
1360
Calin Juravlea308a322017-07-18 16:51:51 -07001361TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1362 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1363
1364 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1365
Mathieu Chartieradc90862018-05-11 13:03:06 -07001366 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1367 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001368}
1369
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001370TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1371 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1372
1373 ScopedObjectAccess soa(Thread::Current());
1374 StackHandleScope<1> hs(soa.Self());
1375 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1376 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1377 soa.Self(),
1378 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1379 1));
1380 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1381
1382 jobject class_loader_b = LoadDexInPathClassLoader(
1383 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1384
1385 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1386 ASSERT_TRUE(context != nullptr);
1387 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1388 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1389 dex_files = OpenTestDexFiles("ForClassLoaderA");
1390 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1391
1392 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1393 ClassLoaderContext::VerificationResult::kVerifies);
1394}
1395
Calin Juravle87e2cb62017-06-13 21:48:45 -07001396} // namespace art