LLDB  mainline
NativeRegisterContextLinux.cpp
Go to the documentation of this file.
1 //===-- NativeRegisterContextLinux.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 
10 
13 #include "lldb/Host/linux/Ptrace.h"
15 
18 
19 using namespace lldb_private;
20 using namespace lldb_private::process_linux;
21 
23  NativeThreadProtocol &native_thread,
24  RegisterInfoInterface *reg_info_interface_p)
25  : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
26 
28  return m_thread.GetProcess().GetByteOrder();
29 }
30 
32  RegisterValue &reg_value) {
33  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
34  if (!reg_info)
35  return Status("register %" PRIu32 " not found", reg_index);
36 
37  return DoReadRegisterValue(GetPtraceOffset(reg_index), reg_info->name,
38  reg_info->byte_size, reg_value);
39 }
40 
41 Status
43  const RegisterValue &reg_value) {
44  uint32_t reg_to_write = reg_index;
45  RegisterValue value_to_write = reg_value;
46 
47  // Check if this is a subregister of a full register.
48  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
49  if (reg_info->invalidate_regs &&
50  (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
51  Status error;
52 
53  RegisterValue full_value;
54  uint32_t full_reg = reg_info->invalidate_regs[0];
55  const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
56 
57  // Read the full register.
58  error = ReadRegister(full_reg_info, full_value);
59  if (error.Fail())
60  return error;
61 
62  lldb::ByteOrder byte_order = GetByteOrder();
64 
65  // Get the bytes for the full register.
66  const uint32_t dest_size = full_value.GetAsMemoryData(
67  full_reg_info, dst, sizeof(dst), byte_order, error);
68  if (error.Success() && dest_size) {
70 
71  // Get the bytes for the source data.
72  const uint32_t src_size = reg_value.GetAsMemoryData(
73  reg_info, src, sizeof(src), byte_order, error);
74  if (error.Success() && src_size && (src_size < dest_size)) {
75  // Copy the src bytes to the destination.
76  memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
77  // Set this full register as the value to write.
78  value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
79  value_to_write.SetType(full_reg_info);
80  reg_to_write = full_reg;
81  }
82  }
83  }
84 
85  const RegisterInfo *const register_to_write_info_p =
86  GetRegisterInfoAtIndex(reg_to_write);
87  assert(register_to_write_info_p &&
88  "register to write does not have valid RegisterInfo");
89  if (!register_to_write_info_p)
90  return Status("NativeRegisterContextLinux::%s failed to get RegisterInfo "
91  "for write register index %" PRIu32,
92  __FUNCTION__, reg_to_write);
93 
94  return DoWriteRegisterValue(GetPtraceOffset(reg_index), reg_info->name,
95  reg_value);
96 }
97 
101 }
102 
106 }
107 
110  nullptr, GetFPRBuffer(),
111  GetFPRSize());
112 }
113 
116  nullptr, GetFPRBuffer(),
117  GetFPRSize());
118 }
119 
121  unsigned int regset) {
123  static_cast<void *>(&regset), buf,
124  buf_size);
125 }
126 
128  unsigned int regset) {
130  static_cast<void *>(&regset), buf,
131  buf_size);
132 }
133 
135  const char *reg_name,
136  uint32_t size,
137  RegisterValue &value) {
139 
140  long data;
142  PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset),
143  nullptr, 0, &data);
144 
145  if (error.Success())
146  // First cast to an unsigned of the same size to avoid sign extension.
147  value.SetUInt(static_cast<unsigned long>(data), size);
148 
149  LLDB_LOG(log, "{0}: {1:x}", reg_name, data);
150  return error;
151 }
152 
154  uint32_t offset, const char *reg_name, const RegisterValue &value) {
156 
157  void *buf = reinterpret_cast<void *>(value.GetAsUInt64());
158  LLDB_LOG(log, "{0}: {1}", reg_name, buf);
159 
161  PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
162 }
#define PTRACE_SETREGSET
Definition: Ptrace.h:39
A class that represents a running process on the host machine.
NativeRegisterContextLinux(NativeThreadProtocol &native_thread, RegisterInfoInterface *reg_info_interface_p)
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
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value)
virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name, const RegisterValue &value)
bool SetUInt(uint64_t uint, uint32_t byte_size)
#define PTRACE_GETREGSET
Definition: Ptrace.h:36
#define PTRACE_GETFPREGS
Definition: Ptrace.h:30
#define PTRACE_SETREGS
Definition: Ptrace.h:27
virtual Status ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
virtual Status WriteRegisterRaw(uint32_t reg_index, const RegisterValue &reg_value)
NativeProcessProtocol & GetProcess()
#define POSIX_LOG_REGISTERS
ByteOrder
Byte ordering definitions.
bool Success() const
Test for success condition.
Definition: Status.cpp:288
virtual Status ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset)
#define PTRACE_SETFPREGS
Definition: Ptrace.h:33
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
const RegisterInfo * GetRegisterInfoAtIndex(uint32_t reg_index) const override
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
#define PTRACE_GETREGS
Definition: Ptrace.h:24
static Log * GetLogIfAllCategoriesSet(uint32_t mask)
virtual Status DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size, RegisterValue &value)
void SetType(RegisterValue::Type type)
Definition: RegisterValue.h:85
An error handling class.
Definition: Status.h:44
virtual Status WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset)
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90