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. 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. 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