//===-- SoftwareBreakpoint.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/common/SoftwareBreakpoint.h"

#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/Debug.h"

#include "lldb/Host/common/NativeProcessProtocol.h"

using namespace lldb_private;

// -------------------------------------------------------------------
// static members
// -------------------------------------------------------------------

Error SoftwareBreakpoint::CreateSoftwareBreakpoint(
    NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint,
    NativeBreakpointSP &breakpoint_sp) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

  // Validate the address.
  if (addr == LLDB_INVALID_ADDRESS)
    return Error("SoftwareBreakpoint::%s invalid load address specified.",
                 __FUNCTION__);

  // Ask the NativeProcessProtocol subclass to fill in the correct software
  // breakpoint
  // trap for the breakpoint site.
  size_t bp_opcode_size = 0;
  const uint8_t *bp_opcode_bytes = NULL;
  Error error = process.GetSoftwareBreakpointTrapOpcode(
      size_hint, bp_opcode_size, bp_opcode_bytes);

  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve software "
                  "breakpoint trap opcode: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Validate size of trap opcode.
  if (bp_opcode_size == 0) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve any trap opcodes",
                  __FUNCTION__);
    return Error("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                 "returned zero, unable to get breakpoint trap for address "
                 "0x%" PRIx64,
                 addr);
  }

  if (bp_opcode_size > MAX_TRAP_OPCODE_SIZE) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s cannot support %lu trapcode bytes, "
                  "max size is %lu",
                  __FUNCTION__, bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
    return Error("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                 "returned too many trap opcode bytes: requires %lu but we "
                 "only support a max of %lu",
                 bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
  }

  // Validate that we received opcodes.
  if (!bp_opcode_bytes) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to retrieve trap opcode bytes",
                  __FUNCTION__);
    return Error("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
                 "returned NULL trap opcode bytes, unable to get breakpoint "
                 "trap for address 0x%" PRIx64,
                 addr);
  }

  // Enable the breakpoint.
  uint8_t saved_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
  error = EnableSoftwareBreakpoint(process, addr, bp_opcode_size,
                                   bp_opcode_bytes, saved_opcode_bytes);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s: failed to enable new breakpoint at "
                  "0x%" PRIx64 ": %s",
                  __FUNCTION__, addr, error.AsCString());
    return error;
  }

  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
                __FUNCTION__, addr);

  // Set the breakpoint and verified it was written properly.  Now
  // create a breakpoint remover that understands how to undo this
  // breakpoint.
  breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes,
                                             bp_opcode_bytes, bp_opcode_size));
  return Error();
}

Error SoftwareBreakpoint::EnableSoftwareBreakpoint(
    NativeProcessProtocol &process, lldb::addr_t addr, size_t bp_opcode_size,
    const uint8_t *bp_opcode_bytes, uint8_t *saved_opcode_bytes) {
  assert(bp_opcode_size <= MAX_TRAP_OPCODE_SIZE &&
         "bp_opcode_size out of valid range");
  assert(bp_opcode_bytes && "bp_opcode_bytes is NULL");
  assert(saved_opcode_bytes && "saved_opcode_bytes is NULL");

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);

  // Save the original opcodes by reading them so we can restore later.
  size_t bytes_read = 0;

  Error error =
      process.ReadMemory(addr, saved_opcode_bytes, bp_opcode_size, bytes_read);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to set breakpoint: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we read as many bytes as we expected.
  if (bytes_read != bp_opcode_size) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to set breakpoint: attempted to read %lu bytes "
                  "but only read %" PRIu64,
                  __FUNCTION__, bp_opcode_size, (uint64_t)bytes_read);
    return Error("SoftwareBreakpoint::%s failed to read memory while "
                 "attempting to set breakpoint: attempted to read %lu bytes "
                 "but only read %" PRIu64,
                 __FUNCTION__, bp_opcode_size, (uint64_t)bytes_read);
  }

  // Log what we read.
  if (log) {
    int i = 0;
    for (const uint8_t *read_byte = saved_opcode_bytes;
         read_byte < saved_opcode_bytes + bp_opcode_size; ++read_byte) {
      log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                  " ovewriting byte index %d (was 0x%hhx)",
                  __FUNCTION__, addr, i++, *read_byte);
    }
  }

  // Write a software breakpoint in place of the original opcode.
  size_t bytes_written = 0;
  error =
      process.WriteMemory(addr, bp_opcode_bytes, bp_opcode_size, bytes_written);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to write memory while "
                  "attempting to set breakpoint: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we wrote as many bytes as we expected.
  if (bytes_written != bp_opcode_size) {
    error.SetErrorStringWithFormat(
        "SoftwareBreakpoint::%s failed write memory while attempting to set "
        "breakpoint: attempted to write %lu bytes but only wrote %" PRIu64,
        __FUNCTION__, bp_opcode_size, (uint64_t)bytes_written);
    if (log)
      log->PutCString(error.AsCString());
    return error;
  }

  uint8_t verify_bp_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
  size_t verify_bytes_read = 0;
  error = process.ReadMemory(addr, verify_bp_opcode_bytes, bp_opcode_size,
                             verify_bytes_read);
  if (error.Fail()) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to verify the breakpoint set: %s",
                  __FUNCTION__, error.AsCString());
    return error;
  }

  // Ensure we read as many verification bytes as we expected.
  if (verify_bytes_read != bp_opcode_size) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s failed to read memory while "
                  "attempting to verify breakpoint: attempted to read %lu "
                  "bytes but only read %" PRIu64,
                  __FUNCTION__, bp_opcode_size, (uint64_t)verify_bytes_read);
    return Error("SoftwareBreakpoint::%s failed to read memory while "
                 "attempting to verify breakpoint: attempted to read %lu bytes "
                 "but only read %" PRIu64,
                 __FUNCTION__, bp_opcode_size, (uint64_t)verify_bytes_read);
  }

  if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) != 0) {
    if (log)
      log->Printf("SoftwareBreakpoint::%s: verification of software breakpoint "
                  "writing failed - trap opcodes not successfully read back "
                  "after writing when setting breakpoint at 0x%" PRIx64,
                  __FUNCTION__, addr);
    return Error("SoftwareBreakpoint::%s: verification of software breakpoint "
                 "writing failed - trap opcodes not successfully read back "
                 "after writing when setting breakpoint at 0x%" PRIx64,
                 __FUNCTION__, addr);
  }

  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
                __FUNCTION__, addr);

  return Error();
}

// -------------------------------------------------------------------
// instance-level members
// -------------------------------------------------------------------

SoftwareBreakpoint::SoftwareBreakpoint(NativeProcessProtocol &process,
                                       lldb::addr_t addr,
                                       const uint8_t *saved_opcodes,
                                       const uint8_t *trap_opcodes,
                                       size_t opcode_size)
    : NativeBreakpoint(addr), m_process(process), m_saved_opcodes(),
      m_trap_opcodes(), m_opcode_size(opcode_size) {
  assert(opcode_size > 0 && "setting software breakpoint with no trap opcodes");
  assert(opcode_size <= MAX_TRAP_OPCODE_SIZE && "trap opcode size too large");

  ::memcpy(m_saved_opcodes, saved_opcodes, opcode_size);
  ::memcpy(m_trap_opcodes, trap_opcodes, opcode_size);
}

Error SoftwareBreakpoint::DoEnable() {
  return EnableSoftwareBreakpoint(m_process, m_addr, m_opcode_size,
                                  m_trap_opcodes, m_saved_opcodes);
}

Error SoftwareBreakpoint::DoDisable() {
  Error error;
  assert(m_addr && (m_addr != LLDB_INVALID_ADDRESS) &&
         "can't remove a software breakpoint for an invalid address");

  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
  if (log)
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
                m_addr);

  assert((m_opcode_size > 0) &&
         "cannot restore opcodes when there are no opcodes");

  if (m_opcode_size > 0) {
    // Clear a software breakpoint instruction
    uint8_t curr_break_op[MAX_TRAP_OPCODE_SIZE];
    bool break_op_found = false;
    assert(m_opcode_size <= sizeof(curr_break_op));

    // Read the breakpoint opcode
    size_t bytes_read = 0;
    error =
        m_process.ReadMemory(m_addr, curr_break_op, m_opcode_size, bytes_read);
    if (error.Success() && bytes_read < m_opcode_size) {
      error.SetErrorStringWithFormat(
          "SoftwareBreakpointr::%s addr=0x%" PRIx64
          ": tried to read %lu bytes but only read %" PRIu64,
          __FUNCTION__, m_addr, m_opcode_size, (uint64_t)bytes_read);
    }
    if (error.Success()) {
      bool verify = false;
      // Make sure the breakpoint opcode exists at this address
      if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) {
        break_op_found = true;
        // We found a valid breakpoint opcode at this address, now restore
        // the saved opcode.
        size_t bytes_written = 0;
        error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size,
                                      bytes_written);
        if (error.Success() && bytes_written < m_opcode_size) {
          error.SetErrorStringWithFormat(
              "SoftwareBreakpoint::%s addr=0x%" PRIx64
              ": tried to write %lu bytes but only wrote %" PRIu64,
              __FUNCTION__, m_addr, m_opcode_size, (uint64_t)bytes_written);
        }
        if (error.Success()) {
          verify = true;
        }
      } else {
        error.SetErrorString(
            "Original breakpoint trap is no longer in memory.");
        // Set verify to true and so we can check if the original opcode has
        // already been restored
        verify = true;
      }

      if (verify) {
        uint8_t verify_opcode[MAX_TRAP_OPCODE_SIZE];
        assert(m_opcode_size <= sizeof(verify_opcode));
        // Verify that our original opcode made it back to the inferior

        size_t verify_bytes_read = 0;
        error = m_process.ReadMemory(m_addr, verify_opcode, m_opcode_size,
                                     verify_bytes_read);
        if (error.Success() && verify_bytes_read < m_opcode_size) {
          error.SetErrorStringWithFormat(
              "SoftwareBreakpoint::%s addr=0x%" PRIx64
              ": tried to read %lu verification bytes but only read %" PRIu64,
              __FUNCTION__, m_addr, m_opcode_size, (uint64_t)verify_bytes_read);
        }
        if (error.Success()) {
          // compare the memory we just read with the original opcode
          if (::memcmp(m_saved_opcodes, verify_opcode, m_opcode_size) == 0) {
            // SUCCESS
            if (log) {
              int i = 0;
              for (const uint8_t *verify_byte = verify_opcode;
                   verify_byte < verify_opcode + m_opcode_size; ++verify_byte) {
                log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                            " replaced byte index %d with 0x%hhx",
                            __FUNCTION__, m_addr, i++, *verify_byte);
              }
              log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
                          " -- SUCCESS",
                          __FUNCTION__, m_addr);
            }
            return error;
          } else {
            if (break_op_found)
              error.SetErrorString("Failed to restore original opcode.");
          }
        } else
          error.SetErrorString("Failed to read memory to verify that "
                               "breakpoint trap was restored.");
      }
    }
  }

  if (log && error.Fail())
    log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- FAILED: %s",
                __FUNCTION__, m_addr, error.AsCString());
  return error;
}

bool SoftwareBreakpoint::IsSoftwareBreakpoint() const { return true; }
