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