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; }; _______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits