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