//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "RegisterContextMacOSXFrameBackchain.h"

#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/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);
}
