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  |