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

#if defined(__s390x__) && defined(__linux__)

#include "NativeRegisterContextLinux_s390x.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"

#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"

#include <asm/ptrace.h>
#include <linux/uio.h>
#include <sys/ptrace.h>

using namespace lldb_private;
using namespace lldb_private::process_linux;

// ----------------------------------------------------------------------------
// Private namespace.
// ----------------------------------------------------------------------------

namespace {
// s390x 64-bit general purpose registers.
static const uint32_t g_gpr_regnums_s390x[] = {
    lldb_r0_s390x,      lldb_r1_s390x,    lldb_r2_s390x,    lldb_r3_s390x,
    lldb_r4_s390x,      lldb_r5_s390x,    lldb_r6_s390x,    lldb_r7_s390x,
    lldb_r8_s390x,      lldb_r9_s390x,    lldb_r10_s390x,   lldb_r11_s390x,
    lldb_r12_s390x,     lldb_r13_s390x,   lldb_r14_s390x,   lldb_r15_s390x,
    lldb_acr0_s390x,    lldb_acr1_s390x,  lldb_acr2_s390x,  lldb_acr3_s390x,
    lldb_acr4_s390x,    lldb_acr5_s390x,  lldb_acr6_s390x,  lldb_acr7_s390x,
    lldb_acr8_s390x,    lldb_acr9_s390x,  lldb_acr10_s390x, lldb_acr11_s390x,
    lldb_acr12_s390x,   lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
    lldb_pswm_s390x,    lldb_pswa_s390x,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
                      1 ==
                  k_num_gpr_registers_s390x,
              "g_gpr_regnums_s390x has wrong number of register infos");

// s390x 64-bit floating point registers.
static const uint32_t g_fpu_regnums_s390x[] = {
    lldb_f0_s390x,      lldb_f1_s390x,  lldb_f2_s390x,  lldb_f3_s390x,
    lldb_f4_s390x,      lldb_f5_s390x,  lldb_f6_s390x,  lldb_f7_s390x,
    lldb_f8_s390x,      lldb_f9_s390x,  lldb_f10_s390x, lldb_f11_s390x,
    lldb_f12_s390x,     lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
    lldb_fpc_s390x,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
                      1 ==
                  k_num_fpr_registers_s390x,
              "g_fpu_regnums_s390x has wrong number of register infos");

// s390x Linux operating-system information.
static const uint32_t g_linux_regnums_s390x[] = {
    lldb_orig_r2_s390x, lldb_last_break_s390x, lldb_system_call_s390x,
    LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_linux_regnums_s390x) /
               sizeof(g_linux_regnums_s390x[0])) -
                      1 ==
                  k_num_linux_registers_s390x,
              "g_linux_regnums_s390x has wrong number of register infos");

// Number of register sets provided by this context.
enum { k_num_register_sets = 3 };

// Register sets for s390x 64-bit.
static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
    {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
     g_gpr_regnums_s390x},
    {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
     g_fpu_regnums_s390x},
    {"Linux Operating System Data", "linux", k_num_linux_registers_s390x,
     g_linux_regnums_s390x},
};
}

#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)

// ----------------------------------------------------------------------------
// Required ptrace defines.
// ----------------------------------------------------------------------------

#define NT_S390_LAST_BREAK 0x306  /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */

std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
  return llvm::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
                                                             native_thread);
}

// ----------------------------------------------------------------------------
// NativeRegisterContextLinux_s390x members.
// ----------------------------------------------------------------------------

static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec &target_arch) {
  assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
         "Register setting path assumes this is a 64-bit host");
  return new RegisterContextLinux_s390x(target_arch);
}

NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
    : NativeRegisterContextLinux(native_thread,
                                 CreateRegisterInfoInterface(target_arch)) {
  // Set up data about ranges of valid registers.
  switch (target_arch.GetMachine()) {
  case llvm::Triple::systemz:
    m_reg_info.num_registers = k_num_registers_s390x;
    m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
    m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
    m_reg_info.last_gpr = k_last_gpr_s390x;
    m_reg_info.first_fpr = k_first_fpr_s390x;
    m_reg_info.last_fpr = k_last_fpr_s390x;
    break;
  default:
    assert(false && "Unhandled target architecture.");
    break;
  }

  // Clear out the watchpoint state.
  m_watchpoint_addr = LLDB_INVALID_ADDRESS;
}

uint32_t NativeRegisterContextLinux_s390x::GetRegisterSetCount() const {
  uint32_t sets = 0;
  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
    if (IsRegisterSetAvailable(set_index))
      ++sets;
  }

  return sets;
}

uint32_t NativeRegisterContextLinux_s390x::GetUserRegisterCount() const {
  uint32_t count = 0;
  for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
    const RegisterSet *set = GetRegisterSet(set_index);
    if (set)
      count += set->num_registers;
  }
  return count;
}

const RegisterSet *
NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const {
  if (!IsRegisterSetAvailable(set_index))
    return nullptr;

  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
  case llvm::Triple::systemz:
    return &g_reg_sets_s390x[set_index];
  default:
    assert(false && "Unhandled target architecture.");
    return nullptr;
  }

  return nullptr;
}

bool NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(
    uint32_t set_index) const {
  return set_index < k_num_register_sets;
}

bool NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const {
  // GPRs come first.  "orig_r2" counts as GPR since it is part of the GPR
  // register area.
  return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
}

bool NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const {
  return (m_reg_info.first_fpr <= reg_index &&
          reg_index <= m_reg_info.last_fpr);
}

Status
NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info,
                                               RegisterValue &reg_value) {
  if (!reg_info)
    return Status("reg_info NULL");

  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
  if (reg == LLDB_INVALID_REGNUM)
    return Status("register \"%s\" is an internal-only lldb register, cannot "
                  "read directly",
                  reg_info->name);

  if (IsGPR(reg)) {
    s390_regs regs;
    Status error = DoReadGPR(&regs, sizeof(regs));
    if (error.Fail())
      return error;

    uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
    switch (reg_info->byte_size) {
    case 4:
      reg_value.SetUInt32(*(uint32_t *)src);
      break;
    case 8:
      reg_value.SetUInt64(*(uint64_t *)src);
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return Status();
  }

  if (IsFPR(reg)) {
    s390_fp_regs fp_regs;
    Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
    if (error.Fail())
      return error;

    // byte_offset is just the offset within FPR, not the whole user area.
    uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
    switch (reg_info->byte_size) {
    case 4:
      reg_value.SetUInt32(*(uint32_t *)src);
      break;
    case 8:
      reg_value.SetUInt64(*(uint64_t *)src);
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return Status();
  }

  if (reg == lldb_last_break_s390x) {
    uint64_t last_break;
    Status error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
    if (error.Fail())
      return error;

    reg_value.SetUInt64(last_break);
    return Status();
  }

  if (reg == lldb_system_call_s390x) {
    uint32_t system_call;
    Status error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
    if (error.Fail())
      return error;

    reg_value.SetUInt32(system_call);
    return Status();
  }

  return Status("failed - register wasn't recognized");
}

Status NativeRegisterContextLinux_s390x::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
  if (!reg_info)
    return Status("reg_info NULL");

  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
  if (reg == LLDB_INVALID_REGNUM)
    return Status("register \"%s\" is an internal-only lldb register, cannot "
                  "write directly",
                  reg_info->name);

  if (IsGPR(reg)) {
    s390_regs regs;
    Status error = DoReadGPR(&regs, sizeof(regs));
    if (error.Fail())
      return error;

    uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
    switch (reg_info->byte_size) {
    case 4:
      *(uint32_t *)dst = reg_value.GetAsUInt32();
      break;
    case 8:
      *(uint64_t *)dst = reg_value.GetAsUInt64();
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return DoWriteGPR(&regs, sizeof(regs));
  }

  if (IsFPR(reg)) {
    s390_fp_regs fp_regs;
    Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
    if (error.Fail())
      return error;

    // byte_offset is just the offset within fp_regs, not the whole user area.
    uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
    switch (reg_info->byte_size) {
    case 4:
      *(uint32_t *)dst = reg_value.GetAsUInt32();
      break;
    case 8:
      *(uint64_t *)dst = reg_value.GetAsUInt64();
      break;
    default:
      assert(false && "Unhandled data size.");
      return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
    }
    return DoWriteFPR(&fp_regs, sizeof(fp_regs));
  }

  if (reg == lldb_last_break_s390x) {
    return Status("The last break address is read-only");
  }

  if (reg == lldb_system_call_s390x) {
    uint32_t system_call = reg_value.GetAsUInt32();
    return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
  }

  return Status("failed - register wasn't recognized");
}

Status NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
    lldb::DataBufferSP &data_sp) {
  Status error;

  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
  if (!data_sp) {
    error.SetErrorStringWithFormat(
        "failed to allocate DataBufferHeap instance of size %" PRIu64,
        REG_CONTEXT_SIZE);
    return error;
  }

  uint8_t *dst = data_sp->GetBytes();
  if (dst == nullptr) {
    error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
                                   " returned a null pointer",
                                   REG_CONTEXT_SIZE);
    return error;
  }

  error = DoReadGPR(dst, sizeof(s390_regs));
  dst += sizeof(s390_regs);
  if (error.Fail())
    return error;

  error = DoReadFPR(dst, sizeof(s390_fp_regs));
  dst += sizeof(s390_fp_regs);
  if (error.Fail())
    return error;

  // Ignore errors if the regset is unsupported (happens on older kernels).
  DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
  dst += 4;

  // To enable inferior function calls while the process is stopped in an
  // interrupted system call, we need to clear the system call flag. It will be
  // restored to its original value by WriteAllRegisterValues. Again we ignore
  // error if the regset is unsupported.
  uint32_t system_call = 0;
  DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);

  return error;
}

Status NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  Status error;

  if (!data_sp) {
    error.SetErrorStringWithFormat(
        "NativeRegisterContextLinux_s390x::%s invalid data_sp provided",
        __FUNCTION__);
    return error;
  }

  if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
    error.SetErrorStringWithFormat(
        "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched "
        "data size, expected %" PRIu64 ", actual %" PRIu64,
        __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
    return error;
  }

  uint8_t *src = data_sp->GetBytes();
  if (src == nullptr) {
    error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s "
                                   "DataBuffer::GetBytes() returned a null "
                                   "pointer",
                                   __FUNCTION__);
    return error;
  }

  error = DoWriteGPR(src, sizeof(s390_regs));
  src += sizeof(s390_regs);
  if (error.Fail())
    return error;

  error = DoWriteFPR(src, sizeof(s390_fp_regs));
  src += sizeof(s390_fp_regs);
  if (error.Fail())
    return error;

  // Ignore errors if the regset is unsupported (happens on older kernels).
  DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
  src += 4;

  return error;
}

Status NativeRegisterContextLinux_s390x::DoReadRegisterValue(
    uint32_t offset, const char *reg_name, uint32_t size,
    RegisterValue &value) {
  return Status("DoReadRegisterValue unsupported");
}

Status NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
    uint32_t offset, const char *reg_name, const RegisterValue &value) {
  return Status("DoWriteRegisterValue unsupported");
}

Status NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset,
                                                      void *buf,
                                                      size_t buf_size) {
  ptrace_area parea;
  parea.len = buf_size;
  parea.process_addr = (addr_t)buf;
  parea.kernel_addr = offset;

  return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA,
                                           m_thread.GetID(), &parea);
}

Status NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset,
                                                      const void *buf,
                                                      size_t buf_size) {
  ptrace_area parea;
  parea.len = buf_size;
  parea.process_addr = (addr_t)buf;
  parea.kernel_addr = offset;

  return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA,
                                           m_thread.GetID(), &parea);
}

Status NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size) {
  assert(buf_size == sizeof(s390_regs));
  return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}

Status NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf,
                                                    size_t buf_size) {
  assert(buf_size == sizeof(s390_regs));
  return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
}

Status NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size) {
  assert(buf_size == sizeof(s390_fp_regs));
  return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}

Status NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf,
                                                    size_t buf_size) {
  assert(buf_size == sizeof(s390_fp_regs));
  return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
}

Status NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset,
                                                           void *buf,
                                                           size_t buf_size) {
  struct iovec iov;
  iov.iov_base = buf;
  iov.iov_len = buf_size;

  return ReadRegisterSet(&iov, buf_size, regset);
}

Status NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset,
                                                            const void *buf,
                                                            size_t buf_size) {
  struct iovec iov;
  iov.iov_base = const_cast<void *>(buf);
  iov.iov_len = buf_size;

  return WriteRegisterSet(&iov, buf_size, regset);
}

Status NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index,
                                                         bool &is_hit) {
  per_lowcore_bits per_lowcore;

  if (wp_index >= NumSupportedHardwareWatchpoints())
    return Status("Watchpoint index out of range");

  if (m_watchpoint_addr == LLDB_INVALID_ADDRESS) {
    is_hit = false;
    return Status();
  }

  Status error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore),
                              &per_lowcore, sizeof(per_lowcore));
  if (error.Fail()) {
    is_hit = false;
    return error;
  }

  is_hit = (per_lowcore.perc_storage_alteration == 1 &&
            per_lowcore.perc_store_real_address == 0);

  if (is_hit) {
    // Do not report this watchpoint again.
    memset(&per_lowcore, 0, sizeof(per_lowcore));
    PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore,
                 sizeof(per_lowcore));
  }

  return Status();
}

Status NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(
    uint32_t &wp_index, lldb::addr_t trap_addr) {
  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
  for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
    bool is_hit;
    Status error = IsWatchpointHit(wp_index, is_hit);
    if (error.Fail()) {
      wp_index = LLDB_INVALID_INDEX32;
      return error;
    } else if (is_hit) {
      return error;
    }
  }
  wp_index = LLDB_INVALID_INDEX32;
  return Status();
}

Status NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index,
                                                            bool &is_vacant) {
  if (wp_index >= NumSupportedHardwareWatchpoints())
    return Status("Watchpoint index out of range");

  is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;

  return Status();
}

bool NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(
    uint32_t wp_index) {
  per_struct per_info;

  if (wp_index >= NumSupportedHardwareWatchpoints())
    return false;

  Status error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
                              sizeof(per_info));
  if (error.Fail())
    return false;

  per_info.control_regs.bits.em_storage_alteration = 0;
  per_info.control_regs.bits.storage_alt_space_ctl = 0;
  per_info.starting_addr = 0;
  per_info.ending_addr = 0;

  error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
                       sizeof(per_info));
  if (error.Fail())
    return false;

  m_watchpoint_addr = LLDB_INVALID_ADDRESS;
  return true;
}

Status NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints() {
  if (ClearHardwareWatchpoint(0))
    return Status();
  return Status("Clearing all hardware watchpoints failed.");
}

uint32_t NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(
    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
  per_struct per_info;

  if (watch_flags != 0x1)
    return LLDB_INVALID_INDEX32;

  if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
    return LLDB_INVALID_INDEX32;

  Status error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
                              sizeof(per_info));
  if (error.Fail())
    return LLDB_INVALID_INDEX32;

  per_info.control_regs.bits.em_storage_alteration = 1;
  per_info.control_regs.bits.storage_alt_space_ctl = 1;
  per_info.starting_addr = addr;
  per_info.ending_addr = addr + size - 1;

  error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
                       sizeof(per_info));
  if (error.Fail())
    return LLDB_INVALID_INDEX32;

  m_watchpoint_addr = addr;
  return 0;
}

lldb::addr_t
NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index) {
  if (wp_index >= NumSupportedHardwareWatchpoints())
    return LLDB_INVALID_ADDRESS;
  return m_watchpoint_addr;
}

uint32_t NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints() {
  return 1;
}

#endif // defined(__s390x__) && defined(__linux__)
