Fix incomplete commit of http://llvm.org/viewvc/llvm-project?rev=147609&view=rev:

This patch combines common code from Linux and FreeBSD into
a new POSIX platform.  It also contains fixes for 64bit FreeBSD.

The patch is based on changes by Mark Peek <mp@FreeBSD.org> and
"K. Macy" <kmacy@freebsd.org> in their github repo located at
https://github.com/fbsd/lldb.

llvm-svn: 147613
diff --git a/lldb/source/Plugins/Process/POSIX/Makefile b/lldb/source/Plugins/Process/POSIX/Makefile
new file mode 100644
index 0000000..6705b0d
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/Makefile
@@ -0,0 +1,28 @@
+##===- source/Plugins/Process/POSIX/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 := lldbPluginProcessPOSIX
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/../../Makefile.config
+
+# Extend the include path so we may locate UnwindLLDB.h
+CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility
+
+ifeq ($(HOST_OS),Linux)
+CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Linux
+endif
+
+ifeq ($(HOST_OS),FreeBSD)
+# Extend the include path so we may locate ProcessMonitor
+CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/FreeBSD
+endif
+
+include $(LLDB_LEVEL)/Makefile
diff --git a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
new file mode 100644
index 0000000..79f0a58
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
@@ -0,0 +1,60 @@
+//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "POSIXStopInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//===----------------------------------------------------------------------===//
+// POSIXLimboStopInfo
+
+POSIXLimboStopInfo::~POSIXLimboStopInfo() { }
+
+lldb::StopReason
+POSIXLimboStopInfo::GetStopReason() const
+{
+    return lldb::eStopReasonTrace;
+}
+
+const char *
+POSIXLimboStopInfo::GetDescription()
+{
+    return "thread exiting";
+}
+
+bool
+POSIXLimboStopInfo::ShouldStop(Event *event_ptr)
+{
+    return true;
+}
+
+bool
+POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
+{
+    return true;
+}
+
+//===----------------------------------------------------------------------===//
+// POSIXCrashStopInfo
+
+POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
+
+lldb::StopReason
+POSIXCrashStopInfo::GetStopReason() const
+{
+    return lldb::eStopReasonException;
+}
+
+const char *
+POSIXCrashStopInfo::GetDescription()
+{
+    return ProcessMessage::GetCrashReasonString(m_crash_reason);
+}
diff --git a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h
new file mode 100644
index 0000000..c510377
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h
@@ -0,0 +1,92 @@
+//===-- POSIXStopInfo.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_POSIXStopInfo_H_
+#define liblldb_POSIXStopInfo_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/StopInfo.h"
+
+#include "POSIXThread.h"
+#include "ProcessMessage.h"
+
+//===----------------------------------------------------------------------===//
+/// @class POSIXStopInfo
+/// @brief Simple base class for all POSIX-specific StopInfo objects.
+///
+class POSIXStopInfo
+    : public lldb_private::StopInfo
+{
+public:
+    POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
+        : StopInfo(thread, status)
+        { }
+};
+
+//===----------------------------------------------------------------------===//
+/// @class POSIXLimboStopInfo
+/// @brief Represents the stop state of a process ready to exit.
+///
+class POSIXLimboStopInfo
+    : public POSIXStopInfo
+{
+public:
+    POSIXLimboStopInfo(POSIXThread &thread)
+        : POSIXStopInfo(thread, 0)
+        { }
+
+    ~POSIXLimboStopInfo();
+
+    lldb::StopReason
+    GetStopReason() const;
+
+    const char *
+    GetDescription();
+
+    bool
+    ShouldStop(lldb_private::Event *event_ptr);
+
+    bool
+    ShouldNotify(lldb_private::Event *event_ptr);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// @class POSIXCrashStopInfo
+/// @brief Represents the stop state of process that is ready to crash.
+///
+class POSIXCrashStopInfo
+    : public POSIXStopInfo
+{
+public:
+    POSIXCrashStopInfo(POSIXThread &thread, uint32_t status, 
+                  ProcessMessage::CrashReason reason)
+        : POSIXStopInfo(thread, status),
+          m_crash_reason(reason)
+        { }
+
+    ~POSIXCrashStopInfo();
+
+    lldb::StopReason
+    GetStopReason() const;
+
+    const char *
+    GetDescription();
+
+    ProcessMessage::CrashReason
+    GetCrashReason() const;
+
+private:
+    ProcessMessage::CrashReason m_crash_reason;
+};    
+
+#endif
diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp
new file mode 100644
index 0000000..3f5e022
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp
@@ -0,0 +1,352 @@
+//===-- POSIXThread.cpp -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <errno.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Debugger.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "POSIXStopInfo.h"
+#include "POSIXThread.h"
+#include "ProcessPOSIX.h"
+#include "ProcessPOSIXLog.h"
+#include "ProcessMonitor.h"
+#include "RegisterContext_i386.h"
+#include "RegisterContext_x86_64.h"
+#include "RegisterContextPOSIX.h"
+
+#include "UnwindLLDB.h"
+
+using namespace lldb_private;
+
+
+POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
+    : Thread(process, tid),
+      m_frame_ap(0)
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("POSIXThread::%s (tid = %i)", __FUNCTION__, tid);
+}
+
+POSIXThread::~POSIXThread()
+{
+    DestroyThread();
+}
+
+ProcessMonitor &
+POSIXThread::GetMonitor()
+{
+    ProcessPOSIX &process = static_cast<ProcessPOSIX&>(GetProcess());
+    return process.GetMonitor();
+}
+
+void
+POSIXThread::RefreshStateAfterStop()
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("POSIXThread::%s ()", __FUNCTION__);
+
+    // Let all threads recover from stopping and do any clean up based
+    // on the previous thread state (if any).
+    ProcessPOSIX &process = static_cast<ProcessPOSIX&>(GetProcess());
+    process.GetThreadList().RefreshStateAfterStop();
+}
+
+const char *
+POSIXThread::GetInfo()
+{
+    return NULL;
+}
+
+lldb::RegisterContextSP
+POSIXThread::GetRegisterContext()
+{
+    if (!m_reg_context_sp)
+    {
+        ArchSpec arch = Host::GetArchitecture();
+
+        switch (arch.GetCore())
+        {
+        default:
+            assert(false && "CPU type not supported!");
+            break;
+
+        case ArchSpec::eCore_x86_32_i386:
+        case ArchSpec::eCore_x86_32_i486:
+        case ArchSpec::eCore_x86_32_i486sx:
+            m_reg_context_sp.reset(new RegisterContext_i386(*this, 0));
+            break;
+
+        case ArchSpec::eCore_x86_64_x86_64:
+            m_reg_context_sp.reset(new RegisterContext_x86_64(*this, 0));
+            break;
+        }
+    }
+    return m_reg_context_sp;
+}
+
+lldb::RegisterContextSP
+POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
+{
+    lldb::RegisterContextSP reg_ctx_sp;
+    uint32_t concrete_frame_idx = 0;
+
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("POSIXThread::%s ()", __FUNCTION__);
+
+    if (frame)
+        concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+    if (concrete_frame_idx == 0)
+        reg_ctx_sp = GetRegisterContext();
+    else
+    {
+        assert(GetUnwinder());
+        reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
+    }
+
+    return reg_ctx_sp;
+}
+
+lldb::StopInfoSP
+POSIXThread::GetPrivateStopReason()
+{
+    return m_stop_info;
+}
+
+Unwind *
+POSIXThread::GetUnwinder()
+{
+    if (m_unwinder_ap.get() == NULL)
+        m_unwinder_ap.reset(new UnwindLLDB(*this));
+
+    return m_unwinder_ap.get();
+}
+
+bool
+POSIXThread::WillResume(lldb::StateType resume_state)
+{
+    SetResumeState(resume_state);
+
+    ClearStackFrames();
+    if (m_unwinder_ap.get())
+        m_unwinder_ap->Clear();
+
+    return Thread::WillResume(resume_state);
+}
+
+bool
+POSIXThread::Resume()
+{
+    lldb::StateType resume_state = GetResumeState();
+    ProcessMonitor &monitor = GetMonitor();
+    bool status;
+
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("POSIXThread::%s ()", __FUNCTION__);
+
+    switch (resume_state)
+    {
+    default:
+        assert(false && "Unexpected state for resume!");
+        status = false;
+        break;
+
+    case lldb::eStateRunning:
+        SetState(resume_state);
+        status = monitor.Resume(GetID(), GetResumeSignal());
+        break;
+
+    case lldb::eStateStepping:
+        SetState(resume_state);
+        status = monitor.SingleStep(GetID(), GetResumeSignal());
+        break;
+    }
+
+    return status;
+}
+
+void
+POSIXThread::Notify(const ProcessMessage &message)
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log)
+        log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
+
+    switch (message.GetKind())
+    {
+    default:
+        assert(false && "Unexpected message kind!");
+        break;
+
+    case ProcessMessage::eLimboMessage:
+        LimboNotify(message);
+        break;
+        
+    case ProcessMessage::eSignalMessage:
+        SignalNotify(message);
+        break;
+
+    case ProcessMessage::eSignalDeliveredMessage:
+        SignalDeliveredNotify(message);
+        break;
+
+    case ProcessMessage::eTraceMessage:
+        TraceNotify(message);
+        break;
+
+    case ProcessMessage::eBreakpointMessage:
+        BreakNotify(message);
+        break;
+
+    case ProcessMessage::eCrashMessage:
+        CrashNotify(message);
+        break;
+    }
+}
+
+void
+POSIXThread::BreakNotify(const ProcessMessage &message)
+{
+    bool status;
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+
+    assert(GetRegisterContext());
+    status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
+    assert(status && "Breakpoint update failed!");
+
+    // With our register state restored, resolve the breakpoint object
+    // corresponding to our current PC.
+    assert(GetRegisterContext());
+    lldb::addr_t pc = GetRegisterContext()->GetPC();
+    if (log)
+        log->Printf ("POSIXThread::%s () PC=0x%8.8llx", __FUNCTION__, pc);
+    lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
+    assert(bp_site);
+    lldb::break_id_t bp_id = bp_site->GetID();
+    assert(bp_site && bp_site->ValidForThisThread(this));
+
+    
+    m_breakpoint = bp_site;
+    m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
+}
+
+void
+POSIXThread::TraceNotify(const ProcessMessage &message)
+{
+    m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
+}
+
+void
+POSIXThread::LimboNotify(const ProcessMessage &message)
+{
+    m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this));
+}
+
+void
+POSIXThread::SignalNotify(const ProcessMessage &message)
+{
+    int signo = message.GetSignal();
+
+    m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
+    SetResumeSignal(signo);
+}
+
+void
+POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
+{
+    int signo = message.GetSignal();
+
+    // Just treat debugger generated signal events like breakpoints for now.
+    m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
+    SetResumeSignal(signo);
+}
+
+void
+POSIXThread::CrashNotify(const ProcessMessage &message)
+{
+    int signo = message.GetSignal();
+
+    assert(message.GetKind() == ProcessMessage::eCrashMessage);
+
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log)
+        log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
+
+    m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo(
+                                       *this, signo, message.GetCrashReason()));
+    SetResumeSignal(signo);
+}
+
+unsigned
+POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
+{
+    unsigned reg;
+    ArchSpec arch = Host::GetArchitecture();
+
+    switch (arch.GetCore())
+    {
+    default:
+        assert(false && "CPU type not supported!");
+        break;
+
+    case ArchSpec::eCore_x86_32_i386:
+    case ArchSpec::eCore_x86_32_i486:
+    case ArchSpec::eCore_x86_32_i486sx:
+        reg = RegisterContext_i386::GetRegisterIndexFromOffset(offset);
+        break;
+
+    case ArchSpec::eCore_x86_64_x86_64:
+        reg = RegisterContext_x86_64::GetRegisterIndexFromOffset(offset);
+        break;
+    }
+    return reg;
+}
+
+const char *
+POSIXThread::GetRegisterName(unsigned reg)
+{
+    const char * name;
+    ArchSpec arch = Host::GetArchitecture();
+
+    switch (arch.GetCore())
+    {
+    default:
+        assert(false && "CPU type not supported!");
+        break;
+
+    case ArchSpec::eCore_x86_32_i386:
+    case ArchSpec::eCore_x86_32_i486:
+    case ArchSpec::eCore_x86_32_i486sx:
+        name = RegisterContext_i386::GetRegisterName(reg);
+        break;
+
+    case ArchSpec::eCore_x86_64_x86_64:
+        name = RegisterContext_x86_64::GetRegisterName(reg);
+        break;
+    }
+    return name;
+}
+
+const char *
+POSIXThread::GetRegisterNameFromOffset(unsigned offset)
+{
+    return GetRegisterName(GetRegisterIndexFromOffset(offset));
+}
+
diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.h b/lldb/source/Plugins/Process/POSIX/POSIXThread.h
new file mode 100644
index 0000000..95280d4
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/POSIXThread.h
@@ -0,0 +1,106 @@
+//===-- POSIXThread.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_POSIXThread_H_
+#define liblldb_POSIXThread_H_
+
+// C Includes
+// C++ Includes
+#include <memory>
+
+// Other libraries and framework includes
+#include "lldb/Target/Thread.h"
+#include "RegisterContextPOSIX.h"
+
+class ProcessMessage;
+class ProcessMonitor;
+class RegisterContextPOSIX;
+
+//------------------------------------------------------------------------------
+// @class POSIXThread
+// @brief Abstraction of a linux process (thread).
+class POSIXThread
+    : public lldb_private::Thread
+{
+public:
+    POSIXThread(lldb_private::Process &process, lldb::tid_t tid);
+
+    virtual ~POSIXThread();
+
+    void
+    RefreshStateAfterStop();
+
+    bool
+    WillResume(lldb::StateType resume_state);
+
+    const char *
+    GetInfo();
+
+    virtual lldb::RegisterContextSP
+    GetRegisterContext();
+
+    virtual lldb::RegisterContextSP
+    CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
+
+    //--------------------------------------------------------------------------
+    // These static functions provide a mapping from the register offset
+    // back to the register index or name for use in debugging or log
+    // output.
+
+    static unsigned
+    GetRegisterIndexFromOffset(unsigned offset);
+
+    static const char *
+    GetRegisterName(unsigned reg);
+
+    static const char *
+    GetRegisterNameFromOffset(unsigned offset);
+
+    //--------------------------------------------------------------------------
+    // These methods form a specialized interface to linux threads.
+    //
+    bool Resume();
+
+    void Notify(const ProcessMessage &message);
+
+private:
+    RegisterContextPOSIX *
+    GetRegisterContextPOSIX ()
+    {
+        if (!m_reg_context_sp)
+            m_reg_context_sp = GetRegisterContext();
+#if 0
+        return dynamic_cast<RegisterContextPOSIX*>(m_reg_context_sp.get());
+#endif
+        return (RegisterContextPOSIX *)m_reg_context_sp.get();
+    }
+    
+    std::auto_ptr<lldb_private::StackFrame> m_frame_ap;
+
+    lldb::BreakpointSiteSP m_breakpoint;
+    lldb::StopInfoSP m_stop_info;
+
+    ProcessMonitor &
+    GetMonitor();
+
+    lldb::StopInfoSP
+    GetPrivateStopReason();
+
+    void BreakNotify(const ProcessMessage &message);
+    void TraceNotify(const ProcessMessage &message);
+    void LimboNotify(const ProcessMessage &message);
+    void SignalNotify(const ProcessMessage &message);
+    void SignalDeliveredNotify(const ProcessMessage &message);
+    void CrashNotify(const ProcessMessage &message);
+
+    lldb_private::Unwind *
+    GetUnwinder();
+};
+
+#endif // #ifndef liblldb_POSIXThread_H_
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
new file mode 100644
index 0000000..2e72b59
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -0,0 +1,245 @@
+//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessMessage.h"
+
+using namespace lldb_private;
+
+const char *
+ProcessMessage::GetCrashReasonString(CrashReason reason)
+{
+    const char *str = NULL;
+
+    switch (reason)
+    {
+    default:
+        assert(false && "invalid CrashReason");
+        break;
+
+    case eInvalidAddress:
+        str = "invalid address";
+        break;
+    case ePrivilegedAddress:
+        str = "address access protected";
+        break;
+    case eIllegalOpcode:
+        str = "illegal instruction";
+        break;
+    case eIllegalOperand:
+        str = "illegal instruction operand";
+        break;
+    case eIllegalAddressingMode:
+        str = "illegal addressing mode";
+        break;
+    case eIllegalTrap:
+        str = "illegal trap";
+        break;
+    case ePrivilegedOpcode:
+        str = "privileged instruction";
+        break;
+    case ePrivilegedRegister:
+        str = "privileged register";
+        break;
+    case eCoprocessorError:
+        str = "coprocessor error";
+        break;
+    case eInternalStackError:
+        str = "internal stack error";
+        break;
+    case eIllegalAlignment:
+        str = "illegal alignment";
+        break;
+    case eIllegalAddress:
+        str = "illegal address";
+        break;
+    case eHardwareError:
+        str = "hardware error";
+        break;
+    case eIntegerDivideByZero:
+        str = "integer divide by zero";
+        break;
+    case eIntegerOverflow:
+        str = "integer overflow";
+        break;
+    case eFloatDivideByZero:
+        str = "floating point divide by zero";
+        break;
+    case eFloatOverflow:
+        str = "floating point overflow";
+        break;
+    case eFloatUnderflow:
+        str = "floating point underflow";
+        break;
+    case eFloatInexactResult:
+        str = "inexact floating point result";
+        break;
+    case eFloatInvalidOperation:
+        str = "invalid floating point operation";
+        break;
+    case eFloatSubscriptRange:
+        str = "invalid floating point subscript range";
+        break;
+    }
+
+    return str;
+}
+
+const char *
+ProcessMessage::PrintCrashReason(CrashReason reason)
+{
+#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
+    // Just return the code in asci for integration builds.
+    chcar str[8];
+    sprintf(str, "%d", reason);
+#else
+    const char *str = NULL;
+
+    switch (reason)
+    {
+    default:
+        assert(false && "invalid CrashReason");
+        break;
+
+        case eInvalidCrashReason:
+            str = "eInvalidCrashReason";
+            break;
+
+        // SIGSEGV crash reasons.
+        case eInvalidAddress:
+            str = "eInvalidAddress";
+            break;
+        case ePrivilegedAddress:
+            str = "ePrivilegedAddress";
+            break;
+
+        // SIGILL crash reasons.
+        case eIllegalOpcode:
+            str = "eIllegalOpcode";
+            break;
+        case eIllegalOperand:
+            str = "eIllegalOperand";
+            break;
+        case eIllegalAddressingMode:
+            str = "eIllegalAddressingMode";
+            break;
+        case eIllegalTrap:
+            str = "eIllegalTrap";
+            break;
+        case ePrivilegedOpcode:
+            str = "ePrivilegedOpcode";
+            break;
+        case ePrivilegedRegister:
+            str = "ePrivilegedRegister";
+            break;
+        case eCoprocessorError:
+            str = "eCoprocessorError";
+            break;
+        case eInternalStackError:
+            str = "eInternalStackError";
+            break;
+
+        // SIGBUS crash reasons:
+        case eIllegalAlignment:
+            str = "eIllegalAlignment";
+            break;
+        case eIllegalAddress:
+            str = "eIllegalAddress";
+            break;
+        case eHardwareError:
+            str = "eHardwareError";
+            break;
+
+        // SIGFPE crash reasons:
+        case eIntegerDivideByZero:
+            str = "eIntegerDivideByZero";
+            break;
+        case eIntegerOverflow:
+            str = "eIntegerOverflow";
+            break;
+        case eFloatDivideByZero:
+            str = "eFloatDivideByZero";
+            break;
+        case eFloatOverflow:
+            str = "eFloatOverflow";
+            break;
+        case eFloatUnderflow:
+            str = "eFloatUnderflow";
+            break;
+        case eFloatInexactResult:
+            str = "eFloatInexactResult";
+            break;
+        case eFloatInvalidOperation:
+            str = "eFloatInvalidOperation";
+            break;
+        case eFloatSubscriptRange:
+            str = "eFloatSubscriptRange";
+            break;
+    }
+#endif
+
+    return str;
+}
+
+const char *
+ProcessMessage::PrintCrashReason() const
+{
+    return PrintCrashReason(m_crash_reason);
+}
+
+const char *
+ProcessMessage::PrintKind(Kind kind)
+{
+#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
+    // Just return the code in asci for integration builds.
+    chcar str[8];
+    sprintf(str, "%d", reason);
+#else
+    const char *str = NULL;
+
+    switch (kind)
+    {
+    default:
+        assert(false && "invalid Kind");
+        break;
+
+    case eInvalidMessage:
+        str = "eInvalidMessage";
+        break;
+    case eExitMessage:
+        str = "eExitMessage";
+        break;
+    case eLimboMessage:
+        str = "eLimboMessage";
+        break;
+    case eSignalMessage:
+        str = "eSignalMessage";
+        break;
+    case eSignalDeliveredMessage:
+        str = "eSignalDeliveredMessage";
+        break;
+    case eTraceMessage:
+        str = "eTraceMessage";
+        break;
+    case eBreakpointMessage:
+        str = "eBreakpointMessage";
+        break;
+    case eCrashMessage:
+        str = "eCrashMessage";
+        break;
+    }
+#endif
+
+    return str;
+}
+
+const char *
+ProcessMessage::PrintKind() const
+{
+    return PrintKind(m_kind);
+}
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessMessage.h b/lldb/source/Plugins/Process/POSIX/ProcessMessage.h
new file mode 100644
index 0000000..826567e
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -0,0 +1,171 @@
+//===-- ProcessMessage.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_ProcessMessage_H_
+#define liblldb_ProcessMessage_H_
+
+#include <cassert>
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+class ProcessMessage
+{
+public:
+
+    /// The type of signal this message can correspond to.
+    enum Kind
+    {
+        eInvalidMessage,
+        eExitMessage,
+        eLimboMessage,
+        eSignalMessage,
+        eSignalDeliveredMessage,
+        eTraceMessage,
+        eBreakpointMessage,
+        eCrashMessage
+    };
+
+    enum CrashReason
+    {
+        eInvalidCrashReason,
+
+        // SIGSEGV crash reasons.
+        eInvalidAddress,
+        ePrivilegedAddress,
+
+        // SIGILL crash reasons.
+        eIllegalOpcode,
+        eIllegalOperand,
+        eIllegalAddressingMode,
+        eIllegalTrap,
+        ePrivilegedOpcode,
+        ePrivilegedRegister,
+        eCoprocessorError,
+        eInternalStackError,
+
+        // SIGBUS crash reasons,
+        eIllegalAlignment,
+        eIllegalAddress,
+        eHardwareError,
+
+        // SIGFPE crash reasons,
+        eIntegerDivideByZero,
+        eIntegerOverflow,
+        eFloatDivideByZero,
+        eFloatOverflow,
+        eFloatUnderflow,
+        eFloatInexactResult,
+        eFloatInvalidOperation,
+        eFloatSubscriptRange
+    };
+
+    ProcessMessage()
+        : m_tid(LLDB_INVALID_PROCESS_ID),
+          m_kind(eInvalidMessage),
+          m_crash_reason(eInvalidCrashReason),
+          m_status(0),
+          m_addr(0) { }
+
+    Kind GetKind() const { return m_kind; }
+
+    lldb::tid_t GetTID() const { return m_tid; }
+
+    /// Indicates that the thread @p tid is about to exit with status @p status.
+    static ProcessMessage Limbo(lldb::tid_t tid, int status) {
+        return ProcessMessage(tid, eLimboMessage, status);
+    }
+
+    /// Indicates that the thread @p tid had the signal @p signum delivered.
+    static ProcessMessage Signal(lldb::tid_t tid, int signum) {
+        return ProcessMessage(tid, eSignalMessage, signum);
+    }
+
+    /// Indicates that a signal @p signum generated by the debugging process was
+    /// delivered to the thread @p tid.
+    static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
+        return ProcessMessage(tid, eSignalDeliveredMessage, signum);
+    }
+
+    /// Indicates that the thread @p tid encountered a trace point.
+    static ProcessMessage Trace(lldb::tid_t tid) {
+        return ProcessMessage(tid, eTraceMessage);
+    }
+
+    /// Indicates that the thread @p tid encountered a break point.
+    static ProcessMessage Break(lldb::tid_t tid) {
+        return ProcessMessage(tid, eBreakpointMessage);
+    }
+
+    /// Indicates that the thread @p tid crashed.
+    static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
+                                int signo, lldb::addr_t fault_addr) {
+        ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
+        message.m_crash_reason = reason;
+        return message;
+    }
+
+    int GetExitStatus() const {
+        assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
+        return m_status;
+    }
+
+    int GetSignal() const {
+        assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
+               GetKind() == eSignalDeliveredMessage);
+        return m_status;
+    }
+
+    int GetStopStatus() const {
+        assert(GetKind() == eSignalMessage);
+        return m_status;
+    }
+
+    CrashReason GetCrashReason() const {
+        assert(GetKind() == eCrashMessage);
+        return m_crash_reason;
+    }
+
+    lldb::addr_t GetFaultAddress() const {
+        assert(GetKind() == eCrashMessage);
+        return m_addr;
+    }
+
+    static const char *
+    GetCrashReasonString(CrashReason reason);
+
+    const char *
+    PrintCrashReason() const;
+
+    static const char *
+    PrintCrashReason(CrashReason reason);
+
+    const char *
+    PrintKind() const;
+
+    static const char *
+    PrintKind(Kind);
+
+private:
+    ProcessMessage(lldb::tid_t tid, Kind kind, 
+                   int status = 0, lldb::addr_t addr = 0)
+        : m_tid(tid),
+          m_kind(kind),
+          m_crash_reason(eInvalidCrashReason),
+          m_status(status),
+          m_addr(addr) { }
+
+    lldb::tid_t m_tid;
+    Kind        m_kind         : 8;
+    CrashReason m_crash_reason : 8;
+    int m_status;
+    lldb::addr_t m_addr;
+};
+
+#endif // #ifndef liblldb_ProcessMessage_H_
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
new file mode 100644
index 0000000..67cf8a9
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -0,0 +1,594 @@
+//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <errno.h>
+
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/Target.h"
+
+#include "ProcessPOSIX.h"
+#include "ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
+#include "ProcessMonitor.h"
+#include "POSIXThread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//------------------------------------------------------------------------------
+// Static functions.
+#if 0
+Process*
+ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
+{
+    return new ProcessPOSIX(target, listener);
+}
+
+
+void
+ProcessPOSIX::Initialize()
+{
+    static bool g_initialized = false;
+
+    if (!g_initialized)
+    {
+        g_initialized = true;
+        PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                      GetPluginDescriptionStatic(),
+                                      CreateInstance);
+
+        Log::Callbacks log_callbacks = {
+            ProcessPOSIXLog::DisableLog,
+            ProcessPOSIXLog::EnableLog,
+            ProcessPOSIXLog::ListLogCategories
+        };
+        
+        Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
+    }
+}
+#endif
+
+//------------------------------------------------------------------------------
+// Constructors and destructors.
+
+ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
+    : Process(target, listener),
+      m_monitor(NULL),
+      m_module(NULL),
+      m_in_limbo(false),
+      m_exit_now(false)
+{
+    // FIXME: Putting this code in the ctor and saving the byte order in a
+    // member variable is a hack to avoid const qual issues in GetByteOrder.
+    ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
+    m_byte_order = obj_file->GetByteOrder();
+}
+
+ProcessPOSIX::~ProcessPOSIX()
+{
+    delete m_monitor;
+}
+
+//------------------------------------------------------------------------------
+// Process protocol.
+
+bool
+ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
+{
+    // For now we are just making sure the file exists for a given module
+    ModuleSP exe_module_sp(target.GetExecutableModule());
+    if (exe_module_sp.get())
+        return exe_module_sp->GetFileSpec().Exists();
+    return false;
+}
+
+Error
+ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
+{
+    Error error;
+    assert(m_monitor == NULL);
+
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("ProcessPOSIX::%s(pid = %i)", __FUNCTION__, GetID());
+
+    m_monitor = new ProcessMonitor(this, pid, error);
+
+    if (!error.Success())
+        return error;
+
+    SetID(pid);
+    return error;
+}
+
+Error
+ProcessPOSIX::WillLaunch(Module* module)
+{
+    Error error;
+    return error;
+}
+
+const char *
+ProcessPOSIX::GetFilePath(
+    const lldb_private::ProcessLaunchInfo::FileAction *file_action,
+    const char *default_path)
+{
+    const char *pts_name = "/dev/pts/";
+    const char *path = NULL;
+
+    if (file_action)
+    {
+        if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
+            path = file_action->GetPath();
+            // By default the stdio paths passed in will be pseudo-terminal
+            // (/dev/pts). If so, convert to using a different default path
+            // instead to redirect I/O to the debugger console. This should
+            //  also handle user overrides to /dev/null or a different file.
+            if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
+                path = default_path;
+    }
+
+    return path;
+}
+
+Error
+ProcessPOSIX::DoLaunch (Module *module,
+                       const ProcessLaunchInfo &launch_info)
+{
+    Error error;
+    assert(m_monitor == NULL);
+
+    SetPrivateState(eStateLaunching);
+
+    const lldb_private::ProcessLaunchInfo::FileAction *file_action;
+
+    // Default of NULL will mean to use existing open file descriptors
+    const char *stdin_path = NULL;
+    const char *stdout_path = NULL;
+    const char *stderr_path = NULL;
+    
+    file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
+    stdin_path = GetFilePath(file_action, stdin_path);
+
+    file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
+    stdout_path = GetFilePath(file_action, stdout_path);
+
+    file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
+    stderr_path = GetFilePath(file_action, stderr_path);
+
+    m_monitor = new ProcessMonitor (this, 
+                                    module,
+                                    launch_info.GetArguments().GetConstArgumentVector(), 
+                                    launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
+                                    stdin_path, 
+                                    stdout_path, 
+                                    stderr_path,
+                                    error);
+
+    m_module = module;
+
+    if (!error.Success())
+        return error;
+
+    SetID(m_monitor->GetPID());
+    return error;
+}
+
+void
+ProcessPOSIX::DidLaunch()
+{
+}
+
+Error
+ProcessPOSIX::DoResume()
+{
+    StateType state = GetPrivateState();
+
+    assert(state == eStateStopped || state == eStateCrashed);
+
+    // We are about to resume a thread that will cause the process to exit so
+    // set our exit status now.  Do not change our state if the inferior
+    // crashed.
+    if (state == eStateStopped) 
+    {
+        if (m_in_limbo)
+            SetExitStatus(m_exit_status, NULL);
+        else
+            SetPrivateState(eStateRunning);
+    }
+
+    bool did_resume = false;
+    uint32_t thread_count = m_thread_list.GetSize(false);
+    for (uint32_t i = 0; i < thread_count; ++i)
+    {
+        POSIXThread *thread = static_cast<POSIXThread*>(
+            m_thread_list.GetThreadAtIndex(i, false).get());
+        did_resume = thread->Resume() || did_resume;
+    }
+    assert(did_resume && "Process resume failed!");
+
+    return Error();
+}
+
+addr_t
+ProcessPOSIX::GetImageInfoAddress()
+{
+    Target *target = &GetTarget();
+    ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+    Address addr = obj_file->GetImageInfoAddress();
+
+    if (addr.IsValid()) 
+        return addr.GetLoadAddress(target);
+    else
+        return LLDB_INVALID_ADDRESS;
+}
+
+Error
+ProcessPOSIX::DoHalt(bool &caused_stop)
+{
+    Error error;
+
+    if (IsStopped())
+    {
+        caused_stop = false;
+    }
+    else if (kill(GetID(), SIGSTOP))
+    {
+        caused_stop = false;
+        error.SetErrorToErrno();
+    }
+    else
+    {
+        caused_stop = true;
+    }
+
+    return error;
+}
+
+Error
+ProcessPOSIX::DoDetach()
+{
+    Error error;
+
+    error = m_monitor->Detach();
+    if (error.Success())
+        SetPrivateState(eStateDetached);
+
+    return error;
+}
+
+Error
+ProcessPOSIX::DoSignal(int signal)
+{
+    Error error;
+
+    if (kill(GetID(), signal))
+        error.SetErrorToErrno();
+
+    return error;
+}
+
+Error
+ProcessPOSIX::DoDestroy()
+{
+    Error error;
+
+    if (!HasExited())
+    {
+        // Drive the exit event to completion (do not keep the inferior in
+        // limbo).
+        m_exit_now = true;
+
+        if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
+        {
+            error.SetErrorToErrno();
+            return error;
+        }
+
+        SetPrivateState(eStateExited);
+    }
+
+    return error;
+}
+
+void
+ProcessPOSIX::SendMessage(const ProcessMessage &message)
+{
+    Mutex::Locker lock(m_message_mutex);
+
+    switch (message.GetKind())
+    {
+    default:
+        assert(false && "Unexpected process message!");
+        break;
+
+    case ProcessMessage::eInvalidMessage:
+        return;
+
+    case ProcessMessage::eLimboMessage:
+        m_in_limbo = true;
+        m_exit_status = message.GetExitStatus();
+        if (m_exit_now)
+        {
+            SetPrivateState(eStateExited);
+            m_monitor->Detach();
+        }
+        else
+            SetPrivateState(eStateStopped);
+        break;
+
+    case ProcessMessage::eExitMessage:
+        m_exit_status = message.GetExitStatus();
+        SetExitStatus(m_exit_status, NULL);
+        break;
+
+    case ProcessMessage::eTraceMessage:
+    case ProcessMessage::eBreakpointMessage:
+        SetPrivateState(eStateStopped);
+        break;
+
+    case ProcessMessage::eSignalMessage:
+    case ProcessMessage::eSignalDeliveredMessage:
+        SetPrivateState(eStateStopped);
+        break;
+
+    case ProcessMessage::eCrashMessage:
+        SetPrivateState(eStateCrashed);
+        break;
+    }
+
+    m_message_queue.push(message);
+}
+
+void
+ProcessPOSIX::RefreshStateAfterStop()
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
+
+    Mutex::Locker lock(m_message_mutex);
+    if (m_message_queue.empty())
+        return;
+
+    ProcessMessage &message = m_message_queue.front();
+
+    // Resolve the thread this message corresponds to and pass it along.
+    // FIXME: we're really dealing with the pid here.  This should get
+    // fixed when this code is fixed to handle multiple threads.
+    lldb::tid_t tid = message.GetTID();
+    if (log)
+        log->Printf ("ProcessPOSIX::%s() pid = %i", __FUNCTION__, tid);
+    POSIXThread *thread = static_cast<POSIXThread*>(
+        GetThreadList().FindThreadByID(tid, false).get());
+
+    assert(thread);
+    thread->Notify(message);
+
+    m_message_queue.pop();
+}
+
+bool
+ProcessPOSIX::IsAlive()
+{
+    StateType state = GetPrivateState();
+    return state != eStateDetached && state != eStateExited && state != eStateInvalid;
+}
+
+size_t
+ProcessPOSIX::DoReadMemory(addr_t vm_addr,
+                           void *buf, size_t size, Error &error)
+{
+    assert(m_monitor);
+    return m_monitor->ReadMemory(vm_addr, buf, size, error);
+}
+
+size_t
+ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
+                            Error &error)
+{
+    assert(m_monitor);
+    return m_monitor->WriteMemory(vm_addr, buf, size, error);
+}
+
+addr_t
+ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
+                               Error &error)
+{
+    addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+    unsigned prot = 0;
+    if (permissions & lldb::ePermissionsReadable)
+        prot |= eMmapProtRead;
+    if (permissions & lldb::ePermissionsWritable)
+        prot |= eMmapProtWrite;
+    if (permissions & lldb::ePermissionsExecutable)
+        prot |= eMmapProtExec;
+
+    if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+                         eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
+        m_addr_to_mmap_size[allocated_addr] = size;
+        error.Clear();
+    } else {
+        allocated_addr = LLDB_INVALID_ADDRESS;
+        error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
+    }
+
+    return allocated_addr;
+}
+
+Error
+ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
+{
+    Error error;
+    MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+    if (pos != m_addr_to_mmap_size.end() &&
+        InferiorCallMunmap(this, addr, pos->second))
+        m_addr_to_mmap_size.erase (pos);
+    else
+        error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+
+    return error;
+}
+
+size_t
+ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
+{
+    static const uint8_t g_i386_opcode[] = { 0xCC };
+
+    ArchSpec arch = GetTarget().GetArchitecture();
+    const uint8_t *opcode = NULL;
+    size_t opcode_size = 0;
+
+    switch (arch.GetCore())
+    {
+    default:
+        assert(false && "CPU type not supported!");
+        break;
+
+    case ArchSpec::eCore_x86_32_i386:
+    case ArchSpec::eCore_x86_64_x86_64:
+        opcode = g_i386_opcode;
+        opcode_size = sizeof(g_i386_opcode);
+        break;
+    }
+
+    bp_site->SetTrapOpcode(opcode, opcode_size);
+    return opcode_size;
+}
+
+Error
+ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
+{
+    return EnableSoftwareBreakpoint(bp_site);
+}
+
+Error
+ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
+{
+    return DisableSoftwareBreakpoint(bp_site);
+}
+
+uint32_t
+ProcessPOSIX::UpdateThreadListIfNeeded()
+{
+    // Do not allow recursive updates.
+    return m_thread_list.GetSize(false);
+}
+
+uint32_t
+ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("ProcessPOSIX::%s() (pid = %i)", __FUNCTION__, GetID());
+
+    // Update the process thread list with this new thread.
+    // FIXME: We should be using tid, not pid.
+    assert(m_monitor);
+    ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
+    if (!thread_sp)
+        thread_sp.reset(new POSIXThread(*this, GetID()));
+
+    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
+        log->Printf ("ProcessPOSIX::%s() updated pid = %i", __FUNCTION__, GetID());
+    new_thread_list.AddThread(thread_sp);
+
+    return new_thread_list.GetSize(false);
+}
+
+ByteOrder
+ProcessPOSIX::GetByteOrder() const
+{
+    // FIXME: We should be able to extract this value directly.  See comment in
+    // ProcessPOSIX().
+    return m_byte_order;
+}
+
+size_t
+ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
+{
+    ssize_t status;
+    if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) 
+    {
+        error.SetErrorToErrno();
+        return 0;
+    }
+    return status;
+}
+
+size_t
+ProcessPOSIX::GetSTDOUT(char *buf, size_t len, Error &error)
+{
+    ssize_t bytes_read;
+
+    // The terminal file descriptor is always in non-block mode.
+    if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0) 
+    {
+        if (errno != EAGAIN)
+            error.SetErrorToErrno();
+        return 0;
+    }
+    return bytes_read;
+}
+
+size_t
+ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error)
+{
+    return GetSTDOUT(buf, len, error);
+}
+
+UnixSignals &
+ProcessPOSIX::GetUnixSignals()
+{
+    return m_signals;
+}
+
+//------------------------------------------------------------------------------
+// Utility functions.
+
+bool
+ProcessPOSIX::HasExited()
+{
+    switch (GetPrivateState())
+    {
+    default:
+        break;
+
+    case eStateDetached:
+    case eStateExited:
+        return true;
+    }
+
+    return false;
+}
+
+bool
+ProcessPOSIX::IsStopped()
+{
+    switch (GetPrivateState())
+    {
+    default:
+        break;
+
+    case eStateStopped:
+    case eStateCrashed:
+    case eStateSuspended:
+        return true;
+    }
+
+    return false;
+}
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
new file mode 100644
index 0000000..dd887cf
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
@@ -0,0 +1,180 @@
+//===-- ProcessPOSIX.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_ProcessPOSIX_H_
+#define liblldb_ProcessPOSIX_H_
+
+// C Includes
+
+// C++ Includes
+#include <queue>
+
+// Other libraries and framework includes
+#include "lldb/Target/Process.h"
+#include "lldb/Target/UnixSignals.h"
+#include "ProcessMessage.h"
+
+class ProcessMonitor;
+
+class ProcessPOSIX :
+    public lldb_private::Process
+{
+public:
+
+    //------------------------------------------------------------------
+    // Constructors and destructors
+    //------------------------------------------------------------------
+    ProcessPOSIX(lldb_private::Target& target,
+                 lldb_private::Listener &listener);
+
+    virtual
+    ~ProcessPOSIX();
+
+    //------------------------------------------------------------------
+    // Process protocol.
+    //------------------------------------------------------------------
+    virtual bool
+    CanDebug(lldb_private::Target &target, bool plugin_specified_by_name);
+
+    virtual lldb_private::Error
+    WillLaunch(lldb_private::Module *module);
+
+    virtual lldb_private::Error
+    DoAttachToProcessWithID(lldb::pid_t pid);
+
+    virtual lldb_private::Error
+    DoLaunch (lldb_private::Module *exe_module, 
+              const lldb_private::ProcessLaunchInfo &launch_info);
+
+    virtual void
+    DidLaunch();
+
+    virtual lldb_private::Error
+    DoResume();
+
+    virtual lldb_private::Error
+    DoHalt(bool &caused_stop);
+
+    virtual lldb_private::Error
+    DoDetach();
+
+    virtual lldb_private::Error
+    DoSignal(int signal);
+
+    virtual lldb_private::Error
+    DoDestroy();
+
+    virtual void
+    RefreshStateAfterStop();
+
+    virtual bool
+    IsAlive();
+
+    virtual size_t
+    DoReadMemory(lldb::addr_t vm_addr,
+                 void *buf,
+                 size_t size,
+                 lldb_private::Error &error);
+
+    virtual size_t
+    DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+                  lldb_private::Error &error);
+
+    virtual lldb::addr_t
+    DoAllocateMemory(size_t size, uint32_t permissions,
+                     lldb_private::Error &error);
+
+    virtual lldb_private::Error
+    DoDeallocateMemory(lldb::addr_t ptr);
+
+    virtual size_t
+    GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
+
+    virtual lldb_private::Error
+    EnableBreakpoint(lldb_private::BreakpointSite *bp_site);
+
+    virtual lldb_private::Error
+    DisableBreakpoint(lldb_private::BreakpointSite *bp_site);
+
+    virtual uint32_t
+    UpdateThreadListIfNeeded();
+
+    virtual uint32_t
+    UpdateThreadList(lldb_private::ThreadList &old_thread_list, 
+                     lldb_private::ThreadList &new_thread_list) = 0;
+
+    virtual lldb::ByteOrder
+    GetByteOrder() const;
+
+    virtual lldb::addr_t
+    GetImageInfoAddress();
+
+    virtual size_t
+    PutSTDIN(const char *buf, size_t len, lldb_private::Error &error);
+
+    virtual size_t
+    GetSTDOUT(char *buf, size_t len, lldb_private::Error &error);
+
+    virtual size_t
+    GetSTDERR(char *buf, size_t len, lldb_private::Error &error);
+
+    //--------------------------------------------------------------------------
+    // ProcessPOSIX internal API.
+
+    /// Registers the given message with this process.
+    void SendMessage(const ProcessMessage &message);
+
+    ProcessMonitor &
+    GetMonitor() { assert(m_monitor); return *m_monitor; }
+
+    lldb_private::UnixSignals &
+    GetUnixSignals();
+
+    const char *
+    GetFilePath(const lldb_private::ProcessLaunchInfo::FileAction *file_action,
+                const char *default_path);
+
+protected:
+    /// Target byte order.
+    lldb::ByteOrder m_byte_order;
+
+    /// Process monitor;
+    ProcessMonitor *m_monitor;
+
+    /// The module we are executing.
+    lldb_private::Module *m_module;
+
+    /// Message queue notifying this instance of inferior process state changes.
+    lldb_private::Mutex m_message_mutex;
+    std::queue<ProcessMessage> m_message_queue;
+
+    /// True when the process has entered a state of "limbo".
+    ///
+    /// This flag qualifies eStateStopped.  It lets us know that when we
+    /// continue from this state the process will exit.  Also, when true,
+    /// Process::m_exit_status is set.
+    bool m_in_limbo;
+
+    /// Drive any exit events to completion.
+    bool m_exit_now;
+
+    /// OS-specific signal set.
+    lldb_private::UnixSignals m_signals;
+
+    /// Returns true if the process has exited.
+    bool HasExited();
+
+    /// Returns true if the process is stopped.
+    bool IsStopped();
+
+    typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+    MMapMap m_addr_to_mmap_size;
+};
+
+#endif  // liblldb_MacOSXProcess_H_
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
new file mode 100644
index 0000000..6e7ae14
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -0,0 +1,195 @@
+//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessPOSIXLog.h"
+
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/StreamFile.h"
+
+#include "ProcessPOSIX.h"
+#include "ProcessPOSIXLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+// We want to avoid global constructors where code needs to be run so here we
+// control access to our static g_log_sp by hiding it in a singleton function
+// that will construct the static g_lob_sp the first time this function is 
+// called.
+static LogSP &
+GetLog ()
+{
+    static LogSP g_log_sp;
+    return g_log_sp;
+}
+
+LogSP
+ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
+{
+    LogSP log(GetLog ());
+    if (log && mask)
+    {
+        uint32_t log_mask = log->GetMask().Get();
+        if ((log_mask & mask) != mask)
+            return LogSP();
+    }
+    return log;
+}
+
+void
+ProcessPOSIXLog::DisableLog (Args &args, Stream *feedback_strm)
+{
+    LogSP log (GetLog ());
+    if (log)
+    {
+        uint32_t flag_bits = 0;
+        
+        const size_t argc = args.GetArgumentCount ();
+        if (argc > 0)
+        {
+            flag_bits = log->GetMask().Get();
+            for (size_t i = 0; i < argc; ++i)
+            {
+                const char *arg = args.GetArgumentAtIndex (i);
+                
+
+                if      (::strcasecmp (arg, "all")        == 0 ) flag_bits &= ~POSIX_LOG_ALL;
+                else if (::strcasecmp (arg, "async")      == 0 ) flag_bits &= ~POSIX_LOG_ASYNC;
+                else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits &= ~POSIX_LOG_BREAKPOINTS;
+                else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits &= ~POSIX_LOG_COMM;
+                else if (::strcasecmp (arg, "default")    == 0 ) flag_bits &= ~POSIX_LOG_DEFAULT;
+                else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits &= ~POSIX_LOG_PACKETS;
+                else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits &= ~POSIX_LOG_MEMORY;
+                else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_SHORT;
+                else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_LONG;
+                else if (::strcasecmp (arg, "process")    == 0 ) flag_bits &= ~POSIX_LOG_PROCESS;
+                else if (::strcasecmp (arg, "ptrace")     == 0 ) flag_bits &= ~POSIX_LOG_PTRACE;
+                else if (::strcasecmp (arg, "registers")  == 0 ) flag_bits &= ~POSIX_LOG_REGISTERS;
+                else if (::strcasecmp (arg, "step")       == 0 ) flag_bits &= ~POSIX_LOG_STEP;
+                else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits &= ~POSIX_LOG_THREAD;
+                else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits &= ~POSIX_LOG_VERBOSE;
+                else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits &= ~POSIX_LOG_WATCHPOINTS;
+                else
+                {
+                    feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+                    ListLogCategories (feedback_strm);
+                }
+                
+            }
+        }
+        
+        if (flag_bits == 0)
+            GetLog ().reset();
+        else
+            log->GetMask().Reset (flag_bits);
+    }
+    
+    return;
+}
+
+LogSP
+ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm)
+{
+    // Try see if there already is a log - that way we can reuse its settings.
+    // We could reuse the log in toto, but we don't know that the stream is the same.
+    uint32_t flag_bits = 0;
+    LogSP log(GetLog ());
+    if (log)
+        flag_bits = log->GetMask().Get();
+
+    // Now make a new log with this stream if one was provided
+    if (log_stream_sp)
+    {
+        log = make_shared<Log>(log_stream_sp);
+        GetLog () = log;
+    }
+
+    if (log)
+    {
+        bool got_unknown_category = false;
+        const size_t argc = args.GetArgumentCount();
+        for (size_t i=0; i<argc; ++i)
+        {
+            const char *arg = args.GetArgumentAtIndex(i);
+
+            if      (::strcasecmp (arg, "all")        == 0 ) flag_bits |= POSIX_LOG_ALL;
+            else if (::strcasecmp (arg, "async")      == 0 ) flag_bits |= POSIX_LOG_ASYNC;
+            else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits |= POSIX_LOG_BREAKPOINTS;
+            else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits |= POSIX_LOG_COMM;
+            else if (::strcasecmp (arg, "default")    == 0 ) flag_bits |= POSIX_LOG_DEFAULT;
+            else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits |= POSIX_LOG_PACKETS;
+            else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits |= POSIX_LOG_MEMORY;
+            else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_SHORT;
+            else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_LONG;
+            else if (::strcasecmp (arg, "process")    == 0 ) flag_bits |= POSIX_LOG_PROCESS;
+            else if (::strcasecmp (arg, "ptrace")     == 0 ) flag_bits |= POSIX_LOG_PTRACE;
+            else if (::strcasecmp (arg, "registers")  == 0 ) flag_bits |= POSIX_LOG_REGISTERS;
+            else if (::strcasecmp (arg, "step")       == 0 ) flag_bits |= POSIX_LOG_STEP;
+            else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits |= POSIX_LOG_THREAD;
+            else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits |= POSIX_LOG_VERBOSE;
+            else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits |= POSIX_LOG_WATCHPOINTS;
+            else
+            {
+                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+                if (got_unknown_category == false)
+                {
+                    got_unknown_category = true;
+                    ListLogCategories (feedback_strm);
+                }
+            }
+        }
+        if (flag_bits == 0)
+            flag_bits = POSIX_LOG_DEFAULT;
+        log->GetMask().Reset(flag_bits);
+        log->GetOptions().Reset(log_options);
+    }
+    return log;
+}
+
+void
+ProcessPOSIXLog::ListLogCategories (Stream *strm)
+{
+    strm->Printf ("Logging categories for '%s':\n"
+                  "  all - turn on all available logging categories\n"
+                  "  async - log asynchronous activity\n"
+                  "  break - log breakpoints\n"
+                  "  communication - log communication activity\n"
+                  "  default - enable the default set of logging categories for liblldb\n"
+                  "  packets - log gdb remote packets\n"
+                  "  memory - log memory reads and writes\n"
+                  "  data-short - log memory bytes for memory reads and writes for short transactions only\n"
+                  "  data-long - log memory bytes for memory reads and writes for all transactions\n"
+                  "  process - log process events and activities\n"
+#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
+                  "  ptrace - log all calls to ptrace\n"
+#endif
+                  "  registers - log register read/writes\n"
+                  "  thread - log thread events and activities\n"
+                  "  step - log step related activities\n"
+                  "  verbose - enable verbose logging\n"
+                  "  watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname);
+}
+
+
+void
+ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
+    if (log)
+    {
+        va_list args;
+        va_start (args, format);
+        log->VAPrintf (format, args);
+        va_end (args);
+    }
+}
+
+int ProcessPOSIXLog::m_nestinglevel;
+const char *ProcessPOSIXLog::m_pluginname = "";
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
new file mode 100644
index 0000000..5c34a88
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -0,0 +1,106 @@
+//===-- ProcessLinuxLog.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_ProcessLinuxLog_h_
+#define liblldb_ProcessLinuxLog_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/Core/Log.h"
+
+#define POSIX_LOG_VERBOSE                  (1u << 0)
+#define POSIX_LOG_PROCESS                  (1u << 1)
+#define POSIX_LOG_THREAD                   (1u << 2)
+#define POSIX_LOG_PACKETS                  (1u << 3)
+#define POSIX_LOG_MEMORY                   (1u << 4)    // Log memory reads/writes calls
+#define POSIX_LOG_MEMORY_DATA_SHORT        (1u << 5)    // Log short memory reads/writes bytes
+#define POSIX_LOG_MEMORY_DATA_LONG         (1u << 6)    // Log all memory reads/writes bytes
+#define POSIX_LOG_BREAKPOINTS              (1u << 7)
+#define POSIX_LOG_WATCHPOINTS              (1u << 8)
+#define POSIX_LOG_STEP                     (1u << 9)
+#define POSIX_LOG_COMM                     (1u << 10)
+#define POSIX_LOG_ASYNC                    (1u << 11)
+#define POSIX_LOG_PTRACE                   (1u << 12)
+#define POSIX_LOG_REGISTERS                (1u << 13)
+#define POSIX_LOG_ALL                      (UINT32_MAX)
+#define POSIX_LOG_DEFAULT                  POSIX_LOG_PACKETS
+
+// The size which determines "short memory reads/writes".
+#define POSIX_LOG_MEMORY_SHORT_BYTES       (4 * sizeof(ptrdiff_t))
+
+class ProcessPOSIXLog
+{
+    static int m_nestinglevel;
+    static const char *m_pluginname;
+
+public:
+    static void
+    RegisterPluginName(const char *pluginName)
+    {
+        m_pluginname = pluginName;
+    }
+
+
+    static lldb::LogSP
+    GetLogIfAllCategoriesSet(uint32_t mask = 0);
+
+    static void
+    DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
+
+    static lldb::LogSP
+    EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
+               lldb_private::Args &args, lldb_private::Stream *feedback_strm);
+
+    static void
+    ListLogCategories (lldb_private::Stream *strm);
+
+    static void
+    LogIf (uint32_t mask, const char *format, ...);
+
+    // The following functions can be used to enable the client to limit
+    // logging to only the top level function calls.  This is useful for
+    // recursive functions.  FIXME: not thread safe!
+    //     Example:
+    //     void NestingFunc() {
+    //         LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL));
+    //         if (log)
+    //         {
+    //             ProcessLinuxLog::IncNestLevel();
+    //             if (ProcessLinuxLog::AtTopNestLevel())
+    //                 log->Print(msg);
+    //         }
+    //         NestingFunc();
+    //         if (log)
+    //             ProcessLinuxLog::DecNestLevel();
+    //     }
+
+    static bool
+    AtTopNestLevel()
+    {
+        return m_nestinglevel == 1;
+    }
+
+    static void
+    IncNestLevel()
+    {
+        ++m_nestinglevel;
+    }
+
+    static void
+    DecNestLevel()
+    {
+        --m_nestinglevel;
+        assert(m_nestinglevel >= 0);
+    }
+};
+
+#endif  // liblldb_ProcessLinuxLog_h_
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
new file mode 100644
index 0000000..f97e710
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
@@ -0,0 +1,40 @@
+//===-- RegisterContextPOSIX.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_H_
+#define liblldb_RegisterContextPOSIX_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Target/RegisterContext.h"
+
+//------------------------------------------------------------------------------
+/// @class RegisterContextPOSIX
+///
+/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
+class RegisterContextPOSIX
+    : public lldb_private::RegisterContext
+{
+public:
+    RegisterContextPOSIX(lldb_private::Thread &thread,
+                         uint32_t concrete_frame_idx)
+        : RegisterContext(thread, concrete_frame_idx) { }
+
+    /// Updates the register state of the associated thread after hitting a
+    /// breakpoint (if that make sense for the architecture).  Default
+    /// implementation simply returns true for architectures which do not
+    /// require any update.
+    ///
+    /// @return
+    ///    True if the operation succeeded and false otherwise.
+    virtual bool UpdateAfterBreakpoint() { return true; }
+};
+
+#endif // #ifndef liblldb_RegisterContextPOSIX_H_
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
new file mode 100644
index 0000000..9aef237
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
@@ -0,0 +1,643 @@
+//===-- RegisterContextPOSIX_i386.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/Target/Thread.h"
+#include "lldb/Host/Endian.h"
+
+#include "ProcessPOSIX.h"
+#include "ProcessPOSIXLog.h"
+#include "ProcessMonitor.h"
+#include "RegisterContext_i386.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+enum
+{
+    k_first_gpr,
+    gpr_eax = k_first_gpr,
+    gpr_ebx,
+    gpr_ecx,
+    gpr_edx,
+    gpr_edi,
+    gpr_esi,
+    gpr_ebp,
+    gpr_esp,
+    gpr_ss,
+    gpr_eflags,
+#ifdef __FreeBSD__
+    gpr_orig_ax,
+#endif
+    gpr_eip,
+    gpr_cs,
+    gpr_ds,
+    gpr_es,
+    gpr_fs,
+    gpr_gs,
+    k_last_gpr = gpr_gs,
+
+    k_first_fpr,
+    fpu_fcw = k_first_fpr,
+    fpu_fsw,
+    fpu_ftw,
+    fpu_fop,
+    fpu_ip,
+    fpu_cs,
+    fpu_foo,
+    fpu_fos,
+    fpu_mxcsr,
+    fpu_stmm0,
+    fpu_stmm1,
+    fpu_stmm2,
+    fpu_stmm3,
+    fpu_stmm4,
+    fpu_stmm5,
+    fpu_stmm6,
+    fpu_stmm7,
+    fpu_xmm0,
+    fpu_xmm1,
+    fpu_xmm2,
+    fpu_xmm3,
+    fpu_xmm4,
+    fpu_xmm5,
+    fpu_xmm6,
+    fpu_xmm7,
+    k_last_fpr = fpu_xmm7,
+
+    k_num_registers,
+    k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
+    k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
+};
+
+// Number of register sets provided by this context.
+enum
+{
+    k_num_register_sets = 2
+};
+
+enum
+{
+    gcc_eax = 0,
+    gcc_ecx,
+    gcc_edx,
+    gcc_ebx,
+    gcc_ebp,
+    gcc_esp,
+    gcc_esi,
+    gcc_edi,
+    gcc_eip,
+    gcc_eflags
+};
+
+enum
+{
+    dwarf_eax = 0,
+    dwarf_ecx,
+    dwarf_edx,
+    dwarf_ebx,
+    dwarf_esp,
+    dwarf_ebp,
+    dwarf_esi,
+    dwarf_edi,
+    dwarf_eip,
+    dwarf_eflags,
+    dwarf_stmm0 = 11,
+    dwarf_stmm1,
+    dwarf_stmm2,
+    dwarf_stmm3,
+    dwarf_stmm4,
+    dwarf_stmm5,
+    dwarf_stmm6,
+    dwarf_stmm7,
+    dwarf_xmm0 = 21,
+    dwarf_xmm1,
+    dwarf_xmm2,
+    dwarf_xmm3,
+    dwarf_xmm4,
+    dwarf_xmm5,
+    dwarf_xmm6,
+    dwarf_xmm7
+};
+
+enum
+{
+    gdb_eax        =  0,
+    gdb_ecx        =  1,
+    gdb_edx        =  2,
+    gdb_ebx        =  3,
+    gdb_esp        =  4,
+    gdb_ebp        =  5,
+    gdb_esi        =  6,
+    gdb_edi        =  7,
+    gdb_eip        =  8,
+    gdb_eflags     =  9,
+    gdb_cs         = 10,
+    gdb_ss         = 11,
+    gdb_ds         = 12,
+    gdb_es         = 13,
+    gdb_fs         = 14,
+    gdb_gs         = 15,
+    gdb_stmm0      = 16,
+    gdb_stmm1      = 17,
+    gdb_stmm2      = 18,
+    gdb_stmm3      = 19,
+    gdb_stmm4      = 20,
+    gdb_stmm5      = 21,
+    gdb_stmm6      = 22,
+    gdb_stmm7      = 23,
+    gdb_fcw        = 24,
+    gdb_fsw        = 25,
+    gdb_ftw        = 26,
+    gdb_fpu_cs     = 27,
+    gdb_ip         = 28,
+    gdb_fpu_ds     = 29,
+    gdb_dp         = 30,
+    gdb_fop        = 31,
+    gdb_xmm0       = 32,
+    gdb_xmm1       = 33,
+    gdb_xmm2       = 34,
+    gdb_xmm3       = 35,
+    gdb_xmm4       = 36,
+    gdb_xmm5       = 37,
+    gdb_xmm6       = 38,
+    gdb_xmm7       = 39,
+    gdb_mxcsr      = 40,
+    gdb_mm0        = 41,
+    gdb_mm1        = 42,
+    gdb_mm2        = 43,
+    gdb_mm3        = 44,
+    gdb_mm4        = 45,
+    gdb_mm5        = 46,
+    gdb_mm6        = 47,
+    gdb_mm7        = 48
+};
+
+static const
+uint32_t g_gpr_regnums[k_num_gpr_registers] =
+{
+    gpr_eax,
+    gpr_ebx,
+    gpr_ecx,
+    gpr_edx,
+    gpr_edi,
+    gpr_esi,
+    gpr_ebp,
+    gpr_esp,
+    gpr_ss,
+    gpr_eflags,
+#ifdef __FreeBSD__
+    gpr_orig_ax,
+#endif
+    gpr_eip,
+    gpr_cs,
+    gpr_ds,
+    gpr_es,
+    gpr_fs,
+    gpr_gs,
+};
+
+static const uint32_t
+g_fpu_regnums[k_num_fpu_registers] =
+{
+    fpu_fcw,
+    fpu_fsw,
+    fpu_ftw,
+    fpu_fop,
+    fpu_ip,
+    fpu_cs,
+    fpu_foo,
+    fpu_fos,
+    fpu_mxcsr,
+    fpu_stmm0,
+    fpu_stmm1,
+    fpu_stmm2,
+    fpu_stmm3,
+    fpu_stmm4,
+    fpu_stmm5,
+    fpu_stmm6,
+    fpu_stmm7,
+    fpu_xmm0,
+    fpu_xmm1,
+    fpu_xmm2,
+    fpu_xmm3,
+    fpu_xmm4,
+    fpu_xmm5,
+    fpu_xmm6,
+    fpu_xmm7,
+};
+
+static const RegisterSet
+g_reg_sets[k_num_register_sets] =
+{
+    { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
+    { "Floating Point Registers",  "fpu", k_num_fpu_registers, g_fpu_regnums }
+};
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+    (offsetof(RegisterContext_i386::UserArea, regs) + \
+     offsetof(RegisterContext_i386::GPR, regname))
+
+// Computes the offset of the given FPR in the user data area.
+#define FPR_OFFSET(regname) \
+    (offsetof(RegisterContext_i386::UserArea, i387) + \
+     offsetof(RegisterContext_i386::FPU, regname))
+
+// Number of bytes needed to represent a GPR.
+#define GPR_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
+
+// Number of bytes needed to represent a FPR.
+#define FPR_SIZE(reg) sizeof(((RegisterContext_i386::FPU*)NULL)->reg)
+
+// Number of bytes needed to represent the i'th FP register.
+#define FP_SIZE sizeof(((RegisterContext_i386::MMSReg*)NULL)->bytes)
+
+// Number of bytes needed to represent an XMM register.
+#define XMM_SIZE sizeof(RegisterContext_i386::XMMReg)
+
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)        \
+    { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
+
+#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4)              \
+    { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
+
+#define DEFINE_FP(reg, i)                                          \
+    { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector,  \
+      eFormatVectorOfUInt8,                                        \
+      { dwarf_##reg##i, dwarf_##reg##i,                            \
+        LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
+
+#define DEFINE_XMM(reg, i)                                         \
+    { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
+      eFormatVectorOfUInt8,                                        \
+      { dwarf_##reg##i, dwarf_##reg##i,                            \
+        LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
+
+static RegisterInfo
+g_register_infos[k_num_registers] =
+{
+    // General purpose registers.
+    DEFINE_GPR(eax,    NULL,    gcc_eax,    dwarf_eax,    LLDB_INVALID_REGNUM,    gdb_eax),
+    DEFINE_GPR(ebx,    NULL,    gcc_ebx,    dwarf_ebx,    LLDB_INVALID_REGNUM,    gdb_ebx),
+    DEFINE_GPR(ecx,    NULL,    gcc_ecx,    dwarf_ecx,    LLDB_INVALID_REGNUM,    gdb_ecx),
+    DEFINE_GPR(edx,    NULL,    gcc_edx,    dwarf_edx,    LLDB_INVALID_REGNUM,    gdb_edx),
+    DEFINE_GPR(edi,    NULL,    gcc_edi,    dwarf_edi,    LLDB_INVALID_REGNUM,    gdb_edi),
+    DEFINE_GPR(esi,    NULL,    gcc_esi,    dwarf_esi,    LLDB_INVALID_REGNUM,    gdb_esi),
+    DEFINE_GPR(ebp,    "fp",    gcc_ebp,    dwarf_ebp,    LLDB_INVALID_REGNUM,    gdb_ebp),
+    DEFINE_GPR(esp,    "sp",    gcc_esp,    dwarf_esp,    LLDB_INVALID_REGNUM,    gdb_esp),
+    DEFINE_GPR(ss,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_ss),
+    DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM,    gdb_eflags),
+    DEFINE_GPR(eip,    "pc",    gcc_eip,    dwarf_eip,    LLDB_INVALID_REGNUM,    gdb_eip),
+    DEFINE_GPR(cs,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_cs),
+    DEFINE_GPR(ds,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_ds),
+    DEFINE_GPR(es,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_es),
+    DEFINE_GPR(fs,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_fs),
+    DEFINE_GPR(gs,     NULL,    LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,     LLDB_INVALID_REGNUM,    gdb_gs),
+
+    // Floating point registers.
+    DEFINE_FPR(fcw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw),
+    DEFINE_FPR(fsw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw),
+    DEFINE_FPR(ftw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw),
+    DEFINE_FPR(fop,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop),
+    DEFINE_FPR(ip,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip),
+    DEFINE_FPR(cs,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
+    DEFINE_FPR(foo,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp),
+    DEFINE_FPR(fos,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
+    DEFINE_FPR(mxcsr,     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr),
+
+    DEFINE_FP(stmm, 0),
+    DEFINE_FP(stmm, 1),
+    DEFINE_FP(stmm, 2),
+    DEFINE_FP(stmm, 3),
+    DEFINE_FP(stmm, 4),
+    DEFINE_FP(stmm, 5),
+    DEFINE_FP(stmm, 6),
+    DEFINE_FP(stmm, 7),
+
+    // XMM registers
+    DEFINE_XMM(xmm, 0),
+    DEFINE_XMM(xmm, 1),
+    DEFINE_XMM(xmm, 2),
+    DEFINE_XMM(xmm, 3),
+    DEFINE_XMM(xmm, 4),
+    DEFINE_XMM(xmm, 5),
+    DEFINE_XMM(xmm, 6),
+    DEFINE_XMM(xmm, 7),
+
+};
+
+#ifndef NDEBUG
+static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
+#endif
+
+static unsigned GetRegOffset(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register number.");
+    return g_register_infos[reg].byte_offset;
+}
+
+static unsigned GetRegSize(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register number.");
+    return g_register_infos[reg].byte_size;
+}
+
+RegisterContext_i386::RegisterContext_i386(Thread &thread,
+                                                     uint32_t concrete_frame_idx)
+    : RegisterContextPOSIX(thread, concrete_frame_idx)
+{
+}
+
+RegisterContext_i386::~RegisterContext_i386()
+{
+}
+
+ProcessMonitor &
+RegisterContext_i386::GetMonitor()
+{
+    ProcessPOSIX *process = static_cast<ProcessPOSIX*>(CalculateProcess());
+    return process->GetMonitor();
+}
+
+void
+RegisterContext_i386::Invalidate()
+{
+}
+
+void
+RegisterContext_i386::InvalidateAllRegisters()
+{
+}
+
+size_t
+RegisterContext_i386::GetRegisterCount()
+{
+    assert(k_num_register_infos == k_num_registers);
+    return k_num_registers;
+}
+
+const RegisterInfo *
+RegisterContext_i386::GetRegisterInfoAtIndex(uint32_t reg)
+{
+    assert(k_num_register_infos == k_num_registers);
+    if (reg < k_num_registers)
+        return &g_register_infos[reg];
+    else
+        return NULL;
+}
+
+size_t
+RegisterContext_i386::GetRegisterSetCount()
+{
+    return k_num_register_sets;
+}
+
+const RegisterSet *
+RegisterContext_i386::GetRegisterSet(uint32_t set)
+{
+    if (set < k_num_register_sets)
+        return &g_reg_sets[set];
+    else
+        return NULL;
+}
+
+unsigned
+RegisterContext_i386::GetRegisterIndexFromOffset(unsigned offset)
+{
+    unsigned reg;
+    for (reg = 0; reg < k_num_registers; reg++)
+    {
+        if (g_register_infos[reg].byte_offset == offset)
+            break;
+    }
+    assert(reg < k_num_registers && "Invalid register offset.");
+    return reg;
+}
+
+const char *
+RegisterContext_i386::GetRegisterName(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register offset.");
+    return g_register_infos[reg].name;
+}
+
+bool
+RegisterContext_i386::ReadRegister(const RegisterInfo *reg_info,
+                                        RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value);
+}
+
+bool
+RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
+{
+    return false;
+}
+
+bool RegisterContext_i386::WriteRegister(const RegisterInfo *reg_info,
+                                              const RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteRegisterValue(GetRegOffset(reg), value);
+}
+
+bool
+RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data)
+{
+    return false;
+}
+
+bool
+RegisterContext_i386::UpdateAfterBreakpoint()
+{
+    // PC points one byte past the int3 responsible for the breakpoint.
+    lldb::addr_t pc;
+
+    if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+        return false;
+
+    SetPC(pc - 1);
+    return true;
+}
+
+uint32_t
+RegisterContext_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+                                                               uint32_t num)
+{
+    if (kind == eRegisterKindGeneric)
+    {
+        switch (num)
+        {
+        case LLDB_REGNUM_GENERIC_PC:    return gpr_eip;
+        case LLDB_REGNUM_GENERIC_SP:    return gpr_esp;
+        case LLDB_REGNUM_GENERIC_FP:    return gpr_ebp;
+        case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
+        case LLDB_REGNUM_GENERIC_RA:
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+
+    if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+    {
+        switch (num)
+        {
+        case dwarf_eax:  return gpr_eax;
+        case dwarf_edx:  return gpr_edx;
+        case dwarf_ecx:  return gpr_ecx;
+        case dwarf_ebx:  return gpr_ebx;
+        case dwarf_esi:  return gpr_esi;
+        case dwarf_edi:  return gpr_edi;
+        case dwarf_ebp:  return gpr_ebp;
+        case dwarf_esp:  return gpr_esp;
+        case dwarf_eip:  return gpr_eip;
+        case dwarf_xmm0: return fpu_xmm0;
+        case dwarf_xmm1: return fpu_xmm1;
+        case dwarf_xmm2: return fpu_xmm2;
+        case dwarf_xmm3: return fpu_xmm3;
+        case dwarf_xmm4: return fpu_xmm4;
+        case dwarf_xmm5: return fpu_xmm5;
+        case dwarf_xmm6: return fpu_xmm6;
+        case dwarf_xmm7: return fpu_xmm7;
+        case dwarf_stmm0: return fpu_stmm0;
+        case dwarf_stmm1: return fpu_stmm1;
+        case dwarf_stmm2: return fpu_stmm2;
+        case dwarf_stmm3: return fpu_stmm3;
+        case dwarf_stmm4: return fpu_stmm4;
+        case dwarf_stmm5: return fpu_stmm5;
+        case dwarf_stmm6: return fpu_stmm6;
+        case dwarf_stmm7: return fpu_stmm7;
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+
+    if (kind == eRegisterKindGDB)
+    {
+        switch (num)
+        {
+        case gdb_eax     : return gpr_eax;
+        case gdb_ebx     : return gpr_ebx;
+        case gdb_ecx     : return gpr_ecx;
+        case gdb_edx     : return gpr_edx;
+        case gdb_esi     : return gpr_esi;
+        case gdb_edi     : return gpr_edi;
+        case gdb_ebp     : return gpr_ebp;
+        case gdb_esp     : return gpr_esp;
+        case gdb_eip     : return gpr_eip;
+        case gdb_eflags  : return gpr_eflags;
+        case gdb_cs      : return gpr_cs;
+        case gdb_ss      : return gpr_ss;
+        case gdb_ds      : return gpr_ds;
+        case gdb_es      : return gpr_es;
+        case gdb_fs      : return gpr_fs;
+        case gdb_gs      : return gpr_gs;
+        case gdb_stmm0   : return fpu_stmm0;
+        case gdb_stmm1   : return fpu_stmm1;
+        case gdb_stmm2   : return fpu_stmm2;
+        case gdb_stmm3   : return fpu_stmm3;
+        case gdb_stmm4   : return fpu_stmm4;
+        case gdb_stmm5   : return fpu_stmm5;
+        case gdb_stmm6   : return fpu_stmm6;
+        case gdb_stmm7   : return fpu_stmm7;
+        case gdb_fcw     : return fpu_fcw;
+        case gdb_fsw     : return fpu_fsw;
+        case gdb_ftw     : return fpu_ftw;
+        case gdb_fpu_cs  : return fpu_cs;
+        case gdb_ip      : return fpu_ip;
+        case gdb_fpu_ds  : return fpu_fos;
+        case gdb_dp      : return fpu_foo;
+        case gdb_fop     : return fpu_fop;
+        case gdb_xmm0    : return fpu_xmm0;
+        case gdb_xmm1    : return fpu_xmm1;
+        case gdb_xmm2    : return fpu_xmm2;
+        case gdb_xmm3    : return fpu_xmm3;
+        case gdb_xmm4    : return fpu_xmm4;
+        case gdb_xmm5    : return fpu_xmm5;
+        case gdb_xmm6    : return fpu_xmm6;
+        case gdb_xmm7    : return fpu_xmm7;
+        case gdb_mxcsr   : return fpu_mxcsr;
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+    else if (kind == eRegisterKindLLDB)
+    {
+        return num;
+    }
+
+    return LLDB_INVALID_REGNUM;
+}
+
+bool
+RegisterContext_i386::HardwareSingleStep(bool enable)
+{
+    enum { TRACE_BIT = 0x100 };
+    uint64_t eflags;
+
+    if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL)
+        return false;
+
+    if (enable)
+    {
+        if (eflags & TRACE_BIT)
+            return true;
+
+        eflags |= TRACE_BIT;
+    }
+    else
+    {
+        if (!(eflags & TRACE_BIT))
+            return false;
+
+        eflags &= ~TRACE_BIT;
+    }
+
+    return WriteRegisterFromUnsigned(gpr_eflags, eflags);
+}
+
+void
+RegisterContext_i386::LogGPR(const char *title)
+{
+    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+    if (log)
+    {
+        if (title)
+            log->Printf ("%s", title);
+        for (uint32_t i=0; i<k_num_gpr_registers; i++)
+        {
+            uint32_t reg = gpr_eax + i;
+            log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]);
+        }
+    }
+}
+
+bool
+RegisterContext_i386::ReadGPR()
+{
+    bool result;
+
+    ProcessMonitor &monitor = GetMonitor();
+    result = monitor.ReadGPR(&user.regs);
+    LogGPR("RegisterContext_i386::ReadGPR()");
+    return result;
+}
+
+bool
+RegisterContext_i386::ReadFPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadFPR(&user.i387);
+}
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h
new file mode 100644
index 0000000..1586501
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h
@@ -0,0 +1,169 @@
+//===-- RegisterContext_i386.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_i386_h_
+#define liblldb_RegisterContext_i386_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Log.h"
+#include "RegisterContextPOSIX.h"
+
+class RegisterContext_i386 : public RegisterContextPOSIX
+{
+public:
+    RegisterContext_i386(lldb_private::Thread &thread,
+                              uint32_t concreate_frame_idx);
+
+    ~RegisterContext_i386();
+
+    void
+    Invalidate();
+
+    void
+    InvalidateAllRegisters();
+
+    size_t
+    GetRegisterCount();
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfoAtIndex(uint32_t reg);
+
+    size_t
+    GetRegisterSetCount();
+
+    const lldb_private::RegisterSet *
+    GetRegisterSet(uint32_t set);
+
+    static unsigned
+    GetRegisterIndexFromOffset(unsigned offset);
+
+    static const char *
+    GetRegisterName(unsigned reg);
+
+    bool
+    ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
+
+    bool
+    ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
+
+    virtual bool
+    ReadRegister(const lldb_private::RegisterInfo *reg_info,
+                 lldb_private::RegisterValue &value);
+
+    bool
+    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+    bool
+    WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value);
+
+    bool
+    WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data,
+                       uint32_t data_offset = 0);
+
+    virtual bool
+    WriteRegister(const lldb_private::RegisterInfo *reg_info,
+                  const lldb_private::RegisterValue &value);
+
+    bool
+    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+    uint32_t
+    ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
+
+    bool
+    HardwareSingleStep(bool enable);
+
+    bool
+    UpdateAfterBreakpoint();
+
+    struct GPR
+    {
+        uint32_t ebx;
+        uint32_t ecx;
+        uint32_t edx;
+        uint32_t esi;
+        uint32_t edi;
+        uint32_t ebp;
+        uint32_t eax;
+        uint32_t ds;
+        uint32_t es;
+        uint32_t fs;
+        uint32_t gs;
+        uint32_t orig_ax;
+        uint32_t eip;
+        uint32_t cs;
+        uint32_t eflags;
+        uint32_t esp;
+        uint32_t ss;
+    };
+
+    struct MMSReg
+    {
+        uint8_t bytes[8];
+    };
+
+    struct XMMReg
+    {
+        uint8_t bytes[16];
+    };
+
+    struct FPU
+    {
+        uint16_t    fcw;
+        uint16_t    fsw;
+        uint16_t    ftw;
+        uint16_t    fop;
+        uint32_t    ip;
+        uint32_t    cs;
+        uint32_t    foo;
+        uint32_t    fos;
+        uint32_t    mxcsr;
+        uint32_t    reserved;
+        MMSReg      stmm[8];
+        XMMReg      xmm[8];
+        uint32_t    pad[56];
+    };
+
+    // A user area like this no longer exists on FreeBSD
+    // making this a Linux artifact. Nonetheless, it is safe
+    // leaving it here while the code is being cleaned up and generalized.
+
+    struct UserArea
+    {
+        GPR      regs;          // General purpose registers.
+        int32_t  fpvalid;       // True if FPU is being used.
+        FPU      i387;          // FPU registers.
+        uint32_t tsize;         // Text segment size.
+        uint32_t dsize;         // Data segment size.
+        uint32_t ssize;         // Stack segment size.
+        uint32_t start_code;    // VM address of text.
+        uint32_t start_stack;   // VM address of stack bottom (top in rsp).
+        int32_t  signal;        // Signal causing core dump.
+        int32_t  reserved;      // Unused.
+        uint32_t ar0;           // Location of GPR's.
+        FPU*     fpstate;       // Location of FPR's.
+        uint32_t magic;         // Identifier for core dumps.
+        char     u_comm[32];    // Command causing core dump.
+        uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+    };
+private:
+    UserArea user;
+
+    ProcessMonitor &GetMonitor();
+
+    void LogGPR(const char *title);
+
+    bool ReadGPR();
+    bool ReadFPR();
+};
+
+#endif // #ifndef liblldb_RegisterContext_i386_h_
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
new file mode 100644
index 0000000..8ecb4d1
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
@@ -0,0 +1,757 @@
+//===-- RegisterContext_x86_64.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/Scalar.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Host/Endian.h"
+
+#include "ProcessPOSIX.h"
+#include "ProcessMonitor.h"
+#include "RegisterContext_x86_64.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// Internal codes for all x86_64 registers.
+enum
+{
+    k_first_gpr,
+    gpr_rax = k_first_gpr,
+    gpr_rbx,
+    gpr_rcx,
+    gpr_rdx,
+    gpr_rdi,
+    gpr_rsi,
+    gpr_rbp,
+    gpr_rsp,
+    gpr_r8,
+    gpr_r9,
+    gpr_r10,
+    gpr_r11,
+    gpr_r12,
+    gpr_r13,
+    gpr_r14,
+    gpr_r15,
+    gpr_rip,
+    gpr_rflags,
+    gpr_cs,
+    gpr_fs,
+    gpr_gs,
+    gpr_ss,
+    gpr_ds,
+    gpr_es,
+    k_last_gpr = gpr_es,
+
+    k_first_fpr,
+    fpu_fcw = k_first_fpr,
+    fpu_fsw,
+    fpu_ftw,
+    fpu_fop,
+    fpu_ip,
+    fpu_cs,
+    fpu_dp,
+    fpu_ds,
+    fpu_mxcsr,
+    fpu_mxcsrmask,
+    fpu_stmm0,
+    fpu_stmm1,
+    fpu_stmm2,
+    fpu_stmm3,
+    fpu_stmm4,
+    fpu_stmm5,
+    fpu_stmm6,
+    fpu_stmm7,
+    fpu_xmm0,
+    fpu_xmm1,
+    fpu_xmm2,
+    fpu_xmm3,
+    fpu_xmm4,
+    fpu_xmm5,
+    fpu_xmm6,
+    fpu_xmm7,
+    fpu_xmm8,
+    fpu_xmm9,
+    fpu_xmm10,
+    fpu_xmm11,
+    fpu_xmm12,
+    fpu_xmm13,
+    fpu_xmm14,
+    fpu_xmm15,
+    k_last_fpr = fpu_xmm15,
+
+    k_num_registers,
+    k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
+    k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
+};
+
+// Number of register sets provided by this context.
+enum
+{
+    k_num_register_sets = 2
+};
+
+enum gcc_dwarf_regnums
+{
+    gcc_dwarf_gpr_rax = 0,
+    gcc_dwarf_gpr_rdx,
+    gcc_dwarf_gpr_rcx,
+    gcc_dwarf_gpr_rbx,
+    gcc_dwarf_gpr_rsi,
+    gcc_dwarf_gpr_rdi,
+    gcc_dwarf_gpr_rbp,
+    gcc_dwarf_gpr_rsp,
+    gcc_dwarf_gpr_r8,
+    gcc_dwarf_gpr_r9,
+    gcc_dwarf_gpr_r10,
+    gcc_dwarf_gpr_r11,
+    gcc_dwarf_gpr_r12,
+    gcc_dwarf_gpr_r13,
+    gcc_dwarf_gpr_r14,
+    gcc_dwarf_gpr_r15,
+    gcc_dwarf_gpr_rip,
+    gcc_dwarf_fpu_xmm0,
+    gcc_dwarf_fpu_xmm1,
+    gcc_dwarf_fpu_xmm2,
+    gcc_dwarf_fpu_xmm3,
+    gcc_dwarf_fpu_xmm4,
+    gcc_dwarf_fpu_xmm5,
+    gcc_dwarf_fpu_xmm6,
+    gcc_dwarf_fpu_xmm7,
+    gcc_dwarf_fpu_xmm8,
+    gcc_dwarf_fpu_xmm9,
+    gcc_dwarf_fpu_xmm10,
+    gcc_dwarf_fpu_xmm11,
+    gcc_dwarf_fpu_xmm12,
+    gcc_dwarf_fpu_xmm13,
+    gcc_dwarf_fpu_xmm14,
+    gcc_dwarf_fpu_xmm15,
+    gcc_dwarf_fpu_stmm0,
+    gcc_dwarf_fpu_stmm1,
+    gcc_dwarf_fpu_stmm2,
+    gcc_dwarf_fpu_stmm3,
+    gcc_dwarf_fpu_stmm4,
+    gcc_dwarf_fpu_stmm5,
+    gcc_dwarf_fpu_stmm6,
+    gcc_dwarf_fpu_stmm7
+};
+
+enum gdb_regnums
+{
+    gdb_gpr_rax     =   0,
+    gdb_gpr_rbx     =   1,
+    gdb_gpr_rcx     =   2,
+    gdb_gpr_rdx     =   3,
+    gdb_gpr_rsi     =   4,
+    gdb_gpr_rdi     =   5,
+    gdb_gpr_rbp     =   6,
+    gdb_gpr_rsp     =   7,
+    gdb_gpr_r8      =   8,
+    gdb_gpr_r9      =   9,
+    gdb_gpr_r10     =  10,
+    gdb_gpr_r11     =  11,
+    gdb_gpr_r12     =  12,
+    gdb_gpr_r13     =  13,
+    gdb_gpr_r14     =  14,
+    gdb_gpr_r15     =  15,
+    gdb_gpr_rip     =  16,
+    gdb_gpr_rflags  =  17,
+    gdb_gpr_cs      =  18,
+    gdb_gpr_ss      =  19,
+    gdb_gpr_ds      =  20,
+    gdb_gpr_es      =  21,
+    gdb_gpr_fs      =  22,
+    gdb_gpr_gs      =  23,
+    gdb_fpu_stmm0   =  24,
+    gdb_fpu_stmm1   =  25,
+    gdb_fpu_stmm2   =  26,
+    gdb_fpu_stmm3   =  27,
+    gdb_fpu_stmm4   =  28,
+    gdb_fpu_stmm5   =  29,
+    gdb_fpu_stmm6   =  30,
+    gdb_fpu_stmm7   =  31,
+    gdb_fpu_fcw     =  32,
+    gdb_fpu_fsw     =  33,
+    gdb_fpu_ftw     =  34,
+    gdb_fpu_cs      =  35,
+    gdb_fpu_ip      =  36,
+    gdb_fpu_ds      =  37,
+    gdb_fpu_dp      =  38,
+    gdb_fpu_fop     =  39,
+    gdb_fpu_xmm0    =  40,
+    gdb_fpu_xmm1    =  41,
+    gdb_fpu_xmm2    =  42,
+    gdb_fpu_xmm3    =  43,
+    gdb_fpu_xmm4    =  44,
+    gdb_fpu_xmm5    =  45,
+    gdb_fpu_xmm6    =  46,
+    gdb_fpu_xmm7    =  47,
+    gdb_fpu_xmm8    =  48,
+    gdb_fpu_xmm9    =  49,
+    gdb_fpu_xmm10   =  50,
+    gdb_fpu_xmm11   =  51,
+    gdb_fpu_xmm12   =  52,
+    gdb_fpu_xmm13   =  53,
+    gdb_fpu_xmm14   =  54,
+    gdb_fpu_xmm15   =  55,
+    gdb_fpu_mxcsr   =  56
+};
+
+static const
+uint32_t g_gpr_regnums[k_num_gpr_registers] =
+{
+    gpr_rax,
+    gpr_rbx,
+    gpr_rcx,
+    gpr_rdx,
+    gpr_rdi,
+    gpr_rsi,
+    gpr_rbp,
+    gpr_rsp,
+    gpr_r8,
+    gpr_r9,
+    gpr_r10,
+    gpr_r11,
+    gpr_r12,
+    gpr_r13,
+    gpr_r14,
+    gpr_r15,
+    gpr_rip,
+    gpr_rflags,
+    gpr_cs,
+    gpr_fs,
+    gpr_gs,
+    gpr_ss,
+    gpr_ds,
+    gpr_es
+};
+
+static const uint32_t
+g_fpu_regnums[k_num_fpu_registers] =
+{
+    fpu_fcw,
+    fpu_fsw,
+    fpu_ftw,
+    fpu_fop,
+    fpu_ip,
+    fpu_cs,
+    fpu_dp,
+    fpu_ds,
+    fpu_mxcsr,
+    fpu_mxcsrmask,
+    fpu_stmm0,
+    fpu_stmm1,
+    fpu_stmm2,
+    fpu_stmm3,
+    fpu_stmm4,
+    fpu_stmm5,
+    fpu_stmm6,
+    fpu_stmm7,
+    fpu_xmm0,
+    fpu_xmm1,
+    fpu_xmm2,
+    fpu_xmm3,
+    fpu_xmm4,
+    fpu_xmm5,
+    fpu_xmm6,
+    fpu_xmm7,
+    fpu_xmm8,
+    fpu_xmm9,
+    fpu_xmm10,
+    fpu_xmm11,
+    fpu_xmm12,
+    fpu_xmm13,
+    fpu_xmm14,
+    fpu_xmm15
+};
+
+static const RegisterSet
+g_reg_sets[k_num_register_sets] =
+{
+    { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
+    { "Floating Point Registers",  "fpu", k_num_fpu_registers, g_fpu_regnums }
+};
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+    (offsetof(RegisterContext_x86_64::UserArea, regs) + \
+     offsetof(GPR, regname))
+
+// Computes the offset of the given FPR in the user data area.
+#define FPR_OFFSET(regname) \
+    (offsetof(RegisterContext_x86_64::UserArea, i387) + \
+     offsetof(RegisterContext_x86_64::FPU, regname))
+
+// Number of bytes needed to represent a GPR.
+#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg)
+
+// Number of bytes needed to represent a FPR.
+#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FPU*)NULL)->reg)
+
+// Number of bytes needed to represent the i'th FP register.
+#define FP_SIZE sizeof(((RegisterContext_x86_64::MMSReg*)NULL)->bytes)
+
+// Number of bytes needed to represent an XMM register.
+#define XMM_SIZE sizeof(RegisterContext_x86_64::XMMReg)
+
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)        \
+    { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
+
+#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4)              \
+    { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
+      eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
+
+#define DEFINE_FP(reg, i)                                          \
+    { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector,  \
+      eFormatVectorOfUInt8,                                        \
+      { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i,            \
+        LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
+
+#define DEFINE_XMM(reg, i)                                         \
+    { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
+      eFormatVectorOfUInt8,                                        \
+      { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i,            \
+        LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } }
+
+#define REG_CONTEXT_SIZE (sizeof(GPR) + sizeof(RegisterContext_x86_64::FPU))
+
+static RegisterInfo
+g_register_infos[k_num_registers] =
+{
+    // General purpose registers.
+    DEFINE_GPR(rax,    NULL,    gcc_dwarf_gpr_rax,   gcc_dwarf_gpr_rax,   LLDB_INVALID_REGNUM,       gdb_gpr_rax),
+    DEFINE_GPR(rbx,    NULL,    gcc_dwarf_gpr_rbx,   gcc_dwarf_gpr_rbx,   LLDB_INVALID_REGNUM,       gdb_gpr_rbx),
+    DEFINE_GPR(rcx,    NULL,    gcc_dwarf_gpr_rcx,   gcc_dwarf_gpr_rcx,   LLDB_INVALID_REGNUM,       gdb_gpr_rcx),
+    DEFINE_GPR(rdx,    NULL,    gcc_dwarf_gpr_rdx,   gcc_dwarf_gpr_rdx,   LLDB_INVALID_REGNUM,       gdb_gpr_rdx),
+    DEFINE_GPR(rdi,    NULL,    gcc_dwarf_gpr_rdi,   gcc_dwarf_gpr_rdi,   LLDB_INVALID_REGNUM,       gdb_gpr_rdi),
+    DEFINE_GPR(rsi,    NULL,    gcc_dwarf_gpr_rsi,   gcc_dwarf_gpr_rsi,   LLDB_INVALID_REGNUM,       gdb_gpr_rsi),
+    DEFINE_GPR(rbp,    "fp",    gcc_dwarf_gpr_rbp,   gcc_dwarf_gpr_rbp,   LLDB_REGNUM_GENERIC_FP,    gdb_gpr_rbp),
+    DEFINE_GPR(rsp,    "sp",    gcc_dwarf_gpr_rsp,   gcc_dwarf_gpr_rsp,   LLDB_REGNUM_GENERIC_SP,    gdb_gpr_rsp),
+    DEFINE_GPR(r8,     NULL,    gcc_dwarf_gpr_r8,    gcc_dwarf_gpr_r8,    LLDB_INVALID_REGNUM,       gdb_gpr_r8),
+    DEFINE_GPR(r9,     NULL,    gcc_dwarf_gpr_r9,    gcc_dwarf_gpr_r9,    LLDB_INVALID_REGNUM,       gdb_gpr_r9),
+    DEFINE_GPR(r10,    NULL,    gcc_dwarf_gpr_r10,   gcc_dwarf_gpr_r10,   LLDB_INVALID_REGNUM,       gdb_gpr_r10),
+    DEFINE_GPR(r11,    NULL,    gcc_dwarf_gpr_r11,   gcc_dwarf_gpr_r11,   LLDB_INVALID_REGNUM,       gdb_gpr_r11),
+    DEFINE_GPR(r12,    NULL,    gcc_dwarf_gpr_r12,   gcc_dwarf_gpr_r12,   LLDB_INVALID_REGNUM,       gdb_gpr_r12),
+    DEFINE_GPR(r13,    NULL,    gcc_dwarf_gpr_r13,   gcc_dwarf_gpr_r13,   LLDB_INVALID_REGNUM,       gdb_gpr_r13),
+    DEFINE_GPR(r14,    NULL,    gcc_dwarf_gpr_r14,   gcc_dwarf_gpr_r14,   LLDB_INVALID_REGNUM,       gdb_gpr_r14),
+    DEFINE_GPR(r15,    NULL,    gcc_dwarf_gpr_r15,   gcc_dwarf_gpr_r15,   LLDB_INVALID_REGNUM,       gdb_gpr_r15),
+    DEFINE_GPR(rip,    "pc",    gcc_dwarf_gpr_rip,   gcc_dwarf_gpr_rip,   LLDB_REGNUM_GENERIC_PC,    gdb_gpr_rip),
+    DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags),
+    DEFINE_GPR(cs,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_cs),
+    DEFINE_GPR(fs,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_fs),
+    DEFINE_GPR(gs,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_gs),
+    DEFINE_GPR(ss,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_ss),
+    DEFINE_GPR(ds,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_ds),
+    DEFINE_GPR(es,     NULL,    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       gdb_gpr_es),
+
+    // i387 Floating point registers.
+    DEFINE_FPR(fcw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
+    DEFINE_FPR(fsw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
+    DEFINE_FPR(ftw,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw),
+    DEFINE_FPR(fop,       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
+    DEFINE_FPR(ip,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
+    // FIXME: Extract segment from ip.
+    DEFINE_FPR(ip,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
+    DEFINE_FPR(dp,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
+    // FIXME: Extract segment from dp.
+    DEFINE_FPR(dp,        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
+    DEFINE_FPR(mxcsr,     LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
+    DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+    // FP registers.
+    DEFINE_FP(stmm, 0),
+    DEFINE_FP(stmm, 1),
+    DEFINE_FP(stmm, 2),
+    DEFINE_FP(stmm, 3),
+    DEFINE_FP(stmm, 4),
+    DEFINE_FP(stmm, 5),
+    DEFINE_FP(stmm, 6),
+    DEFINE_FP(stmm, 7),
+
+    // XMM registers
+    DEFINE_XMM(xmm, 0),
+    DEFINE_XMM(xmm, 1),
+    DEFINE_XMM(xmm, 2),
+    DEFINE_XMM(xmm, 3),
+    DEFINE_XMM(xmm, 4),
+    DEFINE_XMM(xmm, 5),
+    DEFINE_XMM(xmm, 6),
+    DEFINE_XMM(xmm, 7),
+    DEFINE_XMM(xmm, 8),
+    DEFINE_XMM(xmm, 9),
+    DEFINE_XMM(xmm, 10),
+    DEFINE_XMM(xmm, 11),
+    DEFINE_XMM(xmm, 12),
+    DEFINE_XMM(xmm, 13),
+    DEFINE_XMM(xmm, 14),
+    DEFINE_XMM(xmm, 15)
+};
+
+static unsigned GetRegOffset(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register number.");
+    return g_register_infos[reg].byte_offset;
+}
+
+static unsigned GetRegSize(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register number.");
+    return g_register_infos[reg].byte_size;
+}
+
+static bool IsGPR(unsigned reg)
+{
+    return reg <= k_last_gpr;   // GPR's come first.
+}
+
+static bool IsFPR(unsigned reg)
+{
+    return (k_first_fpr <= reg && reg <= k_last_fpr);
+}
+
+RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread,
+                                                         uint32_t concrete_frame_idx)
+    : RegisterContextPOSIX(thread, concrete_frame_idx)
+{
+}
+
+RegisterContext_x86_64::~RegisterContext_x86_64()
+{
+}
+
+ProcessMonitor &
+RegisterContext_x86_64::GetMonitor()
+{
+    ProcessPOSIX *process = static_cast<ProcessPOSIX*>(CalculateProcess());
+    return process->GetMonitor();
+}
+
+void
+RegisterContext_x86_64::Invalidate()
+{
+}
+
+void
+RegisterContext_x86_64::InvalidateAllRegisters()
+{
+}
+
+size_t
+RegisterContext_x86_64::GetRegisterCount()
+{
+    return k_num_registers;
+}
+
+const RegisterInfo *
+RegisterContext_x86_64::GetRegisterInfoAtIndex(uint32_t reg)
+{
+    if (reg < k_num_registers)
+        return &g_register_infos[reg];
+    else
+        return NULL;
+}
+
+size_t
+RegisterContext_x86_64::GetRegisterSetCount()
+{
+    return k_num_register_sets;
+}
+
+const RegisterSet *
+RegisterContext_x86_64::GetRegisterSet(uint32_t set)
+{
+    if (set < k_num_register_sets)
+        return &g_reg_sets[set];
+    else
+        return NULL;
+}
+
+unsigned
+RegisterContext_x86_64::GetRegisterIndexFromOffset(unsigned offset)
+{
+    unsigned reg;
+    for (reg = 0; reg < k_num_registers; reg++)
+    {
+        if (g_register_infos[reg].byte_offset == offset)
+            break;
+    }
+    assert(reg < k_num_registers && "Invalid register offset.");
+    return reg;
+}
+
+const char *
+RegisterContext_x86_64::GetRegisterName(unsigned reg)
+{
+    assert(reg < k_num_registers && "Invalid register offset.");
+    return g_register_infos[reg].name;
+}
+
+bool
+RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info,
+                                          RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value);
+}
+
+bool
+RegisterContext_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
+{
+    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+    if (data_sp && ReadGPR () && ReadFPR ())
+    {
+        uint8_t *dst = data_sp->GetBytes();
+        ::memcpy (dst, &user.regs, sizeof(user.regs));
+        dst += sizeof(user.regs);
+
+        ::memcpy (dst, &user.i387, sizeof(user.i387));
+        return true;
+    }
+    return false;
+}
+
+bool
+RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info,
+                                           const lldb_private::RegisterValue &value)
+{
+    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteRegisterValue(GetRegOffset(reg), value);
+}
+
+bool
+RegisterContext_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
+{
+    if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
+    {
+        const uint8_t *src = data_sp->GetBytes();
+        ::memcpy (&user.regs, src, sizeof(user.regs));
+        src += sizeof(user.regs);
+
+        ::memcpy (&user.i387, src, sizeof(user.i387));
+        return WriteGPR() & WriteFPR();
+    }
+    return false;
+}
+
+bool
+RegisterContext_x86_64::UpdateAfterBreakpoint()
+{
+    // PC points one byte past the int3 responsible for the breakpoint.
+    lldb::addr_t pc;
+
+    if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+        return false;
+
+    SetPC(pc - 1);
+    return true;
+}
+
+uint32_t
+RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+                                                                 uint32_t num)
+{
+    if (kind == eRegisterKindGeneric)
+    {
+        switch (num)
+        {
+        case LLDB_REGNUM_GENERIC_PC:    return gpr_rip;
+        case LLDB_REGNUM_GENERIC_SP:    return gpr_rsp;
+        case LLDB_REGNUM_GENERIC_FP:    return gpr_rbp;
+        case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
+        case LLDB_REGNUM_GENERIC_RA:
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+
+    if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+    {
+        switch (num)
+        {
+        case gcc_dwarf_gpr_rax:  return gpr_rax;
+        case gcc_dwarf_gpr_rdx:  return gpr_rdx;
+        case gcc_dwarf_gpr_rcx:  return gpr_rcx;
+        case gcc_dwarf_gpr_rbx:  return gpr_rbx;
+        case gcc_dwarf_gpr_rsi:  return gpr_rsi;
+        case gcc_dwarf_gpr_rdi:  return gpr_rdi;
+        case gcc_dwarf_gpr_rbp:  return gpr_rbp;
+        case gcc_dwarf_gpr_rsp:  return gpr_rsp;
+        case gcc_dwarf_gpr_r8:   return gpr_r8;
+        case gcc_dwarf_gpr_r9:   return gpr_r9;
+        case gcc_dwarf_gpr_r10:  return gpr_r10;
+        case gcc_dwarf_gpr_r11:  return gpr_r11;
+        case gcc_dwarf_gpr_r12:  return gpr_r12;
+        case gcc_dwarf_gpr_r13:  return gpr_r13;
+        case gcc_dwarf_gpr_r14:  return gpr_r14;
+        case gcc_dwarf_gpr_r15:  return gpr_r15;
+        case gcc_dwarf_gpr_rip:  return gpr_rip;
+        case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
+        case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
+        case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
+        case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
+        case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
+        case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
+        case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
+        case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
+        case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
+        case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
+        case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
+        case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
+        case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
+        case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
+        case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
+        case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
+        case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
+        case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
+        case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
+        case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
+        case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
+        case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
+        case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
+        case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+
+    if (kind == eRegisterKindGDB)
+    {
+        switch (num)
+        {
+        case gdb_gpr_rax     : return gpr_rax;
+        case gdb_gpr_rbx     : return gpr_rbx;
+        case gdb_gpr_rcx     : return gpr_rcx;
+        case gdb_gpr_rdx     : return gpr_rdx;
+        case gdb_gpr_rsi     : return gpr_rsi;
+        case gdb_gpr_rdi     : return gpr_rdi;
+        case gdb_gpr_rbp     : return gpr_rbp;
+        case gdb_gpr_rsp     : return gpr_rsp;
+        case gdb_gpr_r8      : return gpr_r8;
+        case gdb_gpr_r9      : return gpr_r9;
+        case gdb_gpr_r10     : return gpr_r10;
+        case gdb_gpr_r11     : return gpr_r11;
+        case gdb_gpr_r12     : return gpr_r12;
+        case gdb_gpr_r13     : return gpr_r13;
+        case gdb_gpr_r14     : return gpr_r14;
+        case gdb_gpr_r15     : return gpr_r15;
+        case gdb_gpr_rip     : return gpr_rip;
+        case gdb_gpr_rflags  : return gpr_rflags;
+        case gdb_gpr_cs      : return gpr_cs;
+        case gdb_gpr_ss      : return gpr_ss;
+        case gdb_gpr_ds      : return gpr_ds;
+        case gdb_gpr_es      : return gpr_es;
+        case gdb_gpr_fs      : return gpr_fs;
+        case gdb_gpr_gs      : return gpr_gs;
+        case gdb_fpu_stmm0   : return fpu_stmm0;
+        case gdb_fpu_stmm1   : return fpu_stmm1;
+        case gdb_fpu_stmm2   : return fpu_stmm2;
+        case gdb_fpu_stmm3   : return fpu_stmm3;
+        case gdb_fpu_stmm4   : return fpu_stmm4;
+        case gdb_fpu_stmm5   : return fpu_stmm5;
+        case gdb_fpu_stmm6   : return fpu_stmm6;
+        case gdb_fpu_stmm7   : return fpu_stmm7;
+        case gdb_fpu_fcw     : return fpu_fcw;
+        case gdb_fpu_fsw     : return fpu_fsw;
+        case gdb_fpu_ftw     : return fpu_ftw;
+        case gdb_fpu_cs      : return fpu_cs;
+        case gdb_fpu_ip      : return fpu_ip;
+        case gdb_fpu_ds      : return fpu_ds;
+        case gdb_fpu_dp      : return fpu_dp;
+        case gdb_fpu_fop     : return fpu_fop;
+        case gdb_fpu_xmm0    : return fpu_xmm0;
+        case gdb_fpu_xmm1    : return fpu_xmm1;
+        case gdb_fpu_xmm2    : return fpu_xmm2;
+        case gdb_fpu_xmm3    : return fpu_xmm3;
+        case gdb_fpu_xmm4    : return fpu_xmm4;
+        case gdb_fpu_xmm5    : return fpu_xmm5;
+        case gdb_fpu_xmm6    : return fpu_xmm6;
+        case gdb_fpu_xmm7    : return fpu_xmm7;
+        case gdb_fpu_xmm8    : return fpu_xmm8;
+        case gdb_fpu_xmm9    : return fpu_xmm9;
+        case gdb_fpu_xmm10   : return fpu_xmm10;
+        case gdb_fpu_xmm11   : return fpu_xmm11;
+        case gdb_fpu_xmm12   : return fpu_xmm12;
+        case gdb_fpu_xmm13   : return fpu_xmm13;
+        case gdb_fpu_xmm14   : return fpu_xmm14;
+        case gdb_fpu_xmm15   : return fpu_xmm15;
+        case gdb_fpu_mxcsr   : return fpu_mxcsr;
+        default:
+            return LLDB_INVALID_REGNUM;
+        }
+    }
+    else if (kind == eRegisterKindLLDB)
+    {
+        return num;
+    }
+
+    return LLDB_INVALID_REGNUM;
+}
+
+bool
+RegisterContext_x86_64::HardwareSingleStep(bool enable)
+{
+    enum { TRACE_BIT = 0x100 };
+    uint64_t rflags;
+
+    if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
+        return false;
+    
+    if (enable)
+    {
+        if (rflags & TRACE_BIT)
+            return true;
+
+        rflags |= TRACE_BIT;
+    }
+    else
+    {
+        if (!(rflags & TRACE_BIT))
+            return false;
+
+        rflags &= ~TRACE_BIT;
+    }
+
+    return WriteRegisterFromUnsigned(gpr_rflags, rflags);
+}
+
+bool
+RegisterContext_x86_64::ReadGPR()
+{
+     ProcessMonitor &monitor = GetMonitor();
+     return monitor.ReadGPR(&user.regs);
+}
+
+bool
+RegisterContext_x86_64::ReadFPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.ReadFPR(&user.i387);
+}
+
+bool
+RegisterContext_x86_64::WriteGPR()
+{
+     ProcessMonitor &monitor = GetMonitor();
+     return monitor.WriteGPR(&user.regs);
+}
+
+bool
+RegisterContext_x86_64::WriteFPR()
+{
+    ProcessMonitor &monitor = GetMonitor();
+    return monitor.WriteFPR(&user.i387);
+}
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
new file mode 100644
index 0000000..56a1843
--- /dev/null
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
@@ -0,0 +1,143 @@
+//===-- RegisterContext_x86_64.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_x86_64_H_
+#define liblldb_RegisterContext_x86_64_H_
+
+#include "lldb/Core/Log.h"
+#include "RegisterContextPOSIX.h"
+
+#ifdef __FreeBSD__
+#include "RegisterContextFreeBSD_x86_64.h"
+#endif
+
+#ifdef __linux__
+#include "RegisterContextLinux_x86_64.h"
+#endif
+
+class ProcessMonitor;
+
+class RegisterContext_x86_64
+  : public RegisterContextPOSIX
+{
+public:
+    RegisterContext_x86_64 (lldb_private::Thread &thread,
+                                 uint32_t concrete_frame_idx);
+
+    ~RegisterContext_x86_64();
+
+    void
+    Invalidate();
+
+    void
+    InvalidateAllRegisters();
+
+    size_t
+    GetRegisterCount();
+
+    const lldb_private::RegisterInfo *
+    GetRegisterInfoAtIndex(uint32_t reg);
+
+    size_t
+    GetRegisterSetCount();
+
+    const lldb_private::RegisterSet *
+    GetRegisterSet(uint32_t set);
+
+    static unsigned
+    GetRegisterIndexFromOffset(unsigned offset);
+
+    static const char *
+    GetRegisterName(unsigned reg);
+
+    virtual bool
+    ReadRegister(const lldb_private::RegisterInfo *reg_info,
+                 lldb_private::RegisterValue &value);
+
+    bool
+    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+    virtual bool
+    WriteRegister(const lldb_private::RegisterInfo *reg_info,
+                  const lldb_private::RegisterValue &value);
+
+    bool
+    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+    uint32_t
+    ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
+
+    bool
+    HardwareSingleStep(bool enable);
+
+    bool
+    UpdateAfterBreakpoint();
+
+    struct MMSReg
+    {
+        uint8_t bytes[10];
+        uint8_t pad[6];
+    };
+
+    struct XMMReg
+    {
+        uint8_t bytes[16];
+    };
+
+    struct FPU
+    {
+        uint16_t fcw;
+        uint16_t fsw;
+        uint16_t ftw;
+        uint16_t fop;
+        uint64_t ip;
+        uint64_t dp;
+        uint32_t mxcsr;
+        uint32_t mxcsrmask;
+        MMSReg   stmm[8];
+        XMMReg   xmm[16];
+        uint32_t padding[24];
+    };
+
+    struct UserArea
+    {
+        GPR      regs;          // General purpose registers.
+        int32_t  fpvalid;       // True if FPU is being used.
+        int32_t  pad0;
+        FPU      i387;          // FPU registers.
+        uint64_t tsize;         // Text segment size.
+        uint64_t dsize;         // Data segment size.
+        uint64_t ssize;         // Stack segment size.
+        uint64_t start_code;    // VM address of text.
+        uint64_t start_stack;   // VM address of stack bottom (top in rsp).
+        int64_t  signal;        // Signal causing core dump.
+        int32_t  reserved;      // Unused.
+        int32_t  pad1;
+        uint64_t ar0;           // Location of GPR's.
+        FPU*     fpstate;       // Location of FPR's.
+        uint64_t magic;         // Identifier for core dumps.
+        char     u_comm[32];    // Command causing core dump.
+        uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+        uint64_t error_code;    // CPU error code.
+        uint64_t fault_address; // Control register CR3.
+    };
+
+private:
+    UserArea user;
+
+    ProcessMonitor &GetMonitor();
+
+    bool ReadGPR();
+    bool ReadFPR();
+
+    bool WriteGPR();
+    bool WriteFPR();
+};
+
+#endif // #ifndef liblldb_RegisterContext_x86_64_H_