LLDB mainline
NativeRegisterContextLinux_arm64.cpp
Go to the documentation of this file.
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
14
15#include "lldb/Host/HostInfo.h"
19#include "lldb/Utility/Log.h"
21#include "lldb/Utility/Status.h"
22
29
30// System includes - They have to be included after framework includes because
31// they define some macros which collide with variable names in other modules
32#include <sys/uio.h>
33// NT_PRSTATUS and NT_FPREGSET definition
34#include <elf.h>
35#include <mutex>
36#include <optional>
37
38#ifndef NT_ARM_SVE
39#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension */
40#endif
41
42#ifndef NT_ARM_SSVE
43#define NT_ARM_SSVE \
44 0x40b /* ARM Scalable Matrix Extension, Streaming SVE mode */
45#endif
46
47#ifndef NT_ARM_ZA
48#define NT_ARM_ZA 0x40c /* ARM Scalable Matrix Extension, Array Storage */
49#endif
50
51#ifndef NT_ARM_ZT
52#define NT_ARM_ZT \
53 0x40d /* ARM Scalable Matrix Extension 2, lookup table register */
54#endif
55
56#ifndef NT_ARM_PAC_MASK
57#define NT_ARM_PAC_MASK 0x406 /* Pointer authentication code masks */
58#endif
59
60#ifndef NT_ARM_TAGGED_ADDR_CTRL
61#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* Tagged address control register */
62#endif
63
64#ifndef NT_ARM_FPMR
65#define NT_ARM_FPMR 0x40e /* Floating point mode register */
66#endif
67
68#ifndef NT_ARM_POE
69#define NT_ARM_POE 0x40f /* Permission Overlay registers */
70#endif
71
72#ifndef NT_ARM_GCS
73#define NT_ARM_GCS 0x410 /* Guarded Control Stack control registers */
74#endif
75
76#ifndef HWCAP_PACA
77#define HWCAP_PACA (1 << 30)
78#endif
79
80#ifndef HWCAP_GCS
81#define HWCAP_GCS (1UL << 32)
82#endif
83
84#ifndef HWCAP2_MTE
85#define HWCAP2_MTE (1 << 18)
86#endif
87
88#ifndef HWCAP2_FPMR
89#define HWCAP2_FPMR (1UL << 48)
90#endif
91
92#ifndef HWCAP2_POE
93#define HWCAP2_POE (1ULL << 63)
94#endif
95
96using namespace lldb;
97using namespace lldb_private;
98using namespace lldb_private::process_linux;
99
100// A NativeRegisterContext is constructed per thread, but all threads' registers
101// will contain the same fields. Therefore this mutex prevents each instance
102// competing with the other, and subsequent instances from having to detect the
103// fields all over again.
104static std::mutex g_register_flags_detector_mutex;
105static Arm64RegisterFlagsDetector g_register_flags_detector;
106
107std::unique_ptr<NativeRegisterContextLinux>
109 const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
110 switch (target_arch.GetMachine()) {
111 case llvm::Triple::arm:
112 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
113 native_thread);
114 case llvm::Triple::aarch64: {
115 // Configure register sets supported by this AArch64 target.
116 // Read SVE header to check for SVE support.
117 struct sve::user_sve_header sve_header;
118 struct iovec ioVec;
119 ioVec.iov_base = &sve_header;
120 ioVec.iov_len = sizeof(sve_header);
121 unsigned int regset = NT_ARM_SVE;
122
123 Flags opt_regsets;
125 native_thread.GetID(), &regset,
126 &ioVec, sizeof(sve_header))
127 .Success()) {
129
130 // We may also have the Scalable Matrix Extension (SME) which adds a
131 // streaming SVE mode.
132 ioVec.iov_len = sizeof(sve_header);
133 regset = NT_ARM_SSVE;
135 native_thread.GetID(), &regset,
136 &ioVec, sizeof(sve_header))
137 .Success())
139 }
140
141 sve::user_za_header za_header;
142 ioVec.iov_base = &za_header;
143 ioVec.iov_len = sizeof(za_header);
144 regset = NT_ARM_ZA;
146 native_thread.GetID(), &regset,
147 &ioVec, sizeof(za_header))
148 .Success())
150
151 // SME's ZT0 is a 512 bit register.
152 std::array<uint8_t, 64> zt_reg;
153 ioVec.iov_base = zt_reg.data();
154 ioVec.iov_len = zt_reg.size();
155 regset = NT_ARM_ZT;
157 native_thread.GetID(), &regset,
158 &ioVec, zt_reg.size())
159 .Success())
161
162 NativeProcessLinux &process = native_thread.GetProcess();
163
164 std::optional<uint64_t> auxv_at_hwcap =
166 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
168
169 std::optional<uint64_t> auxv_at_hwcap2 =
171 if (auxv_at_hwcap2) {
172 if (*auxv_at_hwcap2 & HWCAP2_MTE)
174 if (*auxv_at_hwcap2 & HWCAP2_FPMR)
176 if (*auxv_at_hwcap & HWCAP_GCS)
178 if (*auxv_at_hwcap2 & HWCAP2_POE)
180 }
181
183
184 std::optional<uint64_t> auxv_at_hwcap3 =
186 std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
187 if (!g_register_flags_detector.HasDetected())
188 g_register_flags_detector.DetectFields(auxv_at_hwcap.value_or(0),
189 auxv_at_hwcap2.value_or(0),
190 auxv_at_hwcap3.value_or(0));
191
192 auto register_info_up =
193 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
194 return std::make_unique<NativeRegisterContextLinux_arm64>(
195 target_arch, native_thread, std::move(register_info_up));
196 }
197 default:
198 llvm_unreachable("have no register context for architecture");
199 }
200}
201
202llvm::Expected<ArchSpec>
204 return DetermineArchitectureViaGPR(
206}
207
208NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
209 const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
210 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
211 : NativeRegisterContextRegisterInfo(native_thread,
212 register_info_up.release()),
213 NativeRegisterContextLinux(native_thread) {
214 g_register_flags_detector.UpdateRegisterInfo(
215 GetRegisterInfoInterface().GetRegisterInfo(),
216 GetRegisterInfoInterface().GetRegisterCount());
217
218 ::memset(&m_fpr, 0, sizeof(m_fpr));
219 ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
220 ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
221 ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
222 ::memset(&m_sve_header, 0, sizeof(m_sve_header));
223 ::memset(&m_pac_mask, 0, sizeof(m_pac_mask));
224 ::memset(&m_tls_regs, 0, sizeof(m_tls_regs));
225 ::memset(&m_sme_pseudo_regs, 0, sizeof(m_sme_pseudo_regs));
226 ::memset(&m_gcs_regs, 0, sizeof(m_gcs_regs));
227 ::memset(&m_poe_regs, 0, sizeof(m_poe_regs));
228 std::fill(m_zt_reg.begin(), m_zt_reg.end(), 0);
229
230 m_mte_ctrl_reg = 0;
231 m_fpmr_reg = 0;
232
233 // 16 is just a maximum value, query hardware for actual watchpoint count
234 m_max_hwp_supported = 16;
235 m_max_hbp_supported = 16;
236
237 m_refresh_hwdebug_info = true;
238
239 m_gpr_is_valid = false;
240 m_fpu_is_valid = false;
241 m_sve_buffer_is_valid = false;
242 m_sve_header_is_valid = false;
243 m_pac_mask_is_valid = false;
244 m_mte_ctrl_is_valid = false;
245 m_tls_is_valid = false;
246 m_zt_buffer_is_valid = false;
247 m_fpmr_is_valid = false;
248 m_gcs_is_valid = false;
249 m_poe_is_valid = false;
250
251 // SME adds the tpidr2 register
252 m_tls_size = GetRegisterInfo().IsSSVEPresent() ? sizeof(m_tls_regs)
253 : sizeof(m_tls_regs.tpidr_reg);
254
255 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
256 m_sve_state = SVEState::Unknown;
257 else
258 m_sve_state = SVEState::Disabled;
259}
260
262NativeRegisterContextLinux_arm64::GetRegisterInfo() const {
263 return static_cast<RegisterInfoPOSIX_arm64 &>(*m_register_info_interface_up);
264}
265
266uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
267 return GetRegisterInfo().GetRegisterSetCount();
268}
269
270const RegisterSet *
271NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
272 return GetRegisterInfo().GetRegisterSet(set_index);
273}
274
275uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
276 uint32_t count = 0;
277 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
278 count += GetRegisterSet(set_index)->num_registers;
279 return count;
280}
281
282Status
283NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
284 RegisterValue &reg_value) {
286
287 if (!reg_info) {
288 error = Status::FromErrorString("reg_info NULL");
289 return error;
290 }
291
292 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
293
294 if (reg == LLDB_INVALID_REGNUM)
296 "no lldb regnum for %s",
297 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
298
299 uint8_t *src;
300 uint32_t offset = LLDB_INVALID_INDEX32;
301 uint64_t sve_vg;
302 std::vector<uint8_t> sve_reg_non_live;
303
304 if (IsGPR(reg)) {
305 error = ReadGPR();
306 if (error.Fail())
307 return error;
308
309 offset = reg_info->byte_offset;
310 assert(offset < GetGPRSize());
311 src = (uint8_t *)GetGPRBuffer() + offset;
312
313 } else if (IsFPR(reg)) {
314 if (m_sve_state == SVEState::Disabled) {
315 // SVE is disabled take legacy route for FPU register access
316 error = ReadFPR();
317 if (error.Fail())
318 return error;
319
320 offset = CalculateFprOffset(reg_info);
321 assert(offset < GetFPRSize());
322 src = (uint8_t *)GetFPRBuffer() + offset;
323 } else {
324 // SVE or SSVE enabled, we will read and cache SVE ptrace data.
325 // In SIMD or Full mode, the data comes from the SVE regset. In streaming
326 // mode it comes from the streaming SVE regset.
327 error = ReadAllSVE();
328 if (error.Fail())
329 return error;
330
331 // FPSR and FPCR will be located right after Z registers in
332 // SVEState::FPSIMD while in SVEState::Full or SVEState::Streaming they
333 // will be located at the end of register data after an alignment
334 // correction based on currently selected vector length.
335 uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
336 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
337 sve_reg_num = reg;
338 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
339 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
340 else if (m_sve_state == SVEState::FPSIMD)
341 offset = sve::ptrace_fpsimd_offset + (32 * 16);
342 } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
343 sve_reg_num = reg;
344 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
345 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
346 else if (m_sve_state == SVEState::FPSIMD)
347 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
348 } else {
349 // Extract SVE Z register value register number for this reg_info
350 if (reg_info->value_regs &&
351 reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
352 sve_reg_num = reg_info->value_regs[0];
353 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
354 }
355
356 assert(offset < GetSVEBufferSize());
357 src = (uint8_t *)GetSVEBuffer() + offset;
358 }
359 } else if (IsTLS(reg)) {
360 error = ReadTLS();
361 if (error.Fail())
362 return error;
363
364 offset = reg_info->byte_offset - GetRegisterInfo().GetTLSOffset();
365 assert(offset < GetTLSBufferSize());
366 src = (uint8_t *)GetTLSBuffer() + offset;
367 } else if (IsSVE(reg)) {
368 if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown)
369 return Status::FromErrorString("SVE disabled or not supported");
370
371 if (GetRegisterInfo().IsSVERegVG(reg)) {
372 sve_vg = GetSVERegVG();
373 src = (uint8_t *)&sve_vg;
374 } else {
375 // SVE enabled, we will read and cache SVE ptrace data
376 error = ReadAllSVE();
377 if (error.Fail())
378 return error;
379
380 if (m_sve_state == SVEState::FPSIMD) {
381 // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so
382 // just copy 16 bytes of v register to the start of z register. All
383 // other SVE register will be set to zero.
384 sve_reg_non_live.resize(reg_info->byte_size, 0);
385 src = sve_reg_non_live.data();
386
387 if (GetRegisterInfo().IsSVEZReg(reg)) {
388 offset = CalculateSVEOffset(reg_info);
389 assert(offset < GetSVEBufferSize());
390 ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
391 16);
392 }
393 } else {
394 offset = CalculateSVEOffset(reg_info);
395 assert(offset < GetSVEBufferSize());
396 src = (uint8_t *)GetSVEBuffer() + offset;
397 }
398 }
399 } else if (IsPAuth(reg)) {
400 error = ReadPAuthMask();
401 if (error.Fail())
402 return error;
403
404 offset = reg_info->byte_offset - GetRegisterInfo().GetPAuthOffset();
405 assert(offset < GetPACMaskSize());
406 src = (uint8_t *)GetPACMask() + offset;
407 } else if (IsMTE(reg)) {
408 error = ReadMTEControl();
409 if (error.Fail())
410 return error;
411
412 offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
413 assert(offset < GetMTEControlSize());
414 src = (uint8_t *)GetMTEControl() + offset;
415 } else if (IsSME(reg)) {
416 if (GetRegisterInfo().IsSMERegZA(reg)) {
417 error = ReadZAHeader();
418 if (error.Fail())
419 return error;
420
421 // If there is only a header and no registers, ZA is inactive. Read as 0
422 // in this case.
423 if (m_za_header.size == sizeof(m_za_header)) {
424 // This will get reconfigured/reset later, so we are safe to use it.
425 // ZA is a square of VL * VL and the ptrace buffer also includes the
426 // header itself.
427 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
428 GetZAHeaderSize());
429 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
430 } else {
431 // ZA is active, read the real register.
432 error = ReadZA();
433 if (error.Fail())
434 return error;
435 }
436
437 // ZA is part of the SME set but uses a separate member buffer for
438 // storage. Therefore its effective byte offset is always 0 even if it
439 // isn't 0 within the SME register set.
440 src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
441 } else if (GetRegisterInfo().IsSMERegZT(reg)) {
442 // Unlike ZA, the kernel will return register data for ZT0 when ZA is not
443 // enabled. This data will be all 0s so we don't have to invent anything
444 // like we did for ZA.
445 error = ReadZT();
446 if (error.Fail())
447 return error;
448
449 src = (uint8_t *)GetZTBuffer();
450 } else {
451 error = ReadSMESVG();
452 if (error.Fail())
453 return error;
454
455 // This is a psuedo so it never fails.
456 ReadSMEControl();
457
458 offset = reg_info->byte_offset - GetRegisterInfo().GetSMEOffset();
459 assert(offset < GetSMEPseudoBufferSize());
460 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
461 }
462 } else if (IsFPMR(reg)) {
463 error = ReadFPMR();
464 if (error.Fail())
465 return error;
466
467 offset = reg_info->byte_offset - GetRegisterInfo().GetFPMROffset();
468 assert(offset < GetFPMRBufferSize());
469 src = (uint8_t *)GetFPMRBuffer() + offset;
470 } else if (IsGCS(reg)) {
471 error = ReadGCS();
472 if (error.Fail())
473 return error;
474
475 offset = reg_info->byte_offset - GetRegisterInfo().GetGCSOffset();
476 assert(offset < GetGCSBufferSize());
477 src = (uint8_t *)GetGCSBuffer() + offset;
478 } else if (IsPOE(reg)) {
479 error = ReadPOE();
480 if (error.Fail())
481 return error;
482
483 offset = reg_info->byte_offset - GetRegisterInfo().GetPOEOffset();
484 assert(offset < GetPOEBufferSize());
485 src = (uint8_t *)GetPOEBuffer() + offset;
486 } else
488 "failed - register wasn't recognized to be a GPR or an FPR, "
489 "write strategy unknown");
490
491 reg_value.SetFromMemoryData(*reg_info, src, reg_info->byte_size,
493
494 return error;
495}
496
497Status NativeRegisterContextLinux_arm64::WriteRegister(
498 const RegisterInfo *reg_info, const RegisterValue &reg_value) {
500
501 if (!reg_info)
502 return Status::FromErrorString("reg_info NULL");
503
504 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
505
506 if (reg == LLDB_INVALID_REGNUM)
508 "no lldb regnum for %s",
509 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
510
511 uint8_t *dst;
512 uint32_t offset = LLDB_INVALID_INDEX32;
513 std::vector<uint8_t> sve_reg_non_live;
514
515 if (IsGPR(reg)) {
516 error = ReadGPR();
517 if (error.Fail())
518 return error;
519
520 assert(reg_info->byte_offset < GetGPRSize());
521 dst = (uint8_t *)GetGPRBuffer() + reg_info->byte_offset;
522 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
523
524 return WriteGPR();
525 } else if (IsFPR(reg)) {
526 if (m_sve_state == SVEState::Disabled) {
527 // SVE is disabled take legacy route for FPU register access
528 error = ReadFPR();
529 if (error.Fail())
530 return error;
531
532 offset = CalculateFprOffset(reg_info);
533 assert(offset < GetFPRSize());
534 dst = (uint8_t *)GetFPRBuffer() + offset;
535 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
536
537 return WriteFPR();
538 } else {
539 // SVE enabled, we will read and cache SVE ptrace data.
540 error = ReadAllSVE();
541 if (error.Fail())
542 return error;
543
544 // FPSR and FPCR will be located right after Z registers in
545 // SVEState::FPSIMD while in SVEState::Full or SVEState::Streaming they
546 // will be located at the end of register data after an alignment
547 // correction based on currently selected vector length.
548 uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
549 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
550 sve_reg_num = reg;
551 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
552 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
553 else if (m_sve_state == SVEState::FPSIMD)
554 offset = sve::ptrace_fpsimd_offset + (32 * 16);
555 } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
556 sve_reg_num = reg;
557 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
558 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
559 else if (m_sve_state == SVEState::FPSIMD)
560 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
561 } else {
562 // Extract SVE Z register value register number for this reg_info
563 if (reg_info->value_regs &&
564 reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
565 sve_reg_num = reg_info->value_regs[0];
566 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
567 }
568
569 assert(offset < GetSVEBufferSize());
570 dst = (uint8_t *)GetSVEBuffer() + offset;
571 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
572 return WriteAllSVE();
573 }
574 } else if (IsSVE(reg)) {
575 if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown)
576 return Status::FromErrorString("SVE disabled or not supported");
577 else {
578 // Target has SVE enabled, we will read and cache SVE ptrace data
579 error = ReadAllSVE();
580 if (error.Fail())
581 return error;
582
583 if (GetRegisterInfo().IsSVERegVG(reg)) {
584 uint64_t vg_value = reg_value.GetAsUInt64();
585
586 if (sve::vl_valid(vg_value * 8)) {
587 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
588 return error;
589
590 SetSVERegVG(vg_value);
591
592 error = WriteSVEHeader();
593 if (error.Success()) {
594 // Changing VG during streaming mode also changes the size of ZA.
595 if (m_sve_state == SVEState::Streaming)
596 m_za_header_is_valid = false;
597 ConfigureRegisterContext();
598 }
599
600 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
601 return error;
602 }
603
604 return Status::FromErrorString("SVE vector length update failed.");
605 }
606
607 // If target supports SVE but currently in FPSIMD mode.
608 if (m_sve_state == SVEState::FPSIMD) {
609 // Here we will check if writing this SVE register enables
610 // SVEState::Full
611 bool set_sve_state_full = false;
612 const uint8_t *reg_bytes = (const uint8_t *)reg_value.GetBytes();
613 if (GetRegisterInfo().IsSVEZReg(reg)) {
614 for (uint32_t i = 16; i < reg_info->byte_size; i++) {
615 if (reg_bytes[i]) {
616 set_sve_state_full = true;
617 break;
618 }
619 }
620 } else if (GetRegisterInfo().IsSVEPReg(reg) ||
621 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
622 for (uint32_t i = 0; i < reg_info->byte_size; i++) {
623 if (reg_bytes[i]) {
624 set_sve_state_full = true;
625 break;
626 }
627 }
628 }
629
630 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
631 // We are writing a Z register which is zero beyond 16 bytes so copy
632 // first 16 bytes only as SVE payload mirrors legacy fpsimd structure
633 offset = CalculateSVEOffset(reg_info);
634 assert(offset < GetSVEBufferSize());
635 dst = (uint8_t *)GetSVEBuffer() + offset;
636 ::memcpy(dst, reg_value.GetBytes(), 16);
637
638 return WriteAllSVE();
639 } else
641 "SVE state change operation not supported");
642 } else {
643 offset = CalculateSVEOffset(reg_info);
644 assert(offset < GetSVEBufferSize());
645 dst = (uint8_t *)GetSVEBuffer() + offset;
646 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
647 return WriteAllSVE();
648 }
649 }
650 } else if (IsMTE(reg)) {
651 error = ReadMTEControl();
652 if (error.Fail())
653 return error;
654
655 offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
656 assert(offset < GetMTEControlSize());
657 dst = (uint8_t *)GetMTEControl() + offset;
658 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
659
660 return WriteMTEControl();
661 } else if (IsTLS(reg)) {
662 error = ReadTLS();
663 if (error.Fail())
664 return error;
665
666 offset = reg_info->byte_offset - GetRegisterInfo().GetTLSOffset();
667 assert(offset < GetTLSBufferSize());
668 dst = (uint8_t *)GetTLSBuffer() + offset;
669 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
670
671 return WriteTLS();
672 } else if (IsSME(reg)) {
673 if (GetRegisterInfo().IsSMERegZA(reg)) {
674 error = ReadZA();
675 if (error.Fail())
676 return error;
677
678 // ZA is part of the SME set but not stored with the other SME registers.
679 // So its byte offset is effectively always 0.
680 dst = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
681 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
682
683 // While this is writing a header that contains a vector length, the only
684 // way to change that is via the vg register. So here we assume the length
685 // will always be the current length and no reconfigure is needed.
686 return WriteZA();
687 } else if (GetRegisterInfo().IsSMERegZT(reg)) {
688 error = ReadZT();
689 if (error.Fail())
690 return error;
691
692 dst = (uint8_t *)GetZTBuffer();
693 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
694
695 return WriteZT();
696 } else
698 "Writing to SVG or SVCR is not supported.");
699 } else if (IsFPMR(reg)) {
700 error = ReadFPMR();
701 if (error.Fail())
702 return error;
703
704 offset = reg_info->byte_offset - GetRegisterInfo().GetFPMROffset();
705 assert(offset < GetFPMRBufferSize());
706 dst = (uint8_t *)GetFPMRBuffer() + offset;
707 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
708
709 return WriteFPMR();
710 } else if (IsGCS(reg)) {
711 error = ReadGCS();
712 if (error.Fail())
713 return error;
714
715 offset = reg_info->byte_offset - GetRegisterInfo().GetGCSOffset();
716 assert(offset < GetGCSBufferSize());
717 dst = (uint8_t *)GetGCSBuffer() + offset;
718 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
719
720 return WriteGCS();
721 } else if (IsPOE(reg)) {
722 error = ReadPOE();
723 if (error.Fail())
724 return error;
725
726 offset = reg_info->byte_offset - GetRegisterInfo().GetPOEOffset();
727 assert(offset < GetPOEBufferSize());
728 dst = (uint8_t *)GetPOEBuffer() + offset;
729 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
730
731 return WritePOE();
732 }
733
734 return Status::FromErrorString("Failed to write register value");
735}
736
737enum RegisterSetType : uint32_t {
738 GPR,
739 SVE, // Used for SVE and SSVE.
740 FPR, // When there is no SVE, or SVE in FPSIMD mode.
741 // Pointer authentication registers are read only, so not included here.
742 MTE,
743 TLS,
744 SME, // ZA only, because SVCR and SVG are pseudo registers.
745 SME2, // ZT only.
746 FPMR,
747 GCS, // Guarded Control Stack registers.
748 POE, // Permission Overlay registers.
749};
750
751static uint8_t *AddRegisterSetType(uint8_t *dst,
752 RegisterSetType register_set_type) {
753 *(reinterpret_cast<uint32_t *>(dst)) = register_set_type;
754 return dst + sizeof(uint32_t);
755}
756
757static uint8_t *AddSavedRegistersData(uint8_t *dst, void *src, size_t size) {
758 ::memcpy(dst, src, size);
759 return dst + size;
760}
761
762static uint8_t *AddSavedRegisters(uint8_t *dst,
763 enum RegisterSetType register_set_type,
764 void *src, size_t size) {
765 dst = AddRegisterSetType(dst, register_set_type);
766 return AddSavedRegistersData(dst, src, size);
767}
768
769Status
770NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
772 cached_size = sizeof(RegisterSetType) + GetGPRBufferSize();
773 error = ReadGPR();
774 if (error.Fail())
775 return error;
776
777 if (GetRegisterInfo().IsZAPresent()) {
778 error = ReadZAHeader();
779 if (error.Fail())
780 return error;
781 // Use header size here because the buffer may contain fake data when ZA is
782 // disabled. We do not want to write this fake data (all 0s) because this
783 // would tell the kernel that we want ZA to become active. Which is the
784 // opposite of what we want in the case where it is currently inactive.
785 cached_size += sizeof(RegisterSetType) + m_za_header.size;
786 // For the same reason, we need to force it to be re-read so that it will
787 // always contain the real header.
788 m_za_buffer_is_valid = false;
789 error = ReadZA();
790 if (error.Fail())
791 return error;
792
793 // We will only be restoring ZT data if ZA is active. As writing to an
794 // inactive ZT enables ZA, which may not be desireable.
795 if (
796 // If we have ZT0, or in other words, if we have SME2.
797 GetRegisterInfo().IsZTPresent() &&
798 // And ZA is active, which means that ZT0 is also active.
799 m_za_header.size > sizeof(m_za_header)) {
800 cached_size += sizeof(RegisterSetType) + GetZTBufferSize();
801 // The kernel handles an inactive ZT0 for us, and it will read as 0s if
802 // inactive (unlike ZA where we fake that behaviour).
803 error = ReadZT();
804 if (error.Fail())
805 return error;
806 }
807 }
808
809 // If SVE is enabled we need not copy FPR separately.
810 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
811 // Store mode and register data.
812 cached_size +=
813 sizeof(RegisterSetType) + sizeof(m_sve_state) + GetSVEBufferSize();
814 error = ReadAllSVE();
815 } else {
816 cached_size += sizeof(RegisterSetType) + GetFPRSize();
817 error = ReadFPR();
818 }
819 if (error.Fail())
820 return error;
821
822 if (GetRegisterInfo().IsMTEPresent()) {
823 cached_size += sizeof(RegisterSetType) + GetMTEControlSize();
824 error = ReadMTEControl();
825 if (error.Fail())
826 return error;
827 }
828
829 if (GetRegisterInfo().IsFPMRPresent()) {
830 cached_size += sizeof(RegisterSetType) + GetFPMRBufferSize();
831 error = ReadFPMR();
832 if (error.Fail())
833 return error;
834 }
835
836 if (GetRegisterInfo().IsGCSPresent()) {
837 cached_size += sizeof(RegisterSetType) + GetGCSBufferSize();
838 error = ReadGCS();
839 if (error.Fail())
840 return error;
841 }
842
843 if (GetRegisterInfo().IsPOEPresent()) {
844 cached_size += sizeof(RegisterSetType) + GetPOEBufferSize();
845 error = ReadPOE();
846 if (error.Fail())
847 return error;
848 }
849
850 // tpidr is always present but tpidr2 depends on SME.
851 cached_size += sizeof(RegisterSetType) + GetTLSBufferSize();
852 error = ReadTLS();
853
854 return error;
855}
856
857Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
859 // AArch64 register data must contain GPRs and either FPR or SVE registers.
860 // SVE registers can be non-streaming (aka SVE) or streaming (aka SSVE).
861 // Finally an optional MTE register. Pointer Authentication (PAC) registers
862 // are read-only and will be skipped.
863
864 // In order to create register data checkpoint we first read all register
865 // values if not done already and calculate total size of register set data.
866 // We store all register values in data_sp by copying full PTrace data that
867 // corresponds to register sets enabled by current register context.
868
869 uint32_t reg_data_byte_size = 0;
870 Status error = CacheAllRegisters(reg_data_byte_size);
871 if (error.Fail())
872 return error;
873
874 data_sp.reset(new DataBufferHeap(reg_data_byte_size, 0));
875 uint8_t *dst = data_sp->GetBytes();
876
877 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
878 GetGPRBufferSize());
879
880 // Streaming SVE and the ZA register both use the streaming vector length.
881 // When you change this, the kernel will invalidate parts of the process
882 // state. Therefore we need a specific order of restoration for each mode, if
883 // we also have ZA to restore.
884 //
885 // Streaming mode enabled, ZA enabled:
886 // * Write streaming registers. This sets SVCR.SM and clears SVCR.ZA.
887 // * Write ZA, this set SVCR.ZA. The register data we provide is written to
888 // ZA.
889 // * Result is SVCR.SM and SVCR.ZA set, with the expected data in both
890 // register sets.
891 //
892 // Streaming mode disabled, ZA enabled:
893 // * Write ZA. This sets SVCR.ZA, and the ZA content. In the majority of cases
894 // the streaming vector length is changing, so the thread is converted into
895 // an FPSIMD thread if it is not already one. This also clears SVCR.SM.
896 // * Write SVE registers, which also clears SVCR.SM but most importantly, puts
897 // us into full SVE mode instead of FPSIMD mode (where the registers are
898 // actually the 128 bit Neon registers).
899 // * Result is we have SVCR.SM = 0, SVCR.ZA = 1 and the expected register
900 // state.
901 //
902 // Restoring in different orders leads to things like the SVE registers being
903 // truncated due to the FPSIMD mode and ZA being disabled or filled with 0s
904 // (disabled and 0s looks the same from inside lldb since we fake the value
905 // when it's disabled).
906 //
907 // For more information on this, look up the uses of the relevant NT_ARM_
908 // constants and the functions vec_set_vector_length, sve_set_common and
909 // za_set in the Linux Kernel.
910
911 if ((m_sve_state != SVEState::Streaming) && GetRegisterInfo().IsZAPresent()) {
912 // Use the header size not the buffer size, as we may be using the buffer
913 // for fake data, which we do not want to write out.
914 assert(m_za_header.size <= GetZABufferSize());
915 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
916 m_za_header.size);
917 }
918
919 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
920 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
921 *(reinterpret_cast<SVEState *>(dst)) = m_sve_state;
922 dst += sizeof(m_sve_state);
923 dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
924 } else {
925 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
926 GetFPRSize());
927 }
928
929 if ((m_sve_state == SVEState::Streaming) && GetRegisterInfo().IsZAPresent()) {
930 assert(m_za_header.size <= GetZABufferSize());
931 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
932 m_za_header.size);
933 }
934
935 // If ZT0 is present and we are going to be restoring an active ZA (which
936 // implies an active ZT0), then restore ZT0 after ZA has been set. This
937 // prevents us enabling ZA accidentally after the restore of ZA disabled it.
938 // If we leave ZA/ZT0 inactive and read ZT0, the kernel returns 0s. Therefore
939 // there's nothing for us to restore if ZA was originally inactive.
940 if (
941 // If we have SME2 and therefore ZT0.
942 GetRegisterInfo().IsZTPresent() &&
943 // And ZA is enabled.
944 m_za_header.size > sizeof(m_za_header))
945 dst = AddSavedRegisters(dst, RegisterSetType::SME2, GetZTBuffer(),
946 GetZTBufferSize());
947
948 if (GetRegisterInfo().IsMTEPresent()) {
949 dst = AddSavedRegisters(dst, RegisterSetType::MTE, GetMTEControl(),
950 GetMTEControlSize());
951 }
952
953 if (GetRegisterInfo().IsFPMRPresent()) {
954 dst = AddSavedRegisters(dst, RegisterSetType::FPMR, GetFPMRBuffer(),
955 GetFPMRBufferSize());
956 }
957
958 if (GetRegisterInfo().IsGCSPresent()) {
959 dst = AddSavedRegisters(dst, RegisterSetType::GCS, GetGCSBuffer(),
960 GetGCSBufferSize());
961 }
962
963 if (GetRegisterInfo().IsPOEPresent()) {
964 dst = AddSavedRegisters(dst, RegisterSetType::POE, GetPOEBuffer(),
965 GetPOEBufferSize());
966 }
967
968 dst = AddSavedRegisters(dst, RegisterSetType::TLS, GetTLSBuffer(),
969 GetTLSBufferSize());
970
971 return error;
972}
973
974static Status RestoreRegisters(void *buffer, const uint8_t **src, size_t len,
975 bool &is_valid, std::function<Status()> writer) {
976 ::memcpy(buffer, *src, len);
977 is_valid = true;
978 *src += len;
979 return writer();
980}
981
982Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
983 const lldb::DataBufferSP &data_sp) {
984 // AArch64 register data must contain GPRs, either FPR or SVE registers
985 // (which can be streaming or non-streaming) and optional MTE register.
986 // Pointer Authentication (PAC) registers are read-only and will be skipped.
987
988 // We store all register values in data_sp by copying full PTrace data that
989 // corresponds to register sets enabled by current register context. In order
990 // to restore from register data checkpoint we will first restore GPRs, based
991 // on size of remaining register data either SVE or FPRs should be restored
992 // next. SVE is not enabled if we have register data size less than or equal
993 // to size of GPR + FPR + MTE.
994
996 if (!data_sp) {
998 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
999 __FUNCTION__);
1000 return error;
1001 }
1002
1003 const uint8_t *src = data_sp->GetBytes();
1004 if (src == nullptr) {
1006 "NativeRegisterContextLinux_arm64::%s "
1007 "DataBuffer::GetBytes() returned a null "
1008 "pointer",
1009 __FUNCTION__);
1010 return error;
1011 }
1012
1013 uint64_t reg_data_min_size =
1014 GetGPRBufferSize() + GetFPRSize() + 2 * (sizeof(RegisterSetType));
1015 if (data_sp->GetByteSize() < reg_data_min_size) {
1017 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1018 "register data bytes, expected at least %" PRIu64 ", actual %" PRIu64,
1019 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1020 return error;
1021 }
1022
1023 const uint8_t *end = src + data_sp->GetByteSize();
1024 while (src < end) {
1025 const RegisterSetType kind =
1026 *reinterpret_cast<const RegisterSetType *>(src);
1027 src += sizeof(RegisterSetType);
1028
1029 switch (kind) {
1030 case RegisterSetType::GPR:
1031 error = RestoreRegisters(
1032 GetGPRBuffer(), &src, GetGPRBufferSize(), m_gpr_is_valid,
1033 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR, this));
1034 break;
1035 case RegisterSetType::SVE:
1036 // Restore to the correct mode, streaming or not.
1037 m_sve_state = static_cast<SVEState>(*src);
1038 src += sizeof(m_sve_state);
1039
1040 // First write SVE header. We do not use RestoreRegisters because we do
1041 // not want src to be modified yet.
1042 ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
1043 if (!sve::vl_valid(m_sve_header.vl)) {
1044 m_sve_header_is_valid = false;
1046 "NativeRegisterContextLinux_arm64::%s "
1047 "Invalid SVE header in data_sp",
1048 __FUNCTION__);
1049 return error;
1050 }
1051 m_sve_header_is_valid = true;
1052 error = WriteSVEHeader();
1053 if (error.Fail())
1054 return error;
1055
1056 // SVE header has been written configure SVE vector length if needed.
1057 // This could change ZA data too, but that will be restored again later
1058 // anyway.
1059 ConfigureRegisterContext();
1060
1061 // Write header and register data, incrementing src this time.
1062 error = RestoreRegisters(
1063 GetSVEBuffer(), &src, GetSVEBufferSize(), m_sve_buffer_is_valid,
1064 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE, this));
1065 break;
1066 case RegisterSetType::FPR:
1067 error = RestoreRegisters(
1068 GetFPRBuffer(), &src, GetFPRSize(), m_fpu_is_valid,
1069 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR, this));
1070 break;
1071 case RegisterSetType::MTE:
1072 error = RestoreRegisters(
1073 GetMTEControl(), &src, GetMTEControlSize(), m_mte_ctrl_is_valid,
1074 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl, this));
1075 break;
1076 case RegisterSetType::TLS:
1077 error = RestoreRegisters(
1078 GetTLSBuffer(), &src, GetTLSBufferSize(), m_tls_is_valid,
1079 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS, this));
1080 break;
1081 case RegisterSetType::SME:
1082 // To enable or disable ZA you write the regset with or without register
1083 // data. The kernel detects this by looking at the ioVec's length, not the
1084 // ZA header size you pass in. Therefore we must write header and register
1085 // data (if present) in one go every time. Read the header only first just
1086 // to get the size.
1087 ::memcpy(GetZAHeader(), src, GetZAHeaderSize());
1088 // Read the header and register data. Can't use the buffer size here, it
1089 // may be incorrect due to being filled with dummy data previously. Resize
1090 // this so WriteZA uses the correct size.
1091 m_za_ptrace_payload.resize(m_za_header.size);
1092 ::memcpy(GetZABuffer(), src, GetZABufferSize());
1093 m_za_buffer_is_valid = true;
1094
1095 error = WriteZA();
1096 if (error.Fail())
1097 return error;
1098
1099 // Update size of ZA, which resizes the ptrace payload potentially
1100 // trashing our copy of the data we just wrote.
1101 ConfigureRegisterContext();
1102
1103 // ZA buffer now has proper size, read back the data we wrote above, from
1104 // ptrace.
1105 error = ReadZA();
1106 src += GetZABufferSize();
1107 break;
1108 case RegisterSetType::SME2:
1109 // Doing this would activate an inactive ZA, however we will only get here
1110 // if the state we are restoring had an active ZA. Restoring ZT0 will
1111 // always come after restoring ZA.
1112 error = RestoreRegisters(
1113 GetZTBuffer(), &src, GetZTBufferSize(), m_zt_buffer_is_valid,
1114 std::bind(&NativeRegisterContextLinux_arm64::WriteZT, this));
1115 break;
1116 case RegisterSetType::FPMR:
1117 error = RestoreRegisters(
1118 GetFPMRBuffer(), &src, GetFPMRBufferSize(), m_fpmr_is_valid,
1119 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR, this));
1120 break;
1121 case RegisterSetType::GCS: {
1122 // It is not permitted to enable GCS via ptrace. We can disable it, but
1123 // to keep things simple we will not revert any change to the
1124 // PR_SHADOW_STACK_ENABLE bit. Instead patch in the current enable bit
1125 // into the registers we are about to restore.
1126 m_gcs_is_valid = false;
1127 error = ReadGCS();
1128 if (error.Fail())
1129 return error;
1130
1131 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1132 gcs_regs new_gcs_regs = *reinterpret_cast<const gcs_regs *>(src);
1133 new_gcs_regs.features_enabled =
1134 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1135
1136 const uint8_t *new_gcs_src =
1137 reinterpret_cast<const uint8_t *>(&new_gcs_regs);
1138 error = RestoreRegisters(
1139 GetGCSBuffer(), &new_gcs_src, GetGCSBufferSize(), m_gcs_is_valid,
1140 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS, this));
1141 src += GetGCSBufferSize();
1142
1143 break;
1144 }
1145 case RegisterSetType::POE:
1146 error = RestoreRegisters(
1147 GetPOEBuffer(), &src, GetPOEBufferSize(), m_poe_is_valid,
1148 std::bind(&NativeRegisterContextLinux_arm64::WritePOE, this));
1149 break;
1150 }
1151
1152 if (error.Fail())
1153 return error;
1154 }
1155
1156 return error;
1157}
1158
1159bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const {
1160 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1162 return true;
1163 return false;
1164}
1165
1166bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const {
1167 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1169 return true;
1170 return false;
1171}
1172
1173bool NativeRegisterContextLinux_arm64::IsSVE(unsigned reg) const {
1174 return GetRegisterInfo().IsSVEReg(reg);
1175}
1176
1177bool NativeRegisterContextLinux_arm64::IsSME(unsigned reg) const {
1178 return GetRegisterInfo().IsSMEReg(reg);
1179}
1180
1181bool NativeRegisterContextLinux_arm64::IsPAuth(unsigned reg) const {
1182 return GetRegisterInfo().IsPAuthReg(reg);
1183}
1184
1185bool NativeRegisterContextLinux_arm64::IsMTE(unsigned reg) const {
1186 return GetRegisterInfo().IsMTEReg(reg);
1187}
1188
1189bool NativeRegisterContextLinux_arm64::IsTLS(unsigned reg) const {
1190 return GetRegisterInfo().IsTLSReg(reg);
1191}
1192
1193bool NativeRegisterContextLinux_arm64::IsFPMR(unsigned reg) const {
1194 return GetRegisterInfo().IsFPMRReg(reg);
1195}
1196
1197bool NativeRegisterContextLinux_arm64::IsGCS(unsigned reg) const {
1198 return GetRegisterInfo().IsGCSReg(reg);
1199}
1200
1201bool NativeRegisterContextLinux_arm64::IsPOE(unsigned reg) const {
1202 return GetRegisterInfo().IsPOEReg(reg);
1203}
1204
1205llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1206 if (!m_refresh_hwdebug_info) {
1207 return llvm::Error::success();
1208 }
1209
1210 ::pid_t tid = m_thread.GetID();
1211
1212 Status error = arm64::ReadHardwareDebugInfo(tid, m_max_hwp_supported,
1213 m_max_hbp_supported);
1214 if (error.Fail())
1215 return error.ToError();
1216
1217 m_refresh_hwdebug_info = false;
1218
1219 return llvm::Error::success();
1220}
1221
1222llvm::Error
1223NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1224 uint32_t max_supported =
1225 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1226 auto &regs = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1227 return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
1228 regs)
1229 .ToError();
1230}
1231
1232Status NativeRegisterContextLinux_arm64::ReadGPR() {
1233 Status error;
1234
1235 if (m_gpr_is_valid)
1236 return error;
1237
1238 struct iovec ioVec;
1239 ioVec.iov_base = GetGPRBuffer();
1240 ioVec.iov_len = GetGPRBufferSize();
1241
1242 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1243
1244 if (error.Success())
1245 m_gpr_is_valid = true;
1246
1247 return error;
1248}
1249
1250Status NativeRegisterContextLinux_arm64::WriteGPR() {
1251 Status error = ReadGPR();
1252 if (error.Fail())
1253 return error;
1254
1255 struct iovec ioVec;
1256 ioVec.iov_base = GetGPRBuffer();
1257 ioVec.iov_len = GetGPRBufferSize();
1258
1259 m_gpr_is_valid = false;
1260
1261 return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1262}
1263
1264Status NativeRegisterContextLinux_arm64::ReadFPR() {
1265 Status error;
1266
1267 if (m_fpu_is_valid)
1268 return error;
1269
1270 struct iovec ioVec;
1271 ioVec.iov_base = GetFPRBuffer();
1272 ioVec.iov_len = GetFPRSize();
1273
1274 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1275
1276 if (error.Success())
1277 m_fpu_is_valid = true;
1278
1279 return error;
1280}
1281
1282Status NativeRegisterContextLinux_arm64::WriteFPR() {
1283 Status error = ReadFPR();
1284 if (error.Fail())
1285 return error;
1286
1287 struct iovec ioVec;
1288 ioVec.iov_base = GetFPRBuffer();
1289 ioVec.iov_len = GetFPRSize();
1290
1291 m_fpu_is_valid = false;
1292
1293 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1294}
1295
1296void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1297 m_gpr_is_valid = false;
1298 m_fpu_is_valid = false;
1299 m_sve_buffer_is_valid = false;
1300 m_sve_header_is_valid = false;
1301 m_za_buffer_is_valid = false;
1302 m_za_header_is_valid = false;
1303 m_pac_mask_is_valid = false;
1304 m_mte_ctrl_is_valid = false;
1305 m_tls_is_valid = false;
1306 m_zt_buffer_is_valid = false;
1307 m_fpmr_is_valid = false;
1308 m_gcs_is_valid = false;
1309 m_poe_is_valid = false;
1310
1311 // Update SVE and ZA registers in case there is change in configuration.
1312 ConfigureRegisterContext();
1313}
1314
1315unsigned NativeRegisterContextLinux_arm64::GetSVERegSet() {
1316 return m_sve_state == SVEState::Streaming ? NT_ARM_SSVE : NT_ARM_SVE;
1317}
1318
1319Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1320 Status error;
1321
1322 if (m_sve_header_is_valid)
1323 return error;
1324
1325 struct iovec ioVec;
1326 ioVec.iov_base = GetSVEHeader();
1327 ioVec.iov_len = GetSVEHeaderSize();
1328
1329 error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1330
1331 if (error.Success())
1332 m_sve_header_is_valid = true;
1333
1334 return error;
1335}
1336
1337Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1338 Status error;
1339
1340 if (m_pac_mask_is_valid)
1341 return error;
1342
1343 struct iovec ioVec;
1344 ioVec.iov_base = GetPACMask();
1345 ioVec.iov_len = GetPACMaskSize();
1346
1347 error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
1348
1349 if (error.Success())
1350 m_pac_mask_is_valid = true;
1351
1352 return error;
1353}
1354
1355Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1356 Status error;
1357
1358 error = ReadSVEHeader();
1359 if (error.Fail())
1360 return error;
1361
1362 struct iovec ioVec;
1363 ioVec.iov_base = GetSVEHeader();
1364 ioVec.iov_len = GetSVEHeaderSize();
1365
1366 m_sve_buffer_is_valid = false;
1367 m_sve_header_is_valid = false;
1368 m_fpu_is_valid = false;
1369
1370 return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1371}
1372
1373Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1374 Status error;
1375 if (m_sve_buffer_is_valid)
1376 return error;
1377
1378 struct iovec ioVec;
1379 ioVec.iov_base = GetSVEBuffer();
1380 ioVec.iov_len = GetSVEBufferSize();
1381
1382 error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1383
1384 if (error.Success())
1385 m_sve_buffer_is_valid = true;
1386
1387 return error;
1388}
1389
1390Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1391 Status error;
1392
1393 error = ReadAllSVE();
1394 if (error.Fail())
1395 return error;
1396
1397 struct iovec ioVec;
1398
1399 ioVec.iov_base = GetSVEBuffer();
1400 ioVec.iov_len = GetSVEBufferSize();
1401
1402 m_sve_buffer_is_valid = false;
1403 m_sve_header_is_valid = false;
1404 m_fpu_is_valid = false;
1405
1406 return WriteRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1407}
1408
1409Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1410 // The real register is SVCR and is accessible from EL0. However we don't want
1411 // to have to JIT code into the target process so we'll just recreate it using
1412 // what we know from ptrace.
1413
1414 // Bit 0 indicates whether streaming mode is active.
1415 m_sme_pseudo_regs.ctrl_reg = m_sve_state == SVEState::Streaming;
1416
1417 // Bit 1 indicates whether the array storage is active.
1418 // It is active if we can read the header and the size field tells us that
1419 // there is register data following it.
1420 Status error = ReadZAHeader();
1421 if (error.Success() && (m_za_header.size > sizeof(m_za_header)))
1422 m_sme_pseudo_regs.ctrl_reg |= 2;
1423
1424 return error;
1425}
1426
1427Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1428 Status error;
1429
1430 if (m_mte_ctrl_is_valid)
1431 return error;
1432
1433 struct iovec ioVec;
1434 ioVec.iov_base = GetMTEControl();
1435 ioVec.iov_len = GetMTEControlSize();
1436
1437 error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1438
1439 if (error.Success())
1440 m_mte_ctrl_is_valid = true;
1441
1442 return error;
1443}
1444
1445Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1446 Status error;
1447
1448 error = ReadMTEControl();
1449 if (error.Fail())
1450 return error;
1451
1452 struct iovec ioVec;
1453 ioVec.iov_base = GetMTEControl();
1454 ioVec.iov_len = GetMTEControlSize();
1455
1456 m_mte_ctrl_is_valid = false;
1457
1458 return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1459}
1460
1461Status NativeRegisterContextLinux_arm64::ReadTLS() {
1462 Status error;
1463
1464 if (m_tls_is_valid)
1465 return error;
1466
1467 struct iovec ioVec;
1468 ioVec.iov_base = GetTLSBuffer();
1469 ioVec.iov_len = GetTLSBufferSize();
1470
1471 error = ReadRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1472
1473 if (error.Success())
1474 m_tls_is_valid = true;
1475
1476 return error;
1477}
1478
1479Status NativeRegisterContextLinux_arm64::WriteTLS() {
1480 Status error;
1481
1482 error = ReadTLS();
1483 if (error.Fail())
1484 return error;
1485
1486 struct iovec ioVec;
1487 ioVec.iov_base = GetTLSBuffer();
1488 ioVec.iov_len = GetTLSBufferSize();
1489
1490 m_tls_is_valid = false;
1491
1492 return WriteRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1493}
1494
1495Status NativeRegisterContextLinux_arm64::ReadGCS() {
1496 Status error;
1497
1498 if (m_gcs_is_valid)
1499 return error;
1500
1501 struct iovec ioVec;
1502 ioVec.iov_base = GetGCSBuffer();
1503 ioVec.iov_len = GetGCSBufferSize();
1504
1505 error = ReadRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1506
1507 if (error.Success())
1508 m_gcs_is_valid = true;
1509
1510 return error;
1511}
1512
1513Status NativeRegisterContextLinux_arm64::WriteGCS() {
1514 Status error;
1515
1516 error = ReadGCS();
1517 if (error.Fail())
1518 return error;
1519
1520 struct iovec ioVec;
1521 ioVec.iov_base = GetGCSBuffer();
1522 ioVec.iov_len = GetGCSBufferSize();
1523
1524 m_gcs_is_valid = false;
1525
1526 return WriteRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1527}
1528
1529Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1530 Status error;
1531
1532 if (m_za_header_is_valid)
1533 return error;
1534
1535 struct iovec ioVec;
1536 ioVec.iov_base = GetZAHeader();
1537 ioVec.iov_len = GetZAHeaderSize();
1538
1539 error = ReadRegisterSet(&ioVec, GetZAHeaderSize(), NT_ARM_ZA);
1540
1541 if (error.Success())
1542 m_za_header_is_valid = true;
1543
1544 return error;
1545}
1546
1547Status NativeRegisterContextLinux_arm64::ReadZA() {
1548 Status error;
1549
1550 if (m_za_buffer_is_valid)
1551 return error;
1552
1553 struct iovec ioVec;
1554 ioVec.iov_base = GetZABuffer();
1555 ioVec.iov_len = GetZABufferSize();
1556
1557 error = ReadRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1558
1559 if (error.Success())
1560 m_za_buffer_is_valid = true;
1561
1562 return error;
1563}
1564
1565Status NativeRegisterContextLinux_arm64::WriteZA() {
1566 // Note that because the ZA ptrace payload contains the header also, this
1567 // method will write both. This is done because writing only the header
1568 // will disable ZA, even if .size in the header is correct for an enabled ZA.
1569 Status error;
1570
1571 error = ReadZA();
1572 if (error.Fail())
1573 return error;
1574
1575 struct iovec ioVec;
1576 ioVec.iov_base = GetZABuffer();
1577 ioVec.iov_len = GetZABufferSize();
1578
1579 m_za_buffer_is_valid = false;
1580 m_za_header_is_valid = false;
1581 // Writing to ZA may enable ZA, which means ZT0 may change too.
1582 m_zt_buffer_is_valid = false;
1583
1584 return WriteRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1585}
1586
1587Status NativeRegisterContextLinux_arm64::ReadZT() {
1588 Status error;
1589
1590 if (m_zt_buffer_is_valid)
1591 return error;
1592
1593 struct iovec ioVec;
1594 ioVec.iov_base = GetZTBuffer();
1595 ioVec.iov_len = GetZTBufferSize();
1596
1597 error = ReadRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1598 m_zt_buffer_is_valid = error.Success();
1599
1600 return error;
1601}
1602
1603Status NativeRegisterContextLinux_arm64::WriteZT() {
1604 Status error;
1605
1606 error = ReadZT();
1607 if (error.Fail())
1608 return error;
1609
1610 struct iovec ioVec;
1611 ioVec.iov_base = GetZTBuffer();
1612 ioVec.iov_len = GetZTBufferSize();
1613
1614 m_zt_buffer_is_valid = false;
1615 // Writing to an inactive ZT0 will enable ZA as well, which invalidates our
1616 // current copy of it.
1617 m_za_buffer_is_valid = false;
1618 m_za_header_is_valid = false;
1619
1620 return WriteRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1621}
1622
1623Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1624 Status error;
1625
1626 if (m_fpmr_is_valid)
1627 return error;
1628
1629 struct iovec ioVec;
1630 ioVec.iov_base = GetFPMRBuffer();
1631 ioVec.iov_len = GetFPMRBufferSize();
1632
1633 error = ReadRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1634
1635 if (error.Success())
1636 m_fpmr_is_valid = true;
1637
1638 return error;
1639}
1640
1641Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1642 Status error;
1643
1644 error = ReadFPMR();
1645 if (error.Fail())
1646 return error;
1647
1648 struct iovec ioVec;
1649 ioVec.iov_base = GetFPMRBuffer();
1650 ioVec.iov_len = GetFPMRBufferSize();
1651
1652 m_fpmr_is_valid = false;
1653
1654 return WriteRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1655}
1656
1657Status NativeRegisterContextLinux_arm64::ReadPOE() {
1658 Status error;
1659
1660 if (m_poe_is_valid)
1661 return error;
1662
1663 struct iovec ioVec;
1664 ioVec.iov_base = GetPOEBuffer();
1665 ioVec.iov_len = GetPOEBufferSize();
1666
1667 error = ReadRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1668
1669 if (error.Success())
1670 m_poe_is_valid = true;
1671
1672 return error;
1673}
1674
1675Status NativeRegisterContextLinux_arm64::WritePOE() {
1676 Status error;
1677
1678 error = ReadPOE();
1679 if (error.Fail())
1680 return error;
1681
1682 struct iovec ioVec;
1683 ioVec.iov_base = GetPOEBuffer();
1684 ioVec.iov_len = GetPOEBufferSize();
1685
1686 m_poe_is_valid = false;
1687
1688 return WriteRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1689}
1690
1691void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1692 // ConfigureRegisterContext gets called from InvalidateAllRegisters
1693 // on every stop and configures SVE vector length and whether we are in
1694 // streaming SVE mode.
1695 // If m_sve_state is set to SVEState::Disabled on first stop, code below will
1696 // be deemed non operational for the lifetime of current process.
1697 if (!m_sve_header_is_valid && m_sve_state != SVEState::Disabled) {
1698 // If we have SVE we may also have the SVE streaming mode that SME added.
1699 // We can read the header of either mode, but only the active mode will
1700 // have valid register data.
1701
1702 // Check whether SME is present and the streaming SVE mode is active.
1703 m_sve_header_is_valid = false;
1704 m_sve_buffer_is_valid = false;
1705 m_sve_state = SVEState::Streaming;
1706 Status error = ReadSVEHeader();
1707
1708 // Streaming mode is active if the header has the SVE active flag set.
1709 if (!(error.Success() && ((m_sve_header.flags & sve::ptrace_regs_mask) ==
1711 // Non-streaming might be active instead.
1712 m_sve_header_is_valid = false;
1713 m_sve_buffer_is_valid = false;
1714 m_sve_state = SVEState::Full;
1715 error = ReadSVEHeader();
1716 if (error.Success()) {
1717 // If SVE is enabled thread can switch between SVEState::FPSIMD and
1718 // SVEState::Full on every stop.
1719 if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
1721 m_sve_state = SVEState::FPSIMD;
1722 // Else we are in SVEState::Full.
1723 } else {
1724 m_sve_state = SVEState::Disabled;
1725 }
1726 }
1727
1728 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::FPSIMD ||
1729 m_sve_state == SVEState::Streaming) {
1730 // On every stop we configure SVE vector length by calling
1731 // ConfigureVectorLengthSVE regardless of current SVEState of this thread.
1733 if (sve::vl_valid(m_sve_header.vl))
1734 vq = sve::vq_from_vl(m_sve_header.vl);
1735
1736 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1737 m_sve_ptrace_payload.resize(sve::PTraceSize(vq, sve::ptrace_regs_sve));
1738 }
1739 }
1740
1741 if (!m_za_header_is_valid) {
1742 Status error = ReadZAHeader();
1743 if (error.Success()) {
1745 if (sve::vl_valid(m_za_header.vl))
1746 vq = sve::vq_from_vl(m_za_header.vl);
1747
1748 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1749 m_za_ptrace_payload.resize(m_za_header.size);
1750 m_za_buffer_is_valid = false;
1751 }
1752 }
1753}
1754
1755uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1756 const RegisterInfo *reg_info) const {
1757 return reg_info->byte_offset - GetGPRSize();
1758}
1759
1760uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1761 const RegisterInfo *reg_info) const {
1762 // Start of Z0 data is after GPRs plus 8 bytes of vg register
1763 uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
1764 if (m_sve_state == SVEState::FPSIMD) {
1765 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
1766 sve_reg_offset = sve::ptrace_fpsimd_offset +
1767 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1768 // Between non-streaming and streaming mode, the layout is identical.
1769 } else if (m_sve_state == SVEState::Full ||
1770 m_sve_state == SVEState::Streaming) {
1771 uint32_t sve_z0_offset = GetGPRSize() + 16;
1772 sve_reg_offset =
1773 sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
1774 }
1775 return sve_reg_offset;
1776}
1777
1778Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
1779 // This register is the streaming vector length, so we will get it from
1780 // NT_ARM_ZA regardless of the current streaming mode.
1781 Status error = ReadZAHeader();
1782 if (error.Success())
1783 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
1784
1785 return error;
1786}
1787
1788std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
1789 ExpeditedRegs expType) const {
1790 std::vector<uint32_t> expedited_reg_nums =
1792 // SVE, non-streaming vector length.
1793 if (m_sve_state == SVEState::FPSIMD || m_sve_state == SVEState::Full)
1794 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
1795 // SME, streaming vector length. This is used by the ZA register which is
1796 // present even when streaming mode is not enabled.
1797 if (GetRegisterInfo().IsSSVEPresent())
1798 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
1799
1800 return expedited_reg_nums;
1801}
1802
1803llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
1804NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
1806 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
1808 }
1809
1810 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1811 "Unknown AArch64 memory tag type %d", type);
1812}
1813
1814lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
1815 lldb::addr_t hit_addr) {
1816 // Linux configures user-space virtual addresses with top byte ignored.
1817 // We set default value of mask such that top byte is masked out.
1818 lldb::addr_t mask = ~((1ULL << 56) - 1);
1819
1820 // Try to read pointer authentication data_mask register and calculate a
1821 // consolidated data address mask after ignoring the top byte.
1822 if (ReadPAuthMask().Success())
1823 mask |= m_pac_mask.data_mask;
1824
1825 return hit_addr & ~mask;
1826 ;
1827}
1828
1829#endif // defined (__arm64__) || defined (__aarch64__)
#define GPR(r16)
Definition ABIX86.cpp:145
static llvm::raw_ostream & error(Stream &strm)
#define HWCAP2_MTE
#define PTRACE_PEEKMTETAGS
Definition Ptrace.h:61
#define PTRACE_POKEMTETAGS
Definition Ptrace.h:64
#define PTRACE_GETREGSET
Definition Ptrace.h:36
struct _FPR FPR
#define HWCAP2_FPMR
@ AUXV_AT_HWCAP2
Extension of AT_HWCAP.
Definition AuxVector.h:59
@ AUXV_AT_HWCAP3
Extension of AT_HWCAP.
Definition AuxVector.h:60
@ AUXV_AT_HWCAP
Machine dependent hints about processor capabilities.
Definition AuxVector.h:49
size_t GetRegisterSetCount() const override
This class manages the storage and detection of register field information.
void DetectFields(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
For the registers listed in this class, detect which fields are present.
void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs)
Add the field information of any registers named in this class, to the relevant RegisterInfo instance...
bool HasDetected() const
Returns true if field detection has been run at least once.
A subclass of DataBuffer that stores a data buffer on the heap.
std::optional< uint64_t > GetAuxValue(enum AuxVector::EntryType type)
virtual std::vector< uint32_t > GetExpeditedRegisters(ExpeditedRegs expType) const
uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
const void * GetBytes() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
Manages communication with the inferior (debugee) process.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
static std::unique_ptr< NativeRegisterContextLinux > CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch, NativeThreadLinux &native_thread)
static llvm::Expected< ArchSpec > DetermineArchitecture(lldb::tid_t tid)
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_REGNUM
Status WriteHardwareDebugRegs(int hwbType, ::pid_t tid, uint32_t max_supported, const std::array< NativeRegisterContextDBReg::DREG, 16 > &regs)
Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported, uint32_t &max_hbp_supported)
uint16_t vq_from_vl(uint16_t vl)
uint32_t PTraceFPSROffset(uint16_t vq)
uint32_t PTraceFPCROffset(uint16_t vq)
uint16_t vl_valid(uint16_t vl)
uint32_t PTraceSize(uint16_t vq, uint16_t flags)
A class that represents a running process on the host machine.
uint64_t pid_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:84
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t * value_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.