Move register reading form NativeProcessLinux to NativeRegisterContextLinux*
authorTamas Berghammer <tberghammer@google.com>
Tue, 26 May 2015 11:58:52 +0000 (11:58 +0000)
committerTamas Berghammer <tberghammer@google.com>
Tue, 26 May 2015 11:58:52 +0000 (11:58 +0000)
This change reorganize the register read/write code inside lldb-server on Linux
with moving the architecture independent code into a new class called
NativeRegisterContextLinux and all of the architecture dependent code into the
appropriate NativeRegisterContextLinux_* class. As part of it the compilation of
the architecture specific register contexts are only compiled on the specific
architecture because they can't be used in other cases.

The purpose of this change is to remove a lot of duplicated code from the different
register contexts and to remove the architecture dependent codes from the global
NativeProcessLinux class.

Differential revision: http://reviews.llvm.org/D9935

llvm-svn: 238196

17 files changed:
lldb/source/Plugins/Process/Linux/CMakeLists.txt
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp [new file with mode: 0644]
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h [new file with mode: 0644]
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
lldb/source/Plugins/Process/Linux/Procfs.h
lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h

index f3f5576..f8a7e45 100644 (file)
@@ -7,6 +7,7 @@ include_directories(../Utility)
 add_lldb_library(lldbPluginProcessLinux
   LinuxThread.cpp
   NativeProcessLinux.cpp
+  NativeRegisterContextLinux.cpp
   NativeRegisterContextLinux_arm.cpp
   NativeRegisterContextLinux_arm64.cpp
   NativeRegisterContextLinux_x86_64.cpp
@@ -16,4 +17,3 @@ add_lldb_library(lldbPluginProcessLinux
   ProcessMonitor.cpp
   ProcFileReader.cpp
   )
-
index 048819c..325fdde 100644 (file)
 #include <sys/user.h>
 #include <sys/wait.h>
 
-#if defined (__arm64__) || defined (__aarch64__)
-// NT_PRSTATUS and NT_FPREGSET definition
-#include <elf.h>
-#endif
-
 #include "lldb/Host/linux/Personality.h"
 #include "lldb/Host/linux/Ptrace.h"
 #include "lldb/Host/linux/Signalfd.h"
   #define TRAP_HWBKPT 4
 #endif
 
-// We disable the tracing of ptrace calls for integration builds to
-// avoid the additional indirection and checks.
-#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
-#define PTRACE(req, pid, addr, data, data_size, error) \
-    PtraceWrapper((req), (pid), (addr), (data), (data_size), (error), #req, __FILE__, __LINE__)
-#else
-#define PTRACE(req, pid, addr, data, data_size, error) \
-    PtraceWrapper((req), (pid), (addr), (data), (data_size), (error))
-#endif
-
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
@@ -204,72 +189,6 @@ namespace
         }
     }
 
-    // Wrapper for ptrace to catch errors and log calls.
-    // Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
-    long
-    PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error,
-                  const char* reqName, const char* file, int line)
-    {
-        long int result;
-
-        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
-
-        PtraceDisplayBytes(req, data, data_size);
-
-        error.Clear();
-        errno = 0;
-        if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
-            result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data);
-        else
-            result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data);
-
-        if (result == -1)
-            error.SetErrorToErrno();
-
-        if (log)
-            log->Printf("ptrace(%s, %" PRIu64 ", %p, %p, %zu)=%lX called from file %s line %d",
-                    reqName, pid, addr, data, data_size, result, file, line);
-
-        PtraceDisplayBytes(req, data, data_size);
-
-        if (log && error.GetError() != 0)
-        {
-            const char* str;
-            switch (error.GetError())
-            {
-            case ESRCH:  str = "ESRCH"; break;
-            case EINVAL: str = "EINVAL"; break;
-            case EBUSY:  str = "EBUSY"; break;
-            case EPERM:  str = "EPERM"; break;
-            default:     str = error.AsCString();
-            }
-            log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
-        }
-
-        return result;
-    }
-
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
-    // Wrapper for ptrace when logging is not required.
-    // Sets errno to 0 prior to calling ptrace.
-    long
-    PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error)
-    {
-        long result = 0;
-
-        error.Clear();
-        errno = 0;
-        if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
-            result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data);
-        else
-            result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data);
-
-        if (result == -1)
-            error.SetErrorToErrno();
-        return result;
-    }
-#endif
-
     //------------------------------------------------------------------------------
     // Static implementations of NativeProcessLinux::ReadMemory and
     // NativeProcessLinux::WriteMemory.  This enables mutual recursion between these
@@ -300,7 +219,7 @@ namespace
         assert(sizeof(data) >= word_size);
         for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
         {
-            data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error);
+            data = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error);
             if (error.Fail())
             {
                 if (log)
@@ -377,7 +296,7 @@ namespace
                     log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
                             (void*)vm_addr, *(const unsigned long*)src, data);
 
-                if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0, error))
+                if (NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0, error))
                 {
                     if (log)
                         ProcessPOSIXLog::DecNestLevel();
@@ -422,38 +341,9 @@ namespace
     }
 
     //------------------------------------------------------------------------------
-    /// @class Operation
-    /// @brief Represents a NativeProcessLinux operation.
-    ///
-    /// Under Linux, it is not possible to ptrace() from any other thread but the
-    /// one that spawned or attached to the process from the start.  Therefore, when
-    /// a NativeProcessLinux is asked to deliver or change the state of an inferior
-    /// process the operation must be "funneled" to a specific thread to perform the
-    /// task.  The Operation class provides an abstract base for all services the
-    /// NativeProcessLinux must perform via the single virtual function Execute, thus
-    /// encapsulating the code that needs to run in the privileged context.
-    class Operation
-    {
-    public:
-        Operation () : m_error() { }
-
-        virtual
-        ~Operation() {}
-
-        virtual void
-        Execute (NativeProcessLinux *process) = 0;
-
-        const Error &
-        GetError () const { return m_error; }
-
-    protected:
-        Error m_error;
-    };
-
-    //------------------------------------------------------------------------------
     /// @class ReadOperation
     /// @brief Implements NativeProcessLinux::ReadMemory.
-    class ReadOperation : public Operation
+    class ReadOperation : public NativeProcessLinux::Operation
     {
     public:
         ReadOperation(
@@ -487,7 +377,7 @@ namespace
     //------------------------------------------------------------------------------
     /// @class WriteOperation
     /// @brief Implements NativeProcessLinux::WriteMemory.
-    class WriteOperation : public Operation
+    class WriteOperation : public NativeProcessLinux::Operation
     {
     public:
         WriteOperation(
@@ -519,463 +409,9 @@ namespace
     }
 
     //------------------------------------------------------------------------------
-    /// @class ReadRegOperation
-    /// @brief Implements NativeProcessLinux::ReadRegisterValue.
-    class ReadRegOperation : public Operation
-    {
-    public:
-        ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name,
-                RegisterValue &value)
-            : m_tid(tid),
-              m_offset(static_cast<uintptr_t> (offset)),
-              m_reg_name(reg_name),
-              m_value(value)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        uintptr_t m_offset;
-        const char *m_reg_name;
-        RegisterValue &m_value;
-    };
-
-    void
-    ReadRegOperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        if (m_offset > sizeof(struct user_pt_regs))
-        {
-            uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
-            if (offset > sizeof(struct user_fpsimd_state))
-            {
-                m_error.SetErrorString("invalid offset value");
-                return;
-            }
-            elf_fpregset_t regs;
-            int regset = NT_FPREGSET;
-            struct iovec ioVec;
-
-            ioVec.iov_base = &regs;
-            ioVec.iov_len = sizeof regs;
-            PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            if (m_error.Success())
-            {
-                ArchSpec arch;
-                if (monitor->GetArchitecture(arch))
-                    m_value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
-                else
-                    m_error.SetErrorString("failed to get architecture");
-            }
-        }
-        else
-        {
-            elf_gregset_t regs;
-            int regset = NT_PRSTATUS;
-            struct iovec ioVec;
-
-            ioVec.iov_base = &regs;
-            ioVec.iov_len = sizeof regs;
-            PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            if (m_error.Success())
-            {
-                ArchSpec arch;
-                if (monitor->GetArchitecture(arch))
-                    m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
-                else
-                    m_error.SetErrorString("failed to get architecture");
-            }
-        }
-#elif defined (__mips__)
-        elf_gregset_t regs;
-        PTRACE(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
-        if (m_error.Success())
-        {
-            lldb_private::ArchSpec arch;
-            if (monitor->GetArchitecture(arch))
-                m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
-            else
-                m_error.SetErrorString("failed to get architecture");
-        }
-#else
-        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
-
-        lldb::addr_t data = static_cast<unsigned long>(PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, nullptr, 0, m_error));
-        if (m_error.Success())
-            m_value = data;
-
-        if (log)
-            log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__,
-                    m_reg_name, data);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class WriteRegOperation
-    /// @brief Implements NativeProcessLinux::WriteRegisterValue.
-    class WriteRegOperation : public Operation
-    {
-    public:
-        WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name,
-                const RegisterValue &value)
-            : m_tid(tid),
-              m_offset(offset),
-              m_reg_name(reg_name),
-              m_value(value)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        uintptr_t m_offset;
-        const char *m_reg_name;
-        const RegisterValue &m_value;
-    };
-
-    void
-    WriteRegOperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        if (m_offset > sizeof(struct user_pt_regs))
-        {
-            uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
-            if (offset > sizeof(struct user_fpsimd_state))
-            {
-                m_error.SetErrorString("invalid offset value");
-                return;
-            }
-            elf_fpregset_t regs;
-            int regset = NT_FPREGSET;
-            struct iovec ioVec;
-
-            ioVec.iov_base = &regs;
-            ioVec.iov_len = sizeof regs;
-            PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            if (m_error.Success())
-            {
-                ::memcpy((void *)(((unsigned char *)(&regs)) + offset), m_value.GetBytes(), 16);
-                PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            }
-        }
-        else
-        {
-            elf_gregset_t regs;
-            int regset = NT_PRSTATUS;
-            struct iovec ioVec;
-
-            ioVec.iov_base = &regs;
-            ioVec.iov_len = sizeof regs;
-            PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            if (m_error.Success())
-            {
-                ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
-                PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
-            }
-        }
-#elif defined (__mips__)
-        elf_gregset_t regs;
-        PTRACE(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
-        if (m_error.Success())
-        {
-            ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
-            PTRACE(PTRACE_SETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
-        }
-#else
-        void* buf;
-        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
-
-        buf = (void*) m_value.GetAsUInt64();
-
-        if (log)
-            log->Printf ("NativeProcessLinux::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf);
-        PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0, m_error);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class ReadGPROperation
-    /// @brief Implements NativeProcessLinux::ReadGPR.
-    class ReadGPROperation : public Operation
-    {
-    public:
-        ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
-            : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-    };
-
-    void
-    ReadGPROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        int regset = NT_PRSTATUS;
-        struct iovec ioVec;
-
-        ioVec.iov_base = m_buf;
-        ioVec.iov_len = m_buf_size;
-        PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
-#else
-        PTRACE(PTRACE_GETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class ReadFPROperation
-    /// @brief Implements NativeProcessLinux::ReadFPR.
-    class ReadFPROperation : public Operation
-    {
-    public:
-        ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
-            : m_tid(tid),
-              m_buf(buf),
-              m_buf_size(buf_size)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-    };
-
-    void
-    ReadFPROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        int regset = NT_FPREGSET;
-        struct iovec ioVec;
-
-        ioVec.iov_base = m_buf;
-        ioVec.iov_len = m_buf_size;
-        PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
-#else
-        PTRACE(PTRACE_GETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class ReadDBGROperation
-    /// @brief Implements NativeProcessLinux::ReadHardwareDebugInfo.
-    class ReadDBGROperation : public Operation
-    {
-    public:
-        ReadDBGROperation(lldb::tid_t tid, unsigned int &count_wp, unsigned int &count_bp)
-            : m_tid(tid),
-              m_count_wp(count_wp),
-              m_count_bp(count_bp)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        unsigned int &m_count_wp;
-        unsigned int &m_count_bp;
-    };
-
-    void
-    ReadDBGROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-       int regset = NT_ARM_HW_WATCH;
-       struct iovec ioVec;
-       struct user_hwdebug_state dreg_state;
-
-       ioVec.iov_base = &dreg_state;
-       ioVec.iov_len = sizeof (dreg_state);
-
-       PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
-
-       m_count_wp = dreg_state.dbg_info & 0xff;
-       regset = NT_ARM_HW_BREAK;
-
-       PTRACE(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
-       m_count_bp = dreg_state.dbg_info & 0xff;
-#endif
-    }
-
-
-    //------------------------------------------------------------------------------
-    /// @class ReadRegisterSetOperation
-    /// @brief Implements NativeProcessLinux::ReadRegisterSet.
-    class ReadRegisterSetOperation : public Operation
-    {
-    public:
-        ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-            : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-        const unsigned int m_regset;
-    };
-
-    void
-    ReadRegisterSetOperation::Execute(NativeProcessLinux *monitor)
-    {
-        PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error);
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class WriteGPROperation
-    /// @brief Implements NativeProcessLinux::WriteGPR.
-    class WriteGPROperation : public Operation
-    {
-    public:
-        WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
-            : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-    };
-
-    void
-    WriteGPROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        int regset = NT_PRSTATUS;
-        struct iovec ioVec;
-
-        ioVec.iov_base = m_buf;
-        ioVec.iov_len = m_buf_size;
-        PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
-#else
-        PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size, m_error);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class WriteFPROperation
-    /// @brief Implements NativeProcessLinux::WriteFPR.
-    class WriteFPROperation : public Operation
-    {
-    public:
-        WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
-            : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-    };
-
-    void
-    WriteFPROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        int regset = NT_FPREGSET;
-        struct iovec ioVec;
-
-        ioVec.iov_base = m_buf;
-        ioVec.iov_len = m_buf_size;
-        PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
-#else
-        PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size, m_error);
-#endif
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class WriteDBGROperation
-    /// @brief Implements NativeProcessLinux::WriteHardwareDebugRegs.
-    class WriteDBGROperation : public Operation
-    {
-    public:
-        WriteDBGROperation(lldb::tid_t tid, lldb::addr_t *addr_buf,
-                           uint32_t *cntrl_buf, int type, int count)
-            : m_tid(tid),
-              m_address(addr_buf),
-              m_control(cntrl_buf),
-              m_type(type),
-              m_count(count)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        lldb::addr_t * m_address;
-        uint32_t * m_control;
-        int m_type;
-        int m_count;
-    };
-
-    void
-    WriteDBGROperation::Execute(NativeProcessLinux *monitor)
-    {
-#if defined (__arm64__) || defined (__aarch64__)
-        struct iovec ioVec;
-        struct user_hwdebug_state dreg_state;
-
-        memset (&dreg_state, 0, sizeof (dreg_state));
-        ioVec.iov_base = &dreg_state;
-        ioVec.iov_len = sizeof (dreg_state);
-
-        if (m_type == 0)
-            m_type = NT_ARM_HW_WATCH;
-        else
-            m_type = NT_ARM_HW_BREAK;
-
-        for (int i = 0; i < m_count; i++)
-        {
-            dreg_state.dbg_regs[i].addr = m_address[i];
-            dreg_state.dbg_regs[i].ctrl = m_control[i];
-        }
-
-        PTRACE(PTRACE_SETREGSET, m_tid, &m_type, &ioVec, ioVec.iov_len, m_error);
-#endif
-    }
-
-
-    //------------------------------------------------------------------------------
-    /// @class WriteRegisterSetOperation
-    /// @brief Implements NativeProcessLinux::WriteRegisterSet.
-    class WriteRegisterSetOperation : public Operation
-    {
-    public:
-        WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-            : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset)
-            { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_buf;
-        size_t m_buf_size;
-        const unsigned int m_regset;
-    };
-
-    void
-    WriteRegisterSetOperation::Execute(NativeProcessLinux *monitor)
-    {
-        PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error);
-    }
-
-    //------------------------------------------------------------------------------
     /// @class ResumeOperation
     /// @brief Implements NativeProcessLinux::Resume.
-    class ResumeOperation : public Operation
+    class ResumeOperation : public NativeProcessLinux::Operation
     {
     public:
         ResumeOperation(lldb::tid_t tid, uint32_t signo) :
@@ -996,7 +432,7 @@ namespace
         if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
             data = m_signo;
 
-        PTRACE(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error);
         if (m_error.Fail())
         {
             Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -1009,7 +445,7 @@ namespace
     //------------------------------------------------------------------------------
     /// @class SingleStepOperation
     /// @brief Implements NativeProcessLinux::SingleStep.
-    class SingleStepOperation : public Operation
+    class SingleStepOperation : public NativeProcessLinux::Operation
     {
     public:
         SingleStepOperation(lldb::tid_t tid, uint32_t signo)
@@ -1030,13 +466,13 @@ namespace
         if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
             data = m_signo;
 
-        PTRACE(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error);
     }
 
     //------------------------------------------------------------------------------
     /// @class SiginfoOperation
     /// @brief Implements NativeProcessLinux::GetSignalInfo.
-    class SiginfoOperation : public Operation
+    class SiginfoOperation : public NativeProcessLinux::Operation
     {
     public:
         SiginfoOperation(lldb::tid_t tid, void *info)
@@ -1052,13 +488,13 @@ namespace
     void
     SiginfoOperation::Execute(NativeProcessLinux *monitor)
     {
-        PTRACE(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error);
     }
 
     //------------------------------------------------------------------------------
     /// @class EventMessageOperation
     /// @brief Implements NativeProcessLinux::GetEventMessage.
-    class EventMessageOperation : public Operation
+    class EventMessageOperation : public NativeProcessLinux::Operation
     {
     public:
         EventMessageOperation(lldb::tid_t tid, unsigned long *message)
@@ -1074,10 +510,10 @@ namespace
     void
     EventMessageOperation::Execute(NativeProcessLinux *monitor)
     {
-        PTRACE(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error);
     }
 
-    class DetachOperation : public Operation
+    class DetachOperation : public NativeProcessLinux::Operation
     {
     public:
         DetachOperation(lldb::tid_t tid) : m_tid(tid) { }
@@ -1091,7 +527,7 @@ namespace
     void
     DetachOperation::Execute(NativeProcessLinux *monitor)
     {
-        PTRACE(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error);
     }
 } // end of anonymous namespace
 
@@ -1833,7 +1269,7 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error)
         // send log info to parent re: launch status, in place of the log lines removed here.
 
         // Start tracing this child that is about to exec.
-        PTRACE(PTRACE_TRACEME, 0, nullptr, nullptr, 0, error);
+        NativeProcessLinux::PtraceWrapper(PTRACE_TRACEME, 0, nullptr, nullptr, 0, error);
         if (error.Fail())
             exit(ePtraceFailed);
 
@@ -2070,7 +1506,7 @@ NativeProcessLinux::Attach(lldb::pid_t pid, Error &error)
 
                 // Attach to the requested process.
                 // An attach will cause the thread to stop with a SIGSTOP.
-                PTRACE(PTRACE_ATTACH, tid, nullptr, nullptr, 0, error);
+                NativeProcessLinux::PtraceWrapper(PTRACE_ATTACH, tid, nullptr, nullptr, 0, error);
                 if (error.Fail())
                 {
                     // No such thread. The thread may have exited.
@@ -2162,7 +1598,7 @@ NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid)
     ptrace_opts |= PTRACE_O_TRACEEXEC;
 
     Error error;
-    PTRACE(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts, 0, error);
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts, 0, error);
     return error;
 }
 
@@ -3842,88 +3278,6 @@ NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
 }
 
 Error
-NativeProcessLinux::ReadRegisterValue(lldb::tid_t tid, uint32_t offset, const char* reg_name,
-                                      uint32_t size, RegisterValue &value)
-{
-    ReadRegOperation op(tid, offset, reg_name, value);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
-                                   const char* reg_name, const RegisterValue &value)
-{
-    WriteRegOperation op(tid, offset, reg_name, value);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
-    ReadGPROperation op(tid, buf, buf_size);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
-    ReadFPROperation op(tid, buf, buf_size);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
-    ReadRegisterSetOperation op(tid, buf, buf_size, regset);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::ReadHardwareDebugInfo (lldb::tid_t tid, unsigned int &watch_count , unsigned int &break_count)
-{
-    ReadDBGROperation op(tid, watch_count, break_count);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::WriteHardwareDebugRegs (lldb::tid_t tid, lldb::addr_t *addr_buf, uint32_t *cntrl_buf, int type, int count)
-{
-    WriteDBGROperation op(tid, addr_buf, cntrl_buf, type, count);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
-    WriteGPROperation op(tid, buf, buf_size);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
-{
-    WriteFPROperation op(tid, buf, buf_size);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
-NativeProcessLinux::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
-{
-    WriteRegisterSetOperation op(tid, buf, buf_size, regset);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
-}
-
-Error
 NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -4431,3 +3785,53 @@ NativeProcessLinux::ThreadWasCreated (lldb::tid_t tid)
         thread_sp->RequestStop();
     }
 }
+
+Error
+NativeProcessLinux::DoOperation(Operation* op)
+{
+    m_monitor_up->DoOperation(op);
+    return op->GetError();
+}
+
+// Wrapper for ptrace to catch errors and log calls.
+// Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
+long
+NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error)
+{
+    long int result;
+
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
+
+    PtraceDisplayBytes(req, data, data_size);
+
+    error.Clear();
+    errno = 0;
+    if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+        result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data);
+    else
+        result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data);
+
+    if (result == -1)
+        error.SetErrorToErrno();
+
+    if (log)
+        log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr, data, data_size, result);
+
+    PtraceDisplayBytes(req, data, data_size);
+
+    if (log && error.GetError() != 0)
+    {
+        const char* str;
+        switch (error.GetError())
+        {
+        case ESRCH:  str = "ESRCH"; break;
+        case EINVAL: str = "EINVAL"; break;
+        case EBUSY:  str = "EBUSY"; break;
+        case EPERM:  str = "EPERM"; break;
+        default:     str = error.AsCString();
+        }
+        log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str);
+    }
+
+    return result;
+}
index 57c598f..8e9c28d 100644 (file)
@@ -60,6 +60,37 @@ namespace process_linux {
             NativeProcessProtocol::NativeDelegate &native_delegate,
             NativeProcessProtocolSP &native_process_sp);
 
+        //------------------------------------------------------------------------------
+        /// @class Operation
+        /// @brief Represents a NativeProcessLinux operation.
+        ///
+        /// Under Linux, it is not possible to ptrace() from any other thread but the
+        /// one that spawned or attached to the process from the start.  Therefore, when
+        /// a NativeProcessLinux is asked to deliver or change the state of an inferior
+        /// process the operation must be "funneled" to a specific thread to perform the
+        /// task.  The Operation class provides an abstract base for all services the
+        /// NativeProcessLinux must perform via the single virtual function Execute, thus
+        /// encapsulating the code that needs to run in the privileged context.
+        class Operation
+        {
+        public:
+            Operation () : m_error() { }
+
+            virtual
+            ~Operation() {}
+
+            virtual void
+            Execute (NativeProcessLinux *process) = 0;
+
+            const Error &
+            GetError () const { return m_error; }
+
+        protected:
+            Error m_error;
+        };
+
+        typedef std::unique_ptr<Operation> OperationUP;
+
         // ---------------------------------------------------------------------
         // NativeProcessProtocol Interface
         // ---------------------------------------------------------------------
@@ -123,64 +154,20 @@ namespace process_linux {
         void
         Terminate () override;
 
+        Error
+        GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
+
         // ---------------------------------------------------------------------
         // Interface used by NativeRegisterContext-derived classes.
         // ---------------------------------------------------------------------
-
-        /// Reads the contents from the register identified by the given (architecture
-        /// dependent) offset.
-        ///
-        /// This method is provided for use by RegisterContextLinux derivatives.
-        Error
-        ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
-                          unsigned size, RegisterValue &value);
-
-        /// Writes the given value to the register identified by the given
-        /// (architecture dependent) offset.
-        ///
-        /// This method is provided for use by RegisterContextLinux derivatives.
         Error
-        WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
-                           const RegisterValue &value);
+        DoOperation(Operation* op);
 
-        /// Reads all general purpose registers into the specified buffer.
         Error
-        ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+        DoOperation(OperationUP op) { return DoOperation(op.get()); }
 
-        /// Reads generic floating point registers into the specified buffer.
-        Error
-        ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-        /// Reads hardware breakpoints and watchpoints capability information.
-        Error
-        ReadHardwareDebugInfo (lldb::tid_t tid, unsigned int &watch_count ,
-                               unsigned int &break_count);
-
-        /// Write hardware breakpoint/watchpoint control and address registers.
-        Error
-        WriteHardwareDebugRegs (lldb::tid_t tid, lldb::addr_t *addr_buf,
-                                uint32_t *cntrl_buf, int type, int count);
-
-        /// Reads the specified register set into the specified buffer.
-        /// For instance, the extended floating-point register set.
-        Error
-        ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
-        /// Writes all general purpose registers into the specified buffer.
-        Error
-        WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-        /// Writes generic floating point registers into the specified buffer.
-        Error
-        WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-        /// Writes the specified register set into the specified buffer.
-        /// For instance, the extended floating-point register set.
-        Error
-        WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-
-        Error
-        GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
+        static long
+        PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error);
 
     protected:
         // ---------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
new file mode 100644 (file)
index 0000000..8d99cda
--- /dev/null
@@ -0,0 +1,452 @@
+//===-- NativeRegisterContextLinux.cpp --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextLinux.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/Host/linux/Ptrace.h"
+
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+namespace
+{
+
+class ReadRegOperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, RegisterValue &value) :
+       m_tid(tid),
+        m_offset(static_cast<uintptr_t>(offset)),
+        m_reg_name(reg_name),
+        m_value(value)
+    { }
+
+    void
+    Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    uintptr_t m_offset;
+    const char *m_reg_name;
+    RegisterValue &m_value;
+};
+
+class WriteRegOperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) :
+       m_tid(tid),
+        m_offset(offset),
+        m_reg_name(reg_name),
+        m_value(value)
+    { }
+
+    void
+    Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    uintptr_t m_offset;
+    const char *m_reg_name;
+    const RegisterValue &m_value;
+};
+
+class ReadGPROperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+       m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class WriteGPROperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+       m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class ReadFPROperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+        m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class WriteFPROperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+        m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class ReadRegisterSetOperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) :
+        m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+    const unsigned int m_regset;
+};
+
+class WriteRegisterSetOperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) :
+        m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+    const unsigned int m_regset;
+};
+
+} // end of anonymous namespace
+
+void
+ReadRegOperation::Execute(NativeProcessLinux *monitor)
+{
+       Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+
+    lldb::addr_t data = static_cast<unsigned long>(NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSER, m_tid, (void*)m_offset, nullptr, 0, m_error));
+    if (m_error.Success())
+        m_value = data;
+
+    if (log)
+        log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__, m_reg_name, data);
+}
+
+void
+WriteRegOperation::Execute(NativeProcessLinux *monitor)
+{
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+
+    void* buf = (void*)m_value.GetAsUInt64();
+
+    if (log)
+        log->Printf ("NativeProcessLinux::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf);
+    NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0, m_error);
+}
+
+void
+ReadGPROperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
+}
+
+void
+WriteGPROperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
+}
+
+void
+ReadFPROperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
+}
+
+void
+WriteFPROperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error);
+}
+
+void
+ReadRegisterSetOperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error);
+}
+
+void
+WriteRegisterSetOperation::Execute(NativeProcessLinux *monitor)
+{
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error);
+}
+
+NativeRegisterContextLinux::NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
+                                                       uint32_t concrete_frame_idx,
+                                                       RegisterInfoInterface *reg_info_interface_p) :
+       NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx, reg_info_interface_p)
+{}
+
+lldb::ByteOrder
+NativeRegisterContextLinux::GetByteOrder() const
+{
+    // Get the target process whose privileged thread was used for the register read.
+    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return byte_order;
+
+    if (!process_sp->GetByteOrder (byte_order))
+    {
+        // FIXME log here
+    }
+
+    return byte_order;
+}
+
+Error
+NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value)
+{
+    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
+    if (!reg_info)
+       return Error("register %" PRIu32 " not found", reg_index);
+
+    NativeProcessProtocolSP process_sp(m_thread.GetProcess());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+    return process_p->DoOperation(GetReadRegisterValueOperation(reg_info->byte_offset,
+                                                                reg_info->name,
+                                                                reg_info->byte_size,
+                                                                reg_value));
+}
+
+Error
+NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index, const RegisterValue &reg_value)
+{
+    uint32_t reg_to_write = reg_index;
+    RegisterValue value_to_write = reg_value;
+
+    // Check if this is a subregister of a full register.
+    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
+    if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
+    {
+               Error error;
+
+        RegisterValue full_value;
+        uint32_t full_reg = reg_info->invalidate_regs[0];
+        const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+        // Read the full register.
+        error = ReadRegister(full_reg_info, full_value);
+        if (error.Fail ())
+            return error;
+
+        lldb::ByteOrder byte_order = GetByteOrder();
+        uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+        // Get the bytes for the full register.
+        const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
+                                                               dst,
+                                                               sizeof(dst),
+                                                               byte_order,
+                                                               error);
+        if (error.Success() && dest_size)
+        {
+            uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+            // Get the bytes for the source data.
+            const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
+            if (error.Success() && src_size && (src_size < dest_size))
+            {
+                // Copy the src bytes to the destination.
+                memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
+                // Set this full register as the value to write.
+                value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+                value_to_write.SetType(full_reg_info);
+                reg_to_write = full_reg;
+            }
+        }
+    }
+
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+           return Error("NativeProcessProtocol is NULL");
+
+    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
+    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
+    if (!register_to_write_info_p)
+        return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
+    return process_p->DoOperation(GetWriteRegisterValueOperation(reg_info->byte_offset,
+                                                                 reg_info->name,
+                                                                 reg_value));
+}
+
+Error
+NativeRegisterContextLinux::ReadGPR()
+{
+       NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+
+    void* buf = GetGPRBuffer();
+    if (!buf)
+       return Error("GPR buffer is NULL");
+    size_t buf_size = GetGPRSize();
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+    return process_p->DoOperation(GetReadGPROperation(buf, buf_size));
+}
+
+Error
+NativeRegisterContextLinux::WriteGPR()
+{
+       NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+
+    void* buf = GetGPRBuffer();
+    if (!buf)
+       return Error("GPR buffer is NULL");
+    size_t buf_size = GetGPRSize();
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+    return process_p->DoOperation(GetWriteGPROperation(buf, buf_size));
+}
+
+Error
+NativeRegisterContextLinux::ReadFPR()
+{
+       NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+
+    void* buf = GetFPRBuffer();
+    if (!buf)
+       return Error("GPR buffer is NULL");
+    size_t buf_size = GetFPRSize();
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+    return process_p->DoOperation(GetReadFPROperation(buf, buf_size));
+}
+
+Error
+NativeRegisterContextLinux::WriteFPR()
+{
+       NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+
+    void* buf = GetFPRBuffer();
+    if (!buf)
+       return Error("GPR buffer is NULL");
+    size_t buf_size = GetFPRSize();
+
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+    return process_p->DoOperation(GetWriteFPROperation(buf, buf_size));
+}
+
+Error
+NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset)
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+
+    ReadRegisterSetOperation op(m_thread.GetID(), buf, buf_size, regset);
+    return process_p->DoOperation(&op);
+}
+
+Error
+NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset)
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
+
+    WriteRegisterSetOperation op(m_thread.GetID(), buf, buf_size, regset);
+    return process_p->DoOperation(&op);
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetReadRegisterValueOperation(uint32_t offset,
+                                                          const char* reg_name,
+                                                             uint32_t size,
+                                                             RegisterValue &value)
+{
+       return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetWriteRegisterValueOperation(uint32_t offset,
+                                                           const char* reg_name,
+                                                              const RegisterValue &value)
+{
+       return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetReadGPROperation(void *buf, size_t buf_size)
+{
+       return NativeProcessLinux::OperationUP(new ReadGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetWriteGPROperation(void *buf, size_t buf_size)
+{
+       return NativeProcessLinux::OperationUP(new WriteGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetReadFPROperation(void *buf, size_t buf_size)
+{
+       return NativeProcessLinux::OperationUP(new ReadFPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux::GetWriteFPROperation(void *buf, size_t buf_size)
+{
+       return NativeProcessLinux::OperationUP(new WriteFPROperation(m_thread.GetID(), buf, buf_size));
+}
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
new file mode 100644 (file)
index 0000000..d63a073
--- /dev/null
@@ -0,0 +1,105 @@
+//===-- NativeRegisterContextLinux.h ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextLinux_h
+#define lldb_NativeRegisterContextLinux_h
+
+#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+
+namespace lldb_private {
+namespace process_linux {
+
+class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo
+{
+public:
+    NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
+                               uint32_t concrete_frame_idx,
+                               RegisterInfoInterface *reg_info_interface_p);
+
+    // This function is implemented in the NativeRegisterContextLinux_* subclasses to create a new
+    // instance of the host specific NativeRegisterContextLinux. The implementations can't collide
+    // as only one NativeRegisterContextLinux_* variant should be compiled into the final
+    // executable.
+    static NativeRegisterContextLinux*
+    CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+                                         NativeThreadProtocol &native_thread,
+                                         uint32_t concrete_frame_idx);
+
+protected:
+    lldb::ByteOrder
+    GetByteOrder() const;
+
+    virtual Error
+    ReadRegisterRaw(uint32_t reg_index, RegisterValue& reg_value);
+
+    virtual Error
+    WriteRegisterRaw(uint32_t reg_index, const RegisterValue& reg_value);
+
+    virtual Error
+    ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+
+    virtual Error
+    WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset);
+
+    virtual Error
+    ReadGPR();
+
+    virtual Error
+    WriteGPR();
+
+    virtual Error
+    ReadFPR();
+
+    virtual Error
+    WriteFPR();
+
+    virtual void*
+    GetGPRBuffer() { return nullptr; };
+
+    virtual size_t
+    GetGPRSize() { return GetRegisterInfoInterface().GetGPRSize(); }
+
+    virtual void*
+    GetFPRBuffer() { return nullptr; }
+
+    virtual size_t
+    GetFPRSize() { return 0; }
+
+    virtual NativeProcessLinux::OperationUP
+    GetReadRegisterValueOperation(uint32_t offset,
+                                  const char* reg_name,
+                                  uint32_t size,
+                                  RegisterValue &value);
+
+    virtual NativeProcessLinux::OperationUP
+    GetWriteRegisterValueOperation(uint32_t offset,
+                                   const char* reg_name,
+                                   const RegisterValue &value);
+
+    virtual NativeProcessLinux::OperationUP
+    GetReadGPROperation(void *buf, size_t buf_size);
+
+    virtual NativeProcessLinux::OperationUP
+    GetWriteGPROperation(void *buf, size_t buf_size);
+
+    virtual NativeProcessLinux::OperationUP
+    GetReadFPROperation(void *buf, size_t buf_size);
+
+    virtual NativeProcessLinux::OperationUP
+    GetWriteFPROperation(void *buf, size_t buf_size);
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_h
+
index 670b2f8..a2db613 100644 (file)
@@ -7,15 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__arm__)
+
 #include "NativeRegisterContextLinux_arm.h"
 
-#include "lldb/lldb-private-forward.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
+
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
 
 #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
 
@@ -105,13 +105,20 @@ g_reg_sets_arm[k_num_register_sets] =
     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
 };
 
-NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (
-        NativeThreadProtocol &native_thread,
-        uint32_t concrete_frame_idx,
-        RegisterInfoInterface *reg_info_interface_p) :
-    NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+                                                                 NativeThreadProtocol &native_thread,
+                                                                 uint32_t concrete_frame_idx)
+{
+    return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
+}
+
+NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
+                                                                NativeThreadProtocol &native_thread,
+                                                                uint32_t concrete_frame_idx) :
+    NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm(target_arch))
 {
-    switch (reg_info_interface_p->m_target_arch.GetMachine())
+    switch (target_arch.GetMachine())
     {
         case llvm::Triple::arm:
             m_reg_info.num_registers     = k_num_registers_arm;
@@ -172,11 +179,9 @@ NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, Regi
 
     if (IsFPR(reg))
     {
-        if (!ReadFPR())
-        {
-            error.SetErrorString ("failed to read floating point register");
+        error = ReadFPR();
+        if (error.Fail())
             return error;
-        }
     }
     else
     {
@@ -262,10 +267,9 @@ NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, con
                 return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
         }
 
-        if (!WriteFPR())
-        {
-            return Error ("NativeRegisterContextLinux_arm::WriteRegister: WriteFPR failed");
-        }
+        Error error = WriteFPR();
+        if (error.Fail())
+            return error;
 
         return Error ();
     }
@@ -282,17 +286,13 @@ NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_
     if (!data_sp)
         return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE);
 
-    if (!ReadGPR ())
-    {
-        error.SetErrorString ("ReadGPR() failed");
+    error = ReadGPR();
+    if (error.Fail())
         return error;
-    }
 
-    if (!ReadFPR ())
-    {
-        error.SetErrorString ("ReadFPR() failed");
+    error = ReadFPR();
+    if (error.Fail())
         return error;
-    }
 
     uint8_t *dst = data_sp->GetBytes ();
     if (dst == nullptr)
@@ -334,120 +334,20 @@ NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP
     }
     ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ());
 
-    if (!WriteGPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+    error = WriteGPR();
+    if (error.Fail())
         return error;
-    }
 
     src += GetRegisterInfoInterface ().GetGPRSize ();
     ::memcpy (&m_fpr, src, sizeof(m_fpr));
 
-    if (!WriteFPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+    error = WriteFPR();
+    if (error.Fail())
         return error;
-    }
 
     return error;
 }
 
-Error
-NativeRegisterContextLinux_arm::WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value)
-{
-    Error error;
-
-    uint32_t reg_to_write = reg_index;
-    RegisterValue value_to_write = reg_value;
-
-    // Check if this is a subregister of a full register.
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
-    if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
-    {
-        RegisterValue full_value;
-        uint32_t full_reg = reg_info->invalidate_regs[0];
-        const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-        // Read the full register.
-        error = ReadRegister(full_reg_info, full_value);
-        if (error.Fail ())
-            return error;
-
-        lldb::ByteOrder byte_order = GetByteOrder();
-        uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the full register.
-        const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
-                                                               dst,
-                                                               sizeof(dst),
-                                                               byte_order,
-                                                               error);
-        if (error.Success() && dest_size)
-        {
-            uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-            // Get the bytes for the source data.
-            const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
-            if (error.Success() && src_size && (src_size < dest_size))
-            {
-                // Copy the src bytes to the destination.
-                memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
-                // Set this full register as the value to write.
-                value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-                value_to_write.SetType(full_reg_info);
-                reg_to_write = full_reg;
-            }
-        }
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
-    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
-    if (!register_to_write_info_p)
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_arm::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteRegisterValue(m_thread.GetID(),
-                                         register_to_write_info_p->byte_offset,
-                                         register_to_write_info_p->name,
-                                         value_to_write);
-}
-
-Error
-NativeRegisterContextLinux_arm::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
-    Error error;
-    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
-    if (!reg_info)
-    {
-        error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
-        return error;
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadRegisterValue(m_thread.GetID(),
-                                        reg_info->byte_offset,
-                                        reg_info->name,
-                                        reg_info->byte_size,
-                                        reg_value);
-}
-
 bool
 NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
 {
@@ -455,75 +355,9 @@ NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
 }
 
 bool
-NativeRegisterContextLinux_arm::ReadGPR()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->ReadGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm::WriteGPR()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->WriteGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
 NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const
 {
     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
 }
 
-bool
-NativeRegisterContextLinux_arm::ReadFPR ()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm::WriteFPR ()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-lldb::ByteOrder
-NativeRegisterContextLinux_arm::GetByteOrder() const
-{
-    // Get the target process whose privileged thread was used for the register read.
-    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return byte_order;
-
-    if (!process_sp->GetByteOrder (byte_order))
-    {
-        // FIXME log here
-    }
-
-    return byte_order;
-}
-
-size_t
-NativeRegisterContextLinux_arm::GetGPRSize() const
-{
-    return GetRegisterInfoInterface().GetGPRSize();
-}
+#endif // defined(__arm__)
index d96cec6..0d23528 100644 (file)
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__arm__) // arm register context only needed on arm devices
 
 #ifndef lldb_NativeRegisterContextLinux_arm_h
 #define lldb_NativeRegisterContextLinux_arm_h
 
-#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
 #include "Plugins/Process/Utility/lldb-arm-register-enums.h"
 
 namespace lldb_private {
@@ -19,10 +20,12 @@ namespace process_linux {
 
     class NativeProcessLinux;
 
-    class NativeRegisterContextLinux_arm : public NativeRegisterContextRegisterInfo
+    class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux
     {
     public:
-        NativeRegisterContextLinux_arm (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);
+        NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
+                                        NativeThreadProtocol &native_thread,
+                                        uint32_t concrete_frame_idx);
 
         uint32_t
         GetRegisterSetCount () const override;
@@ -45,6 +48,16 @@ namespace process_linux {
         Error
         WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
 
+    protected:
+        void*
+        GetGPRBuffer() override { return &m_gpr_arm; }
+
+        void*
+        GetFPRBuffer() override { return &m_fpr; }
+
+        size_t
+        GetFPRSize() override { return sizeof(m_fpr); }
+
     private:
         struct RegInfo
         {
@@ -85,31 +98,7 @@ namespace process_linux {
         IsGPR(unsigned reg) const;
 
         bool
-        ReadGPR ();
-
-        bool
-        WriteGPR ();
-
-        bool
         IsFPR(unsigned reg) const;
-
-        bool
-        ReadFPR ();
-
-        bool
-        WriteFPR ();
-
-        Error
-        ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
-
-        Error
-        WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value);
-
-        lldb::ByteOrder
-        GetByteOrder() const;
-
-        size_t
-        GetGPRSize() const;
     };
 
 } // namespace process_linux
@@ -117,3 +106,4 @@ namespace process_linux {
 
 #endif // #ifndef lldb_NativeRegisterContextLinux_arm_h
 
+#endif // defined(__arm__)
index aef1ae9..ea6d6c3 100644 (file)
@@ -7,19 +7,31 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined (__arm64__) || defined (__aarch64__)
+
 #include "NativeRegisterContextLinux_arm64.h"
 
-#include "lldb/lldb-private-forward.h"
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
+
 #include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "lldb/Core/Log.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
+
+// System includes - They have to be included after framework includes because they define some
+// macros which collide with variable names in other modules
+#include <sys/socket.h>
+// NT_PRSTATUS and NT_FPREGSET definition
+#include <elf.h>
 
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
+#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
 
 using namespace lldb;
 using namespace lldb_private;
@@ -125,13 +137,341 @@ g_reg_sets_arm64[k_num_register_sets] =
     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
 };
 
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (
-        NativeThreadProtocol &native_thread,
-        uint32_t concrete_frame_idx,
-        RegisterInfoInterface *reg_info_interface_p) :
-    NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
+namespace
+{
+
+class ReadRegOperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, RegisterValue &value) :
+        m_tid(tid),
+        m_offset(static_cast<uintptr_t>(offset)),
+        m_reg_name(reg_name),
+        m_value(value)
+    { }
+
+    void
+    Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    uintptr_t m_offset;
+    const char *m_reg_name;
+    RegisterValue &m_value;
+};
+
+class WriteRegOperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) :
+        m_tid(tid),
+        m_offset(offset),
+        m_reg_name(reg_name),
+        m_value(value)
+    { }
+
+    void
+    Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    uintptr_t m_offset;
+    const char *m_reg_name;
+    const RegisterValue &m_value;
+};
+
+class ReadGPROperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+        : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+        { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class WriteGPROperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) :
+        m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+    { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class ReadFPROperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+        : m_tid(tid),
+          m_buf(buf),
+          m_buf_size(buf_size)
+        { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class WriteFPROperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size)
+        : m_tid(tid), m_buf(buf), m_buf_size(buf_size)
+        { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+};
+
+class ReadDBGROperation : public NativeProcessLinux::Operation
+{
+public:
+    ReadDBGROperation(lldb::tid_t tid, unsigned int &count_wp, unsigned int &count_bp)
+        : m_tid(tid),
+          m_count_wp(count_wp),
+          m_count_bp(count_bp)
+        { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    unsigned int &m_count_wp;
+    unsigned int &m_count_bp;
+};
+
+class WriteDBGROperation : public NativeProcessLinux::Operation
+{
+public:
+    WriteDBGROperation(lldb::tid_t tid, lldb::addr_t *addr_buf,
+                       uint32_t *cntrl_buf, int type, int count)
+        : m_tid(tid),
+          m_address(addr_buf),
+          m_control(cntrl_buf),
+          m_type(type),
+          m_count(count)
+        { }
+
+    void Execute(NativeProcessLinux *monitor) override;
+
+private:
+    lldb::tid_t m_tid;
+    lldb::addr_t * m_address;
+    uint32_t * m_control;
+    int m_type;
+    int m_count;
+};
+
+} // end of anonymous namespace
+
+void
+ReadRegOperation::Execute(NativeProcessLinux *monitor)
+{
+    if (m_offset > sizeof(struct user_pt_regs))
+    {
+        uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
+        if (offset > sizeof(struct user_fpsimd_state))
+        {
+            m_error.SetErrorString("invalid offset value");
+            return;
+        }
+        elf_fpregset_t regs;
+        int regset = NT_FPREGSET;
+        struct iovec ioVec;
+
+        ioVec.iov_base = &regs;
+        ioVec.iov_len = sizeof regs;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        if (m_error.Success())
+        {
+            ArchSpec arch;
+            if (monitor->GetArchitecture(arch))
+                m_value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
+            else
+                m_error.SetErrorString("failed to get architecture");
+        }
+    }
+    else
+    {
+        elf_gregset_t regs;
+        int regset = NT_PRSTATUS;
+        struct iovec ioVec;
+
+        ioVec.iov_base = &regs;
+        ioVec.iov_len = sizeof regs;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        if (m_error.Success())
+        {
+            ArchSpec arch;
+            if (monitor->GetArchitecture(arch))
+                m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
+            else
+                m_error.SetErrorString("failed to get architecture");
+        }
+    }
+}
+
+void
+WriteRegOperation::Execute(NativeProcessLinux *monitor)
+{
+    if (m_offset > sizeof(struct user_pt_regs))
+    {
+        uintptr_t offset = m_offset - sizeof(struct user_pt_regs);
+        if (offset > sizeof(struct user_fpsimd_state))
+        {
+            m_error.SetErrorString("invalid offset value");
+            return;
+        }
+        elf_fpregset_t regs;
+        int regset = NT_FPREGSET;
+        struct iovec ioVec;
+
+        ioVec.iov_base = &regs;
+        ioVec.iov_len = sizeof regs;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        if (m_error.Success())
+        {
+            ::memcpy((void *)(((unsigned char *)(&regs)) + offset), m_value.GetBytes(), 16);
+            NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        }
+    }
+    else
+    {
+        elf_gregset_t regs;
+        int regset = NT_PRSTATUS;
+        struct iovec ioVec;
+
+        ioVec.iov_base = &regs;
+        ioVec.iov_len = sizeof regs;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        if (m_error.Success())
+        {
+            ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
+            NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs, m_error);
+        }
+    }
+}
+
+void
+ReadGPROperation::Execute(NativeProcessLinux *monitor)
+{
+    int regset = NT_PRSTATUS;
+    struct iovec ioVec;
+
+    ioVec.iov_base = m_buf;
+    ioVec.iov_len = m_buf_size;
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+WriteGPROperation::Execute(NativeProcessLinux *monitor)
+{
+    int regset = NT_PRSTATUS;
+    struct iovec ioVec;
+
+    ioVec.iov_base = m_buf;
+    ioVec.iov_len = m_buf_size;
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+ReadFPROperation::Execute(NativeProcessLinux *monitor)
+{
+    int regset = NT_FPREGSET;
+    struct iovec ioVec;
+
+    ioVec.iov_base = m_buf;
+    ioVec.iov_len = m_buf_size;
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+WriteFPROperation::Execute(NativeProcessLinux *monitor)
 {
-    switch (reg_info_interface_p->m_target_arch.GetMachine())
+    int regset = NT_FPREGSET;
+    struct iovec ioVec;
+
+    ioVec.iov_base = m_buf;
+    ioVec.iov_len = m_buf_size;
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &regset, &ioVec, m_buf_size, m_error);
+}
+
+void
+ReadDBGROperation::Execute(NativeProcessLinux *monitor)
+{
+   int regset = NT_ARM_HW_WATCH;
+   struct iovec ioVec;
+   struct user_hwdebug_state dreg_state;
+
+   ioVec.iov_base = &dreg_state;
+   ioVec.iov_len = sizeof (dreg_state);
+
+   NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
+
+   m_count_wp = dreg_state.dbg_info & 0xff;
+   regset = NT_ARM_HW_BREAK;
+
+   NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_tid, &regset, &ioVec, ioVec.iov_len, m_error);
+   m_count_bp = dreg_state.dbg_info & 0xff;
+}
+
+void
+WriteDBGROperation::Execute(NativeProcessLinux *monitor)
+{
+    struct iovec ioVec;
+    struct user_hwdebug_state dreg_state;
+
+    memset (&dreg_state, 0, sizeof (dreg_state));
+    ioVec.iov_base = &dreg_state;
+    ioVec.iov_len = sizeof (dreg_state);
+
+    if (m_type == 0)
+        m_type = NT_ARM_HW_WATCH;
+    else
+        m_type = NT_ARM_HW_BREAK;
+
+    for (int i = 0; i < m_count; i++)
+    {
+        dreg_state.dbg_regs[i].addr = m_address[i];
+        dreg_state.dbg_regs[i].ctrl = m_control[i];
+    }
+
+    NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_tid, &m_type, &ioVec, ioVec.iov_len, m_error);
+}
+
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+                                                                 NativeThreadProtocol &native_thread,
+                                                                 uint32_t concrete_frame_idx)
+{
+    return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx);
+}
+
+NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
+                                                                    NativeThreadProtocol &native_thread,
+                                                                    uint32_t concrete_frame_idx) :
+    NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm64(target_arch))
+{
+    switch (target_arch.GetMachine())
     {
         case llvm::Triple::aarch64:
             m_reg_info.num_registers     = k_num_registers_arm64;
@@ -189,11 +529,9 @@ NativeRegisterContextLinux_arm64::ReadRegister (const RegisterInfo *reg_info, Re
 
     if (IsFPR(reg))
     {
-        if (!ReadFPR())
-        {
-            error.SetErrorString ("failed to read floating point register");
+        error = ReadFPR();
+        if (error.Fail())
             return error;
-        }
     }
     else
     {
@@ -279,10 +617,9 @@ NativeRegisterContextLinux_arm64::WriteRegister (const RegisterInfo *reg_info, c
                 return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
         }
 
-        if (!WriteFPR())
-        {
-            return Error ("NativeRegisterContextLinux_arm64::WriteRegister: WriteFPR failed");
-        }
+        Error error = WriteFPR();
+        if (error.Fail())
+            return error;
 
         return Error ();
     }
@@ -299,17 +636,13 @@ NativeRegisterContextLinux_arm64::ReadAllRegisterValues (lldb::DataBufferSP &dat
     if (!data_sp)
         return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
 
-    if (!ReadGPR ())
-    {
-        error.SetErrorString ("ReadGPR() failed");
+    error = ReadGPR();
+    if (error.Fail())
         return error;
-    }
 
-    if (!ReadFPR ())
-    {
-        error.SetErrorString ("ReadFPR() failed");
+    error = ReadFPR();
+    if (error.Fail())
         return error;
-    }
 
     uint8_t *dst = data_sp->GetBytes ();
     if (dst == nullptr)
@@ -351,120 +684,20 @@ NativeRegisterContextLinux_arm64::WriteAllRegisterValues (const lldb::DataBuffer
     }
     ::memcpy (&m_gpr_arm64, src, GetRegisterInfoInterface ().GetGPRSize ());
 
-    if (!WriteGPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+    error = WriteGPR();
+    if (error.Fail())
         return error;
-    }
 
     src += GetRegisterInfoInterface ().GetGPRSize ();
     ::memcpy (&m_fpr, src, sizeof(m_fpr));
 
-    if (!WriteFPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+    error = WriteFPR();
+    if (error.Fail())
         return error;
-    }
 
     return error;
 }
 
-Error
-NativeRegisterContextLinux_arm64::WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value)
-{
-    Error error;
-
-    uint32_t reg_to_write = reg_index;
-    RegisterValue value_to_write = reg_value;
-
-    // Check if this is a subregister of a full register.
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
-    if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
-    {
-        RegisterValue full_value;
-        uint32_t full_reg = reg_info->invalidate_regs[0];
-        const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-        // Read the full register.
-        error = ReadRegister(full_reg_info, full_value);
-        if (error.Fail ())
-            return error;
-
-        lldb::ByteOrder byte_order = GetByteOrder();
-        uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the full register.
-        const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
-                                                               dst,
-                                                               sizeof(dst),
-                                                               byte_order,
-                                                               error);
-        if (error.Success() && dest_size)
-        {
-            uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-            // Get the bytes for the source data.
-            const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
-            if (error.Success() && src_size && (src_size < dest_size))
-            {
-                // Copy the src bytes to the destination.
-                memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
-                // Set this full register as the value to write.
-                value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-                value_to_write.SetType(full_reg_info);
-                reg_to_write = full_reg;
-            }
-        }
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
-    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
-    if (!register_to_write_info_p)
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_arm64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteRegisterValue(m_thread.GetID(),
-                                         register_to_write_info_p->byte_offset,
-                                         register_to_write_info_p->name,
-                                         value_to_write);
-}
-
-Error
-NativeRegisterContextLinux_arm64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
-    Error error;
-    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
-    if (!reg_info)
-    {
-        error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
-        return error;
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadRegisterValue(m_thread.GetID(),
-                                        reg_info->byte_offset,
-                                        reg_info->name,
-                                        reg_info->byte_size,
-                                        reg_value);
-}
-
 bool
 NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
 {
@@ -472,79 +705,11 @@ NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const
 }
 
 bool
-NativeRegisterContextLinux_arm64::ReadGPR()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->ReadGPR (m_thread.GetID (), &m_gpr_arm64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm64::WriteGPR()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->WriteGPR (m_thread.GetID (), &m_gpr_arm64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
-}
-
-bool
 NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const
 {
     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
 }
 
-bool
-NativeRegisterContextLinux_arm64::ReadFPR ()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-bool
-NativeRegisterContextLinux_arm64::WriteFPR ()
-{
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success();
-}
-
-lldb::ByteOrder
-NativeRegisterContextLinux_arm64::GetByteOrder() const
-{
-    // Get the target process whose privileged thread was used for the register read.
-    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return byte_order;
-
-    if (!process_sp->GetByteOrder (byte_order))
-    {
-        // FIXME log here
-    }
-
-    return byte_order;
-}
-
-size_t
-NativeRegisterContextLinux_arm64::GetGPRSize() const
-{
-    return GetRegisterInfoInterface().GetGPRSize();
-}
-
 uint32_t
 NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
 {
@@ -557,12 +722,10 @@ NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size
     if (!process_sp)
         return false;
 
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
     // Check if our hardware breakpoint and watchpoint information is updated.
     if (m_refresh_hwdebug_info)
     {
-        process_p->ReadHardwareDebugInfo (m_thread.GetID (), m_max_hwp_supported,
-                                          m_max_hbp_supported);
+        ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
         m_refresh_hwdebug_info = false;
     }
 
@@ -668,12 +831,11 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
     if (!process_sp)
         return false;
 
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
+    
     // Check if our hardware breakpoint and watchpoint information is updated.
     if (m_refresh_hwdebug_info)
     {
-        process_p->ReadHardwareDebugInfo (m_thread.GetID (), m_max_hwp_supported,
-                                          m_max_hbp_supported);
+        ReadHardwareDebugInfo (m_max_hwp_supported, m_max_hbp_supported);
         m_refresh_hwdebug_info = false;
     }
                
@@ -724,8 +886,7 @@ NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size
         m_hwp_regs[wp_index].refcount = 1;
 
         // PTRACE call to set corresponding watchpoint register.
-        process_p->WriteHardwareDebugRegs(m_thread.GetID (), &addr,
-                                          &control_value, 0, wp_index);
+        WriteHardwareDebugRegs(&addr, &control_value, 0, wp_index);
     }
     else
         m_hwp_regs[wp_index].refcount++;
@@ -745,8 +906,6 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
     if (!process_sp)
         return false;
 
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
     if (wp_index >= m_max_hwp_supported)
         return false;
 
@@ -763,10 +922,7 @@ NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index)
         m_hwp_regs[wp_index].refcount = 0;
 
         //TODO: PTRACE CALL HERE for an UPDATE
-        process_p->WriteHardwareDebugRegs(m_thread.GetID (),
-                                          &m_hwp_regs[wp_index].address,
-                                          &m_hwp_regs[wp_index].control,
-                                          0, wp_index);
+        WriteHardwareDebugRegs(&m_hwp_regs[wp_index].address, &m_hwp_regs[wp_index].control, 0, wp_index);
         return true;
     }
 
@@ -788,8 +944,6 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
     if (!process_sp)
         return ml_error;
 
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
     {
         if (m_hwp_regs[i].control & 0x01)
@@ -798,10 +952,7 @@ NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints ()
             m_hwp_regs[i].address = 0;
             m_hwp_regs[i].refcount = 0;
 
-            process_p->WriteHardwareDebugRegs(m_thread.GetID (),
-                                          &m_hwp_regs[i].address,
-                                          &m_hwp_regs[i].control,
-                                          0, i);
+            WriteHardwareDebugRegs(&m_hwp_regs[i].address, &m_hwp_regs[i].control, 0, i);
         }
     }
 
@@ -887,13 +1038,73 @@ NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index)
         return LLDB_INVALID_ADDRESS;
 }
 
-bool
-NativeRegisterContextLinux_arm64::HardwareSingleStep (bool enable)
+Error
+NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo(unsigned int &watch_count,
+                                                        unsigned int &break_count)
 {
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
 
-    if (log)
-        log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
+    ReadDBGROperation op(m_thread.GetID(), watch_count, break_count);
+    return process_p->DoOperation(&op);
+}
 
-    return false;
+Error
+NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(lldb::addr_t *addr_buf,
+                                                         uint32_t *cntrl_buf,
+                                                         int type,
+                                                         int count)
+{
+    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
+    if (!process_sp)
+        return Error("NativeProcessProtocol is NULL");
+    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
+
+    WriteDBGROperation op(m_thread.GetID(), addr_buf, cntrl_buf, type, count);
+    return process_p->DoOperation(&op);
 }
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadRegisterValueOperation(uint32_t offset,
+                                                                const char* reg_name,
+                                                                uint32_t size,
+                                                                RegisterValue &value)
+{
+    return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteRegisterValueOperation(uint32_t offset,
+                                                                 const char* reg_name,
+                                                                 const RegisterValue &value)
+{
+    return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadGPROperation(void *buf, size_t buf_size)
+{
+    return NativeProcessLinux::OperationUP(new ReadGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteGPROperation(void *buf, size_t buf_size)
+{
+    return NativeProcessLinux::OperationUP(new WriteGPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetReadFPROperation(void *buf, size_t buf_size)
+{
+    return NativeProcessLinux::OperationUP(new ReadFPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_arm64::GetWriteFPROperation(void *buf, size_t buf_size)
+{
+    return NativeProcessLinux::OperationUP(new WriteFPROperation(m_thread.GetID(), buf, buf_size));
+}
+
+#endif // defined (__arm64__) || defined (__aarch64__)
index 49389c2..ff925cd 100644 (file)
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined (__arm64__) || defined (__aarch64__)
 
 #ifndef lldb_NativeRegisterContextLinux_arm64_h
 #define lldb_NativeRegisterContextLinux_arm64_h
 
-#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
 #include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
 
 namespace lldb_private {
@@ -19,12 +20,12 @@ namespace process_linux {
 
     class NativeProcessLinux;
 
-    class NativeRegisterContextLinux_arm64 : public NativeRegisterContextRegisterInfo
+    class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux
     {
     public:
-        NativeRegisterContextLinux_arm64 (NativeThreadProtocol &native_thread,
-                                          uint32_t concrete_frame_idx,
-                                          RegisterInfoInterface *reg_info_interface_p);
+        NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
+                                          NativeThreadProtocol &native_thread,
+                                          uint32_t concrete_frame_idx);
 
         uint32_t
         GetRegisterSetCount () const override;
@@ -72,15 +73,45 @@ namespace process_linux {
         lldb::addr_t
         GetWatchpointAddress (uint32_t wp_index) override;
 
-        bool
-        HardwareSingleStep (bool enable) override;
-
         uint32_t
         GetWatchpointSize(uint32_t wp_index);
 
         bool
         WatchpointIsEnabled(uint32_t wp_index);
 
+    protected:
+        NativeProcessLinux::OperationUP
+        GetReadRegisterValueOperation(uint32_t offset,
+                                      const char* reg_name,
+                                      uint32_t size,
+                                      RegisterValue &value) override;
+
+        NativeProcessLinux::OperationUP
+        GetWriteRegisterValueOperation(uint32_t offset,
+                                       const char* reg_name,
+                                       const RegisterValue &value) override;
+
+        NativeProcessLinux::OperationUP
+        GetReadGPROperation(void *buf, size_t buf_size) override;
+
+        NativeProcessLinux::OperationUP
+        GetWriteGPROperation(void *buf, size_t buf_size) override;
+
+        NativeProcessLinux::OperationUP
+        GetReadFPROperation(void *buf, size_t buf_size) override;
+
+        NativeProcessLinux::OperationUP
+        GetWriteFPROperation(void *buf, size_t buf_size) override;
+
+        void*
+        GetGPRBuffer() override { return &m_gpr_arm64; }
+
+        void*
+        GetFPRBuffer() override { return &m_fpr; }
+
+        size_t
+        GetFPRSize() override { return sizeof(m_fpr); }
+
     private:
         struct RegInfo
         {
@@ -135,31 +166,13 @@ namespace process_linux {
         IsGPR(unsigned reg) const;
 
         bool
-        ReadGPR ();
-
-        bool
-        WriteGPR ();
-
-        bool
         IsFPR(unsigned reg) const;
 
-        bool
-        ReadFPR ();
-
-        bool
-        WriteFPR ();
-
         Error
-        ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
+        ReadHardwareDebugInfo(unsigned int &watch_count , unsigned int &break_count);
 
         Error
-        WriteRegisterRaw (uint32_t reg_index, const RegisterValue &reg_value);
-
-        lldb::ByteOrder
-        GetByteOrder() const;
-
-        size_t
-        GetGPRSize() const;
+        WriteHardwareDebugRegs(lldb::addr_t *addr_buf, uint32_t *cntrl_buf, int type, int count);
     };
 
 } // namespace process_linux
@@ -167,3 +180,4 @@ namespace process_linux {
 
 #endif // #ifndef lldb_NativeRegisterContextLinux_arm64_h
 
+#endif // defined (__arm64__) || defined (__aarch64__)
index 43986fc..1e7a1fa 100644 (file)
@@ -7,15 +7,20 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined (__mips__)
+
 #include "NativeRegisterContextLinux_mips64.h"
 
-#include "lldb/lldb-private-forward.h"
-#include "lldb/Core/DataBufferHeap.h"
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
 #include "lldb/Core/Error.h"
 #include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
+
 #include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
 
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
@@ -86,15 +91,90 @@ namespace
     {
         { "General Purpose Registers",  "gpr", k_num_gp_reg_mips64, g_gp_regnums_mips64 }
     };
+
+    class ReadRegOperation : public NativeProcessLinux::Operation
+    {
+    public:
+        ReadRegOperation(lldb::tid_t tid, uint32_t offset, RegisterValue &value) :
+            m_tid(tid),
+            m_offset(static_cast<uintptr_t>(offset)),
+            m_value(value)
+        { }
+
+        void
+        Execute(NativeProcessLinux *monitor) override;
+
+    private:
+        lldb::tid_t m_tid;
+        uintptr_t m_offset;
+        RegisterValue &m_value;
+    };
+
+    class WriteRegOperation : public NativeProcessLinux::Operation
+    {
+    public:
+        WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, const RegisterValue &value) :
+            m_tid(tid),
+            m_offset(offset),
+            m_reg_name(reg_name),
+            m_value(value)
+        { }
+
+        void
+        Execute(NativeProcessLinux *monitor) override;
+
+    private:
+        lldb::tid_t m_tid;
+        uintptr_t m_offset;
+        const char *m_reg_name;
+        const RegisterValue &m_value;
+    };
+
+} // end of anonymous namespace
+
+void
+ReadRegOperation::Execute(NativeProcessLinux *monitor)
+{
+    elf_gregset_t regs;
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
+    if (m_error.Success())
+    {
+        lldb_private::ArchSpec arch;
+        if (monitor->GetArchitecture(arch))
+            m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
+        else
+            m_error.SetErrorString("failed to get architecture");
+    }
+}
+
+void
+WriteRegOperation::Execute(NativeProcessLinux *monitor)
+{
+    elf_gregset_t regs;
+    NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
+    if (m_error.Success())
+    {
+        ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
+        NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_tid, NULL, &regs, sizeof regs, m_error);
+    }
+}
+
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+                                                                 NativeThreadProtocol &native_thread,
+                                                                 uint32_t concrete_frame_idx)
+{
+    return new NativeRegisterContextLinux_mips64(target_arch, native_thread, concrete_frame_idx);
 }
 
 // ----------------------------------------------------------------------------
 // NativeRegisterContextLinux_mips64 members.
 // ----------------------------------------------------------------------------
 
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (NativeThreadProtocol &native_thread, 
-        uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
-    NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p)
+NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
+                                                                      NativeThreadProtocol &native_thread, 
+                                                                      uint32_t concrete_frame_idx) :
+    NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_mips64 (target_arch))
 {
 }
 
@@ -124,33 +204,6 @@ NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
 }
 
 lldb_private::Error
-NativeRegisterContextLinux_mips64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
-    Error error;
-
-    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
-    if (!reg_info)
-    {
-        error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
-        return error;
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadRegisterValue(m_thread.GetID(),
-                                        reg_info->byte_offset,
-                                        reg_info->name,
-                                        reg_info->byte_size,
-                                        reg_value);
-}
-
-lldb_private::Error
 NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
 {
     Error error;
@@ -183,39 +236,6 @@ NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, R
 }
 
 lldb_private::Error
-NativeRegisterContextLinux_mips64::WriteRegister(const uint32_t reg,
-                                                 const RegisterValue &value)
-{
-    Error error;
-
-    uint32_t reg_to_write = reg;
-    RegisterValue value_to_write = value;
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
-    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
-    if (!register_to_write_info_p)
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_mips64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteRegisterValue(m_thread.GetID(),
-                                         register_to_write_info_p->byte_offset,
-                                         register_to_write_info_p->name,
-                                         value_to_write);
-}
-
-
-
-lldb_private::Error
 NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
 {
     assert (reg_info && "reg_info is null");
@@ -225,7 +245,7 @@ NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info,
     if (reg_index == LLDB_INVALID_REGNUM)
         return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
 
-    return WriteRegister(reg_index, reg_value);
+    return WriteRegisterRaw(reg_index, reg_value);
 }
 
 Error
@@ -299,3 +319,22 @@ NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints ()
 {
     return 0;
 }
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_mips64::GetReadRegisterValueOperation(uint32_t offset,
+                                                                 const char* reg_name,
+                                                                 uint32_t size,
+                                                                 RegisterValue &value)
+{
+    return NativeProcessLinux::OperationUP(new ReadRegOperation(m_thread.GetID(), offset, value));
+}
+
+NativeProcessLinux::OperationUP
+NativeRegisterContextLinux_mips64::GetWriteRegisterValueOperation(uint32_t offset,
+                                                                  const char* reg_name,
+                                                                  const RegisterValue &value)
+{
+    return NativeProcessLinux::OperationUP(new WriteRegOperation(m_thread.GetID(), offset, reg_name, value));
+}
+
+#endif // defined (__mips__)
index 07e8f20..135b780 100644 (file)
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined (__mips__)
 
 #ifndef lldb_NativeRegisterContextLinux_mips64_h
 #define lldb_NativeRegisterContextLinux_mips64_h
 
-#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
 #include "Plugins/Process/Utility/RegisterContext_mips64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
 
@@ -68,11 +69,12 @@ namespace process_linux {
         k_num_gp_reg_mips64,
     };
 
-    class NativeRegisterContextLinux_mips64 : public NativeRegisterContextRegisterInfo
+    class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux
     {
     public:
-        NativeRegisterContextLinux_mips64 (NativeThreadProtocol &native_thread, 
-            uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);
+        NativeRegisterContextLinux_mips64 (const ArchSpec& target_arch,
+                                           NativeThreadProtocol &native_thread, 
+                                           uint32_t concrete_frame_idx);
 
         uint32_t
         GetRegisterSetCount () const override;
@@ -118,13 +120,17 @@ namespace process_linux {
         uint32_t
         NumSupportedHardwareWatchpoints () override;
 
-    private:
-
-        lldb_private::Error
-        WriteRegister(const uint32_t reg, const RegisterValue &value);
-
-        lldb_private::Error
-        ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
+    protected:
+        NativeProcessLinux::OperationUP
+        GetReadRegisterValueOperation(uint32_t offset,
+                                      const char* reg_name,
+                                      uint32_t size,
+                                      RegisterValue &value) override;
+
+        NativeProcessLinux::OperationUP
+        GetWriteRegisterValueOperation(uint32_t offset,
+                                       const char* reg_name,
+                                       const RegisterValue &value) override;
     };
 
 } // namespace process_linux
@@ -132,3 +138,4 @@ namespace process_linux {
 
 #endif // #ifndef lldb_NativeRegisterContextLinux_mips64_h
 
+#endif // defined (__mips__)
index 8a4a7ae..a7390f5 100644 (file)
@@ -7,16 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__i386__) || defined(__x86_64__)
+
 #include "NativeRegisterContextLinux_x86_64.h"
 
 #include "lldb/Core/Log.h"
-#include "lldb/lldb-private-forward.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/RegisterValue.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "lldb/Host/HostInfo.h"
+
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
@@ -326,12 +328,39 @@ namespace
 #define NT_X86_XSTATE 0x202
 #endif
 
+NativeRegisterContextLinux*
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
+                                                                 NativeThreadProtocol &native_thread,
+                                                                 uint32_t concrete_frame_idx)
+{
+    return new NativeRegisterContextLinux_x86_64(target_arch, native_thread, concrete_frame_idx);
+}
+
 // ----------------------------------------------------------------------------
 // NativeRegisterContextLinux_x86_64 members.
 // ----------------------------------------------------------------------------
 
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
-    NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p),
+static RegisterInfoInterface*
+CreateRegisterInfoInterface(const ArchSpec& target_arch)
+{
+    if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
+    {
+        // 32-bit hosts run with a RegisterContextLinux_i386 context.
+        return new RegisterContextLinux_i386(target_arch);
+    }
+    else
+    {
+        assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+               "Register setting path assumes this is a 64-bit host");
+        // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
+        return new RegisterContextLinux_x86_64 (target_arch);
+    }
+}
+
+NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
+                                                                      NativeThreadProtocol &native_thread,
+                                                                      uint32_t concrete_frame_idx) :
+    NativeRegisterContextLinux (native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch)),
     m_fpr_type (eFPRTypeNotValid),
     m_fpr (),
     m_iovec (),
@@ -340,7 +369,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThre
     m_gpr_x86_64 ()
 {
     // Set up data about ranges of valid registers.
-    switch (reg_info_interface_p->GetTargetArchitecture ().GetMachine ())
+    switch (target_arch.GetMachine ())
     {
         case llvm::Triple::x86:
             m_reg_info.num_registers        = k_num_registers_i386;
@@ -444,32 +473,6 @@ NativeRegisterContextLinux_x86_64::GetRegisterSet (uint32_t set_index) const
 }
 
 Error
-NativeRegisterContextLinux_x86_64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
-{
-    Error error;
-    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
-    if (!reg_info)
-    {
-        error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
-        return error;
-    }
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->ReadRegisterValue(m_thread.GetID(),
-                                        reg_info->byte_offset,
-                                        reg_info->name,
-                                        reg_info->byte_size,
-                                        reg_value);
-}
-
-Error
 NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
 {
     Error error;
@@ -490,11 +493,9 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
 
     if (IsFPR(reg, GetFPRType()))
     {
-        if (!ReadFPR())
-        {
-            error.SetErrorString ("failed to read floating point register");
+        error = ReadFPR();
+        if (error.Fail())
             return error;
-        }
     }
     else
     {
@@ -581,78 +582,6 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
 }
 
 Error
-NativeRegisterContextLinux_x86_64::WriteRegister(const uint32_t reg,
-                                                 const RegisterValue &value)
-{
-    Error error;
-
-    uint32_t reg_to_write = reg;
-    RegisterValue value_to_write = value;
-
-    // Check if this is a subregister of a full register.
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-    if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
-    {
-        RegisterValue full_value;
-        uint32_t full_reg = reg_info->invalidate_regs[0];
-        const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-        // Read the full register.
-        error = ReadRegister(full_reg_info, full_value);
-        if (error.Fail ())
-            return error;
-
-        lldb::ByteOrder byte_order = GetByteOrder();
-        uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the full register.
-        const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
-                                                               dst,
-                                                               sizeof(dst),
-                                                               byte_order,
-                                                               error);
-        if (error.Success() && dest_size)
-        {
-            uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-            // Get the bytes for the source data.
-            const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
-            if (error.Success() && src_size && (src_size < dest_size))
-            {
-                // Copy the src bytes to the destination.
-                memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
-                // Set this full register as the value to write.
-                value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-                value_to_write.SetType(full_reg_info);
-                reg_to_write = full_reg;
-            }
-        }
-    }
-
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-    {
-        error.SetErrorString ("NativeProcessProtocol is NULL");
-        return error;
-    }
-
-    const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
-    assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
-    if (!register_to_write_info_p)
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
-        return error;
-    }
-
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->WriteRegisterValue(m_thread.GetID(),
-                                         register_to_write_info_p->byte_offset,
-                                         register_to_write_info_p->name,
-                                         value_to_write);
-}
-
-Error
 NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
 {
     assert (reg_info && "reg_info is null");
@@ -662,7 +591,7 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
         return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
 
     if (IsGPR(reg_index))
-        return WriteRegister(reg_index, reg_value);
+        return WriteRegisterRaw(reg_index, reg_value);
 
     if (IsFPR(reg_index, GetFPRType()))
     {
@@ -710,15 +639,16 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
             }
         }
 
-        if (WriteFPR())
+        Error error = WriteFPR();
+        if (error.Fail())
+            return error;
+
+        if (IsAVX(reg_index))
         {
-            if (IsAVX(reg_index))
-            {
-                if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
-                    return Error ("CopyYMMtoXSTATE() failed");
-            }
-            return Error ();
+            if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
+                return Error ("CopyYMMtoXSTATE() failed");
         }
+        return Error ();
     }
     return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
 }
@@ -735,17 +665,13 @@ NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &da
         return error;
     }
 
-    if (!ReadGPR ())
-    {
-        error.SetErrorString ("ReadGPR() failed");
+    error = ReadGPR();
+    if (error.Fail())
         return error;
-    }
 
-    if (!ReadFPR ())
-    {
-        error.SetErrorString ("ReadFPR() failed");
+    error = ReadFPR();
+    if (error.Fail())
         return error;
-    }
 
     uint8_t *dst = data_sp->GetBytes ();
     if (dst == nullptr)
@@ -810,11 +736,9 @@ NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBuffe
     }
     ::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
 
-    if (!WriteGPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
+    error = WriteGPR();
+    if (error.Fail())
         return error;
-    }
 
     src += GetRegisterInfoInterface ().GetGPRSize ();
     if (GetFPRType () == eFPRTypeFXSAVE)
@@ -822,11 +746,9 @@ NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBuffe
     else if (GetFPRType () == eFPRTypeXSAVE)
         ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
 
-    if (!WriteFPR ())
-    {
-        error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
+    error = WriteFPR();
+    if (error.Fail())
         return error;
-    }
 
     if (GetFPRType() == eFPRTypeXSAVE)
     {
@@ -860,24 +782,6 @@ NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) c
     return (set_index < num_sets);
 }
 
-lldb::ByteOrder
-NativeRegisterContextLinux_x86_64::GetByteOrder() const
-{
-    // Get the target process whose privileged thread was used for the register read.
-    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return byte_order;
-
-    if (!process_sp->GetByteOrder (byte_order))
-    {
-        // FIXME log here
-    }
-
-    return byte_order;
-}
-
 bool
 NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
 {
@@ -894,7 +798,7 @@ NativeRegisterContextLinux_x86_64::GetFPRType () const
 
         // Try and see if AVX register retrieval works.
         m_fpr_type = eFPRTypeXSAVE;
-        if (!const_cast<NativeRegisterContextLinux_x86_64*> (this)->ReadFPR ())
+        if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
         {
             // Fall back to general floating point with no AVX support.
             m_fpr_type = eFPRTypeFXSAVE;
@@ -920,20 +824,19 @@ NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) c
     return generic_fpr;
 }
 
-bool
+Error
 NativeRegisterContextLinux_x86_64::WriteFPR()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    if (GetFPRType() == eFPRTypeFXSAVE)
-        return process_p->WriteFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave)).Success();
-
-    if (GetFPRType() == eFPRTypeXSAVE)
-        return process_p->WriteRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE).Success();
-    return false;
+    const FPRType fpr_type = GetFPRType ();
+    switch (fpr_type)
+    {
+    case FPRType::eFPRTypeFXSAVE:
+        return NativeRegisterContextLinux::WriteFPR();
+    case FPRType::eFPRTypeXSAVE:
+        return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+    default:
+        return Error("Unrecognized FPR type");
+    }
 }
 
 bool
@@ -1003,48 +906,49 @@ NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder
     return false; // unsupported or invalid byte order
 }
 
-bool
-NativeRegisterContextLinux_x86_64::ReadFPR ()
+void*
+NativeRegisterContextLinux_x86_64::GetFPRBuffer()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
     const FPRType fpr_type = GetFPRType ();
     switch (fpr_type)
     {
     case FPRType::eFPRTypeFXSAVE:
-        return process_p->ReadFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave)).Success();
-
+        return &m_fpr.xstate.fxsave;
     case FPRType::eFPRTypeXSAVE:
-        return process_p->ReadRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE).Success();
-
+        return &m_iovec;
     default:
-        return false;
+        return nullptr;
     }
 }
 
-bool
-NativeRegisterContextLinux_x86_64::ReadGPR()
+size_t
+NativeRegisterContextLinux_x86_64::GetFPRSize()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->ReadGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+    const FPRType fpr_type = GetFPRType ();
+    switch (fpr_type)
+    {
+    case FPRType::eFPRTypeFXSAVE:
+        return sizeof(m_fpr.xstate.fxsave);
+    case FPRType::eFPRTypeXSAVE:
+        return sizeof(m_iovec);
+    default:
+        return 0;
+    }
 }
 
-bool
-NativeRegisterContextLinux_x86_64::WriteGPR()
+Error
+NativeRegisterContextLinux_x86_64::ReadFPR ()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return false;
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
-
-    return process_p->WriteGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ()).Success();
+    const FPRType fpr_type = GetFPRType ();
+    switch (fpr_type)
+    {
+    case FPRType::eFPRTypeFXSAVE:
+        return NativeRegisterContextLinux::ReadFPR();
+    case FPRType::eFPRTypeXSAVE:
+        return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+    default:
+        return Error("Unrecognized FPR type");
+    }
 }
 
 Error
@@ -1148,10 +1052,10 @@ NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
 
     control_bits |= enable_bit | rw_bits | size_bits;
 
-    error = WriteRegister(m_reg_info.first_dr + wp_index, RegisterValue(addr));
+    error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
     if (error.Fail()) return error;
 
-    error = WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+    error = WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
     if (error.Fail()) return error;
 
     error.Clear();
@@ -1172,7 +1076,7 @@ NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
     if (error.Fail()) return false;
     uint64_t bit_mask = 1 << wp_index;
     uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
-    error = WriteRegister(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+    error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
     if (error.Fail()) return false;
 
     // for watchpoints 0, 1, 2, or 3, respectively,
@@ -1182,7 +1086,7 @@ NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(uint32_t wp_index)
     if (error.Fail()) return false;
     bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
     uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-    return WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
+    return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits)).Success();
 }
 
 Error
@@ -1195,7 +1099,7 @@ NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
     if (error.Fail()) return error;
     uint64_t bit_mask = 0xF;
     uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
-    error = WriteRegister(m_reg_info.first_dr + 6, RegisterValue(status_bits));
+    error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
     if (error.Fail()) return error;
 
     // clear bits {0-7,16-31} of the debug control register (DR7)
@@ -1203,7 +1107,7 @@ NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints()
     if (error.Fail()) return error;
     bit_mask = 0xFF | (0xFFFF << 16);
     uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-    return WriteRegister(m_reg_info.first_dr + 7, RegisterValue(control_bits));
+    return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
 }
 
 uint32_t
@@ -1248,3 +1152,5 @@ NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints ()
     // Available debug address registers: dr0, dr1, dr2, dr3
     return 4;
 }
+
+#endif // defined(__i386__) || defined(__x86_64__)
index c6edcf6..f410a37 100644 (file)
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__i386__) || defined(__x86_64__)
 
 #ifndef lldb_NativeRegisterContextLinux_x86_64_h
 #define lldb_NativeRegisterContextLinux_x86_64_h
 
-#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 
@@ -20,10 +21,12 @@ namespace process_linux {
 
     class NativeProcessLinux;
 
-    class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextRegisterInfo
+    class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux
     {
     public:
-        NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p);
+        NativeRegisterContextLinux_x86_64 (const ArchSpec& target_arch,
+                                           NativeThreadProtocol &native_thread,
+                                           uint32_t concrete_frame_idx);
 
         uint32_t
         GetRegisterSetCount () const override;
@@ -75,6 +78,22 @@ namespace process_linux {
         uint32_t
         NumSupportedHardwareWatchpoints() override;
 
+    protected:
+        void*
+        GetGPRBuffer() override { return &m_gpr_x86_64; }
+
+        void*
+        GetFPRBuffer() override;
+
+        size_t
+        GetFPRSize() override;
+
+        Error
+        ReadFPR() override;
+
+        Error
+        WriteFPR() override;
+
     private:
 
         // Private member types.
@@ -119,14 +138,8 @@ namespace process_linux {
         uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
 
         // Private member methods.
-        Error
-        WriteRegister(const uint32_t reg, const RegisterValue &value);
-
         bool IsRegisterSetAvailable (uint32_t set_index) const;
 
-        lldb::ByteOrder
-        GetByteOrder() const;
-
         bool
         IsGPR(uint32_t reg_index) const;
 
@@ -137,9 +150,7 @@ namespace process_linux {
         IsFPR(uint32_t reg_index) const;
 
         bool
-        WriteFPR();
-
-        bool IsFPR(uint32_t reg_index, FPRType fpr_type) const;
+        IsFPR(uint32_t reg_index, FPRType fpr_type) const;
 
         bool
         CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order);
@@ -149,18 +160,6 @@ namespace process_linux {
 
         bool
         IsAVX (uint32_t reg_index) const;
-
-        bool
-        ReadFPR ();
-
-        Error
-        ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value);
-
-        bool
-        ReadGPR();
-
-        bool
-        WriteGPR();
     };
 
 } // namespace process_linux
@@ -168,3 +167,4 @@ namespace process_linux {
 
 #endif // #ifndef lldb_NativeRegisterContextLinux_x86_64_h
 
+#endif // defined(__i386__) || defined(__x86_64__)
index c7c13a5..cd0dd7e 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
 #include "lldb/Host/HostNativeThread.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/lldb-enumerations.h"
 
 #include "Plugins/Process/POSIX/CrashReason.h"
 
-#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "Plugins/Process/Utility/RegisterInfoInterface.h"
-
 #include <sys/syscall.h>
 // Try to define a macro to encapsulate the tgkill syscall
 #define tgkill(pid, tid, sig) \
@@ -172,8 +163,6 @@ NativeThreadLinux::GetRegisterContext ()
     if (m_reg_context_sp)
         return m_reg_context_sp;
 
-    // First select the appropriate RegisterInfoInterface.
-    RegisterInfoInterface *reg_interface = nullptr;
     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
     if (!m_process_sp)
         return NativeRegisterContextSP ();
@@ -182,93 +171,10 @@ NativeThreadLinux::GetRegisterContext ()
     if (!m_process_sp->GetArchitecture (target_arch))
         return NativeRegisterContextSP ();
 
-    switch (target_arch.GetTriple().getOS())
-    {
-        case llvm::Triple::Linux:
-            switch (target_arch.GetMachine())
-            {
-            case llvm::Triple::aarch64:
-                assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
-                reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch));
-                break;
-            case llvm::Triple::arm:
-                assert(HostInfo::GetArchitecture ().GetAddressByteSize() == 4);
-                reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm(target_arch));
-                break;
-            case llvm::Triple::x86:
-            case llvm::Triple::x86_64:
-                if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
-                {
-                    // 32-bit hosts run with a RegisterContextLinux_i386 context.
-                    reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
-                }
-                else
-                {
-                    assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
-                           "Register setting path assumes this is a 64-bit host");
-                    // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
-                    reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch));
-                }
-                break;
-            case llvm::Triple::mips64:
-            case llvm::Triple::mips64el:
-                assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8)
-                    && "Register setting path assumes this is a 64-bit host");
-                reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_mips64 (target_arch));
-                break;
-            default:
-                break;
-            }
-            break;
-        default:
-            break;
-    }
-
-    assert(reg_interface && "OS or CPU not supported!");
-    if (!reg_interface)
-        return NativeRegisterContextSP ();
-
-    // Now create the register context.
-    switch (target_arch.GetMachine())
-    {
-#if 0
-        case llvm::Triple::mips64:
-        {
-            RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
-            m_posix_thread = reg_ctx;
-            m_reg_context_sp.reset(reg_ctx);
-            break;
-        }
-#endif
-        case llvm::Triple::mips64:
-        case llvm::Triple::mips64el:
-        {
-            const uint32_t concrete_frame_idx = 0;
-            m_reg_context_sp.reset (new NativeRegisterContextLinux_mips64 (*this, concrete_frame_idx, reg_interface));
-            break;
-        }
-        case llvm::Triple::aarch64:
-        {
-            const uint32_t concrete_frame_idx = 0;
-            m_reg_context_sp.reset (new NativeRegisterContextLinux_arm64(*this, concrete_frame_idx, reg_interface));
-            break;
-        }
-        case llvm::Triple::arm:
-        {
-            const uint32_t concrete_frame_idx = 0;
-            m_reg_context_sp.reset (new NativeRegisterContextLinux_arm(*this, concrete_frame_idx, reg_interface));
-            break;
-        }
-        case llvm::Triple::x86:
-        case llvm::Triple::x86_64:
-        {
-            const uint32_t concrete_frame_idx = 0;
-            m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface));
-            break;
-        }
-        default:
-            break;
-    }
+    const uint32_t concrete_frame_idx = 0;
+    m_reg_context_sp.reset (NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(target_arch,
+                                                                                             *this,
+                                                                                             concrete_frame_idx));
 
     return m_reg_context_sp;
 }
index ce686b5..1b383fb 100644 (file)
@@ -20,7 +20,14 @@ typedef struct user_fpsimd_state elf_fpregset_t;
 #ifndef NT_FPREGSET
     #define NT_FPREGSET NT_PRFPREG
 #endif // NT_FPREGSET
-#endif // defined (__arm64__) || defined (__aarch64__)
+#elif defined (__mips__)
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[(sizeof (struct user_regs_struct) / sizeof(elf_greg_t))];
+typedef struct user_fpsimd_state elf_fpregset_t;
+#ifndef NT_FPREGSET
+    #define NT_FPREGSET NT_PRFPREG
+#endif // NT_FPREGSET
+#endif
 #else  // __ANDROID__
 #include <sys/procfs.h>
 #endif // __ANDROID__
index ccb6da4..22efd3f 100644 (file)
@@ -7,6 +7,8 @@
 //
 //===---------------------------------------------------------------------===//
 
+#if defined (__mips__)
+
 #include <vector>
 #include <stddef.h>
 
@@ -150,3 +152,4 @@ RegisterContextLinux_mips64::GetRegisterCount () const
     return m_register_info_count;
 }
 
+#endif
index 9a1d092..546d148 100644 (file)
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined (__mips__)
+
 #ifndef liblldb_RegisterContextLinux_mips64_H_
 #define liblldb_RegisterContextLinux_mips64_H_
 
@@ -34,3 +36,5 @@ private:
 };
 
 #endif
+
+#endif