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

#include "ThreadKDP.h"

#include "lldb/Utility/SafeMachO.h"

#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"

#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ProcessKDP.h"
#include "ProcessKDPLog.h"
#include "RegisterContextKDP_arm.h"
#include "RegisterContextKDP_arm64.h"
#include "RegisterContextKDP_i386.h"
#include "RegisterContextKDP_x86_64.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// Thread Registers
//----------------------------------------------------------------------

ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
    : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
      m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
  Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
  LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
}

ThreadKDP::~ThreadKDP() {
  Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
  LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
  DestroyThread();
}

const char *ThreadKDP::GetName() {
  if (m_thread_name.empty())
    return nullptr;
  return m_thread_name.c_str();
}

const char *ThreadKDP::GetQueueName() { return nullptr; }

void ThreadKDP::RefreshStateAfterStop() {
  // Invalidate all registers in our register context. We don't set "force" to
  // true because the stop reply packet might have had some register values
  // that were expedited and these will already be copied into the register
  // context by the time this function gets called. The KDPRegisterContext
  // class has been made smart enough to detect when it needs to invalidate
  // which registers are valid by putting hooks in the register read and
  // register supply functions where they check the process stop ID and do the
  // right thing.
  const bool force = false;
  lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
  if (reg_ctx_sp)
    reg_ctx_sp->InvalidateIfNeeded(force);
}

bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }

void ThreadKDP::Dump(Log *log, uint32_t index) {}

bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
  if (!m_reg_context_sp)
    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
  return m_reg_context_sp;
}

lldb::RegisterContextSP
ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
  lldb::RegisterContextSP reg_ctx_sp;
  uint32_t concrete_frame_idx = 0;

  if (frame)
    concrete_frame_idx = frame->GetConcreteFrameIndex();

  if (concrete_frame_idx == 0) {
    ProcessSP process_sp(CalculateProcess());
    if (process_sp) {
      switch (static_cast<ProcessKDP *>(process_sp.get())
                  ->GetCommunication()
                  .GetCPUType()) {
      case llvm::MachO::CPU_TYPE_ARM:
        reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
        break;
      case llvm::MachO::CPU_TYPE_ARM64:
        reg_ctx_sp.reset(
            new RegisterContextKDP_arm64(*this, concrete_frame_idx));
        break;
      case llvm::MachO::CPU_TYPE_I386:
        reg_ctx_sp.reset(
            new RegisterContextKDP_i386(*this, concrete_frame_idx));
        break;
      case llvm::MachO::CPU_TYPE_X86_64:
        reg_ctx_sp.reset(
            new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
        break;
      default:
        llvm_unreachable("Add CPU type support in KDP");
      }
    }
  } else {
    Unwind *unwinder = GetUnwinder();
    if (unwinder != nullptr)
      reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
  }
  return reg_ctx_sp;
}

bool ThreadKDP::CalculateStopInfo() {
  ProcessSP process_sp(GetProcess());
  if (process_sp) {
    if (m_cached_stop_info_sp) {
      SetStopInfo(m_cached_stop_info_sp);
    } else {
      SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
    }
    return true;
  }
  return false;
}

void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
    const DataExtractor &exc_reply_packet) {
  lldb::offset_t offset = 0;
  uint8_t reply_command = exc_reply_packet.GetU8(&offset);
  if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
    offset = 8;
    const uint32_t count = exc_reply_packet.GetU32(&offset);
    if (count >= 1) {
      // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
      offset += 4; // Skip the useless CPU field
      const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
      const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
      const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
      // We have to make a copy of the stop info because the thread list will
      // iterate through the threads and clear all stop infos..

      // Let the StopInfoMachException::CreateStopReasonWithMachException()
      // function update the PC if needed as we might hit a software breakpoint
      // and need to decrement the PC (i386 and x86_64 need this) and KDP
      // doesn't do this for us.
      const bool pc_already_adjusted = false;
      const bool adjust_pc_if_needed = true;

      m_cached_stop_info_sp =
          StopInfoMachException::CreateStopReasonWithMachException(
              *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
              adjust_pc_if_needed);
    }
  }
}
