Index: source/Plugins/Process/Linux/CMakeLists.txt =================================================================== --- source/Plugins/Process/Linux/CMakeLists.txt +++ source/Plugins/Process/Linux/CMakeLists.txt @@ -7,9 +7,10 @@ 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 Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1078,7 +1078,8 @@ } 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 @@ // 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 @@ actual_opcode_size = static_cast(sizeof(g_s390x_opcode)); return Status(); + case llvm::Triple::ppc64le: + actual_opcode_size = static_cast(sizeof(g_ppc64le_opcode)); + return Status(); + case llvm::Triple::arm: case llvm::Triple::aarch64: case llvm::Triple::mips64: @@ -1635,6 +1641,7 @@ 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 @@ 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"); Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h =================================================================== --- /dev/null +++ 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 ®_value) override; + + Status WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_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__) Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp =================================================================== --- /dev/null +++ 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 +#include +#include + +#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 ®_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 ®_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 + : ""); + + 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(), + ®set, 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(), + ®set, buf, buf_size); +} + +#endif // defined(__powerpc64__) Index: source/Plugins/Process/Utility/CMakeLists.txt =================================================================== --- source/Plugins/Process/Utility/CMakeLists.txt +++ source/Plugins/Process/Utility/CMakeLists.txt @@ -44,6 +44,7 @@ RegisterContextThreadMemory.cpp RegisterInfoPOSIX_arm.cpp RegisterInfoPOSIX_arm64.cpp + RegisterInfoPOSIX_ppc64le.cpp StopInfoMachException.cpp ThreadMemory.cpp UnwindLLDB.cpp Index: source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h =================================================================== --- /dev/null +++ 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 Index: source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp =================================================================== --- /dev/null +++ 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 +#include +#include + +#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(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; +} Index: source/Plugins/Process/Utility/RegisterInfos_ppc64le.h =================================================================== --- /dev/null +++ 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 + +// 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 Index: source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h =================================================================== --- /dev/null +++ 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 Index: source/Target/Platform.cpp =================================================================== --- source/Target/Platform.cpp +++ source/Target/Platform.cpp @@ -1878,6 +1878,12 @@ 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}; Index: source/Target/Thread.cpp =================================================================== --- source/Target/Thread.cpp +++ source/Target/Thread.cpp @@ -2075,6 +2075,7 @@ 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)); Index: source/Utility/PPC64LE_DWARF_Registers.h =================================================================== --- /dev/null +++ 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_ Index: source/Utility/PPC64LE_ehframe_Registers.h =================================================================== --- /dev/null +++ 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_