pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lldb-netbsd: Add more watchpoint functions



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Mon Apr 10 18:06:39 2017 +0200
Changeset:	09e17cd15754d2f6d5bde552529edca80e468072

Modified Files:
	lldb-netbsd/distinfo
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
Added Files:
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h

Log Message:
lldb-netbsd: Add more watchpoint functions

This is work in progress with watchpoints for x86_64.

Sponsored by <The NetBSD Foundation>

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=09e17cd15754d2f6d5bde552529edca80e468072

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 lldb-netbsd/distinfo                               |   9 +-
 ..._Plugins_Process_NetBSD_NativeProcessNetBSD.cpp | 154 ++++++++++++
 ..._Process_NetBSD_NativeRegisterContextNetBSD.cpp |  44 ++++
 ...ns_Process_NetBSD_NativeRegisterContextNetBSD.h |  33 +++
 ...NetBSD_NativeRegisterContextNetBSD__x86__64.cpp | 261 +++++++++++++++++++++
 ...s_NetBSD_NativeRegisterContextNetBSD__x86__64.h |  45 ++++
 ...e_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp |  36 ++-
 ...rce_Plugins_Process_NetBSD_NativeThreadNetBSD.h |  10 +-
 8 files changed, 588 insertions(+), 4 deletions(-)

diffs:
diff --git a/lldb-netbsd/distinfo b/lldb-netbsd/distinfo
index 3c6330ba55..e1c2542975 100644
--- a/lldb-netbsd/distinfo
+++ b/lldb-netbsd/distinfo
@@ -13,6 +13,11 @@ SHA1 (llvm-3.6.2.src.tar.xz) = 7a00257eb2bc9431e4c77c3a36b033072c54bc7e
 RMD160 (llvm-3.6.2.src.tar.xz) = 521cbc5fe2925ea3c6e90c7a31f752a04045c972
 Size (llvm-3.6.2.src.tar.xz) = 12802380 bytes
 SHA1 (patch-source_Core_ArchSpec.cpp) = 1585f4ffa707bc69e96f7dd3b5137e00858ed7be
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = d19f2d0ef3957e20355d5864955ad869ec2ead2f
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = 8de6137551edc1747ad8d744cb456561214bd2d4
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = f20a1520d282f40c92408d3106a3bba1027e3069
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp) = abeb0ceb532831404f692f2e25532f81f2a83163
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h) = 30ef94fb108271313ec61cf4d293fe5d9709948b
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp) = 8cae520fcce66b16075d2ecb20cae338700ec506
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h) = e6f51be1b1a0d14242dffc971a71fb7b9e10fda8
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = 6bcf4b7fafe63e74e5f6127d5dc816e95070e7c6
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = d2586e2ecdc2c979c59fc1a6a569e7870d3334ba
 SHA1 (patch-source_Plugins_Process_elf-core_ProcessElfCore.cpp) = 91575c49560da29d5d83c446012ed04ca957d99c
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
new file mode 100644
index 0000000000..ecbac05671
--- /dev/null
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
@@ -0,0 +1,154 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+@@ -224,36 +224,75 @@ void NativeProcessNetBSD::MonitorSIGTRAP
+       PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
+ 
+   // Get details on the signal raised.
+-  if (siginfo_err.Success()) {
+-    switch (info.psi_siginfo.si_code) {
+-    case TRAP_BRKPT:
++  if (siginfo_err.Fail()) {
++    return;
++  }
++
++  switch (info.psi_siginfo.si_code) {
++  case TRAP_BRKPT:
++    for (const auto &thread_sp : m_threads) {
++      static_pointer_cast<NativeThreadNetBSD>(thread_sp)
++          ->SetStoppedByBreakpoint();
++      FixupBreakpointPCAsNeeded(
++          *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
++    }
++    SetState(StateType::eStateStopped, true);
++    break;
++  case TRAP_TRACE:
++    for (const auto &thread_sp : m_threads) {
++      static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
++    }
++    SetState(StateType::eStateStopped, true);
++    break;
++  case TRAP_EXEC: {
++    Error error = ReinitializeThreads();
++    if (error.Fail()) {
++      SetState(StateType::eStateInvalid);
++      return;
++    }
++
++    // Let our delegate know we have just exec'd.
++    NotifyDidExec();
++
++    SetState(StateType::eStateStopped, true);
++  } break;
++  case TRAP_DBREG: {
++    // If a watchpoint was hit, report it
++    uint32_t wp_index;
++    Error error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])->GetRegisterContext()->GetWatchpointHitIndex(
++        wp_index, (uintptr_t)info.psi_siginfo.si_addr);
++    if (error.Fail())
++      LLDB_LOG(log,
++               "received error while checking for watchpoint hits, pid = "
++               "{0}, LWP = {1}, error = {2}",
++               GetID(), info.psi_lwpid, error);
++    if (wp_index != LLDB_INVALID_INDEX32) {
+       for (const auto &thread_sp : m_threads) {
+         static_pointer_cast<NativeThreadNetBSD>(thread_sp)
+-            ->SetStoppedByBreakpoint();
+-        FixupBreakpointPCAsNeeded(
+-            *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
++          ->SetStoppedByWatchpoint(wp_index);
+       }
+       SetState(StateType::eStateStopped, true);
+       break;
+-    case TRAP_TRACE:
++    }
++
++    // If a breakpoint was hit, report it
++    uint32_t bp_index;
++    error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])->GetRegisterContext()->GetHardwareBreakHitIndex(
++        bp_index, (uintptr_t)info.psi_siginfo.si_addr);
++    if (error.Fail())
++      LLDB_LOG(log,
++               "received error while checking for hardware "
++               "breakpoint hits, pid = {0}, LWP = {1}, error = {2}",
++               GetID(), info.psi_lwpid, error);
++    if (bp_index != LLDB_INVALID_INDEX32) {
+       for (const auto &thread_sp : m_threads) {
+-        static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
++        static_pointer_cast<NativeThreadNetBSD>(thread_sp)
++            ->SetStoppedByBreakpoint();
+       }
+       SetState(StateType::eStateStopped, true);
+       break;
+-    case TRAP_EXEC: {
+-      Error error = ReinitializeThreads();
+-      if (error.Fail()) {
+-        SetState(StateType::eStateInvalid);
+-        return;
+-      }
+-
+-      // Let our delegate know we have just exec'd.
+-      NotifyDidExec();
+-
+-      SetState(StateType::eStateStopped, true);
+-    } break;
+     }
++  } break;
+   }
+ }
+ 
+@@ -328,8 +367,8 @@ Error NativeProcessNetBSD::FixupBreakpoi
+     return error;
+   } else
+     LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
+-  // First try probing for a breakpoint at a software breakpoint location: PC -
+-  // breakpoint size.
++  // First try probing for a breakpoint at a software breakpoint location: PC
++  // - breakpoint size.
+   const lldb::addr_t initial_pc_addr =
+       context_sp->GetPCfromBreakpointLocation();
+   lldb::addr_t breakpoint_addr = initial_pc_addr;
+@@ -439,7 +478,7 @@ Error NativeProcessNetBSD::Resume(const 
+     llvm_unreachable("Unexpected state");
+ 
+   default:
+-    return Error("NativeProcessLinux::%s (): unexpected state %s specified "
++    return Error("NativeProcessNetBSD::%s (): unexpected state %s specified "
+                  "for pid %" PRIu64 ", tid %" PRIu64,
+                  __FUNCTION__, StateAsCString(action->state), GetID(),
+                  thread_sp->GetID());
+@@ -540,8 +579,8 @@ Error NativeProcessNetBSD::GetMemoryRegi
+            "descending memory map entries detected, unexpected");
+     prev_base_address = proc_entry_info.GetRange().GetRangeBase();
+     UNUSED_IF_ASSERT_DISABLED(prev_base_address);
+-    // If the target address comes before this entry, indicate distance to next
+-    // region.
++    // If the target address comes before this entry, indicate distance to
++    // next region.
+     if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
+       range_info.GetRange().SetRangeBase(load_addr);
+       range_info.GetRange().SetByteSize(
+@@ -561,9 +600,8 @@ Error NativeProcessNetBSD::GetMemoryRegi
+   }
+   // If we made it here, we didn't find an entry that contained the given
+   // address. Return the
+-  // load_addr as start and the amount of bytes betwwen load address and the end
+-  // of the memory as
+-  // size.
++  // load_addr as start and the amount of bytes betwwen load address and the
++  // end of the memory as size.
+   range_info.GetRange().SetRangeBase(load_addr);
+   range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+   range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+@@ -722,8 +760,8 @@ Error NativeProcessNetBSD::LaunchInferio
+     LLDB_LOG(log, "waitpid for inferior failed with %s", error);
+ 
+     // Mark the inferior as invalid.
+-    // FIXME this could really use a new state - eStateLaunchFailure.  For now,
+-    // using eStateInvalid.
++    // FIXME this could really use a new state - eStateLaunchFailure.  For
++    // now, using eStateInvalid.
+     SetState(StateType::eStateInvalid);
+ 
+     return error;
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp
new file mode 100644
index 0000000000..5fc7a117f1
--- /dev/null
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp
@@ -0,0 +1,44 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+@@ -57,6 +57,22 @@ Error NativeRegisterContextNetBSD::Write
+   return DoWriteFPR(buf);
+ }
+ 
++Error NativeRegisterContextNetBSD::ReadDBR() {
++  void *buf = GetDBRBuffer();
++  if (!buf)
++    return Error("DBR buffer is NULL");
++
++  return DoReadDBR(buf);
++}
++
++Error NativeRegisterContextNetBSD::WriteDBR() {
++  void *buf = GetDBRBuffer();
++  if (!buf)
++    return Error("DBR buffer is NULL");
++
++  return DoWriteDBR(buf);
++}
++
+ Error NativeRegisterContextNetBSD::DoReadGPR(void *buf) {
+   return NativeProcessNetBSD::PtraceWrapper(PT_GETREGS, GetProcessPid(), buf,
+                                             m_thread.GetID());
+@@ -77,6 +93,16 @@ Error NativeRegisterContextNetBSD::DoWri
+                                             m_thread.GetID());
+ }
+ 
++Error NativeRegisterContextNetBSD::DoReadDBR(void *buf) {
++  return NativeProcessNetBSD::PtraceWrapper(PT_GETDBREGS, GetProcessPid(), buf,
++                                            m_thread.GetID());
++}
++
++Error NativeRegisterContextNetBSD::DoWriteDBR(void *buf) {
++  return NativeProcessNetBSD::PtraceWrapper(PT_SETDBREGS, GetProcessPid(), buf,
++                                            m_thread.GetID());
++}
++
+ NativeProcessNetBSD &NativeRegisterContextNetBSD::GetProcess() {
+   auto process_sp =
+       std::static_pointer_cast<NativeProcessNetBSD>(m_thread.GetProcess());
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h
new file mode 100644
index 0000000000..c825b8517e
--- /dev/null
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h
@@ -0,0 +1,33 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+@@ -41,6 +41,9 @@ protected:
+   virtual Error ReadFPR();
+   virtual Error WriteFPR();
+ 
++  virtual Error ReadDBR();
++  virtual Error WriteDBR();
++
+   virtual void *GetGPRBuffer() { return nullptr; }
+   virtual size_t GetGPRSize() {
+     return GetRegisterInfoInterface().GetGPRSize();
+@@ -49,12 +52,18 @@ protected:
+   virtual void *GetFPRBuffer() { return nullptr; }
+   virtual size_t GetFPRSize() { return 0; }
+ 
++  virtual void *GetDBRBuffer() { return nullptr; }
++  virtual size_t GetDBRSize() { return 0; }
++
+   virtual Error DoReadGPR(void *buf);
+   virtual Error DoWriteGPR(void *buf);
+ 
+   virtual Error DoReadFPR(void *buf);
+   virtual Error DoWriteFPR(void *buf);
+ 
++  virtual Error DoReadDBR(void *buf);
++  virtual Error DoWriteDBR(void *buf);
++
+   virtual NativeProcessNetBSD &GetProcess();
+   virtual ::pid_t GetProcessPid();
+ };
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp
new file mode 100644
index 0000000000..6093f0e082
--- /dev/null
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp
@@ -0,0 +1,261 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+@@ -143,8 +143,20 @@ NativeRegisterContextNetBSD_x86_64::GetR
+ 
+ int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
+     int reg_num) const {
+-  if (reg_num < lldb_fctrl_x86_64)
++  if (reg_num <= k_last_gpr_x86_64)
+     return GPRegSet;
++  else if (reg_num <= k_last_fpr_x86_64)
++    return FPRegSet;
++  else if (reg_num <= k_last_avx_x86_64)
++    return -1; // AVX
++  else if (reg_num <= k_last_mpxr_x86_64)
++    return -1; // MPXR
++  else if (reg_num <= k_last_mpxc_x86_64)
++    return -1; // MPXC
++  else if (reg_num <= k_last_avx_x86_64)
++    return -1; // AVX
++  else if (reg_num <= lldb_dr7_x86_64)
++    return -1; // AVX
+   else
+     return -1;
+ }
+@@ -157,6 +169,9 @@ int NativeRegisterContextNetBSD_x86_64::
+   case FPRegSet:
+     ReadFPR();
+     return 0;
++  case DBRegSet:
++    ReadDBR();
++    return 0;
+   default:
+     break;
+   }
+@@ -170,6 +185,9 @@ int NativeRegisterContextNetBSD_x86_64::
+   case FPRegSet:
+     WriteFPR();
+     return 0;
++  case DBRegSet:
++    WriteDBR();
++    return 0;
+   default:
+     break;
+   }
+@@ -480,4 +498,214 @@ Error NativeRegisterContextNetBSD_x86_64
+   return error;
+ }
+ 
++Error NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index,
++                                                         bool &is_hit) {
++  if (wp_index >= NumSupportedHardwareWatchpoints())
++    return Error("Watchpoint index out of range");
++  
++  RegisterValue reg_value;
++  Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
++  if (error.Fail()) {
++    is_hit = false;
++    return error;
++  } 
++    
++  uint64_t status_bits = reg_value.GetAsUInt64();
++   
++  is_hit = status_bits & (1 << wp_index);
++ 
++  return error;
++}
++
++Error NativeRegisterContextNetBSD_x86_64::GetWatchpointHitIndex(
++    uint32_t &wp_index, lldb::addr_t trap_addr) {
++  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
++  for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
++    bool is_hit;
++    Error error = IsWatchpointHit(wp_index, is_hit);
++    if (error.Fail()) {
++      wp_index = LLDB_INVALID_INDEX32;
++      return error;
++    } else if (is_hit) {
++      return error;
++    }
++  }
++  wp_index = LLDB_INVALID_INDEX32;
++  return Error();
++}
++
++Error NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
++                                                            bool &is_vacant) {
++  if (wp_index >= NumSupportedHardwareWatchpoints())
++    return Error("Watchpoint index out of range");
++
++  RegisterValue reg_value;
++  Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
++  if (error.Fail()) {
++    is_vacant = false;
++    return error;
++  }
++     
++  uint64_t control_bits = reg_value.GetAsUInt64();
++
++  is_vacant = !(control_bits & (1 << (2 * wp_index)));
++ 
++  return error;
++}
++
++Error NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
++    lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
++
++  if (wp_index >= NumSupportedHardwareWatchpoints())
++    return Error("Watchpoint index out of range");
++
++  // Read only watchpoints aren't supported on x86_64. Fall back to read/write
++  // waitchpoints instead.
++  // TODO: Add logic to detect when a write happens and ignore that watchpoint
++  // hit.
++  if (watch_flags == 0x2)
++    watch_flags = 0x3;
++     
++  if (watch_flags != 0x1 && watch_flags != 0x3)   
++    return Error("Invalid read/write bits for watchpoint");
++
++  if (size != 1 && size != 2 && size != 4 && size != 8)
++    return Error("Invalid size for watchpoint");
++ 
++  bool is_vacant;
++  Error error = IsWatchpointVacant(wp_index, is_vacant);
++  if (error.Fail())
++    return error;
++  if (!is_vacant)                                                                                                                     
++    return Error("Watchpoint index not vacant");
++
++  RegisterValue reg_value;
++  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
++  if (error.Fail())
++    return error;
++
++  // for watchpoints 0, 1, 2, or 3, respectively,
++  // set bits 1, 3, 5, or 7
++  uint64_t enable_bit = 1 << (2 * wp_index);
++
++  // set bits 16-17, 20-21, 24-25, or 28-29
++  // with 0b01 for write, and 0b11 for read/write
++  uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
++
++  // set bits 18-19, 22-23, 26-27, or 30-31
++  // with 0b00, 0b01, 0b10, or 0b11
++  // for 1, 2, 8 (if supported), or 4 bytes, respectively
++  uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);                                                           
++
++  uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
++
++  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
++
++  control_bits |= enable_bit | rw_bits | size_bits;
++
++  error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
++  if (error.Fail())
++    return error;
++
++  error =
++      WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
++  if (error.Fail())
++    return error;
++
++  error =
++      WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
++  if (error.Fail())
++    return error;
++
++  error.Clear();
++  return error;
++}
++
++bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
++    uint32_t wp_index) {
++  if (wp_index >= NumSupportedHardwareWatchpoints())
++    return false;
++
++  RegisterValue reg_value;
++    
++  // for watchpoints 0, 1, 2, or 3, respectively,
++  // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
++  Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
++  if (error.Fail())
++    return false;
++  uint64_t bit_mask = 1 << wp_index;
++  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
++  if (error.Fail())
++    return false;
++ 
++  // for watchpoints 0, 1, 2, or 3, respectively,
++  // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
++  // of the debug control register (DR7)
++  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
++  if (error.Fail())
++    return false;
++  bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
++  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
++      .Success();
++}
++
++Error NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
++  RegisterValue reg_value;
++
++  // clear bits {0-4} of the debug status register (DR6)
++  Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
++  if (error.Fail())
++    return error;
++  uint64_t bit_mask = 0xF;
++  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
++  if (error.Fail())
++    return error;
++ 
++  // clear bits {0-7,16-31} of the debug control register (DR7)
++  error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
++  if (error.Fail())
++    return error;
++  bit_mask = 0xFF | (0xFFFF << 16);
++  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
++}
++
++uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
++    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
++  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
++  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
++  for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
++    bool is_vacant;
++    Error error = IsWatchpointVacant(wp_index, is_vacant);
++    if (is_vacant) {
++      error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
++      if (error.Success())
++        return wp_index;
++    }
++    if (error.Fail() && log) {
++      log->Printf("NativeRegisterContextNetBSD_x86_64::%s Error: %s",
++                  __FUNCTION__, error.AsCString());
++    }
++  }
++  return LLDB_INVALID_INDEX32;
++}
++
++lldb::addr_t
++NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
++  if (wp_index >= NumSupportedHardwareWatchpoints())
++    return LLDB_INVALID_ADDRESS;
++  RegisterValue reg_value;
++  if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
++    return LLDB_INVALID_ADDRESS;
++  return reg_value.GetAsUInt64();
++}                                                                                                                                     
++
++uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() {
++  // Available debug address registers: dr0, dr1, dr2, dr3
++  return 4;
++}
++
+ #endif // defined(__x86_64__)
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h
new file mode 100644
index 0000000000..90301bce91
--- /dev/null
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h
@@ -0,0 +1,45 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+@@ -46,17 +46,39 @@ public:
+ 
+   Error WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+ 
++  Error IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
++                                    
++  Error GetWatchpointHitIndex(uint32_t &wp_index,
++                              lldb::addr_t trap_addr) override;
++
++  Error IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
++
++  bool ClearHardwareWatchpoint(uint32_t wp_index) override;
++
++  Error ClearAllHardwareWatchpoints() override;   
++                     
++  Error SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
++                                       uint32_t watch_flags, uint32_t wp_index);
++                      
++  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
++                                 uint32_t watch_flags) override;
++
++  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
++
++  uint32_t NumSupportedHardwareWatchpoints() override;
++
+ protected:
+   void *GetGPRBuffer() override { return &m_gpr_x86_64; }
+   void *GetFPRBuffer() override { return &m_fpr_x86_64; }
+ 
+ private:
+   // Private member types.
+-  enum { GPRegSet, FPRegSet };
++  enum { GPRegSet, FPRegSet, DBRegSet };
+ 
+   // Private member variables.
+   struct reg m_gpr_x86_64;
+   struct fpreg m_fpr_x86_64;
++  struct dbreg m_dbr_x86_64;
+ 
+   int GetSetForNativeRegNum(int reg_num) const;
+ 
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
index 33f75f702f..8d9cd97c18 100644
--- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
@@ -2,7 +2,41 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp.orig	2017-03-30 22:14:30.000000000 +0000
 +++ source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
-@@ -142,18 +142,61 @@ NativeRegisterContextSP NativeThreadNetB
+@@ -16,6 +16,9 @@
+ #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+ #include "lldb/Core/RegisterValue.h"
+ #include "lldb/Core/State.h"
++#include "lldb/Utility/LLDBAssert.h"
++
++#include <sstream>
+ 
+ using namespace lldb;
+ using namespace lldb_private;
+@@ -68,6 +71,23 @@ void NativeThreadNetBSD::SetStoppedByExe
+   m_stop_info.details.signal.signo = SIGTRAP;
+ }
+ 
++void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
++  SetStopped();
++
++  lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
++
++  std::ostringstream ostr;
++  ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
++  ostr << wp_index;
++
++  ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
++  
++  m_stop_description = ostr.str();
++  
++  m_stop_info.reason = StopReason::eStopReasonWatchpoint;
++  m_stop_info.details.signal.signo = SIGTRAP;
++}
++
+ void NativeThreadNetBSD::SetStopped() {
+   const StateType new_state = StateType::eStateStopped;
+   m_state = new_state;
+@@ -142,18 +162,61 @@ NativeRegisterContextSP NativeThreadNetB
  
  Error NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
                                          uint32_t watch_flags, bool hardware) {
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
index a7e2f5fc94..07de670a4e 100644
--- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
@@ -12,7 +12,15 @@ $NetBSD$
  namespace lldb_private {
  namespace process_netbsd {
  
-@@ -64,6 +67,9 @@ private:
+@@ -53,6 +56,7 @@ private:
+   void SetStoppedByBreakpoint();
+   void SetStoppedByTrace();
+   void SetStoppedByExec();
++  void SetStoppedByWatchpoint(uint32_t wp_index);
+   void SetStopped();
+   void SetRunning();
+   void SetStepping();
+@@ -64,6 +68,9 @@ private:
    ThreadStopInfo m_stop_info;
    NativeRegisterContextSP m_reg_context_sp;
    std::string m_stop_description;


Home | Main Index | Thread Index | Old Index