1 //===-- NativeRegisterContextLinux_x86_64.cpp ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #if defined(__i386__) || defined(__x86_64__)
11 
12 #include "NativeRegisterContextLinux_x86_64.h"
13 
14 #include "lldb/Core/DataBufferHeap.h"
15 #include "lldb/Core/Error.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/RegisterValue.h"
18 #include "lldb/Host/HostInfo.h"
19 
20 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
21 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
22 
23 using namespace lldb_private;
24 using namespace lldb_private::process_linux;
25 
26 // ----------------------------------------------------------------------------
27 // Private namespace.
28 // ----------------------------------------------------------------------------
29 
30 namespace {
31 // x86 32-bit general purpose registers.
32 const uint32_t g_gpr_regnums_i386[] = {
33     lldb_eax_i386,      lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
34     lldb_edi_i386,      lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
35     lldb_eip_i386,      lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
36     lldb_gs_i386,       lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
37     lldb_ax_i386,       lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
38     lldb_di_i386,       lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
39     lldb_ah_i386,       lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
40     lldb_al_i386,       lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
41     LLDB_INVALID_REGNUM // register sets need to end with this flag
42 };
43 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
44                       1 ==
45                   k_num_gpr_registers_i386,
46               "g_gpr_regnums_i386 has wrong number of register infos");
47 
48 // x86 32-bit floating point registers.
49 const uint32_t g_fpu_regnums_i386[] = {
50     lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
51     lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
52     lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
53     lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
54     lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
55     lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
56     lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
57     lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
58     lldb_xmm6_i386,     lldb_xmm7_i386,
59     LLDB_INVALID_REGNUM // register sets need to end with this flag
60 };
61 static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
62                       1 ==
63                   k_num_fpr_registers_i386,
64               "g_fpu_regnums_i386 has wrong number of register infos");
65 
66 // x86 32-bit AVX registers.
67 const uint32_t g_avx_regnums_i386[] = {
68     lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
69     lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
70     LLDB_INVALID_REGNUM // register sets need to end with this flag
71 };
72 static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
73                       1 ==
74                   k_num_avx_registers_i386,
75               " g_avx_regnums_i386 has wrong number of register infos");
76 
77 // x86 64-bit general purpose registers.
78 static const uint32_t g_gpr_regnums_x86_64[] = {
79     lldb_rax_x86_64,    lldb_rbx_x86_64,    lldb_rcx_x86_64, lldb_rdx_x86_64,
80     lldb_rdi_x86_64,    lldb_rsi_x86_64,    lldb_rbp_x86_64, lldb_rsp_x86_64,
81     lldb_r8_x86_64,     lldb_r9_x86_64,     lldb_r10_x86_64, lldb_r11_x86_64,
82     lldb_r12_x86_64,    lldb_r13_x86_64,    lldb_r14_x86_64, lldb_r15_x86_64,
83     lldb_rip_x86_64,    lldb_rflags_x86_64, lldb_cs_x86_64,  lldb_fs_x86_64,
84     lldb_gs_x86_64,     lldb_ss_x86_64,     lldb_ds_x86_64,  lldb_es_x86_64,
85     lldb_eax_x86_64,    lldb_ebx_x86_64,    lldb_ecx_x86_64, lldb_edx_x86_64,
86     lldb_edi_x86_64,    lldb_esi_x86_64,    lldb_ebp_x86_64, lldb_esp_x86_64,
87     lldb_r8d_x86_64,  // Low 32 bits or r8
88     lldb_r9d_x86_64,  // Low 32 bits or r9
89     lldb_r10d_x86_64, // Low 32 bits or r10
90     lldb_r11d_x86_64, // Low 32 bits or r11
91     lldb_r12d_x86_64, // Low 32 bits or r12
92     lldb_r13d_x86_64, // Low 32 bits or r13
93     lldb_r14d_x86_64, // Low 32 bits or r14
94     lldb_r15d_x86_64, // Low 32 bits or r15
95     lldb_ax_x86_64,     lldb_bx_x86_64,     lldb_cx_x86_64,  lldb_dx_x86_64,
96     lldb_di_x86_64,     lldb_si_x86_64,     lldb_bp_x86_64,  lldb_sp_x86_64,
97     lldb_r8w_x86_64,  // Low 16 bits or r8
98     lldb_r9w_x86_64,  // Low 16 bits or r9
99     lldb_r10w_x86_64, // Low 16 bits or r10
100     lldb_r11w_x86_64, // Low 16 bits or r11
101     lldb_r12w_x86_64, // Low 16 bits or r12
102     lldb_r13w_x86_64, // Low 16 bits or r13
103     lldb_r14w_x86_64, // Low 16 bits or r14
104     lldb_r15w_x86_64, // Low 16 bits or r15
105     lldb_ah_x86_64,     lldb_bh_x86_64,     lldb_ch_x86_64,  lldb_dh_x86_64,
106     lldb_al_x86_64,     lldb_bl_x86_64,     lldb_cl_x86_64,  lldb_dl_x86_64,
107     lldb_dil_x86_64,    lldb_sil_x86_64,    lldb_bpl_x86_64, lldb_spl_x86_64,
108     lldb_r8l_x86_64,    // Low 8 bits or r8
109     lldb_r9l_x86_64,    // Low 8 bits or r9
110     lldb_r10l_x86_64,   // Low 8 bits or r10
111     lldb_r11l_x86_64,   // Low 8 bits or r11
112     lldb_r12l_x86_64,   // Low 8 bits or r12
113     lldb_r13l_x86_64,   // Low 8 bits or r13
114     lldb_r14l_x86_64,   // Low 8 bits or r14
115     lldb_r15l_x86_64,   // Low 8 bits or r15
116     LLDB_INVALID_REGNUM // register sets need to end with this flag
117 };
118 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
119                       1 ==
120                   k_num_gpr_registers_x86_64,
121               "g_gpr_regnums_x86_64 has wrong number of register infos");
122 
123 // x86 64-bit floating point registers.
124 static const uint32_t g_fpu_regnums_x86_64[] = {
125     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
126     lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
127     lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
128     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
129     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
130     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
131     lldb_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
132     lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
133     lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
134     lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
135     lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
136     lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
137     lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
138     lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_x86_64,
139     LLDB_INVALID_REGNUM // register sets need to end with this flag
140 };
141 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
142                       1 ==
143                   k_num_fpr_registers_x86_64,
144               "g_fpu_regnums_x86_64 has wrong number of register infos");
145 
146 // x86 64-bit AVX registers.
147 static const uint32_t g_avx_regnums_x86_64[] = {
148     lldb_ymm0_x86_64,   lldb_ymm1_x86_64,  lldb_ymm2_x86_64,  lldb_ymm3_x86_64,
149     lldb_ymm4_x86_64,   lldb_ymm5_x86_64,  lldb_ymm6_x86_64,  lldb_ymm7_x86_64,
150     lldb_ymm8_x86_64,   lldb_ymm9_x86_64,  lldb_ymm10_x86_64, lldb_ymm11_x86_64,
151     lldb_ymm12_x86_64,  lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
152     LLDB_INVALID_REGNUM // register sets need to end with this flag
153 };
154 static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
155                       1 ==
156                   k_num_avx_registers_x86_64,
157               "g_avx_regnums_x86_64 has wrong number of register infos");
158 
159 // Number of register sets provided by this context.
160 enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
161 
162 // Register sets for x86 32-bit.
163 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
164     {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
165      g_gpr_regnums_i386},
166     {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
167      g_fpu_regnums_i386},
168     {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
169      g_avx_regnums_i386}};
170 
171 // Register sets for x86 64-bit.
172 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
173     {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
174      g_gpr_regnums_x86_64},
175     {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
176      g_fpu_regnums_x86_64},
177     {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
178      g_avx_regnums_x86_64}};
179 }
180 
181 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
182 
183 // ----------------------------------------------------------------------------
184 // Required ptrace defines.
185 // ----------------------------------------------------------------------------
186 
187 // Support ptrace extensions even when compiled without required kernel support
188 #ifndef NT_X86_XSTATE
189 #define NT_X86_XSTATE 0x202
190 #endif
191 #ifndef NT_PRXFPREG
192 #define NT_PRXFPREG 0x46e62b7f
193 #endif
194 
195 NativeRegisterContextLinux *
196 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
197     const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
198     uint32_t concrete_frame_idx) {
199   return new NativeRegisterContextLinux_x86_64(target_arch, native_thread,
200                                                concrete_frame_idx);
201 }
202 
203 // ----------------------------------------------------------------------------
204 // NativeRegisterContextLinux_x86_64 members.
205 // ----------------------------------------------------------------------------
206 
207 static RegisterInfoInterface *
208 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
209   if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
210     // 32-bit hosts run with a RegisterContextLinux_i386 context.
211     return new RegisterContextLinux_i386(target_arch);
212   } else {
213     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
214            "Register setting path assumes this is a 64-bit host");
215     // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
216     // x86_64 register context.
217     return new RegisterContextLinux_x86_64(target_arch);
218   }
219 }
220 
221 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
222     const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
223     uint32_t concrete_frame_idx)
224     : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
225                                  CreateRegisterInfoInterface(target_arch)),
226       m_fpr_type(eFPRTypeNotValid), m_fpr(), m_iovec(), m_ymm_set(),
227       m_reg_info(), m_gpr_x86_64() {
228   // Set up data about ranges of valid registers.
229   switch (target_arch.GetMachine()) {
230   case llvm::Triple::x86:
231     m_reg_info.num_registers = k_num_registers_i386;
232     m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
233     m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
234     m_reg_info.num_avx_registers = k_num_avx_registers_i386;
235     m_reg_info.last_gpr = k_last_gpr_i386;
236     m_reg_info.first_fpr = k_first_fpr_i386;
237     m_reg_info.last_fpr = k_last_fpr_i386;
238     m_reg_info.first_st = lldb_st0_i386;
239     m_reg_info.last_st = lldb_st7_i386;
240     m_reg_info.first_mm = lldb_mm0_i386;
241     m_reg_info.last_mm = lldb_mm7_i386;
242     m_reg_info.first_xmm = lldb_xmm0_i386;
243     m_reg_info.last_xmm = lldb_xmm7_i386;
244     m_reg_info.first_ymm = lldb_ymm0_i386;
245     m_reg_info.last_ymm = lldb_ymm7_i386;
246     m_reg_info.first_dr = lldb_dr0_i386;
247     m_reg_info.gpr_flags = lldb_eflags_i386;
248     break;
249   case llvm::Triple::x86_64:
250     m_reg_info.num_registers = k_num_registers_x86_64;
251     m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
252     m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
253     m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
254     m_reg_info.last_gpr = k_last_gpr_x86_64;
255     m_reg_info.first_fpr = k_first_fpr_x86_64;
256     m_reg_info.last_fpr = k_last_fpr_x86_64;
257     m_reg_info.first_st = lldb_st0_x86_64;
258     m_reg_info.last_st = lldb_st7_x86_64;
259     m_reg_info.first_mm = lldb_mm0_x86_64;
260     m_reg_info.last_mm = lldb_mm7_x86_64;
261     m_reg_info.first_xmm = lldb_xmm0_x86_64;
262     m_reg_info.last_xmm = lldb_xmm15_x86_64;
263     m_reg_info.first_ymm = lldb_ymm0_x86_64;
264     m_reg_info.last_ymm = lldb_ymm15_x86_64;
265     m_reg_info.first_dr = lldb_dr0_x86_64;
266     m_reg_info.gpr_flags = lldb_rflags_x86_64;
267     break;
268   default:
269     assert(false && "Unhandled target architecture.");
270     break;
271   }
272 
273   // Initialize m_iovec to point to the buffer and buffer size
274   // using the conventions of Berkeley style UIO structures, as required
275   // by PTRACE extensions.
276   m_iovec.iov_base = &m_fpr.xstate.xsave;
277   m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
278 
279   // Clear out the FPR state.
280   ::memset(&m_fpr, 0, sizeof(FPR));
281 
282   // Store byte offset of fctrl (i.e. first register of FPR)
283   const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
284   m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
285 }
286 
287 // CONSIDER after local and llgs debugging are merged, register set support can
288 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
289 uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
290   uint32_t sets = 0;
291   for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
292     if (IsRegisterSetAvailable(set_index))
293       ++sets;
294   }
295 
296   return sets;
297 }
298 
299 uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
300   uint32_t count = 0;
301   for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
302     const RegisterSet *set = GetRegisterSet(set_index);
303     if (set)
304       count += set->num_registers;
305   }
306   return count;
307 }
308 
309 const RegisterSet *
310 NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
311   if (!IsRegisterSetAvailable(set_index))
312     return nullptr;
313 
314   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
315   case llvm::Triple::x86:
316     return &g_reg_sets_i386[set_index];
317   case llvm::Triple::x86_64:
318     return &g_reg_sets_x86_64[set_index];
319   default:
320     assert(false && "Unhandled target architecture.");
321     return nullptr;
322   }
323 
324   return nullptr;
325 }
326 
327 Error NativeRegisterContextLinux_x86_64::ReadRegister(
328     const RegisterInfo *reg_info, RegisterValue &reg_value) {
329   Error error;
330 
331   if (!reg_info) {
332     error.SetErrorString("reg_info NULL");
333     return error;
334   }
335 
336   const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
337   if (reg == LLDB_INVALID_REGNUM) {
338     // This is likely an internal register for lldb use only and should not be
339     // directly queried.
340     error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
341                                    "register, cannot read directly",
342                                    reg_info->name);
343     return error;
344   }
345 
346   if (IsFPR(reg, GetFPRType())) {
347     error = ReadFPR();
348     if (error.Fail())
349       return error;
350   } else {
351     uint32_t full_reg = reg;
352     bool is_subreg = reg_info->invalidate_regs &&
353                      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
354 
355     if (is_subreg) {
356       // Read the full aligned 64-bit register.
357       full_reg = reg_info->invalidate_regs[0];
358     }
359 
360     error = ReadRegisterRaw(full_reg, reg_value);
361 
362     if (error.Success()) {
363       // If our read was not aligned (for ah,bh,ch,dh), shift our returned value
364       // one byte to the right.
365       if (is_subreg && (reg_info->byte_offset & 0x1))
366         reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
367 
368       // If our return byte size was greater than the return value reg size,
369       // then
370       // use the type specified by reg_info rather than the uint64_t default
371       if (reg_value.GetByteSize() > reg_info->byte_size)
372         reg_value.SetType(reg_info);
373     }
374     return error;
375   }
376 
377   if (reg_info->encoding == lldb::eEncodingVector) {
378     lldb::ByteOrder byte_order = GetByteOrder();
379 
380     if (byte_order != lldb::eByteOrderInvalid) {
381       if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
382         reg_value.SetBytes(
383             m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
384             reg_info->byte_size, byte_order);
385       if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
386         reg_value.SetBytes(
387             m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
388             reg_info->byte_size, byte_order);
389       if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
390         reg_value.SetBytes(
391             m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
392             reg_info->byte_size, byte_order);
393       if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
394         // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
395         if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoYMM(reg, byte_order))
396           reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
397                              reg_info->byte_size, byte_order);
398         else {
399           error.SetErrorString("failed to copy ymm register value");
400           return error;
401         }
402       }
403 
404       if (reg_value.GetType() != RegisterValue::eTypeBytes)
405         error.SetErrorString(
406             "write failed - type was expected to be RegisterValue::eTypeBytes");
407 
408       return error;
409     }
410 
411     error.SetErrorString("byte order is invalid");
412     return error;
413   }
414 
415   // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
416 
417   // Byte offsets of all registers are calculated wrt 'UserArea' structure.
418   // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
419   // and stores them in 'm_fpr' (of type FPR structure). To extract values of
420   // fpu
421   // registers, m_fpr should be read at byte offsets calculated wrt to FPR
422   // structure.
423 
424   // Since, FPR structure is also one of the member of UserArea structure.
425   // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
426   // byte_offset(fctrl wrt UserArea)
427   assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
428   uint8_t *src =
429       (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
430   switch (reg_info->byte_size) {
431   case 1:
432     reg_value.SetUInt8(*(uint8_t *)src);
433     break;
434   case 2:
435     reg_value.SetUInt16(*(uint16_t *)src);
436     break;
437   case 4:
438     reg_value.SetUInt32(*(uint32_t *)src);
439     break;
440   case 8:
441     reg_value.SetUInt64(*(uint64_t *)src);
442     break;
443   default:
444     assert(false && "Unhandled data size.");
445     error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
446                                    reg_info->byte_size);
447     break;
448   }
449 
450   return error;
451 }
452 
453 Error NativeRegisterContextLinux_x86_64::WriteRegister(
454     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
455   assert(reg_info && "reg_info is null");
456 
457   const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
458   if (reg_index == LLDB_INVALID_REGNUM)
459     return Error("no lldb regnum for %s", reg_info && reg_info->name
460                                               ? reg_info->name
461                                               : "<unknown register>");
462 
463   if (IsGPR(reg_index))
464     return WriteRegisterRaw(reg_index, reg_value);
465 
466   if (IsFPR(reg_index, GetFPRType())) {
467     if (reg_info->encoding == lldb::eEncodingVector) {
468       if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
469         ::memcpy(
470             m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
471             reg_value.GetBytes(), reg_value.GetByteSize());
472 
473       if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
474         ::memcpy(
475             m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
476             reg_value.GetBytes(), reg_value.GetByteSize());
477 
478       if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
479         ::memcpy(
480             m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
481             reg_value.GetBytes(), reg_value.GetByteSize());
482 
483       if (reg_index >= m_reg_info.first_ymm &&
484           reg_index <= m_reg_info.last_ymm) {
485         if (GetFPRType() != eFPRTypeXSAVE)
486           return Error("target processor does not support AVX");
487 
488         // Store ymm register content, and split into the register halves in
489         // xmm.bytes and ymmh.bytes
490         ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
491                  reg_value.GetBytes(), reg_value.GetByteSize());
492         if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
493           return Error("CopyYMMtoXSTATE() failed");
494       }
495     } else {
496       // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
497 
498       // Byte offsets of all registers are calculated wrt 'UserArea' structure.
499       // However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
500       // fpu
501       // registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu registers
502       // should
503       // be written in m_fpr at byte offsets calculated wrt FPR structure.
504 
505       // Since, FPR structure is also one of the member of UserArea structure.
506       // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
507       // byte_offset(fctrl wrt UserArea)
508       assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
509              sizeof(m_fpr));
510       uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
511                      m_fctrl_offset_in_userarea;
512       switch (reg_info->byte_size) {
513       case 1:
514         *(uint8_t *)dst = reg_value.GetAsUInt8();
515         break;
516       case 2:
517         *(uint16_t *)dst = reg_value.GetAsUInt16();
518         break;
519       case 4:
520         *(uint32_t *)dst = reg_value.GetAsUInt32();
521         break;
522       case 8:
523         *(uint64_t *)dst = reg_value.GetAsUInt64();
524         break;
525       default:
526         assert(false && "Unhandled data size.");
527         return Error("unhandled register data size %" PRIu32,
528                      reg_info->byte_size);
529       }
530     }
531 
532     Error error = WriteFPR();
533     if (error.Fail())
534       return error;
535 
536     if (IsAVX(reg_index)) {
537       if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
538         return Error("CopyYMMtoXSTATE() failed");
539     }
540     return Error();
541   }
542   return Error("failed - register wasn't recognized to be a GPR or an FPR, "
543                "write strategy unknown");
544 }
545 
546 Error NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
547     lldb::DataBufferSP &data_sp) {
548   Error error;
549 
550   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
551   if (!data_sp) {
552     error.SetErrorStringWithFormat(
553         "failed to allocate DataBufferHeap instance of size %" PRIu64,
554         REG_CONTEXT_SIZE);
555     return error;
556   }
557 
558   error = ReadGPR();
559   if (error.Fail())
560     return error;
561 
562   error = ReadFPR();
563   if (error.Fail())
564     return error;
565 
566   uint8_t *dst = data_sp->GetBytes();
567   if (dst == nullptr) {
568     error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
569                                    " returned a null pointer",
570                                    REG_CONTEXT_SIZE);
571     return error;
572   }
573 
574   ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
575   dst += GetRegisterInfoInterface().GetGPRSize();
576   if (GetFPRType() == eFPRTypeFXSAVE)
577     ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
578   else if (GetFPRType() == eFPRTypeXSAVE) {
579     lldb::ByteOrder byte_order = GetByteOrder();
580 
581     // Assemble the YMM register content from the register halves.
582     for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
583          ++reg) {
584       if (!CopyXSTATEtoYMM(reg, byte_order)) {
585         error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
586                                        "CopyXSTATEtoYMM() failed for reg num "
587                                        "%" PRIu32,
588                                        __FUNCTION__, reg);
589         return error;
590       }
591     }
592 
593     // Copy the extended register state including the assembled ymm registers.
594     ::memcpy(dst, &m_fpr, sizeof(m_fpr));
595   } else {
596     assert(false && "how do we save the floating point registers?");
597     error.SetErrorString("unsure how to save the floating point registers");
598   }
599   /** The following code is specific to Linux x86 based architectures,
600    *  where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
601    *  -1 to solve the bug 23659, such a setting prevents the automatic
602    *  decrement of the instruction pointer which was causing the SIGILL
603    *  exception.
604    * **/
605 
606   RegisterValue value((uint64_t)-1);
607   const RegisterInfo *reg_info =
608       GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
609   if (reg_info == nullptr)
610     reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
611 
612   if (reg_info != nullptr)
613     return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
614 
615   return error;
616 }
617 
618 Error NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
619     const lldb::DataBufferSP &data_sp) {
620   Error error;
621 
622   if (!data_sp) {
623     error.SetErrorStringWithFormat(
624         "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
625         __FUNCTION__);
626     return error;
627   }
628 
629   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
630     error.SetErrorStringWithFormat(
631         "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
632         "data size, expected %" PRIu64 ", actual %" PRIu64,
633         __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
634     return error;
635   }
636 
637   uint8_t *src = data_sp->GetBytes();
638   if (src == nullptr) {
639     error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
640                                    "DataBuffer::GetBytes() returned a null "
641                                    "pointer",
642                                    __FUNCTION__);
643     return error;
644   }
645   ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
646 
647   error = WriteGPR();
648   if (error.Fail())
649     return error;
650 
651   src += GetRegisterInfoInterface().GetGPRSize();
652   if (GetFPRType() == eFPRTypeFXSAVE)
653     ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
654   else if (GetFPRType() == eFPRTypeXSAVE)
655     ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
656 
657   error = WriteFPR();
658   if (error.Fail())
659     return error;
660 
661   if (GetFPRType() == eFPRTypeXSAVE) {
662     lldb::ByteOrder byte_order = GetByteOrder();
663 
664     // Parse the YMM register content from the register halves.
665     for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
666          ++reg) {
667       if (!CopyYMMtoXSTATE(reg, byte_order)) {
668         error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
669                                        "CopyYMMtoXSTATE() failed for reg num "
670                                        "%" PRIu32,
671                                        __FUNCTION__, reg);
672         return error;
673       }
674     }
675   }
676 
677   return error;
678 }
679 
680 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
681     uint32_t set_index) const {
682   // Note: Extended register sets are assumed to be at the end of g_reg_sets.
683   uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
684 
685   if (GetFPRType() == eFPRTypeXSAVE) {
686     // AVX is the first extended register set.
687     ++num_sets;
688   }
689   return (set_index < num_sets);
690 }
691 
692 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
693   // GPRs come first.
694   return reg_index <= m_reg_info.last_gpr;
695 }
696 
697 NativeRegisterContextLinux_x86_64::FPRType
698 NativeRegisterContextLinux_x86_64::GetFPRType() const {
699   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
700   if (m_fpr_type == eFPRTypeNotValid) {
701     // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
702 
703     // Try and see if AVX register retrieval works.
704     m_fpr_type = eFPRTypeXSAVE;
705     if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)
706             ->ReadFPR()
707             .Fail()) {
708       // Fall back to general floating point with no AVX support.
709       m_fpr_type = eFPRTypeFXSAVE;
710 
711       // Check if FXSAVE area can be read.
712       if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)
713               ->ReadFPR()
714               .Fail()) {
715         if (log)
716           log->Printf("NativeRegisterContextLinux_x86_64::%s ptrace APIs "
717                       "failed to read XSAVE/FXSAVE area",
718                       __FUNCTION__);
719       }
720     }
721   }
722   return m_fpr_type;
723 }
724 
725 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
726   return (m_reg_info.first_fpr <= reg_index &&
727           reg_index <= m_reg_info.last_fpr);
728 }
729 
730 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index,
731                                               FPRType fpr_type) const {
732   bool generic_fpr = IsFPR(reg_index);
733 
734   if (fpr_type == eFPRTypeXSAVE)
735     return generic_fpr || IsAVX(reg_index);
736   return generic_fpr;
737 }
738 
739 Error NativeRegisterContextLinux_x86_64::WriteFPR() {
740   const FPRType fpr_type = GetFPRType();
741   const lldb_private::ArchSpec &target_arch =
742       GetRegisterInfoInterface().GetTargetArchitecture();
743   switch (fpr_type) {
744   case FPRType::eFPRTypeFXSAVE:
745     // For 32-bit inferiors on x86_32/x86_64 architectures,
746     // FXSAVE area can be written using PTRACE_SETREGSET ptrace api
747     // For 64-bit inferiors on x86_64 architectures,
748     // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api
749     switch (target_arch.GetMachine()) {
750     case llvm::Triple::x86:
751       return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
752                               NT_PRXFPREG);
753     case llvm::Triple::x86_64:
754       return NativeRegisterContextLinux::WriteFPR();
755     default:
756       assert(false && "Unhandled target architecture.");
757       break;
758     }
759   case FPRType::eFPRTypeXSAVE:
760     return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
761                             NT_X86_XSTATE);
762   default:
763     return Error("Unrecognized FPR type");
764   }
765 }
766 
767 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
768   return (m_reg_info.first_ymm <= reg_index &&
769           reg_index <= m_reg_info.last_ymm);
770 }
771 
772 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
773     uint32_t reg_index, lldb::ByteOrder byte_order) {
774   if (!IsAVX(reg_index))
775     return false;
776 
777   if (byte_order == lldb::eByteOrderLittle) {
778     ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
779              m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
780              sizeof(XMMReg));
781     ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
782                  sizeof(XMMReg),
783              m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
784              sizeof(YMMHReg));
785     return true;
786   }
787 
788   if (byte_order == lldb::eByteOrderBig) {
789     ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
790                  sizeof(XMMReg),
791              m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
792              sizeof(XMMReg));
793     ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
794              m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
795              sizeof(YMMHReg));
796     return true;
797   }
798   return false; // unsupported or invalid byte order
799 }
800 
801 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
802     uint32_t reg, lldb::ByteOrder byte_order) {
803   if (!IsAVX(reg))
804     return false;
805 
806   if (byte_order == lldb::eByteOrderLittle) {
807     ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
808              m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
809     ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
810              m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
811              sizeof(YMMHReg));
812     return true;
813   }
814 
815   if (byte_order == lldb::eByteOrderBig) {
816     ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
817              m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
818              sizeof(XMMReg));
819     ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
820              m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
821     return true;
822   }
823   return false; // unsupported or invalid byte order
824 }
825 
826 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
827   const FPRType fpr_type = GetFPRType();
828   switch (fpr_type) {
829   case FPRType::eFPRTypeFXSAVE:
830     return &m_fpr.xstate.fxsave;
831   case FPRType::eFPRTypeXSAVE:
832     return &m_iovec;
833   default:
834     return nullptr;
835   }
836 }
837 
838 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
839   const FPRType fpr_type = GetFPRType();
840   switch (fpr_type) {
841   case FPRType::eFPRTypeFXSAVE:
842     return sizeof(m_fpr.xstate.fxsave);
843   case FPRType::eFPRTypeXSAVE:
844     return sizeof(m_iovec);
845   default:
846     return 0;
847   }
848 }
849 
850 Error NativeRegisterContextLinux_x86_64::ReadFPR() {
851   const FPRType fpr_type = GetFPRType();
852   const lldb_private::ArchSpec &target_arch =
853       GetRegisterInfoInterface().GetTargetArchitecture();
854   switch (fpr_type) {
855   case FPRType::eFPRTypeFXSAVE:
856     // For 32-bit inferiors on x86_32/x86_64 architectures,
857     // FXSAVE area can be read using PTRACE_GETREGSET ptrace api
858     // For 64-bit inferiors on x86_64 architectures,
859     // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api
860     switch (target_arch.GetMachine()) {
861     case llvm::Triple::x86:
862       return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
863     case llvm::Triple::x86_64:
864       return NativeRegisterContextLinux::ReadFPR();
865     default:
866       assert(false && "Unhandled target architecture.");
867       break;
868     }
869   case FPRType::eFPRTypeXSAVE:
870     return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
871   default:
872     return Error("Unrecognized FPR type");
873   }
874 }
875 
876 Error NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
877                                                          bool &is_hit) {
878   if (wp_index >= NumSupportedHardwareWatchpoints())
879     return Error("Watchpoint index out of range");
880 
881   RegisterValue reg_value;
882   Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
883   if (error.Fail()) {
884     is_hit = false;
885     return error;
886   }
887 
888   uint64_t status_bits = reg_value.GetAsUInt64();
889 
890   is_hit = status_bits & (1 << wp_index);
891 
892   return error;
893 }
894 
895 Error NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
896     uint32_t &wp_index, lldb::addr_t trap_addr) {
897   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
898   for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
899     bool is_hit;
900     Error error = IsWatchpointHit(wp_index, is_hit);
901     if (error.Fail()) {
902       wp_index = LLDB_INVALID_INDEX32;
903       return error;
904     } else if (is_hit) {
905       return error;
906     }
907   }
908   wp_index = LLDB_INVALID_INDEX32;
909   return Error();
910 }
911 
912 Error NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
913                                                             bool &is_vacant) {
914   if (wp_index >= NumSupportedHardwareWatchpoints())
915     return Error("Watchpoint index out of range");
916 
917   RegisterValue reg_value;
918   Error error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
919   if (error.Fail()) {
920     is_vacant = false;
921     return error;
922   }
923 
924   uint64_t control_bits = reg_value.GetAsUInt64();
925 
926   is_vacant = !(control_bits & (1 << (2 * wp_index)));
927 
928   return error;
929 }
930 
931 Error NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
932     lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
933 
934   if (wp_index >= NumSupportedHardwareWatchpoints())
935     return Error("Watchpoint index out of range");
936 
937   // Read only watchpoints aren't supported on x86_64. Fall back to read/write
938   // waitchpoints instead.
939   // TODO: Add logic to detect when a write happens and ignore that watchpoint
940   // hit.
941   if (watch_flags == 0x2)
942     watch_flags = 0x3;
943 
944   if (watch_flags != 0x1 && watch_flags != 0x3)
945     return Error("Invalid read/write bits for watchpoint");
946 
947   if (size != 1 && size != 2 && size != 4 && size != 8)
948     return Error("Invalid size for watchpoint");
949 
950   bool is_vacant;
951   Error error = IsWatchpointVacant(wp_index, is_vacant);
952   if (error.Fail())
953     return error;
954   if (!is_vacant)
955     return Error("Watchpoint index not vacant");
956 
957   RegisterValue reg_value;
958   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
959   if (error.Fail())
960     return error;
961 
962   // for watchpoints 0, 1, 2, or 3, respectively,
963   // set bits 1, 3, 5, or 7
964   uint64_t enable_bit = 1 << (2 * wp_index);
965 
966   // set bits 16-17, 20-21, 24-25, or 28-29
967   // with 0b01 for write, and 0b11 for read/write
968   uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
969 
970   // set bits 18-19, 22-23, 26-27, or 30-31
971   // with 0b00, 0b01, 0b10, or 0b11
972   // for 1, 2, 8 (if supported), or 4 bytes, respectively
973   uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
974 
975   uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
976 
977   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
978 
979   control_bits |= enable_bit | rw_bits | size_bits;
980 
981   error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
982   if (error.Fail())
983     return error;
984 
985   error =
986       WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
987   if (error.Fail())
988     return error;
989 
990   error.Clear();
991   return error;
992 }
993 
994 bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
995     uint32_t wp_index) {
996   if (wp_index >= NumSupportedHardwareWatchpoints())
997     return false;
998 
999   RegisterValue reg_value;
1000 
1001   // for watchpoints 0, 1, 2, or 3, respectively,
1002   // clear bits 0, 1, 2, or 3 of the debug status register (DR6)
1003   Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
1004   if (error.Fail())
1005     return false;
1006   uint64_t bit_mask = 1 << wp_index;
1007   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1008   error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
1009   if (error.Fail())
1010     return false;
1011 
1012   // for watchpoints 0, 1, 2, or 3, respectively,
1013   // clear bits {0-1,16-19}, {2-3,20-23}, {4-5,24-27}, or {6-7,28-31}
1014   // of the debug control register (DR7)
1015   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1016   if (error.Fail())
1017     return false;
1018   bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
1019   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1020   return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
1021       .Success();
1022 }
1023 
1024 Error NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
1025   RegisterValue reg_value;
1026 
1027   // clear bits {0-4} of the debug status register (DR6)
1028   Error error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
1029   if (error.Fail())
1030     return error;
1031   uint64_t bit_mask = 0xF;
1032   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1033   error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
1034   if (error.Fail())
1035     return error;
1036 
1037   // clear bits {0-7,16-31} of the debug control register (DR7)
1038   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1039   if (error.Fail())
1040     return error;
1041   bit_mask = 0xFF | (0xFFFF << 16);
1042   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1043   return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
1044 }
1045 
1046 uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
1047     lldb::addr_t addr, size_t size, uint32_t watch_flags) {
1048   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1049   const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1050   for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
1051     bool is_vacant;
1052     Error error = IsWatchpointVacant(wp_index, is_vacant);
1053     if (is_vacant) {
1054       error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
1055       if (error.Success())
1056         return wp_index;
1057     }
1058     if (error.Fail() && log) {
1059       log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
1060                   __FUNCTION__, error.AsCString());
1061     }
1062   }
1063   return LLDB_INVALID_INDEX32;
1064 }
1065 
1066 lldb::addr_t
1067 NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
1068   if (wp_index >= NumSupportedHardwareWatchpoints())
1069     return LLDB_INVALID_ADDRESS;
1070   RegisterValue reg_value;
1071   if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
1072     return LLDB_INVALID_ADDRESS;
1073   return reg_value.GetAsUInt64();
1074 }
1075 
1076 uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
1077   // Available debug address registers: dr0, dr1, dr2, dr3
1078   return 4;
1079 }
1080 
1081 #endif // defined(__i386__) || defined(__x86_64__)
1082