Add ELF loader to OatFile.

Change-Id: I062c3cc78ff9a35d0efcbc9451e7e7ccb055667b
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;