LLDB  mainline
RegisterContextPOSIXProcessMonitor_arm.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIXProcessMonitor_arm.cpp -----------*- C++ -*-===//
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 
9 #include "lldb/Target/Thread.h"
12 
13 #include "ProcessFreeBSD.h"
14 #include "ProcessMonitor.h"
17 
18 using namespace lldb_private;
19 using namespace lldb;
20 
21 #define REG_CONTEXT_SIZE (GetGPRSize())
22 
24  Thread &thread, uint32_t concrete_frame_idx,
26  : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info) {}
27 
28 ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm::GetMonitor() {
29  ProcessSP base = CalculateProcess();
30  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
31  return process->GetMonitor();
32 }
33 
35  ProcessMonitor &monitor = GetMonitor();
36  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
37 }
38 
40  ProcessMonitor &monitor = GetMonitor();
41  return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
42 }
43 
45  ProcessMonitor &monitor = GetMonitor();
46  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
47 }
48 
50  ProcessMonitor &monitor = GetMonitor();
51  return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
52 }
53 
55  const unsigned reg, RegisterValue &value) {
56  ProcessMonitor &monitor = GetMonitor();
57  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
59  value);
60 }
61 
63  const unsigned reg, const RegisterValue &value) {
64  unsigned reg_to_write = reg;
65  RegisterValue value_to_write = value;
66 
67  // Check if this is a subregister of a full register.
68  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
69  if (reg_info->invalidate_regs &&
70  (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
71  RegisterValue full_value;
72  uint32_t full_reg = reg_info->invalidate_regs[0];
73  const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
74 
75  // Read the full register.
76  if (ReadRegister(full_reg_info, full_value)) {
77  Status error;
78  ByteOrder byte_order = GetByteOrder();
79  uint8_t dst[RegisterValue::kMaxRegisterByteSize];
80 
81  // Get the bytes for the full register.
82  const uint32_t dest_size = full_value.GetAsMemoryData(
83  full_reg_info, dst, sizeof(dst), byte_order, error);
84  if (error.Success() && dest_size) {
85  uint8_t src[RegisterValue::kMaxRegisterByteSize];
86 
87  // Get the bytes for the source data.
88  const uint32_t src_size = value.GetAsMemoryData(
89  reg_info, src, sizeof(src), byte_order, error);
90  if (error.Success() && src_size && (src_size < dest_size)) {
91  // Copy the src bytes to the destination.
92  memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
93  // Set this full register as the value to write.
94  value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
95  value_to_write.SetType(full_reg_info);
96  reg_to_write = full_reg;
97  }
98  }
99  }
100  }
101 
102  ProcessMonitor &monitor = GetMonitor();
103  return monitor.WriteRegisterValue(
104  m_thread.GetID(), GetRegisterOffset(reg_to_write),
105  GetRegisterName(reg_to_write), value_to_write);
106 }
107 
109  const RegisterInfo *reg_info, RegisterValue &value) {
110  if (!reg_info)
111  return false;
112 
113  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
114 
115  if (IsFPR(reg)) {
116  if (!ReadFPR())
117  return false;
118  } else {
119  return ReadRegister(reg, value);
120  }
121 
122  // Get pointer to m_fpr variable and set the data from it.
123  assert(reg_info->byte_offset < sizeof m_fpr);
124  uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
125  switch (reg_info->byte_size) {
126  case 2:
127  value.SetUInt16(*(uint16_t *)src);
128  return true;
129  case 4:
130  value.SetUInt32(*(uint32_t *)src);
131  return true;
132  case 8:
133  value.SetUInt64(*(uint64_t *)src);
134  return true;
135  default:
136  assert(false && "Unhandled data size.");
137  return false;
138  }
139 }
140 
142  const RegisterInfo *reg_info, const RegisterValue &value) {
143  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
144 
145  if (IsGPR(reg)) {
146  return WriteRegister(reg, value);
147  } else if (IsFPR(reg)) {
148  return WriteFPR();
149  }
150 
151  return false;
152 }
153 
155  DataBufferSP &data_sp) {
156  bool success = false;
157  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
158  if (data_sp && ReadGPR() && ReadFPR()) {
159  uint8_t *dst = data_sp->GetBytes();
160  success = dst != 0;
161 
162  if (success) {
163  ::memcpy(dst, &m_gpr_arm, GetGPRSize());
164  dst += GetGPRSize();
165  ::memcpy(dst, &m_fpr, sizeof(m_fpr));
166  }
167  }
168  return success;
169 }
170 
172  const DataBufferSP &data_sp) {
173  bool success = false;
174  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
175  uint8_t *src = data_sp->GetBytes();
176  if (src) {
177  ::memcpy(&m_gpr_arm, src, GetGPRSize());
178 
179  if (WriteGPR()) {
180  src += GetGPRSize();
181  ::memcpy(&m_fpr, src, sizeof(m_fpr));
182 
183  success = WriteFPR();
184  }
185  }
186  }
187  return success;
188 }
189 
191  addr_t addr, size_t size, bool read, bool write) {
192  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
193  uint32_t hw_index;
194 
195  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
196  if (IsWatchpointVacant(hw_index))
197  return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
198  }
199 
200  return LLDB_INVALID_INDEX32;
201 }
202 
204  uint32_t hw_index) {
205  return false;
206 }
207 
209  return false;
210 }
211 
214 
215  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
216  return false;
217 
218  return true;
219 }
220 
222  unsigned offset) {
223  unsigned reg;
224  for (reg = 0; reg < k_num_registers_arm; reg++) {
225  if (GetRegisterInfo()[reg].byte_offset == offset)
226  break;
227  }
228  assert(reg < k_num_registers_arm && "Invalid register offset.");
229  return reg;
230 }
231 
233  uint32_t hw_index) {
234  return false;
235 }
236 
238  return false;
239 }
240 
242  uint32_t hw_index) {
243  return LLDB_INVALID_ADDRESS;
244 }
245 
247  uint32_t hw_index) {
248  return false;
249 }
250 
252  addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
253  return false;
254 }
255 
256 uint32_t
258  return 0;
259 }
virtual const lldb_private::RegisterInfo * GetRegisterInfo()
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
RegisterInfo interface to patch RegisterInfo structure for archs.
virtual unsigned GetRegisterOffset(unsigned reg)
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write)
bool UpdateAfterBreakpoint()
Updates the register state of the associated thread after hitting a breakpoint (if that make sense fo...
A subclass of DataBuffer that stores a data buffer on the heap.
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
const char * GetRegisterName(unsigned reg)
void SetUInt16(uint16_t uint)
bool ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
Reads all floating point registers into the specified buffer.
Manages communication with the inferior (debugee) process.
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
uint64_t GetPC(uint64_t fail_value=LLDB_INVALID_ADDRESS)
ProcessMonitor & GetMonitor()
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
struct RegisterContextPOSIX_arm::FPU m_fpr
bool Success() const
Test for success condition.
Definition: Status.cpp:287
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
virtual unsigned GetRegisterSize(unsigned reg)
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index)
unsigned GetRegisterIndexFromOffset(unsigned offset)
Determines the index in lldb&#39;s register file given a kernel byte offset.
bool WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value)
bool WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
Writes all floating point registers into the specified buffer.
uint64_t addr_t
Definition: lldb-types.h:83
bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value)
Definition: SBAddress.h:15
bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, unsigned size, lldb_private::RegisterValue &value)
Reads the contents from the register identified by the given (architecture dependent) offset...
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
lldb::ProcessSP CalculateProcess() override
RegisterContextPOSIXProcessMonitor_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info)
uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]
void SetType(RegisterValue::Type type)
Definition: RegisterValue.h:83
bool ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
Reads all general purpose registers into the specified buffer.
bool WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, const lldb_private::RegisterValue &value)
Writes the given value to the register identified by the given (architecture dependent) offset...
An error handling class.
Definition: Status.h:44
bool WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
Writes all general purpose registers into the specified buffer.
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90