Merge "Switch over to the google3 unix_file File*." into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 97b25ba..a81914e 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -703,9 +703,7 @@
   oat_filename += runtime->GetHostPrefix();
   oat_filename += oat_location->ToModifiedUtf8();
   runtime->GetHeap()->UnReserveOatFileAddressRange();
-  OatFile* oat_file = OatFile::Open(oat_filename, oat_filename,
-                                    image_header.GetOatBegin(),
-                                    OatFile::kRelocNone);
+  OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatBegin());
   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.";
@@ -744,8 +742,7 @@
 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, OatFile::kRelocAll));
+  UniquePtr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, NULL));
   if (oat_file.get() == NULL) {
     return NULL;
   }
@@ -806,8 +803,7 @@
     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, OatFile::kRelocAll);
+  const OatFile* oat_file = OatFile::Open(*file.get(), oat_location, NULL);
   if (oat_file == NULL) {
     LOG(ERROR) << "Failed to open generated oat file: " << oat_location;
     return NULL;
@@ -956,8 +952,7 @@
     return oat_file;
   }
 
-  oat_file = OatFile::Open(oat_location, oat_location, NULL,
-                           OatFile::kRelocAll);
+  oat_file = OatFile::Open(oat_location, oat_location, NULL);
   if (oat_file == NULL) {
     return NULL;
   }
@@ -3877,11 +3872,4 @@
   class_roots_->Set(class_root, klass);
 }
 
-void ClassLinker::RelocateExecutable() {
-  MutexLock mu(Thread::Current(), dex_lock_);
-  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 e85a7f9..cf93b8b 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -375,9 +375,6 @@
   // Get the oat code for a method from a method index.
   const void* GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx);
 
-  // Relocate the OatFiles (ELF images)
-  void RelocateExecutable() LOCKS_EXCLUDED(dex_lock_);
-
   pid_t GetClassesLockOwner(); // For SignalCatcher.
   pid_t GetDexLockOwner(); // For SignalCatcher.
 
diff --git a/src/debugger.cc b/src/debugger.cc
index 87e9c72..5a9faa6 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -177,13 +177,13 @@
 static size_t gAllocRecordCount GUARDED_BY(gAllocTrackerLock) = 0;
 
 // Breakpoints and single-stepping.
-static Mutex gBreakpointsLock DEFAULT_MUTEX_ACQUIRED_AFTER ("breakpoints lock");
-static std::vector<Breakpoint> gBreakpoints GUARDED_BY(gBreakpointsLock);
-static SingleStepControl gSingleStepControl GUARDED_BY(gBreakpointsLock);
+static std::vector<Breakpoint> gBreakpoints GUARDED_BY(Locks::breakpoint_lock_);
+static SingleStepControl gSingleStepControl GUARDED_BY(Locks::breakpoint_lock_);
 
 static bool IsBreakpoint(AbstractMethod* m, uint32_t dex_pc)
+    LOCKS_EXCLUDED(Locks::breakpoint_lock_)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  MutexLock mu(Thread::Current(), gBreakpointsLock);
+  MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
   for (size_t i = 0; i < gBreakpoints.size(); ++i) {
     if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == dex_pc) {
       VLOG(jdwp) << "Hit breakpoint #" << i << ": " << gBreakpoints[i];
@@ -508,7 +508,7 @@
 
   {
     // TODO: dalvik only warned if there were breakpoints left over. clear in Dbg::Disconnected?
-    MutexLock mu(Thread::Current(), gBreakpointsLock);
+    MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
     CHECK_EQ(gBreakpoints.size(), 0U);
   }
 
@@ -1572,7 +1572,7 @@
 
   if (kIsDebugBuild) {
     MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);
-    CHECK(thread->IsSuspended());
+    CHECK(thread == Thread::Current() || thread->IsSuspended());
   }
   CountStackDepthVisitor visitor(thread->GetManagedStack(), thread->GetInstrumentationStack());
   visitor.WalkStack();
@@ -2065,63 +2065,63 @@
     event_flags |= kBreakpoint;
   }
 
-  // If the debugger is single-stepping one of our threads, check to
-  // see if we're that thread and we've reached a step point.
-  MutexLock mu(Thread::Current(), gBreakpointsLock);
-  if (gSingleStepControl.is_active && gSingleStepControl.thread == self) {
-    CHECK(!m->IsNative());
-    if (gSingleStepControl.step_depth == JDWP::SD_INTO) {
-      // Step into method calls.  We break when the line number
-      // or method pointer changes.  If we're in SS_MIN mode, we
-      // always stop.
-      if (gSingleStepControl.method != m) {
-        event_flags |= kSingleStep;
-        VLOG(jdwp) << "SS new method";
-      } else if (gSingleStepControl.step_size == JDWP::SS_MIN) {
-        event_flags |= kSingleStep;
-        VLOG(jdwp) << "SS new instruction";
-      } else if (gSingleStepControl.dex_pcs.find(dex_pc) == gSingleStepControl.dex_pcs.end()) {
-        event_flags |= kSingleStep;
-        VLOG(jdwp) << "SS new line";
-      }
-    } else if (gSingleStepControl.step_depth == JDWP::SD_OVER) {
-      // Step over method calls.  We break when the line number is
-      // different and the frame depth is <= the original frame
-      // depth.  (We can't just compare on the method, because we
-      // might get unrolled past it by an exception, and it's tricky
-      // to identify recursion.)
-
-      // TODO: can we just use the value of 'sp'?
-      int stack_depth = GetStackDepth(self);
-
-      if (stack_depth < gSingleStepControl.stack_depth) {
-        // popped up one or more frames, always trigger
-        event_flags |= kSingleStep;
-        VLOG(jdwp) << "SS method pop";
-      } else if (stack_depth == gSingleStepControl.stack_depth) {
-        // same depth, see if we moved
-        if (gSingleStepControl.step_size == JDWP::SS_MIN) {
+  {
+    // If the debugger is single-stepping one of our threads, check to
+    // see if we're that thread and we've reached a step point.
+    MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
+    if (gSingleStepControl.is_active && gSingleStepControl.thread == self) {
+      CHECK(!m->IsNative());
+      if (gSingleStepControl.step_depth == JDWP::SD_INTO) {
+        // Step into method calls.  We break when the line number
+        // or method pointer changes.  If we're in SS_MIN mode, we
+        // always stop.
+        if (gSingleStepControl.method != m) {
+          event_flags |= kSingleStep;
+          VLOG(jdwp) << "SS new method";
+        } else if (gSingleStepControl.step_size == JDWP::SS_MIN) {
           event_flags |= kSingleStep;
           VLOG(jdwp) << "SS new instruction";
         } else if (gSingleStepControl.dex_pcs.find(dex_pc) == gSingleStepControl.dex_pcs.end()) {
           event_flags |= kSingleStep;
           VLOG(jdwp) << "SS new line";
         }
-      }
-    } else {
-      CHECK_EQ(gSingleStepControl.step_depth, JDWP::SD_OUT);
-      // Return from the current method.  We break when the frame
-      // depth pops up.
+      } else if (gSingleStepControl.step_depth == JDWP::SD_OVER) {
+        // Step over method calls.  We break when the line number is
+        // different and the frame depth is <= the original frame
+        // depth.  (We can't just compare on the method, because we
+        // might get unrolled past it by an exception, and it's tricky
+        // to identify recursion.)
 
-      // This differs from the "method exit" break in that it stops
-      // with the PC at the next instruction in the returned-to
-      // function, rather than the end of the returning function.
+        int stack_depth = GetStackDepth(self);
 
-      // TODO: can we just use the value of 'sp'?
-      int stack_depth = GetStackDepth(self);
-      if (stack_depth < gSingleStepControl.stack_depth) {
-        event_flags |= kSingleStep;
-        VLOG(jdwp) << "SS method pop";
+        if (stack_depth < gSingleStepControl.stack_depth) {
+          // popped up one or more frames, always trigger
+          event_flags |= kSingleStep;
+          VLOG(jdwp) << "SS method pop";
+        } else if (stack_depth == gSingleStepControl.stack_depth) {
+          // same depth, see if we moved
+          if (gSingleStepControl.step_size == JDWP::SS_MIN) {
+            event_flags |= kSingleStep;
+            VLOG(jdwp) << "SS new instruction";
+          } else if (gSingleStepControl.dex_pcs.find(dex_pc) == gSingleStepControl.dex_pcs.end()) {
+            event_flags |= kSingleStep;
+            VLOG(jdwp) << "SS new line";
+          }
+        }
+      } else {
+        CHECK_EQ(gSingleStepControl.step_depth, JDWP::SD_OUT);
+        // Return from the current method.  We break when the frame
+        // depth pops up.
+
+        // This differs from the "method exit" break in that it stops
+        // with the PC at the next instruction in the returned-to
+        // function, rather than the end of the returning function.
+
+        int stack_depth = GetStackDepth(self);
+        if (stack_depth < gSingleStepControl.stack_depth) {
+          event_flags |= kSingleStep;
+          VLOG(jdwp) << "SS method pop";
+        }
       }
     }
   }
@@ -2151,14 +2151,14 @@
 }
 
 void Dbg::WatchLocation(const JDWP::JdwpLocation* location) {
-  MutexLock mu(Thread::Current(), gBreakpointsLock);
+  MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
   AbstractMethod* m = FromMethodId(location->method_id);
   gBreakpoints.push_back(Breakpoint(m, location->dex_pc));
   VLOG(jdwp) << "Set breakpoint #" << (gBreakpoints.size() - 1) << ": " << gBreakpoints[gBreakpoints.size() - 1];
 }
 
 void Dbg::UnwatchLocation(const JDWP::JdwpLocation* location) {
-  MutexLock mu(Thread::Current(), gBreakpointsLock);
+  MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
   AbstractMethod* m = FromMethodId(location->method_id);
   for (size_t i = 0; i < gBreakpoints.size(); ++i) {
     if (gBreakpoints[i].method == m && gBreakpoints[i].dex_pc == location->dex_pc) {
@@ -2178,7 +2178,7 @@
     return JDWP::ERR_INVALID_THREAD;
   }
 
-  MutexLock mu2(soa.Self(), gBreakpointsLock);
+  MutexLock mu2(soa.Self(), *Locks::breakpoint_lock_);
   // TODO: there's no theoretical reason why we couldn't support single-stepping
   // of multiple threads at once, but we never did so historically.
   if (gSingleStepControl.thread != NULL && thread != gSingleStepControl.thread) {
@@ -2194,10 +2194,9 @@
   struct SingleStepStackVisitor : public StackVisitor {
     SingleStepStackVisitor(const ManagedStack* stack,
                            const std::vector<InstrumentationStackFrame>* instrumentation_stack)
-        EXCLUSIVE_LOCKS_REQUIRED(gBreakpointsLock)
+        EXCLUSIVE_LOCKS_REQUIRED(Locks::breakpoint_lock_)
         SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
         : StackVisitor(stack, instrumentation_stack, NULL) {
-      gBreakpointsLock.AssertHeld(Thread::Current());
       gSingleStepControl.method = NULL;
       gSingleStepControl.stack_depth = 0;
     }
@@ -2205,7 +2204,7 @@
     // TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
     // annotalysis.
     bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
-      gBreakpointsLock.AssertHeld(Thread::Current());
+      Locks::breakpoint_lock_->AssertHeld(Thread::Current());
       const AbstractMethod* m = GetMethod();
       if (!m->IsRuntimeMethod()) {
         ++gSingleStepControl.stack_depth;
@@ -2230,13 +2229,15 @@
   //
 
   struct DebugCallbackContext {
-    DebugCallbackContext() {
+    DebugCallbackContext() EXCLUSIVE_LOCKS_REQUIRED(Locks::breakpoint_lock_) {
       last_pc_valid = false;
       last_pc = 0;
     }
 
-    static bool Callback(void* raw_context, uint32_t address, uint32_t line_number) {
-      MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
+    // TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
+    // annotalysis.
+    static bool Callback(void* raw_context, uint32_t address, uint32_t line_number) NO_THREAD_SAFETY_ANALYSIS {
+      Locks::breakpoint_lock_->AssertHeld(Thread::Current());
       DebugCallbackContext* context = reinterpret_cast<DebugCallbackContext*>(raw_context);
       if (static_cast<int32_t>(line_number) == gSingleStepControl.line_number) {
         if (!context->last_pc_valid) {
@@ -2256,8 +2257,10 @@
       return false; // There may be multiple entries for any given line.
     }
 
-    ~DebugCallbackContext() {
-      MutexLock mu(Thread::Current(), gBreakpointsLock); // Keep GCC happy.
+    // TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
+    // annotalysis.
+    ~DebugCallbackContext() NO_THREAD_SAFETY_ANALYSIS {
+      Locks::breakpoint_lock_->AssertHeld(Thread::Current());
       // If the line number was the last in the position table...
       if (last_pc_valid) {
         size_t end = MethodHelper(gSingleStepControl.method).GetCodeItem()->insns_size_in_code_units_;
@@ -2307,7 +2310,7 @@
 }
 
 void Dbg::UnconfigureStep(JDWP::ObjectId /*threadId*/) {
-  MutexLock mu(Thread::Current(), gBreakpointsLock);
+  MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
 
   gSingleStepControl.is_active = false;
   gSingleStepControl.thread = NULL;
diff --git a/src/debugger.h b/src/debugger.h
index f9d00d1..d7d2800 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -94,7 +94,7 @@
    * when the debugger attaches.
    */
   static void Connected();
-  static void GoActive();
+  static void GoActive() LOCKS_EXCLUDED(Locks::breakpoint_lock_);
   static void Disconnected();
   static void Disposed();
 
@@ -295,17 +295,20 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static void UpdateDebugger(int32_t dex_pc, Thread* self)
+      LOCKS_EXCLUDED(Locks::breakpoint_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static void WatchLocation(const JDWP::JdwpLocation* pLoc)
+      LOCKS_EXCLUDED(Locks::breakpoint_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static void UnwatchLocation(const JDWP::JdwpLocation* pLoc)
+      LOCKS_EXCLUDED(Locks::breakpoint_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static JDWP::JdwpError ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size,
                                        JDWP::JdwpStepDepth depth)
-      LOCKS_EXCLUDED(gBreakpointsLock)
+      LOCKS_EXCLUDED(Locks::breakpoint_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static void UnconfigureStep(JDWP::ObjectId threadId);
+  static void UnconfigureStep(JDWP::ObjectId threadId) LOCKS_EXCLUDED(Locks::breakpoint_lock_);
 
   static JDWP::JdwpError InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId,
                                       JDWP::RefTypeId classId, JDWP::MethodId methodId,
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 6065760..877d5de 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -64,8 +64,7 @@
     dex_caches_.insert(dex_cache);
   }
 
-  oat_file_ = OatFile::Open(oat_filename, oat_location, NULL,
-                            OatFile::kRelocNone, true);
+  oat_file_ = OatFile::Open(oat_filename, oat_location, NULL, true);
   if (oat_file_ == NULL) {
     LOG(ERROR) << "Failed to open oat file " << oat_filename;
     return false;
diff --git a/src/locks.cc b/src/locks.cc
index 312b021..0422aff 100644
--- a/src/locks.cc
+++ b/src/locks.cc
@@ -21,6 +21,7 @@
 namespace art {
 
 Mutex* Locks::abort_lock_ = NULL;
+Mutex* Locks::breakpoint_lock_ = NULL;
 Mutex* Locks::classlinker_classes_lock_ = NULL;
 ReaderWriterMutex* Locks::heap_bitmap_lock_ = NULL;
 Mutex* Locks::logging_lock_ = NULL;
@@ -34,6 +35,7 @@
   if (logging_lock_ != NULL) {
     // Already initialized.
     DCHECK(abort_lock_ != NULL);
+    DCHECK(breakpoint_lock_ != NULL);
     DCHECK(classlinker_classes_lock_ != NULL);
     DCHECK(heap_bitmap_lock_ != NULL);
     DCHECK(logging_lock_ != NULL);
@@ -45,6 +47,8 @@
     logging_lock_ = new Mutex("logging lock", kLoggingLock, true);
     abort_lock_ = new Mutex("abort lock", kAbortLock, true);
 
+    DCHECK(breakpoint_lock_ == NULL);
+    breakpoint_lock_ = new Mutex("breakpoint lock", kBreakpointLock);
     DCHECK(classlinker_classes_lock_ == NULL);
     classlinker_classes_lock_ = new Mutex("ClassLinker classes lock", kClassLinkerClassesLock);
     DCHECK(heap_bitmap_lock_ == NULL);
diff --git a/src/locks.h b/src/locks.h
index 6f8400d..aacd6c6 100644
--- a/src/locks.h
+++ b/src/locks.h
@@ -40,16 +40,17 @@
   kAllocSpaceLock = 5,
   kLoadLibraryLock = 6,
   kClassLinkerClassesLock = 7,
-  kThreadListLock = 8,
-  kJdwpEventListLock = 9,
-  kJdwpAttachLock = 10,
-  kJdwpStartLock = 11,
-  kJdwpSerialLock = 12,
-  kRuntimeShutdownLock = 13,
-  kHeapBitmapLock = 14,
-  kMonitorLock = 15,
-  kMutatorLock = 16,
-  kZygoteCreationLock = 17,
+  kBreakpointLock = 8,
+  kThreadListLock = 9,
+  kJdwpEventListLock = 10,
+  kJdwpAttachLock = 11,
+  kJdwpStartLock = 12,
+  kJdwpSerialLock = 13,
+  kRuntimeShutdownLock = 14,
+  kHeapBitmapLock = 15,
+  kMonitorLock = 16,
+  kMutatorLock = 17,
+  kZygoteCreationLock = 18,
   kMaxMutexLevel = kZygoteCreationLock,
 };
 std::ostream& operator<<(std::ostream& os, const LockLevel& rhs);
@@ -129,8 +130,11 @@
   // attaching and detaching.
   static Mutex* thread_list_lock_ ACQUIRED_AFTER(runtime_shutdown_lock_);
 
+  // Guards breakpoints and single-stepping.
+  static Mutex* breakpoint_lock_ ACQUIRED_AFTER(thread_list_lock_);
+
   // Guards lists of classes within the class linker.
-  static Mutex* classlinker_classes_lock_ ACQUIRED_AFTER(thread_list_lock_);
+  static Mutex* classlinker_classes_lock_ ACQUIRED_AFTER(breakpoint_lock_);
 
   // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code
   // doesn't try to hold a higher level Mutex.
diff --git a/src/native/dalvik_system_DexFile.cc b/src/native/dalvik_system_DexFile.cc
index a55d7f1..fca9bf7 100644
--- a/src/native/dalvik_system_DexFile.cc
+++ b/src/native/dalvik_system_DexFile.cc
@@ -206,8 +206,7 @@
 
   // Check if we have an oat file next to the dex file.
   std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str()));
-  UniquePtr<const OatFile> oat_file(
-      OatFile::Open(oat_filename, oat_filename, NULL, OatFile::kRelocNone));
+  UniquePtr<const OatFile> oat_file(OatFile::Open(oat_filename, oat_filename, NULL));
   if (oat_file.get() != NULL && oat_file->GetOatDexFile(filename.c_str()) != NULL) {
     uint32_t location_checksum;
     // If we have no classes.dex checksum such as in a user build, assume up-to-date.
@@ -229,8 +228,7 @@
 
   // 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, OatFile::kRelocNone));
+  oat_file.reset(OatFile::Open(cache_location, oat_filename, NULL));
   if (oat_file.get() == NULL) {
     LOG(INFO) << "DexFile_isDexOptNeeded cache file " << cache_location
               << " does not exist for " << filename.c_str();
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 04ee545..d3e1079 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -32,27 +32,25 @@
 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, reloc, writable);
+  return Open(*file.get(), location, requested_base, 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 oat file with unknown extension '" << location << "'";
   }
   UniquePtr<OatFile> oat_file(new OatFile(location));
-  bool success = oat_file->Map(file, requested_base, reloc, writable);
+  bool success = oat_file->Map(file, requested_base, writable);
   if (!success) {
     return NULL;
   }
@@ -70,7 +68,6 @@
 
 bool OatFile::Map(File& file,
                   byte* requested_base,
-                  RelocationBehavior /*UNUSED*/,
                   bool writable) {
   OatHeader oat_header;
   bool success = file.ReadFully(&oat_header, sizeof(oat_header));
@@ -211,12 +208,6 @@
   return result;
 }
 
-void OatFile::RelocateExecutable() {
-#if defined(ART_USE_LLVM_COMPILER)
-  UNIMPLEMENTED(WARNING) << "Relocate the executable";
-#endif
-}
-
 OatFile::OatDexFile::OatDexFile(const OatFile* oat_file,
                                 const std::string& dex_file_location,
                                 uint32_t dex_file_location_checksum,
diff --git a/src/oat_file.h b/src/oat_file.h
index 1481ce5..9161230 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -29,11 +29,6 @@
 
 class OatFile {
  public:
-  enum RelocationBehavior {
-    kRelocNone,
-    kRelocAll,
-  };
-
   // Returns an OatFile name based on a DexFile location
   static std::string DexFilenameToOatFilename(const std::string& location);
 
@@ -42,14 +37,12 @@
   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();
@@ -223,11 +216,9 @@
     return End() - Begin();
   }
 
-  void RelocateExecutable();
-
  private:
   explicit OatFile(const std::string& filename);
-  bool Map(File& file, byte* requested_base, RelocationBehavior reloc, bool writable);
+  bool Map(File& file, byte* requested_base, bool writable);
 
   const byte* Begin() const;
   const byte* End() const;
diff --git a/src/oat_test.cc b/src/oat_test.cc
index 52217b2..ae30c7e 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -92,8 +92,7 @@
   }
   UniquePtr<OatFile> oat_file(OatFile::Open(tmp.GetFilename(),
                                             tmp.GetFilename(),
-                                            NULL,
-                                            OatFile::kRelocNone));
+                                            NULL));
   ASSERT_TRUE(oat_file.get() != NULL);
   const OatHeader& oat_header = oat_file->GetOatHeader();
   ASSERT_TRUE(oat_header.IsValid());
diff --git a/src/oatdump.cc b/src/oatdump.cc
index cd8b4bb..a24a1bf 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -1422,7 +1422,7 @@
 
   if (oat_filename != NULL) {
     OatFile* oat_file =
-        OatFile::Open(oat_filename, oat_filename, NULL, OatFile::kRelocNone);
+        OatFile::Open(oat_filename, oat_filename, NULL);
     if (oat_file == NULL) {
       fprintf(stderr, "Failed to open oat file from %s\n", oat_filename);
       return EXIT_FAILURE;
diff --git a/src/runtime.cc b/src/runtime.cc
index 4ecc73a..2416581 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -652,9 +652,6 @@
 
   CHECK(host_prefix_.empty()) << host_prefix_;
 
-  // Relocate the OatFiles (ELF images).
-  class_linker_->RelocateExecutable();
-
   // Pre-allocate an OutOfMemoryError for the double-OOME case.
   Thread* self = Thread::Current();
   self->ThrowNewException("Ljava/lang/OutOfMemoryError;",