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

#include "courgette/disassembler.h"

#include "base/check_op.h"
#include "base/memory/ptr_util.h"
#include "courgette/assembly_program.h"
#include "courgette/encoded_program.h"

namespace courgette {

Disassembler::RvaVisitor_Abs32::RvaVisitor_Abs32(
    const std::vector<RVA>& rva_locations,
    const AddressTranslator& translator)
    : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
}

RVA Disassembler::RvaVisitor_Abs32::Get() const {
  // For Abs32 targets, get target RVA from architecture-dependent functions.
  return translator_->PointerToTargetRVA(translator_->RVAToPointer(*it_));
}

Disassembler::RvaVisitor_Rel32::RvaVisitor_Rel32(
    const std::vector<RVA>& rva_locations,
    const AddressTranslator& translator)
    : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
}

RVA Disassembler::RvaVisitor_Rel32::Get() const {
  // For Rel32 targets, only handle 32-bit offsets.
  return *it_ + 4 + Read32LittleEndian(translator_->RVAToPointer(*it_));
}

Disassembler::Disassembler(const uint8_t* start, size_t length)
    : failure_reason_("uninitialized") {
  start_ = start;
  length_ = length;
  end_ = start_ + length_;
}

Disassembler::~Disassembler() = default;

const uint8_t* Disassembler::FileOffsetToPointer(FileOffset file_offset) const {
  CHECK_LE(file_offset, static_cast<FileOffset>(end_ - start_));
  return start_ + file_offset;
}

const uint8_t* Disassembler::RVAToPointer(RVA rva) const {
  FileOffset file_offset = RVAToFileOffset(rva);
  if (file_offset == kNoFileOffset)
    return nullptr;

  return FileOffsetToPointer(file_offset);
}

std::unique_ptr<AssemblyProgram> Disassembler::CreateProgram(bool annotate) {
  if (!ok() || !ExtractAbs32Locations() || !ExtractRel32Locations())
    return nullptr;

  std::unique_ptr<AssemblyProgram> program =
      std::make_unique<AssemblyProgram>(kind(), image_base());

  PrecomputeLabels(program.get());
  RemoveUnusedRel32Locations(program.get());
  program->DefaultAssignIndexes();

  if (annotate) {
    if (!program->AnnotateLabels(GetInstructionGenerator(program.get())))
      return nullptr;
  }

  return program;
}

Status Disassembler::DisassembleAndEncode(AssemblyProgram* program,
                                          EncodedProgram* encoded) {
  program->PrepareEncodedProgram(encoded);
  return encoded->GenerateInstructions(program->kind(),
                                       GetInstructionGenerator(program))
             ? C_OK
             : C_DISASSEMBLY_FAILED;
}

bool Disassembler::Good() {
  failure_reason_ = nullptr;
  return true;
}

bool Disassembler::Bad(const char* reason) {
  failure_reason_ = reason;
  return false;
}

void Disassembler::PrecomputeLabels(AssemblyProgram* program) {
  std::unique_ptr<RvaVisitor> abs32_visitor(CreateAbs32TargetRvaVisitor());
  std::unique_ptr<RvaVisitor> rel32_visitor(CreateRel32TargetRvaVisitor());
  program->PrecomputeLabels(abs32_visitor.get(), rel32_visitor.get());
}

void Disassembler::ReduceLength(size_t reduced_length) {
  CHECK_LE(reduced_length, length_);
  length_ = reduced_length;
  end_ = start_ + length_;
}

}  // namespace courgette
