1 //===-- DNBArchImplX86_64.h -------------------------------------*- C++ -*-===//
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 // Created by Greg Clayton on 6/25/07.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H
14 #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H
16 #if defined(__i386__) || defined(__x86_64__)
18 #include "MachRegisterStatesX86_64.h"
24 class DNBArchImplX86_64
: public DNBArchProtocol
{
26 DNBArchImplX86_64(MachThread
*thread
)
27 : DNBArchProtocol(), m_thread(thread
), m_state(), m_2pc_dbg_checkpoint(),
28 m_2pc_trans_state(Trans_Done
), m_saved_register_states() {}
29 virtual ~DNBArchImplX86_64() {}
31 static void Initialize();
33 bool GetRegisterValue(uint32_t set
, uint32_t reg
,
34 DNBRegisterValue
*value
) override
;
35 bool SetRegisterValue(uint32_t set
, uint32_t reg
,
36 const DNBRegisterValue
*value
) override
;
37 nub_size_t
GetRegisterContext(void *buf
, nub_size_t buf_len
) override
;
38 nub_size_t
SetRegisterContext(const void *buf
, nub_size_t buf_len
) override
;
39 uint32_t SaveRegisterState() override
;
40 bool RestoreRegisterState(uint32_t save_id
) override
;
42 kern_return_t
GetRegisterState(int set
, bool force
) override
;
43 kern_return_t
SetRegisterState(int set
) override
;
44 bool RegisterSetStateIsValid(int set
) const override
;
46 uint64_t GetPC(uint64_t failValue
) override
; // Get program counter
47 kern_return_t
SetPC(uint64_t value
) override
;
48 uint64_t GetSP(uint64_t failValue
) override
; // Get stack pointer
49 void ThreadWillResume() override
;
50 bool ThreadDidStop() override
;
51 bool NotifyException(MachException::Data
&exc
) override
;
53 uint32_t NumSupportedHardwareBreakpoints() override
;
54 uint32_t NumSupportedHardwareWatchpoints() override
;
56 uint32_t EnableHardwareBreakpoint(nub_addr_t addr
, nub_size_t size
,
57 bool also_set_on_task
) override
;
58 bool DisableHardwareBreakpoint(uint32_t hw_break_index
,
59 bool also_set_on_task
) override
;
60 uint32_t EnableHardwareWatchpoint(nub_addr_t addr
, nub_size_t size
,
61 bool read
, bool write
,
62 bool also_set_on_task
) override
;
63 bool DisableHardwareWatchpoint(uint32_t hw_break_index
,
64 bool also_set_on_task
) override
;
65 uint32_t GetHardwareWatchpointHit(nub_addr_t
&addr
) override
;
68 kern_return_t
EnableHardwareSingleStep(bool enable
);
70 typedef __x86_64_thread_state_t GPR
;
71 typedef __x86_64_float_state_t FPU
;
72 typedef __x86_64_exception_state_t EXC
;
73 typedef __x86_64_avx_state_t AVX
;
74 typedef __x86_64_debug_state_t DBG
;
76 static const DNBRegisterInfo g_gpr_registers
[];
77 static const DNBRegisterInfo g_fpu_registers_no_avx
[];
78 static const DNBRegisterInfo g_fpu_registers_avx
[];
79 static const DNBRegisterInfo g_exc_registers
[];
80 static const DNBRegisterSetInfo g_reg_sets_no_avx
[];
81 static const DNBRegisterSetInfo g_reg_sets_avx
[];
82 static const size_t k_num_gpr_registers
;
83 static const size_t k_num_fpu_registers_no_avx
;
84 static const size_t k_num_fpu_registers_avx
;
85 static const size_t k_num_exc_registers
;
86 static const size_t k_num_all_registers_no_avx
;
87 static const size_t k_num_all_registers_avx
;
88 static const size_t k_num_register_sets
;
90 typedef __x86_64_avx512f_state_t AVX512F
;
91 static const DNBRegisterInfo g_fpu_registers_avx512f
[];
92 static const DNBRegisterSetInfo g_reg_sets_avx512f
[];
93 static const size_t k_num_fpu_registers_avx512f
;
94 static const size_t k_num_all_registers_avx512f
;
97 e_regSetALL
= REGISTER_SET_ALL
,
105 enum RegisterSetWordSize
{
106 e_regSetWordSizeGPR
= (sizeof(GPR
) - 32) / sizeof(int),
107 e_regSetWordSizeGPRFull
= sizeof(GPR
) / sizeof(int),
108 e_regSetWordSizeFPU
= sizeof(FPU
) / sizeof(int),
109 e_regSetWordSizeEXC
= sizeof(EXC
) / sizeof(int),
110 e_regSetWordSizeAVX
= sizeof(AVX
) / sizeof(int),
111 e_regSetWordSizeAVX512f
= sizeof(AVX512F
) / sizeof(int),
112 e_regSetWordSizeDBG
= sizeof(DBG
) / sizeof(int)
115 enum { Read
= 0, Write
= 1, kNumErrors
= 2 };
130 kern_return_t gpr_errs
[2]; // Read/Write errors
131 kern_return_t fpu_errs
[2]; // Read/Write errors
132 kern_return_t exc_errs
[2]; // Read/Write errors
133 kern_return_t dbg_errs
[2]; // Read/Write errors
134 bool hasFullGPRState
;
138 for (i
= 0; i
< kNumErrors
; i
++) {
146 void InvalidateAllRegisterStates() { SetError(e_regSetALL
, Read
, -1); }
148 kern_return_t
GetError(int flavor
, uint32_t err_idx
) const {
149 if (err_idx
< kNumErrors
) {
151 // When getting all errors, just OR all values together to see if
152 // we got any kind of error.
154 return gpr_errs
[err_idx
] | fpu_errs
[err_idx
] | exc_errs
[err_idx
];
156 return gpr_errs
[err_idx
];
158 return fpu_errs
[err_idx
];
160 return exc_errs
[err_idx
];
162 return dbg_errs
[err_idx
];
170 bool SetError(int flavor
, uint32_t err_idx
, kern_return_t err
) {
171 if (err_idx
< kNumErrors
) {
174 gpr_errs
[err_idx
] = fpu_errs
[err_idx
] = exc_errs
[err_idx
] =
175 dbg_errs
[err_idx
] = err
;
179 gpr_errs
[err_idx
] = err
;
183 fpu_errs
[err_idx
] = err
;
187 exc_errs
[err_idx
] = err
;
191 dbg_errs
[err_idx
] = err
;
201 bool RegsAreValid(int flavor
) const {
202 return GetError(flavor
, Read
) == KERN_SUCCESS
;
206 kern_return_t
GetGPRState(bool force
);
207 kern_return_t
GetFPUState(bool force
);
208 kern_return_t
GetEXCState(bool force
);
209 kern_return_t
GetDBGState(bool force
);
211 kern_return_t
SetGPRState();
212 kern_return_t
SetFPUState();
213 kern_return_t
SetEXCState();
214 kern_return_t
SetDBGState(bool also_set_on_task
);
216 static DNBArchProtocol
*Create(MachThread
*thread
);
218 static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size
);
220 static const DNBRegisterSetInfo
*GetRegisterSetInfo(nub_size_t
*num_reg_sets
);
222 static uint32_t GetRegisterContextSize();
224 static void SetHardwareBreakpoint(DBG
&debug_state
, uint32_t hw_index
,
225 nub_addr_t addr
, nub_size_t size
);
227 // Helper functions for watchpoint manipulations.
228 static void SetWatchpoint(DBG
&debug_state
, uint32_t hw_index
,
229 nub_addr_t addr
, nub_size_t size
, bool read
,
231 static void ClearWatchpoint(DBG
&debug_state
, uint32_t hw_index
);
232 static bool IsWatchpointVacant(const DBG
&debug_state
, uint32_t hw_index
);
233 static void ClearWatchpointHits(DBG
&debug_state
);
234 static bool IsWatchpointHit(const DBG
&debug_state
, uint32_t hw_index
);
235 static nub_addr_t
GetWatchAddress(const DBG
&debug_state
, uint32_t hw_index
);
237 bool StartTransForHWP() override
;
238 bool RollbackTransForHWP() override
;
239 bool FinishTransForHWP() override
;
240 DBG
GetDBGCheckpoint();
242 MachThread
*m_thread
;
244 DBG m_2pc_dbg_checkpoint
;
245 uint32_t m_2pc_trans_state
; // Is transaction of DBG state change: Pedning
246 // (0), Done (1), or Rolled Back (2)?
247 typedef std::map
<uint32_t, Context
> SaveRegisterStates
;
248 SaveRegisterStates m_saved_register_states
;
251 #endif // #if defined (__i386__) || defined (__x86_64__)
252 #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H