1 //===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===//
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 #ifndef liblldb_RegisterContext_x86_H_
10 #define liblldb_RegisterContext_x86_H_
11
12 #include <cstddef>
13 #include <cstdint>
14
15 #include "llvm/ADT/BitmaskEnum.h"
16 #include "llvm/Support/Compiler.h"
17
18 namespace lldb_private {
19 // i386 ehframe, dwarf regnums
20
21 // Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems
22 // (non-Darwin)
23 //
24 enum {
25 ehframe_eax_i386 = 0,
26 ehframe_ecx_i386,
27 ehframe_edx_i386,
28 ehframe_ebx_i386,
29
30 // on Darwin esp & ebp are reversed in the eh_frame section for i386 (versus
31 // dwarf's reg numbering).
32 // To be specific:
33 // i386+darwin eh_frame: 4 is ebp, 5 is esp
34 // i386+everyone else eh_frame: 4 is esp, 5 is ebp
35 // i386 dwarf: 4 is esp, 5 is ebp
36 // lldb will get the darwin-specific eh_frame reg numberings from debugserver,
37 // or the ABI, so we
38 // only encode the generally correct 4 == esp, 5 == ebp numbers in this
39 // generic header.
40
41 ehframe_esp_i386,
42 ehframe_ebp_i386,
43 ehframe_esi_i386,
44 ehframe_edi_i386,
45 ehframe_eip_i386,
46 ehframe_eflags_i386,
47 ehframe_st0_i386 = 12,
48 ehframe_st1_i386,
49 ehframe_st2_i386,
50 ehframe_st3_i386,
51 ehframe_st4_i386,
52 ehframe_st5_i386,
53 ehframe_st6_i386,
54 ehframe_st7_i386,
55 ehframe_xmm0_i386 = 21,
56 ehframe_xmm1_i386,
57 ehframe_xmm2_i386,
58 ehframe_xmm3_i386,
59 ehframe_xmm4_i386,
60 ehframe_xmm5_i386,
61 ehframe_xmm6_i386,
62 ehframe_xmm7_i386,
63 ehframe_mm0_i386 = 29,
64 ehframe_mm1_i386,
65 ehframe_mm2_i386,
66 ehframe_mm3_i386,
67 ehframe_mm4_i386,
68 ehframe_mm5_i386,
69 ehframe_mm6_i386,
70 ehframe_mm7_i386,
71 };
72
73 // DWARF register numbers (eRegisterKindDWARF)
74 // Intel's x86 or IA-32
75 enum {
76 // General Purpose Registers.
77 dwarf_eax_i386 = 0,
78 dwarf_ecx_i386,
79 dwarf_edx_i386,
80 dwarf_ebx_i386,
81 dwarf_esp_i386,
82 dwarf_ebp_i386,
83 dwarf_esi_i386,
84 dwarf_edi_i386,
85 dwarf_eip_i386,
86 dwarf_eflags_i386,
87 // Floating Point Registers
88 dwarf_st0_i386 = 11,
89 dwarf_st1_i386,
90 dwarf_st2_i386,
91 dwarf_st3_i386,
92 dwarf_st4_i386,
93 dwarf_st5_i386,
94 dwarf_st6_i386,
95 dwarf_st7_i386,
96 // SSE Registers
97 dwarf_xmm0_i386 = 21,
98 dwarf_xmm1_i386,
99 dwarf_xmm2_i386,
100 dwarf_xmm3_i386,
101 dwarf_xmm4_i386,
102 dwarf_xmm5_i386,
103 dwarf_xmm6_i386,
104 dwarf_xmm7_i386,
105 // MMX Registers
106 dwarf_mm0_i386 = 29,
107 dwarf_mm1_i386,
108 dwarf_mm2_i386,
109 dwarf_mm3_i386,
110 dwarf_mm4_i386,
111 dwarf_mm5_i386,
112 dwarf_mm6_i386,
113 dwarf_mm7_i386,
114 dwarf_fctrl_i386 = 37, // x87 control word
115 dwarf_fstat_i386 = 38, // x87 status word
116 dwarf_mxcsr_i386 = 39,
117 dwarf_es_i386 = 40,
118 dwarf_cs_i386 = 41,
119 dwarf_ss_i386 = 42,
120 dwarf_ds_i386 = 43,
121 dwarf_fs_i386 = 44,
122 dwarf_gs_i386 = 45,
123
124 // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
125 // then differentiate based on size of the register.
126 dwarf_bnd0_i386 = 101,
127 dwarf_bnd1_i386,
128 dwarf_bnd2_i386,
129 dwarf_bnd3_i386,
130 };
131
132 // AMD x86_64, AMD64, Intel EM64T, or Intel 64 ehframe, dwarf regnums
133
134 // EHFrame and DWARF Register numbers (eRegisterKindEHFrame &
135 // eRegisterKindDWARF)
136 // This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
137 // http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
138 enum {
139 // GP Registers
140 dwarf_rax_x86_64 = 0,
141 dwarf_rdx_x86_64,
142 dwarf_rcx_x86_64,
143 dwarf_rbx_x86_64,
144 dwarf_rsi_x86_64,
145 dwarf_rdi_x86_64,
146 dwarf_rbp_x86_64,
147 dwarf_rsp_x86_64,
148 // Extended GP Registers
149 dwarf_r8_x86_64 = 8,
150 dwarf_r9_x86_64,
151 dwarf_r10_x86_64,
152 dwarf_r11_x86_64,
153 dwarf_r12_x86_64,
154 dwarf_r13_x86_64,
155 dwarf_r14_x86_64,
156 dwarf_r15_x86_64,
157 // Return Address (RA) mapped to RIP
158 dwarf_rip_x86_64 = 16,
159 // SSE Vector Registers
160 dwarf_xmm0_x86_64 = 17,
161 dwarf_xmm1_x86_64,
162 dwarf_xmm2_x86_64,
163 dwarf_xmm3_x86_64,
164 dwarf_xmm4_x86_64,
165 dwarf_xmm5_x86_64,
166 dwarf_xmm6_x86_64,
167 dwarf_xmm7_x86_64,
168 dwarf_xmm8_x86_64,
169 dwarf_xmm9_x86_64,
170 dwarf_xmm10_x86_64,
171 dwarf_xmm11_x86_64,
172 dwarf_xmm12_x86_64,
173 dwarf_xmm13_x86_64,
174 dwarf_xmm14_x86_64,
175 dwarf_xmm15_x86_64,
176 // Floating Point Registers
177 dwarf_st0_x86_64 = 33,
178 dwarf_st1_x86_64,
179 dwarf_st2_x86_64,
180 dwarf_st3_x86_64,
181 dwarf_st4_x86_64,
182 dwarf_st5_x86_64,
183 dwarf_st6_x86_64,
184 dwarf_st7_x86_64,
185 // MMX Registers
186 dwarf_mm0_x86_64 = 41,
187 dwarf_mm1_x86_64,
188 dwarf_mm2_x86_64,
189 dwarf_mm3_x86_64,
190 dwarf_mm4_x86_64,
191 dwarf_mm5_x86_64,
192 dwarf_mm6_x86_64,
193 dwarf_mm7_x86_64,
194 // Control and Status Flags Register
195 dwarf_rflags_x86_64 = 49,
196 // selector registers
197 dwarf_es_x86_64 = 50,
198 dwarf_cs_x86_64,
199 dwarf_ss_x86_64,
200 dwarf_ds_x86_64,
201 dwarf_fs_x86_64,
202 dwarf_gs_x86_64,
203 // Floating point control registers
204 dwarf_mxcsr_x86_64 = 64, // Media Control and Status
205 dwarf_fctrl_x86_64, // x87 control word
206 dwarf_fstat_x86_64, // x87 status word
207 // Upper Vector Registers
208 dwarf_ymm0h_x86_64 = 67,
209 dwarf_ymm1h_x86_64,
210 dwarf_ymm2h_x86_64,
211 dwarf_ymm3h_x86_64,
212 dwarf_ymm4h_x86_64,
213 dwarf_ymm5h_x86_64,
214 dwarf_ymm6h_x86_64,
215 dwarf_ymm7h_x86_64,
216 dwarf_ymm8h_x86_64,
217 dwarf_ymm9h_x86_64,
218 dwarf_ymm10h_x86_64,
219 dwarf_ymm11h_x86_64,
220 dwarf_ymm12h_x86_64,
221 dwarf_ymm13h_x86_64,
222 dwarf_ymm14h_x86_64,
223 dwarf_ymm15h_x86_64,
224 // MPX registers
225 dwarf_bnd0_x86_64 = 126,
226 dwarf_bnd1_x86_64,
227 dwarf_bnd2_x86_64,
228 dwarf_bnd3_x86_64,
229 // AVX2 Vector Mask Registers
230 // dwarf_k0_x86_64 = 118,
231 // dwarf_k1_x86_64,
232 // dwarf_k2_x86_64,
233 // dwarf_k3_x86_64,
234 // dwarf_k4_x86_64,
235 // dwarf_k5_x86_64,
236 // dwarf_k6_x86_64,
237 // dwarf_k7_x86_64,
238 };
239
240 // Generic floating-point registers
241
242 struct MMSReg {
243 uint8_t bytes[10];
244 uint8_t pad[6];
245 };
246
247 struct XMMReg {
248 uint8_t bytes[16]; // 128-bits for each XMM register
249 };
250
251 // i387_fxsave_struct
252 struct FXSAVE {
253 uint16_t fctrl; // FPU Control Word (fcw)
254 uint16_t fstat; // FPU Status Word (fsw)
255 uint16_t ftag; // FPU Tag Word (ftw)
256 uint16_t fop; // Last Instruction Opcode (fop)
257 union {
258 struct {
259 uint64_t fip; // Instruction Pointer
260 uint64_t fdp; // Data Pointer
261 } x86_64;
262 struct {
263 uint32_t fioff; // FPU IP Offset (fip)
264 uint32_t fiseg; // FPU IP Selector (fcs)
265 uint32_t fooff; // FPU Operand Pointer Offset (foo)
266 uint32_t foseg; // FPU Operand Pointer Selector (fos)
267 } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
268 // cases
269 } ptr;
270 uint32_t mxcsr; // MXCSR Register State
271 uint32_t mxcsrmask; // MXCSR Mask
272 MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
273 XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
274 uint8_t padding1[48];
275 uint64_t xcr0;
276 uint8_t padding2[40];
277 };
278
279 // Extended floating-point registers
280
281 struct YMMHReg {
282 uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
283 };
284
285 struct YMMReg {
286 uint8_t bytes[32]; // 16 * 16 bits for each YMM register
287 };
288
289 struct YMM {
290 YMMReg ymm[16]; // assembled from ymmh and xmm registers
291 };
292
293 struct MPXReg {
294 uint8_t bytes[16]; // MPX 128 bit bound registers
295 };
296
297 struct MPXCsr {
298 uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively
299 // BNDCSR state)
300 };
301
302 struct MPX {
303 MPXReg mpxr[4];
304 MPXCsr mpxc[2];
305 };
306
307 LLVM_PACKED_START
308 struct XSAVE_HDR {
309 enum class XFeature : uint64_t {
310 FP = 1,
311 SSE = FP << 1,
312 YMM = SSE << 1,
313 BNDREGS = YMM << 1,
314 BNDCSR = BNDREGS << 1,
315 OPMASK = BNDCSR << 1,
316 ZMM_Hi256 = OPMASK << 1,
317 Hi16_ZMM = ZMM_Hi256 << 1,
318 PT = Hi16_ZMM << 1,
319 PKRU = PT << 1,
320 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU)
321 };
322
323 XFeature xstate_bv; // OS enabled xstate mask to determine the extended states
324 // supported by the processor
325 XFeature xcomp_bv; // Mask to indicate the format of the XSAVE area and of
326 // the XRSTOR instruction
327 uint64_t reserved1[1];
328 uint64_t reserved2[5];
329 };
330 static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect");
331 LLVM_PACKED_END
332
333 // x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
334 LLVM_PACKED_START
335 struct XSAVE {
336 FXSAVE i387; // floating point registers typical in i387_fxsave_struct
337 XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the
338 // following extensions are usable
339 YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes
340 // are in FXSAVE.xmm for compatibility with SSE)
341 uint64_t reserved3[16];
342 MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers
343 MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and
344 // BNDSTATUS registers
345 };
346 LLVM_PACKED_END
347
348 // Floating-point registers
349 union FPR {
350 FXSAVE fxsave; // Generic floating-point registers.
351 XSAVE xsave; // x86 extended processor state.
352 };
353
354 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
355
356 // Convenience function to combine YMM register data from XSAVE-style input.
XStateToYMM(const void * xmm_bytes,const void * ymmh_bytes)357 inline YMMReg XStateToYMM(const void* xmm_bytes, const void* ymmh_bytes) {
358 YMMReg ret;
359
360 ::memcpy(ret.bytes, xmm_bytes, sizeof(XMMReg));
361 ::memcpy(ret.bytes + sizeof(XMMReg), ymmh_bytes, sizeof(YMMHReg));
362
363 return ret;
364 }
365
366 // Convenience function to copy YMM register data into XSAVE-style output.
YMMToXState(const YMMReg & input,void * xmm_bytes,void * ymmh_bytes)367 inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes) {
368 ::memcpy(xmm_bytes, input.bytes, sizeof(XMMReg));
369 ::memcpy(ymmh_bytes, input.bytes + sizeof(XMMReg), sizeof(YMMHReg));
370 }
371
372 } // namespace lldb_private
373
374 #endif
375