[Lldb-commits] [lldb] r190757 - Clean up RegisterContextPOSIX. Renamed to POSIXBreakpointProtocol.
Michael Sartain
mikesart at valvesoftware.com
Sat Sep 14 11:44:02 PDT 2013
Author: mikesart
Date: Sat Sep 14 13:44:01 2013
New Revision: 190757
URL: http://llvm.org/viewvc/llvm-project?rev=190757&view=rev
Log:
Clean up RegisterContextPOSIX. Renamed to POSIXBreakpointProtocol.
Will clean up header files and m_register_infos shortly.
Modified:
lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_i386.h
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.cpp
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.h
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.cpp
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.h
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.cpp
lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h
lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
Modified: lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp Sat Sep 14 13:44:01 2013
@@ -44,7 +44,7 @@ LinuxThread::RefreshStateAfterStop()
void
LinuxThread::TraceNotify(const ProcessMessage &message)
{
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
{
uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
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=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Sat Sep 14 13:44:01 2013
@@ -46,7 +46,8 @@ POSIXThread::POSIXThread(Process &proces
m_frame_ap (),
m_breakpoint (),
m_thread_name_valid (false),
- m_thread_name ()
+ m_thread_name (),
+ m_posix_thread(NULL)
{
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
@@ -138,8 +139,9 @@ POSIXThread::GetRegisterContext()
{
if (!m_reg_context_sp)
{
- ArchSpec arch = Host::GetArchitecture();
+ m_posix_thread = NULL;
+ ArchSpec arch = Host::GetArchitecture();
switch (arch.GetCore())
{
default:
@@ -149,24 +151,39 @@ POSIXThread::GetRegisterContext()
case ArchSpec::eCore_x86_32_i386:
case ArchSpec::eCore_x86_32_i486:
case ArchSpec::eCore_x86_32_i486sx:
- m_reg_context_sp.reset(new RegisterContextPOSIXProcessMonitor_i386(*this, 0));
+ {
+ RegisterContextPOSIXProcessMonitor_i386 *reg_ctx = new RegisterContextPOSIXProcessMonitor_i386(*this, 0);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
break;
+ }
case ArchSpec::eCore_x86_64_x86_64:
+ {
+ RegisterInfoInterface *reg_interface = NULL;
+
switch (arch.GetTriple().getOS())
{
case llvm::Triple::FreeBSD:
- m_reg_context_sp.reset(new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, new RegisterContextFreeBSD_x86_64()));
+ reg_interface = new RegisterContextFreeBSD_x86_64();
break;
case llvm::Triple::Linux:
- m_reg_context_sp.reset(new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, new RegisterContextLinux_x86_64()));
+ reg_interface = new RegisterContextLinux_x86_64();
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;
}
+ }
}
return m_reg_context_sp;
}
@@ -328,7 +345,7 @@ POSIXThread::EnableHardwareWatchpoint(Wa
bool wp_read = wp->WatchpointRead();
bool wp_write = wp->WatchpointWrite();
uint32_t wp_hw_index = wp->GetHardwareIndex();
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size,
wp_read, wp_write,
@@ -365,7 +382,7 @@ POSIXThread::FindVacantWatchpointIndex()
uint32_t hw_index = LLDB_INVALID_INDEX32;
uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
uint32_t wp_idx;
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
{
for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
@@ -387,7 +404,7 @@ POSIXThread::BreakNotify(const ProcessMe
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
assert(GetRegisterContext());
- status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
+ status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
assert(status && "Breakpoint update failed!");
// With our register state restored, resolve the breakpoint object
@@ -436,7 +453,7 @@ POSIXThread::WatchNotify(const ProcessMe
log->Printf ("POSIXThread::%s () Hardware Watchpoint Address = 0x%8.8"
PRIx64, __FUNCTION__, halt_addr);
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
{
uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
@@ -537,11 +554,8 @@ POSIXThread::GetRegisterIndexFromOffset(
case ArchSpec::eCore_x86_32_i486sx:
case ArchSpec::eCore_x86_64_x86_64:
{
- RegisterContextSP base = GetRegisterContext();
- if (base) {
- RegisterContextPOSIX &context = static_cast<RegisterContextPOSIX &>(*base);
- reg = context.GetRegisterIndexFromOffset(offset);
- }
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
+ reg = reg_ctx->GetRegisterIndexFromOffset(offset);
}
break;
}
Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h Sat Sep 14 13:44:01 2013
@@ -21,7 +21,7 @@
class ProcessMessage;
class ProcessMonitor;
-class RegisterContextPOSIX;
+class POSIXBreakpointProtocol;
//------------------------------------------------------------------------------
// @class POSIXThread
@@ -92,15 +92,12 @@ public:
uint32_t FindVacantWatchpointIndex();
protected:
- RegisterContextPOSIX *
- GetRegisterContextPOSIX ()
+ POSIXBreakpointProtocol *
+ GetPOSIXBreakpointProtocol ()
{
if (!m_reg_context_sp)
m_reg_context_sp = GetRegisterContext();
-#if 0
- return dynamic_cast<RegisterContextPOSIX*>(m_reg_context_sp.get());
-#endif
- return (RegisterContextPOSIX *)m_reg_context_sp.get();
+ return m_posix_thread;
}
std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
@@ -109,6 +106,7 @@ protected:
bool m_thread_name_valid;
std::string m_thread_name;
+ POSIXBreakpointProtocol *m_posix_thread;
ProcessMonitor &
GetMonitor();
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX.h Sat Sep 14 13:44:01 2013
@@ -16,17 +16,15 @@
#include "lldb/Target/RegisterContext.h"
//------------------------------------------------------------------------------
-/// @class RegisterContextPOSIX
+/// @class POSIXBreakpointProtocol
///
/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
-class RegisterContextPOSIX
- : public lldb_private::RegisterContext
+class POSIXBreakpointProtocol
{
public:
- RegisterContextPOSIX(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx)
- : RegisterContext(thread, concrete_frame_idx)
+ POSIXBreakpointProtocol()
{ m_watchpoints_initialized = false; }
+ virtual ~POSIXBreakpointProtocol() {}
/// Updates the register state of the associated thread after hitting a
/// breakpoint (if that make sense for the architecture). Default
@@ -35,33 +33,37 @@ public:
///
/// @return
/// True if the operation succeeded and false otherwise.
- virtual bool UpdateAfterBreakpoint() { return true; }
+ virtual bool UpdateAfterBreakpoint() = 0;
/// Determines the index in lldb's register file given a kernel byte offset.
virtual unsigned
- GetRegisterIndexFromOffset(unsigned offset) { return LLDB_INVALID_REGNUM; }
+ GetRegisterIndexFromOffset(unsigned offset) = 0;
// Checks to see if a watchpoint specified by hw_index caused the inferior
// to stop.
virtual bool
- IsWatchpointHit (uint32_t hw_index) { return false; }
+ IsWatchpointHit (uint32_t hw_index) = 0;
// Resets any watchpoints that have been hit.
virtual bool
- ClearWatchpointHits () { return false; }
+ ClearWatchpointHits () = 0;
// Returns the watchpoint address associated with a watchpoint hardware
// index.
virtual lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index) { return LLDB_INVALID_ADDRESS; }
+ GetWatchpointAddress (uint32_t hw_index) = 0;
virtual bool
- IsWatchpointVacant (uint32_t hw_index) { return false; }
+ IsWatchpointVacant (uint32_t hw_index) = 0;
virtual bool
SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
bool read, bool write,
- uint32_t hw_index) { return false; }
+ uint32_t hw_index) = 0;
+
+ // From lldb_private::RegisterContext
+ virtual uint32_t
+ NumSupportedHardwareWatchpoints () = 0;
protected:
bool m_watchpoints_initialized;
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_i386.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_i386.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_i386.h Sat Sep 14 13:44:01 2013
@@ -13,7 +13,8 @@
#include "Plugins/Process/POSIX/RegisterContextPOSIX_i386.h"
class RegisterContextPOSIXProcessMonitor_i386:
- public RegisterContextPOSIX_i386
+ public RegisterContextPOSIX_i386,
+ public POSIXBreakpointProtocol
{
public:
RegisterContextPOSIXProcessMonitor_i386(lldb_private::Thread &thread,
@@ -38,6 +39,34 @@ protected:
bool
WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+ // POSIXBreakpointProtocol
+ virtual bool
+ UpdateAfterBreakpoint() { return true; }
+
+ virtual unsigned
+ GetRegisterIndexFromOffset(unsigned offset) { return LLDB_INVALID_REGNUM; }
+
+ virtual bool
+ IsWatchpointHit (uint32_t hw_index) { return false; }
+
+ virtual bool
+ ClearWatchpointHits () { return false; }
+
+ virtual lldb::addr_t
+ GetWatchpointAddress (uint32_t hw_index) { return LLDB_INVALID_ADDRESS; }
+
+ virtual bool
+ IsWatchpointVacant (uint32_t hw_index) { return false; }
+
+ virtual bool
+ SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index) { return false; }
+
+ // From lldb_private::RegisterContext
+ virtual uint32_t
+ NumSupportedHardwareWatchpoints () { return 0; }
+
private:
ProcessMonitor &
GetMonitor();
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.cpp?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.cpp Sat Sep 14 13:44:01 2013
@@ -8,6 +8,7 @@
//===---------------------------------------------------------------------===//
#include "lldb/Target/Thread.h"
+#include "lldb/Core/RegisterValue.h"
#include "ProcessPOSIX.h"
#include "RegisterContextPOSIXProcessMonitor_x86_64.h"
@@ -21,6 +22,34 @@ using namespace lldb;
#define NT_X86_XSTATE 0x202
#endif
+#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(RegisterContextPOSIX_x86_64::FPR))
+
+static uint32_t
+size_and_rw_bits(size_t size, bool read, bool write)
+{
+ uint32_t rw;
+ if (read)
+ rw = 0x3; // READ or READ/WRITE
+ else if (write)
+ rw = 0x1; // WRITE
+ else
+ assert(0 && "read and write cannot both be false");
+
+ switch (size)
+ {
+ case 1:
+ return rw;
+ case 2:
+ return (0x1 << 2) | rw;
+ case 4:
+ return (0x3 << 2) | rw;
+ case 8:
+ return (0x2 << 2) | rw;
+ default:
+ assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
+ }
+}
+
RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info)
@@ -96,3 +125,460 @@ RegisterContextPOSIXProcessMonitor_x86_6
GetRegisterName(reg),
value);
}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+ if (!reg_info)
+ return false;
+
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg, GetFPRType()))
+ {
+ if (!ReadFPR())
+ return false;
+ }
+ else
+ {
+ bool success = ReadRegister(reg, value);
+
+ // If an i386 register should be parsed from an x86_64 register...
+ if (success && reg >= k_first_i386 && reg <= k_last_i386)
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info); // ...use the type specified by reg_info rather than the uint64_t default
+ return success;
+ }
+
+ if (reg_info->encoding == eEncodingVector)
+ {
+ ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != ByteOrder::eByteOrderInvalid)
+ {
+ if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
+ value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, byte_order);
+ if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
+ value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, byte_order);
+ if (reg >= fpu_ymm0 && reg <= fpu_ymm15)
+ {
+ // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
+ value.SetBytes(m_ymm_set.ymm[reg - fpu_ymm0].bytes, reg_info->byte_size, byte_order);
+ else
+ return false;
+ }
+ return value.GetType() == RegisterValue::eTypeBytes;
+ }
+ return false;
+ }
+
+ // Note that lldb uses slightly different naming conventions from sys/user.h
+ switch (reg)
+ {
+ default:
+ return false;
+ case fpu_dp:
+ value = m_fpr.xstate.fxsave.dp;
+ break;
+ case fpu_fcw:
+ value = m_fpr.xstate.fxsave.fcw;
+ break;
+ case fpu_fsw:
+ value = m_fpr.xstate.fxsave.fsw;
+ break;
+ case fpu_ip:
+ value = m_fpr.xstate.fxsave.ip;
+ break;
+ case fpu_fop:
+ value = m_fpr.xstate.fxsave.fop;
+ break;
+ case fpu_ftw:
+ value = m_fpr.xstate.fxsave.ftw;
+ break;
+ case fpu_mxcsr:
+ value = m_fpr.xstate.fxsave.mxcsr;
+ break;
+ case fpu_mxcsrmask:
+ value = m_fpr.xstate.fxsave.mxcsrmask;
+ break;
+ }
+ return true;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
+
+ if (IsFPR(reg, GetFPRType()))
+ {
+ switch (reg)
+ {
+ default:
+ if (reg_info->encoding != eEncodingVector)
+ return false;
+
+ if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
+ ::memcpy (m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
+
+ if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
+ ::memcpy (m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
+
+ if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
+ if (GetFPRType() != eXSAVE)
+ return false; // the target processor does not support AVX
+
+ // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
+ ::memcpy (m_ymm_set.ymm[reg - fpu_ymm0].bytes, value.GetBytes(), value.GetByteSize());
+ if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
+ return false;
+ }
+ break;
+ case fpu_dp:
+ m_fpr.xstate.fxsave.dp = value.GetAsUInt64();
+ break;
+ case fpu_fcw:
+ m_fpr.xstate.fxsave.fcw = value.GetAsUInt16();
+ break;
+ case fpu_fsw:
+ m_fpr.xstate.fxsave.fsw = value.GetAsUInt16();
+ break;
+ case fpu_ip:
+ m_fpr.xstate.fxsave.ip = value.GetAsUInt64();
+ break;
+ case fpu_fop:
+ m_fpr.xstate.fxsave.fop = value.GetAsUInt16();
+ break;
+ case fpu_ftw:
+ m_fpr.xstate.fxsave.ftw = value.GetAsUInt16();
+ break;
+ case fpu_mxcsr:
+ m_fpr.xstate.fxsave.mxcsr = value.GetAsUInt32();
+ break;
+ case fpu_mxcsrmask:
+ m_fpr.xstate.fxsave.mxcsrmask = value.GetAsUInt32();
+ break;
+ }
+ if (WriteFPR())
+ {
+ if (IsAVX(reg))
+ return CopyYMMtoXSTATE(reg, GetByteOrder());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::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, GetGPRSize());
+ dst += GetGPRSize();
+ }
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+
+ if (GetFPRType() == eXSAVE) {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
+ success = CopyXSTATEtoYMM(reg, byte_order);
+
+ if (success) {
+ // Copy the extended register state including the assembled ymm registers.
+ ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+ }
+ }
+ }
+ return success;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::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, src, GetGPRSize());
+
+ if (WriteGPR())
+ {
+ src += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ if (GetFPRType() == eXSAVE)
+ ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+
+ success = WriteFPR();
+ if (success)
+ {
+ success = true;
+
+ if (GetFPRType() == eXSAVE)
+ {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
+ success = CopyYMMtoXSTATE(reg, byte_order);
+ }
+ }
+ }
+ }
+ }
+ return success;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_x86_64::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_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
+{
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(dr7, current_dr7_bits))
+ {
+ uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
+
+ if (WriteRegister(dr7, RegisterValue(new_dr7_bits)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable)
+{
+ enum { TRACE_BIT = 0x100 };
+ uint64_t rflags;
+
+ if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
+ return false;
+
+ if (enable)
+ {
+ if (rflags & TRACE_BIT)
+ return true;
+
+ rflags |= TRACE_BIT;
+ }
+ else
+ {
+ if (!(rflags & TRACE_BIT))
+ return false;
+
+ rflags &= ~TRACE_BIT;
+ }
+
+ return WriteRegisterFromUnsigned(gpr_rflags, rflags);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint()
+{
+ // PC points one byte past the int3 responsible for the breakpoint.
+ lldb::addr_t pc;
+
+ if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
+ return false;
+
+ SetPC(pc - 1);
+ return true;
+}
+
+unsigned
+RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(unsigned offset)
+{
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers; reg++)
+ {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers && "Invalid register offset.");
+ return reg;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
+{
+ bool is_hit = false;
+
+ if (m_watchpoints_initialized == false)
+ {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ RegisterValue value;
+
+ if (ReadRegister(dr6, value))
+ {
+ uint64_t val = value.GetAsUInt64();
+ is_hit = val & (1 << hw_index);
+ }
+ }
+
+ return is_hit;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits()
+{
+ return WriteRegister(dr6, RegisterValue((uint64_t)0));
+}
+
+addr_t
+RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
+{
+ addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
+
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ if (!IsWatchpointVacant(hw_index))
+ {
+ RegisterValue value;
+
+ if (ReadRegister(dr0 + hw_index, value))
+ wp_monitor_addr = value.GetAsUInt64();
+ }
+ }
+
+ return wp_monitor_addr;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
+{
+ bool is_vacant = false;
+ RegisterValue value;
+
+ assert(hw_index < NumSupportedHardwareWatchpoints());
+
+ if (m_watchpoints_initialized == false)
+ {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (ReadRegister(dr7, value))
+ {
+ uint64_t val = value.GetAsUInt64();
+ is_vacant = (val & (3 << 2*hw_index)) == 0;
+ }
+
+ return is_vacant;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index)
+{
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+
+ if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
+ return false;
+
+ if (!(size == 1 || size == 2 || size == 4 || size == 8))
+ return false;
+
+ if (read == false && write == false)
+ return false;
+
+ if (!IsWatchpointVacant(hw_index))
+ return false;
+
+ // Set both dr7 (debug control register) and dri (debug address register).
+
+ // dr7{7-0} encodes the local/gloabl enable bits:
+ // global enable --. .-- local enable
+ // | |
+ // v v
+ // dr0 -> bits{1-0}
+ // dr1 -> bits{3-2}
+ // dr2 -> bits{5-4}
+ // dr3 -> bits{7-6}
+ //
+ // dr7{31-16} encodes the rw/len bits:
+ // b_x+3, b_x+2, b_x+1, b_x
+ // where bits{x+1, x} => rw
+ // 0b00: execute, 0b01: write, 0b11: read-or-write,
+ // 0b10: io read-or-write (unused)
+ // and bits{x+3, x+2} => len
+ // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+ //
+ // dr0 -> bits{19-16}
+ // dr1 -> bits{23-20}
+ // dr2 -> bits{27-24}
+ // dr3 -> bits{31-28}
+ if (hw_index < num_hw_watchpoints)
+ {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(dr7, current_dr7_bits))
+ {
+ uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
+ (1 << (2*hw_index) |
+ size_and_rw_bits(size, read, write) <<
+ (16+4*hw_index));
+
+ if (WriteRegister(dr0 + hw_index, RegisterValue(addr)) &&
+ WriteRegister(dr7, RegisterValue(new_dr7_bits)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints()
+{
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86_64.h Sat Sep 14 13:44:01 2013
@@ -13,7 +13,8 @@
#include "Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h"
class RegisterContextPOSIXProcessMonitor_x86_64:
- public RegisterContextPOSIX_x86_64
+ public RegisterContextPOSIX_x86_64,
+ public POSIXBreakpointProtocol
{
public:
RegisterContextPOSIXProcessMonitor_x86_64(lldb_private::Thread &thread,
@@ -33,12 +34,59 @@ protected:
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();
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.cpp?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.cpp Sat Sep 14 13:44:01 2013
@@ -258,7 +258,7 @@ unsigned RegisterContextPOSIX_i386::GetR
RegisterContextPOSIX_i386::RegisterContextPOSIX_i386(Thread &thread,
uint32_t concrete_frame_idx)
- : RegisterContextPOSIX(thread, concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx)
{
}
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_i386.h Sat Sep 14 13:44:01 2013
@@ -18,7 +18,7 @@
#include "RegisterContextPOSIX.h"
class RegisterContextPOSIX_i386 :
- public RegisterContextPOSIX
+ public lldb_private::RegisterContext
{
public:
RegisterContextPOSIX_i386(lldb_private::Thread &thread,
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.cpp?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.cpp Sat Sep 14 13:44:01 2013
@@ -483,7 +483,7 @@ bool RegisterContextPOSIX_x86_64::IsFPR(
RegisterContextPOSIX_x86_64::RegisterContextPOSIX_x86_64(Thread &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info)
- : RegisterContextPOSIX(thread, concrete_frame_idx)
+ : RegisterContext(thread, concrete_frame_idx)
{
m_register_info_ap.reset(register_info);
@@ -595,19 +595,6 @@ RegisterContextPOSIX_x86_64::GetRegister
return NULL;
}
-unsigned
-RegisterContextPOSIX_x86_64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers && "Invalid register offset.");
- return reg;
-}
-
const char *
RegisterContextPOSIX_x86_64::GetRegisterName(unsigned reg)
{
@@ -633,7 +620,8 @@ bool RegisterContextPOSIX_x86_64::CopyYM
if (!IsAVX(reg))
return false;
- if (byte_order == eByteOrderLittle) {
+ if (byte_order == eByteOrderLittle)
+ {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
m_ymm_set.ymm[reg - fpu_ymm0].bytes,
sizeof(RegisterContextPOSIX_x86_64::XMMReg));
@@ -643,7 +631,8 @@ bool RegisterContextPOSIX_x86_64::CopyYM
return true;
}
- if (byte_order == eByteOrderBig) {
+ if (byte_order == eByteOrderBig)
+ {
::memcpy(m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContextPOSIX_x86_64::XMMReg),
sizeof(RegisterContextPOSIX_x86_64::XMMReg));
@@ -661,7 +650,8 @@ bool RegisterContextPOSIX_x86_64::CopyXS
if (!IsAVX(reg))
return false;
- if (byte_order == eByteOrderLittle) {
+ if (byte_order == eByteOrderLittle)
+ {
::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes,
m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
sizeof(RegisterContextPOSIX_x86_64::XMMReg));
@@ -670,7 +660,8 @@ bool RegisterContextPOSIX_x86_64::CopyXS
sizeof(RegisterContextPOSIX_x86_64::YMMHReg));
return true;
}
- if (byte_order == eByteOrderBig) {
+ if (byte_order == eByteOrderBig)
+ {
::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContextPOSIX_x86_64::XMMReg),
m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
sizeof(RegisterContextPOSIX_x86_64::XMMReg));
@@ -693,230 +684,6 @@ RegisterContextPOSIX_x86_64::IsRegisterS
return (set_index < num_sets);
}
-bool
-RegisterContextPOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg, GetFPRType())) {
- if (!ReadFPR())
- return false;
- }
- else {
- bool success = ReadRegister(reg, value);
-
- // If an i386 register should be parsed from an x86_64 register...
- if (success && reg >= k_first_i386 && reg <= k_last_i386)
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info); // ...use the type specified by reg_info rather than the uint64_t default
- return success;
- }
-
- if (reg_info->encoding == eEncodingVector) {
- ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != ByteOrder::eByteOrderInvalid) {
- if (reg >= fpu_stmm0 && reg <= fpu_stmm7) {
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, byte_order);
- }
- if (reg >= fpu_xmm0 && reg <= fpu_xmm15) {
- value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, byte_order);
- }
- if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
- if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- value.SetBytes(m_ymm_set.ymm[reg - fpu_ymm0].bytes, reg_info->byte_size, byte_order);
- else
- return false;
- }
- return value.GetType() == RegisterValue::eTypeBytes;
- }
- return false;
- }
-
- // Note that lldb uses slightly different naming conventions from sys/user.h
- switch (reg)
- {
- default:
- return false;
- case fpu_dp:
- value = m_fpr.xstate.fxsave.dp;
- break;
- case fpu_fcw:
- value = m_fpr.xstate.fxsave.fcw;
- break;
- case fpu_fsw:
- value = m_fpr.xstate.fxsave.fsw;
- break;
- case fpu_ip:
- value = m_fpr.xstate.fxsave.ip;
- break;
- case fpu_fop:
- value = m_fpr.xstate.fxsave.fop;
- break;
- case fpu_ftw:
- value = m_fpr.xstate.fxsave.ftw;
- break;
- case fpu_mxcsr:
- value = m_fpr.xstate.fxsave.mxcsr;
- break;
- case fpu_mxcsrmask:
- value = m_fpr.xstate.fxsave.mxcsrmask;
- break;
- }
- return true;
-}
-
-bool
-RegisterContextPOSIX_x86_64::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, GetGPRSize());
- dst += GetGPRSize();
- }
- if (GetFPRType() == eFXSAVE)
- ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
-
- if (GetFPRType() == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
- success = CopyXSTATEtoYMM(reg, byte_order);
-
- if (success) {
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
- }
- }
- return success;
-}
-
-bool
-RegisterContextPOSIX_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg)) {
- return WriteRegister(reg, value);
- }
-
- if (IsFPR(reg, GetFPRType())) {
- switch (reg)
- {
- default:
- if (reg_info->encoding != eEncodingVector)
- return false;
-
- if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
- if (GetFPRType() != eXSAVE)
- return false; // the target processor does not support AVX
-
- // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
- ::memcpy (m_ymm_set.ymm[reg - fpu_ymm0].bytes, value.GetBytes(), value.GetByteSize());
- if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
- return false;
- }
- break;
- case fpu_dp:
- m_fpr.xstate.fxsave.dp = value.GetAsUInt64();
- break;
- case fpu_fcw:
- m_fpr.xstate.fxsave.fcw = value.GetAsUInt16();
- break;
- case fpu_fsw:
- m_fpr.xstate.fxsave.fsw = value.GetAsUInt16();
- break;
- case fpu_ip:
- m_fpr.xstate.fxsave.ip = value.GetAsUInt64();
- break;
- case fpu_fop:
- m_fpr.xstate.fxsave.fop = value.GetAsUInt16();
- break;
- case fpu_ftw:
- m_fpr.xstate.fxsave.ftw = value.GetAsUInt16();
- break;
- case fpu_mxcsr:
- m_fpr.xstate.fxsave.mxcsr = value.GetAsUInt32();
- break;
- case fpu_mxcsrmask:
- m_fpr.xstate.fxsave.mxcsrmask = value.GetAsUInt32();
- break;
- }
- if (WriteFPR()) {
- if (IsAVX(reg))
- return CopyYMMtoXSTATE(reg, GetByteOrder());
- return true;
- }
- }
- return false;
-}
-
-bool
-RegisterContextPOSIX_x86_64::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, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- if (GetFPRType() == eXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- success = WriteFPR();
- if (success) {
- success = true;
-
- if (GetFPRType() == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
- success = CopyYMMtoXSTATE(reg, byte_order);
- }
- }
- }
- }
- }
- return success;
-}
-
-bool
-RegisterContextPOSIX_x86_64::UpdateAfterBreakpoint()
-{
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
-
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
-
- SetPC(pc - 1);
- return true;
-}
-
uint32_t
RegisterContextPOSIX_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
uint32_t num)
@@ -1214,241 +981,3 @@ RegisterContextPOSIX_x86_64::ConvertRegi
return LLDB_INVALID_REGNUM;
}
-uint32_t
-RegisterContextPOSIX_x86_64::NumSupportedHardwareWatchpoints()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
-}
-
-bool
-RegisterContextPOSIX_x86_64::IsWatchpointVacant(uint32_t hw_index)
-{
- bool is_vacant = false;
- RegisterValue value;
-
- assert(hw_index < NumSupportedHardwareWatchpoints());
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (ReadRegister(dr7, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_vacant = (val & (3 << 2*hw_index)) == 0;
- }
-
- return is_vacant;
-}
-
-static uint32_t
-size_and_rw_bits(size_t size, bool read, bool write)
-{
- uint32_t rw;
- if (read) {
- rw = 0x3; // READ or READ/WRITE
- } else if (write) {
- rw = 0x1; // WRITE
- } else {
- assert(0 && "read and write cannot both be false");
- }
-
- switch (size) {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- default:
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- }
-}
-
-uint32_t
-RegisterContextPOSIX_x86_64::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
-RegisterContextPOSIX_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
- if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
- return false;
-
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return false;
-
- if (read == false && write == false)
- return false;
-
- if (!IsWatchpointVacant(hw_index))
- return false;
-
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/gloabl enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write,
- // 0b10: io read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- if (hw_index < num_hw_watchpoints)
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(dr7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
- (1 << (2*hw_index) |
- size_and_rw_bits(size, read, write) <<
- (16+4*hw_index));
-
- if (WriteRegister(dr0 + hw_index, RegisterValue(addr)) &&
- WriteRegister(dr7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-bool
-RegisterContextPOSIX_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(dr7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
-
- if (WriteRegister(dr7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-bool
-RegisterContextPOSIX_x86_64::IsWatchpointHit(uint32_t hw_index)
-{
- bool is_hit = false;
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue value;
-
- if (ReadRegister(dr6, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_hit = val & (1 << hw_index);
- }
- }
-
- return is_hit;
-}
-
-addr_t
-RegisterContextPOSIX_x86_64::GetWatchpointAddress(uint32_t hw_index)
-{
- addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- if (!IsWatchpointVacant(hw_index))
- {
- RegisterValue value;
-
- if (ReadRegister(dr0 + hw_index, value))
- wp_monitor_addr = value.GetAsUInt64();
- }
- }
-
- return wp_monitor_addr;
-}
-
-
-bool
-RegisterContextPOSIX_x86_64::ClearWatchpointHits()
-{
- return WriteRegister(dr6, RegisterValue((uint64_t)0));
-}
-
-bool
-RegisterContextPOSIX_x86_64::HardwareSingleStep(bool enable)
-{
- enum { TRACE_BIT = 0x100 };
- uint64_t rflags;
-
- if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
- return false;
-
- if (enable)
- {
- if (rflags & TRACE_BIT)
- return true;
-
- rflags |= TRACE_BIT;
- }
- else
- {
- if (!(rflags & TRACE_BIT))
- return false;
-
- rflags &= ~TRACE_BIT;
- }
-
- return WriteRegisterFromUnsigned(gpr_rflags, rflags);
-}
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86_64.h Sat Sep 14 13:44:01 2013
@@ -128,7 +128,7 @@ enum
};
class RegisterContextPOSIX_x86_64
- : public RegisterContextPOSIX
+ : public lldb_private::RegisterContext
{
public:
RegisterContextPOSIX_x86_64 (lldb_private::Thread &thread,
@@ -164,60 +164,12 @@ public:
const lldb_private::RegisterSet *
GetRegisterSet(size_t set);
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
-
const char *
GetRegisterName(unsigned reg);
- virtual bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- virtual bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
uint32_t
ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
- uint32_t
- NumSupportedHardwareWatchpoints();
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t, size_t size, bool read, bool write);
-
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool
- HardwareSingleStep(bool enable);
-
- bool
- UpdateAfterBreakpoint();
-
- bool
- IsWatchpointVacant(uint32_t hw_index);
-
- bool
- IsWatchpointHit (uint32_t hw_index);
-
- lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index);
-
- bool
- ClearWatchpointHits();
-
//---------------------------------------------------------------------------
// Generic floating-point registers
//---------------------------------------------------------------------------
@@ -304,7 +256,8 @@ public:
struct FPR
{
// Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE {
+ union XSTATE
+ {
FXSAVE fxsave; // Generic floating-point registers.
XSAVE xsave; // x86 extended processor state.
} xstate;
@@ -318,12 +271,6 @@ protected:
virtual const lldb_private::RegisterInfo *
GetRegisterInfo();
- virtual bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value) = 0;
-
- virtual bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value) = 0;
-
static bool
IsGPR(unsigned reg);
Modified: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp Sat Sep 14 13:44:01 2013
@@ -86,12 +86,6 @@ RegisterContextCorePOSIX_x86_64::WriteAl
}
bool
-RegisterContextCorePOSIX_x86_64::UpdateAfterBreakpoint()
-{
- return false;
-}
-
-bool
RegisterContextCorePOSIX_x86_64::HardwareSingleStep(bool enable)
{
return false;
Modified: lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h?rev=190757&r1=190756&r2=190757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h Sat Sep 14 13:44:01 2013
@@ -26,20 +26,17 @@ public:
virtual bool
ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
virtual bool
WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+ ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
bool
- HardwareSingleStep(bool enable);
+ WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
bool
- UpdateAfterBreakpoint();
+ HardwareSingleStep(bool enable);
protected:
bool
@@ -54,9 +51,6 @@ protected:
bool
WriteFPR();
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value) { return false; }
- bool WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value) { return false; }
-
private:
uint8_t *m_gpregset;
};
More information about the lldb-commits
mailing list