summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/elf_writer_test.cc2
-rw-r--r--oatdump/oatdump.cc2
-rw-r--r--runtime/class_linker.cc11
-rw-r--r--runtime/elf_file.cc4
-rw-r--r--runtime/elf_file.h5
-rw-r--r--runtime/native/dalvik_system_DexFile.cc4
-rw-r--r--runtime/oat_file.cc30
-rw-r--r--runtime/oat_file.h8
-rw-r--r--runtime/oat_test.cc2
9 files changed, 38 insertions, 30 deletions
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index d4486d2c56..4a02b61242 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -82,7 +82,7 @@ TEST_F(ElfWriterTest, dlsym) {
{
UniquePtr<ElfFile> ef(ElfFile::Open(file.get(), false, true));
CHECK(ef.get() != NULL);
- ef->Load();
+ ef->Load(false);
EXPECT_EQ(dl_oatdata, ef->FindDynamicSymbolAddress("oatdata"));
EXPECT_EQ(dl_oatexec, ef->FindDynamicSymbolAddress("oatexec"));
EXPECT_EQ(dl_oatlastword, ef->FindDynamicSymbolAddress("oatlastword"));
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index f9caa9d127..fd0bf2f405 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1416,7 +1416,7 @@ static int oatdump(int argc, char** argv) {
if (oat_filename != NULL) {
OatFile* oat_file =
- OatFile::Open(oat_filename, oat_filename, NULL);
+ OatFile::Open(oat_filename, oat_filename, NULL, false);
if (oat_file == NULL) {
fprintf(stderr, "Failed to open oat file from %s\n", oat_filename);
return EXIT_FAILURE;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8ea4295702..e35b95c1e9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -692,7 +692,8 @@ OatFile* ClassLinker::OpenOat(const gc::space::ImageSpace* space) {
oat_filename += runtime->GetHostPrefix();
oat_filename += oat_location->ToModifiedUtf8();
runtime->GetHeap()->UnReserveOatFileAddressRange();
- OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatDataBegin());
+ OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatDataBegin(),
+ !Runtime::Current()->IsCompiler());
VLOG(startup) << "ClassLinker::OpenOat entering oat_filename=" << oat_filename;
if (oat_file == NULL) {
LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image.";
@@ -731,7 +732,8 @@ const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const std::string&
const DexFile* ClassLinker::FindDexFileInOatLocation(const std::string& dex_location,
uint32_t dex_location_checksum,
const std::string& oat_location) {
- UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, NULL));
+ UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, NULL,
+ !Runtime::Current()->IsCompiler()));
if (oat_file.get() == NULL) {
return NULL;
}
@@ -787,7 +789,8 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocationLocked(const std::s
LOG(ERROR) << "Failed to generate oat file: " << oat_location;
return NULL;
}
- const OatFile* oat_file = OatFile::Open(oat_location, oat_location, NULL);
+ const OatFile* oat_file = OatFile::Open(oat_location, oat_location, NULL,
+ !Runtime::Current()->IsCompiler());
if (oat_file == NULL) {
LOG(ERROR) << "Failed to open generated oat file: " << oat_location;
return NULL;
@@ -936,7 +939,7 @@ const OatFile* ClassLinker::FindOatFileFromOatLocationLocked(const std::string&
return oat_file;
}
- oat_file = OatFile::Open(oat_location, oat_location, NULL);
+ oat_file = OatFile::Open(oat_location, oat_location, NULL, !Runtime::Current()->IsCompiler());
if (oat_file == NULL) {
return NULL;
}
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index cb4ef81be3..da122e68ee 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -587,7 +587,7 @@ size_t ElfFile::GetLoadedSize() {
return loaded_size;
}
-bool ElfFile::Load() {
+bool ElfFile::Load(bool executable) {
// TODO: actually return false error
CHECK(program_header_only_) << file_->GetPath();
for (llvm::ELF::Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
@@ -630,7 +630,7 @@ bool ElfFile::Load() {
}
byte* p_vaddr = base_address_ + program_header.p_vaddr;
int prot = 0;
- if ((program_header.p_flags & llvm::ELF::PF_X) != 0) {
+ if (executable && ((program_header.p_flags & llvm::ELF::PF_X) != 0)) {
prot |= PROT_EXEC;
}
if ((program_header.p_flags & llvm::ELF::PF_W) != 0) {
diff --git a/runtime/elf_file.h b/runtime/elf_file.h
index 59ce7f5bfd..cb95cb0df0 100644
--- a/runtime/elf_file.h
+++ b/runtime/elf_file.h
@@ -113,8 +113,9 @@ class ElfFile {
// Returns the expected size when the file is loaded at runtime
size_t GetLoadedSize();
- // Load segments into memory based on PT_LOAD program headers
- bool Load();
+ // Load segments into memory based on PT_LOAD program headers.
+ // executable is true at run time, false at compile time.
+ bool Load(bool executable);
private:
ElfFile();
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index b9838f879a..dc3573dfec 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -212,7 +212,7 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename
// Check if we have an odex file next to the dex file.
std::string odex_filename(OatFile::DexFilenameToOdexFilename(filename.c_str()));
- UniquePtr<const OatFile> oat_file(OatFile::Open(odex_filename, odex_filename, NULL));
+ UniquePtr<const OatFile> oat_file(OatFile::Open(odex_filename, odex_filename, NULL, false));
if (oat_file.get() != NULL) {
ScopedObjectAccess soa(env);
const art::OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename.c_str());
@@ -242,7 +242,7 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename
// Check if we have an oat file in the cache
std::string cache_location(GetDalvikCacheFilenameOrDie(filename.c_str()));
- oat_file.reset(OatFile::Open(cache_location, filename.c_str(), NULL));
+ oat_file.reset(OatFile::Open(cache_location, filename.c_str(), NULL, false));
if (oat_file.get() == NULL) {
LOG(INFO) << "DexFile_isDexOptNeeded cache file " << cache_location
<< " does not exist for " << filename.c_str();
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index ebf92a7f64..0f29915a9b 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -59,29 +59,30 @@ OatFile* OatFile::OpenMemory(std::vector<uint8_t>& oat_contents,
OatFile* OatFile::Open(const std::string& filename,
const std::string& location,
- byte* requested_base) {
+ byte* requested_base,
+ bool executable) {
CHECK(!filename.empty()) << location;
CheckLocation(filename);
- OatFile* result = OpenDlopen(filename, location, requested_base);
- if (result != NULL) {
- return result;
- }
- // On target, only used dlopen to load.
- if (kIsTargetBuild) {
- return NULL;
+ // If we are trying to execute, we need to use dlopen.
+ if (executable) {
+ return OpenDlopen(filename, location, requested_base);
}
+ // If we aren't trying to execute, we just use our own ElfFile loader for a couple reasons:
+ //
+ // On target, dlopen may fail when compiling due to selinux restrictions on installd.
+ //
// On host, dlopen is expected to fail when cross compiling, so fall back to OpenElfFile.
// This won't work for portable runtime execution because it doesn't process relocations.
UniquePtr<File> file(OS::OpenFile(filename.c_str(), false, false));
if (file.get() == NULL) {
return NULL;
}
- return OpenElfFile(file.get(), location, requested_base, false);
+ return OpenElfFile(file.get(), location, requested_base, false, executable);
}
OatFile* OatFile::OpenWritable(File* file, const std::string& location) {
CheckLocation(location);
- return OpenElfFile(file, location, NULL, true);
+ return OpenElfFile(file, location, NULL, true, false);
}
OatFile* OatFile::OpenDlopen(const std::string& elf_filename,
@@ -98,9 +99,10 @@ OatFile* OatFile::OpenDlopen(const std::string& elf_filename,
OatFile* OatFile::OpenElfFile(File* file,
const std::string& location,
byte* requested_base,
- bool writable) {
+ bool writable,
+ bool executable) {
UniquePtr<OatFile> oat_file(new OatFile(location));
- bool success = oat_file->ElfFileOpen(file, requested_base, writable);
+ bool success = oat_file->ElfFileOpen(file, requested_base, writable, executable);
if (!success) {
return NULL;
}
@@ -154,13 +156,13 @@ bool OatFile::Dlopen(const std::string& elf_filename, byte* requested_base) {
return Setup();
}
-bool OatFile::ElfFileOpen(File* file, byte* requested_base, bool writable) {
+bool OatFile::ElfFileOpen(File* file, byte* requested_base, bool writable, bool executable) {
elf_file_.reset(ElfFile::Open(file, writable, true));
if (elf_file_.get() == NULL) {
PLOG(WARNING) << "Failed to create ELF file for " << file->GetPath();
return false;
}
- bool loaded = elf_file_->Load();
+ bool loaded = elf_file_->Load(executable);
if (!loaded) {
LOG(WARNING) << "Failed to load ELF file " << file->GetPath();
return false;
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 0bf79a9c03..e3fd0025f0 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -44,7 +44,8 @@ class OatFile {
// optionally be used to request where the file should be loaded.
static OatFile* Open(const std::string& filename,
const std::string& location,
- byte* requested_base);
+ byte* requested_base,
+ bool executable);
// Open an oat file from an already opened File.
// Does not use dlopen underneath so cannot be used for runtime use
@@ -215,11 +216,12 @@ class OatFile {
static OatFile* OpenElfFile(File* file,
const std::string& location,
byte* requested_base,
- bool writable);
+ bool writable,
+ bool executable);
explicit OatFile(const std::string& filename);
bool Dlopen(const std::string& elf_filename, byte* requested_base);
- bool ElfFileOpen(File* file, byte* requested_base, bool writable);
+ bool ElfFileOpen(File* file, byte* requested_base, bool writable, bool executable);
bool Setup();
const byte* Begin() const;
diff --git a/runtime/oat_test.cc b/runtime/oat_test.cc
index f41a7bad95..70c2e9e88e 100644
--- a/runtime/oat_test.cc
+++ b/runtime/oat_test.cc
@@ -102,7 +102,7 @@ TEST_F(OatTest, WriteRead) {
if (compile) { // OatWriter strips the code, regenerate to compare
compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());
}
- UniquePtr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(), tmp.GetFilename(), NULL));
+ UniquePtr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(), tmp.GetFilename(), NULL, false));
ASSERT_TRUE(oat_file.get() != NULL);
const OatHeader& oat_header = oat_file->GetOatHeader();
ASSERT_TRUE(oat_header.IsValid());