1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "class_loader_context.h" 18 19 #include <gtest/gtest.h> 20 21 #include "android-base/strings.h" 22 #include "art_field-inl.h" 23 #include "base/dchecked_vector.h" 24 #include "base/stl_util.h" 25 #include "class_linker.h" 26 #include "class_root.h" 27 #include "common_runtime_test.h" 28 #include "dex/dex_file.h" 29 #include "handle_scope-inl.h" 30 #include "jni/jni_internal.h" 31 #include "mirror/class.h" 32 #include "mirror/class_loader-inl.h" 33 #include "mirror/object-inl.h" 34 #include "mirror/object_array-alloc-inl.h" 35 #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 41 namespace art { 42 43 class ClassLoaderContextTest : public CommonRuntimeTest { 44 public: 45 void VerifyContextSize(ClassLoaderContext* context, size_t expected_size) { 46 ASSERT_TRUE(context != nullptr); 47 ASSERT_EQ(expected_size, context->GetParentChainSize()); 48 } 49 50 void VerifyClassLoaderPCL(ClassLoaderContext* context, 51 size_t index, 52 const std::string& classpath) { 53 VerifyClassLoaderInfo( 54 context, index, ClassLoaderContext::kPathClassLoader, classpath); 55 } 56 57 void VerifyClassLoaderDLC(ClassLoaderContext* context, 58 size_t index, 59 const std::string& classpath) { 60 VerifyClassLoaderInfo( 61 context, index, ClassLoaderContext::kDelegateLastClassLoader, classpath); 62 } 63 64 void VerifyClassLoaderIMC(ClassLoaderContext* context, 65 size_t index, 66 const std::string& classpath) { 67 VerifyClassLoaderInfo( 68 context, index, ClassLoaderContext::kInMemoryDexClassLoader, classpath); 69 } 70 71 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 80 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 89 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 107 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 121 void VerifyClassLoaderIMCFromTestDex(ClassLoaderContext* context, 122 size_t index, 123 const std::string& test_name) { 124 VerifyClassLoaderFromTestDex( 125 context, index, ClassLoaderContext::kInMemoryDexClassLoader, test_name, "<unknown>"); 126 } 127 128 enum class LocationCheck { 129 kEquals, 130 kEndsWith 131 }; 132 enum class BaseLocationCheck { 133 kEquals, 134 kEndsWith 135 }; 136 137 static bool IsAbsoluteLocation(const std::string& location) { 138 return !location.empty() && location[0] == '/'; 139 } 140 141 void VerifyOpenDexFiles( 142 ClassLoaderContext* context, 143 size_t index, 144 std::vector<std::unique_ptr<const DexFile>>* all_dex_files, 145 bool classpath_matches_dex_location = true) { 146 ASSERT_TRUE(context != nullptr); 147 ASSERT_TRUE(context->dex_files_open_attempted_); 148 ASSERT_TRUE(context->dex_files_open_result_); 149 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index); 150 ASSERT_EQ(all_dex_files->size(), info.classpath.size()); 151 ASSERT_EQ(all_dex_files->size(), info.opened_dex_files.size()); 152 size_t cur_open_dex_index = 0; 153 for (size_t k = 0; k < all_dex_files->size(); k++) { 154 std::unique_ptr<const DexFile>& opened_dex_file = 155 info.opened_dex_files[cur_open_dex_index++]; 156 std::unique_ptr<const DexFile>& expected_dex_file = (*all_dex_files)[k]; 157 158 std::string expected_location = expected_dex_file->GetLocation(); 159 160 const std::string& opened_location = opened_dex_file->GetLocation(); 161 if (!IsAbsoluteLocation(opened_location)) { 162 // If the opened location is relative (it was open from a relative path without a 163 // classpath_dir) it might not match the expected location which is absolute in tests). 164 // So we compare the endings (the checksum will validate it's actually the same file). 165 ASSERT_EQ(0, expected_location.compare( 166 expected_location.length() - opened_location.length(), 167 opened_location.length(), 168 opened_location)); 169 } else { 170 ASSERT_EQ(expected_location, opened_location); 171 } 172 ASSERT_EQ(expected_dex_file->GetLocationChecksum(), opened_dex_file->GetLocationChecksum()); 173 if (classpath_matches_dex_location) { 174 ASSERT_EQ(info.classpath[k], opened_location); 175 } 176 } 177 } 178 179 std::unique_ptr<ClassLoaderContext> CreateContextForClassLoader(jobject class_loader) { 180 return ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr); 181 } 182 183 std::unique_ptr<ClassLoaderContext> ParseContextWithChecksums(const std::string& context_spec) { 184 std::unique_ptr<ClassLoaderContext> context(new ClassLoaderContext()); 185 if (!context->Parse(context_spec, /*parse_checksums=*/ true)) { 186 return nullptr; 187 } 188 return context; 189 } 190 191 void VerifyContextForClassLoader(ClassLoaderContext* context) { 192 ASSERT_TRUE(context != nullptr); 193 ASSERT_TRUE(context->dex_files_open_attempted_); 194 ASSERT_TRUE(context->dex_files_open_result_); 195 ASSERT_FALSE(context->owns_the_dex_files_); 196 ASSERT_FALSE(context->special_shared_library_); 197 } 198 199 void VerifyClassLoaderDexFiles(ScopedObjectAccess& soa, 200 Handle<mirror::ClassLoader> class_loader, 201 jclass type, 202 std::vector<const DexFile*>& expected_dex_files) 203 REQUIRES_SHARED(Locks::mutator_lock_) { 204 ASSERT_TRUE(class_loader->GetClass() == soa.Decode<mirror::Class>(type)); 205 206 std::vector<const DexFile*> class_loader_dex_files = GetDexFiles(soa, class_loader); 207 ASSERT_EQ(expected_dex_files.size(), class_loader_dex_files.size()); 208 209 for (size_t i = 0; i < expected_dex_files.size(); i++) { 210 ASSERT_EQ(expected_dex_files[i]->GetLocation(), 211 class_loader_dex_files[i]->GetLocation()); 212 ASSERT_EQ(expected_dex_files[i]->GetLocationChecksum(), 213 class_loader_dex_files[i]->GetLocationChecksum()); 214 } 215 } 216 217 void PretendContextOpenedDexFiles(ClassLoaderContext* context) { 218 context->dex_files_open_attempted_ = true; 219 context->dex_files_open_result_ = true; 220 } 221 222 private: 223 void VerifyClassLoaderInfo(ClassLoaderContext* context, 224 size_t index, 225 ClassLoaderContext::ClassLoaderType type, 226 const std::string& classpath) { 227 ASSERT_TRUE(context != nullptr); 228 ASSERT_GT(context->GetParentChainSize(), index); 229 ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(index); 230 ASSERT_EQ(type, info.type); 231 std::vector<std::string> expected_classpath; 232 Split(classpath, ':', &expected_classpath); 233 ASSERT_EQ(expected_classpath, info.classpath); 234 } 235 236 void VerifyClassLoaderInfoSL(ClassLoaderContext* context, 237 size_t loader_index, 238 size_t shared_library_index, 239 ClassLoaderContext::ClassLoaderType type, 240 const std::string& classpath) { 241 ASSERT_TRUE(context != nullptr); 242 ASSERT_GT(context->GetParentChainSize(), loader_index); 243 const ClassLoaderContext::ClassLoaderInfo& info = *context->GetParent(loader_index); 244 ASSERT_GT(info.shared_libraries.size(), shared_library_index); 245 const ClassLoaderContext::ClassLoaderInfo& sl = 246 *info.shared_libraries[shared_library_index].get(); 247 ASSERT_EQ(type, info.type); 248 std::vector<std::string> expected_classpath; 249 Split(classpath, ':', &expected_classpath); 250 ASSERT_EQ(expected_classpath, sl.classpath); 251 } 252 253 void VerifyClassLoaderFromTestDex(ClassLoaderContext* context, 254 size_t index, 255 ClassLoaderContext::ClassLoaderType type, 256 const std::string& test_name, 257 const std::string& classpath = "") { 258 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(test_name.c_str()); 259 260 // If `classpath` is set, override the expected value of ClassLoaderInfo::classpath. 261 // Otherwise assume it is equal to dex location (here test dex file name). 262 VerifyClassLoaderInfo(context, 263 index, 264 type, 265 classpath.empty() ? GetTestDexFileName(test_name.c_str()) : classpath); 266 VerifyOpenDexFiles(context, 267 index, 268 &dex_files, 269 /* classpath_matches_dex_location= */ classpath.empty()); 270 } 271 }; 272 273 TEST_F(ClassLoaderContextTest, ParseValidEmptyContext) { 274 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(""); 275 // An empty context should create a single empty PathClassLoader. 276 VerifyContextSize(context.get(), 1); 277 VerifyClassLoaderPCL(context.get(), 0, ""); 278 } 279 280 TEST_F(ClassLoaderContextTest, ParseValidSharedLibraryContext) { 281 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&"); 282 // An shared library context should have no class loader in the chain. 283 VerifyContextSize(context.get(), 0); 284 } 285 286 TEST_F(ClassLoaderContextTest, ParseValidContextPCL) { 287 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("PCL[a.dex]"); 288 VerifyContextSize(context.get(), 1); 289 VerifyClassLoaderPCL(context.get(), 0, "a.dex"); 290 } 291 292 TEST_F(ClassLoaderContextTest, ParseValidContextDLC) { 293 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("DLC[a.dex]"); 294 VerifyContextSize(context.get(), 1); 295 VerifyClassLoaderDLC(context.get(), 0, "a.dex"); 296 } 297 298 TEST_F(ClassLoaderContextTest, ParseValidContextIMC) { 299 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums("IMC[<unknown>*111]"); 300 ASSERT_FALSE(context == nullptr); 301 } 302 303 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCNoChecksum) { 304 // IMC is treated as an unknown class loader unless a checksum is provided. 305 // This is because the dex location is always bogus. 306 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[<unknown>]"); 307 ASSERT_TRUE(context == nullptr); 308 } 309 310 TEST_F(ClassLoaderContextTest, ParseInvalidContextIMCWrongClasspathMagic) { 311 // IMC does not support arbitrary dex location. A magic marker must be used 312 // otherwise the spec should be rejected. 313 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("IMC[a.dex*111]"); 314 ASSERT_TRUE(context == nullptr); 315 } 316 317 TEST_F(ClassLoaderContextTest, ParseValidContextChain) { 318 std::unique_ptr<ClassLoaderContext> context = 319 ClassLoaderContext::Create("PCL[a.dex:b.dex];DLC[c.dex:d.dex];PCL[e.dex]"); 320 VerifyContextSize(context.get(), 3); 321 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); 322 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex"); 323 VerifyClassLoaderPCL(context.get(), 2, "e.dex"); 324 } 325 326 TEST_F(ClassLoaderContextTest, ParseSharedLibraries) { 327 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create( 328 "PCL[a.dex:b.dex]{PCL[s1.dex]#PCL[s2.dex:s3.dex]};DLC[c.dex:d.dex]{DLC[s4.dex]}"); 329 VerifyContextSize(context.get(), 2); 330 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex"); 331 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex:s3.dex"); 332 VerifyClassLoaderDLC(context.get(), 1, "c.dex:d.dex"); 333 VerifyClassLoaderSharedLibraryDLC(context.get(), 1, 0, "s4.dex"); 334 } 335 336 TEST_F(ClassLoaderContextTest, ParseEnclosingSharedLibraries) { 337 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create( 338 "PCL[a.dex:b.dex]{PCL[s1.dex]{PCL[s2.dex:s3.dex];PCL[s4.dex]}}"); 339 VerifyContextSize(context.get(), 1); 340 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex"); 341 } 342 343 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries1) { 344 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create( 345 "PCL[]{PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}}"); 346 VerifyContextSize(context.get(), 1); 347 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s4.dex"); 348 } 349 350 TEST_F(ClassLoaderContextTest, ParseComplexSharedLibraries2) { 351 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create( 352 "PCL[]{PCL[s1.dex]{PCL[s2.dex]}#PCL[s2.dex]#" 353 "PCL[s3.dex]#PCL[s4.dex]{PCL[s5.dex]{PCL[s6.dex]}#PCL[s6.dex]}#PCL[s5.dex]{PCL[s6.dex]}}"); 354 VerifyContextSize(context.get(), 1); 355 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "s1.dex"); 356 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "s2.dex"); 357 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 2, "s3.dex"); 358 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 3, "s4.dex"); 359 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 4, "s5.dex"); 360 } 361 362 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextDLC) { 363 std::unique_ptr<ClassLoaderContext> context = 364 ClassLoaderContext::Create("DLC[]"); 365 VerifyContextSize(context.get(), 1); 366 VerifyClassLoaderDLC(context.get(), 0, ""); 367 } 368 369 TEST_F(ClassLoaderContextTest, ParseValidEmptyContextSharedLibrary) { 370 std::unique_ptr<ClassLoaderContext> context = 371 ClassLoaderContext::Create("DLC[]{}"); 372 VerifyContextSize(context.get(), 1); 373 VerifySharedLibrariesSize(context.get(), 0, 0); 374 } 375 376 TEST_F(ClassLoaderContextTest, ParseValidContextSpecialSymbol) { 377 std::unique_ptr<ClassLoaderContext> context = 378 ClassLoaderContext::Create(OatFile::kSpecialSharedLibrary); 379 VerifyContextSize(context.get(), 0); 380 } 381 382 TEST_F(ClassLoaderContextTest, ParseInvalidValidContexts) { 383 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("ABC[a.dex]")); 384 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL")); 385 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex")); 386 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCLa.dex]")); 387 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{a.dex}")); 388 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex];DLC[b.dex")); 389 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{ABC};DLC[b.dex")); 390 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL[a.dex]{};DLC[b.dex")); 391 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]}")); 392 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC[s4.dex]{")); 393 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("DLC{DLC[s4.dex]}")); 394 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{##}")); 395 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]#}")); 396 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]##}")); 397 ASSERT_TRUE(nullptr == ClassLoaderContext::Create("PCL{PCL[s4.dex]{PCL[s3.dex]}#}")); 398 } 399 400 TEST_F(ClassLoaderContextTest, OpenInvalidDexFiles) { 401 std::unique_ptr<ClassLoaderContext> context = 402 ClassLoaderContext::Create("PCL[does_not_exist.dex]"); 403 VerifyContextSize(context.get(), 1); 404 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ".")); 405 } 406 407 TEST_F(ClassLoaderContextTest, OpenValidDexFiles) { 408 std::string multidex_name = GetTestDexFileName("MultiDex"); 409 std::string myclass_dex_name = GetTestDexFileName("MyClass"); 410 std::string dex_name = GetTestDexFileName("Main"); 411 412 413 std::unique_ptr<ClassLoaderContext> context = 414 ClassLoaderContext::Create( 415 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" + 416 "DLC[" + dex_name + "]"); 417 418 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ "")); 419 420 VerifyContextSize(context.get(), 2); 421 422 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex"); 423 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass"); 424 for (size_t i = 0; i < myclass_dex_files.size(); i++) { 425 all_dex_files0.emplace_back(myclass_dex_files[i].release()); 426 } 427 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); 428 429 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main"); 430 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); 431 } 432 433 // Creates a relative path from cwd to 'in'. Returns false if it cannot be done. 434 // TODO We should somehow support this in all situations. b/72042237. 435 static bool CreateRelativeString(const std::string& in, const char* cwd, std::string* out) { 436 int cwd_len = strlen(cwd); 437 if (!android::base::StartsWith(in, cwd) || (cwd_len < 1)) { 438 return false; 439 } 440 bool contains_trailing_slash = (cwd[cwd_len - 1] == '/'); 441 int start_position = cwd_len + (contains_trailing_slash ? 0 : 1); 442 *out = in.substr(start_position); 443 return true; 444 } 445 446 TEST_F(ClassLoaderContextTest, OpenValidDexFilesRelative) { 447 char cwd_buf[4096]; 448 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) { 449 PLOG(FATAL) << "Could not get working directory"; 450 } 451 std::string multidex_name; 452 std::string myclass_dex_name; 453 std::string dex_name; 454 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) || 455 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) || 456 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) { 457 LOG(ERROR) << "Test OpenValidDexFilesRelative cannot be run because target dex files have no " 458 << "relative path."; 459 SUCCEED(); 460 return; 461 } 462 463 std::unique_ptr<ClassLoaderContext> context = 464 ClassLoaderContext::Create( 465 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" + 466 "DLC[" + dex_name + "]"); 467 468 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, /*classpath_dir=*/ "")); 469 470 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex"); 471 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass"); 472 for (size_t i = 0; i < myclass_dex_files.size(); i++) { 473 all_dex_files0.emplace_back(myclass_dex_files[i].release()); 474 } 475 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); 476 477 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main"); 478 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); 479 } 480 481 TEST_F(ClassLoaderContextTest, OpenValidDexFilesClasspathDir) { 482 char cwd_buf[4096]; 483 if (getcwd(cwd_buf, arraysize(cwd_buf)) == nullptr) { 484 PLOG(FATAL) << "Could not get working directory"; 485 } 486 std::string multidex_name; 487 std::string myclass_dex_name; 488 std::string dex_name; 489 if (!CreateRelativeString(GetTestDexFileName("MultiDex"), cwd_buf, &multidex_name) || 490 !CreateRelativeString(GetTestDexFileName("MyClass"), cwd_buf, &myclass_dex_name) || 491 !CreateRelativeString(GetTestDexFileName("Main"), cwd_buf, &dex_name)) { 492 LOG(ERROR) << "Test OpenValidDexFilesClasspathDir cannot be run because target dex files have " 493 << "no relative path."; 494 SUCCEED(); 495 return; 496 } 497 std::unique_ptr<ClassLoaderContext> context = 498 ClassLoaderContext::Create( 499 "PCL[" + multidex_name + ":" + myclass_dex_name + "];" + 500 "DLC[" + dex_name + "]"); 501 502 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, cwd_buf)); 503 504 VerifyContextSize(context.get(), 2); 505 std::vector<std::unique_ptr<const DexFile>> all_dex_files0 = OpenTestDexFiles("MultiDex"); 506 std::vector<std::unique_ptr<const DexFile>> myclass_dex_files = OpenTestDexFiles("MyClass"); 507 for (size_t i = 0; i < myclass_dex_files.size(); i++) { 508 all_dex_files0.emplace_back(myclass_dex_files[i].release()); 509 } 510 VerifyOpenDexFiles(context.get(), 0, &all_dex_files0); 511 512 std::vector<std::unique_ptr<const DexFile>> all_dex_files1 = OpenTestDexFiles("Main"); 513 VerifyOpenDexFiles(context.get(), 1, &all_dex_files1); 514 } 515 516 TEST_F(ClassLoaderContextTest, OpenInvalidDexFilesMix) { 517 std::string dex_name = GetTestDexFileName("Main"); 518 std::unique_ptr<ClassLoaderContext> context = 519 ClassLoaderContext::Create("PCL[does_not_exist.dex];DLC[" + dex_name + "]"); 520 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, "")); 521 } 522 523 TEST_F(ClassLoaderContextTest, OpenDexFilesForIMCFails) { 524 std::unique_ptr<ClassLoaderContext> context; 525 std::string dex_name = GetTestDexFileName("Main"); 526 527 context = ParseContextWithChecksums("IMC[<unknown>*111]"); 528 VerifyContextSize(context.get(), 1); 529 ASSERT_FALSE(context->OpenDexFiles(InstructionSet::kArm, ".")); 530 } 531 532 TEST_F(ClassLoaderContextTest, CreateClassLoader) { 533 std::string dex_name = GetTestDexFileName("Main"); 534 std::unique_ptr<ClassLoaderContext> context = 535 ClassLoaderContext::Create("PCL[" + dex_name + "]"); 536 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 537 538 std::vector<std::unique_ptr<const DexFile>> classpath_dex = OpenTestDexFiles("Main"); 539 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 540 541 std::vector<const DexFile*> compilation_sources_raw = 542 MakeNonOwningPointerVector(compilation_sources); 543 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 544 ASSERT_TRUE(jclass_loader != nullptr); 545 546 ScopedObjectAccess soa(Thread::Current()); 547 548 StackHandleScope<1> hs(soa.Self()); 549 Handle<mirror::ClassLoader> class_loader = hs.NewHandle( 550 soa.Decode<mirror::ClassLoader>(jclass_loader)); 551 552 ASSERT_TRUE(class_loader->GetClass() == 553 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)); 554 ASSERT_TRUE(class_loader->GetParent()->GetClass() == 555 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 556 557 // For the first class loader the class path dex files must come first and then the 558 // compilation sources. 559 std::vector<const DexFile*> expected_classpath = MakeNonOwningPointerVector(classpath_dex); 560 for (auto& dex : compilation_sources_raw) { 561 expected_classpath.push_back(dex); 562 } 563 564 VerifyClassLoaderDexFiles(soa, 565 class_loader, 566 WellKnownClasses::dalvik_system_PathClassLoader, 567 expected_classpath); 568 } 569 570 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithEmptyContext) { 571 std::unique_ptr<ClassLoaderContext> context = 572 ClassLoaderContext::Create(""); 573 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 574 575 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 576 577 std::vector<const DexFile*> compilation_sources_raw = 578 MakeNonOwningPointerVector(compilation_sources); 579 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 580 ASSERT_TRUE(jclass_loader != nullptr); 581 582 ScopedObjectAccess soa(Thread::Current()); 583 584 StackHandleScope<1> hs(soa.Self()); 585 Handle<mirror::ClassLoader> class_loader = hs.NewHandle( 586 soa.Decode<mirror::ClassLoader>(jclass_loader)); 587 588 // An empty context should create a single PathClassLoader with only the compilation sources. 589 VerifyClassLoaderDexFiles(soa, 590 class_loader, 591 WellKnownClasses::dalvik_system_PathClassLoader, 592 compilation_sources_raw); 593 ASSERT_TRUE(class_loader->GetParent()->GetClass() == 594 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 595 } 596 597 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraryContext) { 598 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create("&"); 599 600 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 601 602 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 603 604 std::vector<const DexFile*> compilation_sources_raw = 605 MakeNonOwningPointerVector(compilation_sources); 606 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 607 ASSERT_TRUE(jclass_loader != nullptr); 608 609 ScopedObjectAccess soa(Thread::Current()); 610 611 StackHandleScope<1> hs(soa.Self()); 612 Handle<mirror::ClassLoader> class_loader = hs.NewHandle( 613 soa.Decode<mirror::ClassLoader>(jclass_loader)); 614 615 // A shared library context should create a single PathClassLoader with only the compilation 616 // sources. 617 VerifyClassLoaderDexFiles(soa, 618 class_loader, 619 WellKnownClasses::dalvik_system_PathClassLoader, 620 compilation_sources_raw); 621 ASSERT_TRUE(class_loader->GetParent()->GetClass() == 622 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 623 } 624 625 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithComplexChain) { 626 // Setup the context. 627 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); 628 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB"); 629 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC"); 630 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD"); 631 632 std::string context_spec = 633 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "];" + 634 "DLC[" + CreateClassPath(classpath_dex_c) + "];" + 635 "PCL[" + CreateClassPath(classpath_dex_d) + "]"; 636 637 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec); 638 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 639 640 // Setup the compilation sources. 641 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 642 std::vector<const DexFile*> compilation_sources_raw = 643 MakeNonOwningPointerVector(compilation_sources); 644 645 // Create the class loader. 646 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 647 ASSERT_TRUE(jclass_loader != nullptr); 648 649 // Verify the class loader. 650 ScopedObjectAccess soa(Thread::Current()); 651 652 StackHandleScope<3> hs(soa.Self()); 653 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle( 654 soa.Decode<mirror::ClassLoader>(jclass_loader)); 655 656 // Verify the first class loader 657 658 // For the first class loader the class path dex files must come first and then the 659 // compilation sources. 660 std::vector<const DexFile*> class_loader_1_dex_files = 661 MakeNonOwningPointerVector(classpath_dex_a); 662 for (auto& dex : classpath_dex_b) { 663 class_loader_1_dex_files.push_back(dex.get()); 664 } 665 for (auto& dex : compilation_sources_raw) { 666 class_loader_1_dex_files.push_back(dex); 667 } 668 VerifyClassLoaderDexFiles(soa, 669 class_loader_1, 670 WellKnownClasses::dalvik_system_PathClassLoader, 671 class_loader_1_dex_files); 672 673 // Verify the second class loader 674 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(class_loader_1->GetParent()); 675 std::vector<const DexFile*> class_loader_2_dex_files = 676 MakeNonOwningPointerVector(classpath_dex_c); 677 VerifyClassLoaderDexFiles(soa, 678 class_loader_2, 679 WellKnownClasses::dalvik_system_DelegateLastClassLoader, 680 class_loader_2_dex_files); 681 682 // Verify the third class loader 683 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_2->GetParent()); 684 std::vector<const DexFile*> class_loader_3_dex_files = 685 MakeNonOwningPointerVector(classpath_dex_d); 686 VerifyClassLoaderDexFiles(soa, 687 class_loader_3, 688 WellKnownClasses::dalvik_system_PathClassLoader, 689 class_loader_3_dex_files); 690 // The last class loader should have the BootClassLoader as a parent. 691 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == 692 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 693 } 694 695 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibraries) { 696 // Setup the context. 697 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); 698 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB"); 699 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC"); 700 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD"); 701 702 std::string context_spec = 703 "PCL[" + CreateClassPath(classpath_dex_a) + ":" + CreateClassPath(classpath_dex_b) + "]{" + 704 "DLC[" + CreateClassPath(classpath_dex_c) + "]#" + 705 "PCL[" + CreateClassPath(classpath_dex_d) + "]}"; 706 707 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec); 708 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 709 710 // Setup the compilation sources. 711 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 712 std::vector<const DexFile*> compilation_sources_raw = 713 MakeNonOwningPointerVector(compilation_sources); 714 715 // Create the class loader. 716 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 717 ASSERT_TRUE(jclass_loader != nullptr); 718 719 // Verify the class loader. 720 ScopedObjectAccess soa(Thread::Current()); 721 722 StackHandleScope<4> hs(soa.Self()); 723 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle( 724 soa.Decode<mirror::ClassLoader>(jclass_loader)); 725 726 // For the first class loader the class path dex files must come first and then the 727 // compilation sources. 728 std::vector<const DexFile*> class_loader_1_dex_files = 729 MakeNonOwningPointerVector(classpath_dex_a); 730 for (auto& dex : classpath_dex_b) { 731 class_loader_1_dex_files.push_back(dex.get()); 732 } 733 for (auto& dex : compilation_sources_raw) { 734 class_loader_1_dex_files.push_back(dex); 735 } 736 VerifyClassLoaderDexFiles(soa, 737 class_loader_1, 738 WellKnownClasses::dalvik_system_PathClassLoader, 739 class_loader_1_dex_files); 740 741 // Verify the shared libraries. 742 ArtField* field = 743 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); 744 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); 745 ASSERT_TRUE(raw_shared_libraries != nullptr); 746 747 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries( 748 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 749 ASSERT_EQ(shared_libraries->GetLength(), 2); 750 751 // Verify the first shared library. 752 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); 753 std::vector<const DexFile*> class_loader_2_dex_files = 754 MakeNonOwningPointerVector(classpath_dex_c); 755 VerifyClassLoaderDexFiles(soa, 756 class_loader_2, 757 WellKnownClasses::dalvik_system_DelegateLastClassLoader, 758 class_loader_2_dex_files); 759 raw_shared_libraries = field->GetObject(class_loader_2.Get()); 760 ASSERT_TRUE(raw_shared_libraries == nullptr); 761 762 // Verify the second shared library. 763 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries->Get(1)); 764 std::vector<const DexFile*> class_loader_3_dex_files = 765 MakeNonOwningPointerVector(classpath_dex_d); 766 VerifyClassLoaderDexFiles(soa, 767 class_loader_3, 768 WellKnownClasses::dalvik_system_PathClassLoader, 769 class_loader_3_dex_files); 770 raw_shared_libraries = field->GetObject(class_loader_3.Get()); 771 ASSERT_TRUE(raw_shared_libraries == nullptr); 772 773 // All class loaders should have the BootClassLoader as a parent. 774 ASSERT_TRUE(class_loader_1->GetParent()->GetClass() == 775 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 776 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == 777 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 778 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == 779 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 780 } 781 782 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesInParentToo) { 783 // Setup the context. 784 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); 785 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB"); 786 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC"); 787 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD"); 788 789 std::string context_spec = 790 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" + 791 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" + 792 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" + 793 "PCL[" + CreateClassPath(classpath_dex_d) + "]}"; 794 795 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec); 796 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 797 798 // Setup the compilation sources. 799 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 800 std::vector<const DexFile*> compilation_sources_raw = 801 MakeNonOwningPointerVector(compilation_sources); 802 803 // Create the class loader. 804 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 805 ASSERT_TRUE(jclass_loader != nullptr); 806 807 // Verify the class loader. 808 ScopedObjectAccess soa(Thread::Current()); 809 810 StackHandleScope<6> hs(soa.Self()); 811 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle( 812 soa.Decode<mirror::ClassLoader>(jclass_loader)); 813 814 // For the first class loader the class path dex files must come first and then the 815 // compilation sources. 816 std::vector<const DexFile*> class_loader_1_dex_files = 817 MakeNonOwningPointerVector(classpath_dex_a); 818 for (auto& dex : compilation_sources_raw) { 819 class_loader_1_dex_files.push_back(dex); 820 } 821 VerifyClassLoaderDexFiles(soa, 822 class_loader_1, 823 WellKnownClasses::dalvik_system_PathClassLoader, 824 class_loader_1_dex_files); 825 826 // Verify its shared library. 827 ArtField* field = 828 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); 829 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); 830 ASSERT_TRUE(raw_shared_libraries != nullptr); 831 832 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries( 833 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 834 ASSERT_EQ(shared_libraries->GetLength(), 1); 835 836 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); 837 std::vector<const DexFile*> class_loader_2_dex_files = 838 MakeNonOwningPointerVector(classpath_dex_b); 839 VerifyClassLoaderDexFiles(soa, 840 class_loader_2, 841 WellKnownClasses::dalvik_system_PathClassLoader, 842 class_loader_2_dex_files); 843 raw_shared_libraries = field->GetObject(class_loader_2.Get()); 844 ASSERT_TRUE(raw_shared_libraries == nullptr); 845 846 // Verify the parent. 847 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent()); 848 std::vector<const DexFile*> class_loader_3_dex_files = 849 MakeNonOwningPointerVector(classpath_dex_c); 850 VerifyClassLoaderDexFiles(soa, 851 class_loader_3, 852 WellKnownClasses::dalvik_system_PathClassLoader, 853 class_loader_3_dex_files); 854 855 // Verify its shared library. 856 raw_shared_libraries = field->GetObject(class_loader_3.Get()); 857 ASSERT_TRUE(raw_shared_libraries != nullptr); 858 859 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2( 860 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 861 ASSERT_EQ(shared_libraries->GetLength(), 1); 862 863 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(shared_libraries_2->Get(0)); 864 std::vector<const DexFile*> class_loader_4_dex_files = 865 MakeNonOwningPointerVector(classpath_dex_d); 866 VerifyClassLoaderDexFiles(soa, 867 class_loader_4, 868 WellKnownClasses::dalvik_system_PathClassLoader, 869 class_loader_4_dex_files); 870 raw_shared_libraries = field->GetObject(class_loader_4.Get()); 871 ASSERT_TRUE(raw_shared_libraries == nullptr); 872 873 // Class loaders should have the BootClassLoader as a parent. 874 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == 875 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 876 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == 877 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 878 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() == 879 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 880 } 881 882 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSharedLibrariesDependencies) { 883 // Setup the context. 884 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); 885 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB"); 886 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC"); 887 std::vector<std::unique_ptr<const DexFile>> classpath_dex_d = OpenTestDexFiles("ForClassLoaderD"); 888 889 std::string context_spec = 890 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" + 891 "PCL[" + CreateClassPath(classpath_dex_b) + "]{" + 892 "PCL[" + CreateClassPath(classpath_dex_c) + "]}};" + 893 "PCL[" + CreateClassPath(classpath_dex_d) + "]"; 894 895 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec); 896 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 897 898 // Setup the compilation sources. 899 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 900 std::vector<const DexFile*> compilation_sources_raw = 901 MakeNonOwningPointerVector(compilation_sources); 902 903 // Create the class loader. 904 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 905 ASSERT_TRUE(jclass_loader != nullptr); 906 907 // Verify the class loader. 908 ScopedObjectAccess soa(Thread::Current()); 909 910 StackHandleScope<6> hs(soa.Self()); 911 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle( 912 soa.Decode<mirror::ClassLoader>(jclass_loader)); 913 914 // For the first class loader the class path dex files must come first and then the 915 // compilation sources. 916 std::vector<const DexFile*> class_loader_1_dex_files = 917 MakeNonOwningPointerVector(classpath_dex_a); 918 for (auto& dex : compilation_sources_raw) { 919 class_loader_1_dex_files.push_back(dex); 920 } 921 VerifyClassLoaderDexFiles(soa, 922 class_loader_1, 923 WellKnownClasses::dalvik_system_PathClassLoader, 924 class_loader_1_dex_files); 925 926 // Verify its shared library. 927 ArtField* field = 928 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); 929 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); 930 ASSERT_TRUE(raw_shared_libraries != nullptr); 931 932 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries( 933 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 934 ASSERT_EQ(shared_libraries->GetLength(), 1); 935 936 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); 937 std::vector<const DexFile*> class_loader_2_dex_files = 938 MakeNonOwningPointerVector(classpath_dex_b); 939 VerifyClassLoaderDexFiles(soa, 940 class_loader_2, 941 WellKnownClasses::dalvik_system_PathClassLoader, 942 class_loader_2_dex_files); 943 944 // Verify the shared library dependency of the shared library. 945 raw_shared_libraries = field->GetObject(class_loader_2.Get()); 946 ASSERT_TRUE(raw_shared_libraries != nullptr); 947 948 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2( 949 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 950 ASSERT_EQ(shared_libraries_2->GetLength(), 1); 951 952 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(shared_libraries_2->Get(0)); 953 std::vector<const DexFile*> class_loader_3_dex_files = 954 MakeNonOwningPointerVector(classpath_dex_c); 955 VerifyClassLoaderDexFiles(soa, 956 class_loader_3, 957 WellKnownClasses::dalvik_system_PathClassLoader, 958 class_loader_3_dex_files); 959 raw_shared_libraries = field->GetObject(class_loader_3.Get()); 960 ASSERT_TRUE(raw_shared_libraries == nullptr); 961 962 // Verify the parent. 963 Handle<mirror::ClassLoader> class_loader_4 = hs.NewHandle(class_loader_1->GetParent()); 964 std::vector<const DexFile*> class_loader_4_dex_files = 965 MakeNonOwningPointerVector(classpath_dex_d); 966 VerifyClassLoaderDexFiles(soa, 967 class_loader_4, 968 WellKnownClasses::dalvik_system_PathClassLoader, 969 class_loader_4_dex_files); 970 raw_shared_libraries = field->GetObject(class_loader_4.Get()); 971 ASSERT_TRUE(raw_shared_libraries == nullptr); 972 973 // Class loaders should have the BootClassLoader as a parent. 974 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == 975 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 976 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == 977 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 978 ASSERT_TRUE(class_loader_4->GetParent()->GetClass() == 979 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 980 } 981 982 TEST_F(ClassLoaderContextTest, RemoveSourceLocations) { 983 std::unique_ptr<ClassLoaderContext> context = 984 ClassLoaderContext::Create("PCL[a.dex]"); 985 dchecked_vector<std::string> classpath_dex; 986 classpath_dex.push_back("a.dex"); 987 dchecked_vector<std::string> compilation_sources; 988 compilation_sources.push_back("src.dex"); 989 990 // Nothing should be removed. 991 ASSERT_FALSE(context->RemoveLocationsFromClassPaths(compilation_sources)); 992 VerifyClassLoaderPCL(context.get(), 0, "a.dex"); 993 // Classes should be removed. 994 ASSERT_TRUE(context->RemoveLocationsFromClassPaths(classpath_dex)); 995 VerifyClassLoaderPCL(context.get(), 0, ""); 996 } 997 998 TEST_F(ClassLoaderContextTest, CreateClassLoaderWithSameSharedLibraries) { 999 // Setup the context. 1000 std::vector<std::unique_ptr<const DexFile>> classpath_dex_a = OpenTestDexFiles("ForClassLoaderA"); 1001 std::vector<std::unique_ptr<const DexFile>> classpath_dex_b = OpenTestDexFiles("ForClassLoaderB"); 1002 std::vector<std::unique_ptr<const DexFile>> classpath_dex_c = OpenTestDexFiles("ForClassLoaderC"); 1003 1004 std::string context_spec = 1005 "PCL[" + CreateClassPath(classpath_dex_a) + "]{" + 1006 "PCL[" + CreateClassPath(classpath_dex_b) + "]};" + 1007 "PCL[" + CreateClassPath(classpath_dex_c) + "]{" + 1008 "PCL[" + CreateClassPath(classpath_dex_b) + "]}"; 1009 1010 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_spec); 1011 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 1012 1013 // Setup the compilation sources. 1014 std::vector<std::unique_ptr<const DexFile>> compilation_sources = OpenTestDexFiles("MultiDex"); 1015 std::vector<const DexFile*> compilation_sources_raw = 1016 MakeNonOwningPointerVector(compilation_sources); 1017 1018 // Create the class loader. 1019 jobject jclass_loader = context->CreateClassLoader(compilation_sources_raw); 1020 ASSERT_TRUE(jclass_loader != nullptr); 1021 1022 // Verify the class loader. 1023 ScopedObjectAccess soa(Thread::Current()); 1024 1025 StackHandleScope<6> hs(soa.Self()); 1026 Handle<mirror::ClassLoader> class_loader_1 = hs.NewHandle( 1027 soa.Decode<mirror::ClassLoader>(jclass_loader)); 1028 1029 // For the first class loader the class path dex files must come first and then the 1030 // compilation sources. 1031 std::vector<const DexFile*> class_loader_1_dex_files = 1032 MakeNonOwningPointerVector(classpath_dex_a); 1033 for (auto& dex : compilation_sources_raw) { 1034 class_loader_1_dex_files.push_back(dex); 1035 } 1036 VerifyClassLoaderDexFiles(soa, 1037 class_loader_1, 1038 WellKnownClasses::dalvik_system_PathClassLoader, 1039 class_loader_1_dex_files); 1040 1041 // Verify its shared library. 1042 ArtField* field = 1043 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders); 1044 ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader_1.Get()); 1045 ASSERT_TRUE(raw_shared_libraries != nullptr); 1046 1047 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries( 1048 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 1049 ASSERT_EQ(shared_libraries->GetLength(), 1); 1050 1051 Handle<mirror::ClassLoader> class_loader_2 = hs.NewHandle(shared_libraries->Get(0)); 1052 std::vector<const DexFile*> class_loader_2_dex_files = 1053 MakeNonOwningPointerVector(classpath_dex_b); 1054 VerifyClassLoaderDexFiles(soa, 1055 class_loader_2, 1056 WellKnownClasses::dalvik_system_PathClassLoader, 1057 class_loader_2_dex_files); 1058 1059 // Verify the parent. 1060 Handle<mirror::ClassLoader> class_loader_3 = hs.NewHandle(class_loader_1->GetParent()); 1061 std::vector<const DexFile*> class_loader_3_dex_files = 1062 MakeNonOwningPointerVector(classpath_dex_c); 1063 VerifyClassLoaderDexFiles(soa, 1064 class_loader_3, 1065 WellKnownClasses::dalvik_system_PathClassLoader, 1066 class_loader_3_dex_files); 1067 1068 // Verify its shared library is the same as the child. 1069 raw_shared_libraries = field->GetObject(class_loader_3.Get()); 1070 ASSERT_TRUE(raw_shared_libraries != nullptr); 1071 Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries_2( 1072 hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>())); 1073 ASSERT_EQ(shared_libraries_2->GetLength(), 1); 1074 ASSERT_OBJ_PTR_EQ(shared_libraries_2->Get(0), class_loader_2.Get()); 1075 1076 // Class loaders should have the BootClassLoader as a parent. 1077 ASSERT_TRUE(class_loader_2->GetParent()->GetClass() == 1078 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 1079 ASSERT_TRUE(class_loader_3->GetParent()->GetClass() == 1080 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)); 1081 } 1082 1083 TEST_F(ClassLoaderContextTest, EncodeInOatFile) { 1084 std::string dex1_name = GetTestDexFileName("Main"); 1085 std::string dex2_name = GetTestDexFileName("MyClass"); 1086 std::unique_ptr<ClassLoaderContext> context = 1087 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]"); 1088 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 1089 1090 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main"); 1091 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass"); 1092 std::string encoding = context->EncodeContextForOatFile(""); 1093 std::string expected_encoding = "PCL[" + CreateClassPathWithChecksums(dex1) + ":" + 1094 CreateClassPathWithChecksums(dex2) + "]"; 1095 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile("")); 1096 } 1097 1098 TEST_F(ClassLoaderContextTest, EncodeInOatFileIMC) { 1099 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr); 1100 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a); 1101 1102 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b); 1103 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 1104 1105 std::vector<std::unique_ptr<const DexFile>> dex1 = OpenTestDexFiles("Main"); 1106 std::vector<std::unique_ptr<const DexFile>> dex2 = OpenTestDexFiles("MyClass"); 1107 ASSERT_EQ(dex2.size(), 1u); 1108 1109 std::string encoding = context->EncodeContextForOatFile(""); 1110 std::string expected_encoding = "IMC[<unknown>*" + std::to_string(dex2[0]->GetLocationChecksum()) 1111 + "];PCL[" + CreateClassPathWithChecksums(dex1) + "]"; 1112 ASSERT_EQ(expected_encoding, context->EncodeContextForOatFile("")); 1113 } 1114 1115 TEST_F(ClassLoaderContextTest, EncodeForDex2oat) { 1116 std::string dex1_name = GetTestDexFileName("Main"); 1117 std::string dex2_name = GetTestDexFileName("MultiDex"); 1118 std::unique_ptr<ClassLoaderContext> context = 1119 ClassLoaderContext::Create("PCL[" + dex1_name + ":" + dex2_name + "]"); 1120 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 1121 1122 std::string encoding = context->EncodeContextForDex2oat(""); 1123 std::string expected_encoding = "PCL[" + dex1_name + ":" + dex2_name + "]"; 1124 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat("")); 1125 } 1126 1127 TEST_F(ClassLoaderContextTest, EncodeForDex2oatIMC) { 1128 jobject class_loader_a = LoadDexInPathClassLoader("Main", nullptr); 1129 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("MyClass", class_loader_a); 1130 1131 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b); 1132 ASSERT_TRUE(context->OpenDexFiles(InstructionSet::kArm, "")); 1133 1134 std::string encoding = context->EncodeContextForDex2oat(""); 1135 std::string expected_encoding = "IMC[<unknown>];PCL[" + GetTestDexFileName("Main") + "]"; 1136 ASSERT_EQ(expected_encoding, context->EncodeContextForDex2oat("")); 1137 } 1138 1139 // TODO(calin) add a test which creates the context for a class loader together with dex_elements. 1140 TEST_F(ClassLoaderContextTest, CreateContextForClassLoader) { 1141 // The chain is 1142 // ClassLoaderA (PathClassLoader) 1143 // ^ 1144 // | 1145 // ClassLoaderB (DelegateLastClassLoader) 1146 // ^ 1147 // | 1148 // ClassLoaderC (PathClassLoader) 1149 // ^ 1150 // | 1151 // ClassLoaderD (DelegateLastClassLoader) 1152 1153 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr); 1154 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a); 1155 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b); 1156 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c); 1157 1158 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d); 1159 1160 VerifyContextForClassLoader(context.get()); 1161 VerifyContextSize(context.get(), 4); 1162 1163 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD"); 1164 VerifyClassLoaderPCLFromTestDex(context.get(), 1, "ForClassLoaderC"); 1165 VerifyClassLoaderDLCFromTestDex(context.get(), 2, "ForClassLoaderB"); 1166 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA"); 1167 } 1168 1169 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderIMC) { 1170 // The chain is 1171 // ClassLoaderA (PathClassLoader) 1172 // ^ 1173 // | 1174 // ClassLoaderB (InMemoryDexClassLoader) 1175 // ^ 1176 // | 1177 // ClassLoaderC (InMemoryDexClassLoader) 1178 // ^ 1179 // | 1180 // ClassLoaderD (DelegateLastClassLoader) 1181 1182 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr); 1183 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a); 1184 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b); 1185 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c); 1186 1187 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d); 1188 1189 VerifyContextForClassLoader(context.get()); 1190 VerifyContextSize(context.get(), 4); 1191 1192 VerifyClassLoaderDLCFromTestDex(context.get(), 0, "ForClassLoaderD"); 1193 VerifyClassLoaderIMCFromTestDex(context.get(), 1, "ForClassLoaderC"); 1194 VerifyClassLoaderIMCFromTestDex(context.get(), 2, "ForClassLoaderB"); 1195 VerifyClassLoaderPCLFromTestDex(context.get(), 3, "ForClassLoaderA"); 1196 } 1197 1198 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextFirstElement) { 1199 std::string context_spec = "PCL[]"; 1200 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1201 ASSERT_TRUE(context != nullptr); 1202 PretendContextOpenedDexFiles(context.get()); 1203 // Ensure that the special shared library marks as verified for the first thing in the class path. 1204 ASSERT_EQ(context->VerifyClassLoaderContextMatch(OatFile::kSpecialSharedLibrary), 1205 ClassLoaderContext::VerificationResult::kVerifies); 1206 } 1207 1208 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatch) { 1209 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890]"; 1210 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1211 // Pretend that we successfully open the dex files to pass the DCHECKS. 1212 // (as it's much easier to test all the corner cases without relying on actual dex files). 1213 PretendContextOpenedDexFiles(context.get()); 1214 1215 VerifyContextSize(context.get(), 2); 1216 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); 1217 VerifyClassLoaderDLC(context.get(), 1, "c.dex"); 1218 1219 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), 1220 ClassLoaderContext::VerificationResult::kVerifies); 1221 1222 std::string wrong_class_loader_type = "PCL[a.dex*123:b.dex*456];PCL[c.dex*890]"; 1223 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type), 1224 ClassLoaderContext::VerificationResult::kMismatch); 1225 1226 std::string wrong_class_loader_order = "DLC[c.dex*890];PCL[a.dex*123:b.dex*456]"; 1227 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order), 1228 ClassLoaderContext::VerificationResult::kMismatch); 1229 1230 std::string wrong_classpath_order = "PCL[b.dex*456:a.dex*123];DLC[c.dex*890]"; 1231 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order), 1232 ClassLoaderContext::VerificationResult::kMismatch); 1233 1234 std::string wrong_checksum = "PCL[a.dex*999:b.dex*456];DLC[c.dex*890]"; 1235 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum), 1236 ClassLoaderContext::VerificationResult::kMismatch); 1237 1238 std::string wrong_extra_class_loader = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];PCL[d.dex*321]"; 1239 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader), 1240 ClassLoaderContext::VerificationResult::kMismatch); 1241 1242 std::string wrong_extra_classpath = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890:d.dex*321]"; 1243 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath), 1244 ClassLoaderContext::VerificationResult::kMismatch); 1245 1246 std::string wrong_spec = "PCL[a.dex*999:b.dex*456];DLC["; 1247 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_spec), 1248 ClassLoaderContext::VerificationResult::kMismatch); 1249 } 1250 1251 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextWithIMCMatch) { 1252 std::string context_spec = "PCL[a.dex*123:b.dex*456];DLC[c.dex*890];IMC[<unknown>*111]"; 1253 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1254 // Pretend that we successfully open the dex files to pass the DCHECKS. 1255 // (as it's much easier to test all the corner cases without relying on actual dex files). 1256 PretendContextOpenedDexFiles(context.get()); 1257 1258 VerifyContextSize(context.get(), 3); 1259 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); 1260 VerifyClassLoaderDLC(context.get(), 1, "c.dex"); 1261 VerifyClassLoaderIMC(context.get(), 2, "<unknown>"); 1262 1263 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), 1264 ClassLoaderContext::VerificationResult::kVerifies); 1265 } 1266 1267 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchSpecial) { 1268 std::string context_spec = "&"; 1269 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1270 // Pretend that we successfully open the dex files to pass the DCHECKS. 1271 // (as it's much easier to test all the corner cases without relying on actual dex files). 1272 PretendContextOpenedDexFiles(context.get()); 1273 1274 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), 1275 ClassLoaderContext::VerificationResult::kForcedToSkipChecks); 1276 } 1277 1278 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithSL) { 1279 std::string context_spec = 1280 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}" 1281 ";DLC[c.dex*890]"; 1282 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1283 // Pretend that we successfully open the dex files to pass the DCHECKS. 1284 // (as it's much easier to test all the corner cases without relying on actual dex files). 1285 PretendContextOpenedDexFiles(context.get()); 1286 1287 VerifyContextSize(context.get(), 2); 1288 VerifyClassLoaderPCL(context.get(), 0, "a.dex:b.dex"); 1289 VerifyClassLoaderDLC(context.get(), 1, "c.dex"); 1290 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, "d.dex"); 1291 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 1, "f.dex:g.dex"); 1292 1293 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), 1294 ClassLoaderContext::VerificationResult::kVerifies); 1295 1296 std::string wrong_class_loader_type = 1297 "PCL[a.dex*123:b.dex*456]{DLC[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}" 1298 ";DLC[c.dex*890]"; 1299 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_type), 1300 ClassLoaderContext::VerificationResult::kMismatch); 1301 1302 std::string wrong_class_loader_order = 1303 "PCL[a.dex*123:b.dex*456]{PCL[f.dex#098:g.dex#999}#PCL[d.dex*321];PCL[e.dex*654]}" 1304 ";DLC[c.dex*890]"; 1305 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_class_loader_order), 1306 ClassLoaderContext::VerificationResult::kMismatch); 1307 1308 std::string wrong_classpath_order = 1309 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}" 1310 ";DLC[c.dex*890]"; 1311 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_classpath_order), 1312 ClassLoaderContext::VerificationResult::kMismatch); 1313 1314 std::string wrong_checksum = 1315 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*333];PCL[e.dex*654]#PCL[g.dex*999:f.dex*098]}" 1316 ";DLC[c.dex*890]"; 1317 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_checksum), 1318 ClassLoaderContext::VerificationResult::kMismatch); 1319 1320 std::string wrong_extra_class_loader = 1321 "PCL[a.dex*123:b.dex*456]" 1322 "{PCL[d.dex*321];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999];PCL[i.dex#444]}" 1323 ";DLC[c.dex*890]"; 1324 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_class_loader), 1325 ClassLoaderContext::VerificationResult::kMismatch); 1326 1327 std::string wrong_extra_classpath = 1328 "PCL[a.dex*123:b.dex*456]{PCL[d.dex*321:i.dex#444];PCL[e.dex*654]#PCL[f.dex*098:g.dex*999]}" 1329 ";DLC[c.dex*890]"; 1330 ASSERT_EQ(context->VerifyClassLoaderContextMatch(wrong_extra_classpath), 1331 ClassLoaderContext::VerificationResult::kMismatch); 1332 } 1333 1334 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchWithIMCSL) { 1335 std::string context_spec = 1336 "IMC[<unknown>*123:<unknown>*456]" 1337 "{IMC[<unknown>*321];IMC[<unknown>*654]#IMC[<unknown>*098:<unknown>*999]};" 1338 "DLC[c.dex*890]"; 1339 std::unique_ptr<ClassLoaderContext> context = ParseContextWithChecksums(context_spec); 1340 // Pretend that we successfully open the dex files to pass the DCHECKS. 1341 // (as it's much easier to test all the corner cases without relying on actual dex files). 1342 PretendContextOpenedDexFiles(context.get()); 1343 1344 VerifyContextSize(context.get(), 2); 1345 VerifyClassLoaderIMC(context.get(), 0, "<unknown>:<unknown>"); 1346 VerifyClassLoaderDLC(context.get(), 1, "c.dex"); 1347 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 0, "<unknown>"); 1348 VerifyClassLoaderSharedLibraryIMC(context.get(), 0, 1, "<unknown>:<unknown>"); 1349 1350 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_spec), 1351 ClassLoaderContext::VerificationResult::kVerifies); 1352 } 1353 1354 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncoding) { 1355 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr); 1356 jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a); 1357 jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b); 1358 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c); 1359 1360 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d); 1361 1362 std::string context_with_no_base_dir = context->EncodeContextForOatFile(""); 1363 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir), 1364 ClassLoaderContext::VerificationResult::kVerifies); 1365 1366 std::string dex_location = GetTestDexFileName("ForClassLoaderA"); 1367 size_t pos = dex_location.rfind('/'); 1368 ASSERT_NE(std::string::npos, pos); 1369 std::string parent = dex_location.substr(0, pos); 1370 1371 std::string context_with_base_dir = context->EncodeContextForOatFile(parent); 1372 ASSERT_NE(context_with_base_dir, context_with_no_base_dir); 1373 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir), 1374 ClassLoaderContext::VerificationResult::kVerifies); 1375 } 1376 1377 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingIMC) { 1378 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr); 1379 jobject class_loader_b = LoadDexInInMemoryDexClassLoader("ForClassLoaderB", class_loader_a); 1380 jobject class_loader_c = LoadDexInInMemoryDexClassLoader("ForClassLoaderC", class_loader_b); 1381 jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c); 1382 1383 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_d); 1384 1385 std::string context_with_no_base_dir = context->EncodeContextForOatFile(""); 1386 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_no_base_dir), 1387 ClassLoaderContext::VerificationResult::kVerifies); 1388 1389 std::string dex_location = GetTestDexFileName("ForClassLoaderA"); 1390 size_t pos = dex_location.rfind('/'); 1391 ASSERT_NE(std::string::npos, pos); 1392 std::string parent = dex_location.substr(0, pos); 1393 1394 std::string context_with_base_dir = context->EncodeContextForOatFile(parent); 1395 ASSERT_NE(context_with_base_dir, context_with_no_base_dir); 1396 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context_with_base_dir), 1397 ClassLoaderContext::VerificationResult::kVerifies); 1398 } 1399 1400 TEST_F(ClassLoaderContextTest, VerifyClassLoaderContextMatchAfterEncodingMultidex) { 1401 jobject class_loader = LoadDexInPathClassLoader("MultiDex", nullptr); 1402 1403 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader); 1404 1405 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")), 1406 ClassLoaderContext::VerificationResult::kVerifies); 1407 } 1408 1409 TEST_F(ClassLoaderContextTest, CreateContextForClassLoaderWithSharedLibraries) { 1410 jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr); 1411 1412 ScopedObjectAccess soa(Thread::Current()); 1413 StackHandleScope<1> hs(soa.Self()); 1414 Handle<mirror::ObjectArray<mirror::ClassLoader>> libraries = hs.NewHandle( 1415 mirror::ObjectArray<mirror::ClassLoader>::Alloc( 1416 soa.Self(), 1417 GetClassRoot<mirror::ObjectArray<mirror::ClassLoader>>(), 1418 1)); 1419 libraries->Set(0, soa.Decode<mirror::ClassLoader>(class_loader_a)); 1420 1421 jobject class_loader_b = LoadDexInPathClassLoader( 1422 "ForClassLoaderB", nullptr, soa.AddLocalReference<jobject>(libraries.Get())); 1423 1424 std::unique_ptr<ClassLoaderContext> context = CreateContextForClassLoader(class_loader_b); 1425 ASSERT_TRUE(context != nullptr); 1426 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("ForClassLoaderB"); 1427 VerifyClassLoaderPCL(context.get(), 0, dex_files[0]->GetLocation()); 1428 dex_files = OpenTestDexFiles("ForClassLoaderA"); 1429 VerifyClassLoaderSharedLibraryPCL(context.get(), 0, 0, dex_files[0]->GetLocation()); 1430 1431 ASSERT_EQ(context->VerifyClassLoaderContextMatch(context->EncodeContextForOatFile("")), 1432 ClassLoaderContext::VerificationResult::kVerifies); 1433 } 1434 1435 } // namespace art 1436