1*06c3fb27SDimitry Andric //===-- RegisterContextLinuxCore_x86_64.cpp -------------------------------===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric
9*06c3fb27SDimitry Andric #include "RegisterContextLinuxCore_x86_64.h"
10*06c3fb27SDimitry Andric #include "lldb/Target/Thread.h"
11*06c3fb27SDimitry Andric #include "lldb/Utility/DataExtractor.h"
12*06c3fb27SDimitry Andric #include "lldb/Utility/RegisterValue.h"
13*06c3fb27SDimitry Andric
14*06c3fb27SDimitry Andric using namespace lldb_private;
15*06c3fb27SDimitry Andric
16*06c3fb27SDimitry Andric const uint32_t g_gpr_regnums_i386[] = {
17*06c3fb27SDimitry Andric lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
18*06c3fb27SDimitry Andric lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
19*06c3fb27SDimitry Andric lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
20*06c3fb27SDimitry Andric lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
21*06c3fb27SDimitry Andric lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
22*06c3fb27SDimitry Andric lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
23*06c3fb27SDimitry Andric lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
24*06c3fb27SDimitry Andric lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
25*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM, // Register sets must be terminated with
26*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
27*06c3fb27SDimitry Andric };
28*06c3fb27SDimitry Andric static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
29*06c3fb27SDimitry Andric 1 ==
30*06c3fb27SDimitry Andric k_num_gpr_registers_i386,
31*06c3fb27SDimitry Andric "g_gpr_regnums_i386 has wrong number of register infos");
32*06c3fb27SDimitry Andric
33*06c3fb27SDimitry Andric const uint32_t g_lldb_regnums_i386[] = {
34*06c3fb27SDimitry Andric lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
35*06c3fb27SDimitry Andric lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
36*06c3fb27SDimitry Andric lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
37*06c3fb27SDimitry Andric lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
38*06c3fb27SDimitry Andric lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
39*06c3fb27SDimitry Andric lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
40*06c3fb27SDimitry Andric lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
41*06c3fb27SDimitry Andric lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
42*06c3fb27SDimitry Andric lldb_xmm6_i386, lldb_xmm7_i386,
43*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
44*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
45*06c3fb27SDimitry Andric };
46*06c3fb27SDimitry Andric static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
47*06c3fb27SDimitry Andric 1 ==
48*06c3fb27SDimitry Andric k_num_fpr_registers_i386,
49*06c3fb27SDimitry Andric "g_lldb_regnums_i386 has wrong number of register infos");
50*06c3fb27SDimitry Andric
51*06c3fb27SDimitry Andric const uint32_t g_avx_regnums_i386[] = {
52*06c3fb27SDimitry Andric lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
53*06c3fb27SDimitry Andric lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
54*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
55*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
56*06c3fb27SDimitry Andric };
57*06c3fb27SDimitry Andric static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
58*06c3fb27SDimitry Andric 1 ==
59*06c3fb27SDimitry Andric k_num_avx_registers_i386,
60*06c3fb27SDimitry Andric " g_avx_regnums_i386 has wrong number of register infos");
61*06c3fb27SDimitry Andric
62*06c3fb27SDimitry Andric static const uint32_t g_gpr_regnums_x86_64[] = {
63*06c3fb27SDimitry Andric x86_64_with_base::lldb_rax,
64*06c3fb27SDimitry Andric x86_64_with_base::lldb_rbx,
65*06c3fb27SDimitry Andric x86_64_with_base::lldb_rcx,
66*06c3fb27SDimitry Andric x86_64_with_base::lldb_rdx,
67*06c3fb27SDimitry Andric x86_64_with_base::lldb_rdi,
68*06c3fb27SDimitry Andric x86_64_with_base::lldb_rsi,
69*06c3fb27SDimitry Andric x86_64_with_base::lldb_rbp,
70*06c3fb27SDimitry Andric x86_64_with_base::lldb_rsp,
71*06c3fb27SDimitry Andric x86_64_with_base::lldb_r8,
72*06c3fb27SDimitry Andric x86_64_with_base::lldb_r9,
73*06c3fb27SDimitry Andric x86_64_with_base::lldb_r10,
74*06c3fb27SDimitry Andric x86_64_with_base::lldb_r11,
75*06c3fb27SDimitry Andric x86_64_with_base::lldb_r12,
76*06c3fb27SDimitry Andric x86_64_with_base::lldb_r13,
77*06c3fb27SDimitry Andric x86_64_with_base::lldb_r14,
78*06c3fb27SDimitry Andric x86_64_with_base::lldb_r15,
79*06c3fb27SDimitry Andric x86_64_with_base::lldb_rip,
80*06c3fb27SDimitry Andric x86_64_with_base::lldb_rflags,
81*06c3fb27SDimitry Andric x86_64_with_base::lldb_cs,
82*06c3fb27SDimitry Andric x86_64_with_base::lldb_fs,
83*06c3fb27SDimitry Andric x86_64_with_base::lldb_gs,
84*06c3fb27SDimitry Andric x86_64_with_base::lldb_ss,
85*06c3fb27SDimitry Andric x86_64_with_base::lldb_fs_base,
86*06c3fb27SDimitry Andric x86_64_with_base::lldb_gs_base,
87*06c3fb27SDimitry Andric x86_64_with_base::lldb_ds,
88*06c3fb27SDimitry Andric x86_64_with_base::lldb_es,
89*06c3fb27SDimitry Andric x86_64_with_base::lldb_eax,
90*06c3fb27SDimitry Andric x86_64_with_base::lldb_ebx,
91*06c3fb27SDimitry Andric x86_64_with_base::lldb_ecx,
92*06c3fb27SDimitry Andric x86_64_with_base::lldb_edx,
93*06c3fb27SDimitry Andric x86_64_with_base::lldb_edi,
94*06c3fb27SDimitry Andric x86_64_with_base::lldb_esi,
95*06c3fb27SDimitry Andric x86_64_with_base::lldb_ebp,
96*06c3fb27SDimitry Andric x86_64_with_base::lldb_esp,
97*06c3fb27SDimitry Andric x86_64_with_base::lldb_r8d, // Low 32 bits or r8
98*06c3fb27SDimitry Andric x86_64_with_base::lldb_r9d, // Low 32 bits or r9
99*06c3fb27SDimitry Andric x86_64_with_base::lldb_r10d, // Low 32 bits or r10
100*06c3fb27SDimitry Andric x86_64_with_base::lldb_r11d, // Low 32 bits or r11
101*06c3fb27SDimitry Andric x86_64_with_base::lldb_r12d, // Low 32 bits or r12
102*06c3fb27SDimitry Andric x86_64_with_base::lldb_r13d, // Low 32 bits or r13
103*06c3fb27SDimitry Andric x86_64_with_base::lldb_r14d, // Low 32 bits or r14
104*06c3fb27SDimitry Andric x86_64_with_base::lldb_r15d, // Low 32 bits or r15
105*06c3fb27SDimitry Andric x86_64_with_base::lldb_ax,
106*06c3fb27SDimitry Andric x86_64_with_base::lldb_bx,
107*06c3fb27SDimitry Andric x86_64_with_base::lldb_cx,
108*06c3fb27SDimitry Andric x86_64_with_base::lldb_dx,
109*06c3fb27SDimitry Andric x86_64_with_base::lldb_di,
110*06c3fb27SDimitry Andric x86_64_with_base::lldb_si,
111*06c3fb27SDimitry Andric x86_64_with_base::lldb_bp,
112*06c3fb27SDimitry Andric x86_64_with_base::lldb_sp,
113*06c3fb27SDimitry Andric x86_64_with_base::lldb_r8w, // Low 16 bits or r8
114*06c3fb27SDimitry Andric x86_64_with_base::lldb_r9w, // Low 16 bits or r9
115*06c3fb27SDimitry Andric x86_64_with_base::lldb_r10w, // Low 16 bits or r10
116*06c3fb27SDimitry Andric x86_64_with_base::lldb_r11w, // Low 16 bits or r11
117*06c3fb27SDimitry Andric x86_64_with_base::lldb_r12w, // Low 16 bits or r12
118*06c3fb27SDimitry Andric x86_64_with_base::lldb_r13w, // Low 16 bits or r13
119*06c3fb27SDimitry Andric x86_64_with_base::lldb_r14w, // Low 16 bits or r14
120*06c3fb27SDimitry Andric x86_64_with_base::lldb_r15w, // Low 16 bits or r15
121*06c3fb27SDimitry Andric x86_64_with_base::lldb_ah,
122*06c3fb27SDimitry Andric x86_64_with_base::lldb_bh,
123*06c3fb27SDimitry Andric x86_64_with_base::lldb_ch,
124*06c3fb27SDimitry Andric x86_64_with_base::lldb_dh,
125*06c3fb27SDimitry Andric x86_64_with_base::lldb_al,
126*06c3fb27SDimitry Andric x86_64_with_base::lldb_bl,
127*06c3fb27SDimitry Andric x86_64_with_base::lldb_cl,
128*06c3fb27SDimitry Andric x86_64_with_base::lldb_dl,
129*06c3fb27SDimitry Andric x86_64_with_base::lldb_dil,
130*06c3fb27SDimitry Andric x86_64_with_base::lldb_sil,
131*06c3fb27SDimitry Andric x86_64_with_base::lldb_bpl,
132*06c3fb27SDimitry Andric x86_64_with_base::lldb_spl,
133*06c3fb27SDimitry Andric x86_64_with_base::lldb_r8l, // Low 8 bits or r8
134*06c3fb27SDimitry Andric x86_64_with_base::lldb_r9l, // Low 8 bits or r9
135*06c3fb27SDimitry Andric x86_64_with_base::lldb_r10l, // Low 8 bits or r10
136*06c3fb27SDimitry Andric x86_64_with_base::lldb_r11l, // Low 8 bits or r11
137*06c3fb27SDimitry Andric x86_64_with_base::lldb_r12l, // Low 8 bits or r12
138*06c3fb27SDimitry Andric x86_64_with_base::lldb_r13l, // Low 8 bits or r13
139*06c3fb27SDimitry Andric x86_64_with_base::lldb_r14l, // Low 8 bits or r14
140*06c3fb27SDimitry Andric x86_64_with_base::lldb_r15l, // Low 8 bits or r15
141*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
142*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
143*06c3fb27SDimitry Andric };
144*06c3fb27SDimitry Andric static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
145*06c3fb27SDimitry Andric 1 ==
146*06c3fb27SDimitry Andric x86_64_with_base::k_num_gpr_registers,
147*06c3fb27SDimitry Andric "g_gpr_regnums_x86_64 has wrong number of register infos");
148*06c3fb27SDimitry Andric
149*06c3fb27SDimitry Andric static const uint32_t g_lldb_regnums_x86_64[] = {
150*06c3fb27SDimitry Andric x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat,
151*06c3fb27SDimitry Andric x86_64_with_base::lldb_ftag, x86_64_with_base::lldb_fop,
152*06c3fb27SDimitry Andric x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff,
153*06c3fb27SDimitry Andric x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg,
154*06c3fb27SDimitry Andric x86_64_with_base::lldb_fooff, x86_64_with_base::lldb_fdp,
155*06c3fb27SDimitry Andric x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask,
156*06c3fb27SDimitry Andric x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1,
157*06c3fb27SDimitry Andric x86_64_with_base::lldb_st2, x86_64_with_base::lldb_st3,
158*06c3fb27SDimitry Andric x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5,
159*06c3fb27SDimitry Andric x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7,
160*06c3fb27SDimitry Andric x86_64_with_base::lldb_mm0, x86_64_with_base::lldb_mm1,
161*06c3fb27SDimitry Andric x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3,
162*06c3fb27SDimitry Andric x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5,
163*06c3fb27SDimitry Andric x86_64_with_base::lldb_mm6, x86_64_with_base::lldb_mm7,
164*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1,
165*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3,
166*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm4, x86_64_with_base::lldb_xmm5,
167*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7,
168*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9,
169*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm10, x86_64_with_base::lldb_xmm11,
170*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13,
171*06c3fb27SDimitry Andric x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15,
172*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
173*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
174*06c3fb27SDimitry Andric };
175*06c3fb27SDimitry Andric static_assert(
176*06c3fb27SDimitry Andric (sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 ==
177*06c3fb27SDimitry Andric x86_64_with_base::k_num_fpr_registers,
178*06c3fb27SDimitry Andric "g_lldb_regnums_x86_64 has wrong number of register infos");
179*06c3fb27SDimitry Andric
180*06c3fb27SDimitry Andric static const uint32_t g_avx_regnums_x86_64[] = {
181*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1,
182*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3,
183*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5,
184*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7,
185*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9,
186*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11,
187*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13,
188*06c3fb27SDimitry Andric x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15,
189*06c3fb27SDimitry Andric LLDB_INVALID_REGNUM // Register sets must be terminated with
190*06c3fb27SDimitry Andric // LLDB_INVALID_REGNUM.
191*06c3fb27SDimitry Andric };
192*06c3fb27SDimitry Andric static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
193*06c3fb27SDimitry Andric 1 ==
194*06c3fb27SDimitry Andric x86_64_with_base::k_num_avx_registers,
195*06c3fb27SDimitry Andric "g_avx_regnums_x86_64 has wrong number of register infos");
196*06c3fb27SDimitry Andric
197*06c3fb27SDimitry Andric static const RegisterSet g_reg_sets_i386[] = {
198*06c3fb27SDimitry Andric {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
199*06c3fb27SDimitry Andric g_gpr_regnums_i386},
200*06c3fb27SDimitry Andric {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
201*06c3fb27SDimitry Andric g_lldb_regnums_i386},
202*06c3fb27SDimitry Andric {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
203*06c3fb27SDimitry Andric g_avx_regnums_i386}};
204*06c3fb27SDimitry Andric
205*06c3fb27SDimitry Andric static const RegisterSet g_reg_sets_x86_64[] = {
206*06c3fb27SDimitry Andric {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,
207*06c3fb27SDimitry Andric g_gpr_regnums_x86_64},
208*06c3fb27SDimitry Andric {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,
209*06c3fb27SDimitry Andric g_lldb_regnums_x86_64},
210*06c3fb27SDimitry Andric {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,
211*06c3fb27SDimitry Andric g_avx_regnums_x86_64}};
212*06c3fb27SDimitry Andric
RegisterContextLinuxCore_x86_64(Thread & thread,RegisterInfoInterface * register_info,const DataExtractor & gpregset,llvm::ArrayRef<CoreNote> notes)213*06c3fb27SDimitry Andric RegisterContextLinuxCore_x86_64::RegisterContextLinuxCore_x86_64(
214*06c3fb27SDimitry Andric Thread &thread, RegisterInfoInterface *register_info,
215*06c3fb27SDimitry Andric const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
216*06c3fb27SDimitry Andric : RegisterContextCorePOSIX_x86_64(thread, register_info, gpregset, notes) {}
217*06c3fb27SDimitry Andric
GetRegisterSet(size_t set)218*06c3fb27SDimitry Andric const RegisterSet *RegisterContextLinuxCore_x86_64::GetRegisterSet(size_t set) {
219*06c3fb27SDimitry Andric if (IsRegisterSetAvailable(set)) {
220*06c3fb27SDimitry Andric switch (m_register_info_up->GetTargetArchitecture().GetMachine()) {
221*06c3fb27SDimitry Andric case llvm::Triple::x86:
222*06c3fb27SDimitry Andric return &g_reg_sets_i386[set];
223*06c3fb27SDimitry Andric case llvm::Triple::x86_64:
224*06c3fb27SDimitry Andric return &g_reg_sets_x86_64[set];
225*06c3fb27SDimitry Andric default:
226*06c3fb27SDimitry Andric assert(false && "Unhandled target architecture.");
227*06c3fb27SDimitry Andric return nullptr;
228*06c3fb27SDimitry Andric }
229*06c3fb27SDimitry Andric }
230*06c3fb27SDimitry Andric return nullptr;
231*06c3fb27SDimitry Andric }
232*06c3fb27SDimitry Andric
GetRegInfo()233*06c3fb27SDimitry Andric RegInfo &RegisterContextLinuxCore_x86_64::GetRegInfo() {
234*06c3fb27SDimitry Andric return GetRegInfoShared(
235*06c3fb27SDimitry Andric m_register_info_up->GetTargetArchitecture().GetMachine(),
236*06c3fb27SDimitry Andric /*with_base=*/true);
237*06c3fb27SDimitry Andric }
238