Add ELF loader to OatFile.
Change-Id: I062c3cc78ff9a35d0efcbc9451e7e7ccb055667b
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 344f844..e755cbd 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -645,7 +645,9 @@
std::string oat_filename;
oat_filename += runtime->GetHostPrefix();
oat_filename += oat_location->ToModifiedUtf8();
- OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatBegin());
+ OatFile* oat_file = OatFile::Open(oat_filename, oat_filename,
+ image_header.GetOatBegin(),
+ OatFile::kRelocNone);
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.";
@@ -729,7 +731,8 @@
static const DexFile* 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, OatFile::kRelocAll));
if (oat_file.get() == NULL) {
return NULL;
}
@@ -781,7 +784,8 @@
LOG(ERROR) << "Failed to seek to start of generated oat file: " << oat_location;
return NULL;
}
- const OatFile* oat_file = OatFile::Open(*file.get(), oat_location, NULL);
+ const OatFile* oat_file =
+ OatFile::Open(*file.get(), oat_location, NULL, OatFile::kRelocAll);
if (oat_file == NULL) {
LOG(ERROR) << "Failed to open generated oat file: " << oat_location;
return NULL;
@@ -877,7 +881,8 @@
return oat_file;
}
- oat_file = OatFile::Open(oat_location, oat_location, NULL);
+ oat_file = OatFile::Open(oat_location, oat_location, NULL,
+ OatFile::kRelocAll);
if (oat_file == NULL) {
return NULL;
}
@@ -3513,4 +3518,10 @@
class_roots_->Set(class_root, klass);
}
+void ClassLinker::RelocateExecutable() {
+ for (size_t i = 0; i < oat_files_.size(); ++i) {
+ const_cast<OatFile*>(oat_files_[i])->RelocateExecutable();
+ }
+}
+
} // namespace art
diff --git a/src/class_linker.h b/src/class_linker.h
index 3226a6f..b6727d9 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -290,6 +290,9 @@
// Get the oat code for a method when its class isn't yet initialized
const void* GetOatCodeFor(const Method* method);
+ // Relocate the OatFiles (ELF images)
+ void RelocateExecutable();
+
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
diff --git a/src/common_test.h b/src/common_test.h
index 3d5b53b..a323831 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -204,7 +204,13 @@
reinterpret_cast<uint32_t>(mapping_table),
reinterpret_cast<uint32_t>(vmap_table),
reinterpret_cast<uint32_t>(gc_map),
- reinterpret_cast<uint32_t>(invoke_stub));
+ reinterpret_cast<uint32_t>(invoke_stub)
+#if defined(ART_USE_LLVM_COMPILER)
+ , NULL,
+ -1u,
+ -1u
+#endif
+ );
}
void MakeExecutable(Method* method) {
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 75ced8b..2b18903 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -27,6 +27,7 @@
#include "jni_compiler.h"
#include "method_compiler.h"
#include "oat_compilation_unit.h"
+#include "oat_file.h"
#include "stl_util.h"
#include "upcall_compiler.h"
@@ -203,7 +204,9 @@
compiler_lock_.AssertHeld();
DCHECK(cunit->IsMaterialized()) << cunit->GetElfIndex();
- if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(), cunit->GetElfImage())) {
+ if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(),
+ cunit->GetElfImage(),
+ OatFile::kRelocAll)) {
LOG(ERROR) << "Failed to load ELF from compilation unit "
<< cunit->GetElfIndex();
}
diff --git a/src/compiler_llvm/elf_loader.cc b/src/compiler_llvm/elf_loader.cc
index 60fce0b..adea85d 100644
--- a/src/compiler_llvm/elf_loader.cc
+++ b/src/compiler_llvm/elf_loader.cc
@@ -19,6 +19,7 @@
#include "compiled_method.h"
#include "elf_image.h"
#include "logging.h"
+#include "oat_file.h"
#include "object.h"
#include "runtime_support_llvm.h"
#include "utils_llvm.h"
@@ -37,7 +38,9 @@
}
-bool ElfLoader::LoadElfAt(size_t elf_idx, const ElfImage& elf_image) {
+bool ElfLoader::LoadElfAt(size_t elf_idx,
+ const ElfImage& elf_image,
+ OatFile::RelocationBehavior reloc) {
if (elf_idx < executables_.size() && executables_[elf_idx] != NULL) {
return false;
}
@@ -46,9 +49,8 @@
executables_.resize(elf_idx + 1);
}
- RSExecRef executable =
- rsloaderCreateExec(elf_image.begin(), elf_image.size(),
- art_find_runtime_support_func, NULL);
+ RSExecRef executable = rsloaderLoadExecutable(elf_image.begin(),
+ elf_image.size());
if (executable == NULL) {
LOG(WARNING) << "Failed to load ELF"
@@ -57,11 +59,31 @@
return false;
}
+ if (reloc == OatFile::kRelocAll) {
+ if (!rsloaderRelocateExecutable(executable,
+ art_find_runtime_support_func, NULL)) {
+ LOG(ERROR) << "Failed to relocate the ELF image";
+ rsloaderDisposeExec(executable);
+ return false;
+ }
+ }
+
executables_[elf_idx] = executable;
return true;
}
+void ElfLoader::RelocateExecutable() {
+ for (size_t i = 0; i < executables_.size(); ++i) {
+ if (executables_[i] != NULL &&
+ !rsloaderRelocateExecutable(executables_[i],
+ art_find_runtime_support_func, NULL)) {
+ LOG(FATAL) << "Failed to relocate ELF image " << i;
+ }
+ }
+}
+
+
const void* ElfLoader::GetMethodCodeAddr(size_t elf_idx,
const Method* method) const {
CHECK_LT(elf_idx, executables_.size());
diff --git a/src/compiler_llvm/elf_loader.h b/src/compiler_llvm/elf_loader.h
index 5c8063a..9e8137f 100644
--- a/src/compiler_llvm/elf_loader.h
+++ b/src/compiler_llvm/elf_loader.h
@@ -19,6 +19,7 @@
#include "elf_image.h"
#include "globals.h"
+#include "oat_file.h"
#include "object.h"
#include <android/librsloader.h>
@@ -35,7 +36,10 @@
public:
~ElfLoader();
- bool LoadElfAt(size_t elf_idx, const ElfImage& elf_image);
+ bool LoadElfAt(size_t elf_idx, const ElfImage& elf_image,
+ OatFile::RelocationBehavior reloc);
+
+ void RelocateExecutable();
const void* GetMethodCodeAddr(size_t elf_idx, const Method* method) const;
diff --git a/src/dalvik_system_DexFile.cc b/src/dalvik_system_DexFile.cc
index a4b270d..3ada9f4 100644
--- a/src/dalvik_system_DexFile.cc
+++ b/src/dalvik_system_DexFile.cc
@@ -197,7 +197,8 @@
// A user build looks like this, and it will have no classes.dex in
// the input for checksum validation.
std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str()));
- UniquePtr<const OatFile> oat_file(OatFile::Open(oat_filename, oat_filename, NULL));
+ UniquePtr<const OatFile> oat_file(
+ OatFile::Open(oat_filename, oat_filename, NULL, OatFile::kRelocNone));
if (oat_file.get() != NULL && oat_file->GetOatDexFile(filename.c_str()) != NULL) {
if (debug_logging) {
LOG(INFO) << "DexFile_isDexOptNeeded ignoring precompiled file: " << filename.c_str();
@@ -207,7 +208,8 @@
// Check if we have an oat file in the cache
std::string cache_location(GetArtCacheFilenameOrDie(oat_filename));
- oat_file.reset(OatFile::Open(cache_location, oat_filename, NULL));
+ oat_file.reset(
+ OatFile::Open(cache_location, oat_filename, NULL, OatFile::kRelocNone));
if (oat_file.get() == NULL) {
LOG(INFO) << "DexFile_isDexOptNeeded cache file " << cache_location
<< " does not exist for " << filename.c_str();
diff --git a/src/image_writer.cc b/src/image_writer.cc
index adaeebc..9e01d01 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -32,6 +32,7 @@
#include "image.h"
#include "intern_table.h"
#include "logging.h"
+#include "oat_file.h"
#include "object.h"
#include "object_utils.h"
#include "runtime.h"
@@ -62,7 +63,8 @@
}
}
- oat_file_ = OatFile::Open(oat_filename, oat_location, NULL, true);
+ oat_file_ = OatFile::Open(oat_filename, oat_location, NULL,
+ OatFile::kRelocNone, true);
if (oat_file_ == NULL) {
LOG(ERROR) << "Failed to open oat file " << oat_filename;
return false;
diff --git a/src/oat_file.cc b/src/oat_file.cc
index a8b89a9..97d8f64 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -22,6 +22,10 @@
#include "os.h"
#include "stl_util.h"
+#if defined(ART_USE_LLVM_COMPILER)
+#include "compiler_llvm/elf_loader.h"
+#endif
+
namespace art {
std::string OatFile::DexFilenameToOatFilename(const std::string& location) {
@@ -34,41 +38,57 @@
OatFile* OatFile::Open(const std::string& filename,
const std::string& location,
byte* requested_base,
+ RelocationBehavior reloc,
bool writable) {
CHECK(!filename.empty()) << location;
UniquePtr<File> file(OS::OpenFile(filename.c_str(), writable, false));
if (file.get() == NULL) {
return NULL;
}
- return Open(*file.get(), location, requested_base, writable);
+ return Open(*file.get(), location, requested_base, reloc, writable);
}
OatFile* OatFile::Open(File& file,
const std::string& location,
byte* requested_base,
+ RelocationBehavior reloc,
bool writable) {
CHECK(!location.empty());
if (!IsValidOatFilename(location)) {
LOG(WARNING) << "Attempting to open dex file with unknown extension '" << location << "'";
}
UniquePtr<OatFile> oat_file(new OatFile(location));
- bool success = oat_file->Map(file, requested_base, writable);
+ bool success = oat_file->Map(file, requested_base, reloc, writable);
if (!success) {
return NULL;
}
return oat_file.release();
}
-OatFile::OatFile(const std::string& location) : location_(location) {
+OatFile::OatFile(const std::string& location)
+ : location_(location)
+#if defined(ART_USE_LLVM_COMPILER)
+ , elf_loader_(new compiler_llvm::ElfLoader())
+#endif
+{
CHECK(!location_.empty());
}
OatFile::~OatFile() {
STLDeleteValues(&oat_dex_files_);
+#if defined(ART_USE_LLVM_COMPILER)
STLDeleteElements(&oat_elf_images_);
+#endif
}
-bool OatFile::Map(File& file, byte* requested_base, bool writable) {
+bool OatFile::Map(File& file,
+ byte* requested_base,
+#if defined(ART_USE_LLVM_COMPILER)
+ RelocationBehavior reloc,
+#else
+ RelocationBehavior /*UNUSED*/,
+#endif
+ bool writable) {
OatHeader oat_header;
bool success = file.ReadFully(&oat_header, sizeof(oat_header));
if (!success || !oat_header.IsValid()) {
@@ -164,6 +184,11 @@
methods_offsets_pointer);
}
+#if !defined(ART_USE_LLVM_COMPILER)
+ CHECK_EQ(oat_header.GetElfImageTableOffset(), 0u);
+ CHECK_EQ(oat_header.GetElfImageCount(), 0u);
+
+#else
oat = map->Begin() + oat_header.GetElfImageTableOffset();
CHECK((reinterpret_cast<uintptr_t>(oat) & 0x3) == 0);
@@ -174,9 +199,15 @@
uint32_t elf_size = *reinterpret_cast<const uint32_t*>(oat);
oat += sizeof(uint32_t);
- oat_elf_images_.push_back(
- new OatElfImage(this, map->Begin() + elf_offset, elf_size));
+ const byte* elf_begin = map->Begin() + elf_offset;
+
+ oat_elf_images_.push_back(new OatElfImage(this, elf_begin, elf_size));
+
+ if (!elf_loader_->LoadElfAt(i, ElfImage(elf_begin, elf_size), reloc)) {
+ LOG(ERROR) << "Failed to load ELF image. index: " << i;
+ }
}
+#endif
mem_map_.reset(map.release());
return true;
@@ -216,6 +247,12 @@
return result;
}
+void OatFile::RelocateExecutable() {
+#if defined(ART_USE_LLVM_COMPILER)
+ elf_loader_->RelocateExecutable();
+#endif
+}
+
OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
const std::string& dex_file_location,
uint32_t dex_file_location_checksum,
@@ -271,7 +308,13 @@
oat_method_offsets.mapping_table_offset_,
oat_method_offsets.vmap_table_offset_,
oat_method_offsets.gc_map_offset_,
- oat_method_offsets.invoke_stub_offset_);
+ oat_method_offsets.invoke_stub_offset_
+#if defined(ART_USE_LLVM_COMPILER)
+ , oat_file_->elf_loader_.get(),
+ oat_method_offsets.code_elf_idx_,
+ oat_method_offsets.invoke_stub_elf_idx_
+#endif
+ );
}
OatFile::OatMethod::OatMethod(const byte* base,
@@ -282,7 +325,13 @@
const uint32_t mapping_table_offset,
const uint32_t vmap_table_offset,
const uint32_t gc_map_offset,
- const uint32_t invoke_stub_offset)
+ const uint32_t invoke_stub_offset
+#if defined(ART_USE_LLVM_COMPILER)
+ , const compiler_llvm::ElfLoader* elf_loader,
+ const uint32_t code_elf_idx,
+ const uint32_t invoke_stub_elf_idx
+#endif
+ )
: begin_(base),
code_offset_(code_offset),
frame_size_in_bytes_(frame_size_in_bytes),
@@ -291,7 +340,13 @@
mapping_table_offset_(mapping_table_offset),
vmap_table_offset_(vmap_table_offset),
gc_map_offset_(gc_map_offset),
- invoke_stub_offset_(invoke_stub_offset) {
+ invoke_stub_offset_(invoke_stub_offset)
+#if defined(ART_USE_LLVM_COMPILER)
+ , elf_loader_(elf_loader),
+ code_elf_idx_(code_elf_idx),
+ invoke_stub_elf_idx_(invoke_stub_elf_idx)
+#endif
+{
#ifndef NDEBUG
if (mapping_table_offset_ != 0) { // implies non-native, non-stub code
if (vmap_table_offset_ == 0) {
@@ -308,6 +363,68 @@
OatFile::OatMethod::~OatMethod() {}
+
+const void* OatFile::OatMethod::GetCode() const {
+ if (!IsCodeInElf()) {
+ return GetOatPointer<const void*>(code_offset_);
+ } else {
+#if !defined(ART_USE_LLVM_COMPILER)
+ UNIMPLEMENTED(FATAL);
+ return NULL;
+#else
+ CHECK(elf_loader_ != NULL);
+ const void* code = elf_loader_->GetMethodCodeAddr(code_elf_idx_, method);
+ CHECK(code != NULL);
+ return code;
+#endif
+ }
+}
+
+uint32_t OatFile::OatMethod::GetCodeSize() const {
+ if (!IsCodeInElf()) {
+ uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
+
+ if (code == 0) {
+ return 0;
+ }
+ // TODO: make this Thumb2 specific
+ code &= ~0x1;
+ return reinterpret_cast<uint32_t*>(code)[-1];
+ } else {
+ UNIMPLEMENTED(ERROR);
+ return 0;
+ }
+}
+
+const Method::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
+ if (!IsInvokeStubInElf()) {
+ return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_);
+ } else {
+#if !defined(ART_USE_LLVM_COMPILER)
+ UNIMPLEMENTED(FATAL);
+ return NULL;
+#else
+ CHECK(elf_loader_ != NULL);
+ const Method::InvokeStub* stub = elf_loader_->GetMethodInvokeStubAddr(invoke_stub_elf_idx_, method);
+ CHECK(stub != NULL);
+ return stub;
+#endif
+ }
+}
+
+uint32_t OatFile::OatMethod::GetInvokeStubSize() const {
+ if (!IsInvokeStubInElf()) {
+ uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
+ if (code == 0) {
+ return 0;
+ }
+ return reinterpret_cast<uint32_t*>(code)[-1];
+ } else {
+ UNIMPLEMENTED(ERROR);
+ return 0;
+ }
+}
+
void OatFile::OatMethod::LinkMethodPointers(Method* method) const {
CHECK(method != NULL);
method->SetCode(GetCode());
diff --git a/src/oat_file.h b/src/oat_file.h
index 281ef78..07d7f63 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -20,14 +20,27 @@
#include <vector>
#include "dex_file.h"
+#include "invoke_type.h"
#include "mem_map.h"
#include "oat.h"
#include "object.h"
+#if defined(ART_USE_LLVM_COMPILER)
+namespace art {
+ namespace compiler_llvm {
+ class ElfLoader;
+ }
+}
+#endif
+
namespace art {
class OatFile {
public:
+ enum RelocationBehavior {
+ kRelocNone,
+ kRelocAll,
+ };
// Returns an OatFile name based on a DexFile location
static std::string DexFilenameToOatFilename(const std::string& location);
@@ -37,12 +50,14 @@
static OatFile* Open(const std::string& filename,
const std::string& location,
byte* requested_base,
+ RelocationBehavior reloc,
bool writable = false);
// Open an oat file from an already opened File with the given location.
static OatFile* Open(File& file,
const std::string& location,
byte* requested_base,
+ RelocationBehavior reloc,
bool writable = false);
~OatFile();
@@ -88,18 +103,34 @@
return invoke_stub_offset_;
}
- const void* GetCode() const {
- return GetOatPointer<const void*>(code_offset_);
+#if defined(ART_USE_LLVM_COMPILER)
+ uint32_t GetCodeElfIndex() const {
+ return code_elf_idx_;
}
- uint32_t GetCodeSize() const {
- uintptr_t code = reinterpret_cast<uint32_t>(GetCode());
- if (code == 0) {
- return 0;
- }
- // TODO: make this Thumb2 specific
- code &= ~0x1;
- return reinterpret_cast<uint32_t*>(code)[-1];
+ uint32_t GetInvokeStubElfIndex() const {
+ return invoke_stub_elf_idx_;
}
+#endif
+
+ bool IsCodeInElf() const {
+#if defined(ART_USE_LLVM_COMPILER)
+ return (code_elf_idx_ != -1u);
+#else
+ return false;
+#endif
+ }
+
+ bool IsInvokeStubInElf() const {
+#if defined(ART_USE_LLVM_COMPILER)
+ return (invoke_stub_elf_idx_ != -1u);
+#else
+ return false;
+#endif
+ }
+
+ const void* GetCode() const;
+ uint32_t GetCodeSize() const;
+
const uint32_t* GetMappingTable() const {
return GetOatPointer<const uint32_t*>(mapping_table_offset_);
}
@@ -109,16 +140,9 @@
const uint8_t* GetGcMap() const {
return GetOatPointer<const uint8_t*>(gc_map_offset_);
}
- const Method::InvokeStub* GetInvokeStub() const {
- return GetOatPointer<const Method::InvokeStub*>(invoke_stub_offset_);
- }
- uint32_t GetInvokeStubSize() const {
- uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub());
- if (code == 0) {
- return 0;
- }
- return reinterpret_cast<uint32_t*>(code)[-1];
- }
+
+ const Method::InvokeStub* GetInvokeStub() const;
+ uint32_t GetInvokeStubSize() const;
~OatMethod();
@@ -131,7 +155,13 @@
const uint32_t mapping_table_offset,
const uint32_t vmap_table_offset,
const uint32_t gc_map_offset,
- const uint32_t invoke_stub_offset);
+ const uint32_t invoke_stub_offset
+#if defined(ART_USE_LLVM_COMPILER)
+ , const compiler_llvm::ElfLoader* elf_loader,
+ const uint32_t code_elf_idx,
+ const uint32_t invoke_stub_elf_idx
+#endif
+ );
private:
template<class T>
@@ -153,6 +183,13 @@
uint32_t gc_map_offset_;
uint32_t invoke_stub_offset_;
+#if defined(ART_USE_LLVM_COMPILER)
+ const compiler_llvm::ElfLoader* elf_loader_;
+
+ uint32_t code_elf_idx_;
+ uint32_t invoke_stub_elf_idx_;
+#endif
+
friend class OatClass;
};
@@ -239,17 +276,21 @@
bool warn_if_not_found = true) const;
std::vector<const OatDexFile*> GetOatDexFiles() const;
+#if defined(ART_USE_LLVM_COMPILER)
const OatElfImage* GetOatElfImage(size_t i) const {
return oat_elf_images_[i];
}
+#endif
size_t Size() const {
return End() - Begin();
}
+ void RelocateExecutable();
+
private:
explicit OatFile(const std::string& filename);
- bool Map(File& file, byte* requested_base, bool writable);
+ bool Map(File& file, byte* requested_base, RelocationBehavior reloc, bool writable);
const byte* Begin() const;
const byte* End() const;
@@ -265,7 +306,10 @@
typedef std::map<std::string, const OatDexFile*> Table;
Table oat_dex_files_;
+#if defined(ART_USE_LLVM_COMPILER)
std::vector<OatElfImage*> oat_elf_images_;
+ UniquePtr<compiler_llvm::ElfLoader> elf_loader_;
+#endif
friend class OatClass;
friend class OatDexFile;
diff --git a/src/oat_test.cc b/src/oat_test.cc
index d50183c..3e92a15 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -80,7 +80,10 @@
if (compile) { // OatWriter strips the code, regenerate to compare
compiler_->CompileAll(class_loader.get(), 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,
+ OatFile::kRelocNone));
ASSERT_TRUE(oat_file.get() != NULL);
const OatHeader& oat_header = oat_file->GetOatHeader();
ASSERT_EQ(1U, oat_header.GetDexFileCount());
diff --git a/src/oatdump.cc b/src/oatdump.cc
index aa63ef5..978060d 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -1257,7 +1257,8 @@
}
if (oat_filename != NULL) {
- OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, NULL);
+ OatFile* oat_file =
+ OatFile::Open(oat_filename, oat_filename, NULL, OatFile::kRelocNone);
if (oat_file == NULL) {
fprintf(stderr, "Failed to open oat file from %s\n", oat_filename);
return EXIT_FAILURE;
@@ -1265,6 +1266,7 @@
OatDumper oat_dumper(*host_prefix.get(), *oat_file);
oat_dumper.Dump(*os);
+#if defined(ART_USE_LLVM_COMPILER)
if (!elf_filename_prefix.empty()) {
uint32_t elf_image_count = oat_file->GetOatHeader().GetElfImageCount();
for (uint32_t i = 0; i < elf_image_count; ++i) {
@@ -1281,6 +1283,7 @@
}
}
}
+#endif
return EXIT_SUCCESS;
}
diff --git a/src/runtime.cc b/src/runtime.cc
index c013726..1d0ab8f 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -529,6 +529,9 @@
CHECK(host_prefix_.empty()) << host_prefix_;
+ // Relocate the OatFiles (ELF images)
+ class_linker_->RelocateExecutable();
+
// Restore main thread state to kNative as expected by native code
Thread::Current()->SetState(Thread::kNative);