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/lldb-private-forward.h"
13 #include "lldb/Core/DataBufferHeap.h"
14 #include "lldb/Core/Error.h"
15 #include "lldb/Core/RegisterValue.h"
16 #include "Host/common/NativeProcessProtocol.h"
17 #include "Host/common/NativeThreadProtocol.h"
18 #include "Plugins/Process/Linux/NativeProcessLinux.h"
19 
20 using namespace lldb_private;
21 
22 // ----------------------------------------------------------------------------
23 // Private namespace.
24 // ----------------------------------------------------------------------------
25 
26 namespace
27 {
28     // x86 32-bit general purpose registers.
29     const uint32_t
30     g_gpr_regnums_i386[] =
31     {
32         gpr_eax_i386,
33         gpr_ebx_i386,
34         gpr_ecx_i386,
35         gpr_edx_i386,
36         gpr_edi_i386,
37         gpr_esi_i386,
38         gpr_ebp_i386,
39         gpr_esp_i386,
40         gpr_eip_i386,
41         gpr_eflags_i386,
42         gpr_cs_i386,
43         gpr_fs_i386,
44         gpr_gs_i386,
45         gpr_ss_i386,
46         gpr_ds_i386,
47         gpr_es_i386,
48         gpr_ax_i386,
49         gpr_bx_i386,
50         gpr_cx_i386,
51         gpr_dx_i386,
52         gpr_di_i386,
53         gpr_si_i386,
54         gpr_bp_i386,
55         gpr_sp_i386,
56         gpr_ah_i386,
57         gpr_bh_i386,
58         gpr_ch_i386,
59         gpr_dh_i386,
60         gpr_al_i386,
61         gpr_bl_i386,
62         gpr_cl_i386,
63         gpr_dl_i386,
64         LLDB_INVALID_REGNUM // register sets need to end with this flag
65     };
66     static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386,
67                   "g_gpr_regnums_i386 has wrong number of register infos");
68 
69     // x86 32-bit floating point registers.
70     const uint32_t
71     g_fpu_regnums_i386[] =
72     {
73         fpu_fctrl_i386,
74         fpu_fstat_i386,
75         fpu_ftag_i386,
76         fpu_fop_i386,
77         fpu_fiseg_i386,
78         fpu_fioff_i386,
79         fpu_foseg_i386,
80         fpu_fooff_i386,
81         fpu_mxcsr_i386,
82         fpu_mxcsrmask_i386,
83         fpu_st0_i386,
84         fpu_st1_i386,
85         fpu_st2_i386,
86         fpu_st3_i386,
87         fpu_st4_i386,
88         fpu_st5_i386,
89         fpu_st6_i386,
90         fpu_st7_i386,
91         fpu_mm0_i386,
92         fpu_mm1_i386,
93         fpu_mm2_i386,
94         fpu_mm3_i386,
95         fpu_mm4_i386,
96         fpu_mm5_i386,
97         fpu_mm6_i386,
98         fpu_mm7_i386,
99         fpu_xmm0_i386,
100         fpu_xmm1_i386,
101         fpu_xmm2_i386,
102         fpu_xmm3_i386,
103         fpu_xmm4_i386,
104         fpu_xmm5_i386,
105         fpu_xmm6_i386,
106         fpu_xmm7_i386,
107         LLDB_INVALID_REGNUM // register sets need to end with this flag
108     };
109     static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 1 == k_num_fpr_registers_i386,
110                   "g_fpu_regnums_i386 has wrong number of register infos");
111 
112     // x86 32-bit AVX registers.
113     const uint32_t
114     g_avx_regnums_i386[] =
115     {
116         fpu_ymm0_i386,
117         fpu_ymm1_i386,
118         fpu_ymm2_i386,
119         fpu_ymm3_i386,
120         fpu_ymm4_i386,
121         fpu_ymm5_i386,
122         fpu_ymm6_i386,
123         fpu_ymm7_i386,
124         LLDB_INVALID_REGNUM // register sets need to end with this flag
125     };
126     static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386,
127                   " g_avx_regnums_i386 has wrong number of register infos");
128 
129     // x86 64-bit general purpose registers.
130     static const
131     uint32_t g_gpr_regnums_x86_64[] =
132     {
133         gpr_rax_x86_64,
134         gpr_rbx_x86_64,
135         gpr_rcx_x86_64,
136         gpr_rdx_x86_64,
137         gpr_rdi_x86_64,
138         gpr_rsi_x86_64,
139         gpr_rbp_x86_64,
140         gpr_rsp_x86_64,
141         gpr_r8_x86_64,
142         gpr_r9_x86_64,
143         gpr_r10_x86_64,
144         gpr_r11_x86_64,
145         gpr_r12_x86_64,
146         gpr_r13_x86_64,
147         gpr_r14_x86_64,
148         gpr_r15_x86_64,
149         gpr_rip_x86_64,
150         gpr_rflags_x86_64,
151         gpr_cs_x86_64,
152         gpr_fs_x86_64,
153         gpr_gs_x86_64,
154         gpr_ss_x86_64,
155         gpr_ds_x86_64,
156         gpr_es_x86_64,
157         gpr_eax_x86_64,
158         gpr_ebx_x86_64,
159         gpr_ecx_x86_64,
160         gpr_edx_x86_64,
161         gpr_edi_x86_64,
162         gpr_esi_x86_64,
163         gpr_ebp_x86_64,
164         gpr_esp_x86_64,
165         gpr_r8d_x86_64,    // Low 32 bits or r8
166         gpr_r9d_x86_64,    // Low 32 bits or r9
167         gpr_r10d_x86_64,   // Low 32 bits or r10
168         gpr_r11d_x86_64,   // Low 32 bits or r11
169         gpr_r12d_x86_64,   // Low 32 bits or r12
170         gpr_r13d_x86_64,   // Low 32 bits or r13
171         gpr_r14d_x86_64,   // Low 32 bits or r14
172         gpr_r15d_x86_64,   // Low 32 bits or r15
173         gpr_ax_x86_64,
174         gpr_bx_x86_64,
175         gpr_cx_x86_64,
176         gpr_dx_x86_64,
177         gpr_di_x86_64,
178         gpr_si_x86_64,
179         gpr_bp_x86_64,
180         gpr_sp_x86_64,
181         gpr_r8w_x86_64,    // Low 16 bits or r8
182         gpr_r9w_x86_64,    // Low 16 bits or r9
183         gpr_r10w_x86_64,   // Low 16 bits or r10
184         gpr_r11w_x86_64,   // Low 16 bits or r11
185         gpr_r12w_x86_64,   // Low 16 bits or r12
186         gpr_r13w_x86_64,   // Low 16 bits or r13
187         gpr_r14w_x86_64,   // Low 16 bits or r14
188         gpr_r15w_x86_64,   // Low 16 bits or r15
189         gpr_ah_x86_64,
190         gpr_bh_x86_64,
191         gpr_ch_x86_64,
192         gpr_dh_x86_64,
193         gpr_al_x86_64,
194         gpr_bl_x86_64,
195         gpr_cl_x86_64,
196         gpr_dl_x86_64,
197         gpr_dil_x86_64,
198         gpr_sil_x86_64,
199         gpr_bpl_x86_64,
200         gpr_spl_x86_64,
201         gpr_r8l_x86_64,    // Low 8 bits or r8
202         gpr_r9l_x86_64,    // Low 8 bits or r9
203         gpr_r10l_x86_64,   // Low 8 bits or r10
204         gpr_r11l_x86_64,   // Low 8 bits or r11
205         gpr_r12l_x86_64,   // Low 8 bits or r12
206         gpr_r13l_x86_64,   // Low 8 bits or r13
207         gpr_r14l_x86_64,   // Low 8 bits or r14
208         gpr_r15l_x86_64,   // Low 8 bits or r15
209         LLDB_INVALID_REGNUM // register sets need to end with this flag
210     };
211     static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64,
212                   "g_gpr_regnums_x86_64 has wrong number of register infos");
213 
214     // x86 64-bit floating point registers.
215     static const uint32_t
216     g_fpu_regnums_x86_64[] =
217     {
218         fpu_fctrl_x86_64,
219         fpu_fstat_x86_64,
220         fpu_ftag_x86_64,
221         fpu_fop_x86_64,
222         fpu_fiseg_x86_64,
223         fpu_fioff_x86_64,
224         fpu_foseg_x86_64,
225         fpu_fooff_x86_64,
226         fpu_mxcsr_x86_64,
227         fpu_mxcsrmask_x86_64,
228         fpu_st0_x86_64,
229         fpu_st1_x86_64,
230         fpu_st2_x86_64,
231         fpu_st3_x86_64,
232         fpu_st4_x86_64,
233         fpu_st5_x86_64,
234         fpu_st6_x86_64,
235         fpu_st7_x86_64,
236         fpu_mm0_x86_64,
237         fpu_mm1_x86_64,
238         fpu_mm2_x86_64,
239         fpu_mm3_x86_64,
240         fpu_mm4_x86_64,
241         fpu_mm5_x86_64,
242         fpu_mm6_x86_64,
243         fpu_mm7_x86_64,
244         fpu_xmm0_x86_64,
245         fpu_xmm1_x86_64,
246         fpu_xmm2_x86_64,
247         fpu_xmm3_x86_64,
248         fpu_xmm4_x86_64,
249         fpu_xmm5_x86_64,
250         fpu_xmm6_x86_64,
251         fpu_xmm7_x86_64,
252         fpu_xmm8_x86_64,
253         fpu_xmm9_x86_64,
254         fpu_xmm10_x86_64,
255         fpu_xmm11_x86_64,
256         fpu_xmm12_x86_64,
257         fpu_xmm13_x86_64,
258         fpu_xmm14_x86_64,
259         fpu_xmm15_x86_64,
260         LLDB_INVALID_REGNUM // register sets need to end with this flag
261     };
262     static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64,
263                   "g_fpu_regnums_x86_64 has wrong number of register infos");
264 
265     // x86 64-bit AVX registers.
266     static const uint32_t
267     g_avx_regnums_x86_64[] =
268     {
269         fpu_ymm0_x86_64,
270         fpu_ymm1_x86_64,
271         fpu_ymm2_x86_64,
272         fpu_ymm3_x86_64,
273         fpu_ymm4_x86_64,
274         fpu_ymm5_x86_64,
275         fpu_ymm6_x86_64,
276         fpu_ymm7_x86_64,
277         fpu_ymm8_x86_64,
278         fpu_ymm9_x86_64,
279         fpu_ymm10_x86_64,
280         fpu_ymm11_x86_64,
281         fpu_ymm12_x86_64,
282         fpu_ymm13_x86_64,
283         fpu_ymm14_x86_64,
284         fpu_ymm15_x86_64,
285         LLDB_INVALID_REGNUM // register sets need to end with this flag
286     };
287     static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64,
288                   "g_avx_regnums_x86_64 has wrong number of register infos");
289 
290     // Number of register sets provided by this context.
291     enum
292     {
293         k_num_extended_register_sets = 1,
294         k_num_register_sets = 3
295     };
296 
297     // Register sets for x86 32-bit.
298     static const RegisterSet
299     g_reg_sets_i386[k_num_register_sets] =
300     {
301         { "General Purpose Registers",  "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
302         { "Floating Point Registers",   "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 },
303         { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
304     };
305 
306     // Register sets for x86 64-bit.
307     static const RegisterSet
308     g_reg_sets_x86_64[k_num_register_sets] =
309     {
310         { "General Purpose Registers",  "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
311         { "Floating Point Registers",   "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
312         { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
313     };
314 }
315 
316 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface ().GetGPRSize () + sizeof(FPR))
317 
318 // ----------------------------------------------------------------------------
319 // Required ptrace defines.
320 // ----------------------------------------------------------------------------
321 
322 // Support ptrace extensions even when compiled without required kernel support
323 #ifndef NT_X86_XSTATE
324 #define NT_X86_XSTATE 0x202
325 #endif
326 
327 // ----------------------------------------------------------------------------
328 // NativeRegisterContextLinux_x86_64 members.
329 // ----------------------------------------------------------------------------
330 
331 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx, RegisterInfoInterface *reg_info_interface_p) :
332     NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p),
333     m_fpr_type (eFPRTypeNotValid),
334     m_fpr (),
335     m_iovec (),
336     m_ymm_set (),
337     m_reg_info (),
338     m_gpr_x86_64 ()
339 {
340     // Set up data about ranges of valid registers.
341     switch (reg_info_interface_p->GetTargetArchitecture ().GetMachine ())
342     {
343         case llvm::Triple::x86:
344             m_reg_info.num_registers        = k_num_registers_i386;
345             m_reg_info.num_gpr_registers    = k_num_gpr_registers_i386;
346             m_reg_info.num_fpr_registers    = k_num_fpr_registers_i386;
347             m_reg_info.num_avx_registers    = k_num_avx_registers_i386;
348             m_reg_info.last_gpr             = k_last_gpr_i386;
349             m_reg_info.first_fpr            = k_first_fpr_i386;
350             m_reg_info.last_fpr             = k_last_fpr_i386;
351             m_reg_info.first_st             = fpu_st0_i386;
352             m_reg_info.last_st              = fpu_st7_i386;
353             m_reg_info.first_mm             = fpu_mm0_i386;
354             m_reg_info.last_mm              = fpu_mm7_i386;
355             m_reg_info.first_xmm            = fpu_xmm0_i386;
356             m_reg_info.last_xmm             = fpu_xmm7_i386;
357             m_reg_info.first_ymm            = fpu_ymm0_i386;
358             m_reg_info.last_ymm             = fpu_ymm7_i386;
359             m_reg_info.first_dr             = dr0_i386;
360             m_reg_info.gpr_flags            = gpr_eflags_i386;
361             break;
362         case llvm::Triple::x86_64:
363             m_reg_info.num_registers        = k_num_registers_x86_64;
364             m_reg_info.num_gpr_registers    = k_num_gpr_registers_x86_64;
365             m_reg_info.num_fpr_registers    = k_num_fpr_registers_x86_64;
366             m_reg_info.num_avx_registers    = k_num_avx_registers_x86_64;
367             m_reg_info.last_gpr             = k_last_gpr_x86_64;
368             m_reg_info.first_fpr            = k_first_fpr_x86_64;
369             m_reg_info.last_fpr             = k_last_fpr_x86_64;
370             m_reg_info.first_st             = fpu_st0_x86_64;
371             m_reg_info.last_st              = fpu_st7_x86_64;
372             m_reg_info.first_mm             = fpu_mm0_x86_64;
373             m_reg_info.last_mm              = fpu_mm7_x86_64;
374             m_reg_info.first_xmm            = fpu_xmm0_x86_64;
375             m_reg_info.last_xmm             = fpu_xmm15_x86_64;
376             m_reg_info.first_ymm            = fpu_ymm0_x86_64;
377             m_reg_info.last_ymm             = fpu_ymm15_x86_64;
378             m_reg_info.first_dr             = dr0_x86_64;
379             m_reg_info.gpr_flags            = gpr_rflags_x86_64;
380             break;
381         default:
382             assert(false && "Unhandled target architecture.");
383             break;
384     }
385 
386     // Initialize m_iovec to point to the buffer and buffer size
387     // using the conventions of Berkeley style UIO structures, as required
388     // by PTRACE extensions.
389     m_iovec.iov_base = &m_fpr.xstate.xsave;
390     m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
391 
392     // Clear out the FPR state.
393     ::memset(&m_fpr, 0, sizeof(FPR));
394 }
395 
396 // CONSIDER after local and llgs debugging are merged, register set support can
397 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
398 uint32_t
399 NativeRegisterContextLinux_x86_64::GetRegisterSetCount () const
400 {
401     uint32_t sets = 0;
402     for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
403     {
404         if (IsRegisterSetAvailable (set_index))
405             ++sets;
406     }
407 
408     return sets;
409 }
410 
411 const lldb_private::RegisterSet *
412 NativeRegisterContextLinux_x86_64::GetRegisterSet (uint32_t set_index) const
413 {
414     if (!IsRegisterSetAvailable (set_index))
415         return nullptr;
416 
417     switch (GetRegisterInfoInterface ().GetTargetArchitecture ().GetMachine ())
418     {
419         case llvm::Triple::x86:
420             return &g_reg_sets_i386[set_index];
421         case llvm::Triple::x86_64:
422             return &g_reg_sets_x86_64[set_index];
423         default:
424             assert (false && "Unhandled target architecture.");
425             return nullptr;
426     }
427 
428     return nullptr;
429 }
430 
431 lldb_private::Error
432 NativeRegisterContextLinux_x86_64::ReadRegisterRaw (uint32_t reg_index, RegisterValue &reg_value)
433 {
434     Error error;
435     const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index);
436     if (!reg_info)
437     {
438         error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index);
439         return error;
440     }
441 
442     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
443     if (!process_sp)
444     {
445         error.SetErrorString ("NativeProcessProtocol is NULL");
446         return error;
447     }
448 
449     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
450     if (!process_p->ReadRegisterValue(m_thread.GetID(),
451                                      reg_info->byte_offset,
452                                      reg_info->name,
453                                      reg_info->byte_size,
454                                      reg_value))
455         error.SetErrorString ("NativeProcessLinux::ReadRegisterValue() failed");
456 
457     return error;
458 }
459 
460 lldb_private::Error
461 NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
462 {
463     Error error;
464 
465     if (!reg_info)
466     {
467         error.SetErrorString ("reg_info NULL");
468         return error;
469     }
470 
471     const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
472     if (reg == LLDB_INVALID_REGNUM)
473     {
474         // This is likely an internal register for lldb use only and should not be directly queried.
475         error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name);
476         return error;
477     }
478 
479     if (IsFPR(reg, GetFPRType()))
480     {
481         if (!ReadFPR())
482         {
483             error.SetErrorString ("failed to read floating point register");
484             return error;
485         }
486     }
487     else
488     {
489         uint32_t full_reg = reg;
490         bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
491 
492         if (is_subreg)
493         {
494             // Read the full aligned 64-bit register.
495             full_reg = reg_info->invalidate_regs[0];
496         }
497 
498         error = ReadRegisterRaw(full_reg, reg_value);
499 
500         if (error.Success ())
501         {
502             // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
503             if (is_subreg && (reg_info->byte_offset & 0x1))
504                 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
505 
506             // If our return byte size was greater than the return value reg size, then
507             // use the type specified by reg_info rather than the uint64_t default
508             if (reg_value.GetByteSize() > reg_info->byte_size)
509                 reg_value.SetType(reg_info);
510         }
511         return error;
512     }
513 
514     if (reg_info->encoding == lldb::eEncodingVector)
515     {
516         lldb::ByteOrder byte_order = GetByteOrder();
517 
518         if (byte_order != lldb::eByteOrderInvalid)
519         {
520             if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
521                 reg_value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
522             if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
523                 reg_value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
524             if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
525                 reg_value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
526             if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
527             {
528                 // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
529                 if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoYMM(reg, byte_order))
530                     reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
531                 else
532                 {
533                     error.SetErrorString ("failed to copy ymm register value");
534                     return error;
535                 }
536             }
537 
538             if (reg_value.GetType() != RegisterValue::eTypeBytes)
539                 error.SetErrorString ("write failed - type was expected to be RegisterValue::eTypeBytes");
540 
541             return error;
542         }
543 
544         error.SetErrorString ("byte order is invalid");
545         return error;
546     }
547 
548     // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
549     assert (reg_info->byte_offset < sizeof(m_fpr));
550     uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
551     switch (reg_info->byte_size)
552     {
553         case 2:
554             reg_value.SetUInt16(*(uint16_t *)src);
555             break;
556         case 4:
557             reg_value.SetUInt32(*(uint32_t *)src);
558             break;
559         case 8:
560             reg_value.SetUInt64(*(uint64_t *)src);
561             break;
562         default:
563             assert(false && "Unhandled data size.");
564             error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
565             break;
566     }
567 
568     return error;
569 }
570 
571 lldb_private::Error
572 NativeRegisterContextLinux_x86_64::WriteRegister(const uint32_t reg,
573                                                  const RegisterValue &value)
574 {
575     Error error;
576 
577     uint32_t reg_to_write = reg;
578     RegisterValue value_to_write = value;
579 
580     // Check if this is a subregister of a full register.
581     const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
582     if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
583     {
584         RegisterValue full_value;
585         uint32_t full_reg = reg_info->invalidate_regs[0];
586         const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
587 
588         // Read the full register.
589         error = ReadRegister(full_reg_info, full_value);
590         if (error.Fail ())
591             return error;
592 
593         lldb::ByteOrder byte_order = GetByteOrder();
594         uint8_t dst[RegisterValue::kMaxRegisterByteSize];
595 
596         // Get the bytes for the full register.
597         const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
598                                                                dst,
599                                                                sizeof(dst),
600                                                                byte_order,
601                                                                error);
602         if (error.Success() && dest_size)
603         {
604             uint8_t src[RegisterValue::kMaxRegisterByteSize];
605 
606             // Get the bytes for the source data.
607             const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
608             if (error.Success() && src_size && (src_size < dest_size))
609             {
610                 // Copy the src bytes to the destination.
611                 memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
612                 // Set this full register as the value to write.
613                 value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
614                 value_to_write.SetType(full_reg_info);
615                 reg_to_write = full_reg;
616             }
617         }
618     }
619 
620 
621     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
622     if (!process_sp)
623     {
624         error.SetErrorString ("NativeProcessProtocol is NULL");
625         return error;
626     }
627 
628     const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
629     assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
630     if (!register_to_write_info_p)
631     {
632         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
633         return error;
634     }
635 
636     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
637     if (!process_p->WriteRegisterValue(m_thread.GetID(),
638                                        register_to_write_info_p->byte_offset,
639                                        register_to_write_info_p->name,
640                                        value_to_write))
641         error.SetErrorString ("NativeProcessLinux::WriteRegisterValue() failed");
642 
643     return error;
644 }
645 
646 lldb_private::Error
647 NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
648 {
649     assert (reg_info && "reg_info is null");
650 
651     const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
652     if (reg_index == LLDB_INVALID_REGNUM)
653         return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
654 
655     if (IsGPR(reg_index))
656         return WriteRegister(reg_index, reg_value);
657 
658     if (IsFPR(reg_index, GetFPRType()))
659     {
660         if (reg_info->encoding == lldb::eEncodingVector)
661         {
662             if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
663                 ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
664 
665             if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
666                 ::memcpy (m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
667 
668             if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
669                 ::memcpy (m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
670 
671             if (reg_index >= m_reg_info.first_ymm && reg_index <= m_reg_info.last_ymm)
672             {
673                 if (GetFPRType() != eFPRTypeXSAVE)
674                     return Error ("target processor does not support AVX");
675 
676                 // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
677                 ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, reg_value.GetBytes(), reg_value.GetByteSize());
678                 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
679                     return Error ("CopyYMMtoXSTATE() failed");
680             }
681         }
682         else
683         {
684             // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
685             assert (reg_info->byte_offset < sizeof(m_fpr));
686             uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
687             switch (reg_info->byte_size)
688             {
689                 case 2:
690                     *(uint16_t *)dst = reg_value.GetAsUInt16();
691                     break;
692                 case 4:
693                     *(uint32_t *)dst = reg_value.GetAsUInt32();
694                     break;
695                 case 8:
696                     *(uint64_t *)dst = reg_value.GetAsUInt64();
697                     break;
698                 default:
699                     assert(false && "Unhandled data size.");
700                     return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
701             }
702         }
703 
704         if (WriteFPR())
705         {
706             if (IsAVX(reg_index))
707             {
708                 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
709                     return Error ("CopyYMMtoXSTATE() failed");
710             }
711             return Error ();
712         }
713     }
714     return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
715 }
716 
717 lldb_private::Error
718 NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
719 {
720     Error error;
721 
722     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
723     if (!data_sp)
724     {
725         error.SetErrorStringWithFormat ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE);
726         return error;
727     }
728 
729     if (!ReadGPR ())
730     {
731         error.SetErrorString ("ReadGPR() failed");
732         return error;
733     }
734 
735     if (!ReadFPR ())
736     {
737         error.SetErrorString ("ReadFPR() failed");
738         return error;
739     }
740 
741     uint8_t *dst = data_sp->GetBytes ();
742     if (dst == nullptr)
743     {
744         error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE);
745         return error;
746     }
747 
748     ::memcpy (dst, &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
749     dst += GetRegisterInfoInterface ().GetGPRSize ();
750     if (GetFPRType () == eFPRTypeFXSAVE)
751         ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
752     else if (GetFPRType () == eFPRTypeXSAVE)
753     {
754         lldb::ByteOrder byte_order = GetByteOrder ();
755 
756         // Assemble the YMM register content from the register halves.
757         for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
758         {
759             if (!CopyXSTATEtoYMM (reg, byte_order))
760             {
761                 error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyXSTATEtoYMM() failed for reg num %" PRIu32, __FUNCTION__, reg);
762                 return error;
763             }
764         }
765 
766         // Copy the extended register state including the assembled ymm registers.
767         ::memcpy (dst, &m_fpr, sizeof (m_fpr));
768     }
769     else
770     {
771         assert (false && "how do we save the floating point registers?");
772         error.SetErrorString ("unsure how to save the floating point registers");
773     }
774 
775     return error;
776 }
777 
778 lldb_private::Error
779 NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
780 {
781     Error error;
782 
783     if (!data_sp)
784     {
785         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
786         return error;
787     }
788 
789     if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
790     {
791         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ());
792         return error;
793     }
794 
795 
796     uint8_t *src = data_sp->GetBytes ();
797     if (src == nullptr)
798     {
799         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
800         return error;
801     }
802     ::memcpy (&m_gpr_x86_64, src, GetRegisterInfoInterface ().GetGPRSize ());
803 
804     if (!WriteGPR ())
805     {
806         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__);
807         return error;
808     }
809 
810     src += GetRegisterInfoInterface ().GetGPRSize ();
811     if (GetFPRType () == eFPRTypeFXSAVE)
812         ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
813     else if (GetFPRType () == eFPRTypeXSAVE)
814         ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
815 
816     if (!WriteFPR ())
817     {
818         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__);
819         return error;
820     }
821 
822     if (GetFPRType() == eFPRTypeXSAVE)
823     {
824         lldb::ByteOrder byte_order = GetByteOrder();
825 
826         // Parse the YMM register content from the register halves.
827         for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm; ++reg)
828         {
829             if (!CopyYMMtoXSTATE (reg, byte_order))
830             {
831                 error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s CopyYMMtoXSTATE() failed for reg num %" PRIu32, __FUNCTION__, reg);
832                 return error;
833             }
834         }
835     }
836 
837     return error;
838 }
839 
840 bool
841 NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) const
842 {
843     // Note: Extended register sets are assumed to be at the end of g_reg_sets.
844     uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
845 
846     if (GetFPRType () == eFPRTypeXSAVE)
847     {
848         // AVX is the first extended register set.
849         ++num_sets;
850     }
851     return (set_index < num_sets);
852 }
853 
854 lldb::ByteOrder
855 NativeRegisterContextLinux_x86_64::GetByteOrder() const
856 {
857     // Get the target process whose privileged thread was used for the register read.
858     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
859 
860     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
861     if (!process_sp)
862         return byte_order;
863 
864     if (!process_sp->GetByteOrder (byte_order))
865     {
866         // FIXME log here
867     }
868 
869     return byte_order;
870 }
871 
872 bool
873 NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const
874 {
875     // GPRs come first.
876     return reg_index <= m_reg_info.last_gpr;
877 }
878 
879 NativeRegisterContextLinux_x86_64::FPRType
880 NativeRegisterContextLinux_x86_64::GetFPRType () const
881 {
882     if (m_fpr_type == eFPRTypeNotValid)
883     {
884         // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
885 
886         // Try and see if AVX register retrieval works.
887         m_fpr_type = eFPRTypeXSAVE;
888         if (!const_cast<NativeRegisterContextLinux_x86_64*> (this)->ReadFPR ())
889         {
890             // Fall back to general floating point with no AVX support.
891             m_fpr_type = eFPRTypeFXSAVE;
892         }
893     }
894 
895     return m_fpr_type;
896 }
897 
898 bool
899 NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const
900 {
901     return (m_reg_info.first_fpr <= reg_index && reg_index <= m_reg_info.last_fpr);
902 }
903 
904 bool
905 NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) const
906 {
907     bool generic_fpr = IsFPR(reg_index);
908 
909     if (fpr_type == eFPRTypeXSAVE)
910         return generic_fpr || IsAVX(reg_index);
911     return generic_fpr;
912 }
913 
914 bool
915 NativeRegisterContextLinux_x86_64::WriteFPR()
916 {
917     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
918     if (!process_sp)
919         return false;
920     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
921 
922     if (GetFPRType() == eFPRTypeFXSAVE)
923         return process_p->WriteFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave));
924 
925     if (GetFPRType() == eFPRTypeXSAVE)
926         return process_p->WriteRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE);
927     return false;
928 }
929 
930 bool
931 NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const
932 {
933     return (m_reg_info.first_ymm <= reg_index && reg_index <= m_reg_info.last_ymm);
934 }
935 
936 bool
937 NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM (uint32_t reg_index, lldb::ByteOrder byte_order)
938 {
939     if (!IsAVX (reg_index))
940         return false;
941 
942     if (byte_order == lldb::eByteOrderLittle)
943     {
944         ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
945                  m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
946                  sizeof (XMMReg));
947         ::memcpy (m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
948                  m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
949                  sizeof (YMMHReg));
950         return true;
951     }
952 
953     if (byte_order == lldb::eByteOrderBig)
954     {
955         ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof (XMMReg),
956                  m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
957                  sizeof (XMMReg));
958         ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
959                  m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
960                  sizeof (YMMHReg));
961         return true;
962     }
963     return false; // unsupported or invalid byte order
964 
965 }
966 
967 bool
968 NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
969 {
970     if (!IsAVX(reg))
971         return false;
972 
973     if (byte_order == lldb::eByteOrderLittle)
974     {
975         ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
976                  m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
977                  sizeof(XMMReg));
978         ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
979                  m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
980                  sizeof(YMMHReg));
981         return true;
982     }
983 
984     if (byte_order == lldb::eByteOrderBig)
985     {
986         ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
987                  m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
988                  sizeof(XMMReg));
989         ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
990                  m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
991                  sizeof(YMMHReg));
992         return true;
993     }
994     return false; // unsupported or invalid byte order
995 }
996 
997 bool
998 NativeRegisterContextLinux_x86_64::ReadFPR ()
999 {
1000     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
1001     if (!process_sp)
1002         return false;
1003     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
1004 
1005     const FPRType fpr_type = GetFPRType ();
1006     switch (fpr_type)
1007     {
1008     case FPRType::eFPRTypeFXSAVE:
1009         return process_p->ReadFPR (m_thread.GetID (), &m_fpr.xstate.fxsave, sizeof (m_fpr.xstate.fxsave));
1010 
1011     case FPRType::eFPRTypeXSAVE:
1012         return process_p->ReadRegisterSet (m_thread.GetID (), &m_iovec, sizeof (m_fpr.xstate.xsave), NT_X86_XSTATE);
1013 
1014     default:
1015         return false;
1016     }
1017 }
1018 
1019 bool
1020 NativeRegisterContextLinux_x86_64::ReadGPR()
1021 {
1022     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
1023     if (!process_sp)
1024         return false;
1025     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
1026 
1027     return process_p->ReadGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
1028 }
1029 
1030 bool
1031 NativeRegisterContextLinux_x86_64::WriteGPR()
1032 {
1033     NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
1034     if (!process_sp)
1035         return false;
1036     NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ());
1037 
1038     return process_p->WriteGPR (m_thread.GetID (), &m_gpr_x86_64, GetRegisterInfoInterface ().GetGPRSize ());
1039 }
1040 
1041