Add arg for overwriting class loader class path
Added stored_context srgument to EncodeContextForOatFile that
overwrites the class path when non-null.
This is used by the --stored-class-loader-context argument. Fixed
the test.
Bug: 70934104
Bug: 67345922
Test: test-art-host-gtest
Change-Id: If877d8cfe9d34eeaa941e9f6df2e12539d9c4a6f
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 741bc64..3fe9c47 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1249,20 +1249,19 @@
class_loader_context_arg.c_str());
}
if (args.Exists(M::StoredClassLoaderContext)) {
- stored_class_loader_context_.reset(new std::string(*args.Get(M::StoredClassLoaderContext)));
- std::unique_ptr<ClassLoaderContext> temp_context =
- ClassLoaderContext::Create(*stored_class_loader_context_);
- if (temp_context == nullptr) {
+ const std::string stored_context_arg = *args.Get(M::StoredClassLoaderContext);
+ stored_class_loader_context_ = ClassLoaderContext::Create(stored_context_arg);
+ if (stored_class_loader_context_ == nullptr) {
Usage("Option --stored-class-loader-context has an incorrect format: %s",
- stored_class_loader_context_->c_str());
+ stored_context_arg.c_str());
} else if (!class_loader_context_->VerifyClassLoaderContextMatch(
- *stored_class_loader_context_,
+ stored_context_arg,
/*verify_names*/ false,
/*verify_checksums*/ false)) {
Usage(
"Option --stored-class-loader-context '%s' mismatches --class-loader-context '%s'",
- stored_class_loader_context_->c_str(),
- class_loader_context_arg.c_str());
+ stored_context_arg.c_str(),
+ class_loader_context_arg.c_str());
}
}
} else if (args.Exists(M::StoredClassLoaderContext)) {
@@ -1609,12 +1608,9 @@
// Store the class loader context in the oat header.
// TODO: deprecate this since store_class_loader_context should be enough to cover the users
// of classpath_dir as well.
- std::string class_path_key;
- if (stored_class_loader_context_ != nullptr) {
- class_path_key = *stored_class_loader_context_;
- } else {
- class_path_key = class_loader_context_->EncodeContextForOatFile(classpath_dir_);
- }
+ std::string class_path_key =
+ class_loader_context_->EncodeContextForOatFile(classpath_dir_,
+ stored_class_loader_context_.get());
key_value_store_->Put(OatHeader::kClassPathKey, class_path_key);
}
@@ -2822,7 +2818,7 @@
std::unique_ptr<ClassLoaderContext> class_loader_context_;
// The class loader context stored in the oat file. May be equal to class_loader_context_.
- std::unique_ptr<std::string> stored_class_loader_context_;
+ std::unique_ptr<ClassLoaderContext> stored_class_loader_context_;
size_t thread_count_;
uint64_t start_ns_;
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 710a6af..bc8468e 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -2126,10 +2126,26 @@
}
TEST_F(Dex2oatClassLoaderContextTest, StoredClassLoaderContext) {
+ std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("MultiDex");
const std::string out_dir = GetScratchDir();
const std::string odex_location = out_dir + "/base.odex";
- const std::string valid_context = "PCL[" + GetUsedDexLocation() + "]";
+ const std::string valid_context = "PCL[" + dex_files[0]->GetLocation() + "]";
const std::string stored_context = "PCL[/system/not_real_lib.jar]";
+ std::string expected_stored_context = "PCL[";
+ size_t index = 1;
+ for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
+ const bool is_first = index == 1u;
+ if (!is_first) {
+ expected_stored_context += ":";
+ }
+ expected_stored_context += "/system/not_real_lib.jar";
+ if (!is_first) {
+ expected_stored_context += "!classes" + std::to_string(index) + ".dex";
+ }
+ expected_stored_context += "*" + std::to_string(dex_file->GetLocationChecksum());
+ ++index;
+ }
+ expected_stored_context += + "]";
// The class path should not be valid and should fail being stored.
GenerateOdexForTest(GetTestDexFileName("ManyMethods"),
odex_location,
@@ -2138,8 +2154,8 @@
true, // expect_success
false, // use_fd
[&](const OatFile& oat_file) {
- EXPECT_NE(oat_file.GetClassLoaderContext(), stored_context);
- EXPECT_NE(oat_file.GetClassLoaderContext(), valid_context);
+ EXPECT_NE(oat_file.GetClassLoaderContext(), stored_context) << output_;
+ EXPECT_NE(oat_file.GetClassLoaderContext(), valid_context) << output_;
});
// The stored context should match what we expect even though it's invalid.
GenerateOdexForTest(GetTestDexFileName("ManyMethods"),
@@ -2150,7 +2166,7 @@
true, // expect_success
false, // use_fd
[&](const OatFile& oat_file) {
- EXPECT_EQ(oat_file.GetClassLoaderContext(), stored_context);
+ EXPECT_EQ(oat_file.GetClassLoaderContext(), expected_stored_context) << output_;
});
}