diff options
| -rw-r--r-- | build/Android.gtest.mk | 17 | ||||
| -rw-r--r-- | runtime/oat_file.cc | 31 | ||||
| -rw-r--r-- | runtime/oat_file_test.cc | 42 |
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 |