Store odex files in oat/<isa>/ directory.
Previously odex files were stored alongside the dex location as:
dex location: /foo/bar/base.apk
odex location: /foo/bar/<isa>/base.odex
This changes where odex files are stored, adding an "oat" directory:
dex location: /foo/bar/base.apk
odex location: /foo/bar/oat/<isa>/base.odex
See also the corresponding change in platform/build and
platform/frameworks/native.
Bug: 19550105
Change-Id: I4c6be4f0c41ff175904846db8e360c4af815b265
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 9a17b01..d92f59b 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -737,18 +737,19 @@
CHECK(error_msg != nullptr);
// The odex file name is formed by replacing the dex_location extension with
- // .odex and inserting an isa directory. For example:
+ // .odex and inserting an oat/<isa> directory. For example:
// location = /foo/bar/baz.jar
- // odex_location = /foo/bar/<isa>/baz.odex
+ // odex_location = /foo/bar/oat/<isa>/baz.odex
- // Find the directory portion of the dex location and add the isa directory.
+ // Find the directory portion of the dex location and add the oat/<isa>
+ // directory.
size_t pos = location.rfind('/');
if (pos == std::string::npos) {
*error_msg = "Dex location " + location + " has no directory.";
return false;
}
std::string dir = location.substr(0, pos+1);
- dir += std::string(GetInstructionSetString(isa));
+ dir += "oat/" + std::string(GetInstructionSetString(isa));
// Find the file portion of the dex location.
std::string file;
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
index 958b440..f2abcf9 100644
--- a/runtime/oat_file_assistant.h
+++ b/runtime/oat_file_assistant.h
@@ -151,11 +151,12 @@
static std::vector<std::unique_ptr<const DexFile>> LoadDexFiles(
const OatFile& oat_file, const char* dex_location);
- // If the dex file has been pre-compiled on the host, the compiled oat file
- // will have the extension .odex, and is referred to as the odex file.
- // It is called odex for legacy reasons; the file is really an oat file. The
- // odex file will typically have a patch delta of 0 and need to be relocated
- // before use for the purposes of ASLR.
+ // If the dex file has been installed with a compiled oat file alongside
+ // it, the compiled oat file will have the extension .odex, and is referred
+ // to as the odex file. It is called odex for legacy reasons; the file is
+ // really an oat file. The odex file will often, but not always, have a
+ // patch delta of 0 and need to be relocated before use for the purposes of
+ // ASLR. The odex file is treated as if it were read-only.
// These methods return the location and status of the odex file for the dex
// location.
// Notes:
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 41dc2d7..b2798d3 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -44,10 +44,13 @@
scratch_dir_ = android_data_ + "/OatFileAssistantTest";
ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
- // Create a subdirectory in scratch for the current isa.
- // This is the location that will be used for odex files in the tests.
- isa_dir_ = scratch_dir_ + "/" + GetInstructionSetString(kRuntimeISA);
- ASSERT_EQ(0, mkdir(isa_dir_.c_str(), 0700));
+ // Create a subdirectory in scratch for odex files.
+ odex_oat_dir_ = scratch_dir_ + "/oat";
+ ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
+
+ odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
+ ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
+
// Verify the environment is as we expect
uint32_t checksum;
@@ -90,8 +93,11 @@
}
virtual void TearDown() {
- ClearDirectory(isa_dir_.c_str());
- ASSERT_EQ(0, rmdir(isa_dir_.c_str()));
+ ClearDirectory(odex_dir_.c_str());
+ ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
+
+ ClearDirectory(odex_oat_dir_.c_str());
+ ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
ClearDirectory(scratch_dir_.c_str());
ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
@@ -153,10 +159,10 @@
return scratch_dir_;
}
- // ISA directory is the subdirectory in the scratch directory where odex
+ // Odex directory is the subdirectory in the scratch directory where odex
// files should be located.
- std::string GetISADir() {
- return isa_dir_;
+ std::string GetOdexDir() {
+ return odex_dir_;
}
// Generate an odex file for the purposes of test.
@@ -241,7 +247,8 @@
}
std::string scratch_dir_;
- std::string isa_dir_;
+ std::string odex_oat_dir_;
+ std::string odex_dir_;
std::vector<std::unique_ptr<MemMap>> image_reservation_;
};
@@ -340,7 +347,7 @@
// Expect: The oat file status is kUpToDate.
TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
- std::string oat_location = GetISADir() + "/RelativeEncodedDexLocation.oat";
+ std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
// Create the dex file
Copy(GetMultiDexSrc1(), dex_location);
@@ -393,7 +400,7 @@
// Expect: The oat file status is kNeedsRelocation.
TEST_F(OatFileAssistantTest, DexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
- std::string odex_location = GetISADir() + "/DexOdexNoOat.odex";
+ std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
@@ -419,7 +426,7 @@
// Expect: The oat file status is kNeedsRelocation.
TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
- std::string odex_location = GetISADir() + "/StrippedDexOdexNoOat.odex";
+ std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
@@ -468,7 +475,7 @@
// Expect: The oat file status is kNeedsRelocation.
TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
- std::string odex_location = GetISADir() + "/StrippedDexOdexOat.odex";
+ std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
// Create the oat file from a different dex file so it looks out of date.
Copy(GetDexSrc2(), dex_location);
@@ -525,8 +532,8 @@
// Expect: It shouldn't crash.
TEST_F(OatFileAssistantTest, OdexOatOverlap) {
std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
- std::string odex_location = GetISADir() + "/OdexOatOverlap.odex";
- std::string oat_location = GetISADir() + "/OdexOatOverlap.oat";
+ std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
+ std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
@@ -563,7 +570,7 @@
// Expect: The oat file status is kUpToDate, because PIC needs no relocation.
TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
- std::string odex_location = GetISADir() + "/DexPicOdexNoOat.odex";
+ std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
@@ -803,7 +810,7 @@
// avoid using up the virtual memory address space.
TEST_F(OatFileAssistantTest, RaceToGenerate) {
std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
- std::string oat_location = GetISADir() + "/RaceToGenerate.oat";
+ std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
// We use the lib core dex file, because it's large, and hopefully should
// take a while to generate.
@@ -833,7 +840,7 @@
// Expect: We should load the odex file non-executable.
TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
- std::string odex_location = GetISADir() + "/LoadDexOdexNoOat.odex";
+ std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
// Create the dex and odex files
Copy(GetDexSrc1(), dex_location);
@@ -855,7 +862,7 @@
// Expect: We should load the odex file non-executable.
TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
- std::string odex_location = GetISADir() + "/LoadMultiDexOdexNoOat.odex";
+ std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
// Create the dex and odex files
Copy(GetMultiDexSrc1(), dex_location);
@@ -878,11 +885,11 @@
EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
"/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
- EXPECT_EQ("/foo/bar/arm/baz.odex", odex_file);
+ EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
"/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
- EXPECT_EQ("/foo/bar/arm/baz.odex", odex_file);
+ EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
"nopath.jar", kArm, &odex_file, &error_msg));