//===-- NativeRegisterContextLinux_s390x.cpp ------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

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

#include "NativeRegisterContextLinux_s390x.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include <sys/ptrace.h>
#include <sys/uio.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, NativeThreadLinux &native_thread) {
  return std::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
                                                             native_thread);
}

llvm::Expected<ArchSpec>
NativeRegisterContextLinux::DetermineArchitecture(lldb::tid_t tid) {
  return HostInfo::GetArchitecture();
}

// 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)
    : NativeRegisterContextRegisterInfo(
          native_thread, CreateRegisterInfoInterface(target_arch)),
      NativeRegisterContextLinux(native_thread) {
  // 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::FromErrorString("reg_info NULL");

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

  if (IsGPR(reg)) {
    Status error = ReadGPR();
    if (error.Fail())
      return error;

    uint8_t *src = (uint8_t *)&m_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_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::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
                                               reg_info->byte_size);
    }
    return Status();
  }

  if (IsFPR(reg)) {
    Status error = ReadFPR();
    if (error.Fail())
      return error;

    // byte_offset is just the offset within FPR, not the whole user area.
    uint8_t *src = (uint8_t *)&m_fp_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_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::FromErrorStringWithFormat("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::FromErrorString("failed - register wasn't recognized");
}

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

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

  if (IsGPR(reg)) {
    Status error = ReadGPR();
    if (error.Fail())
      return error;

    uint8_t *dst = (uint8_t *)&m_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_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::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
                                               reg_info->byte_size);
    }
    return WriteGPR();
  }

  if (IsFPR(reg)) {
    Status error = ReadFPR();
    if (error.Fail())
      return error;

    // byte_offset is just the offset within fp_regs, not the whole user area.
    uint8_t *dst = (uint8_t *)&m_fp_regs + reg_info->byte_offset;
    assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(m_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::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
                                               reg_info->byte_size);
    }
    return WriteFPR();
  }

  if (reg == lldb_last_break_s390x) {
    return Status::FromErrorString("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::FromErrorString("failed - register wasn't recognized");
}

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

  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
  uint8_t *dst = data_sp->GetBytes();
  error = ReadGPR();
  if (error.Fail())
    return error;
  memcpy(dst, GetGPRBuffer(), GetGPRSize());
  dst += GetGPRSize();

  error = ReadFPR();
  if (error.Fail())
    return error;
  memcpy(dst, GetFPRBuffer(), GetFPRSize());
  dst += GetFPRSize();

  // 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 = Status::FromErrorStringWithFormat(
        "NativeRegisterContextLinux_s390x::%s invalid data_sp provided",
        __FUNCTION__);
    return error;
  }

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

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

  memcpy(GetGPRBuffer(), src, GetGPRSize());
  src += GetGPRSize();
  error = WriteGPR();
  if (error.Fail())
    return error;

  memcpy(GetFPRBuffer(), src, GetFPRSize());
  src += GetFPRSize();
  error = WriteFPR();
  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::FromErrorString("DoReadRegisterValue unsupported");
}

Status NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
    uint32_t offset, const char *reg_name, const RegisterValue &value) {
  return Status::FromErrorString("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::ReadGPR() {
  return PeekUserArea(offsetof(user_regs_struct, psw), GetGPRBuffer(),
                      GetGPRSize());
}

Status NativeRegisterContextLinux_s390x::WriteGPR() {
  return PokeUserArea(offsetof(user_regs_struct, psw), GetGPRBuffer(),
                      GetGPRSize());
}

Status NativeRegisterContextLinux_s390x::ReadFPR() {
  return PeekUserArea(offsetof(user_regs_struct, fp_regs), GetGPRBuffer(),
                      GetGPRSize());
}

Status NativeRegisterContextLinux_s390x::WriteFPR() {
  return PokeUserArea(offsetof(user_regs_struct, fp_regs), GetGPRBuffer(),
                      GetGPRSize());
}

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::FromErrorString("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::FromErrorString("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::FromErrorString("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__)
