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

#include "RegisterContextMacOSXFrameBackchain.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// RegisterContextMacOSXFrameBackchain constructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
    Thread &thread, uint32_t concrete_frame_idx,
    const UnwindMacOSXFrameBackchain::Cursor &cursor)
    : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
      m_cursor_is_valid(true) {}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}

void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
  m_cursor_is_valid = false;
}

size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
  return m_thread.GetRegisterContext()->GetRegisterCount();
}

const RegisterInfo *
RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
  return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}

size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
  return m_thread.GetRegisterContext()->GetRegisterSetCount();
}

const RegisterSet *
RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
  return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}

bool RegisterContextMacOSXFrameBackchain::ReadRegister(
    const RegisterInfo *reg_info, RegisterValue &value) {
  if (!m_cursor_is_valid)
    return false;

  uint64_t reg_value = LLDB_INVALID_ADDRESS;

  switch (reg_info->kinds[eRegisterKindGeneric]) {
  case LLDB_REGNUM_GENERIC_PC:
    if (m_cursor.pc == LLDB_INVALID_ADDRESS)
      return false;
    reg_value = m_cursor.pc;
    break;

  case LLDB_REGNUM_GENERIC_FP:
    if (m_cursor.fp == LLDB_INVALID_ADDRESS)
      return false;
    reg_value = m_cursor.fp;
    break;

  default:
    return false;
  }

  switch (reg_info->encoding) {
  case eEncodingInvalid:
  case eEncodingVector:
    break;

  case eEncodingUint:
  case eEncodingSint:
    value.SetUInt(reg_value, reg_info->byte_size);
    return true;

  case eEncodingIEEE754:
    switch (reg_info->byte_size) {
    case sizeof(float):
      if (sizeof(float) == sizeof(uint32_t)) {
        value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
        return true;
      } else if (sizeof(float) == sizeof(uint64_t)) {
        value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
        return true;
      }
      break;

    case sizeof(double):
      if (sizeof(double) == sizeof(uint32_t)) {
        value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
        return true;
      } else if (sizeof(double) == sizeof(uint64_t)) {
        value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
        return true;
      }
      break;

// TOOD: need a better way to detect when "long double" types are
// the same bytes size as "double"
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) &&       \
    !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) &&       \
    !defined(__ANDROID__)
    case sizeof(long double):
      if (sizeof(long double) == sizeof(uint32_t)) {
        value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
        return true;
      } else if (sizeof(long double) == sizeof(uint64_t)) {
        value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
        return true;
      }
      break;
#endif
    }
    break;
  }
  return false;
}

bool RegisterContextMacOSXFrameBackchain::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &value) {
  // Not supported yet. We could easily add support for this by remembering
  // the address of each entry (it would need to be part of the cursor)
  return false;
}

bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
    lldb::DataBufferSP &data_sp) {
  // libunwind frames can't handle this it doesn't always have all register
  // values. This call should only be called on frame zero anyway so there
  // shouldn't be any problem
  return false;
}

bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  // Since this class doesn't respond to "ReadAllRegisterValues()", it must
  // not have been the one that saved all the register values. So we just let
  // the thread's register context (the register context for frame zero) do
  // the writing.
  return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
}

uint32_t
RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
    lldb::RegisterKind kind, uint32_t num) {
  return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
      kind, num);
}
