LLDB  mainline
RegisterContextWindows.cpp
Go to the documentation of this file.
1 //===-- RegisterContextWindows.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "lldb/Utility/Status.h"
14 
15 #include "ProcessWindowsLog.h"
16 #include "RegisterContextWindows.h"
17 #include "TargetThreadWindows.h"
18 
19 #include "llvm/ADT/STLExtras.h"
20 #include "lldb/Target/Target.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 const DWORD kWinContextFlags = CONTEXT_ALL;
26 
27 // Constructors and Destructors
28 RegisterContextWindows::RegisterContextWindows(Thread &thread,
29  uint32_t concrete_frame_idx)
30  : RegisterContext(thread, concrete_frame_idx), m_context(),
31  m_context_stale(true) {}
32 
34 
36  m_context_stale = true;
37 }
38 
40  lldb::DataBufferSP &data_sp) {
41 
43  return false;
44 
45  data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
46  memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
47 
48  return true;
49 }
50 
52  const lldb::DataBufferSP &data_sp) {
53  assert(data_sp->GetByteSize() >= sizeof(m_context));
54  memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
55 
56  return ApplyAllRegisterValues();
57 }
58 
60  lldb::RegisterKind kind, uint32_t num) {
61  const uint32_t num_regs = GetRegisterCount();
62 
63  assert(kind < kNumRegisterKinds);
64  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
65  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
66 
67  if (reg_info->kinds[kind] == num)
68  return reg_idx;
69  }
70 
71  return LLDB_INVALID_REGNUM;
72 }
73 
74 bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
75 
77  lldb::addr_t address,
78  uint32_t size, bool read,
79  bool write) {
81  return false;
82 
83  switch (size) {
84  case 1:
85  case 2:
86  case 4:
87 #if defined(_WIN64)
88  case 8:
89 #endif
90  break;
91  default:
92  return false;
93  }
94 
96  return false;
97 
98 #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
99  unsigned shift = 2 * slot;
100  m_context.Dr7 |= 1ULL << shift;
101 
102  (&m_context.Dr0)[slot] = address;
103 
104  shift = 18 + 4 * slot;
105  m_context.Dr7 &= ~(3ULL << shift);
106  m_context.Dr7 |= (size == 8 ? 2ULL : size - 1) << shift;
107 
108  shift = 16 + 4 * slot;
109  m_context.Dr7 &= ~(3ULL << shift);
110  m_context.Dr7 |= (read ? 3ULL : (write ? 1ULL : 0)) << shift;
111 
112  return ApplyAllRegisterValues();
113 
114 #else
116  LLDB_LOG(log, "hardware breakpoints not currently supported on this arch");
117  return false;
118 #endif
119 }
120 
122  if (slot >= NUM_HARDWARE_BREAKPOINT_SLOTS)
123  return false;
124 
125  if (!CacheAllRegisterValues())
126  return false;
127 
128 #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
129  unsigned shift = 2 * slot;
130  m_context.Dr7 &= ~(1ULL << shift);
131 
132  return ApplyAllRegisterValues();
133 #else
134  return false;
135 #endif
136 }
137 
139  if (!CacheAllRegisterValues())
140  return LLDB_INVALID_INDEX32;
141 
142 #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
143  for (unsigned i = 0UL; i < NUM_HARDWARE_BREAKPOINT_SLOTS; i++)
144  if (m_context.Dr6 & (1ULL << i))
145  return i;
146 #endif
147 
148  return LLDB_INVALID_INDEX32;
149 }
150 
153  if (!m_context_stale)
154  return true;
155 
156  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
157  memset(&m_context, 0, sizeof(m_context));
158  m_context.ContextFlags = kWinContextFlags;
159  if (::SuspendThread(
161  (DWORD)-1) {
162  return false;
163  }
164  if (!::GetThreadContext(
166  &m_context)) {
167  LLDB_LOG(
168  log,
169  "GetThreadContext failed with error {0} while caching register values.",
170  ::GetLastError());
171  return false;
172  }
173  if (::ResumeThread(
175  (DWORD)-1) {
176  return false;
177  }
178  LLDB_LOG(log, "successfully updated the register values.");
179  m_context_stale = false;
180  return true;
181 }
182 
184  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
185  return ::SetThreadContext(
187 }
lldb-private-types.h
lldb_private::HostThread::GetNativeThread
HostNativeThread & GetNativeThread()
Definition: HostThread.cpp:32
WINDOWS_LOG_REGISTERS
#define WINDOWS_LOG_REGISTERS
Definition: ProcessWindowsLog.h:20
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:91
lldb_private::RegisterContextWindows::GetTriggeredHardwareBreakpointSlotId
uint32_t GetTriggeredHardwareBreakpointSlotId()
Definition: RegisterContextWindows.cpp:138
lldb_private::RegisterContext::GetRegisterCount
virtual size_t GetRegisterCount()=0
lldb_private::RegisterContextWindows::ApplyAllRegisterValues
virtual bool ApplyAllRegisterValues()
Definition: RegisterContextWindows.cpp:183
TargetThreadWindows.h
lldb_private::TargetThreadWindows
Definition: TargetThreadWindows.h:24
lldb::kNumRegisterKinds
@ kNumRegisterKinds
Definition: lldb-enumerations.h:235
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::RegisterContext::GetRegisterInfoAtIndex
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
RegisterContextWindows.h
lldb_private::RegisterContextWindows::HardwareSingleStep
bool HardwareSingleStep(bool enable) override
Definition: RegisterContextWindows.cpp:74
lldb_private::RegisterContextWindows::m_context
CONTEXT m_context
Definition: RegisterContextWindows.h:55
ProcessWindowsLog.h
Target.h
lldb_private::RegisterContext::m_thread
Thread & m_thread
Definition: RegisterContext.h:234
lldb_private::Thread
Definition: Thread.h:60
lldb_private::RegisterContextWindows::CacheAllRegisterValues
virtual bool CacheAllRegisterValues()
Definition: RegisterContextWindows.cpp:151
lldb_private::RegisterContextWindows::AddHardwareBreakpoint
bool AddHardwareBreakpoint(uint32_t slot, lldb::addr_t address, uint32_t size, bool read, bool write)
Definition: RegisterContextWindows.cpp:76
lldb_private::RegisterContextWindows::WriteAllRegisterValues
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
Definition: RegisterContextWindows.cpp:51
lldb_private::RegisterContextWindows::InvalidateAllRegisters
void InvalidateAllRegisters() override
Definition: RegisterContextWindows.cpp:35
lldb_private::RegisterContextWindows::ConvertRegisterKindToRegisterNumber
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
Definition: RegisterContextWindows.cpp:59
kWinContextFlags
const DWORD kWinContextFlags
Definition: RegisterContextWindows.cpp:25
lldb_private::HostNativeThreadBase::GetSystemHandle
lldb::thread_t GetSystemHandle() const
Definition: HostNativeThreadBase.cpp:23
lldb_private::RegisterContext
Definition: RegisterContext.h:17
lldb_private::RegisterContextWindows::ReadAllRegisterValues
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override
Definition: RegisterContextWindows.cpp:39
lldb_private::RegisterContextWindows::NUM_HARDWARE_BREAKPOINT_SLOTS
static constexpr unsigned NUM_HARDWARE_BREAKPOINT_SLOTS
Definition: RegisterContextWindows.h:50
lldb::RegisterKind
RegisterKind
Register numbering types.
Definition: lldb-enumerations.h:227
lldb_private::RegisterContextWindows::~RegisterContextWindows
virtual ~RegisterContextWindows()
Definition: RegisterContextWindows.cpp:33
uint32_t
lldb_private::RegisterContextWindows::RemoveHardwareBreakpoint
bool RemoveHardwareBreakpoint(uint32_t slot)
Definition: RegisterContextWindows.cpp:121
lldb_private::ProcessWindowsLog::GetLogIfAny
static Log * GetLogIfAny(uint32_t mask)
Definition: ProcessWindowsLog.h:31
windows.h
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::RegisterContextWindows::m_context_stale
bool m_context_stale
Definition: RegisterContextWindows.h:56
LLDB_INVALID_INDEX32
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:87
lldb_private::Log
Definition: Log.h:49
lldb_private::TargetThreadWindows::GetHostThread
HostThread GetHostThread() const
Definition: TargetThreadWindows.h:40
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb
Definition: SBAddress.h:15
HostThreadWindows.h
DataBufferHeap.h