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