RegisterContextPOSIX_x86.cpp revision 263363
1//===-- RegisterContextPOSIX_x86.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 <cstring>
11#include <errno.h>
12#include <stdint.h>
13
14#include "lldb/Core/DataBufferHeap.h"
15#include "lldb/Core/DataExtractor.h"
16#include "lldb/Core/RegisterValue.h"
17#include "lldb/Core/Scalar.h"
18#include "lldb/Target/Target.h"
19#include "lldb/Target/Thread.h"
20#include "lldb/Host/Endian.h"
21#include "llvm/Support/Compiler.h"
22
23#include "ProcessPOSIX.h"
24#include "RegisterContext_x86.h"
25#include "RegisterContextPOSIX_x86.h"
26#include "Plugins/Process/elf-core/ProcessElfCore.h"
27
28using namespace lldb_private;
29using namespace lldb;
30
31const uint32_t
32g_gpr_regnums_i386[] =
33{
34    gpr_eax_i386,
35    gpr_ebx_i386,
36    gpr_ecx_i386,
37    gpr_edx_i386,
38    gpr_edi_i386,
39    gpr_esi_i386,
40    gpr_ebp_i386,
41    gpr_esp_i386,
42    gpr_eip_i386,
43    gpr_eflags_i386,
44    gpr_cs_i386,
45    gpr_fs_i386,
46    gpr_gs_i386,
47    gpr_ss_i386,
48    gpr_ds_i386,
49    gpr_es_i386,
50    gpr_ax_i386,
51    gpr_bx_i386,
52    gpr_cx_i386,
53    gpr_dx_i386,
54    gpr_di_i386,
55    gpr_si_i386,
56    gpr_bp_i386,
57    gpr_sp_i386,
58    gpr_ah_i386,
59    gpr_bh_i386,
60    gpr_ch_i386,
61    gpr_dh_i386,
62    gpr_al_i386,
63    gpr_bl_i386,
64    gpr_cl_i386,
65    gpr_dl_i386
66};
67static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) == k_num_gpr_registers_i386,
68    "g_gpr_regnums_i386 has wrong number of register infos");
69
70const uint32_t
71g_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};
108static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) == k_num_fpr_registers_i386,
109    "g_fpu_regnums_i386 has wrong number of register infos");
110
111const uint32_t
112g_avx_regnums_i386[] =
113{
114    fpu_ymm0_i386,
115    fpu_ymm1_i386,
116    fpu_ymm2_i386,
117    fpu_ymm3_i386,
118    fpu_ymm4_i386,
119    fpu_ymm5_i386,
120    fpu_ymm6_i386,
121    fpu_ymm7_i386
122};
123static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) == k_num_avx_registers_i386,
124    " g_avx_regnums_i386 has wrong number of register infos");
125
126static const
127uint32_t g_gpr_regnums_x86_64[] =
128{
129    gpr_rax_x86_64,
130    gpr_rbx_x86_64,
131    gpr_rcx_x86_64,
132    gpr_rdx_x86_64,
133    gpr_rdi_x86_64,
134    gpr_rsi_x86_64,
135    gpr_rbp_x86_64,
136    gpr_rsp_x86_64,
137    gpr_r8_x86_64,
138    gpr_r9_x86_64,
139    gpr_r10_x86_64,
140    gpr_r11_x86_64,
141    gpr_r12_x86_64,
142    gpr_r13_x86_64,
143    gpr_r14_x86_64,
144    gpr_r15_x86_64,
145    gpr_rip_x86_64,
146    gpr_rflags_x86_64,
147    gpr_cs_x86_64,
148    gpr_fs_x86_64,
149    gpr_gs_x86_64,
150    gpr_ss_x86_64,
151    gpr_ds_x86_64,
152    gpr_es_x86_64,
153    gpr_eax_x86_64,
154    gpr_ebx_x86_64,
155    gpr_ecx_x86_64,
156    gpr_edx_x86_64,
157    gpr_edi_x86_64,
158    gpr_esi_x86_64,
159    gpr_ebp_x86_64,
160    gpr_esp_x86_64,
161    gpr_r8d_x86_64,    // Low 32 bits or r8
162    gpr_r9d_x86_64,    // Low 32 bits or r9
163    gpr_r10d_x86_64,   // Low 32 bits or r10
164    gpr_r11d_x86_64,   // Low 32 bits or r11
165    gpr_r12d_x86_64,   // Low 32 bits or r12
166    gpr_r13d_x86_64,   // Low 32 bits or r13
167    gpr_r14d_x86_64,   // Low 32 bits or r14
168    gpr_r15d_x86_64,   // Low 32 bits or r15
169    gpr_ax_x86_64,
170    gpr_bx_x86_64,
171    gpr_cx_x86_64,
172    gpr_dx_x86_64,
173    gpr_di_x86_64,
174    gpr_si_x86_64,
175    gpr_bp_x86_64,
176    gpr_sp_x86_64,
177    gpr_r8w_x86_64,    // Low 16 bits or r8
178    gpr_r9w_x86_64,    // Low 16 bits or r9
179    gpr_r10w_x86_64,   // Low 16 bits or r10
180    gpr_r11w_x86_64,   // Low 16 bits or r11
181    gpr_r12w_x86_64,   // Low 16 bits or r12
182    gpr_r13w_x86_64,   // Low 16 bits or r13
183    gpr_r14w_x86_64,   // Low 16 bits or r14
184    gpr_r15w_x86_64,   // Low 16 bits or r15
185    gpr_ah_x86_64,
186    gpr_bh_x86_64,
187    gpr_ch_x86_64,
188    gpr_dh_x86_64,
189    gpr_al_x86_64,
190    gpr_bl_x86_64,
191    gpr_cl_x86_64,
192    gpr_dl_x86_64,
193    gpr_dil_x86_64,
194    gpr_sil_x86_64,
195    gpr_bpl_x86_64,
196    gpr_spl_x86_64,
197    gpr_r8l_x86_64,    // Low 8 bits or r8
198    gpr_r9l_x86_64,    // Low 8 bits or r9
199    gpr_r10l_x86_64,   // Low 8 bits or r10
200    gpr_r11l_x86_64,   // Low 8 bits or r11
201    gpr_r12l_x86_64,   // Low 8 bits or r12
202    gpr_r13l_x86_64,   // Low 8 bits or r13
203    gpr_r14l_x86_64,   // Low 8 bits or r14
204    gpr_r15l_x86_64,   // Low 8 bits or r15
205};
206static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) == k_num_gpr_registers_x86_64,
207    "g_gpr_regnums_x86_64 has wrong number of register infos");
208
209static const uint32_t
210g_fpu_regnums_x86_64[] =
211{
212    fpu_fctrl_x86_64,
213    fpu_fstat_x86_64,
214    fpu_ftag_x86_64,
215    fpu_fop_x86_64,
216    fpu_fiseg_x86_64,
217    fpu_fioff_x86_64,
218    fpu_foseg_x86_64,
219    fpu_fooff_x86_64,
220    fpu_mxcsr_x86_64,
221    fpu_mxcsrmask_x86_64,
222    fpu_st0_x86_64,
223    fpu_st1_x86_64,
224    fpu_st2_x86_64,
225    fpu_st3_x86_64,
226    fpu_st4_x86_64,
227    fpu_st5_x86_64,
228    fpu_st6_x86_64,
229    fpu_st7_x86_64,
230    fpu_mm0_x86_64,
231    fpu_mm1_x86_64,
232    fpu_mm2_x86_64,
233    fpu_mm3_x86_64,
234    fpu_mm4_x86_64,
235    fpu_mm5_x86_64,
236    fpu_mm6_x86_64,
237    fpu_mm7_x86_64,
238    fpu_xmm0_x86_64,
239    fpu_xmm1_x86_64,
240    fpu_xmm2_x86_64,
241    fpu_xmm3_x86_64,
242    fpu_xmm4_x86_64,
243    fpu_xmm5_x86_64,
244    fpu_xmm6_x86_64,
245    fpu_xmm7_x86_64,
246    fpu_xmm8_x86_64,
247    fpu_xmm9_x86_64,
248    fpu_xmm10_x86_64,
249    fpu_xmm11_x86_64,
250    fpu_xmm12_x86_64,
251    fpu_xmm13_x86_64,
252    fpu_xmm14_x86_64,
253    fpu_xmm15_x86_64
254};
255static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) == k_num_fpr_registers_x86_64,
256    "g_fpu_regnums_x86_64 has wrong number of register infos");
257
258static const uint32_t
259g_avx_regnums_x86_64[] =
260{
261    fpu_ymm0_x86_64,
262    fpu_ymm1_x86_64,
263    fpu_ymm2_x86_64,
264    fpu_ymm3_x86_64,
265    fpu_ymm4_x86_64,
266    fpu_ymm5_x86_64,
267    fpu_ymm6_x86_64,
268    fpu_ymm7_x86_64,
269    fpu_ymm8_x86_64,
270    fpu_ymm9_x86_64,
271    fpu_ymm10_x86_64,
272    fpu_ymm11_x86_64,
273    fpu_ymm12_x86_64,
274    fpu_ymm13_x86_64,
275    fpu_ymm14_x86_64,
276    fpu_ymm15_x86_64
277};
278static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) == k_num_avx_registers_x86_64,
279    "g_avx_regnums_x86_64 has wrong number of register infos");
280
281uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { gpr_eax_i386, LLDB_INVALID_REGNUM };
282uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { gpr_ebx_i386, LLDB_INVALID_REGNUM };
283uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { gpr_ecx_i386, LLDB_INVALID_REGNUM };
284uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { gpr_edx_i386, LLDB_INVALID_REGNUM };
285uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { gpr_edi_i386, LLDB_INVALID_REGNUM };
286uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { gpr_esi_i386, LLDB_INVALID_REGNUM };
287uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { gpr_ebp_i386, LLDB_INVALID_REGNUM };
288uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { gpr_esp_i386, LLDB_INVALID_REGNUM };
289
290uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { gpr_eax_i386, gpr_ax_i386, gpr_ah_i386,  gpr_al_i386, LLDB_INVALID_REGNUM };
291uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { gpr_ebx_i386, gpr_bx_i386, gpr_bh_i386,  gpr_bl_i386, LLDB_INVALID_REGNUM };
292uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { gpr_ecx_i386, gpr_cx_i386, gpr_ch_i386,  gpr_cl_i386, LLDB_INVALID_REGNUM };
293uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { gpr_edx_i386, gpr_dx_i386, gpr_dh_i386,  gpr_dl_i386, LLDB_INVALID_REGNUM };
294uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { gpr_edi_i386, gpr_di_i386, LLDB_INVALID_REGNUM };
295uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { gpr_esi_i386, gpr_si_i386, LLDB_INVALID_REGNUM };
296uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { gpr_ebp_i386, gpr_bp_i386, LLDB_INVALID_REGNUM };
297uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { gpr_esp_i386, gpr_sp_i386, LLDB_INVALID_REGNUM };
298
299uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { gpr_rax_x86_64, LLDB_INVALID_REGNUM };
300uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { gpr_rbx_x86_64, LLDB_INVALID_REGNUM };
301uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { gpr_rcx_x86_64, LLDB_INVALID_REGNUM };
302uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { gpr_rdx_x86_64, LLDB_INVALID_REGNUM };
303uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { gpr_rdi_x86_64, LLDB_INVALID_REGNUM };
304uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { gpr_rsi_x86_64, LLDB_INVALID_REGNUM };
305uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { gpr_rbp_x86_64, LLDB_INVALID_REGNUM };
306uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { gpr_rsp_x86_64, LLDB_INVALID_REGNUM };
307uint32_t RegisterContextPOSIX_x86::g_contained_r8[]  = { gpr_r8_x86_64,  LLDB_INVALID_REGNUM };
308uint32_t RegisterContextPOSIX_x86::g_contained_r9[]  = { gpr_r9_x86_64,  LLDB_INVALID_REGNUM };
309uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { gpr_r10_x86_64, LLDB_INVALID_REGNUM };
310uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { gpr_r11_x86_64, LLDB_INVALID_REGNUM };
311uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { gpr_r12_x86_64, LLDB_INVALID_REGNUM };
312uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { gpr_r13_x86_64, LLDB_INVALID_REGNUM };
313uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { gpr_r14_x86_64, LLDB_INVALID_REGNUM };
314uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { gpr_r15_x86_64, LLDB_INVALID_REGNUM };
315
316uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { gpr_rax_x86_64, gpr_eax_x86_64,  gpr_ax_x86_64,   gpr_ah_x86_64,   gpr_al_x86_64, LLDB_INVALID_REGNUM };
317uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { gpr_rbx_x86_64, gpr_ebx_x86_64,  gpr_bx_x86_64,   gpr_bh_x86_64,   gpr_bl_x86_64, LLDB_INVALID_REGNUM };
318uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { gpr_rcx_x86_64, gpr_ecx_x86_64,  gpr_cx_x86_64,   gpr_ch_x86_64,   gpr_cl_x86_64, LLDB_INVALID_REGNUM };
319uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { gpr_rdx_x86_64, gpr_edx_x86_64,  gpr_dx_x86_64,   gpr_dh_x86_64,   gpr_dl_x86_64, LLDB_INVALID_REGNUM };
320uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { gpr_rdi_x86_64, gpr_edi_x86_64,  gpr_di_x86_64,   gpr_dil_x86_64,  LLDB_INVALID_REGNUM };
321uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { gpr_rsi_x86_64, gpr_esi_x86_64,  gpr_si_x86_64,   gpr_sil_x86_64,  LLDB_INVALID_REGNUM };
322uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { gpr_rbp_x86_64, gpr_ebp_x86_64,  gpr_bp_x86_64,   gpr_bpl_x86_64,  LLDB_INVALID_REGNUM };
323uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { gpr_rsp_x86_64, gpr_esp_x86_64,  gpr_sp_x86_64,   gpr_spl_x86_64,  LLDB_INVALID_REGNUM };
324uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[]  = { gpr_r8_x86_64,  gpr_r8d_x86_64,  gpr_r8w_x86_64,  gpr_r8l_x86_64,  LLDB_INVALID_REGNUM };
325uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[]  = { gpr_r9_x86_64,  gpr_r9d_x86_64,  gpr_r9w_x86_64,  gpr_r9l_x86_64,  LLDB_INVALID_REGNUM };
326uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { gpr_r10_x86_64, gpr_r10d_x86_64, gpr_r10w_x86_64, gpr_r10l_x86_64, LLDB_INVALID_REGNUM };
327uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { gpr_r11_x86_64, gpr_r11d_x86_64, gpr_r11w_x86_64, gpr_r11l_x86_64, LLDB_INVALID_REGNUM };
328uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { gpr_r12_x86_64, gpr_r12d_x86_64, gpr_r12w_x86_64, gpr_r12l_x86_64, LLDB_INVALID_REGNUM };
329uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { gpr_r13_x86_64, gpr_r13d_x86_64, gpr_r13w_x86_64, gpr_r13l_x86_64, LLDB_INVALID_REGNUM };
330uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { gpr_r14_x86_64, gpr_r14d_x86_64, gpr_r14w_x86_64, gpr_r14l_x86_64, LLDB_INVALID_REGNUM };
331uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { gpr_r15_x86_64, gpr_r15d_x86_64, gpr_r15w_x86_64, gpr_r15l_x86_64, LLDB_INVALID_REGNUM };
332
333// Number of register sets provided by this context.
334enum
335{
336    k_num_extended_register_sets = 1,
337    k_num_register_sets = 3
338};
339
340static const RegisterSet
341g_reg_sets_i386[k_num_register_sets] =
342{
343    { "General Purpose Registers",  "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
344    { "Floating Point Registers",   "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 },
345    { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
346};
347
348static const RegisterSet
349g_reg_sets_x86_64[k_num_register_sets] =
350{
351    { "General Purpose Registers",  "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
352    { "Floating Point Registers",   "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
353    { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
354};
355
356bool RegisterContextPOSIX_x86::IsGPR(unsigned reg)
357{
358    return reg <= m_reg_info.last_gpr;   // GPR's come first.
359}
360
361bool RegisterContextPOSIX_x86::IsFPR(unsigned reg)
362{
363    return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
364}
365
366bool RegisterContextPOSIX_x86::IsAVX(unsigned reg)
367{
368    return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
369}
370
371bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type)
372{
373    bool generic_fpr = IsFPR(reg);
374
375    if (fpr_type == eXSAVE)
376        return generic_fpr || IsAVX(reg);
377    return generic_fpr;
378}
379
380RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread,
381                                                   uint32_t concrete_frame_idx,
382                                                   RegisterInfoInterface *register_info)
383    : RegisterContext(thread, concrete_frame_idx)
384{
385    m_register_info_ap.reset(register_info);
386
387    switch (register_info->m_target_arch.GetCore())
388    {
389        case ArchSpec::eCore_x86_32_i386:
390        case ArchSpec::eCore_x86_32_i486:
391        case ArchSpec::eCore_x86_32_i486sx:
392            m_reg_info.num_registers        = k_num_registers_i386;
393            m_reg_info.num_gpr_registers    = k_num_gpr_registers_i386;
394            m_reg_info.num_fpr_registers    = k_num_fpr_registers_i386;
395            m_reg_info.num_avx_registers    = k_num_avx_registers_i386;
396            m_reg_info.last_gpr             = k_last_gpr_i386;
397            m_reg_info.first_fpr            = k_first_fpr_i386;
398            m_reg_info.last_fpr             = k_last_fpr_i386;
399            m_reg_info.first_st             = fpu_st0_i386;
400            m_reg_info.last_st              = fpu_st7_i386;
401            m_reg_info.first_mm             = fpu_mm0_i386;
402            m_reg_info.last_mm              = fpu_mm7_i386;
403            m_reg_info.first_xmm            = fpu_xmm0_i386;
404            m_reg_info.last_xmm             = fpu_xmm7_i386;
405            m_reg_info.first_ymm            = fpu_ymm0_i386;
406            m_reg_info.last_ymm             = fpu_ymm7_i386;
407            m_reg_info.first_dr             = dr0_i386;
408            m_reg_info.gpr_flags            = gpr_eflags_i386;
409            break;
410        case ArchSpec::eCore_x86_64_x86_64:
411            m_reg_info.num_registers        = k_num_registers_x86_64;
412            m_reg_info.num_gpr_registers    = k_num_gpr_registers_x86_64;
413            m_reg_info.num_fpr_registers    = k_num_fpr_registers_x86_64;
414            m_reg_info.num_avx_registers    = k_num_avx_registers_x86_64;
415            m_reg_info.last_gpr             = k_last_gpr_x86_64;
416            m_reg_info.first_fpr            = k_first_fpr_x86_64;
417            m_reg_info.last_fpr             = k_last_fpr_x86_64;
418            m_reg_info.first_st             = fpu_st0_x86_64;
419            m_reg_info.last_st              = fpu_st7_x86_64;
420            m_reg_info.first_mm             = fpu_mm0_x86_64;
421            m_reg_info.last_mm              = fpu_mm7_x86_64;
422            m_reg_info.first_xmm            = fpu_xmm0_x86_64;
423            m_reg_info.last_xmm             = fpu_xmm15_x86_64;
424            m_reg_info.first_ymm            = fpu_ymm0_x86_64;
425            m_reg_info.last_ymm             = fpu_ymm15_x86_64;
426            m_reg_info.first_dr             = dr0_x86_64;
427            m_reg_info.gpr_flags            = gpr_rflags_x86_64;
428            break;
429        default:
430            assert(false && "Unhandled target architecture.");
431            break;
432    }
433
434    // Initialize m_iovec to point to the buffer and buffer size
435    // using the conventions of Berkeley style UIO structures, as required
436    // by PTRACE extensions.
437    m_iovec.iov_base = &m_fpr.xstate.xsave;
438    m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
439
440    ::memset(&m_fpr, 0, sizeof(FPR));
441
442    // elf-core yet to support ReadFPR()
443    ProcessSP base = CalculateProcess();
444    if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
445        return;
446
447    m_fpr_type = eNotValid;
448}
449
450RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86()
451{
452}
453
454RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType()
455{
456    if (m_fpr_type == eNotValid)
457    {
458        // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
459        m_fpr_type = eXSAVE; // extended floating-point registers, if available
460        if (false == ReadFPR())
461            m_fpr_type = eFXSAVE; // assume generic floating-point registers
462    }
463    return m_fpr_type;
464}
465
466void
467RegisterContextPOSIX_x86::Invalidate()
468{
469}
470
471void
472RegisterContextPOSIX_x86::InvalidateAllRegisters()
473{
474}
475
476unsigned
477RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg)
478{
479    assert(reg < m_reg_info.num_registers && "Invalid register number.");
480    return GetRegisterInfo()[reg].byte_offset;
481}
482
483unsigned
484RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg)
485{
486    assert(reg < m_reg_info.num_registers && "Invalid register number.");
487    return GetRegisterInfo()[reg].byte_size;
488}
489
490size_t
491RegisterContextPOSIX_x86::GetRegisterCount()
492{
493    size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
494    if (GetFPRType() == eXSAVE)
495      return num_registers + m_reg_info.num_avx_registers;
496    return num_registers;
497}
498
499size_t
500RegisterContextPOSIX_x86::GetGPRSize()
501{
502    return m_register_info_ap->GetGPRSize ();
503}
504
505const RegisterInfo *
506RegisterContextPOSIX_x86::GetRegisterInfo()
507{
508    // Commonly, this method is overridden and g_register_infos is copied and specialized.
509    // So, use GetRegisterInfo() rather than g_register_infos in this scope.
510    return m_register_info_ap->GetRegisterInfo ();
511}
512
513const RegisterInfo *
514RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg)
515{
516    if (reg < m_reg_info.num_registers)
517        return &GetRegisterInfo()[reg];
518    else
519        return NULL;
520}
521
522size_t
523RegisterContextPOSIX_x86::GetRegisterSetCount()
524{
525    size_t sets = 0;
526    for (size_t set = 0; set < k_num_register_sets; ++set)
527    {
528        if (IsRegisterSetAvailable(set))
529            ++sets;
530    }
531
532    return sets;
533}
534
535const RegisterSet *
536RegisterContextPOSIX_x86::GetRegisterSet(size_t set)
537{
538    if (IsRegisterSetAvailable(set))
539    {
540        switch (m_register_info_ap->m_target_arch.GetCore())
541        {
542            case ArchSpec::eCore_x86_32_i386:
543            case ArchSpec::eCore_x86_32_i486:
544            case ArchSpec::eCore_x86_32_i486sx:
545                return &g_reg_sets_i386[set];
546            case ArchSpec::eCore_x86_64_x86_64:
547                return &g_reg_sets_x86_64[set];
548            default:
549                assert(false && "Unhandled target architecture.");
550                return NULL;
551        }
552    }
553    return NULL;
554}
555
556const char *
557RegisterContextPOSIX_x86::GetRegisterName(unsigned reg)
558{
559    assert(reg < m_reg_info.num_registers && "Invalid register offset.");
560    return GetRegisterInfo()[reg].name;
561}
562
563lldb::ByteOrder
564RegisterContextPOSIX_x86::GetByteOrder()
565{
566    // Get the target process whose privileged thread was used for the register read.
567    lldb::ByteOrder byte_order = eByteOrderInvalid;
568    Process *process = CalculateProcess().get();
569
570    if (process)
571        byte_order = process->GetByteOrder();
572    return byte_order;
573}
574
575// Parse ymm registers and into xmm.bytes and ymmh.bytes.
576bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
577{
578    if (!IsAVX(reg))
579        return false;
580
581    if (byte_order == eByteOrderLittle)
582    {
583        ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
584                 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
585                 sizeof(XMMReg));
586        ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
587                 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
588                 sizeof(YMMHReg));
589        return true;
590    }
591
592    if (byte_order == eByteOrderBig)
593    {
594        ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
595                 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
596                 sizeof(XMMReg));
597        ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
598                 m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
599                 sizeof(YMMHReg));
600        return true;
601    }
602    return false; // unsupported or invalid byte order
603}
604
605// Concatenate xmm.bytes with ymmh.bytes
606bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order)
607{
608    if (!IsAVX(reg))
609        return false;
610
611    if (byte_order == eByteOrderLittle)
612    {
613        ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
614                 m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
615                 sizeof(XMMReg));
616        ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
617                 m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
618                 sizeof(YMMHReg));
619        return true;
620    }
621
622    if (byte_order == eByteOrderBig)
623    {
624        ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
625                 m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
626                 sizeof(XMMReg));
627        ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
628                 m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
629                 sizeof(YMMHReg));
630        return true;
631    }
632    return false; // unsupported or invalid byte order
633}
634
635bool
636RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index)
637{
638    // Note: Extended register sets are assumed to be at the end of g_reg_sets...
639    size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
640
641    if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
642        ++num_sets;
643    return (set_index < num_sets);
644}
645
646
647// Used when parsing DWARF and EH frame information and any other
648// object file sections that contain register numbers in them.
649uint32_t
650RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(uint32_t kind,
651                                                                 uint32_t num)
652{
653    const uint32_t num_regs = GetRegisterCount();
654
655    assert (kind < kNumRegisterKinds);
656    for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
657    {
658        const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
659
660        if (reg_info->kinds[kind] == num)
661            return reg_idx;
662    }
663
664    return LLDB_INVALID_REGNUM;
665}
666
667