I have updated the patch after incorporating suggestions.

I have changed the alpha order issues and also I have marked argument registers 
as suggested.

About arm frame pointer I am still not sure if R11 is the right choice but as 
it works on nexus 5 I have made that change. Arm FP should be r7 in thumb mode 
and r11 in arm mode.

I am not sure if gnu-linux even uses a frame pointer.

Regarding arm trap handling, there is still a bit of work required to handle 
arm/thumb mode trap in little/big endian modes. I have skipped that change for 
now and will work on that and submit it later.

Host/Filesystem and Host/Pipeposix changes were some issues that were only 
visible on my build system so I have removed them from the patch and will later 
submit them with better solution and convincing arguments.

Looking forward to your consideration for accepting these changes.

PS: Can someone kindly help me with getting these patches committed or getting 
the commit rights to do it myself once they are accepted.

Thanks!


http://reviews.llvm.org/D8719

Files:
  source/Plugins/Process/Linux/CMakeLists.txt
  source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
  source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
  source/Plugins/Process/Linux/NativeThreadLinux.cpp
  source/Plugins/Process/POSIX/CMakeLists.txt
  source/Plugins/Process/POSIX/POSIXThread.cpp
  source/Plugins/Process/POSIX/ProcessPOSIX.cpp
  source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.cpp
  source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.h
  source/Plugins/Process/Utility/CMakeLists.txt
  source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
  source/Plugins/Process/Utility/RegisterContextLinux_arm.h
  source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
  source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
  source/Plugins/Process/Utility/RegisterInfos_arm.h
  source/Plugins/Process/Utility/lldb-arm-register-enums.h
  source/Plugins/Process/elf-core/CMakeLists.txt
  source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
  source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
  source/Plugins/Process/elf-core/ThreadElfCore.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: source/Plugins/Process/Linux/CMakeLists.txt
===================================================================
--- source/Plugins/Process/Linux/CMakeLists.txt
+++ source/Plugins/Process/Linux/CMakeLists.txt
@@ -7,6 +7,7 @@
 add_lldb_library(lldbPluginProcessLinux
   LinuxThread.cpp
   NativeProcessLinux.cpp
+  NativeRegisterContextLinux_arm.cpp
   NativeRegisterContextLinux_arm64.cpp
   NativeRegisterContextLinux_x86_64.cpp
   NativeRegisterContextLinux_mips64.cpp
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -0,0 +1,520 @@
+//===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextLinux_arm.h"
+
+#include "lldb/lldb-private-forward.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+
+#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+// arm general purpose registers.
+static const uint32_t g_gpr_regnums_arm[] =
+{
+    gpr_r0_arm,
+    gpr_r1_arm,
+    gpr_r2_arm,
+    gpr_r3_arm,
+    gpr_r4_arm,
+    gpr_r5_arm,
+    gpr_r6_arm,
+    gpr_r7_arm,
+    gpr_r8_arm,
+    gpr_r9_arm,
+    gpr_r10_arm,
+    gpr_r11_arm,
+    gpr_r12_arm,
+    gpr_sp_arm,
+    gpr_lr_arm,
+    gpr_pc_arm,
+    gpr_cpsr_arm,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+              "g_gpr_regnums_arm has wrong number of register infos");
+
+// arm floating point registers.
+static const uint32_t g_fpu_regnums_arm[] =
+{
+    fpu_s0_arm,
+    fpu_s1_arm,
+    fpu_s2_arm,
+    fpu_s3_arm,
+    fpu_s4_arm,
+    fpu_s5_arm,
+    fpu_s6_arm,
+    fpu_s7_arm,
+    fpu_s8_arm,
+    fpu_s9_arm,
+    fpu_s10_arm,
+    fpu_s11_arm,
+    fpu_s12_arm,
+    fpu_s13_arm,
+    fpu_s14_arm,
+    fpu_s15_arm,
+    fpu_s16_arm,
+    fpu_s17_arm,
+    fpu_s18_arm,
+    fpu_s19_arm,
+    fpu_s20_arm,
+    fpu_s21_arm,
+    fpu_s22_arm,
+    fpu_s23_arm,
+    fpu_s24_arm,
+    fpu_s25_arm,
+    fpu_s26_arm,
+    fpu_s27_arm,
+    fpu_s28_arm,
+    fpu_s29_arm,
+    fpu_s30_arm,
+    fpu_s31_arm,
+    fpu_fpscr_arm,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+              "g_fpu_regnums_arm has wrong number of register infos");
+
+namespace {
+    // Number of register sets provided by this context.
+    enum
+    {
+        k_num_register_sets = 2
+    };
+}
+
+// Register sets for arm.
+static const RegisterSet
+g_reg_sets_arm[k_num_register_sets] =
+{
+    { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
+    { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
+};
+
+NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (
+        NativeThreadProtocol &native_thread,
+        uint32_t concrete_frame_idx,
+        RegisterInfoInterface *reg_info_interface_p) :
+    NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
+{
+    switch (reg_info_interface_p->m_target_arch.GetMachine())
+    {
+        case llvm::Triple::arm:
+            m_reg_info.num_registers     = k_num_registers_arm;
+            m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+            m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+            m_reg_info.last_gpr          = k_last_gpr_arm;
+            m_reg_info.first_fpr         = k_first_fpr_arm;
+            m_reg_info.last_fpr          = k_last_fpr_arm;
+            m_reg_info.first_fpr_v       = fpu_s0_arm;
+            m_reg_info.last_fpr_v        = fpu_s31_arm;
+            m_reg_info.gpr_flags         = gpr_cpsr_arm;
+            break;
+        default:
+            assert(false && "Unhandled target architecture.");
+            break;
+    }
+
+    ::memset(&m_fpr, 0, sizeof (m_fpr));
+    ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm));
+}
+
+uint32_t
+NativeRegisterContextLinux_arm::GetRegisterSetCount () const
+{
+    return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const
+{
+    if (set_index < k_num_register_sets)
+        return &g_reg_sets_arm[set_index];
+
+    return nullptr;
+}
+
+Error
+NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
+{
+    Error error;
+
+    if (!reg_info)
+    {
+        error.SetErrorString ("reg_info NULL");
+        return error;
+    }
+
+    const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+    if (IsFPR(reg))
+    {
+        if (!ReadFPR())
+        {
+            error.SetErrorString ("failed to read floating point register");
+            return error;
+        }
+    }
+    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];
+        }
+
+        error = ReadRegisterRaw(full_reg, reg_value);
+
+        if (error.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))
+                reg_value.SetUInt64(reg_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 (reg_value.GetByteSize() > reg_info->byte_size)
+                reg_value.SetType(reg_info);
+        }
+        return error;
+    }
+
+    // Get pointer to m_fpr variable and set the data from it.
+    assert (reg_info->byte_offset < sizeof m_fpr);
+    uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+    switch (reg_info->byte_size)
+    {
+        case 2:
+            reg_value.SetUInt16(*(uint16_t *)src);
+            break;
+        case 4:
+            reg_value.SetUInt32(*(uint32_t *)src);
+            break;
+        case 8:
+            reg_value.SetUInt64(*(uint64_t *)src);
+            break;
+        default:
+            assert(false && "Unhandled data size.");
+            error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
+            break;
+    }
+
+    return error;
+}
+
+Error
+NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
+{
+    if (!reg_info)
+        return Error ("reg_info NULL");
+
+    const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+    if (reg_index == LLDB_INVALID_REGNUM)
+        return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
+
+    if (IsGPR(reg_index))
+        return WriteRegisterRaw(reg_index, reg_value);
+
+    if (IsFPR(reg_index))
+    {
+        // Get pointer to m_fpr variable and set the data to it.
+        assert (reg_info->byte_offset < sizeof(m_fpr));
+        uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
+        switch (reg_info->byte_size)
+        {
+            case 2:
+                *(uint16_t *)dst = reg_value.GetAsUInt16();
+                break;
+            case 4:
+                *(uint32_t *)dst = reg_value.GetAsUInt32();
+                break;
+            case 8:
+                *(uint64_t *)dst = reg_value.GetAsUInt64();
+                break;
+            default:
+                assert(false && "Unhandled data size.");
+                return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
+        }
+
+        if (!WriteFPR())
+        {
+            return Error ("NativeRegisterContextLinux_arm::WriteRegister: WriteFPR failed");
+        }
+
+        return Error ();
+    }
+
+    return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
+}
+
+Error
+NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
+{
+    Error error;
+
+    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+    if (!data_sp)
+        return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
+
+    if (!ReadGPR ())
+    {
+        error.SetErrorString ("ReadGPR() failed");
+        return error;
+    }
+
+    if (!ReadFPR ())
+    {
+        error.SetErrorString ("ReadFPR() failed");
+        return error;
+    }
+
+    uint8_t *dst = data_sp->GetBytes ();
+    if (dst == nullptr)
+    {
+        error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
+        return error;
+    }
+
+    ::memcpy (dst, &m_gpr_arm, GetGPRSize());
+    dst += GetGPRSize();
+    ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+
+    return error;
+}
+
+Error
+NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
+{
+    Error error;
+
+    if (!data_sp)
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
+        return error;
+    }
+
+    if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
+        return error;
+    }
+
+
+    uint8_t *src = data_sp->GetBytes ();
+    if (src == nullptr)
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
+        return error;
+    }
+    ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ());
+
+    if (!WriteGPR ())
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+        return error;
+    }
+
+    src += GetRegisterInfoInterface ().GetGPRSize ();
+    ::memcpy (&m_fpr, src, sizeof(m_fpr));
+
+    if (!WriteFPR ())
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+        return error;
+    }
+
+    return error;
+}
+
+Error
+NativeRegisterContextLinux_arm::WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value)
+{
+    Error error;
+
+    uint32_t reg_to_write = reg_index;
+    RegisterValue value_to_write = reg_value;
+
+    // Check if this is a subregister of a full register.
+    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
+    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.
+        error = ReadRegister(full_reg_info, full_value);
+        if (error.Fail ())
+            return error;
+
+        lldb::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 = reg_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;
+            }
+        }
+    }
+
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+    {
+        error.SetErrorString ("NativeProcessProtocol is NULL");
+        return error;
+    }
+
+    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
+    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
+    if (!register_to_write_info_p)
+    {
+        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_arm::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
+        return error;
+    }
+
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+    return process_p->WriteRegisterValue(m_thread.GetID(),
+                                         register_to_write_info_p->byte_offset,
+                                         register_to_write_info_p->name,
+                                         value_to_write);
+}
+
+Error
+NativeRegisterContextLinux_arm::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
+{
+    Error error;
+    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
+    if (!reg_info)
+    {
+        error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
+        return error;
+    }
+
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+    {
+        error.SetErrorString ("NativeProcessProtocol is NULL");
+        return error;
+    }
+
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+    return process_p->ReadRegisterValue(m_thread.GetID(),
+                                        reg_info->byte_offset,
+                                        reg_info->name,
+                                        reg_info->byte_size,
+                                        reg_value);
+}
+
+bool
+NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
+{
+    return reg <= m_reg_info.last_gpr;   // GPR's come first.
+}
+
+bool
+NativeRegisterContextLinux_arm::ReadGPR()
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return false;
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+    return process_p->ReadGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+}
+
+bool
+NativeRegisterContextLinux_arm::WriteGPR()
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return false;
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+
+    return process_p->WriteGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+}
+
+bool
+NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const
+{
+    return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+}
+
+bool
+NativeRegisterContextLinux_arm::ReadFPR ()
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return false;
+
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+    return process_p->ReadFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
+}
+
+bool
+NativeRegisterContextLinux_arm::WriteFPR ()
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return false;
+
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+    return process_p->WriteFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
+}
+
+lldb::ByteOrder
+NativeRegisterContextLinux_arm::GetByteOrder() const
+{
+    // Get the target process whose privileged thread was used for the register read.
+    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return byte_order;
+
+    if (!process_sp->GetByteOrder (byte_order))
+    {
+        // FIXME log here
+    }
+
+    return byte_order;
+}
+
+size_t
+NativeRegisterContextLinux_arm::GetGPRSize() const
+{
+    return GetRegisterInfoInterface().GetGPRSize();
+}
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -0,0 +1,116 @@
+//===-- NativeRegisterContextLinux_arm.h ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef lldb_NativeRegisterContextLinux_arm_h
+#define lldb_NativeRegisterContextLinux_arm_h
+
+#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
+
+namespace lldb_private {
+namespace process_linux {
+
+    class NativeProcessLinux;
+
+    class NativeRegisterContextLinux_arm : public NativeRegisterContextRegisterInfo
+    {
+    public:
+        NativeRegisterContextLinux_arm (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);
+
+        uint32_t
+        GetRegisterSetCount () const override;
+
+        const RegisterSet *
+        GetRegisterSet (uint32_t set_index) const override;
+
+        Error
+        ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+
+        Error
+        WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+
+        Error
+        ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+
+        Error
+        WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+
+    private:
+        struct RegInfo
+        {
+            uint32_t num_registers;
+            uint32_t num_gpr_registers;
+            uint32_t num_fpr_registers;
+
+            uint32_t last_gpr;
+            uint32_t first_fpr;
+            uint32_t last_fpr;
+
+            uint32_t first_fpr_v;
+            uint32_t last_fpr_v;
+
+            uint32_t gpr_flags;
+        };
+
+        struct QReg
+        {
+            uint8_t bytes[16];
+        };
+
+        struct FPU
+        {
+            union {
+                uint32_t s[32];
+                uint64_t d[32];
+                QReg     q[16];  // the 128-bit NEON registers
+                } floats;
+            uint32_t fpscr;
+        };
+
+        uint32_t m_gpr_arm[k_num_gpr_registers_arm];
+        RegInfo  m_reg_info;
+        FPU m_fpr; 
+
+        bool
+        IsGPR(unsigned reg) const;
+
+        bool
+        ReadGPR ();
+
+        bool
+        WriteGPR ();
+
+        bool
+        IsFPR(unsigned reg) const;
+
+        bool
+        ReadFPR ();
+
+        bool
+        WriteFPR ();
+
+        Error
+        ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
+
+        Error
+        WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value);
+
+        lldb::ByteOrder
+        GetByteOrder() const;
+
+        size_t
+        GetGPRSize() const;
+    };
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_arm_h
+
Index: source/Plugins/Process/Linux/NativeThreadLinux.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -13,6 +13,7 @@
 #include <sstream>
 
 #include "NativeProcessLinux.h"
+#include "NativeRegisterContextLinux_arm.h"
 #include "NativeRegisterContextLinux_arm64.h"
 #include "NativeRegisterContextLinux_x86_64.h"
 #include "NativeRegisterContextLinux_mips64.h"
@@ -29,6 +30,7 @@
 
 #include "Plugins/Process/POSIX/CrashReason.h"
 
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
@@ -184,6 +186,10 @@
                 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
                 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch));
                 break;
+            case llvm::Triple::arm:
+                assert(HostInfo::GetArchitecture ().GetAddressByteSize() == 4);
+                reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm(target_arch));
+                break;
             case llvm::Triple::x86:
             case llvm::Triple::x86_64:
                 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
@@ -242,6 +248,12 @@
             m_reg_context_sp.reset (new NativeRegisterContextLinux_arm64(*this, concrete_frame_idx, reg_interface));
             break;
         }
+        case llvm::Triple::arm:
+        {
+            const uint32_t concrete_frame_idx = 0;
+            m_reg_context_sp.reset (new NativeRegisterContextLinux_arm(*this, concrete_frame_idx, reg_interface));
+            break;
+        }
         case llvm::Triple::x86:
         case llvm::Triple::x86_64:
         {
Index: source/Plugins/Process/POSIX/CMakeLists.txt
===================================================================
--- source/Plugins/Process/POSIX/CMakeLists.txt
+++ source/Plugins/Process/POSIX/CMakeLists.txt
@@ -11,6 +11,7 @@
   ProcessMessage.cpp
   ProcessPOSIX.cpp
   ProcessPOSIXLog.cpp
+  RegisterContextPOSIXProcessMonitor_arm.cpp
   RegisterContextPOSIXProcessMonitor_arm64.cpp
   RegisterContextPOSIXProcessMonitor_mips64.cpp
   RegisterContextPOSIXProcessMonitor_powerpc.cpp
Index: source/Plugins/Process/POSIX/POSIXThread.cpp
===================================================================
--- source/Plugins/Process/POSIX/POSIXThread.cpp
+++ source/Plugins/Process/POSIX/POSIXThread.cpp
@@ -32,10 +32,12 @@
 #include "ProcessPOSIX.h"
 #include "ProcessPOSIXLog.h"
 #include "Plugins/Process/Linux/ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
 #include "RegisterContextPOSIXProcessMonitor_arm64.h"
 #include "RegisterContextPOSIXProcessMonitor_mips64.h"
 #include "RegisterContextPOSIXProcessMonitor_powerpc.h"
 #include "RegisterContextPOSIXProcessMonitor_x86.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
@@ -198,6 +200,10 @@
                         assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
                         reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch));
                         break;
+                    case llvm::Triple::arm:
+                        assert(HostInfo::GetArchitecture().GetAddressByteSize() == 4);
+                        reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm(target_arch));
+                        break;
                     case llvm::Triple::x86:
                     case llvm::Triple::x86_64:
                         if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
@@ -232,6 +238,13 @@
                     m_reg_context_sp.reset(reg_ctx);
                     break;
                 }
+            case llvm::Triple::arm:
+                {
+                    RegisterContextPOSIXProcessMonitor_arm *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
+                    m_posix_thread = reg_ctx;
+                    m_reg_context_sp.reset(reg_ctx);
+                    break;
+                }
             case llvm::Triple::mips64:
                 {
                     RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
@@ -641,6 +654,7 @@
         break;
 
     case llvm::Triple::aarch64:
+    case llvm::Triple::arm:
     case llvm::Triple::mips64:
     case llvm::Triple::ppc:
     case llvm::Triple::ppc64:
@@ -674,6 +688,7 @@
         break;
 
     case llvm::Triple::aarch64:
+    case llvm::Triple::arm:
     case llvm::Triple::mips64:
     case llvm::Triple::ppc:
     case llvm::Triple::ppc64:
Index: source/Plugins/Process/POSIX/ProcessPOSIX.cpp
===================================================================
--- source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -14,6 +14,7 @@
 
 // C++ Includes
 // Other libraries and framework includes
+#include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Breakpoint/Watchpoint.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
@@ -638,6 +639,33 @@
         assert(false && "CPU type not supported!");
         break;
 
+    case llvm::Triple::arm:
+        {
+            // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
+            // but the linux kernel does otherwise.
+            static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 };
+            static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde };
+
+            lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
+            AddressClass addr_class = eAddressClassUnknown;
+
+            if (bp_loc_sp)
+                addr_class = bp_loc_sp->GetAddress ().GetAddressClass ();
+
+            if (addr_class == eAddressClassCodeAlternateISA
+                || (addr_class == eAddressClassUnknown
+                    && bp_loc_sp->GetAddress().GetOffset() & 1))
+            {
+                opcode = g_thumb_breakpoint_opcode;
+                opcode_size = sizeof(g_thumb_breakpoint_opcode);
+            }
+            else
+            {
+                opcode = g_arm_breakpoint_opcode;
+                opcode_size = sizeof(g_arm_breakpoint_opcode);
+            }
+        }
+        break;
     case llvm::Triple::aarch64:
         opcode = g_aarch64_opcode;
         opcode_size = sizeof(g_aarch64_opcode);
Index: source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.cpp
===================================================================
--- source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -0,0 +1,322 @@
+//===-- RegisterContextPOSIXProcessMonitor_arm.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/DataBufferHeap.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Thread.h"
+
+#include "RegisterContextPOSIX_arm.h"
+#include "ProcessPOSIX.h"
+#include "RegisterContextPOSIXProcessMonitor_arm.h"
+#include "ProcessMonitor.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+#define REG_CONTEXT_SIZE (GetGPRSize())
+
+RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(Thread &thread,
+                                                                                     uint32_t concrete_frame_idx,
+                                                                                     lldb_private::RegisterInfoInterface *register_info)
+    : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info)
+{
+}
+
+ProcessMonitor &
+RegisterContextPOSIXProcessMonitor_arm::GetMonitor()
+{
+    ProcessSP base = CalculateProcess();
+    ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
+    return process->GetMonitor();
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::ReadGPR()
+{
+     ProcessMonitor &monitor = GetMonitor();
+     return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::ReadFPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::WriteGPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::WriteFPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const unsigned reg,
+                                                       RegisterValue &value)
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadRegisterValue(m_thread.GetID(),
+                                     GetRegisterOffset(reg),
+                                     GetRegisterName(reg),
+                                     GetRegisterSize(reg),
+                                     value);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::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_arm::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
+    {
+        return ReadRegister(reg, value);
+    }
+
+    // Get pointer to m_fpr variable and set the data from it.
+    assert (reg_info->byte_offset < sizeof m_fpr);
+    uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+    switch (reg_info->byte_size)
+    {
+        case 2:
+            value.SetUInt16(*(uint16_t *)src);
+            return true;
+        case 4:
+            value.SetUInt32(*(uint32_t *)src);
+            return true;
+        case 8:
+            value.SetUInt64(*(uint64_t *)src);
+            return true;
+        default:
+            assert(false && "Unhandled data size.");
+            return false;
+    }
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+    if (IsGPR(reg))
+    {
+        return WriteRegister(reg, value);
+    }
+    else if (IsFPR(reg))
+    {
+        return WriteFPR();
+    }
+
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::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_arm, GetGPRSize());
+            dst += GetGPRSize();
+            ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+        }
+    }
+    return success;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::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_arm, src, GetGPRSize());
+
+            if (WriteGPR())
+            {
+                src += GetGPRSize();
+                ::memcpy (&m_fpr, src, sizeof(m_fpr));
+
+                success = WriteFPR();
+            }
+        }
+    }
+    return success;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_arm::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_arm::ClearHardwareWatchpoint(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint()
+{
+    lldb::addr_t pc;
+
+    if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+        return false;
+
+    return true;
+}
+
+unsigned
+RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(unsigned offset)
+{
+    unsigned reg;
+    for (reg = 0; reg < k_num_registers_arm; reg++)
+    {
+        if (GetRegisterInfo()[reg].byte_offset == offset)
+            break;
+    }
+    assert(reg < k_num_registers_arm && "Invalid register offset.");
+    return reg;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits()
+{
+    return false;
+}
+
+addr_t
+RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(uint32_t hw_index)
+{
+    return LLDB_INVALID_ADDRESS;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(uint32_t hw_index)
+{
+    return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
+                                                                         bool read, bool write,
+                                                                         uint32_t hw_index)
+{
+    return false;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints()
+{
+    return 0;
+}
+
Index: source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.h
===================================================================
--- source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.h
+++ source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm.h
@@ -0,0 +1,95 @@
+//===-- RegisterContextPOSIXProcessMonitor_arm.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_arm_H_
+#define liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+
+class RegisterContextPOSIXProcessMonitor_arm:
+    public RegisterContextPOSIX_arm,
+    public POSIXBreakpointProtocol
+{
+public:
+    RegisterContextPOSIXProcessMonitor_arm(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
Index: source/Plugins/Process/Utility/CMakeLists.txt
===================================================================
--- source/Plugins/Process/Utility/CMakeLists.txt
+++ source/Plugins/Process/Utility/CMakeLists.txt
@@ -20,6 +20,7 @@
   RegisterContextFreeBSD_powerpc.cpp
   RegisterContextFreeBSD_x86_64.cpp
   RegisterContextHistory.cpp
+  RegisterContextLinux_arm.cpp
   RegisterContextLinux_arm64.cpp
   RegisterContextLinux_i386.cpp
   RegisterContextLinux_x86_64.cpp
@@ -30,6 +31,7 @@
   RegisterContextMach_i386.cpp
   RegisterContextMach_x86_64.cpp
   RegisterContextMemory.cpp
+  RegisterContextPOSIX_arm.cpp
   RegisterContextPOSIX_arm64.cpp
   RegisterContextPOSIX_mips64.cpp
   RegisterContextPOSIX_powerpc.cpp
Index: source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
+++ source/Plugins/Process/Utility/RegisterContextLinux_arm.cpp
@@ -0,0 +1,87 @@
+//===-- RegisterContextLinux_arm.cpp ---------------------------*- 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>
+#include <vector>
+#include <cassert>
+
+#include "llvm/Support/Compiler.h"
+#include "lldb/lldb-defines.h"
+
+#include "RegisterContextLinux_arm.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Based on RegisterContextDarwin_arm.cpp
+#define GPR_OFFSET(idx) ((idx) * 4)
+#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR))
+#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU))
+#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextLinux_arm::DBG, reg) + sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC)))
+
+#define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextLinux_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL
+#define REG_CONTEXT_SIZE (sizeof (RegisterContextLinux_arm::GPR) + sizeof (RegisterContextLinux_arm::FPU) + sizeof (RegisterContextLinux_arm::EXC))
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfos_arm to declare our g_register_infos_arm structure.
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_ARM_STRUCT
+#include "RegisterInfos_arm.h"
+#undef DECLARE_REGISTER_INFOS_ARM_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr (const lldb_private::ArchSpec &target_arch)
+{
+    switch (target_arch.GetMachine())
+    {
+        case llvm::Triple::arm:
+            return g_register_infos_arm;
+        default:
+            assert(false && "Unhandled target architecture.");
+            return NULL;
+    }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch)
+{
+    switch (target_arch.GetMachine())
+    {
+        case llvm::Triple::arm:
+            return static_cast<uint32_t>(sizeof(g_register_infos_arm) / sizeof(g_register_infos_arm[0]));
+        default:
+            assert(false && "Unhandled target architecture.");
+            return 0;
+    }
+}
+
+RegisterContextLinux_arm::RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch) :
+    lldb_private::RegisterInfoInterface(target_arch),
+    m_register_info_p(GetRegisterInfoPtr(target_arch)),
+    m_register_info_count(GetRegisterInfoCount(target_arch))
+{
+}
+
+size_t
+RegisterContextLinux_arm::GetGPRSize() const
+{
+    return sizeof(struct RegisterContextLinux_arm::GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterContextLinux_arm::GetRegisterInfo() const
+{
+    return m_register_info_p;
+}
+
+uint32_t
+RegisterContextLinux_arm::GetRegisterCount() const
+{
+    return m_register_info_count;
+}
Index: source/Plugins/Process/Utility/RegisterContextLinux_arm.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_arm.h
+++ source/Plugins/Process/Utility/RegisterContextLinux_arm.h
@@ -0,0 +1,76 @@
+//===-- RegisterContextLinux_arm.h -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextLinux_arm_h_
+#define liblldb_RegisterContextLinux_arm_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/RegisterContext.h"
+#include "RegisterContextPOSIX.h"
+#include "RegisterInfoInterface.h"
+
+class RegisterContextLinux_arm
+    : public lldb_private::RegisterInfoInterface
+{
+public:
+
+    struct GPR
+    {
+        uint32_t    r[16];  // R0-R15
+        uint32_t    cpsr;   // CPSR
+    };
+
+
+    struct QReg
+    {
+        uint8_t bytes[16];
+    };
+
+    struct FPU
+    {
+        union {
+            uint32_t s[32];
+            uint64_t d[32];
+            QReg     q[16];  // the 128-bit NEON registers
+        } floats;
+        uint32_t fpscr;
+    };
+    struct EXC
+    {
+        uint32_t    exception;
+        uint32_t    fsr; /* Fault status */
+        uint32_t    far; /* Virtual Fault Address */
+    };
+
+    struct DBG
+    {
+        uint32_t bvr[16];
+        uint32_t bcr[16];
+        uint32_t wvr[16];
+        uint32_t wcr[16];
+    };
+
+    RegisterContextLinux_arm(const lldb_private::ArchSpec &target_arch);
+
+    size_t
+    GetGPRSize() const override;
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfo() const override;
+
+    uint32_t
+    GetRegisterCount () const override;
+
+private:
+    const lldb_private::RegisterInfo *m_register_info_p;
+    uint32_t m_register_info_count;
+};
+
+#endif  // liblldb_RegisterContextLinux_arm_h_
+
Index: source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -0,0 +1,287 @@
+//===-- RegisterContextPOSIX_arm.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_arm.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// arm general purpose registers.
+const uint32_t g_gpr_regnums_arm[] =
+{
+    gpr_r0_arm,
+    gpr_r1_arm,
+    gpr_r2_arm,
+    gpr_r3_arm,
+    gpr_r4_arm,
+    gpr_r5_arm,
+    gpr_r6_arm,
+    gpr_r7_arm,
+    gpr_r8_arm,
+    gpr_r9_arm,
+    gpr_r10_arm,
+    gpr_r11_arm,
+    gpr_r12_arm,
+    gpr_sp_arm,
+    gpr_lr_arm,
+    gpr_pc_arm,
+    gpr_cpsr_arm,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+
+};
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
+              "g_gpr_regnums_arm has wrong number of register infos");
+
+// arm floating point registers.
+static const uint32_t g_fpu_regnums_arm[] =
+{
+    fpu_s0_arm,
+    fpu_s1_arm,
+    fpu_s2_arm,
+    fpu_s3_arm,
+    fpu_s4_arm,
+    fpu_s5_arm,
+    fpu_s6_arm,
+    fpu_s7_arm,
+    fpu_s8_arm,
+    fpu_s9_arm,
+    fpu_s10_arm,
+    fpu_s11_arm,
+    fpu_s12_arm,
+    fpu_s13_arm,
+    fpu_s14_arm,
+    fpu_s15_arm,
+    fpu_s16_arm,
+    fpu_s17_arm,
+    fpu_s18_arm,
+    fpu_s19_arm,
+    fpu_s20_arm,
+    fpu_s21_arm,
+    fpu_s22_arm,
+    fpu_s23_arm,
+    fpu_s24_arm,
+    fpu_s25_arm,
+    fpu_s26_arm,
+    fpu_s27_arm,
+    fpu_s28_arm,
+    fpu_s29_arm,
+    fpu_s30_arm,
+    fpu_s31_arm,
+    fpu_fpscr_arm,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+
+};
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
+              "g_fpu_regnums_arm has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum
+{
+    k_num_register_sets = 2
+};
+
+// Register sets for arm.
+static const lldb_private::RegisterSet
+g_reg_sets_arm[k_num_register_sets] =
+{
+    { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
+    { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
+};
+
+bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
+{
+    return reg <= m_reg_info.last_gpr;   // GPR's come first.
+}
+
+bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
+{
+    return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+}
+
+RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
+                                                       uint32_t concrete_frame_idx,
+                                                       lldb_private::RegisterInfoInterface *register_info)
+    : lldb_private::RegisterContext(thread, concrete_frame_idx)
+{
+    m_register_info_ap.reset(register_info);
+
+    switch (register_info->m_target_arch.GetMachine())
+    {
+        case llvm::Triple::arm:
+            m_reg_info.num_registers     = k_num_registers_arm;
+            m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
+            m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
+            m_reg_info.last_gpr          = k_last_gpr_arm;
+            m_reg_info.first_fpr         = k_first_fpr_arm;
+            m_reg_info.last_fpr          = k_last_fpr_arm;
+            m_reg_info.first_fpr_v       = fpu_s0_arm;
+            m_reg_info.last_fpr_v        = fpu_s31_arm;
+            m_reg_info.gpr_flags         = gpr_cpsr_arm;
+            break;
+        default:
+            assert(false && "Unhandled target architecture.");
+            break;
+    }
+
+    ::memset(&m_fpr, 0, sizeof m_fpr);
+
+    // elf-core yet to support ReadFPR()
+    lldb::ProcessSP base = CalculateProcess();
+    if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
+        return;
+}
+
+RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
+{
+}
+
+void
+RegisterContextPOSIX_arm::Invalidate()
+{
+}
+
+void
+RegisterContextPOSIX_arm::InvalidateAllRegisters()
+{
+}
+
+unsigned
+RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
+{
+    assert(reg < m_reg_info.num_registers && "Invalid register number.");
+    return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned
+RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
+{
+    assert(reg < m_reg_info.num_registers && "Invalid register number.");
+    return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t
+RegisterContextPOSIX_arm::GetRegisterCount()
+{
+    size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+    return num_registers;
+}
+
+size_t
+RegisterContextPOSIX_arm::GetGPRSize()
+{
+    return m_register_info_ap->GetGPRSize ();
+}
+
+const lldb_private::RegisterInfo *
+RegisterContextPOSIX_arm::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 lldb_private::RegisterInfo *
+RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
+{
+    if (reg < m_reg_info.num_registers)
+        return &GetRegisterInfo()[reg];
+    else
+        return NULL;
+}
+
+size_t
+RegisterContextPOSIX_arm::GetRegisterSetCount()
+{
+    size_t sets = 0;
+    for (size_t set = 0; set < k_num_register_sets; ++set)
+    {
+        if (IsRegisterSetAvailable(set))
+            ++sets;
+    }
+
+    return sets;
+}
+
+const lldb_private::RegisterSet *
+RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
+{
+    if (IsRegisterSetAvailable(set))
+    {
+        switch (m_register_info_ap->m_target_arch.GetMachine())
+        {
+            case llvm::Triple::aarch64:
+                return &g_reg_sets_arm[set];
+            default:
+                assert(false && "Unhandled target architecture.");
+                return NULL;
+        }
+    }
+    return NULL;
+}
+
+const char *
+RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
+{
+    assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+    return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder
+RegisterContextPOSIX_arm::GetByteOrder()
+{
+    // Get the target process whose privileged thread was used for the register read.
+    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+    lldb_private::Process *process = CalculateProcess().get();
+
+    if (process)
+        byte_order = process->GetByteOrder();
+    return byte_order;
+}
+
+bool
+RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
+{
+    return set_index < k_num_register_sets;
+}
+
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them. 
+uint32_t
+RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+                                                                uint32_t num)
+{
+    const uint32_t num_regs = GetRegisterCount();
+
+    assert (kind < lldb::kNumRegisterKinds);
+    for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
+    {
+        const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
+
+        if (reg_info->kinds[kind] == num)
+            return reg_idx;
+    }
+
+    return LLDB_INVALID_REGNUM;
+}
+
Index: source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -0,0 +1,121 @@
+//===-- RegisterContextPOSIX_arm.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_arm_H_
+#define liblldb_RegisterContextPOSIX_arm_H_
+
+#include "lldb/Core/Log.h"
+#include "lldb-arm-register-enums.h"
+#include "RegisterContextPOSIX.h"
+
+class ProcessMonitor;
+
+class RegisterContextPOSIX_arm
+  : public lldb_private::RegisterContext
+{
+public:
+    RegisterContextPOSIX_arm (lldb_private::Thread &thread,
+                            uint32_t concrete_frame_idx,
+                            lldb_private::RegisterInfoInterface *register_info);
+
+    ~RegisterContextPOSIX_arm();
+
+    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:
+    struct RegInfo
+    {
+        uint32_t num_registers;
+        uint32_t num_gpr_registers;
+        uint32_t num_fpr_registers;
+
+        uint32_t last_gpr;
+        uint32_t first_fpr;
+        uint32_t last_fpr;
+
+        uint32_t first_fpr_v;
+        uint32_t last_fpr_v;
+
+        uint32_t gpr_flags;
+    };
+
+    struct QReg
+    {
+        uint8_t bytes[16];
+    };
+
+    struct FPU
+    {
+        union {
+            uint32_t s[32];
+            uint64_t d[32];
+            QReg     q[16];  // the 128-bit NEON registers
+            } floats;
+        uint32_t fpscr;
+    };
+
+    uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm];           // 32-bit general purpose registers.
+    RegInfo  m_reg_info;
+    struct RegisterContextPOSIX_arm::FPU m_fpr;                            // floating-point registers including extended register sets.
+    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_arm_H_
+
Index: source/Plugins/Process/Utility/RegisterInfos_arm.h
===================================================================
--- source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -0,0 +1,303 @@
+//===-- RegisterInfos_arm.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT
+
+#include <stddef.h>
+
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "Utility/ARM_GCC_Registers.h"
+#include "Utility/ARM_DWARF_Registers.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#ifndef GPR_OFFSET
+#error GPR_OFFSET must be defined before including this header file
+#endif
+
+
+#ifndef FPU_OFFSET
+#error FPU_OFFSET must be defined before including this header file
+#endif
+
+#ifndef EXC_OFFSET
+#error EXC_OFFSET_NAME must be defined before including this header file
+#endif
+
+#ifndef DBG_OFFSET
+#error DBG_OFFSET_NAME must be defined before including this header file
+#endif
+
+#ifndef DEFINE_DBG
+#error DEFINE_DBG must be defined before including this header file
+#endif
+
+enum
+{
+    gpr_r0 = 0,
+    gpr_r1,
+    gpr_r2,
+    gpr_r3,
+    gpr_r4,
+    gpr_r5,
+    gpr_r6,
+    gpr_r7,
+    gpr_r8,
+    gpr_r9,
+    gpr_r10,
+    gpr_r11,
+    gpr_r12,
+    gpr_r13, gpr_sp = gpr_r13,
+    gpr_r14, gpr_lr = gpr_r14,
+    gpr_r15, gpr_pc = gpr_r15,
+    gpr_cpsr,
+
+    fpu_s0,
+    fpu_s1,
+    fpu_s2,
+    fpu_s3,
+    fpu_s4,
+    fpu_s5,
+    fpu_s6,
+    fpu_s7,
+    fpu_s8,
+    fpu_s9,
+    fpu_s10,
+    fpu_s11,
+    fpu_s12,
+    fpu_s13,
+    fpu_s14,
+    fpu_s15,
+    fpu_s16,
+    fpu_s17,
+    fpu_s18,
+    fpu_s19,
+    fpu_s20,
+    fpu_s21,
+    fpu_s22,
+    fpu_s23,
+    fpu_s24,
+    fpu_s25,
+    fpu_s26,
+    fpu_s27,
+    fpu_s28,
+    fpu_s29,
+    fpu_s30,
+    fpu_s31,
+    fpu_fpscr,
+
+    exc_exception,
+    exc_fsr,
+    exc_far,
+
+    dbg_bvr0,
+    dbg_bvr1,
+    dbg_bvr2,
+    dbg_bvr3,
+    dbg_bvr4,
+    dbg_bvr5,
+    dbg_bvr6,
+    dbg_bvr7,
+    dbg_bvr8,
+    dbg_bvr9,
+    dbg_bvr10,
+    dbg_bvr11,
+    dbg_bvr12,
+    dbg_bvr13,
+    dbg_bvr14,
+    dbg_bvr15,
+
+    dbg_bcr0,
+    dbg_bcr1,
+    dbg_bcr2,
+    dbg_bcr3,
+    dbg_bcr4,
+    dbg_bcr5,
+    dbg_bcr6,
+    dbg_bcr7,
+    dbg_bcr8,
+    dbg_bcr9,
+    dbg_bcr10,
+    dbg_bcr11,
+    dbg_bcr12,
+    dbg_bcr13,
+    dbg_bcr14,
+    dbg_bcr15,
+
+    dbg_wvr0,
+    dbg_wvr1,
+    dbg_wvr2,
+    dbg_wvr3,
+    dbg_wvr4,
+    dbg_wvr5,
+    dbg_wvr6,
+    dbg_wvr7,
+    dbg_wvr8,
+    dbg_wvr9,
+    dbg_wvr10,
+    dbg_wvr11,
+    dbg_wvr12,
+    dbg_wvr13,
+    dbg_wvr14,
+    dbg_wvr15,
+
+    dbg_wcr0,
+    dbg_wcr1,
+    dbg_wcr2,
+    dbg_wcr3,
+    dbg_wcr4,
+    dbg_wcr5,
+    dbg_wcr6,
+    dbg_wcr7,
+    dbg_wcr8,
+    dbg_wcr9,
+    dbg_wcr10,
+    dbg_wcr11,
+    dbg_wcr12,
+    dbg_wcr13,
+    dbg_wcr14,
+    dbg_wcr15,
+
+    k_num_registers
+};
+
+static RegisterInfo g_register_infos_arm[] = {
+// General purpose registers
+//  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
+//  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
+{   "r0",       NULL,   4,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { gcc_r0,               dwarf_r0,           LLDB_REGNUM_GENERIC_ARG1,   gdb_arm_r0,             gpr_r0      },      NULL,              NULL},
+{   "r1",       NULL,   4,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { gcc_r1,               dwarf_r1,           LLDB_REGNUM_GENERIC_ARG2,   gdb_arm_r1,             gpr_r1      },      NULL,              NULL},
+{   "r2",       NULL,   4,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { gcc_r2,               dwarf_r2,           LLDB_REGNUM_GENERIC_ARG3,   gdb_arm_r2,             gpr_r2      },      NULL,              NULL},
+{   "r3",       NULL,   4,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { gcc_r3,               dwarf_r3,           LLDB_REGNUM_GENERIC_ARG4,   gdb_arm_r3,             gpr_r3      },      NULL,              NULL},
+{   "r4",       NULL,   4,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        gdb_arm_r4,             gpr_r4      },      NULL,              NULL},
+{   "r5",       NULL,   4,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        gdb_arm_r5,             gpr_r5      },      NULL,              NULL},
+{   "r6",       NULL,   4,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        gdb_arm_r6,             gpr_r6      },      NULL,              NULL},
+{   "r7",       NULL,   4,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { gcc_r7,               dwarf_r7,           LLDB_INVALID_REGNUM,        gdb_arm_r7,             gpr_r7      },      NULL,              NULL},
+{   "r8",       NULL,   4,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        gdb_arm_r8,             gpr_r8      },      NULL,              NULL},
+{   "r9",       NULL,   4,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        gdb_arm_r9,             gpr_r9      },      NULL,              NULL},
+{   "r10",      NULL,   4,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        gdb_arm_r10,            gpr_r10     },      NULL,              NULL},
+{   "r11",      NULL,   4,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { gcc_r11,              dwarf_r11,          LLDB_REGNUM_GENERIC_FP,     gdb_arm_r11,            gpr_r11     },      NULL,              NULL},
+{   "r12",      NULL,   4,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        gdb_arm_r12,            gpr_r12     },      NULL,              NULL},
+{   "sp",       "r13",  4,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     gdb_arm_sp,             gpr_sp      },      NULL,              NULL},
+{   "lr",       "r14",  4,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     gdb_arm_lr,             gpr_lr      },      NULL,              NULL},
+{   "pc",       "r15",  4,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     gdb_arm_pc,             gpr_pc      },      NULL,              NULL},
+{   "cpsr",     "psr",  4,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  gdb_arm_cpsr,           gpr_cpsr    },      NULL,              NULL},
+
+{   "s0",       NULL,   4,  FPU_OFFSET(0),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        gdb_arm_s0,             fpu_s0      },      NULL,              NULL},
+{   "s1",       NULL,   4,  FPU_OFFSET(1),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        gdb_arm_s1,             fpu_s1      },      NULL,              NULL},
+{   "s2",       NULL,   4,  FPU_OFFSET(2),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        gdb_arm_s2,             fpu_s2      },      NULL,              NULL},
+{   "s3",       NULL,   4,  FPU_OFFSET(3),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        gdb_arm_s3,             fpu_s3      },      NULL,              NULL},
+{   "s4",       NULL,   4,  FPU_OFFSET(4),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        gdb_arm_s4,             fpu_s4      },      NULL,              NULL},
+{   "s5",       NULL,   4,  FPU_OFFSET(5),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        gdb_arm_s5,             fpu_s5      },      NULL,              NULL},
+{   "s6",       NULL,   4,  FPU_OFFSET(6),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        gdb_arm_s6,             fpu_s6      },      NULL,              NULL},
+{   "s7",       NULL,   4,  FPU_OFFSET(7),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        gdb_arm_s7,             fpu_s7      },      NULL,              NULL},
+{   "s8",       NULL,   4,  FPU_OFFSET(8),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        gdb_arm_s8,             fpu_s8      },      NULL,              NULL},
+{   "s9",       NULL,   4,  FPU_OFFSET(9),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        gdb_arm_s9,             fpu_s9      },      NULL,              NULL},
+{   "s10",      NULL,   4,  FPU_OFFSET(10),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        gdb_arm_s10,            fpu_s10     },      NULL,              NULL},
+{   "s11",      NULL,   4,  FPU_OFFSET(11),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        gdb_arm_s11,            fpu_s11     },      NULL,              NULL},
+{   "s12",      NULL,   4,  FPU_OFFSET(12),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        gdb_arm_s12,            fpu_s12     },      NULL,              NULL},
+{   "s13",      NULL,   4,  FPU_OFFSET(13),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        gdb_arm_s13,            fpu_s13     },      NULL,              NULL},
+{   "s14",      NULL,   4,  FPU_OFFSET(14),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        gdb_arm_s14,            fpu_s14     },      NULL,              NULL},
+{   "s15",      NULL,   4,  FPU_OFFSET(15),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        gdb_arm_s15,            fpu_s15     },      NULL,              NULL},
+{   "s16",      NULL,   4,  FPU_OFFSET(16),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        gdb_arm_s16,            fpu_s16     },      NULL,              NULL},
+{   "s17",      NULL,   4,  FPU_OFFSET(17),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        gdb_arm_s17,            fpu_s17     },      NULL,              NULL},
+{   "s18",      NULL,   4,  FPU_OFFSET(18),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        gdb_arm_s18,            fpu_s18     },      NULL,              NULL},
+{   "s19",      NULL,   4,  FPU_OFFSET(19),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        gdb_arm_s19,            fpu_s19     },      NULL,              NULL},
+{   "s20",      NULL,   4,  FPU_OFFSET(20),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        gdb_arm_s20,            fpu_s20     },      NULL,              NULL},
+{   "s21",      NULL,   4,  FPU_OFFSET(21),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        gdb_arm_s21,            fpu_s21     },      NULL,              NULL},
+{   "s22",      NULL,   4,  FPU_OFFSET(22),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        gdb_arm_s22,            fpu_s22     },      NULL,              NULL},
+{   "s23",      NULL,   4,  FPU_OFFSET(23),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        gdb_arm_s23,            fpu_s23     },      NULL,              NULL},
+{   "s24",      NULL,   4,  FPU_OFFSET(24),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        gdb_arm_s24,            fpu_s24     },      NULL,              NULL},
+{   "s25",      NULL,   4,  FPU_OFFSET(25),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        gdb_arm_s25,            fpu_s25     },      NULL,              NULL},
+{   "s26",      NULL,   4,  FPU_OFFSET(26),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        gdb_arm_s26,            fpu_s26     },      NULL,              NULL},
+{   "s27",      NULL,   4,  FPU_OFFSET(27),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        gdb_arm_s27,            fpu_s27     },      NULL,              NULL},
+{   "s28",      NULL,   4,  FPU_OFFSET(28),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        gdb_arm_s28,            fpu_s28     },      NULL,              NULL},
+{   "s29",      NULL,   4,  FPU_OFFSET(29),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        gdb_arm_s29,            fpu_s29     },      NULL,              NULL},
+{   "s30",      NULL,   4,  FPU_OFFSET(30),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        gdb_arm_s30,            fpu_s30     },      NULL,              NULL},
+{   "s31",      NULL,   4,  FPU_OFFSET(31),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        gdb_arm_s31,            fpu_s31     },      NULL,              NULL},
+{   "fpscr",    NULL,   4,  FPU_OFFSET(32),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        gdb_arm_fpscr,          fpu_fpscr   },      NULL,              NULL},
+
+{   "exception",NULL,   4,  EXC_OFFSET(0),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
+{   "fsr",      NULL,   4,  EXC_OFFSET(1),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_fsr       },    NULL,              NULL},
+{   "far",      NULL,   4,  EXC_OFFSET(2),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
+
+{   DEFINE_DBG (bvr, 0) },
+{   DEFINE_DBG (bvr, 1) },
+{   DEFINE_DBG (bvr, 2) },
+{   DEFINE_DBG (bvr, 3) },
+{   DEFINE_DBG (bvr, 4) },
+{   DEFINE_DBG (bvr, 5) },
+{   DEFINE_DBG (bvr, 6) },
+{   DEFINE_DBG (bvr, 7) },
+{   DEFINE_DBG (bvr, 8) },
+{   DEFINE_DBG (bvr, 9) },
+{   DEFINE_DBG (bvr, 10) },
+{   DEFINE_DBG (bvr, 11) },
+{   DEFINE_DBG (bvr, 12) },
+{   DEFINE_DBG (bvr, 13) },
+{   DEFINE_DBG (bvr, 14) },
+{   DEFINE_DBG (bvr, 15) },
+
+{   DEFINE_DBG (bcr, 0) },
+{   DEFINE_DBG (bcr, 1) },
+{   DEFINE_DBG (bcr, 2) },
+{   DEFINE_DBG (bcr, 3) },
+{   DEFINE_DBG (bcr, 4) },
+{   DEFINE_DBG (bcr, 5) },
+{   DEFINE_DBG (bcr, 6) },
+{   DEFINE_DBG (bcr, 7) },
+{   DEFINE_DBG (bcr, 8) },
+{   DEFINE_DBG (bcr, 9) },
+{   DEFINE_DBG (bcr, 10) },
+{   DEFINE_DBG (bcr, 11) },
+{   DEFINE_DBG (bcr, 12) },
+{   DEFINE_DBG (bcr, 13) },
+{   DEFINE_DBG (bcr, 14) },
+{   DEFINE_DBG (bcr, 15) },
+
+{   DEFINE_DBG (wvr, 0) },
+{   DEFINE_DBG (wvr, 1) },
+{   DEFINE_DBG (wvr, 2) },
+{   DEFINE_DBG (wvr, 3) },
+{   DEFINE_DBG (wvr, 4) },
+{   DEFINE_DBG (wvr, 5) },
+{   DEFINE_DBG (wvr, 6) },
+{   DEFINE_DBG (wvr, 7) },
+{   DEFINE_DBG (wvr, 8) },
+{   DEFINE_DBG (wvr, 9) },
+{   DEFINE_DBG (wvr, 10) },
+{   DEFINE_DBG (wvr, 11) },
+{   DEFINE_DBG (wvr, 12) },
+{   DEFINE_DBG (wvr, 13) },
+{   DEFINE_DBG (wvr, 14) },
+{   DEFINE_DBG (wvr, 15) },
+
+{   DEFINE_DBG (wcr, 0) },
+{   DEFINE_DBG (wcr, 1) },
+{   DEFINE_DBG (wcr, 2) },
+{   DEFINE_DBG (wcr, 3) },
+{   DEFINE_DBG (wcr, 4) },
+{   DEFINE_DBG (wcr, 5) },
+{   DEFINE_DBG (wcr, 6) },
+{   DEFINE_DBG (wcr, 7) },
+{   DEFINE_DBG (wcr, 8) },
+{   DEFINE_DBG (wcr, 9) },
+{   DEFINE_DBG (wcr, 10) },
+{   DEFINE_DBG (wcr, 11) },
+{   DEFINE_DBG (wcr, 12) },
+{   DEFINE_DBG (wcr, 13) },
+{   DEFINE_DBG (wcr, 14) },
+{   DEFINE_DBG (wcr, 15) }
+};
+
+#endif // DECLARE_REGISTER_INFOS_ARM_STRUCT
Index: source/Plugins/Process/Utility/lldb-arm-register-enums.h
===================================================================
--- source/Plugins/Process/Utility/lldb-arm-register-enums.h
+++ source/Plugins/Process/Utility/lldb-arm-register-enums.h
@@ -0,0 +1,153 @@
+//===-- lldb-arm-register-enums.h -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_arm_register_enums_h
+#define lldb_arm_register_enums_h
+
+namespace lldb_private
+{
+    // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+    //---------------------------------------------------------------------------
+    // Internal codes for all ARM registers.
+    //---------------------------------------------------------------------------
+    enum
+    {
+        k_first_gpr_arm = 0,
+        gpr_r0_arm = k_first_gpr_arm,
+        gpr_r1_arm,
+        gpr_r2_arm,
+        gpr_r3_arm,
+        gpr_r4_arm,
+        gpr_r5_arm,
+        gpr_r6_arm,
+        gpr_r7_arm,
+        gpr_r8_arm,
+        gpr_r9_arm,
+        gpr_r10_arm,
+        gpr_r11_arm,
+        gpr_r12_arm,
+        gpr_r13_arm, gpr_sp_arm = gpr_r13_arm,
+        gpr_r14_arm, gpr_lr_arm = gpr_r14_arm,
+        gpr_r15_arm, gpr_pc_arm = gpr_r15_arm,
+        gpr_cpsr_arm,
+
+        k_last_gpr_arm = gpr_cpsr_arm,
+
+        k_first_fpr_arm,
+        fpu_s0_arm = k_first_fpr_arm,
+        fpu_s1_arm,
+        fpu_s2_arm,
+        fpu_s3_arm,
+        fpu_s4_arm,
+        fpu_s5_arm,
+        fpu_s6_arm,
+        fpu_s7_arm,
+        fpu_s8_arm,
+        fpu_s9_arm,
+        fpu_s10_arm,
+        fpu_s11_arm,
+        fpu_s12_arm,
+        fpu_s13_arm,
+        fpu_s14_arm,
+        fpu_s15_arm,
+        fpu_s16_arm,
+        fpu_s17_arm,
+        fpu_s18_arm,
+        fpu_s19_arm,
+        fpu_s20_arm,
+        fpu_s21_arm,
+        fpu_s22_arm,
+        fpu_s23_arm,
+        fpu_s24_arm,
+        fpu_s25_arm,
+        fpu_s26_arm,
+        fpu_s27_arm,
+        fpu_s28_arm,
+        fpu_s29_arm,
+        fpu_s30_arm,
+        fpu_s31_arm,
+        fpu_fpscr_arm,
+        k_last_fpr_arm = fpu_fpscr_arm,
+        exc_exception_arm,
+        exc_fsr_arm,
+        exc_far_arm,
+
+        dbg_bvr0_arm,
+        dbg_bvr1_arm,
+        dbg_bvr2_arm,
+        dbg_bvr3_arm,
+        dbg_bvr4_arm,
+        dbg_bvr5_arm,
+        dbg_bvr6_arm,
+        dbg_bvr7_arm,
+        dbg_bvr8_arm,
+        dbg_bvr9_arm,
+        dbg_bvr10_arm,
+        dbg_bvr11_arm,
+        dbg_bvr12_arm,
+        dbg_bvr13_arm,
+        dbg_bvr14_arm,
+        dbg_bvr15_arm,
+        dbg_bcr0_arm,
+        dbg_bcr1_arm,
+        dbg_bcr2_arm,
+        dbg_bcr3_arm,
+        dbg_bcr4_arm,
+        dbg_bcr5_arm,
+        dbg_bcr6_arm,
+        dbg_bcr7_arm,
+        dbg_bcr8_arm,
+        dbg_bcr9_arm,
+        dbg_bcr10_arm,
+        dbg_bcr11_arm,
+        dbg_bcr12_arm,
+        dbg_bcr13_arm,
+        dbg_bcr14_arm,
+        dbg_bcr15_arm,
+        dbg_wvr0_arm,
+        dbg_wvr1_arm,
+        dbg_wvr2_arm,
+        dbg_wvr3_arm,
+        dbg_wvr4_arm,
+        dbg_wvr5_arm,
+        dbg_wvr6_arm,
+        dbg_wvr7_arm,
+        dbg_wvr8_arm,
+        dbg_wvr9_arm,
+        dbg_wvr10_arm,
+        dbg_wvr11_arm,
+        dbg_wvr12_arm,
+        dbg_wvr13_arm,
+        dbg_wvr14_arm,
+        dbg_wvr15_arm,
+        dbg_wcr0_arm,
+        dbg_wcr1_arm,
+        dbg_wcr2_arm,
+        dbg_wcr3_arm,
+        dbg_wcr4_arm,
+        dbg_wcr5_arm,
+        dbg_wcr6_arm,
+        dbg_wcr7_arm,
+        dbg_wcr8_arm,
+        dbg_wcr9_arm,
+        dbg_wcr10_arm,
+        dbg_wcr11_arm,
+        dbg_wcr12_arm,
+        dbg_wcr13_arm,
+        dbg_wcr14_arm,
+        dbg_wcr15_arm,
+
+        k_num_registers_arm,
+        k_num_gpr_registers_arm = k_last_gpr_arm - k_first_gpr_arm + 1,
+        k_num_fpr_registers_arm = k_last_fpr_arm - k_first_fpr_arm + 1
+    };
+}
+
+#endif // #ifndef lldb_arm64_register_enums_h
Index: source/Plugins/Process/elf-core/CMakeLists.txt
===================================================================
--- source/Plugins/Process/elf-core/CMakeLists.txt
+++ source/Plugins/Process/elf-core/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_lldb_library(lldbPluginProcessElfCore
   ProcessElfCore.cpp
   ThreadElfCore.cpp
+  RegisterContextPOSIXCore_arm.cpp
   RegisterContextPOSIXCore_arm64.cpp
   RegisterContextPOSIXCore_mips64.cpp
   RegisterContextPOSIXCore_powerpc.cpp
Index: source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
===================================================================
--- source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -0,0 +1,94 @@
+//===-- RegisterContextCorePOSIX_arm.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 "Plugins/Process/Utility/RegisterContextPOSIX.h"
+#include "RegisterContextPOSIXCore_arm.h"
+
+using namespace lldb_private;
+
+RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(Thread &thread,
+                                                                 RegisterInfoInterface *register_info,
+                                                                 const DataExtractor &gpregset,
+                                                                 const DataExtractor &fpregset)
+    : RegisterContextPOSIX_arm(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());
+}
+
+RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm()
+{
+}
+
+bool
+RegisterContextCorePOSIX_arm::ReadGPR()
+{
+    return true;
+}
+
+bool
+RegisterContextCorePOSIX_arm::ReadFPR()
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::WriteGPR()
+{
+    assert(0);
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::WriteFPR()
+{
+    assert(0);
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+    lldb::offset_t offset = reg_info->byte_offset;
+    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+    if (offset == reg_info->byte_offset + reg_info->byte_size)
+    {
+        value = v;
+        return true;
+    }
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
+{
+    return false;
+}
+
+bool
+RegisterContextCorePOSIX_arm::HardwareSingleStep(bool enable)
+{
+    return false;
+}
Index: source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
===================================================================
--- source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -0,0 +1,60 @@
+//===-- RegisterContextCorePOSIX_arm.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_arm_H_
+#define liblldb_RegisterContextCorePOSIX_arm_H_
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+
+class RegisterContextCorePOSIX_arm :
+    public RegisterContextPOSIX_arm
+{
+public:
+    RegisterContextCorePOSIX_arm (lldb_private::Thread &thread,
+                                     lldb_private::RegisterInfoInterface *register_info,
+                                     const lldb_private::DataExtractor &gpregset,
+                                     const lldb_private::DataExtractor &fpregset);
+
+    ~RegisterContextCorePOSIX_arm();
+
+    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_private::DataExtractor m_gpr;
+};
+
+#endif // #ifndef liblldb_RegisterContextCorePOSIX_arm_H_
Index: source/Plugins/Process/elf-core/ThreadElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -16,12 +16,14 @@
 
 #include "ThreadElfCore.h"
 #include "ProcessElfCore.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.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_arm.h"
 #include "RegisterContextPOSIXCore_arm64.h"
 #include "RegisterContextPOSIXCore_mips64.h"
 #include "RegisterContextPOSIXCore_powerpc.h"
@@ -127,6 +129,9 @@
             {
                 switch (arch.GetMachine())
                 {
+                    case llvm::Triple::arm:
+                        reg_interface = new RegisterContextLinux_arm(arch);
+                        break;
                     case llvm::Triple::x86_64:
                         reg_interface = new RegisterContextLinux_x86_64(arch);
                         break;
@@ -152,6 +157,9 @@
             case llvm::Triple::aarch64:
                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
                 break;
+            case llvm::Triple::arm:
+                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
+                break;
             case llvm::Triple::mips64:
                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
                 break;
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to