10127ef0fSEd Maste //===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
20127ef0fSEd Maste //
30127ef0fSEd Maste // The LLVM Compiler Infrastructure
40127ef0fSEd Maste //
50127ef0fSEd Maste // This file is distributed under the University of Illinois Open Source
60127ef0fSEd Maste // License. See LICENSE.TXT for details.
70127ef0fSEd Maste //
80127ef0fSEd Maste //===----------------------------------------------------------------------===//
90127ef0fSEd Maste
100127ef0fSEd Maste #include <cstring>
110127ef0fSEd Maste #include <errno.h>
120127ef0fSEd Maste #include <stdint.h>
130127ef0fSEd Maste
14f678e45dSDimitry Andric #include "lldb/Target/Process.h"
150127ef0fSEd Maste #include "lldb/Target/Target.h"
160127ef0fSEd Maste #include "lldb/Target/Thread.h"
17f678e45dSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
18f678e45dSDimitry Andric #include "lldb/Utility/DataExtractor.h"
19f678e45dSDimitry Andric #include "lldb/Utility/Endian.h"
20*b5893f02SDimitry Andric #include "lldb/Utility/RegisterValue.h"
21*b5893f02SDimitry Andric #include "lldb/Utility/Scalar.h"
220127ef0fSEd Maste #include "llvm/Support/Compiler.h"
230127ef0fSEd Maste
240127ef0fSEd Maste #include "RegisterContextPOSIX_x86.h"
25435933ddSDimitry Andric #include "RegisterContext_x86.h"
260127ef0fSEd Maste
270127ef0fSEd Maste using namespace lldb_private;
280127ef0fSEd Maste using namespace lldb;
290127ef0fSEd Maste
30435933ddSDimitry Andric const uint32_t g_gpr_regnums_i386[] = {
31435933ddSDimitry Andric lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
32435933ddSDimitry Andric lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
33435933ddSDimitry Andric lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
34435933ddSDimitry Andric lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
35435933ddSDimitry Andric lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
36435933ddSDimitry Andric lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
37435933ddSDimitry Andric lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
38435933ddSDimitry Andric lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
39435933ddSDimitry Andric LLDB_INVALID_REGNUM, // Register sets must be terminated with
40435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
410127ef0fSEd Maste };
42435933ddSDimitry Andric static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
43435933ddSDimitry Andric 1 ==
44435933ddSDimitry Andric k_num_gpr_registers_i386,
450127ef0fSEd Maste "g_gpr_regnums_i386 has wrong number of register infos");
460127ef0fSEd Maste
47435933ddSDimitry Andric const uint32_t g_lldb_regnums_i386[] = {
48435933ddSDimitry Andric lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
49435933ddSDimitry Andric lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
50435933ddSDimitry Andric lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
51435933ddSDimitry Andric lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
52435933ddSDimitry Andric lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
53435933ddSDimitry Andric lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
54435933ddSDimitry Andric lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
55435933ddSDimitry Andric lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
56435933ddSDimitry Andric lldb_xmm6_i386, lldb_xmm7_i386,
57435933ddSDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
58435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
590127ef0fSEd Maste };
60435933ddSDimitry Andric static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
61435933ddSDimitry Andric 1 ==
62435933ddSDimitry Andric k_num_fpr_registers_i386,
637aa51b79SEd Maste "g_lldb_regnums_i386 has wrong number of register infos");
640127ef0fSEd Maste
65435933ddSDimitry Andric const uint32_t g_avx_regnums_i386[] = {
66435933ddSDimitry Andric lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
67435933ddSDimitry Andric lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
68435933ddSDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
69435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
700127ef0fSEd Maste };
71435933ddSDimitry Andric static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
72435933ddSDimitry Andric 1 ==
73435933ddSDimitry Andric k_num_avx_registers_i386,
740127ef0fSEd Maste " g_avx_regnums_i386 has wrong number of register infos");
750127ef0fSEd Maste
76435933ddSDimitry Andric static const uint32_t g_gpr_regnums_x86_64[] = {
77435933ddSDimitry Andric lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
78435933ddSDimitry Andric lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
79435933ddSDimitry Andric lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
80435933ddSDimitry Andric lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
81435933ddSDimitry Andric lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
82435933ddSDimitry Andric lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
83435933ddSDimitry Andric lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
84435933ddSDimitry Andric lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
857aa51b79SEd Maste lldb_r8d_x86_64, // Low 32 bits or r8
867aa51b79SEd Maste lldb_r9d_x86_64, // Low 32 bits or r9
877aa51b79SEd Maste lldb_r10d_x86_64, // Low 32 bits or r10
887aa51b79SEd Maste lldb_r11d_x86_64, // Low 32 bits or r11
897aa51b79SEd Maste lldb_r12d_x86_64, // Low 32 bits or r12
907aa51b79SEd Maste lldb_r13d_x86_64, // Low 32 bits or r13
917aa51b79SEd Maste lldb_r14d_x86_64, // Low 32 bits or r14
927aa51b79SEd Maste lldb_r15d_x86_64, // Low 32 bits or r15
93435933ddSDimitry Andric lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
94435933ddSDimitry Andric lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
957aa51b79SEd Maste lldb_r8w_x86_64, // Low 16 bits or r8
967aa51b79SEd Maste lldb_r9w_x86_64, // Low 16 bits or r9
977aa51b79SEd Maste lldb_r10w_x86_64, // Low 16 bits or r10
987aa51b79SEd Maste lldb_r11w_x86_64, // Low 16 bits or r11
997aa51b79SEd Maste lldb_r12w_x86_64, // Low 16 bits or r12
1007aa51b79SEd Maste lldb_r13w_x86_64, // Low 16 bits or r13
1017aa51b79SEd Maste lldb_r14w_x86_64, // Low 16 bits or r14
1027aa51b79SEd Maste lldb_r15w_x86_64, // Low 16 bits or r15
103435933ddSDimitry Andric lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
104435933ddSDimitry Andric lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
105435933ddSDimitry Andric lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
1067aa51b79SEd Maste lldb_r8l_x86_64, // Low 8 bits or r8
1077aa51b79SEd Maste lldb_r9l_x86_64, // Low 8 bits or r9
1087aa51b79SEd Maste lldb_r10l_x86_64, // Low 8 bits or r10
1097aa51b79SEd Maste lldb_r11l_x86_64, // Low 8 bits or r11
1107aa51b79SEd Maste lldb_r12l_x86_64, // Low 8 bits or r12
1117aa51b79SEd Maste lldb_r13l_x86_64, // Low 8 bits or r13
1127aa51b79SEd Maste lldb_r14l_x86_64, // Low 8 bits or r14
1137aa51b79SEd Maste lldb_r15l_x86_64, // Low 8 bits or r15
114435933ddSDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
115435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
1160127ef0fSEd Maste };
117435933ddSDimitry Andric static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
118435933ddSDimitry Andric 1 ==
119435933ddSDimitry Andric k_num_gpr_registers_x86_64,
1200127ef0fSEd Maste "g_gpr_regnums_x86_64 has wrong number of register infos");
1210127ef0fSEd Maste
122435933ddSDimitry Andric static const uint32_t g_lldb_regnums_x86_64[] = {
123435933ddSDimitry Andric lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
124435933ddSDimitry Andric lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
125435933ddSDimitry Andric lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
126435933ddSDimitry Andric lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
127435933ddSDimitry Andric lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
128435933ddSDimitry Andric lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
129435933ddSDimitry Andric lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
130435933ddSDimitry Andric lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
131435933ddSDimitry Andric lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
132435933ddSDimitry Andric lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
133435933ddSDimitry Andric lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
134435933ddSDimitry Andric lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
135435933ddSDimitry Andric lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
136435933ddSDimitry Andric lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
137435933ddSDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
138435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
1390127ef0fSEd Maste };
140435933ddSDimitry Andric static_assert((sizeof(g_lldb_regnums_x86_64) /
141435933ddSDimitry Andric sizeof(g_lldb_regnums_x86_64[0])) -
142435933ddSDimitry Andric 1 ==
143435933ddSDimitry Andric k_num_fpr_registers_x86_64,
1447aa51b79SEd Maste "g_lldb_regnums_x86_64 has wrong number of register infos");
1450127ef0fSEd Maste
146435933ddSDimitry Andric static const uint32_t g_avx_regnums_x86_64[] = {
147435933ddSDimitry Andric lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
148435933ddSDimitry Andric lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
149435933ddSDimitry Andric lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
150435933ddSDimitry Andric lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
151435933ddSDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
152435933ddSDimitry Andric // LLDB_INVALID_REGNUM.
1530127ef0fSEd Maste };
154435933ddSDimitry Andric static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
155435933ddSDimitry Andric 1 ==
156435933ddSDimitry Andric k_num_avx_registers_x86_64,
1570127ef0fSEd Maste "g_avx_regnums_x86_64 has wrong number of register infos");
1580127ef0fSEd Maste
159435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = {lldb_eax_i386,
160435933ddSDimitry Andric LLDB_INVALID_REGNUM};
161435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = {lldb_ebx_i386,
162435933ddSDimitry Andric LLDB_INVALID_REGNUM};
163435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = {lldb_ecx_i386,
164435933ddSDimitry Andric LLDB_INVALID_REGNUM};
165435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = {lldb_edx_i386,
166435933ddSDimitry Andric LLDB_INVALID_REGNUM};
167435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = {lldb_edi_i386,
168435933ddSDimitry Andric LLDB_INVALID_REGNUM};
169435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = {lldb_esi_i386,
170435933ddSDimitry Andric LLDB_INVALID_REGNUM};
171435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = {lldb_ebp_i386,
172435933ddSDimitry Andric LLDB_INVALID_REGNUM};
173435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = {lldb_esp_i386,
174435933ddSDimitry Andric LLDB_INVALID_REGNUM};
1750127ef0fSEd Maste
176435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = {
177435933ddSDimitry Andric lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386,
178435933ddSDimitry Andric LLDB_INVALID_REGNUM};
179435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = {
180435933ddSDimitry Andric lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386,
181435933ddSDimitry Andric LLDB_INVALID_REGNUM};
182435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = {
183435933ddSDimitry Andric lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386,
184435933ddSDimitry Andric LLDB_INVALID_REGNUM};
185435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = {
186435933ddSDimitry Andric lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386,
187435933ddSDimitry Andric LLDB_INVALID_REGNUM};
188435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = {
189435933ddSDimitry Andric lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM};
190435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = {
191435933ddSDimitry Andric lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM};
192435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = {
193435933ddSDimitry Andric lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM};
194435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = {
195435933ddSDimitry Andric lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM};
1960127ef0fSEd Maste
197435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = {lldb_rax_x86_64,
198435933ddSDimitry Andric LLDB_INVALID_REGNUM};
199435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = {lldb_rbx_x86_64,
200435933ddSDimitry Andric LLDB_INVALID_REGNUM};
201435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = {lldb_rcx_x86_64,
202435933ddSDimitry Andric LLDB_INVALID_REGNUM};
203435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = {lldb_rdx_x86_64,
204435933ddSDimitry Andric LLDB_INVALID_REGNUM};
205435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = {lldb_rdi_x86_64,
206435933ddSDimitry Andric LLDB_INVALID_REGNUM};
207435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = {lldb_rsi_x86_64,
208435933ddSDimitry Andric LLDB_INVALID_REGNUM};
209435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = {lldb_rbp_x86_64,
210435933ddSDimitry Andric LLDB_INVALID_REGNUM};
211435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = {lldb_rsp_x86_64,
212435933ddSDimitry Andric LLDB_INVALID_REGNUM};
213435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = {lldb_r8_x86_64,
214435933ddSDimitry Andric LLDB_INVALID_REGNUM};
215435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = {lldb_r9_x86_64,
216435933ddSDimitry Andric LLDB_INVALID_REGNUM};
217435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = {lldb_r10_x86_64,
218435933ddSDimitry Andric LLDB_INVALID_REGNUM};
219435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = {lldb_r11_x86_64,
220435933ddSDimitry Andric LLDB_INVALID_REGNUM};
221435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = {lldb_r12_x86_64,
222435933ddSDimitry Andric LLDB_INVALID_REGNUM};
223435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = {lldb_r13_x86_64,
224435933ddSDimitry Andric LLDB_INVALID_REGNUM};
225435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = {lldb_r14_x86_64,
226435933ddSDimitry Andric LLDB_INVALID_REGNUM};
227435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = {lldb_r15_x86_64,
228435933ddSDimitry Andric LLDB_INVALID_REGNUM};
2290127ef0fSEd Maste
230435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = {
231435933ddSDimitry Andric lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64,
232435933ddSDimitry Andric lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM};
233435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = {
234435933ddSDimitry Andric lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64,
235435933ddSDimitry Andric lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM};
236435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = {
237435933ddSDimitry Andric lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64,
238435933ddSDimitry Andric lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM};
239435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = {
240435933ddSDimitry Andric lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64,
241435933ddSDimitry Andric lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM};
242435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = {
243435933ddSDimitry Andric lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64,
244435933ddSDimitry Andric LLDB_INVALID_REGNUM};
245435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = {
246435933ddSDimitry Andric lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64,
247435933ddSDimitry Andric LLDB_INVALID_REGNUM};
248435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = {
249435933ddSDimitry Andric lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64,
250435933ddSDimitry Andric LLDB_INVALID_REGNUM};
251435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = {
252435933ddSDimitry Andric lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64,
253435933ddSDimitry Andric LLDB_INVALID_REGNUM};
254435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = {
255435933ddSDimitry Andric lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64,
256435933ddSDimitry Andric LLDB_INVALID_REGNUM};
257435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = {
258435933ddSDimitry Andric lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64,
259435933ddSDimitry Andric LLDB_INVALID_REGNUM};
260435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = {
261435933ddSDimitry Andric lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64,
262435933ddSDimitry Andric LLDB_INVALID_REGNUM};
263435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = {
264435933ddSDimitry Andric lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64,
265435933ddSDimitry Andric LLDB_INVALID_REGNUM};
266435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = {
267435933ddSDimitry Andric lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64,
268435933ddSDimitry Andric LLDB_INVALID_REGNUM};
269435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = {
270435933ddSDimitry Andric lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64,
271435933ddSDimitry Andric LLDB_INVALID_REGNUM};
272435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = {
273435933ddSDimitry Andric lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64,
274435933ddSDimitry Andric LLDB_INVALID_REGNUM};
275435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
276435933ddSDimitry Andric lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
277435933ddSDimitry Andric LLDB_INVALID_REGNUM};
2780127ef0fSEd Maste
2790127ef0fSEd Maste // Number of register sets provided by this context.
280435933ddSDimitry Andric enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
2810127ef0fSEd Maste
282435933ddSDimitry Andric static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
283435933ddSDimitry Andric {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
284435933ddSDimitry Andric g_gpr_regnums_i386},
285435933ddSDimitry Andric {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
286435933ddSDimitry Andric g_lldb_regnums_i386},
287435933ddSDimitry Andric {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
288435933ddSDimitry Andric g_avx_regnums_i386}};
2890127ef0fSEd Maste
290435933ddSDimitry Andric static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
291435933ddSDimitry Andric {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
292435933ddSDimitry Andric g_gpr_regnums_x86_64},
293435933ddSDimitry Andric {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
294435933ddSDimitry Andric g_lldb_regnums_x86_64},
295435933ddSDimitry Andric {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
296435933ddSDimitry Andric g_avx_regnums_x86_64}};
2970127ef0fSEd Maste
IsGPR(unsigned reg)298435933ddSDimitry Andric bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) {
2990127ef0fSEd Maste return reg <= m_reg_info.last_gpr; // GPR's come first.
3000127ef0fSEd Maste }
3010127ef0fSEd Maste
IsFPR(unsigned reg)302435933ddSDimitry Andric bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) {
3030127ef0fSEd Maste return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
3040127ef0fSEd Maste }
3050127ef0fSEd Maste
IsAVX(unsigned reg)306435933ddSDimitry Andric bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) {
3070127ef0fSEd Maste return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
3080127ef0fSEd Maste }
3090127ef0fSEd Maste
IsFPR(unsigned reg,FPRType fpr_type)310435933ddSDimitry Andric bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) {
3110127ef0fSEd Maste bool generic_fpr = IsFPR(reg);
3120127ef0fSEd Maste
3130127ef0fSEd Maste if (fpr_type == eXSAVE)
3140127ef0fSEd Maste return generic_fpr || IsAVX(reg);
3150127ef0fSEd Maste return generic_fpr;
3160127ef0fSEd Maste }
3170127ef0fSEd Maste
RegisterContextPOSIX_x86(Thread & thread,uint32_t concrete_frame_idx,RegisterInfoInterface * register_info)318435933ddSDimitry Andric RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
319435933ddSDimitry Andric Thread &thread, uint32_t concrete_frame_idx,
3200127ef0fSEd Maste RegisterInfoInterface *register_info)
321435933ddSDimitry Andric : RegisterContext(thread, concrete_frame_idx) {
3220127ef0fSEd Maste m_register_info_ap.reset(register_info);
3230127ef0fSEd Maste
324435933ddSDimitry Andric switch (register_info->m_target_arch.GetMachine()) {
3250127ef0fSEd Maste case llvm::Triple::x86:
3260127ef0fSEd Maste m_reg_info.num_registers = k_num_registers_i386;
3270127ef0fSEd Maste m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
3280127ef0fSEd Maste m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
3290127ef0fSEd Maste m_reg_info.num_avx_registers = k_num_avx_registers_i386;
3300127ef0fSEd Maste m_reg_info.last_gpr = k_last_gpr_i386;
3310127ef0fSEd Maste m_reg_info.first_fpr = k_first_fpr_i386;
3320127ef0fSEd Maste m_reg_info.last_fpr = k_last_fpr_i386;
3337aa51b79SEd Maste m_reg_info.first_st = lldb_st0_i386;
3347aa51b79SEd Maste m_reg_info.last_st = lldb_st7_i386;
3357aa51b79SEd Maste m_reg_info.first_mm = lldb_mm0_i386;
3367aa51b79SEd Maste m_reg_info.last_mm = lldb_mm7_i386;
3377aa51b79SEd Maste m_reg_info.first_xmm = lldb_xmm0_i386;
3387aa51b79SEd Maste m_reg_info.last_xmm = lldb_xmm7_i386;
3397aa51b79SEd Maste m_reg_info.first_ymm = lldb_ymm0_i386;
3407aa51b79SEd Maste m_reg_info.last_ymm = lldb_ymm7_i386;
3417aa51b79SEd Maste m_reg_info.first_dr = lldb_dr0_i386;
3427aa51b79SEd Maste m_reg_info.gpr_flags = lldb_eflags_i386;
3430127ef0fSEd Maste break;
3440127ef0fSEd Maste case llvm::Triple::x86_64:
3450127ef0fSEd Maste m_reg_info.num_registers = k_num_registers_x86_64;
3460127ef0fSEd Maste m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
3470127ef0fSEd Maste m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
3480127ef0fSEd Maste m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
3490127ef0fSEd Maste m_reg_info.last_gpr = k_last_gpr_x86_64;
3500127ef0fSEd Maste m_reg_info.first_fpr = k_first_fpr_x86_64;
3510127ef0fSEd Maste m_reg_info.last_fpr = k_last_fpr_x86_64;
3527aa51b79SEd Maste m_reg_info.first_st = lldb_st0_x86_64;
3537aa51b79SEd Maste m_reg_info.last_st = lldb_st7_x86_64;
3547aa51b79SEd Maste m_reg_info.first_mm = lldb_mm0_x86_64;
3557aa51b79SEd Maste m_reg_info.last_mm = lldb_mm7_x86_64;
3567aa51b79SEd Maste m_reg_info.first_xmm = lldb_xmm0_x86_64;
3577aa51b79SEd Maste m_reg_info.last_xmm = lldb_xmm15_x86_64;
3587aa51b79SEd Maste m_reg_info.first_ymm = lldb_ymm0_x86_64;
3597aa51b79SEd Maste m_reg_info.last_ymm = lldb_ymm15_x86_64;
3607aa51b79SEd Maste m_reg_info.first_dr = lldb_dr0_x86_64;
3617aa51b79SEd Maste m_reg_info.gpr_flags = lldb_rflags_x86_64;
3620127ef0fSEd Maste break;
3630127ef0fSEd Maste default:
3640127ef0fSEd Maste assert(false && "Unhandled target architecture.");
3650127ef0fSEd Maste break;
3660127ef0fSEd Maste }
3670127ef0fSEd Maste
3680127ef0fSEd Maste ::memset(&m_fpr, 0, sizeof(FPR));
3690127ef0fSEd Maste
3700127ef0fSEd Maste m_fpr_type = eNotValid;
3710127ef0fSEd Maste }
3720127ef0fSEd Maste
~RegisterContextPOSIX_x86()373435933ddSDimitry Andric RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {}
3740127ef0fSEd Maste
GetFPRType()375435933ddSDimitry Andric RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
376435933ddSDimitry Andric if (m_fpr_type == eNotValid) {
3770127ef0fSEd Maste // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
3780127ef0fSEd Maste m_fpr_type = eXSAVE; // extended floating-point registers, if available
379*b5893f02SDimitry Andric if (!ReadFPR())
3800127ef0fSEd Maste m_fpr_type = eFXSAVE; // assume generic floating-point registers
3810127ef0fSEd Maste }
3820127ef0fSEd Maste return m_fpr_type;
3830127ef0fSEd Maste }
3840127ef0fSEd Maste
Invalidate()385435933ddSDimitry Andric void RegisterContextPOSIX_x86::Invalidate() {}
3860127ef0fSEd Maste
InvalidateAllRegisters()387435933ddSDimitry Andric void RegisterContextPOSIX_x86::InvalidateAllRegisters() {}
3880127ef0fSEd Maste
GetRegisterOffset(unsigned reg)389435933ddSDimitry Andric unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) {
3900127ef0fSEd Maste assert(reg < m_reg_info.num_registers && "Invalid register number.");
3910127ef0fSEd Maste return GetRegisterInfo()[reg].byte_offset;
3920127ef0fSEd Maste }
3930127ef0fSEd Maste
GetRegisterSize(unsigned reg)394435933ddSDimitry Andric unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) {
3950127ef0fSEd Maste assert(reg < m_reg_info.num_registers && "Invalid register number.");
3960127ef0fSEd Maste return GetRegisterInfo()[reg].byte_size;
3970127ef0fSEd Maste }
3980127ef0fSEd Maste
GetRegisterCount()399435933ddSDimitry Andric size_t RegisterContextPOSIX_x86::GetRegisterCount() {
400435933ddSDimitry Andric size_t num_registers =
401435933ddSDimitry Andric m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
4020127ef0fSEd Maste if (GetFPRType() == eXSAVE)
4030127ef0fSEd Maste return num_registers + m_reg_info.num_avx_registers;
4040127ef0fSEd Maste return num_registers;
4050127ef0fSEd Maste }
4060127ef0fSEd Maste
GetGPRSize()407435933ddSDimitry Andric size_t RegisterContextPOSIX_x86::GetGPRSize() {
4080127ef0fSEd Maste return m_register_info_ap->GetGPRSize();
4090127ef0fSEd Maste }
4100127ef0fSEd Maste
GetFXSAVEOffset()411435933ddSDimitry Andric size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
412435933ddSDimitry Andric return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset;
413435933ddSDimitry Andric }
414435933ddSDimitry Andric
GetRegisterInfo()415435933ddSDimitry Andric const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
416435933ddSDimitry Andric // Commonly, this method is overridden and g_register_infos is copied and
4174ba319b5SDimitry Andric // specialized. So, use GetRegisterInfo() rather than g_register_infos in
4184ba319b5SDimitry Andric // this scope.
4190127ef0fSEd Maste return m_register_info_ap->GetRegisterInfo();
4200127ef0fSEd Maste }
4210127ef0fSEd Maste
4220127ef0fSEd Maste const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)423435933ddSDimitry Andric RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) {
4240127ef0fSEd Maste if (reg < m_reg_info.num_registers)
4250127ef0fSEd Maste return &GetRegisterInfo()[reg];
4260127ef0fSEd Maste else
4270127ef0fSEd Maste return NULL;
4280127ef0fSEd Maste }
4290127ef0fSEd Maste
GetRegisterSetCount()430435933ddSDimitry Andric size_t RegisterContextPOSIX_x86::GetRegisterSetCount() {
4310127ef0fSEd Maste size_t sets = 0;
432435933ddSDimitry Andric for (size_t set = 0; set < k_num_register_sets; ++set) {
4330127ef0fSEd Maste if (IsRegisterSetAvailable(set))
4340127ef0fSEd Maste ++sets;
4350127ef0fSEd Maste }
4360127ef0fSEd Maste
4370127ef0fSEd Maste return sets;
4380127ef0fSEd Maste }
4390127ef0fSEd Maste
GetRegisterSet(size_t set)440435933ddSDimitry Andric const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) {
441435933ddSDimitry Andric if (IsRegisterSetAvailable(set)) {
442435933ddSDimitry Andric switch (m_register_info_ap->m_target_arch.GetMachine()) {
4430127ef0fSEd Maste case llvm::Triple::x86:
4440127ef0fSEd Maste return &g_reg_sets_i386[set];
4450127ef0fSEd Maste case llvm::Triple::x86_64:
4460127ef0fSEd Maste return &g_reg_sets_x86_64[set];
4470127ef0fSEd Maste default:
4480127ef0fSEd Maste assert(false && "Unhandled target architecture.");
4490127ef0fSEd Maste return NULL;
4500127ef0fSEd Maste }
4510127ef0fSEd Maste }
4520127ef0fSEd Maste return NULL;
4530127ef0fSEd Maste }
4540127ef0fSEd Maste
GetRegisterName(unsigned reg)455435933ddSDimitry Andric const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) {
4560127ef0fSEd Maste assert(reg < m_reg_info.num_registers && "Invalid register offset.");
4570127ef0fSEd Maste return GetRegisterInfo()[reg].name;
4580127ef0fSEd Maste }
4590127ef0fSEd Maste
GetByteOrder()460435933ddSDimitry Andric lldb::ByteOrder RegisterContextPOSIX_x86::GetByteOrder() {
461435933ddSDimitry Andric // Get the target process whose privileged thread was used for the register
462435933ddSDimitry Andric // read.
4630127ef0fSEd Maste lldb::ByteOrder byte_order = eByteOrderInvalid;
4640127ef0fSEd Maste Process *process = CalculateProcess().get();
4650127ef0fSEd Maste
4660127ef0fSEd Maste if (process)
4670127ef0fSEd Maste byte_order = process->GetByteOrder();
4680127ef0fSEd Maste return byte_order;
4690127ef0fSEd Maste }
4700127ef0fSEd Maste
4710127ef0fSEd Maste // Parse ymm registers and into xmm.bytes and ymmh.bytes.
CopyYMMtoXSTATE(uint32_t reg,lldb::ByteOrder byte_order)472435933ddSDimitry Andric bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
473435933ddSDimitry Andric lldb::ByteOrder byte_order) {
4740127ef0fSEd Maste if (!IsAVX(reg))
4750127ef0fSEd Maste return false;
4760127ef0fSEd Maste
477435933ddSDimitry Andric if (byte_order == eByteOrderLittle) {
478acac075bSDimitry Andric ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
479435933ddSDimitry Andric m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
480acac075bSDimitry Andric ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
4810127ef0fSEd Maste m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
4820127ef0fSEd Maste sizeof(YMMHReg));
4830127ef0fSEd Maste return true;
4840127ef0fSEd Maste }
4850127ef0fSEd Maste
486435933ddSDimitry Andric if (byte_order == eByteOrderBig) {
487acac075bSDimitry Andric ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
4880127ef0fSEd Maste m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
4890127ef0fSEd Maste sizeof(XMMReg));
490acac075bSDimitry Andric ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
491435933ddSDimitry Andric m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
4920127ef0fSEd Maste return true;
4930127ef0fSEd Maste }
4940127ef0fSEd Maste return false; // unsupported or invalid byte order
4950127ef0fSEd Maste }
4960127ef0fSEd Maste
4970127ef0fSEd Maste // Concatenate xmm.bytes with ymmh.bytes
CopyXSTATEtoYMM(uint32_t reg,lldb::ByteOrder byte_order)498435933ddSDimitry Andric bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
499435933ddSDimitry Andric lldb::ByteOrder byte_order) {
5000127ef0fSEd Maste if (!IsAVX(reg))
5010127ef0fSEd Maste return false;
5020127ef0fSEd Maste
503435933ddSDimitry Andric if (byte_order == eByteOrderLittle) {
5040127ef0fSEd Maste ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
505acac075bSDimitry Andric m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
5060127ef0fSEd Maste sizeof(XMMReg));
5070127ef0fSEd Maste ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
508acac075bSDimitry Andric m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
5090127ef0fSEd Maste sizeof(YMMHReg));
5100127ef0fSEd Maste return true;
5110127ef0fSEd Maste }
5120127ef0fSEd Maste
513435933ddSDimitry Andric if (byte_order == eByteOrderBig) {
5140127ef0fSEd Maste ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
515acac075bSDimitry Andric m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
5160127ef0fSEd Maste sizeof(XMMReg));
5170127ef0fSEd Maste ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
518acac075bSDimitry Andric m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
5190127ef0fSEd Maste sizeof(YMMHReg));
5200127ef0fSEd Maste return true;
5210127ef0fSEd Maste }
5220127ef0fSEd Maste return false; // unsupported or invalid byte order
5230127ef0fSEd Maste }
5240127ef0fSEd Maste
IsRegisterSetAvailable(size_t set_index)525435933ddSDimitry Andric bool RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index) {
5260127ef0fSEd Maste // Note: Extended register sets are assumed to be at the end of g_reg_sets...
5270127ef0fSEd Maste size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
5280127ef0fSEd Maste
5290127ef0fSEd Maste if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
5300127ef0fSEd Maste ++num_sets;
5310127ef0fSEd Maste return (set_index < num_sets);
5320127ef0fSEd Maste }
5330127ef0fSEd Maste
5344ba319b5SDimitry Andric // Used when parsing DWARF and EH frame information and any other object file
5354ba319b5SDimitry Andric // sections that contain register numbers in them.
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t num)536435933ddSDimitry Andric uint32_t RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(
537435933ddSDimitry Andric lldb::RegisterKind kind, uint32_t num) {
5380127ef0fSEd Maste const uint32_t num_regs = GetRegisterCount();
5390127ef0fSEd Maste
5400127ef0fSEd Maste assert(kind < kNumRegisterKinds);
541435933ddSDimitry Andric for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
5420127ef0fSEd Maste const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
5430127ef0fSEd Maste
5440127ef0fSEd Maste if (reg_info->kinds[kind] == num)
5450127ef0fSEd Maste return reg_idx;
5460127ef0fSEd Maste }
5470127ef0fSEd Maste
5480127ef0fSEd Maste return LLDB_INVALID_REGNUM;
5490127ef0fSEd Maste }
550