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