//===-- 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 "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.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 */

NativeRegisterContextLinux *
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
                                                                 NativeThreadProtocol &native_thread,
                                                                 uint32_t concrete_frame_idx)
{
    return new NativeRegisterContextLinux_s390x(target_arch, native_thread, concrete_frame_idx);
}

// ----------------------------------------------------------------------------
// 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,
                                                                   uint32_t concrete_frame_idx)
    : NativeRegisterContextLinux(native_thread, concrete_frame_idx, 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);
}

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

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

    if (IsGPR(reg))
    {
        s390_regs regs;
        Error 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 Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
        }
        return Error();
    }

    if (IsFPR(reg))
    {
        s390_fp_regs fp_regs;
        Error 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 Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
        }
        return Error();
    }

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

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

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

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

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

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

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

    if (IsGPR(reg))
    {
        s390_regs regs;
        Error 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 Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
        }
        return DoWriteGPR(&regs, sizeof(regs));
    }

    if (IsFPR(reg))
    {
        s390_fp_regs fp_regs;
        Error 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 Error("unhandled byte size: %" PRIu32, reg_info->byte_size);
        }
        return DoWriteFPR(&fp_regs, sizeof(fp_regs));
    }

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

Error
NativeRegisterContextLinux_s390x::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
{
    Error 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;
}

Error
NativeRegisterContextLinux_s390x::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
{
    Error 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;
}

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

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

Error
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);
}

Error
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);
}

Error
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);
}

Error
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);
}

Error
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);
}

Error
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);
}

Error
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);
}

Error
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);
}

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

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

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

    Error 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 Error();
}

Error
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;
        Error 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 Error();
}

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

    is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;

    return Error();
}

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

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

    Error 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;
}

Error
NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints()
{
    if (ClearHardwareWatchpoint(0))
        return Error();
    return Error("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;

    Error 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__)
