summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/Process/Linux/CMakeLists.txt3
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp14
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp245
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h70
-rw-r--r--lldb/source/Plugins/Process/Utility/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp66
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h32
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h137
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h67
-rw-r--r--lldb/source/Target/Platform.cpp6
-rw-r--r--lldb/source/Target/Thread.cpp1
-rw-r--r--lldb/source/Utility/PPC64LE_DWARF_Registers.h63
-rw-r--r--lldb/source/Utility/PPC64LE_ehframe_Registers.h63
13 files changed, 766 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
index 8330cac160e..390dbd9ff8b 100644
--- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
@@ -7,9 +7,10 @@ add_lldb_library(lldbPluginProcessLinux PLUGIN
NativeRegisterContextLinux.cpp
NativeRegisterContextLinux_arm.cpp
NativeRegisterContextLinux_arm64.cpp
- NativeRegisterContextLinux_x86_64.cpp
NativeRegisterContextLinux_mips64.cpp
+ NativeRegisterContextLinux_ppc64le.cpp
NativeRegisterContextLinux_s390x.cpp
+ NativeRegisterContextLinux_x86_64.cpp
NativeThreadLinux.cpp
ProcessorTrace.cpp
SingleStepCheck.cpp
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 170d3b10006..a5dac2a98cf 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1078,7 +1078,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
} else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
m_arch.GetMachine() == llvm::Triple::mips64el ||
m_arch.GetMachine() == llvm::Triple::mips ||
- m_arch.GetMachine() == llvm::Triple::mipsel)
+ m_arch.GetMachine() == llvm::Triple::mipsel ||
+ m_arch.GetMachine() == llvm::Triple::ppc64le)
error = SetSoftwareBreakpoint(next_pc, 4);
else {
// No size hint is given for the next breakpoint
@@ -1579,6 +1580,7 @@ Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_i386_opcode[] = {0xCC};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::x86:
@@ -1590,6 +1592,10 @@ Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
return Status();
+ case llvm::Triple::ppc64le:
+ actual_opcode_size = static_cast<uint32_t>(sizeof(g_ppc64le_opcode));
+ return Status();
+
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::mips64:
@@ -1635,6 +1641,7 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -1680,6 +1687,11 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
actual_opcode_size = sizeof(g_s390x_opcode);
return Status();
+ case llvm::Triple::ppc64le:
+ trap_opcode_bytes = g_ppc64le_opcode;
+ actual_opcode_size = sizeof(g_ppc64le_opcode);
+ return Status();
+
default:
assert(false && "CPU type not supported!");
return Status("CPU type not supported");
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
new file mode 100644
index 00000000000..e6cabef4f1a
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -0,0 +1,245 @@
+//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#include "NativeRegisterContextLinux_ppc64le.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
+
+// System includes - They have to be included after framework includes because
+// they define some
+// macros which collide with variable names in other modules
+#include <sys/socket.h>
+#include <elf.h>
+#include <asm/ptrace.h>
+
+#define REG_CONTEXT_SIZE GetGPRSize()
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+static const uint32_t g_gpr_regnums_ppc64le[] = {
+ gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
+ gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
+ gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
+ gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
+ gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
+ gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
+ gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
+ gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le,
+ gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
+ gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
+ gpr_trap_ppc64le,
+};
+
+namespace {
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 1 };
+}
+
+static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
+ g_gpr_regnums_ppc64le},
+};
+
+NativeRegisterContextLinux *
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return new NativeRegisterContextLinux_ppc64le(target_arch, native_thread,
+ concrete_frame_idx);
+ default:
+ llvm_unreachable("have no register context for architecture");
+ }
+}
+
+NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx)
+ : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ new RegisterInfoPOSIX_ppc64le(target_arch)) {
+ if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ ::memset(&m_gpr_ppc64le, 0, sizeof(m_gpr_ppc64le));
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextLinux_ppc64le::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_ppc64le[set_index];
+
+ return nullptr;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_ppc64le[set_index].num_registers;
+ return count;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (IsGPR(reg)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else {
+ return Status("failed - register wasn't recognized to be a GPR, "
+ "read strategy unknown");
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ return Status("failed - register wasn't recognized to be a GPR, "
+ "write strategy unknown");
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+
+ error = ReadGPR();
+ if (error.Fail())
+ 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;
+ }
+
+ ::memcpy(dst, &m_gpr_ppc64le, GetGPRSize());
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%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_ppc64le::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+
+ ::memcpy(&m_gpr_ppc64le, src, GetGPRSize());
+ error = WriteGPR();
+
+ return error;
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsGPR(unsigned reg) const {
+ return reg <= k_last_gpr_ppc64le; // GPR's come first.
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+#endif // defined(__powerpc64__)
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
new file mode 100644
index 00000000000..d9bad424f44
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
@@ -0,0 +1,70 @@
+//===-- NativeRegisterContextLinux_ppc64le.h ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+#define lldb_NativeRegisterContextLinux_ppc64le_h
+
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+namespace lldb_private {
+namespace process_linux {
+
+class NativeProcessLinux;
+
+class NativeRegisterContextLinux_ppc64le : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_ppc64le(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread,
+ uint32_t concrete_frame_idx);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+protected:
+ Status DoReadGPR(void *buf, size_t buf_size) override;
+
+ Status DoWriteGPR(void *buf, size_t buf_size) override;
+
+ void *GetGPRBuffer() override { return &m_gpr_ppc64le; }
+
+private:
+ GPR m_gpr_ppc64le; // 64-bit general purpose registers.
+
+ bool IsGPR(unsigned reg) const;
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+
+#endif // defined(__powerpc64__)
diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
index bda0ad626f6..dc1cf56d940 100644
--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -44,6 +44,7 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN
RegisterContextThreadMemory.cpp
RegisterInfoPOSIX_arm.cpp
RegisterInfoPOSIX_arm64.cpp
+ RegisterInfoPOSIX_ppc64le.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
UnwindLLDB.cpp
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
new file mode 100644
index 00000000000..e5e7350fe68
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -0,0 +1,66 @@
+//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <cassert>
+#include <stddef.h>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterInfoPOSIX_ppc64le.h"
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfoPOSIX_ppc64le to declare our g_register_infos_ppc64le
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return g_register_infos_ppc64le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return static_cast<uint32_t>(sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterInfoPOSIX_ppc64le::RegisterInfoPOSIX_ppc64le(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+
+size_t RegisterInfoPOSIX_ppc64le::GetGPRSize() const {
+ return sizeof(GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_ppc64le::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+uint32_t RegisterInfoPOSIX_ppc64le::GetRegisterCount() const {
+ return m_register_info_count;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
new file mode 100644
index 00000000000..411ab05c2b1
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
@@ -0,0 +1,32 @@
+//===-- RegisterInfoPOSIX_ppc64le.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_ppc64le_H_
+#define liblldb_RegisterContextLinux_ppc64le_H_
+
+#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
+
+class RegisterInfoPOSIX_ppc64le : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterInfoPOSIX_ppc64le(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+};
+
+#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
new file mode 100644
index 00000000000..4f56b3c3b68
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -0,0 +1,137 @@
+//===-- RegisterInfos_ppc64le.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+// C Includes
+#include <stddef.h>
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) (offsetof(GPR, regname))
+#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
+
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "lldb-ppc64le-register-enums.h"
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+// General purpose registers.
+// EH_Frame, Generic, Process Plugin
+#define POWERPC_REGS \
+ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR(msr, "msr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR(softe, "softe", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(trap, "trap", LLDB_INVALID_REGNUM), \
+ /* */
+
+typedef struct _GPR {
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t r28;
+ uint64_t r29;
+ uint64_t r30;
+ uint64_t r31;
+ uint64_t pc;
+ uint64_t msr;
+ uint64_t origr3;
+ uint64_t ctr;
+ uint64_t lr;
+ uint64_t xer;
+ uint64_t cr;
+ uint64_t softe;
+ uint64_t trap;
+ uint64_t pad[4];
+} GPR;
+
+static lldb_private::RegisterInfo g_register_infos_ppc64le[] = {
+ POWERPC_REGS
+};
+
+static_assert((sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0])) ==
+ k_num_registers_ppc64le,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+
+#undef DEFINE_GPR
+
+#endif // DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
diff --git a/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
new file mode 100644
index 00000000000..36b42737cc6
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
@@ -0,0 +1,67 @@
+//===-- lldb-ppc64le-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_ppc64le_register_enums_h
+#define lldb_ppc64le_register_enums_h
+
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+// ---------------------------------------------------------------------------
+// Internal codes for all ppc64le registers.
+// ---------------------------------------------------------------------------
+enum {
+ k_first_gpr_ppc64le,
+ gpr_r0_ppc64le = k_first_gpr_ppc64le,
+ gpr_r1_ppc64le,
+ gpr_r2_ppc64le,
+ gpr_r3_ppc64le,
+ gpr_r4_ppc64le,
+ gpr_r5_ppc64le,
+ gpr_r6_ppc64le,
+ gpr_r7_ppc64le,
+ gpr_r8_ppc64le,
+ gpr_r9_ppc64le,
+ gpr_r10_ppc64le,
+ gpr_r11_ppc64le,
+ gpr_r12_ppc64le,
+ gpr_r13_ppc64le,
+ gpr_r14_ppc64le,
+ gpr_r15_ppc64le,
+ gpr_r16_ppc64le,
+ gpr_r17_ppc64le,
+ gpr_r18_ppc64le,
+ gpr_r19_ppc64le,
+ gpr_r20_ppc64le,
+ gpr_r21_ppc64le,
+ gpr_r22_ppc64le,
+ gpr_r23_ppc64le,
+ gpr_r24_ppc64le,
+ gpr_r25_ppc64le,
+ gpr_r26_ppc64le,
+ gpr_r27_ppc64le,
+ gpr_r28_ppc64le,
+ gpr_r29_ppc64le,
+ gpr_r30_ppc64le,
+ gpr_r31_ppc64le,
+ gpr_pc_ppc64le,
+ gpr_msr_ppc64le,
+ gpr_origr3_ppc64le,
+ gpr_ctr_ppc64le,
+ gpr_lr_ppc64le,
+ gpr_xer_ppc64le,
+ gpr_cr_ppc64le,
+ gpr_softe_ppc64le,
+ gpr_trap_ppc64le,
+ k_last_gpr_ppc64le = gpr_trap_ppc64le,
+
+ k_num_registers_ppc64le,
+ k_num_gpr_registers_ppc64le = k_last_gpr_ppc64le - k_first_gpr_ppc64le + 1,
+};
+
+#endif // #ifndef lldb_ppc64le_register_enums_h
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 1d7288792a8..ab09517b633 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1878,6 +1878,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
trap_opcode_size = sizeof(g_ppc_opcode);
} break;
+ case llvm::Triple::ppc64le: {
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
+ trap_opcode = g_ppc64le_opcode;
+ trap_opcode_size = sizeof(g_ppc64le_opcode);
+ } break;
+
case llvm::Triple::x86:
case llvm::Triple::x86_64: {
static const uint8_t g_i386_opcode[] = {0xCC};
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 505d14012d6..515c41fd99f 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -2075,6 +2075,7 @@ Unwind *Thread::GetUnwinder() {
case llvm::Triple::mips64el:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
case llvm::Triple::systemz:
case llvm::Triple::hexagon:
m_unwinder_ap.reset(new UnwindLLDB(*this));
diff --git a/lldb/source/Utility/PPC64LE_DWARF_Registers.h b/lldb/source/Utility/PPC64LE_DWARF_Registers.h
new file mode 100644
index 00000000000..583a13d6264
--- /dev/null
+++ b/lldb/source/Utility/PPC64LE_DWARF_Registers.h
@@ -0,0 +1,63 @@
+//===-- PPC64LE_DWARF_Registers.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_PPC64LE_DWARF_Registers_h_
+#define utility_PPC64LE_DWARF_Registers_h_
+
+#include "lldb/lldb-private.h"
+
+namespace ppc64le_dwarf {
+
+enum {
+ dwarf_r0_ppc64le = 0,
+ dwarf_r1_ppc64le,
+ dwarf_r2_ppc64le,
+ dwarf_r3_ppc64le,
+ dwarf_r4_ppc64le,
+ dwarf_r5_ppc64le,
+ dwarf_r6_ppc64le,
+ dwarf_r7_ppc64le,
+ dwarf_r8_ppc64le,
+ dwarf_r9_ppc64le,
+ dwarf_r10_ppc64le,
+ dwarf_r11_ppc64le,
+ dwarf_r12_ppc64le,
+ dwarf_r13_ppc64le,
+ dwarf_r14_ppc64le,
+ dwarf_r15_ppc64le,
+ dwarf_r16_ppc64le,
+ dwarf_r17_ppc64le,
+ dwarf_r18_ppc64le,
+ dwarf_r19_ppc64le,
+ dwarf_r20_ppc64le,
+ dwarf_r21_ppc64le,
+ dwarf_r22_ppc64le,
+ dwarf_r23_ppc64le,
+ dwarf_r24_ppc64le,
+ dwarf_r25_ppc64le,
+ dwarf_r26_ppc64le,
+ dwarf_r27_ppc64le,
+ dwarf_r28_ppc64le,
+ dwarf_r29_ppc64le,
+ dwarf_r30_ppc64le,
+ dwarf_r31_ppc64le,
+ dwarf_lr_ppc64le = 65,
+ dwarf_ctr_ppc64le,
+ dwarf_cr_ppc64le = 68,
+ dwarf_xer_ppc64le = 76,
+ dwarf_pc_ppc64le,
+ dwarf_softe_ppc64le,
+ dwarf_trap_ppc64le,
+ dwarf_origr3_ppc64le,
+ dwarf_msr_ppc64le,
+};
+
+} // namespace ppc64le_dwarf
+
+#endif // utility_PPC64LE_DWARF_Registers_h_
diff --git a/lldb/source/Utility/PPC64LE_ehframe_Registers.h b/lldb/source/Utility/PPC64LE_ehframe_Registers.h
new file mode 100644
index 00000000000..3da740944a3
--- /dev/null
+++ b/lldb/source/Utility/PPC64LE_ehframe_Registers.h
@@ -0,0 +1,63 @@
+//===-- PPC64LE_ehframe_Registers.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_PPC64LE_ehframe_Registers_h_
+#define utility_PPC64LE_ehframe_Registers_h_
+
+// The register numbers used in the eh_frame unwind information.
+// Should be the same as DWARF register numbers.
+
+namespace ppc64le_ehframe {
+
+enum {
+ r0 = 0,
+ r1,
+ r2,
+ r3,
+ r4,
+ r5,
+ r6,
+ r7,
+ r8,
+ r9,
+ r10,
+ r11,
+ r12,
+ r13,
+ r14,
+ r15,
+ r16,
+ r17,
+ r18,
+ r19,
+ r20,
+ r21,
+ r22,
+ r23,
+ r24,
+ r25,
+ r26,
+ r27,
+ r28,
+ r29,
+ r30,
+ r31,
+ lr = 65,
+ ctr,
+ cr = 68,
+ xer = 76,
+ pc,
+ softe,
+ trap,
+ origr3,
+ msr,
+};
+}
+
+#endif // utility_PPC64LE_ehframe_Registers_h_
OpenPOWER on IntegriCloud