blob: 6d44b71b67ec27ae04323e3c96b1ca2bb2669a2c [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(
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
Nicolas Geoffray93d99f32019-03-27 08:56:02 +0000286TEST_F(ClassLoaderContextTest, ParseInvalidContextIMC) {
David Brazdil1a9ac532019-03-05 11:57:13 +0000287 // IMC is treated as an unknown class loader unless a checksum is provided.
288 // This is because the dex location is always bogus.
Nicolas Geoffray93d99f32019-03-27 08:56:02 +0000289 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000290 ASSERT_TRUE(context == nullptr);
291}
292
Calin Juravle87e2cb62017-06-13 21:48:45 -0700293TEST_F(ClassLoaderContextTest, ParseValidContextChain) {
294 std::unique_ptr<ClassLoaderContext> context =
295 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]");
296 VerifyContextSize(context.get(), 3);
297 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
298 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
299 VerifyClassLoaderPCL(context.get(), 2, "e.dex");
300}
301
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000302TEST_F(ClassLoaderContextTest, ParseSharedLibraries) {
303 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
304 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}");
305 VerifyContextSize(context.get(), 2);
306 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
307 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex");
308 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex");
309 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex");
310}
311
312TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) {
313 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
314 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}");
315 VerifyContextSize(context.get(), 1);
316 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
317}
318
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000319TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) {
320 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
321 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}");
322 VerifyContextSize(context.get(), 1);
323 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex");
324}
325
326TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) {
327 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(
328 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#"
329 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}");
330 VerifyContextSize(context.get(), 1);
331 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex");
332 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex");
333 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex");
334 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex");
335 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex");
336}
337
Calin Juravle87e2cb62017-06-13 21:48:45 -0700338TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) {
339 std::unique_ptr<ClassLoaderContext> context =
340 ClassLoaderContext::Create("DLC[]");
341 VerifyContextSize(context.get(), 1);
342 VerifyClassLoaderDLC(context.get(), 0, "");
343}
344
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000345TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) {
346 std::unique_ptr<ClassLoaderContext> context =
347 ClassLoaderContext::Create("DLC[]{}");
348 VerifyContextSize(context.get(), 1);
349 VerifySharedLibrariesSize(context.get(), 0, 0);
350}
351
Calin Juravle87e2cb62017-06-13 21:48:45 -0700352TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) {
353 std::unique_ptr<ClassLoaderContext> context =
354 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary);
355 VerifyContextSize(context.get(), 0);
356}
357
358TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) {
359 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]"));
360 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL"));
361 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex"));
362 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]"));
363 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}"));
364 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex"));
Nicolas Geoffray06af3b42018-10-29 10:39:04 +0000365 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex"));
366 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex"));
367 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}"));
368 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{"));
369 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}"));
Nicolas Geoffrayf378fff2018-11-19 12:52:26 +0000370 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}"));
371 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}"));
372 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}"));
373 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}"));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700374}
375
376TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) {
377 std::unique_ptr<ClassLoaderContext> context =
378 ClassLoaderContext::Create("PCL[does_not_exist.dex]");
379 VerifyContextSize(context.get(), 1);
380 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
381}
382
383TEST_F(ClassLoaderContextTest, OpenValidDexFiles) {
384 std::string multidex_name = GetTestDexFileName("MultiDex");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700385 std::string myclass_dex_name = GetTestDexFileName("MyClass");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700386 std::string dex_name = GetTestDexFileName("Main");
Calin Juravle87e2cb62017-06-13 21:48:45 -0700387
Calin Juravle92003fe2017-09-06 02:22:57 +0000388
Calin Juravle87e2cb62017-06-13 21:48:45 -0700389 std::unique_ptr<ClassLoaderContext> context =
390 ClassLoaderContext::Create(
391 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
392 "DLC[" + dex_name + "]");
393
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700394 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Calin Juravle87e2cb62017-06-13 21:48:45 -0700395
396 VerifyContextSize(context.get(), 2);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700397
Calin Juravlec5b215f2017-09-12 14:49:37 -0700398 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
399 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
400 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
401 all_dex_files0.emplace_back(myclass_dex_files[i].release());
402 }
403 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
404
405 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
406 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700407}
408
Alex Light77ef93b2018-01-12 11:18:31 -0800409// Creates a relative path from cwd to 'in'. Returns false if it cannot be done.
410// TODO We should somehow support this in all situations. b/72042237.
411static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) {
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100412 int cwd_len = strlen(cwd);
413 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) {
Alex Light77ef93b2018-01-12 11:18:31 -0800414 return false;
Andreas Gampe72527382017-09-02 16:53:03 -0700415 }
Nicolas Geoffrayc4be2c82017-09-05 12:40:06 +0100416 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/');
417 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1);
Alex Light77ef93b2018-01-12 11:18:31 -0800418 *out = in.substr(start_position);
419 return true;
Andreas Gampe72527382017-09-02 16:53:03 -0700420}
421
422TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) {
423 char cwd_buf[4096];
424 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
425 PLOG(FATAL) << "Could not get working directory";
426 }
Alex Light77ef93b2018-01-12 11:18:31 -0800427 std::string multidex_name;
428 std::string myclass_dex_name;
429 std::string dex_name;
430 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
431 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
432 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
433 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no "
434 << "relative path.";
435 SUCCEED();
436 return;
437 }
Andreas Gampe72527382017-09-02 16:53:03 -0700438
Andreas Gampe72527382017-09-02 16:53:03 -0700439 std::unique_ptr<ClassLoaderContext> context =
440 ClassLoaderContext::Create(
441 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
442 "DLC[" + dex_name + "]");
443
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700444 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ ""));
Andreas Gampe72527382017-09-02 16:53:03 -0700445
Calin Juravlec5b215f2017-09-12 14:49:37 -0700446 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
447 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
448 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
449 all_dex_files0.emplace_back(myclass_dex_files[i].release());
450 }
451 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700452
Calin Juravlec5b215f2017-09-12 14:49:37 -0700453 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
454 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700455}
456
457TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) {
458 char cwd_buf[4096];
459 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) {
460 PLOG(FATAL) << "Could not get working directory";
461 }
Alex Light77ef93b2018-01-12 11:18:31 -0800462 std::string multidex_name;
463 std::string myclass_dex_name;
464 std::string dex_name;
465 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) ||
466 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) ||
467 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) {
468 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have "
469 << "no relative path.";
470 SUCCEED();
471 return;
472 }
Andreas Gampe72527382017-09-02 16:53:03 -0700473 std::unique_ptr<ClassLoaderContext> context =
474 ClassLoaderContext::Create(
475 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" +
476 "DLC[" + dex_name + "]");
477
478 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf));
479
480 VerifyContextSize(context.get(), 2);
Calin Juravlec5b215f2017-09-12 14:49:37 -0700481 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex");
482 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass");
483 for (size_t i = 0; i < myclass_dex_files.size(); i++) {
484 all_dex_files0.emplace_back(myclass_dex_files[i].release());
485 }
486 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0);
Andreas Gampe72527382017-09-02 16:53:03 -0700487
Calin Juravlec5b215f2017-09-12 14:49:37 -0700488 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main");
489 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1);
Andreas Gampe72527382017-09-02 16:53:03 -0700490}
491
Calin Juravle87e2cb62017-06-13 21:48:45 -0700492TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) {
493 std::string dex_name = GetTestDexFileName("Main");
494 std::unique_ptr<ClassLoaderContext> context =
495 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]");
496 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ""));
497}
498
David Brazdil1a9ac532019-03-05 11:57:13 +0000499TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) {
500 std::unique_ptr<ClassLoaderContext> context;
501 std::string dex_name = GetTestDexFileName("Main");
502
Nicolas Geoffray93d99f32019-03-27 08:56:02 +0000503 context = ParseContextWithChecksums("PCL[" + dex_name + "*111]");
504 VerifyContextSize(context.get(), 1);
505 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "."));
506
507 context = ParseContextWithChecksums("IMC[" + dex_name + "*111]");
David Brazdil1a9ac532019-03-05 11:57:13 +0000508 VerifyContextSize(context.get(), 1);
509 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "."));
510}
511
Calin Juravle87e2cb62017-06-13 21:48:45 -0700512TEST_F(ClassLoaderContextTest, CreateClassLoader) {
513 std::string dex_name = GetTestDexFileName("Main");
514 std::unique_ptr<ClassLoaderContext> context =
515 ClassLoaderContext::Create("PCL[" + dex_name + "]");
516 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
517
518 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main");
519 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
520
521 std::vector<const DexFile*> compilation_sources_raw =
522 MakeNonOwningPointerVector(compilation_sources);
523 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
524 ASSERT_TRUE(jclass_loader != nullptr);
525
526 ScopedObjectAccess soa(Thread::Current());
527
Calin Juravlec79470d2017-07-12 17:37:42 -0700528 StackHandleScope<1> hs(soa.Self());
Calin Juravle87e2cb62017-06-13 21:48:45 -0700529 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
530 soa.Decode<mirror::ClassLoader>(jclass_loader));
531
532 ASSERT_TRUE(class_loader->GetClass() ==
533 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
534 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
535 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
536
Calin Juravlec79470d2017-07-12 17:37:42 -0700537 // For the first class loader the class path dex files must come first and then the
538 // compilation sources.
539 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex);
540 for (auto& dex : compilation_sources_raw) {
541 expected_classpath.push_back(dex);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700542 }
543
Calin Juravlec79470d2017-07-12 17:37:42 -0700544 VerifyClassLoaderDexFiles(soa,
545 class_loader,
546 WellKnownClasses::dalvik_system_PathClassLoader,
547 expected_classpath);
Calin Juravle87e2cb62017-06-13 21:48:45 -0700548}
549
Calin Juravle7b0648a2017-07-07 18:40:50 -0700550TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) {
551 std::unique_ptr<ClassLoaderContext> context =
552 ClassLoaderContext::Create("");
553 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
554
555 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
556
557 std::vector<const DexFile*> compilation_sources_raw =
558 MakeNonOwningPointerVector(compilation_sources);
559 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
560 ASSERT_TRUE(jclass_loader != nullptr);
561
562 ScopedObjectAccess soa(Thread::Current());
563
Calin Juravlec79470d2017-07-12 17:37:42 -0700564 StackHandleScope<1> hs(soa.Self());
Calin Juravle7b0648a2017-07-07 18:40:50 -0700565 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
566 soa.Decode<mirror::ClassLoader>(jclass_loader));
567
Calin Juravlec79470d2017-07-12 17:37:42 -0700568 // An empty context should create a single PathClassLoader with only the compilation sources.
569 VerifyClassLoaderDexFiles(soa,
570 class_loader,
571 WellKnownClasses::dalvik_system_PathClassLoader,
572 compilation_sources_raw);
Calin Juravle7b0648a2017-07-07 18:40:50 -0700573 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
574 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
Calin Juravle7b0648a2017-07-07 18:40:50 -0700575}
576
Calin Juravle1a509c82017-07-24 16:51:21 -0700577TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) {
578 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&");
579
580 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
581
582 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
583
584 std::vector<const DexFile*> compilation_sources_raw =
585 MakeNonOwningPointerVector(compilation_sources);
586 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
587 ASSERT_TRUE(jclass_loader != nullptr);
588
589 ScopedObjectAccess soa(Thread::Current());
590
591 StackHandleScope<1> hs(soa.Self());
592 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
593 soa.Decode<mirror::ClassLoader>(jclass_loader));
594
595 // A shared library context should create a single PathClassLoader with only the compilation
596 // sources.
597 VerifyClassLoaderDexFiles(soa,
598 class_loader,
599 WellKnownClasses::dalvik_system_PathClassLoader,
600 compilation_sources_raw);
601 ASSERT_TRUE(class_loader->GetParent()->GetClass() ==
602 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
603}
604
Calin Juravlec79470d2017-07-12 17:37:42 -0700605TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) {
606 // Setup the context.
607 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
608 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
609 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
610 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
611
612 std::string context_spec =
613 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" +
614 "DLC[" + CreateClassPath(classpath_dex_c) + "];" +
615 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
616
617 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
618 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
619
620 // Setup the compilation sources.
621 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
622 std::vector<const DexFile*> compilation_sources_raw =
623 MakeNonOwningPointerVector(compilation_sources);
624
625 // Create the class loader.
626 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
627 ASSERT_TRUE(jclass_loader != nullptr);
628
629 // Verify the class loader.
630 ScopedObjectAccess soa(Thread::Current());
631
632 StackHandleScope<3> hs(soa.Self());
633 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
634 soa.Decode<mirror::ClassLoader>(jclass_loader));
635
636 // Verify the first class loader
637
638 // For the first class loader the class path dex files must come first and then the
639 // compilation sources.
640 std::vector<const DexFile*> class_loader_1_dex_files =
641 MakeNonOwningPointerVector(classpath_dex_a);
642 for (auto& dex : classpath_dex_b) {
643 class_loader_1_dex_files.push_back(dex.get());
644 }
645 for (auto& dex : compilation_sources_raw) {
646 class_loader_1_dex_files.push_back(dex);
647 }
648 VerifyClassLoaderDexFiles(soa,
649 class_loader_1,
650 WellKnownClasses::dalvik_system_PathClassLoader,
651 class_loader_1_dex_files);
652
653 // Verify the second class loader
654 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent());
655 std::vector<const DexFile*> class_loader_2_dex_files =
656 MakeNonOwningPointerVector(classpath_dex_c);
657 VerifyClassLoaderDexFiles(soa,
658 class_loader_2,
659 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
660 class_loader_2_dex_files);
661
662 // Verify the third class loader
663 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent());
664 std::vector<const DexFile*> class_loader_3_dex_files =
665 MakeNonOwningPointerVector(classpath_dex_d);
666 VerifyClassLoaderDexFiles(soa,
667 class_loader_3,
668 WellKnownClasses::dalvik_system_PathClassLoader,
669 class_loader_3_dex_files);
670 // The last class loader should have the BootClassLoader as a parent.
671 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
672 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
673}
674
Nicolas Geoffray6b9fd8c2018-11-16 10:25:42 +0000675TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) {
676 // Setup the context.
677 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
678 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
679 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
680 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
681
682 std::string context_spec =
683 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" +
684 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" +
685 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
686
687 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
688 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
689
690 // Setup the compilation sources.
691 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
692 std::vector<const DexFile*> compilation_sources_raw =
693 MakeNonOwningPointerVector(compilation_sources);
694
695 // Create the class loader.
696 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
697 ASSERT_TRUE(jclass_loader != nullptr);
698
699 // Verify the class loader.
700 ScopedObjectAccess soa(Thread::Current());
701
702 StackHandleScope<4> hs(soa.Self());
703 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
704 soa.Decode<mirror::ClassLoader>(jclass_loader));
705
706 // For the first class loader the class path dex files must come first and then the
707 // compilation sources.
708 std::vector<const DexFile*> class_loader_1_dex_files =
709 MakeNonOwningPointerVector(classpath_dex_a);
710 for (auto& dex : classpath_dex_b) {
711 class_loader_1_dex_files.push_back(dex.get());
712 }
713 for (auto& dex : compilation_sources_raw) {
714 class_loader_1_dex_files.push_back(dex);
715 }
716 VerifyClassLoaderDexFiles(soa,
717 class_loader_1,
718 WellKnownClasses::dalvik_system_PathClassLoader,
719 class_loader_1_dex_files);
720
721 // Verify the shared libraries.
722 ArtField* field =
723 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
724 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
725 ASSERT_TRUE(raw_shared_libraries != nullptr);
726
727 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
728 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
729 ASSERT_EQ(shared_libraries->GetLength(), 2);
730
731 // Verify the first shared library.
732 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
733 std::vector<const DexFile*> class_loader_2_dex_files =
734 MakeNonOwningPointerVector(classpath_dex_c);
735 VerifyClassLoaderDexFiles(soa,
736 class_loader_2,
737 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
738 class_loader_2_dex_files);
739 raw_shared_libraries = field->GetObject(class_loader_2.Get());
740 ASSERT_TRUE(raw_shared_libraries == nullptr);
741
742 // Verify the second shared library.
743 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1));
744 std::vector<const DexFile*> class_loader_3_dex_files =
745 MakeNonOwningPointerVector(classpath_dex_d);
746 VerifyClassLoaderDexFiles(soa,
747 class_loader_3,
748 WellKnownClasses::dalvik_system_PathClassLoader,
749 class_loader_3_dex_files);
750 raw_shared_libraries = field->GetObject(class_loader_3.Get());
751 ASSERT_TRUE(raw_shared_libraries == nullptr);
752
753 // All class loaders should have the BootClassLoader as a parent.
754 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() ==
755 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
756 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
757 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
758 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
759 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
760}
761
762TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) {
763 // Setup the context.
764 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
765 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
766 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
767 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
768
769 std::string context_spec =
770 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
771 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
772 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
773 "PCL[" + CreateClassPath(classpath_dex_d) + "]}";
774
775 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
776 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
777
778 // Setup the compilation sources.
779 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
780 std::vector<const DexFile*> compilation_sources_raw =
781 MakeNonOwningPointerVector(compilation_sources);
782
783 // Create the class loader.
784 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
785 ASSERT_TRUE(jclass_loader != nullptr);
786
787 // Verify the class loader.
788 ScopedObjectAccess soa(Thread::Current());
789
790 StackHandleScope<6> hs(soa.Self());
791 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
792 soa.Decode<mirror::ClassLoader>(jclass_loader));
793
794 // For the first class loader the class path dex files must come first and then the
795 // compilation sources.
796 std::vector<const DexFile*> class_loader_1_dex_files =
797 MakeNonOwningPointerVector(classpath_dex_a);
798 for (auto& dex : compilation_sources_raw) {
799 class_loader_1_dex_files.push_back(dex);
800 }
801 VerifyClassLoaderDexFiles(soa,
802 class_loader_1,
803 WellKnownClasses::dalvik_system_PathClassLoader,
804 class_loader_1_dex_files);
805
806 // Verify its shared library.
807 ArtField* field =
808 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
809 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
810 ASSERT_TRUE(raw_shared_libraries != nullptr);
811
812 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
813 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
814 ASSERT_EQ(shared_libraries->GetLength(), 1);
815
816 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
817 std::vector<const DexFile*> class_loader_2_dex_files =
818 MakeNonOwningPointerVector(classpath_dex_b);
819 VerifyClassLoaderDexFiles(soa,
820 class_loader_2,
821 WellKnownClasses::dalvik_system_PathClassLoader,
822 class_loader_2_dex_files);
823 raw_shared_libraries = field->GetObject(class_loader_2.Get());
824 ASSERT_TRUE(raw_shared_libraries == nullptr);
825
826 // Verify the parent.
827 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
828 std::vector<const DexFile*> class_loader_3_dex_files =
829 MakeNonOwningPointerVector(classpath_dex_c);
830 VerifyClassLoaderDexFiles(soa,
831 class_loader_3,
832 WellKnownClasses::dalvik_system_PathClassLoader,
833 class_loader_3_dex_files);
834
835 // Verify its shared library.
836 raw_shared_libraries = field->GetObject(class_loader_3.Get());
837 ASSERT_TRUE(raw_shared_libraries != nullptr);
838
839 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
840 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
841 ASSERT_EQ(shared_libraries->GetLength(), 1);
842
843 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0));
844 std::vector<const DexFile*> class_loader_4_dex_files =
845 MakeNonOwningPointerVector(classpath_dex_d);
846 VerifyClassLoaderDexFiles(soa,
847 class_loader_4,
848 WellKnownClasses::dalvik_system_PathClassLoader,
849 class_loader_4_dex_files);
850 raw_shared_libraries = field->GetObject(class_loader_4.Get());
851 ASSERT_TRUE(raw_shared_libraries == nullptr);
852
853 // Class loaders should have the BootClassLoader as a parent.
854 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
855 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
856 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
857 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
858 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
859 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
860}
861
862TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) {
863 // Setup the context.
864 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
865 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
866 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
867 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD");
868
869 std::string context_spec =
870 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
871 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" +
872 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" +
873 "PCL[" + CreateClassPath(classpath_dex_d) + "]";
874
875 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
876 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
877
878 // Setup the compilation sources.
879 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
880 std::vector<const DexFile*> compilation_sources_raw =
881 MakeNonOwningPointerVector(compilation_sources);
882
883 // Create the class loader.
884 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
885 ASSERT_TRUE(jclass_loader != nullptr);
886
887 // Verify the class loader.
888 ScopedObjectAccess soa(Thread::Current());
889
890 StackHandleScope<6> hs(soa.Self());
891 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
892 soa.Decode<mirror::ClassLoader>(jclass_loader));
893
894 // For the first class loader the class path dex files must come first and then the
895 // compilation sources.
896 std::vector<const DexFile*> class_loader_1_dex_files =
897 MakeNonOwningPointerVector(classpath_dex_a);
898 for (auto& dex : compilation_sources_raw) {
899 class_loader_1_dex_files.push_back(dex);
900 }
901 VerifyClassLoaderDexFiles(soa,
902 class_loader_1,
903 WellKnownClasses::dalvik_system_PathClassLoader,
904 class_loader_1_dex_files);
905
906 // Verify its shared library.
907 ArtField* field =
908 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
909 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
910 ASSERT_TRUE(raw_shared_libraries != nullptr);
911
912 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
913 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
914 ASSERT_EQ(shared_libraries->GetLength(), 1);
915
916 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
917 std::vector<const DexFile*> class_loader_2_dex_files =
918 MakeNonOwningPointerVector(classpath_dex_b);
919 VerifyClassLoaderDexFiles(soa,
920 class_loader_2,
921 WellKnownClasses::dalvik_system_PathClassLoader,
922 class_loader_2_dex_files);
923
924 // Verify the shared library dependency of the shared library.
925 raw_shared_libraries = field->GetObject(class_loader_2.Get());
926 ASSERT_TRUE(raw_shared_libraries != nullptr);
927
928 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
929 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
930 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
931
932 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0));
933 std::vector<const DexFile*> class_loader_3_dex_files =
934 MakeNonOwningPointerVector(classpath_dex_c);
935 VerifyClassLoaderDexFiles(soa,
936 class_loader_3,
937 WellKnownClasses::dalvik_system_PathClassLoader,
938 class_loader_3_dex_files);
939 raw_shared_libraries = field->GetObject(class_loader_3.Get());
940 ASSERT_TRUE(raw_shared_libraries == nullptr);
941
942 // Verify the parent.
943 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent());
944 std::vector<const DexFile*> class_loader_4_dex_files =
945 MakeNonOwningPointerVector(classpath_dex_d);
946 VerifyClassLoaderDexFiles(soa,
947 class_loader_4,
948 WellKnownClasses::dalvik_system_PathClassLoader,
949 class_loader_4_dex_files);
950 raw_shared_libraries = field->GetObject(class_loader_4.Get());
951 ASSERT_TRUE(raw_shared_libraries == nullptr);
952
953 // Class loaders should have the BootClassLoader as a parent.
954 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
955 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
956 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
957 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
958 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() ==
959 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
960}
Calin Juravlec79470d2017-07-12 17:37:42 -0700961
Calin Juravle87e2cb62017-06-13 21:48:45 -0700962TEST_F(ClassLoaderContextTest, RemoveSourceLocations) {
963 std::unique_ptr<ClassLoaderContext> context =
964 ClassLoaderContext::Create("PCL[a.dex]");
965 dchecked_vector<std::string> classpath_dex;
966 classpath_dex.push_back("a.dex");
967 dchecked_vector<std::string> compilation_sources;
968 compilation_sources.push_back("src.dex");
969
970 // Nothing should be removed.
971 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources));
972 VerifyClassLoaderPCL(context.get(), 0, "a.dex");
973 // Classes should be removed.
974 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex));
975 VerifyClassLoaderPCL(context.get(), 0, "");
976}
977
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +0000978TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) {
979 // Setup the context.
980 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA");
981 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB");
982 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC");
983
984 std::string context_spec =
985 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" +
986 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" +
987 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" +
988 "PCL[" + CreateClassPath(classpath_dex_b) + "]}";
989
990 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec);
991 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
992
993 // Setup the compilation sources.
994 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex");
995 std::vector<const DexFile*> compilation_sources_raw =
996 MakeNonOwningPointerVector(compilation_sources);
997
998 // Create the class loader.
999 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw);
1000 ASSERT_TRUE(jclass_loader != nullptr);
1001
1002 // Verify the class loader.
1003 ScopedObjectAccess soa(Thread::Current());
1004
1005 StackHandleScope<6> hs(soa.Self());
1006 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle(
1007 soa.Decode<mirror::ClassLoader>(jclass_loader));
1008
1009 // For the first class loader the class path dex files must come first and then the
1010 // compilation sources.
1011 std::vector<const DexFile*> class_loader_1_dex_files =
1012 MakeNonOwningPointerVector(classpath_dex_a);
1013 for (auto& dex : compilation_sources_raw) {
1014 class_loader_1_dex_files.push_back(dex);
1015 }
1016 VerifyClassLoaderDexFiles(soa,
1017 class_loader_1,
1018 WellKnownClasses::dalvik_system_PathClassLoader,
1019 class_loader_1_dex_files);
1020
1021 // Verify its shared library.
1022 ArtField* field =
1023 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
1024 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get());
1025 ASSERT_TRUE(raw_shared_libraries != nullptr);
1026
1027 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
1028 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1029 ASSERT_EQ(shared_libraries->GetLength(), 1);
1030
1031 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0));
1032 std::vector<const DexFile*> class_loader_2_dex_files =
1033 MakeNonOwningPointerVector(classpath_dex_b);
1034 VerifyClassLoaderDexFiles(soa,
1035 class_loader_2,
1036 WellKnownClasses::dalvik_system_PathClassLoader,
1037 class_loader_2_dex_files);
1038
1039 // Verify the parent.
1040 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent());
1041 std::vector<const DexFile*> class_loader_3_dex_files =
1042 MakeNonOwningPointerVector(classpath_dex_c);
1043 VerifyClassLoaderDexFiles(soa,
1044 class_loader_3,
1045 WellKnownClasses::dalvik_system_PathClassLoader,
1046 class_loader_3_dex_files);
1047
1048 // Verify its shared library is the same as the child.
1049 raw_shared_libraries = field->GetObject(class_loader_3.Get());
1050 ASSERT_TRUE(raw_shared_libraries != nullptr);
1051 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2(
1052 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
1053 ASSERT_EQ(shared_libraries_2->GetLength(), 1);
Vladimir Marko423bebb2019-03-26 15:17:21 +00001054 ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get());
Nicolas Geoffraycb2e1dd2018-11-20 11:15:13 +00001055
1056 // Class loaders should have the BootClassLoader as a parent.
1057 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() ==
1058 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1059 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() ==
1060 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
1061}
1062
Calin Juravle87e2cb62017-06-13 21:48:45 -07001063TEST_F(ClassLoaderContextTest, EncodeInOatFile) {
1064 std::string dex1_name = GetTestDexFileName("Main");
1065 std::string dex2_name = GetTestDexFileName("MyClass");
1066 std::unique_ptr<ClassLoaderContext> context =
1067 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1068 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1069
1070 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1071 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass");
1072 std::string encoding = context->EncodeContextForOatFile("");
Calin Juravlec79470d2017-07-12 17:37:42 -07001073 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" +
1074 CreateClassPathWithChecksums(dex2) + "]";
Calin Juravle87e2cb62017-06-13 21:48:45 -07001075 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile(""));
1076}
1077
Calin Juravle27e0d1f2017-07-26 00:16:07 -07001078TEST_F(ClassLoaderContextTest, EncodeForDex2oat) {
1079 std::string dex1_name = GetTestDexFileName("Main");
1080 std::string dex2_name = GetTestDexFileName("MultiDex");
1081 std::unique_ptr<ClassLoaderContext> context =
1082 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]");
1083 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, ""));
1084
1085 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main");
1086 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MultiDex");
1087 std::string encoding = context->EncodeContextForDex2oat("");
1088 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]";
1089 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat(""));
1090}
1091
Calin Juravle57d0acc2017-07-11 17:41:30 -07001092// TODO(calin) add a test which creates the context for a class loader together with dex_elements.
1093TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) {
1094 // The chain is
1095 // ClassLoaderA (PathClassLoader)
1096 // ^
1097 // |
1098 // ClassLoaderB (DelegateLastClassLoader)
1099 // ^
1100 // |
1101 // ClassLoaderC (PathClassLoader)
1102 // ^
1103 // |
1104 // ClassLoaderD (DelegateLastClassLoader)
1105
1106 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1107 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1108 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1109 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1110
1111 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1112
1113 VerifyContextForClassLoader(context.get());
1114 VerifyContextSize(context.get(), 4);
1115
1116 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1117 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC");
1118 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB");
1119 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1120}
1121
David Brazdil1a9ac532019-03-05 11:57:13 +00001122TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) {
1123 // The chain is
1124 // ClassLoaderA (PathClassLoader)
1125 // ^
1126 // |
1127 // ClassLoaderB (InMemoryDexClassLoader)
1128 // ^
1129 // |
1130 // ClassLoaderC (InMemoryDexClassLoader)
1131 // ^
1132 // |
1133 // ClassLoaderD (DelegateLastClassLoader)
1134
1135 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1136 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1137 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1138 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1139
1140 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1141
1142 VerifyContextForClassLoader(context.get());
1143 VerifyContextSize(context.get(), 4);
1144
1145 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD");
1146 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC");
1147 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB");
1148 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA");
1149}
Mathieu Chartieradc90862018-05-11 13:03:06 -07001150
1151TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) {
1152 std::string context_spec = "PCL[]";
1153 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1154 ASSERT_TRUE(context != nullptr);
1155 PretendContextOpenedDexFiles(context.get());
1156 // Ensure that the special shared library marks as verified for the first thing in the class path.
1157 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary),
1158 ClassLoaderContext::VerificationResult::kVerifies);
1159}
1160
Calin Juravle3f918642017-07-11 19:04:20 -07001161TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) {
1162 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]";
1163 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
Calin Juravlec5b215f2017-09-12 14:49:37 -07001164 // Pretend that we successfully open the dex files to pass the DCHECKS.
1165 // (as it's much easier to test all the corner cases without relying on actual dex files).
1166 PretendContextOpenedDexFiles(context.get());
Calin Juravle3f918642017-07-11 19:04:20 -07001167
1168 VerifyContextSize(context.get(), 2);
1169 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1170 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1171
Mathieu Chartieradc90862018-05-11 13:03:06 -07001172 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1173 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001174
1175 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001176 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1177 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001178
1179 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001180 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1181 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001182
1183 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001184 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1185 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001186
1187 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001188 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1189 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001190
1191 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 -07001192 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1193 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001194
1195 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 -07001196 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1197 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001198
1199 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC[";
Mathieu Chartieradc90862018-05-11 13:03:06 -07001200 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec),
1201 ClassLoaderContext::VerificationResult::kMismatch);
Calin Juravle3f918642017-07-11 19:04:20 -07001202}
1203
David Brazdil1a9ac532019-03-05 11:57:13 +00001204TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) {
Nicolas Geoffray93d99f32019-03-27 08:56:02 +00001205 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[d.dex*111]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001206 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1207 // Pretend that we successfully open the dex files to pass the DCHECKS.
1208 // (as it's much easier to test all the corner cases without relying on actual dex files).
1209 PretendContextOpenedDexFiles(context.get());
1210
1211 VerifyContextSize(context.get(), 3);
1212 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1213 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
Nicolas Geoffray93d99f32019-03-27 08:56:02 +00001214 VerifyClassLoaderIMC(context.get(), 2, "d.dex");
David Brazdil1a9ac532019-03-05 11:57:13 +00001215
1216 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1217 ClassLoaderContext::VerificationResult::kVerifies);
1218}
1219
Nicolas Geoffray9893c472018-11-13 15:39:53 +00001220TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) {
1221 std::string context_spec = "&";
1222 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1223 // Pretend that we successfully open the dex files to pass the DCHECKS.
1224 // (as it's much easier to test all the corner cases without relying on actual dex files).
1225 PretendContextOpenedDexFiles(context.get());
1226
1227 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1228 ClassLoaderContext::VerificationResult::kForcedToSkipChecks);
1229}
1230
Nicolas Geoffray06af3b42018-10-29 10:39:04 +00001231TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) {
1232 std::string context_spec =
1233 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1234 ";DLC[c.dex*890]";
1235 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1236 // Pretend that we successfully open the dex files to pass the DCHECKS.
1237 // (as it's much easier to test all the corner cases without relying on actual dex files).
1238 PretendContextOpenedDexFiles(context.get());
1239
1240 VerifyContextSize(context.get(), 2);
1241 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex");
1242 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
1243 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex");
1244 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex");
1245
1246 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1247 ClassLoaderContext::VerificationResult::kVerifies);
1248
1249 std::string wrong_class_loader_type =
1250 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}"
1251 ";DLC[c.dex*890]";
1252 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type),
1253 ClassLoaderContext::VerificationResult::kMismatch);
1254
1255 std::string wrong_class_loader_order =
1256 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}"
1257 ";DLC[c.dex*890]";
1258 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order),
1259 ClassLoaderContext::VerificationResult::kMismatch);
1260
1261 std::string wrong_classpath_order =
1262 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1263 ";DLC[c.dex*890]";
1264 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order),
1265 ClassLoaderContext::VerificationResult::kMismatch);
1266
1267 std::string wrong_checksum =
1268 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}"
1269 ";DLC[c.dex*890]";
1270 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum),
1271 ClassLoaderContext::VerificationResult::kMismatch);
1272
1273 std::string wrong_extra_class_loader =
1274 "PCL[a.dex*123:b.dex*456]"
1275 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}"
1276 ";DLC[c.dex*890]";
1277 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader),
1278 ClassLoaderContext::VerificationResult::kMismatch);
1279
1280 std::string wrong_extra_classpath =
1281 "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]}"
1282 ";DLC[c.dex*890]";
1283 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath),
1284 ClassLoaderContext::VerificationResult::kMismatch);
1285}
1286
David Brazdil1a9ac532019-03-05 11:57:13 +00001287TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) {
1288 std::string context_spec =
Nicolas Geoffray93d99f32019-03-27 08:56:02 +00001289 "IMC[a.dex*123:b.dex*456]{IMC[d.dex*321];IMC[e.dex*654]#IMC[f.dex*098:g.dex*999]}"
1290 ";DLC[c.dex*890]";
David Brazdil1a9ac532019-03-05 11:57:13 +00001291 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec);
1292 // Pretend that we successfully open the dex files to pass the DCHECKS.
1293 // (as it's much easier to test all the corner cases without relying on actual dex files).
1294 PretendContextOpenedDexFiles(context.get());
1295
1296 VerifyContextSize(context.get(), 2);
Nicolas Geoffray93d99f32019-03-27 08:56:02 +00001297 VerifyClassLoaderIMC(context.get(), 0, "a.dex:b.dex");
David Brazdil1a9ac532019-03-05 11:57:13 +00001298 VerifyClassLoaderDLC(context.get(), 1, "c.dex");
Nicolas Geoffray93d99f32019-03-27 08:56:02 +00001299 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "d.dex");
1300 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "f.dex:g.dex");
David Brazdil1a9ac532019-03-05 11:57:13 +00001301
1302 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec),
1303 ClassLoaderContext::VerificationResult::kVerifies);
1304}
1305
Calin Juravle3f918642017-07-11 19:04:20 -07001306TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) {
1307 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1308 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
1309 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
1310 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1311
1312 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1313
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001314 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
Mathieu Chartieradc90862018-05-11 13:03:06 -07001315 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1316 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle1e96a5d2017-09-05 17:10:48 -07001317
1318 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1319 size_t pos = dex_location.rfind('/');
1320 ASSERT_NE(std::string::npos, pos);
1321 std::string parent = dex_location.substr(0, pos);
1322
1323 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1324 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
Mathieu Chartieradc90862018-05-11 13:03:06 -07001325 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1326 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravle3f918642017-07-11 19:04:20 -07001327}
1328
David Brazdil1a9ac532019-03-05 11:57:13 +00001329TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) {
1330 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1331 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a);
1332 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b);
1333 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);
1334
1335 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d);
1336
1337 std::string context_with_no_base_dir = context->EncodeContextForOatFile("");
1338 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir),
1339 ClassLoaderContext::VerificationResult::kVerifies);
1340
1341 std::string dex_location = GetTestDexFileName("ForClassLoaderA");
1342 size_t pos = dex_location.rfind('/');
1343 ASSERT_NE(std::string::npos, pos);
1344 std::string parent = dex_location.substr(0, pos);
1345
1346 std::string context_with_base_dir = context->EncodeContextForOatFile(parent);
1347 ASSERT_NE(context_with_base_dir, context_with_no_base_dir);
1348 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir),
1349 ClassLoaderContext::VerificationResult::kVerifies);
1350}
1351
Calin Juravlea308a322017-07-18 16:51:51 -07001352TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) {
1353 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr);
1354
1355 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader);
1356
Mathieu Chartieradc90862018-05-11 13:03:06 -07001357 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1358 ClassLoaderContext::VerificationResult::kVerifies);
Calin Juravlea308a322017-07-18 16:51:51 -07001359}
1360
Nicolas Geoffraye1672732018-11-30 01:09:49 +00001361TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) {
1362 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
1363
1364 ScopedObjectAccess soa(Thread::Current());
1365 StackHandleScope<1> hs(soa.Self());
1366 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle(
1367 mirror::ObjectArray<mirror::ClassLoader>::Alloc(
1368 soa.Self(),
1369 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(),
1370 1));
1371 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a));
1372
1373 jobject class_loader_b = LoadDexInPathClassLoader(
1374 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get()));
1375
1376 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b);
1377 ASSERT_TRUE(context != nullptr);
1378 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB");
1379 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation());
1380 dex_files = OpenTestDexFiles("ForClassLoaderA");
1381 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation());
1382
1383 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")),
1384 ClassLoaderContext::VerificationResult::kVerifies);
1385}
1386
Calin Juravle87e2cb62017-06-13 21:48:45 -07001387} // namespace art