Refactor RelativePatcher out of OatWriter.

Move the relative patcher classes to compiler/linker/ and
compiler/linker/<arch>/ . Refactor them to avoid OatWriter
dependency so that they can be unit tested. Add tests for
x86 and x86-64.

Change-Id: I1b42baa9fc431378e4cce1399bec590c5b5a409f
diff --git a/compiler/linker/relative_patcher.h b/compiler/linker/relative_patcher.h
new file mode 100644
index 0000000..dbb18cc
--- /dev/null
+++ b/compiler/linker/relative_patcher.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_LINKER_RELATIVE_PATCHER_H_
+#define ART_COMPILER_LINKER_RELATIVE_PATCHER_H_
+
+#include <vector>
+
+#include "arch/instruction_set.h"
+#include "arch/instruction_set_features.h"
+#include "base/macros.h"
+#include "method_reference.h"
+#include "utils/array_ref.h"
+
+namespace art {
+
+class CompiledMethod;
+class LinkerPatch;
+class OutputStream;
+
+namespace linker {
+
+/**
+ * @class RelativePatcherTargetProvider
+ * @brief Interface for providing method offsets for relative call targets.
+ */
+class RelativePatcherTargetProvider {
+ public:
+  /**
+   * Find the offset of the target method of a relative call if known.
+   *
+   * The process of assigning target method offsets includes calls to the relative patcher's
+   * ReserveSpace() which in turn can use FindMethodOffset() to determine if a method already
+   * has an offset assigned and, if so, what's that offset. If the offset has not yet been
+   * assigned or if it's too far for the particular architecture's relative call,
+   * ReserveSpace() may need to allocate space for a special dispatch thunk.
+   *
+   * @param ref the target method of the relative call.
+   * @return true in the first element of the pair if the method was found, false otherwise;
+   *         if found, the second element specifies the offset.
+   */
+  virtual std::pair<bool, uint32_t> FindMethodOffset(MethodReference ref) = 0;
+
+ protected:
+  virtual ~RelativePatcherTargetProvider() { }
+};
+
+/**
+ * @class RelativePatcher
+ * @brief Interface for architecture-specific link-time patching of PC-relative references.
+ */
+class RelativePatcher {
+ public:
+  static std::unique_ptr<RelativePatcher> Create(
+      InstructionSet instruction_set, const InstructionSetFeatures* features,
+      RelativePatcherTargetProvider* provider);
+
+  virtual ~RelativePatcher() { }
+
+  uint32_t CodeAlignmentSize() const {
+    return size_code_alignment_;
+  }
+
+  uint32_t RelativeCallThunksSize() const {
+    return size_relative_call_thunks_;
+  }
+
+  uint32_t MiscThunksSize() const {
+    return size_misc_thunks_;
+  }
+
+  // Reserve space for relative call thunks if needed, return adjusted offset. After all methods
+  // of a class have been processed it's called one last time with compiled_method == nullptr.
+  virtual uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method) = 0;
+
+  // Write relative call thunks if needed, return adjusted offset.
+  virtual uint32_t WriteThunks(OutputStream* out, uint32_t offset) = 0;
+
+  // Patch method code. The input displacement is relative to the patched location,
+  // the patcher may need to adjust it if the correct base is different.
+  virtual void PatchCall(std::vector<uint8_t>* code, uint32_t literal_offset,
+                         uint32_t patch_offset, uint32_t target_offset) = 0;
+
+  // Patch a reference to a dex cache location.
+  virtual void PatchDexCacheReference(std::vector<uint8_t>* code, const LinkerPatch& patch,
+                                      uint32_t patch_offset, uint32_t target_offset) = 0;
+
+ protected:
+  RelativePatcher()
+      : size_code_alignment_(0u),
+        size_relative_call_thunks_(0u),
+        size_misc_thunks_(0u) {
+  }
+
+  bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta);
+  bool WriteRelCallThunk(OutputStream* out, const ArrayRef<const uint8_t>& thunk);
+  bool WriteMiscThunk(OutputStream* out, const ArrayRef<const uint8_t>& thunk);
+
+ private:
+  uint32_t size_code_alignment_;
+  uint32_t size_relative_call_thunks_;
+  uint32_t size_misc_thunks_;
+
+  DISALLOW_COPY_AND_ASSIGN(RelativePatcher);
+};
+
+}  // namespace linker
+}  // namespace art
+
+#endif  // ART_COMPILER_LINKER_RELATIVE_PATCHER_H_