diff options
-rw-r--r-- | dex2oat/dex2oat_test.cc | 36 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer_test.cc | 15 | ||||
-rw-r--r-- | dexlayout/dexdiag_test.cc | 3 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 15 | ||||
-rw-r--r-- | runtime/dexopt_test.cc | 3 | ||||
-rw-r--r-- | runtime/gc/collector/concurrent_copying-inl.h | 2 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 3 | ||||
-rw-r--r-- | runtime/gc/space/image_space_test.cc | 3 | ||||
-rw-r--r-- | runtime/jit/profile_compilation_info.cc | 2 | ||||
-rw-r--r-- | runtime/jit/profile_compilation_info_test.cc | 38 | ||||
-rw-r--r-- | runtime/oat_file.cc | 91 | ||||
-rw-r--r-- | runtime/oat_file.h | 20 | ||||
-rw-r--r-- | runtime/oat_file_assistant.cc | 14 | ||||
-rw-r--r-- | runtime/oat_file_assistant.h | 7 | ||||
-rw-r--r-- | runtime/oat_file_test.cc | 9 | ||||
-rw-r--r-- | runtime/runtime.cc | 3 |
16 files changed, 189 insertions, 75 deletions
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index bc8468e12f..a229d7dd71 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -135,7 +135,8 @@ class Dex2oatTest : public Dex2oatEnvironmentTest { ASSERT_TRUE(success) << error_msg << std::endl << output_; // Verify the odex file was generated as expected. - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -154,7 +155,8 @@ class Dex2oatTest : public Dex2oatEnvironmentTest { if (!test_accepts_odex_file_on_failure) { // Verify there's no loadable odex file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -542,7 +544,8 @@ class Dex2oatVeryLargeTest : public Dex2oatTest { } // Host/target independent checks. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -812,7 +815,8 @@ class Dex2oatLayoutTest : public Dex2oatTest { const std::string& app_image_file_name) { // Host/target independent checks. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -973,7 +977,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { void CheckResult(const std::string& dex_location, const std::string& odex_location) { std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -1366,7 +1371,8 @@ TEST_F(Dex2oatTest, LayoutSections) { EXPECT_EQ(res, 0); // Open our generated oat file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_filename.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_filename.c_str(), oat_filename.c_str(), nullptr, nullptr, @@ -1479,7 +1485,8 @@ TEST_F(Dex2oatTest, GenerateCompactDex) { {"--compact-dex-level=fast"}); EXPECT_EQ(res, 0); // Open our generated oat file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_filename.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_filename.c_str(), oat_filename.c_str(), nullptr, nullptr, @@ -1724,7 +1731,8 @@ TEST_F(Dex2oatTest, CompactDexGenerationFailure) { }); // Open our generated oat file. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_filename.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_filename.c_str(), oat_filename.c_str(), nullptr, nullptr, @@ -1801,7 +1809,8 @@ TEST_F(Dex2oatTest, VerifyCompilationReason) { { "--compilation-reason=install" }, true); std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -1826,7 +1835,8 @@ TEST_F(Dex2oatTest, VerifyNoCompilationReason) { {}, true); std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -1863,7 +1873,8 @@ TEST_F(Dex2oatTest, DontExtract) { ASSERT_TRUE(vdex != nullptr); EXPECT_FALSE(vdex->HasDexSection()) << output_; } - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, @@ -2106,7 +2117,8 @@ TEST_F(Dex2oatTest, AppImageNoProfile) { [](const OatFile&) {}); // Open our generated oat file. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc index 37e69f7706..208e96fc6f 100644 --- a/dex2oat/linker/oat_writer_test.cc +++ b/dex2oat/linker/oat_writer_test.cc @@ -426,7 +426,8 @@ TEST_F(OatTest, WriteRead) { if (kCompile) { // OatWriter strips the code, regenerate to compare compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings); } - std::unique_ptr<OatFile> oat_file(OatFile::Open(tmp_oat.GetFilename(), + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + tmp_oat.GetFilename(), tmp_oat.GetFilename(), nullptr, nullptr, @@ -560,7 +561,8 @@ TEST_F(OatTest, EmptyTextSection) { /* verify */ false); ASSERT_TRUE(success); - std::unique_ptr<OatFile> oat_file(OatFile::Open(tmp_oat.GetFilename(), + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + tmp_oat.GetFilename(), tmp_oat.GetFilename(), nullptr, nullptr, @@ -637,7 +639,8 @@ void OatTest::TestDexFileInput(bool verify, bool low_4gb, bool use_profile) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(tmp_oat.GetFilename(), + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + tmp_oat.GetFilename(), tmp_oat.GetFilename(), nullptr, nullptr, @@ -767,7 +770,8 @@ void OatTest::TestZipFileInput(bool verify) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(tmp_oat.GetFilename(), + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + tmp_oat.GetFilename(), tmp_oat.GetFilename(), nullptr, nullptr, @@ -816,7 +820,8 @@ void OatTest::TestZipFileInput(bool verify) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(tmp_oat.GetFilename(), + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + tmp_oat.GetFilename(), tmp_oat.GetFilename(), nullptr, nullptr, diff --git a/dexlayout/dexdiag_test.cc b/dexlayout/dexdiag_test.cc index 068949ceba..53145c22fa 100644 --- a/dexlayout/dexdiag_test.cc +++ b/dexlayout/dexdiag_test.cc @@ -68,7 +68,8 @@ class DexDiagTest : public CommonRuntimeTest { EXPECT_TRUE(!oat_location.empty()); std::cout << "==" << oat_location << std::endl; std::string error_msg; - std::unique_ptr<OatFile> oat(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 6a68b55fad..44050ff8ed 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -2156,7 +2156,8 @@ class ImageDumper { oat_file = runtime->GetOatFileManager().FindOpenedOatFileFromOatLocation(oat_location); } if (oat_file == nullptr) { - oat_file = OatFile::Open(oat_location, + oat_file = OatFile::Open(/* zip_fd */ -1, + oat_location, oat_location, nullptr, nullptr, @@ -3044,7 +3045,8 @@ static int DumpImages(Runtime* runtime, OatDumperOptions* options, std::ostream* // We need to map the oat file in the low 4gb or else the fixup wont be able to fit oat file // pointers into 32 bit pointer sized ArtMethods. std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(options->app_oat_, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + options->app_oat_, options->app_oat_, nullptr, nullptr, @@ -3167,7 +3169,8 @@ static int DumpOat(Runtime* runtime, << "oatdump might fail if the oat file does not contain the dex code."; } std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + oat_filename, oat_filename, nullptr, nullptr, @@ -3192,7 +3195,8 @@ static int SymbolizeOat(const char* oat_filename, std::string& output_name, bool no_bits) { std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + oat_filename, oat_filename, nullptr, nullptr, @@ -3239,7 +3243,8 @@ class IMTDumper { if (oat_filename != nullptr) { std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + oat_filename, oat_filename, nullptr, nullptr, diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc index 8f0f9c61dc..f8388f315d 100644 --- a/runtime/dexopt_test.cc +++ b/runtime/dexopt_test.cc @@ -105,7 +105,8 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, } // Verify the odex file was generated as expected. - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, diff --git a/runtime/gc/collector/concurrent_copying-inl.h b/runtime/gc/collector/concurrent_copying-inl.h index 6e345fb2f2..b331e975fd 100644 --- a/runtime/gc/collector/concurrent_copying-inl.h +++ b/runtime/gc/collector/concurrent_copying-inl.h @@ -146,8 +146,8 @@ inline mirror::Object* ConcurrentCopying::Mark(mirror::Object* from_ref, return MarkUnevacFromSpaceRegion(from_ref, region_space_bitmap_); default: // The reference is in an unused region. - region_space_->DumpNonFreeRegions(LOG_STREAM(FATAL_WITHOUT_ABORT)); LOG(FATAL_WITHOUT_ABORT) << DumpHeapReference(holder, offset, from_ref); + region_space_->DumpNonFreeRegions(LOG_STREAM(FATAL_WITHOUT_ABORT)); heap_->GetVerification()->LogHeapCorruption(holder, offset, from_ref, /* fatal */ true); UNREACHABLE(); } diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index e2154b8e4d..dbe09e8c5b 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1418,7 +1418,8 @@ class ImageSpaceLoader { CHECK(image_header.GetOatDataBegin() != nullptr); - std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + oat_filename, oat_filename, image_header.GetOatDataBegin(), image_header.GetOatFileBegin(), diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc index fcc47d45fc..f202a43be9 100644 --- a/runtime/gc/space/image_space_test.cc +++ b/runtime/gc/space/image_space_test.cc @@ -43,7 +43,8 @@ TEST_F(DexoptTest, ValidateOatFile) { args.push_back("--oat-file=" + oat_location); ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; - std::unique_ptr<OatFile> oat(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc index 7c21916997..d27465dd6e 100644 --- a/runtime/jit/profile_compilation_info.cc +++ b/runtime/jit/profile_compilation_info.cc @@ -1351,7 +1351,7 @@ ProfileCompilationInfo::ProfileLoadStatus ProfileCompilationInfo::LoadInternal( if (!filter_fn(profile_line_headers[k].dex_location, profile_line_headers[k].checksum)) { // We have to skip the line. Advanced the current pointer of the buffer. size_t profile_line_size = - profile_line_headers[k].class_set_size + + profile_line_headers[k].class_set_size * sizeof(uint16_t) + profile_line_headers[k].method_region_size_bytes + DexFileData::ComputeBitmapStorage(profile_line_headers[k].num_method_ids); uncompressed_data.Advance(profile_line_size); diff --git a/runtime/jit/profile_compilation_info_test.cc b/runtime/jit/profile_compilation_info_test.cc index 4e3774e389..0ebadc00fe 100644 --- a/runtime/jit/profile_compilation_info_test.cc +++ b/runtime/jit/profile_compilation_info_test.cc @@ -1160,7 +1160,7 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoading) { ProfileCompilationInfo loaded_info; ASSERT_TRUE(profile.GetFile()->ResetOffset()); - // Filter out dex locations. Keep only dex_location1 and dex_location2. + // Filter out dex locations. Keep only dex_location1 and dex_location3. ProfileCompilationInfo::ProfileLoadFilterFn filter_fn = [](const std::string& dex_location, uint32_t checksum) -> bool { return (dex_location == "dex_location1" && checksum == 1) @@ -1303,4 +1303,40 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingKeepAll) { } } +// Regression test: we were failing to do a filtering loading when the filtered dex file +// contained profiled classes. +TEST_F(ProfileCompilationInfoTest, FilteredLoadingWithClasses) { + ScratchFile profile; + + // Save a profile with 2 dex files containing just classes. + ProfileCompilationInfo saved_info; + uint16_t item_count = 1000; + for (uint16_t i = 0; i < item_count; i++) { + ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, dex::TypeIndex(i), &saved_info)); + ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &saved_info)); + } + + ASSERT_TRUE(saved_info.Save(GetFd(profile))); + ASSERT_EQ(0, profile.GetFile()->Flush()); + + + // Filter out dex locations: kepp only dex_location2. + ProfileCompilationInfo loaded_info; + ASSERT_TRUE(profile.GetFile()->ResetOffset()); + ProfileCompilationInfo::ProfileLoadFilterFn filter_fn = + [](const std::string& dex_location, uint32_t checksum) -> bool { + return (dex_location == "dex_location2" && checksum == 2); + }; + ASSERT_TRUE(loaded_info.Load(GetFd(profile), true, filter_fn)); + + // Compute the expectation. + ProfileCompilationInfo expected_info; + for (uint16_t i = 0; i < item_count; i++) { + ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &expected_info)); + } + + // Validate the expectation. + ASSERT_TRUE(loaded_info.Equals(expected_info)); +} + } // namespace art diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index c7a558cc94..371678d4d9 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -97,7 +97,8 @@ class OatFileBase : public OatFile { virtual ~OatFileBase() {} template <typename kOatFileBaseSubType> - static OatFileBase* OpenOatFile(const std::string& vdex_filename, + static OatFileBase* OpenOatFile(int zip_fd, + const std::string& vdex_filename, const std::string& elf_filename, const std::string& location, uint8_t* requested_base, @@ -109,7 +110,8 @@ class OatFileBase : public OatFile { std::string* error_msg); template <typename kOatFileBaseSubType> - static OatFileBase* OpenOatFile(int vdex_fd, + static OatFileBase* OpenOatFile(int zip_fd, + int vdex_fd, int oat_fd, const std::string& vdex_filename, const std::string& oat_filename, @@ -160,7 +162,7 @@ class OatFileBase : public OatFile { virtual void PreSetup(const std::string& elf_filename) = 0; - bool Setup(const char* abs_dex_location, std::string* error_msg); + bool Setup(int zip_fd, const char* abs_dex_location, std::string* error_msg); // Setters exposed for ElfOatFile. @@ -181,7 +183,8 @@ class OatFileBase : public OatFile { }; template <typename kOatFileBaseSubType> -OatFileBase* OatFileBase::OpenOatFile(const std::string& vdex_filename, +OatFileBase* OatFileBase::OpenOatFile(int zip_fd, + const std::string& vdex_filename, const std::string& elf_filename, const std::string& location, uint8_t* requested_base, @@ -214,7 +217,7 @@ OatFileBase* OatFileBase::OpenOatFile(const std::string& vdex_filename, ret->PreSetup(elf_filename); - if (!ret->Setup(abs_dex_location, error_msg)) { + if (!ret->Setup(zip_fd, abs_dex_location, error_msg)) { return nullptr; } @@ -222,7 +225,8 @@ OatFileBase* OatFileBase::OpenOatFile(const std::string& vdex_filename, } template <typename kOatFileBaseSubType> -OatFileBase* OatFileBase::OpenOatFile(int vdex_fd, +OatFileBase* OatFileBase::OpenOatFile(int zip_fd, + int vdex_fd, int oat_fd, const std::string& vdex_location, const std::string& oat_location, @@ -254,7 +258,7 @@ OatFileBase* OatFileBase::OpenOatFile(int vdex_fd, ret->PreSetup(oat_location); - if (!ret->Setup(abs_dex_location, error_msg)) { + if (!ret->Setup(zip_fd, abs_dex_location, error_msg)) { return nullptr; } @@ -485,7 +489,7 @@ static void DCheckIndexToBssMapping(OatFile* oat_file, } } -bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) { +bool OatFileBase::Setup(int zip_fd, const char* abs_dex_location, std::string* error_msg) { if (!GetOatHeader().IsValid()) { std::string cause = GetOatHeader().GetValidationErrorMessage(); *error_msg = StringPrintf("Invalid oat header for '%s': %s", @@ -641,12 +645,23 @@ bool OatFileBase::Setup(const char* abs_dex_location, std::string* error_msg) { uncompressed_dex_files_.reset(new std::vector<std::unique_ptr<const DexFile>>()); // No dex files, load it from location. const ArtDexFileLoader dex_file_loader; - if (!dex_file_loader.Open(dex_file_location.c_str(), - dex_file_location, - /* verify */ false, - /* verify_checksum */ false, - error_msg, - uncompressed_dex_files_.get())) { + bool loaded = false; + if (zip_fd != -1) { + loaded = dex_file_loader.OpenZip(zip_fd, + dex_file_location, + /* verify */ false, + /* verify_checksum */ false, + error_msg, + uncompressed_dex_files_.get()); + } else { + loaded = dex_file_loader.Open(dex_file_location.c_str(), + dex_file_location, + /* verify */ false, + /* verify_checksum */ false, + error_msg, + uncompressed_dex_files_.get()); + } + if (!loaded) { if (Runtime::Current() == nullptr) { // If there's no runtime, we're running oatdump, so return // a half constructed oat file that oatdump knows how to deal with. @@ -1144,7 +1159,8 @@ class ElfOatFile FINAL : public OatFileBase { public: ElfOatFile(const std::string& filename, bool executable) : OatFileBase(filename, executable) {} - static ElfOatFile* OpenElfFile(File* file, + static ElfOatFile* OpenElfFile(int zip_fd, + File* file, const std::string& location, uint8_t* requested_base, uint8_t* oat_file_begin, // Override base if not null @@ -1154,7 +1170,8 @@ class ElfOatFile FINAL : public OatFileBase { const char* abs_dex_location, std::string* error_msg); - bool InitializeFromElfFile(ElfFile* elf_file, + bool InitializeFromElfFile(int zip_fd, + ElfFile* elf_file, VdexFile* vdex_file, const char* abs_dex_location, std::string* error_msg); @@ -1204,7 +1221,8 @@ class ElfOatFile FINAL : public OatFileBase { DISALLOW_COPY_AND_ASSIGN(ElfOatFile); }; -ElfOatFile* ElfOatFile::OpenElfFile(File* file, +ElfOatFile* ElfOatFile::OpenElfFile(int zip_fd, + File* file, const std::string& location, uint8_t* requested_base, uint8_t* oat_file_begin, // Override base if not null @@ -1231,14 +1249,15 @@ ElfOatFile* ElfOatFile::OpenElfFile(File* file, return nullptr; } - if (!oat_file->Setup(abs_dex_location, error_msg)) { + if (!oat_file->Setup(zip_fd, abs_dex_location, error_msg)) { return nullptr; } return oat_file.release(); } -bool ElfOatFile::InitializeFromElfFile(ElfFile* elf_file, +bool ElfOatFile::InitializeFromElfFile(int zip_fd, + ElfFile* elf_file, VdexFile* vdex_file, const char* abs_dex_location, std::string* error_msg) { @@ -1255,7 +1274,7 @@ bool ElfOatFile::InitializeFromElfFile(ElfFile* elf_file, SetBegin(elf_file->Begin() + offset); SetEnd(elf_file->Begin() + size + offset); // Ignore the optional .bss section when opening non-executable. - return Setup(abs_dex_location, error_msg); + return Setup(zip_fd, abs_dex_location, error_msg); } bool ElfOatFile::Load(const std::string& elf_filename, @@ -1356,18 +1375,20 @@ static void CheckLocation(const std::string& location) { CHECK(!location.empty()); } -OatFile* OatFile::OpenWithElfFile(ElfFile* elf_file, +OatFile* OatFile::OpenWithElfFile(int zip_fd, + ElfFile* elf_file, VdexFile* vdex_file, const std::string& location, const char* abs_dex_location, std::string* error_msg) { std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, false /* executable */)); - return oat_file->InitializeFromElfFile(elf_file, vdex_file, abs_dex_location, error_msg) + return oat_file->InitializeFromElfFile(zip_fd, elf_file, vdex_file, abs_dex_location, error_msg) ? oat_file.release() : nullptr; } -OatFile* OatFile::Open(const std::string& oat_filename, +OatFile* OatFile::Open(int zip_fd, + const std::string& oat_filename, const std::string& oat_location, uint8_t* requested_base, uint8_t* oat_file_begin, @@ -1392,7 +1413,8 @@ OatFile* OatFile::Open(const std::string& oat_filename, // Try dlopen first, as it is required for native debuggability. This will fail fast if dlopen is // disabled. - OatFile* with_dlopen = OatFileBase::OpenOatFile<DlOpenOatFile>(vdex_filename, + OatFile* with_dlopen = OatFileBase::OpenOatFile<DlOpenOatFile>(zip_fd, + vdex_filename, oat_filename, oat_location, requested_base, @@ -1421,7 +1443,8 @@ OatFile* OatFile::Open(const std::string& oat_filename, // // Another independent reason is the absolute placement of boot.oat. dlopen on the host usually // does honor the virtual address encoded in the ELF file only for ET_EXEC files, not ET_DYN. - OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(vdex_filename, + OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(zip_fd, + vdex_filename, oat_filename, oat_location, requested_base, @@ -1434,7 +1457,8 @@ OatFile* OatFile::Open(const std::string& oat_filename, return with_internal; } -OatFile* OatFile::Open(int vdex_fd, +OatFile* OatFile::Open(int zip_fd, + int vdex_fd, int oat_fd, const std::string& oat_location, uint8_t* requested_base, @@ -1447,7 +1471,8 @@ OatFile* OatFile::Open(int vdex_fd, std::string vdex_location = GetVdexFilename(oat_location); - OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(vdex_fd, + OatFile* with_internal = OatFileBase::OpenOatFile<ElfOatFile>(zip_fd, + vdex_fd, oat_fd, vdex_location, oat_location, @@ -1461,12 +1486,14 @@ OatFile* OatFile::Open(int vdex_fd, return with_internal; } -OatFile* OatFile::OpenWritable(File* file, +OatFile* OatFile::OpenWritable(int zip_fd, + File* file, const std::string& location, const char* abs_dex_location, std::string* error_msg) { CheckLocation(location); - return ElfOatFile::OpenElfFile(file, + return ElfOatFile::OpenElfFile(zip_fd, + file, location, nullptr, nullptr, @@ -1477,12 +1504,14 @@ OatFile* OatFile::OpenWritable(File* file, error_msg); } -OatFile* OatFile::OpenReadable(File* file, +OatFile* OatFile::OpenReadable(int zip_fd, + File* file, const std::string& location, const char* abs_dex_location, std::string* error_msg) { CheckLocation(location); - return ElfOatFile::OpenElfFile(file, + return ElfOatFile::OpenElfFile(zip_fd, + file, location, nullptr, nullptr, diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 6494b4c58e..8e18cee729 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -74,7 +74,8 @@ class OatFile { // Opens an oat file contained within the given elf file. This is always opened as // non-executable at the moment. - static OatFile* OpenWithElfFile(ElfFile* elf_file, + static OatFile* OpenWithElfFile(int zip_fd, + ElfFile* elf_file, VdexFile* vdex_file, const std::string& location, const char* abs_dex_location, @@ -83,7 +84,8 @@ class OatFile { // optionally be used to request where the file should be loaded. // See the ResolveRelativeEncodedDexLocation for a description of how the // abs_dex_location argument is used. - static OatFile* Open(const std::string& filename, + static OatFile* Open(int zip_fd, + const std::string& filename, const std::string& location, uint8_t* requested_base, uint8_t* oat_file_begin, @@ -93,8 +95,10 @@ class OatFile { std::string* error_msg); // Similar to OatFile::Open(const std::string...), but accepts input vdex and - // odex files as file descriptors. - static OatFile* Open(int vdex_fd, + // odex files as file descriptors. We also take zip_fd in case the vdex does not + // contain the dex code, and we need to read it from the zip file. + static OatFile* Open(int zip_fd, + int vdex_fd, int oat_fd, const std::string& oat_location, uint8_t* requested_base, @@ -109,11 +113,15 @@ class OatFile { // where relocations may be required. Currently used from // ImageWriter which wants to open a writable version from an existing // file descriptor for patching. - static OatFile* OpenWritable(File* file, const std::string& location, + static OatFile* OpenWritable(int zip_fd, + File* file, + const std::string& location, const char* abs_dex_location, std::string* error_msg); // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. - static OatFile* OpenReadable(File* file, const std::string& location, + static OatFile* OpenReadable(int zip_fd, + File* file, + const std::string& location, const char* abs_dex_location, std::string* error_msg); diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 718f9176e9..9c8b6512a7 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -118,7 +118,7 @@ OatFileAssistant::OatFileAssistant(const char* dex_location, std::string error_msg; std::string odex_file_name; if (DexLocationToOdexFilename(dex_location_, isa_, &odex_file_name, &error_msg)) { - odex_.Reset(odex_file_name, UseFdToReadFiles(), vdex_fd, oat_fd); + odex_.Reset(odex_file_name, UseFdToReadFiles(), zip_fd, vdex_fd, oat_fd); } else { LOG(WARNING) << "Failed to determine odex file name: " << error_msg; } @@ -1148,7 +1148,8 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { std::string error_msg; if (use_fd_) { if (oat_fd_ >= 0 && vdex_fd_ >= 0) { - file_.reset(OatFile::Open(vdex_fd_, + file_.reset(OatFile::Open(zip_fd_, + vdex_fd_, oat_fd_, filename_.c_str(), nullptr, @@ -1159,7 +1160,8 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { &error_msg)); } } else { - file_.reset(OatFile::Open(filename_.c_str(), + file_.reset(OatFile::Open(/* zip_fd */ -1, + filename_.c_str(), filename_.c_str(), nullptr, nullptr, @@ -1235,11 +1237,15 @@ void OatFileAssistant::OatFileInfo::Reset() { status_attempted_ = false; } -void OatFileAssistant::OatFileInfo::Reset(const std::string& filename, bool use_fd, int vdex_fd, +void OatFileAssistant::OatFileInfo::Reset(const std::string& filename, + bool use_fd, + int zip_fd, + int vdex_fd, int oat_fd) { filename_provided_ = true; filename_ = filename; use_fd_ = use_fd; + zip_fd_ = zip_fd; vdex_fd_ = vdex_fd; oat_fd_ = oat_fd; Reset(); diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 8d6ec0014a..a6d0961835 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -378,7 +378,11 @@ class OatFileAssistant { // Clear any cached information and switch to getting info about the oat // file with the given filename. - void Reset(const std::string& filename, bool use_fd, int vdex_fd = -1, int oat_fd = -1); + void Reset(const std::string& filename, + bool use_fd, + int zip_fd = -1, + int vdex_fd = -1, + int oat_fd = -1); // Release the loaded oat file for runtime use. // Returns null if the oat file hasn't been loaded or is out of date. @@ -415,6 +419,7 @@ class OatFileAssistant { bool filename_provided_ = false; std::string filename_; + int zip_fd_ = -1; int oat_fd_ = -1; int vdex_fd_ = -1; bool use_fd_ = false; diff --git a/runtime/oat_file_test.cc b/runtime/oat_file_test.cc index 89812f370f..12dfe20d56 100644 --- a/runtime/oat_file_test.cc +++ b/runtime/oat_file_test.cc @@ -74,7 +74,8 @@ TEST_F(OatFileTest, LoadOat) { std::string error_msg; ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename( dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, @@ -101,7 +102,8 @@ TEST_F(OatFileTest, ChangingMultiDexUncompressed) { // Ensure we can load that file. Just a precondition. { - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, @@ -117,7 +119,8 @@ TEST_F(OatFileTest, ChangingMultiDexUncompressed) { Copy(GetTestDexFileName("MainUncompressed"), dex_location); // And try to load again. - std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(), + std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + oat_location.c_str(), oat_location.c_str(), nullptr, nullptr, diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 8f5295cec6..d12a976be8 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1002,7 +1002,8 @@ static bool OpenDexFilesFromImage(const std::string& image_location, return false; } std::unique_ptr<const OatFile> oat_file( - OatFile::OpenWithElfFile(elf_file.release(), + OatFile::OpenWithElfFile(/* zip_fd */ -1, + elf_file.release(), vdex_file.release(), oat_location, nullptr, |