[Lldb-commits] [lldb] r220944 - First cut of PowerPC(64) support in LLDB.

Justin Hibbits jrh29 at alumni.cwru.edu
Thu Oct 30 19:34:29 PDT 2014


Author: jhibbits
Date: Thu Oct 30 21:34:28 2014
New Revision: 220944

URL: http://llvm.org/viewvc/llvm-project?rev=220944&view=rev
Log:
First cut of PowerPC(64) support in LLDB.

Summary:
This adds preliminary support for PowerPC/PowerPC64, for FreeBSD.  There are
some issues still:

 * Breakpoints don't work well on powerpc64.
 * Shared libraries don't yet get loaded for a 32-bit process on powerpc64 host.
 * Backtraces don't work.  This is due to PowerPC ABI using a backchain pointer
   in memory, instead of a dedicated frame pointer register for the backchain.
 * Breakpoints on functions without debug info may not work correctly for 32-bit
   powerpc.

Reviewers: emaste, tfiala, jingham, clayborg

Reviewed By: clayborg

Subscribers: emaste, lldb-commits

Differential Revision: http://reviews.llvm.org/D5988

Added:
    lldb/trunk/source/Plugins/ABI/SysV-ppc/
    lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
    lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
    lldb/trunk/source/Plugins/ABI/SysV-ppc/CMakeLists.txt
    lldb/trunk/source/Plugins/ABI/SysV-ppc/Makefile
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/Makefile
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContext_powerpc.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
    lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
    lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
Modified:
    lldb/trunk/lib/Makefile
    lldb/trunk/source/CMakeLists.txt
    lldb/trunk/source/Core/ArchSpec.cpp
    lldb/trunk/source/Host/freebsd/Host.cpp
    lldb/trunk/source/Plugins/ABI/CMakeLists.txt
    lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
    lldb/trunk/source/Plugins/Makefile
    lldb/trunk/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
    lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
    lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/lldb.cpp

Modified: lldb/trunk/lib/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lib/Makefile?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/lib/Makefile (original)
+++ lldb/trunk/lib/Makefile Thu Oct 30 21:34:28 2014
@@ -34,6 +34,7 @@ USEDLIBS = lldbAPI.a \
 	lldbPluginABIMacOSX_arm.a \
 	lldbPluginABIMacOSX_arm64.a \
 	lldbPluginABIMacOSX_i386.a \
+	lldbPluginABISysV_ppc64.a \
 	lldbPluginABISysV_x86_64.a \
 	lldbPluginABISysV_hexagon.a \
 	lldbPluginDisassemblerLLVM.a \

Modified: lldb/trunk/source/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/CMakeLists.txt?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/CMakeLists.txt (original)
+++ lldb/trunk/source/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -80,6 +80,8 @@ set( LLDB_USED_LIBS
   lldbPluginABIMacOSX_i386
   lldbPluginABISysV_x86_64
   lldbPluginABISysV_hexagon
+  lldbPluginABISysV_ppc
+  lldbPluginABISysV_ppc64
   lldbPluginInstructionARM
   lldbPluginInstructionARM64
   lldbPluginObjectFilePECOFF

Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Thu Oct 30 21:34:28 2014
@@ -19,6 +19,7 @@
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Host.h"
 #include "lldb/Utility/SafeMachO.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/StringList.h"
 #include "lldb/Host/Endian.h"
@@ -84,7 +85,7 @@ static const CoreDefinition g_core_defin
 
     { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64          , "mips64"    },
     
-    { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_generic     , "ppc"       },
+    { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_generic     , "powerpc"   },
     { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc601      , "ppc601"    },
     { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc602      , "ppc602"    },
     { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc603      , "ppc603"    },
@@ -98,7 +99,7 @@ static const CoreDefinition g_core_defin
     { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc7450     , "ppc7450"   },
     { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc970      , "ppc970"    },
     
-    { eByteOrderBig   , 8, 4, 4, llvm::Triple::ppc64  , ArchSpec::eCore_ppc64_generic   , "ppc64"     },
+    { eByteOrderBig   , 8, 4, 4, llvm::Triple::ppc64  , ArchSpec::eCore_ppc64_generic   , "powerpc64" },
     { eByteOrderBig   , 8, 4, 4, llvm::Triple::ppc64  , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
     
     { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc  , ArchSpec::eCore_sparc_generic   , "sparc"     },

Modified: lldb/trunk/source/Host/freebsd/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/freebsd/Host.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Host/freebsd/Host.cpp (original)
+++ lldb/trunk/source/Host/freebsd/Host.cpp Thu Oct 30 21:34:28 2014
@@ -286,6 +286,49 @@ Host::GetProcessInfo (lldb::pid_t pid, P
     return false;
 }
 
+static lldb::DataBufferSP
+GetAuxvData32(lldb_private::Process *process)
+{
+    struct {
+        uint32_t ps_argvstr;
+        int ps_nargvstr;
+        uint32_t ps_envstr;
+        int ps_nenvstr;
+    } ps_strings;
+    void *ps_strings_addr, *auxv_addr;
+    struct privElf32_Auxinfo { int a_type; unsigned int a_val; } aux_info32[AT_COUNT];
+    struct ptrace_io_desc pid;
+    DataBufferSP buf_sp;
+    std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+    ps_strings_addr = (void *)0xffffdff0;
+    pid.piod_op = PIOD_READ_D;
+    pid.piod_addr = &ps_strings;
+    pid.piod_offs = ps_strings_addr;
+    pid.piod_len = sizeof(ps_strings);
+    if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
+        perror("failed to fetch ps_strings");
+        buf_ap.release();
+        goto done;
+    }
+
+    auxv_addr = (void *)(ps_strings.ps_envstr + sizeof(uint32_t) * (ps_strings.ps_nenvstr + 1));
+
+    pid.piod_addr = aux_info32;
+    pid.piod_offs = auxv_addr;
+    pid.piod_len = sizeof(aux_info32);
+    if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
+        perror("failed to fetch aux_info");
+        buf_ap.release();
+        goto done;
+    }
+    memcpy(buf_ap->GetBytes(), aux_info32, pid.piod_len);
+    buf_sp.reset(buf_ap.release());
+
+    done:
+    return buf_sp;
+}
+
 lldb::DataBufferSP
 Host::GetAuxvData(lldb_private::Process *process)
 {
@@ -296,6 +339,10 @@ Host::GetAuxvData(lldb_private::Process
    struct ps_strings ps_strings;
    struct ptrace_io_desc pid;
    DataBufferSP buf_sp;
+
+   if (process->GetAddressByteSize() < HostInfo::GetArchitecture().GetAddressByteSize())
+           return GetAuxvData32(process);
+
    std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
 
    if (::sysctl(mib, 2, &ps_strings_addr, &ps_strings_size, NULL, 0) == 0) {

Modified: lldb/trunk/source/Plugins/ABI/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/CMakeLists.txt?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/ABI/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -1,4 +1,6 @@
 add_subdirectory(SysV-hexagon)
+add_subdirectory(SysV-ppc64)
+add_subdirectory(SysV-ppc)
 add_subdirectory(SysV-x86_64)
 add_subdirectory(MacOSX-i386)
 add_subdirectory(MacOSX-arm)

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,1097 @@
+//===-- ABISysV_ppc.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABISysV_ppc.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum gcc_dwarf_regnums
+{
+    gcc_dwarf_r0 = 0,
+    gcc_dwarf_r1,
+    gcc_dwarf_r2,
+    gcc_dwarf_r3,
+    gcc_dwarf_r4,
+    gcc_dwarf_r5,
+    gcc_dwarf_r6,
+    gcc_dwarf_r7,
+    gcc_dwarf_r8,
+    gcc_dwarf_r9,
+    gcc_dwarf_r10,
+    gcc_dwarf_r11,
+    gcc_dwarf_r12,
+    gcc_dwarf_r13,
+    gcc_dwarf_r14,
+    gcc_dwarf_r15,
+    gcc_dwarf_r16,
+    gcc_dwarf_r17,
+    gcc_dwarf_r18,
+    gcc_dwarf_r19,
+    gcc_dwarf_r20,
+    gcc_dwarf_r21,
+    gcc_dwarf_r22,
+    gcc_dwarf_r23,
+    gcc_dwarf_r24,
+    gcc_dwarf_r25,
+    gcc_dwarf_r26,
+    gcc_dwarf_r27,
+    gcc_dwarf_r28,
+    gcc_dwarf_r29,
+    gcc_dwarf_r30,
+    gcc_dwarf_r31,
+    gcc_dwarf_f0,
+    gcc_dwarf_f1,
+    gcc_dwarf_f2,
+    gcc_dwarf_f3,
+    gcc_dwarf_f4,
+    gcc_dwarf_f5,
+    gcc_dwarf_f6,
+    gcc_dwarf_f7,
+    gcc_dwarf_f8,
+    gcc_dwarf_f9,
+    gcc_dwarf_f10,
+    gcc_dwarf_f11,
+    gcc_dwarf_f12,
+    gcc_dwarf_f13,
+    gcc_dwarf_f14,
+    gcc_dwarf_f15,
+    gcc_dwarf_f16,
+    gcc_dwarf_f17,
+    gcc_dwarf_f18,
+    gcc_dwarf_f19,
+    gcc_dwarf_f20,
+    gcc_dwarf_f21,
+    gcc_dwarf_f22,
+    gcc_dwarf_f23,
+    gcc_dwarf_f24,
+    gcc_dwarf_f25,
+    gcc_dwarf_f26,
+    gcc_dwarf_f27,
+    gcc_dwarf_f28,
+    gcc_dwarf_f29,
+    gcc_dwarf_f30,
+    gcc_dwarf_f31,
+    gcc_dwarf_cr,
+    gcc_dwarf_fpscr,
+    gcc_dwarf_xer = 101,
+    gcc_dwarf_lr = 108,
+    gcc_dwarf_ctr,
+    gcc_dwarf_pc,
+    gcc_dwarf_cfa,
+};
+
+enum gdb_regnums
+{
+    gdb_r0 = 0,
+    gdb_r1,
+    gdb_r2,
+    gdb_r3,
+    gdb_r4,
+    gdb_r5,
+    gdb_r6,
+    gdb_r7,
+    gdb_r8,
+    gdb_r9,
+    gdb_r10,
+    gdb_r11,
+    gdb_r12,
+    gdb_r13,
+    gdb_r14,
+    gdb_r15,
+    gdb_r16,
+    gdb_r17,
+    gdb_r18,
+    gdb_r19,
+    gdb_r20,
+    gdb_r21,
+    gdb_r22,
+    gdb_r23,
+    gdb_r24,
+    gdb_r25,
+    gdb_r26,
+    gdb_r27,
+    gdb_r28,
+    gdb_r29,
+    gdb_r30,
+    gdb_r31,
+    gdb_lr,
+    gdb_cr,
+    gdb_xer,
+    gdb_ctr,
+    gdb_pc,
+};
+
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)           \
+    { #reg, alt, 8, 0, eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4}, NULL, NULL }
+static const RegisterInfo
+g_register_infos[] =
+{
+    // General purpose registers.                 GCC,                  DWARF,              Generic,                GDB
+    DEFINE_GPR(r0,       NULL,  gcc_dwarf_r0,    gcc_dwarf_r0,    LLDB_INVALID_REGNUM,    gdb_r0),
+    DEFINE_GPR(r1,       "sp",  gcc_dwarf_r1,    gcc_dwarf_r1,    LLDB_REGNUM_GENERIC_SP, gdb_r1),
+    DEFINE_GPR(r2,       NULL,  gcc_dwarf_r2,    gcc_dwarf_r2,    LLDB_INVALID_REGNUM,    gdb_r2),
+    DEFINE_GPR(r3,       "arg1",gcc_dwarf_r3,    gcc_dwarf_r3,    LLDB_REGNUM_GENERIC_ARG1, gdb_r3),
+    DEFINE_GPR(r4,       "arg2",gcc_dwarf_r4,    gcc_dwarf_r4,    LLDB_REGNUM_GENERIC_ARG2 ,gdb_r4),
+    DEFINE_GPR(r5,       "arg3",gcc_dwarf_r5,    gcc_dwarf_r5,    LLDB_REGNUM_GENERIC_ARG3, gdb_r5),
+    DEFINE_GPR(r6,       "arg4",gcc_dwarf_r6,    gcc_dwarf_r6,    LLDB_REGNUM_GENERIC_ARG4, gdb_r6),
+    DEFINE_GPR(r7,       "arg5",gcc_dwarf_r7,    gcc_dwarf_r7,    LLDB_REGNUM_GENERIC_ARG5, gdb_r7),
+    DEFINE_GPR(r8,       "arg6",gcc_dwarf_r8,    gcc_dwarf_r8,    LLDB_REGNUM_GENERIC_ARG6, gdb_r8),
+    DEFINE_GPR(r9,       "arg7",gcc_dwarf_r9,    gcc_dwarf_r9,    LLDB_REGNUM_GENERIC_ARG7, gdb_r9),
+    DEFINE_GPR(r10,      "arg8",gcc_dwarf_r10,   gcc_dwarf_r10,   LLDB_REGNUM_GENERIC_ARG8, gdb_r10),
+    DEFINE_GPR(r11,      NULL,  gcc_dwarf_r11,   gcc_dwarf_r11,   LLDB_INVALID_REGNUM,    gdb_r11),
+    DEFINE_GPR(r12,      NULL,  gcc_dwarf_r12,   gcc_dwarf_r12,   LLDB_INVALID_REGNUM,    gdb_r12),
+    DEFINE_GPR(r13,      NULL,  gcc_dwarf_r13,   gcc_dwarf_r13,   LLDB_INVALID_REGNUM,    gdb_r13),
+    DEFINE_GPR(r14,      NULL,  gcc_dwarf_r14,   gcc_dwarf_r14,   LLDB_INVALID_REGNUM,    gdb_r14),
+    DEFINE_GPR(r15,      NULL,  gcc_dwarf_r15,   gcc_dwarf_r15,   LLDB_INVALID_REGNUM,    gdb_r15),
+    DEFINE_GPR(r16,      NULL,  gcc_dwarf_r16,   gcc_dwarf_r16,   LLDB_INVALID_REGNUM,    gdb_r16),
+    DEFINE_GPR(r17,      NULL,  gcc_dwarf_r17,   gcc_dwarf_r17,   LLDB_INVALID_REGNUM,    gdb_r17),
+    DEFINE_GPR(r18,      NULL,  gcc_dwarf_r18,   gcc_dwarf_r18,   LLDB_INVALID_REGNUM,    gdb_r18),
+    DEFINE_GPR(r19,      NULL,  gcc_dwarf_r19,   gcc_dwarf_r19,   LLDB_INVALID_REGNUM,    gdb_r19),
+    DEFINE_GPR(r20,      NULL,  gcc_dwarf_r20,   gcc_dwarf_r20,   LLDB_INVALID_REGNUM,    gdb_r20),
+    DEFINE_GPR(r21,      NULL,  gcc_dwarf_r21,   gcc_dwarf_r21,   LLDB_INVALID_REGNUM,    gdb_r21),
+    DEFINE_GPR(r22,      NULL,  gcc_dwarf_r22,   gcc_dwarf_r22,   LLDB_INVALID_REGNUM,    gdb_r22),
+    DEFINE_GPR(r23,      NULL,  gcc_dwarf_r23,   gcc_dwarf_r23,   LLDB_INVALID_REGNUM,    gdb_r23),
+    DEFINE_GPR(r24,      NULL,  gcc_dwarf_r24,   gcc_dwarf_r24,   LLDB_INVALID_REGNUM,    gdb_r24),
+    DEFINE_GPR(r25,      NULL,  gcc_dwarf_r25,   gcc_dwarf_r25,   LLDB_INVALID_REGNUM,    gdb_r25),
+    DEFINE_GPR(r26,      NULL,  gcc_dwarf_r26,   gcc_dwarf_r26,   LLDB_INVALID_REGNUM,    gdb_r26),
+    DEFINE_GPR(r27,      NULL,  gcc_dwarf_r27,   gcc_dwarf_r27,   LLDB_INVALID_REGNUM,    gdb_r27),
+    DEFINE_GPR(r28,      NULL,  gcc_dwarf_r28,   gcc_dwarf_r28,   LLDB_INVALID_REGNUM,    gdb_r28),
+    DEFINE_GPR(r29,      NULL,  gcc_dwarf_r29,   gcc_dwarf_r29,   LLDB_INVALID_REGNUM,    gdb_r29),
+    DEFINE_GPR(r30,      NULL,  gcc_dwarf_r30,   gcc_dwarf_r30,   LLDB_INVALID_REGNUM,    gdb_r30),
+    DEFINE_GPR(r31,      NULL,  gcc_dwarf_r31,   gcc_dwarf_r31,   LLDB_INVALID_REGNUM,    gdb_r31),
+    DEFINE_GPR(lr,       "lr",  gcc_dwarf_lr,    gcc_dwarf_lr,    LLDB_REGNUM_GENERIC_RA, gdb_lr),
+    DEFINE_GPR(cr,       "cr",  gcc_dwarf_cr,    gcc_dwarf_cr,    LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+    DEFINE_GPR(xer,      "xer", gcc_dwarf_xer,   gcc_dwarf_xer,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM),
+    DEFINE_GPR(ctr,      "ctr", gcc_dwarf_ctr,   gcc_dwarf_ctr,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM),
+    DEFINE_GPR(pc,       "pc",  gcc_dwarf_pc,    gcc_dwarf_pc,    LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+    { NULL, NULL, 8, 0, eEncodingUint, eFormatHex, { gcc_dwarf_cfa, gcc_dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, NULL, NULL},
+};
+
+static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+
+const lldb_private::RegisterInfo *
+ABISysV_ppc::GetRegisterInfoArray (uint32_t &count)
+{
+    count = k_num_register_infos;
+    return g_register_infos;
+}
+
+
+size_t
+ABISysV_ppc::GetRedZoneSize () const
+{
+    return 224;
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+ABISP
+ABISysV_ppc::CreateInstance (const ArchSpec &arch)
+{
+    static ABISP g_abi_sp;
+    if (arch.GetTriple().getArch() == llvm::Triple::ppc)
+    {
+        if (!g_abi_sp)
+            g_abi_sp.reset (new ABISysV_ppc);
+        return g_abi_sp;
+    }
+    return ABISP();
+}
+
+bool
+ABISysV_ppc::PrepareTrivialCall (Thread &thread,
+                                    addr_t sp,
+                                    addr_t func_addr,
+                                    addr_t return_addr,
+                                    llvm::ArrayRef<addr_t> args) const
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    if (log)
+    {
+        StreamString s;
+        s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+                    thread.GetID(),
+                    (uint64_t)sp,
+                    (uint64_t)func_addr,
+                    (uint64_t)return_addr);
+
+        for (size_t i = 0; i < args.size(); ++i)
+            s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
+        s.PutCString (")");
+        log->PutCString(s.GetString().c_str());
+    }
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return false;
+
+    const RegisterInfo *reg_info = NULL;
+
+    if (args.size() > 8) // TODO handle more than 8 arguments
+        return false;
+
+    for (size_t i = 0; i < args.size(); ++i)
+    {
+        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+        if (log)
+            log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
+        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+            return false;
+    }
+
+    // First, align the SP
+
+    if (log)
+        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+
+    sp &= ~(0xfull); // 16-byte alignment
+
+    sp -= 8;
+
+    Error error;
+    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+    ProcessSP process_sp (thread.GetProcess());
+
+    RegisterValue reg_value;
+
+#if 0
+    // This code adds an extra frame so that we don't lose the function that we came from
+    // by pushing the PC and the FP and then writing the current FP to point to the FP value
+    // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
+
+    // Save current PC
+    const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+    if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
+    {
+        if (log)
+            log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
+
+        if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
+            return false;
+
+        sp -= 8;
+
+        // Save current FP
+        if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
+        {
+            if (log)
+                log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
+
+            if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
+                return false;
+        }
+        // Setup FP backchain
+        reg_value.SetUInt64 (sp);
+
+        if (log)
+            log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
+
+        if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
+        {
+            return false;
+        }
+
+        sp -= 8;
+    }
+#endif
+
+    if (log)
+        log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
+
+    // Save return address onto the stack
+    if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+        return false;
+
+    // %r1 is set to the actual stack value.
+
+    if (log)
+        log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+
+    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
+        return false;
+
+    // %pc is set to the address of the called function.
+
+    if (log)
+        log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+
+    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
+        return false;
+
+    return true;
+}
+
+static bool ReadIntegerArgument(Scalar           &scalar,
+                                unsigned int     bit_width,
+                                bool             is_signed,
+                                Thread           &thread,
+                                uint32_t         *argument_register_ids,
+                                unsigned int     &current_argument_register,
+                                addr_t           &current_stack_argument)
+{
+    if (bit_width > 64)
+        return false; // Scalar can't hold large integer arguments
+
+    if (current_argument_register < 6)
+    {
+        scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
+        current_argument_register++;
+        if (is_signed)
+            scalar.SignExtend (bit_width);
+    }
+    else
+    {
+        uint32_t byte_size = (bit_width + (8-1))/8;
+        Error error;
+        if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
+        {
+            current_stack_argument += byte_size;
+            return true;
+        }
+        return false;
+    }
+    return true;
+}
+
+bool
+ABISysV_ppc::GetArgumentValues (Thread &thread,
+                                   ValueList &values) const
+{
+    unsigned int num_values = values.GetSize();
+    unsigned int value_index;
+
+    // Extract the register context so we can read arguments from registers
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+    if (!reg_ctx)
+        return false;
+
+    // Get the pointer to the first stack argument so we have a place to start
+    // when reading data
+
+    addr_t sp = reg_ctx->GetSP(0);
+
+    if (!sp)
+        return false;
+
+    addr_t current_stack_argument = sp + 48; // jump over return address
+
+    uint32_t argument_register_ids[8];
+
+    argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
+    argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
+    argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
+    argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
+    argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
+    argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
+    argument_register_ids[6] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)->kinds[eRegisterKindLLDB];
+    argument_register_ids[7] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)->kinds[eRegisterKindLLDB];
+
+    unsigned int current_argument_register = 0;
+
+    for (value_index = 0;
+         value_index < num_values;
+         ++value_index)
+    {
+        Value *value = values.GetValueAtIndex(value_index);
+
+        if (!value)
+            return false;
+
+        // We currently only support extracting values with Clang QualTypes.
+        // Do we care about others?
+        ClangASTType clang_type = value->GetClangType();
+        if (!clang_type)
+            return false;
+        bool is_signed;
+
+        if (clang_type.IsIntegerType (is_signed))
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                is_signed,
+                                thread,
+                                argument_register_ids,
+                                current_argument_register,
+                                current_stack_argument);
+        }
+        else if (clang_type.IsPointerType ())
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                false,
+                                thread,
+                                argument_register_ids,
+                                current_argument_register,
+                                current_stack_argument);
+        }
+    }
+
+    return true;
+}
+
+Error
+ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+
+    ClangASTType clang_type = new_value_sp->GetClangType();
+    if (!clang_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+
+    Thread *thread = frame_sp->GetThread().get();
+
+    bool is_signed;
+    uint32_t count;
+    bool is_complex;
+
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+    bool set_it_simple = false;
+    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
+    {
+        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+
+        DataExtractor data;
+        Error data_error;
+        size_t num_bytes = new_value_sp->GetData(data, data_error);
+        if (data_error.Fail())
+        {
+            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+            return error;
+        }
+        lldb::offset_t offset = 0;
+        if (num_bytes <= 8)
+        {
+            uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+            if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
+                set_it_simple = true;
+        }
+        else
+        {
+            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+        }
+
+    }
+    else if (clang_type.IsFloatingPointType (count, is_complex))
+    {
+        if (is_complex)
+            error.SetErrorString ("We don't support returning complex values at present");
+        else
+        {
+            size_t bit_width = clang_type.GetBitSize();
+            if (bit_width <= 64)
+            {
+                DataExtractor data;
+                Error data_error;
+                size_t num_bytes = new_value_sp->GetData(data, data_error);
+                if (data_error.Fail())
+                {
+                    error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+                    return error;
+                }
+
+                unsigned char buffer[16];
+                ByteOrder byte_order = data.GetByteOrder();
+
+                data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
+                set_it_simple = true;
+            }
+            else
+            {
+                // FIXME - don't know how to do 80 bit long doubles yet.
+                error.SetErrorString ("We don't support returning float values > 64 bits at present");
+            }
+        }
+    }
+
+    if (!set_it_simple)
+    {
+        // Okay we've got a structure or something that doesn't fit in a simple register.
+        // We should figure out where it really goes, but we don't support this yet.
+        error.SetErrorString ("We only support setting simple integer and float return types at present.");
+    }
+
+    return error;
+}
+
+
+ValueObjectSP
+ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
+                                            ClangASTType &return_clang_type) const
+{
+    ValueObjectSP return_valobj_sp;
+    Value value;
+
+    if (!return_clang_type)
+        return return_valobj_sp;
+
+    //value.SetContext (Value::eContextTypeClangType, return_value_type);
+    value.SetClangType (return_clang_type);
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return return_valobj_sp;
+
+    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
+    if (type_flags & eTypeIsScalar)
+    {
+        value.SetValueType(Value::eValueTypeScalar);
+
+        bool success = false;
+        if (type_flags & eTypeIsInteger)
+        {
+            // Extract the register context so we can read arguments from registers
+
+            const size_t byte_size = return_clang_type.GetByteSize();
+            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
+            const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+            switch (byte_size)
+            {
+            default:
+                break;
+
+            case sizeof(uint64_t):
+                if (is_signed)
+                    value.GetScalar() = (int64_t)(raw_value);
+                else
+                    value.GetScalar() = (uint64_t)(raw_value);
+                success = true;
+                break;
+
+            case sizeof(uint32_t):
+                if (is_signed)
+                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+                else
+                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint16_t):
+                if (is_signed)
+                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+                else
+                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint8_t):
+                if (is_signed)
+                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+                else
+                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+                success = true;
+                break;
+            }
+        }
+        else if (type_flags & eTypeIsFloat)
+        {
+            if (type_flags & eTypeIsComplex)
+            {
+                // Don't handle complex yet.
+            }
+            else
+            {
+            }
+        }
+
+        if (success)
+            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                               value,
+                                                               ConstString(""));
+
+    }
+    else if (type_flags & eTypeIsPointer)
+    {
+        unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+        value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+        value.SetValueType(Value::eValueTypeScalar);
+        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                           value,
+                                                           ConstString(""));
+    }
+    else if (type_flags & eTypeIsVector)
+    {
+        const size_t byte_size = return_clang_type.GetByteSize();
+        if (byte_size > 0)
+        {
+
+            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
+            if (altivec_reg == NULL)
+                altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+            if (altivec_reg)
+            {
+                if (byte_size <= altivec_reg->byte_size)
+                {
+                    ProcessSP process_sp (thread.GetProcess());
+                    if (process_sp)
+                    {
+                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+                        const ByteOrder byte_order = process_sp->GetByteOrder();
+                        RegisterValue reg_value;
+                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
+                        {
+                            Error error;
+                            if (reg_value.GetAsMemoryData (altivec_reg,
+                                                           heap_data_ap->GetBytes(),
+                                                           heap_data_ap->GetByteSize(),
+                                                           byte_order,
+                                                           error))
+                            {
+                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
+                                                    byte_order,
+                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
+                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                                   return_clang_type,
+                                                                                   ConstString(""),
+                                                                                   data);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return return_valobj_sp;
+}
+
+ValueObjectSP
+ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
+{
+    ValueObjectSP return_valobj_sp;
+
+    if (!return_clang_type)
+        return return_valobj_sp;
+
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
+    if (return_valobj_sp)
+        return return_valobj_sp;
+
+    RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+    if (!reg_ctx_sp)
+        return return_valobj_sp;
+
+    const size_t bit_width = return_clang_type.GetBitSize();
+    if (return_clang_type.IsAggregateType())
+    {
+        Target *target = exe_ctx.GetTargetPtr();
+        bool is_memory = true;
+        if (bit_width <= 128)
+        {
+            ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+            DataBufferSP data_sp (new DataBufferHeap(16, 0));
+            DataExtractor return_ext (data_sp,
+                                      target_byte_order,
+                                      target->GetArchitecture().GetAddressByteSize());
+
+            const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
+            const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+
+            RegisterValue r3_value, rdx_value;
+            reg_ctx_sp->ReadRegister (r3_info, r3_value);
+            reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
+
+            DataExtractor r3_data, rdx_data;
+
+            r3_value.GetData(r3_data);
+            rdx_value.GetData(rdx_data);
+
+            uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
+            uint32_t integer_bytes = 0;  // Tracks how much of the r3/rds registers we've consumed so far
+
+            const uint32_t num_children = return_clang_type.GetNumFields ();
+
+            // Since we are in the small struct regime, assume we are not in memory.
+            is_memory = false;
+
+            for (uint32_t idx = 0; idx < num_children; idx++)
+            {
+                std::string name;
+                uint64_t field_bit_offset = 0;
+                bool is_signed;
+                bool is_complex;
+                uint32_t count;
+
+                ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+                const size_t field_bit_width = field_clang_type.GetBitSize();
+
+                // If there are any unaligned fields, this is stored in memory.
+                if (field_bit_offset % field_bit_width != 0)
+                {
+                    is_memory = true;
+                    break;
+                }
+
+                uint32_t field_byte_width = field_bit_width/8;
+                uint32_t field_byte_offset = field_bit_offset/8;
+
+
+                DataExtractor *copy_from_extractor = NULL;
+                uint32_t       copy_from_offset    = 0;
+
+                if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
+                {
+                    if (integer_bytes < 8)
+                    {
+                        if (integer_bytes + field_byte_width <= 8)
+                        {
+                            // This is in RAX, copy from register to our result structure:
+                            copy_from_extractor = &r3_data;
+                            copy_from_offset = integer_bytes;
+                            integer_bytes += field_byte_width;
+                        }
+                        else
+                        {
+                            // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
+                            copy_from_extractor = &rdx_data;
+                            copy_from_offset = 0;
+                            integer_bytes = 8 + field_byte_width;
+
+                        }
+                    }
+                    else if (integer_bytes + field_byte_width <= 16)
+                    {
+                        copy_from_extractor = &rdx_data;
+                        copy_from_offset = integer_bytes - 8;
+                        integer_bytes += field_byte_width;
+                    }
+                    else
+                    {
+                        // The last field didn't fit.  I can't see how that would happen w/o the overall size being
+                        // greater than 16 bytes.  For now, return a NULL return value object.
+                        return return_valobj_sp;
+                    }
+                }
+                else if (field_clang_type.IsFloatingPointType (count, is_complex))
+                {
+                    // Structs with long doubles are always passed in memory.
+                    if (field_bit_width == 128)
+                    {
+                        is_memory = true;
+                        break;
+                    }
+                    else if (field_bit_width == 64)
+                    {
+                        copy_from_offset = 0;
+                        fp_bytes += field_byte_width;
+                    }
+                    else if (field_bit_width == 32)
+                    {
+                        // This one is kind of complicated.  If we are in an "eightbyte" with another float, we'll
+                        // be stuffed into an xmm register with it.  If we are in an "eightbyte" with one or more ints,
+                        // then we will be stuffed into the appropriate GPR with them.
+                        bool in_gpr;
+                        if (field_byte_offset % 8 == 0)
+                        {
+                            // We are at the beginning of one of the eightbytes, so check the next element (if any)
+                            if (idx == num_children - 1)
+                                in_gpr = false;
+                            else
+                            {
+                                uint64_t next_field_bit_offset = 0;
+                                ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
+                                                                                                        name,
+                                                                                                        &next_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (next_field_clang_type.IsIntegerType (is_signed))
+                                    in_gpr = true;
+                                else
+                                {
+                                    copy_from_offset = 0;
+                                    in_gpr = false;
+                                }
+                            }
+
+                        }
+                        else if (field_byte_offset % 4 == 0)
+                        {
+                            // We are inside of an eightbyte, so see if the field before us is floating point:
+                            // This could happen if somebody put padding in the structure.
+                            if (idx == 0)
+                                in_gpr = false;
+                            else
+                            {
+                                uint64_t prev_field_bit_offset = 0;
+                                ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
+                                                                                                        name,
+                                                                                                        &prev_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (prev_field_clang_type.IsIntegerType (is_signed))
+                                    in_gpr = true;
+                                else
+                                {
+                                    copy_from_offset = 4;
+                                    in_gpr = false;
+                                }
+                            }
+
+                        }
+                        else
+                        {
+                            is_memory = true;
+                            continue;
+                        }
+
+                        // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
+                        if (in_gpr)
+                        {
+                            if (integer_bytes < 8)
+                            {
+                                // This is in RAX, copy from register to our result structure:
+                                copy_from_extractor = &r3_data;
+                                copy_from_offset = integer_bytes;
+                                integer_bytes += field_byte_width;
+                            }
+                            else
+                            {
+                                copy_from_extractor = &rdx_data;
+                                copy_from_offset = integer_bytes - 8;
+                                integer_bytes += field_byte_width;
+                            }
+                        }
+                        else
+                        {
+                            fp_bytes += field_byte_width;
+                        }
+                    }
+                }
+
+                // These two tests are just sanity checks.  If I somehow get the
+                // type calculation wrong above it is better to just return nothing
+                // than to assert or crash.
+                if (!copy_from_extractor)
+                    return return_valobj_sp;
+                if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
+                    return return_valobj_sp;
+
+                copy_from_extractor->CopyByteOrderedData (copy_from_offset,
+                                                          field_byte_width,
+                                                          data_sp->GetBytes() + field_byte_offset,
+                                                          field_byte_width,
+                                                          target_byte_order);
+            }
+
+            if (!is_memory)
+            {
+                // The result is in our data buffer.  Let's make a variable object out of it:
+                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                   return_clang_type,
+                                                                   ConstString(""),
+                                                                   return_ext);
+            }
+        }
+
+
+        // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
+        // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
+        // return, and if we are at the first instruction and if so stash away the return location.  Then we would
+        // only return the memory return value if we know it is valid.
+
+        if (is_memory)
+        {
+            unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+            lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+            return_valobj_sp = ValueObjectMemory::Create (&thread,
+                                                          "",
+                                                          Address (storage_addr, NULL),
+                                                          return_clang_type);
+        }
+    }
+
+    return return_valobj_sp;
+}
+
+bool
+ABISysV_ppc::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    uint32_t lr_reg_num = gcc_dwarf_lr;
+    uint32_t sp_reg_num = gcc_dwarf_r1;
+    uint32_t pc_reg_num = gcc_dwarf_pc;
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+    // Our Call Frame Address is the stack pointer value
+    row->SetCFARegister (sp_reg_num);
+
+    // The previous PC is in the LR
+    row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+    unwind_plan.AppendRow (row);
+
+    // All other registers are the same.
+
+    unwind_plan.SetSourceName ("ppc at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+
+    return true;
+}
+
+bool
+ABISysV_ppc::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    uint32_t sp_reg_num = gcc_dwarf_r1;
+    uint32_t pc_reg_num = gcc_dwarf_lr;
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+    const int32_t ptr_size = 8;
+    row->SetCFARegister (LLDB_REGNUM_GENERIC_SP);
+    row->SetCFAOffset (8);
+    row->SetOffset (0);
+
+    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * -2, true);
+
+    unwind_plan.AppendRow (row);
+    unwind_plan.SetSourceName ("ppc default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+    unwind_plan.SetReturnAddressRegister(gcc_dwarf_lr);
+    return true;
+}
+
+bool
+ABISysV_ppc::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+    return !RegisterIsCalleeSaved (reg_info);
+}
+
+
+
+// See "Register Usage" in the
+// "System V Application Binary Interface"
+// "64-bit PowerPC ELF Application Binary Interface Supplement"
+// current version is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc/PPC-elf64abi-1.9.pdf
+
+bool
+ABISysV_ppc::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+    if (reg_info)
+    {
+        // Preserved registers are :
+        //    r1,r2,r13-r31
+        //    f14-f31 (not yet)
+        //    v20-v31 (not yet)
+        //    vrsave (not yet)
+
+        const char *name = reg_info->name;
+        if (name[0] == 'r')
+        {
+            if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
+                return true;
+            if (name[1] == '1' && name[2] > '2')
+                return true;
+            if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+                return true;
+        }
+
+        if (name[0] == 'f' && name[1] >= '0' && name[1] <= '9')
+        {
+            if (name[3] == '1' && name[4] >= '4')
+                return true;
+            if ((name[3] == '2' || name[3] == '3') && name[4] != '\0')
+                return true;
+        }
+
+        if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
+            return true;
+        if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
+            return true;
+        if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
+            return true;
+    }
+    return false;
+}
+
+
+
+void
+ABISysV_ppc::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "System V ABI for ppc targets",
+                                   CreateInstance);
+}
+
+void
+ABISysV_ppc::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+lldb_private::ConstString
+ABISysV_ppc::GetPluginNameStatic()
+{
+    static ConstString g_name("sysv-ppc");
+    return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+lldb_private::ConstString
+ABISysV_ppc::GetPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+ABISysV_ppc::GetPluginVersion()
+{
+    return 1;
+}
+

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,143 @@
+//===-- ABISysV_ppc.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_ABISysV_ppc_h_
+#define liblldb_ABISysV_ppc_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+
+class ABISysV_ppc :
+    public lldb_private::ABI
+{
+public:
+
+    ~ABISysV_ppc()
+    {
+    }
+
+    virtual size_t
+    GetRedZoneSize () const;
+
+    virtual bool
+    PrepareTrivialCall (lldb_private::Thread &thread, 
+                        lldb::addr_t sp,
+                        lldb::addr_t functionAddress,
+                        lldb::addr_t returnAddress, 
+                        llvm::ArrayRef<lldb::addr_t> args) const;
+    
+    virtual bool
+    GetArgumentValues (lldb_private::Thread &thread,
+                       lldb_private::ValueList &values) const;
+    
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
+protected:
+    lldb::ValueObjectSP
+    GetReturnValueObjectSimple (lldb_private::Thread &thread,
+                                lldb_private::ClangASTType &ast_type) const;
+    
+public:    
+    virtual lldb::ValueObjectSP
+    GetReturnValueObjectImpl (lldb_private::Thread &thread,
+                          lldb_private::ClangASTType &type) const;
+
+    virtual bool
+    CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+    
+    virtual bool
+    CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+        
+    virtual bool
+    RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+    
+    virtual bool
+    StackUsesFrames ()
+    {
+        return true;
+    }
+    
+    // The SysV ppc ABI requires that stack frames be 16 byte aligned.
+    // When there is a trap handler on the stack, e.g. _sigtramp in userland
+    // code, we've seen that the stack pointer is often not aligned properly
+    // before the handler is invoked.  This means that lldb will stop the unwind
+    // early -- before the function which caused the trap.
+    //
+    // To work around this, we relax that alignment to be just word-size (8-bytes).
+    // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+    // in other environments there can be a large number of different functions
+    // involved in async traps.
+    virtual bool
+    CallFrameAddressIsValid (lldb::addr_t cfa)
+    {
+        // Make sure the stack call frame addresses are 8 byte aligned
+        if (cfa & (8ull - 1ull))
+            return false;   // Not 8 byte aligned
+        if (cfa == 0)
+            return false;   // Zero is not a valid stack address
+        return true;
+    }
+    
+    virtual bool
+    CodeAddressIsValid (lldb::addr_t pc)
+    {
+        // We have a 64 bit address space, so anything is valid as opcodes
+        // aren't fixed width...
+        return true;
+    }
+
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return true;
+    }
+
+    virtual const lldb_private::RegisterInfo *
+    GetRegisterInfoArray (uint32_t &count);
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static lldb::ABISP
+    CreateInstance (const lldb_private::ArchSpec &arch);
+
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual lldb_private::ConstString
+    GetPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+protected:
+    void
+    CreateRegisterMapIfNeeded ();
+
+    bool
+    RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
+private:
+    ABISysV_ppc() : lldb_private::ABI() { } // Call CreateInstance instead.
+};
+
+#endif  // liblldb_ABI_h_

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/CMakeLists.txt?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABISysV_ppc
+  ABISysV_ppc.cpp
+  )

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/Makefile?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/Makefile (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/Makefile Thu Oct 30 21:34:28 2014
@@ -0,0 +1,14 @@
+##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginABISysV_ppc
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,1101 @@
+//===-- ABISysV_ppc64.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ABISysV_ppc64.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+enum gcc_dwarf_regnums
+{
+    gcc_dwarf_r0 = 0,
+    gcc_dwarf_r1,
+    gcc_dwarf_r2,
+    gcc_dwarf_r3,
+    gcc_dwarf_r4,
+    gcc_dwarf_r5,
+    gcc_dwarf_r6,
+    gcc_dwarf_r7,
+    gcc_dwarf_r8,
+    gcc_dwarf_r9,
+    gcc_dwarf_r10,
+    gcc_dwarf_r11,
+    gcc_dwarf_r12,
+    gcc_dwarf_r13,
+    gcc_dwarf_r14,
+    gcc_dwarf_r15,
+    gcc_dwarf_r16,
+    gcc_dwarf_r17,
+    gcc_dwarf_r18,
+    gcc_dwarf_r19,
+    gcc_dwarf_r20,
+    gcc_dwarf_r21,
+    gcc_dwarf_r22,
+    gcc_dwarf_r23,
+    gcc_dwarf_r24,
+    gcc_dwarf_r25,
+    gcc_dwarf_r26,
+    gcc_dwarf_r27,
+    gcc_dwarf_r28,
+    gcc_dwarf_r29,
+    gcc_dwarf_r30,
+    gcc_dwarf_r31,
+    gcc_dwarf_f0,
+    gcc_dwarf_f1,
+    gcc_dwarf_f2,
+    gcc_dwarf_f3,
+    gcc_dwarf_f4,
+    gcc_dwarf_f5,
+    gcc_dwarf_f6,
+    gcc_dwarf_f7,
+    gcc_dwarf_f8,
+    gcc_dwarf_f9,
+    gcc_dwarf_f10,
+    gcc_dwarf_f11,
+    gcc_dwarf_f12,
+    gcc_dwarf_f13,
+    gcc_dwarf_f14,
+    gcc_dwarf_f15,
+    gcc_dwarf_f16,
+    gcc_dwarf_f17,
+    gcc_dwarf_f18,
+    gcc_dwarf_f19,
+    gcc_dwarf_f20,
+    gcc_dwarf_f21,
+    gcc_dwarf_f22,
+    gcc_dwarf_f23,
+    gcc_dwarf_f24,
+    gcc_dwarf_f25,
+    gcc_dwarf_f26,
+    gcc_dwarf_f27,
+    gcc_dwarf_f28,
+    gcc_dwarf_f29,
+    gcc_dwarf_f30,
+    gcc_dwarf_f31,
+    gcc_dwarf_cr,
+    gcc_dwarf_fpscr,
+    gcc_dwarf_xer = 101,
+    gcc_dwarf_lr = 108,
+    gcc_dwarf_ctr,
+    gcc_dwarf_pc,
+    gcc_dwarf_cfa,
+};
+
+enum gdb_regnums
+{
+    gdb_r0 = 0,
+    gdb_r1,
+    gdb_r2,
+    gdb_r3,
+    gdb_r4,
+    gdb_r5,
+    gdb_r6,
+    gdb_r7,
+    gdb_r8,
+    gdb_r9,
+    gdb_r10,
+    gdb_r11,
+    gdb_r12,
+    gdb_r13,
+    gdb_r14,
+    gdb_r15,
+    gdb_r16,
+    gdb_r17,
+    gdb_r18,
+    gdb_r19,
+    gdb_r20,
+    gdb_r21,
+    gdb_r22,
+    gdb_r23,
+    gdb_r24,
+    gdb_r25,
+    gdb_r26,
+    gdb_r27,
+    gdb_r28,
+    gdb_r29,
+    gdb_r30,
+    gdb_r31,
+    gdb_lr,
+    gdb_cr,
+    gdb_xer,
+    gdb_ctr,
+    gdb_pc,
+};
+
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)           \
+    { #reg, alt, 8, 0, eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4}, NULL, NULL }
+static const RegisterInfo
+g_register_infos[] =
+{
+    // General purpose registers.                 GCC,                  DWARF,              Generic,                GDB
+    DEFINE_GPR(r0,       NULL,  gcc_dwarf_r0,    gcc_dwarf_r0,    LLDB_INVALID_REGNUM,    gdb_r0),
+    DEFINE_GPR(r1,       "sp",  gcc_dwarf_r1,    gcc_dwarf_r1,    LLDB_REGNUM_GENERIC_SP, gdb_r1),
+    DEFINE_GPR(r2,       NULL,  gcc_dwarf_r2,    gcc_dwarf_r2,    LLDB_INVALID_REGNUM,    gdb_r2),
+    DEFINE_GPR(r3,       "arg1",gcc_dwarf_r3,    gcc_dwarf_r3,    LLDB_REGNUM_GENERIC_ARG1, gdb_r3),
+    DEFINE_GPR(r4,       "arg2",gcc_dwarf_r4,    gcc_dwarf_r4,    LLDB_REGNUM_GENERIC_ARG2 ,gdb_r4),
+    DEFINE_GPR(r5,       "arg3",gcc_dwarf_r5,    gcc_dwarf_r5,    LLDB_REGNUM_GENERIC_ARG3, gdb_r5),
+    DEFINE_GPR(r6,       "arg4",gcc_dwarf_r6,    gcc_dwarf_r6,    LLDB_REGNUM_GENERIC_ARG4, gdb_r6),
+    DEFINE_GPR(r7,       "arg5",gcc_dwarf_r7,    gcc_dwarf_r7,    LLDB_REGNUM_GENERIC_ARG5, gdb_r7),
+    DEFINE_GPR(r8,       "arg6",gcc_dwarf_r8,    gcc_dwarf_r8,    LLDB_REGNUM_GENERIC_ARG6, gdb_r8),
+    DEFINE_GPR(r9,       "arg7",gcc_dwarf_r9,    gcc_dwarf_r9,    LLDB_REGNUM_GENERIC_ARG7, gdb_r9),
+    DEFINE_GPR(r10,      "arg8",gcc_dwarf_r10,   gcc_dwarf_r10,   LLDB_REGNUM_GENERIC_ARG8, gdb_r10),
+    DEFINE_GPR(r11,      NULL,  gcc_dwarf_r11,   gcc_dwarf_r11,   LLDB_INVALID_REGNUM,    gdb_r11),
+    DEFINE_GPR(r12,      NULL,  gcc_dwarf_r12,   gcc_dwarf_r12,   LLDB_INVALID_REGNUM,    gdb_r12),
+    DEFINE_GPR(r13,      NULL,  gcc_dwarf_r13,   gcc_dwarf_r13,   LLDB_INVALID_REGNUM,    gdb_r13),
+    DEFINE_GPR(r14,      NULL,  gcc_dwarf_r14,   gcc_dwarf_r14,   LLDB_INVALID_REGNUM,    gdb_r14),
+    DEFINE_GPR(r15,      NULL,  gcc_dwarf_r15,   gcc_dwarf_r15,   LLDB_INVALID_REGNUM,    gdb_r15),
+    DEFINE_GPR(r16,      NULL,  gcc_dwarf_r16,   gcc_dwarf_r16,   LLDB_INVALID_REGNUM,    gdb_r16),
+    DEFINE_GPR(r17,      NULL,  gcc_dwarf_r17,   gcc_dwarf_r17,   LLDB_INVALID_REGNUM,    gdb_r17),
+    DEFINE_GPR(r18,      NULL,  gcc_dwarf_r18,   gcc_dwarf_r18,   LLDB_INVALID_REGNUM,    gdb_r18),
+    DEFINE_GPR(r19,      NULL,  gcc_dwarf_r19,   gcc_dwarf_r19,   LLDB_INVALID_REGNUM,    gdb_r19),
+    DEFINE_GPR(r20,      NULL,  gcc_dwarf_r20,   gcc_dwarf_r20,   LLDB_INVALID_REGNUM,    gdb_r20),
+    DEFINE_GPR(r21,      NULL,  gcc_dwarf_r21,   gcc_dwarf_r21,   LLDB_INVALID_REGNUM,    gdb_r21),
+    DEFINE_GPR(r22,      NULL,  gcc_dwarf_r22,   gcc_dwarf_r22,   LLDB_INVALID_REGNUM,    gdb_r22),
+    DEFINE_GPR(r23,      NULL,  gcc_dwarf_r23,   gcc_dwarf_r23,   LLDB_INVALID_REGNUM,    gdb_r23),
+    DEFINE_GPR(r24,      NULL,  gcc_dwarf_r24,   gcc_dwarf_r24,   LLDB_INVALID_REGNUM,    gdb_r24),
+    DEFINE_GPR(r25,      NULL,  gcc_dwarf_r25,   gcc_dwarf_r25,   LLDB_INVALID_REGNUM,    gdb_r25),
+    DEFINE_GPR(r26,      NULL,  gcc_dwarf_r26,   gcc_dwarf_r26,   LLDB_INVALID_REGNUM,    gdb_r26),
+    DEFINE_GPR(r27,      NULL,  gcc_dwarf_r27,   gcc_dwarf_r27,   LLDB_INVALID_REGNUM,    gdb_r27),
+    DEFINE_GPR(r28,      NULL,  gcc_dwarf_r28,   gcc_dwarf_r28,   LLDB_INVALID_REGNUM,    gdb_r28),
+    DEFINE_GPR(r29,      NULL,  gcc_dwarf_r29,   gcc_dwarf_r29,   LLDB_INVALID_REGNUM,    gdb_r29),
+    DEFINE_GPR(r30,      NULL,  gcc_dwarf_r30,   gcc_dwarf_r30,   LLDB_INVALID_REGNUM,    gdb_r30),
+    DEFINE_GPR(r31,      NULL,  gcc_dwarf_r31,   gcc_dwarf_r31,   LLDB_INVALID_REGNUM,    gdb_r31),
+    DEFINE_GPR(lr,       "lr",  gcc_dwarf_lr,    gcc_dwarf_lr,    LLDB_REGNUM_GENERIC_RA, gdb_lr),
+    DEFINE_GPR(cr,       "cr",  gcc_dwarf_cr,    gcc_dwarf_cr,    LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM),
+    DEFINE_GPR(xer,      "xer", gcc_dwarf_xer,   gcc_dwarf_xer,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM),
+    DEFINE_GPR(ctr,      "ctr", gcc_dwarf_ctr,   gcc_dwarf_ctr,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM),
+    DEFINE_GPR(pc,       "pc",  gcc_dwarf_pc,    gcc_dwarf_pc,    LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+    { NULL, NULL, 8, 0, eEncodingUint, eFormatHex, { gcc_dwarf_cfa, gcc_dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, NULL, NULL},
+};
+
+static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
+
+const lldb_private::RegisterInfo *
+ABISysV_ppc64::GetRegisterInfoArray (uint32_t &count)
+{
+    count = k_num_register_infos;
+    return g_register_infos;
+}
+
+
+size_t
+ABISysV_ppc64::GetRedZoneSize () const
+{
+    return 224;
+}
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+ABISP
+ABISysV_ppc64::CreateInstance (const ArchSpec &arch)
+{
+    static ABISP g_abi_sp;
+    if (arch.GetTriple().getArch() == llvm::Triple::ppc64)
+    {
+        if (!g_abi_sp)
+            g_abi_sp.reset (new ABISysV_ppc64);
+        return g_abi_sp;
+    }
+    return ABISP();
+}
+
+bool
+ABISysV_ppc64::PrepareTrivialCall (Thread &thread,
+                                    addr_t sp,
+                                    addr_t func_addr,
+                                    addr_t return_addr,
+                                    llvm::ArrayRef<addr_t> args) const
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    if (log)
+    {
+        StreamString s;
+        s.Printf("ABISysV_ppc64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
+                    thread.GetID(),
+                    (uint64_t)sp,
+                    (uint64_t)func_addr,
+                    (uint64_t)return_addr);
+
+        for (size_t i = 0; i < args.size(); ++i)
+            s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
+        s.PutCString (")");
+        log->PutCString(s.GetString().c_str());
+    }
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return false;
+
+    const RegisterInfo *reg_info = NULL;
+
+    if (args.size() > 8) // TODO handle more than 8 arguments
+        return false;
+
+    for (size_t i = 0; i < args.size(); ++i)
+    {
+        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
+        if (log)
+            log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
+        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
+            return false;
+    }
+
+    // First, align the SP
+
+    if (log)
+        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+
+    sp &= ~(0xfull); // 16-byte alignment
+
+    sp -= 8;
+
+    Error error;
+    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
+    ProcessSP process_sp (thread.GetProcess());
+
+    RegisterValue reg_value;
+
+#if 0
+    // This code adds an extra frame so that we don't lose the function that we came from
+    // by pushing the PC and the FP and then writing the current FP to point to the FP value
+    // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
+
+    // Save current PC
+    const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
+    if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
+    {
+        if (log)
+            log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
+
+        if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
+            return false;
+
+        sp -= 8;
+
+        // Save current FP
+        if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
+        {
+            if (log)
+                log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
+
+            if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
+                return false;
+        }
+        // Setup FP backchain
+        reg_value.SetUInt64 (sp);
+
+        if (log)
+            log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
+
+        if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
+        {
+            return false;
+        }
+
+        sp -= 8;
+    }
+#endif
+
+    if (log)
+        log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
+
+    // Save return address onto the stack
+    if (!process_sp->WritePointerToMemory(sp, return_addr, error))
+        return false;
+
+    // %r1 is set to the actual stack value.
+
+    if (log)
+        log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+
+    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
+        return false;
+
+    // %pc is set to the address of the called function.
+
+    if (log)
+        log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
+
+    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
+        return false;
+
+    return true;
+}
+
+static bool ReadIntegerArgument(Scalar           &scalar,
+                                unsigned int     bit_width,
+                                bool             is_signed,
+                                Thread           &thread,
+                                uint32_t         *argument_register_ids,
+                                unsigned int     &current_argument_register,
+                                addr_t           &current_stack_argument)
+{
+    if (bit_width > 64)
+        return false; // Scalar can't hold large integer arguments
+
+    if (current_argument_register < 6)
+    {
+        scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
+        current_argument_register++;
+        if (is_signed)
+            scalar.SignExtend (bit_width);
+    }
+    else
+    {
+        uint32_t byte_size = (bit_width + (8-1))/8;
+        Error error;
+        if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
+        {
+            current_stack_argument += byte_size;
+            return true;
+        }
+        return false;
+    }
+    return true;
+}
+
+bool
+ABISysV_ppc64::GetArgumentValues (Thread &thread,
+                                   ValueList &values) const
+{
+    unsigned int num_values = values.GetSize();
+    unsigned int value_index;
+
+    // Extract the register context so we can read arguments from registers
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+    if (!reg_ctx)
+        return false;
+
+    // Get the pointer to the first stack argument so we have a place to start
+    // when reading data
+
+    addr_t sp = reg_ctx->GetSP(0);
+
+    if (!sp)
+        return false;
+
+    addr_t current_stack_argument = sp + 48; // jump over return address
+
+    uint32_t argument_register_ids[8];
+
+    argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
+    argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
+    argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
+    argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
+    argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
+    argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
+    argument_register_ids[6] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)->kinds[eRegisterKindLLDB];
+    argument_register_ids[7] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)->kinds[eRegisterKindLLDB];
+
+    unsigned int current_argument_register = 0;
+
+    for (value_index = 0;
+         value_index < num_values;
+         ++value_index)
+    {
+        Value *value = values.GetValueAtIndex(value_index);
+
+        if (!value)
+            return false;
+
+        // We currently only support extracting values with Clang QualTypes.
+        // Do we care about others?
+        ClangASTType clang_type = value->GetClangType();
+        if (!clang_type)
+            return false;
+        bool is_signed;
+
+        if (clang_type.IsIntegerType (is_signed))
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                is_signed,
+                                thread,
+                                argument_register_ids,
+                                current_argument_register,
+                                current_stack_argument);
+        }
+        else if (clang_type.IsPointerType ())
+        {
+            ReadIntegerArgument(value->GetScalar(),
+                                clang_type.GetBitSize(),
+                                false,
+                                thread,
+                                argument_register_ids,
+                                current_argument_register,
+                                current_stack_argument);
+        }
+    }
+
+    return true;
+}
+
+Error
+ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+
+    ClangASTType clang_type = new_value_sp->GetClangType();
+    if (!clang_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+
+    Thread *thread = frame_sp->GetThread().get();
+
+    bool is_signed;
+    uint32_t count;
+    bool is_complex;
+
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+    bool set_it_simple = false;
+    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
+    {
+        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+
+        DataExtractor data;
+        Error data_error;
+        size_t num_bytes = new_value_sp->GetData(data, data_error);
+        if (data_error.Fail())
+        {
+            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+            return error;
+        }
+        lldb::offset_t offset = 0;
+        if (num_bytes <= 8)
+        {
+            uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+
+            if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
+                set_it_simple = true;
+        }
+        else
+        {
+            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+        }
+
+    }
+    else if (clang_type.IsFloatingPointType (count, is_complex))
+    {
+        if (is_complex)
+            error.SetErrorString ("We don't support returning complex values at present");
+        else
+        {
+            size_t bit_width = clang_type.GetBitSize();
+            if (bit_width <= 64)
+            {
+                DataExtractor data;
+                Error data_error;
+                size_t num_bytes = new_value_sp->GetData(data, data_error);
+                if (data_error.Fail())
+                {
+                    error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
+                    return error;
+                }
+
+                unsigned char buffer[16];
+                ByteOrder byte_order = data.GetByteOrder();
+
+                data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
+                set_it_simple = true;
+            }
+            else
+            {
+                // FIXME - don't know how to do 80 bit long doubles yet.
+                error.SetErrorString ("We don't support returning float values > 64 bits at present");
+            }
+        }
+    }
+
+    if (!set_it_simple)
+    {
+        // Okay we've got a structure or something that doesn't fit in a simple register.
+        // We should figure out where it really goes, but we don't support this yet.
+        error.SetErrorString ("We only support setting simple integer and float return types at present.");
+    }
+
+    return error;
+}
+
+
+ValueObjectSP
+ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
+                                            ClangASTType &return_clang_type) const
+{
+    ValueObjectSP return_valobj_sp;
+    Value value;
+
+    if (!return_clang_type)
+        return return_valobj_sp;
+
+    //value.SetContext (Value::eContextTypeClangType, return_value_type);
+    value.SetClangType (return_clang_type);
+
+    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+    if (!reg_ctx)
+        return return_valobj_sp;
+
+    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
+    if (type_flags & eTypeIsScalar)
+    {
+        value.SetValueType(Value::eValueTypeScalar);
+
+        bool success = false;
+        if (type_flags & eTypeIsInteger)
+        {
+            // Extract the register context so we can read arguments from registers
+
+            const size_t byte_size = return_clang_type.GetByteSize();
+            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
+            const bool is_signed = (type_flags & eTypeIsSigned) != 0;
+            switch (byte_size)
+            {
+            default:
+                break;
+
+            case sizeof(uint64_t):
+                if (is_signed)
+                    value.GetScalar() = (int64_t)(raw_value);
+                else
+                    value.GetScalar() = (uint64_t)(raw_value);
+                success = true;
+                break;
+
+            case sizeof(uint32_t):
+                if (is_signed)
+                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+                else
+                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint16_t):
+                if (is_signed)
+                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+                else
+                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint8_t):
+                if (is_signed)
+                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+                else
+                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+                success = true;
+                break;
+            }
+        }
+        else if (type_flags & eTypeIsFloat)
+        {
+            if (type_flags & eTypeIsComplex)
+            {
+                // Don't handle complex yet.
+            }
+            else
+            {
+            }
+        }
+
+        if (success)
+            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                               value,
+                                                               ConstString(""));
+
+    }
+    else if (type_flags & eTypeIsPointer)
+    {
+        unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+        value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+        value.SetValueType(Value::eValueTypeScalar);
+        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                           value,
+                                                           ConstString(""));
+    }
+    else if (type_flags & eTypeIsVector)
+    {
+        const size_t byte_size = return_clang_type.GetByteSize();
+        if (byte_size > 0)
+        {
+
+            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
+            if (altivec_reg == NULL)
+                altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+            if (altivec_reg)
+            {
+                if (byte_size <= altivec_reg->byte_size)
+                {
+                    ProcessSP process_sp (thread.GetProcess());
+                    if (process_sp)
+                    {
+                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+                        const ByteOrder byte_order = process_sp->GetByteOrder();
+                        RegisterValue reg_value;
+                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
+                        {
+                            Error error;
+                            if (reg_value.GetAsMemoryData (altivec_reg,
+                                                           heap_data_ap->GetBytes(),
+                                                           heap_data_ap->GetByteSize(),
+                                                           byte_order,
+                                                           error))
+                            {
+                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
+                                                    byte_order,
+                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
+                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                                   return_clang_type,
+                                                                                   ConstString(""),
+                                                                                   data);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return return_valobj_sp;
+}
+
+ValueObjectSP
+ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
+{
+    ValueObjectSP return_valobj_sp;
+
+    if (!return_clang_type)
+        return return_valobj_sp;
+
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
+    if (return_valobj_sp)
+        return return_valobj_sp;
+
+    RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+    if (!reg_ctx_sp)
+        return return_valobj_sp;
+
+    const size_t bit_width = return_clang_type.GetBitSize();
+    if (return_clang_type.IsAggregateType())
+    {
+        Target *target = exe_ctx.GetTargetPtr();
+        bool is_memory = true;
+        if (bit_width <= 128)
+        {
+            ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
+            DataBufferSP data_sp (new DataBufferHeap(16, 0));
+            DataExtractor return_ext (data_sp,
+                                      target_byte_order,
+                                      target->GetArchitecture().GetAddressByteSize());
+
+            const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
+            const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
+
+            RegisterValue r3_value, rdx_value;
+            reg_ctx_sp->ReadRegister (r3_info, r3_value);
+            reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
+
+            DataExtractor r3_data, rdx_data;
+
+            r3_value.GetData(r3_data);
+            rdx_value.GetData(rdx_data);
+
+            uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
+            uint32_t integer_bytes = 0;  // Tracks how much of the r3/rds registers we've consumed so far
+
+            const uint32_t num_children = return_clang_type.GetNumFields ();
+
+            // Since we are in the small struct regime, assume we are not in memory.
+            is_memory = false;
+
+            for (uint32_t idx = 0; idx < num_children; idx++)
+            {
+                std::string name;
+                uint64_t field_bit_offset = 0;
+                bool is_signed;
+                bool is_complex;
+                uint32_t count;
+
+                ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
+                const size_t field_bit_width = field_clang_type.GetBitSize();
+
+                // If there are any unaligned fields, this is stored in memory.
+                if (field_bit_offset % field_bit_width != 0)
+                {
+                    is_memory = true;
+                    break;
+                }
+
+                uint32_t field_byte_width = field_bit_width/8;
+                uint32_t field_byte_offset = field_bit_offset/8;
+
+
+                DataExtractor *copy_from_extractor = NULL;
+                uint32_t       copy_from_offset    = 0;
+
+                if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
+                {
+                    if (integer_bytes < 8)
+                    {
+                        if (integer_bytes + field_byte_width <= 8)
+                        {
+                            // This is in RAX, copy from register to our result structure:
+                            copy_from_extractor = &r3_data;
+                            copy_from_offset = integer_bytes;
+                            integer_bytes += field_byte_width;
+                        }
+                        else
+                        {
+                            // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
+                            copy_from_extractor = &rdx_data;
+                            copy_from_offset = 0;
+                            integer_bytes = 8 + field_byte_width;
+
+                        }
+                    }
+                    else if (integer_bytes + field_byte_width <= 16)
+                    {
+                        copy_from_extractor = &rdx_data;
+                        copy_from_offset = integer_bytes - 8;
+                        integer_bytes += field_byte_width;
+                    }
+                    else
+                    {
+                        // The last field didn't fit.  I can't see how that would happen w/o the overall size being
+                        // greater than 16 bytes.  For now, return a NULL return value object.
+                        return return_valobj_sp;
+                    }
+                }
+                else if (field_clang_type.IsFloatingPointType (count, is_complex))
+                {
+                    // Structs with long doubles are always passed in memory.
+                    if (field_bit_width == 128)
+                    {
+                        is_memory = true;
+                        break;
+                    }
+                    else if (field_bit_width == 64)
+                    {
+                        copy_from_offset = 0;
+                        fp_bytes += field_byte_width;
+                    }
+                    else if (field_bit_width == 32)
+                    {
+                        // This one is kind of complicated.  If we are in an "eightbyte" with another float, we'll
+                        // be stuffed into an xmm register with it.  If we are in an "eightbyte" with one or more ints,
+                        // then we will be stuffed into the appropriate GPR with them.
+                        bool in_gpr;
+                        if (field_byte_offset % 8 == 0)
+                        {
+                            // We are at the beginning of one of the eightbytes, so check the next element (if any)
+                            if (idx == num_children - 1)
+                                in_gpr = false;
+                            else
+                            {
+                                uint64_t next_field_bit_offset = 0;
+                                ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
+                                                                                                        name,
+                                                                                                        &next_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (next_field_clang_type.IsIntegerType (is_signed))
+                                    in_gpr = true;
+                                else
+                                {
+                                    copy_from_offset = 0;
+                                    in_gpr = false;
+                                }
+                            }
+
+                        }
+                        else if (field_byte_offset % 4 == 0)
+                        {
+                            // We are inside of an eightbyte, so see if the field before us is floating point:
+                            // This could happen if somebody put padding in the structure.
+                            if (idx == 0)
+                                in_gpr = false;
+                            else
+                            {
+                                uint64_t prev_field_bit_offset = 0;
+                                ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
+                                                                                                        name,
+                                                                                                        &prev_field_bit_offset,
+                                                                                                        NULL,
+                                                                                                        NULL);
+                                if (prev_field_clang_type.IsIntegerType (is_signed))
+                                    in_gpr = true;
+                                else
+                                {
+                                    copy_from_offset = 4;
+                                    in_gpr = false;
+                                }
+                            }
+
+                        }
+                        else
+                        {
+                            is_memory = true;
+                            continue;
+                        }
+
+                        // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
+                        if (in_gpr)
+                        {
+                            if (integer_bytes < 8)
+                            {
+                                // This is in RAX, copy from register to our result structure:
+                                copy_from_extractor = &r3_data;
+                                copy_from_offset = integer_bytes;
+                                integer_bytes += field_byte_width;
+                            }
+                            else
+                            {
+                                copy_from_extractor = &rdx_data;
+                                copy_from_offset = integer_bytes - 8;
+                                integer_bytes += field_byte_width;
+                            }
+                        }
+                        else
+                        {
+                            fp_bytes += field_byte_width;
+                        }
+                    }
+                }
+
+                // These two tests are just sanity checks.  If I somehow get the
+                // type calculation wrong above it is better to just return nothing
+                // than to assert or crash.
+                if (!copy_from_extractor)
+                    return return_valobj_sp;
+                if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
+                    return return_valobj_sp;
+
+                copy_from_extractor->CopyByteOrderedData (copy_from_offset,
+                                                          field_byte_width,
+                                                          data_sp->GetBytes() + field_byte_offset,
+                                                          field_byte_width,
+                                                          target_byte_order);
+            }
+
+            if (!is_memory)
+            {
+                // The result is in our data buffer.  Let's make a variable object out of it:
+                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                   return_clang_type,
+                                                                   ConstString(""),
+                                                                   return_ext);
+            }
+        }
+
+
+        // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
+        // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
+        // return, and if we are at the first instruction and if so stash away the return location.  Then we would
+        // only return the memory return value if we know it is valid.
+
+        if (is_memory)
+        {
+            unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
+            lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
+            return_valobj_sp = ValueObjectMemory::Create (&thread,
+                                                          "",
+                                                          Address (storage_addr, NULL),
+                                                          return_clang_type);
+        }
+    }
+
+    return return_valobj_sp;
+}
+
+bool
+ABISysV_ppc64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    uint32_t lr_reg_num = gcc_dwarf_lr;
+    uint32_t sp_reg_num = gcc_dwarf_r1;
+    uint32_t pc_reg_num = gcc_dwarf_pc;
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+    // Our Call Frame Address is the stack pointer value
+    row->SetCFARegister (sp_reg_num);
+
+    // The previous PC is in the LR
+    row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
+    unwind_plan.AppendRow (row);
+
+    // All other registers are the same.
+
+    unwind_plan.SetSourceName ("ppc64 at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+
+    return true;
+}
+
+bool
+ABISysV_ppc64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
+{
+    unwind_plan.Clear();
+    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
+
+    uint32_t sp_reg_num = gcc_dwarf_r1;
+    uint32_t pc_reg_num = gcc_dwarf_lr;
+
+    UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+    const int32_t ptr_size = 8;
+    row->SetCFARegister (LLDB_REGNUM_GENERIC_SP);
+    row->SetCFAOffset (48);
+    row->SetOffset (0);
+
+    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -4, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * -6, true);
+    row->SetRegisterLocationToAtCFAPlusOffset(gcc_dwarf_cr, ptr_size * -5, true);
+
+    unwind_plan.AppendRow (row);
+    unwind_plan.SetSourceName ("ppc64 default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+    unwind_plan.SetReturnAddressRegister(gcc_dwarf_lr);
+    return true;
+}
+
+bool
+ABISysV_ppc64::RegisterIsVolatile (const RegisterInfo *reg_info)
+{
+    return !RegisterIsCalleeSaved (reg_info);
+}
+
+
+
+// See "Register Usage" in the
+// "System V Application Binary Interface"
+// "64-bit PowerPC ELF Application Binary Interface Supplement"
+// current version is 1.9 released 2004 at http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf
+
+bool
+ABISysV_ppc64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
+{
+    if (reg_info)
+    {
+        // Preserved registers are :
+        //    r1,r2,r13-r31
+        //    cr2-cr4 (partially preserved)
+        //    f14-f31 (not yet)
+        //    v20-v31 (not yet)
+        //    vrsave (not yet)
+
+        const char *name = reg_info->name;
+        if (name[0] == 'r')
+        {
+            if ((name[1] == '1' || name[1] == '2') && name[2] == '\0')
+                return true;
+            if (name[1] == '1' && name[2] > '2')
+                return true;
+            if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+                return true;
+        }
+
+        if (name[0] == 'f' && name[1] >= '0' && name[2] <= '9')
+        {
+            if (name[2] == '\0')
+                return false;
+            if (name[1] == '1' && name[2] >= '4')
+                return true;
+            if ((name[1] == '2' || name[1] == '3') && name[2] != '\0')
+                return true;
+        }
+
+        if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
+            return true;
+        if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
+            return true;
+        if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
+            return true;
+    }
+    return false;
+}
+
+
+
+void
+ABISysV_ppc64::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "System V ABI for ppc64 targets",
+                                   CreateInstance);
+}
+
+void
+ABISysV_ppc64::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+lldb_private::ConstString
+ABISysV_ppc64::GetPluginNameStatic()
+{
+    static ConstString g_name("sysv-ppc64");
+    return g_name;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+lldb_private::ConstString
+ABISysV_ppc64::GetPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+ABISysV_ppc64::GetPluginVersion()
+{
+    return 1;
+}
+

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,143 @@
+//===-- ABISysV_ppc64.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_ABISysV_ppc64_h_
+#define liblldb_ABISysV_ppc64_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Target/ABI.h"
+
+class ABISysV_ppc64 :
+    public lldb_private::ABI
+{
+public:
+
+    ~ABISysV_ppc64()
+    {
+    }
+
+    virtual size_t
+    GetRedZoneSize () const;
+
+    virtual bool
+    PrepareTrivialCall (lldb_private::Thread &thread, 
+                        lldb::addr_t sp,
+                        lldb::addr_t functionAddress,
+                        lldb::addr_t returnAddress, 
+                        llvm::ArrayRef<lldb::addr_t> args) const;
+    
+    virtual bool
+    GetArgumentValues (lldb_private::Thread &thread,
+                       lldb_private::ValueList &values) const;
+    
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
+protected:
+    lldb::ValueObjectSP
+    GetReturnValueObjectSimple (lldb_private::Thread &thread,
+                                lldb_private::ClangASTType &ast_type) const;
+    
+public:    
+    virtual lldb::ValueObjectSP
+    GetReturnValueObjectImpl (lldb_private::Thread &thread,
+                          lldb_private::ClangASTType &type) const;
+
+    virtual bool
+    CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+    
+    virtual bool
+    CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan);
+        
+    virtual bool
+    RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info);
+    
+    virtual bool
+    StackUsesFrames ()
+    {
+        return true;
+    }
+    
+    // The SysV ppc64 ABI requires that stack frames be 16 byte aligned.
+    // When there is a trap handler on the stack, e.g. _sigtramp in userland
+    // code, we've seen that the stack pointer is often not aligned properly
+    // before the handler is invoked.  This means that lldb will stop the unwind
+    // early -- before the function which caused the trap.
+    //
+    // To work around this, we relax that alignment to be just word-size (8-bytes).
+    // Whitelisting the trap handlers for user space would be easy (_sigtramp) but
+    // in other environments there can be a large number of different functions
+    // involved in async traps.
+    virtual bool
+    CallFrameAddressIsValid (lldb::addr_t cfa)
+    {
+        // Make sure the stack call frame addresses are 8 byte aligned
+        if (cfa & (8ull - 1ull))
+            return false;   // Not 8 byte aligned
+        if (cfa == 0)
+            return false;   // Zero is not a valid stack address
+        return true;
+    }
+    
+    virtual bool
+    CodeAddressIsValid (lldb::addr_t pc)
+    {
+        // We have a 64 bit address space, so anything is valid as opcodes
+        // aren't fixed width...
+        return true;
+    }
+
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return true;
+    }
+
+    virtual const lldb_private::RegisterInfo *
+    GetRegisterInfoArray (uint32_t &count);
+    //------------------------------------------------------------------
+    // Static Functions
+    //------------------------------------------------------------------
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static lldb::ABISP
+    CreateInstance (const lldb_private::ArchSpec &arch);
+
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual lldb_private::ConstString
+    GetPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+protected:
+    void
+    CreateRegisterMapIfNeeded ();
+
+    bool
+    RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info);
+
+private:
+    ABISysV_ppc64() : lldb_private::ABI() { } // Call CreateInstance instead.
+};
+
+#endif  // liblldb_ABI_h_

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABISysV_ppc64
+  ABISysV_ppc64.cpp
+  )

Added: lldb/trunk/source/Plugins/ABI/SysV-ppc64/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/Makefile?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/Makefile (added)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/Makefile Thu Oct 30 21:34:28 2014
@@ -0,0 +1,14 @@
+##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginABISysV_ppc64
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile

Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Thu Oct 30 21:34:28 2014
@@ -558,6 +558,13 @@ DynamicLoaderPOSIXDYLD::GetEntryPoint()
         return LLDB_INVALID_ADDRESS;
 
     m_entry_point = static_cast<addr_t>(I->value);
+
+    const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+
+    // On ppc64, the entry point is actually a descriptor.  Dereference it.
+    if (arch.GetMachine() == llvm::Triple::ppc64)
+        m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
+
     return m_entry_point;
 }
 

Modified: lldb/trunk/source/Plugins/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Makefile?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Makefile (original)
+++ lldb/trunk/source/Plugins/Makefile Thu Oct 30 21:34:28 2014
@@ -13,7 +13,7 @@ include $(LLDB_LEVEL)/../../Makefile.con
 
 
 PARALLEL_DIRS := ABI/MacOSX-arm ABI/MacOSX-arm64 ABI/MacOSX-i386 ABI/SysV-x86_64 \
-	ABI/SysV-hexagon \
+	ABI/SysV-hexagon ABI/SysV-ppc64 \
 	Disassembler/llvm \
 	ObjectContainer/BSD-Archive ObjectFile/ELF ObjectFile/PECOFF \
 	ObjectFile/JIT SymbolFile/DWARF SymbolFile/Symtab Process/Utility \

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ELFHeader.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ELFHeader.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ELFHeader.cpp Thu Oct 30 21:34:28 2014
@@ -173,6 +173,12 @@ ELFHeader::GetRelocationJumpSlotType() c
     default:
         assert(false && "architecture not supported");
         break;
+    case EM_PPC:
+        slot = R_PPC_JMP_SLOT;
+        break;
+    case EM_PPC64:
+        slot = R_PPC64_JMP_SLOT;
+        break;
     case EM_386:
     case EM_486:
         slot = R_386_JUMP_SLOT;

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Thu Oct 30 21:34:28 2014
@@ -1724,6 +1724,7 @@ ObjectFileELF::ParseSymbols (Symtab *sym
     static ConstString rodata1_section_name(".rodata1");
     static ConstString data2_section_name(".data1");
     static ConstString bss_section_name(".bss");
+    static ConstString opd_section_name(".opd");    // For ppc64
 
     //StreamFile strm(stdout, false);
     unsigned i;

Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Thu Oct 30 21:34:28 2014
@@ -326,6 +326,13 @@ PlatformFreeBSD::GetSoftwareBreakpointTr
             trap_opcode_size = sizeof(g_i386_opcode);
         }
         break;
+	case llvm::Triple::ppc:
+	case llvm::Triple::ppc64:
+		{
+			static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
+			trap_opcode = g_ppc_opcode;
+			trap_opcode_size = sizeof(g_ppc_opcode);
+		}
     }
 
     if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Thu Oct 30 21:34:28 2014
@@ -113,6 +113,7 @@ PtraceWrapper(int req, lldb::pid_t pid,
             log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax);
         }
 #endif
+#ifndef __powerpc__
         if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
             struct dbreg *r = (struct dbreg *) addr;
             char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
@@ -120,6 +121,7 @@ PtraceWrapper(int req, lldb::pid_t pid,
             for (int i = 0; i <= 7; i++)
                 log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
         }
+#endif
     }
      
     return result;

Modified: lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -12,5 +12,6 @@ add_lldb_library(lldbPluginProcessPOSIX
   ProcessPOSIXLog.cpp
   RegisterContextPOSIXProcessMonitor_arm64.cpp
   RegisterContextPOSIXProcessMonitor_mips64.cpp
+  RegisterContextPOSIXProcessMonitor_powerpc.cpp
   RegisterContextPOSIXProcessMonitor_x86.cpp
   )

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Thu Oct 30 21:34:28 2014
@@ -34,12 +34,14 @@
 #include "Plugins/Process/Linux/ProcessMonitor.h"
 #include "RegisterContextPOSIXProcessMonitor_arm64.h"
 #include "RegisterContextPOSIXProcessMonitor_mips64.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
 #include "RegisterContextPOSIXProcessMonitor_x86.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
 #include "Plugins/Process/Utility/UnwindLLDB.h"
 
@@ -167,6 +169,14 @@ POSIXThread::GetRegisterContext()
             case llvm::Triple::FreeBSD:
                 switch (target_arch.GetMachine())
                 {
+                    case llvm::Triple::ppc:
+#ifndef __powerpc64__
+                        reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
+                        break;
+#endif
+                    case llvm::Triple::ppc64:
+                        reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
+                        break;
                     case llvm::Triple::mips64:
                         reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
                         break;
@@ -229,6 +239,14 @@ POSIXThread::GetRegisterContext()
                     m_reg_context_sp.reset(reg_ctx);
                     break;
                 }
+            case llvm::Triple::ppc:
+            case llvm::Triple::ppc64:
+                {
+                    RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface);
+                    m_posix_thread = reg_ctx;
+                    m_reg_context_sp.reset(reg_ctx);
+                    break;
+                }
             case llvm::Triple::x86:
             case llvm::Triple::x86_64:
                 {
@@ -624,6 +642,8 @@ POSIXThread::GetRegisterIndexFromOffset(
 
     case llvm::Triple::aarch64:
     case llvm::Triple::mips64:
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
     case llvm::Triple::x86:
     case llvm::Triple::x86_64:
         {
@@ -655,6 +675,8 @@ POSIXThread::GetRegisterName(unsigned re
 
     case llvm::Triple::aarch64:
     case llvm::Triple::mips64:
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
     case llvm::Triple::x86:
     case llvm::Triple::x86_64:
         name = GetRegisterContext()->GetRegisterName(reg);

Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp (added)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,316 @@
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Core/RegisterValue.h"
+
+#include "RegisterContextPOSIX_powerpc.h"
+#include "ProcessPOSIX.h"
+#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
+#include "ProcessMonitor.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+#define REG_CONTEXT_SIZE (GetGPRSize())
+
+RegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread,
+                                                                                     uint32_t concrete_frame_idx,
+                                                                                     lldb_private::RegisterInfoInterface *register_info)
+    : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info)
+{
+}
+
+ProcessMonitor &
+RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor()
+{
+    ProcessSP base = CalculateProcess();
+    ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
+    return process->GetMonitor();
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
+{
+     ProcessMonitor &monitor = GetMonitor();
+     return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
+{
+    // XXX not yet implemented
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
+{
+    // XXX not yet implemented
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg,
+                                                        RegisterValue &value)
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadRegisterValue(m_thread.GetID(),
+                                     GetRegisterOffset(reg),
+                                     GetRegisterName(reg),
+                                     GetRegisterSize(reg),
+                                     value);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const unsigned reg,
+                                                         const RegisterValue &value)
+{
+    unsigned reg_to_write = reg;
+    RegisterValue value_to_write = value;
+
+    // Check if this is a subregister of a full register.
+    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+    if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
+    {
+        RegisterValue full_value;
+        uint32_t full_reg = reg_info->invalidate_regs[0];
+        const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+        // Read the full register.
+        if (ReadRegister(full_reg_info, full_value))
+        {
+            Error error;
+            ByteOrder byte_order = GetByteOrder();
+            uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+            // Get the bytes for the full register.
+            const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
+                                                                   dst,
+                                                                   sizeof(dst),
+                                                                   byte_order,
+                                                                   error);
+            if (error.Success() && dest_size)
+            {
+                uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+                // Get the bytes for the source data.
+                const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
+                if (error.Success() && src_size && (src_size < dest_size))
+                {
+                    // Copy the src bytes to the destination.
+                    memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
+                    // Set this full register as the value to write.
+                    value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+                    value_to_write.SetType(full_reg_info);
+                    reg_to_write = full_reg;
+                }
+            }
+        }
+    }
+
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteRegisterValue(m_thread.GetID(),
+                                      GetRegisterOffset(reg_to_write),
+                                      GetRegisterName(reg_to_write),
+                                      value_to_write);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+    if (!reg_info)
+        return false;
+
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+    if (IsFPR(reg))
+    {
+        if (!ReadFPR())
+            return false;
+    }
+    else
+    {
+        uint32_t full_reg = reg;
+        bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+        if (is_subreg)
+        {
+            // Read the full aligned 64-bit register.
+            full_reg = reg_info->invalidate_regs[0];
+        }
+
+        bool success = ReadRegister(full_reg, value);
+
+        if (success)
+        {
+            // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
+            if (is_subreg && (reg_info->byte_offset & 0x1))
+                value.SetUInt64(value.GetAsUInt64() >> 8);
+
+            // If our return byte size was greater than the return value reg size, then
+            // use the type specified by reg_info rather than the uint64_t default
+            if (value.GetByteSize() > reg_info->byte_size)
+                value.SetType(reg_info);
+        }
+        return success;
+    }
+
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+    if (IsGPR(reg))
+        return WriteRegister(reg, value);
+
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(DataBufferSP &data_sp)
+{
+    bool success = false;
+    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+    if (data_sp && ReadGPR () && ReadFPR ())
+    {
+        uint8_t *dst = data_sp->GetBytes();
+        success = dst != 0;
+
+        if (success)
+        {
+            ::memcpy (dst, &m_gpr_powerpc, GetGPRSize());
+            dst += GetGPRSize();
+        }
+    }
+    return success;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBufferSP &data_sp)
+{
+    bool success = false;
+    if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
+    {
+        uint8_t *src = data_sp->GetBytes();
+        if (src)
+        {
+            ::memcpy (&m_gpr_powerpc, src, GetGPRSize());
+
+            if (WriteGPR())
+            {
+                src += GetGPRSize();
+            }
+        }
+    }
+    return success;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(addr_t addr, size_t size,
+                                              bool read, bool write)
+{
+    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+    uint32_t hw_index;
+
+    for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
+    {
+        if (IsWatchpointVacant(hw_index))
+            return SetHardwareWatchpointWithIndex(addr, size,
+                                                  read, write,
+                                                  hw_index);
+    }
+
+    return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(bool enable)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint()
+{
+    lldb::addr_t pc;
+
+    if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+        return false;
+
+    return true;
+}
+
+unsigned
+RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(unsigned offset)
+{
+    unsigned reg;
+    for (reg = 0; reg < k_num_registers_powerpc; reg++)
+    {
+        if (GetRegisterInfo()[reg].byte_offset == offset)
+            break;
+    }
+    assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+    return reg;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits()
+{
+    return false;
+}
+
+addr_t
+RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(uint32_t hw_index)
+{
+    return LLDB_INVALID_ADDRESS;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
+                                                       bool read, bool write,
+                                                       uint32_t hw_index)
+{
+    return false;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints()
+{
+    return 0;
+}
+

Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,95 @@
+//===-- RegisterContextPOSIXProcessMonitor_powerpc.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_RegisterContextPOSIXProcessMonitor_powerpc_H_
+#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+
+class RegisterContextPOSIXProcessMonitor_powerpc:
+    public RegisterContextPOSIX_powerpc,
+    public POSIXBreakpointProtocol
+{
+public:
+    RegisterContextPOSIXProcessMonitor_powerpc(lldb_private::Thread &thread,
+                                              uint32_t concrete_frame_idx,
+                                              lldb_private::RegisterInfoInterface *register_info);
+
+protected:
+    bool
+    ReadGPR();
+
+    bool
+    ReadFPR();
+
+    bool
+    WriteGPR();
+
+    bool
+    WriteFPR();
+
+    // lldb_private::RegisterContext
+    bool
+    ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+
+    bool
+    WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+
+    bool
+    ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+    bool
+    WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+    bool
+    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+    bool
+    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+    uint32_t
+    SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+
+    bool
+    ClearHardwareWatchpoint(uint32_t hw_index);
+
+    bool
+    HardwareSingleStep(bool enable);
+
+    // POSIXBreakpointProtocol
+    bool
+    UpdateAfterBreakpoint();
+
+    unsigned
+    GetRegisterIndexFromOffset(unsigned offset);
+
+    bool
+    IsWatchpointHit(uint32_t hw_index);
+
+    bool
+    ClearWatchpointHits();
+
+    lldb::addr_t
+    GetWatchpointAddress(uint32_t hw_index);
+
+    bool
+    IsWatchpointVacant(uint32_t hw_index);
+
+    bool
+    SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+
+    uint32_t
+    NumSupportedHardwareWatchpoints();
+
+private:
+    ProcessMonitor &
+    GetMonitor();
+};
+
+#endif

Modified: lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -16,6 +16,7 @@ add_lldb_library(lldbPluginProcessUtilit
   RegisterContextDummy.cpp
   RegisterContextFreeBSD_i386.cpp
   RegisterContextFreeBSD_mips64.cpp
+  RegisterContextFreeBSD_powerpc.cpp
   RegisterContextFreeBSD_x86_64.cpp
   RegisterContextHistory.cpp
   RegisterContextLinux_arm64.cpp
@@ -29,6 +30,7 @@ add_lldb_library(lldbPluginProcessUtilit
   RegisterContextMemory.cpp
   RegisterContextPOSIX_arm64.cpp
   RegisterContextPOSIX_mips64.cpp
+  RegisterContextPOSIX_powerpc.cpp
   RegisterContextPOSIX_x86.cpp
   RegisterContextThreadMemory.cpp
   StopInfoMachException.cpp

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,227 @@
+//===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <vector>
+#include "RegisterContextPOSIX_powerpc.h"
+#include "RegisterContextFreeBSD_powerpc.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h
+typedef struct _GPR64
+{
+    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 lr;
+    uint64_t cr;
+    uint64_t xer;
+    uint64_t ctr;
+    uint64_t pc;
+} GPR64;
+
+typedef struct _GPR32
+{
+    uint32_t r0;
+    uint32_t r1;
+    uint32_t r2;
+    uint32_t r3;
+    uint32_t r4;
+    uint32_t r5;
+    uint32_t r6;
+    uint32_t r7;
+    uint32_t r8;
+    uint32_t r9;
+    uint32_t r10;
+    uint32_t r11;
+    uint32_t r12;
+    uint32_t r13;
+    uint32_t r14;
+    uint32_t r15;
+    uint32_t r16;
+    uint32_t r17;
+    uint32_t r18;
+    uint32_t r19;
+    uint32_t r20;
+    uint32_t r21;
+    uint32_t r22;
+    uint32_t r23;
+    uint32_t r24;
+    uint32_t r25;
+    uint32_t r26;
+    uint32_t r27;
+    uint32_t r28;
+    uint32_t r29;
+    uint32_t r30;
+    uint32_t r31;
+    uint32_t lr;
+    uint32_t cr;
+    uint32_t xer;
+    uint32_t ctr;
+    uint32_t pc;
+} GPR32;
+
+typedef struct _FPR
+{
+    uint64_t f0;
+    uint64_t f1;
+    uint64_t f2;
+    uint64_t f3;
+    uint64_t f4;
+    uint64_t f5;
+    uint64_t f6;
+    uint64_t f7;
+    uint64_t f8;
+    uint64_t f9;
+    uint64_t f10;
+    uint64_t f11;
+    uint64_t f12;
+    uint64_t f13;
+    uint64_t f14;
+    uint64_t f15;
+    uint64_t f16;
+    uint64_t f17;
+    uint64_t f18;
+    uint64_t f19;
+    uint64_t f20;
+    uint64_t f21;
+    uint64_t f22;
+    uint64_t f23;
+    uint64_t f24;
+    uint64_t f25;
+    uint64_t f26;
+    uint64_t f27;
+    uint64_t f28;
+    uint64_t f29;
+    uint64_t f30;
+    uint64_t f31;
+    uint64_t fpscr;
+} FPR;
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_POWERPC_STRUCT
+#include "RegisterInfos_powerpc.h"
+#undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
+
+RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(const ArchSpec &target_arch) :
+    RegisterInfoInterface(target_arch)
+{
+}
+
+RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc()
+{
+}
+
+size_t
+RegisterContextFreeBSD_powerpc::GetGPRSize() const
+{
+    return sizeof(GPR64);
+}
+
+const RegisterInfo *
+RegisterContextFreeBSD_powerpc::GetRegisterInfo() const
+{
+    //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+    llvm_unreachable("Abstract class!");
+    return NULL;
+}
+
+uint32_t
+RegisterContextFreeBSD_powerpc::GetRegisterCount () const
+{
+    return 0;
+}
+
+RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(const ArchSpec &target_arch) :
+    RegisterContextFreeBSD_powerpc(target_arch)
+{
+}
+
+RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32()
+{
+}
+
+size_t
+RegisterContextFreeBSD_powerpc32::GetGPRSize() const
+{
+    return sizeof(GPR32);
+}
+
+const RegisterInfo *
+RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const
+{
+    //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+    return g_register_infos_powerpc32;
+}
+
+uint32_t
+RegisterContextFreeBSD_powerpc32::GetRegisterCount () const
+{
+    return static_cast<uint32_t> (sizeof (g_register_infos_powerpc32) / sizeof (g_register_infos_powerpc32 [0]));
+}
+
+RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(const ArchSpec &target_arch) :
+    RegisterContextFreeBSD_powerpc(target_arch)
+{
+}
+
+RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64()
+{
+}
+
+size_t
+RegisterContextFreeBSD_powerpc64::GetGPRSize() const
+{
+    return sizeof(GPR64);
+}
+
+const RegisterInfo *
+RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const
+{
+    //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc);
+    return g_register_infos_powerpc64;
+}
+
+uint32_t
+RegisterContextFreeBSD_powerpc64::GetRegisterCount () const
+{
+    return static_cast<uint32_t> (sizeof (g_register_infos_powerpc64) / sizeof (g_register_infos_powerpc64 [0]));
+}

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,66 @@
+//===-- RegisterContextFreeBSD_powerpc.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_RegisterContextFreeBSD_powerpc_H_
+#define liblldb_RegisterContextFreeBSD_powerpc_H_
+
+#include "RegisterContextPOSIX.h"
+
+class RegisterContextFreeBSD_powerpc:
+    public lldb_private::RegisterInfoInterface
+{
+public:
+    RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch);
+    virtual ~RegisterContextFreeBSD_powerpc();
+
+    size_t
+    GetGPRSize() const override;
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfo() const override;
+
+    uint32_t
+    GetRegisterCount() const override;
+};
+
+class RegisterContextFreeBSD_powerpc32:
+    public RegisterContextFreeBSD_powerpc
+{
+public:
+    RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch);
+    virtual ~RegisterContextFreeBSD_powerpc32();
+
+    size_t
+    GetGPRSize() const override;
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfo() const override;
+
+    uint32_t
+    GetRegisterCount() const override;
+};
+
+class RegisterContextFreeBSD_powerpc64:
+    public RegisterContextFreeBSD_powerpc
+{
+public:
+    RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch);
+    virtual ~RegisterContextFreeBSD_powerpc64();
+
+    size_t
+    GetGPRSize() const override;
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfo() const override;
+
+    uint32_t
+    GetRegisterCount() const override;
+};
+
+#endif

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Thu Oct 30 21:34:28 2014
@@ -149,7 +149,8 @@ RegisterContextMacOSXFrameBackchain::Rea
 
             // TOOD: need a better way to detect when "long double" types are
             // the same bytes size as "double"
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && !defined(__mips__)
+#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \
+    !defined(__mips__) && !defined(__powerpc__)
         case sizeof (long double):
             if (sizeof (long double) == sizeof(uint32_t))
             {

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,273 @@
+//===-- RegisterContextPOSIX_powerpc.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/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Host/Endian.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterContextPOSIX_powerpc.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+static const
+uint32_t g_gpr_regnums[] =
+{
+    gpr_r0_powerpc,
+    gpr_r1_powerpc,
+    gpr_r2_powerpc,
+    gpr_r3_powerpc,
+    gpr_r4_powerpc,
+    gpr_r5_powerpc,
+    gpr_r6_powerpc,
+    gpr_r7_powerpc,
+    gpr_r8_powerpc,
+    gpr_r9_powerpc,
+    gpr_r10_powerpc,
+    gpr_r11_powerpc,
+    gpr_r12_powerpc,
+    gpr_r13_powerpc,
+    gpr_r14_powerpc,
+    gpr_r15_powerpc,
+    gpr_r16_powerpc,
+    gpr_r17_powerpc,
+    gpr_r18_powerpc,
+    gpr_r19_powerpc,
+    gpr_r20_powerpc,
+    gpr_r21_powerpc,
+    gpr_r22_powerpc,
+    gpr_r23_powerpc,
+    gpr_r24_powerpc,
+    gpr_r25_powerpc,
+    gpr_r26_powerpc,
+    gpr_r27_powerpc,
+    gpr_r28_powerpc,
+    gpr_r29_powerpc,
+    gpr_r30_powerpc,
+    gpr_r31_powerpc,
+    gpr_lr_powerpc,
+    gpr_cr_powerpc,
+    gpr_xer_powerpc,
+    gpr_ctr_powerpc,
+    gpr_pc_powerpc,
+};
+
+static const
+uint32_t g_fpr_regnums[] =
+{
+    fpr_f0_powerpc,
+    fpr_f1_powerpc,
+    fpr_f2_powerpc,
+    fpr_f3_powerpc,
+    fpr_f4_powerpc,
+    fpr_f5_powerpc,
+    fpr_f6_powerpc,
+    fpr_f7_powerpc,
+    fpr_f8_powerpc,
+    fpr_f9_powerpc,
+    fpr_f10_powerpc,
+    fpr_f11_powerpc,
+    fpr_f12_powerpc,
+    fpr_f13_powerpc,
+    fpr_f14_powerpc,
+    fpr_f15_powerpc,
+    fpr_f16_powerpc,
+    fpr_f17_powerpc,
+    fpr_f18_powerpc,
+    fpr_f19_powerpc,
+    fpr_f20_powerpc,
+    fpr_f21_powerpc,
+    fpr_f22_powerpc,
+    fpr_f23_powerpc,
+    fpr_f24_powerpc,
+    fpr_f25_powerpc,
+    fpr_f26_powerpc,
+    fpr_f27_powerpc,
+    fpr_f28_powerpc,
+    fpr_f29_powerpc,
+    fpr_f30_powerpc,
+    fpr_f31_powerpc,
+    fpr_fpscr_powerpc,
+};
+
+// Number of register sets provided by this context.
+enum
+{
+    k_num_register_sets = 2
+};
+
+static const RegisterSet
+g_reg_sets_powerpc[k_num_register_sets] =
+{
+    { "General Purpose Registers",  "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
+    { "Floating Point Registers",  "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
+};
+
+bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
+{
+    return reg <= k_num_gpr_registers_powerpc;   // GPR's come first.
+}
+
+bool
+RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
+{
+    // XXX
+    return (reg >= k_first_fpr) && (reg <= k_last_fpr);
+}
+
+RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
+                                               uint32_t concrete_frame_idx,
+                                               RegisterInfoInterface *register_info)
+    : RegisterContext(thread, concrete_frame_idx)
+{
+    m_register_info_ap.reset(register_info);
+
+    // elf-core yet to support ReadFPR()
+    ProcessSP base = CalculateProcess();
+    if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
+        return;
+}
+
+RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
+{
+}
+
+void
+RegisterContextPOSIX_powerpc::Invalidate()
+{
+}
+
+void
+RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
+{
+}
+
+unsigned
+RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
+{
+    assert(reg < k_num_registers_powerpc && "Invalid register number.");
+    return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned
+RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
+{
+    assert(reg < k_num_registers_powerpc && "Invalid register number.");
+    return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t
+RegisterContextPOSIX_powerpc::GetRegisterCount()
+{
+    size_t num_registers = k_num_registers_powerpc;
+    return num_registers;
+}
+
+size_t
+RegisterContextPOSIX_powerpc::GetGPRSize()
+{
+    return m_register_info_ap->GetGPRSize();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_powerpc::GetRegisterInfo()
+{
+    // Commonly, this method is overridden and g_register_infos is copied and specialized.
+    // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+    return m_register_info_ap->GetRegisterInfo ();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
+{
+    if (reg < k_num_registers_powerpc)
+        return &GetRegisterInfo()[reg];
+    else
+        return NULL;
+}
+
+size_t
+RegisterContextPOSIX_powerpc::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_powerpc::GetRegisterSet(size_t set)
+{
+    if (IsRegisterSetAvailable(set))
+        return &g_reg_sets_powerpc[set];
+    else
+        return NULL;
+}
+
+const char *
+RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
+{
+    assert(reg < k_num_registers_powerpc && "Invalid register offset.");
+    return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder
+RegisterContextPOSIX_powerpc::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;
+}
+
+bool
+RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
+{
+    size_t num_sets = k_num_register_sets;
+
+    return (set_index < num_sets);
+}
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them.
+uint32_t
+RegisterContextPOSIX_powerpc::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;
+}
+

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,173 @@
+//===-- RegisterContextPOSIX_powerpc.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_powerpc_H_
+#define liblldb_RegisterContextPOSIX_powerpc_H_
+
+#include "lldb/Core/Log.h"
+#include "RegisterContextPOSIX.h"
+#include "RegisterContext_powerpc.h"
+
+class ProcessMonitor;
+
+// ---------------------------------------------------------------------------
+// Internal codes for all powerpc registers.
+// ---------------------------------------------------------------------------
+enum
+{
+    k_first_gpr_powerpc,
+    gpr_r0_powerpc = k_first_gpr_powerpc,
+    gpr_r1_powerpc,
+    gpr_r2_powerpc,
+    gpr_r3_powerpc,
+    gpr_r4_powerpc,
+    gpr_r5_powerpc,
+    gpr_r6_powerpc,
+    gpr_r7_powerpc,
+    gpr_r8_powerpc,
+    gpr_r9_powerpc,
+    gpr_r10_powerpc,
+    gpr_r11_powerpc,
+    gpr_r12_powerpc,
+    gpr_r13_powerpc,
+    gpr_r14_powerpc,
+    gpr_r15_powerpc,
+    gpr_r16_powerpc,
+    gpr_r17_powerpc,
+    gpr_r18_powerpc,
+    gpr_r19_powerpc,
+    gpr_r20_powerpc,
+    gpr_r21_powerpc,
+    gpr_r22_powerpc,
+    gpr_r23_powerpc,
+    gpr_r24_powerpc,
+    gpr_r25_powerpc,
+    gpr_r26_powerpc,
+    gpr_r27_powerpc,
+    gpr_r28_powerpc,
+    gpr_r29_powerpc,
+    gpr_r30_powerpc,
+    gpr_r31_powerpc,
+    gpr_lr_powerpc,
+    gpr_cr_powerpc,
+    gpr_xer_powerpc,
+    gpr_ctr_powerpc,
+    gpr_pc_powerpc,
+    k_last_gpr_powerpc = gpr_pc_powerpc,
+
+    k_first_fpr,
+    fpr_f0_powerpc = k_first_fpr,
+    fpr_f1_powerpc,
+    fpr_f2_powerpc,
+    fpr_f3_powerpc,
+    fpr_f4_powerpc,
+    fpr_f5_powerpc,
+    fpr_f6_powerpc,
+    fpr_f7_powerpc,
+    fpr_f8_powerpc,
+    fpr_f9_powerpc,
+    fpr_f10_powerpc,
+    fpr_f11_powerpc,
+    fpr_f12_powerpc,
+    fpr_f13_powerpc,
+    fpr_f14_powerpc,
+    fpr_f15_powerpc,
+    fpr_f16_powerpc,
+    fpr_f17_powerpc,
+    fpr_f18_powerpc,
+    fpr_f19_powerpc,
+    fpr_f20_powerpc,
+    fpr_f21_powerpc,
+    fpr_f22_powerpc,
+    fpr_f23_powerpc,
+    fpr_f24_powerpc,
+    fpr_f25_powerpc,
+    fpr_f26_powerpc,
+    fpr_f27_powerpc,
+    fpr_f28_powerpc,
+    fpr_f29_powerpc,
+    fpr_f30_powerpc,
+    fpr_f31_powerpc,
+    fpr_fpscr_powerpc,
+    k_last_fpr = fpr_fpscr_powerpc,
+
+    k_num_registers_powerpc,
+    k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
+    k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
+};
+
+class RegisterContextPOSIX_powerpc
+  : public lldb_private::RegisterContext
+{
+public:
+    RegisterContextPOSIX_powerpc (lldb_private::Thread &thread,
+                            uint32_t concrete_frame_idx,
+                            lldb_private::RegisterInfoInterface *register_info);
+
+    ~RegisterContextPOSIX_powerpc();
+
+    void
+    Invalidate();
+
+    void
+    InvalidateAllRegisters();
+
+    size_t
+    GetRegisterCount();
+
+    virtual size_t
+    GetGPRSize();
+
+    virtual unsigned
+    GetRegisterSize(unsigned reg);
+
+    virtual unsigned
+    GetRegisterOffset(unsigned reg);
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfoAtIndex(size_t reg);
+
+    size_t
+    GetRegisterSetCount();
+
+    const lldb_private::RegisterSet *
+    GetRegisterSet(size_t set);
+
+    const char *
+    GetRegisterName(unsigned reg);
+
+    uint32_t
+    ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num);
+
+protected:
+    uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc];         // general purpose registers.
+    std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+    // Determines if an extended register set is supported on the processor running the inferior process.
+    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 // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterContext_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContext_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContext_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContext_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,163 @@
+//===-- RegisterContext_powerpc.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_powerpc_H_
+#define liblldb_RegisterContext_powerpc_H_
+
+// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF)
+enum
+{
+    gcc_dwarf_r0_powerpc = 0,
+    gcc_dwarf_r1_powerpc,
+    gcc_dwarf_r2_powerpc,
+    gcc_dwarf_r3_powerpc,
+    gcc_dwarf_r4_powerpc,
+    gcc_dwarf_r5_powerpc,
+    gcc_dwarf_r6_powerpc,
+    gcc_dwarf_r7_powerpc,
+    gcc_dwarf_r8_powerpc,
+    gcc_dwarf_r9_powerpc,
+    gcc_dwarf_r10_powerpc,
+    gcc_dwarf_r11_powerpc,
+    gcc_dwarf_r12_powerpc,
+    gcc_dwarf_r13_powerpc,
+    gcc_dwarf_r14_powerpc,
+    gcc_dwarf_r15_powerpc,
+    gcc_dwarf_r16_powerpc,
+    gcc_dwarf_r17_powerpc,
+    gcc_dwarf_r18_powerpc,
+    gcc_dwarf_r19_powerpc,
+    gcc_dwarf_r20_powerpc,
+    gcc_dwarf_r21_powerpc,
+    gcc_dwarf_r22_powerpc,
+    gcc_dwarf_r23_powerpc,
+    gcc_dwarf_r24_powerpc,
+    gcc_dwarf_r25_powerpc,
+    gcc_dwarf_r26_powerpc,
+    gcc_dwarf_r27_powerpc,
+    gcc_dwarf_r28_powerpc,
+    gcc_dwarf_r29_powerpc,
+    gcc_dwarf_r30_powerpc,
+    gcc_dwarf_r31_powerpc,
+    gcc_dwarf_f0_powerpc,
+    gcc_dwarf_f1_powerpc,
+    gcc_dwarf_f2_powerpc,
+    gcc_dwarf_f3_powerpc,
+    gcc_dwarf_f4_powerpc,
+    gcc_dwarf_f5_powerpc,
+    gcc_dwarf_f6_powerpc,
+    gcc_dwarf_f7_powerpc,
+    gcc_dwarf_f8_powerpc,
+    gcc_dwarf_f9_powerpc,
+    gcc_dwarf_f10_powerpc,
+    gcc_dwarf_f11_powerpc,
+    gcc_dwarf_f12_powerpc,
+    gcc_dwarf_f13_powerpc,
+    gcc_dwarf_f14_powerpc,
+    gcc_dwarf_f15_powerpc,
+    gcc_dwarf_f16_powerpc,
+    gcc_dwarf_f17_powerpc,
+    gcc_dwarf_f18_powerpc,
+    gcc_dwarf_f19_powerpc,
+    gcc_dwarf_f20_powerpc,
+    gcc_dwarf_f21_powerpc,
+    gcc_dwarf_f22_powerpc,
+    gcc_dwarf_f23_powerpc,
+    gcc_dwarf_f24_powerpc,
+    gcc_dwarf_f25_powerpc,
+    gcc_dwarf_f26_powerpc,
+    gcc_dwarf_f27_powerpc,
+    gcc_dwarf_f28_powerpc,
+    gcc_dwarf_f29_powerpc,
+    gcc_dwarf_f30_powerpc,
+    gcc_dwarf_f31_powerpc,
+    gcc_dwarf_cr_powerpc,
+    gcc_dwarf_fpscr_powerpc,
+    gcc_dwarf_xer_powerpc = 101,
+    gcc_dwarf_lr_powerpc = 108,
+    gcc_dwarf_ctr_powerpc,
+    gcc_dwarf_pc_powerpc,
+};
+
+// GDB Register numbers (eRegisterKindGDB)
+enum
+{
+    gdb_r0_powerpc = 0,
+    gdb_r1_powerpc,
+    gdb_r2_powerpc,
+    gdb_r3_powerpc,
+    gdb_r4_powerpc,
+    gdb_r5_powerpc,
+    gdb_r6_powerpc,
+    gdb_r7_powerpc,
+    gdb_r8_powerpc,
+    gdb_r9_powerpc,
+    gdb_r10_powerpc,
+    gdb_r11_powerpc,
+    gdb_r12_powerpc,
+    gdb_r13_powerpc,
+    gdb_r14_powerpc,
+    gdb_r15_powerpc,
+    gdb_r16_powerpc,
+    gdb_r17_powerpc,
+    gdb_r18_powerpc,
+    gdb_r19_powerpc,
+    gdb_r20_powerpc,
+    gdb_r21_powerpc,
+    gdb_r22_powerpc,
+    gdb_r23_powerpc,
+    gdb_r24_powerpc,
+    gdb_r25_powerpc,
+    gdb_r26_powerpc,
+    gdb_r27_powerpc,
+    gdb_r28_powerpc,
+    gdb_r29_powerpc,
+    gdb_r30_powerpc,
+    gdb_r31_powerpc,
+    gdb_f0_powerpc,
+    gdb_f1_powerpc,
+    gdb_f2_powerpc,
+    gdb_f3_powerpc,
+    gdb_f4_powerpc,
+    gdb_f5_powerpc,
+    gdb_f6_powerpc,
+    gdb_f7_powerpc,
+    gdb_f8_powerpc,
+    gdb_f9_powerpc,
+    gdb_f10_powerpc,
+    gdb_f11_powerpc,
+    gdb_f12_powerpc,
+    gdb_f13_powerpc,
+    gdb_f14_powerpc,
+    gdb_f15_powerpc,
+    gdb_f16_powerpc,
+    gdb_f17_powerpc,
+    gdb_f18_powerpc,
+    gdb_f19_powerpc,
+    gdb_f20_powerpc,
+    gdb_f21_powerpc,
+    gdb_f22_powerpc,
+    gdb_f23_powerpc,
+    gdb_f24_powerpc,
+    gdb_f25_powerpc,
+    gdb_f26_powerpc,
+    gdb_f27_powerpc,
+    gdb_f28_powerpc,
+    gdb_f29_powerpc,
+    gdb_f30_powerpc,
+    gdb_f31_powerpc,
+    gdb_cr_powerpc,
+    gdb_fpscr_powerpc,
+    gdb_xer_powerpc = 101,
+    gdb_lr_powerpc = 108,
+    gdb_ctr_powerpc,
+    gdb_pc_powerpc,
+};
+
+#endif // liblldb_RegisterContext_powerpc_H_

Added: lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterInfos_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,127 @@
+//===-- RegisterInfos_powerpc.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <stddef.h>
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname)                                                 \
+    (offsetof(GPR, regname))
+#define FPR_OFFSET(regname)                                                 \
+    (offsetof(FPR, regname))
+
+#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, lldb_kind)           \
+    { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
+      eFormatHex, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, gpr_##reg##_powerpc }, NULL, NULL }
+#define DEFINE_FPR(reg, lldb_kind)           \
+    { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
+      eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL }
+
+    // General purpose registers.                 GCC,                  DWARF,              Generic,                GDB
+#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(lr,       "lr",  LLDB_REGNUM_GENERIC_RA), \
+    DEFINE_GPR(cr,       "cr",  LLDB_REGNUM_GENERIC_FLAGS), \
+    DEFINE_GPR(xer,      "xer", LLDB_INVALID_REGNUM), \
+    DEFINE_GPR(ctr,      "ctr", LLDB_INVALID_REGNUM), \
+    DEFINE_GPR(pc,       "pc",  LLDB_REGNUM_GENERIC_PC), \
+    DEFINE_FPR(f0,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f1,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f2,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f3,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f4,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f5,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f6,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f7,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f8,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f9,       LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f10,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f11,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f12,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f13,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f14,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f15,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f16,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f17,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f18,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f19,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f20,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f21,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f22,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f23,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f24,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f25,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f26,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f27,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f28,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f29,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f30,      LLDB_INVALID_REGNUM), \
+    DEFINE_FPR(f31,      LLDB_INVALID_REGNUM), \
+    { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL },
+    //{ NULL, NULL, sizeof(((GPR*)NULL)->r0), 0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cfa_powerpc}, NULL, NULL}
+static RegisterInfo
+g_register_infos_powerpc64[] =
+{
+#define GPR GPR64
+    POWERPC_REGS
+#undef GPR
+};
+
+static RegisterInfo
+g_register_infos_powerpc32[] =
+{
+#define GPR GPR32
+    POWERPC_REGS
+#undef GPR
+};
+static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc,
+    "g_register_infos_powerpc32 has wrong number of register infos");
+static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc,
+    "g_register_infos_powerpc64 has wrong number of register infos");
+
+#undef DEFINE_FPR
+#undef DEFINE_GPR
+
+#endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT
+
+#undef GPR_OFFSET
+

Modified: lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/CMakeLists.txt Thu Oct 30 21:34:28 2014
@@ -6,5 +6,6 @@ add_lldb_library(lldbPluginProcessElfCor
   ProcessElfCore.cpp
   ThreadElfCore.cpp
   RegisterContextPOSIXCore_mips64.cpp
+  RegisterContextPOSIXCore_powerpc.cpp
   RegisterContextPOSIXCore_x86_64.cpp
   )

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Thu Oct 30 21:34:28 2014
@@ -420,6 +420,7 @@ ParseFreeBSDPrStatus(ThreadData &thread_
 {
     lldb::offset_t offset = 0;
     bool lp64 = (arch.GetMachine() == llvm::Triple::mips64 ||
+                 arch.GetMachine() == llvm::Triple::ppc64 ||
                  arch.GetMachine() == llvm::Triple::x86_64);
     int pr_version = data.GetU32(&offset);
 

Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp (added)
+++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp Thu Oct 30 21:34:28 2014
@@ -0,0 +1,109 @@
+//===-- RegisterContextCorePOSIX_powerpc.cpp ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Thread.h"
+#include "RegisterContextPOSIX.h"
+#include "RegisterContextPOSIXCore_powerpc.h"
+
+using namespace lldb_private;
+
+RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
+                                                                 RegisterInfoInterface *register_info,
+                                                                 const DataExtractor &gpregset,
+                                                                 const DataExtractor &fpregset)
+    : RegisterContextPOSIX_powerpc(thread, 0, register_info)
+{
+    m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+    m_gpr.SetData(m_gpr_buffer);
+    m_gpr.SetByteOrder(gpregset.GetByteOrder());
+    m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+    m_fpr.SetData(m_fpr_buffer);
+    m_fpr.SetByteOrder(fpregset.GetByteOrder());
+}
+
+RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
+{
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::ReadGPR()
+{
+    return true;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::ReadFPR()
+{
+    return true;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::WriteGPR()
+{
+    assert(0);
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::WriteFPR()
+{
+    assert(0);
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+    lldb::offset_t offset = reg_info->byte_offset;
+    if (reg_info->name[0] == 'f') {
+        uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
+        if (offset == reg_info->byte_offset + reg_info->byte_size)
+        {
+            value = v;
+            return true;
+        }
+    } else {
+        uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+        if (offset == reg_info->byte_offset + reg_info->byte_size)
+        {
+            if (reg_info->byte_size < sizeof(v))
+                value = (uint32_t)v;
+            else
+                value = v;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable)
+{
+    return false;
+}

Added: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h?rev=220944&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h (added)
+++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h Thu Oct 30 21:34:28 2014
@@ -0,0 +1,62 @@
+//===-- RegisterContextCorePOSIX_powerpc.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_RegisterContextCorePOSIX_powerpc_H_
+#define liblldb_RegisterContextCorePOSIX_powerpc_H_
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+
+class RegisterContextCorePOSIX_powerpc :
+    public RegisterContextPOSIX_powerpc
+{
+public:
+    RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
+                                     lldb_private::RegisterInfoInterface *register_info,
+                                     const lldb_private::DataExtractor &gpregset,
+                                     const lldb_private::DataExtractor &fpregset);
+
+    ~RegisterContextCorePOSIX_powerpc();
+
+    virtual bool
+    ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+    virtual bool
+    WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+    bool
+    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+    bool
+    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+    bool
+    HardwareSingleStep(bool enable);
+
+protected:
+    bool
+    ReadGPR();
+
+    bool
+    ReadFPR();
+
+    bool
+    WriteGPR();
+
+    bool
+    WriteFPR();
+
+private:
+    lldb::DataBufferSP m_gpr_buffer;
+    lldb::DataBufferSP m_fpr_buffer;
+    lldb_private::DataExtractor m_gpr;
+    lldb_private::DataExtractor m_fpr;
+};
+
+#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_

Modified: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp Thu Oct 30 21:34:28 2014
@@ -19,8 +19,10 @@
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
 #include "RegisterContextPOSIXCore_mips64.h"
+#include "RegisterContextPOSIXCore_powerpc.h"
 #include "RegisterContextPOSIXCore_x86_64.h"
 
 using namespace lldb;
@@ -94,6 +96,12 @@ ThreadElfCore::CreateRegisterContextForF
             {
                 switch (arch.GetMachine())
                 {
+                    case llvm::Triple::ppc:
+                        reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
+                        break;
+                    case llvm::Triple::ppc64:
+                        reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
+                        break;
                     case llvm::Triple::mips64:
                         reg_interface = new RegisterContextFreeBSD_mips64(arch);
                         break;
@@ -138,6 +146,10 @@ ThreadElfCore::CreateRegisterContextForF
             case llvm::Triple::mips64:
                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
                 break;
+            case llvm::Triple::ppc:
+            case llvm::Triple::ppc64:
+                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data));
+                break;
             case llvm::Triple::x86:
             case llvm::Triple::x86_64:
                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Thu Oct 30 21:34:28 2014
@@ -2281,6 +2281,8 @@ Thread::GetUnwinder ()
             case llvm::Triple::aarch64:
             case llvm::Triple::thumb:
             case llvm::Triple::mips64:
+            case llvm::Triple::ppc64:
+            case llvm::Triple::ppc:
             case llvm::Triple::hexagon:
                 m_unwinder_ap.reset (new UnwindLLDB (*this));
                 break;

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=220944&r1=220943&r2=220944&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Thu Oct 30 21:34:28 2014
@@ -31,6 +31,8 @@
 #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
 #include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
 #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
+#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h"
+#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
 #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
@@ -132,6 +134,8 @@ lldb_private::Initialize ()
         ABIMacOSX_arm::Initialize();
         ABIMacOSX_arm64::Initialize();
         ABISysV_x86_64::Initialize();
+        ABISysV_ppc::Initialize();
+        ABISysV_ppc64::Initialize();
         DisassemblerLLVMC::Initialize();
         ObjectContainerBSDArchive::Initialize();
         ObjectFileELF::Initialize();
@@ -225,6 +229,7 @@ lldb_private::Terminate ()
     ABIMacOSX_arm::Terminate();
     ABIMacOSX_arm64::Terminate();
     ABISysV_x86_64::Terminate();
+    ABISysV_ppc64::Terminate();
     DisassemblerLLVMC::Terminate();
     ObjectContainerBSDArchive::Terminate();
     ObjectFileELF::Terminate();





More information about the lldb-commits mailing list