brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · e24da37 Raw
396 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXT_X86_H11 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 19namespace lldb_private {20// i386 ehframe, dwarf regnums21 22// Register numbers seen in eh_frame (eRegisterKindEHFrame) on i386 systems23// (non-Darwin)24//25enum {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 (versus32  // dwarf's reg numbering).33  // To be specific:34  //    i386+darwin eh_frame:        4 is ebp, 5 is esp35  //    i386+everyone else eh_frame: 4 is esp, 5 is ebp36  //    i386 dwarf:                  4 is esp, 5 is ebp37  // lldb will get the darwin-specific eh_frame reg numberings from debugserver,38  // or the ABI, so we39  // only encode the generally correct 4 == esp, 5 == ebp numbers in this40  // 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-3276enum {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 Registers89  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 Registers98  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 Registers107  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 word116  dwarf_fstat_i386 = 38, // x87 status word117  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 and126  //  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 regnums134 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.pdf139enum {140  // GP Registers141  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 Registers150  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 RIP159  dwarf_rip_x86_64 = 16,160  // SSE Vector Registers161  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 Registers178  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 Registers187  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 Register196  dwarf_rflags_x86_64 = 49,197  //  selector registers198  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 registers205  dwarf_fs_base_x86_64 = 58,206  dwarf_gs_base_x86_64 = 59,207  // Floating point control registers208  dwarf_mxcsr_x86_64 = 64, // Media Control and Status209  dwarf_fctrl_x86_64,      // x87 control word210  dwarf_fstat_x86_64,      // x87 status word211  // Upper Vector Registers212  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 registers229  dwarf_bnd0_x86_64 = 126,230  dwarf_bnd1_x86_64,231  dwarf_bnd2_x86_64,232  dwarf_bnd3_x86_64,233  // AVX2 Vector Mask Registers234  // 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 registers245 246LLVM_PACKED_START247struct MMSRegComp {248  uint64_t mantissa;249  uint16_t sign_exp;250};251 252struct MMSReg {253  union {254    uint8_t bytes[10];255    MMSRegComp comp;256  };257  uint8_t pad[6];258};259LLVM_PACKED_END260 261static_assert(sizeof(MMSRegComp) == 10, "MMSRegComp is not 10 bytes of size");262static_assert(sizeof(MMSReg) == 16, "MMSReg is not 16 bytes of size");263 264struct XMMReg {265  uint8_t bytes[16]; // 128-bits for each XMM register266};267 268// i387_fxsave_struct269struct 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 Pointer277      uint64_t fdp; // Data Pointer278    } 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 some285             // cases286  } ptr;287  uint32_t mxcsr;     // MXCSR Register State288  uint32_t mxcsrmask; // MXCSR Mask289  MMSReg stmm[8];     // 8*16 bytes for each FP-reg = 128 bytes290  XMMReg xmm[16];     // 16*16 bytes for each XMM-reg = 256 bytes291  uint8_t padding1[48];292  uint64_t xcr0;293  uint8_t padding2[40];294};295 296// Extended floating-point registers297 298struct YMMHReg {299  uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register300};301 302struct YMMReg {303  uint8_t bytes[32]; // 16 * 16 bits for each YMM register304};305 306struct YMM {307  YMMReg ymm[16]; // assembled from ymmh and xmm registers308};309 310struct MPXReg {311  uint8_t bytes[16]; // MPX 128 bit bound registers312};313 314struct MPXCsr {315  uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively316                    // BNDCSR state)317};318 319struct MPX {320  MPXReg mpxr[4];321  MPXCsr mpxc[2];322};323 324LLVM_PACKED_START325struct 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 states341                      // supported by the processor342  XFeature xcomp_bv;  // Mask to indicate the format of the XSAVE area and of343                      // the XRSTOR instruction344  uint64_t reserved1[1];345  uint64_t reserved2[5];346};347static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect");348LLVM_PACKED_END349 350// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)351LLVM_PACKED_START352struct XSAVE {353  FXSAVE i387;      // floating point registers typical in i387_fxsave_struct354  XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the355                    // following extensions are usable356  YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes357                    // are in FXSAVE.xmm for compatibility with SSE)358  uint64_t reserved3[16];359  MPXReg mpxr[4];   // MPX BNDREG state, containing 128-bit bound registers360  MPXCsr mpxc[2];   // MPX BNDCSR state, containing 64-bit BNDCFGU and361                    // BNDSTATUS registers362};363LLVM_PACKED_END364 365// Floating-point registers366union FPR {367  FXSAVE fxsave; // Generic floating-point registers.368  XSAVE xsave;   // x86 extended processor state.369};370 371LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();372 373// Convenience function to combine YMM register data from XSAVE-style input.374inline 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.384inline 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 389uint16_t AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw,390                               llvm::ArrayRef<MMSReg> st_regs);391uint8_t FullToAbridgedTagWord(uint16_t tw);392 393} // namespace lldb_private394 395#endif396