/*
 * 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 thunks if needed before a method, return adjusted offset.
  virtual uint32_t ReserveSpace(uint32_t offset, const CompiledMethod* compiled_method,
                                MethodReference method_ref) = 0;

  // Reserve space for thunks if needed after the last method, return adjusted offset.
  virtual uint32_t ReserveSpaceEnd(uint32_t offset) = 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_
