pkgsrc-WIP-changes archive

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

lldb-git: Push here patch that is pending upstream



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Sat Apr 15 00:01:51 2017 +0200
Changeset:	58cf50e3af4c263778f7a70e43119be66b1c2b61

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

Log Message:
lldb-git: Push here patch that is pending upstream

Introduce initial Debug Registers/NetBSD/amd64 support
https://reviews.llvm.org/D32080

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=58cf50e3af4c263778f7a70e43119be66b1c2b61

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

diffstat:
 lldb-git/distinfo                                  |   8 +
 ..._Plugins_Process_NetBSD_NativeProcessNetBSD.cpp | 194 +++++++++++++
 ..._Process_NetBSD_NativeRegisterContextNetBSD.cpp |  44 +++
 ...ns_Process_NetBSD_NativeRegisterContextNetBSD.h |  33 +++
 ...NetBSD_NativeRegisterContextNetBSD__x86__64.cpp | 313 +++++++++++++++++++++
 ...s_NetBSD_NativeRegisterContextNetBSD__x86__64.h |  46 +++
 ...e_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp | 104 +++++++
 ...rce_Plugins_Process_NetBSD_NativeThreadNetBSD.h |  32 +++
 ...lugins_Process_Utility_RegisterInfos__x86__64.h |  13 +
 9 files changed, 787 insertions(+)

diffs:
diff --git a/lldb-git/distinfo b/lldb-git/distinfo
index 7931384fd5..8641a0804f 100644
--- a/lldb-git/distinfo
+++ b/lldb-git/distinfo
@@ -12,3 +12,11 @@ Size (libcxx-3.6.2.src.tar.xz) = 944020 bytes
 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_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = e29554252e70fc9e1cb62b40ce32f93fad24d71b
+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) = b85fb334d5fdbfa55705a3a2a36b4b8ecef23054
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h) = 21d5cd9cb1632ed2bbd696f0c3bec68eebf0be83
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = d788ea7d92ffa31f2d6477e11129fc9b9fd0b8eb
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = d2586e2ecdc2c979c59fc1a6a569e7870d3334ba
+SHA1 (patch-source_Plugins_Process_Utility_RegisterInfos__x86__64.h) = 47d7dc03b7da83ff7f02b684b2188da53bf269d3
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
new file mode 100644
index 0000000000..cc38861118
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
@@ -0,0 +1,194 @@
+$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,83 @@ 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();
++
++    for (const auto &thread_sp : m_threads) {
++      static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByExec();
++    }
++    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 +375,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 +486,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 +587,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 +608,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 +768,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;
+@@ -766,6 +812,11 @@ Error NativeProcessNetBSD::LaunchInferio
+     return error;
+   }
+ 
++  for (const auto &thread_sp : m_threads) {
++    static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
++        SIGSTOP);
++  }
++
+   /* Set process stopped */
+   SetState(StateType::eStateStopped);
+ 
+@@ -894,6 +945,11 @@ NativeThreadNetBSDSP NativeProcessNetBSD
+     return -1;
+   }
+ 
++  for (const auto &thread_sp : m_threads) {
++    static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
++        SIGSTOP);
++  }
++
+   // Let our process instance know the thread has stopped.
+   SetState(StateType::eStateStopped);
+ 
+@@ -1007,7 +1063,6 @@ Error NativeProcessNetBSD::ReinitializeT
+   // Reinitialize from scratch threads and register them in process
+   while (info.pl_lwpid != 0) {
+     NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
+-    thread_sp->SetStoppedByExec();
+     error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
+     if (error.Fail()) {
+       return error;
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp
new file mode 100644
index 0000000000..5fc7a117f1
--- /dev/null
+++ b/lldb-git/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-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h
new file mode 100644
index 0000000000..c825b8517e
--- /dev/null
+++ b/lldb-git/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-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp
new file mode 100644
index 0000000000..a8c090f2f9
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp
@@ -0,0 +1,313 @@
+$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
+@@ -114,7 +114,7 @@ NativeRegisterContextNetBSD_x86_64::Nati
+     uint32_t concrete_frame_idx)
+     : NativeRegisterContextNetBSD(native_thread, concrete_frame_idx,
+                                   CreateRegisterInfoInterface(target_arch)),
+-      m_gpr_x86_64() {}
++      m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {}
+ 
+ // CONSIDER after local and llgs debugging are merged, register set support can
+ // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
+@@ -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 DBRegSet; // DBR
+   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;
+   }
+@@ -285,6 +303,16 @@ Error NativeRegisterContextNetBSD_x86_64
+   case lldb_es_x86_64:
+     reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES];
+     break;
++  case lldb_dr0_x86_64:
++  case lldb_dr1_x86_64:
++  case lldb_dr2_x86_64:
++  case lldb_dr3_x86_64:
++  case lldb_dr4_x86_64:
++  case lldb_dr5_x86_64:
++  case lldb_dr6_x86_64:
++  case lldb_dr7_x86_64:
++    reg_value = (uint64_t)m_dbr_x86_64.dr[reg - lldb_dr0_x86_64];
++    break;
+   }
+ 
+   return error;
+@@ -400,6 +428,16 @@ Error NativeRegisterContextNetBSD_x86_64
+   case lldb_es_x86_64:
+     m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64();
+     break;
++  case lldb_dr0_x86_64:
++  case lldb_dr1_x86_64:
++  case lldb_dr2_x86_64:
++  case lldb_dr3_x86_64:
++  case lldb_dr4_x86_64:
++  case lldb_dr5_x86_64:
++  case lldb_dr6_x86_64:
++  case lldb_dr7_x86_64:
++    m_dbr_x86_64.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
++    break;
+   }
+ 
+   if (WriteRegisterSet(set) != 0)
+@@ -480,4 +518,223 @@ 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;
++  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr6_x86_64);
++  Error error = ReadRegister(reg_info, 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;
++  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64);
++  Error error = ReadRegister(reg_info, 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;
++  const RegisterInfo *const reg_info_dr7 =
++      GetRegisterInfoAtIndex(lldb_dr7_x86_64);
++  error = ReadRegister(reg_info_dr7, 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;
++
++  const RegisterInfo *const reg_info_drN =
++      GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
++  error = WriteRegister(reg_info_drN, RegisterValue(addr));
++  if (error.Fail())
++    return error;
++
++  error = WriteRegister(reg_info_dr7, 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)
++  const RegisterInfo *const reg_info_dr6 =
++      GetRegisterInfoAtIndex(lldb_dr6_x86_64);
++  Error error = ReadRegister(reg_info_dr6, reg_value);
++  if (error.Fail())
++    return false;
++  uint64_t bit_mask = 1 << wp_index;
++  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  error = WriteRegister(reg_info_dr6, 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)
++  const RegisterInfo *const reg_info_dr7 =
++      GetRegisterInfoAtIndex(lldb_dr7_x86_64);
++  error = ReadRegister(reg_info_dr7, 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 WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
++}
++
++Error NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
++  RegisterValue reg_value;
++
++  // clear bits {0-4} of the debug status register (DR6)
++  const RegisterInfo *const reg_info_dr6 =
++      GetRegisterInfoAtIndex(lldb_dr6_x86_64);
++  Error error = ReadRegister(reg_info_dr6, reg_value);
++  if (error.Fail())
++    return error;
++  uint64_t bit_mask = 0xF;
++  uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
++  if (error.Fail())
++    return error;
++
++  // clear bits {0-7,16-31} of the debug control register (DR7)
++  const RegisterInfo *const reg_info_dr7 =
++      GetRegisterInfoAtIndex(lldb_dr7_x86_64);
++  error = ReadRegister(reg_info_dr7, reg_value);
++  if (error.Fail())
++    return error;
++  bit_mask = 0xFF | (0xFFFF << 16);
++  uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
++  return WriteRegister(reg_info_dr7, 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;
++  const RegisterInfo *const reg_info_drN =
++      GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index);
++  if (ReadRegister(reg_info_drN, 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-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h
new file mode 100644
index 0000000000..2d8e7a9cb4
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h
@@ -0,0 +1,46 @@
+$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,40 @@ 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; }
++  void *GetDBRBuffer() override { return &m_dbr_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-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
new file mode 100644
index 0000000000..6da4e546b5
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
@@ -0,0 +1,104 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+@@ -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) {
+-  return Error("Unimplemented");
++  if (!hardware)
++    return Error("not implemented");
++  if (m_state == eStateLaunching)
++    return Error();
++  Error error = RemoveWatchpoint(addr);
++  if (error.Fail())
++    return error;
++  NativeRegisterContextSP reg_ctx = GetRegisterContext();
++  uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
++  if (wp_index == LLDB_INVALID_INDEX32)
++    return Error("Setting hardware watchpoint failed.");
++  m_watchpoint_index_map.insert({addr, wp_index});
++  return Error();
+ }
+ 
+ Error NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
+-  return Error("Unimplemented");
++  auto wp = m_watchpoint_index_map.find(addr);
++  if (wp == m_watchpoint_index_map.end())
++    return Error();
++  uint32_t wp_index = wp->second;
++  m_watchpoint_index_map.erase(wp);
++  if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
++    return Error();
++  return Error("Clearing hardware watchpoint failed.");
+ }
+ 
+ Error NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
+                                                 size_t size) {
+-  return Error("Unimplemented");
++  if (m_state == eStateLaunching)
++    return Error();
++
++  Error error = RemoveHardwareBreakpoint(addr);
++  if (error.Fail())
++    return error;
++
++  NativeRegisterContextSP reg_ctx = GetRegisterContext();
++  uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
++
++  if (bp_index == LLDB_INVALID_INDEX32)
++    return Error("Setting hardware breakpoint failed.");
++
++  m_hw_break_index_map.insert({addr, bp_index});
++  return Error();
+ }
+ 
+ Error NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+-  return Error("Unimplemented");
++  auto bp = m_hw_break_index_map.find(addr);
++  if (bp == m_hw_break_index_map.end())
++    return Error();
++
++  uint32_t bp_index = bp->second;
++  if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
++    m_hw_break_index_map.erase(bp);
++    return Error();
++  }
++
++  return Error("Clearing hardware breakpoint failed.");
+ }
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
new file mode 100644
index 0000000000..07de670a4e
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
@@ -0,0 +1,32 @@
+$NetBSD$
+
+--- source/Plugins/Process/NetBSD/NativeThreadNetBSD.h.orig	2017-03-30 22:14:30.000000000 +0000
++++ source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+@@ -12,6 +12,9 @@
+ 
+ #include "lldb/Host/common/NativeThreadProtocol.h"
+ 
++#include <map>
++#include <string>
++
+ namespace lldb_private {
+ namespace process_netbsd {
+ 
+@@ -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;
++  using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
++  WatchpointIndexMap m_watchpoint_index_map;
++  WatchpointIndexMap m_hw_break_index_map;
+ };
+ 
+ typedef std::shared_ptr<NativeThreadNetBSD> NativeThreadNetBSDSP;
diff --git a/lldb-git/patches/patch-source_Plugins_Process_Utility_RegisterInfos__x86__64.h b/lldb-git/patches/patch-source_Plugins_Process_Utility_RegisterInfos__x86__64.h
new file mode 100644
index 0000000000..26f5d9e371
--- /dev/null
+++ b/lldb-git/patches/patch-source_Plugins_Process_Utility_RegisterInfos__x86__64.h
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- source/Plugins/Process/Utility/RegisterInfos_x86_64.h.orig	2016-12-17 10:29:58.000000000 +0000
++++ source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+@@ -148,7 +148,7 @@
+         DR_OFFSET(i), eEncodingUint, eFormatHex,                               \
+                   {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,                   \
+                    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,                   \
+-                   LLDB_INVALID_REGNUM },                                      \
++                   lldb_##reg##i##_x86_64 },                                   \
+                    nullptr, nullptr, nullptr, 0                                \
+   }
+ 


Home | Main Index | Thread Index | Old Index