In-place load ELF.

Change-Id: I88e1f57349bd3646c349d4c965e6c9b46ed77404
diff --git a/src/compiler_llvm/elf_loader.cc b/src/compiler_llvm/elf_loader.cc
index 07072df..8432a07 100644
--- a/src/compiler_llvm/elf_loader.cc
+++ b/src/compiler_llvm/elf_loader.cc
@@ -47,10 +47,12 @@
 
   if (elf_idx >= executables_.size()) {
     executables_.resize(elf_idx + 1);
+    elf_images_.resize(elf_idx + 1);
   }
 
   RSExecRef executable = rsloaderLoadExecutable(elf_image.begin(),
-                                                elf_image.size());
+                                                elf_image.size(),
+                                                reloc == OatFile::kRelocNone ? 1 : 0);
 
   if (executable == NULL) {
     LOG(WARNING) << "Failed to load ELF"
@@ -66,21 +68,35 @@
       rsloaderDisposeExec(executable);
       return false;
     }
+    relocated = true;
   }
 
   executables_[elf_idx] = executable;
+  elf_images_[elf_idx] = elf_image;
   return true;
 }
 
 
 void ElfLoader::RelocateExecutable() {
+  if (relocated) {
+    return;
+  }
+  LOG(INFO) << "Reload ELF for relocate.";
   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;
+    if (executables_[i] != NULL) {
+      // TODO: After implement in-place linking, we will no longer need to dispose and reload.
+      rsloaderDisposeExec(executables_[i]);
+      executables_[i] = rsloaderLoadExecutable(elf_images_[i].begin(), elf_images_[i].size(), 0);
+      if (executables_[i] == NULL) {
+        LOG(FATAL) << "Failed to reload ELF image " << i;
+      }
+      if (!rsloaderRelocateExecutable(executables_[i],
+                                      art_find_runtime_support_func, NULL)) {
+        LOG(FATAL) << "Failed to relocate ELF image " << i;
+      }
     }
   }
+  relocated = true;
 }
 
 
diff --git a/src/compiler_llvm/elf_loader.h b/src/compiler_llvm/elf_loader.h
index 263a9fa..9e8611c 100644
--- a/src/compiler_llvm/elf_loader.h
+++ b/src/compiler_llvm/elf_loader.h
@@ -30,6 +30,7 @@
 
 class ElfLoader {
  public:
+  ElfLoader() : relocated(false) {}
   ~ElfLoader();
 
   bool LoadElfAt(size_t elf_idx, const ElfImage& elf_image,
@@ -48,6 +49,8 @@
  private:
   const void* GetAddr(size_t elf_idx, const char* sym_name) const;
 
+  bool relocated;
+  std::vector<ElfImage> elf_images_;
   std::vector<RSExecRef> executables_;
 };
 
diff --git a/src/elf_image.h b/src/elf_image.h
index 79bfd90..094467a 100644
--- a/src/elf_image.h
+++ b/src/elf_image.h
@@ -37,6 +37,10 @@
       : begin_(begin), size_(size) {
   }
 
+  // TODO: Remove this after implement in-place linking.
+  ElfImage() : begin_(NULL), size_(0) {
+  }
+
   const byte* begin() const {
     return begin_;
   }