summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.gtest.mk17
-rw-r--r--runtime/oat_file.cc31
-rw-r--r--runtime/oat_file_test.cc42
3 files changed, 89 insertions, 1 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 894b33b00a..65b691f8ec 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -83,6 +83,11 @@ ART_TEST_TARGET_GTEST_MainUncompressed_DEX := $(basename $(ART_TEST_TARGET_GTEST
ART_TEST_HOST_GTEST_EmptyUncompressed_DEX := $(basename $(ART_TEST_HOST_GTEST_Main_DEX))EmptyUncompressed$(suffix $(ART_TEST_HOST_GTEST_Main_DEX))
ART_TEST_TARGET_GTEST_EmptyUncompressed_DEX := $(basename $(ART_TEST_TARGET_GTEST_Main_DEX))EmptyUncompressed$(suffix $(ART_TEST_TARGET_GTEST_Main_DEX))
+# Create rules for MultiDexUncompressed, a copy of MultiDex with the classes.dex uncompressed
+# for the OatFile tests.
+ART_TEST_HOST_GTEST_MultiDexUncompressed_DEX := $(basename $(ART_TEST_HOST_GTEST_MultiDex_DEX))Uncompressed$(suffix $(ART_TEST_HOST_GTEST_MultiDex_DEX))
+ART_TEST_TARGET_GTEST_MultiDexUncompressed_DEX := $(basename $(ART_TEST_TARGET_GTEST_MultiDex_DEX))Uncompressed$(suffix $(ART_TEST_TARGET_GTEST_MultiDex_DEX))
+
$(ART_TEST_HOST_GTEST_MainStripped_DEX): $(ART_TEST_HOST_GTEST_Main_DEX)
cp $< $@
$(call dexpreopt-remove-classes.dex,$@)
@@ -111,6 +116,16 @@ $(ART_TEST_TARGET_GTEST_EmptyUncompressed_DEX): $(ZIPALIGN)
zip -j -qD -X -0 $@ $(dir $@)classes.dex
rm $(dir $@)classes.dex
+$(ART_TEST_HOST_GTEST_MultiDexUncompressed_DEX): $(ART_TEST_HOST_GTEST_MultiDex_DEX) $(ZIPALIGN)
+ cp $< $@
+ $(call uncompress-dexs, $@)
+ $(call align-package, $@)
+
+$(ART_TEST_TARGET_GTEST_MultiDexUncompressed_DEX): $(ART_TEST_TARGET_GTEST_MultiDex_DEX) $(ZIPALIGN)
+ cp $< $@
+ $(call uncompress-dexs, $@)
+ $(call align-package, $@)
+
ART_TEST_GTEST_VerifierDeps_SRC := $(abspath $(wildcard $(LOCAL_PATH)/VerifierDeps/*.smali))
ART_TEST_GTEST_VerifierDepsMulti_SRC := $(abspath $(wildcard $(LOCAL_PATH)/VerifierDepsMulti/*.smali))
ART_TEST_HOST_GTEST_VerifierDeps_DEX := $(dir $(ART_TEST_HOST_GTEST_Main_DEX))$(subst Main,VerifierDeps,$(basename $(notdir $(ART_TEST_HOST_GTEST_Main_DEX))))$(suffix $(ART_TEST_HOST_GTEST_Main_DEX))
@@ -153,7 +168,7 @@ ART_GTEST_jni_internal_test_DEX_DEPS := AllFields StaticLeafMethods
ART_GTEST_oat_file_assistant_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS)
ART_GTEST_dexoptanalyzer_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS)
ART_GTEST_image_space_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS)
-ART_GTEST_oat_file_test_DEX_DEPS := Main MultiDex
+ART_GTEST_oat_file_test_DEX_DEPS := Main MultiDex MainUncompressed MultiDexUncompressed
ART_GTEST_oat_test_DEX_DEPS := Main
ART_GTEST_object_test_DEX_DEPS := ProtoCompare ProtoCompare2 StaticsFromCode XandY
ART_GTEST_patchoat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS)
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index dc4bae3415..600449ccb9 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -633,6 +633,15 @@ bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {
const uint8_t* dex_file_pointer = nullptr;
if (UNLIKELY(dex_file_offset == 0U)) {
if (uncompressed_dex_files_ == nullptr) {
+ // Do not support mixed-mode oat files.
+ if (i > 0) {
+ *error_msg = StringPrintf("In oat file '%s', unsupported uncompressed-dex-file for dex "
+ "file %zu (%s)",
+ GetLocation().c_str(),
+ i,
+ dex_file_location.c_str());
+ return false;
+ }
uncompressed_dex_files_.reset(new std::vector<std::unique_ptr<const DexFile>>());
// No dex files, load it from location.
const ArtDexFileLoader dex_file_loader;
@@ -652,9 +661,31 @@ bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) {
return false;
}
}
+ // The oat file may be out of date wrt/ the dex-file location. We need to be defensive
+ // here and ensure that at least the number of dex files still matches.
+ // Note: actual checksum comparisons are the duty of the OatFileAssistant and will be
+ // done after loading the OatFile.
+ if (uncompressed_dex_files_->size() != dex_file_count) {
+ *error_msg = StringPrintf("In oat file '%s', expected %u uncompressed dex files, but "
+ "found %zu in '%s'",
+ GetLocation().c_str(),
+ dex_file_count,
+ uncompressed_dex_files_->size(),
+ dex_file_location.c_str());
+ return false;
+ }
}
dex_file_pointer = uncompressed_dex_files_.get()->at(i)->Begin();
} else {
+ // Do not support mixed-mode oat files.
+ if (uncompressed_dex_files_ != nullptr) {
+ *error_msg = StringPrintf("In oat file '%s', unsupported embedded dex-file for dex file "
+ "%zu (%s)",
+ GetLocation().c_str(),
+ i,
+ dex_file_location.c_str());
+ return false;
+ }
if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
"offset %u of %zu but the size of dex file header is %zu",
diff --git a/runtime/oat_file_test.cc b/runtime/oat_file_test.cc
index 8d864018ab..89812f370f 100644
--- a/runtime/oat_file_test.cc
+++ b/runtime/oat_file_test.cc
@@ -88,4 +88,46 @@ TEST_F(OatFileTest, LoadOat) {
EXPECT_EQ(odex_file->GetVdexFile()->Begin(), odex_file->VdexBegin());
}
+TEST_F(OatFileTest, ChangingMultiDexUncompressed) {
+ std::string dex_location = GetScratchDir() + "/MultiDexUncompressed.jar";
+
+ Copy(GetTestDexFileName("MultiDexUncompressed"), dex_location);
+ GenerateOatForTest(dex_location.c_str(), CompilerFilter::kQuicken);
+
+ std::string oat_location;
+ std::string error_msg;
+ ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
+ dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
+
+ // Ensure we can load that file. Just a precondition.
+ {
+ std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(),
+ oat_location.c_str(),
+ nullptr,
+ nullptr,
+ false,
+ /*low_4gb*/false,
+ dex_location.c_str(),
+ &error_msg));
+ ASSERT_TRUE(odex_file != nullptr);
+ ASSERT_EQ(2u, odex_file->GetOatDexFiles().size());
+ }
+
+ // Now replace the source.
+ Copy(GetTestDexFileName("MainUncompressed"), dex_location);
+
+ // And try to load again.
+ std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(),
+ oat_location.c_str(),
+ nullptr,
+ nullptr,
+ false,
+ /*low_4gb*/false,
+ dex_location.c_str(),
+ &error_msg));
+ EXPECT_TRUE(odex_file == nullptr);
+ EXPECT_NE(std::string::npos, error_msg.find("expected 2 uncompressed dex files, but found 1"))
+ << error_msg;
+}
+
} // namespace art