// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_ZUCCHINI_REL32_UTILS_H_
#define COMPONENTS_ZUCCHINI_REL32_UTILS_H_

#include <algorithm>
#include <array>
#include <deque>
#include <memory>
#include <optional>

#include "base/logging.h"
#include "components/zucchini/address_translator.h"
#include "components/zucchini/arm_utils.h"
#include "components/zucchini/buffer_view.h"
#include "components/zucchini/image_utils.h"
#include "components/zucchini/io_utils.h"

namespace zucchini {

// Reader that emits x86 / x64 References (locations and target) from a list of
// valid locations, constrained by a portion of an image.
class Rel32ReaderX86 : public ReferenceReader {
 public:
  // |image| is an image containing x86 / x64 code in [|lo|, |hi|).
  // |locations| is a sorted list of offsets of rel32 reference locations.
  // |translator| (for |image|) is embedded into |target_rva_to_offset_| and
  // |location_offset_to_rva_| for address translation, and therefore must
  // outlive |*this|.
  Rel32ReaderX86(ConstBufferView image,
                 offset_t lo,
                 offset_t hi,
                 const std::deque<offset_t>* locations,
                 const AddressTranslator& translator);
  Rel32ReaderX86(const Rel32ReaderX86&) = delete;
  const Rel32ReaderX86& operator=(const Rel32ReaderX86&) = delete;
  ~Rel32ReaderX86() override;

  // Returns the next reference, or std::nullopt if exhausted.
  std::optional<Reference> GetNext() override;

 private:
  ConstBufferView image_;
  AddressTranslator::RvaToOffsetCache target_rva_to_offset_;
  AddressTranslator::OffsetToRvaCache location_offset_to_rva_;
  const offset_t hi_;
  const std::deque<offset_t>::const_iterator last_;
  std::deque<offset_t>::const_iterator current_;
};

// Writer for x86 / x64 rel32 References.
class Rel32WriterX86 : public ReferenceWriter {
 public:
  // |image| wraps the raw bytes of a binary in which rel32 references will be
  // written. |translator| (for |image|) is embedded into
  // |target_offset_to_rva_| and |location_offset_to_rva_| for address
  // translation, and therefore must outlive |*this|.
  Rel32WriterX86(MutableBufferView image, const AddressTranslator& translator);
  Rel32WriterX86(const Rel32WriterX86&) = delete;
  const Rel32WriterX86& operator=(const Rel32WriterX86&) = delete;
  ~Rel32WriterX86() override;

  void PutNext(Reference ref) override;

 private:
  MutableBufferView image_;
  AddressTranslator::OffsetToRvaCache target_offset_to_rva_;
  AddressTranslator::OffsetToRvaCache location_offset_to_rva_;
};

// Reader that emits x86 / x64 References (locations and target) of a spcific
// type from a list of valid locations, constrained by a portion of an image.
template <class ADDR_TRAITS>
class Rel32ReaderArm : public ReferenceReader {
 public:
  using CODE_T = typename ADDR_TRAITS::code_t;

  Rel32ReaderArm(const AddressTranslator& translator,
                 ConstBufferView view,
                 const std::deque<offset_t>& rel32_locations,
                 offset_t lo,
                 offset_t hi)
      : view_(view),
        offset_to_rva_(translator),
        rva_to_offset_(translator),
        hi_(hi) {
    cur_it_ =
        std::lower_bound(rel32_locations.begin(), rel32_locations.end(), lo);
    rel32_end_ = rel32_locations.end();
  }

  Rel32ReaderArm(const Rel32ReaderArm&) = delete;
  const Rel32ReaderArm& operator=(const Rel32ReaderArm&) = delete;

  std::optional<Reference> GetNext() override {
    while (cur_it_ < rel32_end_ && *cur_it_ < hi_) {
      offset_t location = *(cur_it_++);
      CODE_T code = ADDR_TRAITS::Fetch(view_, location);
      rva_t instr_rva = offset_to_rva_.Convert(location);
      rva_t target_rva = kInvalidRva;
      if (ADDR_TRAITS::Read(instr_rva, code, &target_rva)) {
        offset_t target = rva_to_offset_.Convert(target_rva);
        if (target != kInvalidOffset)
          return Reference{location, target};
      }
    }
    return std::nullopt;
  }

 private:
  ConstBufferView view_;
  AddressTranslator::OffsetToRvaCache offset_to_rva_;
  AddressTranslator::RvaToOffsetCache rva_to_offset_;
  std::deque<offset_t>::const_iterator cur_it_;
  std::deque<offset_t>::const_iterator rel32_end_;
  offset_t hi_;
};

// Writer for ARM rel32 References of a specific type.
template <class ADDR_TRAITS>
class Rel32WriterArm : public ReferenceWriter {
 public:
  using CODE_T = typename ADDR_TRAITS::code_t;

  Rel32WriterArm(const AddressTranslator& translator,
                 MutableBufferView mutable_view)
      : mutable_view_(mutable_view), offset_to_rva_(translator) {}

  Rel32WriterArm(const Rel32WriterArm&) = delete;
  const Rel32WriterArm& operator=(const Rel32WriterArm&) = delete;

  void PutNext(Reference ref) override {
    CODE_T code = ADDR_TRAITS::Fetch(mutable_view_, ref.location);
    rva_t instr_rva = offset_to_rva_.Convert(ref.location);
    rva_t target_rva = offset_to_rva_.Convert(ref.target);
    if (ADDR_TRAITS::Write(instr_rva, target_rva, &code)) {
      ADDR_TRAITS::Store(mutable_view_, ref.location, code);
    } else {
      LOG(ERROR) << "Write error: " << AsHex<8>(ref.location) << ": "
                 << AsHex<static_cast<int>(sizeof(CODE_T)) * 2>(code)
                 << " <= " << AsHex<8>(target_rva) << ".";
    }
  }

 private:
  MutableBufferView mutable_view_;
  AddressTranslator::OffsetToRvaCache offset_to_rva_;
};

// Copier that makes |*dst_it| similar to |*src_it| (both assumed to point to
// rel32 instructions of type ADDR_TRAITS) by copying the displacement (i.e.,
// payload bits) from |src_it| to |dst_it|. If successful, updates |*dst_it|,
// and returns true. Otherwise returns false. Note that alignment is not an
// issue since the displacement is not translated to target RVA!
template <class ADDR_TRAITS>
bool ArmCopyDisp(ConstBufferView src_view,
                 offset_t src_idx,
                 MutableBufferView dst_view,
                 offset_t dst_idx) {
  using CODE_T = typename ADDR_TRAITS::code_t;
  CODE_T src_code = ADDR_TRAITS::Fetch(src_view, src_idx);
  arm_disp_t disp = 0;
  if (ADDR_TRAITS::Decode(src_code, &disp)) {
    CODE_T dst_code = ADDR_TRAITS::Fetch(dst_view, dst_idx);
    if (ADDR_TRAITS::Encode(disp, &dst_code)) {
      ADDR_TRAITS::Store(dst_view, dst_idx, dst_code);
      return true;
    }
  }
  return false;
}

// Outputs error message (throttled) on ArmCopyDisp failure.
void OutputArmCopyDispFailure(uint32_t addr_type);

// Mixer for ARM rel32 References of a specific type.
template <class ADDR_TRAITS>
class Rel32MixerArm : public ReferenceMixer {
  using code_t = typename ADDR_TRAITS::code_t;
  static constexpr size_t kCodeWidth = sizeof(code_t);

 public:
  Rel32MixerArm(ConstBufferView src_image, ConstBufferView dst_image)
      : src_image_(src_image), dst_image_(dst_image) {}
  ~Rel32MixerArm() override = default;

  ConstBufferView Mix(offset_t src_offset, offset_t dst_offset) override {
    ConstBufferView::const_iterator new_it = dst_image_.begin() + dst_offset;
    MutableBufferView out_buffer_view(out_buffer_.data(), kCodeWidth);
    std::copy(new_it, new_it + kCodeWidth, out_buffer_view.begin());

    if (!ArmCopyDisp<ADDR_TRAITS>(src_image_, src_offset, out_buffer_view,
                                  0U)) {
      OutputArmCopyDispFailure(static_cast<uint32_t>(ADDR_TRAITS::addr_type));
      // Fall back to direct copy.
      std::copy(new_it, new_it + kCodeWidth, out_buffer_.begin());
    }
    return ConstBufferView(out_buffer_.data(), kCodeWidth);
  }

 private:
  ConstBufferView src_image_;
  ConstBufferView dst_image_;

  std::array<uint8_t, sizeof(code_t)> out_buffer_;
};

}  // namespace zucchini

#endif  // COMPONENTS_ZUCCHINI_REL32_UTILS_H_
