1 //===-- NativeRegisterContextLinux_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 
9 #if defined(__arm64__) || defined(__aarch64__)
10 
11 #include "NativeRegisterContextLinux_arm.h"
12 #include "NativeRegisterContextLinux_arm64.h"
13 
14 
15 #include "lldb/Host/common/NativeProcessProtocol.h"
16 #include "lldb/Host/linux/Ptrace.h"
17 #include "lldb/Utility/DataBufferHeap.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/RegisterValue.h"
20 #include "lldb/Utility/Status.h"
21 
22 #include "Plugins/Process/Linux/NativeProcessLinux.h"
23 #include "Plugins/Process/Linux/Procfs.h"
24 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
25 #include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
26 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
27 
28 // System includes - They have to be included after framework includes because
29 // they define some macros which collide with variable names in other modules
30 #include <sys/uio.h>
31 // NT_PRSTATUS and NT_FPREGSET definition
32 #include <elf.h>
33 
34 #ifndef NT_ARM_SVE
35 #define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension */
36 #endif
37 
38 #ifndef NT_ARM_PAC_MASK
39 #define NT_ARM_PAC_MASK 0x406 /* Pointer authentication code masks */
40 #endif
41 
42 #ifndef NT_ARM_TAGGED_ADDR_CTRL
43 #define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* Tagged address control register */
44 #endif
45 
46 #define HWCAP_PACA (1 << 30)
47 #define HWCAP2_MTE (1 << 18)
48 
49 using namespace lldb;
50 using namespace lldb_private;
51 using namespace lldb_private::process_linux;
52 
53 std::unique_ptr<NativeRegisterContextLinux>
CreateHostNativeRegisterContextLinux(const ArchSpec & target_arch,NativeThreadLinux & native_thread)54 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
55     const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
56   switch (target_arch.GetMachine()) {
57   case llvm::Triple::arm:
58     return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
59                                                             native_thread);
60   case llvm::Triple::aarch64: {
61     // Configure register sets supported by this AArch64 target.
62     // Read SVE header to check for SVE support.
63     struct user_sve_header sve_header;
64     struct iovec ioVec;
65     ioVec.iov_base = &sve_header;
66     ioVec.iov_len = sizeof(sve_header);
67     unsigned int regset = NT_ARM_SVE;
68 
69     Flags opt_regsets;
70     if (NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,
71                                           native_thread.GetID(), &regset,
72                                           &ioVec, sizeof(sve_header))
73             .Success())
74       opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
75 
76     NativeProcessLinux &process = native_thread.GetProcess();
77 
78     llvm::Optional<uint64_t> auxv_at_hwcap =
79         process.GetAuxValue(AuxVector::AUXV_AT_HWCAP);
80     if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
81       opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
82 
83     llvm::Optional<uint64_t> auxv_at_hwcap2 =
84         process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
85     if (auxv_at_hwcap2 && (*auxv_at_hwcap2 & HWCAP2_MTE))
86       opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskMTE);
87 
88     auto register_info_up =
89         std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
90     return std::make_unique<NativeRegisterContextLinux_arm64>(
91         target_arch, native_thread, std::move(register_info_up));
92   }
93   default:
94     llvm_unreachable("have no register context for architecture");
95   }
96 }
97 
NativeRegisterContextLinux_arm64(const ArchSpec & target_arch,NativeThreadProtocol & native_thread,std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)98 NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
99     const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
100     std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
101     : NativeRegisterContextRegisterInfo(native_thread,
102                                         register_info_up.release()),
103       NativeRegisterContextLinux(native_thread) {
104   ::memset(&m_fpr, 0, sizeof(m_fpr));
105   ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
106   ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
107   ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
108   ::memset(&m_sve_header, 0, sizeof(m_sve_header));
109   ::memset(&m_pac_mask, 0, sizeof(m_pac_mask));
110 
111   m_mte_ctrl_reg = 0;
112 
113   // 16 is just a maximum value, query hardware for actual watchpoint count
114   m_max_hwp_supported = 16;
115   m_max_hbp_supported = 16;
116 
117   m_refresh_hwdebug_info = true;
118 
119   m_gpr_is_valid = false;
120   m_fpu_is_valid = false;
121   m_sve_buffer_is_valid = false;
122   m_sve_header_is_valid = false;
123   m_pac_mask_is_valid = false;
124   m_mte_ctrl_is_valid = false;
125 
126   if (GetRegisterInfo().IsSVEEnabled())
127     m_sve_state = SVEState::Unknown;
128   else
129     m_sve_state = SVEState::Disabled;
130 }
131 
132 RegisterInfoPOSIX_arm64 &
GetRegisterInfo() const133 NativeRegisterContextLinux_arm64::GetRegisterInfo() const {
134   return static_cast<RegisterInfoPOSIX_arm64 &>(*m_register_info_interface_up);
135 }
136 
GetRegisterSetCount() const137 uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
138   return GetRegisterInfo().GetRegisterSetCount();
139 }
140 
141 const RegisterSet *
GetRegisterSet(uint32_t set_index) const142 NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
143   return GetRegisterInfo().GetRegisterSet(set_index);
144 }
145 
GetUserRegisterCount() const146 uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
147   uint32_t count = 0;
148   for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
149     count += GetRegisterSet(set_index)->num_registers;
150   return count;
151 }
152 
153 Status
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)154 NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
155                                                RegisterValue &reg_value) {
156   Status error;
157 
158   if (!reg_info) {
159     error.SetErrorString("reg_info NULL");
160     return error;
161   }
162 
163   const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
164 
165   if (reg == LLDB_INVALID_REGNUM)
166     return Status("no lldb regnum for %s", reg_info && reg_info->name
167                                                ? reg_info->name
168                                                : "<unknown register>");
169 
170   uint8_t *src;
171   uint32_t offset = LLDB_INVALID_INDEX32;
172   uint64_t sve_vg;
173   std::vector<uint8_t> sve_reg_non_live;
174 
175   if (IsGPR(reg)) {
176     error = ReadGPR();
177     if (error.Fail())
178       return error;
179 
180     offset = reg_info->byte_offset;
181     assert(offset < GetGPRSize());
182     src = (uint8_t *)GetGPRBuffer() + offset;
183 
184   } else if (IsFPR(reg)) {
185     if (m_sve_state == SVEState::Disabled) {
186       // SVE is disabled take legacy route for FPU register access
187       error = ReadFPR();
188       if (error.Fail())
189         return error;
190 
191       offset = CalculateFprOffset(reg_info);
192       assert(offset < GetFPRSize());
193       src = (uint8_t *)GetFPRBuffer() + offset;
194     } else {
195       // SVE enabled, we will read and cache SVE ptrace data
196       error = ReadAllSVE();
197       if (error.Fail())
198         return error;
199 
200       // FPSR and FPCR will be located right after Z registers in
201       // SVEState::FPSIMD while in SVEState::Full they will be located at the
202       // end of register data after an alignment correction based on currently
203       // selected vector length.
204       uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
205       if (reg == GetRegisterInfo().GetRegNumFPSR()) {
206         sve_reg_num = reg;
207         if (m_sve_state == SVEState::Full)
208           offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
209         else if (m_sve_state == SVEState::FPSIMD)
210           offset = sve::ptrace_fpsimd_offset + (32 * 16);
211       } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
212         sve_reg_num = reg;
213         if (m_sve_state == SVEState::Full)
214           offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
215         else if (m_sve_state == SVEState::FPSIMD)
216           offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
217       } else {
218         // Extract SVE Z register value register number for this reg_info
219         if (reg_info->value_regs &&
220             reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
221           sve_reg_num = reg_info->value_regs[0];
222         offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
223       }
224 
225       assert(offset < GetSVEBufferSize());
226       src = (uint8_t *)GetSVEBuffer() + offset;
227     }
228   } else if (IsSVE(reg)) {
229 
230     if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown)
231       return Status("SVE disabled or not supported");
232 
233     if (GetRegisterInfo().IsSVERegVG(reg)) {
234       sve_vg = GetSVERegVG();
235       src = (uint8_t *)&sve_vg;
236     } else {
237       // SVE enabled, we will read and cache SVE ptrace data
238       error = ReadAllSVE();
239       if (error.Fail())
240         return error;
241 
242       if (m_sve_state == SVEState::FPSIMD) {
243         // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so
244         // just copy 16 bytes of v register to the start of z register. All
245         // other SVE register will be set to zero.
246         sve_reg_non_live.resize(reg_info->byte_size, 0);
247         src = sve_reg_non_live.data();
248 
249         if (GetRegisterInfo().IsSVEZReg(reg)) {
250           offset = CalculateSVEOffset(reg_info);
251           assert(offset < GetSVEBufferSize());
252           ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
253                    16);
254         }
255       } else {
256         offset = CalculateSVEOffset(reg_info);
257         assert(offset < GetSVEBufferSize());
258         src = (uint8_t *)GetSVEBuffer() + offset;
259       }
260     }
261   } else if (IsPAuth(reg)) {
262     error = ReadPAuthMask();
263     if (error.Fail())
264       return error;
265 
266     offset = reg_info->byte_offset - GetRegisterInfo().GetPAuthOffset();
267     assert(offset < GetPACMaskSize());
268     src = (uint8_t *)GetPACMask() + offset;
269   } else if (IsMTE(reg)) {
270     error = ReadMTEControl();
271     if (error.Fail())
272       return error;
273 
274     offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
275     assert(offset < GetMTEControlSize());
276     src = (uint8_t *)GetMTEControl() + offset;
277   } else
278     return Status("failed - register wasn't recognized to be a GPR or an FPR, "
279                   "write strategy unknown");
280 
281   reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
282                               eByteOrderLittle, error);
283 
284   return error;
285 }
286 
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)287 Status NativeRegisterContextLinux_arm64::WriteRegister(
288     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
289   Status error;
290 
291   if (!reg_info)
292     return Status("reg_info NULL");
293 
294   const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
295 
296   if (reg == LLDB_INVALID_REGNUM)
297     return Status("no lldb regnum for %s", reg_info && reg_info->name
298                                                ? reg_info->name
299                                                : "<unknown register>");
300 
301   uint8_t *dst;
302   uint32_t offset = LLDB_INVALID_INDEX32;
303   std::vector<uint8_t> sve_reg_non_live;
304 
305   if (IsGPR(reg)) {
306     error = ReadGPR();
307     if (error.Fail())
308       return error;
309 
310     assert(reg_info->byte_offset < GetGPRSize());
311     dst = (uint8_t *)GetGPRBuffer() + reg_info->byte_offset;
312     ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
313 
314     return WriteGPR();
315   } else if (IsFPR(reg)) {
316     if (m_sve_state == SVEState::Disabled) {
317       // SVE is disabled take legacy route for FPU register access
318       error = ReadFPR();
319       if (error.Fail())
320         return error;
321 
322       offset = CalculateFprOffset(reg_info);
323       assert(offset < GetFPRSize());
324       dst = (uint8_t *)GetFPRBuffer() + offset;
325       ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
326 
327       return WriteFPR();
328     } else {
329       // SVE enabled, we will read and cache SVE ptrace data
330       error = ReadAllSVE();
331       if (error.Fail())
332         return error;
333 
334       // FPSR and FPCR will be located right after Z registers in
335       // SVEState::FPSIMD while in SVEState::Full they will be located at the
336       // end of register data after an alignment correction based on currently
337       // selected vector length.
338       uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
339       if (reg == GetRegisterInfo().GetRegNumFPSR()) {
340         sve_reg_num = reg;
341         if (m_sve_state == SVEState::Full)
342           offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
343         else if (m_sve_state == SVEState::FPSIMD)
344           offset = sve::ptrace_fpsimd_offset + (32 * 16);
345       } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
346         sve_reg_num = reg;
347         if (m_sve_state == SVEState::Full)
348           offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
349         else if (m_sve_state == SVEState::FPSIMD)
350           offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
351       } else {
352         // Extract SVE Z register value register number for this reg_info
353         if (reg_info->value_regs &&
354             reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
355           sve_reg_num = reg_info->value_regs[0];
356         offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
357       }
358 
359       assert(offset < GetSVEBufferSize());
360       dst = (uint8_t *)GetSVEBuffer() + offset;
361       ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
362       return WriteAllSVE();
363     }
364   } else if (IsSVE(reg)) {
365     if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown)
366       return Status("SVE disabled or not supported");
367     else {
368       // Target has SVE enabled, we will read and cache SVE ptrace data
369       error = ReadAllSVE();
370       if (error.Fail())
371         return error;
372 
373       if (GetRegisterInfo().IsSVERegVG(reg)) {
374         uint64_t vg_value = reg_value.GetAsUInt64();
375 
376         if (sve_vl_valid(vg_value * 8)) {
377           if (m_sve_header_is_valid && vg_value == GetSVERegVG())
378             return error;
379 
380           SetSVERegVG(vg_value);
381 
382           error = WriteSVEHeader();
383           if (error.Success())
384             ConfigureRegisterContext();
385 
386           if (m_sve_header_is_valid && vg_value == GetSVERegVG())
387             return error;
388         }
389 
390         return Status("SVE vector length update failed.");
391       }
392 
393       // If target supports SVE but currently in FPSIMD mode.
394       if (m_sve_state == SVEState::FPSIMD) {
395         // Here we will check if writing this SVE register enables
396         // SVEState::Full
397         bool set_sve_state_full = false;
398         const uint8_t *reg_bytes = (const uint8_t *)reg_value.GetBytes();
399         if (GetRegisterInfo().IsSVEZReg(reg)) {
400           for (uint32_t i = 16; i < reg_info->byte_size; i++) {
401             if (reg_bytes[i]) {
402               set_sve_state_full = true;
403               break;
404             }
405           }
406         } else if (GetRegisterInfo().IsSVEPReg(reg) ||
407                    reg == GetRegisterInfo().GetRegNumSVEFFR()) {
408           for (uint32_t i = 0; i < reg_info->byte_size; i++) {
409             if (reg_bytes[i]) {
410               set_sve_state_full = true;
411               break;
412             }
413           }
414         }
415 
416         if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
417           // We are writing a Z register which is zero beyond 16 bytes so copy
418           // first 16 bytes only as SVE payload mirrors legacy fpsimd structure
419           offset = CalculateSVEOffset(reg_info);
420           assert(offset < GetSVEBufferSize());
421           dst = (uint8_t *)GetSVEBuffer() + offset;
422           ::memcpy(dst, reg_value.GetBytes(), 16);
423 
424           return WriteAllSVE();
425         } else
426           return Status("SVE state change operation not supported");
427       } else {
428         offset = CalculateSVEOffset(reg_info);
429         assert(offset < GetSVEBufferSize());
430         dst = (uint8_t *)GetSVEBuffer() + offset;
431         ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
432         return WriteAllSVE();
433       }
434     }
435   } else if (IsMTE(reg)) {
436     error = ReadMTEControl();
437     if (error.Fail())
438       return error;
439 
440     offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
441     assert(offset < GetMTEControlSize());
442     dst = (uint8_t *)GetMTEControl() + offset;
443     ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
444 
445     return WriteMTEControl();
446   }
447 
448   return Status("Failed to write register value");
449 }
450 
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)451 Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
452     lldb::WritableDataBufferSP &data_sp) {
453   // AArch64 register data must contain GPRs, either FPR or SVE registers
454   // and optional MTE register. Pointer Authentication (PAC) registers are
455   // read-only and will be skiped.
456 
457   // In order to create register data checkpoint we first read all register
458   // values if not done already and calculate total size of register set data.
459   // We store all register values in data_sp by copying full PTrace data that
460   // corresponds to register sets enabled by current register context.
461 
462   Status error;
463   uint32_t reg_data_byte_size = GetGPRBufferSize();
464   error = ReadGPR();
465   if (error.Fail())
466     return error;
467 
468   // If SVE is enabled we need not copy FPR separately.
469   if (GetRegisterInfo().IsSVEEnabled()) {
470     reg_data_byte_size += GetSVEBufferSize();
471     error = ReadAllSVE();
472   } else {
473     reg_data_byte_size += GetFPRSize();
474     error = ReadFPR();
475   }
476   if (error.Fail())
477     return error;
478 
479   if (GetRegisterInfo().IsMTEEnabled()) {
480     reg_data_byte_size += GetMTEControlSize();
481     error = ReadMTEControl();
482     if (error.Fail())
483       return error;
484   }
485 
486   data_sp.reset(new DataBufferHeap(reg_data_byte_size, 0));
487   uint8_t *dst = data_sp->GetBytes();
488 
489   ::memcpy(dst, GetGPRBuffer(), GetGPRBufferSize());
490   dst += GetGPRBufferSize();
491 
492   if (GetRegisterInfo().IsSVEEnabled()) {
493     ::memcpy(dst, GetSVEBuffer(), GetSVEBufferSize());
494     dst += GetSVEBufferSize();
495   } else {
496     ::memcpy(dst, GetFPRBuffer(), GetFPRSize());
497     dst += GetFPRSize();
498   }
499 
500   if (GetRegisterInfo().IsMTEEnabled())
501     ::memcpy(dst, GetMTEControl(), GetMTEControlSize());
502 
503   return error;
504 }
505 
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)506 Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
507     const lldb::DataBufferSP &data_sp) {
508   // AArch64 register data must contain GPRs, either FPR or SVE registers
509   // and optional MTE register. Pointer Authentication (PAC) registers are
510   // read-only and will be skiped.
511 
512   // We store all register values in data_sp by copying full PTrace data that
513   // corresponds to register sets enabled by current register context. In order
514   // to restore from register data checkpoint we will first restore GPRs, based
515   // on size of remaining register data either SVE or FPRs should be restored
516   // next. SVE is not enabled if we have register data size less than or equal
517   // to size of GPR + FPR + MTE.
518 
519   Status error;
520   if (!data_sp) {
521     error.SetErrorStringWithFormat(
522         "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
523         __FUNCTION__);
524     return error;
525   }
526 
527   const uint8_t *src = data_sp->GetBytes();
528   if (src == nullptr) {
529     error.SetErrorStringWithFormat("NativeRegisterContextLinux_arm64::%s "
530                                    "DataBuffer::GetBytes() returned a null "
531                                    "pointer",
532                                    __FUNCTION__);
533     return error;
534   }
535 
536   uint64_t reg_data_min_size = GetGPRBufferSize() + GetFPRSize();
537   if (data_sp->GetByteSize() < reg_data_min_size) {
538     error.SetErrorStringWithFormat(
539         "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
540         "register data bytes, expected at least %" PRIu64 ", actual %" PRIu64,
541         __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
542     return error;
543   }
544 
545   // Register data starts with GPRs
546   ::memcpy(GetGPRBuffer(), src, GetGPRBufferSize());
547   m_gpr_is_valid = true;
548 
549   error = WriteGPR();
550   if (error.Fail())
551     return error;
552 
553   src += GetGPRBufferSize();
554 
555   // Verify if register data may contain SVE register values.
556   bool contains_sve_reg_data =
557       (data_sp->GetByteSize() > (reg_data_min_size + GetSVEHeaderSize()));
558 
559   if (contains_sve_reg_data) {
560     // We have SVE register data first write SVE header.
561     ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
562     if (!sve_vl_valid(m_sve_header.vl)) {
563       m_sve_header_is_valid = false;
564       error.SetErrorStringWithFormat("NativeRegisterContextLinux_arm64::%s "
565                                      "Invalid SVE header in data_sp",
566                                      __FUNCTION__);
567       return error;
568     }
569     m_sve_header_is_valid = true;
570     error = WriteSVEHeader();
571     if (error.Fail())
572       return error;
573 
574     // SVE header has been written configure SVE vector length if needed.
575     ConfigureRegisterContext();
576 
577     // Make sure data_sp contains sufficient data to write all SVE registers.
578     reg_data_min_size = GetGPRBufferSize() + GetSVEBufferSize();
579     if (data_sp->GetByteSize() < reg_data_min_size) {
580       error.SetErrorStringWithFormat(
581           "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
582           "register data bytes, expected %" PRIu64 ", actual %" PRIu64,
583           __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
584       return error;
585     }
586 
587     ::memcpy(GetSVEBuffer(), src, GetSVEBufferSize());
588     m_sve_buffer_is_valid = true;
589     error = WriteAllSVE();
590     src += GetSVEBufferSize();
591   } else {
592     ::memcpy(GetFPRBuffer(), src, GetFPRSize());
593     m_fpu_is_valid = true;
594     error = WriteFPR();
595     src += GetFPRSize();
596   }
597 
598   if (error.Fail())
599     return error;
600 
601   if (GetRegisterInfo().IsMTEEnabled() &&
602       data_sp->GetByteSize() > reg_data_min_size) {
603     ::memcpy(GetMTEControl(), src, GetMTEControlSize());
604     m_mte_ctrl_is_valid = true;
605     error = WriteMTEControl();
606   }
607 
608   return error;
609 }
610 
IsGPR(unsigned reg) const611 bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const {
612   if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
613       RegisterInfoPOSIX_arm64::GPRegSet)
614     return true;
615   return false;
616 }
617 
IsFPR(unsigned reg) const618 bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const {
619   if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
620       RegisterInfoPOSIX_arm64::FPRegSet)
621     return true;
622   return false;
623 }
624 
IsSVE(unsigned reg) const625 bool NativeRegisterContextLinux_arm64::IsSVE(unsigned reg) const {
626   return GetRegisterInfo().IsSVEReg(reg);
627 }
628 
IsPAuth(unsigned reg) const629 bool NativeRegisterContextLinux_arm64::IsPAuth(unsigned reg) const {
630   return GetRegisterInfo().IsPAuthReg(reg);
631 }
632 
IsMTE(unsigned reg) const633 bool NativeRegisterContextLinux_arm64::IsMTE(unsigned reg) const {
634   return GetRegisterInfo().IsMTEReg(reg);
635 }
636 
ReadHardwareDebugInfo()637 llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
638   if (!m_refresh_hwdebug_info) {
639     return llvm::Error::success();
640   }
641 
642   ::pid_t tid = m_thread.GetID();
643 
644   int regset = NT_ARM_HW_WATCH;
645   struct iovec ioVec;
646   struct user_hwdebug_state dreg_state;
647   Status error;
648 
649   ioVec.iov_base = &dreg_state;
650   ioVec.iov_len = sizeof(dreg_state);
651   error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
652                                             &ioVec, ioVec.iov_len);
653 
654   if (error.Fail())
655     return error.ToError();
656 
657   m_max_hwp_supported = dreg_state.dbg_info & 0xff;
658 
659   regset = NT_ARM_HW_BREAK;
660   error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
661                                             &ioVec, ioVec.iov_len);
662 
663   if (error.Fail())
664     return error.ToError();
665 
666   m_max_hbp_supported = dreg_state.dbg_info & 0xff;
667   m_refresh_hwdebug_info = false;
668 
669   return llvm::Error::success();
670 }
671 
672 llvm::Error
WriteHardwareDebugRegs(DREGType hwbType)673 NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
674   struct iovec ioVec;
675   struct user_hwdebug_state dreg_state;
676   int regset;
677 
678   memset(&dreg_state, 0, sizeof(dreg_state));
679   ioVec.iov_base = &dreg_state;
680 
681   switch (hwbType) {
682   case eDREGTypeWATCH:
683     regset = NT_ARM_HW_WATCH;
684     ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
685                     (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
686 
687     for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
688       dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
689       dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
690     }
691     break;
692   case eDREGTypeBREAK:
693     regset = NT_ARM_HW_BREAK;
694     ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
695                     (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
696 
697     for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
698       dreg_state.dbg_regs[i].addr = m_hbp_regs[i].address;
699       dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
700     }
701     break;
702   }
703 
704   return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
705                                            &regset, &ioVec, ioVec.iov_len)
706       .ToError();
707 }
708 
ReadGPR()709 Status NativeRegisterContextLinux_arm64::ReadGPR() {
710   Status error;
711 
712   if (m_gpr_is_valid)
713     return error;
714 
715   struct iovec ioVec;
716   ioVec.iov_base = GetGPRBuffer();
717   ioVec.iov_len = GetGPRBufferSize();
718 
719   error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
720 
721   if (error.Success())
722     m_gpr_is_valid = true;
723 
724   return error;
725 }
726 
WriteGPR()727 Status NativeRegisterContextLinux_arm64::WriteGPR() {
728   Status error = ReadGPR();
729   if (error.Fail())
730     return error;
731 
732   struct iovec ioVec;
733   ioVec.iov_base = GetGPRBuffer();
734   ioVec.iov_len = GetGPRBufferSize();
735 
736   m_gpr_is_valid = false;
737 
738   return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
739 }
740 
ReadFPR()741 Status NativeRegisterContextLinux_arm64::ReadFPR() {
742   Status error;
743 
744   if (m_fpu_is_valid)
745     return error;
746 
747   struct iovec ioVec;
748   ioVec.iov_base = GetFPRBuffer();
749   ioVec.iov_len = GetFPRSize();
750 
751   error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
752 
753   if (error.Success())
754     m_fpu_is_valid = true;
755 
756   return error;
757 }
758 
WriteFPR()759 Status NativeRegisterContextLinux_arm64::WriteFPR() {
760   Status error = ReadFPR();
761   if (error.Fail())
762     return error;
763 
764   struct iovec ioVec;
765   ioVec.iov_base = GetFPRBuffer();
766   ioVec.iov_len = GetFPRSize();
767 
768   m_fpu_is_valid = false;
769 
770   return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
771 }
772 
InvalidateAllRegisters()773 void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
774   m_gpr_is_valid = false;
775   m_fpu_is_valid = false;
776   m_sve_buffer_is_valid = false;
777   m_sve_header_is_valid = false;
778   m_pac_mask_is_valid = false;
779   m_mte_ctrl_is_valid = false;
780 
781   // Update SVE registers in case there is change in configuration.
782   ConfigureRegisterContext();
783 }
784 
ReadSVEHeader()785 Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
786   Status error;
787 
788   if (m_sve_header_is_valid)
789     return error;
790 
791   struct iovec ioVec;
792   ioVec.iov_base = GetSVEHeader();
793   ioVec.iov_len = GetSVEHeaderSize();
794 
795   error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), NT_ARM_SVE);
796 
797   if (error.Success())
798     m_sve_header_is_valid = true;
799 
800   return error;
801 }
802 
ReadPAuthMask()803 Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
804   Status error;
805 
806   if (m_pac_mask_is_valid)
807     return error;
808 
809   struct iovec ioVec;
810   ioVec.iov_base = GetPACMask();
811   ioVec.iov_len = GetPACMaskSize();
812 
813   error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
814 
815   if (error.Success())
816     m_pac_mask_is_valid = true;
817 
818   return error;
819 }
820 
WriteSVEHeader()821 Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
822   Status error;
823 
824   error = ReadSVEHeader();
825   if (error.Fail())
826     return error;
827 
828   struct iovec ioVec;
829   ioVec.iov_base = GetSVEHeader();
830   ioVec.iov_len = GetSVEHeaderSize();
831 
832   m_sve_buffer_is_valid = false;
833   m_sve_header_is_valid = false;
834   m_fpu_is_valid = false;
835 
836   return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), NT_ARM_SVE);
837 }
838 
ReadAllSVE()839 Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
840   Status error;
841 
842   if (m_sve_buffer_is_valid)
843     return error;
844 
845   struct iovec ioVec;
846   ioVec.iov_base = GetSVEBuffer();
847   ioVec.iov_len = GetSVEBufferSize();
848 
849   error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), NT_ARM_SVE);
850 
851   if (error.Success())
852     m_sve_buffer_is_valid = true;
853 
854   return error;
855 }
856 
WriteAllSVE()857 Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
858   Status error;
859 
860   error = ReadAllSVE();
861   if (error.Fail())
862     return error;
863 
864   struct iovec ioVec;
865 
866   ioVec.iov_base = GetSVEBuffer();
867   ioVec.iov_len = GetSVEBufferSize();
868 
869   m_sve_buffer_is_valid = false;
870   m_sve_header_is_valid = false;
871   m_fpu_is_valid = false;
872 
873   return WriteRegisterSet(&ioVec, GetSVEBufferSize(), NT_ARM_SVE);
874 }
875 
ReadMTEControl()876 Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
877   Status error;
878 
879   if (m_mte_ctrl_is_valid)
880     return error;
881 
882   struct iovec ioVec;
883   ioVec.iov_base = GetMTEControl();
884   ioVec.iov_len = GetMTEControlSize();
885 
886   error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
887 
888   if (error.Success())
889     m_mte_ctrl_is_valid = true;
890 
891   return error;
892 }
893 
WriteMTEControl()894 Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
895   Status error;
896 
897   error = ReadMTEControl();
898   if (error.Fail())
899     return error;
900 
901   struct iovec ioVec;
902   ioVec.iov_base = GetMTEControl();
903   ioVec.iov_len = GetMTEControlSize();
904 
905   m_mte_ctrl_is_valid = false;
906 
907   return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
908 }
909 
ConfigureRegisterContext()910 void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
911   // ConfigureRegisterContext gets called from InvalidateAllRegisters
912   // on every stop and configures SVE vector length.
913   // If m_sve_state is set to SVEState::Disabled on first stop, code below will
914   // be deemed non operational for the lifetime of current process.
915   if (!m_sve_header_is_valid && m_sve_state != SVEState::Disabled) {
916     Status error = ReadSVEHeader();
917     if (error.Success()) {
918       // If SVE is enabled thread can switch between SVEState::FPSIMD and
919       // SVEState::Full on every stop.
920       if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
921           sve::ptrace_regs_fpsimd)
922         m_sve_state = SVEState::FPSIMD;
923       else if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
924                sve::ptrace_regs_sve)
925         m_sve_state = SVEState::Full;
926 
927       // On every stop we configure SVE vector length by calling
928       // ConfigureVectorLength regardless of current SVEState of this thread.
929       uint32_t vq = RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64SVE;
930       if (sve_vl_valid(m_sve_header.vl))
931         vq = sve::vq_from_vl(m_sve_header.vl);
932 
933       GetRegisterInfo().ConfigureVectorLength(vq);
934       m_sve_ptrace_payload.resize(sve::PTraceSize(vq, sve::ptrace_regs_sve));
935     }
936   }
937 }
938 
CalculateFprOffset(const RegisterInfo * reg_info) const939 uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
940     const RegisterInfo *reg_info) const {
941   return reg_info->byte_offset - GetGPRSize();
942 }
943 
CalculateSVEOffset(const RegisterInfo * reg_info) const944 uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
945     const RegisterInfo *reg_info) const {
946   // Start of Z0 data is after GPRs plus 8 bytes of vg register
947   uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
948   if (m_sve_state == SVEState::FPSIMD) {
949     const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
950     sve_reg_offset = sve::ptrace_fpsimd_offset +
951                      (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
952   } else if (m_sve_state == SVEState::Full) {
953     uint32_t sve_z0_offset = GetGPRSize() + 16;
954     sve_reg_offset =
955         sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
956   }
957   return sve_reg_offset;
958 }
959 
GetExpeditedRegisters(ExpeditedRegs expType) const960 std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
961     ExpeditedRegs expType) const {
962   std::vector<uint32_t> expedited_reg_nums =
963       NativeRegisterContext::GetExpeditedRegisters(expType);
964   if (m_sve_state == SVEState::FPSIMD || m_sve_state == SVEState::Full)
965     expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
966 
967   return expedited_reg_nums;
968 }
969 
970 llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
GetMemoryTaggingDetails(int32_t type)971 NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
972   if (type == MemoryTagManagerAArch64MTE::eMTE_allocation) {
973     return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
974                                 PTRACE_PEEKMTETAGS, PTRACE_POKEMTETAGS};
975   }
976 
977   return llvm::createStringError(llvm::inconvertibleErrorCode(),
978                                  "Unknown AArch64 memory tag type %d", type);
979 }
980 
FixWatchpointHitAddress(lldb::addr_t hit_addr)981 lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
982     lldb::addr_t hit_addr) {
983   // Linux configures user-space virtual addresses with top byte ignored.
984   // We set default value of mask such that top byte is masked out.
985   lldb::addr_t mask = ~((1ULL << 56) - 1);
986 
987   // Try to read pointer authentication data_mask register and calculate a
988   // consolidated data address mask after ignoring the top byte.
989   if (ReadPAuthMask().Success())
990     mask |= m_pac_mask.data_mask;
991 
992   return hit_addr & ~mask;
993   ;
994 }
995 
996 #endif // defined (__arm64__) || defined (__aarch64__)
997