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