//===-- 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/ArchSpec.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/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 NULL;
  return m_thread_name.c_str();
}

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

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.get() == NULL)
    m_reg_context_sp = CreateRegisterContextForFrame(NULL);
  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)
      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);
    }
  }
}
