diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2016-04-14 14:28:34 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2016-04-14 14:28:34 +0000 |
commit | bb00d0b6b29a2ab1c59d3040a21f14156d8779df (patch) | |
tree | cbe5c64120aa89abbfd4cfc9e6d54b958f0e85bd /lldb/source/Plugins/Process/Utility | |
parent | 7311bb34f63df58edb4819e5b483b49932b371bd (diff) | |
download | bcm5719-llvm-bb00d0b6b29a2ab1c59d3040a21f14156d8779df.tar.gz bcm5719-llvm-bb00d0b6b29a2ab1c59d3040a21f14156d8779df.zip |
Support Linux on SystemZ as platform
This patch adds support for Linux on SystemZ:
- A new ArchSpec value of eCore_s390x_generic
- A new directory Plugins/ABI/SysV-s390x providing an ABI implementation
- Register context support
- Native Linux support including watchpoint support
- ELF core file support
- Misc. support throughout the code base (e.g. breakpoint opcodes)
- Test case updates to support the platform
This should provide complete support for debugging the SystemZ platform.
Not yet supported are optional features like transaction support (zEC12)
or SIMD vector support (z13).
There is no instruction emulation, since our ABI requires that all code
provide correct DWARF CFI at all PC locations in .eh_frame to support
unwinding (i.e. -fasynchronous-unwind-tables is on by default).
The implementation follows existing platforms in a mostly straightforward
manner. A couple of things that are different:
- We do not use PTRACE_PEEKUSER / PTRACE_POKEUSER to access single registers,
since some registers (access register) reside at offsets in the user area
that are multiples of 4, but the PTRACE_PEEKUSER interface only allows
accessing aligned 8-byte blocks in the user area. Instead, we use a s390
specific ptrace interface PTRACE_PEEKUSR_AREA / PTRACE_POKEUSR_AREA that
allows accessing a whole block of the user area in one go, so in effect
allowing to treat parts of the user area as register sets.
- SystemZ hardware does not provide any means to implement read watchpoints,
only write watchpoints. In fact, we can only support a *single* write
watchpoint (but this can span a range of arbitrary size). In LLDB this
means we support only a single watchpoint. I've set all test cases that
require read watchpoints (or multiple watchpoints) to expected failure
on the platform. [ Note that there were two test cases that install
a read/write watchpoint even though they nowhere rely on the "read"
property. I've changed those to simply use plain write watchpoints. ]
Differential Revision: http://reviews.llvm.org/D18978
llvm-svn: 266308
Diffstat (limited to 'lldb/source/Plugins/Process/Utility')
8 files changed, 829 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt index 28e789ad18d..eb0c81fd797 100644 --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -28,6 +28,7 @@ add_lldb_library(lldbPluginProcessUtility RegisterContextLinux_x86_64.cpp RegisterContextLinux_mips64.cpp RegisterContextLinux_mips.cpp + RegisterContextLinux_s390x.cpp RegisterContextLLDB.cpp RegisterContextMacOSXFrameBackchain.cpp RegisterContextMach_arm.cpp @@ -39,6 +40,7 @@ add_lldb_library(lldbPluginProcessUtility RegisterContextPOSIX_arm64.cpp RegisterContextPOSIX_mips64.cpp RegisterContextPOSIX_powerpc.cpp + RegisterContextPOSIX_s390x.cpp RegisterContextPOSIX_x86.cpp RegisterContextThreadMemory.cpp StopInfoMachException.cpp diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp new file mode 100644 index 00000000000..9aef1e9830e --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp @@ -0,0 +1,98 @@ +//===-- RegisterContextLinux_s390x.cpp --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextPOSIX_s390x.h" +#include "RegisterContextLinux_s390x.h" + +using namespace lldb_private; +using namespace lldb; + +//--------------------------------------------------------------------------- +// Include RegisterInfos_s390x to declare our g_register_infos_s390x structure. +//--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_S390X_STRUCT +#include "RegisterInfos_s390x.h" +#undef DECLARE_REGISTER_INFOS_S390X_STRUCT + +static const RegisterInfo * +GetRegisterInfoPtr(const ArchSpec &target_arch) +{ + switch (target_arch.GetMachine()) + { + case llvm::Triple::systemz: + return g_register_infos_s390x; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +static uint32_t +GetRegisterInfoCount(const ArchSpec &target_arch) +{ + switch (target_arch.GetMachine()) + { + case llvm::Triple::systemz: + return k_num_registers_s390x; + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +static uint32_t +GetUserRegisterInfoCount(const ArchSpec &target_arch) +{ + switch (target_arch.GetMachine()) + { + case llvm::Triple::systemz: + return k_num_user_registers_s390x + k_num_linux_registers_s390x; + default: + assert(false && "Unhandled target architecture."); + return 0; + } +} + +RegisterContextLinux_s390x::RegisterContextLinux_s390x(const ArchSpec &target_arch) + : lldb_private::RegisterInfoInterface(target_arch), + m_register_info_p(GetRegisterInfoPtr(target_arch)), + m_register_info_count(GetRegisterInfoCount(target_arch)), + m_user_register_count(GetUserRegisterInfoCount(target_arch)) +{ +} + +const std::vector<lldb_private::RegisterInfo> * +RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const +{ + return &d_register_infos; +} + +const RegisterInfo * +RegisterContextLinux_s390x::GetRegisterInfo() const +{ + return m_register_info_p; +} + +uint32_t +RegisterContextLinux_s390x::GetRegisterCount() const +{ + return m_register_info_count; +} + +uint32_t +RegisterContextLinux_s390x::GetUserRegisterCount() const +{ + return m_user_register_count; +} + +size_t +RegisterContextLinux_s390x::GetGPRSize() const +{ + return 0; +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h new file mode 100644 index 00000000000..bdc7f34f62e --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h @@ -0,0 +1,42 @@ +//===-- RegisterContextLinux_s390x.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextLinux_s390x_h_ +#define liblldb_RegisterContextLinux_s390x_h_ + +#include "RegisterInfoInterface.h" + +class RegisterContextLinux_s390x : public lldb_private::RegisterInfoInterface +{ +public: + RegisterContextLinux_s390x(const lldb_private::ArchSpec &target_arch); + + size_t + GetGPRSize() const override; + + const lldb_private::RegisterInfo * + GetRegisterInfo() const override; + + uint32_t + GetRegisterCount() const override; + + uint32_t + GetUserRegisterCount() const override; + + const std::vector<lldb_private::RegisterInfo> * + GetDynamicRegisterInfoP() const override; + +private: + const lldb_private::RegisterInfo *m_register_info_p; + uint32_t m_register_info_count; + uint32_t m_user_register_count; + std::vector<lldb_private::RegisterInfo> d_register_infos; +}; + +#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp new file mode 100644 index 00000000000..960be50c7be --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -0,0 +1,265 @@ +//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <cstring> +#include <errno.h> +#include <stdint.h> + +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Host/Endian.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContext_s390x.h" +#include "RegisterContextPOSIX_s390x.h" + +using namespace lldb_private; +using namespace lldb; + +// 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"); + +// Number of register sets provided by this context. +enum +{ + k_num_register_sets = 2 +}; + +// 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 }, +}; + +bool +RegisterContextPOSIX_s390x::IsGPR(unsigned reg) +{ + return reg <= m_reg_info.last_gpr; // GPRs come first. +} + +bool +RegisterContextPOSIX_s390x::IsFPR(unsigned reg) +{ + return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); +} + +RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(Thread &thread, uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) +{ + m_register_info_ap.reset(register_info); + + switch (register_info->m_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; + } +} + +RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() +{ +} + +void +RegisterContextPOSIX_s390x::Invalidate() +{ +} + +void +RegisterContextPOSIX_s390x::InvalidateAllRegisters() +{ +} + +const RegisterInfo * +RegisterContextPOSIX_s390x::GetRegisterInfo() +{ + return m_register_info_ap->GetRegisterInfo(); +} + +const RegisterInfo * +RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) +{ + if (reg < m_reg_info.num_registers) + return &GetRegisterInfo()[reg]; + else + return NULL; +} + +size_t +RegisterContextPOSIX_s390x::GetRegisterCount() +{ + return m_reg_info.num_registers; +} + +unsigned +RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) +{ + assert(reg < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned +RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) +{ + assert(reg < m_reg_info.num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +const char * +RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) +{ + assert(reg < m_reg_info.num_registers && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +bool +RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) +{ + return set_index < k_num_register_sets; +} + +size_t +RegisterContextPOSIX_s390x::GetRegisterSetCount() +{ + size_t sets = 0; + for (size_t set = 0; set < k_num_register_sets; ++set) + { + if (IsRegisterSetAvailable(set)) + ++sets; + } + + return sets; +} + +const RegisterSet * +RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) +{ + if (IsRegisterSetAvailable(set)) + { + switch (m_register_info_ap->m_target_arch.GetMachine()) + { + case llvm::Triple::systemz: + return &g_reg_sets_s390x[set]; + default: + assert(false && "Unhandled target architecture."); + return NULL; + } + } + return NULL; +} + +lldb::ByteOrder +RegisterContextPOSIX_s390x::GetByteOrder() +{ + // Get the target process whose privileged thread was used for the register read. + lldb::ByteOrder byte_order = eByteOrderInvalid; + Process *process = CalculateProcess().get(); + + if (process) + byte_order = process->GetByteOrder(); + return byte_order; +} + +// Used when parsing DWARF and EH frame information and any other +// object file sections that contain register numbers in them. +uint32_t +RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) +{ + const uint32_t num_regs = GetRegisterCount(); + + assert(kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h new file mode 100644 index 00000000000..4904b2857c4 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -0,0 +1,103 @@ +//===-- RegisterContextPOSIX_s390x.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextPOSIX_s390x_h_ +#define liblldb_RegisterContextPOSIX_s390x_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Log.h" +#include "lldb/Target/RegisterContext.h" +#include "RegisterInfoInterface.h" +#include "RegisterContext_s390x.h" +#include "lldb-s390x-register-enums.h" + +class ProcessMonitor; + +class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext +{ +public: + RegisterContextPOSIX_s390x(lldb_private::Thread &thread, uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_s390x() override; + + void + Invalidate(); + + void + InvalidateAllRegisters() override; + + size_t + GetRegisterCount() override; + + virtual unsigned + GetRegisterSize(unsigned reg); + + virtual unsigned + GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo * + GetRegisterInfoAtIndex(size_t reg) override; + + size_t + GetRegisterSetCount() override; + + const lldb_private::RegisterSet * + GetRegisterSet(size_t set) override; + + const char * + GetRegisterName(unsigned reg); + + uint32_t + ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override; + +protected: + struct RegInfo + { + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + }; + + RegInfo m_reg_info; + std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; + + virtual bool + IsRegisterSetAvailable(size_t set_index); + + virtual const lldb_private::RegisterInfo * + GetRegisterInfo(); + + bool + IsGPR(unsigned reg); + + bool + IsFPR(unsigned reg); + + lldb::ByteOrder + GetByteOrder(); + + virtual bool + ReadGPR() = 0; + virtual bool + ReadFPR() = 0; + virtual bool + WriteGPR() = 0; + virtual bool + WriteFPR() = 0; +}; + +#endif // liblldb_RegisterContextPOSIX_s390x_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h new file mode 100644 index 00000000000..9777c774440 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_s390x.h @@ -0,0 +1,93 @@ +//===-- RegisterContext_s390x.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContext_s390x_h_ +#define liblldb_RegisterContext_s390x_h_ + +//--------------------------------------------------------------------------- +// SystemZ ehframe, dwarf regnums +//--------------------------------------------------------------------------- + +// EHFrame and DWARF Register numbers (eRegisterKindEHFrame & eRegisterKindDWARF) +enum +{ + // General Purpose Registers + dwarf_r0_s390x = 0, + dwarf_r1_s390x, + dwarf_r2_s390x, + dwarf_r3_s390x, + dwarf_r4_s390x, + dwarf_r5_s390x, + dwarf_r6_s390x, + dwarf_r7_s390x, + dwarf_r8_s390x, + dwarf_r9_s390x, + dwarf_r10_s390x, + dwarf_r11_s390x, + dwarf_r12_s390x, + dwarf_r13_s390x, + dwarf_r14_s390x, + dwarf_r15_s390x, + // Floating Point Registers / Vector Registers 0-15 + dwarf_f0_s390x = 16, + dwarf_f2_s390x, + dwarf_f4_s390x, + dwarf_f6_s390x, + dwarf_f1_s390x, + dwarf_f3_s390x, + dwarf_f5_s390x, + dwarf_f7_s390x, + dwarf_f8_s390x, + dwarf_f10_s390x, + dwarf_f12_s390x, + dwarf_f14_s390x, + dwarf_f9_s390x, + dwarf_f11_s390x, + dwarf_f13_s390x, + dwarf_f15_s390x, + // Access Registers + dwarf_acr0_s390x = 48, + dwarf_acr1_s390x, + dwarf_acr2_s390x, + dwarf_acr3_s390x, + dwarf_acr4_s390x, + dwarf_acr5_s390x, + dwarf_acr6_s390x, + dwarf_acr7_s390x, + dwarf_acr8_s390x, + dwarf_acr9_s390x, + dwarf_acr10_s390x, + dwarf_acr11_s390x, + dwarf_acr12_s390x, + dwarf_acr13_s390x, + dwarf_acr14_s390x, + dwarf_acr15_s390x, + // Program Status Word + dwarf_pswm_s390x = 64, + dwarf_pswa_s390x, + // Vector Registers 16-31 + dwarf_v16_s390x = 68, + dwarf_v18_s390x, + dwarf_v20_s390x, + dwarf_v22_s390x, + dwarf_v17_s390x, + dwarf_v19_s390x, + dwarf_v21_s390x, + dwarf_v23_s390x, + dwarf_v24_s390x, + dwarf_v26_s390x, + dwarf_v28_s390x, + dwarf_v30_s390x, + dwarf_v25_s390x, + dwarf_v27_s390x, + dwarf_v29_s390x, + dwarf_v31_s390x, +}; + +#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h new file mode 100644 index 00000000000..43152640297 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -0,0 +1,132 @@ +//===-- RegisterInfos_s390x.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +#include <stddef.h> + +// C++ Includes +// Other libraries and framework includes +#include "llvm/Support/Compiler.h" + +// Project includes + +#ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(num) (16 + 8 * num) +// Computes the offset of the given ACR in the user data area. +#define ACR_OFFSET(num) (16 + 8 * 16 + 4 * num) +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(num) (8 + 8 * num) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +#define DEFINE_GPR(name, size, offset, alt, generic) \ + { \ + #name, alt, size, offset, eEncodingUint, eFormatHex, \ + { dwarf_##name##_s390x, dwarf_##name##_s390x, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, \ + } + +#define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \ + { \ + #name, alt, size, offset, eEncodingUint, eFormatHex, \ + { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, \ + } + +#define DEFINE_FPR(name, size, offset) \ + { \ + #name, NULL, size, offset, eEncodingUint, eFormatHex, \ + { dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, \ + } + +#define DEFINE_FPR_NODWARF(name, size, offset) \ + { \ + #name, NULL, size, offset, eEncodingUint, eFormatHex, \ + { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ + NULL, NULL, \ + } + +static RegisterInfo g_register_infos_s390x[] = +{ + // General purpose registers. + DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r2, 8, GPR_OFFSET(2), "arg1", LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR(r3, 8, GPR_OFFSET(3), "arg2", LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR(r4, 8, GPR_OFFSET(4), "arg3", LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR(r5, 8, GPR_OFFSET(5), "arg4", LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR(r6, 8, GPR_OFFSET(6), "arg5", LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR(r7, 8, GPR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, 8, GPR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, 8, GPR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, 8, GPR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, 8, GPR_OFFSET(11), "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR(r12, 8, GPR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, 8, GPR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, 8, GPR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, 8, GPR_OFFSET(15), "sp", LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR(acr0, 4, ACR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr1, 4, ACR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr2, 4, ACR_OFFSET(2), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr3, 4, ACR_OFFSET(3), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr4, 4, ACR_OFFSET(4), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr5, 4, ACR_OFFSET(5), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr6, 4, ACR_OFFSET(6), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr7, 4, ACR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr8, 4, ACR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr9, 4, ACR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr10, 4, ACR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr11, 4, ACR_OFFSET(11), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr12, 4, ACR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr13, 4, ACR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr14, 4, ACR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(acr15, 4, ACR_OFFSET(15), nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR(pswm, 8, 0, "flags", LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_GPR(pswa, 8, 8, "pc", LLDB_REGNUM_GENERIC_PC), + + // Floating point registers. + DEFINE_FPR(f0, 8, FPR_OFFSET(0)), + DEFINE_FPR(f1, 8, FPR_OFFSET(1)), + DEFINE_FPR(f2, 8, FPR_OFFSET(2)), + DEFINE_FPR(f3, 8, FPR_OFFSET(3)), + DEFINE_FPR(f4, 8, FPR_OFFSET(4)), + DEFINE_FPR(f5, 8, FPR_OFFSET(5)), + DEFINE_FPR(f6, 8, FPR_OFFSET(6)), + DEFINE_FPR(f7, 8, FPR_OFFSET(7)), + DEFINE_FPR(f8, 8, FPR_OFFSET(8)), + DEFINE_FPR(f9, 8, FPR_OFFSET(9)), + DEFINE_FPR(f10, 8, FPR_OFFSET(10)), + DEFINE_FPR(f11, 8, FPR_OFFSET(11)), + DEFINE_FPR(f12, 8, FPR_OFFSET(12)), + DEFINE_FPR(f13, 8, FPR_OFFSET(13)), + DEFINE_FPR(f14, 8, FPR_OFFSET(14)), + DEFINE_FPR(f15, 8, FPR_OFFSET(15)), + DEFINE_FPR_NODWARF(fpc, 4, 0), + + // Linux operating-specific info. + DEFINE_GPR_NODWARF(orig_r2, 8, 16 + 16 * 8 + 16 * 4, nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR_NODWARF(last_break, 8, 0, nullptr, LLDB_INVALID_REGNUM), + DEFINE_GPR_NODWARF(system_call, 4, 0, nullptr, LLDB_INVALID_REGNUM), +}; + +static_assert((sizeof(g_register_infos_s390x) / sizeof(g_register_infos_s390x[0])) == k_num_registers_s390x, + "g_register_infos_s390x has wrong number of register infos"); + +#undef GPR_OFFSET +#undef ACR_OFFSET +#undef FPR_OFFSET +#undef DEFINE_GPR +#undef DEFINE_GPR_NODWARF +#undef DEFINE_FPR +#undef DEFINE_FPR_NODWARF + +#endif // DECLARE_REGISTER_INFOS_S390X_STRUCT diff --git a/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h new file mode 100644 index 00000000000..174daa25e21 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/lldb-s390x-register-enums.h @@ -0,0 +1,94 @@ +//===-- lldb-s390x-register-enums.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_s390x_register_enums_h +#define lldb_s390x_register_enums_h + +namespace lldb_private +{ +// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) + +//--------------------------------------------------------------------------- +// Internal codes for all s390x registers. +//--------------------------------------------------------------------------- +enum +{ + k_first_gpr_s390x, + lldb_r0_s390x = k_first_gpr_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, + k_last_gpr_s390x = lldb_pswa_s390x, + + k_first_fpr_s390x, + lldb_f0_s390x = k_first_fpr_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, + k_last_fpr_s390x = lldb_fpc_s390x, + + // These are only available on Linux. + k_first_linux_s390x, + lldb_orig_r2_s390x = k_first_linux_s390x, + lldb_last_break_s390x, + lldb_system_call_s390x, + k_last_linux_s390x = lldb_system_call_s390x, + + k_num_registers_s390x, + k_num_gpr_registers_s390x = k_last_gpr_s390x - k_first_gpr_s390x + 1, + k_num_fpr_registers_s390x = k_last_fpr_s390x - k_first_fpr_s390x + 1, + k_num_linux_registers_s390x = k_last_linux_s390x - k_first_linux_s390x + 1, + k_num_user_registers_s390x = k_num_gpr_registers_s390x + k_num_fpr_registers_s390x, +}; +} + +#endif // #ifndef lldb_s390x_register_enums_h |