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

source code of lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp