1 //===-- RegisterContextDarwin_x86_64.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 //===----------------------------------------------------------------------===//
15 #include "lldb/Utility/DataBufferHeap.h"
16 #include "lldb/Utility/DataExtractor.h"
17 #include "lldb/Utility/Endian.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/RegisterValue.h"
20 #include "lldb/Utility/Scalar.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Support/Compiler.h"
24 #include "RegisterContextDarwin_x86_64.h"
27 using namespace lldb_private
;
103 enum ehframe_dwarf_regnums
{
104 ehframe_dwarf_gpr_rax
= 0,
105 ehframe_dwarf_gpr_rdx
,
106 ehframe_dwarf_gpr_rcx
,
107 ehframe_dwarf_gpr_rbx
,
108 ehframe_dwarf_gpr_rsi
,
109 ehframe_dwarf_gpr_rdi
,
110 ehframe_dwarf_gpr_rbp
,
111 ehframe_dwarf_gpr_rsp
,
112 ehframe_dwarf_gpr_r8
,
113 ehframe_dwarf_gpr_r9
,
114 ehframe_dwarf_gpr_r10
,
115 ehframe_dwarf_gpr_r11
,
116 ehframe_dwarf_gpr_r12
,
117 ehframe_dwarf_gpr_r13
,
118 ehframe_dwarf_gpr_r14
,
119 ehframe_dwarf_gpr_r15
,
120 ehframe_dwarf_gpr_rip
,
121 ehframe_dwarf_fpu_xmm0
,
122 ehframe_dwarf_fpu_xmm1
,
123 ehframe_dwarf_fpu_xmm2
,
124 ehframe_dwarf_fpu_xmm3
,
125 ehframe_dwarf_fpu_xmm4
,
126 ehframe_dwarf_fpu_xmm5
,
127 ehframe_dwarf_fpu_xmm6
,
128 ehframe_dwarf_fpu_xmm7
,
129 ehframe_dwarf_fpu_xmm8
,
130 ehframe_dwarf_fpu_xmm9
,
131 ehframe_dwarf_fpu_xmm10
,
132 ehframe_dwarf_fpu_xmm11
,
133 ehframe_dwarf_fpu_xmm12
,
134 ehframe_dwarf_fpu_xmm13
,
135 ehframe_dwarf_fpu_xmm14
,
136 ehframe_dwarf_fpu_xmm15
,
137 ehframe_dwarf_fpu_stmm0
,
138 ehframe_dwarf_fpu_stmm1
,
139 ehframe_dwarf_fpu_stmm2
,
140 ehframe_dwarf_fpu_stmm3
,
141 ehframe_dwarf_fpu_stmm4
,
142 ehframe_dwarf_fpu_stmm5
,
143 ehframe_dwarf_fpu_stmm6
,
144 ehframe_dwarf_fpu_stmm7
148 #define GPR_OFFSET(reg) \
149 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
150 #define FPU_OFFSET(reg) \
151 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \
152 sizeof(RegisterContextDarwin_x86_64::GPR))
153 #define EXC_OFFSET(reg) \
154 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \
155 sizeof(RegisterContextDarwin_x86_64::GPR) + \
156 sizeof(RegisterContextDarwin_x86_64::FPU))
158 // These macros will auto define the register name, alt name, register size,
159 // register offset, encoding, format and native register. This ensures that the
160 // register state structures are defined correctly and have the correct sizes
162 #define DEFINE_GPR(reg, alt) \
163 #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
164 GPR_OFFSET(reg), eEncodingUint, eFormatHex
165 #define DEFINE_FPU_UINT(reg) \
166 #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \
167 FPU_OFFSET(reg), eEncodingUint, eFormatHex
168 #define DEFINE_FPU_VECT(reg, i) \
170 sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \
171 FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
172 {ehframe_dwarf_fpu_##reg##i, \
173 ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \
174 LLDB_INVALID_REGNUM, fpu_##reg##i }, \
175 nullptr, nullptr, nullptr,
176 #define DEFINE_EXC(reg) \
177 #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \
178 EXC_OFFSET(reg), eEncodingUint, eFormatHex
180 #define REG_CONTEXT_SIZE \
181 (sizeof(RegisterContextDarwin_x86_64::GPR) + \
182 sizeof(RegisterContextDarwin_x86_64::FPU) + \
183 sizeof(RegisterContextDarwin_x86_64::EXC))
185 // General purpose registers for 64 bit
186 static RegisterInfo g_register_infos
[] = {
187 {DEFINE_GPR(rax
, nullptr),
188 {ehframe_dwarf_gpr_rax
, ehframe_dwarf_gpr_rax
, LLDB_INVALID_REGNUM
,
189 LLDB_INVALID_REGNUM
, gpr_rax
},
194 {DEFINE_GPR(rbx
, nullptr),
195 {ehframe_dwarf_gpr_rbx
, ehframe_dwarf_gpr_rbx
, LLDB_INVALID_REGNUM
,
196 LLDB_INVALID_REGNUM
, gpr_rbx
},
201 {DEFINE_GPR(rcx
, nullptr),
202 {ehframe_dwarf_gpr_rcx
, ehframe_dwarf_gpr_rcx
, LLDB_INVALID_REGNUM
,
203 LLDB_INVALID_REGNUM
, gpr_rcx
},
208 {DEFINE_GPR(rdx
, nullptr),
209 {ehframe_dwarf_gpr_rdx
, ehframe_dwarf_gpr_rdx
, LLDB_INVALID_REGNUM
,
210 LLDB_INVALID_REGNUM
, gpr_rdx
},
215 {DEFINE_GPR(rdi
, nullptr),
216 {ehframe_dwarf_gpr_rdi
, ehframe_dwarf_gpr_rdi
, LLDB_INVALID_REGNUM
,
217 LLDB_INVALID_REGNUM
, gpr_rdi
},
222 {DEFINE_GPR(rsi
, nullptr),
223 {ehframe_dwarf_gpr_rsi
, ehframe_dwarf_gpr_rsi
, LLDB_INVALID_REGNUM
,
224 LLDB_INVALID_REGNUM
, gpr_rsi
},
229 {DEFINE_GPR(rbp
, "fp"),
230 {ehframe_dwarf_gpr_rbp
, ehframe_dwarf_gpr_rbp
, LLDB_REGNUM_GENERIC_FP
,
231 LLDB_INVALID_REGNUM
, gpr_rbp
},
236 {DEFINE_GPR(rsp
, "sp"),
237 {ehframe_dwarf_gpr_rsp
, ehframe_dwarf_gpr_rsp
, LLDB_REGNUM_GENERIC_SP
,
238 LLDB_INVALID_REGNUM
, gpr_rsp
},
243 {DEFINE_GPR(r8
, nullptr),
244 {ehframe_dwarf_gpr_r8
, ehframe_dwarf_gpr_r8
, LLDB_INVALID_REGNUM
,
245 LLDB_INVALID_REGNUM
, gpr_r8
},
250 {DEFINE_GPR(r9
, nullptr),
251 {ehframe_dwarf_gpr_r9
, ehframe_dwarf_gpr_r9
, LLDB_INVALID_REGNUM
,
252 LLDB_INVALID_REGNUM
, gpr_r9
},
257 {DEFINE_GPR(r10
, nullptr),
258 {ehframe_dwarf_gpr_r10
, ehframe_dwarf_gpr_r10
, LLDB_INVALID_REGNUM
,
259 LLDB_INVALID_REGNUM
, gpr_r10
},
264 {DEFINE_GPR(r11
, nullptr),
265 {ehframe_dwarf_gpr_r11
, ehframe_dwarf_gpr_r11
, LLDB_INVALID_REGNUM
,
266 LLDB_INVALID_REGNUM
, gpr_r11
},
271 {DEFINE_GPR(r12
, nullptr),
272 {ehframe_dwarf_gpr_r12
, ehframe_dwarf_gpr_r12
, LLDB_INVALID_REGNUM
,
273 LLDB_INVALID_REGNUM
, gpr_r12
},
278 {DEFINE_GPR(r13
, nullptr),
279 {ehframe_dwarf_gpr_r13
, ehframe_dwarf_gpr_r13
, LLDB_INVALID_REGNUM
,
280 LLDB_INVALID_REGNUM
, gpr_r13
},
285 {DEFINE_GPR(r14
, nullptr),
286 {ehframe_dwarf_gpr_r14
, ehframe_dwarf_gpr_r14
, LLDB_INVALID_REGNUM
,
287 LLDB_INVALID_REGNUM
, gpr_r14
},
292 {DEFINE_GPR(r15
, nullptr),
293 {ehframe_dwarf_gpr_r15
, ehframe_dwarf_gpr_r15
, LLDB_INVALID_REGNUM
,
294 LLDB_INVALID_REGNUM
, gpr_r15
},
299 {DEFINE_GPR(rip
, "pc"),
300 {ehframe_dwarf_gpr_rip
, ehframe_dwarf_gpr_rip
, LLDB_REGNUM_GENERIC_PC
,
301 LLDB_INVALID_REGNUM
, gpr_rip
},
306 {DEFINE_GPR(rflags
, "flags"),
307 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_REGNUM_GENERIC_FLAGS
,
308 LLDB_INVALID_REGNUM
, gpr_rflags
},
313 {DEFINE_GPR(cs
, nullptr),
314 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
315 LLDB_INVALID_REGNUM
, gpr_cs
},
320 {DEFINE_GPR(fs
, nullptr),
321 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
322 LLDB_INVALID_REGNUM
, gpr_fs
},
327 {DEFINE_GPR(gs
, nullptr),
328 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
329 LLDB_INVALID_REGNUM
, gpr_gs
},
335 {DEFINE_FPU_UINT(fcw
),
336 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
337 LLDB_INVALID_REGNUM
, fpu_fcw
},
342 {DEFINE_FPU_UINT(fsw
),
343 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
344 LLDB_INVALID_REGNUM
, fpu_fsw
},
349 {DEFINE_FPU_UINT(ftw
),
350 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
351 LLDB_INVALID_REGNUM
, fpu_ftw
},
356 {DEFINE_FPU_UINT(fop
),
357 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
358 LLDB_INVALID_REGNUM
, fpu_fop
},
363 {DEFINE_FPU_UINT(ip
),
364 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
365 LLDB_INVALID_REGNUM
, fpu_ip
},
370 {DEFINE_FPU_UINT(cs
),
371 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
372 LLDB_INVALID_REGNUM
, fpu_cs
},
377 {DEFINE_FPU_UINT(dp
),
378 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
379 LLDB_INVALID_REGNUM
, fpu_dp
},
384 {DEFINE_FPU_UINT(ds
),
385 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
386 LLDB_INVALID_REGNUM
, fpu_ds
},
391 {DEFINE_FPU_UINT(mxcsr
),
392 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
393 LLDB_INVALID_REGNUM
, fpu_mxcsr
},
398 {DEFINE_FPU_UINT(mxcsrmask
),
399 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
400 LLDB_INVALID_REGNUM
, fpu_mxcsrmask
},
405 {DEFINE_FPU_VECT(stmm
, 0)},
406 {DEFINE_FPU_VECT(stmm
, 1)},
407 {DEFINE_FPU_VECT(stmm
, 2)},
408 {DEFINE_FPU_VECT(stmm
, 3)},
409 {DEFINE_FPU_VECT(stmm
, 4)},
410 {DEFINE_FPU_VECT(stmm
, 5)},
411 {DEFINE_FPU_VECT(stmm
, 6)},
412 {DEFINE_FPU_VECT(stmm
, 7)},
413 {DEFINE_FPU_VECT(xmm
, 0)},
414 {DEFINE_FPU_VECT(xmm
, 1)},
415 {DEFINE_FPU_VECT(xmm
, 2)},
416 {DEFINE_FPU_VECT(xmm
, 3)},
417 {DEFINE_FPU_VECT(xmm
, 4)},
418 {DEFINE_FPU_VECT(xmm
, 5)},
419 {DEFINE_FPU_VECT(xmm
, 6)},
420 {DEFINE_FPU_VECT(xmm
, 7)},
421 {DEFINE_FPU_VECT(xmm
, 8)},
422 {DEFINE_FPU_VECT(xmm
, 9)},
423 {DEFINE_FPU_VECT(xmm
, 10)},
424 {DEFINE_FPU_VECT(xmm
, 11)},
425 {DEFINE_FPU_VECT(xmm
, 12)},
426 {DEFINE_FPU_VECT(xmm
, 13)},
427 {DEFINE_FPU_VECT(xmm
, 14)},
428 {DEFINE_FPU_VECT(xmm
, 15)},
431 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
432 LLDB_INVALID_REGNUM
, exc_trapno
},
438 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
439 LLDB_INVALID_REGNUM
, exc_err
},
444 {DEFINE_EXC(faultvaddr
),
445 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
446 LLDB_INVALID_REGNUM
, exc_faultvaddr
},
452 static size_t k_num_register_infos
= std::size(g_register_infos
);
454 RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
455 Thread
&thread
, uint32_t concrete_frame_idx
)
456 : RegisterContext(thread
, concrete_frame_idx
), gpr(), fpu(), exc() {
458 for (i
= 0; i
< kNumErrors
; i
++) {
465 RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
467 void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
468 InvalidateAllRegisterStates();
471 size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
472 assert(k_num_register_infos
== k_num_registers
);
473 return k_num_registers
;
477 RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg
) {
478 assert(k_num_register_infos
== k_num_registers
);
479 if (reg
< k_num_registers
)
480 return &g_register_infos
[reg
];
484 size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
485 return k_num_register_infos
;
488 const lldb_private::RegisterInfo
*
489 RegisterContextDarwin_x86_64::GetRegisterInfos() {
490 return g_register_infos
;
493 static uint32_t g_gpr_regnums
[] = {
494 gpr_rax
, gpr_rbx
, gpr_rcx
, gpr_rdx
, gpr_rdi
, gpr_rsi
, gpr_rbp
,
495 gpr_rsp
, gpr_r8
, gpr_r9
, gpr_r10
, gpr_r11
, gpr_r12
, gpr_r13
,
496 gpr_r14
, gpr_r15
, gpr_rip
, gpr_rflags
, gpr_cs
, gpr_fs
, gpr_gs
};
498 static uint32_t g_fpu_regnums
[] = {
499 fpu_fcw
, fpu_fsw
, fpu_ftw
, fpu_fop
, fpu_ip
, fpu_cs
,
500 fpu_dp
, fpu_ds
, fpu_mxcsr
, fpu_mxcsrmask
, fpu_stmm0
, fpu_stmm1
,
501 fpu_stmm2
, fpu_stmm3
, fpu_stmm4
, fpu_stmm5
, fpu_stmm6
, fpu_stmm7
,
502 fpu_xmm0
, fpu_xmm1
, fpu_xmm2
, fpu_xmm3
, fpu_xmm4
, fpu_xmm5
,
503 fpu_xmm6
, fpu_xmm7
, fpu_xmm8
, fpu_xmm9
, fpu_xmm10
, fpu_xmm11
,
504 fpu_xmm12
, fpu_xmm13
, fpu_xmm14
, fpu_xmm15
};
506 static uint32_t g_exc_regnums
[] = {exc_trapno
, exc_err
, exc_faultvaddr
};
508 // Number of registers in each register set
509 const size_t k_num_gpr_registers
= std::size(g_gpr_regnums
);
510 const size_t k_num_fpu_registers
= std::size(g_fpu_regnums
);
511 const size_t k_num_exc_registers
= std::size(g_exc_regnums
);
513 // Register set definitions. The first definitions at register set index of
514 // zero is for all registers, followed by other registers sets. The register
515 // information for the all register set need not be filled in.
516 static const RegisterSet g_reg_sets
[] = {
518 "General Purpose Registers", "gpr", k_num_gpr_registers
, g_gpr_regnums
,
520 {"Floating Point Registers", "fpu", k_num_fpu_registers
, g_fpu_regnums
},
521 {"Exception State Registers", "exc", k_num_exc_registers
, g_exc_regnums
}};
523 const size_t k_num_regsets
= std::size(g_reg_sets
);
525 size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
526 return k_num_regsets
;
530 RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set
) {
531 if (reg_set
< k_num_regsets
)
532 return &g_reg_sets
[reg_set
];
536 int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num
) {
537 if (reg_num
< fpu_fcw
)
539 else if (reg_num
< exc_trapno
)
541 else if (reg_num
< k_num_registers
)
546 int RegisterContextDarwin_x86_64::ReadGPR(bool force
) {
548 if (force
|| !RegisterSetIsCached(set
)) {
549 SetError(set
, Read
, DoReadGPR(GetThreadID(), set
, gpr
));
551 return GetError(GPRRegSet
, Read
);
554 int RegisterContextDarwin_x86_64::ReadFPU(bool force
) {
556 if (force
|| !RegisterSetIsCached(set
)) {
557 SetError(set
, Read
, DoReadFPU(GetThreadID(), set
, fpu
));
559 return GetError(FPURegSet
, Read
);
562 int RegisterContextDarwin_x86_64::ReadEXC(bool force
) {
564 if (force
|| !RegisterSetIsCached(set
)) {
565 SetError(set
, Read
, DoReadEXC(GetThreadID(), set
, exc
));
567 return GetError(EXCRegSet
, Read
);
570 int RegisterContextDarwin_x86_64::WriteGPR() {
572 if (!RegisterSetIsCached(set
)) {
573 SetError(set
, Write
, -1);
576 SetError(set
, Write
, DoWriteGPR(GetThreadID(), set
, gpr
));
577 SetError(set
, Read
, -1);
578 return GetError(set
, Write
);
581 int RegisterContextDarwin_x86_64::WriteFPU() {
583 if (!RegisterSetIsCached(set
)) {
584 SetError(set
, Write
, -1);
587 SetError(set
, Write
, DoWriteFPU(GetThreadID(), set
, fpu
));
588 SetError(set
, Read
, -1);
589 return GetError(set
, Write
);
592 int RegisterContextDarwin_x86_64::WriteEXC() {
594 if (!RegisterSetIsCached(set
)) {
595 SetError(set
, Write
, -1);
598 SetError(set
, Write
, DoWriteEXC(GetThreadID(), set
, exc
));
599 SetError(set
, Read
, -1);
600 return GetError(set
, Write
);
603 int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set
, bool force
) {
606 return ReadGPR(force
);
608 return ReadFPU(force
);
610 return ReadEXC(force
);
617 int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set
) {
618 // Make sure we have a valid context to set.
632 bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo
*reg_info
,
633 RegisterValue
&value
) {
634 const uint32_t reg
= reg_info
->kinds
[eRegisterKindLLDB
];
635 int set
= RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg
);
639 if (ReadRegisterSet(set
, false) != 0)
664 value
= (&gpr
.rax
)[reg
- gpr_rax
];
704 value
= fpu
.mxcsrmask
;
715 value
.SetBytes(fpu
.stmm
[reg
- fpu_stmm0
].bytes
, reg_info
->byte_size
,
716 endian::InlHostByteOrder());
735 value
.SetBytes(fpu
.xmm
[reg
- fpu_xmm0
].bytes
, reg_info
->byte_size
,
736 endian::InlHostByteOrder());
748 value
= exc
.faultvaddr
;
757 bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo
*reg_info
,
758 const RegisterValue
&value
) {
759 const uint32_t reg
= reg_info
->kinds
[eRegisterKindLLDB
];
760 int set
= RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg
);
765 if (ReadRegisterSet(set
, false) != 0)
790 (&gpr
.rax
)[reg
- gpr_rax
] = value
.GetAsUInt64();
794 fpu
.fcw
= value
.GetAsUInt16();
798 fpu
.fsw
= value
.GetAsUInt16();
802 fpu
.ftw
= value
.GetAsUInt8();
806 fpu
.fop
= value
.GetAsUInt16();
810 fpu
.ip
= value
.GetAsUInt32();
814 fpu
.cs
= value
.GetAsUInt16();
818 fpu
.dp
= value
.GetAsUInt32();
822 fpu
.ds
= value
.GetAsUInt16();
826 fpu
.mxcsr
= value
.GetAsUInt32();
830 fpu
.mxcsrmask
= value
.GetAsUInt32();
841 ::memcpy(fpu
.stmm
[reg
- fpu_stmm0
].bytes
, value
.GetBytes(),
842 value
.GetByteSize());
861 ::memcpy(fpu
.xmm
[reg
- fpu_xmm0
].bytes
, value
.GetBytes(),
862 value
.GetByteSize());
866 exc
.trapno
= value
.GetAsUInt32();
870 exc
.err
= value
.GetAsUInt32();
874 exc
.faultvaddr
= value
.GetAsUInt64();
880 return WriteRegisterSet(set
) == 0;
883 bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
884 lldb::WritableDataBufferSP
&data_sp
) {
885 data_sp
= std::make_shared
<DataBufferHeap
>(REG_CONTEXT_SIZE
, 0);
886 if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
887 uint8_t *dst
= data_sp
->GetBytes();
888 ::memcpy(dst
, &gpr
, sizeof(gpr
));
891 ::memcpy(dst
, &fpu
, sizeof(fpu
));
894 ::memcpy(dst
, &exc
, sizeof(exc
));
900 bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
901 const lldb::DataBufferSP
&data_sp
) {
902 if (data_sp
&& data_sp
->GetByteSize() == REG_CONTEXT_SIZE
) {
903 const uint8_t *src
= data_sp
->GetBytes();
904 ::memcpy(&gpr
, src
, sizeof(gpr
));
907 ::memcpy(&fpu
, src
, sizeof(fpu
));
910 ::memcpy(&exc
, src
, sizeof(exc
));
911 uint32_t success_count
= 0;
918 return success_count
== 3;
923 uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
924 lldb::RegisterKind kind
, uint32_t reg
) {
925 if (kind
== eRegisterKindGeneric
) {
927 case LLDB_REGNUM_GENERIC_PC
:
929 case LLDB_REGNUM_GENERIC_SP
:
931 case LLDB_REGNUM_GENERIC_FP
:
933 case LLDB_REGNUM_GENERIC_FLAGS
:
935 case LLDB_REGNUM_GENERIC_RA
:
939 } else if (kind
== eRegisterKindEHFrame
|| kind
== eRegisterKindDWARF
) {
941 case ehframe_dwarf_gpr_rax
:
943 case ehframe_dwarf_gpr_rdx
:
945 case ehframe_dwarf_gpr_rcx
:
947 case ehframe_dwarf_gpr_rbx
:
949 case ehframe_dwarf_gpr_rsi
:
951 case ehframe_dwarf_gpr_rdi
:
953 case ehframe_dwarf_gpr_rbp
:
955 case ehframe_dwarf_gpr_rsp
:
957 case ehframe_dwarf_gpr_r8
:
959 case ehframe_dwarf_gpr_r9
:
961 case ehframe_dwarf_gpr_r10
:
963 case ehframe_dwarf_gpr_r11
:
965 case ehframe_dwarf_gpr_r12
:
967 case ehframe_dwarf_gpr_r13
:
969 case ehframe_dwarf_gpr_r14
:
971 case ehframe_dwarf_gpr_r15
:
973 case ehframe_dwarf_gpr_rip
:
975 case ehframe_dwarf_fpu_xmm0
:
977 case ehframe_dwarf_fpu_xmm1
:
979 case ehframe_dwarf_fpu_xmm2
:
981 case ehframe_dwarf_fpu_xmm3
:
983 case ehframe_dwarf_fpu_xmm4
:
985 case ehframe_dwarf_fpu_xmm5
:
987 case ehframe_dwarf_fpu_xmm6
:
989 case ehframe_dwarf_fpu_xmm7
:
991 case ehframe_dwarf_fpu_xmm8
:
993 case ehframe_dwarf_fpu_xmm9
:
995 case ehframe_dwarf_fpu_xmm10
:
997 case ehframe_dwarf_fpu_xmm11
:
999 case ehframe_dwarf_fpu_xmm12
:
1001 case ehframe_dwarf_fpu_xmm13
:
1003 case ehframe_dwarf_fpu_xmm14
:
1005 case ehframe_dwarf_fpu_xmm15
:
1007 case ehframe_dwarf_fpu_stmm0
:
1009 case ehframe_dwarf_fpu_stmm1
:
1011 case ehframe_dwarf_fpu_stmm2
:
1013 case ehframe_dwarf_fpu_stmm3
:
1015 case ehframe_dwarf_fpu_stmm4
:
1017 case ehframe_dwarf_fpu_stmm5
:
1019 case ehframe_dwarf_fpu_stmm6
:
1021 case ehframe_dwarf_fpu_stmm7
:
1026 } else if (kind
== eRegisterKindLLDB
) {
1029 return LLDB_INVALID_REGNUM
;
1032 bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable
) {
1033 if (ReadGPR(true) != 0)
1036 const uint64_t trace_bit
= 0x100ull
;
1039 if (gpr
.rflags
& trace_bit
)
1040 return true; // trace bit is already set, there is nothing to do
1042 gpr
.rflags
|= trace_bit
;
1044 if (gpr
.rflags
& trace_bit
)
1045 gpr
.rflags
&= ~trace_bit
;
1047 return true; // trace bit is clear, there is nothing to do
1050 return WriteGPR() == 0;