1 //===-- RegisterContextDarwin_arm64.cpp -----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "RegisterContextDarwin_arm64.h"
10 #include "RegisterContextDarwinConstants.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/DataBufferHeap.h"
15 #include "lldb/Utility/DataExtractor.h"
16 #include "lldb/Utility/Endian.h"
17 #include "lldb/Utility/Log.h"
18 #include "lldb/Utility/RegisterValue.h"
19 #include "lldb/Utility/Scalar.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/Support/Compiler.h"
23 #include "Plugins/Process/Utility/InstructionUtils.h"
27 #if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))
28 #include <sys/types.h>
29 #include <sys/sysctl.h>
32 #include "Utility/ARM64_DWARF_Registers.h"
35 using namespace lldb_private
;
37 #define GPR_OFFSET(idx) ((idx)*8)
38 #define GPR_OFFSET_NAME(reg) \
39 (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::GPR, reg))
41 #define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterContextDarwin_arm64::GPR))
42 #define FPU_OFFSET_NAME(reg) \
43 (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::FPU, reg))
45 #define EXC_OFFSET_NAME(reg) \
46 (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::EXC, reg) + \
47 sizeof(RegisterContextDarwin_arm64::GPR) + \
48 sizeof(RegisterContextDarwin_arm64::FPU))
49 #define DBG_OFFSET_NAME(reg) \
50 (LLVM_EXTENSION offsetof(RegisterContextDarwin_arm64::DBG, reg) + \
51 sizeof(RegisterContextDarwin_arm64::GPR) + \
52 sizeof(RegisterContextDarwin_arm64::FPU) + \
53 sizeof(RegisterContextDarwin_arm64::EXC))
55 #define DEFINE_DBG(reg, i) \
57 sizeof(((RegisterContextDarwin_arm64::DBG *) NULL)->reg[i]), \
58 DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \
59 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
60 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
61 LLDB_INVALID_REGNUM }, \
63 #define REG_CONTEXT_SIZE \
64 (sizeof(RegisterContextDarwin_arm64::GPR) + \
65 sizeof(RegisterContextDarwin_arm64::FPU) + \
66 sizeof(RegisterContextDarwin_arm64::EXC))
68 // Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
69 #define DECLARE_REGISTER_INFOS_ARM64_STRUCT
70 #include "RegisterInfos_arm64.h"
71 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
73 // General purpose registers
74 static uint32_t g_gpr_regnums
[] = {
75 gpr_x0
, gpr_x1
, gpr_x2
, gpr_x3
, gpr_x4
, gpr_x5
, gpr_x6
,
76 gpr_x7
, gpr_x8
, gpr_x9
, gpr_x10
, gpr_x11
, gpr_x12
, gpr_x13
,
77 gpr_x14
, gpr_x15
, gpr_x16
, gpr_x17
, gpr_x18
, gpr_x19
, gpr_x20
,
78 gpr_x21
, gpr_x22
, gpr_x23
, gpr_x24
, gpr_x25
, gpr_x26
, gpr_x27
,
79 gpr_x28
, gpr_fp
, gpr_lr
, gpr_sp
, gpr_pc
, gpr_cpsr
};
81 // Floating point registers
82 static uint32_t g_fpu_regnums
[] = {
83 fpu_v0
, fpu_v1
, fpu_v2
, fpu_v3
, fpu_v4
, fpu_v5
, fpu_v6
,
84 fpu_v7
, fpu_v8
, fpu_v9
, fpu_v10
, fpu_v11
, fpu_v12
, fpu_v13
,
85 fpu_v14
, fpu_v15
, fpu_v16
, fpu_v17
, fpu_v18
, fpu_v19
, fpu_v20
,
86 fpu_v21
, fpu_v22
, fpu_v23
, fpu_v24
, fpu_v25
, fpu_v26
, fpu_v27
,
87 fpu_v28
, fpu_v29
, fpu_v30
, fpu_v31
, fpu_fpsr
, fpu_fpcr
};
89 // Exception registers
91 static uint32_t g_exc_regnums
[] = {exc_far
, exc_esr
, exc_exception
};
93 static size_t k_num_register_infos
= std::size(g_register_infos_arm64_le
);
95 RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(
96 Thread
&thread
, uint32_t concrete_frame_idx
)
97 : RegisterContext(thread
, concrete_frame_idx
), gpr(), fpu(), exc(), dbg() {
99 for (i
= 0; i
< kNumErrors
; i
++) {
106 RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default;
108 void RegisterContextDarwin_arm64::InvalidateAllRegisters() {
109 InvalidateAllRegisterStates();
112 size_t RegisterContextDarwin_arm64::GetRegisterCount() {
113 assert(k_num_register_infos
== k_num_registers
);
114 return k_num_registers
;
118 RegisterContextDarwin_arm64::GetRegisterInfoAtIndex(size_t reg
) {
119 assert(k_num_register_infos
== k_num_registers
);
120 if (reg
< k_num_registers
)
121 return &g_register_infos_arm64_le
[reg
];
125 size_t RegisterContextDarwin_arm64::GetRegisterInfosCount() {
126 return k_num_register_infos
;
129 const RegisterInfo
*RegisterContextDarwin_arm64::GetRegisterInfos() {
130 return g_register_infos_arm64_le
;
133 // Number of registers in each register set
134 const size_t k_num_gpr_registers
= std::size(g_gpr_regnums
);
135 const size_t k_num_fpu_registers
= std::size(g_fpu_regnums
);
136 const size_t k_num_exc_registers
= std::size(g_exc_regnums
);
138 // Register set definitions. The first definitions at register set index of
139 // zero is for all registers, followed by other registers sets. The register
140 // information for the all register set need not be filled in.
141 static const RegisterSet g_reg_sets
[] = {
143 "General Purpose Registers", "gpr", k_num_gpr_registers
, g_gpr_regnums
,
145 {"Floating Point Registers", "fpu", k_num_fpu_registers
, g_fpu_regnums
},
146 {"Exception State Registers", "exc", k_num_exc_registers
, g_exc_regnums
}};
148 const size_t k_num_regsets
= std::size(g_reg_sets
);
150 size_t RegisterContextDarwin_arm64::GetRegisterSetCount() {
151 return k_num_regsets
;
154 const RegisterSet
*RegisterContextDarwin_arm64::GetRegisterSet(size_t reg_set
) {
155 if (reg_set
< k_num_regsets
)
156 return &g_reg_sets
[reg_set
];
160 // Register information definitions for arm64
161 int RegisterContextDarwin_arm64::GetSetForNativeRegNum(int reg
) {
164 else if (reg
< exc_far
)
166 else if (reg
< k_num_registers
)
171 int RegisterContextDarwin_arm64::ReadGPR(bool force
) {
173 if (force
|| !RegisterSetIsCached(set
)) {
174 SetError(set
, Read
, DoReadGPR(GetThreadID(), set
, gpr
));
176 return GetError(GPRRegSet
, Read
);
179 int RegisterContextDarwin_arm64::ReadFPU(bool force
) {
181 if (force
|| !RegisterSetIsCached(set
)) {
182 SetError(set
, Read
, DoReadFPU(GetThreadID(), set
, fpu
));
184 return GetError(FPURegSet
, Read
);
187 int RegisterContextDarwin_arm64::ReadEXC(bool force
) {
189 if (force
|| !RegisterSetIsCached(set
)) {
190 SetError(set
, Read
, DoReadEXC(GetThreadID(), set
, exc
));
192 return GetError(EXCRegSet
, Read
);
195 int RegisterContextDarwin_arm64::ReadDBG(bool force
) {
197 if (force
|| !RegisterSetIsCached(set
)) {
198 SetError(set
, Read
, DoReadDBG(GetThreadID(), set
, dbg
));
200 return GetError(DBGRegSet
, Read
);
203 int RegisterContextDarwin_arm64::WriteGPR() {
205 if (!RegisterSetIsCached(set
)) {
206 SetError(set
, Write
, -1);
207 return KERN_INVALID_ARGUMENT
;
209 SetError(set
, Write
, DoWriteGPR(GetThreadID(), set
, gpr
));
210 SetError(set
, Read
, -1);
211 return GetError(GPRRegSet
, Write
);
214 int RegisterContextDarwin_arm64::WriteFPU() {
216 if (!RegisterSetIsCached(set
)) {
217 SetError(set
, Write
, -1);
218 return KERN_INVALID_ARGUMENT
;
220 SetError(set
, Write
, DoWriteFPU(GetThreadID(), set
, fpu
));
221 SetError(set
, Read
, -1);
222 return GetError(FPURegSet
, Write
);
225 int RegisterContextDarwin_arm64::WriteEXC() {
227 if (!RegisterSetIsCached(set
)) {
228 SetError(set
, Write
, -1);
229 return KERN_INVALID_ARGUMENT
;
231 SetError(set
, Write
, DoWriteEXC(GetThreadID(), set
, exc
));
232 SetError(set
, Read
, -1);
233 return GetError(EXCRegSet
, Write
);
236 int RegisterContextDarwin_arm64::WriteDBG() {
238 if (!RegisterSetIsCached(set
)) {
239 SetError(set
, Write
, -1);
240 return KERN_INVALID_ARGUMENT
;
242 SetError(set
, Write
, DoWriteDBG(GetThreadID(), set
, dbg
));
243 SetError(set
, Read
, -1);
244 return GetError(DBGRegSet
, Write
);
247 int RegisterContextDarwin_arm64::ReadRegisterSet(uint32_t set
, bool force
) {
250 return ReadGPR(force
);
252 return ReadFPU(force
);
254 return ReadEXC(force
);
256 return ReadDBG(force
);
260 return KERN_INVALID_ARGUMENT
;
263 int RegisterContextDarwin_arm64::WriteRegisterSet(uint32_t set
) {
264 // Make sure we have a valid context to set.
265 if (RegisterSetIsCached(set
)) {
279 return KERN_INVALID_ARGUMENT
;
282 void RegisterContextDarwin_arm64::LogDBGRegisters(Log
*log
, const DBG
&dbg
) {
284 for (uint32_t i
= 0; i
< 16; i
++)
286 "BVR%-2u/BCR%-2u = { 0x%8.8" PRIu64
", 0x%8.8" PRIu64
287 " } WVR%-2u/WCR%-2u "
288 "= { 0x%8.8" PRIu64
", 0x%8.8" PRIu64
" }",
289 i
, i
, dbg
.bvr
[i
], dbg
.bcr
[i
], i
, i
, dbg
.wvr
[i
], dbg
.wcr
[i
]);
293 bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo
*reg_info
,
294 RegisterValue
&value
) {
295 const uint32_t reg
= reg_info
->kinds
[eRegisterKindLLDB
];
296 int set
= RegisterContextDarwin_arm64::GetSetForNativeRegNum(reg
);
301 if (ReadRegisterSet(set
, false) != KERN_SUCCESS
)
334 value
.SetUInt64(gpr
.x
[reg
- gpr_x0
]);
337 value
.SetUInt64(gpr
.fp
);
340 value
.SetUInt64(gpr
.sp
);
343 value
.SetUInt64(gpr
.lr
);
346 value
.SetUInt64(gpr
.pc
);
349 value
.SetUInt64(gpr
.cpsr
);
381 ProcessSP
process_sp(m_thread
.GetProcess());
382 if (process_sp
.get()) {
383 DataExtractor
regdata(&gpr
.x
[reg
- gpr_w0
], 8, process_sp
->GetByteOrder(),
384 process_sp
->GetAddressByteSize());
386 uint64_t retval
= regdata
.GetMaxU64(&offset
, 8);
387 uint32_t retval_lower32
= static_cast<uint32_t>(retval
& 0xffffffff);
388 value
.SetUInt32(retval_lower32
);
424 value
.SetBytes(fpu
.v
[reg
- fpu_v0
].bytes
, reg_info
->byte_size
,
425 endian::InlHostByteOrder());
460 ProcessSP
process_sp(m_thread
.GetProcess());
461 if (process_sp
.get()) {
462 DataExtractor
regdata(&fpu
.v
[reg
- fpu_s0
], 4, process_sp
->GetByteOrder(),
463 process_sp
->GetAddressByteSize());
465 value
.SetFloat(regdata
.GetFloat(&offset
));
501 ProcessSP
process_sp(m_thread
.GetProcess());
502 if (process_sp
.get()) {
503 DataExtractor
regdata(&fpu
.v
[reg
- fpu_d0
], 8, process_sp
->GetByteOrder(),
504 process_sp
->GetAddressByteSize());
506 value
.SetDouble(regdata
.GetDouble(&offset
));
511 value
.SetUInt32(fpu
.fpsr
);
515 value
.SetUInt32(fpu
.fpcr
);
519 value
.SetUInt32(exc
.exception
);
522 value
.SetUInt32(exc
.esr
);
525 value
.SetUInt64(exc
.far
);
529 value
.SetValueToInvalid();
535 bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo
*reg_info
,
536 const RegisterValue
&value
) {
537 const uint32_t reg
= reg_info
->kinds
[eRegisterKindLLDB
];
538 int set
= GetSetForNativeRegNum(reg
);
543 if (ReadRegisterSet(set
, false) != KERN_SUCCESS
)
581 gpr
.x
[reg
- gpr_x0
] = value
.GetAsUInt64();
616 ::memcpy(fpu
.v
[reg
- fpu_v0
].bytes
, value
.GetBytes(),
617 value
.GetByteSize());
621 fpu
.fpsr
= value
.GetAsUInt32();
625 fpu
.fpcr
= value
.GetAsUInt32();
629 exc
.exception
= value
.GetAsUInt32();
632 exc
.esr
= value
.GetAsUInt32();
635 exc
.far
= value
.GetAsUInt64();
641 return WriteRegisterSet(set
) == KERN_SUCCESS
;
644 bool RegisterContextDarwin_arm64::ReadAllRegisterValues(
645 lldb::WritableDataBufferSP
&data_sp
) {
646 data_sp
= std::make_shared
<DataBufferHeap
>(REG_CONTEXT_SIZE
, 0);
647 if (ReadGPR(false) == KERN_SUCCESS
&& ReadFPU(false) == KERN_SUCCESS
&&
648 ReadEXC(false) == KERN_SUCCESS
) {
649 uint8_t *dst
= data_sp
->GetBytes();
650 ::memcpy(dst
, &gpr
, sizeof(gpr
));
653 ::memcpy(dst
, &fpu
, sizeof(fpu
));
656 ::memcpy(dst
, &exc
, sizeof(exc
));
662 bool RegisterContextDarwin_arm64::WriteAllRegisterValues(
663 const lldb::DataBufferSP
&data_sp
) {
664 if (data_sp
&& data_sp
->GetByteSize() == REG_CONTEXT_SIZE
) {
665 const uint8_t *src
= data_sp
->GetBytes();
666 ::memcpy(&gpr
, src
, sizeof(gpr
));
669 ::memcpy(&fpu
, src
, sizeof(fpu
));
672 ::memcpy(&exc
, src
, sizeof(exc
));
673 uint32_t success_count
= 0;
674 if (WriteGPR() == KERN_SUCCESS
)
676 if (WriteFPU() == KERN_SUCCESS
)
678 if (WriteEXC() == KERN_SUCCESS
)
680 return success_count
== 3;
685 uint32_t RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber(
686 RegisterKind kind
, uint32_t reg
) {
687 if (kind
== eRegisterKindGeneric
) {
689 case LLDB_REGNUM_GENERIC_PC
:
691 case LLDB_REGNUM_GENERIC_SP
:
693 case LLDB_REGNUM_GENERIC_FP
:
695 case LLDB_REGNUM_GENERIC_RA
:
697 case LLDB_REGNUM_GENERIC_FLAGS
:
702 } else if (kind
== eRegisterKindDWARF
) {
704 case arm64_dwarf::x0
:
706 case arm64_dwarf::x1
:
708 case arm64_dwarf::x2
:
710 case arm64_dwarf::x3
:
712 case arm64_dwarf::x4
:
714 case arm64_dwarf::x5
:
716 case arm64_dwarf::x6
:
718 case arm64_dwarf::x7
:
720 case arm64_dwarf::x8
:
722 case arm64_dwarf::x9
:
724 case arm64_dwarf::x10
:
726 case arm64_dwarf::x11
:
728 case arm64_dwarf::x12
:
730 case arm64_dwarf::x13
:
732 case arm64_dwarf::x14
:
734 case arm64_dwarf::x15
:
736 case arm64_dwarf::x16
:
738 case arm64_dwarf::x17
:
740 case arm64_dwarf::x18
:
742 case arm64_dwarf::x19
:
744 case arm64_dwarf::x20
:
746 case arm64_dwarf::x21
:
748 case arm64_dwarf::x22
:
750 case arm64_dwarf::x23
:
752 case arm64_dwarf::x24
:
754 case arm64_dwarf::x25
:
756 case arm64_dwarf::x26
:
758 case arm64_dwarf::x27
:
760 case arm64_dwarf::x28
:
763 case arm64_dwarf::fp
:
765 case arm64_dwarf::sp
:
767 case arm64_dwarf::lr
:
769 case arm64_dwarf::pc
:
771 case arm64_dwarf::cpsr
:
774 case arm64_dwarf::v0
:
776 case arm64_dwarf::v1
:
778 case arm64_dwarf::v2
:
780 case arm64_dwarf::v3
:
782 case arm64_dwarf::v4
:
784 case arm64_dwarf::v5
:
786 case arm64_dwarf::v6
:
788 case arm64_dwarf::v7
:
790 case arm64_dwarf::v8
:
792 case arm64_dwarf::v9
:
794 case arm64_dwarf::v10
:
796 case arm64_dwarf::v11
:
798 case arm64_dwarf::v12
:
800 case arm64_dwarf::v13
:
802 case arm64_dwarf::v14
:
804 case arm64_dwarf::v15
:
806 case arm64_dwarf::v16
:
808 case arm64_dwarf::v17
:
810 case arm64_dwarf::v18
:
812 case arm64_dwarf::v19
:
814 case arm64_dwarf::v20
:
816 case arm64_dwarf::v21
:
818 case arm64_dwarf::v22
:
820 case arm64_dwarf::v23
:
822 case arm64_dwarf::v24
:
824 case arm64_dwarf::v25
:
826 case arm64_dwarf::v26
:
828 case arm64_dwarf::v27
:
830 case arm64_dwarf::v28
:
832 case arm64_dwarf::v29
:
834 case arm64_dwarf::v30
:
836 case arm64_dwarf::v31
:
842 } else if (kind
== eRegisterKindEHFrame
) {
844 case arm64_ehframe::x0
:
846 case arm64_ehframe::x1
:
848 case arm64_ehframe::x2
:
850 case arm64_ehframe::x3
:
852 case arm64_ehframe::x4
:
854 case arm64_ehframe::x5
:
856 case arm64_ehframe::x6
:
858 case arm64_ehframe::x7
:
860 case arm64_ehframe::x8
:
862 case arm64_ehframe::x9
:
864 case arm64_ehframe::x10
:
866 case arm64_ehframe::x11
:
868 case arm64_ehframe::x12
:
870 case arm64_ehframe::x13
:
872 case arm64_ehframe::x14
:
874 case arm64_ehframe::x15
:
876 case arm64_ehframe::x16
:
878 case arm64_ehframe::x17
:
880 case arm64_ehframe::x18
:
882 case arm64_ehframe::x19
:
884 case arm64_ehframe::x20
:
886 case arm64_ehframe::x21
:
888 case arm64_ehframe::x22
:
890 case arm64_ehframe::x23
:
892 case arm64_ehframe::x24
:
894 case arm64_ehframe::x25
:
896 case arm64_ehframe::x26
:
898 case arm64_ehframe::x27
:
900 case arm64_ehframe::x28
:
902 case arm64_ehframe::fp
:
904 case arm64_ehframe::sp
:
906 case arm64_ehframe::lr
:
908 case arm64_ehframe::pc
:
910 case arm64_ehframe::cpsr
:
913 } else if (kind
== eRegisterKindLLDB
) {
916 return LLDB_INVALID_REGNUM
;
919 uint32_t RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints() {
920 #if defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__))
921 // autodetect how many watchpoints are supported dynamically...
922 static uint32_t g_num_supported_hw_watchpoints
= UINT32_MAX
;
923 if (g_num_supported_hw_watchpoints
== UINT32_MAX
) {
927 if (::sysctlbyname("hw.optional.watchpoint", &n
, &len
, NULL
, 0) == 0) {
928 g_num_supported_hw_watchpoints
= n
;
931 return g_num_supported_hw_watchpoints
;
933 // TODO: figure out remote case here!
938 uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr
,
942 // if (log) log->Printf
943 // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p,
944 // size = %u, read = %u, write = %u)", addr, size, read, write);
946 const uint32_t num_hw_watchpoints
= NumSupportedHardwareWatchpoints();
948 // Can't watch zero bytes
950 return LLDB_INVALID_INDEX32
;
952 // We must watch for either read or write
954 return LLDB_INVALID_INDEX32
;
956 // Can't watch more than 4 bytes per WVR/WCR pair
958 return LLDB_INVALID_INDEX32
;
960 // We can only watch up to four bytes that follow a 4 byte aligned address
961 // per watchpoint register pair. Since we have at most so we can only watch
962 // until the next 4 byte boundary and we need to make sure we can properly
964 uint32_t addr_word_offset
= addr
% 4;
965 // if (log) log->Printf
966 // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() -
967 // addr_word_offset = 0x%8.8x", addr_word_offset);
969 uint32_t byte_mask
= ((1u << size
) - 1u) << addr_word_offset
;
970 // if (log) log->Printf
971 // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask =
972 // 0x%8.8x", byte_mask);
973 if (byte_mask
> 0xfu
)
974 return LLDB_INVALID_INDEX32
;
976 // Read the debug state
977 int kret
= ReadDBG(false);
979 if (kret
== KERN_SUCCESS
) {
980 // Check to make sure we have the needed hardware support
983 for (i
= 0; i
< num_hw_watchpoints
; ++i
) {
984 if ((dbg
.wcr
[i
] & WCR_ENABLE
) == 0)
985 break; // We found an available hw breakpoint slot (in i)
988 // See if we found an available hw breakpoint slot above
989 if (i
< num_hw_watchpoints
) {
990 // Make the byte_mask into a valid Byte Address Select mask
991 uint32_t byte_address_select
= byte_mask
<< 5;
992 // Make sure bits 1:0 are clear in our address
993 dbg
.wvr
[i
] = addr
& ~((lldb::addr_t
)3);
994 dbg
.wcr
[i
] = byte_address_select
| // Which bytes that follow the IMVA
995 // that we will watch
996 S_USER
| // Stop only in user mode
997 (read
? WCR_LOAD
: 0) | // Stop on read access?
998 (write
? WCR_STORE
: 0) | // Stop on write access?
999 WCR_ENABLE
; // Enable this watchpoint;
1002 // if (log) log->Printf
1003 // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint()
1004 // WriteDBG() => 0x%8.8x.", kret);
1006 if (kret
== KERN_SUCCESS
)
1009 // if (log) log->Printf
1010 // ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint():
1011 // All hardware resources (%u) are in use.",
1012 // num_hw_watchpoints);
1015 return LLDB_INVALID_INDEX32
;
1018 bool RegisterContextDarwin_arm64::ClearHardwareWatchpoint(uint32_t hw_index
) {
1019 int kret
= ReadDBG(false);
1021 const uint32_t num_hw_points
= NumSupportedHardwareWatchpoints();
1022 if (kret
== KERN_SUCCESS
) {
1023 if (hw_index
< num_hw_points
) {
1024 dbg
.wcr
[hw_index
] = 0;
1025 // if (log) log->Printf
1026 // ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u )
1027 // - WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
1030 // dbg.wvr[hw_index],
1032 // dbg.wcr[hw_index]);
1036 if (kret
== KERN_SUCCESS
)