LLDB  mainline
RegisterContextPOSIXProcessMonitor_mips64.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIXProcessMonitor_mips64.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 
14 #include "ProcessFreeBSD.h"
15 #include "ProcessMonitor.h"
17 
18 using namespace lldb_private;
19 using namespace lldb;
20 
21 #define REG_CONTEXT_SIZE (GetGPRSize())
22 
25  Thread &thread, uint32_t concrete_frame_idx,
27  : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) {}
28 
29 ProcessMonitor &RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() {
30  ProcessSP base = CalculateProcess();
31  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
32  return process->GetMonitor();
33 }
34 
36  ProcessMonitor &monitor = GetMonitor();
37  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
38 }
39 
41  // XXX not yet implemented
42  return false;
43 }
44 
46  ProcessMonitor &monitor = GetMonitor();
47  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
48 }
49 
51  // XXX not yet implemented
52  return false;
53 }
54 
56  const unsigned reg, RegisterValue &value) {
57  ProcessMonitor &monitor = GetMonitor();
58  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
60  value);
61 }
62 
64  const unsigned reg, const RegisterValue &value) {
65  unsigned reg_to_write = reg;
66  RegisterValue value_to_write = value;
67 
68  // Check if this is a subregister of a full register.
69  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
70  if (reg_info->invalidate_regs &&
71  (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
72  RegisterValue full_value;
73  uint32_t full_reg = reg_info->invalidate_regs[0];
74  const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
75 
76  // Read the full register.
77  if (ReadRegister(full_reg_info, full_value)) {
78  Status error;
79  ByteOrder byte_order = GetByteOrder();
80  uint8_t dst[RegisterValue::kMaxRegisterByteSize];
81 
82  // Get the bytes for the full register.
83  const uint32_t dest_size = full_value.GetAsMemoryData(
84  full_reg_info, dst, sizeof(dst), byte_order, error);
85  if (error.Success() && dest_size) {
86  uint8_t src[RegisterValue::kMaxRegisterByteSize];
87 
88  // Get the bytes for the source data.
89  const uint32_t src_size = value.GetAsMemoryData(
90  reg_info, src, sizeof(src), byte_order, error);
91  if (error.Success() && src_size && (src_size < dest_size)) {
92  // Copy the src bytes to the destination.
93  memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
94  // Set this full register as the value to write.
95  value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
96  value_to_write.SetType(full_reg_info);
97  reg_to_write = full_reg;
98  }
99  }
100  }
101  }
102 
103  ProcessMonitor &monitor = GetMonitor();
104  return monitor.WriteRegisterValue(
105  m_thread.GetID(), GetRegisterOffset(reg_to_write),
106  GetRegisterName(reg_to_write), value_to_write);
107 }
108 
110  const RegisterInfo *reg_info, RegisterValue &value) {
111  if (!reg_info)
112  return false;
113 
114  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
115 
116  if (IsFPR(reg)) {
117  if (!ReadFPR())
118  return false;
119  } else {
120  uint32_t full_reg = reg;
121  bool is_subreg = reg_info->invalidate_regs &&
122  (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
123 
124  if (is_subreg) {
125  // Read the full aligned 64-bit register.
126  full_reg = reg_info->invalidate_regs[0];
127  }
128 
129  bool success = ReadRegister(full_reg, value);
130 
131  if (success) {
132  // If our read was not aligned (for ah,bh,ch,dh), shift our returned
133  // value one byte to the right.
134  if (is_subreg && (reg_info->byte_offset & 0x1))
135  value.SetUInt64(value.GetAsUInt64() >> 8);
136 
137  // If our return byte size was greater than the return value reg size,
138  // then use the type specified by reg_info rather than the uint64_t
139  // default
140  if (value.GetByteSize() > reg_info->byte_size)
141  value.SetType(reg_info);
142  }
143  return success;
144  }
145 
146  return false;
147 }
148 
150  const RegisterInfo *reg_info, const RegisterValue &value) {
151  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
152 
153  if (IsGPR(reg))
154  return WriteRegister(reg, value);
155 
156  return false;
157 }
158 
160  DataBufferSP &data_sp) {
161  bool success = false;
162  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
163  if (data_sp && ReadGPR() && ReadFPR()) {
164  uint8_t *dst = data_sp->GetBytes();
165  success = dst != 0;
166 
167  if (success) {
168  ::memcpy(dst, &m_gpr_mips64, GetGPRSize());
169  }
170  }
171  return success;
172 }
173 
175  const DataBufferSP &data_sp) {
176  bool success = false;
177  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
178  uint8_t *src = data_sp->GetBytes();
179  if (src) {
180  ::memcpy(&m_gpr_mips64, src, GetGPRSize());
181 
182  if (WriteGPR()) {
183  src += GetGPRSize();
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  bool enable) {
210  return false;
211 }
212 
214  // PC points one byte past the int3 responsible for the breakpoint.
216 
217  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
218  return false;
219 
220  SetPC(pc - 1);
221  return true;
222 }
223 
225  unsigned offset) {
226  unsigned reg;
227  for (reg = 0; reg < k_num_registers_mips64; reg++) {
228  if (GetRegisterInfo()[reg].byte_offset == offset)
229  break;
230  }
231  assert(reg < k_num_registers_mips64 && "Invalid register offset.");
232  return reg;
233 }
234 
236  uint32_t hw_index) {
237  return false;
238 }
239 
241  return false;
242 }
243 
245  uint32_t hw_index) {
246  return LLDB_INVALID_ADDRESS;
247 }
248 
250  uint32_t hw_index) {
251  return false;
252 }
253 
255  addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
256  return false;
257 }
258 
259 uint32_t
261  return 0;
262 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value)
uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write)
RegisterInfo interface to patch RegisterInfo structure for archs.
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
const char * GetRegisterName(unsigned reg)
virtual const lldb_private::RegisterInfo * GetRegisterInfo()
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
A subclass of DataBuffer that stores a data buffer on the heap.
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
bool UpdateAfterBreakpoint()
Updates the register state of the associated thread after hitting a breakpoint (if that make sense fo...
Manages communication with the inferior (debugee) process.
bool WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
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.
uint64_t GetPC(uint64_t fail_value=LLDB_INVALID_ADDRESS)
ProcessMonitor & GetMonitor()
RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info)
bool Success() const
Test for success condition.
Definition: Status.cpp:287
uint64_t addr_t
Definition: lldb-types.h:83
virtual unsigned GetRegisterSize(unsigned reg)
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
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
virtual unsigned GetRegisterOffset(unsigned reg)
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