summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/dex2oat_test.cc36
-rw-r--r--dex2oat/linker/oat_writer_test.cc15
-rw-r--r--dexlayout/dexdiag_test.cc3
-rw-r--r--oatdump/oatdump.cc15
-rw-r--r--runtime/dexopt_test.cc3
-rw-r--r--runtime/gc/collector/concurrent_copying-inl.h2
-rw-r--r--runtime/gc/space/image_space.cc3
-rw-r--r--runtime/gc/space/image_space_test.cc3
-rw-r--r--runtime/jit/profile_compilation_info.cc2
-rw-r--r--runtime/jit/profile_compilation_info_test.cc38
-rw-r--r--runtime/oat_file.cc91
-rw-r--r--runtime/oat_file.h20
-rw-r--r--runtime/oat_file_assistant.cc14
-rw-r--r--runtime/oat_file_assistant.h7
-rw-r--r--runtime/oat_file_test.cc9
-rw-r--r--runtime/runtime.cc3
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,