[Lldb-commits] [lldb] r192387 - Initial FreeBSD mips64 ProcessMonitor support

Ed Maste emaste at freebsd.org
Thu Oct 10 12:14:55 PDT 2013


Author: emaste
Date: Thu Oct 10 14:14:55 2013
New Revision: 192387

URL: http://llvm.org/viewvc/llvm-project?rev=192387&view=rev
Log:
Initial FreeBSD mips64 ProcessMonitor support

Committing early to ease tracking other ongoing POSIX changes.

Review: http://llvm-reviews.chandlerc.com/D1886

Added:
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h
Modified:
    lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h

Modified: lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt?rev=192387&r1=192386&r2=192387&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt Thu Oct 10 14:14:55 2013
@@ -12,6 +12,7 @@ add_lldb_library(lldbPluginProcessPOSIX
   ProcessPOSIXLog.cpp
   RegisterContextPOSIX_mips64.cpp
   RegisterContextPOSIX_x86.cpp
+  RegisterContextPOSIXProcessMonitor_mips64.cpp
   RegisterContextPOSIXProcessMonitor_x86.cpp
   RegisterContextFreeBSD_i386.cpp
   RegisterContextFreeBSD_mips64.cpp

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=192387&r1=192386&r2=192387&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Thu Oct 10 14:14:55 2013
@@ -29,10 +29,12 @@
 #include "ProcessPOSIX.h"
 #include "ProcessPOSIXLog.h"
 #include "ProcessMonitor.h"
+#include "RegisterContextPOSIXProcessMonitor_mips64.h"
 #include "RegisterContextPOSIXProcessMonitor_x86.h"
 #include "RegisterContextLinux_i386.h"
 #include "RegisterContextLinux_x86_64.h"
 #include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextFreeBSD_mips64.h"
 #include "RegisterContextFreeBSD_x86_64.h"
 
 #include "UnwindLLDB.h"
@@ -144,25 +146,62 @@ POSIXThread::GetRegisterContext()
         RegisterInfoInterface *reg_interface = NULL;
         const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
 
-        switch (target_arch.GetTriple().getOS())
+        switch (target_arch.GetCore())
         {
-            case llvm::Triple::FreeBSD:
-                reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
+            case ArchSpec::eCore_mips64:
+            {
+                RegisterInfoInterface *reg_interface = NULL;
+
+                switch (target_arch.GetTriple().getOS())
+                {
+                    case llvm::Triple::FreeBSD:
+                        reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
+                        break;
+                    default:
+                        assert(false && "OS not supported");
+                        break;
+                }
+
+                if (reg_interface)
+                {
+                    RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
+                    m_posix_thread = reg_ctx;
+                    m_reg_context_sp.reset(reg_ctx);
+                }
                 break;
-            case llvm::Triple::Linux:
-                reg_interface = new RegisterContextLinux_x86_64(target_arch);
+            }
+
+            case ArchSpec::eCore_x86_32_i386:
+            case ArchSpec::eCore_x86_32_i486:
+            case ArchSpec::eCore_x86_32_i486sx:
+            case ArchSpec::eCore_x86_64_x86_64:
+            {
+                switch (target_arch.GetTriple().getOS())
+                {
+                    case llvm::Triple::FreeBSD:
+                        reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
+                        break;
+                    case llvm::Triple::Linux:
+                        reg_interface = new RegisterContextLinux_x86_64(target_arch);
+                        break;
+                    default:
+                        assert(false && "OS not supported");
+                        break;
+                }
+
+                if (reg_interface)
+                {
+                    RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface);
+                    m_posix_thread = reg_ctx;
+                    m_reg_context_sp.reset(reg_ctx);
+                }
                 break;
+            }
+
             default:
-                assert(false && "OS not supported");
+                assert(false && "CPU type not supported!");
                 break;
         }
-
-        if (reg_interface)
-        {
-            RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface);
-            m_posix_thread = reg_ctx;
-            m_reg_context_sp.reset(reg_ctx);
-        }
     }
     return m_reg_context_sp;
 }
@@ -523,6 +562,7 @@ POSIXThread::GetRegisterIndexFromOffset(
         llvm_unreachable("CPU type not supported!");
         break;
 
+    case ArchSpec::eCore_mips64:
     case ArchSpec::eCore_x86_32_i386:
     case ArchSpec::eCore_x86_32_i486:
     case ArchSpec::eCore_x86_32_i486sx:
@@ -554,6 +594,7 @@ POSIXThread::GetRegisterName(unsigned re
         assert(false && "CPU type not supported!");
         break;
 
+    case ArchSpec::eCore_mips64:
     case ArchSpec::eCore_x86_32_i386:
     case ArchSpec::eCore_x86_32_i486:
     case ArchSpec::eCore_x86_32_i486sx:

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

Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h?rev=192387&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h (added)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h Thu Oct 10 14:14:55 2013
@@ -0,0 +1,95 @@
+//===-- RegisterContextPOSIXProcessMonitor_mips64.h -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
+#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
+
+#include "Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h"
+
+class RegisterContextPOSIXProcessMonitor_mips64:
+    public RegisterContextPOSIX_mips64,
+    public POSIXBreakpointProtocol
+{
+public:
+    RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread,
+                                              uint32_t concrete_frame_idx,
+                                              RegisterInfoInterface *register_info);
+
+protected:
+    bool
+    ReadGPR();
+
+    bool
+    ReadFPR();
+
+    bool
+    WriteGPR();
+
+    bool
+    WriteFPR();
+
+    // lldb_private::RegisterContext
+    bool
+    ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+
+    bool
+    WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+
+    bool
+    ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+    bool
+    WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+    bool
+    ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+    bool
+    WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+    uint32_t
+    SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+
+    bool
+    ClearHardwareWatchpoint(uint32_t hw_index);
+
+    bool
+    HardwareSingleStep(bool enable);
+
+    // POSIXBreakpointProtocol
+    bool
+    UpdateAfterBreakpoint();
+
+    unsigned
+    GetRegisterIndexFromOffset(unsigned offset);
+
+    bool
+    IsWatchpointHit(uint32_t hw_index);
+
+    bool
+    ClearWatchpointHits();
+
+    lldb::addr_t
+    GetWatchpointAddress(uint32_t hw_index);
+
+    bool
+    IsWatchpointVacant(uint32_t hw_index);
+
+    bool
+    SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+
+    uint32_t
+    NumSupportedHardwareWatchpoints();
+
+private:
+    ProcessMonitor &
+    GetMonitor();
+};
+
+#endif

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h?rev=192387&r1=192386&r2=192387&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h Thu Oct 10 14:14:55 2013
@@ -111,7 +111,7 @@ public:
     ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
 
 protected:
-    uint64_t m_gpr[k_num_gpr_registers_mips64];                // general purpose registers.
+    uint64_t m_gpr_mips64[k_num_gpr_registers_mips64];         // general purpose registers.
     std::unique_ptr<RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
 
     // Determines if an extended register set is supported on the processor running the inferior process.





More information about the lldb-commits mailing list