LLDB  mainline
RegisterContextPOSIXCore_arm64.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIXCore_arm64.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 
11 
13 #include "lldb/Target/Thread.h"
15 
16 #include <memory>
17 
18 using namespace lldb_private;
19 
20 std::unique_ptr<RegisterContextCorePOSIX_arm64>
22  const DataExtractor &gpregset,
23  llvm::ArrayRef<CoreNote> notes) {
25 
26  DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
27  if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
29 
30  // Pointer Authentication register set data is based on struct
31  // user_pac_mask declared in ptrace.h. See reference implementation
32  // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h.
33  DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc);
34  if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
36 
37  auto register_info_up =
38  std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
39  return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
40  new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up),
41  gpregset, notes));
42 }
43 
45  Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
46  const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
47  : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
48  m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
49  gpregset.GetByteSize()));
51 
52  const llvm::Triple &target_triple =
53  m_register_info_up->GetTargetArchitecture().GetTriple();
54  m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
55 
56  if (m_register_info_up->IsSVEEnabled())
57  m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
58 
59  if (m_register_info_up->IsPAuthEnabled())
60  m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
61 
63 }
64 
66 
68 
70 
72  assert(0);
73  return false;
74 }
75 
77  assert(0);
78  return false;
79 }
80 
81 const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
82  return m_sve_data.GetDataStart() + offset;
83 }
84 
87  uint64_t sve_header_field_offset = 8;
88  m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
89  sve_header_field_offset = 12;
90  uint16_t sve_header_flags_field =
91  m_sve_data.GetU16(&sve_header_field_offset);
92  if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
95  else if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
98 
102  }
103  } else
105 
107  m_register_info_up->ConfigureVectorLength(
109 }
110 
112  const RegisterInfo *reg_info) {
113  // Start of Z0 data is after GPRs plus 8 bytes of vg register
114  uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
115  if (m_sve_state == SVEState::FPSIMD) {
116  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
117  sve_reg_offset = sve::ptrace_fpsimd_offset + (reg - GetRegNumSVEZ0()) * 16;
118  } else if (m_sve_state == SVEState::Full) {
119  uint32_t sve_z0_offset = GetGPRSize() + 16;
120  sve_reg_offset =
121  sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
122  }
123 
124  return sve_reg_offset;
125 }
126 
127 bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
128  RegisterValue &value) {
129  Status error;
130  lldb::offset_t offset;
131 
132  offset = reg_info->byte_offset;
133  if (offset + reg_info->byte_size <= GetGPRSize()) {
134  uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size);
135  if (offset == reg_info->byte_offset + reg_info->byte_size) {
136  value = v;
137  return true;
138  }
139  }
140 
141  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
142  if (reg == LLDB_INVALID_REGNUM)
143  return false;
144 
145  if (IsFPR(reg)) {
147  // SVE is disabled take legacy route for FPU register access
148  offset -= GetGPRSize();
149  if (offset < m_fpr_data.GetByteSize()) {
150  value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset,
151  reg_info->byte_size, lldb::eByteOrderLittle,
152  error);
153  return error.Success();
154  }
155  } else {
156  // FPSR and FPCR will be located right after Z registers in
157  // SVEState::FPSIMD while in SVEState::Full they will be located at the
158  // end of register data after an alignment correction based on currently
159  // selected vector length.
160  uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
161  if (reg == GetRegNumFPSR()) {
162  sve_reg_num = reg;
165  else if (m_sve_state == SVEState::FPSIMD)
166  offset = sve::ptrace_fpsimd_offset + (32 * 16);
167  } else if (reg == GetRegNumFPCR()) {
168  sve_reg_num = reg;
171  else if (m_sve_state == SVEState::FPSIMD)
172  offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
173  } else {
174  // Extract SVE Z register value register number for this reg_info
175  if (reg_info->value_regs &&
176  reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
177  sve_reg_num = reg_info->value_regs[0];
178  offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
179  }
180 
181  assert(sve_reg_num != LLDB_INVALID_REGNUM);
182  assert(offset < m_sve_data.GetByteSize());
183  value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
184  reg_info->byte_size, lldb::eByteOrderLittle,
185  error);
186  }
187  } else if (IsSVE(reg)) {
188  if (IsSVEVG(reg)) {
189  value = GetSVERegVG();
190  return true;
191  }
192 
193  switch (m_sve_state) {
194  case SVEState::FPSIMD: {
195  // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so just
196  // copy 16 bytes of v register to the start of z register. All other
197  // SVE register will be set to zero.
198  uint64_t byte_size = 1;
199  uint8_t zeros = 0;
200  const uint8_t *src = &zeros;
201  if (IsSVEZ(reg)) {
202  byte_size = 16;
203  offset = CalculateSVEOffset(reg_info);
204  assert(offset < m_sve_data.GetByteSize());
205  src = GetSVEBuffer(offset);
206  }
207  value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
208  error);
209  } break;
210  case SVEState::Full:
211  offset = CalculateSVEOffset(reg_info);
212  assert(offset < m_sve_data.GetByteSize());
213  value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
214  reg_info->byte_size, lldb::eByteOrderLittle,
215  error);
216  break;
217  case SVEState::Disabled:
218  default:
219  return false;
220  }
221  } else if (IsPAuth(reg)) {
222  offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset();
223  assert(offset < m_pac_data.GetByteSize());
224  value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset,
225  reg_info->byte_size, lldb::eByteOrderLittle, error);
226  } else
227  return false;
228 
229  return error.Success();
230 }
231 
233  lldb::DataBufferSP &data_sp) {
234  return false;
235 }
236 
237 bool RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info,
238  const RegisterValue &value) {
239  return false;
240 }
241 
243  const lldb::DataBufferSP &data_sp) {
244  return false;
245 }
246 
248  return false;
249 }
RegisterInfoPOSIX_arm64::eRegsetMaskSVE
@ eRegsetMaskSVE
Definition: RegisterInfoPOSIX_arm64.h:28
lldb_private::ArchSpec
Definition: ArchSpec.h:33
RegisterContextPOSIX_arm64::IsSVEZ
bool IsSVEZ(unsigned reg) const
Definition: RegisterContextPOSIX_arm64.h:59
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:91
RegisterContextCorePOSIX_arm64::m_sve_state
SVEState m_sve_state
Definition: RegisterContextPOSIXCore_arm64.h:61
lldb_private::sve::ptrace_fpsimd_offset
const uint32_t ptrace_fpsimd_offset
Definition: LinuxPTraceDefines_arm64sve.h:190
lldb_private::RegisterValue
Definition: RegisterValue.h:28
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64
RegisterContextCorePOSIX_arm64(lldb_private::Thread &thread, std::unique_ptr< RegisterInfoPOSIX_arm64 > register_info, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef< lldb_private::CoreNote > notes)
Definition: RegisterContextPOSIXCore_arm64.cpp:44
RegisterContextCorePOSIX_arm64::ReadRegister
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override
Definition: RegisterContextPOSIXCore_arm64.cpp:127
lldb_private::FPR_Desc
constexpr RegsetDesc FPR_Desc[]
Definition: RegisterUtilities.h:102
RegisterContextPOSIX_arm64::IsSVE
bool IsSVE(unsigned reg) const
Definition: RegisterContextPOSIX_arm64.cpp:42
RegisterContextPOSIX_arm64::GetRegNumFPCR
uint32_t GetRegNumFPCR() const
Definition: RegisterContextPOSIX_arm64.h:71
RegisterContextCorePOSIX_arm64::ReadFPR
bool ReadFPR() override
Definition: RegisterContextPOSIXCore_arm64.cpp:69
RegisterContextCorePOSIX_arm64::ReadAllRegisterValues
bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override
Definition: RegisterContextPOSIXCore_arm64.cpp:232
lldb_private::sve::user_sve_header
Definition: LinuxPTraceDefines_arm64sve.h:146
SVEState::FPSIMD
@ FPSIMD
RegisterUtilities.h
lldb_private::Flags
Definition: Flags.h:22
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
RegisterValue.h
RegisterContextCorePOSIX_arm64::ConfigureRegisterContext
void ConfigureRegisterContext()
Definition: RegisterContextPOSIXCore_arm64.cpp:85
SVEState::Disabled
@ Disabled
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb_private::sve::PTraceFPSROffset
uint32_t PTraceFPSROffset(uint16_t vq)
Definition: LinuxPTraceDefines_arm64sve.h:263
lldb_private::sve::vl_valid
uint16_t vl_valid(uint16_t vl)
Definition: LinuxPTraceDefines_arm64sve.h:37
RegisterContextCorePOSIX_arm64::m_pac_data
lldb_private::DataExtractor m_pac_data
Definition: RegisterContextPOSIXCore_arm64.h:59
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:225
RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
Definition: RegisterContextPOSIX_arm64.cpp:87
lldb_private::sve::ptrace_regs_fpsimd
const uint16_t ptrace_regs_fpsimd
Definition: LinuxPTraceDefines_arm64sve.h:157
lldb_private::DataExtractor::SetByteOrder
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
Definition: DataExtractor.h:931
RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64
~RegisterContextCorePOSIX_arm64() override
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
RegisterContextCorePOSIX_arm64::WriteFPR
bool WriteFPR() override
Definition: RegisterContextPOSIXCore_arm64.cpp:76
RegisterContextPOSIX_arm64::IsFPR
bool IsFPR(unsigned reg)
Definition: RegisterContextPOSIX_arm64.cpp:35
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
lldb_private::DataExtractor
Definition: DataExtractor.h:48
RegisterInfoPOSIX_arm64::eRegsetMaskPAuth
@ eRegsetMaskPAuth
Definition: RegisterInfoPOSIX_arm64.h:29
SVEState::Full
@ Full
lldb_private::Thread
Definition: Thread.h:60
RegisterContextCorePOSIX_arm64::Create
static std::unique_ptr< RegisterContextCorePOSIX_arm64 > Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch, const lldb_private::DataExtractor &gpregset, llvm::ArrayRef< lldb_private::CoreNote > notes)
Definition: RegisterContextPOSIXCore_arm64.cpp:21
lldb_private::sve::ptrace_regs_mask
const uint16_t ptrace_regs_mask
Definition: LinuxPTraceDefines_arm64sve.h:156
RegisterContextPOSIX_arm64::GetRegNumSVEZ0
uint32_t GetRegNumSVEZ0() const
Definition: RegisterContextPOSIX_arm64.h:65
lldb_private::sve::vq_from_vl
uint16_t vq_from_vl(uint16_t vl)
Definition: LinuxPTraceDefines_arm64sve.h:41
lldb_private::DataExtractor::GetDataStart
const uint8_t * GetDataStart() const
Get the data start pointer.
Definition: DataExtractor.h:422
lldb_private::DataExtractor::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
Definition: DataExtractor.h:594
RegisterInfoPOSIX_arm64.h
RegisterContextPOSIXCore_arm64.h
RegisterContextCorePOSIX_arm64::ReadGPR
bool ReadGPR() override
Definition: RegisterContextPOSIXCore_arm64.cpp:67
RegisterContextCorePOSIX_arm64::GetSVEBuffer
const uint8_t * GetSVEBuffer(uint64_t offset=0)
Definition: RegisterContextPOSIXCore_arm64.cpp:81
RegisterContextPOSIX_arm64::m_register_info_up
std::unique_ptr< RegisterInfoPOSIX_arm64 > m_register_info_up
Definition: RegisterContextPOSIX_arm64.h:46
Thread.h
lldb_private::sve::SigRegsOffset
uint32_t SigRegsOffset()
Definition: LinuxPTraceDefines_arm64sve.h:108
RegisterContextCorePOSIX_arm64::CalculateSVEOffset
uint32_t CalculateSVEOffset(const lldb_private::RegisterInfo *reg_info)
Definition: RegisterContextPOSIXCore_arm64.cpp:111
RegisterContextCorePOSIX_arm64::HardwareSingleStep
bool HardwareSingleStep(bool enable) override
Definition: RegisterContextPOSIXCore_arm64.cpp:247
lldb_private::getRegset
DataExtractor getRegset(llvm::ArrayRef< CoreNote > Notes, const llvm::Triple &Triple, llvm::ArrayRef< RegsetDesc > RegsetDescs)
Definition: RegisterUtilities.cpp:28
RegisterContextCorePOSIX_arm64::WriteAllRegisterValues
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
Definition: RegisterContextPOSIXCore_arm64.cpp:242
RegisterContextPOSIX_arm64::GetGPRSize
virtual size_t GetGPRSize()
Definition: RegisterContextPOSIX_arm64.cpp:74
lldb_private::AARCH64_SVE_Desc
constexpr RegsetDesc AARCH64_SVE_Desc[]
Definition: RegisterUtilities.h:118
lldb_private::RegisterValue::SetFromMemoryData
uint32_t SetFromMemoryData(const RegisterInfo *reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
Definition: RegisterValue.cpp:84
RegisterContextPOSIX_arm64::IsSVEVG
bool IsSVEVG(unsigned reg) const
Definition: RegisterContextPOSIX_arm64.h:61
lldb_private::Status
Definition: Status.h:44
lldb_private::sve::PTraceFPCROffset
uint32_t PTraceFPCROffset(uint16_t vq)
Definition: LinuxPTraceDefines_arm64sve.h:268
uint32_t
RegisterContextPOSIX_arm64::IsPAuth
bool IsPAuth(unsigned reg) const
Definition: RegisterContextPOSIX_arm64.cpp:46
RegisterContextCorePOSIX_arm64::m_sve_data
lldb_private::DataExtractor m_sve_data
Definition: RegisterContextPOSIXCore_arm64.h:58
lldb_private::DataExtractor::GetMaxU64
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:526
uint16_t
RegisterInfoPOSIX_arm64::eRegsetMaskDefault
@ eRegsetMaskDefault
Definition: RegisterInfoPOSIX_arm64.h:27
lldb_private::AARCH64_PAC_Desc
constexpr RegsetDesc AARCH64_PAC_Desc[]
Definition: RegisterUtilities.h:122
lldb_private::sve::ptrace_regs_sve
const uint16_t ptrace_regs_sve
Definition: LinuxPTraceDefines_arm64sve.h:158
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetU16
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:349
RegisterContextCorePOSIX_arm64::m_fpr_data
lldb_private::DataExtractor m_fpr_data
Definition: RegisterContextPOSIXCore_arm64.h:57
RegisterContextCorePOSIX_arm64::WriteRegister
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override
Definition: RegisterContextPOSIXCore_arm64.cpp:237
lldb_private::Flags::Set
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
Definition: Flags.h:73
RegisterContextCorePOSIX_arm64::WriteGPR
bool WriteGPR() override
Definition: RegisterContextPOSIXCore_arm64.cpp:71
RegisterContextCorePOSIX_arm64::GetSVERegVG
uint64_t GetSVERegVG()
Definition: RegisterContextPOSIXCore_arm64.h:70
LLDB_INVALID_INDEX32
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:87
RegisterContextCorePOSIX_arm64
Definition: RegisterContextPOSIXCore_arm64.h:19
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
RegisterContextCorePOSIX_arm64::m_gpr_data
lldb_private::DataExtractor m_gpr_data
Definition: RegisterContextPOSIXCore_arm64.h:56
RegisterContextCorePOSIX_arm64::m_sve_vector_length
uint16_t m_sve_vector_length
Definition: RegisterContextPOSIXCore_arm64.h:62
RegisterContextPOSIX_arm64
Definition: RegisterContextPOSIX_arm64.h:17
RegisterContextPOSIX_arm64::GetRegNumFPSR
uint32_t GetRegNumFPSR() const
Definition: RegisterContextPOSIX_arm64.h:72