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