// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DISASSEMBLER_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DISASSEMBLER_H_

#include <inttypes.h>

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "src/developer/debug/zxdb/common/err.h"
#include "src/lib/fxl/macros.h"

namespace llvm {
class MCContext;
class MCDisassembler;
class MCInst;
class MCInstPrinter;
}  // namespace llvm

namespace zxdb {

class ArchInfo;
class MemoryDump;

// Disassembles a block of data.
class Disassembler {
 public:
  struct Options {
    // Controls the behavior for undecodable instructions. When false, DisassembleOne() will report
    // no data consumed and the empty string will be returned. When true, it will emit a "data"
    // mnemonic and advance to the next instruction boundary.
    //
    // DisassembleMany will always should undecodable instructions (otherwise it won't advance).
    bool emit_undecodable = true;
  };

  // One disassembled instruction.
  struct Row {
    Row();
    Row(uint64_t address, const uint8_t* bytes, size_t bytes_len, std::string op,
        std::string params, std::string comment, std::optional<uint64_t> call_dest = std::nullopt);
    ~Row();

    uint64_t address;
    std::vector<uint8_t> bytes;
    std::string op;
    std::string params;
    std::string comment;

    // If this instruction is a call instruction, this will contain the address of the destination
    // of the call.
    //
    // This is currently filled in for the most common cases but is not complete. It could be
    // expanded to handle more call variants, and we could also add a tag have a destination address
    // for jump instructions.
    std::optional<uint64_t> call_dest;

    // For unit testing.
    bool operator==(const Row& other) const;
  };

  Disassembler();
  ~Disassembler();

  // The ArchInfo pointer must outlive this class. Since typically this will come from the Session
  // object which can destroy the LLVM context when the agent is disconnected, you will not want to
  // store Disassembler objects.
  Err Init(const ArchInfo* arch);

  // Disassembles one machine instruction, setting the required information the to columns of the
  // output vector. The output buffer will have columns for instruction, parameters, and comments.
  // If addresses and bytes are requested, those will be prepended.
  //
  // The number of bytes consumed will be returned.
  //
  // Be sure the input buffer always has enough data for any instruction.
  size_t DisassembleOne(const uint8_t* data, size_t data_len, uint64_t address,
                        const Options& options, Row* out) const;

  // Disassembles the block, either until there is no more data, or |max_instructions| have been
  // decoded. If max_instructions is 0 it will always decode the whole block.
  //
  // *Appends* the instructions to the output vector. The max_instructions applies to the total size
  // of the output (so counts what may have already been there).
  //
  // The output will be one vector of columns per line. See DisassembleOne for row format.
  size_t DisassembleMany(const uint8_t* data, size_t data_len, uint64_t start_address,
                         const Options& options, size_t max_instructions,
                         std::vector<Row>* out) const;

  // Like DisassembleMany() but uses a MemoryDump object. The dump will start at the beginning of
  // the memory dump. This function understands the addresses of the memory dump, and also invalid
  // ranges (which will be marked in the disassembly).
  //
  // An unmapped range will be counted as one instruction. The memory addresses for unmapped ranges
  // will always be shown even if disabled in the options.
  size_t DisassembleDump(const MemoryDump& dump, uint64_t start_address, const Options& options,
                         size_t max_instructions, std::vector<Row>* out) const;

 private:
  // Determines if this is a call instruction and computes the destination of the call. Returns
  // a nullopt if it's not decodable as a call.
  //
  // The address is the address of the beginning of the instruction. It is needed to decode relative
  // addresses. The data and data_len indicates the array of bytes that makes up the instruction.
  std::optional<uint64_t> GetCallDest(uint64_t address, const uint8_t* data, uint64_t data_len,
                                      const llvm::MCInst& inst) const;

  const ArchInfo* arch_ = nullptr;

  std::unique_ptr<llvm::MCContext> context_;
  std::unique_ptr<llvm::MCDisassembler> disasm_;
  std::unique_ptr<llvm::MCInstPrinter> printer_;

  FXL_DISALLOW_COPY_AND_ASSIGN(Disassembler);
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DISASSEMBLER_H_
