Index: source/Plugins/Process/FreeBSD/ProcessMonitor.h =================================================================== --- source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -120,6 +120,27 @@ WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, const lldb_private::RegisterValue &value); + /// Reads the contents from the debug register identified by the given + /// (architecture dependent) offset. + /// + /// This method is provided for use by RegisterContextFreeBSD derivatives. + /// FIXME: ???? The FreeBSD implementation of this function should use tid in order + /// to enable support for debugging threaded programs. + bool + ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset, + const char *reg_name, unsigned size, + lldb_private::RegisterValue &value); + + /// Writes the given value to the debug register identified by the given + /// (architecture dependent) offset. + /// + /// This method is provided for use by RegisterContextFreeBSD derivatives. + /// FIXME: ???? The FreeBSD implementation of this function should use tid in order + /// to enable support for debugging threaded programs. + bool + WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset, + const char *reg_name, + const lldb_private::RegisterValue &value); /// Reads all general purpose registers into the specified buffer. /// FIXME: The FreeBSD implementation of this function should use tid in order /// to enable support for debugging threaded programs. Index: source/Plugins/Process/FreeBSD/ProcessMonitor.cpp =================================================================== --- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -111,6 +111,16 @@ log->Printf("PT_GETREGS: bp=0x%lx", r->r_rbp); log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax); } + if (req == PT_GETDBREGS) { + struct dbreg *r = (struct dbreg *) addr; + + log->Printf("PT_GETDBREGS: dr[0]=0x%lx", r->dr[0]); + log->Printf("PT_GETDBREGS: dr[1]=0x%lx", r->dr[1]); + log->Printf("PT_GETDBREGS: dr[2]=0x%lx", r->dr[2]); + log->Printf("PT_GETDBREGS: dr[3]=0x%lx", r->dr[3]); + log->Printf("PT_GETDBREGS: dr[6]=0x%lx", r->dr[6]); + log->Printf("PT_GETDBREGS: dr[7]=0x%lx", r->dr[7]); + } } #endif @@ -348,6 +358,82 @@ } //------------------------------------------------------------------------------ +/// @class ReadDebugRegOperation +/// @brief Implements ProcessMonitor::ReadDebugRegisterValue. +class ReadDebugRegOperation : public Operation +{ +public: + ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size, + RegisterValue &value, bool &result) + : m_tid(tid), m_offset(offset), m_size(size), + m_value(value), m_result(result) + { } + + void Execute(ProcessMonitor *monitor); + +private: + lldb::tid_t m_tid; + unsigned m_offset; + unsigned m_size; + RegisterValue &m_value; + bool &m_result; +}; + +void +ReadDebugRegOperation::Execute(ProcessMonitor *monitor) +{ + struct dbreg regs; + int rc; + + if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)®s, 0)) < 0) { + m_result = false; + } else { + if (m_size == sizeof(uintptr_t)) + m_value = *(uintptr_t *)(((caddr_t)®s) + m_offset); + else + memcpy(&m_value, (((caddr_t)®s) + m_offset), m_size); + m_result = true; + } +} + +//------------------------------------------------------------------------------ +/// @class WriteDebugRegOperation +/// @brief Implements ProcessMonitor::WriteDebugRegisterValue. +class WriteDebugRegOperation : public Operation +{ +public: + WriteDebugRegOperation(lldb::tid_t tid, unsigned offset, + const RegisterValue &value, bool &result) + : m_tid(tid), m_offset(offset), + m_value(value), m_result(result) + { } + + void Execute(ProcessMonitor *monitor); + +private: + lldb::tid_t m_tid; + unsigned m_offset; + const RegisterValue &m_value; + bool &m_result; +}; + +void +WriteDebugRegOperation::Execute(ProcessMonitor *monitor) +{ + struct dbreg regs; + + if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)®s, 0) < 0) { + m_result = false; + return; + } + *(uintptr_t *)(((caddr_t)®s) + m_offset) = (uintptr_t)m_value.GetAsUInt64(); + if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)®s, 0) < 0) + m_result = false; + else + m_result = true; +} + +//------------------------------------------------------------------------------ /// @class ReadGPROperation /// @brief Implements ProcessMonitor::ReadGPR. class ReadGPROperation : public Operation @@ -1459,6 +1545,28 @@ } bool +ProcessMonitor::ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset, + const char *reg_name, unsigned size, + lldb_private::RegisterValue &value) +{ + bool result; + ReadDebugRegOperation op(tid, offset, size, value, result); + DoOperation(&op); + return result; +} + +bool +ProcessMonitor::WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset, + const char *reg_name, + const lldb_private::RegisterValue &value) +{ + bool result; + WriteDebugRegOperation op(tid, offset, value, result); + DoOperation(&op); + return result; +} + +bool ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) { bool result; Index: source/Plugins/Process/Linux/LinuxThread.h =================================================================== --- source/Plugins/Process/Linux/LinuxThread.h +++ source/Plugins/Process/Linux/LinuxThread.h @@ -34,10 +34,6 @@ // POSIXThread override virtual void RefreshStateAfterStop(); - -protected: - virtual void - TraceNotify(const ProcessMessage &message); }; #endif // #ifndef liblldb_LinuxThread_H_ Index: source/Plugins/Process/Linux/LinuxThread.cpp =================================================================== --- source/Plugins/Process/Linux/LinuxThread.cpp +++ source/Plugins/Process/Linux/LinuxThread.cpp @@ -40,24 +40,3 @@ POSIXThread::RefreshStateAfterStop(); } - -void -LinuxThread::TraceNotify(const ProcessMessage &message) -{ - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) - { - uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); - uint32_t wp_idx; - for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) - { - if (reg_ctx->IsWatchpointHit(wp_idx)) - { - WatchNotify(message); - return; - } - } - } - - POSIXThread::TraceNotify (message); -} Index: source/Plugins/Process/POSIX/POSIXThread.cpp =================================================================== --- source/Plugins/Process/POSIX/POSIXThread.cpp +++ source/Plugins/Process/POSIX/POSIXThread.cpp @@ -511,6 +511,21 @@ void POSIXThread::TraceNotify(const ProcessMessage &message) { + POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); + if (reg_ctx) + { + uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); + uint32_t wp_idx; + for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) + { + if (reg_ctx->IsWatchpointHit(wp_idx)) + { + WatchNotify(message); + return; + } + } + } + SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); } Index: source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp =================================================================== --- source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp +++ source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp @@ -11,6 +11,7 @@ #include "RegisterContextPOSIX_x86.h" #include "RegisterContextFreeBSD_i386.h" #include "RegisterContextFreeBSD_x86_64.h" +#include using namespace lldb_private; using namespace lldb; @@ -46,8 +47,10 @@ uint64_t ss; } GPR; -#define DR_SIZE 0 -#define DR_OFFSET(reg_index) 0 +#define DR_SIZE sizeof(uint64_t) +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(dbreg, dr[reg_index])) + //--------------------------------------------------------------------------- // Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure. Index: source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp =================================================================== --- source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp +++ source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -109,6 +109,15 @@ RegisterValue &value) { ProcessMonitor &monitor = GetMonitor(); + +#if defined(__FreeBSD__) + if (reg >= m_reg_info.first_dr) + return monitor.ReadDebugRegisterValue(m_thread.GetID(), + GetRegisterOffset(reg), + GetRegisterName(reg), + GetRegisterSize(reg), + value); +#endif return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg), @@ -164,6 +173,13 @@ } ProcessMonitor &monitor = GetMonitor(); +#if defined(__FreeBSD__) + if (reg >= m_reg_info.first_dr) + return monitor.WriteDebugRegisterValue(m_thread.GetID(), + GetRegisterOffset(reg_to_write), + GetRegisterName(reg_to_write), + value_to_write); +#endif return monitor.WriteRegisterValue(m_thread.GetID(), GetRegisterOffset(reg_to_write), GetRegisterName(reg_to_write),