LLDB  mainline
RegisterContext.cpp
Go to the documentation of this file.
1 //===-- RegisterContext.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 
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/Value.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/StackFrame.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
19 #include "lldb/Utility/Endian.h"
21 #include "lldb/Utility/Scalar.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 RegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
27  : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx),
28  m_stop_id(thread.GetProcess()->GetStopID()) {}
29 
31 
33  ProcessSP process_sp(m_thread.GetProcess());
34  bool invalidate = force;
35  uint32_t process_stop_id = UINT32_MAX;
36 
37  if (process_sp)
38  process_stop_id = process_sp->GetStopID();
39  else
40  invalidate = true;
41 
42  if (!invalidate)
43  invalidate = process_stop_id != GetStopID();
44 
45  if (invalidate) {
47  SetStopID(process_stop_id);
48  }
49 }
50 
51 const RegisterInfo *
52 RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name,
53  uint32_t start_idx) {
54  if (reg_name.empty())
55  return nullptr;
56 
57  const uint32_t num_registers = GetRegisterCount();
58  for (uint32_t reg = start_idx; reg < num_registers; ++reg) {
59  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
60 
61  if (reg_name.equals_lower(reg_info->name) ||
62  reg_name.equals_lower(reg_info->alt_name))
63  return reg_info;
64  }
65  return nullptr;
66 }
67 
70  RegisterInfo *reg_info) {
72 
73  // In MIPS, the floating point registers size is depends on FR bit of SR
74  // register. if SR.FR == 1 then all floating point registers are 64 bits.
75  // else they are all 32 bits.
76 
77  int expr_result;
78  uint32_t addr_size = arch.GetAddressByteSize();
79  const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
80  const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
81 
82  DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
83  arch.GetByteOrder(), addr_size);
84  ModuleSP opcode_ctx;
85  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr, 0,
86  dwarf_opcode_len);
87  Value result;
88  Status error;
89  const lldb::offset_t offset = 0;
90  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
91  offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr,
92  nullptr, result, &error)) {
93  expr_result = result.GetScalar().SInt(-1);
94  switch (expr_result) {
95  case 0:
96  return 4;
97  case 1:
98  return 8;
99  default:
100  return reg_info->byte_size;
101  }
102  } else {
103  printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
104  return reg_info->byte_size;
105  }
106 }
107 
109  uint32_t num) {
110  const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
111  if (reg_num == LLDB_INVALID_REGNUM)
112  return nullptr;
113  return GetRegisterInfoAtIndex(reg_num);
114 }
115 
117  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
118  if (reg_info)
119  return reg_info->name;
120  return nullptr;
121 }
122 
123 uint64_t RegisterContext::GetPC(uint64_t fail_value) {
126  uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value);
127 
128  if (pc != fail_value) {
129  TargetSP target_sp = m_thread.CalculateTarget();
130  if (target_sp) {
131  Target *target = target_sp.get();
132  if (target)
133  pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);
134  }
135  }
136 
137  return pc;
138 }
139 
140 bool RegisterContext::SetPC(uint64_t pc) {
143  bool success = WriteRegisterFromUnsigned(reg, pc);
144  if (success) {
145  StackFrameSP frame_sp(
147  if (frame_sp)
148  frame_sp->ChangePC(pc);
149  else
151  }
152  return success;
153 }
154 
156  TargetSP target_sp = m_thread.CalculateTarget();
157  Target *target = target_sp.get();
158 
159  lldb::addr_t callAddr = addr.GetCallableLoadAddress(target);
160  if (callAddr == LLDB_INVALID_ADDRESS)
161  return false;
162 
163  return SetPC(callAddr);
164 }
165 
166 uint64_t RegisterContext::GetSP(uint64_t fail_value) {
169  return ReadRegisterAsUnsigned(reg, fail_value);
170 }
171 
172 bool RegisterContext::SetSP(uint64_t sp) {
175  return WriteRegisterFromUnsigned(reg, sp);
176 }
177 
178 uint64_t RegisterContext::GetFP(uint64_t fail_value) {
181  return ReadRegisterAsUnsigned(reg, fail_value);
182 }
183 
184 bool RegisterContext::SetFP(uint64_t fp) {
187  return WriteRegisterFromUnsigned(reg, fp);
188 }
189 
190 uint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) {
193  return ReadRegisterAsUnsigned(reg, fail_value);
194 }
195 
196 uint64_t RegisterContext::GetFlags(uint64_t fail_value) {
199  return ReadRegisterAsUnsigned(reg, fail_value);
200 }
201 
203  uint64_t fail_value) {
204  if (reg != LLDB_INVALID_REGNUM)
205  return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value);
206  return fail_value;
207 }
208 
209 uint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
210  uint64_t fail_value) {
211  if (reg_info) {
212  RegisterValue value;
213  if (ReadRegister(reg_info, value))
214  return value.GetAsUInt64();
215  }
216  return fail_value;
217 }
218 
220  if (reg == LLDB_INVALID_REGNUM)
221  return false;
223 }
224 
225 bool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info,
226  uint64_t uval) {
227  if (reg_info) {
228  RegisterValue value;
229  if (value.SetUInt(uval, reg_info->byte_size))
230  return WriteRegister(reg_info, value);
231  }
232  return false;
233 }
234 
235 bool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {
236  uint32_t num_register_sets = context->GetRegisterSetCount();
237  // We don't know that two threads have the same register context, so require
238  // the threads to be the same.
239  if (context->GetThreadID() != GetThreadID())
240  return false;
241 
242  if (num_register_sets != GetRegisterSetCount())
243  return false;
244 
245  RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
246 
247  for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) {
248  const RegisterSet *const reg_set = GetRegisterSet(set_idx);
249 
250  const uint32_t num_registers = reg_set->num_registers;
251  for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {
252  const uint32_t reg = reg_set->registers[reg_idx];
253  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
254  if (!reg_info || reg_info->value_regs)
255  continue;
256  RegisterValue reg_value;
257 
258  // If we can reconstruct the register from the frame we are copying from,
259  // then do so, otherwise use the value from frame 0.
260  if (context->ReadRegister(reg_info, reg_value)) {
261  WriteRegister(reg_info, reg_value);
262  } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {
263  WriteRegister(reg_info, reg_value);
264  }
265  }
266  }
267  return true;
268 }
269 
271 
273 
275  size_t size) {
276  return LLDB_INVALID_INDEX32;
277 }
278 
280 
282 
284  bool read, bool write) {
285  return LLDB_INVALID_INDEX32;
286 }
287 
289  return false;
290 }
291 
292 bool RegisterContext::HardwareSingleStep(bool enable) { return false; }
293 
295  const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len,
296  RegisterValue &reg_value) {
297  Status error;
298  if (reg_info == nullptr) {
299  error.SetErrorString("invalid register info argument.");
300  return error;
301  }
302 
303  // Moving from addr into a register
304  //
305  // Case 1: src_len == dst_len
306  //
307  // |AABBCCDD| Address contents
308  // |AABBCCDD| Register contents
309  //
310  // Case 2: src_len > dst_len
311  //
312  // Status! (The register should always be big enough to hold the data)
313  //
314  // Case 3: src_len < dst_len
315  //
316  // |AABB| Address contents
317  // |AABB0000| Register contents [on little-endian hardware]
318  // |0000AABB| Register contents [on big-endian hardware]
319  if (src_len > RegisterValue::kMaxRegisterByteSize) {
320  error.SetErrorString("register too small to receive memory data");
321  return error;
322  }
323 
324  const uint32_t dst_len = reg_info->byte_size;
325 
326  if (src_len > dst_len) {
328  "%u bytes is too big to store in register %s (%u bytes)", src_len,
329  reg_info->name, dst_len);
330  return error;
331  }
332 
333  ProcessSP process_sp(m_thread.GetProcess());
334  if (process_sp) {
336 
337  // Read the memory
338  const uint32_t bytes_read =
339  process_sp->ReadMemory(src_addr, src, src_len, error);
340 
341  // Make sure the memory read succeeded...
342  if (bytes_read != src_len) {
343  if (error.Success()) {
344  // This might happen if we read _some_ bytes but not all
345  error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read,
346  src_len);
347  }
348  return error;
349  }
350 
351  // We now have a memory buffer that contains the part or all of the
352  // register value. Set the register value using this memory data.
353  // TODO: we might need to add a parameter to this function in case the byte
354  // order of the memory data doesn't match the process. For now we are
355  // assuming they are the same.
356  reg_value.SetFromMemoryData(reg_info, src, src_len,
357  process_sp->GetByteOrder(), error);
358  } else
359  error.SetErrorString("invalid process");
360 
361  return error;
362 }
363 
365  const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len,
366  const RegisterValue &reg_value) {
368 
369  Status error;
370 
371  ProcessSP process_sp(m_thread.GetProcess());
372  if (process_sp) {
373 
374  // TODO: we might need to add a parameter to this function in case the byte
375  // order of the memory data doesn't match the process. For now we are
376  // assuming they are the same.
377 
378  const uint32_t bytes_copied = reg_value.GetAsMemoryData(
379  reg_info, dst, dst_len, process_sp->GetByteOrder(), error);
380 
381  if (error.Success()) {
382  if (bytes_copied == 0) {
383  error.SetErrorString("byte copy failed.");
384  } else {
385  const uint32_t bytes_written =
386  process_sp->WriteMemory(dst_addr, dst, bytes_copied, error);
387  if (bytes_written != bytes_copied) {
388  if (error.Success()) {
389  // This might happen if we read _some_ bytes but not all
390  error.SetErrorStringWithFormat("only wrote %u of %u bytes",
391  bytes_written, bytes_copied);
392  }
393  }
394  }
395  }
396  } else
397  error.SetErrorString("invalid process");
398 
399  return error;
400 }
401 
403  lldb_private::RegisterCheckpoint &reg_checkpoint) {
404  return ReadAllRegisterValues(reg_checkpoint.GetData());
405 }
406 
408  const lldb_private::RegisterCheckpoint &reg_checkpoint) {
409  return WriteAllRegisterValues(reg_checkpoint.GetData());
410 }
411 
413  return m_thread.CalculateTarget();
414 }
415 
417  return m_thread.CalculateProcess();
418 }
419 
421  return m_thread.shared_from_this();
422 }
423 
425  // Register contexts might belong to many frames if we have inlined functions
426  // inside a frame since all inlined functions share the same registers, so we
427  // can't definitively say which frame we come from...
428  return StackFrameSP();
429 }
430 
433 }
434 
436  uint32_t source_regnum,
437  lldb::RegisterKind target_rk,
438  uint32_t &target_regnum) {
439  const uint32_t num_registers = GetRegisterCount();
440  for (uint32_t reg = 0; reg < num_registers; ++reg) {
441  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
442 
443  if (reg_info->kinds[source_rk] == source_regnum) {
444  target_regnum = reg_info->kinds[target_rk];
445  return (target_regnum != LLDB_INVALID_REGNUM);
446  }
447  }
448  return false;
449 }
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:317
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
An data extractor class.
Definition: DataExtractor.h:47
virtual bool ClearHardwareWatchpoint(uint32_t hw_index)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:742
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66
uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value)
uint64_t GetReturnAddress(uint64_t fail_value=LLDB_INVALID_ADDRESS)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it...
lldb::TargetSP CalculateTarget() override
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
bool CopyFromRegisterContext(lldb::RegisterContextSP context)
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)=0
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual bool ClearHardwareBreakpoint(uint32_t hw_idx)
virtual lldb::StackFrameSP GetFrameWithConcreteFrameIndex(uint32_t unwind_idx)
Definition: Thread.cpp:1632
An architecture specification class.
Definition: ArchSpec.h:32
void CalculateExecutionContext(ExecutionContext &exe_ctx) override
Reconstruct the object&#39;s execution context into sc.
Definition: Thread.cpp:1598
uint64_t GetFP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
virtual uint32_t NumSupportedHardwareBreakpoints()
void CalculateExecutionContext(ExecutionContext &exe_ctx) override
Reconstruct the object&#39;s execution context into sc.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
virtual uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
virtual bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp)
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
virtual Status ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
lldb::ThreadSP CalculateThread() override
virtual uint32_t NumSupportedHardwareWatchpoints()
bool SetUInt(uint64_t uint, uint32_t byte_size)
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define UINT32_MAX
Definition: lldb-defines.h:31
virtual const RegisterSet * GetRegisterSet(size_t reg_set)=0
virtual size_t GetRegisterCount()=0
virtual bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
uint64_t offset_t
Definition: lldb-types.h:87
uint64_t GetPC(uint64_t fail_value=LLDB_INVALID_ADDRESS)
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1584
int SInt(int fail_value=0) const
Definition: Scalar.cpp:1424
uint64_t tid_t
Definition: lldb-types.h:86
const char * GetRegisterName(uint32_t reg)
virtual lldb::RegisterContextSP GetRegisterContext()=0
virtual lldb::tid_t GetThreadID() const
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr, AddressClass addr_class=AddressClass::eInvalid) const
Get load_addr as an opcode for this target.
Definition: Target.cpp:2469
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:788
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
lldb::ProcessSP CalculateProcess() override
Definition: Thread.cpp:1592
lldb::StackFrameSP CalculateStackFrame() override
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
void SetStopID(uint32_t stop_id)
bool Success() const
Test for success condition.
Definition: Status.cpp:287
A section + offset based address class.
Definition: Address.h:80
virtual void ClearStackFrames()
Definition: Thread.cpp:1612
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
uint64_t GetFlags(uint64_t fail_value=0)
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t loclist_base_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const
Wrapper for the static evaluate function that accepts an ExecutionContextScope instead of an Executio...
uint64_t addr_t
Definition: lldb-types.h:83
Definition: SBAddress.h:15
lldb::ProcessSP CalculateProcess() override
virtual void InvalidateAllRegisters()=0
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
virtual uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write)
const Scalar & GetScalar() const
Definition: Value.h:178
uint32_t SetFromMemoryData(const RegisterInfo *reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
uint32_t UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, RegisterInfo *reg_info)
bool ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t &target_regnum)
virtual bool HardwareSingleStep(bool enable)
virtual size_t GetRegisterSetCount()=0
An error handling class.
Definition: Status.h:44
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90